Skip to content

Commit

Permalink
eth_getCode tests
Browse files Browse the repository at this point in the history
  • Loading branch information
shunjizhan committed Oct 8, 2024
1 parent 73e70e5 commit c9db8a6
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 258 deletions.
258 changes: 0 additions & 258 deletions packages/eth-rpc-adapter/src/__tests__/endpoint-tests/endpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -610,51 +610,6 @@ describe('endpoint', () => {
});


describe('eth_getCode', () => {
const preCompileAddresses = [
'0x0000000000000000000100000000000000000001', // AUSD
'0x0000000000000000000200000000000000000001', // LP_ACA_AUSD
'0x0000000000000000000000000000000000000803', // DEX
];

const tags = ['latest', 'earliest', 'finalized', 'safe'];

it('get correct precompile token code', async () => {
for (const addr of preCompileAddresses) {
for (const t of tags) {
const res = (await eth_getCode([addr, t])).data.result;
expect(res.length).to.greaterThan(2);
}
}
});

it.skip('get correct user deployed contract code', async () => {});

it('returns empty for pending tag or non-exist contract address', async () => {
const randAddr = '0x1ebEc3D7fd088d9eE4B6d8272788f028e5122218';
for (const t of [...tags, 'pending']) {
const res = (await eth_getCode([randAddr, t])).data.result;
expect(res).to.equal('0x');
}
});

it('supports calling historical blocks', async () => {
const dexAddr = '0x0230135fded668a3f7894966b14f42e65da322e4'; // created at block 5
expect((await eth_getCode([dexAddr, { blockNumber: 1 }])).data.result).to.equal('0x');
expect((await eth_getCode([dexAddr, { blockNumber: 5 }])).data.result.length).to.greaterThan(2);
expect((await eth_getCode([dexAddr, { blockNumber: 8 }])).data.result.length).to.greaterThan(2);
expect((await eth_getCode([dexAddr, 7])).data.result.length).to.greaterThan(2);
});
});

describe('net_runtimeVersion', () => {
it('get correct runtime version', async () => {
const version = (await net_runtimeVersion([])).data.result;

expect(version).to.be.gt(2000);
});
});

describe('eth_getBlockByNumber', () => {
if (process.env.SKIP_PUBLIC) {
console.log('public karura tests are skipped ❗');
Expand Down Expand Up @@ -749,219 +704,6 @@ describe('endpoint', () => {
});
});

describe('eth_subscribe', () => {
const provider = new EvmRpcProvider(NODE_RPC_URL);
const aca = new Contract(ADDRESS.ACA, TokenABI.abi, wallet1.connect(provider));

const notifications: any[] = [];
let subId0;
let subId1;
let subId2;
let subId3;
let ws: WebSocket;

beforeAll(() => {
// these has to be in <before block>, since everything outside of <before block> will be globally executed before any <before block>
// also, instantiating ws (next line) has to be inside <before block>, otherwise there will be mysterious failure...
ws = new WebSocket(WS_URL);
ws.on('open', () => {
ws.on('message', data => {
const parsedData = JSON.parse(data.toString());
notifications.push(parsedData);
});

ws.send(
JSON.stringify({
jsonrpc: '2.0',
id: 0,
method: 'eth_subscribe',
params: ['newHeads'],
})
);

ws.send(
JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'eth_subscribe',
params: ['logs', {}],
})
);

ws.send(
JSON.stringify({
jsonrpc: '2.0',
id: 2,
method: 'eth_subscribe',
params: [
'logs',
{
topics: [
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', // transfer
null,
['0x000000000000000000000000b00cb924ae22b2bbb15e10c17258d6a2af980421'],
],
},
],
})
);

ws.send(
JSON.stringify({
jsonrpc: '2.0',
id: 3,
method: 'eth_subscribe',
params: [
'logs',
{
topics: [
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55aaaaaaaaaaa', // shouldn't match
],
},
],
})
);
});
});

afterAll(async () => {
await provider.disconnect();
ws.close();
});

it('get correct subscrption notification', async () => {
await provider.isReady();
await aca.transfer(evmAccounts[1].evmAddress, 111222333444555);

await sleep(3000); // give ws some time to notify

subId0 = notifications.find(n => n.id === 0).result;
subId1 = notifications.find(n => n.id === 1).result;
subId2 = notifications.find(n => n.id === 2).result;
subId3 = notifications.find(n => n.id === 3).result;

const notification0 = notifications.find(n => n.params?.subscription === subId0); // new block
const notification1 = notifications.find(n => n.params?.subscription === subId1); // ACA transfer
const notification2 = notifications.find(n => n.params?.subscription === subId2); // ACA transfer
const notification3 = notifications.find(n => n.params?.subscription === subId3); // no match

const curBlock = (await eth_blockNumber()).data.result;
const curBlockInfo = (await eth_getBlockByNumber([curBlock, false])).data.result;

expect(notification0).to.deep.contains({
jsonrpc: '2.0',
method: 'eth_subscription',
params: {
subscription: subId0,
result: curBlockInfo,
},
});

await sleep(10000); // give subql some time to index
const expectedLog = (
await eth_getLogs([
{
blockHash: curBlockInfo.hash,
},
])
).data.result;

expect(expectedLog.length).to.equal(1);
delete (expectedLog[0] as any).removed;

expect(notification1).to.deep.contains({
jsonrpc: '2.0',
method: 'eth_subscription',
params: {
subscription: subId1,
result: expectedLog[0],
},
});

expect(notification2).to.deep.contains({
jsonrpc: '2.0',
method: 'eth_subscription',
params: {
subscription: subId2,
result: expectedLog[0],
},
});

expect(notification3).to.equal(undefined);
});

it('unsubscribe works', async () => {
notifications.length = 0;

let reqId = 10;
const unsubscribe = async (id: string) => {
ws.send(
JSON.stringify({
jsonrpc: '2.0',
id: reqId++,
method: 'eth_unsubscribe',
params: [id],
})
);

await sleep(300); // delay each msg to make sure result order is correct
};

await unsubscribe(subId0);
await unsubscribe(subId1);
await unsubscribe(subId3);
await unsubscribe(Wallet.createRandom().address);

await sleep(3000); // give ws some time to notify

expect(notifications).to.deep.equal([
{ id: 10, jsonrpc: '2.0', result: true },
{ id: 11, jsonrpc: '2.0', result: true },
{ id: 12, jsonrpc: '2.0', result: true },
{ id: 13, jsonrpc: '2.0', result: false },
]);

// only sub2 is left
notifications.length = 0;
await aca.transfer(evmAccounts[1].evmAddress, 1234567654321);

await sleep(10000); // give ws some time to notify

const notification0 = notifications.find(n => n.params?.subscription === subId0); // no match
const notification1 = notifications.find(n => n.params?.subscription === subId1); // no match
const notification2 = notifications.find(n => n.params?.subscription === subId2); // ACA transfer
const notification3 = notifications.find(n => n.params?.subscription === subId3); // no match

// after unsubscribe they should not be notified anymore
expect(notification0).to.equal(undefined);
expect(notification1).to.equal(undefined);
expect(notification3).to.equal(undefined);

await sleep(10000); // give subql some time to index
const curBlock = (await eth_blockNumber()).data.result;
const curBlockInfo = (await eth_getBlockByNumber([curBlock, false])).data.result;
const expectedLog = (
await eth_getLogs([
{
blockHash: curBlockInfo.hash,
},
])
).data.result;

expect(expectedLog.length).to.equal(1);
delete (expectedLog[0] as any).removed;

expect(notification2).to.deep.contains({
jsonrpc: '2.0',
method: 'eth_subscription',
params: {
subscription: subId2,
result: expectedLog[0],
},
});
});
});

describe('eth_newBlockFilter', () => {
const provider = new EvmRpcProvider(NODE_RPC_URL);
const aca = new Contract(ADDRESS.ACA, TokenABI.abi, wallet1.connect(provider));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import {
ACA as ACA_ADDR,
LP_LCDOT_DOT,
} from '@acala-network/contracts/utils/AcalaAddress';
import { BlockTagish, Eip1898BlockTag } from '@acala-network/eth-providers';
import { Contract, Wallet } from 'ethers';
import { beforeAll, describe, expect, it } from 'vitest';

import {
deployErc20,
eth_blockNumber,
eth_getCode,
testSetup,
} from '../utils';

const { wallet } = testSetup;

const PRE_DEPLOYED_ADDRS = [
ACA_ADDR,
LP_LCDOT_DOT,
];

const tags = ['latest', 'earliest', 'finalized', 'safe'];

describe('eth_getCode', () => {
let token: Contract;
let tokenDeployedBlock: number;

beforeAll(async () => {
token = await deployErc20(wallet);
tokenDeployedBlock = Number((await eth_blockNumber()).data.result);
});

it('can get contract code', async () => {
const allAddrs = PRE_DEPLOYED_ADDRS.concat(token.address as any);

for (const addr of allAddrs) {
for (const t of tags) {
const res = (await eth_getCode([addr, t])).data.result;

if (t === 'earliest') {
expect(res).to.equal('0x');
} else {
expect(res.length).to.greaterThan(2);
}
}
}
});

it('returns empty for pending tag or non-exist contract address', async () => {
const randAddr = Wallet.createRandom().address;
for (const t of [...tags, 'pending']) {
const res = (await eth_getCode([randAddr, t])).data.result;
expect(res).to.equal('0x');
}
});

it('supports calling historical blocks', async () => {
const _getTokenCode = async (blockTag: BlockTagish | Eip1898BlockTag) =>
(await eth_getCode([token.address, blockTag])).data.result;

expect((await _getTokenCode('earliest'))).to.equal('0x');
expect((await _getTokenCode({ blockNumber: tokenDeployedBlock - 1 }))).to.equal('0x');

expect((await _getTokenCode('latest')).length).to.greaterThan(2);
expect((await _getTokenCode({ blockNumber: tokenDeployedBlock })).length).to.greaterThan(2);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
eth_blockNumber,
eth_getEthGas,
net_listening,
net_runtimeVersion,
} from '../utils';

describe('eth_accounts', () => {
Expand All @@ -21,6 +22,14 @@ describe('net_listening', () => {
});
});

describe('net_runtimeVersion', () => {
it('get correct runtime version', async () => {
const version = (await net_runtimeVersion([])).data.result;

expect(version).to.be.gte(2250);
});
});

describe('eth_getEthGas', () => {
it('get correct default contract deployment eth gas params', async () => {
const gasLimit = 21000000;
Expand Down

0 comments on commit c9db8a6

Please sign in to comment.