diff --git a/libtonode-tests/tests/concrete.rs b/libtonode-tests/tests/concrete.rs index 0ecf86560..5f1e4d52d 100644 --- a/libtonode-tests/tests/concrete.rs +++ b/libtonode-tests/tests/concrete.rs @@ -145,117 +145,408 @@ mod fast { use super::*; #[tokio::test] - async fn create_send_to_self_with_zfz_active() { - let (_regtest_manager, _cph, _faucet, recipient, _txid) = - scenarios::orchard_funded_recipient(5_000_000).await; - - recipient - .propose_send_all( - address_from_str(&get_base_address_macro!(&recipient, "unified")).unwrap(), - true, + async fn mempool_clearing_and_full_batch_syncs_correct_trees() { + async fn do_maybe_recent_txid(lc: &LightClient) -> JsonValue { + json::object! { + "last_txid" => lc.wallet.transactions().read().await.get_some_txid_from_highest_wallet_block().map(|t| t.to_string()) + } + } + let value = 100_000; + let regtest_network = RegtestNetwork::all_upgrades_active(); + let (regtest_manager, _cph, faucet, recipient, orig_transaction_id, _, _) = + scenarios::faucet_funded_recipient( + Some(value), + None, None, + PoolType::Shielded(ShieldedProtocol::Sapling), + regtest_network, + ) + .await; + let orig_transaction_id = orig_transaction_id.unwrap(); + assert_eq!( + do_maybe_recent_txid(&recipient).await["last_txid"], + orig_transaction_id + ); + // Put some transactions unrelated to the recipient (faucet->faucet) on-chain, to get some clutter + for _ in 0..5 { + zingolib::testutils::send_value_between_clients_and_sync( + ®test_manager, + &faucet, + &faucet, + 5_000, + "unified", ) .await .unwrap(); + } - recipient - .complete_and_broadcast_stored_proposal() - .await - .unwrap(); - - let value_transfers = &recipient.sorted_value_transfers(true).await; + let sent_to_self = 10; + // Send recipient->recipient, to make tree equality check at the end simpler + zingolib::testutils::send_value_between_clients_and_sync( + ®test_manager, + &recipient, + &recipient, + sent_to_self, + "unified", + ) + .await + .unwrap(); + let fees = zingolib::testutils::lightclient::get_fees_paid_by_client(&recipient).await; + assert_eq!(value - fees, 90_000); + let balance_minus_step_one_fees = value - fees; - dbg!(value_transfers); + // 3a. stash zcashd state + log::debug!( + "old zcashd chain info {}", + std::str::from_utf8( + ®test_manager + .get_cli_handle() + .arg("getblockchaininfo") + .output() + .unwrap() + .stdout + ) + .unwrap() + ); - assert!(value_transfers.iter().any(|vt| vt.kind() - == ValueTransferKind::Sent(SentValueTransfer::SendToSelf( - SelfSendValueTransfer::Basic - )))); - assert!(value_transfers.iter().any(|vt| vt.kind() - == ValueTransferKind::Sent(SentValueTransfer::Send) - && vt.recipient_address() == Some(ZENNIES_FOR_ZINGO_REGTEST_ADDRESS))); - } + // Turn zcashd off and on again, to write down the blocks + drop(_cph); // turn off zcashd and lightwalletd + let _cph = regtest_manager.launch(false).unwrap(); + log::debug!( + "new zcashd chain info {}", + std::str::from_utf8( + ®test_manager + .get_cli_handle() + .arg("getblockchaininfo") + .output() + .unwrap() + .stdout + ) + .unwrap() + ); - /// This tests checks that messages_containing returns an empty vector when empty memos are included. - #[tokio::test] - async fn filter_empty_messages() { - let mut environment = LibtonodeEnvironment::setup().await; + let zcd_datadir = ®test_manager.zcashd_data_dir; + let zcashd_parent = Path::new(zcd_datadir).parent().unwrap(); + let original_zcashd_directory = zcashd_parent.join("original_zcashd"); - let faucet = environment.create_faucet().await; - let recipient = environment.create_client().await; + log::debug!( + "The original zcashd directory is at: {}", + &original_zcashd_directory.to_string_lossy().to_string() + ); - environment.bump_chain().await; - faucet.do_sync(false).await.unwrap(); + let source = &zcd_datadir.to_string_lossy().to_string(); + let dest = &original_zcashd_directory.to_string_lossy().to_string(); + std::process::Command::new("cp") + .arg("-rf") + .arg(source) + .arg(dest) + .output() + .expect("directory copy failed"); - check_client_balances!(faucet, o: 0 s: 2_500_000_000u64 t: 0u64); + // 3. Send z-to-z transaction to external z address with a memo + let sent_value = 2000; + let outgoing_memo = "Outgoing Memo"; - from_inputs::quick_send( - &faucet, - vec![ - ( - get_base_address_macro!(recipient, "unified").as_str(), - 5_000, - Some(""), - ), - ( - get_base_address_macro!(recipient, "unified").as_str(), - 5_000, - Some(""), - ), - ], + let sent_transaction_id = from_inputs::quick_send( + &recipient, + vec![( + &get_base_address_macro!(faucet, "sapling"), + sent_value, + Some(outgoing_memo), + )], ) .await - .unwrap(); + .unwrap() + .first() + .to_string(); - environment.bump_chain().await; + let second_transaction_fee; + { + let tmds = recipient + .wallet + .transaction_context + .transaction_metadata_set + .read() + .await; + let record = tmds + .transaction_records_by_id + .get( + &crate::utils::conversion::txid_from_hex_encoded_str(&sent_transaction_id) + .unwrap(), + ) + .unwrap(); + second_transaction_fee = tmds + .transaction_records_by_id + .calculate_transaction_fee(record) + .unwrap(); + // Sync recipient + } // drop transaction_record references and tmds read lock recipient.do_sync(false).await.unwrap(); - let no_messages = &recipient.messages_containing(None).await; + // 4b write down state before clearing the mempool + let notes_before = recipient.do_list_notes(true).await; + let transactions_before = recipient.do_list_transactions().await; - assert_eq!(no_messages.0.len(), 0); + // Sync recipient again. We assert this should be a no-op, as we just synced + recipient.do_sync(false).await.unwrap(); + let post_sync_notes_before = recipient.do_list_notes(true).await; + let post_sync_transactions_before = recipient.do_list_transactions().await; + assert_eq!(post_sync_notes_before, notes_before); + assert_eq!(post_sync_transactions_before, transactions_before); - from_inputs::quick_send( - &faucet, - vec![ - ( - get_base_address_macro!(recipient, "unified").as_str(), - 5_000, - Some("Hello"), - ), - ( - get_base_address_macro!(recipient, "unified").as_str(), - 5_000, - Some(""), - ), - ], - ) - .await - .unwrap(); + drop(_cph); // Turn off zcashd and lightwalletd - environment.bump_chain().await; - recipient.do_sync(false).await.unwrap(); + // 5. check that the sent transaction is correctly marked in the client + let transactions = recipient.do_list_transactions().await; + let mempool_only_tx = transactions + .members() + .find(|tx| tx["txid"] == sent_transaction_id) + .unwrap() + .clone(); + dbg!(&mempool_only_tx["txid"]); + assert_eq!( + mempool_only_tx["outgoing_metadata"][0]["memo"], + "Outgoing Memo" + ); + assert_eq!(mempool_only_tx["txid"], sent_transaction_id); - let single_message = &recipient.messages_containing(None).await; + // 6. note that the client correctly considers the note pending + assert_eq!(mempool_only_tx["pending"], true); - assert_eq!(single_message.0.len(), 1); - } + std::process::Command::new("rm") + .arg("-rf") + .arg(source) + .output() + .expect("recursive rm failed"); + std::process::Command::new("cp") + .arg("--recursive") + .arg("--remove-destination") + .arg(dest) + .arg(source) + .output() + .expect("directory copy failed"); + assert_eq!( + source, + ®test_manager + .zcashd_data_dir + .to_string_lossy() + .to_string() + ); + let _cph = regtest_manager.launch(false).unwrap(); + let notes_after = recipient.do_list_notes(true).await; + let transactions_after = recipient.do_list_transactions().await; - /// Test sending and receiving messages between three parties. - /// - /// This test case consists of the following sequence of events: - /// - /// 1. Alice sends a message to Bob. - /// 2. Alice sends another message to Bob. - /// 3. Bob sends a message to Alice. - /// 4. Alice sends a message to Charlie. - /// 5. Charlie sends a message to Alice. - /// - /// After the messages are sent, the test checks that the `messages_containing` method - /// returns the expected messages for each party in the correct order. - #[tokio::test] - async fn message_thread() { - let (regtest_manager, _cph, faucet, recipient, _txid) = - scenarios::orchard_funded_recipient(10_000_000).await; + assert_eq!(notes_before.pretty(2), notes_after.pretty(2)); + assert_eq!(transactions_before.pretty(2), transactions_after.pretty(2)); + + // 6. Mine 10 blocks, the pending transaction should still be there. + zingolib::testutils::increase_height_and_wait_for_client(®test_manager, &recipient, 1) + .await + .unwrap(); + assert_eq!(recipient.wallet.last_synced_height().await, 12); + + let notes = recipient.do_list_notes(true).await; + + let transactions = recipient.do_list_transactions().await; + + // There are 2 unspent notes, the pending transaction, and the final receipt + //println!("{}", json::stringify_pretty(notes.clone(), 4)); + //println!("{}", json::stringify_pretty(transactions.clone(), 4)); + // Two unspent notes: one change, pending, one from faucet, confirmed + assert_eq!(notes["unspent_orchard_notes"].len(), 2); + assert_eq!(notes["unspent_sapling_notes"].len(), 0); + let note = notes["unspent_orchard_notes"][1].clone(); + assert_eq!(note["created_in_txid"], sent_transaction_id); + assert_eq!( + note["value"].as_u64().unwrap(), + balance_minus_step_one_fees - sent_value - second_transaction_fee - sent_to_self + ); + assert!(note["pending"].as_bool().unwrap()); + assert_eq!(transactions.len(), 3); + + // 7. Mine 3 blocks, so the 2 block pending_window is passed + zingolib::testutils::increase_height_and_wait_for_client(®test_manager, &recipient, 3) + .await + .unwrap(); + assert_eq!(recipient.wallet.last_synced_height().await, 15); + + let notes = recipient.do_list_notes(true).await; + let transactions = recipient.do_list_transactions().await; + + // There are now three notes, the original (confirmed and spent) note, the send to self note, and its change. + assert_eq!(notes["unspent_orchard_notes"].len(), 2); + assert_eq!( + notes["spent_orchard_notes"][0]["created_in_txid"], + orig_transaction_id + ); + assert!(!notes["unspent_orchard_notes"][0]["pending"] + .as_bool() + .unwrap()); + assert_eq!(notes["pending_orchard_notes"].len(), 0); + assert_eq!(transactions.len(), 2); + let read_lock = recipient + .wallet + .transaction_context + .transaction_metadata_set + .read() + .await; + let wallet_trees = read_lock.witness_trees().unwrap(); + let last_leaf = wallet_trees + .witness_tree_orchard + .max_leaf_position(None) + .unwrap(); + let server_trees = zingolib::grpc_connector::get_trees( + recipient.get_server_uri(), + recipient.wallet.last_synced_height().await, + ) + .await + .unwrap(); + let server_orchard_front = zcash_primitives::merkle_tree::read_commitment_tree::< + MerkleHashOrchard, + &[u8], + { zingolib::wallet::data::COMMITMENT_TREE_LEVELS }, + >(&hex::decode(server_trees.orchard_tree).unwrap()[..]) + .unwrap() + .to_frontier() + .take(); + let mut server_orchard_shardtree: ShardTree<_, COMMITMENT_TREE_LEVELS, MAX_SHARD_LEVEL> = + ShardTree::new( + MemoryShardStore::::empty(), + MAX_REORG, + ); + server_orchard_shardtree + .insert_frontier_nodes( + server_orchard_front.unwrap(), + zingolib::testutils::incrementalmerkletree::Retention::Marked, + ) + .unwrap(); + // This height doesn't matter, all we need is any arbitrary checkpoint ID + // as witness_at_checkpoint_depth requres a checkpoint to function now + server_orchard_shardtree + .checkpoint(BlockHeight::from_u32(0)) + .unwrap(); + assert_eq!( + wallet_trees + .witness_tree_orchard + .witness_at_checkpoint_depth(last_leaf.unwrap(), 0) + .unwrap_or_else(|_| panic!("{:#?}", wallet_trees.witness_tree_orchard)), + server_orchard_shardtree + .witness_at_checkpoint_depth(last_leaf.unwrap(), 0) + .unwrap() + ) + } + #[tokio::test] + async fn create_send_to_self_with_zfz_active() { + let (_regtest_manager, _cph, _faucet, recipient, _txid) = + scenarios::orchard_funded_recipient(5_000_000).await; + + recipient + .propose_send_all( + address_from_str(&get_base_address_macro!(&recipient, "unified")).unwrap(), + true, + None, + ) + .await + .unwrap(); + + recipient + .complete_and_broadcast_stored_proposal() + .await + .unwrap(); + + let value_transfers = &recipient.sorted_value_transfers(true).await; + + dbg!(value_transfers); + + assert!(value_transfers.iter().any(|vt| vt.kind() + == ValueTransferKind::Sent(SentValueTransfer::SendToSelf( + SelfSendValueTransfer::Basic + )))); + assert!(value_transfers.iter().any(|vt| vt.kind() + == ValueTransferKind::Sent(SentValueTransfer::Send) + && vt.recipient_address() == Some(ZENNIES_FOR_ZINGO_REGTEST_ADDRESS))); + } + + /// This tests checks that messages_containing returns an empty vector when empty memos are included. + #[tokio::test] + async fn filter_empty_messages() { + let mut environment = LibtonodeEnvironment::setup().await; + + let faucet = environment.create_faucet().await; + let recipient = environment.create_client().await; + + environment.bump_chain().await; + faucet.do_sync(false).await.unwrap(); + + check_client_balances!(faucet, o: 0 s: 2_500_000_000u64 t: 0u64); + + from_inputs::quick_send( + &faucet, + vec![ + ( + get_base_address_macro!(recipient, "unified").as_str(), + 5_000, + Some(""), + ), + ( + get_base_address_macro!(recipient, "unified").as_str(), + 5_000, + Some(""), + ), + ], + ) + .await + .unwrap(); + + environment.bump_chain().await; + recipient.do_sync(false).await.unwrap(); + + let no_messages = &recipient.messages_containing(None).await; + + assert_eq!(no_messages.0.len(), 0); + + from_inputs::quick_send( + &faucet, + vec![ + ( + get_base_address_macro!(recipient, "unified").as_str(), + 5_000, + Some("Hello"), + ), + ( + get_base_address_macro!(recipient, "unified").as_str(), + 5_000, + Some(""), + ), + ], + ) + .await + .unwrap(); + + environment.bump_chain().await; + recipient.do_sync(false).await.unwrap(); + + let single_message = &recipient.messages_containing(None).await; + + assert_eq!(single_message.0.len(), 1); + } + + /// Test sending and receiving messages between three parties. + /// + /// This test case consists of the following sequence of events: + /// + /// 1. Alice sends a message to Bob. + /// 2. Alice sends another message to Bob. + /// 3. Bob sends a message to Alice. + /// 4. Alice sends a message to Charlie. + /// 5. Charlie sends a message to Alice. + /// + /// After the messages are sent, the test checks that the `messages_containing` method + /// returns the expected messages for each party in the correct order. + #[tokio::test] + async fn message_thread() { + let (regtest_manager, _cph, faucet, recipient, _txid) = + scenarios::orchard_funded_recipient(10_000_000).await; let alice = get_base_address(&recipient, PoolType::ORCHARD).await; let bob = faucet @@ -2741,298 +3032,6 @@ mod slow { */ } - // FIXME: it seems this test makes assertions on mempool but mempool monitoring is off? - #[tokio::test] - async fn mempool_clearing_and_full_batch_syncs_correct_trees() { - async fn do_maybe_recent_txid(lc: &LightClient) -> JsonValue { - json::object! { - "last_txid" => lc.wallet.transactions().read().await.get_some_txid_from_highest_wallet_block().map(|t| t.to_string()) - } - } - let value = 100_000; - let regtest_network = RegtestNetwork::all_upgrades_active(); - let (regtest_manager, _cph, faucet, recipient, orig_transaction_id, _, _) = - scenarios::faucet_funded_recipient( - Some(value), - None, - None, - PoolType::Shielded(ShieldedProtocol::Sapling), - regtest_network, - ) - .await; - let orig_transaction_id = orig_transaction_id.unwrap(); - assert_eq!( - do_maybe_recent_txid(&recipient).await["last_txid"], - orig_transaction_id - ); - // Put some transactions unrelated to the recipient (faucet->faucet) on-chain, to get some clutter - for _ in 0..5 { - zingolib::testutils::send_value_between_clients_and_sync( - ®test_manager, - &faucet, - &faucet, - 5_000, - "unified", - ) - .await - .unwrap(); - } - - let sent_to_self = 10; - // Send recipient->recipient, to make tree equality check at the end simpler - zingolib::testutils::send_value_between_clients_and_sync( - ®test_manager, - &recipient, - &recipient, - sent_to_self, - "unified", - ) - .await - .unwrap(); - let fees = get_fees_paid_by_client(&recipient).await; - assert_eq!(value - fees, 90_000); - let balance_minus_step_one_fees = value - fees; - - // 3a. stash zcashd state - log::debug!( - "old zcashd chain info {}", - std::str::from_utf8( - ®test_manager - .get_cli_handle() - .arg("getblockchaininfo") - .output() - .unwrap() - .stdout - ) - .unwrap() - ); - - // Turn zcashd off and on again, to write down the blocks - drop(_cph); // turn off zcashd and lightwalletd - let _cph = regtest_manager.launch(false).unwrap(); - log::debug!( - "new zcashd chain info {}", - std::str::from_utf8( - ®test_manager - .get_cli_handle() - .arg("getblockchaininfo") - .output() - .unwrap() - .stdout - ) - .unwrap() - ); - - let zcd_datadir = ®test_manager.zcashd_data_dir; - let zcashd_parent = Path::new(zcd_datadir).parent().unwrap(); - let original_zcashd_directory = zcashd_parent.join("original_zcashd"); - - log::debug!( - "The original zcashd directory is at: {}", - &original_zcashd_directory.to_string_lossy().to_string() - ); - - let source = &zcd_datadir.to_string_lossy().to_string(); - let dest = &original_zcashd_directory.to_string_lossy().to_string(); - std::process::Command::new("cp") - .arg("-rf") - .arg(source) - .arg(dest) - .output() - .expect("directory copy failed"); - - // 3. Send z-to-z transaction to external z address with a memo - let sent_value = 2000; - let outgoing_memo = "Outgoing Memo"; - - let sent_transaction_id = from_inputs::quick_send( - &recipient, - vec![( - &get_base_address_macro!(faucet, "sapling"), - sent_value, - Some(outgoing_memo), - )], - ) - .await - .unwrap() - .first() - .to_string(); - - let second_transaction_fee; - { - let tmds = recipient - .wallet - .transaction_context - .transaction_metadata_set - .read() - .await; - let record = tmds - .transaction_records_by_id - .get( - &crate::utils::conversion::txid_from_hex_encoded_str(&sent_transaction_id) - .unwrap(), - ) - .unwrap(); - second_transaction_fee = tmds - .transaction_records_by_id - .calculate_transaction_fee(record) - .unwrap(); - // Sync recipient - } // drop transaction_record references and tmds read lock - recipient.do_sync(false).await.unwrap(); - - // 4b write down state before clearing the mempool - let notes_before = recipient.do_list_notes(true).await; - let transactions_before = recipient.do_list_transactions().await; - - // Sync recipient again. We assert this should be a no-op, as we just synced - recipient.do_sync(false).await.unwrap(); - let post_sync_notes_before = recipient.do_list_notes(true).await; - let post_sync_transactions_before = recipient.do_list_transactions().await; - assert_eq!(post_sync_notes_before, notes_before); - assert_eq!(post_sync_transactions_before, transactions_before); - - drop(_cph); // Turn off zcashd and lightwalletd - - // 5. check that the sent transaction is correctly marked in the client - let transactions = recipient.do_list_transactions().await; - let mempool_only_tx = transactions - .members() - .find(|tx| tx["txid"] == sent_transaction_id) - .unwrap() - .clone(); - log::debug!("the transactions are: {}", &mempool_only_tx); - assert_eq!( - mempool_only_tx["outgoing_metadata"][0]["memo"], - "Outgoing Memo" - ); - assert_eq!(mempool_only_tx["txid"], sent_transaction_id); - - // 6. note that the client correctly considers the note pending - assert_eq!(mempool_only_tx["pending"], true); - - std::process::Command::new("rm") - .arg("-rf") - .arg(source) - .output() - .expect("recursive rm failed"); - std::process::Command::new("cp") - .arg("--recursive") - .arg("--remove-destination") - .arg(dest) - .arg(source) - .output() - .expect("directory copy failed"); - assert_eq!( - source, - ®test_manager - .zcashd_data_dir - .to_string_lossy() - .to_string() - ); - let _cph = regtest_manager.launch(false).unwrap(); - let notes_after = recipient.do_list_notes(true).await; - let transactions_after = recipient.do_list_transactions().await; - - assert_eq!(notes_before.pretty(2), notes_after.pretty(2)); - assert_eq!(transactions_before.pretty(2), transactions_after.pretty(2)); - - // 6. Mine 10 blocks, the pending transaction should still be there. - zingolib::testutils::increase_height_and_wait_for_client(®test_manager, &recipient, 10) - .await - .unwrap(); - assert_eq!(recipient.wallet.last_synced_height().await, 21); - - let notes = recipient.do_list_notes(true).await; - - let transactions = recipient.do_list_transactions().await; - - // There are 2 unspent notes, the pending transaction, and the final receipt - println!("{}", json::stringify_pretty(notes.clone(), 4)); - println!("{}", json::stringify_pretty(transactions.clone(), 4)); - // Two unspent notes: one change, pending, one from faucet, confirmed - assert_eq!(notes["unspent_orchard_notes"].len(), 2); - assert_eq!(notes["unspent_sapling_notes"].len(), 0); - let note = notes["unspent_orchard_notes"][1].clone(); - assert_eq!(note["created_in_txid"], sent_transaction_id); - assert_eq!( - note["value"].as_u64().unwrap(), - balance_minus_step_one_fees - sent_value - second_transaction_fee - sent_to_self - ); - assert!(note["pending"].as_bool().unwrap()); - assert_eq!(transactions.len(), 3); - - // 7. Mine 100 blocks, so the mempool expires - zingolib::testutils::increase_height_and_wait_for_client(®test_manager, &recipient, 100) - .await - .unwrap(); - assert_eq!(recipient.wallet.last_synced_height().await, 121); - - let notes = recipient.do_list_notes(true).await; - let transactions = recipient.do_list_transactions().await; - - // There are now three notes, the original (confirmed and spent) note, the send to self note, and its change. - assert_eq!(notes["unspent_orchard_notes"].len(), 2); - assert_eq!( - notes["spent_orchard_notes"][0]["created_in_txid"], - orig_transaction_id - ); - assert!(!notes["unspent_orchard_notes"][0]["pending"] - .as_bool() - .unwrap()); - assert_eq!(notes["pending_orchard_notes"].len(), 0); - assert_eq!(transactions.len(), 2); - let read_lock = recipient - .wallet - .transaction_context - .transaction_metadata_set - .read() - .await; - let wallet_trees = read_lock.witness_trees().unwrap(); - let last_leaf = wallet_trees - .witness_tree_orchard - .max_leaf_position(None) - .unwrap(); - let server_trees = zingolib::grpc_connector::get_trees( - recipient.get_server_uri(), - recipient.wallet.last_synced_height().await, - ) - .await - .unwrap(); - let server_orchard_front = zcash_primitives::merkle_tree::read_commitment_tree::< - MerkleHashOrchard, - &[u8], - { zingolib::wallet::data::COMMITMENT_TREE_LEVELS }, - >(&hex::decode(server_trees.orchard_tree).unwrap()[..]) - .unwrap() - .to_frontier() - .take(); - let mut server_orchard_shardtree: ShardTree<_, COMMITMENT_TREE_LEVELS, MAX_SHARD_LEVEL> = - ShardTree::new( - MemoryShardStore::::empty(), - MAX_REORG, - ); - server_orchard_shardtree - .insert_frontier_nodes( - server_orchard_front.unwrap(), - zingolib::testutils::incrementalmerkletree::Retention::Marked, - ) - .unwrap(); - // This height doesn't matter, all we need is any arbitrary checkpoint ID - // as witness_at_checkpoint_depth requres a checkpoint to function now - server_orchard_shardtree - .checkpoint(BlockHeight::from_u32(0)) - .unwrap(); - assert_eq!( - wallet_trees - .witness_tree_orchard - .witness_at_checkpoint_depth(last_leaf.unwrap(), 0) - .unwrap_or_else(|_| panic!("{:#?}", wallet_trees.witness_tree_orchard)), - server_orchard_shardtree - .witness_at_checkpoint_depth(last_leaf.unwrap(), 0) - .unwrap() - ) - } // FIXME: it seems this test makes assertions on mempool but mempool monitoring is off? #[tokio::test] async fn mempool_and_balance() { diff --git a/zingolib/src/wallet/transaction_records_by_id.rs b/zingolib/src/wallet/transaction_records_by_id.rs index e8d9f9204..678b438d6 100644 --- a/zingolib/src/wallet/transaction_records_by_id.rs +++ b/zingolib/src/wallet/transaction_records_by_id.rs @@ -466,9 +466,9 @@ impl TransactionRecordsById { /// Invalidates all those transactions which were broadcast but never 'confirmed' accepted by a miner. pub(crate) fn clear_expired_mempool(&mut self, latest_height: u64) { - let cutoff = BlockHeight::from_u32( - (latest_height.saturating_sub(crate::config::MAX_REORG as u64)) as u32, - ); + // Pending window: How long to wait past the chain tip before clearing a pending + let pending_window = 2; + let cutoff = BlockHeight::from_u32((latest_height.saturating_sub(pending_window)) as u32); let txids_to_remove = self .iter()