core/state/snapshot: faster account iteration, CLI integration

This commit is contained in:
Martin Holst Swende
2020-01-19 20:57:56 +01:00
committed by Péter Szilágyi
parent 6ddb92a089
commit 19099421dc
9 changed files with 69 additions and 38 deletions

View File

@ -64,7 +64,7 @@ type diffAccountIterator struct {
// is explicitly tracked since the referenced diff layer might go stale after
// the iterator was positioned and we don't want to fail accessing the old
// value as long as the iterator is not touched any more.
curAccount []byte
//curAccount []byte
layer *diffLayer // Live layer to retrieve values from
keys []common.Hash // Keys left in the layer to iterate
@ -98,22 +98,13 @@ func (it *diffAccountIterator) Next() bool {
if len(it.keys) == 0 {
return false
}
// Iterator seems to be still alive, retrieve and cache the live hash and
// account value, or fail now if layer became stale
it.layer.lock.RLock()
defer it.layer.lock.RUnlock()
if it.layer.stale {
if it.layer.Stale() {
it.fail, it.keys = ErrSnapshotStale, nil
return false
}
// Iterator seems to be still alive, retrieve and cache the live hash
it.curHash = it.keys[0]
if blob, ok := it.layer.accountData[it.curHash]; !ok {
panic(fmt.Sprintf("iterator referenced non-existent account: %x", it.curHash))
} else {
it.curAccount = blob
}
// Values cached, shift the iterator and notify the user of success
// key cached, shift the iterator and notify the user of success
it.keys = it.keys[1:]
return true
}
@ -130,8 +121,22 @@ func (it *diffAccountIterator) Hash() common.Hash {
}
// Account returns the RLP encoded slim account the iterator is currently at.
// This method may _fail_, if the underlying layer has been flattened between
// the call to Next and Acccount. That type of error will set it.Err.
// This method assumes that flattening does not delete elements from
// the accountdata mapping (writing nil into it is fine though), and will panic
// if elements have been deleted.
func (it *diffAccountIterator) Account() []byte {
return it.curAccount
it.layer.lock.RLock()
blob, ok := it.layer.accountData[it.curHash]
if !ok {
panic(fmt.Sprintf("iterator referenced non-existent account: %x", it.curHash))
}
it.layer.lock.RUnlock()
if it.layer.Stale() {
it.fail, it.keys = ErrSnapshotStale, nil
}
return blob
}
// Release is a noop for diff account iterators as there are no held resources.