Skip to content

Commit ab9b156

Browse files
committed
test: newFilter getFilterChanges getFilterLogs
1 parent 4669cc8 commit ab9b156

File tree

5 files changed

+327
-53
lines changed

5 files changed

+327
-53
lines changed

client/src/index.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -242,13 +242,7 @@ function main() {
242242
params,
243243
});
244244
} catch (error: unknown) {
245-
webSocket?.send(
246-
JSON.stringify({
247-
number: msg.number,
248-
error,
249-
})
250-
);
251-
return;
245+
result.error = error;
252246
}
253247

254248
webSocket?.send(

client/src/tests.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ export async function run(myBlockchain: TestChain, myWallet: Chain) {
2323
await import("./tests/eth/newBlockFilter");
2424
await import("./tests/eth/newPendingTransactionFilter");
2525
await import("./tests/eth/uninstallFilter");
26+
await import("./tests/eth/getFilterChanges");
27+
await import("./tests/eth/getFilterLogs");
2628
await import("./tests/eth/getBalance");
2729
await import("./tests/eth/getStorageAt");
2830
await import("./tests/eth/getTransactionCount");
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import { EMIT_ABI, EMIT_BYTECODE } from "../../contracts/newFilter.sol";
2+
import * as tests from "../../tests";
3+
import assert from "assert";
4+
import * as viem from "viem";
5+
6+
const blockchain = tests.blockchain;
7+
const wallet = tests.wallet;
8+
9+
if (!blockchain || !wallet) {
10+
throw "not ready";
11+
}
12+
13+
describe("getFilterChanges", () => {
14+
let contract0: viem.GetContractReturnType<
15+
typeof EMIT_ABI,
16+
typeof blockchain.public,
17+
typeof blockchain.wallet
18+
>;
19+
20+
before(async () => {
21+
const contractHash0 = await blockchain.wallet.deployContract({
22+
abi: EMIT_ABI,
23+
bytecode: EMIT_BYTECODE,
24+
gas: 150000n,
25+
});
26+
27+
await blockchain.test.mine({ blocks: 1 });
28+
29+
const receipt0 = await blockchain.public.waitForTransactionReceipt({
30+
hash: contractHash0,
31+
});
32+
if (receipt0.status !== "success") {
33+
throw new Error(`not deployed: ${receipt0.status}`);
34+
}
35+
36+
const address0 = receipt0.contractAddress;
37+
38+
if (address0 == null) {
39+
throw "not deployed";
40+
}
41+
42+
contract0 = viem.getContract({
43+
publicClient: blockchain.public,
44+
walletClient: blockchain.wallet,
45+
address: address0,
46+
abi: EMIT_ABI,
47+
});
48+
});
49+
50+
it("behaves when getting changes from an uninstalled filter", async () => {
51+
const filter = await wallet.public.createPendingTransactionFilter();
52+
53+
await wallet.public.uninstallFilter({ filter });
54+
55+
await assert.rejects(wallet.public.getFilterChanges({ filter }));
56+
});
57+
58+
it("behaves when getting changes from a filter that never existed", async () => {
59+
await assert.rejects(
60+
wallet.provider.request({
61+
method: "eth_getFilterChanges",
62+
params: ["0xdeadc0de"],
63+
})
64+
);
65+
});
66+
67+
it("doesn't return events outside of block range", async () => {
68+
const filter = await wallet.public.createEventFilter({
69+
fromBlock:
70+
0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffen,
71+
toBlock:
72+
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn,
73+
});
74+
try {
75+
const call = await contract0.write.logSomething([1234n]);
76+
await blockchain.test.mine({ blocks: 1 });
77+
await wallet.public.waitForTransactionReceipt({ hash: call });
78+
const logs = await wallet.public.getFilterChanges({ filter });
79+
assert.equal(logs.length, 0);
80+
} finally {
81+
await wallet.public.uninstallFilter({ filter });
82+
}
83+
});
84+
85+
it("returns events inside the block range", async () => {
86+
const blockNumber = await wallet.public.getBlockNumber();
87+
const filter = await wallet.public.createEventFilter({
88+
fromBlock: blockNumber + 1n,
89+
toBlock: blockNumber + 2n,
90+
});
91+
try {
92+
const call = await contract0.write.logSomething([1234n]);
93+
await blockchain.test.mine({ blocks: 1 });
94+
const receipt = await wallet.public.waitForTransactionReceipt({
95+
hash: call,
96+
});
97+
const logs = await wallet.public.getFilterChanges({ filter });
98+
assert.equal(logs.length, 1);
99+
assert.equal(logs[0].address, contract0.address);
100+
assert.equal(logs[0].blockHash, receipt.blockHash);
101+
assert.equal(logs[0].blockNumber, blockNumber + 1n);
102+
assert.equal(
103+
logs[0].topics[1],
104+
"0x00000000000000000000000000000000000000000000000000000000000004d2"
105+
);
106+
assert.equal(logs[0].transactionHash, call);
107+
assert.equal(logs[0].transactionIndex, receipt.transactionIndex);
108+
} finally {
109+
await wallet.public.uninstallFilter({ filter });
110+
}
111+
});
112+
});
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
import { EMIT_ABI, EMIT_BYTECODE } from "../../contracts/newFilter.sol";
2+
import * as tests from "../../tests";
3+
import assert from "assert";
4+
import * as viem from "viem";
5+
6+
const blockchain = tests.blockchain;
7+
const wallet = tests.wallet;
8+
9+
if (!blockchain || !wallet) {
10+
throw "not ready";
11+
}
12+
13+
describe("getFilterLogs", () => {
14+
let contract0: viem.GetContractReturnType<
15+
typeof EMIT_ABI,
16+
typeof blockchain.public,
17+
typeof blockchain.wallet
18+
>;
19+
20+
let contract1: viem.GetContractReturnType<
21+
typeof EMIT_ABI,
22+
typeof blockchain.public,
23+
typeof blockchain.wallet
24+
>;
25+
26+
before(async () => {
27+
const contractHash0 = await blockchain.wallet.deployContract({
28+
abi: EMIT_ABI,
29+
bytecode: EMIT_BYTECODE,
30+
gas: 150000n,
31+
});
32+
const contractHash1 = await blockchain.wallet.deployContract({
33+
abi: EMIT_ABI,
34+
bytecode: EMIT_BYTECODE,
35+
gas: 150000n,
36+
});
37+
38+
await blockchain.test.mine({ blocks: 1 });
39+
40+
const receipt0 = await blockchain.public.waitForTransactionReceipt({
41+
hash: contractHash0,
42+
});
43+
const receipt1 = await blockchain.public.waitForTransactionReceipt({
44+
hash: contractHash1,
45+
});
46+
if (receipt0.status !== "success" || receipt1.status !== "success") {
47+
throw new Error(
48+
`not deployed: ${receipt0.status} and ${receipt1.status}`
49+
);
50+
}
51+
52+
const address0 = receipt0.contractAddress;
53+
const address1 = receipt1.contractAddress;
54+
55+
if (address0 == null || address1 == null) {
56+
throw "not deployed";
57+
}
58+
59+
contract0 = viem.getContract({
60+
publicClient: blockchain.public,
61+
walletClient: blockchain.wallet,
62+
address: address0,
63+
abi: EMIT_ABI,
64+
});
65+
contract1 = viem.getContract({
66+
publicClient: blockchain.public,
67+
walletClient: blockchain.wallet,
68+
address: address1,
69+
abi: EMIT_ABI,
70+
});
71+
});
72+
73+
it("returns events matching filter", async () => {
74+
const filter = await wallet.public.createEventFilter({
75+
address: contract0.address,
76+
});
77+
try {
78+
const call = await contract0.write.logSomething([1234n]);
79+
await blockchain.test.mine({ blocks: 1 });
80+
await wallet.public.waitForTransactionReceipt({ hash: call });
81+
const actual = await wallet.public.getFilterLogs({ filter });
82+
assert.equal(actual[0].topics[1], 1234n);
83+
} finally {
84+
await wallet.public.uninstallFilter({ filter });
85+
}
86+
});
87+
88+
it("doesn't return events from different contract", async () => {
89+
const filter = await wallet.public.createEventFilter({
90+
address: contract0.address,
91+
});
92+
try {
93+
const call = await contract1.write.logSomething([1234n]);
94+
await blockchain.test.mine({ blocks: 1 });
95+
await wallet.public.waitForTransactionReceipt({ hash: call });
96+
const actual = await wallet.public.getFilterLogs({ filter });
97+
assert.equal(actual.length, 0);
98+
} finally {
99+
await wallet.public.uninstallFilter({ filter });
100+
}
101+
});
102+
103+
it("doesn't return events outside of block range", async () => {
104+
const filter = await wallet.public.createEventFilter({
105+
fromBlock:
106+
0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffen,
107+
toBlock:
108+
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn,
109+
});
110+
try {
111+
const call = await contract0.write.logSomething([1234n]);
112+
await blockchain.test.mine({ blocks: 1 });
113+
await wallet.public.waitForTransactionReceipt({ hash: call });
114+
const logs = await wallet.public.getFilterLogs({ filter });
115+
assert.equal(logs.length, 0);
116+
} finally {
117+
await wallet.public.uninstallFilter({ filter });
118+
}
119+
});
120+
121+
it("returns events inside the block range", async () => {
122+
const blockNumber = await wallet.public.getBlockNumber();
123+
const filter = await wallet.public.createEventFilter({
124+
fromBlock: blockNumber + 1n,
125+
toBlock: blockNumber + 2n,
126+
});
127+
try {
128+
const call = await contract0.write.logSomething([1234n]);
129+
await blockchain.test.mine({ blocks: 1 });
130+
const receipt = await wallet.public.waitForTransactionReceipt({
131+
hash: call,
132+
});
133+
const logs = await wallet.public.getFilterLogs({ filter });
134+
assert.equal(logs.length, 1);
135+
assert.equal(logs[0].address, contract0.address);
136+
assert.equal(logs[0].blockHash, receipt.blockHash);
137+
assert.equal(logs[0].blockNumber, blockNumber + 1n);
138+
assert.equal(
139+
logs[0].topics[1],
140+
"0x00000000000000000000000000000000000000000000000000000000000004d2"
141+
);
142+
assert.equal(logs[0].transactionHash, call);
143+
assert.equal(logs[0].transactionIndex, receipt.transactionIndex);
144+
} finally {
145+
await wallet.public.uninstallFilter({ filter });
146+
}
147+
});
148+
149+
it("behaves when getting logs from new block filter", async () => {
150+
const filter: unknown = await wallet.provider.request({
151+
method: "eth_newBlockFilter",
152+
});
153+
if (typeof filter !== "string") {
154+
assert.fail("filter not a string");
155+
}
156+
157+
try {
158+
await assert.rejects(
159+
wallet.provider.request({
160+
method: "eth_getFilterLogs",
161+
params: [filter],
162+
})
163+
);
164+
} finally {
165+
await wallet.provider.request({
166+
method: "eth_uninstallFilter",
167+
params: [filter],
168+
});
169+
}
170+
});
171+
172+
it("behaves when getting logs from new pending transaction filter", async () => {
173+
const filter: unknown = await wallet.provider.request({
174+
method: "eth_newPendingTransactionFilter",
175+
});
176+
if (typeof filter !== "string") {
177+
assert.fail("filter not a string");
178+
}
179+
180+
try {
181+
await assert.rejects(
182+
wallet.provider.request({
183+
method: "eth_getFilterLogs",
184+
params: [filter],
185+
})
186+
);
187+
} finally {
188+
await wallet.provider.request({
189+
method: "eth_uninstallFilter",
190+
params: [filter],
191+
});
192+
}
193+
});
194+
195+
it("behaves when getting logs from an uninstalled filter", async () => {
196+
const filter = await wallet.public.createEventFilter();
197+
198+
await wallet.public.uninstallFilter({ filter });
199+
200+
await assert.rejects(wallet.public.getFilterLogs({ filter }));
201+
});
202+
203+
it("behaves when getting changes from a filter that never existed", async () => {
204+
await assert.rejects(
205+
wallet.provider.request({
206+
method: "eth_getFilterLogs",
207+
params: ["0xdeadc0de"],
208+
})
209+
);
210+
});
211+
});

0 commit comments

Comments
 (0)