Open mds1 opened 2 months ago
I looked a bit into this, trying to find a way to detect support for EIP-1559 and EIP-4844 txs.
My first attempt was to just make an eth_call
with maxFeePerGas
and maxPriorityFeePerGas
fields, but this doesn't work: if a property is unknown, it seems to just be ignored, at least by most nodes.
What I ended up doing is sending an eth_call
that executes this bytecode:
GASPRICE
PUSH1 0x00
MSTORE
PUSH1 0x20
PUSH1 0x00
RETURN
which returns the gas price. If you send a call with that input data and a gas price of 0x1234567890, then the return data is 1234567890. But if you send a call with both maxFeePerGas
and maxPriorityFeePerGas
of 0x1234567890, you won't get that expected value.
Now, there are two things that make this a bit harder to use in practice:
from
address with some balance to make it work. This means that the test cases should have addressses that have enough balance and are unlikely to reduce that balance. At the moment of writing this, the zero address only has 0.077 ETH, but that coupled with a lower gas price could be enough.For this, I think it's enough to make an eth_call
with {blobs: ["0x"], blobVersionedHashes: ["0x"]}
. Both mainnet and optimism fail with this message: invalid argument 0: hex string has length 0, want 262144 for kzg4844.Blob
.
But Arbitrum doesn't fail. Maybe this is just because they don't support EIP-4844 txs, but I'm not sure that's the case because the BLOBBASEFEE
opcode is supported (at least according to evmdiff.com 😛)
The three mainnet transaction types not currently covered are pre-EIP155 legacy txs, post-EIP155 legacy txs and access list txs. The latter might be done with estimateGas and a clever use of the access list. But I'm not sure if there's a way to detect that EIP-155 is supported without actually sending a tx.
Access lists are even easier than I thought: just use estimateGas
with a plain call with and without an access list entry, and they will return different results, because access list entries have an extra cost.
This is great, thank you!
Could an alternative here be to use eth_estimateGas
with maxFeePerGas
and maxPriorityFeePerGas
fields? It feels likely nodes will also ignore them here like they do with eth_call
though
But if you send a call with both
maxFeePerGas
andmaxPriorityFeePerGas
of 0x1234567890, you won't get that expected value.
What do you get instead? I also wonder how this will behave on arbitrum where 1559 is a bit different, as explained here: https://github.com/mds1/evm-diff/pull/60#issuecomment-1926794404
Now, there are two things that make this a bit harder to use in practice:
We could fetch the base fee beforehand and bump it by e.g. 50% if we want to avoid hardcoding a really big value. But hardcoding something huge is probably just as good and simpler.
I've been wondering if most or all nodes support state overrides, which would be a way we can work around the insufficient balance issue
Both Optimism and Arbitrum don't support blobs being posted to L2, see here for optimism and here for arbitrum. I wonder if we could also use eth_estimateGas
here?
For access lists, can we rely on eth_createAccessList
? It seems this is not required by EIP-2930 though, so perhaps not, and I think your idea is probably preferable
Could an alternative here be to use eth_estimateGas with maxFeePerGas and maxPriorityFeePerGas fields?
How that would work? The gas price shouldn't affect the gas estimate in almost all cases.
What do you get instead?
You get the default gas price. Whatever that is, it's unlikely to be 0x1234567890
(or whatever number like that we use).
How that would work? The gas price shouldn't affect the gas estimate in almost all cases.
I was thinking it would error if you try estimating gas with unsupported fields, but I have not yet tested if that's the case or if they get ignored like with eth_call
You get the default gas price. Whatever that is, it's unlikely to be
0x1234567890
(or whatever number like that we use).
Ah I see, that does make sense
These were removed as part of #62 and should be added back. I'm not sure if there is a good way to automatically detect transaction types, so we may need to instead define a set of known transaction types, along with the test data for each (e.g. an RPC method name + associated input data)