Skip to content

Commit

Permalink
feat!: sending one-sided transactions in wallet_ffi (#3634)
Browse files Browse the repository at this point in the history
Description
---
This PR allows one-sided transactions to be sent via the wallet_ffi library.

Motivation and Context
---
Feature

How Has This Been Tested?
---
nvm use 12.22.6 && node_modules/.bin/cucumber-js --profile "ci" --tags "not @long-running and not @broken and @wallet-ffi"
cargo test --all
  • Loading branch information
StriderDM authored Dec 2, 2021
1 parent 7d49fa4 commit e501aa0
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 20 deletions.
48 changes: 35 additions & 13 deletions base_layer/wallet_ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
},
}
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion base_layer/wallet_ffi/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
24 changes: 24 additions & 0 deletions integration_tests/features/WalletFFI.feature
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
18 changes: 17 additions & 1 deletion integration_tests/features/support/ffi_steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
5 changes: 4 additions & 1 deletion integration_tests/helpers/ffi/ffiInterface.js
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ class InterfaceFFI {
this.ulonglong,
this.ulonglong,
this.string,
this.bool,
this.intPtr,
],
],
Expand Down Expand Up @@ -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(
Expand All @@ -1340,6 +1342,7 @@ class InterfaceFFI {
amount,
fee_per_gram,
message,
one_sided,
error
);
this.checkErrorResult(error, `walletSendTransaction`);
Expand Down
5 changes: 3 additions & 2 deletions integration_tests/helpers/ffi/wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 3 additions & 2 deletions integration_tests/helpers/walletFFIClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
}

Expand Down

0 comments on commit e501aa0

Please sign in to comment.