Skip to content

Commit 7bf8d3e

Browse files
committed
feature: ensure chain state is consistent across nodes
1 parent 19ec171 commit 7bf8d3e

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

tests/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ uuid.workspace = true
3131
tracing-subscriber.workspace = true
3232
bip39.workspace = true
3333
clap.workspace = true
34-
34+
tonic.workspace = true
3535
abci = { path = "../crates/abci" }
3636
protocol = { path = "../crates/protocol" }
3737
node = { path = "../crates/node" }

tests/src/bin/integration-tests/main.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use node::key_manager::generate_keys_from_mnemonic;
1010
use node::wallet::{TaprootWallet, Wallet};
1111
use oracle::esplora::EsploraOracle;
1212
use oracle::oracle::Oracle;
13+
use tonic::transport::Channel;
1314
use types::proto::node_proto::node_control_client::NodeControlClient;
1415
use types::proto::node_proto::{
1516
CheckBalanceRequest, ConfirmWithdrawalRequest, CreateDepositIntentRequest, GetChainInfoRequest,
@@ -658,6 +659,9 @@ async fn run_consensus_test(
658659
}
659660
}
660661

662+
println!("🔗 Verifying chain state consistency across nodes");
663+
verify_chain_state_consistency(&mut clients).await?;
664+
661665
// Check final balances to verify transaction execution
662666
println!("🔍 Verifying transaction execution across nodes");
663667
let mut execution_consistent = true;
@@ -764,3 +768,48 @@ where
764768
tokio::time::sleep(poll_interval).await;
765769
}
766770
}
771+
772+
async fn verify_chain_state_consistency(
773+
clients: &mut [NodeControlClient<Channel>],
774+
) -> Result<(), Box<dyn std::error::Error>> {
775+
use types::proto::node_proto::GetChainInfoRequest;
776+
777+
let mut reference_height: Option<u64> = None;
778+
let mut reference_hash: Option<String> = None;
779+
780+
for (idx, client) in clients.iter_mut().enumerate() {
781+
let info = client
782+
.get_chain_info(GetChainInfoRequest {})
783+
.await?
784+
.into_inner();
785+
786+
println!(
787+
" 🌐 Node {}: height={} | hash={}",
788+
idx + 1,
789+
info.latest_height,
790+
info.latest_block_hash
791+
);
792+
793+
if let Some(h) = reference_height {
794+
if let Some(hash) = &reference_hash {
795+
if h != info.latest_height || hash != &info.latest_block_hash {
796+
return Err(format!(
797+
"Chain state mismatch on node {} (height/hash differ)",
798+
idx + 1
799+
)
800+
.into());
801+
}
802+
}
803+
} else {
804+
reference_height = Some(info.latest_height);
805+
reference_hash = Some(info.latest_block_hash);
806+
}
807+
}
808+
809+
println!(
810+
" ✅ Chain state is consistent across all {} nodes",
811+
clients.len()
812+
);
813+
814+
Ok(())
815+
}

0 commit comments

Comments
 (0)