diff --git a/core/state/database.go b/core/state/database.go index f8327c4e383b..db1baf0727c5 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -141,7 +141,7 @@ type Trie interface { // UpdateAccount abstracts an account write to the trie. It encodes the // provided account object with associated algorithm and then updates it // in the trie with provided address. - UpdateAccount(address common.Address, account *types.StateAccount) error + UpdateAccount(address common.Address, account *types.StateAccount, codeLen int) error // UpdateContractCode abstracts code write to the trie. It is expected // to be moved to the stateWriter interface when the latter is ready. diff --git a/core/state/statedb.go b/core/state/statedb.go index 4f64d19f4a3e..bbc7b649365c 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -576,7 +576,7 @@ func (s *StateDB) updateStateObject(obj *stateObject) { } // Encode the account and update the account trie addr := obj.Address() - if err := s.trie.UpdateAccount(addr, &obj.data); err != nil { + if err := s.trie.UpdateAccount(addr, &obj.data, len(obj.code)); err != nil { s.setError(fmt.Errorf("updateStateObject (%x) error: %v", addr[:], err)) } if obj.dirtyCode { diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 6fe37cc631dc..5a03ad124bd0 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -775,8 +775,8 @@ func TestProcessVerkleInvalidContractCreation(t *testing.T) { if stemStateDiff.SuffixDiffs[0].NewValue == nil { t.Fatalf("missing post state value for BLOCKHASH contract at block #2") } - if *stemStateDiff.SuffixDiffs[0].NewValue != common.HexToHash("0a130e6478e47593861d8c3feb65045497327d89619dd12ae12d70e73a0191dd") { - t.Fatalf("invalid post state value for BLOCKHASH contract at block #2: 0a130e6478e47593861d8c3feb65045497327d89619dd12ae12d70e73a0191dd != %x", (*stemStateDiff.SuffixDiffs[0].NewValue)[:]) + if *stemStateDiff.SuffixDiffs[0].NewValue != common.HexToHash("9707126aaa05384bff8a3b9218e00ba75a6bb8ed0a2110661649ff34546a8380") { + t.Fatalf("invalid post state value for BLOCKHASH contract at block #2: 9707126aaa05384bff8a3b9218e00ba75a6bb8ed0a2110661649ff34546a8380 != %x", (*stemStateDiff.SuffixDiffs[0].NewValue)[:]) } } else if suffixDiff.Suffix > 4 { t.Fatalf("invalid suffix diff found for %x in block #2: %d\n", stemStateDiff.Stem, suffixDiff.Suffix) @@ -1202,20 +1202,20 @@ func TestProcessVerkleSelfDestructInSeparateTx(t *testing.T) { t.Fatalf("no state diff found for stem") } - balanceStateDiff := statediff[1][stateDiffIdx].SuffixDiffs[1] + balanceStateDiff := statediff[1][stateDiffIdx].SuffixDiffs[0] if balanceStateDiff.Suffix != utils.BasicDataLeafKey { t.Fatalf("balance invalid suffix") } // The original balance was 42. - var fourtyTwo [32]byte + var fourtyTwo [16]byte fourtyTwo[0] = 42 - if *balanceStateDiff.CurrentValue != fourtyTwo { - t.Fatalf("the pre-state balance before self-destruct must be 42") + if !bytes.Equal((*balanceStateDiff.CurrentValue)[utils.BasicDataBalanceOffset:], fourtyTwo[:]) { + t.Fatalf("the pre-state balance before self-destruct must be %x, got %x", fourtyTwo, *balanceStateDiff.CurrentValue) } // The new balance must be 0. - if *balanceStateDiff.NewValue != zero { + if !bytes.Equal((*balanceStateDiff.NewValue)[utils.BasicDataBalanceOffset:], zero[utils.BasicDataBalanceOffset:]) { t.Fatalf("the post-state balance after self-destruct must be 0") } } @@ -1243,8 +1243,8 @@ func TestProcessVerkleSelfDestructInSeparateTx(t *testing.T) { if balanceStateDiff.NewValue == nil { t.Fatalf("codeHash.NewValue must not be empty") } - preStateBalance := binary.LittleEndian.Uint64(balanceStateDiff.CurrentValue[:]) - postStateBalance := binary.LittleEndian.Uint64(balanceStateDiff.NewValue[:]) + preStateBalance := binary.LittleEndian.Uint64(balanceStateDiff.CurrentValue[utils.BasicDataBalanceOffset:]) + postStateBalance := binary.LittleEndian.Uint64(balanceStateDiff.NewValue[utils.BasicDataBalanceOffset:]) if postStateBalance-preStateBalance != 42 { t.Fatalf("the post-state balance after self-destruct must be 42") } @@ -1330,7 +1330,7 @@ func TestProcessVerkleSelfDestructInSameTx(t *testing.T) { t.Fatalf("no state diff found for stem") } - balanceStateDiff := statediff[0][stateDiffIdx].SuffixDiffs[1] + balanceStateDiff := statediff[0][stateDiffIdx].SuffixDiffs[0] if balanceStateDiff.Suffix != utils.BasicDataLeafKey { t.Fatalf("balance invalid suffix") } @@ -1367,8 +1367,8 @@ func TestProcessVerkleSelfDestructInSameTx(t *testing.T) { if balanceStateDiff.NewValue == nil { t.Fatalf("codeHash.NewValue must not be empty") } - preStateBalance := binary.LittleEndian.Uint64(balanceStateDiff.CurrentValue[:]) - postStateBalance := binary.LittleEndian.Uint64(balanceStateDiff.NewValue[:]) + preStateBalance := binary.LittleEndian.Uint64(balanceStateDiff.CurrentValue[utils.BasicDataBalanceOffset:]) + postStateBalance := binary.LittleEndian.Uint64(balanceStateDiff.NewValue[utils.BasicDataBalanceOffset:]) if postStateBalance-preStateBalance != 42 { t.Fatalf("the post-state balance after self-destruct must be 42") } @@ -1476,15 +1476,15 @@ func TestProcessVerkleSelfDestructInSeparateTxWithSelfBeneficiary(t *testing.T) t.Fatalf("no state diff found for stem") } - balanceStateDiff := statediff[1][stateDiffIdx].SuffixDiffs[1] + balanceStateDiff := statediff[1][stateDiffIdx].SuffixDiffs[0] if balanceStateDiff.Suffix != utils.BasicDataLeafKey { t.Fatalf("balance invalid suffix") } // The original balance was 42. - var fourtyTwo [32]byte + var fourtyTwo [16]byte fourtyTwo[0] = 42 - if *balanceStateDiff.CurrentValue != fourtyTwo { + if !bytes.Equal((*balanceStateDiff.CurrentValue)[utils.BasicDataBalanceOffset:], fourtyTwo[:]) { t.Fatalf("the pre-state balance before self-destruct must be 42") } @@ -1575,7 +1575,7 @@ func TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiary(t *testing.T) { t.Fatalf("no state diff found for stem") } - balanceStateDiff := statediff[0][stateDiffIdx].SuffixDiffs[1] + balanceStateDiff := statediff[0][stateDiffIdx].SuffixDiffs[0] if balanceStateDiff.Suffix != utils.BasicDataLeafKey { t.Fatalf("balance invalid suffix") } diff --git a/light/trie.go b/light/trie.go index 7e7c03bc16c1..f29e67a5da76 100644 --- a/light/trie.go +++ b/light/trie.go @@ -223,7 +223,7 @@ func (t *odrTrie) GetAccount(address common.Address) (*types.StateAccount, error return acct, nil } -func (t *odrTrie) UpdateAccount(address common.Address, acc *types.StateAccount) error { +func (t *odrTrie) UpdateAccount(address common.Address, acc *types.StateAccount, _ int) error { key := crypto.Keccak256(address.Bytes()) value, err := rlp.EncodeToBytes(acc) if err != nil { diff --git a/trie/secure_trie.go b/trie/secure_trie.go index f4a999c2f68f..9198f595796e 100644 --- a/trie/secure_trie.go +++ b/trie/secure_trie.go @@ -163,7 +163,7 @@ func (t *StateTrie) UpdateStorage(_ common.Address, key, value []byte) error { } // UpdateAccount will abstract the write of an account to the secure trie. -func (t *StateTrie) UpdateAccount(address common.Address, acc *types.StateAccount) error { +func (t *StateTrie) UpdateAccount(address common.Address, acc *types.StateAccount, _ int) error { hk := t.hashKey(address.Bytes()) data, err := rlp.EncodeToBytes(acc) if err != nil { diff --git a/trie/transition.go b/trie/transition.go index 0fe197336524..61e61d2d8d56 100644 --- a/trie/transition.go +++ b/trie/transition.go @@ -113,11 +113,11 @@ func (t *TransitionTrie) UpdateStorage(address common.Address, key []byte, value } // UpdateAccount abstract an account write to the trie. -func (t *TransitionTrie) UpdateAccount(addr common.Address, account *types.StateAccount) error { +func (t *TransitionTrie) UpdateAccount(addr common.Address, account *types.StateAccount, codeLen int) error { if account.Root != (common.Hash{}) && account.Root != types.EmptyRootHash { t.overlay.db.SetStorageRootConversion(addr, account.Root) } - return t.overlay.UpdateAccount(addr, account) + return t.overlay.UpdateAccount(addr, account, codeLen) } // Delete removes any existing value for key from the trie. If a node was not diff --git a/trie/verkle.go b/trie/verkle.go index 62a271ea4ca9..808d16cd313c 100644 --- a/trie/verkle.go +++ b/trie/verkle.go @@ -145,7 +145,7 @@ func (t *VerkleTrie) GetAccount(addr common.Address) (*types.StateAccount, error var balance [32]byte copy(balance[16:], values[utils.BasicDataLeafKey][utils.BasicDataBalanceOffset:]) for i := 0; i < 8; i++ { - balance[16-i-1], balance[i] = balance[i], balance[16-i-1] + balance[31-i], balance[utils.BasicDataBalanceOffset+i] = balance[utils.BasicDataBalanceOffset+i], balance[31-i] } acc.Balance = new(big.Int).SetBytes(balance[:]) acc.CodeHash = values[utils.CodeHashLeafKey] @@ -155,7 +155,7 @@ func (t *VerkleTrie) GetAccount(addr common.Address) (*types.StateAccount, error var zero [32]byte -func (t *VerkleTrie) UpdateAccount(addr common.Address, acc *types.StateAccount) error { +func (t *VerkleTrie) UpdateAccount(addr common.Address, acc *types.StateAccount, codeLen int) error { var ( err error basicData [32]byte @@ -169,6 +169,9 @@ func (t *VerkleTrie) UpdateAccount(addr common.Address, acc *types.StateAccount) for i := 0; i < 16 && i < len(balanceBytes); i++ { basicData[utils.BasicDataBalanceOffset+i] = balanceBytes[len(balanceBytes)-1-i] } + var cs [8]byte + binary.LittleEndian.PutUint64(cs[:], uint64(codeLen)) + copy(basicData[utils.BasicDataCodeSizeOffset:], cs[:3]) values[utils.BasicDataLeafKey] = basicData[:] values[utils.CodeHashLeafKey] = acc.CodeHash[:] @@ -182,7 +185,6 @@ func (t *VerkleTrie) UpdateAccount(addr common.Address, acc *types.StateAccount) if err != nil { return fmt.Errorf("UpdateAccount (%x) error: %v", addr, err) } - // TODO figure out if the code size needs to be updated, too return nil } @@ -453,17 +455,6 @@ func (t *VerkleTrie) UpdateContractCode(addr common.Address, codeHash common.Has } values[groupOffset] = chunks[i : i+32] - // Reuse the calculated key to also update the code size. - if i == 0 { - headervals, err := t.root.(*verkle.InternalNode).GetValuesAtStem(key[:31], t.FlatdbNodeResolver) - if err != nil { - return fmt.Errorf("UpdateContractCode (addr=%x) error while getting account header: %w", addr[:], err) - } - var cs [8]byte - binary.LittleEndian.PutUint64(cs[:], uint64(len(code))) - copy(headervals[utils.BasicDataLeafKey][utils.BasicDataCodeSizeOffset:], cs[5:8]) - values[utils.BasicDataLeafKey] = headervals[utils.BasicDataLeafKey] - } if groupOffset == 255 || len(chunks)-i <= 32 { err = t.UpdateStem(key[:31], values) diff --git a/trie/verkle_iterator_test.go b/trie/verkle_iterator_test.go index ce59a21e60e4..42f8f9fd3406 100644 --- a/trie/verkle_iterator_test.go +++ b/trie/verkle_iterator_test.go @@ -37,7 +37,7 @@ func TestVerkleIterator(t *testing.T) { } // NOTE: the code size isn't written to the trie via TryUpdateAccount // so it will be missing from the test nodes. - trie.UpdateAccount(common.Address{}, account0) + trie.UpdateAccount(common.Address{}, account0, 0) account1 := &types.StateAccount{ Nonce: 1337, Balance: big.NewInt(2000), @@ -46,7 +46,7 @@ func TestVerkleIterator(t *testing.T) { } // This address is meant to hash to a value that has the same first byte as 0xbf var clash = common.HexToAddress("69fd8034cdb20934dedffa7dccb4fb3b8062a8be") - trie.UpdateAccount(clash, account1) + trie.UpdateAccount(clash, account1, 0) // Manually go over every node to check that we get all // the correct nodes.