From 9d75a251b03dfa556a3741de7e3769b1ccf8cd70 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 05cda56658..3a91a50105 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -163,7 +163,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.