Skip to content

Commit a574ae6

Browse files
authored
feat: params.ExtraPayloads.SetOnChainConfig() + Rules equiv (#14)
* feat: `params.ExtraPayloadGetter.SetOnChainConfig()` + `Rules` equiv * refactor: rename `ExtraPayloadsGetter` to `ExtraPayloads`
1 parent d31803a commit a574ae6

File tree

4 files changed

+54
-42
lines changed

4 files changed

+54
-42
lines changed

params/config.libevm.go

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -47,27 +47,27 @@ type Extras[C ChainConfigHooks, R RulesHooks] struct {
4747
// Calls to [ChainConfig.Rules] will call the `NewRules` function of the
4848
// registered [Extras] to create a new `R`.
4949
//
50-
// The payloads can be accessed via the [ExtraPayloadGetter.FromChainConfig] and
51-
// [ExtraPayloadGetter.FromRules] methods of the getter returned by
52-
// RegisterExtras. Where stated in the interface definitions, they will also be
53-
// used as hooks to alter Ethereum behaviour; if this isn't desired then they
54-
// can embed [NOOPHooks] to satisfy either interface.
55-
func RegisterExtras[C ChainConfigHooks, R RulesHooks](e Extras[C, R]) ExtraPayloadGetter[C, R] {
50+
// The payloads can be accessed via the [ExtraPayloads.FromChainConfig] and
51+
// [ExtraPayloads.FromRules] methods of the accessor returned by RegisterExtras.
52+
// Where stated in the interface definitions, they will also be used as hooks to
53+
// alter Ethereum behaviour; if this isn't desired then they can embed
54+
// [NOOPHooks] to satisfy either interface.
55+
func RegisterExtras[C ChainConfigHooks, R RulesHooks](e Extras[C, R]) ExtraPayloads[C, R] {
5656
if registeredExtras != nil {
5757
panic("re-registration of Extras")
5858
}
5959
mustBeStructOrPointerToOne[C]()
6060
mustBeStructOrPointerToOne[R]()
6161

62-
getter := e.getter()
62+
payloads := e.payloads()
6363
registeredExtras = &extraConstructors{
6464
newChainConfig: pseudo.NewConstructor[C]().Zero,
6565
newRules: pseudo.NewConstructor[R]().Zero,
6666
reuseJSONRoot: e.ReuseJSONRoot,
6767
newForRules: e.newForRules,
68-
getter: getter,
68+
payloads: payloads,
6969
}
70-
return getter
70+
return payloads
7171
}
7272

7373
// TestOnlyClearRegisteredExtras clears the [Extras] previously passed to
@@ -102,7 +102,7 @@ type extraConstructors struct {
102102
newForRules func(_ *ChainConfig, _ *Rules, blockNum *big.Int, isMerge bool, timestamp uint64) *pseudo.Type
103103
// use top-level hooksFrom<X>() functions instead of these as they handle
104104
// instances where no [Extras] were registered.
105-
getter interface {
105+
payloads interface {
106106
hooksFromChainConfig(*ChainConfig) ChainConfigHooks
107107
hooksFromRules(*Rules) RulesHooks
108108
}
@@ -112,11 +112,11 @@ func (e *Extras[C, R]) newForRules(c *ChainConfig, r *Rules, blockNum *big.Int,
112112
if e.NewRules == nil {
113113
return registeredExtras.newRules()
114114
}
115-
rExtra := e.NewRules(c, r, e.getter().FromChainConfig(c), blockNum, isMerge, timestamp)
115+
rExtra := e.NewRules(c, r, e.payloads().FromChainConfig(c), blockNum, isMerge, timestamp)
116116
return pseudo.From(rExtra).Type
117117
}
118118

119-
func (*Extras[C, R]) getter() (g ExtraPayloadGetter[C, R]) { return }
119+
func (*Extras[C, R]) payloads() (g ExtraPayloads[C, R]) { return }
120120

121121
// mustBeStructOrPointerToOne panics if `T` isn't a struct or a *struct.
122122
func mustBeStructOrPointerToOne[T any]() {
@@ -140,44 +140,56 @@ func notStructMessage[T any]() string {
140140
return fmt.Sprintf("%T is not a struct nor a pointer to a struct", x)
141141
}
142142

143-
// An ExtraPayloadGettter provides strongly typed access to the extra payloads
144-
// carried by [ChainConfig] and [Rules] structs. The only valid way to construct
145-
// a getter is by a call to [RegisterExtras].
146-
type ExtraPayloadGetter[C ChainConfigHooks, R RulesHooks] struct {
147-
_ struct{} // make godoc show unexported fields so nobody tries to make their own getter ;)
143+
// ExtraPayloads provides strongly typed access to the extra payloads carried by
144+
// [ChainConfig] and [Rules] structs. The only valid way to construct an
145+
// instance is by a call to [RegisterExtras].
146+
type ExtraPayloads[C ChainConfigHooks, R RulesHooks] struct {
147+
_ struct{} // make godoc show unexported fields so nobody tries to make their own instance ;)
148148
}
149149

150150
// FromChainConfig returns the ChainConfig's extra payload.
151-
func (ExtraPayloadGetter[C, R]) FromChainConfig(c *ChainConfig) C {
151+
func (ExtraPayloads[C, R]) FromChainConfig(c *ChainConfig) C {
152152
return pseudo.MustNewValue[C](c.extraPayload()).Get()
153153
}
154154

155155
// PointerFromChainConfig returns a pointer to the ChainConfig's extra payload.
156156
// This is guaranteed to be non-nil.
157-
func (ExtraPayloadGetter[C, R]) PointerFromChainConfig(c *ChainConfig) *C {
157+
func (ExtraPayloads[C, R]) PointerFromChainConfig(c *ChainConfig) *C {
158158
return pseudo.MustPointerTo[C](c.extraPayload()).Value.Get()
159159
}
160160

161+
// SetOnChainConfig sets the ChainConfig's extra payload. It is equivalent to
162+
// `*e.PointerFromChainConfig(cc) = val`.
163+
func (e ExtraPayloads[C, R]) SetOnChainConfig(cc *ChainConfig, val C) {
164+
*e.PointerFromChainConfig(cc) = val
165+
}
166+
161167
// hooksFromChainConfig is equivalent to FromChainConfig(), but returns an
162168
// interface instead of the concrete type implementing it; this allows it to be
163169
// used in non-generic code.
164-
func (e ExtraPayloadGetter[C, R]) hooksFromChainConfig(c *ChainConfig) ChainConfigHooks {
170+
func (e ExtraPayloads[C, R]) hooksFromChainConfig(c *ChainConfig) ChainConfigHooks {
165171
return e.FromChainConfig(c)
166172
}
167173

168174
// FromRules returns the Rules' extra payload.
169-
func (ExtraPayloadGetter[C, R]) FromRules(r *Rules) R {
175+
func (ExtraPayloads[C, R]) FromRules(r *Rules) R {
170176
return pseudo.MustNewValue[R](r.extraPayload()).Get()
171177
}
172178

173179
// PointerFromRules returns a pointer to the Rules's extra payload. This is
174180
// guaranteed to be non-nil.
175-
func (ExtraPayloadGetter[C, R]) PointerFromRules(r *Rules) *R {
181+
func (ExtraPayloads[C, R]) PointerFromRules(r *Rules) *R {
176182
return pseudo.MustPointerTo[R](r.extraPayload()).Value.Get()
177183
}
178184

185+
// SetOnRules sets the Rules' extra payload. It is equivalent to
186+
// `*e.PointerFromRules(r) = val`.
187+
func (e ExtraPayloads[C, R]) SetOnRules(r *Rules, val R) {
188+
*e.PointerFromRules(r) = val
189+
}
190+
179191
// hooksFromRules is the [RulesHooks] equivalent of hooksFromChainConfig().
180-
func (e ExtraPayloadGetter[C, R]) hooksFromRules(r *Rules) RulesHooks {
192+
func (e ExtraPayloads[C, R]) hooksFromRules(r *Rules) RulesHooks {
181193
return e.FromRules(r)
182194
}
183195

@@ -195,7 +207,7 @@ func (c *ChainConfig) addRulesExtra(r *Rules, blockNum *big.Int, isMerge bool, t
195207
// unmarshalling of JSON), a nil value is constructed and returned.
196208
func (c *ChainConfig) extraPayload() *pseudo.Type {
197209
if registeredExtras == nil {
198-
// This will only happen if someone constructs an [ExtraPayloadGetter]
210+
// This will only happen if someone constructs an [ExtraPayloads]
199211
// directly, without a call to [RegisterExtras].
200212
//
201213
// See https://google.github.io/styleguide/go/best-practices#when-to-panic

params/config.libevm_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -135,38 +135,38 @@ func TestModificationOfZeroExtras(t *testing.T) {
135135

136136
TestOnlyClearRegisteredExtras()
137137
t.Cleanup(TestOnlyClearRegisteredExtras)
138-
getter := RegisterExtras(Extras[ccExtra, rulesExtra]{})
138+
extras := RegisterExtras(Extras[ccExtra, rulesExtra]{})
139139

140140
config := new(ChainConfig)
141141
rules := new(Rules)
142142
// These assertion helpers are defined before any modifications so that the
143143
// closure is demonstrably over the original zero values.
144144
assertChainConfigExtra := func(t *testing.T, want ccExtra, msg string) {
145145
t.Helper()
146-
assert.Equalf(t, want, getter.FromChainConfig(config), "%T: "+msg, &config)
146+
assert.Equalf(t, want, extras.FromChainConfig(config), "%T: "+msg, &config)
147147
}
148148
assertRulesExtra := func(t *testing.T, want rulesExtra, msg string) {
149149
t.Helper()
150-
assert.Equalf(t, want, getter.FromRules(rules), "%T: "+msg, &rules)
150+
assert.Equalf(t, want, extras.FromRules(rules), "%T: "+msg, &rules)
151151
}
152152

153153
assertChainConfigExtra(t, ccExtra{}, "zero value")
154154
assertRulesExtra(t, rulesExtra{}, "zero value")
155155

156156
const answer = 42
157-
getter.PointerFromChainConfig(config).X = answer
157+
extras.PointerFromChainConfig(config).X = answer
158158
assertChainConfigExtra(t, ccExtra{X: answer}, "after setting via pointer field")
159159

160160
const pi = 314159
161-
getter.PointerFromRules(rules).X = pi
161+
extras.PointerFromRules(rules).X = pi
162162
assertRulesExtra(t, rulesExtra{X: pi}, "after setting via pointer field")
163163

164164
ccReplace := ccExtra{X: 142857}
165-
*getter.PointerFromChainConfig(config) = ccReplace
165+
extras.SetOnChainConfig(config, ccReplace)
166166
assertChainConfigExtra(t, ccReplace, "after replacement of entire extra via `*pointer = x`")
167167

168168
rulesReplace := rulesExtra{X: 18101986}
169-
*getter.PointerFromRules(rules) = rulesReplace
169+
extras.SetOnRules(rules, rulesReplace)
170170
assertRulesExtra(t, rulesReplace, "after replacement of entire extra via `*pointer = x`")
171171

172172
if t.Failed() {
@@ -177,15 +177,15 @@ func TestModificationOfZeroExtras(t *testing.T) {
177177
ccCopy := *config
178178
rCopy := *rules
179179

180-
assert.Equal(t, getter.FromChainConfig(&ccCopy), ccReplace, "ChainConfig extras copied")
181-
assert.Equal(t, getter.FromRules(&rCopy), rulesReplace, "Rules extras copied")
180+
assert.Equal(t, extras.FromChainConfig(&ccCopy), ccReplace, "ChainConfig extras copied")
181+
assert.Equal(t, extras.FromRules(&rCopy), rulesReplace, "Rules extras copied")
182182

183183
const seqUp = 123456789
184-
getter.PointerFromChainConfig(&ccCopy).X = seqUp
184+
extras.PointerFromChainConfig(&ccCopy).X = seqUp
185185
assertChainConfigExtra(t, ccExtra{X: seqUp}, "original changed because copy only shallow")
186186

187187
const seqDown = 987654321
188-
getter.PointerFromRules(&rCopy).X = seqDown
188+
extras.PointerFromRules(&rCopy).X = seqDown
189189
assertRulesExtra(t, rulesExtra{X: seqDown}, "original changed because copy only shallow")
190190
})
191191
}

params/example.libevm_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ func initFn() {
3030
// This registration makes *all* [params.ChainConfig] and [params.Rules]
3131
// instances respect the payload types. They do not need to be modified to
3232
// know about `extraparams`.
33-
getter = params.RegisterExtras(params.Extras[ChainConfigExtra, RulesExtra]{
33+
payloads = params.RegisterExtras(params.Extras[ChainConfigExtra, RulesExtra]{
3434
NewRules: constructRulesExtra,
3535
})
3636
}
3737

38-
var getter params.ExtraPayloadGetter[ChainConfigExtra, RulesExtra]
38+
var payloads params.ExtraPayloads[ChainConfigExtra, RulesExtra]
3939

4040
// constructRulesExtra acts as an adjunct to the [params.ChainConfig.Rules]
4141
// method. Its primary purpose is to construct the extra payload for the
@@ -67,12 +67,12 @@ type RulesExtra struct {
6767

6868
// FromChainConfig returns the extra payload carried by the ChainConfig.
6969
func FromChainConfig(c *params.ChainConfig) ChainConfigExtra {
70-
return getter.FromChainConfig(c)
70+
return payloads.FromChainConfig(c)
7171
}
7272

7373
// FromRules returns the extra payload carried by the Rules.
7474
func FromRules(r *params.Rules) RulesExtra {
75-
return getter.FromRules(r)
75+
return payloads.FromRules(r)
7676
}
7777

7878
// myForkPrecompiledContracts is analogous to the vm.PrecompiledContracts<Fork>
@@ -114,7 +114,7 @@ func (r RulesExtra) CanCreateContract(*libevm.AddressContext, libevm.StateReader
114114

115115
// This example demonstrates how the rest of this file would be used from a
116116
// *different* package.
117-
func ExampleExtraPayloadGetter() {
117+
func ExampleExtraPayloads() {
118118
initFn() // Outside of an example this is unnecessary as the function will be a regular init().
119119

120120
const forkTime = 530003640

params/hooks.libevm.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ type RulesAllowlistHooks interface {
4040
// none were registered.
4141
func (c *ChainConfig) Hooks() ChainConfigHooks {
4242
if e := registeredExtras; e != nil {
43-
return e.getter.hooksFromChainConfig(c)
43+
return e.payloads.hooksFromChainConfig(c)
4444
}
4545
return NOOPHooks{}
4646
}
@@ -49,7 +49,7 @@ func (c *ChainConfig) Hooks() ChainConfigHooks {
4949
// none were registered.
5050
func (r *Rules) Hooks() RulesHooks {
5151
if e := registeredExtras; e != nil {
52-
return e.getter.hooksFromRules(r)
52+
return e.payloads.hooksFromRules(r)
5353
}
5454
return NOOPHooks{}
5555
}

0 commit comments

Comments
 (0)