diff --git a/base_layer/wallet_ffi/src/lib.rs b/base_layer/wallet_ffi/src/lib.rs index 26ec4fdbc4..a4623d4841 100644 --- a/base_layer/wallet_ffi/src/lib.rs +++ b/base_layer/wallet_ffi/src/lib.rs @@ -3801,6 +3801,7 @@ pub unsafe extern "C" fn wallet_send_transaction( amount: c_ulonglong, fee_per_gram: c_ulonglong, message: *const c_char, + one_sided: bool, error_out: *mut c_int, ) -> c_ulonglong { let mut error = 0; @@ -3843,19 +3844,40 @@ pub unsafe extern "C" fn wallet_send_transaction( .to_owned(); }; - match (*wallet) - .runtime - .block_on((*wallet).wallet.transaction_service.send_transaction( - (*dest_public_key).clone(), - MicroTari::from(amount), - MicroTari::from(fee_per_gram), - message_string, - )) { - Ok(tx_id) => tx_id, - Err(e) => { - error = LibWalletError::from(WalletError::TransactionServiceError(e)).code; - ptr::swap(error_out, &mut error as *mut c_int); - 0 + match one_sided { + true => { + match (*wallet) + .runtime + .block_on((*wallet).wallet.transaction_service.send_one_sided_transaction( + (*dest_public_key).clone(), + MicroTari::from(amount), + MicroTari::from(fee_per_gram), + message_string, + )) { + Ok(tx_id) => tx_id, + Err(e) => { + error = LibWalletError::from(WalletError::TransactionServiceError(e)).code; + ptr::swap(error_out, &mut error as *mut c_int); + 0 + }, + } + }, + false => { + match (*wallet) + .runtime + .block_on((*wallet).wallet.transaction_service.send_transaction( + (*dest_public_key).clone(), + MicroTari::from(amount), + MicroTari::from(fee_per_gram), + message_string, + )) { + Ok(tx_id) => tx_id, + Err(e) => { + error = LibWalletError::from(WalletError::TransactionServiceError(e)).code; + ptr::swap(error_out, &mut error as *mut c_int); + 0 + }, + } }, } } diff --git a/base_layer/wallet_ffi/wallet.h b/base_layer/wallet_ffi/wallet.h index 661d861103..c6ed604541 100644 --- a/base_layer/wallet_ffi/wallet.h +++ b/base_layer/wallet_ffi/wallet.h @@ -531,7 +531,7 @@ unsigned long long wallet_get_num_confirmations_required(struct TariWallet *wall void wallet_set_num_confirmations_required(struct TariWallet *wallet, unsigned long long num, int *error_out); // Sends a TariPendingOutboundTransaction -unsigned long long wallet_send_transaction(struct TariWallet *wallet, struct TariPublicKey *destination, unsigned long long amount, unsigned long long fee_per_gram, const char *message, int *error_out); +unsigned long long wallet_send_transaction(struct TariWallet *wallet, struct TariPublicKey *destination, unsigned long long amount, unsigned long long fee_per_gram, const char *message, bool one_sided, int *error_out); // Get the TariContacts from a TariWallet struct TariContacts *wallet_get_contacts(struct TariWallet *wallet, int *error_out); diff --git a/integration_tests/features/WalletFFI.feature b/integration_tests/features/WalletFFI.feature index 79b23f241d..df04647db7 100644 --- a/integration_tests/features/WalletFFI.feature +++ b/integration_tests/features/WalletFFI.feature @@ -135,6 +135,30 @@ Feature: Wallet FFI Then I wait for ffi wallet FFI_WALLET to have at least 1000000 uT And I stop ffi wallet FFI_WALLET + Scenario: As a client I want to send a one-sided transaction + Given I have a seed node SEED + And I have a base node BASE1 connected to all seed nodes + And I have a base node BASE2 connected to all seed nodes + And I have wallet SENDER connected to base node BASE1 + And I have a ffi wallet FFI_WALLET connected to base node BASE2 + And I have wallet RECEIVER connected to base node BASE2 + And I have mining node MINER connected to base node BASE1 and wallet SENDER + And mining node MINER mines 10 blocks + Then I wait for wallet SENDER to have at least 1000000 uT + And I send 2000000 uT from wallet SENDER to wallet FFI_WALLET at fee 20 + Then ffi wallet FFI_WALLET detects AT_LEAST 1 ffi transactions to be Broadcast + And mining node MINER mines 10 blocks + Then I wait for ffi wallet FFI_WALLET to have at least 1000000 uT + And I send 1000000 uT from ffi wallet FFI_WALLET to wallet RECEIVER at fee 20 via one-sided transactions + And mining node MINER mines 2 blocks + Then all nodes are at height 22 + And mining node MINER mines 2 blocks + Then all nodes are at height 24 + And mining node MINER mines 6 blocks + Then I wait for wallet RECEIVER to have at least 1000000 uT + Then I wait for ffi wallet FFI_WALLET to receive 2 mined + And I stop ffi wallet FFI_WALLET + # Scenario: As a client I want to get my balance # It's a subtest of "As a client I want to retrieve a list of transactions I have made and received" diff --git a/integration_tests/features/support/ffi_steps.js b/integration_tests/features/support/ffi_steps.js index 6c083b01d1..1e41a71cb3 100644 --- a/integration_tests/features/support/ffi_steps.js +++ b/integration_tests/features/support/ffi_steps.js @@ -31,7 +31,23 @@ When( this.getWalletPubkey(receiver), amount, feePerGram, - `Send from ffi ${sender} to ${receiver} at fee ${feePerGram}` + `Send from ffi ${sender} to ${receiver} at fee ${feePerGram}`, + false + ); + console.log(result); + } +); + +When( + "I send {int} uT from ffi wallet {word} to wallet {word} at fee {int} via one-sided transactions", + function (amount, sender, receiver, feePerGram) { + let ffiWallet = this.getWallet(sender); + let result = ffiWallet.sendTransaction( + this.getWalletPubkey(receiver), + amount, + feePerGram, + `Send from ffi ${sender} to ${receiver} at fee ${feePerGram}`, + true ); console.log(result); } diff --git a/integration_tests/helpers/ffi/ffiInterface.js b/integration_tests/helpers/ffi/ffiInterface.js index 9507ad18f9..8eb3b95ade 100644 --- a/integration_tests/helpers/ffi/ffiInterface.js +++ b/integration_tests/helpers/ffi/ffiInterface.js @@ -341,6 +341,7 @@ class InterfaceFFI { this.ulonglong, this.ulonglong, this.string, + this.bool, this.intPtr, ], ], @@ -1331,7 +1332,8 @@ class InterfaceFFI { destination, amount, fee_per_gram, - message + message, + one_sided ) { let error = this.initError(); let result = this.fn.wallet_send_transaction( @@ -1340,6 +1342,7 @@ class InterfaceFFI { amount, fee_per_gram, message, + one_sided, error ); this.checkErrorResult(error, `walletSendTransaction`); diff --git a/integration_tests/helpers/ffi/wallet.js b/integration_tests/helpers/ffi/wallet.js index ff1b783ca1..feae5535b8 100644 --- a/integration_tests/helpers/ffi/wallet.js +++ b/integration_tests/helpers/ffi/wallet.js @@ -373,14 +373,15 @@ class Wallet { return result; } - sendTransaction(destination, amount, fee_per_gram, message) { + sendTransaction(destination, amount, fee_per_gram, message, one_sided) { let dest_public_key = PublicKey.fromHexString(utf8.encode(destination)); let result = InterfaceFFI.walletSendTransaction( this.ptr, dest_public_key.getPtr(), amount, fee_per_gram, - utf8.encode(message) + utf8.encode(message), + one_sided ); dest_public_key.destroy(); return result; diff --git a/integration_tests/helpers/walletFFIClient.js b/integration_tests/helpers/walletFFIClient.js index 592ddaff6c..2a84de67cf 100644 --- a/integration_tests/helpers/walletFFIClient.js +++ b/integration_tests/helpers/walletFFIClient.js @@ -139,12 +139,13 @@ class WalletFFIClient { } } - sendTransaction(destination, amount, fee_per_gram, message) { + sendTransaction(destination, amount, fee_per_gram, message, one_sided) { return this.wallet.sendTransaction( destination, amount, fee_per_gram, - message + message, + one_sided ); }