mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
trie, core/state: use cache unloading for account trie
This commit is contained in:
parent
c4568fb625
commit
b74240ff76
7 changed files with 21 additions and 15 deletions
|
|
@ -269,7 +269,7 @@ func (self *BlockChain) FastSyncCommitHead(hash common.Hash) error {
|
||||||
if block == nil {
|
if block == nil {
|
||||||
return fmt.Errorf("non existent block [%x…]", hash[:4])
|
return fmt.Errorf("non existent block [%x…]", hash[:4])
|
||||||
}
|
}
|
||||||
if _, err := trie.NewSecure(block.Root(), self.chainDb); err != nil {
|
if _, err := trie.NewSecure(block.Root(), self.chainDb, 0); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// If all checks out, manually set the head block
|
// If all checks out, manually set the head block
|
||||||
|
|
|
||||||
|
|
@ -137,9 +137,9 @@ func (self *StateObject) markSuicided() {
|
||||||
func (c *StateObject) getTrie(db trie.Database) *trie.SecureTrie {
|
func (c *StateObject) getTrie(db trie.Database) *trie.SecureTrie {
|
||||||
if c.trie == nil {
|
if c.trie == nil {
|
||||||
var err error
|
var err error
|
||||||
c.trie, err = trie.NewSecure(c.data.Root, db)
|
c.trie, err = trie.NewSecure(c.data.Root, db, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.trie, _ = trie.NewSecure(common.Hash{}, db)
|
c.trie, _ = trie.NewSecure(common.Hash{}, db, 0)
|
||||||
c.setError(fmt.Errorf("can't create storage trie: %v", err))
|
c.setError(fmt.Errorf("can't create storage trie: %v", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,9 @@ const (
|
||||||
// is max uncle depth + 1.
|
// is max uncle depth + 1.
|
||||||
maxTrieCacheLength = 8
|
maxTrieCacheLength = 8
|
||||||
|
|
||||||
|
// Trie cache generation limit.
|
||||||
|
maxTrieCacheGen = 100
|
||||||
|
|
||||||
// Number of codehash->size associations to keep.
|
// Number of codehash->size associations to keep.
|
||||||
codeSizeCacheSize = 100000
|
codeSizeCacheSize = 100000
|
||||||
)
|
)
|
||||||
|
|
@ -86,7 +89,7 @@ type StateDB struct {
|
||||||
|
|
||||||
// Create a new state from a given trie
|
// Create a new state from a given trie
|
||||||
func New(root common.Hash, db ethdb.Database) (*StateDB, error) {
|
func New(root common.Hash, db ethdb.Database) (*StateDB, error) {
|
||||||
tr, err := trie.NewSecure(root, db)
|
tr, err := trie.NewSecure(root, db, maxTrieCacheGen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -155,7 +158,7 @@ func (self *StateDB) openTrie(root common.Hash) (*trie.SecureTrie, error) {
|
||||||
return &tr, nil
|
return &tr, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return trie.NewSecure(root, self.db)
|
return trie.NewSecure(root, self.db, maxTrieCacheGen)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) pushTrie(t *trie.SecureTrie) {
|
func (self *StateDB) pushTrie(t *trie.SecureTrie) {
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,7 @@ func (dl *downloadTester) headFastBlock() *types.Block {
|
||||||
func (dl *downloadTester) commitHeadBlock(hash common.Hash) error {
|
func (dl *downloadTester) commitHeadBlock(hash common.Hash) error {
|
||||||
// For now only check that the state trie is correct
|
// For now only check that the state trie is correct
|
||||||
if block := dl.getBlock(hash); block != nil {
|
if block := dl.getBlock(hash); block != nil {
|
||||||
_, err := trie.NewSecure(block.Root(), dl.stateDb)
|
_, err := trie.NewSecure(block.Root(), dl.stateDb, 0)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return fmt.Errorf("non existent block: %x", hash[:4])
|
return fmt.Errorf("non existent block: %x", hash[:4])
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ func (t *LightTrie) do(ctx context.Context, fallbackKey []byte, fn func() error)
|
||||||
func (t *LightTrie) Get(ctx context.Context, key []byte) (res []byte, err error) {
|
func (t *LightTrie) Get(ctx context.Context, key []byte) (res []byte, err error) {
|
||||||
err = t.do(ctx, key, func() (err error) {
|
err = t.do(ctx, key, func() (err error) {
|
||||||
if t.trie == nil {
|
if t.trie == nil {
|
||||||
t.trie, err = trie.NewSecure(t.originalRoot, t.db)
|
t.trie, err = trie.NewSecure(t.originalRoot, t.db, 0)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
res, err = t.trie.TryGet(key)
|
res, err = t.trie.TryGet(key)
|
||||||
|
|
@ -98,7 +98,7 @@ func (t *LightTrie) Get(ctx context.Context, key []byte) (res []byte, err error)
|
||||||
func (t *LightTrie) Update(ctx context.Context, key, value []byte) (err error) {
|
func (t *LightTrie) Update(ctx context.Context, key, value []byte) (err error) {
|
||||||
err = t.do(ctx, key, func() (err error) {
|
err = t.do(ctx, key, func() (err error) {
|
||||||
if t.trie == nil {
|
if t.trie == nil {
|
||||||
t.trie, err = trie.NewSecure(t.originalRoot, t.db)
|
t.trie, err = trie.NewSecure(t.originalRoot, t.db, 0)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = t.trie.TryUpdate(key, value)
|
err = t.trie.TryUpdate(key, value)
|
||||||
|
|
@ -112,7 +112,7 @@ func (t *LightTrie) Update(ctx context.Context, key, value []byte) (err error) {
|
||||||
func (t *LightTrie) Delete(ctx context.Context, key []byte) (err error) {
|
func (t *LightTrie) Delete(ctx context.Context, key []byte) (err error) {
|
||||||
err = t.do(ctx, key, func() (err error) {
|
err = t.do(ctx, key, func() (err error) {
|
||||||
if t.trie == nil {
|
if t.trie == nil {
|
||||||
t.trie, err = trie.NewSecure(t.originalRoot, t.db)
|
t.trie, err = trie.NewSecure(t.originalRoot, t.db, 0)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = t.trie.TryDelete(key)
|
err = t.trie.TryDelete(key)
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,12 @@ type SecureTrie struct {
|
||||||
// If root is the zero hash or the sha3 hash of an empty string, the
|
// If root is the zero hash or the sha3 hash of an empty string, the
|
||||||
// trie is initially empty. Otherwise, New will panic if db is nil
|
// trie is initially empty. Otherwise, New will panic if db is nil
|
||||||
// and returns MissingNodeError if the root node cannot be found.
|
// and returns MissingNodeError if the root node cannot be found.
|
||||||
|
//
|
||||||
// Accessing the trie loads nodes from db on demand.
|
// Accessing the trie loads nodes from db on demand.
|
||||||
func NewSecure(root common.Hash, db Database) (*SecureTrie, error) {
|
// Loaded nodes are kept around until their 'cache generation' expires.
|
||||||
|
// A new cache generation is created by each call to Commit.
|
||||||
|
// cachelimit sets the number of past cache generations to keep.
|
||||||
|
func NewSecure(root common.Hash, db Database, cachelimit uint16) (*SecureTrie, error) {
|
||||||
if db == nil {
|
if db == nil {
|
||||||
panic("NewSecure called with nil database")
|
panic("NewSecure called with nil database")
|
||||||
}
|
}
|
||||||
|
|
@ -58,9 +62,8 @@ func NewSecure(root common.Hash, db Database) (*SecureTrie, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &SecureTrie{
|
trie.SetCacheLimit(cachelimit)
|
||||||
trie: *trie,
|
return &SecureTrie{trie: *trie}, nil
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the value for key stored in the trie.
|
// Get returns the value for key stored in the trie.
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ import (
|
||||||
|
|
||||||
func newEmptySecure() *SecureTrie {
|
func newEmptySecure() *SecureTrie {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
trie, _ := NewSecure(common.Hash{}, db)
|
trie, _ := NewSecure(common.Hash{}, db, 0)
|
||||||
return trie
|
return trie
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ func newEmptySecure() *SecureTrie {
|
||||||
func makeTestSecureTrie() (ethdb.Database, *SecureTrie, map[string][]byte) {
|
func makeTestSecureTrie() (ethdb.Database, *SecureTrie, map[string][]byte) {
|
||||||
// Create an empty trie
|
// Create an empty trie
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
trie, _ := NewSecure(common.Hash{}, db)
|
trie, _ := NewSecure(common.Hash{}, db, 0)
|
||||||
|
|
||||||
// Fill it with some arbitrary data
|
// Fill it with some arbitrary data
|
||||||
content := make(map[string][]byte)
|
content := make(map[string][]byte)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue