From 592ab0be4281c77e10b4988bcc313559bd0ef9cf Mon Sep 17 00:00:00 2001 From: idky137 Date: Sat, 1 Mar 2025 14:06:56 +0000 Subject: [PATCH] added state service tests --- .config/nextest.toml | 2 +- zaino-state/src/fetch.rs | 6 +- zaino-state/src/state.rs | 1002 ++++++++++++++++++++------------------ 3 files changed, 544 insertions(+), 466 deletions(-) diff --git a/.config/nextest.toml b/.config/nextest.toml index f57f687..f8c2304 100644 --- a/.config/nextest.toml +++ b/.config/nextest.toml @@ -1,4 +1,4 @@ [profile.default] test-threads = 4 fail-fast = false -retries = 1 +# retries = 1 diff --git a/zaino-state/src/fetch.rs b/zaino-state/src/fetch.rs index 5e10338..cdd6d211 100644 --- a/zaino-state/src/fetch.rs +++ b/zaino-state/src/fetch.rs @@ -147,11 +147,11 @@ impl Drop for FetchService { #[derive(Debug, Clone)] pub struct FetchServiceSubscriber { /// JsonRPC Client. - fetcher: JsonRpcConnector, + pub fetcher: JsonRpcConnector, /// Local compact block cache. - block_cache: BlockCacheSubscriber, + pub block_cache: BlockCacheSubscriber, /// Internal mempool. - mempool: MempoolSubscriber, + pub mempool: MempoolSubscriber, /// Service metadata. data: ServiceMetadata, /// StateService config data. diff --git a/zaino-state/src/state.rs b/zaino-state/src/state.rs index 8648ab9..bfbafdd 100644 --- a/zaino-state/src/state.rs +++ b/zaino-state/src/state.rs @@ -1363,43 +1363,44 @@ fn header_to_block_commitments( Ok(hash) } -/// !!! NOTE / TODO: This code should be retested before continued development, once zebra regtest is fully operational. #[cfg(test)] mod tests { + use crate::{ + config::FetchServiceConfig, + fetch::{FetchService, FetchServiceSubscriber}, + indexer::ZcashService, + }; use super::*; - use futures::stream::StreamExt; - use zaino_fetch::jsonrpc::connector::test_node_and_return_url; - use zaino_proto::proto::service::BlockId; - use zaino_testutils::{TestManager, ZEBRAD_CHAIN_CACHE_BIN, ZEBRAD_TESTNET_CACHE_BIN}; + use zaino_testutils::{TestManager, ZEBRAD_CHAIN_CACHE_BIN}; + use zebra_chain::parameters::Network; use zingo_infra_services::validator::Validator; - async fn create_test_manager_and_state_service( + + async fn create_test_manager_and_services( + validator: &str, + chain_cache: Option, enable_zaino: bool, - zaino_no_sync: bool, - zaino_no_db: bool, enable_clients: bool, - ) -> (TestManager, StateService) { + ) -> ( + TestManager, + FetchService, + FetchServiceSubscriber, + StateService, + ) { let test_manager = TestManager::launch( - "zebrad", - Some(zingo_infra_services::network::Network::Testnet), - ZEBRAD_TESTNET_CACHE_BIN.clone(), + validator, + None, + chain_cache.clone(), enable_zaino, - zaino_no_sync, - zaino_no_db, + true, + true, enable_clients, ) .await .unwrap(); - let state_service = StateService::spawn(StateServiceConfig::new( - zebra_state::Config { - cache_dir: test_manager.data_dir.clone(), - ephemeral: false, - delete_old_database: true, - debug_stop_at_height: None, - debug_validity_check_interval: None, - }, + let fetch_service = FetchService::spawn(FetchServiceConfig::new( test_manager.zebrad_rpc_listen_address, false, None, @@ -1407,23 +1408,32 @@ mod tests { None, None, None, - Network::new_default_testnet(), + None, + None, + test_manager + .local_net + .data_dir() + .path() + .to_path_buf() + .join("zaino"), + None, + Network::new_regtest(Some(1), Some(1)), + true, + true, )) .await .unwrap(); - (test_manager, state_service) - } - #[ignore = "ignoring until working reliably."] - #[tokio::test] - async fn launch_state_regtest_service_no_cache() { - let mut test_manager = TestManager::launch("zebrad", None, None, false, true, true, false) - .await - .unwrap(); + let subscriber = fetch_service.get_subscriber().inner(); + + let state_chain_cache_dir = match chain_cache { + Some(dir) => dir, + None => test_manager.data_dir.clone(), + }; let state_service = StateService::spawn(StateServiceConfig::new( zebra_state::Config { - cache_dir: test_manager.data_dir.clone(), + cache_dir: state_chain_cache_dir, ephemeral: false, delete_old_database: true, debug_stop_at_height: None, @@ -1441,548 +1451,616 @@ mod tests { .await .unwrap(); - assert_eq!( - state_service.fetch_status_from_validator().await, - StatusType::Ready - ); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; - test_manager.close().await; + (test_manager, fetch_service, subscriber, state_service) } - #[ignore = "ignoring until working reliably."] #[tokio::test] - async fn launch_state_regtest_service_with_cache() { - let mut test_manager = TestManager::launch( - "zebrad", - None, - ZEBRAD_CHAIN_CACHE_BIN.clone(), - false, - true, - true, - false, - ) - .await - .unwrap(); + async fn state_service_check_info_no_cache_zebrad() { + state_service_check_info("zebrad", None).await; + } - let state_service = StateService::spawn(StateServiceConfig::new( - zebra_state::Config { - cache_dir: test_manager.data_dir.clone(), - ephemeral: false, - delete_old_database: true, - debug_stop_at_height: None, - debug_validity_check_interval: None, - }, - test_manager.zebrad_rpc_listen_address, - false, - None, - None, - None, - None, - None, - Network::new_regtest(Some(1), Some(1)), - )) - .await - .unwrap(); + #[tokio::test] + async fn state_service_check_info_with_cache_zebrad() { + state_service_check_info("zebrad", ZEBRAD_CHAIN_CACHE_BIN.clone()).await; + } + + async fn state_service_check_info(validator: &str, chain_cache: Option) { + let (mut test_manager, _fetch_service, fetch_service_subscriber, state_service) = + create_test_manager_and_services(validator, chain_cache, false, false).await; + + test_manager.local_net.generate_blocks(1).await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + + let fetch_service_info = dbg!(fetch_service_subscriber.get_info().await.unwrap()); + let fetch_service_blockchain_info = dbg!(fetch_service_subscriber + .get_blockchain_info() + .await + .unwrap()); + + let state_service_info = dbg!(state_service.get_info().await.unwrap()); + let state_service_blockchain_info = + dbg!(state_service.get_blockchain_info().await.unwrap()); + + // Clean timestamp from get_info + let ( + version, + build, + subversion, + protocol_version, + blocks, + connections, + proxy, + difficulty, + testnet, + pay_tx_fee, + relay_fee, + errors, + _, // ignore the timestamp + ) = fetch_service_info.into_parts(); + let cleaned_fetch_info = GetInfo::from_parts( + version, + build, + subversion, + protocol_version, + blocks, + connections, + proxy, + difficulty, + testnet, + pay_tx_fee, + relay_fee, + errors, + String::new(), // clean the timestamp + ); + + let ( + version, + build, + subversion, + protocol_version, + blocks, + connections, + proxy, + difficulty, + testnet, + pay_tx_fee, + relay_fee, + errors, + _, // ignore the timestamp + ) = state_service_info.into_parts(); + let cleaned_state_info = GetInfo::from_parts( + version, + build, + subversion, + protocol_version, + blocks, + connections, + proxy, + difficulty, + testnet, + pay_tx_fee, + relay_fee, + errors, + String::new(), // clean the timestamp + ); + + assert_eq!(cleaned_fetch_info, cleaned_state_info); assert_eq!( - state_service.fetch_status_from_validator().await, - StatusType::Ready + fetch_service_blockchain_info.chain(), + state_service_blockchain_info.chain() + ); + assert_eq!( + fetch_service_blockchain_info.blocks(), + state_service_blockchain_info.blocks() + ); + assert_eq!( + fetch_service_blockchain_info.best_block_hash(), + state_service_blockchain_info.best_block_hash() + ); + assert_eq!( + fetch_service_blockchain_info.estimated_height(), + state_service_blockchain_info.estimated_height() + ); + assert_eq!( + fetch_service_blockchain_info.value_pools(), + state_service_blockchain_info.value_pools() + ); + assert_eq!( + fetch_service_blockchain_info.upgrades(), + state_service_blockchain_info.upgrades() + ); + assert_eq!( + fetch_service_blockchain_info.consensus(), + state_service_blockchain_info.consensus() ); test_manager.close().await; } - #[ignore = "ignoring until working reliably."] #[tokio::test] - async fn state_service_regtest_get_info() { - let mut test_manager = TestManager::launch( - "zebrad", - None, - ZEBRAD_CHAIN_CACHE_BIN.clone(), - false, - true, - true, - false, + async fn state_service_get_address_balance_zebrad() { + state_service_get_address_balance("zebrad").await; + } + + async fn state_service_get_address_balance(validator: &str) { + let (mut test_manager, _fetch_service, fetch_service_subscriber, state_service) = + create_test_manager_and_services(validator, None, true, true).await; + + let clients = test_manager + .clients + .as_ref() + .expect("Clients are not initialized"); + let recipient_address = clients.get_recipient_address("transparent").await; + + clients.faucet.do_sync(true).await.unwrap(); + + if validator == "zebrad" { + test_manager.local_net.generate_blocks(100).await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + clients.faucet.do_sync(true).await.unwrap(); + clients.faucet.quick_shield().await.unwrap(); + test_manager.local_net.generate_blocks(1).await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + clients.faucet.do_sync(true).await.unwrap(); + }; + + zingolib::testutils::lightclient::from_inputs::quick_send( + &clients.faucet, + vec![(recipient_address.as_str(), 250_000, None)], ) .await .unwrap(); + test_manager.local_net.generate_blocks(1).await.unwrap(); + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; - let state_service = StateService::spawn(StateServiceConfig::new( - zebra_state::Config { - cache_dir: test_manager.data_dir.clone(), - ephemeral: false, - delete_old_database: true, - debug_stop_at_height: None, - debug_validity_check_interval: None, - }, - test_manager.zebrad_rpc_listen_address, - false, - None, - None, - None, - None, - None, - Network::new_regtest(Some(1), Some(1)), - )) - .await - .unwrap(); - let json_service = JsonRpcConnector::new_with_basic_auth( - test_node_and_return_url( - test_manager.zebrad_rpc_listen_address, - false, - None, - Some("xxxxxx".to_string()), - Some("xxxxxx".to_string()), + clients.recipient.do_sync(true).await.unwrap(); + let recipient_balance = clients.recipient.do_balance().await; + + let fetch_service_balance = fetch_service_subscriber + .z_get_address_balance( + AddressStrings::new_valid(vec![recipient_address.clone()]).unwrap(), ) .await - .unwrap(), - "xxxxxx".to_string(), - "xxxxxx".to_string(), - ) - .unwrap(); - - let state_start = tokio::time::Instant::now(); - let state_service_get_info = state_service.get_info().await.unwrap(); - let state_service_duration = state_start.elapsed(); + .unwrap(); - let fetch_start = tokio::time::Instant::now(); - let fetch_service_get_info = json_service.get_info().await.unwrap(); - let fetch_service_duration = fetch_start.elapsed(); + let state_service_balance = state_service + .z_get_address_balance(AddressStrings::new_valid(vec![recipient_address]).unwrap()) + .await + .unwrap(); - assert_eq!(state_service_get_info, fetch_service_get_info.into()); + dbg!(&recipient_balance); + dbg!(&fetch_service_balance); + dbg!(&state_service_balance); - println!("GetInfo responses correct. State-Service processing time: {:?} - fetch-Service processing time: {:?}.", state_service_duration, fetch_service_duration); + assert_eq!(recipient_balance.transparent_balance.unwrap(), 250_000,); + assert_eq!( + recipient_balance.transparent_balance.unwrap(), + fetch_service_balance.balance, + ); + assert_eq!(fetch_service_balance, state_service_balance); test_manager.close().await; } - #[ignore = "ignoring until working reliably."] #[tokio::test] - async fn state_service_regtest_get_blockchain_info() { - let mut test_manager = TestManager::launch( - "zebrad", - None, - ZEBRAD_CHAIN_CACHE_BIN.clone(), - false, - true, - true, - false, - ) - .await - .unwrap(); + async fn state_service_get_block_raw_zebrad() { + state_service_get_block_raw("zebrad").await; + } - let state_service = StateService::spawn(StateServiceConfig::new( - zebra_state::Config { - cache_dir: test_manager.data_dir.clone(), - ephemeral: false, - delete_old_database: true, - debug_stop_at_height: None, - debug_validity_check_interval: None, - }, - test_manager.zebrad_rpc_listen_address, - false, - None, - None, - None, - None, - None, - Network::new_regtest(Some(1), Some(1)), - )) - .await - .unwrap(); - let json_service = JsonRpcConnector::new_with_basic_auth( - test_node_and_return_url( - test_manager.zebrad_rpc_listen_address, - false, - None, - Some("xxxxxx".to_string()), - Some("xxxxxx".to_string()), - ) + async fn state_service_get_block_raw(validator: &str) { + let (mut test_manager, _fetch_service, fetch_service_subscriber, state_service) = + create_test_manager_and_services(validator, None, false, false).await; + + let fetch_service_block = dbg!(fetch_service_subscriber + .z_get_block("1".to_string(), Some(0)) .await - .unwrap(), - "xxxxxx".to_string(), - "xxxxxx".to_string(), - ) - .unwrap(); + .unwrap()); - let state_start = tokio::time::Instant::now(); - let state_service_get_blockchain_info = state_service.get_blockchain_info().await.unwrap(); - let state_service_duration = state_start.elapsed(); + let state_service_block = dbg!(state_service + .z_get_block("1".to_string(), Some(0)) + .await + .unwrap()); - let fetch_start = tokio::time::Instant::now(); - let fetch_service_get_blockchain_info = json_service.get_blockchain_info().await.unwrap(); - let fetch_service_duration = fetch_start.elapsed(); - let fetch_service_get_blockchain_info: GetBlockChainInfo = - fetch_service_get_blockchain_info.try_into().unwrap(); + assert_eq!(fetch_service_block, state_service_block); - // Zaino-Fetch does not return value_pools, ignore this field. - assert_eq!( - ( - state_service_get_blockchain_info.chain(), - state_service_get_blockchain_info.blocks(), - state_service_get_blockchain_info.best_block_hash(), - state_service_get_blockchain_info.estimated_height(), - state_service_get_blockchain_info.upgrades(), - state_service_get_blockchain_info.consensus(), - ), - ( - fetch_service_get_blockchain_info.chain(), - fetch_service_get_blockchain_info.blocks(), - fetch_service_get_blockchain_info.best_block_hash(), - fetch_service_get_blockchain_info.estimated_height(), - fetch_service_get_blockchain_info.upgrades(), - fetch_service_get_blockchain_info.consensus(), - ) - ); + test_manager.close().await; + } + + #[tokio::test] + async fn state_service_get_block_object_zebrad() { + state_service_get_block_object("zebrad").await; + } + + async fn state_service_get_block_object(validator: &str) { + let (mut test_manager, _fetch_service, fetch_service_subscriber, state_service) = + create_test_manager_and_services(validator, None, false, false).await; + + let fetch_service_block = dbg!(fetch_service_subscriber + .z_get_block("1".to_string(), Some(1)) + .await + .unwrap()); - println!("GetBlockChainInfo responses correct. State-Service processing time: {:?} - fetch-Service processing time: {:?}.", state_service_duration, fetch_service_duration); + let state_service_block = dbg!(state_service + .z_get_block("1".to_string(), Some(1)) + .await + .unwrap()); + + assert_eq!(fetch_service_block, state_service_block); test_manager.close().await; } - /// Bug documented in https://github.com/zingolabs/zaino/issues/146. - #[ignore = "ignoring until working reliably."] #[tokio::test] - async fn state_service_get_blockchain_info_no_cache() { - let mut test_manager = TestManager::launch("zebrad", None, None, false, true, true, false) - .await - .unwrap(); + async fn state_service_get_raw_mempool_zebrad() { + state_service_get_raw_mempoolstate("zebrad").await; + } + + async fn state_service_get_raw_mempoolstate(validator: &str) { + let (mut test_manager, _fetch_service, fetch_service_subscriber, state_service) = + create_test_manager_and_services(validator, None, true, true).await; + let clients = test_manager + .clients + .as_ref() + .expect("Clients are not initialized"); + test_manager.local_net.generate_blocks(1).await.unwrap(); + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; + + clients.faucet.do_sync(true).await.unwrap(); + + if validator == "zebrad" { + test_manager.local_net.generate_blocks(100).await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + clients.faucet.do_sync(true).await.unwrap(); + clients.faucet.quick_shield().await.unwrap(); + test_manager.local_net.generate_blocks(100).await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + clients.faucet.do_sync(true).await.unwrap(); + clients.faucet.quick_shield().await.unwrap(); + test_manager.local_net.generate_blocks(1).await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + clients.faucet.do_sync(true).await.unwrap(); + }; - let state_service = StateService::spawn(StateServiceConfig::new( - zebra_state::Config { - cache_dir: test_manager.data_dir.clone(), - ephemeral: false, - delete_old_database: true, - debug_stop_at_height: None, - debug_validity_check_interval: None, - }, - test_manager.zebrad_rpc_listen_address, - false, - None, - None, - None, - None, - None, - Network::new_regtest(Some(1), Some(1)), - )) + zingolib::testutils::lightclient::from_inputs::quick_send( + &clients.faucet, + vec![( + &clients.get_recipient_address("transparent").await, + 250_000, + None, + )], + ) .await .unwrap(); - let json_service = JsonRpcConnector::new_with_basic_auth( - test_node_and_return_url( - test_manager.zebrad_rpc_listen_address, - false, + zingolib::testutils::lightclient::from_inputs::quick_send( + &clients.faucet, + vec![( + &clients.get_recipient_address("unified").await, + 250_000, None, - Some("xxxxxx".to_string()), - Some("xxxxxx".to_string()), - ) - .await - .unwrap(), - "xxxxxx".to_string(), - "xxxxxx".to_string(), + )], ) + .await .unwrap(); - let state_start = tokio::time::Instant::now(); - let state_service_get_blockchain_info = state_service.get_blockchain_info().await.unwrap(); - let state_service_duration = state_start.elapsed(); + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; - let fetch_start = tokio::time::Instant::now(); - let fetch_service_get_blockchain_info = json_service.get_blockchain_info().await.unwrap(); - let fetch_service_duration = fetch_start.elapsed(); - let fetch_service_get_blockchain_info: GetBlockChainInfo = - fetch_service_get_blockchain_info.try_into().unwrap(); + let mut fetch_service_mempool = fetch_service_subscriber.get_raw_mempool().await.unwrap(); + let mut state_service_mempool = state_service.get_raw_mempool().await.unwrap(); - println!( - "Fetch Service Chain Height: {}", - fetch_service_get_blockchain_info.blocks().0 - ); - println!( - "State Service Chain Height: {}", - state_service_get_blockchain_info.blocks().0 - ); + dbg!(&fetch_service_mempool); + fetch_service_mempool.sort(); - test_manager.local_net.print_stdout(); + dbg!(&state_service_mempool); + state_service_mempool.sort(); - // Zaino-Fetch does not return value_pools, ignore this field. - assert_eq!( - ( - state_service_get_blockchain_info.chain(), - state_service_get_blockchain_info.blocks(), - state_service_get_blockchain_info.best_block_hash(), - state_service_get_blockchain_info.estimated_height(), - state_service_get_blockchain_info.upgrades(), - state_service_get_blockchain_info.consensus(), - ), - ( - fetch_service_get_blockchain_info.chain(), - fetch_service_get_blockchain_info.blocks(), - fetch_service_get_blockchain_info.best_block_hash(), - fetch_service_get_blockchain_info.estimated_height(), - fetch_service_get_blockchain_info.upgrades(), - fetch_service_get_blockchain_info.consensus(), - ) - ); - - println!("GetBlockChainInfo responses correct. State-Service processing time: {:?} - fetch-Service processing time: {:?}.", state_service_duration, fetch_service_duration); + assert_eq!(fetch_service_mempool, state_service_mempool); test_manager.close().await; } - #[ignore = "ignoring until working reliably."] #[tokio::test] - async fn state_service_regtest_get_block_raw() { - let (mut test_manager, state_service) = - create_test_manager_and_state_service(false, true, true, false).await; - let fetch_service = zaino_fetch::jsonrpc::connector::JsonRpcConnector::new_with_basic_auth( - test_node_and_return_url( - test_manager.zebrad_rpc_listen_address, - false, + async fn state_service_z_get_treestate_zebrad() { + state_service_z_get_treestate("zebrad").await; + } + + async fn state_service_z_get_treestate(validator: &str) { + let (mut test_manager, _fetch_service, fetch_service_subscriber, state_service) = + create_test_manager_and_services(validator, None, true, true).await; + + let clients = test_manager + .clients + .as_ref() + .expect("Clients are not initialized"); + + clients.faucet.do_sync(true).await.unwrap(); + + if validator == "zebrad" { + test_manager.local_net.generate_blocks(100).await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + clients.faucet.do_sync(true).await.unwrap(); + clients.faucet.quick_shield().await.unwrap(); + test_manager.local_net.generate_blocks(1).await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + clients.faucet.do_sync(true).await.unwrap(); + }; + + zingolib::testutils::lightclient::from_inputs::quick_send( + &clients.faucet, + vec![( + &clients.get_recipient_address("unified").await, + 250_000, None, - Some("xxxxxx".to_string()), - Some("xxxxxx".to_string()), - ) - .await - .unwrap(), - "xxxxxx".to_string(), - "xxxxxx".to_string(), + )], ) + .await .unwrap(); - let state_start = tokio::time::Instant::now(); - let state_service_get_block = state_service - .z_get_block("1".to_string(), Some(0)) - .await - .unwrap(); - let state_service_duration = state_start.elapsed(); + test_manager.local_net.generate_blocks(1).await.unwrap(); + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; - let fetch_start = tokio::time::Instant::now(); - let fetch_service_get_block = fetch_service - .get_block("1".to_string(), Some(0)) + let fetch_service_treestate = dbg!(fetch_service_subscriber + .z_get_treestate("2".to_string()) .await - .unwrap(); - let fetch_service_duration = fetch_start.elapsed(); + .unwrap()); - assert_eq!( - state_service_get_block, - fetch_service_get_block.try_into().unwrap() - ); + let state_service_treestate = dbg!(state_service + .z_get_treestate("2".to_string()) + .await + .unwrap()); - println!("GetBlock(raw) responses correct. State-Service processing time: {:?} - fetch-Service processing time: {:?}.", state_service_duration, fetch_service_duration); + assert_eq!(fetch_service_treestate, state_service_treestate); test_manager.close().await; } - #[ignore = "ignoring until working reliably."] #[tokio::test] - async fn state_service_regtest_get_block_object() { - let (mut test_manager, state_service) = - create_test_manager_and_state_service(false, true, true, false).await; - let fetch_service = zaino_fetch::jsonrpc::connector::JsonRpcConnector::new_with_basic_auth( - test_node_and_return_url( - test_manager.zebrad_rpc_listen_address, - false, + async fn state_service_z_get_subtrees_by_index_zebrad() { + state_service_z_get_subtrees_by_index("zebrad").await; + } + + async fn state_service_z_get_subtrees_by_index(validator: &str) { + let (mut test_manager, _fetch_service, fetch_service_subscriber, state_service) = + create_test_manager_and_services(validator, None, true, true).await; + + let clients = test_manager + .clients + .as_ref() + .expect("Clients are not initialized"); + + clients.faucet.do_sync(true).await.unwrap(); + + if validator == "zebrad" { + test_manager.local_net.generate_blocks(100).await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + clients.faucet.do_sync(true).await.unwrap(); + clients.faucet.quick_shield().await.unwrap(); + test_manager.local_net.generate_blocks(1).await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + clients.faucet.do_sync(true).await.unwrap(); + }; + + zingolib::testutils::lightclient::from_inputs::quick_send( + &clients.faucet, + vec![( + &clients.get_recipient_address("unified").await, + 250_000, None, - Some("xxxxxx".to_string()), - Some("xxxxxx".to_string()), - ) - .await - .unwrap(), - "xxxxxx".to_string(), - "xxxxxx".to_string(), + )], ) + .await .unwrap(); - let state_start = tokio::time::Instant::now(); - let state_service_get_block = state_service - .z_get_block("1".to_string(), Some(1)) + test_manager.local_net.generate_blocks(1).await.unwrap(); + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; + + let fetch_service_subtrees = dbg!(fetch_service_subscriber + .z_get_subtrees_by_index("orchard".to_string(), NoteCommitmentSubtreeIndex(0), None) .await - .unwrap(); - let state_service_duration = state_start.elapsed(); + .unwrap()); - let fetch_start = tokio::time::Instant::now(); - let fetch_service_get_block = fetch_service - .get_block("1".to_string(), Some(1)) + let state_service_subtrees = dbg!(state_service + .z_get_subtrees_by_index("orchard".to_string(), NoteCommitmentSubtreeIndex(0), None) .await - .unwrap(); - let fetch_service_duration = fetch_start.elapsed(); - - // Zaino-fetch only returns fields that are required by the lightwallet services. Check those fields match and ignore the others. - match ( - state_service_get_block, - fetch_service_get_block.try_into().unwrap(), - ) { - ( - zebra_rpc::methods::GetBlock::Object { - hash: state_hash, - confirmations: state_confirmations, - height: state_height, - time: state_time, - tx: state_tx, - trees: state_trees, - .. - }, - zebra_rpc::methods::GetBlock::Object { - hash: fetch_hash, - confirmations: fetch_confirmations, - height: fetch_height, - time: fetch_time, - tx: fetch_tx, - trees: fetch_trees, - .. - }, - ) => { - assert_eq!(state_hash, fetch_hash); - assert_eq!(state_confirmations, fetch_confirmations); - assert_eq!(state_height, fetch_height); - assert_eq!(state_time, fetch_time); - assert_eq!(state_tx, fetch_tx); - assert_eq!(state_trees, fetch_trees); - } - _ => panic!("Mismatched variants or unexpected types in block response"), - } + .unwrap()); - println!("GetBlock(object) responses correct. State-Service processing time: {:?} - fetch-Service processing time: {:?}.", state_service_duration, fetch_service_duration); + assert_eq!(fetch_service_subtrees, state_service_subtrees); test_manager.close().await; } - /// WARNING: This tests needs refactoring due to code removed in zaino-state. - #[ignore = "ignoring until working reliably."] #[tokio::test] - async fn state_service_regtest_get_block_compact() { - let (mut test_manager, state_service) = - create_test_manager_and_state_service(false, true, true, false).await; - - let state_start = tokio::time::Instant::now(); - let state_service_get_compact_block = StateService::get_compact_block( - &state_service.read_state_service, - "1".to_string(), - &state_service.config.network, + async fn state_service_get_raw_transaction_zebrad() { + state_service_get_raw_transaction("zebrad").await; + } + + async fn state_service_get_raw_transaction(validator: &str) { + let (mut test_manager, _fetch_service, fetch_service_subscriber, state_service) = + create_test_manager_and_services(validator, None, true, true).await; + + let clients = test_manager + .clients + .as_ref() + .expect("Clients are not initialized"); + + clients.faucet.do_sync(true).await.unwrap(); + + if validator == "zebrad" { + test_manager.local_net.generate_blocks(100).await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + clients.faucet.do_sync(true).await.unwrap(); + clients.faucet.quick_shield().await.unwrap(); + test_manager.local_net.generate_blocks(1).await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + clients.faucet.do_sync(true).await.unwrap(); + }; + + let tx = zingolib::testutils::lightclient::from_inputs::quick_send( + &clients.faucet, + vec![( + &clients.get_recipient_address("unified").await, + 250_000, + None, + )], ) .await .unwrap(); - let state_service_duration = state_start.elapsed(); - dbg!(state_service_get_compact_block); + test_manager.local_net.generate_blocks(1).await.unwrap(); + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; - println!( - "State-Service processing time: {:?}.", - state_service_duration - ); + let fetch_service_transaction = dbg!(fetch_service_subscriber + .get_raw_transaction(tx.first().to_string(), Some(1)) + .await + .unwrap()); + + let state_service_transaction = dbg!(state_service + .get_raw_transaction(tx.first().to_string(), Some(1)) + .await + .unwrap()); + + assert_eq!(fetch_service_transaction, state_service_transaction); test_manager.close().await; } - /// WARNING: This tests needs refactoring due to code removed in zaino-state. - #[ignore = "ignoring until working reliably."] #[tokio::test] - async fn state_service_regtest_get_block_range() { - let (mut test_manager, state_service) = - create_test_manager_and_state_service(false, true, true, false).await; - let block_range = BlockRange { - start: Some(BlockId { - height: 50, - hash: Vec::new(), - }), - end: Some(BlockId { - height: 1, - hash: Vec::new(), - }), + async fn state_service_get_address_tx_ids_zebrad() { + state_service_get_address_tx_ids("zebrad").await; + } + + async fn state_service_get_address_tx_ids(validator: &str) { + let (mut test_manager, _fetch_service, fetch_service_subscriber, state_service) = + create_test_manager_and_services(validator, None, true, true).await; + + let clients = test_manager + .clients + .as_ref() + .expect("Clients are not initialized"); + let recipient_address = clients.get_recipient_address("transparent").await; + + clients.faucet.do_sync(true).await.unwrap(); + + if validator == "zebrad" { + test_manager.local_net.generate_blocks(100).await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + clients.faucet.do_sync(true).await.unwrap(); + clients.faucet.quick_shield().await.unwrap(); + test_manager.local_net.generate_blocks(1).await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + clients.faucet.do_sync(true).await.unwrap(); }; - let state_start = tokio::time::Instant::now(); - let state_service_stream = state_service - .get_block_range(block_range.clone()) + let tx = zingolib::testutils::lightclient::from_inputs::quick_send( + &clients.faucet, + vec![(recipient_address.as_str(), 250_000, None)], + ) + .await + .unwrap(); + test_manager.local_net.generate_blocks(1).await.unwrap(); + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; + + let chain_height = fetch_service_subscriber + .block_cache + .get_chain_height() + .await + .unwrap() + .0; + dbg!(&chain_height); + + let fetch_service_txids = fetch_service_subscriber + .get_address_tx_ids(GetAddressTxIdsRequest::from_parts( + vec![recipient_address.clone()], + chain_height - 2, + chain_height, + )) .await .unwrap(); - let state_service_compact_blocks: Vec<_> = state_service_stream.collect().await; - let state_service_duration = state_start.elapsed(); - // Extract only the successful `CompactBlock` results - let state_blocks: Vec<_> = state_service_compact_blocks - .into_iter() - .filter_map(|result| result.ok()) - .collect(); + let state_service_txids = state_service + .get_address_tx_ids(GetAddressTxIdsRequest::from_parts( + vec![recipient_address], + chain_height - 2, + chain_height, + )) + .await + .unwrap(); - dbg!(state_blocks); + dbg!(&tx); + dbg!(&fetch_service_txids); + assert_eq!(tx.first().to_string(), fetch_service_txids[0]); - println!( - "State-Service processing time: {:?}.", - state_service_duration - ); + dbg!(&state_service_txids); + assert_eq!(fetch_service_txids, state_service_txids); test_manager.close().await; } - #[ignore = "ignoring until working reliably."] #[tokio::test] - async fn state_service_testnet_get_block_range_large() { - let (mut test_manager, state_service) = - create_test_manager_and_state_service(false, true, true, false).await; - - let block_range = BlockRange { - start: Some(BlockId { - height: 2000000, - hash: Vec::new(), - }), - end: Some(BlockId { - height: 3000000, - hash: Vec::new(), - }), + async fn state_service_get_address_utxos_zebrad() { + state_service_get_address_utxos("zebrad").await; + } + + async fn state_service_get_address_utxos(validator: &str) { + let (mut test_manager, _fetch_service, fetch_service_subscriber, state_service) = + create_test_manager_and_services(validator, None, true, true).await; + + let clients = test_manager + .clients + .as_ref() + .expect("Clients are not initialized"); + let recipient_address = clients.get_recipient_address("transparent").await; + + clients.faucet.do_sync(true).await.unwrap(); + + if validator == "zebrad" { + test_manager.local_net.generate_blocks(100).await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + clients.faucet.do_sync(true).await.unwrap(); + clients.faucet.quick_shield().await.unwrap(); + test_manager.local_net.generate_blocks(1).await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(500)).await; + clients.faucet.do_sync(true).await.unwrap(); }; - let num_blocks = - block_range.clone().end.unwrap().height - block_range.clone().start.unwrap().height; - println!("Fetching {} blocks in range: {:?}", num_blocks, block_range); + let txid_1 = zingolib::testutils::lightclient::from_inputs::quick_send( + &clients.faucet, + vec![(recipient_address.as_str(), 250_000, None)], + ) + .await + .unwrap(); + test_manager.local_net.generate_blocks(1).await.unwrap(); + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; - let state_start = tokio::time::Instant::now(); - let state_service_stream = state_service - .get_block_range(block_range.clone()) + clients.faucet.do_sync(true).await.unwrap(); + + let fetch_service_utxos = fetch_service_subscriber + .z_get_address_utxos( + AddressStrings::new_valid(vec![recipient_address.clone()]).unwrap(), + ) .await .unwrap(); - let state_service_compact_blocks: Vec<_> = state_service_stream.collect().await; - let state_service_duration = state_start.elapsed(); - - let state_blocks: Vec<_> = state_service_compact_blocks - .into_iter() - .filter_map(|result| result.ok()) - .collect(); - - println!("First block in range: {:?}", state_blocks.first()); - println!("Last block in range: {:?}", state_blocks.last()); - println!("GetBlockRange response received. State-Service fetch 1,000,000 blocks in processing time: {:?}.", state_service_duration); + let (_, fetch_service_txid, ..) = fetch_service_utxos[0].into_parts(); - test_manager.close().await; - } - - #[ignore = "ignoring until working reliably."] - #[tokio::test] - async fn state_service_testnet_get_blockchain_info() { - let (mut test_manager, state_service) = - create_test_manager_and_state_service(false, true, true, false).await; - - let fetch_service = zaino_fetch::jsonrpc::connector::JsonRpcConnector::new_with_basic_auth( - test_node_and_return_url( - test_manager.zebrad_rpc_listen_address, - false, - None, - Some("xxxxxx".to_string()), - Some("xxxxxx".to_string()), - ) + let state_service_utxos = state_service + .z_get_address_utxos(AddressStrings::new_valid(vec![recipient_address]).unwrap()) .await - .unwrap(), - "xxxxxx".to_string(), - "xxxxxx".to_string(), - ) - .unwrap(); - let state_service_bcinfo = state_service.get_blockchain_info().await.unwrap(); - let fetch_service_bcinfo = fetch_service.get_blockchain_info().await.unwrap(); + .unwrap(); + let (_, state_service_txid, ..) = state_service_utxos[0].into_parts(); + + dbg!(&txid_1); + dbg!(&fetch_service_utxos); + assert_eq!(txid_1.first().to_string(), fetch_service_txid.to_string()); - dbg!(state_service_bcinfo); - dbg!(fetch_service_bcinfo); + dbg!(&state_service_utxos); - // assert_eq!(state_service_bcinfo, fetch_service_bcinfo); + assert_eq!( + fetch_service_txid.to_string(), + state_service_txid.to_string() + ); test_manager.close().await; }