foundry
foundry copied to clipboard
anvil/eth: Use the raw `v` signature value instead of `bool`
Fixes https://github.com/foundry-rs/foundry/issues/7898
Motivation
Cf. the linked issue. The v
value (which should be deprecated for some tx types) was wrongly set as the y parity byte converted into a uint.
Solution
Instead of converting the boolean corresponding to the y parity byte to a u64/U256, use the raw v
value for the v
field when available.
I added a 2nd commit that fixes invalid (from geth's PoV) dummy signatures. The issue was that it was using v == 0
, while this snippet in geth'd code: https://github.com/ethereum/go-ethereum/blob/d2f00cb54edc4486314c25d9e6c5b739009c2201/core/types/transaction.go#L234-L238 was computing plainV = byte(v.Uint64() - 27)
which made it invalid.
By using Parity::NonEip155(false)
, v
is actually encoded as 27
instead of 0
, which makes the validation pass.
OK and one last commit, to actually use the provided signature when creating a transaction. This resolves an issue where the computed transaction hash in anvil
(computed once, reused everywhere afterward) wouldn't match a computed hash from the transactions' details (eg. from a eth_getBlock
call). In geth's Go library, a transaction hash is (almost) never parsed from the RPC response, but recomputed. This caused mismatches and all kinds of troubles.
This is a bit tangential to the initial issue, so I could if needed open another PR for it.
I think the failing tests are related
I think the failing tests are related
~You mean unrelated? The only failing ones are integration tests which pass after retry.~ My bad, I thought they were retried twice, but it seems the tests are just split in 3. I'll look into it.
OK, I found the issue! So TIL, for all transactions that are not legacy, the v
value for the signature should actually just be the parity byte (so 0
or 1
). This means that the impersonate signature cannot be constant, but depends on the transaction type. I removed some code (2nd commit) that did seem really relevant, and simplified things so that the impersonate signature is creating within the api.rs
file, dependent on the transaction type.
To see the issue, cf. the signature change in the failing test. The previous signature wasn't actually valid. This can be checked here, for example: https://toolkit.abdk.consulting/ethereum#rlp,transaction (the v value was set to 62710
while it was an EIP-1559 tx).