mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
eth: Include Felix' feedback
This commit is contained in:
parent
1783c3bf0c
commit
795cfed5c0
2 changed files with 38 additions and 15 deletions
14
eth/api.go
14
eth/api.go
|
|
@ -335,14 +335,18 @@ func (api *PrivateDebugAPI) GetBadBlocks(ctx context.Context) ([]*BadBlockArgs,
|
||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AccountRangeResult returns a mapping from the hash of an account addresses
|
||||||
|
// to its preimage. It will return the JSON null if no preimage is found.
|
||||||
|
// Since a query can return a limited amount of results, a "next" field is
|
||||||
|
// also present for paging.
|
||||||
type AccountRangeResult struct {
|
type AccountRangeResult struct {
|
||||||
Addresses []common.Address `json:"addresses"`
|
Accounts map[common.Hash]*common.Address `json:"accounts"`
|
||||||
Next common.Hash `json:"next"`
|
Next common.Hash `json:"next"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func accountRange(st state.Trie, start *common.Hash, maxResults int) (AccountRangeResult, error) {
|
func accountRange(st state.Trie, start *common.Hash, maxResults int) (AccountRangeResult, error) {
|
||||||
it := trie.NewIterator(st.NodeIterator(start.Bytes()))
|
it := trie.NewIterator(st.NodeIterator(start.Bytes()))
|
||||||
result := AccountRangeResult{Addresses: []common.Address{}, Next: common.Hash{}}
|
result := AccountRangeResult{Accounts: make(map[common.Hash]*common.Address), Next: common.Hash{}}
|
||||||
|
|
||||||
if maxResults > AccountRangeMaxResults {
|
if maxResults > AccountRangeMaxResults {
|
||||||
maxResults = AccountRangeMaxResults
|
maxResults = AccountRangeMaxResults
|
||||||
|
|
@ -350,9 +354,11 @@ func accountRange(st state.Trie, start *common.Hash, maxResults int) (AccountRan
|
||||||
|
|
||||||
for i := 0; i < maxResults && it.Next(); i++ {
|
for i := 0; i < maxResults && it.Next(); i++ {
|
||||||
if preimage := st.GetKey(it.Key); preimage != nil {
|
if preimage := st.GetKey(it.Key); preimage != nil {
|
||||||
result.Addresses = append(result.Addresses, common.BytesToAddress(preimage))
|
addr := &common.Address{}
|
||||||
|
addr.SetBytes(preimage)
|
||||||
|
result.Accounts[common.BytesToHash(it.Key)] = addr
|
||||||
} else {
|
} else {
|
||||||
return AccountRangeResult{}, fmt.Errorf("preimage not found for 0x%s", hex.EncodeToString(it.Key))
|
result.Accounts[common.BytesToHash(it.Key)] = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,13 +38,16 @@ func accountRangeTest(t *testing.T, trie *state.Trie, statedb *state.StateDB, st
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(result.Addresses) != expectedNum {
|
if len(result.Accounts) != expectedNum {
|
||||||
t.Fatalf("expected %d results. Got %d", expectedNum, len(result.Addresses))
|
t.Fatalf("expected %d results. Got %d", expectedNum, len(result.Accounts))
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range result.Addresses {
|
for _, address := range result.Accounts {
|
||||||
if !statedb.Exist(result.Addresses[i]) {
|
if address == nil {
|
||||||
t.Fatalf("account not found in state %s", result.Addresses[i].String())
|
t.Fatalf("null address returned")
|
||||||
|
}
|
||||||
|
if !statedb.Exist(*address) {
|
||||||
|
t.Fatalf("account not found in state %s", address.Hex())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,11 +96,25 @@ func TestAccountRange(t *testing.T) {
|
||||||
t.Logf("test pagination 2")
|
t.Logf("test pagination 2")
|
||||||
secondResult := accountRangeTest(t, &trie, state, &firstResult.Next, AccountRangeMaxResults, AccountRangeMaxResults)
|
secondResult := accountRangeTest(t, &trie, state, &firstResult.Next, AccountRangeMaxResults, AccountRangeMaxResults)
|
||||||
|
|
||||||
for i := range firstResult.Addresses {
|
for h1, addr1 := range firstResult.Accounts {
|
||||||
for j := range secondResult.Addresses {
|
for h2, addr2 := range secondResult.Accounts {
|
||||||
if bytes.Equal(firstResult.Addresses[i].Bytes(), secondResult.Addresses[j].Bytes()) {
|
// Make sure that the hashes aren't the same
|
||||||
|
if bytes.Equal(h1.Bytes(), h2.Bytes()) {
|
||||||
t.Fatalf("pagination test failed: results should not overlap")
|
t.Fatalf("pagination test failed: results should not overlap")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If either address is nil, then it makes no sense to compare
|
||||||
|
// them as they might be two different accounts.
|
||||||
|
if addr1 == nil || addr2 == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since the two hashes are different, they should not have
|
||||||
|
// the same preimage, but let's check anyway in case there
|
||||||
|
// is a bug in the (hash, addr) map generation code.
|
||||||
|
if bytes.Equal(addr1.Bytes(), addr2.Bytes()) {
|
||||||
|
t.Fatalf("pagination test failed: addresses should not repeat")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -123,8 +140,8 @@ func TestEmptyAccountRange(t *testing.T) {
|
||||||
if results.Next != common.HexToHash("0") {
|
if results.Next != common.HexToHash("0") {
|
||||||
t.Fatalf("Empty results should not return a second page")
|
t.Fatalf("Empty results should not return a second page")
|
||||||
}
|
}
|
||||||
if len(results.Addresses) != 0 {
|
if len(results.Accounts) != 0 {
|
||||||
t.Fatalf("Empty state should not return addresses: %v", results.Addresses)
|
t.Fatalf("Empty state should not return addresses: %v", results.Accounts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue