Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions hook/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,38 @@ import (

// Points define user-injected hook points.
type Points interface {
GasTarget(parent *types.Block) gas.Gas
SubSecondBlockTime(*types.Block) gas.Gas
BeforeBlock(params.Rules, *state.StateDB, *types.Block) error
AfterBlock(*state.StateDB, *types.Block, types.Receipts)
GasTarget(parent *types.Header) gas.Gas
// SubSecondBlockTime returns the sub-second portion of the block time based
// on the gas rate.
//
// For example, if the block timestamp is 10.75 seconds and the gas rate is
// 100 gas/second, then this method should return 75 gas.
SubSecondBlockTime(*types.Header) gas.Gas
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're going to need a SetSubSecondBlockTime() too, aren't we? Not necessarily here, but just thinking out loud.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't think we would need to do that, but I suppose it depends on how we are planning on constructing the header.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assumed it would have to be in a libevm extra payload, and we don't want to do any libevm registration in SAE as that would stop consumers from being able to.

// BeforeExecutingBlock is called immediately prior to executing the block.
BeforeExecutingBlock(params.Rules, *state.StateDB, *types.Block) error
// AfterExecutingBlock is called immediately after executing the block.
AfterExecutingBlock(*state.StateDB, *types.Block, types.Receipts)
}

// BeforeBlock is intended to be called before processing a block, with the gas
// target sourced from [Points].
func BeforeBlock(pts Points, rules params.Rules, sdb *state.StateDB, b *blocks.Block, clock *gastime.Time) error {
clock.FastForwardTo(
b.BuildTime(),
pts.SubSecondBlockTime(b.EthBlock()),
pts.SubSecondBlockTime(b.Header()),
)
target := pts.GasTarget(b.ParentBlock().EthBlock())
target := pts.GasTarget(b.ParentBlock().Header())
if err := clock.SetTarget(target); err != nil {
return fmt.Errorf("%T.SetTarget() before block: %w", clock, err)
}
return pts.BeforeBlock(rules, sdb, b.EthBlock())
return pts.BeforeExecutingBlock(rules, sdb, b.EthBlock())
}

// AfterBlock is intended to be called after processing a block, with the gas
// sourced from [types.Block.GasUsed] or equivalent.
func AfterBlock(pts Points, sdb *state.StateDB, b *types.Block, clock *gastime.Time, used gas.Gas, rs types.Receipts) {
clock.Tick(used)
pts.AfterBlock(sdb, b, rs)
pts.AfterExecutingBlock(sdb, b, rs)
}

// MinimumGasConsumption MUST be used as the implementation for the respective
Expand Down
12 changes: 6 additions & 6 deletions hook/hookstest/stub.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@ type Stub struct {
var _ hook.Points = (*Stub)(nil)

// GasTarget ignores its argument and always returns [Stub.Target].
func (s *Stub) GasTarget(parent *types.Block) gas.Gas {
func (s *Stub) GasTarget(*types.Header) gas.Gas {
return s.Target
}

// SubSecondBlockTime time ignores its argument and always returns 0.
func (*Stub) SubSecondBlockTime(*types.Block) gas.Gas {
func (*Stub) SubSecondBlockTime(*types.Header) gas.Gas {
return 0
}

// BeforeBlock is a no-op that always returns nil.
func (*Stub) BeforeBlock(params.Rules, *state.StateDB, *types.Block) error {
// BeforeExecutingBlock is a no-op that always returns nil.
func (*Stub) BeforeExecutingBlock(params.Rules, *state.StateDB, *types.Block) error {
return nil
}

// AfterBlock is a no-op.
func (*Stub) AfterBlock(*state.StateDB, *types.Block, types.Receipts) {}
// AfterExecutingBlock is a no-op.
func (*Stub) AfterExecutingBlock(*state.StateDB, *types.Block, types.Receipts) {}