Fixed legacy serialization for implicit chainId transactions (#3898, #3899).

This commit is contained in:
Richard Moore 2023-03-16 12:11:46 -04:00
parent 3ad4273b8b
commit fcf6c8fcee
2 changed files with 12 additions and 7 deletions

@ -181,9 +181,9 @@ export class SigningKey {
const der = secp256k1.Signature.fromCompact(getBytesCopy(concat([ sig.r, sig.s ]))).toDERRawBytes(); const der = secp256k1.Signature.fromCompact(getBytesCopy(concat([ sig.r, sig.s ]))).toDERRawBytes();
const pubKey = secp256k1.recoverPublicKey(getBytesCopy(digest), der, sig.yParity); const pubKey = secp256k1.recoverPublicKey(getBytesCopy(digest), der, sig.yParity);
if (pubKey != null) { return hexlify(pubKey); } assertArgument(pubKey != null, "invalid signautre for digest", "signature", signature);
assertArgument(false, "invalid signautre for digest", "signature", signature); return hexlify(pubKey);
} }
/** /**

@ -191,7 +191,7 @@ function _serializeLegacy(tx: Transaction, sig?: Signature): string {
]; ];
let chainId = BN_0; let chainId = BN_0;
if (tx.chainId != null) { if (tx.chainId != BN_0) {
// A chainId was provided; if non-zero we'll use EIP-155 // A chainId was provided; if non-zero we'll use EIP-155
chainId = getBigInt(tx.chainId, "tx.chainId"); chainId = getBigInt(tx.chainId, "tx.chainId");
@ -200,9 +200,9 @@ function _serializeLegacy(tx: Transaction, sig?: Signature): string {
assertArgument(!sig || sig.networkV == null || sig.legacyChainId === chainId, assertArgument(!sig || sig.networkV == null || sig.legacyChainId === chainId,
"tx.chainId/sig.v mismatch", "sig", sig); "tx.chainId/sig.v mismatch", "sig", sig);
} else if (sig) { } else if (tx.signature) {
// No chainId provided, but the signature is signing with EIP-155; derive chainId // No explicit chainId, but EIP-155 have a derived implicit chainId
const legacy = sig.legacyChainId; const legacy = tx.signature.legacyChainId;
if (legacy != null) { chainId = legacy; } if (legacy != null) { chainId = legacy; }
} }
@ -218,7 +218,11 @@ function _serializeLegacy(tx: Transaction, sig?: Signature): string {
return encodeRlp(fields); return encodeRlp(fields);
} }
// We pushed a chainId and null r, s on for hashing only; remove those // @TODO: We should probably check that tx.signature, chainId, and sig
// match but that logic could break existing code, so schedule
// this for the next major bump.
// Compute the EIP-155 v
let v = BigInt(27 + sig.yParity); let v = BigInt(27 + sig.yParity);
if (chainId !== BN_0) { if (chainId !== BN_0) {
v = Signature.getChainIdV(chainId, sig.v); v = Signature.getChainIdV(chainId, sig.v);
@ -226,6 +230,7 @@ function _serializeLegacy(tx: Transaction, sig?: Signature): string {
assertArgument(false, "tx.chainId/sig.v mismatch", "sig", sig); assertArgument(false, "tx.chainId/sig.v mismatch", "sig", sig);
} }
// Add the signature
fields.push(toBeArray(v)); fields.push(toBeArray(v));
fields.push(toBeArray(sig.r)); fields.push(toBeArray(sig.r));
fields.push(toBeArray(sig.s)); fields.push(toBeArray(sig.s));