Skip to content

Commit

Permalink
eth rpc adapter tests (#1032)
Browse files Browse the repository at this point in the history
* subscription tests

* errors test

* utils refactor and eth_estimate gas tests

* add retry

* eth_sendTx tests

* misc corner endpoints

* blocktag tests

* eth_call tests

* fix and switch endpoint

* eth_getCode tests

* eth_getStorageAt tests

* use retry 2 times

* use dwellir node url

* moved karura getblockbynumber tests to parseblock test

* eth_getBlockByNumber tests

* get tx and receipt tests

* eth_newFilter tests

* all filter family

* eth_getlogs test

* clean up

* add retry to start test infra

* cleanup

* decrease test timeout
  • Loading branch information
shunjizhan authored Oct 10, 2024
1 parent 29e56bb commit e2435dd
Show file tree
Hide file tree
Showing 42 changed files with 2,854 additions and 3,430 deletions.
28 changes: 24 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,26 @@ jobs:
run: yarn install --immutable

- name: start test infra
run: docker compose up -d
uses: nick-fields/retry@v2
with:
timeout_minutes: 5
max_attempts: 3
command: docker compose up -d

- name: start rpc adapter for eth-providers
if: matrix.project == 'eth-providers'
run: yarn workspace @acala-network/eth-rpc-adapter run start:coverage

- name: generate typechain for eth-rpc-adapter tests
if: matrix.project == 'eth-rpc-adapter'
run: yarn workspace @acala-network/eth-rpc-adapter run typegen

- name: run tests
run: yarn workspace @acala-network/${{ matrix.project }} run test:coverage
uses: nick-fields/retry@v2
with:
timeout_minutes: 15
max_attempts: 2
command: yarn workspace @acala-network/${{ matrix.project }} run test:coverage

- name: save coverage reports
uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -85,7 +97,11 @@ jobs:
run: yarn install --immutable

- name: start test infra
run: docker compose up -d
uses: nick-fields/retry@v2
with:
timeout_minutes: 5
max_attempts: 3
command: docker compose up -d

- name: start coverage server
env:
Expand All @@ -96,7 +112,11 @@ jobs:
run: cd e2e-tests/${{ matrix.project }} && yarn install --immutable

- name: run e2e tests
run: cd e2e-tests/${{ matrix.project }} && yarn test:acalaFork
uses: nick-fields/retry@v2
with:
timeout_minutes: 15
max_attempts: 2
command: cd e2e-tests/${{ matrix.project }} && yarn test:acalaFork

- name: stop coverage server and generate coverage report
run: yarn workspace @acala-network/eth-rpc-adapter run stop:coverage
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,7 @@ lib
**/.yarn/install-state.gz

## openzeppelin cache
**/.openzeppelin/
**/.openzeppelin/

## typechain files
**/types
2 changes: 1 addition & 1 deletion chopsticks/configs/acala.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
endpoint: wss://acala-rpc.aca-api.network
endpoint: wss://acala-rpc.dwellir.com
mock-signature-host: true
runtime-log-level: 5
block: 7000000
Expand Down
2 changes: 1 addition & 1 deletion codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ coverage:

comment:
layout: "reach, diff, flags, files"
behavior: default
behavior: new
require_changes: false
require_base: false
require_head: false
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,111 @@ exports[`getAllReceiptsAtBlock > contract creation > with logs + legacy gas 1`]
]
`;

exports[`getAllReceiptsAtBlock > different evm tx count > when there are 0 EVM transactions 1`] = `[]`;

exports[`getAllReceiptsAtBlock > different evm tx count > when there are 1 EVM transactions 1`] = `
[
{
"blockHash": "0xab9f0519e9f9885861da35765dad61161c5f939c66b4c4b7091f7e9555e9f92f",
"blockNumber": "0x1bbf96",
"contractAddress": "0x0000000000000000000000000000000000000801",
"cumulativeGasUsed": "0x0",
"effectiveGasPrice": "0x4ced5668c50",
"from": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x3181f",
"logs": [],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"status": "0x1",
"to": null,
"transactionHash": "0x79090e3e64da12012839fb40f95ad03703a6d3c999c262b4196796f9753861ca",
"transactionIndex": "0x0",
"type": "0x0",
},
]
`;

exports[`getAllReceiptsAtBlock > different evm tx count > when there are 2 EVM transactions 1`] = `
[
{
"blockHash": "0xbdae06c67294bca57bffd390c997d6730a837e1c11252d9bba00cac7384c1f16",
"blockNumber": "0x25623f",
"contractAddress": null,
"cumulativeGasUsed": "0x0",
"effectiveGasPrice": "0x15fde28667",
"from": "0x9cb3b68e0c48c53b70f465bda3ba6481a9cb7720",
"gasUsed": "0x2a9f7",
"logs": [
{
"address": "0x0000000000000000000100000000000000000084",
"blockHash": "0xbdae06c67294bca57bffd390c997d6730a837e1c11252d9bba00cac7384c1f16",
"blockNumber": "0x25623f",
"data": "0x0000000000000000000000000000000000000000000000000001550f7dca7000",
"logIndex": "0x0",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x00000000000000000000000030385059196602a1498f5f8ef91f3450e3a7b27a",
"0x0000000000000000000000009cb3b68e0c48c53b70f465bda3ba6481a9cb7720",
],
"transactionHash": "0x7b0361f47dc0be798cb9f7d115d74d68960e685714c515df81dd1a17e3db0cff",
"transactionIndex": "0x0",
},
{
"address": "0x30385059196602a1498f5f8ef91f3450e3a7b27a",
"blockHash": "0xbdae06c67294bca57bffd390c997d6730a837e1c11252d9bba00cac7384c1f16",
"blockNumber": "0x25623f",
"data": "0x0000000000000000000000009cb3b68e0c48c53b70f465bda3ba6481a9cb77200000000000000000000000000000000000000000000000000001550f7dca70000000000000000000000000000000000000000000000000000000000062f8bc54000000000000000000000000000000000000000000000000000000000025623f0000000000000000000000009cb3b68e0c48c53b70f465bda3ba6481a9cb7720",
"logIndex": "0x1",
"topics": [
"0xcb3fe4174668d512bcb57104a92bc21df0b8fdeb1cacc3575aa50b74a3e5ad5a",
"0xeac06b4f60edb2a940a2170eea5cef018dc569f5d98b8176f5da7ea640c9bd27",
"0x0000000000000000000000000000000000000000000100000000000000000084",
"0x0000000000000000000000000000000000000000000000000000000000000004",
],
"transactionHash": "0x7b0361f47dc0be798cb9f7d115d74d68960e685714c515df81dd1a17e3db0cff",
"transactionIndex": "0x0",
},
],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"status": "0x1",
"to": "0x30385059196602a1498f5f8ef91f3450e3a7b27a",
"transactionHash": "0x7b0361f47dc0be798cb9f7d115d74d68960e685714c515df81dd1a17e3db0cff",
"transactionIndex": "0x0",
"type": "0x0",
},
{
"blockHash": "0xbdae06c67294bca57bffd390c997d6730a837e1c11252d9bba00cac7384c1f16",
"blockNumber": "0x25623f",
"contractAddress": null,
"cumulativeGasUsed": "0x0",
"effectiveGasPrice": "0xb460f6718",
"from": "0xc760da3c525c8511938c35613684c3f6175c01a5",
"gasUsed": "0xc26d",
"logs": [
{
"address": "0x1f3a10587a20114ea25ba1b388ee2dd4a337ce27",
"blockHash": "0xbdae06c67294bca57bffd390c997d6730a837e1c11252d9bba00cac7384c1f16",
"blockNumber": "0x25623f",
"data": "0x0000000000000000000000000000000000000000000000000000000025342e5d",
"logIndex": "0x0",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000c760da3c525c8511938c35613684c3f6175c01a5",
"0x000000000000000000000000f7abcfa42bf7e7d43d3d53c665ded80fdafb5244",
],
"transactionHash": "0x9824e1111ba926db7df3091ec45344f224a3086daf5580eaf7ab3e6bf5a6dde6",
"transactionIndex": "0x1",
},
],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"status": "0x1",
"to": "0x1f3a10587a20114ea25ba1b388ee2dd4a337ce27",
"transactionHash": "0x9824e1111ba926db7df3091ec45344f224a3086daf5580eaf7ab3e6bf5a6dde6",
"transactionIndex": "0x1",
"type": "0x0",
},
]
`;

exports[`getAllReceiptsAtBlock > erc20 XCM > basic xcm 1`] = `
[
{
Expand Down
10 changes: 6 additions & 4 deletions packages/eth-providers/src/__tests__/evm-rpc-provider.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { EvmRpcProvider } from '../rpc-provider';
import { afterAll, describe, expect, it } from 'vitest';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
import { runWithTiming, sleep } from '../utils';
import dotenv from 'dotenv';

dotenv.config();

const ACALA_NODE_URL = 'wss://acala-rpc.aca-api.network';
const ACALA_NODE_URL = 'wss://acala-rpc.dwellir.com';
const ACALA_SUBQL = 'https://subql-query-acala.aca-api.network';
const endpoint = process.env.ENDPOINT_URL || 'ws://127.0.0.1:9944';

Expand Down Expand Up @@ -98,10 +98,12 @@ describe.skip('all cache', async () => {

describe.concurrent('rpc test', async () => {
const provider = EvmRpcProvider.from(endpoint);
await provider.isReady();

beforeAll(async () => {
await provider.isReady();
});

afterAll(async () => {
await sleep(5000);
await provider.disconnect();
});

Expand Down
29 changes: 27 additions & 2 deletions packages/eth-providers/src/__tests__/parseBlock.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ describe.concurrent('getAllReceiptsAtBlock', () => {
beforeAll(async () => {
console.log('connecting to node...');
const KARURA_NODE_URL = 'wss://karura-rpc.aca-api.network';
const ACALA_NODE_URL = 'wss://acala-rpc.aca-api.network';
const ACALA_NODE_URL = 'wss://acala-rpc.dwellir.com';

apiK = new ApiPromise(
options({
Expand All @@ -72,7 +72,6 @@ describe.concurrent('getAllReceiptsAtBlock', () => {
});

afterAll(async () => {
await sleep(10_000);
await apiK.disconnect();
await apiA.disconnect();
});
Expand Down Expand Up @@ -199,6 +198,32 @@ describe.concurrent('getAllReceiptsAtBlock', () => {
});
});

describe.concurrent('different evm tx count', () => {
it('when there are 0 EVM transactions', async ({ expect }) => {
const blockNumber = 1818188;
const receipts = await getAllReceiptsAtBlockNumber(apiK, blockNumber);

expect(receipts.length).to.equal(0);
expect(receipts).toMatchSnapshot();
});

it('when there are 1 EVM transactions', async ({ expect }) => {
const blockNumber = 1818518;
const receipts = await getAllReceiptsAtBlockNumber(apiK, blockNumber);

expect(receipts.length).to.equal(1);
expect(receipts).toMatchSnapshot();
});

it('when there are 2 EVM transactions', async ({ expect }) => {
const blockNumber = 2449983;
const receipts = await getAllReceiptsAtBlockNumber(apiK, blockNumber);

expect(receipts.length).to.equal(2);
expect(receipts).toMatchSnapshot();
});
});

describe.concurrent.skip('other types', () => {
// it('failed EVM extrinsic - 0 gasLimit', async ({ expect }) => {
// // TODO: construct a similar one on karura
Expand Down
20 changes: 8 additions & 12 deletions packages/eth-providers/src/base-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1701,7 +1701,6 @@ export abstract class BaseProvider extends AbstractProvider {
return sortedReceipts?.[receiptIdx] ? subqlReceiptAdapter(sortedReceipts[receiptIdx]) : null;
};

// TODO: test pending
_getPendingTX = async (txHash: string): Promise<TX | null> => {
const pendingExtrinsics = await this.api.rpc.author.pendingExtrinsics();
const targetExtrinsic = pendingExtrinsics.find(ex => ex.hash.toHex() === txHash);
Expand Down Expand Up @@ -1827,7 +1826,8 @@ export abstract class BaseProvider extends AbstractProvider {
.map(this.blockCache.getLogsAtBlock.bind(this))
.flat()
.filter(log => filterLogByBlockNumber(log, filter.fromBlock, filter.toBlock))
.filter(log => filterLogByAddress(log, filter.address));
.filter(log => filterLogByAddress(log, filter.address))
.filter(log => filterLogByTopics(log, filter.topics));
};

// Bloom-filter Queries
Expand Down Expand Up @@ -2071,19 +2071,13 @@ export abstract class BaseProvider extends AbstractProvider {
toBlock: effectiveTo,
};

if (!this.subql) {
return logger.throwError(
'missing subql url to fetch logs, to initialize base provider with subql, please provide a subqlUrl param.'
);
}

filterInfo.lastPollBlockNumber = curBlockNumber;
filterInfo.lastPollTimestamp = Date.now();

const subqlLogs = await this.subql.getFilteredLogs(effectiveFilter); // FIXME: this misses unfinalized logs
const filteredLogs = subqlLogs.filter(log => filterLogByTopics(log, sanitizedFilter.topics));
const logs = await this.getLogs(effectiveFilter);
const formattedLogs = logs.map(log => this.formatter.filterLog(log));

return hexlifyRpcResult(filteredLogs.map(log => this.formatter.filterLog(log)));
return hexlifyRpcResult(formattedLogs);
};

_pollBlocks = async (filterInfo: BlockPollFilter): Promise<string[]> => {
Expand All @@ -2110,7 +2104,9 @@ export abstract class BaseProvider extends AbstractProvider {
}

// TODO: TS bug?? why filterInfo type is not BlockPollFilter | LogPollFilter
return filterInfo['logFilter'] ? this._pollLogs(filterInfo as LogPollFilter) : this._pollBlocks(filterInfo);
return filterInfo['logFilter']
? this._pollLogs(filterInfo as LogPollFilter)
: this._pollBlocks(filterInfo as BlockPollFilter);
};

removePollFilter = (id: string): boolean => {
Expand Down
6 changes: 4 additions & 2 deletions packages/eth-rpc-adapter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
"scripts": {
"build": "tsc",
"ncc:pack": "ncc build src/index.ts -t --target es2020",
"dev": "ts-node-dev -T -r tsconfig-paths/register src/index.ts -l | pino-pretty --singleLine --colorize --ignore time,hostname,jsonrpc,dd",
"typegen": "typechain --target=ethers-v5 --out-dir=./src/__tests__/types src/__tests__/abis/*.json",
"dev": "ts-node-dev -T -r tsconfig-paths/register src/index.ts | pino-pretty --singleLine --colorize --ignore time,hostname,jsonrpc,dd",
"clean": "rm -rf tsconfig.tsbuildinfo .nyc_output coverage/ lib/",
"health-check": "./scripts/health-check.sh",
"start": "ts-node -r tsconfig-paths/register src/index.ts",
"start:coverage": "COVERAGE_DIR=${COVERAGE_DIR:-eth-rpc-adapter/coverage} pm2 start --name eth-rpc 'nyc --report-dir=$COVERAGE_DIR node -r ts-node/register -r tsconfig-paths/register src/index.ts' && yarn health-check",
"stop:coverage": "pm2 stop eth-rpc && pm2 delete eth-rpc",
"test": "vitest",
"test": "vitest --no-file-parallelism",
"test:coverage": "COVERAGE_DIR=${COVERAGE_DIR:-eth-rpc-adapter/coverage} yarn start:coverage && COVERAGE_DIR=${COVERAGE_DIR:-eth-rpc-adapter/coverage} yarn test --run && yarn stop:coverage"
},
"peerDependencies": {
Expand Down Expand Up @@ -47,6 +48,7 @@
"pm2": "^5.4.2",
"ts-node": "^10.9.1",
"ts-node-dev": "^2.0.0",
"typechain": "^8.3.2",
"vitest": "^2.1.1"
},
"files": [
Expand Down
Loading

0 comments on commit e2435dd

Please sign in to comment.