remove snapshot usage and unused internal methods; note this is different than the journaling used to simulate state transitions
This commit is contained in:
parent
b7b1896699
commit
ae70c88e19
@ -37,7 +37,6 @@ func makePGXConfig(config Config) (*pgxpool.Config, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
//conf.ConnConfig.BuildStatementCache = nil
|
|
||||||
conf.ConnConfig.Config.Host = config.Hostname
|
conf.ConnConfig.Config.Host = config.Hostname
|
||||||
conf.ConnConfig.Config.Port = uint16(config.Port)
|
conf.ConnConfig.Config.Port = uint16(config.Port)
|
||||||
conf.ConnConfig.Config.Database = config.DatabaseName
|
conf.ConnConfig.Config.Database = config.DatabaseName
|
||||||
|
@ -3,6 +3,8 @@ package ipld_eth_statedb
|
|||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
"github.com/jackc/pgx/pgxpool"
|
"github.com/jackc/pgx/pgxpool"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -15,10 +17,13 @@ type Database interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type StateDatabase struct {
|
type StateDatabase struct {
|
||||||
pgxpool.Pool
|
db pgxpool.Pool
|
||||||
|
trieDB *trie.Database
|
||||||
|
ethDB ethdb.Database
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sd *StateDatabase) ContractCode(addrHash common.Hash, codeHash common.Hash) ([]byte, error) {
|
func (sd *StateDatabase) ContractCode(addrHash common.Hash, codeHash common.Hash) ([]byte, error) {
|
||||||
|
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,7 +32,7 @@ func (sd *StateDatabase) ContractCodeSize(addrHash common.Hash, codeHash common.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sd *StateDatabase) OpenTrie(root common.Hash) (state.Trie, error) {
|
func (sd *StateDatabase) OpenTrie(root common.Hash) (state.Trie, error) {
|
||||||
panic("replace my usage")
|
return trie.NewStateTrie(common.Hash{}, root, sd.trieDB), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sd *StateDatabase) OpenStorageTrie(addrHash common.Hash, root common.Hash) (state.Trie, error) {
|
func (sd *StateDatabase) OpenStorageTrie(addrHash common.Hash, root common.Hash) (state.Trie, error) {
|
||||||
|
@ -135,9 +135,6 @@ func (ch createObjectChange) dirtied() *common.Address {
|
|||||||
|
|
||||||
func (ch resetObjectChange) revert(s *StateDB) {
|
func (ch resetObjectChange) revert(s *StateDB) {
|
||||||
s.setStateObject(ch.prev)
|
s.setStateObject(ch.prev)
|
||||||
if !ch.prevdestruct && s.snap != nil {
|
|
||||||
delete(s.snapDestructs, ch.prev.addrHash)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ch resetObjectChange) dirtied() *common.Address {
|
func (ch resetObjectChange) dirtied() *common.Address {
|
||||||
|
@ -186,36 +186,7 @@ func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Has
|
|||||||
// If no live objects are available, attempt to use snapshots
|
// If no live objects are available, attempt to use snapshots
|
||||||
var (
|
var (
|
||||||
enc []byte
|
enc []byte
|
||||||
err error
|
|
||||||
)
|
)
|
||||||
if s.db.snap != nil {
|
|
||||||
// If the object was destructed in *this* block (and potentially resurrected),
|
|
||||||
// the storage has been cleared out, and we should *not* consult the previous
|
|
||||||
// snapshot about any storage values. The only possible alternatives are:
|
|
||||||
// 1) resurrect happened, and new slot values were set -- those should
|
|
||||||
// have been handles via pendingStorage above.
|
|
||||||
// 2) we don't have new values, and can deliver empty response back
|
|
||||||
if _, destructed := s.db.snapDestructs[s.addrHash]; destructed {
|
|
||||||
return common.Hash{}
|
|
||||||
}
|
|
||||||
start := time.Now()
|
|
||||||
enc, err = s.db.snap.Storage(s.addrHash, crypto.Keccak256Hash(key.Bytes()))
|
|
||||||
if metrics.EnabledExpensive {
|
|
||||||
s.db.SnapshotStorageReads += time.Since(start)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If the snapshot is unavailable or reading from it fails, load from the database.
|
|
||||||
if s.db.snap == nil || err != nil {
|
|
||||||
start := time.Now()
|
|
||||||
enc, err = s.getTrie(db).TryGet(key.Bytes())
|
|
||||||
if metrics.EnabledExpensive {
|
|
||||||
s.db.StorageReads += time.Since(start)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
s.setError(err)
|
|
||||||
return common.Hash{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var value common.Hash
|
var value common.Hash
|
||||||
if len(enc) > 0 {
|
if len(enc) > 0 {
|
||||||
_, content, _, err := rlp.Split(enc)
|
_, content, _, err := rlp.Split(enc)
|
||||||
@ -301,11 +272,8 @@ func (s *stateObject) updateTrie(db Database) state.Trie {
|
|||||||
if metrics.EnabledExpensive {
|
if metrics.EnabledExpensive {
|
||||||
defer func(start time.Time) { s.db.StorageUpdates += time.Since(start) }(time.Now())
|
defer func(start time.Time) { s.db.StorageUpdates += time.Since(start) }(time.Now())
|
||||||
}
|
}
|
||||||
// The snapshot storage map for the object
|
|
||||||
var storage map[common.Hash][]byte
|
|
||||||
// Insert all the pending updates into the trie
|
// Insert all the pending updates into the trie
|
||||||
tr := s.getTrie(db)
|
tr := s.getTrie(db)
|
||||||
hasher := s.db.hasher
|
|
||||||
|
|
||||||
usedStorage := make([][]byte, 0, len(s.pendingStorage))
|
usedStorage := make([][]byte, 0, len(s.pendingStorage))
|
||||||
for key, value := range s.pendingStorage {
|
for key, value := range s.pendingStorage {
|
||||||
@ -325,17 +293,6 @@ func (s *stateObject) updateTrie(db Database) state.Trie {
|
|||||||
s.setError(tr.TryUpdate(key[:], v))
|
s.setError(tr.TryUpdate(key[:], v))
|
||||||
s.db.StorageUpdated += 1
|
s.db.StorageUpdated += 1
|
||||||
}
|
}
|
||||||
// If state snapshotting is active, cache the data til commit
|
|
||||||
if s.db.snap != nil {
|
|
||||||
if storage == nil {
|
|
||||||
// Retrieve the old storage map, if available, create a new one otherwise
|
|
||||||
if storage = s.db.snapStorage[s.addrHash]; storage == nil {
|
|
||||||
storage = make(map[common.Hash][]byte)
|
|
||||||
s.db.snapStorage[s.addrHash] = storage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
storage[crypto.HashData(hasher, key[:])] = v // v will be nil if it's deleted
|
|
||||||
}
|
|
||||||
usedStorage = append(usedStorage, common.CopyBytes(key[:])) // Copy needed for closure
|
usedStorage = append(usedStorage, common.CopyBytes(key[:])) // Copy needed for closure
|
||||||
}
|
}
|
||||||
if s.db.prefetcher != nil {
|
if s.db.prefetcher != nil {
|
||||||
|
102
statedb.go
102
statedb.go
@ -65,7 +65,6 @@ type StateDB struct {
|
|||||||
originalRoot common.Hash
|
originalRoot common.Hash
|
||||||
|
|
||||||
snaps *snapshot.Tree
|
snaps *snapshot.Tree
|
||||||
snap snapshot.Snapshot
|
|
||||||
snapDestructs map[common.Hash]struct{}
|
snapDestructs map[common.Hash]struct{}
|
||||||
snapAccounts map[common.Hash][]byte
|
snapAccounts map[common.Hash][]byte
|
||||||
snapStorage map[common.Hash]map[common.Hash][]byte
|
snapStorage map[common.Hash]map[common.Hash][]byte
|
||||||
@ -140,13 +139,6 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error)
|
|||||||
accessList: newAccessList(),
|
accessList: newAccessList(),
|
||||||
hasher: crypto.NewKeccakState(),
|
hasher: crypto.NewKeccakState(),
|
||||||
}
|
}
|
||||||
if sdb.snaps != nil {
|
|
||||||
if sdb.snap = sdb.snaps.Snapshot(root); sdb.snap != nil {
|
|
||||||
sdb.snapDestructs = make(map[common.Hash]struct{})
|
|
||||||
sdb.snapAccounts = make(map[common.Hash][]byte)
|
|
||||||
sdb.snapStorage = make(map[common.Hash]map[common.Hash][]byte)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sdb, nil
|
return sdb, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,42 +339,6 @@ func (s *StateDB) Suicide(addr common.Address) bool {
|
|||||||
// Setting, updating & deleting state object methods.
|
// Setting, updating & deleting state object methods.
|
||||||
//
|
//
|
||||||
|
|
||||||
// updateStateObject writes the given object to the trie.
|
|
||||||
// TODO:
|
|
||||||
func (s *StateDB) updateStateObject(obj *stateObject) {
|
|
||||||
// Track the amount of time wasted on updating the account from the trie
|
|
||||||
if metrics.EnabledExpensive {
|
|
||||||
defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now())
|
|
||||||
}
|
|
||||||
// Encode the account and update the account trie
|
|
||||||
addr := obj.Address()
|
|
||||||
if err := s.trie.TryUpdateAccount(addr[:], &obj.data); err != nil {
|
|
||||||
s.setError(fmt.Errorf("updateStateObject (%x) error: %v", addr[:], err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// If state snapshotting is active, cache the data til commit. Note, this
|
|
||||||
// update mechanism is not symmetric to the deletion, because whereas it is
|
|
||||||
// enough to track account updates at commit time, deletions need tracking
|
|
||||||
// at transaction boundary level to ensure we capture state clearing.
|
|
||||||
if s.snap != nil {
|
|
||||||
s.snapAccounts[obj.addrHash] = snapshot.SlimAccountRLP(obj.data.Nonce, obj.data.Balance, obj.data.Root, obj.data.CodeHash)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// deleteStateObject removes the given object from the state trie.
|
|
||||||
// TODO:
|
|
||||||
func (s *StateDB) deleteStateObject(obj *stateObject) {
|
|
||||||
// Track the amount of time wasted on deleting the account from the trie
|
|
||||||
if metrics.EnabledExpensive {
|
|
||||||
defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now())
|
|
||||||
}
|
|
||||||
// Delete the account from the trie
|
|
||||||
addr := obj.Address()
|
|
||||||
if err := s.trie.TryDeleteAccount(addr[:]); err != nil {
|
|
||||||
s.setError(fmt.Errorf("deleteStateObject (%x) error: %v", addr[:], err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// getStateObject retrieves a state object given by the address, returning nil if
|
// getStateObject retrieves a state object given by the address, returning nil if
|
||||||
// the object is not found or was deleted in this execution context. If you need
|
// the object is not found or was deleted in this execution context. If you need
|
||||||
// to differentiate between non-existent/just-deleted, use getDeletedStateObject.
|
// to differentiate between non-existent/just-deleted, use getDeletedStateObject.
|
||||||
@ -403,37 +359,11 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
|
|||||||
if obj := s.stateObjects[addr]; obj != nil {
|
if obj := s.stateObjects[addr]; obj != nil {
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
// If no live objects are available, attempt to use snapshots
|
// If no live objects are available, load from the database
|
||||||
var data *types.StateAccount
|
// TODO: REPLACE TRIE ACCESS HERE
|
||||||
if s.snap != nil {
|
// can add a fallback option to use ipfsethdb to do the trie access if direct access fails
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
acc, err := s.snap.Account(crypto.HashData(s.hasher, addr.Bytes()))
|
data, err := s.trie.TryGetAccount(addr.Bytes())
|
||||||
if metrics.EnabledExpensive {
|
|
||||||
s.SnapshotAccountReads += time.Since(start)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
if acc == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
data = &types.StateAccount{
|
|
||||||
Nonce: acc.Nonce,
|
|
||||||
Balance: acc.Balance,
|
|
||||||
CodeHash: acc.CodeHash,
|
|
||||||
Root: common.BytesToHash(acc.Root),
|
|
||||||
}
|
|
||||||
if len(data.CodeHash) == 0 {
|
|
||||||
data.CodeHash = emptyCodeHash
|
|
||||||
}
|
|
||||||
if data.Root == (common.Hash{}) {
|
|
||||||
data.Root = emptyRoot
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If snapshot unavailable or reading from it failed, load from the database
|
|
||||||
if data == nil {
|
|
||||||
start := time.Now()
|
|
||||||
var err error
|
|
||||||
data, err = s.trie.TryGetAccount(addr.Bytes())
|
|
||||||
if metrics.EnabledExpensive {
|
if metrics.EnabledExpensive {
|
||||||
s.AccountReads += time.Since(start)
|
s.AccountReads += time.Since(start)
|
||||||
}
|
}
|
||||||
@ -444,7 +374,6 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
|
|||||||
if data == nil {
|
if data == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Insert into the live set
|
// Insert into the live set
|
||||||
obj := newObject(s, addr, *data)
|
obj := newObject(s, addr, *data)
|
||||||
s.setStateObject(obj)
|
s.setStateObject(obj)
|
||||||
@ -468,19 +397,11 @@ func (s *StateDB) getOrNewStateObject(addr common.Address) *stateObject {
|
|||||||
// the given address, it is overwritten and returned as the second return value.
|
// the given address, it is overwritten and returned as the second return value.
|
||||||
func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) {
|
func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) {
|
||||||
prev = s.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that!
|
prev = s.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that!
|
||||||
|
|
||||||
var prevdestruct bool
|
|
||||||
if s.snap != nil && prev != nil {
|
|
||||||
_, prevdestruct = s.snapDestructs[prev.addrHash]
|
|
||||||
if !prevdestruct {
|
|
||||||
s.snapDestructs[prev.addrHash] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newobj = newObject(s, addr, types.StateAccount{})
|
newobj = newObject(s, addr, types.StateAccount{})
|
||||||
if prev == nil {
|
if prev == nil {
|
||||||
s.journal.append(createObjectChange{account: &addr})
|
s.journal.append(createObjectChange{account: &addr})
|
||||||
} else {
|
} else {
|
||||||
s.journal.append(resetObjectChange{prev: prev, prevdestruct: prevdestruct})
|
s.journal.append(resetObjectChange{prev: prev}) // NOTE: prevdestruct used to be set here from snapshot
|
||||||
}
|
}
|
||||||
s.setStateObject(newobj)
|
s.setStateObject(newobj)
|
||||||
if prev != nil && !prev.deleted {
|
if prev != nil && !prev.deleted {
|
||||||
@ -506,6 +427,7 @@ func (s *StateDB) CreateAccount(addr common.Address) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: not sure trie access can be replaced for this method, might need to use ipfs-ethdb
|
||||||
func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) error {
|
func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) error {
|
||||||
so := db.getStateObject(addr)
|
so := db.getStateObject(addr)
|
||||||
if so == nil {
|
if so == nil {
|
||||||
@ -552,10 +474,10 @@ func (s *StateDB) RevertToSnapshot(revid int) {
|
|||||||
if idx == len(s.validRevisions) || s.validRevisions[idx].id != revid {
|
if idx == len(s.validRevisions) || s.validRevisions[idx].id != revid {
|
||||||
panic(fmt.Errorf("revision id %v cannot be reverted", revid))
|
panic(fmt.Errorf("revision id %v cannot be reverted", revid))
|
||||||
}
|
}
|
||||||
snapshot := s.validRevisions[idx].journalIndex
|
snp := s.validRevisions[idx].journalIndex
|
||||||
|
|
||||||
// Replay the journal to undo changes and remove invalidated snapshots
|
// Replay the journal to undo changes and remove invalidated snapshots
|
||||||
s.journal.revert(s, snapshot)
|
s.journal.revert(s, snp)
|
||||||
s.validRevisions = s.validRevisions[:idx]
|
s.validRevisions = s.validRevisions[:idx]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -564,14 +486,6 @@ func (s *StateDB) GetRefund() uint64 {
|
|||||||
return s.refund
|
return s.refund
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StateDB) clearJournalAndRefund() {
|
|
||||||
if len(s.journal.entries) > 0 {
|
|
||||||
s.journal = newJournal()
|
|
||||||
s.refund = 0
|
|
||||||
}
|
|
||||||
s.validRevisions = s.validRevisions[:0] // Snapshots can be created without journal entries
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrepareAccessList handles the preparatory steps for executing a state transition with
|
// PrepareAccessList handles the preparatory steps for executing a state transition with
|
||||||
// regards to both EIP-2929 and EIP-2930:
|
// regards to both EIP-2929 and EIP-2930:
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user