cmd/geth, eth, core: snapshot dump + unify with trie dump (#22795)

* cmd/geth, eth, core: snapshot dump + unify with trie dump

* cmd/evm: dump API fixes

* cmd/geth, core, eth: fix some remaining errors

* cmd/evm: dump - add limit, support address startkey, address review concerns

* cmd, core/state, eth: minor polishes, fix snap dump crash, unify format

Co-authored-by: Péter Szilágyi <peterke@gmail.com>
This commit is contained in:
Martin Holst Swende
2021-05-12 10:05:39 +02:00
committed by GitHub
parent 1cca781a02
commit addd8824cf
10 changed files with 300 additions and 95 deletions

View File

@ -264,12 +264,16 @@ func NewPublicDebugAPI(eth *Ethereum) *PublicDebugAPI {
// DumpBlock retrieves the entire state of the database at a given block.
func (api *PublicDebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) {
opts := &state.DumpConfig{
OnlyWithAddresses: true,
Max: AccountRangeMaxResults, // Sanity limit over RPC
}
if blockNr == rpc.PendingBlockNumber {
// If we're dumping the pending state, we need to request
// both the pending block as well as the pending state from
// the miner and operate on those
_, stateDb := api.eth.miner.Pending()
return stateDb.RawDump(false, false, true), nil
return stateDb.RawDump(opts), nil
}
var block *types.Block
if blockNr == rpc.LatestBlockNumber {
@ -284,7 +288,7 @@ func (api *PublicDebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error
if err != nil {
return state.Dump{}, err
}
return stateDb.RawDump(false, false, true), nil
return stateDb.RawDump(opts), nil
}
// PrivateDebugAPI is the collection of Ethereum full node APIs exposed over
@ -386,10 +390,17 @@ func (api *PublicDebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, sta
return state.IteratorDump{}, errors.New("either block number or block hash must be specified")
}
if maxResults > AccountRangeMaxResults || maxResults <= 0 {
maxResults = AccountRangeMaxResults
opts := &state.DumpConfig{
SkipCode: nocode,
SkipStorage: nostorage,
OnlyWithAddresses: !incompletes,
Start: start,
Max: uint64(maxResults),
}
return stateDb.IteratorDump(nocode, nostorage, incompletes, start, maxResults), nil
if maxResults > AccountRangeMaxResults || maxResults <= 0 {
opts.Max = AccountRangeMaxResults
}
return stateDb.IteratorDump(opts), nil
}
// StorageRangeResult is the result of a debug_storageRangeAt API call.

View File

@ -34,7 +34,13 @@ import (
var dumper = spew.ConfigState{Indent: " "}
func accountRangeTest(t *testing.T, trie *state.Trie, statedb *state.StateDB, start common.Hash, requestedNum int, expectedNum int) state.IteratorDump {
result := statedb.IteratorDump(true, true, false, start.Bytes(), requestedNum)
result := statedb.IteratorDump(&state.DumpConfig{
SkipCode: true,
SkipStorage: true,
OnlyWithAddresses: false,
Start: start.Bytes(),
Max: uint64(requestedNum),
})
if len(result.Accounts) != expectedNum {
t.Fatalf("expected %d results, got %d", expectedNum, len(result.Accounts))
@ -131,12 +137,17 @@ func TestEmptyAccountRange(t *testing.T) {
t.Parallel()
var (
statedb = state.NewDatabase(rawdb.NewMemoryDatabase())
state, _ = state.New(common.Hash{}, statedb, nil)
statedb = state.NewDatabase(rawdb.NewMemoryDatabase())
st, _ = state.New(common.Hash{}, statedb, nil)
)
state.Commit(true)
state.IntermediateRoot(true)
results := state.IteratorDump(true, true, true, (common.Hash{}).Bytes(), AccountRangeMaxResults)
st.Commit(true)
st.IntermediateRoot(true)
results := st.IteratorDump(&state.DumpConfig{
SkipCode: true,
SkipStorage: true,
OnlyWithAddresses: true,
Max: uint64(AccountRangeMaxResults),
})
if bytes.Equal(results.Next, (common.Hash{}).Bytes()) {
t.Fatalf("Empty results should not return a second page")
}