From ebb3e7ce4ab52938b3fa4098e0563a5a022c665f Mon Sep 17 00:00:00 2001 From: Piers Powlesland Date: Mon, 28 Feb 2022 11:51:53 +0000 Subject: [PATCH] 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 https://github.com/ethereum/go-ethereum/pull/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. --- miner/worker.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/miner/worker.go b/miner/worker.go index aebad34b9b..45e8203b10 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -168,7 +168,12 @@ 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. + // See https://github.com/celo-org/celo-blockchain/pull/1858#issuecomment-1054159493 + stateCopy.Prepare(common.Hash{}, 0) + return w.snapshotBlock, stateCopy } // pendingBlock returns pending block.