Skip to content

Commit

Permalink
core/state: fixes for issues found during fuzzing
Browse files Browse the repository at this point in the history
  • Loading branch information
holiman committed Nov 24, 2024
1 parent 474e2be commit fa13bd6
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 3 deletions.
19 changes: 17 additions & 2 deletions core/state/journal_linear.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ var _ journal = (*linearJournal)(nil)

// newLinearJournal creates a new initialized linearJournal.
func newLinearJournal() *linearJournal {
return &linearJournal{
s := &linearJournal{
dirties: make(map[common.Address]int),
}
s.snapshot() // create snaphot zero
return s
}

// reset clears the journal, after this operation the journal can be used anew.
Expand All @@ -65,6 +67,7 @@ func (j *linearJournal) reset() {
j.entries = j.entries[:0]
j.revisions = j.revisions[:0]
clear(j.dirties)
j.snapshot()
}

func (j linearJournal) dirtyAccounts() []common.Address {
Expand All @@ -84,18 +87,25 @@ func (j *linearJournal) snapshot() {
// revertSnapshot reverts all state changes made since the last call to snapshot().
func (j *linearJournal) revertSnapshot(s *StateDB) {
id := len(j.revisions) - 1
if id < 0 {
j.snapshot()
return
}
revision := j.revisions[id]
// Replay the linearJournal to undo changes and remove invalidated snapshots
j.revertTo(s, revision)
j.revisions = j.revisions[:id]
if id == 0 {
j.snapshot()
}
}

// discardSnapshot removes the latest snapshot; after calling this
// method, it is no longer possible to revert to that particular snapshot, the
// changes are considered part of the parent scope.
func (j *linearJournal) discardSnapshot() {
id := len(j.revisions) - 1
if id == 0 {
if id <= 0 {
// If a transaction is applied successfully, the statedb.Finalize will
// end by clearing and resetting the journal. Invoking a discardSnapshot
// afterwards will land here: calling discard on an empty journal.
Expand Down Expand Up @@ -312,6 +322,11 @@ func (ch createContractChange) revert(s *StateDB) {
}

func (ch createContractChange) dirtied() *common.Address {
// This method returns nil, since the transformation from non-contract to
// contract is not an operation which has an effect on the trie:
// it does not make the account part of the dirty-set.
// Creating the account (createObject) or setting the code (setCode)
// however, do, and are.
return nil
}

Expand Down
7 changes: 6 additions & 1 deletion core/state/journal_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,12 +334,14 @@ func newSparseJournal() *sparseJournal {
// slices can be reused
func (j *sparseJournal) reset() {
j.entries = j.entries[:0]
j.ripeMagic = false
j.snapshot()
}

func (j *sparseJournal) copy() journal {
cp := &sparseJournal{
entries: make([]*scopedJournal, 0, len(j.entries)),
entries: make([]*scopedJournal, 0, len(j.entries)),
ripeMagic: j.ripeMagic,
}
for _, entry := range j.entries {
cp.entries = append(cp.entries, entry.deepCopy())
Expand All @@ -360,6 +362,9 @@ func (j *sparseJournal) revertSnapshot(s *StateDB) {
id := len(j.entries) - 1
j.entries[id].revert(s)
j.entries = j.entries[:id]
if id == 0 {
j.snapshot()
}
}

// discardSnapshot removes the latest snapshot; after calling this
Expand Down

0 comments on commit fa13bd6

Please sign in to comment.