Skip to content
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

[Bug] Signers apply EIP-155 even for EIP-{1559,2718} transactions #144

Closed
cgst opened this issue Jan 23, 2024 · 4 comments · Fixed by #150
Closed

[Bug] Signers apply EIP-155 even for EIP-{1559,2718} transactions #144

cgst opened this issue Jan 23, 2024 · 4 comments · Fixed by #150
Labels
bug Something isn't working

Comments

@cgst
Copy link
Contributor

cgst commented Jan 23, 2024

Component

signers

What version of Alloy are you on?

No response

Operating System

None

Describe the bug

Signers::sign_transaction and SignerSync::sign_transaction_sync should not apply EIP-155 when the signer's chain_id is None. Indeed, this is the expected behavior according to Signer's docstring, but EIP-155 is applied anyway if the chain ID is found on the transaction instead.

Ref:

if let Some(chain_id) = chain_id.or_else(|| tx.chain_id()) {

EIP-{1559,2718} always embed a chain ID value but they're not compatible with EIP-155. Thus, they get an EIP-155 signature when they shouldn't.

@cgst cgst added the bug Something isn't working label Jan 23, 2024
@cgst
Copy link
Contributor Author

cgst commented Jan 23, 2024

I can send a PR for a direct fix if useful, but this comment made me think that there are more changes coming that might preempt a direct fix.

@prestwich
Copy link
Member

the "correct" fix here is to change the Transaction::into_signed implementation to ensure that the signature parity is in the correct format when instantiating a Signed<T>

@cgst
Copy link
Contributor Author

cgst commented Jan 23, 2024

the "correct" fix here is to change the Transaction::into_signed implementation to ensure that the signature parity is in the correct format when instantiating a Signed<T>

🤔 Transaction::into_signed takes a Signature, so EIP-155 will have already been applied by that time. Are you saying we should "undo" the EIP-155 application?

I'm not 100% sure, but from looking at the code, if s is a y-parity Signature, then s.with_chain_id(...).to_parity_bool() != s, i.e., the roundtrip won't preserve the y-parity value. I'm not a cryptographer though, so maybe there's an easy way to do it.

Perhaps we should avoid applying EIP-155 in the first place. For example, the Transaction trait could indicate compatibility with EIP-155, so the signer has all the information it needs to decide what signature is required.

@prestwich
Copy link
Member

Transaction::into_signed takes a Signature, so EIP-155 will have already been applied by that time. Are you saying we should "undo" the EIP-155 application?

I'm saying that the txn should ensure the signature is in the format that it accepts at the time it is joined with the siganture.
The problem is that a signature may come from any source with or without eip155 applied. We can guarantee correct format at the time of combination, but not necessarily at any other time.

I'm not 100% sure, but from looking at the code, if s is a y-parity Signature, then s.with_chain_id(...).to_parity_bool() != s, i.e., the roundtrip won't preserve the y-parity value. I'm not a cryptographer though, so maybe there's an easy way to do it.

That's a bug, thanks. fixed in 497

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants