Skip to content

Commit 30f75be

Browse files
Add tests for trace_filter to check heavy contracts logic
1 parent a8896b5 commit 30f75be

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-0
lines changed
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import { beforeEach, describe, expect, it } from "vitest";
2+
import { RunNodeState, runNode } from "../../lib/node";
3+
import * as eth from "../../lib/ethViem";
4+
import { beforeEachWithCleanup } from "../../lib/lifecycle";
5+
import heavy from "../../lib/abis/evmTracing/heavy";
6+
import { customRpcRequest } from "../../lib/rpcUtils";
7+
import { encodeFunctionData } from "viem";
8+
9+
describe("test trace filter for heavy contract logic", () => {
10+
let node: RunNodeState;
11+
let publicClient: eth.PublicClientWebSocket;
12+
let devClients: eth.DevClientsWebSocket;
13+
beforeEachWithCleanup(async (cleanup) => {
14+
node = runNode(
15+
{
16+
args: ["--tracing-mode=trace", "--dev", "--tmp"],
17+
},
18+
cleanup.push,
19+
);
20+
21+
await node.waitForBoot;
22+
23+
publicClient = eth.publicClientFromNodeWebSocket(node, cleanup.push);
24+
devClients = eth.devClientsFromNodeWebSocket(node, cleanup.push);
25+
}, 60 * 1000);
26+
27+
let heavyContracts: {
28+
address: `0x${string}`;
29+
blockNumberHex: string;
30+
txHash: `0x${string}`;
31+
}[] = [];
32+
33+
beforeEach(async () => {
34+
const [alice, _] = devClients;
35+
36+
for (let index = 0; index < 4; index++) {
37+
let shouldRevert = false;
38+
let gas;
39+
40+
if (index == 3) {
41+
shouldRevert = true;
42+
gas = 150_000n; // should be increased for revert logic.
43+
}
44+
45+
const deployHeavyContractTxHash = await alice.deployContract({
46+
abi: heavy.abi,
47+
bytecode: heavy.bytecode,
48+
gas: gas,
49+
args: [shouldRevert],
50+
});
51+
52+
const deployHeavyContractTxReceipt =
53+
await publicClient.waitForTransactionReceipt({
54+
hash: deployHeavyContractTxHash,
55+
timeout: 18_000,
56+
});
57+
58+
heavyContracts.push({
59+
address: deployHeavyContractTxReceipt.contractAddress!,
60+
blockNumberHex: deployHeavyContractTxReceipt.blockNumber.toString(16),
61+
txHash: deployHeavyContractTxReceipt.transactionHash,
62+
});
63+
}
64+
});
65+
66+
it("should be able to replay deployed contract", async () => {
67+
const [alice, _] = devClients;
68+
69+
const response = await customRpcRequest(
70+
node.meta.rpcUrlHttp,
71+
"trace_filter",
72+
[
73+
{
74+
fromBlock: heavyContracts[0]!.blockNumberHex,
75+
toBlock: heavyContracts[0]!.blockNumberHex,
76+
},
77+
],
78+
);
79+
80+
expect(response.length).to.equal(1);
81+
82+
expect(response[0].action).to.include({
83+
creationMethod: "create",
84+
from: alice.account.address.toLocaleLowerCase(),
85+
gas: "0x66fa5",
86+
value: "0x0",
87+
});
88+
89+
expect(response[0]).to.include({
90+
blockNumber: 1,
91+
subtraces: 0,
92+
transactionHash: heavyContracts[0]!.txHash,
93+
transactionPosition: 0,
94+
type: "create",
95+
});
96+
});
97+
98+
it("should be able to replay reverted contract", async () => {
99+
const [alice, _] = devClients;
100+
101+
const response = await customRpcRequest(
102+
node.meta.rpcUrlHttp,
103+
"trace_filter",
104+
[
105+
{
106+
fromBlock: heavyContracts[3]!.blockNumberHex,
107+
toBlock: heavyContracts[3]!.blockNumberHex,
108+
},
109+
],
110+
);
111+
112+
expect(response.length).to.equal(1);
113+
expect(response[0].action.creationMethod).to.equal("create");
114+
expect(response[0].action.from).to.equal(
115+
alice.account.address.toLocaleLowerCase(),
116+
);
117+
expect(response[0].action.gas).to.equal("0xf576");
118+
expect(response[0].action.init).to.be.a("string");
119+
expect(response[0].action.value).to.equal("0x0");
120+
expect(response[0].blockHash).to.be.a("string");
121+
expect(response[0].blockNumber).to.equal(4);
122+
expect(response[0].result).to.equal(undefined);
123+
expect(response[0].error).to.equal("Reverted");
124+
expect(response[0].subtraces).to.equal(0);
125+
expect(response[0].traceAddress.length).to.equal(0);
126+
expect(response[0].transactionHash).to.equal(heavyContracts[3]!.txHash);
127+
expect(response[0].transactionPosition).to.equal(0);
128+
expect(response[0].type).to.equal("create");
129+
});
130+
131+
it("should be able to trace sub-call with reverts", async () => {
132+
const [alice, _] = devClients;
133+
134+
const txHash = await alice.sendTransaction({
135+
to: heavyContracts[0]!.address,
136+
data: encodeFunctionData({
137+
abi: heavy.abi,
138+
functionName: "subcalls",
139+
args: [heavyContracts[1]!.address, heavyContracts[2]!.address],
140+
}),
141+
gas: 1000_000n,
142+
});
143+
const txReceipt = await publicClient.waitForTransactionReceipt({
144+
hash: txHash,
145+
});
146+
const blockNumberHex = txReceipt.blockNumber.toString(16);
147+
148+
const response = await customRpcRequest(
149+
node.meta.rpcUrlHttp,
150+
"trace_filter",
151+
[
152+
{
153+
fromBlock: blockNumberHex,
154+
toBlock: blockNumberHex,
155+
},
156+
],
157+
);
158+
159+
expect(response.length).to.equal(7);
160+
expect(response[0].subtraces).to.equal(2);
161+
expect(response[0].traceAddress).to.deep.equal([]);
162+
expect(response[1].subtraces).to.equal(2);
163+
expect(response[1].traceAddress).to.deep.equal([0]);
164+
expect(response[2].subtraces).to.equal(0);
165+
expect(response[2].traceAddress).to.deep.equal([0, 0]);
166+
expect(response[3].subtraces).to.equal(0);
167+
expect(response[3].traceAddress).to.deep.equal([0, 1]);
168+
expect(response[4].subtraces).to.equal(2);
169+
expect(response[4].traceAddress).to.deep.equal([1]);
170+
expect(response[5].subtraces).to.equal(0);
171+
expect(response[5].traceAddress).to.deep.equal([1, 0]);
172+
expect(response[6].subtraces).to.equal(0);
173+
expect(response[6].traceAddress).to.deep.equal([1, 1]);
174+
});
175+
});

0 commit comments

Comments
 (0)