diff --git a/Cargo.lock b/Cargo.lock index a7fb26cb77..2cdd520ad4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4238,7 +4238,6 @@ dependencies = [ "env_logger 0.7.1", "fs2", "futures 0.3.31", - "indexmap 2.7.0", "itertools 0.10.5", "libsqlite3-sys", "log", diff --git a/base_layer/wallet/Cargo.toml b/base_layer/wallet/Cargo.toml index a40626d725..2f95abf2d2 100644 --- a/base_layer/wallet/Cargo.toml +++ b/base_layer/wallet/Cargo.toml @@ -7,7 +7,6 @@ version = "1.9.2-pre.0" edition = "2018" [dependencies] -indexmap = "2.7.0" tari_common = { path = "../../common", version = "1.9.2-pre.0" } tari_common_sqlite = { path = "../../common_sqlite", version = "1.9.2-pre.0" } tari_common_types = { path = "../../base_layer/common_types", version = "1.9.2-pre.0" } diff --git a/base_layer/wallet/src/transaction_service/handle.rs b/base_layer/wallet/src/transaction_service/handle.rs index b2adba44a5..96a4850018 100644 --- a/base_layer/wallet/src/transaction_service/handle.rs +++ b/base_layer/wallet/src/transaction_service/handle.rs @@ -28,7 +28,6 @@ use std::{ }; use chrono::{DateTime, Utc}; -use indexmap::IndexMap; use tari_common_types::{ burnt_proof::BurntProof, tari_address::TariAddress, @@ -418,9 +417,9 @@ pub enum TransactionServiceResponse { template_registration: Box, }, TransactionCancelled, - PendingInboundTransactions(HashMap), - PendingOutboundTransactions(HashMap), - CompletedTransactions(IndexMap), + PendingInboundTransactions(Vec), + PendingOutboundTransactions(Vec), + CompletedTransactions(Vec), CompletedTransaction(Box), BaseNodePublicKeySet, UtxoImported(TxId), @@ -912,9 +911,10 @@ impl TransactionServiceHandle { } } + /////////////////////////////// pub async fn get_pending_inbound_transactions( &mut self, - ) -> Result, TransactionServiceError> { + ) -> Result, TransactionServiceError> { match self .handle .call(TransactionServiceRequest::GetPendingInboundTransactions) @@ -927,7 +927,7 @@ impl TransactionServiceHandle { pub async fn get_cancelled_pending_inbound_transactions( &mut self, - ) -> Result, TransactionServiceError> { + ) -> Result, TransactionServiceError> { match self .handle .call(TransactionServiceRequest::GetCancelledPendingInboundTransactions) @@ -940,7 +940,7 @@ impl TransactionServiceHandle { pub async fn get_pending_outbound_transactions( &mut self, - ) -> Result, TransactionServiceError> { + ) -> Result, TransactionServiceError> { match self .handle .call(TransactionServiceRequest::GetPendingOutboundTransactions) @@ -953,7 +953,7 @@ impl TransactionServiceHandle { pub async fn get_cancelled_pending_outbound_transactions( &mut self, - ) -> Result, TransactionServiceError> { + ) -> Result, TransactionServiceError> { match self .handle .call(TransactionServiceRequest::GetCancelledPendingOutboundTransactions) @@ -964,9 +964,7 @@ impl TransactionServiceHandle { } } - pub async fn get_completed_transactions( - &mut self, - ) -> Result, TransactionServiceError> { + pub async fn get_completed_transactions(&mut self) -> Result, TransactionServiceError> { match self .handle .call(TransactionServiceRequest::GetCompletedTransactions) @@ -979,7 +977,7 @@ impl TransactionServiceHandle { pub async fn get_cancelled_completed_transactions( &mut self, - ) -> Result, TransactionServiceError> { + ) -> Result, TransactionServiceError> { match self .handle .call(TransactionServiceRequest::GetCancelledCompletedTransactions) @@ -990,6 +988,8 @@ impl TransactionServiceHandle { } } + /////////////////////////// + pub async fn get_completed_transaction( &mut self, tx_id: TxId, diff --git a/base_layer/wallet/src/transaction_service/service.rs b/base_layer/wallet/src/transaction_service/service.rs index c6108fb797..645030b354 100644 --- a/base_layer/wallet/src/transaction_service/service.rs +++ b/base_layer/wallet/src/transaction_service/service.rs @@ -2750,29 +2750,29 @@ where >, ) -> Result<(), TransactionServiceError> { let outbound_txs = self.db.get_pending_outbound_transactions()?; - for (tx_id, tx) in outbound_txs { + for tx in outbound_txs { let (sender_protocol, stage) = if tx.send_count > 0 { (None, TransactionSendProtocolStage::WaitForReply) } else { (Some(tx.sender_protocol), TransactionSendProtocolStage::Queued) }; let (not_yet_pending, queued) = ( - !self.pending_transaction_reply_senders.contains_key(&tx_id), + !self.pending_transaction_reply_senders.contains_key(&tx.tx_id), stage == TransactionSendProtocolStage::Queued, ); if not_yet_pending { debug!( target: LOG_TARGET, - "Restarting listening for Reply for Pending Outbound Transaction TxId: {}", tx_id + "Restarting listening for Reply for Pending Outbound Transaction TxId: {}", tx.tx_id ); } else if queued { debug!( target: LOG_TARGET, - "Retry sending queued Pending Outbound Transaction TxId: {}", tx_id + "Retry sending queued Pending Outbound Transaction TxId: {}", tx.tx_id ); - let _sender = self.pending_transaction_reply_senders.remove(&tx_id); - let _sender = self.send_transaction_cancellation_senders.remove(&tx_id); + let _sender = self.pending_transaction_reply_senders.remove(&tx.tx_id); + let _sender = self.send_transaction_cancellation_senders.remove(&tx.tx_id); } else { // dont care } @@ -2780,12 +2780,12 @@ where if not_yet_pending || queued { let (tx_reply_sender, tx_reply_receiver) = mpsc::channel(100); let (cancellation_sender, cancellation_receiver) = oneshot::channel(); - self.pending_transaction_reply_senders.insert(tx_id, tx_reply_sender); + self.pending_transaction_reply_senders.insert(tx.tx_id, tx_reply_sender); self.send_transaction_cancellation_senders - .insert(tx_id, cancellation_sender); + .insert(tx.tx_id, cancellation_sender); let protocol = TransactionSendProtocol::new( - tx_id, + tx.tx_id, self.resources.clone(), tx_reply_receiver, cancellation_receiver, diff --git a/base_layer/wallet/src/transaction_service/storage/database.rs b/base_layer/wallet/src/transaction_service/storage/database.rs index c539485660..143e8936aa 100644 --- a/base_layer/wallet/src/transaction_service/storage/database.rs +++ b/base_layer/wallet/src/transaction_service/storage/database.rs @@ -21,14 +21,12 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use std::{ - collections::HashMap, fmt, fmt::{Display, Error, Formatter}, sync::Arc, }; use chrono::{DateTime, Utc}; -use indexmap::IndexMap; use log::*; use tari_common_types::{ tari_address::TariAddress, @@ -246,9 +244,9 @@ pub enum DbValue { PendingOutboundTransaction(Box), PendingInboundTransaction(Box), CompletedTransaction(Box), - PendingOutboundTransactions(HashMap), - PendingInboundTransactions(HashMap), - CompletedTransactions(IndexMap), + PendingOutboundTransactions(Vec), + PendingInboundTransactions(Vec), + CompletedTransactions(Vec), WalletTransaction(Box), } @@ -509,22 +507,20 @@ where T: TransactionBackend + 'static Ok(*t) } - pub fn get_pending_inbound_transactions( - &self, - ) -> Result, TransactionStorageError> { + pub fn get_pending_inbound_transactions(&self) -> Result, TransactionStorageError> { self.get_pending_inbound_transactions_by_cancelled(false) } pub fn get_cancelled_pending_inbound_transactions( &self, - ) -> Result, TransactionStorageError> { + ) -> Result, TransactionStorageError> { self.get_pending_inbound_transactions_by_cancelled(true) } fn get_pending_inbound_transactions_by_cancelled( &self, cancelled: bool, - ) -> Result, TransactionStorageError> { + ) -> Result, TransactionStorageError> { let key = if cancelled { DbKey::CancelledPendingInboundTransactions } else { @@ -545,22 +541,20 @@ where T: TransactionBackend + 'static Ok(t) } - pub fn get_pending_outbound_transactions( - &self, - ) -> Result, TransactionStorageError> { + pub fn get_pending_outbound_transactions(&self) -> Result, TransactionStorageError> { self.get_pending_outbound_transactions_by_cancelled(false) } pub fn get_cancelled_pending_outbound_transactions( &self, - ) -> Result, TransactionStorageError> { + ) -> Result, TransactionStorageError> { self.get_pending_outbound_transactions_by_cancelled(true) } fn get_pending_outbound_transactions_by_cancelled( &self, cancelled: bool, - ) -> Result, TransactionStorageError> { + ) -> Result, TransactionStorageError> { let key = if cancelled { DbKey::CancelledPendingOutboundTransactions } else { @@ -589,13 +583,11 @@ where T: TransactionBackend + 'static Ok(address) } - pub fn get_completed_transactions(&self) -> Result, TransactionStorageError> { + pub fn get_completed_transactions(&self) -> Result, TransactionStorageError> { self.get_completed_transactions_by_cancelled(false) } - pub fn get_cancelled_completed_transactions( - &self, - ) -> Result, TransactionStorageError> { + pub fn get_cancelled_completed_transactions(&self) -> Result, TransactionStorageError> { self.get_completed_transactions_by_cancelled(true) } @@ -621,7 +613,7 @@ where T: TransactionBackend + 'static fn get_completed_transactions_by_cancelled( &self, cancelled: bool, - ) -> Result, TransactionStorageError> { + ) -> Result, TransactionStorageError> { let key = if cancelled { DbKey::CancelledCompletedTransactions } else { diff --git a/base_layer/wallet/src/transaction_service/storage/sqlite_db.rs b/base_layer/wallet/src/transaction_service/storage/sqlite_db.rs index 4919321bf1..d3ebd0659f 100644 --- a/base_layer/wallet/src/transaction_service/storage/sqlite_db.rs +++ b/base_layer/wallet/src/transaction_service/storage/sqlite_db.rs @@ -21,7 +21,6 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use std::{ - collections::HashMap, convert::{TryFrom, TryInto}, sync::{Arc, RwLock}, }; @@ -48,7 +47,6 @@ use tari_utilities::{hex::Hex, ByteArray, Hidden}; use thiserror::Error; use tokio::time::Instant; use zeroize::Zeroize; -use indexmap::IndexMap; use crate::{ schema::{completed_transactions, inbound_transactions, outbound_transactions}, @@ -267,67 +265,49 @@ impl TransactionBackend for TransactionServiceSqliteDatabase { None }, DbKey::PendingOutboundTransactions => { - let mut result = HashMap::new(); + let mut result = Vec::new(); for o in OutboundTransactionSql::index_by_cancelled(&mut conn, false)? { - result.insert( - (o.tx_id as u64).into(), - OutboundTransaction::try_from(o.clone(), &cipher)?, - ); + result.push(OutboundTransaction::try_from(o.clone(), &cipher)?); } Some(DbValue::PendingOutboundTransactions(result)) }, DbKey::PendingInboundTransactions => { - let mut result = HashMap::new(); + let mut result = Vec::new(); for i in InboundTransactionSql::index_by_cancelled(&mut conn, false)? { - result.insert( - (i.tx_id as u64).into(), - InboundTransaction::try_from((i).clone(), &cipher)?, - ); + result.push(InboundTransaction::try_from((i).clone(), &cipher)?); } Some(DbValue::PendingInboundTransactions(result)) }, DbKey::CompletedTransactions => { - let mut result = IndexMap::new(); + let mut result = Vec::new(); for c in CompletedTransactionSql::index_by_cancelled(&mut conn, false)? { - result.insert( - (c.tx_id as u64).into(), - CompletedTransaction::try_from((c).clone(), &cipher)?, - ); + result.push(CompletedTransaction::try_from((c).clone(), &cipher)?); } Some(DbValue::CompletedTransactions(result)) }, DbKey::CancelledPendingOutboundTransactions => { - let mut result = HashMap::new(); + let mut result = Vec::new(); for o in OutboundTransactionSql::index_by_cancelled(&mut conn, true)? { - result.insert( - (o.tx_id as u64).into(), - OutboundTransaction::try_from((o).clone(), &cipher)?, - ); + result.push(OutboundTransaction::try_from((o).clone(), &cipher)?); } Some(DbValue::PendingOutboundTransactions(result)) }, DbKey::CancelledPendingInboundTransactions => { - let mut result = HashMap::new(); + let mut result = Vec::new(); for i in InboundTransactionSql::index_by_cancelled(&mut conn, true)? { - result.insert( - (i.tx_id as u64).into(), - InboundTransaction::try_from(i.clone(), &cipher)?, - ); + result.push(InboundTransaction::try_from(i.clone(), &cipher)?); } Some(DbValue::PendingInboundTransactions(result)) }, DbKey::CancelledCompletedTransactions => { - let mut result = IndexMap::new(); + let mut result = Vec::new(); for c in CompletedTransactionSql::index_by_cancelled(&mut conn, true)? { - result.insert( - (c.tx_id as u64).into(), - CompletedTransaction::try_from((c).clone(), &cipher)?, - ); + result.push(CompletedTransaction::try_from((c).clone(), &cipher)?); } Some(DbValue::CompletedTransactions(result)) @@ -1193,6 +1173,8 @@ impl InboundTransactionSql { ) -> Result, TransactionStorageError> { Ok(inbound_transactions::table .filter(inbound_transactions::cancelled.eq(i32::from(cancelled))) + // QUESTION(A): Should we order by timestamp or last_send_timestamp? + .order_by(inbound_transactions::timestamp.desc()) .load::(conn)?) } @@ -1457,6 +1439,8 @@ impl OutboundTransactionSql { ) -> Result, TransactionStorageError> { Ok(outbound_transactions::table .filter(outbound_transactions::cancelled.eq(i32::from(cancelled))) + // QUESTION(A): Should we order by timestamp or last_send_timestamp? + .order_by(outbound_transactions::timestamp.desc()) .load::(conn)?) } diff --git a/base_layer/wallet/tests/transaction_service_tests/service.rs b/base_layer/wallet/tests/transaction_service_tests/service.rs index 4fd0ae0149..ce452d9dda 100644 --- a/base_layer/wallet/tests/transaction_service_tests/service.rs +++ b/base_layer/wallet/tests/transaction_service_tests/service.rs @@ -803,9 +803,10 @@ async fn large_interactive_transaction() { // We want to ensure that we can get the pending outbound transaction from the database, // and excercise the sender_protocol let pending_outbound = alice_ts.get_pending_outbound_transactions().await.unwrap(); - pending_outbound.get(id).unwrap().sender_protocol.get_amount_to_recipient().unwrap(); + let po_tx = pending_outbound.iter().find(|tx| tx.tx_id == *id).unwrap(); + po_tx.sender_protocol.get_amount_to_recipient().unwrap(); assert_eq!( - pending_outbound.get(id).unwrap().sender_protocol.get_amount_to_recipient().unwrap(), + po_tx.sender_protocol.get_amount_to_recipient().unwrap(), transaction_value ); }, @@ -825,8 +826,9 @@ async fn large_interactive_transaction() { // We want to ensure that we can get the pending inbound transaction from the database, // and excercise the receiver_protocol let pending_inbound = bob_ts.get_pending_inbound_transactions().await.unwrap(); - assert!(pending_inbound.get(id).unwrap().receiver_protocol.get_signed_data().is_ok()); - assert_eq!(pending_inbound.get(id).unwrap().amount, transaction_value); + let pi_tx = pending_inbound.iter().find(|tx| tx.tx_id == *id).unwrap(); + assert!(pi_tx.receiver_protocol.get_signed_data().is_ok()); + assert_eq!(pi_tx.amount, transaction_value); }, TransactionEvent::ReceivedFinalizedTransaction(id) => { tx_id = *id; @@ -1236,6 +1238,7 @@ async fn test_spend_dust_happy_path() { #[tokio::test] async fn single_transaction_to_self() { + // Question(B): Why stackoverflow? let network = Network::LocalNet; let consensus_manager = ConsensusManager::builder(network).build().unwrap(); let factories = CryptoFactories::default(); @@ -3246,7 +3249,8 @@ async fn test_transaction_cancellation() { .get_pending_outbound_transactions() .await .unwrap() - .remove(&tx_id) + .iter() + .find(|tx| tx.tx_id == tx_id) { None => (), Some(_) => break, @@ -3303,7 +3307,8 @@ async fn test_transaction_cancellation() { .get_pending_outbound_transactions() .await .unwrap() - .remove(&tx_id) + .iter() + .find(|tx| tx.tx_id == tx_id) .is_none()); let key_manager = create_memory_db_key_manager().unwrap(); @@ -3373,13 +3378,13 @@ async fn test_transaction_cancellation() { } } - alice_ts_interface + assert!(alice_ts_interface .transaction_service_handle .get_pending_inbound_transactions() .await .unwrap() - .remove(&tx_id2) - .expect("Pending Transaction 2 should be in list"); + .iter() + .any(|tx| tx.tx_id == tx_id2)); alice_ts_interface .transaction_service_handle @@ -3392,7 +3397,8 @@ async fn test_transaction_cancellation() { .get_pending_inbound_transactions() .await .unwrap() - .remove(&tx_id2) + .iter() + .find(|tx| tx.tx_id == tx_id2) .is_none()); // Lets cancel the last one using a Comms stack message @@ -3460,13 +3466,13 @@ async fn test_transaction_cancellation() { } } - alice_ts_interface + assert!(alice_ts_interface .transaction_service_handle .get_pending_inbound_transactions() .await .unwrap() - .remove(&tx_id3) - .expect("Pending Transaction 3 should be in list"); + .iter() + .any(|tx| tx.tx_id == tx_id3)); let proto_message = proto::TransactionCancelledMessage { tx_id: tx_id3.as_u64() }; // Sent from the wrong source address so should not cancel @@ -3481,13 +3487,13 @@ async fn test_transaction_cancellation() { sleep(Duration::from_secs(5)).await; - alice_ts_interface + assert!(alice_ts_interface .transaction_service_handle .get_pending_inbound_transactions() .await .unwrap() - .remove(&tx_id3) - .expect("Pending Transaction 3 should be in list"); + .iter() + .any(|tx| tx.tx_id == tx_id3)); let proto_message = proto::TransactionCancelledMessage { tx_id: tx_id3.as_u64() }; alice_ts_interface @@ -3519,7 +3525,8 @@ async fn test_transaction_cancellation() { .get_pending_inbound_transactions() .await .unwrap() - .remove(&tx_id3) + .iter() + .find(|tx| tx.tx_id == tx_id3) .is_none()); } #[tokio::test] @@ -5531,12 +5538,14 @@ async fn transaction_service_tx_broadcast() { } assert!(tx1_received); - let alice_completed_tx1 = alice_ts_interface + let alice_completed_txs = alice_ts_interface .transaction_service_handle .get_completed_transactions() .await - .unwrap() - .remove(&tx_id1) + .unwrap(); + let alice_completed_tx1 = alice_completed_txs + .iter() + .find(|tx| tx.tx_id == tx_id1) .expect("Transaction must be in collection"); let tx1_fee = alice_completed_tx1.fee; @@ -5637,12 +5646,14 @@ async fn transaction_service_tx_broadcast() { mined_timestamp: None, }); - let alice_completed_tx2 = alice_ts_interface + let alice_completed_txs = alice_ts_interface .transaction_service_handle .get_completed_transactions() .await - .unwrap() - .remove(&tx_id2) + .unwrap(); + let alice_completed_tx2 = alice_completed_txs + .iter() + .find(|tx| tx.tx_id == tx_id2) .expect("Transaction must be in collection"); assert!( diff --git a/base_layer/wallet/tests/transaction_service_tests/storage.rs b/base_layer/wallet/tests/transaction_service_tests/storage.rs index bed5f10ba4..e0e39ce1e4 100644 --- a/base_layer/wallet/tests/transaction_service_tests/storage.rs +++ b/base_layer/wallet/tests/transaction_service_tests/storage.rs @@ -163,8 +163,7 @@ pub async fn test_db_backend(backend: T) { assert_eq!(&retrieved_outbound_tx, i); assert_eq!(retrieved_outbound_tx.send_count, 0); assert!(retrieved_outbound_tx.last_send_timestamp.is_none()); - - assert_eq!(&retrieved_outbound_txs.get(&i.tx_id).unwrap(), &i); + assert!(retrieved_outbound_txs.iter().any(|tx| tx == i)); } db.increment_send_count(outbound_txs[0].tx_id).unwrap(); @@ -270,7 +269,7 @@ pub async fn test_db_backend(backend: T) { let retrieved_inbound_txs = db.get_pending_inbound_transactions().unwrap(); assert_eq!(inbound_txs.len(), messages.len()); for i in inbound_txs.iter().take(messages.len()) { - let retrieved_tx = retrieved_inbound_txs.get(&i.tx_id).unwrap(); + let retrieved_tx = retrieved_inbound_txs.iter().find(|tx| tx.tx_id == i.tx_id).unwrap(); assert_eq!(&retrieved_tx, &i); assert_eq!(retrieved_tx.send_count, 0); assert!(retrieved_tx.last_send_timestamp.is_none()); @@ -361,14 +360,20 @@ pub async fn test_db_backend(backend: T) { for i in 0..messages.len() { assert_eq!( - retrieved_completed_txs.get(&inbound_txs[i].tx_id).unwrap(), + retrieved_completed_txs + .iter() + .find(|tx| tx.tx_id == inbound_txs[i].tx_id) + .unwrap(), &CompletedTransaction { tx_id: inbound_txs[i].tx_id, ..completed_txs[i].clone() } ); assert_eq!( - retrieved_completed_txs.get(&outbound_txs[i].tx_id).unwrap(), + retrieved_completed_txs + .iter() + .find(|tx| tx.tx_id == outbound_txs[i].tx_id) + .unwrap(), &completed_txs[i] ); } @@ -408,23 +413,23 @@ pub async fn test_db_backend(backend: T) { panic!("Should have found completed tx"); } - let completed_txs_map = db.get_completed_transactions().unwrap(); - let num_completed_txs = completed_txs_map.len(); + let completed_txs = db.get_completed_transactions().unwrap(); + let num_completed_txs = completed_txs.len(); assert_eq!(db.get_cancelled_completed_transactions().unwrap().len(), 0); - let cancelled_tx_id = completed_txs_map[&1u64.into()].tx_id; + let cancelled_tx_id = completed_txs[1].tx_id; assert!(db.get_cancelled_completed_transaction(cancelled_tx_id).is_err()); db.reject_completed_transaction(cancelled_tx_id, TxCancellationReason::Unknown) .unwrap(); - let completed_txs_map = db.get_completed_transactions().unwrap(); - assert_eq!(completed_txs_map.len(), num_completed_txs - 1); + let completed_txs = db.get_completed_transactions().unwrap(); + assert_eq!(completed_txs.len(), num_completed_txs - 1); db.get_cancelled_completed_transaction(cancelled_tx_id) .expect("Should find cancelled transaction"); - let mut cancelled_txs = db.get_cancelled_completed_transactions().unwrap(); + let cancelled_txs = db.get_cancelled_completed_transactions().unwrap(); assert_eq!(cancelled_txs.len(), 1); - assert!(cancelled_txs.remove(&cancelled_tx_id).is_some()); + assert!(cancelled_txs.iter().any(|c_tx| c_tx.tx_id == cancelled_tx_id)); let any_cancelled_completed_tx = db.get_any_transaction(cancelled_tx_id).unwrap().unwrap(); if let WalletTransaction::Completed(tx) = any_cancelled_completed_tx { @@ -481,9 +486,9 @@ pub async fn test_db_backend(backend: T) { panic!("Should have found cancelled inbound tx"); } - let mut cancelled_txs = db.get_cancelled_pending_inbound_transactions().unwrap(); + let cancelled_txs = db.get_cancelled_pending_inbound_transactions().unwrap(); assert_eq!(cancelled_txs.len(), 1); - assert!(cancelled_txs.remove(&999u64.into()).is_some()); + assert!(cancelled_txs.iter().any(|c_tx| c_tx.tx_id == TxId::from(999u64))); let address = TariAddress::new_dual_address_with_default_features( PublicKey::from_secret_key(&PrivateKey::random(&mut OsRng)), PublicKey::from_secret_key(&PrivateKey::random(&mut OsRng)), @@ -530,9 +535,9 @@ pub async fn test_db_backend(backend: T) { assert_eq!(db.get_pending_outbound_transactions().unwrap().len(), 0); - let mut cancelled_txs = db.get_cancelled_pending_outbound_transactions().unwrap(); + let cancelled_txs = db.get_cancelled_pending_outbound_transactions().unwrap(); assert_eq!(cancelled_txs.len(), 1); - assert!(cancelled_txs.remove(&998u64.into()).is_some()); + assert!(cancelled_txs.iter().any(|c_tx| c_tx.tx_id == TxId::from(998u64))); let any_cancelled_outbound_tx = db.get_any_transaction(998u64.into()).unwrap().unwrap(); if let WalletTransaction::PendingOutbound(tx) = any_cancelled_outbound_tx { diff --git a/base_layer/wallet/tests/transaction_service_tests/transaction_protocols.rs b/base_layer/wallet/tests/transaction_service_tests/transaction_protocols.rs index b94d648e81..184d3aa608 100644 --- a/base_layer/wallet/tests/transaction_service_tests/transaction_protocols.rs +++ b/base_layer/wallet/tests/transaction_service_tests/transaction_protocols.rs @@ -844,11 +844,19 @@ async fn tx_validation_protocol_tx_becomes_mined_unconfirmed_then_confirmed() { let completed_txs = resources.db.get_completed_transactions().unwrap(); assert_eq!( - completed_txs.get(&1u64.into()).unwrap().status, + completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(1u64)) + .unwrap() + .status, TransactionStatus::Broadcast ); assert_eq!( - completed_txs.get(&2u64.into()).unwrap().status, + completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(2u64)) + .unwrap() + .status, TransactionStatus::MinedUnconfirmed ); @@ -871,11 +879,19 @@ async fn tx_validation_protocol_tx_becomes_mined_unconfirmed_then_confirmed() { let completed_txs = resources.db.get_completed_transactions().unwrap(); assert_eq!( - completed_txs.get(&1u64.into()).unwrap().status, + completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(1u64)) + .unwrap() + .status, TransactionStatus::Broadcast ); assert_eq!( - completed_txs.get(&2u64.into()).unwrap().status, + completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(2u64)) + .unwrap() + .status, TransactionStatus::Completed ); @@ -916,10 +932,22 @@ async fn tx_validation_protocol_tx_becomes_mined_unconfirmed_then_confirmed() { let completed_txs = resources.db.get_completed_transactions().unwrap(); assert_eq!( - completed_txs.get(&2u64.into()).unwrap().status, + completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(2u64)) + .unwrap() + .status, TransactionStatus::MinedConfirmed ); - assert_eq!(completed_txs.get(&2u64.into()).unwrap().confirmations.unwrap(), 4); + assert_eq!( + completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(2u64)) + .unwrap() + .confirmations + .unwrap(), + 4 + ); } /// Test that revalidation clears the correct db fields and calls for validation of is said transactions @@ -997,10 +1025,22 @@ async fn tx_revalidation() { let completed_txs = resources.db.get_completed_transactions().unwrap(); assert_eq!( - completed_txs.get(&2u64.into()).unwrap().status, + completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(2u64)) + .unwrap() + .status, TransactionStatus::MinedConfirmed ); - assert_eq!(completed_txs.get(&2u64.into()).unwrap().confirmations.unwrap(), 4); + assert_eq!( + completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(2u64)) + .unwrap() + .confirmations + .unwrap(), + 4 + ); let transaction_query_batch_responses = vec![TxQueryBatchResponseProto { signature: Some(SignatureProto::from( @@ -1028,12 +1068,13 @@ async fn tx_revalidation() { .mark_all_non_coinbases_transactions_as_unvalidated() .unwrap(); let completed_txs = resources.db.get_completed_transactions().unwrap(); - assert_eq!( - completed_txs.get(&2u64.into()).unwrap().status, - TransactionStatus::MinedConfirmed - ); - assert_eq!(completed_txs.get(&2u64.into()).unwrap().mined_height, None); - assert_eq!(completed_txs.get(&2u64.into()).unwrap().mined_in_block, None); + let completed_tx_2 = completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(2u64)) + .unwrap(); + assert_eq!(completed_tx_2.status, TransactionStatus::MinedConfirmed); + assert_eq!(completed_tx_2.mined_height, None); + assert_eq!(completed_tx_2.mined_in_block, None); let protocol = TransactionValidationProtocol::new( 5.into(), @@ -1049,11 +1090,12 @@ async fn tx_revalidation() { let completed_txs = resources.db.get_completed_transactions().unwrap(); // data should now be updated and changed - assert_eq!( - completed_txs.get(&2u64.into()).unwrap().status, - TransactionStatus::MinedConfirmed - ); - assert_eq!(completed_txs.get(&2u64.into()).unwrap().confirmations.unwrap(), 8); + let completed_tx_2 = completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(2u64)) + .unwrap(); + assert_eq!(completed_tx_2.status, TransactionStatus::MinedConfirmed); + assert_eq!(completed_tx_2.confirmations.unwrap(), 8); } /// Test that validation detects transactions becoming mined unconfirmed and then confirmed with some going back to @@ -1219,7 +1261,7 @@ async fn tx_validation_protocol_reorg() { let completed_txs = resources.db.get_completed_transactions().unwrap(); let mut unconfirmed_count = 0; let mut confirmed_count = 0; - for tx in completed_txs.values() { + for tx in completed_txs { if tx.status == TransactionStatus::MinedUnconfirmed { unconfirmed_count += 1; } @@ -1335,23 +1377,58 @@ async fn tx_validation_protocol_reorg() { let completed_txs = resources.db.get_completed_transactions().unwrap(); // Tx 1 - assert!(completed_txs.get(&1u64.into()).unwrap().mined_in_block.is_some()); + assert!(completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(1u64)) + .unwrap() + .mined_in_block + .is_some()); // Tx 2 - assert!(completed_txs.get(&2u64.into()).unwrap().mined_in_block.is_some()); + assert!(completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(2u64)) + .unwrap() + .mined_in_block + .is_some()); // Tx 3 - assert!(completed_txs.get(&3u64.into()).unwrap().mined_in_block.is_some()); + assert!(completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(3u64)) + .unwrap() + .mined_in_block + .is_some()); // Tx 4 (reorged out) - assert!(completed_txs.get(&4u64.into()).unwrap().mined_in_block.is_none()); + assert!(completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(4u64)) + .unwrap() + .mined_in_block + .is_none()); // Tx 5 - assert!(completed_txs.get(&5u64.into()).unwrap().mined_in_block.is_some()); + assert!(completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(5u64)) + .unwrap() + .mined_in_block + .is_some()); // Tx 6 (reorged out) - assert!(completed_txs.get(&6u64.into()).unwrap().mined_in_block.is_none()); + assert!(completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(6u64)) + .unwrap() + .mined_in_block + .is_none()); // Tx 7 (reorged out) - assert!(completed_txs.get(&7u64.into()).unwrap().mined_in_block.is_none()); + assert!(completed_txs + .iter() + .find(|c_tx| c_tx.tx_id == TxId::from(7u64)) + .unwrap() + .mined_in_block + .is_none()); }