mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
core, miner, trie: Integrate directcache with statedb
This commit is contained in:
parent
2fb08643cb
commit
de5a818baa
8 changed files with 43 additions and 21 deletions
|
|
@ -545,6 +545,11 @@ func (self *BlockChain) GetBlockByNumber(number uint64) *types.Block {
|
||||||
return self.GetBlock(hash, number)
|
return self.GetBlock(hash, number)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsCanonChainBlock checks whether the given block is in the current canonical chain.
|
||||||
|
func (self *BlockChain) IsCanonChainBlock(number uint64, hash common.Hash) bool {
|
||||||
|
return number < uint64(self.currentBlock.Number().Int64()) && GetCanonicalHash(self.chainDb, number) == hash
|
||||||
|
}
|
||||||
|
|
||||||
// [deprecated by eth/62]
|
// [deprecated by eth/62]
|
||||||
// GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
|
// GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
|
||||||
func (self *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
|
func (self *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ func (b *BlockGen) AddTx(tx *types.Transaction) {
|
||||||
if b.gasPool == nil {
|
if b.gasPool == nil {
|
||||||
b.SetCoinbase(common.Address{})
|
b.SetCoinbase(common.Address{})
|
||||||
}
|
}
|
||||||
b.statedb.StartRecord(tx.Hash(), common.Hash{}, len(b.txs))
|
b.statedb.SetTxContext(common.Hash{}, b.header.Number.Uint64(), tx.Hash(), len(b.txs), nil)
|
||||||
receipt, _, _, err := ApplyTransaction(MakeChainConfig(), nil, b.gasPool, b.statedb, b.header, tx, b.header.GasUsed, vm.Config{})
|
receipt, _, _, err := ApplyTransaction(MakeChainConfig(), nil, b.gasPool, b.statedb, b.header, tx, b.header.GasUsed, vm.Config{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ func TestNodeIteratorCoverage(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, key := range db.(*ethdb.MemDatabase).Keys() {
|
for _, key := range db.(*ethdb.MemDatabase).Keys() {
|
||||||
if bytes.HasPrefix(key, []byte("secure-key-")) {
|
if bytes.HasPrefix(key, []byte("secure-key-")) || bytes.HasPrefix(key, CachePrefix) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, ok := hashes[common.BytesToHash(key)]; !ok {
|
if _, ok := hashes[common.BytesToHash(key)]; !ok {
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,8 @@ var StartingNonce uint64
|
||||||
// Trie cache generation limit after which to evic trie nodes from memory.
|
// Trie cache generation limit after which to evic trie nodes from memory.
|
||||||
var MaxTrieCacheGen = uint16(120)
|
var MaxTrieCacheGen = uint16(120)
|
||||||
|
|
||||||
|
var CachePrefix = []byte("accounthashcache:")
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Number of past tries to keep. This value is chosen such that
|
// Number of past tries to keep. This value is chosen such that
|
||||||
// reasonable chain reorg depths will hit an existing trie.
|
// reasonable chain reorg depths will hit an existing trie.
|
||||||
|
|
@ -94,17 +96,19 @@ func New(root common.Hash, db ethdb.Database) (*StateDB, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
csc, _ := lru.New(codeSizeCacheSize)
|
csc, _ := lru.New(codeSizeCacheSize)
|
||||||
return &StateDB{
|
ret := &StateDB{
|
||||||
db: db,
|
db: db,
|
||||||
trie: tr,
|
trie: tr,
|
||||||
storage: trie.NewSecure(tr, db),
|
|
||||||
codeSizeCache: csc,
|
codeSizeCache: csc,
|
||||||
stateObjects: make(map[common.Address]*StateObject),
|
stateObjects: make(map[common.Address]*StateObject),
|
||||||
stateObjectsDirty: make(map[common.Address]struct{}),
|
stateObjectsDirty: make(map[common.Address]struct{}),
|
||||||
refund: new(big.Int),
|
refund: new(big.Int),
|
||||||
logs: make(map[common.Hash]vm.Logs),
|
logs: make(map[common.Hash]vm.Logs),
|
||||||
}, nil
|
}
|
||||||
|
ret.SetTxContext(common.Hash{}, 0, common.Hash{}, 0, nil)
|
||||||
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new statedb by reusing any journalled tries to avoid costly
|
// New creates a new statedb by reusing any journalled tries to avoid costly
|
||||||
|
|
@ -117,16 +121,17 @@ func (self *StateDB) New(root common.Hash) (*StateDB, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &StateDB{
|
ret := &StateDB{
|
||||||
db: self.db,
|
db: self.db,
|
||||||
trie: tr,
|
trie: tr,
|
||||||
storage: trie.NewSecure(tr, self.db),
|
|
||||||
codeSizeCache: self.codeSizeCache,
|
codeSizeCache: self.codeSizeCache,
|
||||||
stateObjects: make(map[common.Address]*StateObject),
|
stateObjects: make(map[common.Address]*StateObject),
|
||||||
stateObjectsDirty: make(map[common.Address]struct{}),
|
stateObjectsDirty: make(map[common.Address]struct{}),
|
||||||
refund: new(big.Int),
|
refund: new(big.Int),
|
||||||
logs: make(map[common.Hash]vm.Logs),
|
logs: make(map[common.Hash]vm.Logs),
|
||||||
}, nil
|
}
|
||||||
|
ret.SetTxContext(common.Hash{}, 0, common.Hash{}, 0, nil)
|
||||||
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset clears out all emphemeral state objects from the state db, but keeps
|
// Reset clears out all emphemeral state objects from the state db, but keeps
|
||||||
|
|
@ -140,7 +145,6 @@ func (self *StateDB) Reset(root common.Hash) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
self.trie = tr
|
self.trie = tr
|
||||||
self.storage = trie.NewSecure(tr, self.db)
|
|
||||||
self.stateObjects = make(map[common.Address]*StateObject)
|
self.stateObjects = make(map[common.Address]*StateObject)
|
||||||
self.stateObjectsDirty = make(map[common.Address]struct{})
|
self.stateObjectsDirty = make(map[common.Address]struct{})
|
||||||
self.thash = common.Hash{}
|
self.thash = common.Hash{}
|
||||||
|
|
@ -149,6 +153,8 @@ func (self *StateDB) Reset(root common.Hash) error {
|
||||||
self.logs = make(map[common.Hash]vm.Logs)
|
self.logs = make(map[common.Hash]vm.Logs)
|
||||||
self.logSize = 0
|
self.logSize = 0
|
||||||
self.clearJournalAndRefund()
|
self.clearJournalAndRefund()
|
||||||
|
self.SetTxContext(common.Hash{}, 0, common.Hash{}, 0, nil)
|
||||||
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -177,10 +183,16 @@ func (self *StateDB) pushTrie(t *trie.Trie) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) StartRecord(thash, bhash common.Hash, ti int) {
|
func (self *StateDB) SetTxContext(blockHash common.Hash, blockNum uint64, txHash common.Hash, txIndex int, validator trie.CacheValidator) {
|
||||||
self.thash = thash
|
self.bhash = blockHash
|
||||||
self.bhash = bhash
|
self.thash = txHash
|
||||||
self.txIndex = ti
|
self.txIndex = txIndex
|
||||||
|
|
||||||
|
if validator == nil {
|
||||||
|
validator = &trie.NullCacheValidator{}
|
||||||
|
}
|
||||||
|
storage := trie.NewDirectCache(self.trie, self.db, CachePrefix, validator, true)
|
||||||
|
self.storage = trie.NewSecure(storage, self.db)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) AddLog(log *vm.Log) {
|
func (self *StateDB) AddLog(log *vm.Log) {
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
||||||
}
|
}
|
||||||
// Iterate over and process the individual transactions
|
// Iterate over and process the individual transactions
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
statedb.StartRecord(tx.Hash(), block.Hash(), i)
|
statedb.SetTxContext(block.Hash(), block.NumberU64(), tx.Hash(), i, p.bc)
|
||||||
receipt, logs, _, err := ApplyTransaction(p.config, p.bc, gp, statedb, header, tx, totalUsedGas, cfg)
|
receipt, logs, _, err := ApplyTransaction(p.config, p.bc, gp, statedb, header, tx, totalUsedGas, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, totalUsedGas, err
|
return nil, nil, totalUsedGas, err
|
||||||
|
|
|
||||||
|
|
@ -583,7 +583,7 @@ func (env *Work) commitTransactions(mux *event.TypeMux, txs *types.TransactionsB
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Start executing the transaction
|
// Start executing the transaction
|
||||||
env.state.StartRecord(tx.Hash(), common.Hash{}, env.tcount)
|
env.state.SetTxContext(common.Hash{}, env.header.Number.Uint64(), tx.Hash(), env.tcount, bc)
|
||||||
|
|
||||||
err, logs := env.commitTransaction(tx, bc, gp)
|
err, logs := env.commitTransaction(tx, bc, gp)
|
||||||
switch {
|
switch {
|
||||||
|
|
|
||||||
|
|
@ -52,13 +52,17 @@ type DirectCache struct {
|
||||||
dirty map[string]bool
|
dirty map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDirectCache(s Storage, db Database, keyPrefix []byte, blockNum uint64, blockHash common.Hash, validator CacheValidator, complete bool) *DirectCache {
|
type NullCacheValidator struct {}
|
||||||
|
|
||||||
|
func (cv *NullCacheValidator) IsCanonChainBlock(num uint64, hash common.Hash) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDirectCache(s Storage, db Database, keyPrefix []byte, validator CacheValidator, complete bool) *DirectCache {
|
||||||
return &DirectCache{
|
return &DirectCache{
|
||||||
storage: s,
|
storage: s,
|
||||||
db: db,
|
db: db,
|
||||||
keyPrefix: keyPrefix,
|
keyPrefix: keyPrefix,
|
||||||
blockNum: blockNum,
|
|
||||||
blockHash: blockHash,
|
|
||||||
validator: validator,
|
validator: validator,
|
||||||
complete: complete,
|
complete: complete,
|
||||||
dirty: make(map[string]bool),
|
dirty: make(map[string]bool),
|
||||||
|
|
@ -83,6 +87,7 @@ func (dc *DirectCache) Get(key []byte) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DirectCache) TryGet(key []byte) ([]byte, error) {
|
func (dc *DirectCache) TryGet(key []byte) ([]byte, error) {
|
||||||
|
return dc.storage.TryGet(key)
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
// Use the underlying object for dirty keys
|
// Use the underlying object for dirty keys
|
||||||
|
|
|
||||||
|
|
@ -583,14 +583,14 @@ func tempDB() (string, Database) {
|
||||||
return dir, db
|
return dir, db
|
||||||
}
|
}
|
||||||
|
|
||||||
func getString(trie Trie, k string) []byte {
|
func getString(trie *Trie, k string) []byte {
|
||||||
return trie.Get([]byte(k))
|
return trie.Get([]byte(k))
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateString(trie Trie, k, v string) {
|
func updateString(trie *Trie, k, v string) {
|
||||||
trie.Update([]byte(k), []byte(v))
|
trie.Update([]byte(k), []byte(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteString(trie Trie, k string) {
|
func deleteString(trie *Trie, k string) {
|
||||||
trie.Delete([]byte(k))
|
trie.Delete([]byte(k))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue