Skip to content

Commit 443afc9

Browse files
gballetholimanfjl
authored
core/state: move state account to core/types + abstracted "write account to trie" (#23567)
* core/state: abstracted "write account to trie" method * fix appveyor build * Apply suggestions from code review Co-authored-by: Martin Holst Swende <[email protected]> * review feedback * core/state/accounts: move Account to core/types * core/types: rename Account -> StateAccount * core/state: restore EncodeRLP for stateObject * core/types: add the missing file * more review feedback * more review feedback Co-authored-by: Martin Holst Swende <[email protected]> Co-authored-by: Felix Lange <[email protected]>
1 parent ac7baea commit 443afc9

File tree

18 files changed

+122
-61
lines changed

18 files changed

+122
-61
lines changed

cmd/geth/snapshot.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/ethereum/go-ethereum/core/state"
3030
"github.com/ethereum/go-ethereum/core/state/pruner"
3131
"github.com/ethereum/go-ethereum/core/state/snapshot"
32+
"github.com/ethereum/go-ethereum/core/types"
3233
"github.com/ethereum/go-ethereum/crypto"
3334
"github.com/ethereum/go-ethereum/log"
3435
"github.com/ethereum/go-ethereum/rlp"
@@ -287,7 +288,7 @@ func traverseState(ctx *cli.Context) error {
287288
accIter := trie.NewIterator(t.NodeIterator(nil))
288289
for accIter.Next() {
289290
accounts += 1
290-
var acc state.Account
291+
var acc types.StateAccount
291292
if err := rlp.DecodeBytes(accIter.Value, &acc); err != nil {
292293
log.Error("Invalid account encountered during traversal", "err", err)
293294
return err
@@ -393,7 +394,7 @@ func traverseRawState(ctx *cli.Context) error {
393394
// dig into the storage trie further.
394395
if accIter.Leaf() {
395396
accounts += 1
396-
var acc state.Account
397+
var acc types.StateAccount
397398
if err := rlp.DecodeBytes(accIter.LeafBlob(), &acc); err != nil {
398399
log.Error("Invalid account encountered during traversal", "err", err)
399400
return errors.New("invalid account")

core/state/database.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/VictoriaMetrics/fastcache"
2424
"github.com/ethereum/go-ethereum/common"
2525
"github.com/ethereum/go-ethereum/core/rawdb"
26+
"github.com/ethereum/go-ethereum/core/types"
2627
"github.com/ethereum/go-ethereum/ethdb"
2728
"github.com/ethereum/go-ethereum/trie"
2829
lru "github.com/hashicorp/golang-lru"
@@ -70,6 +71,9 @@ type Trie interface {
7071
// trie.MissingNodeError is returned.
7172
TryGet(key []byte) ([]byte, error)
7273

74+
// TryUpdateAccount abstract an account write in the trie.
75+
TryUpdateAccount(key []byte, account *types.StateAccount) error
76+
7377
// TryUpdate associates key with value in the trie. If value has length zero, any
7478
// existing value is deleted from the trie. The value bytes must not be modified
7579
// by the caller while they are stored in the trie. If a node was not found in the

core/state/dump.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323

2424
"github.com/ethereum/go-ethereum/common"
2525
"github.com/ethereum/go-ethereum/common/hexutil"
26+
"github.com/ethereum/go-ethereum/core/types"
2627
"github.com/ethereum/go-ethereum/log"
2728
"github.com/ethereum/go-ethereum/rlp"
2829
"github.com/ethereum/go-ethereum/trie"
@@ -140,7 +141,7 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []
140141

141142
it := trie.NewIterator(s.trie.NodeIterator(conf.Start))
142143
for it.Next() {
143-
var data Account
144+
var data types.StateAccount
144145
if err := rlp.DecodeBytes(it.Value, &data); err != nil {
145146
panic(err)
146147
}

core/state/iterator.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"fmt"
2222

2323
"github.com/ethereum/go-ethereum/common"
24+
"github.com/ethereum/go-ethereum/core/types"
2425
"github.com/ethereum/go-ethereum/rlp"
2526
"github.com/ethereum/go-ethereum/trie"
2627
)
@@ -104,7 +105,7 @@ func (it *NodeIterator) step() error {
104105
return nil
105106
}
106107
// Otherwise we've reached an account node, initiate data iteration
107-
var account Account
108+
var account types.StateAccount
108109
if err := rlp.Decode(bytes.NewReader(it.stateIt.LeafBlob()), &account); err != nil {
109110
return err
110111
}

core/state/pruner/pruner.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import (
2929

3030
"github.com/ethereum/go-ethereum/common"
3131
"github.com/ethereum/go-ethereum/core/rawdb"
32-
"github.com/ethereum/go-ethereum/core/state"
3332
"github.com/ethereum/go-ethereum/core/state/snapshot"
3433
"github.com/ethereum/go-ethereum/core/types"
3534
"github.com/ethereum/go-ethereum/crypto"
@@ -426,7 +425,7 @@ func extractGenesis(db ethdb.Database, stateBloom *stateBloom) error {
426425
// If it's a leaf node, yes we are touching an account,
427426
// dig into the storage trie further.
428427
if accIter.Leaf() {
429-
var acc state.Account
428+
var acc types.StateAccount
430429
if err := rlp.DecodeBytes(accIter.LeafBlob(), &acc); err != nil {
431430
return err
432431
}

core/state/state_object.go

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"time"
2525

2626
"github.com/ethereum/go-ethereum/common"
27+
"github.com/ethereum/go-ethereum/core/types"
2728
"github.com/ethereum/go-ethereum/crypto"
2829
"github.com/ethereum/go-ethereum/metrics"
2930
"github.com/ethereum/go-ethereum/rlp"
@@ -65,7 +66,7 @@ func (s Storage) Copy() Storage {
6566
type stateObject struct {
6667
address common.Address
6768
addrHash common.Hash // hash of ethereum address of the account
68-
data Account
69+
data types.StateAccount
6970
db *StateDB
7071

7172
// DB error.
@@ -97,17 +98,8 @@ func (s *stateObject) empty() bool {
9798
return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash)
9899
}
99100

100-
// Account is the Ethereum consensus representation of accounts.
101-
// These objects are stored in the main account trie.
102-
type Account struct {
103-
Nonce uint64
104-
Balance *big.Int
105-
Root common.Hash // merkle root of the storage trie
106-
CodeHash []byte
107-
}
108-
109101
// newObject creates a state object.
110-
func newObject(db *StateDB, address common.Address, data Account) *stateObject {
102+
func newObject(db *StateDB, address common.Address, data types.StateAccount) *stateObject {
111103
if data.Balance == nil {
112104
data.Balance = new(big.Int)
113105
}
@@ -130,7 +122,7 @@ func newObject(db *StateDB, address common.Address, data Account) *stateObject {
130122

131123
// EncodeRLP implements rlp.Encoder.
132124
func (s *stateObject) EncodeRLP(w io.Writer) error {
133-
return rlp.Encode(w, s.data)
125+
return rlp.Encode(w, &s.data)
134126
}
135127

136128
// setError remembers the first non-nil error it is called with.

core/state/statedb.go

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -460,12 +460,7 @@ func (s *StateDB) updateStateObject(obj *stateObject) {
460460
}
461461
// Encode the account and update the account trie
462462
addr := obj.Address()
463-
464-
data, err := rlp.EncodeToBytes(obj)
465-
if err != nil {
466-
panic(fmt.Errorf("can't encode object at %x: %v", addr[:], err))
467-
}
468-
if err = s.trie.TryUpdate(addr[:], data); err != nil {
463+
if err := s.trie.TryUpdateAccount(addr[:], &obj.data); err != nil {
469464
s.setError(fmt.Errorf("updateStateObject (%x) error: %v", addr[:], err))
470465
}
471466

@@ -512,7 +507,7 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
512507
}
513508
// If no live objects are available, attempt to use snapshots
514509
var (
515-
data *Account
510+
data *types.StateAccount
516511
err error
517512
)
518513
if s.snap != nil {
@@ -524,7 +519,7 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
524519
if acc == nil {
525520
return nil
526521
}
527-
data = &Account{
522+
data = &types.StateAccount{
528523
Nonce: acc.Nonce,
529524
Balance: acc.Balance,
530525
CodeHash: acc.CodeHash,
@@ -551,7 +546,7 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
551546
if len(enc) == 0 {
552547
return nil
553548
}
554-
data = new(Account)
549+
data = new(types.StateAccount)
555550
if err := rlp.DecodeBytes(enc, data); err != nil {
556551
log.Error("Failed to decode state object", "addr", addr, "err", err)
557552
return nil
@@ -588,7 +583,7 @@ func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject)
588583
s.snapDestructs[prev.addrHash] = struct{}{}
589584
}
590585
}
591-
newobj = newObject(s, addr, Account{})
586+
newobj = newObject(s, addr, types.StateAccount{})
592587
if prev == nil {
593588
s.journal.append(createObjectChange{account: &addr})
594589
} else {
@@ -942,7 +937,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
942937
}
943938
// The onleaf func is called _serially_, so we can reuse the same account
944939
// for unmarshalling every time.
945-
var account Account
940+
var account types.StateAccount
946941
root, accountCommitted, err := s.trie.Commit(func(_ [][]byte, _ []byte, leaf []byte, parent common.Hash) error {
947942
if err := rlp.DecodeBytes(leaf, &account); err != nil {
948943
return nil

core/state/sync.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"bytes"
2121

2222
"github.com/ethereum/go-ethereum/common"
23+
"github.com/ethereum/go-ethereum/core/types"
2324
"github.com/ethereum/go-ethereum/ethdb"
2425
"github.com/ethereum/go-ethereum/rlp"
2526
"github.com/ethereum/go-ethereum/trie"
@@ -43,7 +44,7 @@ func NewStateSync(root common.Hash, database ethdb.KeyValueReader, bloom *trie.S
4344
return err
4445
}
4546
}
46-
var obj Account
47+
var obj types.StateAccount
4748
if err := rlp.Decode(bytes.NewReader(leaf), &obj); err != nil {
4849
return err
4950
}

core/state/sync_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323

2424
"github.com/ethereum/go-ethereum/common"
2525
"github.com/ethereum/go-ethereum/core/rawdb"
26+
"github.com/ethereum/go-ethereum/core/types"
2627
"github.com/ethereum/go-ethereum/crypto"
2728
"github.com/ethereum/go-ethereum/ethdb"
2829
"github.com/ethereum/go-ethereum/ethdb/memorydb"
@@ -203,7 +204,7 @@ func testIterativeStateSync(t *testing.T, count int, commit bool, bypath bool) {
203204
}
204205
results[len(hashQueue)+i] = trie.SyncResult{Hash: crypto.Keccak256Hash(data), Data: data}
205206
} else {
206-
var acc Account
207+
var acc types.StateAccount
207208
if err := rlp.DecodeBytes(srcTrie.Get(path[0]), &acc); err != nil {
208209
t.Fatalf("failed to decode account on path %x: %v", path, err)
209210
}

core/types/state_account.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2021 The go-ethereum Authors
2+
// This file is part of the go-ethereum library.
3+
//
4+
// The go-ethereum library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Lesser General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// The go-ethereum library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package types
18+
19+
import (
20+
"math/big"
21+
22+
"github.com/ethereum/go-ethereum/common"
23+
)
24+
25+
// StateAccount is the Ethereum consensus representation of accounts.
26+
// These objects are stored in the main account trie.
27+
type StateAccount struct {
28+
Nonce uint64
29+
Balance *big.Int
30+
Root common.Hash // merkle root of the storage trie
31+
CodeHash []byte
32+
}

0 commit comments

Comments
 (0)