Skip to content

Commit

Permalink
tests: just wait some blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
vklachkov committed Feb 14, 2025
1 parent 01bf2f1 commit 54e261d
Showing 1 changed file with 67 additions and 28 deletions.
95 changes: 67 additions & 28 deletions js-packages/test-utils/eth/tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,87 @@
/* eslint @typescript-eslint/no-floating-promises: 0 */

import * as web3 from 'web3';
import * as web3eth from 'web3-eth';

const RECEIPT_TIMEOUT: number = 48 * 6;
const REQUIRED_CONFIRMATION: number = 12;

type Receipt = web3eth.TransactionReceipt;
type Receipt = any; /* web3eth.TransactionReceipt */
type Event = any; /* web3core.EventLog */

export function sendAndWait(
export async function sendAndWait(
web3: web3.default,
tx: any /* web3contract.ContractSendMethod */,
options?: any /* web3contract.SendOptions */,
): Promise<any /* Receipt + Event[] */> {
const contract = tx._parent;
): Promise<Receipt> {
try {
return await sendAndWaitInternal(web3, tx, options);
} catch (error: any) {
console.log('sendAndWait failed with error:');
console.log(error);
throw error;
}
}

function sendAndWaitInternal(
web3: web3.default,
tx: any /* web3contract.ContractSendMethod */,
options?: any /* web3contract.SendOptions */,
): Promise<Receipt> {
return new Promise((resolve, reject) => {
tx.send(options as any)
.on('confirmation', (confirmationNumber: number, receipt: Receipt) => {
if(REQUIRED_CONFIRMATION > confirmationNumber) {
return;
}

const eventsOptions = {fromBlock: receipt.blockNumber, toBlock: receipt.blockNumber};
contract.getPastEvents('allEvents', eventsOptions)
.then((events: Event[]) => {
resolve({
...receipt,
events: repackEvents(receipt.transactionHash, events),
});
})
.catch((error: Error) => {
console.log(`getPastEvents(allEvents, ...) returns an error: ${error}`);
reject(error);
});
.on('transactionHash', (hash: string) => {
const contract = tx._parent;
waitForTransaction(web3, contract, hash)
.then((receipt: Receipt) => resolve(receipt))
.catch((error: Error) => reject(error));
})
.on('error', (error: Error) => {
console.log(`send(...) returns an error: ${error}`);
.on('error', (error: any) => {
reject(error);
});
});
}

async function waitForTransaction(
web3: web3.default,
contract: any,
txHash: string,
): Promise<Receipt> {
if(!txHash) {
throw new Error(`invalid tx hash: ${txHash}`);
}

const receipt: Receipt = await getReceipt(web3, txHash);

while(await web3.eth.getBlockNumber() - receipt.blockNumber < REQUIRED_CONFIRMATION) {
await new Promise(resolve => setTimeout(resolve, 1000));
}

const eventsOptions = {fromBlock: receipt.blockNumber, toBlock: await web3.eth.getBlockNumber()};
const events = await contract.getPastEvents('allEvents', eventsOptions);

return {
...receipt,
events: repackEvents(txHash, events),
};
}

async function getReceipt(
web3: web3.default,
txHash: string,
): Promise<Receipt> {
const now = () => new Date().getTime();
const receiptWaitStart = now();
const receiptWaitTime = () => (now() - receiptWaitStart) / 1000;

while(receiptWaitTime() < RECEIPT_TIMEOUT) {
const receipt = await web3.eth.getTransactionReceipt(txHash);
if(receipt && receipt.blockNumber) return receipt;
await new Promise(resolve => setTimeout(resolve, 2000));
}

throw new Error(`timeout ${RECEIPT_TIMEOUT} seconds waiting for getTransactionReceipt(${txHash})`);
}

function repackEvents(
transactionHash: string,
events: Event[],
Expand All @@ -57,10 +97,9 @@ function repackEvents(
}

// FIXME: Why events can duplicate?
// if (event.event in eventMap) {
// console.log(events);
// throw new Error(`Multiple ${event.event} events are not supported`);
// }
if(event.event in eventMap) {
console.log(`Found multiple ${event.event} events`);
}

eventMap[event.event] = event;
}
Expand Down

0 comments on commit 54e261d

Please sign in to comment.