diff --git a/applications/tari_console_wallet/src/ui/state/wallet_event_monitor.rs b/applications/tari_console_wallet/src/ui/state/wallet_event_monitor.rs index dca471ee9b..c1b51207d0 100644 --- a/applications/tari_console_wallet/src/ui/state/wallet_event_monitor.rs +++ b/applications/tari_console_wallet/src/ui/state/wallet_event_monitor.rs @@ -100,7 +100,7 @@ impl WalletEventMonitor { self.trigger_balance_refresh(); notifier.transaction_mined(tx_id); }, - TransactionEvent::TransactionCancelled(tx_id) => { + TransactionEvent::TransactionCancelled(tx_id, _) => { self.trigger_tx_state_refresh(tx_id).await; self.trigger_balance_refresh(); notifier.transaction_cancelled(tx_id); diff --git a/base_layer/p2p/src/services/liveness/state.rs b/base_layer/p2p/src/services/liveness/state.rs index 4e89d8e91f..3fc0478dba 100644 --- a/base_layer/p2p/src/services/liveness/state.rs +++ b/base_layer/p2p/src/services/liveness/state.rs @@ -152,7 +152,7 @@ impl LivenessState { self.failed_pings .entry(node_id) .and_modify(|v| { - *v = *v + 1; + *v += 1; }) .or_insert(1); } @@ -167,7 +167,7 @@ impl LivenessState { /// a latency sample is added and calculated. The given `peer` must match the recorded peer pub fn record_pong(&mut self, nonce: u64, sent_by: &NodeId) -> Option { self.inc_pongs_received(); - self.failed_pings.remove_entry(&sent_by); + self.failed_pings.remove_entry(sent_by); let (node_id, _) = self.inflight_pings.get(&nonce)?; if node_id == sent_by { diff --git a/base_layer/wallet/src/transaction_service/handle.rs b/base_layer/wallet/src/transaction_service/handle.rs index 0f91f8fee8..6e914aebde 100644 --- a/base_layer/wallet/src/transaction_service/handle.rs +++ b/base_layer/wallet/src/transaction_service/handle.rs @@ -36,6 +36,7 @@ use tari_service_framework::reply_channel::SenderService; use crate::transaction_service::{ error::TransactionServiceError, + protocols::TxRejection, storage::models::{CompletedTransaction, InboundTransaction, OutboundTransaction, WalletTransaction}, }; @@ -150,7 +151,7 @@ pub enum TransactionEvent { TransactionDirectSendResult(TxId, bool), TransactionCompletedImmediately(TxId), TransactionStoreForwardSendResult(TxId, bool), - TransactionCancelled(TxId), + TransactionCancelled(TxId, TxRejection), TransactionBroadcast(TxId), TransactionImported(TxId), TransactionMined { diff --git a/base_layer/wallet/src/transaction_service/protocols/mod.rs b/base_layer/wallet/src/transaction_service/protocols/mod.rs index 15bdb1dd1c..664aab6146 100644 --- a/base_layer/wallet/src/transaction_service/protocols/mod.rs +++ b/base_layer/wallet/src/transaction_service/protocols/mod.rs @@ -20,6 +20,17 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum TxRejection { + Unknown, // 0 + UserCancelled, // 1 + Timeout, // 2 + DoubleSpend, // 3 + Orphan, // 4 + TimeLocked, // 5 + InvalidTransaction, // 6 +} + pub mod transaction_broadcast_protocol; pub mod transaction_receive_protocol; pub mod transaction_send_protocol; diff --git a/base_layer/wallet/src/transaction_service/protocols/transaction_broadcast_protocol.rs b/base_layer/wallet/src/transaction_service/protocols/transaction_broadcast_protocol.rs index 7bcf3ccb3e..4983a7d140 100644 --- a/base_layer/wallet/src/transaction_service/protocols/transaction_broadcast_protocol.rs +++ b/base_layer/wallet/src/transaction_service/protocols/transaction_broadcast_protocol.rs @@ -48,6 +48,7 @@ use crate::{ transaction_service::{ error::{TransactionServiceError, TransactionServiceProtocolError}, handle::TransactionEvent, + protocols::TxRejection, service::TransactionServiceResources, storage::{database::TransactionBackend, models::CompletedTransaction}, }, @@ -215,10 +216,31 @@ where self.cancel_transaction().await; + let reason = match response.rejection_reason { + TxSubmissionRejectionReason::None | TxSubmissionRejectionReason::ValidationFailed => { + TransactionServiceError::MempoolRejectionInvalidTransaction + }, + TxSubmissionRejectionReason::DoubleSpend => TransactionServiceError::MempoolRejectionDoubleSpend, + TxSubmissionRejectionReason::Orphan => TransactionServiceError::MempoolRejectionOrphan, + TxSubmissionRejectionReason::TimeLocked => TransactionServiceError::MempoolRejectionTimeLocked, + _ => TransactionServiceError::UnexpectedBaseNodeResponse, + }; + + let cancellation_event_reason = match reason { + TransactionServiceError::MempoolRejectionInvalidTransaction => TxRejection::InvalidTransaction, + TransactionServiceError::MempoolRejectionDoubleSpend => TxRejection::DoubleSpend, + TransactionServiceError::MempoolRejectionOrphan => TxRejection::Orphan, + TransactionServiceError::MempoolRejectionTimeLocked => TxRejection::TimeLocked, + _ => TxRejection::Unknown, + }; + let _ = self .resources .event_publisher - .send(Arc::new(TransactionEvent::TransactionCancelled(self.tx_id))) + .send(Arc::new(TransactionEvent::TransactionCancelled( + self.tx_id, + cancellation_event_reason, + ))) .map_err(|e| { trace!( target: LOG_TARGET, @@ -228,15 +250,6 @@ where e }); - let reason = match response.rejection_reason { - TxSubmissionRejectionReason::None | TxSubmissionRejectionReason::ValidationFailed => { - TransactionServiceError::MempoolRejectionInvalidTransaction - }, - TxSubmissionRejectionReason::DoubleSpend => TransactionServiceError::MempoolRejectionDoubleSpend, - TxSubmissionRejectionReason::Orphan => TransactionServiceError::MempoolRejectionOrphan, - TxSubmissionRejectionReason::TimeLocked => TransactionServiceError::MempoolRejectionTimeLocked, - _ => TransactionServiceError::UnexpectedBaseNodeResponse, - }; return Err(TransactionServiceProtocolError::new(self.tx_id, reason)); } else if response.rejection_reason == TxSubmissionRejectionReason::AlreadyMined { info!( @@ -342,7 +355,10 @@ where let _ = self .resources .event_publisher - .send(Arc::new(TransactionEvent::TransactionCancelled(self.tx_id))) + .send(Arc::new(TransactionEvent::TransactionCancelled( + self.tx_id, + TxRejection::InvalidTransaction, + ))) .map_err(|e| { trace!( target: LOG_TARGET, diff --git a/base_layer/wallet/src/transaction_service/protocols/transaction_receive_protocol.rs b/base_layer/wallet/src/transaction_service/protocols/transaction_receive_protocol.rs index 2be90c9b48..1ce1e4ba9c 100644 --- a/base_layer/wallet/src/transaction_service/protocols/transaction_receive_protocol.rs +++ b/base_layer/wallet/src/transaction_service/protocols/transaction_receive_protocol.rs @@ -39,7 +39,7 @@ use tari_common_types::transaction::{TransactionDirection, TransactionStatus, Tx use tari_comms::types::CommsPublicKey; use tokio::sync::{mpsc, oneshot}; -use crate::connectivity_service::WalletConnectivityInterface; +use crate::{connectivity_service::WalletConnectivityInterface, transaction_service::protocols::TxRejection}; use tari_common_types::types::HashOutput; use tari_core::transactions::{ transaction_entities::Transaction, @@ -504,7 +504,10 @@ where let _ = self .resources .event_publisher - .send(Arc::new(TransactionEvent::TransactionCancelled(self.id))) + .send(Arc::new(TransactionEvent::TransactionCancelled( + self.id, + TxRejection::Timeout, + ))) .map_err(|e| { trace!( target: LOG_TARGET, diff --git a/base_layer/wallet/src/transaction_service/protocols/transaction_send_protocol.rs b/base_layer/wallet/src/transaction_service/protocols/transaction_send_protocol.rs index 34d68644df..5812f2ac58 100644 --- a/base_layer/wallet/src/transaction_service/protocols/transaction_send_protocol.rs +++ b/base_layer/wallet/src/transaction_service/protocols/transaction_send_protocol.rs @@ -26,6 +26,7 @@ use crate::{ config::TransactionRoutingMechanism, error::{TransactionServiceError, TransactionServiceProtocolError}, handle::{TransactionEvent, TransactionServiceResponse}, + protocols::TxRejection, service::TransactionServiceResources, storage::{ database::TransactionBackend, @@ -826,7 +827,10 @@ where let _ = self .resources .event_publisher - .send(Arc::new(TransactionEvent::TransactionCancelled(self.id))) + .send(Arc::new(TransactionEvent::TransactionCancelled( + self.id, + TxRejection::Timeout, + ))) .map_err(|e| { trace!( target: LOG_TARGET, diff --git a/base_layer/wallet/src/transaction_service/protocols/transaction_validation_protocol.rs b/base_layer/wallet/src/transaction_service/protocols/transaction_validation_protocol.rs index 639a246e7a..bf34834081 100644 --- a/base_layer/wallet/src/transaction_service/protocols/transaction_validation_protocol.rs +++ b/base_layer/wallet/src/transaction_service/protocols/transaction_validation_protocol.rs @@ -64,6 +64,7 @@ pub struct TransactionValidationProtocol { - if let TransactionEvent::TransactionCancelled(_) = &*event.unwrap() { + if let TransactionEvent::TransactionCancelled(..) = &*event.unwrap() { cancelled = true; break; } @@ -2380,7 +2380,7 @@ fn test_transaction_cancellation() { loop { tokio::select! { event = alice_event_stream.recv() => { - if let TransactionEvent::TransactionCancelled(_) = &*event.unwrap() { + if let TransactionEvent::TransactionCancelled(..) = &*event.unwrap() { cancelled = true; break; } @@ -3524,7 +3524,7 @@ fn test_coinbase_abandoned() { loop { tokio::select! { event = alice_event_stream.recv() => { - if let TransactionEvent::TransactionCancelled(tx_id) = &*event.unwrap() { + if let TransactionEvent::TransactionCancelled(tx_id, _) = &*event.unwrap() { if tx_id == &tx_id1 { count += 1; } @@ -3684,7 +3684,7 @@ fn test_coinbase_abandoned() { count += 1; } }, - TransactionEvent::TransactionCancelled(tx_id) => { + TransactionEvent::TransactionCancelled(tx_id, _) => { if tx_id == &tx_id2 { count += 1; } @@ -3771,7 +3771,7 @@ fn test_coinbase_abandoned() { count += 1; } }, - TransactionEvent::TransactionCancelled(tx_id) => { + TransactionEvent::TransactionCancelled(tx_id, _) => { if tx_id == &tx_id1 { count += 1; } @@ -4755,7 +4755,7 @@ fn test_transaction_timeout_cancellation() { loop { tokio::select! { event = carol_event_stream.recv() => { - if let TransactionEvent::TransactionCancelled(t) = &*event.unwrap() { + if let TransactionEvent::TransactionCancelled(t, _) = &*event.unwrap() { if t == &tx_id { transaction_cancelled = true; break; @@ -5074,7 +5074,7 @@ fn transaction_service_tx_broadcast() { loop { tokio::select! { event = alice_event_stream.recv() => { - if let TransactionEvent::TransactionCancelled(tx_id) = &*event.unwrap(){ + if let TransactionEvent::TransactionCancelled(tx_id, _) = &*event.unwrap(){ if tx_id == &tx_id2 { tx2_cancelled = true; break; diff --git a/base_layer/wallet/tests/transaction_service/transaction_protocols.rs b/base_layer/wallet/tests/transaction_service/transaction_protocols.rs index 102c744769..e38cf6f022 100644 --- a/base_layer/wallet/tests/transaction_service/transaction_protocols.rs +++ b/base_layer/wallet/tests/transaction_service/transaction_protocols.rs @@ -370,7 +370,7 @@ async fn tx_broadcast_protocol_submit_rejection() { loop { tokio::select! { event = event_stream.recv() => { - if let TransactionEvent::TransactionCancelled(_) = &*event.unwrap() { + if let TransactionEvent::TransactionCancelled(..) = &*event.unwrap() { cancelled = true; } }, @@ -547,7 +547,7 @@ async fn tx_broadcast_protocol_submit_success_followed_by_rejection() { loop { tokio::select! { event = event_stream.recv() => { - if let TransactionEvent::TransactionCancelled(_) = &*event.unwrap() { + if let TransactionEvent::TransactionCancelled(..) = &*event.unwrap() { cancelled = true; } }, diff --git a/base_layer/wallet/tests/wallet/mod.rs b/base_layer/wallet/tests/wallet/mod.rs index bd6e6f8d79..ee090ca23a 100644 --- a/base_layer/wallet/tests/wallet/mod.rs +++ b/base_layer/wallet/tests/wallet/mod.rs @@ -632,7 +632,7 @@ fn test_store_and_forward_send_tx() { event = carol_event_stream.recv() => { match &*event.unwrap() { TransactionEvent::ReceivedTransaction(_) => tx_recv = true, - TransactionEvent::TransactionCancelled(_) => tx_cancelled = true, + TransactionEvent::TransactionCancelled(..) => tx_cancelled = true, _ => (), } if tx_recv && tx_cancelled { diff --git a/base_layer/wallet_ffi/src/callback_handler.rs b/base_layer/wallet_ffi/src/callback_handler.rs index fffbe5800e..9418b38e1b 100644 --- a/base_layer/wallet_ffi/src/callback_handler.rs +++ b/base_layer/wallet_ffi/src/callback_handler.rs @@ -88,7 +88,7 @@ where TBackend: TransactionBackend + 'static callback_transaction_mined_unconfirmed: unsafe extern "C" fn(*mut CompletedTransaction, u64), callback_direct_send_result: unsafe extern "C" fn(TxId, bool), callback_store_and_forward_send_result: unsafe extern "C" fn(TxId, bool), - callback_transaction_cancellation: unsafe extern "C" fn(*mut CompletedTransaction), + callback_transaction_cancellation: unsafe extern "C" fn(*mut CompletedTransaction, u64), callback_txo_validation_complete: unsafe extern "C" fn(u64, u8), callback_balance_updated: unsafe extern "C" fn(*mut Balance), callback_transaction_validation_complete: unsafe extern "C" fn(u64, u8), @@ -123,7 +123,7 @@ where TBackend: TransactionBackend + 'static callback_transaction_mined_unconfirmed: unsafe extern "C" fn(*mut CompletedTransaction, u64), callback_direct_send_result: unsafe extern "C" fn(TxId, bool), callback_store_and_forward_send_result: unsafe extern "C" fn(TxId, bool), - callback_transaction_cancellation: unsafe extern "C" fn(*mut CompletedTransaction), + callback_transaction_cancellation: unsafe extern "C" fn(*mut CompletedTransaction, u64), callback_txo_validation_complete: unsafe extern "C" fn(TxId, u8), callback_balance_updated: unsafe extern "C" fn(*mut Balance), callback_transaction_validation_complete: unsafe extern "C" fn(TxId, u8), @@ -242,8 +242,8 @@ where TBackend: TransactionBackend + 'static self.receive_store_and_forward_send_result(tx_id, result); self.trigger_balance_refresh().await; }, - TransactionEvent::TransactionCancelled(tx_id) => { - self.receive_transaction_cancellation(tx_id).await; + TransactionEvent::TransactionCancelled(tx_id, reason) => { + self.receive_transaction_cancellation(tx_id, reason as u64).await; self.trigger_balance_refresh().await; }, TransactionEvent::TransactionBroadcast(tx_id) => { @@ -425,7 +425,7 @@ where TBackend: TransactionBackend + 'static } } - async fn receive_transaction_cancellation(&mut self, tx_id: TxId) { + async fn receive_transaction_cancellation(&mut self, tx_id: TxId, reason: u64) { let mut transaction = None; if let Ok(tx) = self.db.get_cancelled_completed_transaction(tx_id).await { transaction = Some(tx); @@ -451,7 +451,7 @@ where TBackend: TransactionBackend + 'static ); let boxing = Box::into_raw(Box::new(tx)); unsafe { - (self.callback_transaction_cancellation)(boxing); + (self.callback_transaction_cancellation)(boxing, reason); } }, } diff --git a/base_layer/wallet_ffi/src/callback_handler_tests.rs b/base_layer/wallet_ffi/src/callback_handler_tests.rs index e544fab345..4d90f2b3ee 100644 --- a/base_layer/wallet_ffi/src/callback_handler_tests.rs +++ b/base_layer/wallet_ffi/src/callback_handler_tests.rs @@ -63,6 +63,7 @@ mod test { }; use crate::{callback_handler::CallbackHandler, output_manager_service_mock::MockOutputManagerService}; + use tari_wallet::transaction_service::protocols::TxRejection; struct CallbackState { pub received_tx_callback_called: bool, @@ -168,7 +169,7 @@ mod test { drop(lock); } - unsafe extern "C" fn tx_cancellation_callback(tx: *mut CompletedTransaction) { + unsafe extern "C" fn tx_cancellation_callback(tx: *mut CompletedTransaction, _reason: u64) { let mut lock = CALLBACK_STATE.lock().unwrap(); match (*tx).tx_id { 3 => lock.tx_cancellation_callback_called_inbound = true, @@ -415,7 +416,10 @@ mod test { mock_output_manager_service_state.set_balance(balance.clone()); // Balance updated should be detected with following event, total = 4 times transaction_event_sender - .send(Arc::new(TransactionEvent::TransactionCancelled(3u64))) + .send(Arc::new(TransactionEvent::TransactionCancelled( + 3u64, + TxRejection::UserCancelled, + ))) .unwrap(); let start = Instant::now(); while start.elapsed().as_secs() < 10 { @@ -431,11 +435,17 @@ mod test { assert_eq!(callback_balance_updated, 4); transaction_event_sender - .send(Arc::new(TransactionEvent::TransactionCancelled(4u64))) + .send(Arc::new(TransactionEvent::TransactionCancelled( + 4u64, + TxRejection::UserCancelled, + ))) .unwrap(); transaction_event_sender - .send(Arc::new(TransactionEvent::TransactionCancelled(5u64))) + .send(Arc::new(TransactionEvent::TransactionCancelled( + 5u64, + TxRejection::UserCancelled, + ))) .unwrap(); oms_event_sender diff --git a/base_layer/wallet_ffi/src/lib.rs b/base_layer/wallet_ffi/src/lib.rs index d5ec154748..2a65bf8fd5 100644 --- a/base_layer/wallet_ffi/src/lib.rs +++ b/base_layer/wallet_ffi/src/lib.rs @@ -72,35 +72,6 @@ //! 6. This wallet will then monitor the Base Layer to see when the transaction is mined which means the //! `CompletedTransaction` status will become `Mined` and the funds will then move from the `PendingIncomingBalance` //! to the `AvailableBalance`. -//! -//! ## Using the test functions -//! The above two flows both require a second wallet for this wallet to interact with. Because we do not yet have a live -//! Test Net and the communications layer is not quite ready the library supplies four functions to help simulate the -//! second wallets role in these flows. The following will describe how to use these functions to produce the flows. -//! -//! ### Send Transaction with test functions -//! 1. Send Transaction as above to produce a `PendingOutboundTransaction`. -//! 2. Call the `complete_sent_transaction(...)` function with the tx_id of the sent transaction to simulate a reply. -//! This will move the `PendingOutboundTransaction` to become a `CompletedTransaction` with the `Completed` status. -//! 3. Call the 'broadcast_transaction(...)` function with the tx_id of the sent transaction and its status will move -//! from 'Completed' to 'Broadcast' which means it has been broadcast to the Base Layer Mempool but not mined yet. -//! from 'Completed' to 'Broadcast' which means it has been broadcast to the Base Layer Mempool but not mined yet. -//! 4. Call the `mined_transaction(...)` function with the tx_id of the sent transaction which will change -//! the status of the `CompletedTransaction` from `Broadcast` to `Mined`. The pending funds will also become -//! finalized as spent and available funds respectively. -//! -//! ### Receive Transaction with test functions -//! Under normal operation another wallet would initiate a Receive Transaction flow by sending you a transaction. We -//! will use the `receive_test_transaction(...)` function to initiate the flow: -//! -//! 1. Calling `receive_test_transaction(...)` will produce an `InboundTransaction`, the amount of the transaction will -//! appear under the `PendingIncomingBalance`. -//! 2. To simulate detecting the `InboundTransaction` being broadcast to the Base Layer Mempool call -//! `broadcast_transaction(...)` function. This will change the `InboundTransaction` to a -//! `CompletedTransaction` with the `Broadcast` status. The funds will still reflect in the pending balance. -//! 3. Call the `mined_transaction(...)` function with the tx_id of the received transaction which will -//! change the status of the `CompletedTransaction` from `Broadcast` to `Mined`. The pending funds will also -//! become finalized as spent and available funds respectively #![recursion_limit = "1024"] @@ -3044,9 +3015,24 @@ unsafe fn init_logging( /// when a Broadcast transaction is detected as mined AND confirmed. /// `callback_transaction_mined_unconfirmed` - The callback function pointer matching the function signature. This will /// be called when a Broadcast transaction is detected as mined but not yet confirmed. -/// `callback_discovery_process_complete` - The callback function pointer matching the function signature. This will be -/// called when a `send_transacion(..)` call is made to a peer whose address is not known and a discovery process must -/// be conducted. The outcome of the discovery process is relayed via this callback +/// `callback_direct_send_result` - The callback function pointer matching the function signature. This is called +/// when a direct send is completed. The first parameter is the transaction id and the second is whether if was +/// successful or not. +/// `callback_store_and_forward_send_result` - The callback function pointer matching the function +/// signature. This is called when a direct send is completed. The first parameter is the transaction id and the second +/// is whether if was successful or not. +/// `callback_transaction_cancellation` - The callback function pointer matching +/// the function signature. This is called when a transaction is cancelled. The first parameter is a pointer to the +/// cancelled transaction, the second is a reason as to why said transaction failed that is mapped to the `TxRejection` +/// enum: pub enum TxRejection { +/// Unknown, // 0 +/// UserCancelled, // 1 +/// Timeout, // 2 +/// DoubleSpend, // 3 +/// Orphan, // 4 +/// TimeLocked, // 5 +/// InvalidTransaction, // 6 +/// } /// `callback_txo_validation_complete` - The callback function pointer matching the function signature. This is called /// when a TXO validation process is completed. The request_key is used to identify which request this /// callback references and the second parameter is a u8 that represent the ClassbackValidationResults enum. @@ -3085,7 +3071,7 @@ pub unsafe extern "C" fn wallet_create( callback_transaction_mined_unconfirmed: unsafe extern "C" fn(*mut TariCompletedTransaction, u64), callback_direct_send_result: unsafe extern "C" fn(c_ulonglong, bool), callback_store_and_forward_send_result: unsafe extern "C" fn(c_ulonglong, bool), - callback_transaction_cancellation: unsafe extern "C" fn(*mut TariCompletedTransaction), + callback_transaction_cancellation: unsafe extern "C" fn(*mut TariCompletedTransaction, u64), callback_txo_validation_complete: unsafe extern "C" fn(u64, u8), callback_balance_updated: unsafe extern "C" fn(*mut TariBalance), callback_transaction_validation_complete: unsafe extern "C" fn(u64, u8), @@ -5850,7 +5836,7 @@ mod test { // assert!(true); //optimized out by compiler } - unsafe extern "C" fn tx_cancellation_callback(tx: *mut TariCompletedTransaction) { + unsafe extern "C" fn tx_cancellation_callback(tx: *mut TariCompletedTransaction, _reason: u64) { assert!(!tx.is_null()); assert_eq!( type_of((*tx).clone()), diff --git a/base_layer/wallet_ffi/wallet.h b/base_layer/wallet_ffi/wallet.h index c4be5b890c..d7266603e2 100644 --- a/base_layer/wallet_ffi/wallet.h +++ b/base_layer/wallet_ffi/wallet.h @@ -423,9 +423,22 @@ void comms_config_destroy(struct TariCommsConfig *wc); /// when a Broadcast transaction is detected as mined AND confirmed. /// `callback_transaction_mined_unconfirmed` - The callback function pointer matching the function signature. This will /// be called when a Broadcast transaction is detected as mined but not yet confirmed. -/// `callback_discovery_process_complete` - The callback function pointer matching the function signature. This will be -/// called when a `send_transacion(..)` call is made to a peer whose address is not known and a discovery process must -/// be conducted. The outcome of the discovery process is relayed via this callback +/// `callback_direct_send_result` - The callback function pointer matching the function signature. This is called +/// when a direct send is completed. The first parameter is the transaction id and the second is whether if was successful or not. +/// `callback_store_and_forward_send_result` - The callback function pointer matching the function signature. This is called +/// when a direct send is completed. The first parameter is the transaction id and the second is whether if was successful or not. +/// `callback_transaction_cancellation` - The callback function pointer matching the function signature. This is called +/// when a transaction is cancelled. The first parameter is a pointer to the cancelled transaction, the second is a reason as to +/// why said transaction failed that is mapped to the `TxRejection` enum: +/// pub enum TxRejection { +/// Unknown, // 0 +/// UserCancelled, // 1 +/// Timeout, // 2 +/// DoubleSpend, // 3 +/// Orphan, // 4 +/// TimeLocked, // 5 +/// InvalidTransaction, // 6 +/// } /// `callback_txo_validation_complete` - The callback function pointer matching the function signature. This is called /// when a TXO validation process is completed. The request_key is used to identify which request this /// callback references and the second parameter is a u8 that represent the CallbackValidationResults enum. @@ -469,7 +482,7 @@ struct TariWallet *wallet_create(struct TariCommsConfig *config, void (*callback_transaction_mined_unconfirmed)(struct TariCompletedTransaction *, unsigned long long), void (*callback_direct_send_result)(unsigned long long, bool), void (*callback_store_and_forward_send_result)(unsigned long long, bool), - void (*callback_transaction_cancellation)(struct TariCompletedTransaction *), + void (*callback_transaction_cancellation)(struct TariCompletedTransaction *, unsigned long long), void (*callback_txo_validation_complete)(unsigned long long, unsigned char), void (*callback_balance_updated)(struct TariBalance *), void (*callback_transaction_validation_complete)(unsigned long long, unsigned char), diff --git a/integration_tests/helpers/ffi/ffiInterface.js b/integration_tests/helpers/ffi/ffiInterface.js index 78430ac90e..607252a07e 100644 --- a/integration_tests/helpers/ffi/ffiInterface.js +++ b/integration_tests/helpers/ffi/ffiInterface.js @@ -1129,7 +1129,7 @@ class InterfaceFFI { } static createCallbackTransactionCancellation(fn) { - return ffi.Callback(this.void, [this.ptr], fn); + return ffi.Callback(this.void, [this.ptr, this.ulonglong], fn); } static createCallbackTxoValidationComplete(fn) { return ffi.Callback(this.void, [this.ulonglong, this.uchar], fn); diff --git a/integration_tests/helpers/ffi/wallet.js b/integration_tests/helpers/ffi/wallet.js index 0797ad81d5..ff1b783ca1 100644 --- a/integration_tests/helpers/ffi/wallet.js +++ b/integration_tests/helpers/ffi/wallet.js @@ -245,11 +245,11 @@ class Wallet { this.minedunconfirmed += 1; }; - onTransactionCancellation = (ptr) => { + onTransactionCancellation = (ptr, reason) => { let tx = new CompletedTransaction(); tx.pointerAssign(ptr); console.log( - `${new Date().toISOString()} Transaction with txID ${tx.getTransactionID()} was cancelled` + `${new Date().toISOString()} Transaction with txID ${tx.getTransactionID()} was cancelled with reason code ${reason}.` ); tx.destroy(); this.cancelled += 1;