mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 09:53:48 +00:00
core, trie: fix duplicate references, sanity check on shutdown
This commit is contained in:
parent
b46b291742
commit
4315480e09
2 changed files with 19 additions and 13 deletions
|
|
@ -669,6 +669,9 @@ func (bc *BlockChain) Stop() {
|
|||
for !bc.triegc.Empty() {
|
||||
bc.triedb.Dereference(bc.triegc.PopItem().(common.Hash), common.Hash{})
|
||||
}
|
||||
if size := bc.triedb.Size(); size != 0 {
|
||||
log.Error("Dangling trie nodes after full cleanup")
|
||||
}
|
||||
log.Info("Blockchain manager stopped")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,9 +61,9 @@ type Database struct {
|
|||
// cachedNode is all the information we know about a single cached node in the
|
||||
// memory database write layer.
|
||||
type cachedNode struct {
|
||||
blob []byte // Cached data block of the trie node
|
||||
parents int // Number of live nodes referencing this one
|
||||
children map[common.Hash]int // Children referenced by this nodes
|
||||
blob []byte // Cached data block of the trie node
|
||||
parents int // Number of live nodes referencing this one
|
||||
children map[common.Hash]struct{} // Children referenced by this nodes
|
||||
}
|
||||
|
||||
// NewDatabase creates a new trie database to store ephemeral trie content before
|
||||
|
|
@ -72,7 +72,7 @@ func NewDatabase(diskdb ethdb.Database) *Database {
|
|||
return &Database{
|
||||
diskdb: diskdb,
|
||||
nodes: map[common.Hash]*cachedNode{
|
||||
common.Hash{}: {children: make(map[common.Hash]int)},
|
||||
common.Hash{}: {children: make(map[common.Hash]struct{})},
|
||||
},
|
||||
preimages: make(map[common.Hash][]byte),
|
||||
}
|
||||
|
|
@ -99,7 +99,7 @@ func (db *Database) insert(hash common.Hash, blob []byte) {
|
|||
}
|
||||
db.nodes[hash] = &cachedNode{
|
||||
blob: common.CopyBytes(blob),
|
||||
children: make(map[common.Hash]int),
|
||||
children: make(map[common.Hash]struct{}),
|
||||
}
|
||||
db.size += common.StorageSize(common.HashLength + len(blob))
|
||||
}
|
||||
|
|
@ -185,8 +185,12 @@ func (db *Database) reference(child common.Hash, parent common.Hash) {
|
|||
if !ok {
|
||||
return
|
||||
}
|
||||
// If the reference already exists, don't duplicate it
|
||||
if _, ok = db.nodes[parent].children[child]; ok {
|
||||
return
|
||||
}
|
||||
node.parents++
|
||||
db.nodes[parent].children[child]++
|
||||
db.nodes[parent].children[child] = struct{}{}
|
||||
}
|
||||
|
||||
// Dereference removes an existing reference from a parent node to a child node.
|
||||
|
|
@ -200,17 +204,16 @@ func (db *Database) Dereference(child common.Hash, parent common.Hash) {
|
|||
db.gcnodes += uint64(nodes - len(db.nodes))
|
||||
db.gcsize += storage - db.size
|
||||
db.gctime += time.Since(start)
|
||||
|
||||
log.Debug("Dereferenced trie from memory database", "nodes", nodes-len(db.nodes), "size", storage-db.size, "time", time.Since(start),
|
||||
"gcnodes", db.gcnodes, "gcsize", db.gcsize, "gctime", db.gctime, "livenodes", len(db.nodes), "livesize", db.size)
|
||||
}
|
||||
|
||||
// dereference is the private locked version of Dereference.
|
||||
func (db *Database) dereference(child common.Hash, parent common.Hash) {
|
||||
// Dereference the parent-child
|
||||
node := db.nodes[parent]
|
||||
// Dereference the parent-child relationship
|
||||
delete(db.nodes[parent].children, child)
|
||||
|
||||
node.children[child]--
|
||||
if node.children[child] == 0 {
|
||||
delete(node.children, child)
|
||||
}
|
||||
// If the node does not exist, it's a previously comitted node.
|
||||
node, ok := db.nodes[child]
|
||||
if !ok {
|
||||
|
|
@ -271,7 +274,7 @@ func (db *Database) Commit(node common.Hash) error {
|
|||
db.preimages = make(map[common.Hash][]byte)
|
||||
db.uncache(node)
|
||||
|
||||
log.Debug("Persisted trie from memory database", "nodes", nodes-len(db.nodes), "size", storage-db.size, "time", time.Since(start),
|
||||
log.Info("Persisted trie from memory database", "nodes", nodes-len(db.nodes), "size", storage-db.size, "time", time.Since(start),
|
||||
"gcnodes", db.gcnodes, "gcsize", db.gcsize, "gctime", db.gctime, "livenodes", len(db.nodes), "livesize", db.size)
|
||||
|
||||
// Reset the garbage collection statistics
|
||||
|
|
|
|||
Loading…
Reference in a new issue