Skip to content

Commit

Permalink
WIP: syncer tests for block height limits
Browse files Browse the repository at this point in the history
  • Loading branch information
teor2345 committed Dec 7, 2021
1 parent c4d89f7 commit f4635ee
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 0 deletions.
3 changes: 3 additions & 0 deletions zebrad/src/components/sync/tests.rs
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
//! Syncer tests
mod timing;
mod vectors;
139 changes: 139 additions & 0 deletions zebrad/src/components/sync/tests/vectors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
//! Fixed test vectors for the syncer.
use std::{iter, sync::Arc, time::Duration};

use color_eyre::Report;
use futures::{Future, FutureExt};
use tower::{buffer::Buffer, util::BoxService, ServiceExt};

use zebra_chain::{
block::{self, Block},
serialization::ZcashDeserializeInto,
};
use zebra_consensus::Config as ConsensusConfig;
use zebra_network::{Request, Response};
use zebra_state::Config as StateConfig;
use zebra_test::mock_service::{MockService, PanicAssertion};

use crate::{
components::{sync::SyncStatus, ChainSync},
config::ZebradConfig,
BoxError,
};

/// Maximum time to wait for a network service request.
///
/// The default [`MockService`] value can be too short for some of these tests that take a little
/// longer than expected to actually send the network request.
///
/// Increasing this value causes the tests to take longer to complete, so it can't be too large.
const MAX_PEER_SET_REQUEST_DELAY: Duration = Duration::from_millis(500);

#[tokio::test]
async fn sync_block_height_lookahead_limit() -> Result<(), crate::BoxError> {
// Get services
let (chain_sync_future, sync_status, chain_verifier, peer_set, state_service) = setup();

// Get the genesis block
let block: Arc<Block> =
zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES.zcash_deserialize_into()?;
let block_hash = block.hash();

// Start the syncer
let chain_sync_task_handle = tokio::spawn(chain_sync_future);

// Block is fetched, and committed to the state
peer_set
.expect_request(Request::BlocksByHash(iter::once(block_hash).collect()))
.await
.respond(Response::Blocks(vec![block]));

// check that nothing unexpected happened
chain_verifier.expect_no_requests().await;
peer_set.expect_no_requests().await;

let response = state_service
.clone()
.oneshot(zebra_state::Request::Depth(block_hash))
.await?;
assert_eq!(response, zebra_state::Response::Depth(Some(0)));

/*
// Get a block that is a long way away from genesis
let block: Arc<Block> =
zebra_test::vectors::BLOCK_MAINNET_982681_BYTES.zcash_deserialize_into()?;
let block_hash = block.hash();
// Block is fetched, but the downloader drops it because it is too high
peer_set
.expect_request(Request::BlocksByHash(iter::once(block_hash).collect()))
.await
.respond(Response::Blocks(vec![block]));
let response = state_service
.clone()
.oneshot(zebra_state::Request::Depth(block_hash))
.await?;
assert_eq!(response, zebra_state::Response::Depth(None));
// TODO: check that the block is not queued in the checkpoint verifier or non-finalized state
// check that nothing unexpected happened
peer_set.expect_no_requests().await;
*/

let chain_sync_result = chain_sync_task_handle.now_or_never();
assert!(
matches!(chain_sync_result, None),
"unexpected error or panic in chain sync task: {:?}",
chain_sync_result,
);

Ok(())
}

fn setup() -> (
impl Future<Output = Result<(), Report>> + Send + Sync,
SyncStatus,
MockService<Arc<Block>, block::Hash, PanicAssertion>,
MockService<zebra_network::Request, zebra_network::Response, PanicAssertion>,
Buffer<BoxService<zebra_state::Request, zebra_state::Response, BoxError>, zebra_state::Request>,
) {
let consensus_config = ConsensusConfig::default();
let state_config = StateConfig::ephemeral();
let config = ZebradConfig {
consensus: consensus_config,
state: state_config,
..Default::default()
};

let (state_service, latest_chain_tip, chain_tip_change) =
zebra_state::init(config.state.clone(), config.network.network);
let state_service = Buffer::new(BoxService::new(state_service), 1);

let peer_set = MockService::build()
.with_max_request_delay(MAX_PEER_SET_REQUEST_DELAY)
.for_unit_tests();
let buffered_peer_set = Buffer::new(BoxService::new(peer_set.clone()), 10);

let chain_verifier = MockService::build().for_unit_tests();
let buffered_chain_verifier = Buffer::new(BoxService::new(chain_verifier.clone()), 1);

let (chain_sync, sync_status) = ChainSync::new(
&config,
buffered_peer_set,
buffered_chain_verifier,
state_service.clone(),
latest_chain_tip,
);

let chain_sync_future = chain_sync.sync();

(
chain_sync_future,
sync_status,
chain_verifier,
peer_set,
state_service,
)
}

0 comments on commit f4635ee

Please sign in to comment.