#![allow(clippy::unwrap_in_result)]
use std::{collections::HashMap, iter, sync::Arc, time::Duration};
use color_eyre::Report;
use futures::{Future, FutureExt};
use zebra_chain::{
block::{self, Block, Height},
chain_tip::mock::{MockChainTip, MockChainTipSender},
serialization::ZcashDeserializeInto,
};
use zebra_consensus::{Config as ConsensusConfig, RouterError, VerifyBlockError};
use zebra_network::InventoryResponse;
use zebra_state::Config as StateConfig;
use zebra_test::mock_service::{MockService, PanicAssertion};
use zebra_network as zn;
use zebra_state as zs;
use crate::{
components::{
sync::{self, downloads::BlockDownloadVerifyError, SyncStatus},
ChainSync,
},
config::ZebradConfig,
};
use InventoryResponse::*;
const MAX_SERVICE_REQUEST_DELAY: Duration = Duration::from_millis(1000);
#[tokio::test]
async fn sync_blocks_ok() -> Result<(), crate::BoxError> {
let (
chain_sync_future,
_sync_status,
mut block_verifier_router,
mut peer_set,
mut state_service,
_mock_chain_tip_sender,
) = setup();
let block0: Arc<Block> =
zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES.zcash_deserialize_into()?;
let block0_hash = block0.hash();
let block1: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_1_BYTES.zcash_deserialize_into()?;
let block1_hash = block1.hash();
let block2: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_2_BYTES.zcash_deserialize_into()?;
let block2_hash = block2.hash();
let block3: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_3_BYTES.zcash_deserialize_into()?;
let block3_hash = block3.hash();
let block4: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_4_BYTES.zcash_deserialize_into()?;
let block4_hash = block4.hash();
let block5: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_5_BYTES.zcash_deserialize_into()?;
let block5_hash = block5.hash();
let chain_sync_task_handle = tokio::spawn(chain_sync_future);
state_service
.expect_request(zs::Request::KnownBlock(block0_hash))
.await
.respond(zs::Response::KnownBlock(None));
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block0_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block0.clone(),
None,
))]));
block_verifier_router
.expect_request(zebra_consensus::Request::Commit(block0))
.await
.respond(block0_hash);
peer_set.expect_no_requests().await;
block_verifier_router.expect_no_requests().await;
state_service
.expect_request(zs::Request::KnownBlock(block0_hash))
.await
.respond(zs::Response::KnownBlock(Some(zs::KnownBlock::BestChain)));
state_service
.expect_request(zs::Request::BlockLocator)
.await
.respond(zs::Response::BlockLocator(vec![block0_hash]));
peer_set
.expect_request(zn::Request::FindBlocks {
known_blocks: vec![block0_hash],
stop: None,
})
.await
.respond(zn::Response::BlockHashes(vec![
block1_hash, block2_hash, block3_hash, ]));
state_service
.expect_request(zs::Request::KnownBlock(block1_hash))
.await
.respond(zs::Response::KnownBlock(None));
for _ in 0..(sync::FANOUT - 1) {
peer_set
.expect_request(zn::Request::FindBlocks {
known_blocks: vec![block0_hash],
stop: None,
})
.await
.respond(Err(zn::BoxError::from("synthetic test obtain tips error")));
}
peer_set.expect_no_requests().await;
block_verifier_router.expect_no_requests().await;
state_service
.expect_request(zs::Request::KnownBlock(block1_hash))
.await
.respond(zs::Response::KnownBlock(None));
state_service
.expect_request(zs::Request::KnownBlock(block2_hash))
.await
.respond(zs::Response::KnownBlock(None));
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block1_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block1.clone(),
None,
))]));
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block2_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block2.clone(),
None,
))]));
let mut remaining_blocks: HashMap<block::Hash, Arc<Block>> =
[(block1_hash, block1), (block2_hash, block2)]
.iter()
.cloned()
.collect();
for _ in 1..=2 {
block_verifier_router
.expect_request_that(|req| remaining_blocks.remove(&req.block().hash()).is_some())
.await
.respond_with(|req| req.block().hash());
}
assert_eq!(
remaining_blocks,
HashMap::new(),
"expected all non-tip blocks to be verified by obtain tips"
);
block_verifier_router.expect_no_requests().await;
state_service.expect_no_requests().await;
peer_set
.expect_request(zn::Request::FindBlocks {
known_blocks: vec![block1_hash],
stop: None,
})
.await
.respond(zn::Response::BlockHashes(vec![
block2_hash, block3_hash, block4_hash,
block5_hash, ]));
for _ in 0..(sync::FANOUT - 1) {
peer_set
.expect_request(zn::Request::FindBlocks {
known_blocks: vec![block1_hash],
stop: None,
})
.await
.respond(Err(zn::BoxError::from("synthetic test extend tips error")));
}
block_verifier_router.expect_no_requests().await;
state_service.expect_no_requests().await;
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block3_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block3.clone(),
None,
))]));
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block4_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block4.clone(),
None,
))]));
let mut remaining_blocks: HashMap<block::Hash, Arc<Block>> =
[(block3_hash, block3), (block4_hash, block4)]
.iter()
.cloned()
.collect();
for _ in 3..=4 {
block_verifier_router
.expect_request_that(|req| remaining_blocks.remove(&req.block().hash()).is_some())
.await
.respond_with(|req| req.block().hash());
}
assert_eq!(
remaining_blocks,
HashMap::new(),
"expected all non-tip blocks to be verified by extend tips"
);
block_verifier_router.expect_no_requests().await;
state_service.expect_no_requests().await;
let chain_sync_result = chain_sync_task_handle.now_or_never();
assert!(
chain_sync_result.is_none(),
"unexpected error or panic in chain sync task: {chain_sync_result:?}",
);
Ok(())
}
#[tokio::test]
async fn sync_blocks_duplicate_hashes_ok() -> Result<(), crate::BoxError> {
let (
chain_sync_future,
_sync_status,
mut block_verifier_router,
mut peer_set,
mut state_service,
_mock_chain_tip_sender,
) = setup();
let block0: Arc<Block> =
zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES.zcash_deserialize_into()?;
let block0_hash = block0.hash();
let block1: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_1_BYTES.zcash_deserialize_into()?;
let block1_hash = block1.hash();
let block2: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_2_BYTES.zcash_deserialize_into()?;
let block2_hash = block2.hash();
let block3: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_3_BYTES.zcash_deserialize_into()?;
let block3_hash = block3.hash();
let block4: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_4_BYTES.zcash_deserialize_into()?;
let block4_hash = block4.hash();
let block5: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_5_BYTES.zcash_deserialize_into()?;
let block5_hash = block5.hash();
let chain_sync_task_handle = tokio::spawn(chain_sync_future);
state_service
.expect_request(zs::Request::KnownBlock(block0_hash))
.await
.respond(zs::Response::KnownBlock(None));
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block0_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block0.clone(),
None,
))]));
block_verifier_router
.expect_request(zebra_consensus::Request::Commit(block0))
.await
.respond(block0_hash);
peer_set.expect_no_requests().await;
block_verifier_router.expect_no_requests().await;
state_service
.expect_request(zs::Request::KnownBlock(block0_hash))
.await
.respond(zs::Response::KnownBlock(Some(zs::KnownBlock::BestChain)));
state_service
.expect_request(zs::Request::BlockLocator)
.await
.respond(zs::Response::BlockLocator(vec![block0_hash]));
peer_set
.expect_request(zn::Request::FindBlocks {
known_blocks: vec![block0_hash],
stop: None,
})
.await
.respond(zn::Response::BlockHashes(vec![
block1_hash,
block1_hash,
block1_hash, block2_hash, block3_hash, ]));
state_service
.expect_request(zs::Request::KnownBlock(block1_hash))
.await
.respond(zs::Response::KnownBlock(None));
for _ in 0..(sync::FANOUT - 1) {
peer_set
.expect_request(zn::Request::FindBlocks {
known_blocks: vec![block0_hash],
stop: None,
})
.await
.respond(Err(zn::BoxError::from("synthetic test obtain tips error")));
}
peer_set.expect_no_requests().await;
block_verifier_router.expect_no_requests().await;
state_service
.expect_request(zs::Request::KnownBlock(block1_hash))
.await
.respond(zs::Response::KnownBlock(None));
state_service
.expect_request(zs::Request::KnownBlock(block2_hash))
.await
.respond(zs::Response::KnownBlock(None));
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block1_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block1.clone(),
None,
))]));
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block2_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block2.clone(),
None,
))]));
let mut remaining_blocks: HashMap<block::Hash, Arc<Block>> =
[(block1_hash, block1), (block2_hash, block2)]
.iter()
.cloned()
.collect();
for _ in 1..=2 {
block_verifier_router
.expect_request_that(|req| remaining_blocks.remove(&req.block().hash()).is_some())
.await
.respond_with(|req| req.block().hash());
}
assert_eq!(
remaining_blocks,
HashMap::new(),
"expected all non-tip blocks to be verified by obtain tips"
);
block_verifier_router.expect_no_requests().await;
state_service.expect_no_requests().await;
peer_set
.expect_request(zn::Request::FindBlocks {
known_blocks: vec![block1_hash],
stop: None,
})
.await
.respond(zn::Response::BlockHashes(vec![
block2_hash, block3_hash, block4_hash,
block3_hash,
block4_hash,
block5_hash, ]));
for _ in 0..(sync::FANOUT - 1) {
peer_set
.expect_request(zn::Request::FindBlocks {
known_blocks: vec![block1_hash],
stop: None,
})
.await
.respond(Err(zn::BoxError::from("synthetic test extend tips error")));
}
block_verifier_router.expect_no_requests().await;
state_service.expect_no_requests().await;
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block3_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block3.clone(),
None,
))]));
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block4_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block4.clone(),
None,
))]));
let mut remaining_blocks: HashMap<block::Hash, Arc<Block>> =
[(block3_hash, block3), (block4_hash, block4)]
.iter()
.cloned()
.collect();
for _ in 3..=4 {
block_verifier_router
.expect_request_that(|req| remaining_blocks.remove(&req.block().hash()).is_some())
.await
.respond_with(|req| req.block().hash());
}
assert_eq!(
remaining_blocks,
HashMap::new(),
"expected all non-tip blocks to be verified by extend tips"
);
block_verifier_router.expect_no_requests().await;
state_service.expect_no_requests().await;
let chain_sync_result = chain_sync_task_handle.now_or_never();
assert!(
chain_sync_result.is_none(),
"unexpected error or panic in chain sync task: {chain_sync_result:?}",
);
Ok(())
}
#[tokio::test]
async fn sync_block_lookahead_drop() -> Result<(), crate::BoxError> {
let (
chain_sync_future,
_sync_status,
mut block_verifier_router,
mut peer_set,
mut state_service,
_mock_chain_tip_sender,
) = setup();
let block0: Arc<Block> =
zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES.zcash_deserialize_into()?;
let block0_hash = block0.hash();
let block982k: Arc<Block> =
zebra_test::vectors::BLOCK_MAINNET_982681_BYTES.zcash_deserialize_into()?;
let chain_sync_task_handle = tokio::spawn(chain_sync_future);
state_service
.expect_request(zs::Request::KnownBlock(block0_hash))
.await
.respond(zs::Response::KnownBlock(None));
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block0_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block982k.clone(),
None,
))]));
peer_set.expect_no_requests().await;
block_verifier_router.expect_no_requests().await;
let chain_sync_result = chain_sync_task_handle.now_or_never();
assert!(
chain_sync_result.is_none(),
"unexpected error or panic in chain sync task: {chain_sync_result:?}",
);
Ok(())
}
#[tokio::test]
async fn sync_block_too_high_obtain_tips() -> Result<(), crate::BoxError> {
let (
chain_sync_future,
_sync_status,
mut block_verifier_router,
mut peer_set,
mut state_service,
_mock_chain_tip_sender,
) = setup();
let block0: Arc<Block> =
zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES.zcash_deserialize_into()?;
let block0_hash = block0.hash();
let block1: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_1_BYTES.zcash_deserialize_into()?;
let block1_hash = block1.hash();
let block2: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_2_BYTES.zcash_deserialize_into()?;
let block2_hash = block2.hash();
let block3: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_3_BYTES.zcash_deserialize_into()?;
let block3_hash = block3.hash();
let block982k: Arc<Block> =
zebra_test::vectors::BLOCK_MAINNET_982681_BYTES.zcash_deserialize_into()?;
let block982k_hash = block982k.hash();
let chain_sync_task_handle = tokio::spawn(chain_sync_future);
state_service
.expect_request(zs::Request::KnownBlock(block0_hash))
.await
.respond(zs::Response::KnownBlock(None));
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block0_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block0.clone(),
None,
))]));
block_verifier_router
.expect_request(zebra_consensus::Request::Commit(block0))
.await
.respond(block0_hash);
peer_set.expect_no_requests().await;
block_verifier_router.expect_no_requests().await;
state_service
.expect_request(zs::Request::KnownBlock(block0_hash))
.await
.respond(zs::Response::KnownBlock(Some(zs::KnownBlock::BestChain)));
state_service
.expect_request(zs::Request::BlockLocator)
.await
.respond(zs::Response::BlockLocator(vec![block0_hash]));
peer_set
.expect_request(zn::Request::FindBlocks {
known_blocks: vec![block0_hash],
stop: None,
})
.await
.respond(zn::Response::BlockHashes(vec![
block982k_hash,
block1_hash, block2_hash, block3_hash, ]));
state_service
.expect_request(zs::Request::KnownBlock(block982k_hash))
.await
.respond(zs::Response::KnownBlock(None));
for _ in 0..(sync::FANOUT - 1) {
peer_set
.expect_request(zn::Request::FindBlocks {
known_blocks: vec![block0_hash],
stop: None,
})
.await
.respond(Err(zn::BoxError::from("synthetic test obtain tips error")));
}
peer_set.expect_no_requests().await;
block_verifier_router.expect_no_requests().await;
state_service
.expect_request(zs::Request::KnownBlock(block982k_hash))
.await
.respond(zs::Response::KnownBlock(None));
state_service
.expect_request(zs::Request::KnownBlock(block1_hash))
.await
.respond(zs::Response::KnownBlock(None));
state_service
.expect_request(zs::Request::KnownBlock(block2_hash))
.await
.respond(zs::Response::KnownBlock(None));
peer_set
.expect_request(zn::Request::BlocksByHash(
iter::once(block982k_hash).collect(),
))
.await
.respond(zn::Response::Blocks(vec![Available((
block982k.clone(),
None,
))]));
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block1_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block1.clone(),
None,
))]));
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block2_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block2.clone(),
None,
))]));
let chain_sync_result = chain_sync_task_handle.now_or_never();
assert!(
chain_sync_result.is_none(),
"unexpected error or panic in chain sync task: {chain_sync_result:?}",
);
Ok(())
}
#[tokio::test]
async fn sync_block_too_high_extend_tips() -> Result<(), crate::BoxError> {
let (
chain_sync_future,
_sync_status,
mut block_verifier_router,
mut peer_set,
mut state_service,
_mock_chain_tip_sender,
) = setup();
let block0: Arc<Block> =
zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES.zcash_deserialize_into()?;
let block0_hash = block0.hash();
let block1: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_1_BYTES.zcash_deserialize_into()?;
let block1_hash = block1.hash();
let block2: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_2_BYTES.zcash_deserialize_into()?;
let block2_hash = block2.hash();
let block3: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_3_BYTES.zcash_deserialize_into()?;
let block3_hash = block3.hash();
let block4: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_4_BYTES.zcash_deserialize_into()?;
let block4_hash = block4.hash();
let block5: Arc<Block> = zebra_test::vectors::BLOCK_MAINNET_5_BYTES.zcash_deserialize_into()?;
let block5_hash = block5.hash();
let block982k: Arc<Block> =
zebra_test::vectors::BLOCK_MAINNET_982681_BYTES.zcash_deserialize_into()?;
let block982k_hash = block982k.hash();
let chain_sync_task_handle = tokio::spawn(chain_sync_future);
state_service
.expect_request(zs::Request::KnownBlock(block0_hash))
.await
.respond(zs::Response::KnownBlock(None));
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block0_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block0.clone(),
None,
))]));
block_verifier_router
.expect_request(zebra_consensus::Request::Commit(block0))
.await
.respond(block0_hash);
peer_set.expect_no_requests().await;
block_verifier_router.expect_no_requests().await;
state_service
.expect_request(zs::Request::KnownBlock(block0_hash))
.await
.respond(zs::Response::KnownBlock(Some(zs::KnownBlock::BestChain)));
state_service
.expect_request(zs::Request::BlockLocator)
.await
.respond(zs::Response::BlockLocator(vec![block0_hash]));
peer_set
.expect_request(zn::Request::FindBlocks {
known_blocks: vec![block0_hash],
stop: None,
})
.await
.respond(zn::Response::BlockHashes(vec![
block1_hash, block2_hash, block3_hash, ]));
state_service
.expect_request(zs::Request::KnownBlock(block1_hash))
.await
.respond(zs::Response::KnownBlock(None));
for _ in 0..(sync::FANOUT - 1) {
peer_set
.expect_request(zn::Request::FindBlocks {
known_blocks: vec![block0_hash],
stop: None,
})
.await
.respond(Err(zn::BoxError::from("synthetic test obtain tips error")));
}
peer_set.expect_no_requests().await;
block_verifier_router.expect_no_requests().await;
state_service
.expect_request(zs::Request::KnownBlock(block1_hash))
.await
.respond(zs::Response::KnownBlock(None));
state_service
.expect_request(zs::Request::KnownBlock(block2_hash))
.await
.respond(zs::Response::KnownBlock(None));
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block1_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block1.clone(),
None,
))]));
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block2_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block2.clone(),
None,
))]));
let mut remaining_blocks: HashMap<block::Hash, Arc<Block>> =
[(block1_hash, block1), (block2_hash, block2)]
.iter()
.cloned()
.collect();
for _ in 1..=2 {
block_verifier_router
.expect_request_that(|req| remaining_blocks.remove(&req.block().hash()).is_some())
.await
.respond_with(|req| req.block().hash());
}
assert_eq!(
remaining_blocks,
HashMap::new(),
"expected all non-tip blocks to be verified by obtain tips"
);
block_verifier_router.expect_no_requests().await;
state_service.expect_no_requests().await;
peer_set
.expect_request(zn::Request::FindBlocks {
known_blocks: vec![block1_hash],
stop: None,
})
.await
.respond(zn::Response::BlockHashes(vec![
block2_hash, block3_hash, block4_hash,
block982k_hash,
block5_hash, ]));
for _ in 0..(sync::FANOUT - 1) {
peer_set
.expect_request(zn::Request::FindBlocks {
known_blocks: vec![block1_hash],
stop: None,
})
.await
.respond(Err(zn::BoxError::from("synthetic test extend tips error")));
}
block_verifier_router.expect_no_requests().await;
state_service.expect_no_requests().await;
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block3_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block3.clone(),
None,
))]));
peer_set
.expect_request(zn::Request::BlocksByHash(iter::once(block4_hash).collect()))
.await
.respond(zn::Response::Blocks(vec![Available((
block4.clone(),
None,
))]));
peer_set
.expect_request(zn::Request::BlocksByHash(
iter::once(block982k_hash).collect(),
))
.await
.respond(zn::Response::Blocks(vec![Available((
block982k.clone(),
None,
))]));
let chain_sync_result = chain_sync_task_handle.now_or_never();
assert!(
chain_sync_result.is_none(),
"unexpected error or panic in chain sync task: {chain_sync_result:?}",
);
Ok(())
}
#[tokio::test]
async fn should_restart_sync_returns_false() {
let commit_error = zs::CommitBlockError::Duplicate {
hash_or_height: None,
location: zebra_state::KnownBlock::BestChain,
};
let verify_block_error = VerifyBlockError::Commit(commit_error);
let router_error = RouterError::Block {
source: Box::new(verify_block_error),
};
let err = BlockDownloadVerifyError::Invalid {
error: router_error,
height: block::Height(42),
hash: block::Hash::from([0xAA; 32]),
advertiser_addr: None,
};
let restart = ChainSync::<
MockService<zn::Request, zn::Response, PanicAssertion>,
MockService<zs::Request, zs::Response, PanicAssertion>,
MockService<zebra_consensus::Request, block::Hash, PanicAssertion>,
MockChainTip,
>::should_restart_sync(&err);
assert!(
!restart,
"duplicate commit block errors should NOT trigger sync restart"
);
}
fn setup() -> (
// ChainSync
impl Future<Output = Result<(), Report>> + Send,
SyncStatus,
// BlockVerifierRouter
MockService<zebra_consensus::Request, block::Hash, PanicAssertion>,
// PeerSet
MockService<zebra_network::Request, zebra_network::Response, PanicAssertion>,
// StateService
MockService<zebra_state::Request, zebra_state::Response, PanicAssertion>,
MockChainTipSender,
) {
let _init_guard = zebra_test::init();
let consensus_config = ConsensusConfig::default();
let state_config = StateConfig::ephemeral();
let config = ZebradConfig {
consensus: consensus_config,
state: state_config,
..Default::default()
};
let peer_set = MockService::build()
.with_max_request_delay(MAX_SERVICE_REQUEST_DELAY)
.for_unit_tests();
let block_verifier_router = MockService::build()
.with_max_request_delay(MAX_SERVICE_REQUEST_DELAY)
.for_unit_tests();
let state_service = MockService::build()
.with_max_request_delay(MAX_SERVICE_REQUEST_DELAY)
.for_unit_tests();
let (mock_chain_tip, mock_chain_tip_sender) = MockChainTip::new();
let (misbehavior_tx, _misbehavior_rx) = tokio::sync::mpsc::channel(1);
let (chain_sync, sync_status) = ChainSync::new(
&config,
Height(0),
peer_set.clone(),
block_verifier_router.clone(),
state_service.clone(),
mock_chain_tip,
misbehavior_tx,
);
let chain_sync_future = chain_sync.sync();
(
chain_sync_future,
sync_status,
block_verifier_router,
peer_set,
state_service,
mock_chain_tip_sender,
)
}