From 7d49fa4c092f5d7e0a373f3f0c91d9007534e575 Mon Sep 17 00:00:00 2001 From: Stan Bondi Date: Thu, 2 Dec 2021 13:26:26 +0200 Subject: [PATCH 1/2] fix: use json 5 for tor identity (regression) (#3624) Description --- Use json 5 for save/load identity functions Motivation and Context --- Save and load identity were using older version of the json parser which coul not parse the json comments. This causes a new tor identity and onion address to be created on each base node startup. How Has This Been Tested? --- Onion address does not change on base node restart --- Cargo.lock | 2 +- applications/tari_app_utilities/Cargo.toml | 2 +- .../tari_app_utilities/src/identity_management.rs | 14 ++++++-------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 730b9ef7f5..caa7719ce2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4539,7 +4539,7 @@ dependencies = [ "log", "qrcode", "rand 0.8.4", - "serde_json", + "serde 1.0.130", "structopt", "strum 0.19.5", "strum_macros 0.19.4", diff --git a/applications/tari_app_utilities/Cargo.toml b/applications/tari_app_utilities/Cargo.toml index ae6d9c9d1f..d4f64bc4c7 100644 --- a/applications/tari_app_utilities/Cargo.toml +++ b/applications/tari_app_utilities/Cargo.toml @@ -15,7 +15,7 @@ config = { version = "0.9.3" } futures = { version = "^0.3.16", default-features = false, features = ["alloc"] } qrcode = { version = "0.12" } dirs-next = "1.0.2" -serde_json = "1.0" +serde = "1.0.126" json5 = "0.2.2" log = { version = "0.4.8", features = ["std"] } rand = "0.8" diff --git a/applications/tari_app_utilities/src/identity_management.rs b/applications/tari_app_utilities/src/identity_management.rs index 7dc6458b5f..086d35c672 100644 --- a/applications/tari_app_utilities/src/identity_management.rs +++ b/applications/tari_app_utilities/src/identity_management.rs @@ -22,6 +22,7 @@ use log::*; use rand::rngs::OsRng; +use serde::{de::DeserializeOwned, Serialize}; use std::{clone::Clone, fs, path::Path, str::FromStr, string::ToString, sync::Arc}; use tari_common::{ configuration::{bootstrap::prompt, utils::get_local_ip}, @@ -29,10 +30,7 @@ use tari_common::{ }; use tari_common_types::types::PrivateKey; use tari_comms::{multiaddr::Multiaddr, peer_manager::PeerFeatures, NodeIdentity}; -use tari_crypto::{ - keys::SecretKey, - tari_utilities::{hex::Hex, message_format::MessageFormat}, -}; +use tari_crypto::{keys::SecretKey, tari_utilities::hex::Hex}; pub const LOG_TARGET: &str = "tari_application"; @@ -194,7 +192,7 @@ pub fn recover_node_identity>( /// /// ## Returns /// Result containing an object on success, string will indicate reason on error -pub fn load_from_json, T: MessageFormat>(path: P) -> Result { +pub fn load_from_json, T: DeserializeOwned>(path: P) -> Result { if !path.as_ref().exists() { return Err(format!( "Identity file, {}, does not exist.", @@ -203,7 +201,7 @@ pub fn load_from_json, T: MessageFormat>(path: P) -> Result, T: MessageFormat>(path: P) -> Result, T: MessageFormat>(path: P, object: &T) -> Result<(), String> { - let json = object.to_json().unwrap(); +pub fn save_as_json, T: Serialize>(path: P, object: &T) -> Result<(), String> { + let json = json5::to_string(object).unwrap(); if let Some(p) = path.as_ref().parent() { if !p.exists() { fs::create_dir_all(p).map_err(|e| format!("Could not save json to data folder. {}", e.to_string()))?; From e501aa09baf21cba6dbed940fbdf4432399cf2cc Mon Sep 17 00:00:00 2001 From: David Main <51991544+StriderDM@users.noreply.github.com> Date: Thu, 2 Dec 2021 22:05:24 +0200 Subject: [PATCH 2/2] feat!: sending one-sided transactions in wallet_ffi (#3634) 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 --- base_layer/wallet_ffi/src/lib.rs | 48 ++++++++++++++----- base_layer/wallet_ffi/wallet.h | 2 +- integration_tests/features/WalletFFI.feature | 24 ++++++++++ .../features/support/ffi_steps.js | 18 ++++++- integration_tests/helpers/ffi/ffiInterface.js | 5 +- integration_tests/helpers/ffi/wallet.js | 5 +- integration_tests/helpers/walletFFIClient.js | 5 +- 7 files changed, 87 insertions(+), 20 deletions(-) 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 ); }