Skip to content

Commit b23074f

Browse files
committed
feat!: types.ExtraPayloads supports SlimAccount
1 parent 7d1b45b commit b23074f

File tree

6 files changed

+58
-38
lines changed

6 files changed

+58
-38
lines changed

core/state/state.libevm.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import (
2727
func GetExtra[SA any](s *StateDB, p types.ExtraPayloads[SA], addr common.Address) SA {
2828
stateObject := s.getStateObject(addr)
2929
if stateObject != nil {
30-
return p.FromStateAccount(&stateObject.data)
30+
return p.FromPayloadCarrier(&stateObject.data)
3131
}
3232
var zero SA
3333
return zero
@@ -45,9 +45,9 @@ func setExtraOnObject[SA any](s *stateObject, p types.ExtraPayloads[SA], addr co
4545
s.db.journal.append(extraChange[SA]{
4646
payloads: p,
4747
account: &addr,
48-
prev: p.FromStateAccount(&s.data),
48+
prev: p.FromPayloadCarrier(&s.data),
4949
})
50-
p.SetOnStateAccount(&s.data, extra)
50+
p.SetOnPayloadCarrier(&s.data, extra)
5151
}
5252

5353
// extraChange is a [journalEntry] for [SetExtra] / [setExtraOnObject].
@@ -60,5 +60,5 @@ type extraChange[SA any] struct {
6060
func (e extraChange[SA]) dirtied() *common.Address { return e.account }
6161

6262
func (e extraChange[SA]) revert(s *StateDB) {
63-
e.payloads.SetOnStateAccount(&s.getStateObject(*e.account).data, e.prev)
63+
e.payloads.SetOnPayloadCarrier(&s.getStateObject(*e.account).data, e.prev)
6464
}

core/state/state.libevm_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func TestGetSetExtra(t *testing.T) {
8787
Root: types.EmptyRootHash,
8888
CodeHash: types.EmptyCodeHash[:],
8989
}
90-
payloads.SetOnStateAccount(want, extra)
90+
payloads.SetOnPayloadCarrier(want, extra)
9191

9292
if diff := cmp.Diff(want, got); diff != "" {
9393
t.Errorf("types.FullAccount(%T.Account()) diff (-want +got):\n%s", iter, diff)

core/state/state_object.libevm_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func TestStateObjectEmpty(t *testing.T) {
4646
{
4747
name: "explicit false bool",
4848
registerAndSet: func(acc *types.StateAccount) {
49-
types.RegisterExtras[bool]().SetOnStateAccount(acc, false)
49+
types.RegisterExtras[bool]().SetOnPayloadCarrier(acc, false)
5050
},
5151
wantEmpty: true,
5252
},
@@ -60,7 +60,7 @@ func TestStateObjectEmpty(t *testing.T) {
6060
{
6161
name: "true bool",
6262
registerAndSet: func(acc *types.StateAccount) {
63-
types.RegisterExtras[bool]().SetOnStateAccount(acc, true)
63+
types.RegisterExtras[bool]().SetOnPayloadCarrier(acc, true)
6464
},
6565
wantEmpty: false,
6666
},

core/types/rlp_payload.libevm.go

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
3939
func 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].
8787
type 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

126138
func (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

135155
func (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].
147167
func (e *StateAccountExtra) Equal(f *StateAccountExtra) bool {
148168
if false {
149169
// TODO(arr4n): calling this results in an error from cmp.Diff():

core/types/state_account.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ type StateAccount struct {
3535
Root common.Hash // merkle root of the storage trie
3636
CodeHash []byte
3737

38-
Extra *StateAccountExtra
38+
Extra *StateAccountExtra // only access via [ExtraPayloads] instances
3939
}
4040

4141
// NewEmptyStateAccount constructs an empty state account.
@@ -71,7 +71,7 @@ type SlimAccount struct {
7171
Root []byte // Nil if root equals to types.EmptyRootHash
7272
CodeHash []byte // Nil if hash equals to types.EmptyCodeHash
7373

74-
Extra *StateAccountExtra
74+
Extra *StateAccountExtra // only access via [ExtraPayloads] instances
7575
}
7676

7777
// SlimAccountRLP encodes the state account in 'slim RLP' format.

core/types/state_account_storage.libevm_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,25 +71,25 @@ func TestStateAccountExtraViaTrieStorage(t *testing.T) {
7171
{
7272
name: "true-boolean payload",
7373
registerAndSetExtra: func(a *types.StateAccount) *types.StateAccount {
74-
types.RegisterExtras[bool]().SetOnStateAccount(a, true)
74+
types.RegisterExtras[bool]().SetOnPayloadCarrier(a, true)
7575
return a
7676
},
7777
assertExtra: func(t *testing.T, sa *types.StateAccount) {
7878
t.Helper()
79-
assert.Truef(t, types.ExtraPayloads[bool]{}.FromStateAccount(sa), "")
79+
assert.Truef(t, types.ExtraPayloads[bool]{}.FromPayloadCarrier(sa), "")
8080
},
8181
wantTrieHash: trueBool,
8282
},
8383
{
8484
name: "explicit false-boolean payload",
8585
registerAndSetExtra: func(a *types.StateAccount) *types.StateAccount {
8686
p := types.RegisterExtras[bool]()
87-
p.SetOnStateAccount(a, false) // the explicit part
87+
p.SetOnPayloadCarrier(a, false) // the explicit part
8888
return a
8989
},
9090
assertExtra: func(t *testing.T, sa *types.StateAccount) {
9191
t.Helper()
92-
assert.Falsef(t, types.ExtraPayloads[bool]{}.FromStateAccount(sa), "")
92+
assert.Falsef(t, types.ExtraPayloads[bool]{}.FromPayloadCarrier(sa), "")
9393
},
9494
wantTrieHash: falseBool,
9595
},
@@ -102,20 +102,20 @@ func TestStateAccountExtraViaTrieStorage(t *testing.T) {
102102
},
103103
assertExtra: func(t *testing.T, sa *types.StateAccount) {
104104
t.Helper()
105-
assert.Falsef(t, types.ExtraPayloads[bool]{}.FromStateAccount(sa), "")
105+
assert.Falsef(t, types.ExtraPayloads[bool]{}.FromPayloadCarrier(sa), "")
106106
},
107107
wantTrieHash: falseBool,
108108
},
109109
{
110110
name: "arbitrary payload",
111111
registerAndSetExtra: func(a *types.StateAccount) *types.StateAccount {
112112
p := arbitraryPayload{arbitraryData}
113-
types.RegisterExtras[arbitraryPayload]().SetOnStateAccount(a, p)
113+
types.RegisterExtras[arbitraryPayload]().SetOnPayloadCarrier(a, p)
114114
return a
115115
},
116116
assertExtra: func(t *testing.T, sa *types.StateAccount) {
117117
t.Helper()
118-
got := types.ExtraPayloads[arbitraryPayload]{}.FromStateAccount(sa)
118+
got := types.ExtraPayloads[arbitraryPayload]{}.FromPayloadCarrier(sa)
119119
assert.Equalf(t, arbitraryPayload{arbitraryData}, got, "")
120120
},
121121
wantTrieHash: arbitrary,

0 commit comments

Comments
 (0)