mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-04 10:04:28 +00:00
5ea590c18e
* State cache init * More code * Fix lint * More tests * More tests * More tests * Fix test * Transformations * remove writeQueue, before fixing the tests * Fix tests * Add more tests, incarnation to the code items * Fix lint * Fix lint * Remove shards prototype, add incarnation to the state reader code * Clean up and replace cache in call_traces stage * fix flaky test * Save changes * Readers to use addrHash, writes - addresses * Fix lint * Fix lint * More accurate tracking of size * Optimise for smaller write batches * Attempt to integrate state cache into Execution stage * cacheSize to default flags * Print correct cache sizes and batch sizes * cacheSize in the integration * Fix tests * Fix lint * Remove print * Fix exec stage * Fix test * Refresh sequence on write * No double increment * heap.Remove * Try to fix alignment * Refactoring, adding hashItems * More changes * Fix compile errors * Fix lint * Wrapping cached reader * Wrap writer into cached writer * Turn state cache off by default * Fix plain state writer * Fix for code/storage mixup * Fix tests * Fix clique test * Better fix for the tests * Add test and fix some more * Fix compile error| * More functions * Fixes * Fix for the tests * sepatate DeletedFlag and AbsentFlag * Minor fixes * Test refactoring * More changes * Fix some tests * More test fixes * More test fixes * Fix lint * Move blockchain_test to be able to use stagedsync * More fixes * Fixes and cleanup * Fix tests in turbo/stages * Fix lint * Fix lint * Intemediate * Fix tests * Intemediate * More fixes * Compilation fixes * More fixes * Fix compile errors * More test fixes * More fixes * More test fixes * Fix compile error * Fixes * Fix * Fix * More fixes * Fixes * More fixes and cleanup * Further fix * Check gas used and bloom with header Co-authored-by: Alexey Sharp <alexeysharp@Alexeys-iMac.local>
89 lines
2.9 KiB
Go
89 lines
2.9 KiB
Go
package state
|
|
|
|
import (
|
|
"bytes"
|
|
|
|
"github.com/ledgerwatch/turbo-geth/common"
|
|
"github.com/ledgerwatch/turbo-geth/core/types/accounts"
|
|
"github.com/ledgerwatch/turbo-geth/turbo/shards"
|
|
)
|
|
|
|
// CachedReader is a wrapper for an instance of type StateReader
|
|
// This wrapper only makes calls to the underlying reader if the item is not in the cache
|
|
type CachedReader struct {
|
|
r StateReader
|
|
cache *shards.StateCache
|
|
}
|
|
|
|
// NewCachedReader wraps a given state reader into the cached reader
|
|
func NewCachedReader(r StateReader, cache *shards.StateCache) *CachedReader {
|
|
return &CachedReader{r: r, cache: cache}
|
|
}
|
|
|
|
// ReadAccountData is called when an account needs to be fetched from the state
|
|
func (cr *CachedReader) ReadAccountData(address common.Address) (*accounts.Account, error) {
|
|
if a, ok := cr.cache.GetAccount(address.Bytes()); ok {
|
|
return a, nil
|
|
}
|
|
a, err := cr.r.ReadAccountData(address)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if a == nil {
|
|
cr.cache.SetAccountAbsent(address.Bytes())
|
|
} else {
|
|
cr.cache.SetAccountRead(address.Bytes(), a)
|
|
}
|
|
return a, nil
|
|
}
|
|
|
|
// ReadAccountStorage is called when a storage item needs to be fetched from the state
|
|
func (cr *CachedReader) ReadAccountStorage(address common.Address, incarnation uint64, key *common.Hash) ([]byte, error) {
|
|
if s, ok := cr.cache.GetStorage(address.Bytes(), incarnation, key.Bytes()); ok {
|
|
return s, nil
|
|
}
|
|
v, err := cr.r.ReadAccountStorage(address, incarnation, key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(v) == 0 {
|
|
cr.cache.SetStorageAbsent(address.Bytes(), incarnation, key.Bytes())
|
|
} else {
|
|
cr.cache.SetStorageRead(address.Bytes(), incarnation, key.Bytes(), v)
|
|
}
|
|
return v, nil
|
|
}
|
|
|
|
// ReadAccountCode is called when code of an account needs to be fetched from the state
|
|
// Usually, one of (address;incarnation) or codeHash is enough to uniquely identify the code
|
|
func (cr *CachedReader) ReadAccountCode(address common.Address, incarnation uint64, codeHash common.Hash) ([]byte, error) {
|
|
if bytes.Equal(codeHash[:], emptyCodeHash) {
|
|
return nil, nil
|
|
}
|
|
if c, ok := cr.cache.GetCode(address.Bytes(), incarnation); ok {
|
|
return c, nil
|
|
}
|
|
c, err := cr.r.ReadAccountCode(address, incarnation, codeHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if cr.cache != nil && len(c) <= 1024 {
|
|
cr.cache.SetCodeRead(address.Bytes(), incarnation, c)
|
|
}
|
|
return c, nil
|
|
}
|
|
|
|
func (cr *CachedReader) ReadAccountCodeSize(address common.Address, incarnation uint64, codeHash common.Hash) (int, error) {
|
|
c, err := cr.ReadAccountCode(address, incarnation, codeHash)
|
|
return len(c), err
|
|
}
|
|
|
|
// ReadAccountIncarnation is called when incarnation of the account is required (to create and recreate contract)
|
|
func (cr *CachedReader) ReadAccountIncarnation(address common.Address) (uint64, error) {
|
|
deleted := cr.cache.GetDeletedAccount(address.Bytes())
|
|
if deleted != nil {
|
|
return deleted.Incarnation, nil
|
|
}
|
|
return cr.r.ReadAccountIncarnation(address)
|
|
}
|