Skip to content

Commit

Permalink
feat: index pre-eip155 transactions (#1363)
Browse files Browse the repository at this point in the history
* fix: check whitelisted tx

* feat: unit test toTypedEthTx with hash not whitelisted

* fix: WHITE_LISTED_EIP_155_TRANSACTION_HASHES indexer env

* fix: custom error for v !== 27 and v!==28

* fix: fmt

* fix: remove WHITE_LISTED_EIP_155_TRANSACTION_HASHES check

* fix: remove WHITE_LISTED_EIP_155_TRANSACTION_HASHES

* fix: error message
  • Loading branch information
eugypalu authored Sep 9, 2024
1 parent 5d941cd commit 281eba0
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 4 deletions.
106 changes: 106 additions & 0 deletions indexer/src/types/transaction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,112 @@ Deno.test("toTypedEthTx Legacy Transaction", () => {
assertEquals(ethTx.data, tx.data);
});

Deno.test("toTypedEthTx Legacy Transaction with v = 28", () => {
// Given
const common = new Common({ chain: "mainnet", hardfork: "shanghai" });
const tx = new LegacyTransaction(
{
nonce: 1n,
gasPrice: 2n,
gasLimit: 3n,
to: "0x0000000000000000000000000000000000000001",
value: 4n,
data: new Uint8Array([0x12, 0x34]),
},
{ common },
);
const raw = RLP.encode(tx.getMessageToSign());

const bytesLength = raw.byteLength;

const starknetTxCalldata: `0x${string}`[] = [
"0x1",
"0x0",
"0x0",
"0x0",
"0x0",
"0x0",
`0x${bytesLength.toString(16)}`,
...packCallData(raw),
];

const starknetTx: Transaction = {
invokeV1: {
senderAddress: "0x01",
calldata: starknetTxCalldata,
},
meta: {
hash: "0x01",
maxFee: "0x01",
nonce: "0x01",
signature: ["0x1", "0x2", "0x3", "0x4", "0x1c"], // 0x1c -> 28
version: "1",
},
};

// When
const ethTx = toTypedEthTx({ transaction: starknetTx }) as LegacyTransaction;

// Then
assertExists(ethTx);
assertEquals(ethTx.nonce, 1n);
assertEquals(ethTx.gasPrice, 2n);
assertEquals(ethTx.gasLimit, 3n);
assertEquals(ethTx.value, 4n);
assertEquals(ethTx.type, 0);
assertEquals(ethTx.data, tx.data);
});

Deno.test("toTypedEthTx Legacy Transaction with v = 26 (failure case)", () => {
// Given
const common = new Common({ chain: "mainnet", hardfork: "shanghai" });
const tx = new LegacyTransaction(
{
nonce: 1n,
gasPrice: 2n,
gasLimit: 3n,
to: "0x0000000000000000000000000000000000000001",
value: 4n,
data: new Uint8Array([0x12, 0x34]),
},
{ common },
);
const raw = RLP.encode(tx.getMessageToSign());

const bytesLength = raw.byteLength;

const starknetTxCalldata: `0x${string}`[] = [
"0x1",
"0x0",
"0x0",
"0x0",
"0x0",
"0x0",
`0x${bytesLength.toString(16)}`,
...packCallData(raw),
];

const starknetTx: Transaction = {
invokeV1: {
senderAddress: "0x01",
calldata: starknetTxCalldata,
},
meta: {
hash: "0x01",
maxFee: "0x01",
nonce: "0x01",
signature: ["0x1", "0x2", "0x3", "0x4", "0x1a"], // 0x1a -> 26
version: "1",
},
};

// When
const ethTx = toTypedEthTx({ transaction: starknetTx }) as LegacyTransaction;

// Then
assertEquals(ethTx, null);
});

Deno.test("toTypedEthTx EIP1559 Transaction", () => {
// Given
const common = new Common({ chain: "mainnet", hardfork: "shanghai" });
Expand Down
15 changes: 11 additions & 4 deletions indexer/src/types/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,10 +386,7 @@ function addSignature(
): TypedTransaction {
const TypedTxData = ((): TypedTxData => {
if (isLegacyTx(tx)) {
if (v < 35) {
throw new Error(`Invalid v value: ${v}`);
}
return LegacyTransaction.fromTxData({
const legacyTx = LegacyTransaction.fromTxData({
nonce: tx.nonce,
gasPrice: tx.gasPrice,
gasLimit: tx.gasLimit,
Expand All @@ -400,6 +397,16 @@ function addSignature(
r,
s,
});

if (
v < 35 && Number(v) !== 27 && Number(v) !== 28
) {
throw new Error(
`Legacy txs need either v = 27/28 or v >= 35 (EIP-155 replay protection), got v = ${v}`,
);
}

return legacyTx;
} else if (isAccessListEIP2930Tx(tx)) {
return AccessListEIP2930Transaction.fromTxData({
chainId: tx.chainId,
Expand Down

0 comments on commit 281eba0

Please sign in to comment.