Skip to content
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

🧪 Add web3.js tests to getTransaction and getTransactionReceipt #109

Merged
merged 4 commits into from
Apr 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 92 additions & 25 deletions src/providers/test/json-rpc-provider/get-transaction-receipt.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ethers } from 'ethers';
import omit from 'just-omit';
import Web3 from 'web3';
import web3core from 'web3-core';
import { JsonRpcProvider } from '../../../index';
import { TransactionReceipt } from '../../../types/Transaction.types';
import { rpcUrls } from '../rpc-urls';
Expand All @@ -8,37 +10,102 @@ const rpcUrl = rpcUrls.mainnet;

describe('provider.getTransactionReceipt', () => {
function testTransactionReceiptEquality(
transactionReceipt1: ethers.providers.TransactionReceipt,
transactionReceipt1:
| ethers.providers.TransactionReceipt
| web3core.Transaction,
transactionReceipt2: TransactionReceipt,
) {
// requires manually comparing values via bigNum conversion
const bignumCheckKeys = [
'gasUsed',
'cumulativeGasUsed',
'effectiveGasPrice',
];
const omittedTransactionReceipt1 = omit(transactionReceipt1, [
...bignumCheckKeys,
]);
const omittedTransactionReceipt2 = omit(transactionReceipt2, [
...bignumCheckKeys,
]);
let typeCheckKeys: Array<string> = [];
let omittable1: Array<string> = [];
let omittable2: Array<string> = [];
if (
(transactionReceipt1 as ethers.providers.TransactionReceipt).confirmations
) {
// only ethers response has confirmations
// requires manually comparing values via bigNum conversion
typeCheckKeys = ['gasUsed', 'cumulativeGasUsed', 'effectiveGasPrice'];
omittable1 = typeCheckKeys;
omittable2 = typeCheckKeys;

typeCheckKeys.forEach((key) => {
expect((transactionReceipt1 as any)[key].toString()).toBe(
(transactionReceipt2 as any)[key].toString(),
);
});

expect(
Math.abs(
(transactionReceipt1 as ethers.providers.TransactionReceipt)
.confirmations - transactionReceipt2.confirmations,
),
).toBeLessThan(3);
} else {
typeCheckKeys = [
'cumulativeGasUsed',
'effectiveGasPrice',
'from',
'gasUsed',
'status',
'to',
'type',
];
omittable1 = typeCheckKeys;
omittable2 = ['byzantium', 'confirmations', ...typeCheckKeys];

typeCheckKeys.forEach((key) => {
switch (key) {
case 'cumulativeGasUsed':
case 'effectiveGasPrice':
case 'gasUsed':
expect((transactionReceipt1 as any)[key].toString()).toBe(
(transactionReceipt2 as any)[key].toString(),
);
break;
case 'from':
case 'to':
expect((transactionReceipt1 as any)[key]).toBe(
(transactionReceipt2 as any)[key].toLowerCase(),
);
break;
}
});
}

const omittedTransactionReceipt1 = omit(transactionReceipt1, omittable1) as
| TransactionReceipt
| web3core.TransactionReceipt;
const omittedTransactionReceipt2 = omit(transactionReceipt2, omittable2) as
| TransactionReceipt
| web3core.TransactionReceipt;
omittedTransactionReceipt1.logs = (() => {
const logs: any = [];
omittedTransactionReceipt1.logs.forEach((log) => {
logs.push(omit(log, ['id', 'removed']));
});
return logs as any;
})();

expect(omittedTransactionReceipt1).toStrictEqual(
omittedTransactionReceipt2,
);
expect(
Math.abs(
transactionReceipt1.confirmations - transactionReceipt2.confirmations,
),
).toBeLessThan(3);
bignumCheckKeys.forEach((key) => {
const ethersKey = key as keyof ethers.providers.TransactionResponse;
expect((transactionReceipt1 as any)[ethersKey].toString()).toBe(
(transactionReceipt2 as any)[key].toString(),
);
});
}
it('should match ethers and essential-eth', async () => {
it('should match web3.js', async () => {
const transactionHash =
'0x9014ae6ef92464338355a79e5150e542ff9a83e2323318b21f40d6a3e65b4789';
const web3Provider = new Web3(rpcUrl);
const essentialEthProvider = new JsonRpcProvider(rpcUrl);
const [web3TransactionReceipt, essentialEthTransactionReceipt] =
await Promise.all([
web3Provider.eth.getTransactionReceipt(transactionHash),
essentialEthProvider.getTransactionReceipt(transactionHash),
]);

testTransactionReceiptEquality(
web3TransactionReceipt as any,
essentialEthTransactionReceipt,
);
});
it('should match ethers', async () => {
const transactionHash =
'0x9014ae6ef92464338355a79e5150e542ff9a83e2323318b21f40d6a3e65b4789';
const ethersProvider = new ethers.providers.StaticJsonRpcProvider(rpcUrl);
Expand Down
134 changes: 88 additions & 46 deletions src/providers/test/json-rpc-provider/get-transaction.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { ethers } from 'ethers';
import omit from 'just-omit';
import Web3 from 'web3';
import web3core from 'web3-core';
import { hexToDecimal } from '../../../classes/utils/hex-to-decimal';
import { JsonRpcProvider } from '../../../index';
import { TransactionResponse } from '../../../types/Transaction.types';
import { rpcUrls } from '../rpc-urls';
Expand All @@ -8,57 +11,96 @@ const rpcUrl = rpcUrls.mainnet;

describe('provider.getTransaction', () => {
function testTransactionEquality(
transaction1: ethers.providers.TransactionResponse,
transaction1: ethers.providers.TransactionResponse | web3core.Transaction,
transaction2: TransactionResponse,
) {
// requires manually comparing values via bigNum conversion
const bignumCheckKeys = [
'value',
'gas',
'gasPrice',
'maxFeePerGas',
'maxPriorityFeePerGas',
'confirmations',
];
const omittedTransaction1 = omit(transaction1, [
'wait', // ethers injects this to allow you to wait on a certain confirmation count
'creates', // ethers injects this custom https://github.com/ethers-io/ethers.js/blob/948f77050dae884fe88932fd88af75560aac9d78/packages/providers/src.ts/formatter.ts#L336
'data', // ethers renames input to data https://github.com/ethers-io/ethers.js/blob/948f77050dae884fe88932fd88af75560aac9d78/packages/providers/src.ts/formatter.ts#L331
'gasLimit', // ethers renames gas to gasLimit https://github.com/ethers-io/ethers.js/blob/948f77050dae884fe88932fd88af75560aac9d78/packages/providers/src.ts/formatter.ts#L320
'input',
...bignumCheckKeys,
]);
const omittedTransaction2 = omit(transaction2, [
'input', // ee proxies exactly this from the eth node
...bignumCheckKeys,
]);
let numCheckKeys: Array<string> = [];
let omittable1: Array<string> = [];
let omittable2: Array<string> = [];
if ((transaction1 as ethers.providers.TransactionResponse).confirmations) {
// only the ethers response has confirmations
// requires manually comparing values via bigNum conversion
numCheckKeys = [
'value',
'gas',
'gasPrice',
'maxFeePerGas',
'maxPriorityFeePerGas',
'confirmations',
];

omittable1 = [
'wait', // ethers injects this to allow you to wait on a certain confirmation count
'creates', // ethers injects this custom https://github.com/ethers-io/ethers.js/blob/948f77050dae884fe88932fd88af75560aac9d78/packages/providers/src.ts/formatter.ts#L336
'data', // ethers renames input to data https://github.com/ethers-io/ethers.js/blob/948f77050dae884fe88932fd88af75560aac9d78/packages/providers/src.ts/formatter.ts#L331
'gasLimit', // ethers renames gas to gasLimit https://github.com/ethers-io/ethers.js/blob/948f77050dae884fe88932fd88af75560aac9d78/packages/providers/src.ts/formatter.ts#L320
'input',
...numCheckKeys,
];

omittable2 = ['input', ...numCheckKeys];

numCheckKeys.forEach((key) => {
let ethersKey = key as keyof ethers.providers.TransactionResponse;
if (key === 'gas') {
ethersKey = 'gasLimit';
}
expect((transaction1 as any)[ethersKey].toString()).toBe(
(transaction2 as any)[key].toString(),
);
});

expect(
Math.abs(
(transaction1 as ethers.providers.TransactionResponse).confirmations -
transaction2.confirmations,
),
).toBeLessThan(3);
} else {
numCheckKeys = [
'chainId',
'gas',
'gasPrice',
'maxFeePerGas',
'maxPriorityFeePerGas',
'v',
'value',
];
omittable1 = [...numCheckKeys];
omittable2 = ['confirmations', ...numCheckKeys];

numCheckKeys.forEach((key) => {
if (
typeof (transaction1 as any)[key] === 'string' &&
(transaction1 as any)[key].startsWith('0x')
) {
(transaction1 as any)[key] = Number(
hexToDecimal((transaction1 as any)[key]),
);
}
expect((transaction1 as any)[key].toString()).toBe(
(transaction2 as any)[key].toString(),
);
});
}

const omittedTransaction1 = omit(transaction1, omittable1);
const omittedTransaction2 = omit(transaction2, omittable2);
expect(omittedTransaction1).toStrictEqual(omittedTransaction2);
expect(
Math.abs(transaction1.confirmations - transaction2.confirmations),
).toBeLessThan(3);
bignumCheckKeys.forEach((key) => {
let ethersKey = key as keyof ethers.providers.TransactionResponse;
if (key === 'gas') {
ethersKey = 'gasLimit';
}
expect((transaction1 as any)[ethersKey].toString()).toBe(
(transaction2 as any)[key].toString(),
);
});
}
// it('should match web3 and essential-eth', async () => {
// const transactionHash =
// '0x9014ae6ef92464338355a79e5150e542ff9a83e2323318b21f40d6a3e65b4789';
// const web3Provider = new Web3(rpcUrl);
// const essentialEthProvider = new JsonRpcProvider(rpcUrl);
// const [web3Transaction, essentialEthTransaction] = await Promise.all([
// web3Provider.eth.getTransaction(transactionHash),
// essentialEthProvider.getTransaction(transactionHash),
// ]);
it('should match web3.js', async () => {
const transactionHash =
'0x9014ae6ef92464338355a79e5150e542ff9a83e2323318b21f40d6a3e65b4789';
const web3Provider = new Web3(rpcUrl);
const essentialEthProvider = new JsonRpcProvider(rpcUrl);
const [web3Transaction, essentialEthTransaction] = await Promise.all([
web3Provider.eth.getTransaction(transactionHash),
essentialEthProvider.getTransaction(transactionHash),
]);

// testTransactionEquality(web3Transaction as any, essentialEthTransaction);
// });
it('should match ethers and essential-eth', async () => {
testTransactionEquality(web3Transaction, essentialEthTransaction);
});
it('should match ethers.js', async () => {
const transactionHash =
'0x9014ae6ef92464338355a79e5150e542ff9a83e2323318b21f40d6a3e65b4789';
const ethersProvider = new ethers.providers.StaticJsonRpcProvider(rpcUrl);
Expand Down