Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions core/state/state_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (s Storage) Copy() Storage {
return maps.Clone(s)
}

// StateObject represents an Ethereum account which is being modified.
// stateObject represents an Ethereum account which is being modified.
//
// The usage pattern is as follows:
// - First you need to obtain a state object.
Expand Down Expand Up @@ -98,16 +98,15 @@ func newObject(db *StateDB, address common.Address, acct *types.StateAccount) *s
if acct == nil {
acct = types.NewEmptyStateAccount()
}

return &stateObject{
db: db,
address: address,
addrHash: crypto.Keccak256Hash(address[:]),
origin: origin,
data: *acct,
originStorage: make(Storage),
pendingStorage: make(Storage),
dirtyStorage: make(Storage),
pendingStorage: make(Storage),
uncommittedStorage: make(Storage),
}
}
Expand Down
64 changes: 12 additions & 52 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ type StateDB struct {
originalRoot common.Hash
expectedRoot common.Hash // The state root in the block header

fullProcessed bool
// if needBadSharedStorage = true, try read from sharedPool firstly, compatible with old erroneous data(https://forum.bnbchain.org/t/about-the-hertzfix/2400).
// else read from sharedPool which is not in stateObjectsDestruct.
needBadSharedStorage bool

// This map holds 'live' objects, which will get modified while
// processing a state transition.
Expand All @@ -111,10 +113,6 @@ type StateDB struct {
// perspective. This map is populated at the transaction boundaries.
mutations map[common.Address]*mutation

// if needBadSharedStorage = true, try read from sharedPool firstly, compatible with old erroneous data(https://forum.bnbchain.org/t/about-the-hertzfix/2400).
// else read from sharedPool which is not in stateObjectsDestruct.
needBadSharedStorage bool

// DB error.
// State objects are used by the consensus core and VM which are
// unable to deal with database-level errors. Any error that occurs
Expand Down Expand Up @@ -151,8 +149,6 @@ type StateDB struct {
witness *stateless.Witness // TODO(Nathan): more define the relation with `noTrie`

// Measurements gathered during execution for debugging purposes
// MetricsMux should be used in more places, but will affect on performance, so following meteration is not accurate
MetricsMux sync.Mutex
AccountReads time.Duration
AccountHashes time.Duration
AccountUpdates time.Duration
Expand Down Expand Up @@ -273,11 +269,6 @@ func (s *StateDB) SetExpectedStateRoot(root common.Hash) {
s.expectedRoot = root
}

// Mark that the block is full processed
func (s *StateDB) MarkFullProcessed() {
s.fullProcessed = true
}

// setError remembers the first non-nil error it is called with.
func (s *StateDB) setError(err error) {
if s.dbErr == nil {
Expand Down Expand Up @@ -410,14 +401,6 @@ func (s *StateDB) GetCode(addr common.Address) []byte {
return nil
}

func (s *StateDB) GetRoot(addr common.Address) common.Hash {
stateObject := s.getStateObject(addr)
if stateObject != nil {
return stateObject.data.Root
}
return common.Hash{}
}

func (s *StateDB) GetCodeSize(addr common.Address) int {
stateObject := s.getStateObject(addr)
if stateObject != nil {
Expand Down Expand Up @@ -763,6 +746,13 @@ func (s *StateDB) copyInternal(doPrefetch bool) *StateDB {
logSize: s.logSize,
preimages: maps.Clone(s.preimages),

// Do we need to copy the access list and transient storage?
// In practice: No. At the start of a transaction, these two lists are empty.
// In practice, we only ever copy state _between_ transactions/blocks, never
// in the middle of a transaction. However, it doesn't cost us much to copy
// empty lists, so we do it anyway to not blow up if we ever decide copy them
// in the middle of a transaction.
accessList: s.accessList.Copy(),
transientStorage: s.transientStorage.Copy(),
journal: s.journal.copy(),
}
Expand All @@ -772,15 +762,6 @@ func (s *StateDB) copyInternal(doPrefetch bool) *StateDB {
if s.witness != nil {
state.witness = s.witness.Copy()
}
// Do we need to copy the access list and transient storage?
// In practice: No. At the start of a transaction, these two lists are empty.
// In practice, we only ever copy state _between_ transactions/blocks, never
// in the middle of a transaction. However, it doesn't cost us much to copy
// empty lists, so we do it anyway to not blow up if we ever decide copy them
// in the middle of a transaction.
if s.accessList != nil {
state.accessList = s.accessList.Copy()
}
if s.accessEvents != nil {
state.accessEvents = s.accessEvents.Copy()
}
Expand Down Expand Up @@ -908,7 +889,6 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
start time.Time
workers errgroup.Group
)

if metrics.EnabledExpensive() {
start = time.Now()
}
Expand Down Expand Up @@ -985,7 +965,6 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
// Don't check prefetcher if verkle trie has been used. In the context of verkle,
// only a single trie is used for state hashing. Replacing a non-nil verkle tree
// here could result in losing uncommitted changes from storage.

if metrics.EnabledExpensive() {
start = time.Now()
}
Expand All @@ -996,13 +975,6 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
s.trie = trie
}
}
if s.trie == nil {
tr, err := s.db.OpenTrie(s.originalRoot)
if err != nil {
panic(fmt.Sprintf("failed to open trie tree %s", s.originalRoot))
}
s.trie = tr
}
// Perform updates before deletions. This prevents resolution of unnecessary trie nodes
// in circumstances similar to the following:
//
Expand Down Expand Up @@ -1072,7 +1044,7 @@ func (s *StateDB) SetTxContext(thash common.Hash, ti int) {

// StateDB.Prepare is not called before processing a system transaction, call ClearAccessList instead.
func (s *StateDB) ClearAccessList() {
s.accessList = nil
s.accessList = newAccessList()
}

func (s *StateDB) clearJournalAndRefund() {
Expand Down Expand Up @@ -1346,7 +1318,7 @@ func (s *StateDB) commit(deleteEmptyObjects bool, noStorageWiping bool) (*stateU
// Write the account trie changes, measuring the amount of wasted time
newroot, set := s.trie.Commit(true)
root = newroot
if s.fullProcessed && s.expectedRoot != root {
if (s.expectedRoot != common.Hash{}) && (s.expectedRoot != root) {
log.Error("Invalid merkle root", "remote", s.expectedRoot, "local", root)
return fmt.Errorf("invalid merkle root (remote: %x local: %x)", s.expectedRoot, root)
}
Expand Down Expand Up @@ -1545,19 +1517,13 @@ func (s *StateDB) Prepare(rules params.Rules, sender, coinbase common.Address, d

// AddAddressToAccessList adds the given address to the access list
func (s *StateDB) AddAddressToAccessList(addr common.Address) {
if s.accessList == nil {
s.accessList = newAccessList()
}
if s.accessList.AddAddress(addr) {
s.journal.accessListAddAccount(addr)
}
}

// AddSlotToAccessList adds the given (address, slot)-tuple to the access list
func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) {
if s.accessList == nil {
s.accessList = newAccessList()
}
addrMod, slotMod := s.accessList.AddSlot(addr, slot)
if addrMod {
// In practice, this should not happen, since there is no way to enter the
Expand All @@ -1573,17 +1539,11 @@ func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) {

// AddressInAccessList returns true if the given address is in the access list.
func (s *StateDB) AddressInAccessList(addr common.Address) bool {
if s.accessList == nil {
return false
}
return s.accessList.ContainsAddress(addr)
}

// SlotInAccessList returns true if the given (address, slot)-tuple is in the access list.
func (s *StateDB) SlotInAccessList(addr common.Address, slot common.Hash) (addressPresent bool, slotPresent bool) {
if s.accessList == nil {
return false, false
}
return s.accessList.Contains(addr, slot)
}

Expand Down
1 change: 0 additions & 1 deletion core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg

// initialise bloom processors
bloomProcessors := NewAsyncReceiptBloomGenerator(txNum)
statedb.MarkFullProcessed()

// usually do have two tx, one for validator set contract, another for system reward contract.
systemTxs := make([]*types.Transaction, 0, 2)
Expand Down
2 changes: 1 addition & 1 deletion internal/ethapi/transaction_opts_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func TxOptsCheck(o types.TransactionOpts, blockNumber uint64, timeStamp uint64,
func TxOptsCheckStorage(o types.TransactionOpts, statedb *state.StateDB) error {
for address, accountStorage := range o.KnownAccounts {
if accountStorage.StorageRoot != nil {
rootHash := statedb.GetRoot(address)
rootHash := statedb.GetStorageRoot(address)
if rootHash != *accountStorage.StorageRoot {
return errors.New("storage root hash condition not met")
}
Expand Down