Skip to content

Commit 02b51d0

Browse files
committed
refactor(params): reusable pseudo.Accessor
1 parent c2f1269 commit 02b51d0

File tree

2 files changed

+81
-12
lines changed

2 files changed

+81
-12
lines changed

libevm/pseudo/accessor.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2024 the libevm authors.
2+
//
3+
// The libevm additions to go-ethereum are free software: you can redistribute
4+
// them and/or modify them under the terms of the GNU Lesser General Public License
5+
// as published by the Free Software Foundation, either version 3 of the License,
6+
// or (at your option) any later version.
7+
//
8+
// The libevm additions are distributed in the hope that they will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
11+
// General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU Lesser General Public License
14+
// along with the go-ethereum library. If not, see
15+
// <http://www.gnu.org/licenses/>.
16+
17+
package pseudo
18+
19+
// An Accessor provides access to T values held in other types.
20+
type Accessor[From any, T any] struct {
21+
get func(From) *Type
22+
set func(From, *Type)
23+
}
24+
25+
// NewAccessor constructs a new [Accessor]. The `get` function MUST return a
26+
// [Type] holding a T.
27+
func NewAccessor[From any, T any](get func(From) *Type, set func(From, *Type)) Accessor[From, T] {
28+
return Accessor[From, T]{get, set}
29+
}
30+
31+
// Get returns the T held by the C.
32+
func (a Accessor[C, T]) Get(from C) T {
33+
return MustNewValue[T](a.get(from)).Get()
34+
}
35+
36+
// Get returns a pointer to the T held by the C, which is guaranteed to be
37+
// non-nil. However, if T is itself a pointer, no guarantees are provided.
38+
func (a Accessor[C, T]) GetPointer(from C) *T {
39+
return MustPointerTo[T](a.get(from)).Value.Get()
40+
}
41+
42+
// Set sets the T carried by the C.
43+
func (a Accessor[C, T]) Set(on C, val T) {
44+
a.set(on, From(val).Type)
45+
}

params/config.libevm.go

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,18 @@ func (e *Extras[C, R]) newForRules(c *ChainConfig, r *Rules, blockNum *big.Int,
121121
return pseudo.From(rExtra).Type
122122
}
123123

124-
func (*Extras[C, R]) payloads() (g ExtraPayloads[C, R]) { return }
124+
func (*Extras[C, R]) payloads() ExtraPayloads[C, R] {
125+
return ExtraPayloads[C, R]{
126+
ChainConfig: pseudo.NewAccessor[*ChainConfig, C](
127+
func(c *ChainConfig) *pseudo.Type { return c.extraPayload() },
128+
func(c *ChainConfig, t *pseudo.Type) { c.extra = t },
129+
),
130+
Rules: pseudo.NewAccessor[*Rules, R](
131+
func(r *Rules) *pseudo.Type { return r.extraPayload() },
132+
func(r *Rules, t *pseudo.Type) { r.extra = t },
133+
),
134+
}
135+
}
125136

126137
// mustBeStructOrPointerToOne panics if `T` isn't a struct or a *struct.
127138
func mustBeStructOrPointerToOne[T any]() {
@@ -149,12 +160,15 @@ func notStructMessage[T any]() string {
149160
// [ChainConfig] and [Rules] structs. The only valid way to construct an
150161
// instance is by a call to [RegisterExtras].
151162
type ExtraPayloads[C ChainConfigHooks, R RulesHooks] struct {
152-
_ struct{} // make godoc show unexported fields so nobody tries to make their own instance ;)
163+
ChainConfig pseudo.Accessor[*ChainConfig, C]
164+
Rules pseudo.Accessor[*Rules, R]
153165
}
154166

155167
// FromChainConfig returns the ChainConfig's extra payload.
156-
func (ExtraPayloads[C, R]) FromChainConfig(c *ChainConfig) C {
157-
return pseudo.MustNewValue[C](c.extraPayload()).Get()
168+
//
169+
// Deprecated: use the equivalent [ExtraPayloads.ChainConfig] method.
170+
func (e ExtraPayloads[C, R]) FromChainConfig(c *ChainConfig) C {
171+
return e.ChainConfig.Get(c)
158172
}
159173

160174
// PointerFromChainConfig returns a pointer to the ChainConfig's extra payload.
@@ -164,13 +178,17 @@ func (ExtraPayloads[C, R]) FromChainConfig(c *ChainConfig) C {
164178
// shallow copy and that the *C returned here will therefore be shared by all
165179
// copies. If this is not the desired behaviour, use
166180
// [ExtraPayloads.SetOnChainConfig].
167-
func (ExtraPayloads[C, R]) PointerFromChainConfig(c *ChainConfig) *C {
168-
return pseudo.MustPointerTo[C](c.extraPayload()).Value.Get()
181+
//
182+
// Deprecated: use the equivalent [ExtraPayloads.ChainConfig] method.
183+
func (e ExtraPayloads[C, R]) PointerFromChainConfig(c *ChainConfig) *C {
184+
return e.ChainConfig.GetPointer(c)
169185
}
170186

171187
// SetOnChainConfig sets the ChainConfig's extra payload.
188+
//
189+
// Deprecated: use the equivalent [ExtraPayloads.ChainConfig] method.
172190
func (e ExtraPayloads[C, R]) SetOnChainConfig(cc *ChainConfig, val C) {
173-
cc.extra = pseudo.From(val).Type
191+
e.ChainConfig.Set(cc, val)
174192
}
175193

176194
// hooksFromChainConfig is equivalent to FromChainConfig(), but returns an
@@ -181,8 +199,10 @@ func (e ExtraPayloads[C, R]) hooksFromChainConfig(c *ChainConfig) ChainConfigHoo
181199
}
182200

183201
// FromRules returns the Rules' extra payload.
184-
func (ExtraPayloads[C, R]) FromRules(r *Rules) R {
185-
return pseudo.MustNewValue[R](r.extraPayload()).Get()
202+
//
203+
// Deprecated: use the equivalent [ExtraPayloads.Rules] method.
204+
func (e ExtraPayloads[C, R]) FromRules(r *Rules) R {
205+
return e.Rules.Get(r)
186206
}
187207

188208
// PointerFromRules returns a pointer to the Rules's extra payload. This is
@@ -191,13 +211,17 @@ func (ExtraPayloads[C, R]) FromRules(r *Rules) R {
191211
// Note that copying a Rules by dereferencing a pointer will result in a shallow
192212
// copy and that the *R returned here will therefore be shared by all copies. If
193213
// this is not the desired behaviour, use [ExtraPayloads.SetOnRules].
194-
func (ExtraPayloads[C, R]) PointerFromRules(r *Rules) *R {
195-
return pseudo.MustPointerTo[R](r.extraPayload()).Value.Get()
214+
//
215+
// Deprecated: use the equivalent [ExtraPayloads.Rules] method.
216+
func (e ExtraPayloads[C, R]) PointerFromRules(r *Rules) *R {
217+
return e.Rules.GetPointer(r)
196218
}
197219

198220
// SetOnRules sets the Rules' extra payload.
221+
//
222+
// Deprecated: use the equivalent [ExtraPayloads.Rules] method.
199223
func (e ExtraPayloads[C, R]) SetOnRules(r *Rules, val R) {
200-
r.extra = pseudo.From(val).Type
224+
e.Rules.Set(r, val)
201225
}
202226

203227
// hooksFromRules is the [RulesHooks] equivalent of hooksFromChainConfig().

0 commit comments

Comments
 (0)