fix(execute): derive the EOA start key instead of randomising it - #3504
fix(execute): derive the EOA start key instead of randomising it#3504jochem-brouwer wants to merge 1 commit into
Conversation
`--eoa-start` defaulted to `randint(0, 2**256)`, so every run handed `pre.fund_eoa()` a different set of addresses and nothing in the configuration could pin them. `fill-stateful` loads this plugin too, which makes a filled prestate unreproducible: two builds from one snapshot agree until the first test EOA appears and diverge on every block after it. Measured on snapshot 24,402,727, two 7,736-payload builds shared blocks 24,402,728 and 24,402,729 -- neither uses a test EOA -- then split at 24,402,730 on transactions identical in length, nonce, gas price, gas limit and value, differing only in recipient. A prestate can therefore only be shipped as a datadir or a replay bundle, and fixtures record `snapshotBlockHash`, so a suite filled against one build is rejected against an equivalent rebuild of it. Derive the default instead. Two properties the randomness did provide have to survive being pinned, so both go into the derivation: - xdist workers. Each worker process evaluates the option default for itself, so a random one gave every worker a range of its own. Nothing else offsets them and `session_worker_key` takes the first key from this iterator, so a bare constant would have every worker funding and spending one account. - concurrent runs against a shared network. Two runs sharing a range would race each other's nonces. The seed key already has to belong to a single command, so it separates runs whenever one is set, by flag or by RPC_SEED_KEY. `keccak256(b"eoa-start:<worker>[:<seed key>]") >> 8` gives 248 bits: never the invalid key zero, and far enough below the secp256k1 group order that counting upwards from it stays valid for any run length. An explicit `--eoa-start` still wins, which is what reproduces a run made before this change. Two fill-stateful sessions with RPC_SEED_KEY=0x..01 now both report 0x4f4b0f0b0af2385d3ff86ac2ba5d9e2529cd9bc5415aefce34b9f848e9e66f, and 0x..02 reports a different one.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## forks/amsterdam #3504 +/- ##
================================================
Coverage 93.90% 93.90%
================================================
Files 624 624
Lines 36905 36905
Branches 3326 3326
================================================
Hits 34655 34655
Misses 1569 1569
Partials 681 681
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Hi! I've been meaning to do something like this for a long time, but with a different purpose: In I think the only conflict with this approach and the other goal we have is that if the test ends up being assigned to a different worker, the setup will no longer be valid. I want to suggest using |
--eoa-startdefaulted torandint(0, 2**256), so every run handedpre.fund_eoa()a different set of addresses and nothing in the configuration could pin them.fill-statefulloads this plugin too, which makes a filled prestate unreproducible: two builds from one snapshot agree until the first test EOA appears and diverge on every block after it. Measured on snapshot 24,402,727, two 7,736-payload builds shared blocks 24,402,728 and 24,402,729 -- neither uses a test EOA -- then split at 24,402,730 on transactions identical in length, nonce, gas price, gas limit and value, differing only in recipient. A prestate can therefore only be shipped as a datadir or a replay bundle, and fixtures recordsnapshotBlockHash, so a suite filled against one build is rejected against an equivalent rebuild of it.Derive the default instead. Two properties the randomness did provide have to survive being pinned, so both go into the derivation:
session_worker_keytakes the first key from this iterator, so a bare constant would have every worker funding and spending one account.keccak256(b"eoa-start:<worker>[:<seed key>]") >> 8gives 248 bits: never the invalid key zero, and far enough below the secp256k1 group order that counting upwards from it stays valid for any run length. An explicit--eoa-startstill wins, which is what reproduces a run made before this change.Two fill-stateful sessions with RPC_SEED_KEY=0x..01 now both report 0x4f4b0f0b0af2385d3ff86ac2ba5d9e2529cd9bc5415aefce34b9f848e9e66f, and 0x..02 reports a different one.
Description
Related Issues or PRs
N/A.
Checklist
just static<type>(<area>): <title>, where<type>and<area>come from an appropriateC-<type>, respectivelyA-<area>, label. The title should match the target squash commit message.Cute Animal Picture