From 20c195449f78b5f4b589f1b39913405f27851b61 Mon Sep 17 00:00:00 2001 From: hyeonLewis Date: Sun, 15 Dec 2024 23:11:22 +0900 Subject: [PATCH 1/4] Copy code fields for EOA --- blockchain/state/statedb_test.go | 24 +++++++++++++++++++ .../types/account/externally_owned_account.go | 3 +++ 2 files changed, 27 insertions(+) diff --git a/blockchain/state/statedb_test.go b/blockchain/state/statedb_test.go index b127675e4..337a10b16 100644 --- a/blockchain/state/statedb_test.go +++ b/blockchain/state/statedb_test.go @@ -35,7 +35,9 @@ import ( "testing/quick" "github.com/kaiachain/kaia/blockchain/types" + "github.com/kaiachain/kaia/blockchain/types/account" "github.com/kaiachain/kaia/common" + "github.com/kaiachain/kaia/crypto" "github.com/kaiachain/kaia/params" "github.com/kaiachain/kaia/storage/database" "github.com/kaiachain/kaia/storage/statedb" @@ -211,6 +213,28 @@ func TestStateObjects(t *testing.T) { assert.Equal(t, 128, len(stateDB.stateObjects)) } +// TestCopiedEIP7702 tests that copied EOA has the same code related fields as the original EOA. +// This test has been introduced since the implementation of EIP-7702. +func TestCopiedEIP7702(t *testing.T) { + stateDB, _ := New(common.Hash{}, NewDatabase(database.NewMemoryDBManager()), nil, nil) + + testCode := common.Hex2Bytes("0xef0100") + testCodeHash := crypto.Keccak256Hash(testCode) + + addr := common.BytesToAddress([]byte{5}) + stateDB.SetCodeToEOA(addr, testCode, params.Rules{}) + + assert.Equal(t, stateDB.GetCodeHash(addr), testCodeHash) + pa := account.GetProgramAccount(stateDB.GetAccount(addr)) + assert.Equal(t, pa.GetStorageRoot(), types.EmptyRootHash.ExtendZero()) + + copy := stateDB.Copy() + + assert.Equal(t, copy.GetCodeHash(addr), testCodeHash) + pa = account.GetProgramAccount(copy.GetAccount(addr)) + assert.Equal(t, pa.GetStorageRoot(), types.EmptyRootHash.ExtendZero()) +} + // Test that invalid pruning options are prohibited. func TestPruningOptions(t *testing.T) { opens := func(pruning bool, pruningNum bool) bool { diff --git a/blockchain/types/account/externally_owned_account.go b/blockchain/types/account/externally_owned_account.go index 0eeb97454..14f8404d3 100644 --- a/blockchain/types/account/externally_owned_account.go +++ b/blockchain/types/account/externally_owned_account.go @@ -105,6 +105,9 @@ func (e *ExternallyOwnedAccount) String() string { func (e *ExternallyOwnedAccount) DeepCopy() Account { return &ExternallyOwnedAccount{ AccountCommon: e.AccountCommon.DeepCopy(), + storageRoot: e.storageRoot, + codeHash: common.CopyBytes(e.codeHash), + codeInfo: e.codeInfo, } } From d5b9efa4773aa3ed9df831f766592d11d44fdb17 Mon Sep 17 00:00:00 2001 From: hyeonLewis Date: Sun, 15 Dec 2024 23:12:37 +0900 Subject: [PATCH 2/4] Use program account for storage root --- blockchain/state/statedb.go | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/blockchain/state/statedb.go b/blockchain/state/statedb.go index 584e82741..6d2445dcc 100644 --- a/blockchain/state/statedb.go +++ b/blockchain/state/statedb.go @@ -1183,7 +1183,7 @@ func (s *StateDB) GetTxHash() common.Hash { var ( errNotExistingAddress = fmt.Errorf("there is no account corresponding to the given address") - errNotContractAddress = fmt.Errorf("given address is not a contract address") + errNotProgramAccount = fmt.Errorf("given address is not a program account") ) func (s *StateDB) GetContractStorageRoot(contractAddr common.Address) (common.ExtHash, error) { @@ -1191,14 +1191,11 @@ func (s *StateDB) GetContractStorageRoot(contractAddr common.Address) (common.Ex if acc == nil { return common.ExtHash{}, errNotExistingAddress } - if acc.Type() != account.SmartContractAccountType { - return common.ExtHash{}, errNotContractAddress + pa := account.GetProgramAccount(acc) + if pa == nil { + return common.ExtHash{}, errNotProgramAccount } - contract, true := acc.(*account.SmartContractAccount) - if !true { - return common.ExtHash{}, errNotContractAddress - } - return contract.GetStorageRoot(), nil + return pa.GetStorageRoot(), nil } // Prepare handles the preparatory steps for executing a state transition with. From 250b9dce4812cad4cb0603400c68600c5926c96a Mon Sep 17 00:00:00 2001 From: hyeonLewis Date: Sun, 15 Dec 2024 23:13:03 +0900 Subject: [PATCH 3/4] Fix EOA test for EIP-7702 --- blockchain/types/account/account_test.go | 9 +++++++++ .../types/account/externally_owned_account.go | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/blockchain/types/account/account_test.go b/blockchain/types/account/account_test.go index 50de22441..147721d2d 100644 --- a/blockchain/types/account/account_test.go +++ b/blockchain/types/account/account_test.go @@ -149,6 +149,9 @@ func TestAccountSerializer(t *testing.T) { "Empty EOA", &ExternallyOwnedAccount{ AccountCommon: commonFieldsEmpty, + storageRoot: emptyRoot.ExtendZero(), + codeHash: emptyCodeHash, + codeInfo: codeinfoZero, }, // 01 ["","","","01",[]] "0x01c580808001c0", @@ -171,6 +174,9 @@ func TestAccountSerializer(t *testing.T) { "Nonempty EOA", &ExternallyOwnedAccount{ AccountCommon: commonFields, + storageRoot: emptyRoot.ExtendZero(), + codeHash: emptyCodeHash, + codeInfo: codeinfoZero, }, // 01 ["0x2a","0x12345678","","0x01",[]] "0x01c92a84123456788001c0", @@ -193,6 +199,9 @@ func TestAccountSerializer(t *testing.T) { "AccountUpdated EOA", &ExternallyOwnedAccount{ AccountCommon: commonFieldsUpdated, + storageRoot: emptyRoot.ExtendZero(), + codeHash: emptyCodeHash, + codeInfo: codeinfoZero, }, // 01 ["0x2a","0x12345678","","0x02","0x038318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75"] "0x01ea2a84123456788002a1038318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75", diff --git a/blockchain/types/account/externally_owned_account.go b/blockchain/types/account/externally_owned_account.go index 14f8404d3..71b10f478 100644 --- a/blockchain/types/account/externally_owned_account.go +++ b/blockchain/types/account/externally_owned_account.go @@ -99,7 +99,14 @@ func (e *ExternallyOwnedAccount) Dump() { } func (e *ExternallyOwnedAccount) String() string { - return fmt.Sprintf("EOA: %s", e.AccountCommon.String()) + return fmt.Sprintf(`EOA:%s + StorageRoot: %s + CodeHash: %s + CodeInfo: %s`, + e.AccountCommon.String(), + e.storageRoot.String(), + common.Bytes2Hex(e.codeHash), + e.codeInfo.String()) } func (e *ExternallyOwnedAccount) DeepCopy() Account { @@ -117,7 +124,10 @@ func (e *ExternallyOwnedAccount) Equal(a Account) bool { return false } - return e.AccountCommon.Equal(e2.AccountCommon) + return e.AccountCommon.Equal(e2.AccountCommon) && + e.storageRoot == e2.storageRoot && + bytes.Equal(e.codeHash, e2.codeHash) && + e.codeInfo == e2.codeInfo } func (e *ExternallyOwnedAccount) GetStorageRoot() common.ExtHash { From 338a9c621bc3bc76cb9ac45713dd26e1fd4d1476 Mon Sep 17 00:00:00 2001 From: hyeonLewis Date: Mon, 16 Dec 2024 09:03:57 +0900 Subject: [PATCH 4/4] Use errors instead of fmt --- blockchain/state/statedb.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/blockchain/state/statedb.go b/blockchain/state/statedb.go index 6d2445dcc..f91611329 100644 --- a/blockchain/state/statedb.go +++ b/blockchain/state/statedb.go @@ -24,6 +24,7 @@ package state import ( "bytes" + "errors" "fmt" "math/big" "sort" @@ -1182,8 +1183,8 @@ func (s *StateDB) GetTxHash() common.Hash { } var ( - errNotExistingAddress = fmt.Errorf("there is no account corresponding to the given address") - errNotProgramAccount = fmt.Errorf("given address is not a program account") + errNotExistingAddress = errors.New("there is no account corresponding to the given address") + errNotProgramAccount = errors.New("given address is not a program account") ) func (s *StateDB) GetContractStorageRoot(contractAddr common.Address) (common.ExtHash, error) {