@@ -26,16 +26,16 @@ import (
2626)
2727
2828// RegisterExtras registers the type `SA` to be carried as an extra payload in
29- // [StateAccount] structs. It is expected to be called in an `init()` function
30- // and MUST NOT be called more than once.
29+ // [StateAccount] and [SlimAccount] structs. It is expected to be called in an
30+ // `init()` function and MUST NOT be called more than once.
3131//
3232// The payload will be treated as an extra struct field for the purposes of RLP
3333// encoding and decoding. RLP handling is plumbed through to the `SA` via the
3434// [StateAccountExtra] that holds it such that it acts as if there were a field
35- // of type `SA` in all StateAccount structs.
35+ // of type `SA` in all StateAccount and SlimAccount structs.
3636//
37- // The payload can be acced via the [ExtraPayloads.FromStateAccount ] method of
38- // the accessor returned by RegisterExtras.
37+ // The payload can be accessed via the [ExtraPayloads.FromPayloadCarrier ] method
38+ // of the accessor returned by RegisterExtras.
3939func RegisterExtras [SA any ]() ExtraPayloads [SA ] {
4040 if registeredExtras != nil {
4141 panic ("re-registration of Extras" )
@@ -82,8 +82,8 @@ func (e *StateAccountExtra) clone() *StateAccountExtra {
8282}
8383
8484// ExtraPayloads provides strongly typed access to the extra payload carried by
85- // [StateAccount] structs. The only valid way to construct an instance is by a
86- // call to [RegisterExtras].
85+ // [StateAccount] and [SlimAccount] structs. The only valid way to construct an
86+ // instance is by a call to [RegisterExtras].
8787type ExtraPayloads [SA any ] struct {
8888 _ struct {} // make godoc show unexported fields so nobody tries to make their own instance ;)
8989}
@@ -95,24 +95,36 @@ func (ExtraPayloads[SA]) cloneStateAccount(s *StateAccountExtra) *StateAccountEx
9595 }
9696}
9797
98- // FromStateAccount returns the StateAccount's payload.
99- func (ExtraPayloads [SA ]) FromStateAccount (a * StateAccount ) SA {
98+ // ExtraPayloadCarrier is implemented by both [StateAccount] and [SlimAccount],
99+ // allowing for their [StateAccountExtra] payloads to be accessed in a type-safe
100+ // manner by [ExtraPayloads] instances.
101+ type ExtraPayloadCarrier interface {
102+ extra () * StateAccountExtra
103+ }
104+
105+ var _ = []ExtraPayloadCarrier {
106+ (* StateAccount )(nil ),
107+ (* SlimAccount )(nil ),
108+ }
109+
110+ // FromPayloadCarrier returns the carriers's payload.
111+ func (ExtraPayloads [SA ]) FromPayloadCarrier (a ExtraPayloadCarrier ) SA {
100112 return pseudo.MustNewValue [SA ](a .extra ().payload ()).Get ()
101113}
102114
103- // PointerFromStateAccount returns a pointer to the StateAccounts 's extra
104- // payload. This is guaranteed to be non-nil.
115+ // PointerFromPayloadCarrier returns a pointer to the carriers 's extra payload.
116+ // This is guaranteed to be non-nil.
105117//
106- // Note that copying a StateAccount by dereferencing a pointer will result in a
107- // shallow copy and that the *SA returned here will therefore be shared by all
108- // copies. If this is not the desired behaviour, use
109- // [StateAccount.Copy] or [ExtraPayloads.SetOnStateAccount ].
110- func (ExtraPayloads [SA ]) PointerFromStateAccount (a * StateAccount ) * SA {
118+ // Note that copying a [ StateAccount] or [SlimAccount] by dereferencing a
119+ // pointer will result in a shallow copy and that the *SA returned here will
120+ // therefore be shared by all copies. If this is not the desired behaviour, use
121+ // [StateAccount.Copy] or [ExtraPayloads.SetOnPayloadCarrier ].
122+ func (ExtraPayloads [SA ]) PointerFromPayloadCarrier (a ExtraPayloadCarrier ) * SA {
111123 return pseudo.MustPointerTo [SA ](a .extra ().payload ()).Value .Get ()
112124}
113125
114- // SetOnStateAccount sets the StateAccount 's payload.
115- func (ExtraPayloads [SA ]) SetOnStateAccount (a * StateAccount , val SA ) {
126+ // SetOnPayloadCarrier sets the carriers 's payload.
127+ func (ExtraPayloads [SA ]) SetOnPayloadCarrier (a ExtraPayloadCarrier , val SA ) {
116128 a .extra ().t = pseudo .From (val ).Type
117129}
118130
@@ -124,12 +136,20 @@ type StateAccountExtra struct {
124136}
125137
126138func (a * StateAccount ) extra () * StateAccountExtra {
127- if a .Extra == nil {
128- a .Extra = & StateAccountExtra {
139+ return getOrSetNewStateAccountExtra (& a .Extra )
140+ }
141+
142+ func (a * SlimAccount ) extra () * StateAccountExtra {
143+ return getOrSetNewStateAccountExtra (& a .Extra )
144+ }
145+
146+ func getOrSetNewStateAccountExtra (curr * * StateAccountExtra ) * StateAccountExtra {
147+ if * curr == nil {
148+ * curr = & StateAccountExtra {
129149 t : registeredExtras .newStateAccount (),
130150 }
131151 }
132- return a . Extra
152+ return * curr
133153}
134154
135155func (e * StateAccountExtra ) payload () * pseudo.Type {
@@ -143,7 +163,7 @@ func (e *StateAccountExtra) payload() *pseudo.Type {
143163// of tests.
144164//
145165// Equal MUST NOT be used in production. Instead, compare values returned by
146- // [ExtraPayloads.FromStateAccount ].
166+ // [ExtraPayloads.FromPayloadCarrier ].
147167func (e * StateAccountExtra ) Equal (f * StateAccountExtra ) bool {
148168 if false {
149169 // TODO(arr4n): calling this results in an error from cmp.Diff():
0 commit comments