Skip to content

Commit

Permalink
execute eth_estimateGas and eth_createAccessList on latest block (#…
Browse files Browse the repository at this point in the history
…3220)

# Description
For a while we had mysteriously failing transactions. What I mean is
that we execute `eth_estimateGas` to see if a transaction would still
work. If it fails we log all the data needed to re-simulate it on
tenderly. But when you then actually re-simulate on tenderly the
transaction would work.

The solution unravels with this
[issue](tomusdrw/rust-web3#290).
The spec for `eth_estimateGas` mentions 2 arguments: the tx and an
identifier for a block. The block is supposed to be optional but geth
had a bug for a very long time. When you don't pass a block argument it
should be sent over the wire as `null`. But geth tried to deserialize
`null` which then caused these calls to fail.

As a workaround the `web3` crate stopped serializing the block tag if it
was `None`. Eventually geth fixed this issue and implemented it such
that a missing block tag would default to `pending`.
Also a rule of thumb in node development is "if in doubt do whatever
geth does" so reth also implemented the default to `pending`.

Defaulting to `pending` is what can make these reverts unpredictable.
When you simulate the tx on `pending` the node takes the state of the
`latest` block PLUS transactions that it currently has in its mempool.
So whenever we log a reverting tx that works on tenderly it only failed
in our node because some tx in the nodes mempool interfered with the
solution.
Interestingly there also a lot of cases where you can even simulate the
tx on the next block. In those cases simulating on `pending` caused the
driver completely erroneously since the problematic tx didn't even make
it into the next block.

<details>
<summary>example</summary>


[log](https://aws-es.cow.fi/_dashboards/app/discover#/doc/86e4a5a0-4e4b-11ef-85c5-3946a99ed1a7/cowlogs-prod-2025.01.06?id=1F1ROpQBOTpjfSxxfB9z)
```
2025-01-06T06:33:25.748Z  INFO request{id="4114843"}:/solve{solver=extzeroex-solve auction_id=9990122}: driver::infra::observe: discarded solution: settlement encoding id=Id { id: 17739308, merged_solutions: [22] } err=Simulation(Revert(RevertError { err: Blockchain(AccessList(String("execution reverted"))), tx: Tx { from: Address(0x28b1bd44996105b5c14c4de41093226ff78a4eb1), to: Address(0x9008d19f58aabd9ed0d60971565aa8510560ab41), value: Ether(0), input: 0x13d79a0b0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000003e00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000839d4a05d6d23a22365bd90c2114c199d53e674c000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000839d4a05d6d23a22365bd90c2114c199d53e674c000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000017c836d081141b7000000000000000000000000000000000000000000000034cafbfac2c90f727a000000000000000000000000000000000000000000000000017c836d081141b700000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000006a7fe93d1e194d31b8076c255779c4b12a45192c00000000000000000000000000000000000000000000003635c9adc5dea00000000000000000000000000000000000000000000000000000010df3f85654f86700000000000000000000000000000000000000000000000000000000677b7e7d5b203ebd4ff6f6667daa775bd3de4410b0b834f059fccecd85660cb72bf031e30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003635c9adc5dea00000000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000410fd3b1f82fc78a190ccf38bbfa08652ca518ef025802fe671c0b7e1b8cc1c8e762470c92b313dd597fde1022168575929770076f30cc6581377d174f76ce675e1c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000300000000000000000000000000839d4a05d6d23a22365bd90c2114c199d53e674c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044095ea7b3000000000000000000000000def1c0ded9bec7f1a1670819833240f027b25eff00000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000000000000000000000000000def1c0ded9bec7f1a1670819833240f027b25eff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000128d9627aa4000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000003635c9adc5dea000000000000000000000000000000000000000000000000000000186565d4040733b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000839d4a05d6d23a22365bd90c2114c199d53e674c000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2869584cd0000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab410000000000000000000000000000000000000000b507dba868e8950578d34d3f000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000242e1a7d4d000000000000000000000000000000000000000000000000017c836d081141b70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000986fea, access_list: AccessList({}) }, block: BlockNo(21563660) }))
```

Results in this
[simulation](https://dashboard.tenderly.co/cow-protocol/staging/simulator/0b89b4d0-418f-40e3-8502-59c85e4da885)
that even works 2 blocks past the block we logged.
</details>

# Changes
Always estimate gas and create access lists on the `latest` block
instead of `pending`.
This should be the better default for 2 reasons:
1. it makes our simulation reverts consistent with what we see on
tenderly
2. most blocks get built by sophisticated algorithms including and
arranging blocks in a way that maximizes MEV. That means whatever
transactions ordering the node applies in the `pending` likely isn't
accurate anyway.
  • Loading branch information
MartinquaXD authored Jan 8, 2025
1 parent 2f54635 commit 672b30f
Showing 1 changed file with 5 additions and 2 deletions.
7 changes: 5 additions & 2 deletions crates/driver/src/infra/blockchain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,10 @@ impl Ethereum {
.transport()
.execute(
"eth_createAccessList",
vec![serde_json::to_value(&tx).unwrap()],
vec![
serde_json::to_value(&tx).unwrap(),
serde_json::Value::String("latest".into()),
],
)
.await?;
if let Some(err) = json.get("error") {
Expand All @@ -207,7 +210,7 @@ impl Ethereum {
gas_price: self.simulation_gas_price().await,
..Default::default()
},
None,
Some(ethcontract::BlockNumber::Latest),
)
.await
.map(Into::into)
Expand Down

0 comments on commit 672b30f

Please sign in to comment.