Skip to content

Commit

Permalink
cmd, core, eth, les, light, trie: trie id
Browse files Browse the repository at this point in the history
  • Loading branch information
rjl493456442 committed Sep 23, 2022
1 parent 90a63c5 commit 1f72e45
Show file tree
Hide file tree
Showing 27 changed files with 216 additions and 140 deletions.
27 changes: 17 additions & 10 deletions cmd/geth/dbcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ WARNING: This is a low-level operation which may cause database corruption!`,
Action: dbDumpTrie,
Name: "dumptrie",
Usage: "Show the storage key/values of a given storage trie",
ArgsUsage: "<hex-encoded state root> <hex-encoded storage trie root> <hex-encoded start (optional)> <int max elements (optional)>",
ArgsUsage: "<hex-encoded state root> <hex-encoded account hash> <hex-encoded storage trie root> <hex-encoded start (optional)> <int max elements (optional)>",
Flags: flags.Merge([]cli.Flag{
utils.SyncModeFlag,
}, utils.NetworkFlags, utils.DatabasePathFlags),
Expand Down Expand Up @@ -486,42 +486,49 @@ func dbPut(ctx *cli.Context) error {

// dbDumpTrie shows the key-value slots of a given storage trie
func dbDumpTrie(ctx *cli.Context) error {
if ctx.NArg() < 2 {
if ctx.NArg() < 3 {
return fmt.Errorf("required arguments: %v", ctx.Command.ArgsUsage)
}
stack, _ := makeConfigNode(ctx)
defer stack.Close()

db := utils.MakeChainDatabase(ctx, stack, true)
defer db.Close()

var (
state []byte
storage []byte
account []byte
start []byte
max = int64(-1)
err error
)
if state, err = hexutil.Decode(ctx.Args().Get(0)); err != nil {
log.Info("Could not decode the root", "error", err)
log.Info("Could not decode the state root", "error", err)
return err
}
if account, err = hexutil.Decode(ctx.Args().Get(1)); err != nil {
log.Info("Could not decode the account hash", "error", err)
return err
}
if storage, err = hexutil.Decode(ctx.Args().Get(1)); err != nil {
log.Info("Could not decode the root", "error", err)
if storage, err = hexutil.Decode(ctx.Args().Get(2)); err != nil {
log.Info("Could not decode the storage trie root", "error", err)
return err
}
if ctx.NArg() >= 3 {
if start, err = hexutil.Decode(ctx.Args().Get(2)); err != nil {
if ctx.NArg() > 3 {
if start, err = hexutil.Decode(ctx.Args().Get(3)); err != nil {
log.Info("Could not decode the seek position", "error", err)
return err
}
}
if ctx.NArg() >= 4 {
if max, err = strconv.ParseInt(ctx.Args().Get(3), 10, 64); err != nil {
if ctx.NArg() > 4 {
if max, err = strconv.ParseInt(ctx.Args().Get(4), 10, 64); err != nil {
log.Info("Could not decode the max count", "error", err)
return err
}
}
theTrie, err := trie.New(common.BytesToHash(state), common.Hash{}, common.BytesToHash(storage), trie.NewDatabase(db))
id := trie.StorageTrieID(common.BytesToHash(state), common.BytesToHash(account), common.BytesToHash(storage))
theTrie, err := trie.New(id, trie.NewDatabase(db))
if err != nil {
return err
}
Expand Down
10 changes: 6 additions & 4 deletions cmd/geth/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ func traverseState(ctx *cli.Context) error {
log.Info("Start traversing the state", "root", root, "number", headBlock.NumberU64())
}
triedb := trie.NewDatabase(chaindb)
t, err := trie.NewStateTrie(root, common.Hash{}, root, triedb)
t, err := trie.NewStateTrie(trie.StateTrieID(root), triedb)
if err != nil {
log.Error("Failed to open trie", "root", root, "err", err)
return err
Expand All @@ -292,7 +292,8 @@ func traverseState(ctx *cli.Context) error {
return err
}
if acc.Root != emptyRoot {
storageTrie, err := trie.NewStateTrie(root, common.BytesToHash(accIter.Key), acc.Root, triedb)
id := trie.StorageTrieID(root, common.BytesToHash(accIter.Key), acc.Root)
storageTrie, err := trie.NewStateTrie(id, triedb)
if err != nil {
log.Error("Failed to open storage trie", "root", acc.Root, "err", err)
return err
Expand Down Expand Up @@ -360,7 +361,7 @@ func traverseRawState(ctx *cli.Context) error {
log.Info("Start traversing the state", "root", root, "number", headBlock.NumberU64())
}
triedb := trie.NewDatabase(chaindb)
t, err := trie.NewStateTrie(root, common.Hash{}, root, triedb)
t, err := trie.NewStateTrie(trie.StateTrieID(root), triedb)
if err != nil {
log.Error("Failed to open trie", "root", root, "err", err)
return err
Expand Down Expand Up @@ -406,7 +407,8 @@ func traverseRawState(ctx *cli.Context) error {
return errors.New("invalid account")
}
if acc.Root != emptyRoot {
storageTrie, err := trie.NewStateTrie(root, common.BytesToHash(accIter.LeafKey()), acc.Root, triedb)
id := trie.StorageTrieID(root, common.BytesToHash(accIter.LeafKey()), acc.Root)
storageTrie, err := trie.NewStateTrie(id, triedb)
if err != nil {
log.Error("Failed to open storage trie", "root", acc.Root, "err", err)
return errors.New("missing storage trie")
Expand Down
4 changes: 2 additions & 2 deletions core/state/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ type cachingDB struct {

// OpenTrie opens the main account trie at a specific root hash.
func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) {
tr, err := trie.NewStateTrie(root, common.Hash{}, root, db.db)
tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.db)
if err != nil {
return nil, err
}
Expand All @@ -157,7 +157,7 @@ func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) {

// OpenStorageTrie opens the storage trie of an account.
func (db *cachingDB) OpenStorageTrie(stateRoot common.Hash, addrHash, root common.Hash) (Trie, error) {
tr, err := trie.NewStateTrie(stateRoot, addrHash, root, db.db)
tr, err := trie.NewStateTrie(trie.StorageTrieID(stateRoot, addrHash, root), db.db)
if err != nil {
return nil, err
}
Expand Down
5 changes: 3 additions & 2 deletions core/state/pruner/pruner.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ func extractGenesis(db ethdb.Database, stateBloom *stateBloom) error {
if genesis == nil {
return errors.New("missing genesis block")
}
t, err := trie.NewStateTrie(genesis.Root(), common.Hash{}, genesis.Root(), trie.NewDatabase(db))
t, err := trie.NewStateTrie(trie.StateTrieID(genesis.Root()), trie.NewDatabase(db))
if err != nil {
return err
}
Expand All @@ -430,7 +430,8 @@ func extractGenesis(db ethdb.Database, stateBloom *stateBloom) error {
return err
}
if acc.Root != emptyRoot {
storageTrie, err := trie.NewStateTrie(genesis.Root(), common.BytesToHash(accIter.LeafKey()), acc.Root, trie.NewDatabase(db))
id := trie.StorageTrieID(genesis.Root(), common.BytesToHash(accIter.LeafKey()), acc.Root)
storageTrie, err := trie.NewStateTrie(id, trie.NewDatabase(db))
if err != nil {
return err
}
Expand Down
23 changes: 13 additions & 10 deletions core/state/snapshot/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ func (result *proofResult) forEach(callback func(key []byte, val []byte) error)
//
// The proof result will be returned if the range proving is finished, otherwise
// the error will be returned to abort the entire procedure.
func (dl *diskLayer) proveRange(ctx *generatorContext, stateRoot common.Hash, owner common.Hash, root common.Hash, prefix []byte, kind string, origin []byte, max int, valueConvertFn func([]byte) ([]byte, error)) (*proofResult, error) {
func (dl *diskLayer) proveRange(ctx *generatorContext, trieId *trie.ID, prefix []byte, kind string, origin []byte, max int, valueConvertFn func([]byte) ([]byte, error)) (*proofResult, error) {
var (
keys [][]byte
vals [][]byte
Expand Down Expand Up @@ -233,8 +233,9 @@ func (dl *diskLayer) proveRange(ctx *generatorContext, stateRoot common.Hash, ow
}(time.Now())

// The snap state is exhausted, pass the entire key/val set for verification
root := trieId.Root
if origin == nil && !diskMore {
stackTr := trie.NewStackTrieWithOwner(nil, owner)
stackTr := trie.NewStackTrieWithOwner(nil, trieId.Owner)
for i, key := range keys {
stackTr.TryUpdate(key, vals[i])
}
Expand All @@ -248,7 +249,7 @@ func (dl *diskLayer) proveRange(ctx *generatorContext, stateRoot common.Hash, ow
return &proofResult{keys: keys, vals: vals}, nil
}
// Snap state is chunked, generate edge proofs for verification.
tr, err := trie.New(stateRoot, owner, root, dl.triedb)
tr, err := trie.New(trieId, dl.triedb)
if err != nil {
ctx.stats.Log("Trie missing, state snapshotting paused", dl.root, dl.genMarker)
return nil, errMissingTrie
Expand Down Expand Up @@ -313,9 +314,9 @@ type onStateCallback func(key []byte, val []byte, write bool, delete bool) error
// generateRange generates the state segment with particular prefix. Generation can
// either verify the correctness of existing state through range-proof and skip
// generation, or iterate trie to regenerate state on demand.
func (dl *diskLayer) generateRange(ctx *generatorContext, state common.Hash, owner common.Hash, root common.Hash, prefix []byte, kind string, origin []byte, max int, onState onStateCallback, valueConvertFn func([]byte) ([]byte, error)) (bool, []byte, error) {
func (dl *diskLayer) generateRange(ctx *generatorContext, trieId *trie.ID, prefix []byte, kind string, origin []byte, max int, onState onStateCallback, valueConvertFn func([]byte) ([]byte, error)) (bool, []byte, error) {
// Use range prover to check the validity of the flat state in the range
result, err := dl.proveRange(ctx, state, owner, root, prefix, kind, origin, max, valueConvertFn)
result, err := dl.proveRange(ctx, trieId, prefix, kind, origin, max, valueConvertFn)
if err != nil {
return false, nil, err
}
Expand Down Expand Up @@ -363,7 +364,7 @@ func (dl *diskLayer) generateRange(ctx *generatorContext, state common.Hash, own
if len(result.keys) > 0 {
snapNodeCache = memorydb.New()
snapTrieDb := trie.NewDatabase(snapNodeCache)
snapTrie, _ := trie.New(common.Hash{}, owner, common.Hash{}, snapTrieDb)
snapTrie, _ := trie.New(trie.TrieID(common.Hash{}), snapTrieDb)
for i, key := range result.keys {
snapTrie.Update(key, result.vals[i])
}
Expand All @@ -377,7 +378,7 @@ func (dl *diskLayer) generateRange(ctx *generatorContext, state common.Hash, own
// if it's already opened with some nodes resolved.
tr := result.tr
if tr == nil {
tr, err = trie.New(state, owner, root, dl.triedb)
tr, err = trie.New(trieId, dl.triedb)
if err != nil {
ctx.stats.Log("Trie missing, state snapshotting paused", dl.root, dl.genMarker)
return false, nil, errMissingTrie
Expand Down Expand Up @@ -460,7 +461,7 @@ func (dl *diskLayer) generateRange(ctx *generatorContext, state common.Hash, own
} else {
snapAccountTrieReadCounter.Inc((time.Since(start) - internal).Nanoseconds())
}
logger.Debug("Regenerated state range", "root", root, "last", hexutil.Encode(last),
logger.Debug("Regenerated state range", "root", trieId.Root, "last", hexutil.Encode(last),
"count", count, "created", created, "updated", updated, "untouched", untouched, "deleted", deleted)

// If there are either more trie items, or there are more snap items
Expand Down Expand Up @@ -540,7 +541,8 @@ func generateStorages(ctx *generatorContext, dl *diskLayer, stateRoot common.Has
// Loop for re-generating the missing storage slots.
var origin = common.CopyBytes(storeMarker)
for {
exhausted, last, err := dl.generateRange(ctx, stateRoot, account, storageRoot, append(rawdb.SnapshotStoragePrefix, account.Bytes()...), snapStorage, origin, storageCheckRange, onStorage, nil)
id := trie.StorageTrieID(stateRoot, account, storageRoot)
exhausted, last, err := dl.generateRange(ctx, id, append(rawdb.SnapshotStoragePrefix, account.Bytes()...), snapStorage, origin, storageCheckRange, onStorage, nil)
if err != nil {
return err // The procedure it aborted, either by external signal or internal error.
}
Expand Down Expand Up @@ -640,7 +642,8 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er
}
origin := common.CopyBytes(accMarker)
for {
exhausted, last, err := dl.generateRange(ctx, dl.root, common.Hash{}, dl.root, rawdb.SnapshotAccountPrefix, snapAccount, origin, accountRange, onAccount, FullAccountRLP)
id := trie.StateTrieID(dl.root)
exhausted, last, err := dl.generateRange(ctx, id, rawdb.SnapshotAccountPrefix, snapAccount, origin, accountRange, onAccount, FullAccountRLP)
if err != nil {
return err // The procedure it aborted, either by external signal or internal error.
}
Expand Down
5 changes: 3 additions & 2 deletions core/state/snapshot/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ type testHelper struct {
func newHelper() *testHelper {
diskdb := rawdb.NewMemoryDatabase()
triedb := trie.NewDatabase(diskdb)
accTrie, _ := trie.NewStateTrie(common.Hash{}, common.Hash{}, common.Hash{}, triedb)
accTrie, _ := trie.NewStateTrie(trie.StateTrieID(common.Hash{}), triedb)
return &testHelper{
diskdb: diskdb,
triedb: triedb,
Expand Down Expand Up @@ -182,7 +182,8 @@ func (t *testHelper) addSnapStorage(accKey string, keys []string, vals []string)
}

func (t *testHelper) makeStorageTrie(stateRoot, owner common.Hash, keys []string, vals []string, commit bool) []byte {
stTrie, _ := trie.NewStateTrie(stateRoot, owner, common.Hash{}, t.triedb)
id := trie.StorageTrieID(stateRoot, owner, common.Hash{})
stTrie, _ := trie.NewStateTrie(id, t.triedb)
for i, k := range keys {
stTrie.Update([]byte(k), []byte(vals[i]))
}
Expand Down
7 changes: 4 additions & 3 deletions core/state/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func checkTrieConsistency(db ethdb.KeyValueStore, root common.Hash) error {
if v, _ := db.Get(root[:]); v == nil {
return nil // Consider a non existent state consistent.
}
trie, err := trie.New(root, common.Hash{}, root, trie.NewDatabase(db))
trie, err := trie.New(trie.StateTrieID(root), trie.NewDatabase(db))
if err != nil {
return err
}
Expand Down Expand Up @@ -174,7 +174,7 @@ func testIterativeStateSync(t *testing.T, count int, commit bool, bypath bool) {
if commit {
srcDb.TrieDB().Commit(srcRoot, false, nil)
}
srcTrie, _ := trie.New(srcRoot, common.Hash{}, srcRoot, srcDb.TrieDB())
srcTrie, _ := trie.New(trie.StateTrieID(srcRoot), srcDb.TrieDB())

// Create a destination state and sync with the scheduler
dstDb := rawdb.NewMemoryDatabase()
Expand Down Expand Up @@ -222,7 +222,8 @@ func testIterativeStateSync(t *testing.T, count int, commit bool, bypath bool) {
if err := rlp.DecodeBytes(srcTrie.Get(node.syncPath[0]), &acc); err != nil {
t.Fatalf("failed to decode account on path %x: %v", node.syncPath[0], err)
}
stTrie, err := trie.New(srcRoot, common.BytesToHash(node.syncPath[0]), acc.Root, srcDb.TrieDB())
id := trie.StorageTrieID(srcRoot, common.BytesToHash(node.syncPath[0]), acc.Root)
stTrie, err := trie.New(id, srcDb.TrieDB())
if err != nil {
t.Fatalf("failed to retriev storage trie for path %x: %v", node.syncPath[1], err)
}
Expand Down
4 changes: 2 additions & 2 deletions eth/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,11 +508,11 @@ func (api *DebugAPI) getModifiedAccounts(startBlock, endBlock *types.Block) ([]c
}
triedb := api.eth.BlockChain().StateCache().TrieDB()

oldTrie, err := trie.NewStateTrie(startBlock.Root(), common.Hash{}, startBlock.Root(), triedb)
oldTrie, err := trie.NewStateTrie(trie.StateTrieID(startBlock.Root()), triedb)
if err != nil {
return nil, err
}
newTrie, err := trie.NewStateTrie(endBlock.Root(), common.Hash{}, endBlock.Root(), triedb)
newTrie, err := trie.NewStateTrie(trie.StateTrieID(endBlock.Root()), triedb)
if err != nil {
return nil, err
}
Expand Down
12 changes: 7 additions & 5 deletions eth/protocols/snap/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ func ServiceGetAccountRangeQuery(chain *core.BlockChain, req *GetAccountRangePac
req.Bytes = softResponseLimit
}
// Retrieve the requested state and bail out if non existent
tr, err := trie.New(req.Root, common.Hash{}, req.Root, chain.StateCache().TrieDB())
tr, err := trie.New(trie.StateTrieID(req.Root), chain.StateCache().TrieDB())
if err != nil {
return nil, nil
}
Expand Down Expand Up @@ -413,15 +413,16 @@ func ServiceGetStorageRangesQuery(chain *core.BlockChain, req *GetStorageRangesP
if origin != (common.Hash{}) || (abort && len(storage) > 0) {
// Request started at a non-zero hash or was capped prematurely, add
// the endpoint Merkle proofs
accTrie, err := trie.NewStateTrie(req.Root, common.Hash{}, req.Root, chain.StateCache().TrieDB())
accTrie, err := trie.NewStateTrie(trie.StateTrieID(req.Root), chain.StateCache().TrieDB())
if err != nil {
return nil, nil
}
acc, err := accTrie.TryGetAccountWithPreHashedKey(account[:])
if err != nil || acc == nil {
return nil, nil
}
stTrie, err := trie.NewStateTrie(req.Root, account, acc.Root, chain.StateCache().TrieDB())
id := trie.StorageTrieID(req.Root, account, acc.Root)
stTrie, err := trie.NewStateTrie(id, chain.StateCache().TrieDB())
if err != nil {
return nil, nil
}
Expand Down Expand Up @@ -487,7 +488,7 @@ func ServiceGetTrieNodesQuery(chain *core.BlockChain, req *GetTrieNodesPacket, s
// Make sure we have the state associated with the request
triedb := chain.StateCache().TrieDB()

accTrie, err := trie.NewStateTrie(req.Root, common.Hash{}, req.Root, triedb)
accTrie, err := trie.NewStateTrie(trie.StateTrieID(req.Root), triedb)
if err != nil {
// We don't have the requested state available, bail out
return nil, nil
Expand Down Expand Up @@ -529,7 +530,8 @@ func ServiceGetTrieNodesQuery(chain *core.BlockChain, req *GetTrieNodesPacket, s
if err != nil || account == nil {
break
}
stTrie, err := trie.NewStateTrie(req.Root, common.BytesToHash(pathset[0]), common.BytesToHash(account.Root), triedb)
id := trie.StorageTrieID(req.Root, common.BytesToHash(pathset[0]), common.BytesToHash(account.Root))
stTrie, err := trie.NewStateTrie(id, triedb)
loads++ // always account database reads, even for failures
if err != nil {
break
Expand Down
Loading

0 comments on commit 1f72e45

Please sign in to comment.