mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 09:23:48 +00:00
core, trie: commit trie mempool on close, fix dao test
This commit is contained in:
parent
33cca2bbea
commit
0e91a178b7
3 changed files with 38 additions and 8 deletions
|
|
@ -592,6 +592,17 @@ func (bc *BlockChain) Stop() {
|
|||
atomic.StoreInt32(&bc.procInterrupt, 1)
|
||||
|
||||
bc.wg.Wait()
|
||||
|
||||
// Ensure the state of the latest block is also stored to disk
|
||||
root := bc.CurrentHeader().Root
|
||||
|
||||
batch := bc.chainDb.NewBatch()
|
||||
if err := bc.trieMemPool.Commit(root, batch); err != nil {
|
||||
log.Error("Failed to commit latest state trie", "err", err)
|
||||
}
|
||||
if err := batch.Write(); err != nil {
|
||||
log.Error("Failed to write latest state trie", "err", err)
|
||||
}
|
||||
log.Info("Blockchain manager stopped")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -79,6 +79,9 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
|||
if _, err := bc.InsertChain(blocks); err != nil {
|
||||
t.Fatalf("failed to import contra-fork chain for expansion: %v", err)
|
||||
}
|
||||
if err := bc.trieMemPool.Commit(bc.CurrentHeader().Root, db); err != nil {
|
||||
t.Fatalf("failed to commit contra-fork head for expansion: %v", err)
|
||||
}
|
||||
blocks, _ = GenerateChain(&proConf, conBc.CurrentBlock(), ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
|
||||
if _, err := conBc.InsertChain(blocks); err == nil {
|
||||
t.Fatalf("contra-fork chain accepted pro-fork block: %v", blocks[0])
|
||||
|
|
@ -101,6 +104,9 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
|||
if _, err := bc.InsertChain(blocks); err != nil {
|
||||
t.Fatalf("failed to import pro-fork chain for expansion: %v", err)
|
||||
}
|
||||
if err := bc.trieMemPool.Commit(bc.CurrentHeader().Root, db); err != nil {
|
||||
t.Fatalf("failed to commit pro-fork head for expansion: %v", err)
|
||||
}
|
||||
blocks, _ = GenerateChain(&conConf, proBc.CurrentBlock(), ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
|
||||
if _, err := proBc.InsertChain(blocks); err == nil {
|
||||
t.Fatalf("pro-fork chain accepted contra-fork block: %v", blocks[0])
|
||||
|
|
@ -124,6 +130,9 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
|||
if _, err := bc.InsertChain(blocks); err != nil {
|
||||
t.Fatalf("failed to import contra-fork chain for expansion: %v", err)
|
||||
}
|
||||
if err := bc.trieMemPool.Commit(bc.CurrentHeader().Root, db); err != nil {
|
||||
t.Fatalf("failed to commit contra-fork head for expansion: %v", err)
|
||||
}
|
||||
blocks, _ = GenerateChain(&proConf, conBc.CurrentBlock(), ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
|
||||
if _, err := conBc.InsertChain(blocks); err != nil {
|
||||
t.Fatalf("contra-fork chain didn't accept pro-fork block post-fork: %v", err)
|
||||
|
|
@ -141,6 +150,9 @@ func TestDAOForkRangeExtradata(t *testing.T) {
|
|||
if _, err := bc.InsertChain(blocks); err != nil {
|
||||
t.Fatalf("failed to import pro-fork chain for expansion: %v", err)
|
||||
}
|
||||
if err := bc.trieMemPool.Commit(bc.CurrentHeader().Root, db); err != nil {
|
||||
t.Fatalf("failed to commit pro-fork head for expansion: %v", err)
|
||||
}
|
||||
blocks, _ = GenerateChain(&conConf, proBc.CurrentBlock(), ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
|
||||
if _, err := proBc.InsertChain(blocks); err != nil {
|
||||
t.Fatalf("pro-fork chain didn't accept contra-fork block post-fork: %v", err)
|
||||
|
|
|
|||
|
|
@ -132,13 +132,15 @@ func (pool *MemPool) dereference(node common.Hash, parent common.Hash) {
|
|||
|
||||
// Commit iterates over all the children of a particular node, writes them out
|
||||
// to disk, forcefully tearing down all references in both directions.
|
||||
func (pool *MemPool) Commit(node common.Hash, db DatabaseWriter) {
|
||||
func (pool *MemPool) Commit(node common.Hash, db DatabaseWriter) error {
|
||||
pool.lock.Lock()
|
||||
defer pool.lock.Unlock()
|
||||
|
||||
nodes, storage, start := len(pool.cache), pool.size, time.Now()
|
||||
pool.commit(node, db)
|
||||
|
||||
if err := pool.commit(node, db); err != nil {
|
||||
log.Error("Failed to commit trie from mempool", "err", err)
|
||||
return err
|
||||
}
|
||||
log.Debug("Committed trie from memory pool", "nodes", nodes-len(pool.cache), "size", storage-pool.size, "time", time.Since(start),
|
||||
"gcnodes", pool.gcnodes, "gcsize", pool.gcsize, "gctime", pool.gctime, "livenodes", len(pool.cache), "livesize", pool.size)
|
||||
|
||||
|
|
@ -152,23 +154,28 @@ func (pool *MemPool) Commit(node common.Hash, db DatabaseWriter) {
|
|||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// commit is the private locked version of Commit.
|
||||
func (pool *MemPool) commit(node common.Hash, db DatabaseWriter) {
|
||||
func (pool *MemPool) commit(node common.Hash, db DatabaseWriter) error {
|
||||
// If the node does not exist, it's a previously comitted node.
|
||||
blob, ok := pool.cache[node]
|
||||
if !ok {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
for child := range pool.children[node] {
|
||||
pool.commit(child, db)
|
||||
if err := pool.commit(child, db); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := db.Put(node[:], blob); err != nil {
|
||||
return err
|
||||
}
|
||||
db.Put(node[:], blob)
|
||||
|
||||
delete(pool.cache, node)
|
||||
delete(pool.parents, node)
|
||||
delete(pool.children, node)
|
||||
|
||||
pool.size -= common.StorageSize(common.HashLength + len(blob))
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue