-
Notifications
You must be signed in to change notification settings - Fork 772
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
Util: Allow v
to be 0
or 1
for EIP1559 transactions
#1905
Conversation
Ah, just seeing that you already opened a PR on this. So for context (sorry, this is likely not obvious, we likely want to better document): we are doing work on the current version of the packages towards Let's anyhow continue here with discussing the things I raised in the issue, this would be the first step here. |
Codecov Report
Flags with carried forward coverage won't be shown. Click here to find out more. |
a59b51d
to
f57dd58
Compare
Thanks for context, I changed the target branch to master and rebased accordingly. I replied about the details on the issue, just right here |
4953c7b
to
8168d3f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, reasoning and justification see separate comment, will merge.
@@ -46,6 +46,9 @@ export function ecsign(msgHash: Buffer, privateKey: Buffer, chainId: any): any { | |||
|
|||
function calculateSigRecovery(v: BNLike, chainId?: BNLike): BN { | |||
const vBN = toType(v, TypeOutput.BN) | |||
|
|||
if (vBN.eqn(0) || vBN.eqn(1)) return toType(v, TypeOutput.BN) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, this is the central line of this PR (this is just an additional transparency explanation for everyone to follow including the team). So this allows v
to directly pass through if 0
or 1
. The chainId
parameter is ignored in this case.
The function here is not exported. Effects are indirect, to all methods below this comment where additional NOTE:
line comments are added. I've checked all the methods and do not see security or other implications or side effects.
Namely:
ecrecover
: This will then allow with this update to directly pass in an EIP-1559 (or any other typed) tx with v being0
or1
and will recover the correct PK in these cases as well. No side effects on other (legacy) txs.toRpcSig
: Now allows EIP-1559 txs to be converted ineth_sign
format, no side effectstoCompactSig
: Now allows EIP-1559 txs to be converted ineth_sign
format, no side effects (was first a bit unsure about the0
case but this is included as well respectively not affected)isValidSignature
: Now allows EIP-1559 txs to be converted ineth_sign
format, no side effects
So I would give this a go and merge this and would include in the very imminent last round of master
releases before we merge in develop
.
We can then continue on develop
with do some further signature code cleanup - with some inspiration from the breaking-release-TODOs - in favor of a complete direct removal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I think I just realized a cleaner method of fixing the precompiles than doing this guard in the precompiles. What if we throw here if v = 0
or v = 1
and a chainId
is provided? If you would now pass in a chainId
and v = 1
or v = 0
then ecrecover
will not throw, while it would throw before (since this signature recovery method returns a negative value in that case).
EDIT nvm this will not fix the precompiles. (But it might be cleaner to throw here if chainId is provided and v is 0 or 1?)
Oh, respectively tests are failing, then we have to figure out before. This is likely related to the merge of #1900, @jochem-brouwer do you have an idea what happens? 🤔 |
Hi @holgerd77, I don't think it is related to #1900 since ecrecover tests are failing. I'll take a look now 😄 |
Ah, interesting, I thought tests would have been passed before here, but also not 100% sure. |
There are errors in blockchain tests;
These all have to do with the Take a look at where
The input to these tests have
In this PR, I don't see a clean way how to fix this, it would need an extra argument to |
Actually, we could also do these |
Tx tests will fail, we should figure out why this |
I am on it. |
packages/tx/src/legacyTransaction.ts
Outdated
throw new Error(`Non-EIP155 txs need either v = 27 or v = 28, got v = ${this.v}`) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't tie this to "after the _validateTxV() analysis" but rather do before respectively directly in the method, think this will get more robust (less ocassion for the analysis to go wrong).
Will try this and update the tests.
…55 determination logic
@jochem-brouwer ok, I would have a tendency to give this a go, but I would wait for your final confirmation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One question, otherwise LGTM.
@@ -416,7 +412,7 @@ tape('[Transaction]', function (t) { | |||
st.notEqual(signedWithEIP155.v?.toString('hex'), '1c') | |||
st.notEqual(signedWithEIP155.v?.toString('hex'), '1b') | |||
|
|||
let signedWithoutEIP155 = Transaction.fromTxData(<any>fixtureTxSignedWithEIP155.toJSON(), { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For these tests we should review if there was any reason why we used this toJSON
logic for already-signed txs.
@@ -46,6 +46,9 @@ export function ecsign(msgHash: Buffer, privateKey: Buffer, chainId: any): any { | |||
|
|||
function calculateSigRecovery(v: BNLike, chainId?: BNLike): BN { | |||
const vBN = toType(v, TypeOutput.BN) | |||
|
|||
if (vBN.eqn(0) || vBN.eqn(1)) return toType(v, TypeOutput.BN) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I think I just realized a cleaner method of fixing the precompiles than doing this guard in the precompiles. What if we throw here if v = 0
or v = 1
and a chainId
is provided? If you would now pass in a chainId
and v = 1
or v = 0
then ecrecover
will not throw, while it would throw before (since this signature recovery method returns a negative value in that case).
EDIT nvm this will not fix the precompiles. (But it might be cleaner to throw here if chainId is provided and v is 0 or 1?)
if (v !== undefined) { | ||
// v is 1. not matching the EIP-155 chainId included case and... | ||
// v is 2. not matching the classic v=27 or v=28 case | ||
if (v.ltn(37) && !v.eqn(27) && !v.eqn(28)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If v = 36
then we get a chainId = 0, right? Why is this not ok?
In case of v = 35
, then v - 35
(thus 0
, which is odd) means we subtract 36, so we end up with a negative chain id which is obviously wrong. But for 36 this logic seems to work..? Unless chain id 0 is special?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH I don't find any reference about chain ID 0 and I'm unsure if this theoretically a valid chain ID. I would rather assume for now that it is not, mainnet starts with 1 and all other chain IDs I came across were some arbitrary higher value. In doubt I would tend to leave "as is", if someone demands we could still add later on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, I agree
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks @ernestognw 😄
Thanks to you folks! Many things happened here that I would've not been able to address, I appreciate it. |
!v.eqn(27) && | ||
!v.eqn(28) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these becoming unreachable code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Fixes #1904