Skip to content

Commit 6e09eb3

Browse files
committed
feat: CheckConfig{Compatible,ForkOrder} + Description hooks
1 parent 58f3883 commit 6e09eb3

File tree

4 files changed

+53
-7
lines changed

4 files changed

+53
-7
lines changed

libevm/hookstest/stub.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ func Register[C params.ChainConfigHooks, R params.RulesHooks](tb testing.TB, ext
2525
// [params.RulesHooks]. Each of the fields, if non-nil, back their respective
2626
// hook methods, which otherwise fall back to the default behaviour.
2727
type Stub struct {
28+
CheckConfigForkOrderFn func() error
29+
CheckConfigCompatibleFn func(*params.ChainConfig, *big.Int, uint64) *params.ConfigCompatError
30+
DescriptionValue string
2831
PrecompileOverrides map[common.Address]libevm.PrecompiledContract
2932
CanExecuteTransactionFn func(common.Address, *common.Address, libevm.StateReader) error
3033
CanCreateContractFn func(*libevm.AddressContext, libevm.StateReader) error
@@ -52,6 +55,29 @@ func (s Stub) PrecompileOverride(a common.Address) (libevm.PrecompiledContract,
5255
return p, ok
5356
}
5457

58+
// CheckConfigForkOrder proxies arguments to the s.CheckConfigForkOrderFn
59+
// function if non-nil, otherwise it acts as a noop.
60+
func (s Stub) CheckConfigForkOrder() error {
61+
if f := s.CheckConfigForkOrderFn; f != nil {
62+
return f()
63+
}
64+
return nil
65+
}
66+
67+
// CheckConfigCompatible proxies arguments to the s.CheckConfigCompatibleFn
68+
// function if non-nil, otherwise it acts as a noop.
69+
func (s Stub) CheckConfigCompatible(newcfg *params.ChainConfig, headNumber *big.Int, headTimestamp uint64) *params.ConfigCompatError {
70+
if f := s.CheckConfigCompatibleFn; f != nil {
71+
return f(newcfg, headNumber, headTimestamp)
72+
}
73+
return nil
74+
}
75+
76+
// Description returns s.DescriptionValue.
77+
func (s Stub) Description() string {
78+
return s.DescriptionValue
79+
}
80+
5581
// CanExecuteTransaction proxies arguments to the s.CanExecuteTransactionFn
5682
// function if non-nil, otherwise it acts as a noop.
5783
func (s Stub) CanExecuteTransaction(from common.Address, to *common.Address, sr libevm.StateReader) error {

params/config.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ func (c *ChainConfig) Description() string {
478478
if c.VerkleTime != nil {
479479
banner += fmt.Sprintf(" - Verkle: @%-10v\n", *c.VerkleTime)
480480
}
481-
return banner
481+
return banner + c.Hooks().Description()
482482
}
483483

484484
// IsHomestead returns whether num is either equal to the homestead block or greater.
@@ -671,7 +671,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
671671
lastFork = cur
672672
}
673673
}
674-
return nil
674+
return c.Hooks().CheckConfigForkOrder()
675675
}
676676

677677
func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int, headTimestamp uint64) *ConfigCompatError {
@@ -742,7 +742,7 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int,
742742
if isForkTimestampIncompatible(c.VerkleTime, newcfg.VerkleTime, headTimestamp) {
743743
return newTimestampCompatError("Verkle fork timestamp", c.VerkleTime, newcfg.VerkleTime)
744744
}
745-
return nil
745+
return c.Hooks().CheckConfigCompatible(newcfg, headNumber, headTimestamp)
746746
}
747747

748748
// BaseFeeChangeDenominator bounds the amount the base fee can change between blocks.

params/example.libevm_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ func constructRulesExtra(c *params.ChainConfig, r *params.Rules, cEx ChainConfig
5151
// the standard [params.ChainConfig] struct.
5252
type ChainConfigExtra struct {
5353
MyForkTime *uint64 `json:"myForkTime"`
54+
55+
// (Optional) If not all hooks are desirable then embedding a [NOOPHooks]
56+
// allows the type to satisfy the [ChainConfigHooks] interface, resulting in
57+
// default Ethereum behaviour.
58+
params.NOOPHooks
5459
}
5560

5661
// RulesExtra can be any struct. It too mirrors a common pattern in
@@ -59,9 +64,6 @@ type RulesExtra struct {
5964
IsMyFork bool
6065
timestamp uint64
6166

62-
// (Optional) If not all hooks are desirable then embedding a [NOOPHooks]
63-
// allows the type to satisfy the [RulesHooks] interface, resulting in
64-
// default Ethereum behaviour.
6567
params.NOOPHooks
6668
}
6769

params/hooks.libevm.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
package params
22

33
import (
4+
"math/big"
5+
46
"github.com/ethereum/go-ethereum/common"
57
"github.com/ethereum/go-ethereum/libevm"
68
)
79

810
// ChainConfigHooks are required for all types registered as [Extras] for
911
// [ChainConfig] payloads.
10-
type ChainConfigHooks interface{}
12+
type ChainConfigHooks interface {
13+
CheckConfigForkOrder() error
14+
CheckConfigCompatible(newcfg *ChainConfig, headNumber *big.Int, headTimestamp uint64) *ConfigCompatError
15+
Description() string
16+
}
1117

1218
// TODO(arr4n): given the choice of whether a hook should be defined on a
1319
// ChainConfig or on the Rules, what are the guiding principles? A ChainConfig
@@ -66,6 +72,18 @@ var _ interface {
6672
RulesHooks
6773
} = NOOPHooks{}
6874

75+
func (NOOPHooks) CheckConfigForkOrder() error {
76+
return nil
77+
}
78+
79+
func (NOOPHooks) CheckConfigCompatible(*ChainConfig, *big.Int, uint64) *ConfigCompatError {
80+
return nil
81+
}
82+
83+
func (NOOPHooks) Description() string {
84+
return ""
85+
}
86+
6987
// CanExecuteTransaction allows all (otherwise valid) transactions.
7088
func (NOOPHooks) CanExecuteTransaction(_ common.Address, _ *common.Address, _ libevm.StateReader) error {
7189
return nil

0 commit comments

Comments
 (0)