-
Notifications
You must be signed in to change notification settings - Fork 206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ensure pending state is ready for tx execution #1858
Conversation
Coverage from tests in coverage: 51.9% of statements across all listed packagescoverage: 65.4% of statements in consensus/istanbul coverage: 43.1% of statements in consensus/istanbul/announce coverage: 55.9% of statements in consensus/istanbul/backend coverage: 0.0% of statements in consensus/istanbul/backend/backendtest coverage: 24.3% of statements in consensus/istanbul/backend/internal/replica coverage: 71.0% of statements in consensus/istanbul/core coverage: 50.0% of statements in consensus/istanbul/db coverage: 0.0% of statements in consensus/istanbul/proxy coverage: 75.3% of statements in consensus/istanbul/uptime coverage: 100.0% of statements in consensus/istanbul/uptime/store coverage: 51.8% of statements in consensus/istanbul/validator coverage: 79.2% of statements in consensus/istanbul/validator/randomCommentID: cc27fd229a |
Nice detective work so far! I don't think calling
I'm guessing that the key in this actually the following line:
Or possibly the call to
Both of these mutate the state DB, and the first of the two modifies the header as well. |
Thank you @nategraf. I decided to look at the TraceBlock api, because trace block is tracing each tx in the block and has to prepare some intermediate state for each tx such that the tx traces correctly. And that is I think what we need to achieve here. Below is the code block that prepares a state for tracing a tx. celo-blockchain/eth/tracers/api.go Lines 561 to 576 in 6ad68f2
There seem to be 2 things that are done to the state in preparation for tracing.
The prepare implementation is below, and we can see that it creates an
So if celo-blockchain/core/state/statedb.go Lines 884 to 888 in 6ad68f2
The
Based on that it would seem that failing to call celo-blockchain/core/state/statedb.go Lines 775 to 819 in 6ad68f2
Looking into the miner code that manages the pending block I can see that both |
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.
94bdc9f
to
fefe91b
Compare
Codecov Report
@@ Coverage Diff @@
## master #1858 +/- ##
=======================================
Coverage 54.23% 54.23%
=======================================
Files 673 673
Lines 88991 88993 +2
=======================================
+ Hits 48262 48268 +6
+ Misses 37090 37077 -13
- Partials 3639 3648 +9
Continue to review full report at Codecov.
|
* 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
* Ensure pending state is ready for tx execution (#1858) * 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 * set version to 1.5.4-stable Co-authored-by: piersy <[email protected]>
* 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
Fixes #1856
Before introducing this change gas estimations against the pending block on non validating nodes with the espresso fork enabled would sometimes be lower than they should be.
What this PR does is better described here
Its still not clear to me exactly how the lower gas estimates were being calculated but ensuring that the pending block is finalized and assembled seems to resolve this. Validating nodes were already finalizing and assembling their pending blocks and looking back it seems that prior to #1545 the pending block was always finalized and assembled (see permalink below). So this seems like this change is correcting a long running problem.celo-blockchain/miner/worker.go
Line 969 in ab78658
This change also changes the behaviour of the debug tracing apis when used run against the pending block.Since #1545 caused the pending block to not be finalized, the state root in the pending block was zero. Strangely, looking up the zero root in the state trie doesn't fail but the state returned is essentially empty, meaning that all transactions would be traced as a simple send ( because that is how a contract transaction executes if the contract does not exist).With this change, calls to the tracing apis with the pending block will return the errorrequired historical state unavailable
.This is because the pending block will have been finalized and will therefore have a state root, and the tracing apis first look up the block and then try to get the state for it usingEthereum.StateAtBlock
which doesn't take into account the pending state and therefore the state cannot be found.Tested
I have verified that the tests linked in #1856 produce reliable gas estimates running against a local node connected to a 1 validator network run with mycelo and also on a fullnode deployed in alfajores.
Backwards compatibility
The results of the rpc apis are chainging.