mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
core/state/snapshot: verify account in range at interruption point
This commit is contained in:
parent
c10ac4f48f
commit
140ee32dbf
3 changed files with 30 additions and 36 deletions
|
|
@ -74,6 +74,14 @@ func (dl *diskLayer) Stale() bool {
|
||||||
return dl.stale
|
return dl.stale
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// markStale sets the stale flag as true.
|
||||||
|
func (dl *diskLayer) markStale() {
|
||||||
|
dl.lock.Lock()
|
||||||
|
defer dl.lock.Unlock()
|
||||||
|
|
||||||
|
dl.stale = true
|
||||||
|
}
|
||||||
|
|
||||||
// Account directly retrieves the account associated with a particular hash in
|
// Account directly retrieves the account associated with a particular hash in
|
||||||
// the snapshot slim data format.
|
// the snapshot slim data format.
|
||||||
func (dl *diskLayer) Account(hash common.Hash) (*types.SlimAccount, error) {
|
func (dl *diskLayer) Account(hash common.Hash) (*types.SlimAccount, error) {
|
||||||
|
|
@ -175,3 +183,18 @@ func (dl *diskLayer) Storage(accountHash, storageHash common.Hash) ([]byte, erro
|
||||||
func (dl *diskLayer) Update(blockHash common.Hash, destructs map[common.Hash]struct{}, accounts map[common.Hash][]byte, storage map[common.Hash]map[common.Hash][]byte) *diffLayer {
|
func (dl *diskLayer) Update(blockHash common.Hash, destructs map[common.Hash]struct{}, accounts map[common.Hash][]byte, storage map[common.Hash]map[common.Hash][]byte) *diffLayer {
|
||||||
return newDiffLayer(dl, blockHash, destructs, accounts, storage)
|
return newDiffLayer(dl, blockHash, destructs, accounts, storage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stopGeneration aborts the state snapshot generation if it is currently running.
|
||||||
|
func (dl *diskLayer) stopGeneration() {
|
||||||
|
dl.lock.RLock()
|
||||||
|
generating := dl.genMarker != nil
|
||||||
|
dl.lock.RUnlock()
|
||||||
|
if !generating {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if dl.genAbort != nil {
|
||||||
|
abort := make(chan *generatorStats)
|
||||||
|
dl.genAbort <- abort
|
||||||
|
<-abort
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -631,16 +631,10 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er
|
||||||
accMarker = nil
|
accMarker = nil
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// Always reset the initial account range as 1 whenever recover from the
|
|
||||||
// interruption. TODO(rjl493456442) can we remove it?
|
|
||||||
var accountRange = accountCheckRange
|
|
||||||
if len(accMarker) > 0 {
|
|
||||||
accountRange = 1
|
|
||||||
}
|
|
||||||
origin := common.CopyBytes(accMarker)
|
origin := common.CopyBytes(accMarker)
|
||||||
for {
|
for {
|
||||||
id := trie.StateTrieID(dl.root)
|
id := trie.StateTrieID(dl.root)
|
||||||
exhausted, last, err := dl.generateRange(ctx, id, rawdb.SnapshotAccountPrefix, snapAccount, origin, accountRange, onAccount, types.FullAccountRLP)
|
exhausted, last, err := dl.generateRange(ctx, id, rawdb.SnapshotAccountPrefix, snapAccount, origin, accountCheckRange, onAccount, types.FullAccountRLP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err // The procedure it aborted, either by external signal or internal error.
|
return err // The procedure it aborted, either by external signal or internal error.
|
||||||
}
|
}
|
||||||
|
|
@ -652,7 +646,6 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er
|
||||||
ctx.removeStorageLeft()
|
ctx.removeStorageLeft()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
accountRange = accountCheckRange
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -258,24 +258,9 @@ func (t *Tree) Disable() {
|
||||||
for _, layer := range t.layers {
|
for _, layer := range t.layers {
|
||||||
switch layer := layer.(type) {
|
switch layer := layer.(type) {
|
||||||
case *diskLayer:
|
case *diskLayer:
|
||||||
|
layer.stopGeneration()
|
||||||
layer.lock.RLock()
|
layer.markStale()
|
||||||
generating := layer.genMarker != nil
|
layer.Release()
|
||||||
layer.lock.RUnlock()
|
|
||||||
if !generating {
|
|
||||||
// Generator is already aborted or finished
|
|
||||||
break
|
|
||||||
}
|
|
||||||
// If the base layer is generating, abort it
|
|
||||||
if layer.genAbort != nil {
|
|
||||||
abort := make(chan *generatorStats)
|
|
||||||
layer.genAbort <- abort
|
|
||||||
<-abort
|
|
||||||
}
|
|
||||||
// Layer should be inactive now, mark it as stale
|
|
||||||
layer.lock.Lock()
|
|
||||||
layer.stale = true
|
|
||||||
layer.lock.Unlock()
|
|
||||||
|
|
||||||
case *diffLayer:
|
case *diffLayer:
|
||||||
// If the layer is a simple diff, simply mark as stale
|
// If the layer is a simple diff, simply mark as stale
|
||||||
|
|
@ -730,16 +715,9 @@ func (t *Tree) Rebuild(root common.Hash) {
|
||||||
for _, layer := range t.layers {
|
for _, layer := range t.layers {
|
||||||
switch layer := layer.(type) {
|
switch layer := layer.(type) {
|
||||||
case *diskLayer:
|
case *diskLayer:
|
||||||
// If the base layer is generating, abort it and save
|
layer.stopGeneration()
|
||||||
if layer.genAbort != nil {
|
layer.markStale()
|
||||||
abort := make(chan *generatorStats)
|
layer.Release()
|
||||||
layer.genAbort <- abort
|
|
||||||
<-abort
|
|
||||||
}
|
|
||||||
// Layer should be inactive now, mark it as stale
|
|
||||||
layer.lock.Lock()
|
|
||||||
layer.stale = true
|
|
||||||
layer.lock.Unlock()
|
|
||||||
|
|
||||||
case *diffLayer:
|
case *diffLayer:
|
||||||
// If the layer is a simple diff, simply mark as stale
|
// If the layer is a simple diff, simply mark as stale
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue