Skip to content

Commit

Permalink
fix(API): return correct v value for Legacy tx (#154)
Browse files Browse the repository at this point in the history
  • Loading branch information
AnastasiiaVashchuk authored Oct 12, 2023
1 parent f276eb7 commit ed502ea
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 2 deletions.
6 changes: 6 additions & 0 deletions core/lib/dal/src/models/storage_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,12 @@ pub fn web3_transaction_select_sql() -> &'static str {
pub fn extract_web3_transaction(db_row: PgRow, chain_id: L2ChainId) -> api::Transaction {
let mut storage_api_tx = StorageApiTransaction::from_row(&db_row).unwrap();
storage_api_tx.inner_api_transaction.chain_id = chain_id.as_u64();
if storage_api_tx.inner_api_transaction.transaction_type == Some(U64::from(0)) {
storage_api_tx.inner_api_transaction.v = storage_api_tx
.inner_api_transaction
.v
.map(|v| v + 35 + chain_id.as_u64() * 2);
}
storage_api_tx.into()
}

Expand Down
81 changes: 79 additions & 2 deletions core/tests/ts-integration/tests/api/web3.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -790,13 +790,13 @@ describe('web3 API compatibility tests', () => {
expect(logs).toEqual([]);

logs = await alice.provider.send('zks_getLogsWithVirtualBlocks', [{ fromBlock: '0x1', toBlock: '0x2' }]);
expect(logs.length > 0);
expect(logs.length > 0).toEqual(true);

logs = await alice.provider.send('zks_getLogsWithVirtualBlocks', [{ fromBlock: '0x2', toBlock: '0x1' }]);
expect(logs).toEqual([]);

logs = await alice.provider.send('zks_getLogsWithVirtualBlocks', [{ fromBlock: '0x3', toBlock: '0x3' }]);
expect(logs.length > 0);
expect(logs.length > 0).toEqual(true);

await expect(
alice.provider.send('zks_getLogsWithVirtualBlocks', [{ fromBlock: '0x100000000', toBlock: '0x100000000' }]) // 2^32
Expand All @@ -808,6 +808,83 @@ describe('web3 API compatibility tests', () => {
).toBeRejected();
});

test('Should check transaction signature', async () => {
const CHAIN_ID = +process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID!;
const value = 1;
const gasLimit = 300000;
const gasPrice = await alice.provider.getGasPrice();
const data = '0x';
const to = alice.address;

let tx_handle;
let txFromApi;
let signerAddr;

// check for legacy transaction type
const LEGACY_TX_TYPE = 0;
const legacyTxReq = {
type: LEGACY_TX_TYPE,
to,
value,
chainId: CHAIN_ID,
gasLimit,
gasPrice,
data,
nonce: await alice.getTransactionCount()
};
const signedLegacyTx = await alice.signTransaction(legacyTxReq);
tx_handle = await alice.provider.sendTransaction(signedLegacyTx);
await tx_handle.wait();

txFromApi = await alice.provider.getTransaction(tx_handle.hash);

const serializedLegacyTxReq = ethers.utils.serializeTransaction(legacyTxReq);

// check that API returns correct signature values for the given transaction
// by invoking recoverAddress() method with the serialized transaction and signature values
signerAddr = ethers.utils.recoverAddress(ethers.utils.keccak256(serializedLegacyTxReq), {
r: txFromApi.r!,
s: txFromApi.s!,
v: txFromApi.v!
});
expect(signerAddr).toEqual(alice.address);

const expectedV = 35 + CHAIN_ID! * 2;
expect(Math.abs(txFromApi.v! - expectedV) <= 1).toEqual(true);

// check for EIP1559 transaction type
const EIP1559_TX_TYPE = 2;
const eip1559TxReq = {
type: EIP1559_TX_TYPE,
to,
value,
chainId: CHAIN_ID,
gasLimit,
data,
nonce: await alice.getTransactionCount(),
maxFeePerGas: gasPrice,
maxPriorityFeePerGas: gasPrice
};

const signedEip1559TxReq = await alice.signTransaction(eip1559TxReq);
tx_handle = await alice.provider.sendTransaction(signedEip1559TxReq);
await tx_handle.wait();

txFromApi = await alice.provider.getTransaction(tx_handle.hash);

const serializedEip1559TxReq = ethers.utils.serializeTransaction(eip1559TxReq);

// check that API returns correct signature values for the given transaction
// by invoking recoverAddress() method with the serialized transaction and signature values
signerAddr = ethers.utils.recoverAddress(ethers.utils.keccak256(serializedEip1559TxReq), {
r: txFromApi.r!,
s: txFromApi.s!,
v: txFromApi.v!
});
expect(signerAddr).toEqual(alice.address);
expect(txFromApi.v! <= 1).toEqual(true);
});

afterAll(async () => {
await testMaster.deinitialize();
});
Expand Down

0 comments on commit ed502ea

Please sign in to comment.