From 5761a0dcfeb85b16091dd6e011fcd16480735c41 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Tue, 5 Nov 2024 19:59:46 +0700 Subject: [PATCH 1/4] Add tests --- tests/bitcoin.rs | 114 +++++++++++++++++++++++++++++++++++++++++++++++ tests/docker.rs | 71 +++++++++++++++++++++++++++++ tests/mod.rs | 73 +----------------------------- 3 files changed, 187 insertions(+), 71 deletions(-) create mode 100644 tests/bitcoin.rs create mode 100644 tests/docker.rs diff --git a/tests/bitcoin.rs b/tests/bitcoin.rs new file mode 100644 index 0000000..57721b1 --- /dev/null +++ b/tests/bitcoin.rs @@ -0,0 +1,114 @@ +use std::time::Duration; + +use anyhow::bail; +use async_trait::async_trait; +use bitcoincore_rpc::{json::IndexStatus, RpcApi}; +use citrea_e2e::{ + config::{BitcoinConfig, TestCaseConfig}, + framework::TestFramework, + test_case::{TestCase, TestCaseRunner}, + traits::Restart, + Result, +}; + +struct BasicSyncTest; + +#[async_trait] +impl TestCase for BasicSyncTest { + fn test_config() -> TestCaseConfig { + TestCaseConfig { + with_sequencer: false, + n_nodes: 2, + timeout: Duration::from_secs(60), + ..Default::default() + } + } + + async fn run_test(&mut self, f: &mut TestFramework) -> Result<()> { + let (Some(da0), Some(da1)) = (f.bitcoin_nodes.get(0), f.bitcoin_nodes.get(1)) else { + bail!("bitcoind not running. Test should run with two da nodes") + }; + let initial_height = f.initial_da_height; + + // Generate some blocks on node0 + da0.generate(5, None).await?; + + let height0 = da0.get_block_count().await?; + let height1 = da1.get_block_count().await?; + + // Nodes are now out of sync + assert_eq!(height0, initial_height + 5); + assert_eq!(height1, 0); + + // Sync both nodes + f.bitcoin_nodes + .wait_for_sync(Some(Duration::from_secs(30))) + .await?; + + let height0 = da0.get_block_count().await?; + let height1 = da1.get_block_count().await?; + + // Assert that nodes are in sync + assert_eq!(height0, height1, "Block heights don't match"); + + Ok(()) + } +} + +#[tokio::test] +async fn test_basic_sync() -> Result<()> { + TestCaseRunner::new(BasicSyncTest).run().await +} + +struct RestartBitcoinTest; + +#[async_trait] +impl TestCase for RestartBitcoinTest { + fn test_config() -> TestCaseConfig { + TestCaseConfig { + with_sequencer: false, + ..Default::default() + } + } + + fn bitcoin_config() -> BitcoinConfig { + BitcoinConfig { + extra_args: vec!["-txindex=0"], + ..Default::default() + } + } + + async fn run_test(&mut self, f: &mut TestFramework) -> Result<()> { + let da = f.bitcoin_nodes.get_mut(0).unwrap(); + // Add txindex flag to check that restart takes into account the extra args + let new_conf = BitcoinConfig { + extra_args: vec!["-txindex=1"], + ..da.config.clone() + }; + + let block_before = da.get_block_count().await?; + let info = da.get_index_info().await?; + + assert_eq!(info.txindex, None); + + // Restart node with txindex + da.restart(Some(new_conf)).await?; + + let block_after = da.get_block_count().await?; + let info = da.get_index_info().await?; + + assert!(matches!( + info.txindex, + Some(IndexStatus { synced: true, .. }) + )); + // Assert that state is kept between restarts + assert_eq!(block_before, block_after); + + Ok(()) + } +} + +#[tokio::test] +async fn test_restart_bitcoin() -> Result<()> { + TestCaseRunner::new(RestartBitcoinTest).run().await +} diff --git a/tests/docker.rs b/tests/docker.rs new file mode 100644 index 0000000..3399098 --- /dev/null +++ b/tests/docker.rs @@ -0,0 +1,71 @@ +use async_trait::async_trait; +use bitcoincore_rpc::RpcApi; +use citrea_e2e::{ + bitcoin::FINALITY_DEPTH, + config::{TestCaseConfig, TestCaseDockerConfig}, + framework::TestFramework, + test_case::{TestCase, TestCaseRunner}, + Result, +}; + +struct DockerIntegrationTest; + +#[async_trait] +impl TestCase for DockerIntegrationTest { + fn test_config() -> TestCaseConfig { + TestCaseConfig { + with_batch_prover: true, + with_full_node: true, + docker: TestCaseDockerConfig { + bitcoin: true, + citrea: true, + }, + ..Default::default() + } + } + + async fn run_test(&mut self, f: &mut TestFramework) -> Result<()> { + let sequencer = f.sequencer.as_ref().unwrap(); + let batch_prover = f.batch_prover.as_ref().unwrap(); + let full_node = f.full_node.as_ref().unwrap(); + let da = f.bitcoin_nodes.get(0).unwrap(); + + let min_soft_confirmations_per_commitment = + sequencer.min_soft_confirmations_per_commitment(); + + for _ in 0..min_soft_confirmations_per_commitment { + sequencer.client.send_publish_batch_request().await?; + } + + // Wait for blob inscribe tx to be in mempool + da.wait_mempool_len(1, None).await?; + + da.generate(FINALITY_DEPTH, None).await?; + let finalized_height = da.get_finalized_height().await?; + + batch_prover + .wait_for_l1_height(finalized_height, None) + .await?; + + let commitments = full_node + .wait_for_sequencer_commitments(finalized_height, None) + .await?; + + assert_eq!(commitments.len(), 1); + + let unspent_sequencer = sequencer + .da + .list_unspent(None, None, None, None, None) + .await?; + let unspent_da = da.list_unspent(None, None, None, None, None).await?; + // Make sure sequencer.da and da don't hit the same wallet + assert_ne!(unspent_sequencer, unspent_da); + + Ok(()) + } +} + +#[tokio::test] +async fn test_docker_integration() -> Result<()> { + TestCaseRunner::new(DockerIntegrationTest).run().await +} diff --git a/tests/mod.rs b/tests/mod.rs index 3399098..eab0ee4 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -1,71 +1,2 @@ -use async_trait::async_trait; -use bitcoincore_rpc::RpcApi; -use citrea_e2e::{ - bitcoin::FINALITY_DEPTH, - config::{TestCaseConfig, TestCaseDockerConfig}, - framework::TestFramework, - test_case::{TestCase, TestCaseRunner}, - Result, -}; - -struct DockerIntegrationTest; - -#[async_trait] -impl TestCase for DockerIntegrationTest { - fn test_config() -> TestCaseConfig { - TestCaseConfig { - with_batch_prover: true, - with_full_node: true, - docker: TestCaseDockerConfig { - bitcoin: true, - citrea: true, - }, - ..Default::default() - } - } - - async fn run_test(&mut self, f: &mut TestFramework) -> Result<()> { - let sequencer = f.sequencer.as_ref().unwrap(); - let batch_prover = f.batch_prover.as_ref().unwrap(); - let full_node = f.full_node.as_ref().unwrap(); - let da = f.bitcoin_nodes.get(0).unwrap(); - - let min_soft_confirmations_per_commitment = - sequencer.min_soft_confirmations_per_commitment(); - - for _ in 0..min_soft_confirmations_per_commitment { - sequencer.client.send_publish_batch_request().await?; - } - - // Wait for blob inscribe tx to be in mempool - da.wait_mempool_len(1, None).await?; - - da.generate(FINALITY_DEPTH, None).await?; - let finalized_height = da.get_finalized_height().await?; - - batch_prover - .wait_for_l1_height(finalized_height, None) - .await?; - - let commitments = full_node - .wait_for_sequencer_commitments(finalized_height, None) - .await?; - - assert_eq!(commitments.len(), 1); - - let unspent_sequencer = sequencer - .da - .list_unspent(None, None, None, None, None) - .await?; - let unspent_da = da.list_unspent(None, None, None, None, None).await?; - // Make sure sequencer.da and da don't hit the same wallet - assert_ne!(unspent_sequencer, unspent_da); - - Ok(()) - } -} - -#[tokio::test] -async fn test_docker_integration() -> Result<()> { - TestCaseRunner::new(DockerIntegrationTest).run().await -} +mod bitcoin; +mod docker; From 5faa8412d5b940b69754d71b9e3e3ed959581ff7 Mon Sep 17 00:00:00 2001 From: jfldde <168934971+jfldde@users.noreply.github.com> Date: Tue, 5 Nov 2024 22:08:58 +0000 Subject: [PATCH 2/4] More explicit sync testing --- tests/bitcoin.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/tests/bitcoin.rs b/tests/bitcoin.rs index 57721b1..ed0df6c 100644 --- a/tests/bitcoin.rs +++ b/tests/bitcoin.rs @@ -30,6 +30,15 @@ impl TestCase for BasicSyncTest { }; let initial_height = f.initial_da_height; + f.bitcoin_nodes.wait_for_sync(None).await?; + let height0 = da0.get_block_count().await?; + let height1 = da1.get_block_count().await?; + + // Assert that nodes are in sync before disconnection + assert_eq!(height0, height1, "Block heights don't match"); + + f.bitcoin_nodes.disconnect_nodes().await?; + // Generate some blocks on node0 da0.generate(5, None).await?; @@ -38,17 +47,16 @@ impl TestCase for BasicSyncTest { // Nodes are now out of sync assert_eq!(height0, initial_height + 5); - assert_eq!(height1, 0); + assert_eq!(height1, initial_height); - // Sync both nodes - f.bitcoin_nodes - .wait_for_sync(Some(Duration::from_secs(30))) - .await?; + // Reconnect nodes and sync + f.bitcoin_nodes.connect_nodes().await?; + f.bitcoin_nodes.wait_for_sync(None).await?; let height0 = da0.get_block_count().await?; let height1 = da1.get_block_count().await?; - // Assert that nodes are in sync + // Assert that nodes are back in sync assert_eq!(height0, height1, "Block heights don't match"); Ok(()) From 99c7f81c80d5f5f3c0c1276fc17a7e90f7bb4368 Mon Sep 17 00:00:00 2001 From: jfldde <168934971+jfldde@users.noreply.github.com> Date: Tue, 5 Nov 2024 22:14:50 +0000 Subject: [PATCH 3/4] Run tests fully in docker for now --- tests/bitcoin.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/bitcoin.rs b/tests/bitcoin.rs index ed0df6c..e21f176 100644 --- a/tests/bitcoin.rs +++ b/tests/bitcoin.rs @@ -4,7 +4,7 @@ use anyhow::bail; use async_trait::async_trait; use bitcoincore_rpc::{json::IndexStatus, RpcApi}; use citrea_e2e::{ - config::{BitcoinConfig, TestCaseConfig}, + config::{BitcoinConfig, TestCaseConfig, TestCaseDockerConfig}, framework::TestFramework, test_case::{TestCase, TestCaseRunner}, traits::Restart, @@ -20,6 +20,10 @@ impl TestCase for BasicSyncTest { with_sequencer: false, n_nodes: 2, timeout: Duration::from_secs(60), + docker: TestCaseDockerConfig { + bitcoin: true, + citrea: true, + }, ..Default::default() } } @@ -75,6 +79,10 @@ impl TestCase for RestartBitcoinTest { fn test_config() -> TestCaseConfig { TestCaseConfig { with_sequencer: false, + docker: TestCaseDockerConfig { + bitcoin: true, + citrea: true, + }, ..Default::default() } } From b79d24bc186a3c22db158e1fba7f54248356ead9 Mon Sep 17 00:00:00 2001 From: jfldde <168934971+jfldde@users.noreply.github.com> Date: Tue, 5 Nov 2024 22:31:03 +0000 Subject: [PATCH 4/4] Bump bitcoincore-rpc --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index aa0eb1a..0f62012 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,4 +27,4 @@ sov-ledger-rpc = { git = "https://github.com/chainwayxyz/citrea", rev = "42693cc sov-rollup-interface = { git = "https://github.com/chainwayxyz/citrea", rev = "42693cc"} [patch.crates-io] -bitcoincore-rpc = { version = "0.18.0", git = "https://github.com/chainwayxyz/rust-bitcoincore-rpc.git", rev = "ede8097" } +bitcoincore-rpc = { version = "0.18.0", git = "https://github.com/chainwayxyz/rust-bitcoincore-rpc.git", rev = "5ce1bed" }