Skip to content

Commit 228bca0

Browse files
apollo_integration_tests: add proof flow integration test (#13950)
1 parent 3eb5573 commit 228bca0

6 files changed

Lines changed: 115 additions & 3 deletions

File tree

crates/apollo_integration_tests/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ metrics.workspace = true
9595
mockall.workspace = true
9696
rstest.workspace = true
9797

98+
[[bin]]
99+
name = "integration_test_proof_flow"
100+
path = "src/bin/sequencer_node_end_to_end_integration_tests/integration_test_proof_flow.rs"
101+
98102
[[bin]]
99103
name = "integration_test_positive_flow"
100104
path = "src/bin/sequencer_node_end_to_end_integration_tests/integration_test_positive_flow.rs"
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//! Integration test for the proof submission flow.
2+
//!
3+
//! The test relies on pre-generated fixture files in
4+
//! `crates/apollo_integration_tests/resources/proof_flow/`.
5+
6+
use apollo_infra_utils::test_utils::TestIdentifier;
7+
use apollo_integration_tests::integration_test_manager::{
8+
IntegrationTestManager,
9+
DEFAULT_SENDER_ACCOUNT,
10+
};
11+
use apollo_integration_tests::integration_test_utils::integration_test_setup;
12+
use apollo_integration_tests::utils::ProofFlowTxs;
13+
use blockifier::abi::constants::STORED_BLOCK_HASH_BUFFER;
14+
use starknet_api::block::BlockNumber;
15+
use tracing::info;
16+
17+
#[tokio::main]
18+
async fn main() {
19+
integration_test_setup("proof_flow").await;
20+
21+
// The fixture's proof references block 0, so the proof-bearing tx is only valid once the
22+
// chain has progressed past `STORED_BLOCK_HASH_BUFFER`. We first advance the chain past that
23+
// buffer with filler invokes, then submit the proof tx and wait one more block.
24+
const BLOCK_PAST_HASH_BUFFER: BlockNumber = BlockNumber(STORED_BLOCK_HASH_BUFFER);
25+
const BLOCK_TO_WAIT_FOR: BlockNumber = BlockNumber(STORED_BLOCK_HASH_BUFFER + 1);
26+
const N_CONSOLIDATED_SEQUENCERS: usize = 1;
27+
const N_DISTRIBUTED_SEQUENCERS: usize = 1;
28+
const N_HYBRID_SEQUENCERS: usize = 1;
29+
30+
let mut integration_test_manager = IntegrationTestManager::new(
31+
N_CONSOLIDATED_SEQUENCERS,
32+
N_DISTRIBUTED_SEQUENCERS,
33+
N_HYBRID_SEQUENCERS,
34+
None,
35+
TestIdentifier::ProofFlowIntegrationTest,
36+
)
37+
.await;
38+
39+
let node_indices = integration_test_manager.get_node_indices();
40+
integration_test_manager.run_nodes(node_indices.clone()).await;
41+
42+
integration_test_manager.send_deploy_and_invoke_txs_and_verify().await;
43+
44+
integration_test_manager.await_block_on_all_running_nodes(BLOCK_PAST_HASH_BUFFER).await;
45+
46+
integration_test_manager
47+
.test_and_verify(ProofFlowTxs::new(), DEFAULT_SENDER_ACCOUNT, BLOCK_TO_WAIT_FOR)
48+
.await;
49+
50+
info!("Shutting down nodes.");
51+
integration_test_manager.shutdown_nodes(node_indices);
52+
53+
info!("Proof flow integration test completed successfully!");
54+
}

crates/apollo_integration_tests/src/integration_test_manager.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,7 @@ impl IntegrationTestManager {
874874

875875
/// Waits until all running nodes reach the specified block number.
876876
/// Queries the batcher and state sync metrics to verify progress.
877-
async fn await_block_on_all_running_nodes(&self, expected_block_number: BlockNumber) {
877+
pub async fn await_block_on_all_running_nodes(&self, expected_block_number: BlockNumber) {
878878
self.perform_action_on_all_running_nodes(|running_node| {
879879
let node_setup = &running_node.node_setup;
880880
let batcher_monitoring_client = node_setup.batcher_monitoring_client();

crates/apollo_integration_tests/src/utils.rs

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::collections::HashMap;
22
use std::future::Future;
33
use std::net::{Ipv4Addr, SocketAddr};
44
use std::path::PathBuf;
5+
use std::sync::Arc;
56
use std::time::Duration;
67

78
use apollo_base_layer_tests::anvil_base_layer::AnvilBaseLayer;
@@ -117,9 +118,9 @@ use serde_json::{json, to_value};
117118
use starknet_api::block::BlockNumber;
118119
use starknet_api::core::{ChainId, ContractAddress};
119120
use starknet_api::execution_resources::GasAmount;
120-
use starknet_api::rpc_transaction::RpcTransaction;
121+
use starknet_api::rpc_transaction::{RpcInvokeTransaction, RpcTransaction};
121122
use starknet_api::staking::StakingWeight;
122-
use starknet_api::transaction::fields::ContractAddressSalt;
123+
use starknet_api::transaction::fields::{ContractAddressSalt, Proof, ProofFacts};
123124
use starknet_api::transaction::{L1HandlerTransaction, TransactionHash, TransactionHasher};
124125
use starknet_committer::db::forest_trait::{
125126
ForestMetadata,
@@ -231,6 +232,57 @@ impl TestScenario for DeployAndInvokeTxs {
231232
}
232233
}
233234

235+
fn load_proof_flow_proof_facts() -> ProofFacts {
236+
let path = concat!(env!("CARGO_MANIFEST_DIR"), "/resources/proof_flow/proof_facts.json");
237+
let json = std::fs::read_to_string(path)
238+
.expect("Failed to read proof_facts.json — run the fixture generator first");
239+
serde_json::from_str(&json).expect("Failed to parse proof_facts.json")
240+
}
241+
242+
fn load_proof_flow_proof() -> Proof {
243+
let path = concat!(env!("CARGO_MANIFEST_DIR"), "/resources/proof_flow/proof.bin");
244+
let bytes =
245+
std::fs::read(path).expect("Failed to read proof.bin — run the fixture generator first");
246+
Proof(Arc::new(bytes))
247+
}
248+
249+
pub struct ProofFlowTxs {
250+
proof_facts: ProofFacts,
251+
proof: Proof,
252+
}
253+
254+
impl Default for ProofFlowTxs {
255+
fn default() -> Self {
256+
Self::new()
257+
}
258+
}
259+
260+
impl ProofFlowTxs {
261+
pub fn new() -> Self {
262+
Self { proof_facts: load_proof_flow_proof_facts(), proof: load_proof_flow_proof() }
263+
}
264+
}
265+
266+
impl TestScenario for ProofFlowTxs {
267+
fn create_txs(
268+
&self,
269+
tx_generator: &mut MultiAccountTransactionGenerator,
270+
account_id: AccountId,
271+
) -> (Vec<RpcTransaction>, Vec<L1HandlerTransaction>) {
272+
let tx = tx_generator.account_with_id_mut(account_id).generate_trivial_rpc_invoke_tx(1);
273+
let RpcTransaction::Invoke(RpcInvokeTransaction::V3(mut inner)) = tx else {
274+
panic!("Expected RpcInvokeTransactionV3")
275+
};
276+
inner.proof_facts = self.proof_facts.clone();
277+
inner.proof = self.proof.clone();
278+
(vec![RpcTransaction::Invoke(RpcInvokeTransaction::V3(inner))], vec![])
279+
}
280+
281+
fn n_txs(&self) -> usize {
282+
1
283+
}
284+
}
285+
234286
// TODO(Tsabary): clean the passed args.
235287
#[allow(clippy::too_many_arguments)]
236288
pub fn create_node_config(

scripts/run_tests.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"integration_test_positive_flow",
2828
"integration_test_restart_service_multiple_nodes_flow",
2929
"integration_test_revert_flow",
30+
"integration_test_proof_flow",
3031
]
3132
NIGHTLY_ONLY_SEQUENCER_INTEGRATION_TEST_NAMES: List[str] = [
3233
# TODO(AndrewL): Try adding these tests to CI as well

scripts/sequencer_integration_test.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ declare -A TEST_ALIASES=(
2626
[restart_single_node]="integration_test_restart_service_single_node_flow"
2727
[revert]="integration_test_revert_flow"
2828
[sync]="integration_test_central_and_p2p_sync_flow"
29+
[proof]="integration_test_proof_flow"
2930
)
3031

3132
# Set default test if none provided

0 commit comments

Comments
 (0)