From fe0867732f65459d366ffa029e87b17482574117 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Tue, 10 Sep 2024 15:35:52 +0300 Subject: [PATCH] test: Fix "missing revert data" error; fix / debug integration tests (#2804) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ - Fixes the "missing revert data" error by updating the used reth Docker image. The error is probably caused by [this issue](https://github.com/paradigmxyz/reth/issues/7381) fixed in the new reth versions. - Removes "web3 API compatibility tests › Should check API returns error when there are too many logs in eth_getLogs" test as fundamentally flaky and able to poison other tests. - Adds logging for upgrade test to investigate L1 "nonce too low" errors. ## Why ❔ Flaky CI bad. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Code has been formatted via `zk fmt` and `zk lint`. --- core/bin/zksync_server/src/node_builder.rs | 1 + .../ts-integration/tests/api/web3.test.ts | 58 ++++--------------- core/tests/upgrade-test/tests/upgrade.test.ts | 34 ++++++----- docker-compose-cpu-runner.yml | 2 +- docker-compose-gpu-runner-cuda-12-0.yml | 2 +- docker-compose-gpu-runner.yml | 2 +- docker-compose.yml | 2 +- 7 files changed, 35 insertions(+), 66 deletions(-) diff --git a/core/bin/zksync_server/src/node_builder.rs b/core/bin/zksync_server/src/node_builder.rs index 36ee7d990cf..e2a0c5846b5 100644 --- a/core/bin/zksync_server/src/node_builder.rs +++ b/core/bin/zksync_server/src/node_builder.rs @@ -364,6 +364,7 @@ impl MainNodeBuilder { subscriptions_limit: Some(rpc_config.subscriptions_limit()), batch_request_size_limit: Some(rpc_config.max_batch_request_size()), response_body_size_limit: Some(rpc_config.max_response_body_size()), + with_extended_tracing: rpc_config.extended_api_tracing, ..Default::default() }; self.node.add_layer(Web3ServerLayer::http( diff --git a/core/tests/ts-integration/tests/api/web3.test.ts b/core/tests/ts-integration/tests/api/web3.test.ts index b20e9d1e37d..79789e74447 100644 --- a/core/tests/ts-integration/tests/api/web3.test.ts +++ b/core/tests/ts-integration/tests/api/web3.test.ts @@ -202,7 +202,7 @@ describe('web3 API compatibility tests', () => { test('Should test web3 response extensions', async () => { if (testMaster.isFastMode()) { - // This test requires a new L1 batch to be created, which may be very time consuming on stage. + // This test requires a new L1 batch to be created, which may be very time-consuming on stage. return; } @@ -333,7 +333,7 @@ describe('web3 API compatibility tests', () => { // Pubsub notifier is not reactive + tests are being run in parallel, so we can't expect that the next block // would be expected one. Instead, we just want to receive an event with the particular block number. - wsProvider.on('block', (block) => { + await wsProvider.on('block', (block) => { if (block >= currentBlock) { newBlock = block; } @@ -355,7 +355,6 @@ describe('web3 API compatibility tests', () => { // ...though the gap should not be *too* big. expect(newBlock).toBeLessThan(currentBlock + 100); await tx.wait(); // To not leave a hanging promise. - wsProvider.removeAllListeners(); await wsProvider.destroy(); }); @@ -368,7 +367,7 @@ describe('web3 API compatibility tests', () => { let newTxHash: string | null = null; // We can't use `once` as there may be other pending txs sent together with our one. - wsProvider.on('pending', async (txHash) => { + await wsProvider.on('pending', async (txHash) => { const tx = await alice.provider.getTransaction(txHash); // We're waiting for the exact transaction to appear. if (!tx || tx.to != uniqueRecipient) { @@ -392,7 +391,6 @@ describe('web3 API compatibility tests', () => { expect(newTxHash as string).toEqual(tx.hash); await tx.wait(); // To not leave a hanging promise. - wsProvider.removeAllListeners(); await wsProvider.destroy(); }); @@ -404,7 +402,7 @@ describe('web3 API compatibility tests', () => { // We're sending a few transfers from the wallet, so we'll use a new account to make event unique. let uniqueRecipient = testMaster.newEmptyAccount().address; - // Setup a filter for an ERC20 transfer. + // Set up a filter for an ERC20 transfer. const erc20TransferTopic = ethers.id('Transfer(address,address,uint256)'); let filter = { address: l2Token, @@ -414,15 +412,15 @@ describe('web3 API compatibility tests', () => { ethers.zeroPadValue(uniqueRecipient, 32) // Recipient ] }; - wsProvider.once(filter, (event) => { + await wsProvider.once(filter, (event) => { newEvent = event; }); - // Setup a filter that should not match anything. + // Set up a filter that should not match anything. let incorrectFilter = { address: alice.address }; - wsProvider.once(incorrectFilter, (_) => { + await wsProvider.once(incorrectFilter, (_) => { expect(null).fail('Found log for incorrect filter'); }); @@ -439,7 +437,6 @@ describe('web3 API compatibility tests', () => { expect((newEvent as any).transactionHash).toEqual(tx.hash); await tx.wait(); // To not leave a hanging promise. - wsProvider.removeAllListeners(); await wsProvider.destroy(); }); @@ -608,7 +605,7 @@ describe('web3 API compatibility tests', () => { // Pubsub notify is not reactive and may be laggy, so we want to increase the chances // for test to pass. So we try to sleep a few iterations until we receive expected amount - // of events. If we won't receive them, we continue and the test will fail anyway. + // of events. If we don't receive them, we continue and the test will fail anyway. const expectedTrivialEventsCount = 2; const expectedSimpleEventsCount = 2; const expectedIndexedEventsCount = 1; @@ -681,42 +678,9 @@ describe('web3 API compatibility tests', () => { ).resolves.toHaveProperty('result', expect.stringMatching(HEX_VALUE_REGEX)); }); - test('Should check API returns error when there are too many logs in eth_getLogs', async () => { - const contract = await deployContract(alice, contracts.events, []); - const maxLogsLimit = testMaster.environment().maxLogsLimit; - - // Send 3 transactions that emit `maxLogsLimit / 2` events. - const tx1 = await contract.emitManyEvents(maxLogsLimit / 2); - const tx1Receipt = await tx1.wait(); - - const tx2 = await contract.emitManyEvents(maxLogsLimit / 2); - await tx2.wait(); - - const tx3 = await contract.emitManyEvents(maxLogsLimit / 2); - const tx3Receipt = await tx3.wait(); - - // There are around `0.5 * maxLogsLimit` logs in [tx1Receipt.blockNumber, tx1Receipt.blockNumber] range, - // so query with such filter should succeed. - await expect( - alice.provider.getLogs({ - fromBlock: tx1Receipt.blockNumber, - toBlock: tx1Receipt.blockNumber - }) - ).resolves; - - // There are at least `1.5 * maxLogsLimit` logs in [tx1Receipt.blockNumber, tx3Receipt.blockNumber] range, - // so query with such filter should fail. - await expect( - alice.provider.getLogs({ - fromBlock: tx1Receipt.blockNumber, - toBlock: tx3Receipt.blockNumber - }) - ).rejects.toThrow(`Query returned more than ${maxLogsLimit} results.`); - }); - test('Should throw error for estimate gas for account with balance < tx.value', async () => { let poorBob = testMaster.newEmptyAccount(); - expect( + await expect( poorBob.estimateGas({ value: 1, to: alice.address }) ).toBeRejected(/*'insufficient balance for transfer'*/); }); @@ -860,7 +824,7 @@ describe('web3 API compatibility tests', () => { const getLogsByHash = (await alice.provider.getLogs({ blockHash: latestBlock.hash || undefined })).map((x) => { return new zksync.types.Log({ ...x, l1BatchNumber: 0 }, alice.provider); // Set bogus value. }); - await expect(getLogsByNumber).toEqual(getLogsByHash); + expect(getLogsByNumber).toEqual(getLogsByHash); // Check that incorrect queries are rejected. await expect( @@ -1030,7 +994,7 @@ describe('web3 API compatibility tests', () => { const incrementFunctionData = contract2.interface.encodeFunctionData('increment', [1]); // Assert that the estimation fails because the increment function is not present in contract1 - expect( + await expect( alice.provider.estimateGas({ to: contract1Address.toString(), data: incrementFunctionData diff --git a/core/tests/upgrade-test/tests/upgrade.test.ts b/core/tests/upgrade-test/tests/upgrade.test.ts index ffa28e4f109..0f70e751b84 100644 --- a/core/tests/upgrade-test/tests/upgrade.test.ts +++ b/core/tests/upgrade-test/tests/upgrade.test.ts @@ -280,9 +280,11 @@ describe('Upgrade test', function () { ); executeOperation = chainUpgradeCalldata; + console.log('Sending scheduleTransparentOperation'); await sendGovernanceOperation(stmUpgradeData.scheduleTransparentOperation); + console.log('Sending executeOperation'); await sendGovernanceOperation(stmUpgradeData.executeOperation); - + console.log('Sending chain admin operation'); await sendChainAdminOperation(setTimestampCalldata); // Wait for server to process L1 event. @@ -371,23 +373,25 @@ describe('Upgrade test', function () { }); async function sendGovernanceOperation(data: string) { - await ( - await ecosystemGovWallet.sendTransaction({ - to: await governanceContract.getAddress(), - data: data, - type: 0 - }) - ).wait(); + const transaction = await ecosystemGovWallet.sendTransaction({ + to: await governanceContract.getAddress(), + data: data, + type: 0 + }); + console.log(`Sent governance operation, tx_hash=${transaction.hash}, nonce=${transaction.nonce}`); + await transaction.wait(); + console.log(`Governance operation succeeded, tx_hash=${transaction.hash}`); } async function sendChainAdminOperation(data: string) { - await ( - await adminGovWallet.sendTransaction({ - to: await chainAdminContract.getAddress(), - data: data, - type: 0 - }) - ).wait(); + const transaction = await adminGovWallet.sendTransaction({ + to: await chainAdminContract.getAddress(), + data: data, + type: 0 + }); + console.log(`Sent chain admin operation, tx_hash=${transaction.hash}, nonce=${transaction.nonce}`); + await transaction.wait(); + console.log(`Chain admin operation succeeded, tx_hash=${transaction.hash}`); } }); diff --git a/docker-compose-cpu-runner.yml b/docker-compose-cpu-runner.yml index 08d01390d77..beb54f3ade9 100644 --- a/docker-compose-cpu-runner.yml +++ b/docker-compose-cpu-runner.yml @@ -2,7 +2,7 @@ version: '3.2' services: reth: restart: always - image: "ghcr.io/paradigmxyz/reth:v0.2.0-beta.2" + image: "ghcr.io/paradigmxyz/reth:v1.0.6" volumes: - type: bind source: ./volumes/reth/data diff --git a/docker-compose-gpu-runner-cuda-12-0.yml b/docker-compose-gpu-runner-cuda-12-0.yml index 92a7b0b0088..35a0faeb962 100644 --- a/docker-compose-gpu-runner-cuda-12-0.yml +++ b/docker-compose-gpu-runner-cuda-12-0.yml @@ -2,7 +2,7 @@ version: '3.2' services: reth: restart: always - image: "ghcr.io/paradigmxyz/reth:v0.2.0-beta.2" + image: "ghcr.io/paradigmxyz/reth:v1.0.6" volumes: - type: bind source: ./volumes/reth/data diff --git a/docker-compose-gpu-runner.yml b/docker-compose-gpu-runner.yml index bbd61715842..f95ae0d5f54 100644 --- a/docker-compose-gpu-runner.yml +++ b/docker-compose-gpu-runner.yml @@ -2,7 +2,7 @@ version: '3.2' services: reth: restart: always - image: "ghcr.io/paradigmxyz/reth:v0.2.0-beta.2" + image: "ghcr.io/paradigmxyz/reth:v1.0.6" volumes: - type: bind source: ./volumes/reth/data diff --git a/docker-compose.yml b/docker-compose.yml index 7751c99d68a..1e3a273ec9a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.2' services: reth: restart: always - image: "ghcr.io/paradigmxyz/reth:v0.2.0-beta.2" + image: "ghcr.io/paradigmxyz/reth:v1.0.6" ports: - 127.0.0.1:8545:8545 volumes: