aboutsummaryrefslogtreecommitdiff
path: root/core/state/database.go
diff options
context:
space:
mode:
Diffstat (limited to 'core/state/database.go')
-rw-r--r--core/state/database.go47
1 files changed, 38 insertions, 9 deletions
diff --git a/core/state/database.go b/core/state/database.go
index 8c641c3..385c25d 100644
--- a/core/state/database.go
+++ b/core/state/database.go
@@ -17,17 +17,23 @@
package state
import (
+ "errors"
"fmt"
- "github.com/ava-labs/go-ethereum/common"
- "github.com/ava-labs/go-ethereum/ethdb"
- "github.com/ava-labs/go-ethereum/trie"
+ "github.com/VictoriaMetrics/fastcache"
+ "github.com/ava-labs/coreth/core/rawdb"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/ethereum/go-ethereum/trie"
lru "github.com/hashicorp/golang-lru"
)
const (
// Number of codehash->size associations to keep.
codeSizeCacheSize = 100000
+
+ // Cache size granted for caching clean code.
+ codeCacheSize = 64 * 1024 * 1024
)
// Database wraps access to tries and contract code.
@@ -100,23 +106,25 @@ type Trie interface {
// concurrent use, but does not retain any recent trie nodes in memory. To keep some
// historical state in memory, use the NewDatabaseWithCache constructor.
func NewDatabase(db ethdb.Database) Database {
- return NewDatabaseWithCache(db, 0)
+ return NewDatabaseWithCache(db, 0, "")
}
// NewDatabaseWithCache creates a backing store for state. The returned database
// is safe for concurrent use and retains a lot of collapsed RLP trie nodes in a
// large memory cache.
-func NewDatabaseWithCache(db ethdb.Database, cache int) Database {
+func NewDatabaseWithCache(db ethdb.Database, cache int, journal string) Database {
csc, _ := lru.New(codeSizeCacheSize)
return &cachingDB{
- db: trie.NewDatabaseWithCache(db, cache),
+ db: trie.NewDatabaseWithCache(db, cache, journal),
codeSizeCache: csc,
+ codeCache: fastcache.New(codeCacheSize),
}
}
type cachingDB struct {
db *trie.Database
codeSizeCache *lru.Cache
+ codeCache *fastcache.Cache
}
// OpenTrie opens the main account trie at a specific root hash.
@@ -141,11 +149,32 @@ func (db *cachingDB) CopyTrie(t Trie) Trie {
// ContractCode retrieves a particular contract's code.
func (db *cachingDB) ContractCode(addrHash, codeHash common.Hash) ([]byte, error) {
- code, err := db.db.Node(codeHash)
- if err == nil {
+ if code := db.codeCache.Get(nil, codeHash.Bytes()); len(code) > 0 {
+ return code, nil
+ }
+ code := rawdb.ReadCode(db.db.DiskDB(), codeHash)
+ if len(code) > 0 {
+ db.codeCache.Set(codeHash.Bytes(), code)
+ db.codeSizeCache.Add(codeHash, len(code))
+ return code, nil
+ }
+ return nil, errors.New("not found")
+}
+
+// ContractCodeWithPrefix retrieves a particular contract's code. If the
+// code can't be found in the cache, then check the existence with **new**
+// db scheme.
+func (db *cachingDB) ContractCodeWithPrefix(addrHash, codeHash common.Hash) ([]byte, error) {
+ if code := db.codeCache.Get(nil, codeHash.Bytes()); len(code) > 0 {
+ return code, nil
+ }
+ code := rawdb.ReadCodeWithPrefix(db.db.DiskDB(), codeHash)
+ if len(code) > 0 {
+ db.codeCache.Set(codeHash.Bytes(), code)
db.codeSizeCache.Add(codeHash, len(code))
+ return code, nil
}
- return code, err
+ return nil, errors.New("not found")
}
// ContractCodeSize retrieves a particular contracts code's size.