From 0f7986c54b7d8ef4779a37ec82fd0c537e5afafd Mon Sep 17 00:00:00 2001 From: Darioush Jalali Date: Wed, 9 Oct 2024 15:41:23 -0700 Subject: [PATCH 1/3] add IsZero check in empty --- core/state/state_object.go | 2 +- core/types/rlp_payload.libevm.go | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/core/state/state_object.go b/core/state/state_object.go index bf77f0d8f20..07ebd20c7a6 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -93,7 +93,7 @@ type stateObject struct { // empty returns whether the account is considered empty. func (s *stateObject) empty() bool { - return s.data.Nonce == 0 && s.data.Balance.IsZero() && bytes.Equal(s.data.CodeHash, types.EmptyCodeHash.Bytes()) + return s.data.Nonce == 0 && s.data.Balance.IsZero() && bytes.Equal(s.data.CodeHash, types.EmptyCodeHash.Bytes()) && s.data.Extra.IsZero() } // newObject creates a state object. diff --git a/core/types/rlp_payload.libevm.go b/core/types/rlp_payload.libevm.go index 53f84705e45..765daab2c95 100644 --- a/core/types/rlp_payload.libevm.go +++ b/core/types/rlp_payload.libevm.go @@ -207,3 +207,7 @@ func (e *StateAccountExtra) Format(s fmt.State, verb rune) { } _, _ = s.Write([]byte(out)) } + +func (e *StateAccountExtra) IsZero() bool { + return e == nil || e.t == nil || e.t.IsZero() +} From 83a034c1647e353ee944b50f3721206d115165c5 Mon Sep 17 00:00:00 2001 From: Arran Schlosberg Date: Thu, 24 Oct 2024 17:20:38 +1100 Subject: [PATCH 2/3] test: `state.stateObject.empty()` --- core/state/state_object.libevm_test.go | 62 ++++++++++++++++++++++++++ core/types/rlp_payload.libevm.go | 11 +++-- 2 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 core/state/state_object.libevm_test.go diff --git a/core/state/state_object.libevm_test.go b/core/state/state_object.libevm_test.go new file mode 100644 index 00000000000..85494db983d --- /dev/null +++ b/core/state/state_object.libevm_test.go @@ -0,0 +1,62 @@ +package state + +import ( + "testing" + + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/stretchr/testify/require" +) + +func TestStateObjectEmpty(t *testing.T) { + tests := []struct { + name string + registerAndSet func(*types.StateAccount) + wantEmpty bool + }{ + { + name: "no registered types.StateAccount extra payload", + registerAndSet: func(*types.StateAccount) {}, + wantEmpty: true, + }, + { + name: "erroneously non-nil types.StateAccountExtra when no registered payload", + registerAndSet: func(acc *types.StateAccount) { + acc.Extra = &types.StateAccountExtra{} + }, + wantEmpty: true, + }, + { + name: "explicit false bool", + registerAndSet: func(acc *types.StateAccount) { + types.RegisterExtras[bool]().SetOnStateAccount(acc, false) + }, + wantEmpty: true, + }, + { + name: "implicit false bool", + registerAndSet: func(*types.StateAccount) { + types.RegisterExtras[bool]() + }, + wantEmpty: true, + }, + { + name: "true bool", + registerAndSet: func(acc *types.StateAccount) { + types.RegisterExtras[bool]().SetOnStateAccount(acc, true) + }, + wantEmpty: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + types.TestOnlyClearRegisteredExtras() + t.Cleanup(types.TestOnlyClearRegisteredExtras) + + obj := newObject(nil, common.Address{}, nil) + tt.registerAndSet(&obj.data) + require.Equalf(t, tt.wantEmpty, obj.empty(), "%T.empty()", obj) + }) + } +} diff --git a/core/types/rlp_payload.libevm.go b/core/types/rlp_payload.libevm.go index 765daab2c95..46af867d845 100644 --- a/core/types/rlp_payload.libevm.go +++ b/core/types/rlp_payload.libevm.go @@ -160,6 +160,13 @@ func (e *StateAccountExtra) Equal(f *StateAccountExtra) bool { return e.t.Equal(f.t) } +// IsZero reports whether e carries the the zero value for its type, as +// registered via [RegisterExtras]. It returns true if no type was registered or +// if `e == nil`. +func (e *StateAccountExtra) IsZero() bool { + return e == nil || e.t == nil || e.t.IsZero() +} + var _ interface { rlp.Encoder rlp.Decoder @@ -207,7 +214,3 @@ func (e *StateAccountExtra) Format(s fmt.State, verb rune) { } _, _ = s.Write([]byte(out)) } - -func (e *StateAccountExtra) IsZero() bool { - return e == nil || e.t == nil || e.t.IsZero() -} From 6abb19e3089b427a5628f53c9cf7d8789413b793 Mon Sep 17 00:00:00 2001 From: Arran Schlosberg Date: Thu, 24 Oct 2024 17:28:11 +1100 Subject: [PATCH 3/3] chore: sshhhh linter, sshhhh --- core/state/state_object.libevm_test.go | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/core/state/state_object.libevm_test.go b/core/state/state_object.libevm_test.go index 85494db983d..c4e07ec4b57 100644 --- a/core/state/state_object.libevm_test.go +++ b/core/state/state_object.libevm_test.go @@ -1,11 +1,28 @@ +// Copyright 2024 the libevm authors. +// +// The libevm additions to go-ethereum are free software: you can redistribute +// them and/or modify them under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// The libevm additions are distributed in the hope that they will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +// General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see +// . + package state import ( "testing" + "github.com/stretchr/testify/require" + "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/types" - "github.com/stretchr/testify/require" ) func TestStateObjectEmpty(t *testing.T) {