core: flush out trie cache more meaningfully on stop

This commit is contained in:
Péter Szilágyi 2018-02-20 14:50:03 +02:00
parent 5603715c06
commit 910a8f46f3
No known key found for this signature in database
GPG key ID: E9AE538CEDF8293D

View file

@ -648,22 +648,21 @@ func (bc *BlockChain) Stop() {
bc.wg.Wait() bc.wg.Wait()
// Ensure the state of a recent block is also stored to disk before exiting. // Ensure the state of a recent block is also stored to disk before exiting.
// It is fine if this state does not exist (fast start/stop cycle), but it is // We're writing three different states to catch different restart scenarios:
// advisable to leave an N block gap from the head so 1) a restart loads up // - HEAD: So we don't need to reprocess any blocks in the general case
// the last N blocks as sync assistance to remote nodes; 2) a restart during // - HEAD-1: So we don't do large reorgs if our HEAD becomes an uncle
// a (small) reorg doesn't require deep reprocesses; 3) chain "repair" from // - HEAD-127: So we have a hard limit on the number of blocks reexecuted
// missing states are constantly tested.
//
// This may be tuned a bit on mainnet if its too annoying to reprocess the last
// N blocks.
if !bc.cacheConfig.Disabled { if !bc.cacheConfig.Disabled {
triedb := bc.stateCache.TrieDB() triedb := bc.stateCache.TrieDB()
if number := bc.CurrentBlock().NumberU64(); number >= triesInMemory {
recent := bc.GetBlockByNumber(bc.CurrentBlock().NumberU64() - triesInMemory + 1)
log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root()) for _, offset := range []uint64{0, 1, triesInMemory - 1} {
if err := triedb.Commit(recent.Root(), true); err != nil { if number := bc.CurrentBlock().NumberU64(); number > offset {
log.Error("Failed to commit recent state trie", "err", err) recent := bc.GetBlockByNumber(bc.CurrentBlock().NumberU64() - offset)
log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root())
if err := triedb.Commit(recent.Root(), true); err != nil {
log.Error("Failed to commit recent state trie", "err", err)
}
} }
} }
for !bc.triegc.Empty() { for !bc.triegc.Empty() {