Skip to content

Commit

Permalink
Ensure pending state is ready for tx execution (celo-org#1858)
Browse files Browse the repository at this point in the history
* Enusre pending state is ready for tx execution

This commit ensures that StateDB.Prepare is called on the pending state
before it is returned from the miner/worker. This prevents access logs
from previous transaction executions from interfering with the gas cost
calculations of the subsequently executed transaction.

The problem this solves was introdued by this upstream PR
ethereum/go-ethereum#21509 which added an
access list to the state which was used to reduce gas costs for repeated
access of the same state locations, this resulted in the pending block
having the access list of the last executed transaction, which could
cause gas estimates to be wrong when the estimated transaction accessed
some of the same state as the prior transaction.

* Add more in depth comment on call to Prepare
  • Loading branch information
shinhagunn committed Jan 25, 2022
1 parent 503f156 commit 93e6c02
Showing 1 changed file with 18 additions and 1 deletion.
19 changes: 18 additions & 1 deletion miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,24 @@ func (w *worker) pending() (*types.Block, *state.StateDB) {
if w.snapshotState == nil {
return nil, nil
}
return w.snapshotBlock, w.snapshotState.Copy()
stateCopy := w.snapshotState.Copy()
// Call Prepare to ensure that any access logs from the last executed
// transaction have been erased.
//
// Prior to the upstream PR
// https://github.com/ethereum/go-ethereum/pull/21509 the state returned
// from pending was ready to use for transaction execution, that PR
// essentially changed the contract of the pendng method, in that the
// returned state was not ready for transaction execution and required
// Prepare to be called on it first, but notably the PR did not update any
// of the callers of pending to ensure that Prepare was called. I think
// this broke some of the eth rpc apis. Calling Prepare here essentially
// restores the previous contract for this method which was that the
// returned state is ready to use for transaction execution.
//
// See https://github.com/celo-org/celo-blockchain/pull/1858#issuecomment-1054159493 for more details.
stateCopy.Prepare(common.Hash{}, 0)
return w.snapshotBlock, stateCopy
}

// pendingBlock returns pending block.
Expand Down

0 comments on commit 93e6c02

Please sign in to comment.