Skip to content

Commit e5e7b30

Browse files
more tests
1 parent fa36acf commit e5e7b30

4 files changed

Lines changed: 155 additions & 20 deletions

File tree

config/config.e2e.mainnet.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ features:
2424
enabled: false
2525
port: 6002
2626
stateChanges:
27-
enabled: false
27+
enabled: true
2828
port: 5675
2929
url: 'amqp://guest:guest@127.0.0.1:5672'
3030
exchange: 'state_accesses'

src/test/chain-simulator/state-changes/balances.state-changes-e2e.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,24 @@ describe('State changes: balances parity (v1 vs v2)', () => {
6060
const bob = config.bobAddress;
6161

6262
it('Alice balance matches between v1 and v2', async () => {
63-
const v1 = await fetchBalance(base, alice);
64-
const v2 = await fetchBalanceV2(base, alice);
63+
let v1 = await fetchBalance(base, alice);
64+
let v2 = await fetchBalanceV2(base, alice);
65+
for (let i = 0; i < 20 && v1 !== v2; i++) {
66+
await sleep(1000);
67+
v1 = await fetchBalance(base, alice);
68+
v2 = await fetchBalanceV2(base, alice);
69+
}
6570
expect(v1).toBe(v2);
6671
});
6772

6873
it('Bob balance matches between v1 and v2', async () => {
69-
const v1 = await fetchBalance(base, bob);
70-
const v2 = await fetchBalanceV2(base, bob);
74+
let v1 = await fetchBalance(base, bob);
75+
let v2 = await fetchBalanceV2(base, bob);
76+
for (let i = 0; i < 20 && v1 !== v2; i++) {
77+
await sleep(1000);
78+
v1 = await fetchBalance(base, bob);
79+
v2 = await fetchBalanceV2(base, bob);
80+
}
7181
expect(v1).toBe(v2);
7282
});
7383
});
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import axios from 'axios';
2+
import { config } from '../config/env.config';
3+
import { ChainSimulatorUtils } from '../utils/test.utils';
4+
5+
const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms));
6+
7+
async function fetchAccount(baseUrl: string, address: string): Promise<any> {
8+
for (let i = 0; i < 45; i++) {
9+
const resp = await axios.get(`${baseUrl}/accounts/${address}`).catch(() => undefined);
10+
const acc = resp?.data;
11+
if (acc) return acc;
12+
await sleep(1000);
13+
}
14+
throw new Error(`Could not fetch account ${address}`);
15+
}
16+
17+
async function fetchNonce(baseUrl: string, address: string): Promise<number> {
18+
for (let i = 0; i < 45; i++) {
19+
const resp = await axios.get(`${baseUrl}/proxy/address/${address}/nonce`).catch(() => undefined);
20+
const n = resp?.data?.data?.nonce;
21+
if (typeof n === 'number') return n;
22+
await sleep(1000);
23+
}
24+
throw new Error(`Could not fetch nonce for ${address}`);
25+
}
26+
27+
async function fetchMetaNonce(baseUrl: string): Promise<number> {
28+
for (let i = 0; i < 45; i++) {
29+
const resp = await axios.get(`${baseUrl}/proxy/network/status/4294967295`).catch(() => undefined);
30+
const n = resp?.data?.data?.status?.erd_nonce;
31+
if (typeof n === 'number') return n;
32+
await sleep(1000);
33+
}
34+
throw new Error('Could not fetch meta-chain nonce');
35+
}
36+
37+
describe('State changes: smart contract deploy visibility', () => {
38+
const sim = config.chainSimulatorUrl;
39+
const api = config.apiServiceUrl;
40+
const deployer = config.aliceAddress;
41+
42+
it('Deploys ping-pong contract and exposes codeHash/rootHash; meta nonce increases', async () => {
43+
const startMeta = await fetchMetaNonce(api);
44+
const startNonce = await fetchNonce(api, deployer);
45+
46+
const scAddress = await ChainSimulatorUtils.deployPingPongSc(deployer);
47+
48+
// Wait until /accounts reflects deployment
49+
let account: any = null;
50+
for (let i = 0; i < 45; i++) {
51+
account = await fetchAccount(api, scAddress).catch(() => undefined);
52+
const codeHash = account?.codeHash ?? account?.data?.codeHash;
53+
const rootHash = account?.rootHash ?? account?.data?.rootHash;
54+
if (codeHash && codeHash !== '' && rootHash && rootHash !== '') break;
55+
await sleep(1000);
56+
}
57+
58+
const codeHash = account?.codeHash ?? account?.data?.codeHash;
59+
const rootHash = account?.rootHash ?? account?.data?.rootHash;
60+
expect(typeof codeHash).toBe('string');
61+
expect(codeHash.length).toBeGreaterThan(0);
62+
expect(typeof rootHash).toBe('string');
63+
expect(rootHash.length).toBeGreaterThan(0);
64+
65+
// Nonce of deployer should increase
66+
let endNonce = startNonce;
67+
for (let i = 0; i < 30; i++) {
68+
endNonce = await fetchNonce(api, deployer);
69+
if (endNonce >= startNonce + 1) break;
70+
await sleep(1000);
71+
}
72+
expect(endNonce).toBeGreaterThanOrEqual(startNonce + 1);
73+
74+
// Meta-chain nonce should advance as well
75+
let endMeta = startMeta;
76+
for (let i = 0; i < 30; i++) {
77+
endMeta = await fetchMetaNonce(api);
78+
if (endMeta > startMeta) break;
79+
await sleep(1000);
80+
}
81+
expect(endMeta).toBeGreaterThan(startMeta);
82+
});
83+
});
84+

src/test/chain-simulator/state-changes/transfers.state-changes-e2e.ts

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,17 @@ async function fetchApiBalance(baseUrl: string, address: string): Promise<bigint
4545
return BigInt(bal);
4646
}
4747

48+
async function waitForBalance(baseUrl: string, address: string, expected: bigint, timeoutMs = 60000): Promise<bigint> {
49+
const start = Date.now();
50+
let last: bigint = BigInt(0);
51+
while (Date.now() - start < timeoutMs) {
52+
last = await fetchApiBalance(baseUrl, address);
53+
if (last === expected) return last;
54+
await sleep(1000);
55+
}
56+
return last;
57+
}
58+
4859
async function fetchTxFeeFromSimulator(simUrl: string, txHash: string): Promise<bigint> {
4960
// Prefer explicit fee, fallback to gasUsed * gasPrice if needed
5061
for (let i = 0; i < 30; i++) {
@@ -89,11 +100,13 @@ describe('State changes: native EGLD transfers reflect in balances', () => {
89100

90101
const fee = await fetchTxFeeFromSimulator(sim, txHash);
91102

92-
const afterAlice = await fetchApiBalance(api, alice);
93-
const afterBob = await fetchApiBalance(api, bob);
103+
const expectedAlice = beforeAlice - amount - fee;
104+
const expectedBob = beforeBob + amount;
105+
const afterAlice = await waitForBalance(api, alice, expectedAlice);
106+
const afterBob = await waitForBalance(api, bob, expectedBob);
94107

95-
expect(afterAlice).toBe(beforeAlice - amount - fee);
96-
expect(afterBob).toBe(beforeBob + amount);
108+
expect(afterAlice).toBe(expectedAlice);
109+
expect(afterBob).toBe(expectedBob);
97110
});
98111

99112
it('Round-trip transfers: Alice->Bob then Bob->Alice yields expected finals', async () => {
@@ -123,13 +136,13 @@ describe('State changes: native EGLD transfers reflect in balances', () => {
123136
}));
124137
const fee2 = await fetchTxFeeFromSimulator(sim, hash2);
125138

126-
const endAlice = await fetchApiBalance(api, alice);
127-
const endBob = await fetchApiBalance(api, bob);
139+
const expectedAlice = startAlice - amount1 - fee1 + amount2;
140+
const expectedBob = startBob + amount1 - fee2 - amount2;
141+
const endAlice = await waitForBalance(api, alice, expectedAlice);
142+
const endBob = await waitForBalance(api, bob, expectedBob);
128143

129-
// Alice: -amount1 - fee1 + amount2
130-
expect(endAlice).toBe(startAlice - amount1 - fee1 + amount2);
131-
// Bob: +amount1 - fee2 - amount2
132-
expect(endBob).toBe(startBob + amount1 - fee2 - amount2);
144+
expect(endAlice).toBe(expectedAlice);
145+
expect(endBob).toBe(expectedBob);
133146
});
134147

135148
it('Multiple sequential transfers accumulate correctly (Alice->Bob x3)', async () => {
@@ -160,11 +173,39 @@ describe('State changes: native EGLD transfers reflect in balances', () => {
160173
totalFees += fee;
161174
}
162175

163-
const endAlice = await fetchApiBalance(api, alice);
164-
const endBob = await fetchApiBalance(api, bob);
176+
const expectedAlice = startAlice - totalSent - totalFees;
177+
const expectedBob = startBob + totalSent;
178+
const endAlice = await waitForBalance(api, alice, expectedAlice);
179+
const endBob = await waitForBalance(api, bob, expectedBob);
165180

166-
expect(endAlice).toBe(startAlice - totalSent - totalFees);
167-
expect(endBob).toBe(startBob + totalSent);
181+
expect(endAlice).toBe(expectedAlice);
182+
expect(endBob).toBe(expectedBob);
168183
});
169-
});
170184

185+
it('Sender nonce increases after successful transfers', async () => {
186+
await fundAddress(sim, alice);
187+
const nonceResp = await axios.get(`${api}/proxy/address/${alice}/nonce`);
188+
const startNonce: number = nonceResp?.data?.data?.nonce ?? 0;
189+
190+
const amount = BigInt('1000000000000000'); // 0.001 EGLD
191+
const hash = await sendTransaction(new SendTransactionArgs({
192+
chainSimulatorUrl: sim,
193+
sender: alice,
194+
receiver: bob,
195+
value: amount.toString(),
196+
dataField: '',
197+
}));
198+
// Ensure simulator included the tx
199+
await fetchTxFeeFromSimulator(sim, hash);
200+
201+
// Nonce should increase by 1
202+
let newNonce = startNonce;
203+
for (let i = 0; i < 30; i++) {
204+
const n = await axios.get(`${api}/proxy/address/${alice}/nonce`).then(r => r?.data?.data?.nonce ?? 0).catch(() => startNonce);
205+
if (typeof n === 'number') newNonce = n;
206+
if (newNonce >= startNonce + 1) break;
207+
await sleep(1000);
208+
}
209+
expect(newNonce).toBeGreaterThanOrEqual(startNonce + 1);
210+
});
211+
});

0 commit comments

Comments
 (0)