@aztec/end-to-end 0.0.1-commit.d431d1c → 0.0.1-commit.d58ff9d0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +217 -14
- package/dest/automine/automine_test_context.d.ts +85 -0
- package/dest/automine/automine_test_context.d.ts.map +1 -0
- package/dest/automine/automine_test_context.js +98 -0
- package/dest/automine/contracts/fixtures/storage_proof_fetcher.d.ts +2 -0
- package/dest/automine/contracts/fixtures/storage_proof_fetcher.d.ts.map +1 -0
- package/dest/automine/contracts/fixtures/storage_proof_fetcher.js +184 -0
- package/dest/automine/contracts/fixtures/storage_proof_fixture.d.ts +18 -0
- package/dest/automine/contracts/fixtures/storage_proof_fixture.d.ts.map +1 -0
- package/dest/automine/contracts/fixtures/storage_proof_fixture.js +120 -0
- package/dest/automine/delivery/interactive_handshake_responder.d.ts +48 -0
- package/dest/automine/delivery/interactive_handshake_responder.d.ts.map +1 -0
- package/dest/automine/delivery/interactive_handshake_responder.js +76 -0
- package/dest/automine/delivery/onchain_delivery_harness.d.ts +19 -0
- package/dest/automine/delivery/onchain_delivery_harness.d.ts.map +1 -0
- package/dest/automine/delivery/onchain_delivery_harness.js +141 -0
- package/dest/automine/token/blacklist_token_contract_test.d.ts +49 -0
- package/dest/automine/token/blacklist_token_contract_test.d.ts.map +1 -0
- package/dest/{e2e_blacklist_token_contract → automine/token}/blacklist_token_contract_test.js +50 -54
- package/dest/automine/token/token_contract_test.d.ts +40 -0
- package/dest/automine/token/token_contract_test.d.ts.map +1 -0
- package/dest/{e2e_token_contract → automine/token}/token_contract_test.js +44 -49
- package/dest/automine/token/token_test_helpers.d.ts +73 -0
- package/dest/automine/token/token_test_helpers.d.ts.map +1 -0
- package/dest/automine/token/token_test_helpers.js +97 -0
- package/dest/bench/client_flows/benchmark.d.ts +15 -1
- package/dest/bench/client_flows/benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/benchmark.js +19 -0
- package/dest/bench/client_flows/client_flows_benchmark.d.ts +6 -6
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.js +68 -44
- package/dest/bench/client_flows/config.d.ts +2 -2
- package/dest/bench/client_flows/config.d.ts.map +1 -1
- package/dest/bench/client_flows/config.js +18 -0
- package/dest/bench/client_flows/data_extractor.js +1 -0
- package/dest/bench/utils.d.ts +7 -6
- package/dest/bench/utils.d.ts.map +1 -1
- package/dest/bench/utils.js +108 -12
- package/dest/composed/ha/ha_full_setup.d.ts +77 -0
- package/dest/composed/ha/ha_full_setup.d.ts.map +1 -0
- package/dest/composed/ha/ha_full_setup.js +383 -0
- package/dest/composed/web3signer/multi_validator_keystore_utils.d.ts +12 -0
- package/dest/composed/web3signer/multi_validator_keystore_utils.d.ts.map +1 -0
- package/dest/fixtures/authwit_proxy.d.ts +15 -0
- package/dest/fixtures/authwit_proxy.d.ts.map +1 -0
- package/dest/fixtures/authwit_proxy.js +34 -0
- package/dest/fixtures/e2e_prover_test.d.ts +18 -14
- package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
- package/dest/fixtures/e2e_prover_test.js +85 -74
- package/dest/fixtures/elu_monitor.d.ts +21 -0
- package/dest/fixtures/elu_monitor.d.ts.map +1 -0
- package/dest/fixtures/elu_monitor.js +102 -0
- package/dest/fixtures/fixtures.d.ts +83 -1
- package/dest/fixtures/fixtures.d.ts.map +1 -1
- package/dest/fixtures/fixtures.js +86 -0
- package/dest/fixtures/get_bb_config.d.ts +1 -1
- package/dest/fixtures/get_bb_config.d.ts.map +1 -1
- package/dest/fixtures/get_bb_config.js +5 -5
- package/dest/fixtures/ha_setup.d.ts +71 -0
- package/dest/fixtures/ha_setup.d.ts.map +1 -0
- package/dest/fixtures/ha_setup.js +119 -0
- package/dest/fixtures/index.d.ts +3 -1
- package/dest/fixtures/index.d.ts.map +1 -1
- package/dest/fixtures/index.js +2 -0
- package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts +25 -0
- package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts.map +1 -0
- package/dest/fixtures/schnorr_hardcoded_account_contract.js +37 -0
- package/dest/fixtures/setup.d.ts +113 -60
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +330 -326
- package/dest/fixtures/setup_p2p_test.d.ts +22 -11
- package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.js +46 -35
- package/dest/fixtures/timing.d.ts +42 -0
- package/dest/fixtures/timing.d.ts.map +1 -0
- package/dest/fixtures/timing.js +72 -0
- package/dest/fixtures/token_utils.d.ts +22 -4
- package/dest/fixtures/token_utils.d.ts.map +1 -1
- package/dest/fixtures/token_utils.js +28 -7
- package/dest/fixtures/utils.d.ts +2 -2
- package/dest/fixtures/utils.d.ts.map +1 -1
- package/dest/fixtures/utils.js +1 -1
- package/dest/fixtures/wait_helpers.d.ts +135 -0
- package/dest/fixtures/wait_helpers.d.ts.map +1 -0
- package/dest/fixtures/wait_helpers.js +154 -0
- package/dest/forward-compatibility/wallet_rpc_client.d.ts +7 -0
- package/dest/forward-compatibility/wallet_rpc_client.d.ts.map +1 -0
- package/dest/forward-compatibility/wallet_rpc_client.js +15 -0
- package/dest/forward-compatibility/wallet_service.d.ts +3 -0
- package/dest/forward-compatibility/wallet_service.d.ts.map +1 -0
- package/dest/forward-compatibility/wallet_service.js +109 -0
- package/dest/install_legacy_contracts.d.cts +10 -0
- package/dest/install_legacy_contracts.d.cts.map +1 -0
- package/dest/legacy-jest-resolver.d.cts +3 -0
- package/dest/legacy-jest-resolver.d.cts.map +1 -0
- package/dest/multi-node/block-production/setup.d.ts +97 -0
- package/dest/multi-node/block-production/setup.d.ts.map +1 -0
- package/dest/multi-node/block-production/setup.js +158 -0
- package/dest/multi-node/governance/setup.d.ts +67 -0
- package/dest/multi-node/governance/setup.d.ts.map +1 -0
- package/dest/multi-node/governance/setup.js +126 -0
- package/dest/multi-node/multi_node_test_context.d.ts +212 -0
- package/dest/multi-node/multi_node_test_context.d.ts.map +1 -0
- package/dest/multi-node/multi_node_test_context.js +347 -0
- package/dest/multi-node/slashing/inactivity_setup.d.ts +27 -0
- package/dest/multi-node/slashing/inactivity_setup.d.ts.map +1 -0
- package/dest/multi-node/slashing/inactivity_setup.js +111 -0
- package/dest/multi-node/slashing/setup.d.ts +167 -0
- package/dest/multi-node/slashing/setup.d.ts.map +1 -0
- package/dest/multi-node/slashing/setup.js +275 -0
- package/dest/{e2e_p2p → p2p}/p2p_network.d.ts +22 -12
- package/dest/p2p/p2p_network.d.ts.map +1 -0
- package/dest/{e2e_p2p → p2p}/p2p_network.js +99 -35
- package/dest/p2p/reqresp/utils.d.ts +19 -0
- package/dest/p2p/reqresp/utils.d.ts.map +1 -0
- package/dest/p2p/reqresp/utils.js +193 -0
- package/dest/p2p/shared.d.ts +72 -0
- package/dest/p2p/shared.d.ts.map +1 -0
- package/dest/p2p/shared.js +212 -0
- package/dest/shared/cross_chain_test_harness.d.ts +8 -7
- package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
- package/dest/shared/cross_chain_test_harness.js +44 -39
- package/dest/shared/gas_portal_test_harness.d.ts +8 -5
- package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
- package/dest/shared/gas_portal_test_harness.js +27 -15
- package/dest/shared/index.d.ts +2 -1
- package/dest/shared/index.d.ts.map +1 -1
- package/dest/shared/index.js +1 -0
- package/dest/shared/jest_setup.js +41 -1
- package/dest/shared/mock_state_view.d.ts +86 -0
- package/dest/shared/mock_state_view.d.ts.map +1 -0
- package/dest/shared/mock_state_view.js +186 -0
- package/dest/shared/submit-transactions.d.ts +4 -4
- package/dest/shared/submit-transactions.d.ts.map +1 -1
- package/dest/shared/submit-transactions.js +19 -14
- package/dest/shared/timing_env.d.js +5 -0
- package/dest/shared/timing_env.js +365 -0
- package/dest/shared/uniswap_l1_l2.d.ts +1 -1
- package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
- package/dest/shared/uniswap_l1_l2.js +67 -55
- package/dest/shared/wait_for_l1_to_l2_message.d.ts +13 -0
- package/dest/shared/wait_for_l1_to_l2_message.d.ts.map +1 -0
- package/dest/shared/wait_for_l1_to_l2_message.js +10 -0
- package/dest/simulators/lending_simulator.d.ts +10 -3
- package/dest/simulators/lending_simulator.d.ts.map +1 -1
- package/dest/simulators/lending_simulator.js +29 -17
- package/dest/simulators/token_simulator.d.ts +1 -1
- package/dest/simulators/token_simulator.d.ts.map +1 -1
- package/dest/simulators/token_simulator.js +3 -24
- package/dest/single-node/cross-chain/cross_chain_messaging_test.d.ts +75 -0
- package/dest/single-node/cross-chain/cross_chain_messaging_test.d.ts.map +1 -0
- package/dest/single-node/cross-chain/cross_chain_messaging_test.js +209 -0
- package/dest/single-node/cross-chain/message_test_helpers.d.ts +38 -0
- package/dest/single-node/cross-chain/message_test_helpers.d.ts.map +1 -0
- package/dest/single-node/cross-chain/message_test_helpers.js +70 -0
- package/dest/{e2e_fees → single-node/fees}/bridging_race.notest.d.ts +1 -1
- package/dest/single-node/fees/bridging_race.notest.d.ts.map +1 -0
- package/dest/{e2e_fees → single-node/fees}/bridging_race.notest.js +18 -5
- package/dest/single-node/fees/fees_test.d.ts +93 -0
- package/dest/single-node/fees/fees_test.d.ts.map +1 -0
- package/dest/{e2e_fees → single-node/fees}/fees_test.js +96 -70
- package/dest/single-node/l1-reorgs/setup.d.ts +42 -0
- package/dest/single-node/l1-reorgs/setup.d.ts.map +1 -0
- package/dest/single-node/l1-reorgs/setup.js +57 -0
- package/dest/single-node/partial-proofs/setup.d.ts +5 -0
- package/dest/single-node/partial-proofs/setup.d.ts.map +1 -0
- package/dest/single-node/partial-proofs/setup.js +5 -0
- package/dest/single-node/proving/setup.d.ts +5 -0
- package/dest/single-node/proving/setup.d.ts.map +1 -0
- package/dest/single-node/proving/setup.js +5 -0
- package/dest/single-node/recovery/setup.d.ts +5 -0
- package/dest/single-node/recovery/setup.d.ts.map +1 -0
- package/dest/single-node/recovery/setup.js +5 -0
- package/dest/single-node/setup.d.ts +49 -0
- package/dest/single-node/setup.d.ts.map +1 -0
- package/dest/single-node/setup.js +56 -0
- package/dest/single-node/single_node_test_context.d.ts +360 -0
- package/dest/single-node/single_node_test_context.d.ts.map +1 -0
- package/dest/single-node/single_node_test_context.js +833 -0
- package/dest/spartan/setup_test_wallets.d.ts +12 -3
- package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
- package/dest/spartan/setup_test_wallets.js +153 -49
- package/dest/spartan/tx_metrics.d.ts +64 -5
- package/dest/spartan/tx_metrics.d.ts.map +1 -1
- package/dest/spartan/tx_metrics.js +280 -21
- package/dest/spartan/utils/bot.d.ts +28 -0
- package/dest/spartan/utils/bot.d.ts.map +1 -0
- package/dest/spartan/utils/bot.js +142 -0
- package/dest/spartan/utils/chaos.d.ts +79 -0
- package/dest/spartan/utils/chaos.d.ts.map +1 -0
- package/dest/spartan/utils/chaos.js +142 -0
- package/dest/spartan/utils/clients.d.ts +39 -0
- package/dest/spartan/utils/clients.d.ts.map +1 -0
- package/dest/spartan/utils/clients.js +90 -0
- package/dest/spartan/utils/config.d.ts +19 -0
- package/dest/spartan/utils/config.d.ts.map +1 -0
- package/dest/spartan/utils/config.js +23 -0
- package/dest/spartan/utils/health.d.ts +63 -0
- package/dest/spartan/utils/health.d.ts.map +1 -0
- package/dest/spartan/utils/health.js +202 -0
- package/dest/spartan/utils/helm.d.ts +15 -0
- package/dest/spartan/utils/helm.d.ts.map +1 -0
- package/dest/spartan/utils/helm.js +47 -0
- package/dest/spartan/utils/index.d.ts +11 -0
- package/dest/spartan/utils/index.d.ts.map +1 -0
- package/dest/spartan/utils/index.js +22 -0
- package/dest/spartan/utils/k8s.d.ts +128 -0
- package/dest/spartan/utils/k8s.d.ts.map +1 -0
- package/dest/spartan/utils/k8s.js +381 -0
- package/dest/spartan/utils/nodes.d.ts +40 -0
- package/dest/spartan/utils/nodes.d.ts.map +1 -0
- package/dest/spartan/utils/nodes.js +461 -0
- package/dest/spartan/utils/pod_logs.d.ts +25 -0
- package/dest/spartan/utils/pod_logs.d.ts.map +1 -0
- package/dest/spartan/utils/pod_logs.js +74 -0
- package/dest/spartan/utils/scripts.d.ts +30 -0
- package/dest/spartan/utils/scripts.d.ts.map +1 -0
- package/dest/spartan/utils/scripts.js +81 -0
- package/dest/spartan/utils.d.ts +2 -260
- package/dest/spartan/utils.d.ts.map +1 -1
- package/dest/spartan/utils.js +1 -942
- package/dest/test-wallet/test_wallet.d.ts +105 -0
- package/dest/test-wallet/test_wallet.d.ts.map +1 -0
- package/dest/test-wallet/test_wallet.js +320 -0
- package/dest/test-wallet/utils.d.ts +76 -0
- package/dest/test-wallet/utils.d.ts.map +1 -0
- package/dest/test-wallet/utils.js +126 -0
- package/dest/test-wallet/wallet_worker_script.d.ts +2 -0
- package/dest/test-wallet/wallet_worker_script.d.ts.map +1 -0
- package/dest/test-wallet/wallet_worker_script.js +56 -0
- package/dest/test-wallet/worker_wallet.d.ts +53 -0
- package/dest/test-wallet/worker_wallet.d.ts.map +1 -0
- package/dest/test-wallet/worker_wallet.js +157 -0
- package/dest/test-wallet/worker_wallet_schema.d.ts +4 -0
- package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -0
- package/dest/test-wallet/worker_wallet_schema.js +23 -0
- package/package.json +53 -46
- package/src/automine/README.md +60 -0
- package/src/automine/automine_test_context.ts +153 -0
- package/src/automine/contracts/fixtures/storage_proof.json +915 -0
- package/src/automine/contracts/fixtures/storage_proof_fetcher.ts +190 -0
- package/src/automine/contracts/fixtures/storage_proof_fixture.ts +173 -0
- package/src/automine/delivery/interactive_handshake_responder.ts +125 -0
- package/src/automine/delivery/onchain_delivery_harness.ts +213 -0
- package/src/{e2e_blacklist_token_contract → automine/token}/blacklist_token_contract_test.ts +56 -69
- package/src/{e2e_token_contract → automine/token}/token_contract_test.ts +51 -59
- package/src/automine/token/token_test_helpers.ts +138 -0
- package/src/bench/client_flows/benchmark.ts +21 -0
- package/src/bench/client_flows/client_flows_benchmark.ts +111 -90
- package/src/bench/client_flows/config.ts +9 -1
- package/src/bench/client_flows/data_extractor.ts +1 -0
- package/src/bench/utils.ts +123 -12
- package/src/composed/ha/ha_full_setup.ts +466 -0
- package/src/fixtures/authwit_proxy.ts +54 -0
- package/src/fixtures/dumps/epoch_proof_result.json +1 -1
- package/src/fixtures/e2e_prover_test.ts +102 -103
- package/src/fixtures/elu_monitor.ts +126 -0
- package/src/fixtures/fixtures.ts +110 -0
- package/src/fixtures/get_bb_config.ts +7 -6
- package/src/fixtures/ha_setup.ts +192 -0
- package/src/fixtures/index.ts +2 -0
- package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
- package/src/fixtures/setup.ts +421 -444
- package/src/fixtures/setup_p2p_test.ts +54 -54
- package/src/fixtures/timing.ts +97 -0
- package/src/fixtures/token_utils.ts +46 -10
- package/src/fixtures/utils.ts +2 -3
- package/src/fixtures/wait_helpers.ts +333 -0
- package/src/forward-compatibility/wallet_rpc_client.ts +14 -0
- package/src/forward-compatibility/wallet_service.ts +106 -0
- package/src/guides/up_quick_start.sh +7 -4
- package/src/infra/README.md +12 -0
- package/src/install_legacy_contracts.cjs +75 -0
- package/src/legacy-jest-resolver.cjs +112 -0
- package/src/multi-node/README.md +95 -0
- package/src/multi-node/block-production/setup.ts +272 -0
- package/src/multi-node/governance/setup.ts +172 -0
- package/src/multi-node/multi_node_test_context.ts +447 -0
- package/src/multi-node/slashing/inactivity_setup.ts +139 -0
- package/src/multi-node/slashing/setup.ts +433 -0
- package/src/p2p/README.md +78 -0
- package/src/{e2e_p2p → p2p}/p2p_network.ts +132 -57
- package/src/p2p/reqresp/utils.ts +263 -0
- package/src/p2p/shared.ts +329 -0
- package/src/shared/cross_chain_test_harness.ts +52 -41
- package/src/shared/gas_portal_test_harness.ts +34 -16
- package/src/shared/index.ts +1 -0
- package/src/shared/jest_setup.ts +51 -1
- package/src/shared/mock_state_view.ts +188 -0
- package/src/shared/submit-transactions.ts +22 -19
- package/src/shared/timing_env.d.mts +39 -0
- package/src/shared/timing_env.mjs +363 -0
- package/src/shared/uniswap_l1_l2.ts +109 -74
- package/src/shared/wait_for_l1_to_l2_message.ts +23 -0
- package/src/simulators/lending_simulator.ts +35 -17
- package/src/simulators/token_simulator.ts +6 -30
- package/src/single-node/README.md +60 -0
- package/src/single-node/cross-chain/cross_chain_messaging_test.ts +302 -0
- package/src/single-node/cross-chain/message_test_helpers.ts +125 -0
- package/src/{e2e_fees → single-node/fees}/bridging_race.notest.ts +20 -9
- package/src/{e2e_fees → single-node/fees}/fees_test.ts +120 -95
- package/src/single-node/l1-reorgs/setup.ts +93 -0
- package/src/single-node/partial-proofs/setup.ts +8 -0
- package/src/single-node/proving/setup.ts +15 -0
- package/src/single-node/recovery/setup.ts +8 -0
- package/src/single-node/setup.ts +63 -0
- package/src/single-node/single_node_test_context.ts +1041 -0
- package/src/spartan/setup_test_wallets.ts +208 -34
- package/src/spartan/tx_metrics.ts +255 -26
- package/src/spartan/utils/bot.ts +188 -0
- package/src/spartan/utils/chaos.ts +253 -0
- package/src/spartan/utils/clients.ts +100 -0
- package/src/spartan/utils/config.ts +29 -0
- package/src/spartan/utils/health.ts +255 -0
- package/src/spartan/utils/helm.ts +84 -0
- package/src/spartan/utils/index.ts +71 -0
- package/src/spartan/utils/k8s.ts +535 -0
- package/src/spartan/utils/nodes.ts +543 -0
- package/src/spartan/utils/pod_logs.ts +99 -0
- package/src/spartan/utils/scripts.ts +99 -0
- package/src/spartan/utils.ts +1 -1246
- package/src/test-wallet/test_wallet.ts +426 -0
- package/src/test-wallet/utils.ts +205 -0
- package/src/test-wallet/wallet_worker_script.ts +66 -0
- package/src/test-wallet/worker_wallet.ts +216 -0
- package/src/test-wallet/worker_wallet_schema.ts +14 -0
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +0 -53
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +0 -1
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +0 -47
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +0 -1
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +0 -128
- package/dest/e2e_deploy_contract/deploy_test.d.ts +0 -37
- package/dest/e2e_deploy_contract/deploy_test.d.ts.map +0 -1
- package/dest/e2e_deploy_contract/deploy_test.js +0 -50
- package/dest/e2e_epochs/epochs_test.d.ts +0 -94
- package/dest/e2e_epochs/epochs_test.d.ts.map +0 -1
- package/dest/e2e_epochs/epochs_test.js +0 -339
- package/dest/e2e_fees/bridging_race.notest.d.ts.map +0 -1
- package/dest/e2e_fees/fees_test.d.ts +0 -88
- package/dest/e2e_fees/fees_test.d.ts.map +0 -1
- package/dest/e2e_l1_publisher/write_json.d.ts +0 -10
- package/dest/e2e_l1_publisher/write_json.d.ts.map +0 -1
- package/dest/e2e_l1_publisher/write_json.js +0 -62
- package/dest/e2e_multi_validator/utils.d.ts +0 -12
- package/dest/e2e_multi_validator/utils.d.ts.map +0 -1
- package/dest/e2e_nested_contract/nested_contract_test.d.ts +0 -26
- package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +0 -1
- package/dest/e2e_nested_contract/nested_contract_test.js +0 -56
- package/dest/e2e_p2p/inactivity_slash_test.d.ts +0 -31
- package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +0 -1
- package/dest/e2e_p2p/inactivity_slash_test.js +0 -136
- package/dest/e2e_p2p/p2p_network.d.ts.map +0 -1
- package/dest/e2e_p2p/shared.d.ts +0 -46
- package/dest/e2e_p2p/shared.d.ts.map +0 -1
- package/dest/e2e_p2p/shared.js +0 -184
- package/dest/e2e_token_contract/token_contract_test.d.ts +0 -42
- package/dest/e2e_token_contract/token_contract_test.d.ts.map +0 -1
- package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +0 -194
- package/src/e2e_deploy_contract/deploy_test.ts +0 -85
- package/src/e2e_epochs/epochs_test.ts +0 -451
- package/src/e2e_l1_publisher/write_json.ts +0 -82
- package/src/e2e_nested_contract/nested_contract_test.ts +0 -75
- package/src/e2e_p2p/inactivity_slash_test.ts +0 -179
- package/src/e2e_p2p/shared.ts +0 -290
- /package/dest/{e2e_multi_validator/utils.js → composed/web3signer/multi_validator_keystore_utils.js} +0 -0
- /package/src/{e2e_multi_validator/utils.ts → composed/web3signer/multi_validator_keystore_utils.ts} +0 -0
|
@@ -11,18 +11,18 @@ import type { DeployAztecL1ContractsReturnType } from '@aztec/ethereum/deploy-az
|
|
|
11
11
|
import { deployL1Contract } from '@aztec/ethereum/deploy-l1-contract';
|
|
12
12
|
import type { ExtendedViemWalletClient } from '@aztec/ethereum/types';
|
|
13
13
|
import { extractEvent } from '@aztec/ethereum/utils';
|
|
14
|
-
import {
|
|
14
|
+
import { EpochNumber } from '@aztec/foundation/branded-types';
|
|
15
15
|
import { sha256ToField } from '@aztec/foundation/crypto/sha256';
|
|
16
|
+
import { retryUntil } from '@aztec/foundation/retry';
|
|
16
17
|
import { InboxAbi, UniswapPortalAbi, UniswapPortalBytecode } from '@aztec/l1-artifacts';
|
|
17
18
|
import { UniswapContract } from '@aztec/noir-contracts.js/Uniswap';
|
|
18
19
|
import { computeL2ToL1MessageHash } from '@aztec/stdlib/hash';
|
|
19
|
-
import { computeL2ToL1MembershipWitness } from '@aztec/stdlib/messaging';
|
|
20
|
-
import type { TestWallet } from '@aztec/test-wallet/server';
|
|
21
20
|
|
|
22
21
|
import { jest } from '@jest/globals';
|
|
23
22
|
import { type GetContractReturnType, getContract, parseEther, toFunctionSelector } from 'viem';
|
|
24
23
|
|
|
25
|
-
import { type EndToEndContext,
|
|
24
|
+
import { type EndToEndContext, ensureAuthRegistryPublished } from '../fixtures/utils.js';
|
|
25
|
+
import type { TestWallet } from '../test-wallet/test_wallet.js';
|
|
26
26
|
import { CrossChainTestHarness } from './cross_chain_test_harness.js';
|
|
27
27
|
|
|
28
28
|
// PSA: This tests works on forked mainnet. There is a dump of the data in `dumpedState` such that we
|
|
@@ -32,7 +32,7 @@ import { CrossChainTestHarness } from './cross_chain_test_harness.js';
|
|
|
32
32
|
// anvil --fork-url https://mainnet.infura.io/v3/9928b52099854248b3a096be07a6b23c --fork-block-number 17514288 --chain-id 31337
|
|
33
33
|
// For CI, this is configured in `run_tests.sh` and `docker-compose-images.yml`
|
|
34
34
|
|
|
35
|
-
const TIMEOUT =
|
|
35
|
+
const TIMEOUT = 15 * 60 * 1000;
|
|
36
36
|
|
|
37
37
|
export const uniswapL1L2TestSuite = (
|
|
38
38
|
setup: () => Promise<EndToEndContext>,
|
|
@@ -84,8 +84,6 @@ export const uniswapL1L2TestSuite = (
|
|
|
84
84
|
|
|
85
85
|
l1Client = deployL1ContractsValues.l1Client;
|
|
86
86
|
|
|
87
|
-
t.watcher?.setIsMarkingAsProven(false);
|
|
88
|
-
|
|
89
87
|
if (Number(await l1Client.getBlockNumber()) < expectedForkBlockNumber) {
|
|
90
88
|
throw new Error('This test must be run on a fork of mainnet with the expected fork block');
|
|
91
89
|
}
|
|
@@ -97,7 +95,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
97
95
|
version = Number(await rollup.getVersion());
|
|
98
96
|
ownerEthAddress = EthAddress.fromString((await l1Client.getAddresses())[0]);
|
|
99
97
|
|
|
100
|
-
await
|
|
98
|
+
await ensureAuthRegistryPublished(wallet, ownerAddress);
|
|
101
99
|
|
|
102
100
|
logger.info('Deploying DAI Portal, initializing and deploying l2 contract...');
|
|
103
101
|
daiCrossChainHarness = await CrossChainTestHarness.new(
|
|
@@ -130,9 +128,9 @@ export const uniswapL1L2TestSuite = (
|
|
|
130
128
|
client: l1Client,
|
|
131
129
|
});
|
|
132
130
|
// deploy l2 uniswap contract and attach to portal
|
|
133
|
-
uniswapL2Contract = await UniswapContract.deploy(wallet, uniswapPortalAddress)
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
({ contract: uniswapL2Contract } = await UniswapContract.deploy(wallet, uniswapPortalAddress).send({
|
|
132
|
+
from: ownerAddress,
|
|
133
|
+
}));
|
|
136
134
|
|
|
137
135
|
const registryAddress = (await aztecNode.getNodeInfo()).l1ContractAddresses.registryAddress;
|
|
138
136
|
|
|
@@ -154,7 +152,6 @@ export const uniswapL1L2TestSuite = (
|
|
|
154
152
|
await cleanup();
|
|
155
153
|
});
|
|
156
154
|
|
|
157
|
-
// docs:start:uniswap_private
|
|
158
155
|
it('should uniswap trade on L1 from L2 funds privately (swaps WETH -> DAI)', async () => {
|
|
159
156
|
const wethL1BeforeBalance = await wethCrossChainHarness.getL1BalanceOf(ownerEthAddress);
|
|
160
157
|
|
|
@@ -197,7 +194,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
197
194
|
logger.info('Withdrawing weth to L1 and sending message to swap to dai');
|
|
198
195
|
const [secretForDepositingSwappedDai, secretHashForDepositingSwappedDai] = await generateClaimSecret();
|
|
199
196
|
|
|
200
|
-
const l2UniswapInteractionReceipt = await uniswapL2Contract.methods
|
|
197
|
+
const { receipt: l2UniswapInteractionReceipt } = await uniswapL2Contract.methods
|
|
201
198
|
.swap_private(
|
|
202
199
|
wethCrossChainHarness.l2Token.address,
|
|
203
200
|
wethCrossChainHarness.l2Bridge.address,
|
|
@@ -209,8 +206,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
209
206
|
secretHashForDepositingSwappedDai,
|
|
210
207
|
ownerEthAddress,
|
|
211
208
|
)
|
|
212
|
-
.send({ from: ownerAddress, authWitnesses: [transferToPublicAuhtwit] })
|
|
213
|
-
.wait();
|
|
209
|
+
.send({ from: ownerAddress, authWitnesses: [transferToPublicAuhtwit] });
|
|
214
210
|
|
|
215
211
|
const swapPrivateFunction = 'swap_private(address,uint256,uint24,address,uint256,bytes32,address)';
|
|
216
212
|
const swapPrivateContent = sha256ToField([
|
|
@@ -252,10 +248,13 @@ export const uniswapL1L2TestSuite = (
|
|
|
252
248
|
// ensure that uniswap contract didn't eat the funds.
|
|
253
249
|
await wethCrossChainHarness.expectPublicBalanceOnL2(uniswapL2Contract.address, 0n);
|
|
254
250
|
|
|
255
|
-
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch
|
|
256
|
-
|
|
257
|
-
const
|
|
258
|
-
|
|
251
|
+
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch
|
|
252
|
+
// before we can ask the witness helper for a covering root.
|
|
253
|
+
const minedReceipt = await aztecNode.getTxReceipt(l2UniswapInteractionReceipt.txHash);
|
|
254
|
+
if (minedReceipt.epochNumber === undefined) {
|
|
255
|
+
throw new Error('L2 Uniswap interaction tx is not yet in an epoch');
|
|
256
|
+
}
|
|
257
|
+
await cheatCodes.rollup.advanceToEpoch(EpochNumber(minedReceipt.epochNumber + 1));
|
|
259
258
|
await waitForProven(aztecNode, l2UniswapInteractionReceipt, { provenTimeout: 300 });
|
|
260
259
|
|
|
261
260
|
// 5. Consume L2 to L1 message by calling uniswapPortal.swap_private()
|
|
@@ -263,17 +262,29 @@ export const uniswapL1L2TestSuite = (
|
|
|
263
262
|
const daiL1BalanceOfPortalBeforeSwap = await daiCrossChainHarness.getL1BalanceOf(
|
|
264
263
|
daiCrossChainHarness.tokenPortalAddress,
|
|
265
264
|
);
|
|
266
|
-
const swapResult = await
|
|
267
|
-
|
|
265
|
+
const swapResult = await retryUntil(
|
|
266
|
+
() => aztecNode.getL2ToL1MembershipWitness(minedReceipt.txHash, swapPrivateLeaf),
|
|
267
|
+
'swap private l2 to l1 witness',
|
|
268
|
+
60,
|
|
269
|
+
1,
|
|
270
|
+
);
|
|
271
|
+
const { epochNumber: epoch, numCheckpointsInEpoch } = swapResult;
|
|
272
|
+
const withdrawResult = await retryUntil(
|
|
273
|
+
() => aztecNode.getL2ToL1MembershipWitness(minedReceipt.txHash, withdrawLeaf),
|
|
274
|
+
'withdraw l2 to l1 witness',
|
|
275
|
+
60,
|
|
276
|
+
1,
|
|
277
|
+
);
|
|
268
278
|
|
|
269
|
-
const swapPrivateL2MessageIndex = swapResult
|
|
270
|
-
const swapPrivateSiblingPath = swapResult
|
|
279
|
+
const swapPrivateL2MessageIndex = swapResult.leafIndex;
|
|
280
|
+
const swapPrivateSiblingPath = swapResult.siblingPath;
|
|
271
281
|
|
|
272
|
-
const withdrawL2MessageIndex = withdrawResult
|
|
273
|
-
const withdrawSiblingPath = withdrawResult
|
|
282
|
+
const withdrawL2MessageIndex = withdrawResult.leafIndex;
|
|
283
|
+
const withdrawSiblingPath = withdrawResult.siblingPath;
|
|
274
284
|
|
|
275
285
|
const withdrawMessageMetadata = {
|
|
276
286
|
_epoch: BigInt(epoch),
|
|
287
|
+
_numCheckpointsInEpoch: BigInt(withdrawResult.numCheckpointsInEpoch),
|
|
277
288
|
_leafIndex: BigInt(withdrawL2MessageIndex),
|
|
278
289
|
_path: withdrawSiblingPath
|
|
279
290
|
.toBufferArray()
|
|
@@ -282,6 +293,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
282
293
|
|
|
283
294
|
const swapPrivateMessageMetadata = {
|
|
284
295
|
_epoch: BigInt(epoch),
|
|
296
|
+
_numCheckpointsInEpoch: BigInt(numCheckpointsInEpoch),
|
|
285
297
|
_leafIndex: BigInt(swapPrivateL2MessageIndex),
|
|
286
298
|
_path: swapPrivateSiblingPath
|
|
287
299
|
.toBufferArray()
|
|
@@ -339,10 +351,8 @@ export const uniswapL1L2TestSuite = (
|
|
|
339
351
|
logger.info('WETH balance after swap : ', wethL2BalanceAfterSwap.toString());
|
|
340
352
|
logger.info('DAI balance after swap : ', daiL2BalanceAfterSwap.toString());
|
|
341
353
|
});
|
|
342
|
-
// docs:end:uniswap_private
|
|
343
354
|
|
|
344
355
|
// TODO(#7463): reenable look into this failure https://github.com/AztecProtocol/aztec-packages/actions/runs/9912612912/job/27388320150?pr=7462
|
|
345
|
-
// // docs:start:uniswap_public
|
|
346
356
|
// it('should uniswap trade on L1 from L2 funds publicly (swaps WETH -> DAI)', async () => {
|
|
347
357
|
// const wethL1BeforeBalance = await wethCrossChainHarness.getL1BalanceOf(ownerEthAddress);
|
|
348
358
|
|
|
@@ -428,10 +438,10 @@ export const uniswapL1L2TestSuite = (
|
|
|
428
438
|
// ownerEthAddress,
|
|
429
439
|
// nonceForSwap,
|
|
430
440
|
// );
|
|
431
|
-
// await ownerWallet.setPublicAuthWit({ caller: sponsorAddress, action }, true).send()
|
|
441
|
+
// await ownerWallet.setPublicAuthWit({ caller: sponsorAddress, action }, true).send();
|
|
432
442
|
|
|
433
443
|
// // 4.2 Call swap_public from user2 on behalf of owner
|
|
434
|
-
// const uniswapL2Interaction = await action.send()
|
|
444
|
+
// const uniswapL2Interaction = await action.send();
|
|
435
445
|
|
|
436
446
|
// const swapPublicContent = sha256ToField([
|
|
437
447
|
// Buffer.from(
|
|
@@ -575,7 +585,6 @@ export const uniswapL1L2TestSuite = (
|
|
|
575
585
|
// logger.info('WETH balance after swap : ', wethL2BalanceAfterSwap.toString());
|
|
576
586
|
// logger.info('DAI balance after swap : ', daiL2BalanceAfterSwap.toString());
|
|
577
587
|
// });
|
|
578
|
-
// // docs:end:uniswap_public
|
|
579
588
|
|
|
580
589
|
// Edge cases for the private flow:
|
|
581
590
|
// note - tests for uniswapPortal.sol and minting asset on L2 are covered in other tests.
|
|
@@ -649,8 +658,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
649
658
|
Fr.random(),
|
|
650
659
|
ownerEthAddress,
|
|
651
660
|
)
|
|
652
|
-
.send({ from: ownerAddress, authWitnesses: [transferToPublicAuthwith] })
|
|
653
|
-
.wait(),
|
|
661
|
+
.send({ from: ownerAddress, authWitnesses: [transferToPublicAuthwith] }),
|
|
654
662
|
).rejects.toThrow('Assertion failed: input_asset address is not the same as seen in the bridge contract');
|
|
655
663
|
});
|
|
656
664
|
|
|
@@ -675,7 +683,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
675
683
|
},
|
|
676
684
|
true,
|
|
677
685
|
);
|
|
678
|
-
await validateActionInteraction.send()
|
|
686
|
+
await validateActionInteraction.send();
|
|
679
687
|
|
|
680
688
|
// No approval to call `swap` but should work even without it:
|
|
681
689
|
const [_, secretHashForDepositingSwappedDai] = await generateClaimSecret();
|
|
@@ -694,8 +702,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
694
702
|
ownerEthAddress,
|
|
695
703
|
Fr.ZERO, // nonce for swap -> doesn't matter
|
|
696
704
|
)
|
|
697
|
-
.send({ from: ownerAddress })
|
|
698
|
-
.wait();
|
|
705
|
+
.send({ from: ownerAddress });
|
|
699
706
|
// check weth balance of owner on L2 (we first bridged `wethAmountToBridge` into L2 and now withdrew it!)
|
|
700
707
|
await wethCrossChainHarness.expectPublicBalanceOnL2(ownerAddress, 0n);
|
|
701
708
|
});
|
|
@@ -725,7 +732,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
725
732
|
{ caller: approvedUser, action },
|
|
726
733
|
true,
|
|
727
734
|
);
|
|
728
|
-
await validateActionInteraction.send()
|
|
735
|
+
await validateActionInteraction.send();
|
|
729
736
|
|
|
730
737
|
await expect(action.simulate({ from: sponsorAddress })).rejects.toThrow(/unauthorized/);
|
|
731
738
|
});
|
|
@@ -747,7 +754,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
747
754
|
},
|
|
748
755
|
true,
|
|
749
756
|
);
|
|
750
|
-
await validateActionInteraction.send()
|
|
757
|
+
await validateActionInteraction.send();
|
|
751
758
|
|
|
752
759
|
await expect(
|
|
753
760
|
uniswapL2Contract.methods
|
|
@@ -792,7 +799,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
792
799
|
logger.info('Withdrawing weth to L1 and sending message to swap to dai');
|
|
793
800
|
|
|
794
801
|
const [, secretHashForDepositingSwappedDai] = await generateClaimSecret();
|
|
795
|
-
const withdrawReceipt = await uniswapL2Contract.methods
|
|
802
|
+
const { receipt: withdrawReceipt } = await uniswapL2Contract.methods
|
|
796
803
|
.swap_private(
|
|
797
804
|
wethCrossChainHarness.l2Token.address,
|
|
798
805
|
wethCrossChainHarness.l2Bridge.address,
|
|
@@ -804,8 +811,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
804
811
|
secretHashForDepositingSwappedDai,
|
|
805
812
|
ownerEthAddress,
|
|
806
813
|
)
|
|
807
|
-
.send({ from: ownerAddress, authWitnesses: [transferToPublicAuhtwit] })
|
|
808
|
-
.wait();
|
|
814
|
+
.send({ from: ownerAddress, authWitnesses: [transferToPublicAuhtwit] });
|
|
809
815
|
|
|
810
816
|
const swapPrivateContent = sha256ToField([
|
|
811
817
|
Buffer.from(
|
|
@@ -844,20 +850,41 @@ export const uniswapL1L2TestSuite = (
|
|
|
844
850
|
chainId: new Fr(l1Client.chain.id),
|
|
845
851
|
});
|
|
846
852
|
|
|
847
|
-
|
|
848
|
-
|
|
853
|
+
// ensure that user's funds were burnt
|
|
854
|
+
await wethCrossChainHarness.expectPrivateBalanceOnL2(ownerAddress, wethL2BalanceBeforeSwap - wethAmountToBridge);
|
|
855
|
+
|
|
856
|
+
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch
|
|
857
|
+
// before we can ask the witness helper for a covering root.
|
|
858
|
+
const minedReceipt = await aztecNode.getTxReceipt(withdrawReceipt.txHash);
|
|
859
|
+
if (minedReceipt.epochNumber === undefined) {
|
|
860
|
+
throw new Error('Withdraw tx is not yet in an epoch');
|
|
861
|
+
}
|
|
862
|
+
await cheatCodes.rollup.advanceToEpoch(EpochNumber(minedReceipt.epochNumber + 1));
|
|
863
|
+
await waitForProven(aztecNode, withdrawReceipt, { provenTimeout: 300 });
|
|
864
|
+
|
|
865
|
+
const swapResult = await retryUntil(
|
|
866
|
+
() => aztecNode.getL2ToL1MembershipWitness(minedReceipt.txHash, swapPrivateLeaf),
|
|
867
|
+
'swap private l2 to l1 witness',
|
|
868
|
+
60,
|
|
869
|
+
1,
|
|
870
|
+
);
|
|
871
|
+
const { epochNumber: epoch, numCheckpointsInEpoch } = swapResult;
|
|
872
|
+
const withdrawResult = await retryUntil(
|
|
873
|
+
() => aztecNode.getL2ToL1MembershipWitness(minedReceipt.txHash, withdrawLeaf),
|
|
874
|
+
'withdraw l2 to l1 witness',
|
|
875
|
+
60,
|
|
876
|
+
1,
|
|
849
877
|
);
|
|
850
|
-
const swapResult = await computeL2ToL1MembershipWitness(aztecNode, epoch, swapPrivateLeaf);
|
|
851
|
-
const withdrawResult = await computeL2ToL1MembershipWitness(aztecNode, epoch, withdrawLeaf);
|
|
852
878
|
|
|
853
|
-
const swapPrivateL2MessageIndex = swapResult
|
|
854
|
-
const swapPrivateSiblingPath = swapResult
|
|
879
|
+
const swapPrivateL2MessageIndex = swapResult.leafIndex;
|
|
880
|
+
const swapPrivateSiblingPath = swapResult.siblingPath;
|
|
855
881
|
|
|
856
|
-
const withdrawL2MessageIndex = withdrawResult
|
|
857
|
-
const withdrawSiblingPath = withdrawResult
|
|
882
|
+
const withdrawL2MessageIndex = withdrawResult.leafIndex;
|
|
883
|
+
const withdrawSiblingPath = withdrawResult.siblingPath;
|
|
858
884
|
|
|
859
885
|
const withdrawMessageMetadata = {
|
|
860
886
|
_epoch: BigInt(epoch),
|
|
887
|
+
_numCheckpointsInEpoch: BigInt(withdrawResult.numCheckpointsInEpoch),
|
|
861
888
|
_leafIndex: BigInt(withdrawL2MessageIndex),
|
|
862
889
|
_path: withdrawSiblingPath
|
|
863
890
|
.toBufferArray()
|
|
@@ -866,19 +893,13 @@ export const uniswapL1L2TestSuite = (
|
|
|
866
893
|
|
|
867
894
|
const swapPrivateMessageMetadata = {
|
|
868
895
|
_epoch: BigInt(epoch),
|
|
896
|
+
_numCheckpointsInEpoch: BigInt(numCheckpointsInEpoch),
|
|
869
897
|
_leafIndex: BigInt(swapPrivateL2MessageIndex),
|
|
870
898
|
_path: swapPrivateSiblingPath
|
|
871
899
|
.toBufferArray()
|
|
872
900
|
.map((buf: Buffer) => `0x${buf.toString('hex')}`) as readonly `0x${string}`[],
|
|
873
901
|
};
|
|
874
902
|
|
|
875
|
-
// ensure that user's funds were burnt
|
|
876
|
-
await wethCrossChainHarness.expectPrivateBalanceOnL2(ownerAddress, wethL2BalanceBeforeSwap - wethAmountToBridge);
|
|
877
|
-
|
|
878
|
-
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch.
|
|
879
|
-
await cheatCodes.rollup.advanceToEpoch(EpochNumber(epoch + 1));
|
|
880
|
-
await waitForProven(aztecNode, withdrawReceipt, { provenTimeout: 300 });
|
|
881
|
-
|
|
882
903
|
// On L1 call swap_public!
|
|
883
904
|
logger.info('call swap_public on L1');
|
|
884
905
|
const swapArgs = [
|
|
@@ -918,11 +939,11 @@ export const uniswapL1L2TestSuite = (
|
|
|
918
939
|
},
|
|
919
940
|
true,
|
|
920
941
|
);
|
|
921
|
-
await validateActionInteraction.send()
|
|
942
|
+
await validateActionInteraction.send();
|
|
922
943
|
|
|
923
944
|
// Call swap_public on L2
|
|
924
945
|
const secretHashForDepositingSwappedDai = Fr.random();
|
|
925
|
-
const withdrawReceipt = await uniswapL2Contract.methods
|
|
946
|
+
const { receipt: withdrawReceipt } = await uniswapL2Contract.methods
|
|
926
947
|
.swap_public(
|
|
927
948
|
ownerAddress,
|
|
928
949
|
wethCrossChainHarness.l2Bridge.address,
|
|
@@ -936,8 +957,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
936
957
|
ownerEthAddress,
|
|
937
958
|
Fr.ZERO,
|
|
938
959
|
)
|
|
939
|
-
.send({ from: ownerAddress })
|
|
940
|
-
.wait();
|
|
960
|
+
.send({ from: ownerAddress });
|
|
941
961
|
|
|
942
962
|
const swapPublicContent = sha256ToField([
|
|
943
963
|
Buffer.from(
|
|
@@ -979,20 +999,41 @@ export const uniswapL1L2TestSuite = (
|
|
|
979
999
|
chainId: new Fr(l1Client.chain.id),
|
|
980
1000
|
});
|
|
981
1001
|
|
|
982
|
-
|
|
983
|
-
|
|
1002
|
+
// check weth balance of owner on L2 (we first bridged `wethAmountToBridge` into L2 and now withdrew it!)
|
|
1003
|
+
await wethCrossChainHarness.expectPublicBalanceOnL2(ownerAddress, 0n);
|
|
1004
|
+
|
|
1005
|
+
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch
|
|
1006
|
+
// before we can ask the witness helper for a covering root.
|
|
1007
|
+
const minedReceipt = await aztecNode.getTxReceipt(withdrawReceipt.txHash);
|
|
1008
|
+
if (minedReceipt.epochNumber === undefined) {
|
|
1009
|
+
throw new Error('Withdraw tx is not yet in an epoch');
|
|
1010
|
+
}
|
|
1011
|
+
await cheatCodes.rollup.advanceToEpoch(EpochNumber(minedReceipt.epochNumber + 1));
|
|
1012
|
+
await waitForProven(aztecNode, withdrawReceipt, { provenTimeout: 300 });
|
|
1013
|
+
|
|
1014
|
+
const swapResult = await retryUntil(
|
|
1015
|
+
() => aztecNode.getL2ToL1MembershipWitness(minedReceipt.txHash, swapPublicLeaf),
|
|
1016
|
+
'swap public l2 to l1 witness',
|
|
1017
|
+
60,
|
|
1018
|
+
1,
|
|
1019
|
+
);
|
|
1020
|
+
const { epochNumber: epoch, numCheckpointsInEpoch } = swapResult;
|
|
1021
|
+
const withdrawResult = await retryUntil(
|
|
1022
|
+
() => aztecNode.getL2ToL1MembershipWitness(minedReceipt.txHash, withdrawLeaf),
|
|
1023
|
+
'withdraw l2 to l1 witness',
|
|
1024
|
+
60,
|
|
1025
|
+
1,
|
|
984
1026
|
);
|
|
985
|
-
const swapResult = await computeL2ToL1MembershipWitness(aztecNode, epoch, swapPublicLeaf);
|
|
986
|
-
const withdrawResult = await computeL2ToL1MembershipWitness(aztecNode, epoch, withdrawLeaf);
|
|
987
1027
|
|
|
988
|
-
const swapPublicL2MessageIndex = swapResult
|
|
989
|
-
const swapPublicSiblingPath = swapResult
|
|
1028
|
+
const swapPublicL2MessageIndex = swapResult.leafIndex;
|
|
1029
|
+
const swapPublicSiblingPath = swapResult.siblingPath;
|
|
990
1030
|
|
|
991
|
-
const withdrawL2MessageIndex = withdrawResult
|
|
992
|
-
const withdrawSiblingPath = withdrawResult
|
|
1031
|
+
const withdrawL2MessageIndex = withdrawResult.leafIndex;
|
|
1032
|
+
const withdrawSiblingPath = withdrawResult.siblingPath;
|
|
993
1033
|
|
|
994
1034
|
const withdrawMessageMetadata = {
|
|
995
1035
|
_epoch: BigInt(epoch),
|
|
1036
|
+
_numCheckpointsInEpoch: BigInt(withdrawResult.numCheckpointsInEpoch),
|
|
996
1037
|
_leafIndex: BigInt(withdrawL2MessageIndex),
|
|
997
1038
|
_path: withdrawSiblingPath
|
|
998
1039
|
.toBufferArray()
|
|
@@ -1001,19 +1042,13 @@ export const uniswapL1L2TestSuite = (
|
|
|
1001
1042
|
|
|
1002
1043
|
const swapPublicMessageMetadata = {
|
|
1003
1044
|
_epoch: BigInt(epoch),
|
|
1045
|
+
_numCheckpointsInEpoch: BigInt(numCheckpointsInEpoch),
|
|
1004
1046
|
_leafIndex: BigInt(swapPublicL2MessageIndex),
|
|
1005
1047
|
_path: swapPublicSiblingPath
|
|
1006
1048
|
.toBufferArray()
|
|
1007
1049
|
.map((buf: Buffer) => `0x${buf.toString('hex')}`) as readonly `0x${string}`[],
|
|
1008
1050
|
};
|
|
1009
1051
|
|
|
1010
|
-
// check weth balance of owner on L2 (we first bridged `wethAmountToBridge` into L2 and now withdrew it!)
|
|
1011
|
-
await wethCrossChainHarness.expectPublicBalanceOnL2(ownerAddress, 0n);
|
|
1012
|
-
|
|
1013
|
-
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch.
|
|
1014
|
-
await cheatCodes.rollup.advanceToEpoch(EpochNumber(epoch + 1));
|
|
1015
|
-
await waitForProven(aztecNode, withdrawReceipt, { provenTimeout: 300 });
|
|
1016
|
-
|
|
1017
1052
|
// Call swap_private on L1
|
|
1018
1053
|
logger.info('Execute withdraw and swap on the uniswapPortal!');
|
|
1019
1054
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Fr } from '@aztec/aztec.js/fields';
|
|
2
|
+
import type { AztecNode } from '@aztec/aztec.js/node';
|
|
3
|
+
import { retryUntil } from '@aztec/foundation/retry';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Waits until the archiver has seen the L1 to L2 message and indexed it. Unlike
|
|
7
|
+
* {@link waitForL1ToL2MessageReady} from `@aztec/aztec.js/messaging`, this does not
|
|
8
|
+
* require the L2 chain to have advanced to the message's checkpoint — it only confirms
|
|
9
|
+
* the message has been picked up from L1. Use this in tests that explicitly produce L2
|
|
10
|
+
* blocks afterwards to make the message consumable.
|
|
11
|
+
*/
|
|
12
|
+
export function waitForL1ToL2MessageSeen(
|
|
13
|
+
node: Pick<AztecNode, 'getL1ToL2MessageCheckpoint'>,
|
|
14
|
+
l1ToL2MessageHash: Fr,
|
|
15
|
+
opts: { timeoutSeconds: number },
|
|
16
|
+
) {
|
|
17
|
+
return retryUntil(
|
|
18
|
+
async () => (await node.getL1ToL2MessageCheckpoint(l1ToL2MessageHash)) !== undefined,
|
|
19
|
+
`L1 to L2 message ${l1ToL2MessageHash.toString()} seen`,
|
|
20
|
+
opts.timeoutSeconds,
|
|
21
|
+
0.25,
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -4,9 +4,10 @@ import { Fr } from '@aztec/aztec.js/fields';
|
|
|
4
4
|
import { CheatCodes } from '@aztec/aztec/testing';
|
|
5
5
|
import type { RollupContract } from '@aztec/ethereum/contracts';
|
|
6
6
|
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
7
|
-
import {
|
|
7
|
+
import { poseidon2Hash } from '@aztec/foundation/crypto/poseidon';
|
|
8
8
|
import type { TestDateProvider } from '@aztec/foundation/timer';
|
|
9
9
|
import type { LendingContract } from '@aztec/noir-contracts.js/Lending';
|
|
10
|
+
import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client';
|
|
10
11
|
|
|
11
12
|
import type { TokenSimulator } from './token_simulator.js';
|
|
12
13
|
|
|
@@ -29,7 +30,7 @@ export class LendingAccount {
|
|
|
29
30
|
* @returns Key in public space
|
|
30
31
|
*/
|
|
31
32
|
public key() {
|
|
32
|
-
return
|
|
33
|
+
return poseidon2Hash([this.address, this.secret]);
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
|
|
@@ -92,30 +93,45 @@ export class LendingSimulator {
|
|
|
92
93
|
public stableCoin: TokenSimulator,
|
|
93
94
|
) {}
|
|
94
95
|
|
|
95
|
-
|
|
96
|
+
prepare() {
|
|
96
97
|
this.accumulator = BASE;
|
|
97
|
-
|
|
98
|
-
this.time = Number(await this.rollup.getTimestampForSlot(slot));
|
|
98
|
+
this.time = 0;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Advances the simulator's accumulator and clock to match a block timestamp observed on chain.
|
|
103
|
+
* Call this BEFORE applying any accumulator-sensitive mutation (borrow/repay) so the mutation
|
|
104
|
+
* sees the same accumulator as the contract did during execution.
|
|
105
|
+
*/
|
|
106
|
+
observeBlockTimestamp(ts: number) {
|
|
107
|
+
const diff = ts - this.time;
|
|
108
|
+
if (diff > 0) {
|
|
109
|
+
this.accumulator = muldivDown(this.accumulator, computeMultiplier(this.rate, BigInt(diff)), BASE);
|
|
110
|
+
}
|
|
111
|
+
this.time = ts;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async progressSlots(diff: number, _dateProvider?: TestDateProvider, node?: AztecNode & AztecNodeDebug) {
|
|
102
115
|
if (diff <= 1) {
|
|
103
116
|
return;
|
|
104
117
|
}
|
|
105
118
|
|
|
106
|
-
const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.
|
|
119
|
+
const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.lastBlockTimestamp()));
|
|
107
120
|
const targetSlot = SlotNumber(slot + diff);
|
|
108
121
|
const ts = Number(await this.rollup.getTimestampForSlot(targetSlot));
|
|
109
|
-
const timeDiff = ts - this.time;
|
|
110
|
-
this.time = ts;
|
|
111
122
|
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
// Queue-aware warp under AutomineSequencer: atomic warp + mineBlock that advances L2 time to the
|
|
124
|
+
// target slot. The cheat code routes through the AutomineSequencer queue when one is installed,
|
|
125
|
+
// and otherwise falls back to a manual warp + mineBlock loop.
|
|
126
|
+
if (node) {
|
|
127
|
+
await this.cc.warpL2TimeAtLeastTo(node, ts);
|
|
128
|
+
} else {
|
|
129
|
+
await this.cc.eth.warp(ts - this.ethereumSlotDuration);
|
|
116
130
|
}
|
|
131
|
+
|
|
132
|
+
// Mark the latest checkpoint as proven so the rollup does not reorg pending checkpoints when
|
|
133
|
+
// time jumps far enough forward to cross an unproven epoch boundary.
|
|
117
134
|
await this.cc.rollup.markAsProven(await this.rollup.getCheckpointNumber());
|
|
118
|
-
this.accumulator = muldivDown(this.accumulator, computeMultiplier(this.rate, BigInt(timeDiff)), BASE);
|
|
119
135
|
}
|
|
120
136
|
|
|
121
137
|
depositPrivate(from: AztecAddress, onBehalfOf: Fr, amount: bigint) {
|
|
@@ -186,14 +202,16 @@ export class LendingSimulator {
|
|
|
186
202
|
|
|
187
203
|
expect(this.borrowed).toEqual(this.stableCoin.totalSupply - this.mintedOutside);
|
|
188
204
|
|
|
189
|
-
const asset = await this.lendingContract.methods.get_asset(0).simulate({ from: this.account.address });
|
|
205
|
+
const { result: asset } = await this.lendingContract.methods.get_asset(0).simulate({ from: this.account.address });
|
|
190
206
|
|
|
191
207
|
const interestAccumulator = asset['interest_accumulator'];
|
|
192
208
|
expect(interestAccumulator).toEqual(this.accumulator);
|
|
193
209
|
expect(asset['last_updated_ts']).toEqual(BigInt(this.time));
|
|
194
210
|
|
|
195
|
-
for (const key of [this.account.address, AztecAddress.
|
|
196
|
-
const privatePos = await this.lendingContract.methods
|
|
211
|
+
for (const key of [this.account.address, AztecAddress.fromFieldUnsafe(await this.account.key())]) {
|
|
212
|
+
const { result: privatePos } = await this.lendingContract.methods
|
|
213
|
+
.get_position(key)
|
|
214
|
+
.simulate({ from: this.account.address });
|
|
197
215
|
expect(new Fr(privatePos['collateral'])).toEqual(this.collateral[key.toString()] ?? Fr.ZERO);
|
|
198
216
|
expect(new Fr(privatePos['static_debt'])).toEqual(this.staticDebt[key.toString()] ?? Fr.ZERO);
|
|
199
217
|
expect(privatePos['debt']).toEqual(
|
|
@@ -109,7 +109,9 @@ export class TokenSimulator {
|
|
|
109
109
|
await Promise.all(
|
|
110
110
|
chunk(calls, 5).map(batch => new BatchCall(this.defaultWallet, batch).simulate({ from: this.defaultAddress })),
|
|
111
111
|
)
|
|
112
|
-
)
|
|
112
|
+
)
|
|
113
|
+
.flatMap(r => r.result)
|
|
114
|
+
.map(r => r.result);
|
|
113
115
|
expect(results[0]).toEqual(this.totalSupply);
|
|
114
116
|
|
|
115
117
|
// Check that all our balances match
|
|
@@ -119,39 +121,13 @@ export class TokenSimulator {
|
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
async checkPrivate() {
|
|
122
|
-
// Private calls
|
|
123
|
-
const defaultLookups = [];
|
|
124
|
-
const nonDefaultLookups = [];
|
|
125
|
-
|
|
126
124
|
for (const address of this.accounts) {
|
|
127
|
-
if (this.lookupProvider.has(address.toString())) {
|
|
128
|
-
nonDefaultLookups.push(address);
|
|
129
|
-
} else {
|
|
130
|
-
defaultLookups.push(address);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const defaultCalls = defaultLookups.map(address => this.token.methods.balance_of_private(address));
|
|
135
|
-
const results = (
|
|
136
|
-
await Promise.all(
|
|
137
|
-
chunk(defaultCalls, 4).map(batch =>
|
|
138
|
-
new BatchCall(this.defaultWallet, batch).simulate({ from: this.defaultAddress }),
|
|
139
|
-
),
|
|
140
|
-
)
|
|
141
|
-
).flat();
|
|
142
|
-
for (let i = 0; i < defaultLookups.length; i++) {
|
|
143
|
-
expect(results[i]).toEqual(this.balanceOfPrivate(defaultLookups[i]));
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// We are just running individual calls for the non-default lookups
|
|
147
|
-
// @todo We should also batch these
|
|
148
|
-
for (const address of nonDefaultLookups) {
|
|
149
125
|
const wallet = this.lookupProvider.get(address.toString());
|
|
150
126
|
const asset = wallet ? this.token.withWallet(wallet) : this.token;
|
|
151
127
|
|
|
152
|
-
const actualPrivateBalance = await asset.methods
|
|
153
|
-
.balance_of_private(
|
|
154
|
-
.simulate({ from:
|
|
128
|
+
const { result: actualPrivateBalance } = await asset.methods
|
|
129
|
+
.balance_of_private(address)
|
|
130
|
+
.simulate({ from: address });
|
|
155
131
|
expect(actualPrivateBalance).toEqual(this.balanceOfPrivate(address));
|
|
156
132
|
}
|
|
157
133
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# `single-node` e2e test category
|
|
2
|
+
|
|
3
|
+
Single-node tests run one Aztec node with the production sequencer (and, where a test needs proving,
|
|
4
|
+
a prover node). They cover behavior that only requires a single sequencer and no multi-validator
|
|
5
|
+
committee: block building, sequencer config and governance signalling, world-state sync, the
|
|
6
|
+
proving/epoch lifecycle, partial proofs, L1-reorg handling, and pending-chain recovery.
|
|
7
|
+
|
|
8
|
+
## Base class
|
|
9
|
+
|
|
10
|
+
All tests use `SingleNodeTestContext` (`single_node_test_context.ts`), which owns:
|
|
11
|
+
|
|
12
|
+
- The environment: an in-process anvil plus the L1 contract deploy.
|
|
13
|
+
- Node spawning: `createNonValidatorNode` and `createProverNode` (the latter wires the mock-gossip
|
|
14
|
+
`p2pServiceFactory`, which is harmless with a single node).
|
|
15
|
+
- The `ChainMonitor`.
|
|
16
|
+
- The epoch / checkpoint / proof-window / reorg waiters and assertion helpers (`waitUntilEpochStarts`,
|
|
17
|
+
`waitUntilProvenCheckpointNumber`, `waitForNodeToSync`, `verifyHistoricBlock`, …).
|
|
18
|
+
|
|
19
|
+
`MultiNodeTestContext` (in `../multi-node/`) extends this base with the N-validator topology, so the
|
|
20
|
+
multi-node category inherits the same environment and waiters.
|
|
21
|
+
|
|
22
|
+
## Setup factories
|
|
23
|
+
|
|
24
|
+
`setup.ts` holds thin factories over `SingleNodeTestContext.setup`, named by the prover mode a test
|
|
25
|
+
wants. Tests call the factory rather than the static method directly:
|
|
26
|
+
|
|
27
|
+
- `setupWithProver(opts)` — a single sequencer plus the context's fake in-process prover node. This is
|
|
28
|
+
the default the proving / partial-proofs / l1-reorgs / recovery / misc suites use.
|
|
29
|
+
- `setupBlockProducer(opts)` — a single production sequencer with **no prover node**, used by the
|
|
30
|
+
block-building / sequencer / sync suites. It raises `aztecProofSubmissionEpochs` to `1024` so unproven
|
|
31
|
+
blocks are not pruned without a prover, and points the PXE at `syncChainTip: 'proposed'` so tests can
|
|
32
|
+
assert on freshly proposed blocks. Both are overridable via `opts`.
|
|
33
|
+
|
|
34
|
+
The `prover/` suite (real Barretenberg proofs) builds its environment through `FullProverTest`, which
|
|
35
|
+
extends `SingleNodeTestContext` directly rather than going through a factory.
|
|
36
|
+
|
|
37
|
+
## Organizing principle
|
|
38
|
+
|
|
39
|
+
The top level groups tests by node topology and setup model; the second level names the primary
|
|
40
|
+
behavior under test (the proving lifecycle, partial proofs, reorgs, recovery) rather than the shared
|
|
41
|
+
setup. Each file has a single top-level `describe` named to match its path, and a co-located
|
|
42
|
+
`setup.ts` holds any shared timeout/option wiring. A `.parallel` suffix marks files with more than one
|
|
43
|
+
top-level `it`; CI splits each `it` into its own job.
|
|
44
|
+
|
|
45
|
+
## Subfolders
|
|
46
|
+
|
|
47
|
+
| Path | Contents |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `block-building/` | Block assembly mechanics under the production sequencer with pipelining. `block_building` (multi-tx blocks, double-spend rejection, log ordering, regressions, and L1 reorgs), `debug_trace` (blocks proposed through a Forwarder proxy, including a failing-then-succeeding propose call), `multiple_blobs` (a block whose combined side effects span more than one EIP-4844 blob). |
|
|
50
|
+
| `sequencer/` | Sequencer configuration, governance signalling, and publisher management on a single node. `gov_proposal.parallel` (a 16-validator committee proposes blocks while casting governance votes, and votes even when block building is disabled), `escape_hatch_vote_only` (governance signals advance while the escape hatch is closed), `reload_keystore` (the keystore is hot-reloaded to add a validator and pick up new coinbases), `slasher_config` (slasher config updated at runtime via the admin API), `multi_eoa` (publisher rotation when an L1 tx is withheld; exercises multi-EOA publisher failover), `publisher_funding_multi` (PublisherManager auto top-up of publisher EOAs when balances drop below threshold), `sequencer_config` (runtime `maxL2BlockGas`/`manaTarget` reconfiguration via a live Bot). |
|
|
51
|
+
| `fees/` | Fee mechanics on a single node. `fee_asset_price_oracle` (on-chain fee-asset price-oracle convergence; starts its own Anvil instance with a MockStateView etched at the StateView address). The remaining files run on the `FeesTest` harness (`fees_test.ts`), which extends `SingleNodeTestContext` with the fee/gas domain setup (FPC funding, fee-juice bridging, banana token): `account_init` (fee payment during account-contract initialization), `failures.parallel` (fees still charged when txs revert in setup/app/teardown), `fee_juice_payments` (direct Fee Juice payment with and without initial funds), `fee_settings` (max-fee-per-gas handling, stale-fee-snapshot race, governance fee-config bump), `gas_estimation.parallel` (gas-estimation accuracy and FPC teardown gas prediction), `private_payments.parallel` (private fee payment via the BananaCoin FPC), `public_payments` (public fee payment via the BananaCoin FPC), `sponsored_payments` (sponsored fee payment via SponsoredFPC). |
|
|
52
|
+
| `cross-chain/` | L1↔L2 messaging on a single node, on the `CrossChainMessagingTest` harness (`cross_chain_messaging_test.ts`), which extends `SingleNodeTestContext` and owns a `CrossChainTestHarness` plus the L1 inbox/outbox handles (it auto-proves via an `EpochTestSettler` when no prover node runs). `l1_to_l2.parallel` (L1→L2 message readiness, duplicate messages, and inbox drift after a rollup reorg), `l2_to_l1.parallel` (L2→L1 message inclusion across single/multi-message txs, subtree-root balancing, and a reorg-and-remine case), `token_bridge_private.parallel` (private L1→L2 deposit and L2→L1 withdrawal via the TokenBridge), `token_bridge_public.parallel` (public L1→L2 deposit and L2→L1 withdrawal, including mint-on-behalf), `token_bridge_failure_cases.parallel` (rejected withdrawals without approval and mismatched public/private claim attempts). |
|
|
53
|
+
| `bot/` | Transaction bot implementations. `bot` (transfer bot, AMM bot, and cross-chain bot; exercises fee-juice portal deposits, L2→L1 messages, and bot contract reuse). |
|
|
54
|
+
| `sync/` | World-state sync stress and reorg-replay harness. `synching` builds fixture block data (env-gated, slow) and replays it for sync benchmarks and prune/reorg scenarios; only the outer `it.each` runs in CI. |
|
|
55
|
+
| `proving/` | Epoch and proof lifecycle. `world_state_pruning` (consecutive epochs prove and finalized blocks are purged from world state beyond the checkpoint-history window), `empty_blocks` (a proof is submitted even with no txs), `long_proving_time` (a prover delay spanning multiple epochs), `multi_proof` (multiple prover nodes prove one epoch), `optimistic.parallel` (checkpoint-driven proving across the happy path and several mid-epoch / last-slot / during-proving reorg cases), `proof_fails.parallel` (proof not accepted after epoch end; proving aborts when the next epoch ends), `cross_chain_public_message` (an epoch with a public tx that consumes an L1→L2 message in the block it lands, guarding against a sequencer/prover state-root mismatch), `upload_failed_proof` (a failed proving job's state is uploaded and re-run on a fresh instance). |
|
|
56
|
+
| `prover/` | Real-proof exercises on the `FullProverTest` harness (real Barretenberg when `FAKE_PROOFS=0`, fake otherwise). `client` (client-side proof generation and `verifyProof` for private and public transfers, no on-chain submission) and `full` (the end-to-end pipeline: client proves, node builds blocks, prover node generates epoch proofs, L1 verifies them). |
|
|
57
|
+
| `partial-proofs/` | Manually driven partial-proof submission. `single_root` (the prover node's `startProof` path on a single root) and `multi_root` (three partial-proof roots are staged and messages consume against any covering root, exercising the multi-root Outbox semantics). |
|
|
58
|
+
| `l1-reorgs/` | Behavior under L1 reorgs, split by what reorgs. `blocks.parallel` (prune L2 blocks when a reorg drops a proof, hold when a replacement proof lands in the window, restore blocks when a proof reappears, prune pending-chain blocks, and see new blocks added by a reorg) and `messages.parallel` (L1→L2 messages updated by a reorg, and a missed message inserted by one). `setup.ts` holds the shared `FAST_REORG_TIMING` profile and delayer wiring. |
|
|
59
|
+
| `recovery/` | Reorg and pending-chain recovery. `manual_rollback` (the `rollbackTo` admin API rolls back to an unfinalized block), `sync_after_reorg` (a fresh node syncs world state past an unpruned reorg window), `prune_when_cannot_build` (a solo sequencer prunes the pending chain via the fallback path when it cannot propose). |
|
|
60
|
+
| `misc/` | Genuine single-node outliers. `missed_l1_slot` (the sequencer builds a block after missed L1 slots once the previous checkpoint is synced). |
|