Skip to content

Commit cda5afb

Browse files
committed
feat: vm.SlimAccount.Extra from StateAccount equiv
1 parent 0db9528 commit cda5afb

File tree

5 files changed

+84
-24
lines changed

5 files changed

+84
-24
lines changed

core/state/snapshot/snapshot_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func TestDiskLayerExternalInvalidationFullFlatten(t *testing.T) {
119119
}
120120
// Since the base layer was modified, ensure that data retrievals on the external reference fail
121121
if acc, err := ref.Account(common.HexToHash("0x01")); err != ErrSnapshotStale {
122-
t.Errorf("stale reference returned account: %#x (err: %v)", acc, err)
122+
t.Errorf("stale reference returned account: %+v (err: %v)", acc, err)
123123
}
124124
if slot, err := ref.Storage(common.HexToHash("0xa1"), common.HexToHash("0xb1")); err != ErrSnapshotStale {
125125
t.Errorf("stale reference returned storage slot: %#x (err: %v)", slot, err)
@@ -169,7 +169,7 @@ func TestDiskLayerExternalInvalidationPartialFlatten(t *testing.T) {
169169
}
170170
// Since the base layer was modified, ensure that data retrievals on the external reference fail
171171
if acc, err := ref.Account(common.HexToHash("0x01")); err != ErrSnapshotStale {
172-
t.Errorf("stale reference returned account: %#x (err: %v)", acc, err)
172+
t.Errorf("stale reference returned account: %+v (err: %v)", acc, err)
173173
}
174174
if slot, err := ref.Storage(common.HexToHash("0xa1"), common.HexToHash("0xb1")); err != ErrSnapshotStale {
175175
t.Errorf("stale reference returned storage slot: %#x (err: %v)", slot, err)
@@ -231,7 +231,7 @@ func TestDiffLayerExternalInvalidationPartialFlatten(t *testing.T) {
231231
}
232232
// Since the accumulator diff layer was modified, ensure that data retrievals on the external reference fail
233233
if acc, err := ref.Account(common.HexToHash("0x01")); err != ErrSnapshotStale {
234-
t.Errorf("stale reference returned account: %#x (err: %v)", acc, err)
234+
t.Errorf("stale reference returned account: %+v (err: %v)", acc, err)
235235
}
236236
if slot, err := ref.Storage(common.HexToHash("0xa1"), common.HexToHash("0xb1")); err != ErrSnapshotStale {
237237
t.Errorf("stale reference returned storage slot: %#x (err: %v)", slot, err)
@@ -280,7 +280,7 @@ func TestPostCapBasicDataAccess(t *testing.T) {
280280
// shouldErr checks that an account access errors as expected
281281
shouldErr := func(layer *diffLayer, key string) error {
282282
if data, err := layer.Account(common.HexToHash(key)); err == nil {
283-
return fmt.Errorf("expected error, got data %x", data)
283+
return fmt.Errorf("expected error, got data %+v", data)
284284
}
285285
return nil
286286
}

core/types/gen_slim_account_rlp.libevm.go

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/types/rlp_payload.libevm.go

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,39 +30,57 @@ func RegisterExtras[SA any](extras Extras[SA]) {
3030
panic("re-registration of Extras")
3131
}
3232
registeredExtras = &extraConstructors{
33-
newStateAccount: pseudo.NewConstructor[SA]().Zero,
33+
newStateAccount: pseudo.NewConstructor[SA]().Zero,
34+
cloneStateAccount: extras.cloneStateAccount,
35+
}
36+
}
37+
38+
func (e Extras[SA]) cloneStateAccount(s *StateAccountExtra) *StateAccountExtra {
39+
v := pseudo.MustNewValue[SA](s.t)
40+
return &StateAccountExtra{
41+
t: pseudo.From(v.Get()).Type,
3442
}
3543
}
3644

3745
var registeredExtras *extraConstructors
3846

3947
type extraConstructors struct {
40-
newStateAccount func() *pseudo.Type
48+
newStateAccount func() *pseudo.Type
49+
cloneStateAccount func(*StateAccountExtra) *StateAccountExtra
4150
}
4251

4352
type StateAccountExtra struct {
4453
t *pseudo.Type
4554
}
4655

56+
func (e *StateAccountExtra) clone() *StateAccountExtra {
57+
switch r := registeredExtras; {
58+
case r == nil, e == nil:
59+
return nil
60+
default:
61+
return r.cloneStateAccount(e)
62+
}
63+
}
64+
4765
var _ interface {
4866
rlp.Encoder
4967
rlp.Decoder
5068
} = (*StateAccountExtra)(nil)
5169

52-
func (p *StateAccountExtra) EncodeRLP(w io.Writer) error {
70+
func (e *StateAccountExtra) EncodeRLP(w io.Writer) error {
5371
switch r := registeredExtras; {
5472
case r == nil:
5573
return nil
56-
case p == nil:
57-
p = &StateAccountExtra{}
74+
case e == nil:
75+
e = &StateAccountExtra{}
5876
fallthrough
59-
case p.t == nil:
60-
p.t = r.newStateAccount()
77+
case e.t == nil:
78+
e.t = r.newStateAccount()
6179
}
62-
return p.t.EncodeRLP(w)
80+
return e.t.EncodeRLP(w)
6381
}
6482

65-
func (p *StateAccountExtra) DecodeRLP(s *rlp.Stream) error {
83+
func (e *StateAccountExtra) DecodeRLP(s *rlp.Stream) error {
6684
// DO NOT MERGE without implementation
6785
return nil
6886
}

core/types/state_account.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
)
2626

2727
//go:generate go run ../../rlp/rlpgen -type StateAccount -out gen_account_rlp.go
28+
//go:generate go run ../../rlp/rlpgen -type SlimAccount -out gen_slim_account_rlp.libevm.go
2829

2930
// StateAccount is the Ethereum consensus representation of accounts.
3031
// These objects are stored in the main account trie.
@@ -57,6 +58,7 @@ func (acct *StateAccount) Copy() *StateAccount {
5758
Balance: balance,
5859
Root: acct.Root,
5960
CodeHash: common.CopyBytes(acct.CodeHash),
61+
Extra: acct.Extra.clone(),
6062
}
6163
}
6264

@@ -68,21 +70,24 @@ type SlimAccount struct {
6870
Balance *uint256.Int
6971
Root []byte // Nil if root equals to types.EmptyRootHash
7072
CodeHash []byte // Nil if hash equals to types.EmptyCodeHash
73+
74+
Extra *StateAccountExtra
7175
}
7276

7377
// SlimAccountRLP encodes the state account in 'slim RLP' format.
7478
func SlimAccountRLP(account StateAccount) []byte {
7579
slim := SlimAccount{
7680
Nonce: account.Nonce,
7781
Balance: account.Balance,
82+
Extra: account.Extra.clone(),
7883
}
7984
if account.Root != EmptyRootHash {
8085
slim.Root = account.Root[:]
8186
}
8287
if !bytes.Equal(account.CodeHash, EmptyCodeHash[:]) {
8388
slim.CodeHash = account.CodeHash
8489
}
85-
data, err := rlp.EncodeToBytes(slim)
90+
data, err := rlp.EncodeToBytes(&slim)
8691
if err != nil {
8792
panic(err)
8893
}
@@ -98,6 +103,7 @@ func FullAccount(data []byte) (*StateAccount, error) {
98103
}
99104
var account StateAccount
100105
account.Nonce, account.Balance = slim.Nonce, slim.Balance
106+
account.Extra = slim.Extra.clone()
101107

102108
// Interpret the storage root and code hash in slim format.
103109
if len(slim.Root) == 0 {

core/types/state_account.libevm_test.go

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,34 +142,34 @@ func TestSlimAccountRLP(t *testing.T) {
142142
// modifications, to lock in default behaviour.
143143
tests := []struct {
144144
name string
145-
acc SlimAccount
145+
acc *SlimAccount
146146
wantHex string
147147
}{
148148
{
149-
acc: SlimAccount{
149+
acc: &SlimAccount{
150150
Nonce: 0x444444,
151151
Balance: uint256.NewInt(0x777777),
152152
},
153153
wantHex: `0xca83444444837777778080`,
154154
},
155155
{
156-
acc: SlimAccount{
156+
acc: &SlimAccount{
157157
Nonce: 0x444444,
158158
Balance: uint256.NewInt(0x777777),
159159
Root: common.MaxHash[:],
160160
},
161161
wantHex: `0xea8344444483777777a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80`,
162162
},
163163
{
164-
acc: SlimAccount{
164+
acc: &SlimAccount{
165165
Nonce: 0x444444,
166166
Balance: uint256.NewInt(0x777777),
167167
CodeHash: common.MaxHash[:],
168168
},
169169
wantHex: `0xea834444448377777780a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`,
170170
},
171171
{
172-
acc: SlimAccount{
172+
acc: &SlimAccount{
173173
Nonce: 0x444444,
174174
Balance: uint256.NewInt(0x777777),
175175
Root: common.MaxHash[:],
@@ -183,12 +183,24 @@ func TestSlimAccountRLP(t *testing.T) {
183183
t.Run(tt.name, func(t *testing.T) {
184184
buf := assertRLPEncodingAndReturn(t, tt.acc, tt.wantHex)
185185

186-
var got SlimAccount
187-
require.NoError(t, rlp.DecodeBytes(buf, &got), "rlp.DecodeBytes()")
186+
got := new(SlimAccount)
187+
require.NoError(t, rlp.DecodeBytes(buf, got), "rlp.DecodeBytes()")
188+
189+
opts := []cmp.Option{
190+
// The require package differentiates between empty and nil
191+
// slices and doesn't have a configuration mechanism.
192+
cmpopts.EquateEmpty(),
193+
cmp.Comparer(func(a, b *StateAccountExtra) bool {
194+
aNil := a == nil || a.t == nil
195+
bNil := b == nil || b.t == nil
196+
if aNil && bNil {
197+
return true
198+
}
199+
return false // DO NOT MERGE
200+
}),
201+
}
188202

189-
// The require package differentiates between empty and nil slices
190-
// and doesn't have a configuration mechanism.
191-
if diff := cmp.Diff(tt.acc, got, cmpopts.EquateEmpty()); diff != "" {
203+
if diff := cmp.Diff(tt.acc, got, opts...); diff != "" {
192204
t.Errorf("rlp.DecodeBytes(rlp.EncodeToBytes(%T), ...) round trip; diff (-want +got):\n%s", tt.acc, diff)
193205
}
194206
})

0 commit comments

Comments
 (0)