Skip to content

core/state: semantic journalling (part 1) #28880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Aug 28, 2024
Merged
62 changes: 33 additions & 29 deletions core/state/journal.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,26 +63,26 @@ func newJournal() *journal {
}
}

// Reset clears the journal, after this operation the journal can be used
// anew. It is semantically similar to calling 'newJournal', but the underlying
// slices can be reused
func (j *journal) Reset() {
// reset clears the journal, after this operation the journal can be used
// as new. It is semantically similar to calling 'newJournal', but the underlying
// slices can be reused.
func (j *journal) reset() {
j.entries = j.entries[:0]
j.validRevisions = j.validRevisions[:0]
clear(j.dirties)
j.nextRevisionId = 0
}

// Snapshot returns an identifier for the current revision of the state.
func (j *journal) Snapshot() int {
// snapshot returns an identifier for the current revision of the state.
func (j *journal) snapshot() int {
id := j.nextRevisionId
j.nextRevisionId++
j.validRevisions = append(j.validRevisions, revision{id, j.length()})
return id
}

// RevertToSnapshot reverts all state changes made since the given revision.
func (j *journal) RevertToSnapshot(revid int, s *StateDB) {
// revertToSnapshot reverts all state changes made since the given revision.
func (j *journal) revertToSnapshot(revid int, s *StateDB) {
// Find the snapshot in the stack of valid snapshots.
idx := sort.Search(len(j.validRevisions), func(i int) bool {
return j.validRevisions[i].id >= revid
Expand Down Expand Up @@ -148,30 +148,23 @@ func (j *journal) copy() *journal {
}
}

func (j *journal) AccessListAddAccount(addr common.Address) {
j.append(accessListAddAccountChange{&addr})
}

func (j *journal) AccessListAddSlot(addr common.Address, slot common.Hash) {
j.append(accessListAddSlotChange{
address: &addr,
slot: &slot,
})
}

func (j *journal) Log(txHash common.Hash) {
func (j *journal) logChange(txHash common.Hash) {
j.append(addLogChange{txhash: txHash})
}

func (j *journal) Create(addr common.Address) {
func (j *journal) createObject(addr common.Address) {
j.append(createObjectChange{account: &addr})
}

func (j *journal) Destruct(addr common.Address) {
func (j *journal) createContract(addr common.Address) {
j.append(createContractChange{account: addr})
}

func (j *journal) destruct(addr common.Address) {
j.append(selfDestructChange{account: &addr})
}

func (j *journal) SetStorage(addr common.Address, key, prev, origin common.Hash) {
func (j *journal) storageChange(addr common.Address, key, prev, origin common.Hash) {
j.append(storageChange{
account: &addr,
key: key,
Expand All @@ -180,37 +173,37 @@ func (j *journal) SetStorage(addr common.Address, key, prev, origin common.Hash)
})
}

func (j *journal) SetTransientState(addr common.Address, key, prev common.Hash) {
func (j *journal) transientStateChange(addr common.Address, key, prev common.Hash) {
j.append(transientStorageChange{
account: &addr,
key: key,
prevalue: prev,
})
}

func (j *journal) RefundChange(previous uint64) {
func (j *journal) refundChange(previous uint64) {
j.append(refundChange{prev: previous})
}

func (j *journal) BalanceChange(addr common.Address, previous *uint256.Int) {
func (j *journal) balanceChange(addr common.Address, previous *uint256.Int) {
j.append(balanceChange{
account: &addr,
prev: previous.Clone(),
})
}

func (j *journal) SetCode(address common.Address) {
func (j *journal) codeChange(address common.Address) {
j.append(codeChange{account: &address})
}

func (j *journal) NonceChange(address common.Address, prev uint64) {
func (j *journal) nonceChange(address common.Address, prev uint64) {
j.append(nonceChange{
account: &address,
prev: prev,
})
}

func (j *journal) Touch(address common.Address) {
func (j *journal) touchChange(address common.Address) {
j.append(touchChange{
account: &address,
})
Expand All @@ -221,6 +214,17 @@ func (j *journal) Touch(address common.Address) {
}
}

func (j *journal) accessListAddAccount(addr common.Address) {
j.append(accessListAddAccountChange{&addr})
}

func (j *journal) accessListAddSlot(addr common.Address, slot common.Hash) {
j.append(accessListAddSlotChange{
address: &addr,
slot: &slot,
})
}

type (
// Changes to the account trie.
createObjectChange struct {
Expand Down
10 changes: 5 additions & 5 deletions core/state/state_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func (s *stateObject) markSelfdestructed() {
}

func (s *stateObject) touch() {
s.db.journal.Touch(s.address)
s.db.journal.touchChange(s.address)
}

// getTrie returns the associated storage trie. The trie will be opened if it's
Expand Down Expand Up @@ -244,7 +244,7 @@ func (s *stateObject) SetState(key, value common.Hash) {
return
}
// New value is different, update and journal the change
s.db.journal.SetStorage(s.address, key, prev, origin)
s.db.journal.storageChange(s.address, key, prev, origin)
s.setState(key, value, origin)
if s.db.logger != nil && s.db.logger.OnStorageChange != nil {
s.db.logger.OnStorageChange(s.address, key, prev, value)
Expand Down Expand Up @@ -498,7 +498,7 @@ func (s *stateObject) SubBalance(amount *uint256.Int, reason tracing.BalanceChan
}

func (s *stateObject) SetBalance(amount *uint256.Int, reason tracing.BalanceChangeReason) {
s.db.journal.BalanceChange(s.address, s.data.Balance)
s.db.journal.balanceChange(s.address, s.data.Balance)
if s.db.logger != nil && s.db.logger.OnBalanceChange != nil {
s.db.logger.OnBalanceChange(s.address, s.Balance().ToBig(), amount.ToBig(), reason)
}
Expand Down Expand Up @@ -574,7 +574,7 @@ func (s *stateObject) CodeSize() int {
}

func (s *stateObject) SetCode(codeHash common.Hash, code []byte) {
s.db.journal.SetCode(s.address)
s.db.journal.codeChange(s.address)
if s.db.logger != nil && s.db.logger.OnCodeChange != nil {
// TODO remove prevcode from this callback
s.db.logger.OnCodeChange(s.address, common.BytesToHash(s.CodeHash()), nil, codeHash, code)
Expand All @@ -589,7 +589,7 @@ func (s *stateObject) setCode(codeHash common.Hash, code []byte) {
}

func (s *stateObject) SetNonce(nonce uint64) {
s.db.journal.NonceChange(s.address, s.data.Nonce)
s.db.journal.nonceChange(s.address, s.data.Nonce)
if s.db.logger != nil && s.db.logger.OnNonceChange != nil {
s.db.logger.OnNonceChange(s.address, s.data.Nonce, nonce)
}
Expand Down
26 changes: 13 additions & 13 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ func (s *StateDB) Error() error {
}

func (s *StateDB) AddLog(log *types.Log) {
s.journal.Log(s.thash)
s.journal.logChange(s.thash)

log.TxHash = s.thash
log.TxIndex = uint(s.txIndex)
Expand Down Expand Up @@ -293,14 +293,14 @@ func (s *StateDB) Preimages() map[common.Hash][]byte {

// AddRefund adds gas to the refund counter
func (s *StateDB) AddRefund(gas uint64) {
s.journal.RefundChange(s.refund)
s.journal.refundChange(s.refund)
s.refund += gas
}

// SubRefund removes gas from the refund counter.
// This method will panic if the refund counter goes below zero
func (s *StateDB) SubRefund(gas uint64) {
s.journal.RefundChange(s.refund)
s.journal.refundChange(s.refund)
if gas > s.refund {
panic(fmt.Sprintf("Refund counter below zero (gas: %d > refund: %d)", gas, s.refund))
}
Expand Down Expand Up @@ -508,7 +508,7 @@ func (s *StateDB) SelfDestruct(addr common.Address) {
// If it is already marked as self-destructed, we do not need to add it
// for journalling a second time.
if !stateObject.selfDestructed {
s.journal.Destruct(addr)
s.journal.destruct(addr)
stateObject.markSelfdestructed()
}
}
Expand All @@ -531,7 +531,7 @@ func (s *StateDB) SetTransientState(addr common.Address, key, value common.Hash)
if prev == value {
return
}
s.journal.SetTransientState(addr, key, prev)
s.journal.transientStateChange(addr, key, prev)
s.setTransientState(addr, key, value)
}

Expand Down Expand Up @@ -650,7 +650,7 @@ func (s *StateDB) getOrNewStateObject(addr common.Address) *stateObject {
// existing account with the given address, otherwise it will be silently overwritten.
func (s *StateDB) createObject(addr common.Address) *stateObject {
obj := newObject(s, addr, nil)
s.journal.Create(addr)
s.journal.createObject(addr)
s.setStateObject(obj)
return obj
}
Expand All @@ -672,7 +672,7 @@ func (s *StateDB) CreateContract(addr common.Address) {
obj := s.getStateObject(addr)
if !obj.newContract {
obj.newContract = true
s.journal.append(createContractChange{account: addr})
s.journal.createContract(addr)
}
}

Expand Down Expand Up @@ -741,12 +741,12 @@ func (s *StateDB) Copy() *StateDB {

// Snapshot returns an identifier for the current revision of the state.
func (s *StateDB) Snapshot() int {
return s.journal.Snapshot()
return s.journal.snapshot()
}

// RevertToSnapshot reverts all state changes made since the given revision.
func (s *StateDB) RevertToSnapshot(revid int) {
s.journal.RevertToSnapshot(revid, s)
s.journal.revertToSnapshot(revid, s)
}

// GetRefund returns the current value of the refund counter.
Expand Down Expand Up @@ -960,7 +960,7 @@ func (s *StateDB) SetTxContext(thash common.Hash, ti int) {
}

func (s *StateDB) clearJournalAndRefund() {
s.journal.Reset()
s.journal.reset()
s.refund = 0
}

Expand Down Expand Up @@ -1387,7 +1387,7 @@ 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.AddAddress(addr) {
s.journal.AccessListAddAccount(addr)
s.journal.accessListAddAccount(addr)
}
}

Expand All @@ -1399,10 +1399,10 @@ func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) {
// scope of 'address' without having the 'address' become already added
// to the access list (via call-variant, create, etc).
// Better safe than sorry, though
s.journal.AccessListAddAccount(addr)
s.journal.accessListAddAccount(addr)
}
if slotMod {
s.journal.AccessListAddSlot(addr, slot)
s.journal.accessListAddSlot(addr, slot)
}
}

Expand Down