core/state: fixes for issues found during fuzzing

This commit is contained in:
Martin Holst Swende 2024-11-23 20:12:56 +01:00
parent 81d666859d
commit 95b29b69e9
No known key found for this signature in database
GPG Key ID: 683B438C05A5DDF0
2 changed files with 20 additions and 2 deletions

View File

@ -65,6 +65,7 @@ func (j *linearJournal) reset() {
j.entries = j.entries[:0] j.entries = j.entries[:0]
j.revisions = j.revisions[:0] j.revisions = j.revisions[:0]
clear(j.dirties) clear(j.dirties)
j.snapshot()
} }
func (j linearJournal) dirtyAccounts() []common.Address { func (j linearJournal) dirtyAccounts() []common.Address {
@ -84,10 +85,17 @@ func (j *linearJournal) snapshot() {
// revertSnapshot reverts all state changes made since the last call to snapshot(). // revertSnapshot reverts all state changes made since the last call to snapshot().
func (j *linearJournal) revertSnapshot(s *StateDB) { func (j *linearJournal) revertSnapshot(s *StateDB) {
id := len(j.revisions) - 1 id := len(j.revisions) - 1
if id < 0 {
j.snapshot()
return
}
revision := j.revisions[id] revision := j.revisions[id]
// Replay the linearJournal to undo changes and remove invalidated snapshots // Replay the linearJournal to undo changes and remove invalidated snapshots
j.revertTo(s, revision) j.revertTo(s, revision)
j.revisions = j.revisions[:id] j.revisions = j.revisions[:id]
if id == 0 {
j.snapshot()
}
} }
// discardSnapshot removes the latest snapshot; after calling this // discardSnapshot removes the latest snapshot; after calling this
@ -95,7 +103,7 @@ func (j *linearJournal) revertSnapshot(s *StateDB) {
// changes are considered part of the parent scope. // changes are considered part of the parent scope.
func (j *linearJournal) discardSnapshot() { func (j *linearJournal) discardSnapshot() {
id := len(j.revisions) - 1 id := len(j.revisions) - 1
if id == 0 { if id <= 0 {
// If a transaction is applied successfully, the statedb.Finalize will // If a transaction is applied successfully, the statedb.Finalize will
// end by clearing and resetting the journal. Invoking a discardSnapshot // end by clearing and resetting the journal. Invoking a discardSnapshot
// afterwards will land here: calling discard on an empty journal. // afterwards will land here: calling discard on an empty journal.
@ -312,6 +320,11 @@ func (ch createContractChange) revert(s *StateDB) {
} }
func (ch createContractChange) dirtied() *common.Address { 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 return nil
} }

View File

@ -334,12 +334,14 @@ func newSparseJournal() *sparseJournal {
// slices can be reused // slices can be reused
func (j *sparseJournal) reset() { func (j *sparseJournal) reset() {
j.entries = j.entries[:0] j.entries = j.entries[:0]
j.ripeMagic = false
j.snapshot() j.snapshot()
} }
func (j *sparseJournal) copy() journal { func (j *sparseJournal) copy() journal {
cp := &sparseJournal{ cp := &sparseJournal{
entries: make([]*scopedJournal, 0, len(j.entries)), entries: make([]*scopedJournal, 0, len(j.entries)),
ripeMagic: j.ripeMagic,
} }
for _, entry := range j.entries { for _, entry := range j.entries {
cp.entries = append(cp.entries, entry.deepCopy()) cp.entries = append(cp.entries, entry.deepCopy())
@ -360,6 +362,9 @@ func (j *sparseJournal) revertSnapshot(s *StateDB) {
id := len(j.entries) - 1 id := len(j.entries) - 1
j.entries[id].revert(s) j.entries[id].revert(s)
j.entries = j.entries[:id] j.entries = j.entries[:id]
if id == 0 {
j.snapshot()
}
} }
// discardSnapshot removes the latest snapshot; after calling this // discardSnapshot removes the latest snapshot; after calling this