From 0b2a15585e88240c027175a24dd9757cca4218ac Mon Sep 17 00:00:00 2001 From: Andrei Gubarev <1062334+agubarev@users.noreply.github.com> Date: Wed, 31 Aug 2022 10:24:33 +0300 Subject: [PATCH 01/12] fix: removed `seed_words` and `delete_seed_words` commands (#4567) Description --- Delete Seed words commands from GRPC #4363 https://github.com/tari-project/tari/issues/4363 Motivation and Context --- We need to remove this from GRPC service, this is a dangerous call. How Has This Been Tested? --- existing unit tests --- applications/tari_app_grpc/proto/wallet.proto | 10 ----- .../src/grpc/wallet_grpc_server.rs | 45 +------------------ 2 files changed, 1 insertion(+), 54 deletions(-) diff --git a/applications/tari_app_grpc/proto/wallet.proto b/applications/tari_app_grpc/proto/wallet.proto index 2e08212ad5..3675c3f11d 100644 --- a/applications/tari_app_grpc/proto/wallet.proto +++ b/applications/tari_app_grpc/proto/wallet.proto @@ -74,8 +74,6 @@ service Wallet { rpc SetBaseNode(SetBaseNodeRequest) returns (SetBaseNodeResponse); rpc StreamTransactionEvents(TransactionEventRequest) returns (stream TransactionEventResponse); - rpc SeedWords(Empty) returns (SeedWordsResponse); - rpc DeleteSeedWordsFile(Empty) returns (FileDeletedResponse); } message GetVersionRequest { } @@ -309,11 +307,3 @@ message TransactionEvent { message TransactionEventResponse { TransactionEvent transaction = 1; } - -message SeedWordsResponse { - repeated string words = 1; -} - -message FileDeletedResponse { - -} \ No newline at end of file diff --git a/applications/tari_console_wallet/src/grpc/wallet_grpc_server.rs b/applications/tari_console_wallet/src/grpc/wallet_grpc_server.rs index 4fdb2fb3f2..1af3c6311a 100644 --- a/applications/tari_console_wallet/src/grpc/wallet_grpc_server.rs +++ b/applications/tari_console_wallet/src/grpc/wallet_grpc_server.rs @@ -20,13 +20,8 @@ // 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. -use std::{ - convert::{TryFrom, TryInto}, - fs, - path::PathBuf, -}; +use std::convert::{TryFrom, TryInto}; -use clap::Parser; use futures::{ channel::mpsc::{self, Sender}, future, @@ -48,7 +43,6 @@ use tari_app_grpc::{ CoinSplitResponse, CreateBurnTransactionRequest, CreateBurnTransactionResponse, - FileDeletedResponse, GetBalanceRequest, GetBalanceResponse, GetCoinbaseRequest, @@ -67,7 +61,6 @@ use tari_app_grpc::{ ImportUtxosResponse, RevalidateRequest, RevalidateResponse, - SeedWordsResponse, SendShaAtomicSwapRequest, SendShaAtomicSwapResponse, SetBaseNodeRequest, @@ -106,7 +99,6 @@ use tokio::{sync::broadcast, task}; use tonic::{Request, Response, Status}; use crate::{ - cli::Cli, grpc::{convert_to_transaction_event, TransactionWrapper}, notifier::{CANCELLED, CONFIRMATION, MINED, NEW_BLOCK_MINED, QUEUED, RECEIVED, SENT}, }; @@ -880,41 +872,6 @@ impl wallet_server::Wallet for WalletGrpcServer { }, } } - - /// Returns the contents of a seed words file, provided via CLI - async fn seed_words(&self, _: Request) -> Result, Status> { - let cli = Cli::parse(); - - let filepath: PathBuf = match cli.seed_words_file_name { - Some(filepath) => filepath, - None => return Err(Status::not_found("file path is empty")), - }; - - let words = fs::read_to_string(filepath)? - .split(' ') - .collect::>() - .iter() - .map(|&x| x.into()) - .collect::>(); - - Ok(Response::new(SeedWordsResponse { words })) - } - - /// Deletes the seed words file, provided via CLI - async fn delete_seed_words_file( - &self, - _: Request, - ) -> Result, Status> { - let cli = Cli::parse(); - - // WARNING: the filepath used is supplied as an argument - fs::remove_file(match cli.seed_words_file_name { - Some(filepath) => filepath, - None => return Err(Status::not_found("file path is empty")), - })?; - - Ok(Response::new(FileDeletedResponse {})) - } } async fn handle_completed_tx( From 74645813ab836b19d9d722aaa189a2d190eb5c6e Mon Sep 17 00:00:00 2001 From: Hansie Odendaal <39146854+hansieodendaal@users.noreply.github.com> Date: Wed, 31 Aug 2022 09:26:27 +0200 Subject: [PATCH 02/12] feat: remove spawn blocking calls from wallet db (contacts service) (#4575) Description --- - Removed spawn blocking calls for db operations from the wallet in the contacts service. (This is another PR in a couple of PRs required to implement this fully throughout the wallet code.) - Reset the wallet's default db connection pool size back to 16 (from 5). Motivation and Context --- As per https://github.com/tari-project/tari/pull/3982 and https://github.com/tari-project/tari/issues/4555 How Has This Been Tested? --- Unit tests Cucumber tests System-level test --- base_layer/wallet/src/config.rs | 2 +- .../wallet/src/contacts_service/service.rs | 23 +++---- .../src/contacts_service/storage/database.rs | 68 ++++++------------- common/config/presets/d_console_wallet.toml | 4 +- 4 files changed, 36 insertions(+), 61 deletions(-) diff --git a/base_layer/wallet/src/config.rs b/base_layer/wallet/src/config.rs index 9e13353a3e..6d0997fa6e 100644 --- a/base_layer/wallet/src/config.rs +++ b/base_layer/wallet/src/config.rs @@ -136,7 +136,7 @@ impl Default for WalletConfig { base_node_service_config: Default::default(), data_dir: PathBuf::from_str("data/wallet").unwrap(), db_file: PathBuf::from_str("db/console_wallet.db").unwrap(), - db_connection_pool_size: 5, // TODO: get actual default + db_connection_pool_size: 16, // Note: Do not reduce this default number password: None, contacts_auto_ping_interval: Duration::from_secs(30), contacts_online_ping_window: 30, diff --git a/base_layer/wallet/src/contacts_service/service.rs b/base_layer/wallet/src/contacts_service/service.rs index 9bed181739..e36114b7b9 100644 --- a/base_layer/wallet/src/contacts_service/service.rs +++ b/base_layer/wallet/src/contacts_service/service.rs @@ -148,7 +148,7 @@ where T: ContactsBackend + 'static pin_mut!(shutdown); // Add all contacts as monitored peers to the liveness service - let result = self.db.get_contacts().await; + let result = self.db.get_contacts(); if let Ok(ref contacts) = result { self.add_contacts_to_liveness_service(contacts).await?; } @@ -195,14 +195,14 @@ where T: ContactsBackend + 'static ) -> Result { match request { ContactsServiceRequest::GetContact(pk) => { - let result = self.db.get_contact(pk.clone()).await; + let result = self.db.get_contact(pk.clone()); if let Ok(ref contact) = result { self.liveness.check_add_monitored_peer(contact.node_id.clone()).await?; }; Ok(result.map(ContactsServiceResponse::Contact)?) }, ContactsServiceRequest::UpsertContact(c) => { - self.db.upsert_contact(c.clone()).await?; + self.db.upsert_contact(c.clone())?; self.liveness.check_add_monitored_peer(c.node_id).await?; info!( target: LOG_TARGET, @@ -211,7 +211,7 @@ where T: ContactsBackend + 'static Ok(ContactsServiceResponse::ContactSaved) }, ContactsServiceRequest::RemoveContact(pk) => { - let result = self.db.remove_contact(pk.clone()).await?; + let result = self.db.remove_contact(pk.clone())?; self.liveness .check_remove_monitored_peer(result.node_id.clone()) .await?; @@ -222,7 +222,7 @@ where T: ContactsBackend + 'static Ok(ContactsServiceResponse::ContactRemoved(result)) }, ContactsServiceRequest::GetContacts => { - let result = self.db.get_contacts().await; + let result = self.db.get_contacts(); if let Ok(ref contacts) = result { self.add_contacts_to_liveness_service(contacts).await?; } @@ -254,11 +254,11 @@ where T: ContactsBackend + 'static match event { // Received a ping, check if it contains ContactsLiveness LivenessEvent::ReceivedPing(event) => { - self.update_with_ping_pong(event, ContactMessageType::Ping).await?; + self.update_with_ping_pong(event, ContactMessageType::Ping)?; }, // Received a pong, check if our neighbour sent it and it contains ContactsLiveness LivenessEvent::ReceivedPong(event) => { - self.update_with_ping_pong(event, ContactMessageType::Pong).await?; + self.update_with_ping_pong(event, ContactMessageType::Pong)?; }, // New ping round has begun LivenessEvent::PingRoundBroadcast(num_peers) => { @@ -277,7 +277,7 @@ where T: ContactsBackend + 'static self.resize_contacts_liveness_data_buffer(*num_peers); // Update offline status - if let Ok(contacts) = self.db.get_contacts().await { + if let Ok(contacts) = self.db.get_contacts() { for contact in contacts { let online_status = self.get_online_status(&contact).await?; if online_status == ContactOnlineStatus::Online { @@ -332,7 +332,7 @@ where T: ContactsBackend + 'static Utc::now().naive_utc().sub(last_seen) <= ping_window } - async fn update_with_ping_pong( + fn update_with_ping_pong( &mut self, event: &PingPongEvent, message_type: ContactMessageType, @@ -356,15 +356,14 @@ where T: ContactsBackend + 'static } let this_public_key = self .db - .update_contact_last_seen(&event.node_id, last_seen.naive_utc(), latency) - .await?; + .update_contact_last_seen(&event.node_id, last_seen.naive_utc(), latency)?; let data = ContactsLivenessData::new( this_public_key, event.node_id.clone(), latency, Some(last_seen.naive_utc()), - message_type.clone(), + message_type, ContactOnlineStatus::Online, ); self.liveness_data.push(data.clone()); diff --git a/base_layer/wallet/src/contacts_service/storage/database.rs b/base_layer/wallet/src/contacts_service/storage/database.rs index 447276834e..425f59a464 100644 --- a/base_layer/wallet/src/contacts_service/storage/database.rs +++ b/base_layer/wallet/src/contacts_service/storage/database.rs @@ -118,18 +118,14 @@ where T: ContactsBackend + 'static Self { db: Arc::new(db) } } - pub async fn get_contact(&self, pub_key: CommsPublicKey) -> Result { + pub fn get_contact(&self, pub_key: CommsPublicKey) -> Result { let db_clone = self.db.clone(); - tokio::task::spawn_blocking(move || fetch!(db_clone, pub_key.clone(), Contact)) - .await - .map_err(|err| ContactsServiceStorageError::BlockingTaskSpawnError(err.to_string())) - .and_then(|inner_result| inner_result) + fetch!(db_clone, pub_key, Contact) } - pub async fn get_contacts(&self) -> Result, ContactsServiceStorageError> { + pub fn get_contacts(&self) -> Result, ContactsServiceStorageError> { let db_clone = self.db.clone(); - - let c = tokio::task::spawn_blocking(move || match db_clone.fetch(&DbKey::Contacts) { + match db_clone.fetch(&DbKey::Contacts) { Ok(None) => log_error( DbKey::Contacts, ContactsServiceStorageError::UnexpectedResult("Could not retrieve contacts".to_string()), @@ -137,46 +133,31 @@ where T: ContactsBackend + 'static Ok(Some(DbValue::Contacts(c))) => Ok(c), Ok(Some(other)) => unexpected_result(DbKey::Contacts, other), Err(e) => log_error(DbKey::Contacts, e), - }) - .await - .map_err(|err| ContactsServiceStorageError::BlockingTaskSpawnError(err.to_string()))??; - Ok(c) + } } - pub async fn upsert_contact(&self, contact: Contact) -> Result<(), ContactsServiceStorageError> { - let db_clone = self.db.clone(); - - tokio::task::spawn_blocking(move || { - db_clone.write(WriteOperation::Upsert(Box::new(DbKeyValuePair::Contact( - contact.public_key.clone(), - contact, - )))) - }) - .await - .map_err(|err| ContactsServiceStorageError::BlockingTaskSpawnError(err.to_string()))??; + pub fn upsert_contact(&self, contact: Contact) -> Result<(), ContactsServiceStorageError> { + self.db.write(WriteOperation::Upsert(Box::new(DbKeyValuePair::Contact( + contact.public_key.clone(), + contact, + ))))?; Ok(()) } - pub async fn update_contact_last_seen( + pub fn update_contact_last_seen( &self, node_id: &NodeId, last_seen: NaiveDateTime, latency: Option, ) -> Result { - let db_clone = self.db.clone(); - let node_id_clone = node_id.clone(); - - let result = tokio::task::spawn_blocking(move || { - db_clone.write(WriteOperation::UpdateLastSeen(Box::new(DbKeyValuePair::LastSeen( - node_id_clone, + let result = self + .db + .write(WriteOperation::UpdateLastSeen(Box::new(DbKeyValuePair::LastSeen( + node_id.clone(), last_seen, latency.map(|val| val as i32), - )))) - }) - .await - .map_err(|err| ContactsServiceStorageError::BlockingTaskSpawnError(err.to_string())) - .and_then(|inner_result| inner_result)? - .ok_or_else(|| ContactsServiceStorageError::ValueNotFound(DbKey::ContactId(node_id.clone())))?; + ))))? + .ok_or_else(|| ContactsServiceStorageError::ValueNotFound(DbKey::ContactId(node_id.clone())))?; match result { DbValue::PublicKey(k) => Ok(*k), _ => Err(ContactsServiceStorageError::UnexpectedResult( @@ -185,16 +166,11 @@ where T: ContactsBackend + 'static } } - pub async fn remove_contact(&self, pub_key: CommsPublicKey) -> Result { - let db_clone = self.db.clone(); - let pub_key_clone = pub_key.clone(); - let result = - tokio::task::spawn_blocking(move || db_clone.write(WriteOperation::Remove(DbKey::Contact(pub_key_clone)))) - .await - .map_err(|err| ContactsServiceStorageError::BlockingTaskSpawnError(err.to_string())) - .and_then(|inner_result| inner_result)? - .ok_or_else(|| ContactsServiceStorageError::ValueNotFound(DbKey::Contact(pub_key.clone())))?; - + pub fn remove_contact(&self, pub_key: CommsPublicKey) -> Result { + let result = self + .db + .write(WriteOperation::Remove(DbKey::Contact(pub_key.clone())))? + .ok_or_else(|| ContactsServiceStorageError::ValueNotFound(DbKey::Contact(pub_key.clone())))?; match result { DbValue::Contact(c) => Ok(*c), DbValue::Contacts(_) | DbValue::PublicKey(_) => Err(ContactsServiceStorageError::UnexpectedResult( diff --git a/common/config/presets/d_console_wallet.toml b/common/config/presets/d_console_wallet.toml index 61c18c2c05..0bada2bd9b 100644 --- a/common/config/presets/d_console_wallet.toml +++ b/common/config/presets/d_console_wallet.toml @@ -32,8 +32,8 @@ # DO NOT EVER DELETE THIS FILE unless you (a) have backed up your seed phrase and (b) know what you are doing! #db_file = "db/console_wallet.db" -# The main wallet db sqlite database backend connection pool size for concurrent reads (default = 5) -#db_connection_pool_size = 5 +# The main wallet db sqlite database backend connection pool size for concurrent reads (default = 16) +#db_connection_pool_size = 16 # Console wallet password. Should you wish to start your console wallet without typing in your password, the following # options are available: From c69245bbf5e9f212c07bc1736cedd9351f4d6eef Mon Sep 17 00:00:00 2001 From: jorgeantonio21 Date: Wed, 31 Aug 2022 08:28:04 +0100 Subject: [PATCH 03/12] fix: resolve tests in output_manager_service_tests.rs (see issue #4561) (#4577) Description --- Resolve ignored tests in output manager service. Motivation and Context --- The given tests are failing mainly due to incorrectly hardcoded values. We address these issues. How Has This Been Tested? --- Unit tests --- .../wallet/tests/output_manager_service_tests/service.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/base_layer/wallet/tests/output_manager_service_tests/service.rs b/base_layer/wallet/tests/output_manager_service_tests/service.rs index efab1a6d0f..43b64159bd 100644 --- a/base_layer/wallet/tests/output_manager_service_tests/service.rs +++ b/base_layer/wallet/tests/output_manager_service_tests/service.rs @@ -390,7 +390,6 @@ async fn fee_estimate() { assert!(matches!(err, OutputManagerError::NotEnoughFunds)); } -#[ignore] #[allow(clippy::identity_op)] #[tokio::test] async fn test_utxo_selection_no_chain_metadata() { @@ -492,7 +491,7 @@ async fn test_utxo_selection_no_chain_metadata() { let (_, tx, utxos_total_value) = oms.create_coin_split(vec![], amount, 5, fee_per_gram).await.unwrap(); let expected_fee = fee_calc.calculate(fee_per_gram, 1, 1, 6, default_metadata_byte_size() * 6); assert_eq!(tx.body.get_total_fee(), expected_fee); - assert_eq!(utxos_total_value, MicroTari::from(10_000)); + assert_eq!(utxos_total_value, MicroTari::from(5_000)); // test that largest utxo was encumbered let utxos = oms.get_unspent_outputs().await.unwrap(); @@ -507,7 +506,6 @@ async fn test_utxo_selection_no_chain_metadata() { #[tokio::test] #[allow(clippy::identity_op)] #[allow(clippy::too_many_lines)] -#[ignore] async fn test_utxo_selection_with_chain_metadata() { let factories = CryptoFactories::default(); let (connection, _tempdir) = get_temp_sqlite_database_connection(); @@ -576,7 +574,7 @@ async fn test_utxo_selection_with_chain_metadata() { // test coin split is maturity aware let (_, tx, utxos_total_value) = oms.create_coin_split(vec![], amount, 5, fee_per_gram).await.unwrap(); - assert_eq!(utxos_total_value, MicroTari::from(6_000)); + assert_eq!(utxos_total_value, MicroTari::from(5_000)); let expected_fee = fee_calc.calculate(fee_per_gram, 1, 1, 6, default_metadata_byte_size() * 6); assert_eq!(tx.body.get_total_fee(), expected_fee); @@ -1113,7 +1111,6 @@ async fn sending_transaction_persisted_while_offline() { } #[tokio::test] -#[ignore] async fn coin_split_with_change() { let factories = CryptoFactories::default(); let (connection, _tempdir) = get_temp_sqlite_database_connection(); From ad24bf71714ffc091c9fce7c1fc224235e3666a9 Mon Sep 17 00:00:00 2001 From: Stan Bondi Date: Wed, 31 Aug 2022 11:28:47 +0400 Subject: [PATCH 04/12] fix: update rest of the crates to tokio 1.20 (#4576) Description --- - updates remaining crates to 1.20 Motivation and Context --- Some crates used 1.10 and others 1.14 - search and replace missed 1.14 How Has This Been Tested? --- Search for all tokio deps and make sure they are set to 1.20 --- applications/tari_console_wallet/Cargo.toml | 4 ++-- base_layer/service_framework/Cargo.toml | 4 ++-- base_layer/wallet/Cargo.toml | 4 ++-- comms/core/Cargo.toml | 2 +- comms/dht/Cargo.toml | 4 ++-- infrastructure/metrics/Cargo.toml | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/applications/tari_console_wallet/Cargo.toml b/applications/tari_console_wallet/Cargo.toml index e64ed725ad..af5bb691fe 100644 --- a/applications/tari_console_wallet/Cargo.toml +++ b/applications/tari_console_wallet/Cargo.toml @@ -22,9 +22,9 @@ tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", t # Uncomment for tokio tracing via tokio-console (needs "tracing" featurs) #console-subscriber = "0.1.3" -#tokio = { version = "1.14", features = ["signal", "tracing"] } +#tokio = { version = "1.20", features = ["signal", "tracing"] } # Uncomment for normal use (non tokio-console tracing) -tokio = { version = "1.14", default-features = false, features = ["signal", "sync"] } +tokio = { version = "1.20", default-features = false, features = ["signal", "sync"] } base64 = "0.13.0" bitflags = "1.2.1" diff --git a/base_layer/service_framework/Cargo.toml b/base_layer/service_framework/Cargo.toml index 55b299680c..f22b877229 100644 --- a/base_layer/service_framework/Cargo.toml +++ b/base_layer/service_framework/Cargo.toml @@ -17,12 +17,12 @@ async-trait = "0.1.50" futures = { version = "^0.3.16", features = ["async-await"] } log = "0.4.8" thiserror = "1.0.26" -tokio = { version = "1.14", features = ["rt"] } +tokio = { version = "1.20", features = ["rt"] } tower-service = { version = "0.3" } [dev-dependencies] tari_test_utils = { version = "^0.37", path = "../../infrastructure/test_utils" } -tokio = { version = "1.14", features = ["rt-multi-thread", "macros", "time"] } +tokio = { version = "1.20", features = ["rt-multi-thread", "macros", "time"] } futures-test = { version = "0.3.3" } tower = "0.4" diff --git a/base_layer/wallet/Cargo.toml b/base_layer/wallet/Cargo.toml index 753acbe64c..a8b7798aaa 100644 --- a/base_layer/wallet/Cargo.toml +++ b/base_layer/wallet/Cargo.toml @@ -23,9 +23,9 @@ tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", t # Uncomment for tokio tracing via tokio-console (needs "tracing" featurs) #console-subscriber = "0.1.3" -#tokio = { version = "1.14", features = ["sync", "macros", "tracing"] } +#tokio = { version = "1.20", features = ["sync", "macros", "tracing"] } # Uncomment for normal use (non tokio-console tracing) -tokio = { version = "1.14", features = ["sync", "macros"] } +tokio = { version = "1.20", features = ["sync", "macros"] } async-trait = "0.1.50" argon2 = "0.2" diff --git a/comms/core/Cargo.toml b/comms/core/Cargo.toml index a4b1d86cf0..cf7fc5c3f6 100644 --- a/comms/core/Cargo.toml +++ b/comms/core/Cargo.toml @@ -44,7 +44,7 @@ serde = "1.0.119" serde_derive = "1.0.119" snow = { version = "=0.8.0", features = ["default-resolver"] } thiserror = "1.0.26" -tokio = { version = "1.14", features = ["rt-multi-thread", "time", "sync", "signal", "net", "macros", "io-util"] } +tokio = { version = "1.20", features = ["rt-multi-thread", "time", "sync", "signal", "net", "macros", "io-util"] } tokio-stream = { version = "0.1.9", features = ["sync"] } tokio-util = { version = "0.6.7", features = ["codec", "compat"] } tower = {version = "0.4", features = ["util"]} diff --git a/comms/dht/Cargo.toml b/comms/dht/Cargo.toml index 1671b619e5..985e4217bd 100644 --- a/comms/dht/Cargo.toml +++ b/comms/dht/Cargo.toml @@ -43,9 +43,9 @@ zeroize = "1.4.0" # Uncomment for tokio tracing via tokio-console (needs "tracing" features) #console-subscriber = "0.1.3" -#tokio = { version = "1.14", features = ["rt", "macros", "tracing"] } +#tokio = { version = "1.20", features = ["rt", "macros", "tracing"] } # Uncomment for normal use (non tokio-console tracing) -tokio = { version = "1.14", features = ["rt", "macros"] } +tokio = { version = "1.20", features = ["rt", "macros"] } # tower-filter dependencies pin-project = "0.4" diff --git a/infrastructure/metrics/Cargo.toml b/infrastructure/metrics/Cargo.toml index c704f6b880..2ccbf6959f 100644 --- a/infrastructure/metrics/Cargo.toml +++ b/infrastructure/metrics/Cargo.toml @@ -16,7 +16,7 @@ prometheus = "0.13.0" futures = { version = "0.3.15", default-features = false, optional = true } reqwest = { version = "0.11.4", default-features = false, optional = true } -tokio = { version = "1.7.1", optional = true, features = ["time", "rt-multi-thread"] } +tokio = { version = "1", optional = true, features = ["time", "rt-multi-thread"] } warp = { version = "0.3.1", optional = true, default-features = false } thiserror = "1.0.25" anyhow = { version = "1.0.53", optional = true } From 2eb2edd348c0f1877341c1cfa3c4e4a57c502610 Mon Sep 17 00:00:00 2001 From: stringhandler Date: Wed, 31 Aug 2022 09:41:15 +0200 Subject: [PATCH 05/12] v0.38.0 --- Cargo.lock | 46 +++++++++---------- applications/tari_app_grpc/Cargo.toml | 4 +- applications/tari_app_utilities/Cargo.toml | 2 +- applications/tari_base_node/Cargo.toml | 2 +- applications/tari_console_wallet/Cargo.toml | 2 +- .../tari_merge_mining_proxy/Cargo.toml | 2 +- applications/tari_miner/Cargo.toml | 2 +- base_layer/common_types/Cargo.toml | 2 +- base_layer/core/Cargo.toml | 30 ++++++------ base_layer/key_manager/Cargo.toml | 4 +- base_layer/mmr/Cargo.toml | 2 +- base_layer/p2p/Cargo.toml | 18 ++++---- base_layer/service_framework/Cargo.toml | 6 +-- base_layer/tari_mining_helper_ffi/Cargo.toml | 4 +- base_layer/wallet/Cargo.toml | 26 +++++------ base_layer/wallet_ffi/Cargo.toml | 22 ++++----- changelog.md | 30 ++++++++++++ common/Cargo.toml | 4 +- common_sqlite/Cargo.toml | 2 +- comms/core/Cargo.toml | 10 ++-- comms/dht/Cargo.toml | 14 +++--- comms/rpc_macros/Cargo.toml | 6 +-- infrastructure/derive/Cargo.toml | 2 +- infrastructure/libtor/Cargo.toml | 2 +- infrastructure/shutdown/Cargo.toml | 2 +- infrastructure/storage/Cargo.toml | 2 +- infrastructure/test_utils/Cargo.toml | 2 +- package-lock.json | 2 +- 28 files changed, 141 insertions(+), 111 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d04b094142..86694d42ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4618,7 +4618,7 @@ dependencies = [ [[package]] name = "tari_app_grpc" -version = "0.37.0" +version = "0.38.0" dependencies = [ "argon2 0.4.1", "base64 0.13.0", @@ -4643,7 +4643,7 @@ dependencies = [ [[package]] name = "tari_app_utilities" -version = "0.37.0" +version = "0.38.0" dependencies = [ "clap 3.2.15", "config", @@ -4666,7 +4666,7 @@ dependencies = [ [[package]] name = "tari_base_node" -version = "0.37.0" +version = "0.38.0" dependencies = [ "anyhow", "async-trait", @@ -4758,7 +4758,7 @@ dependencies = [ [[package]] name = "tari_common" -version = "0.37.0" +version = "0.38.0" dependencies = [ "anyhow", "blake2 0.9.2", @@ -4787,7 +4787,7 @@ dependencies = [ [[package]] name = "tari_common_sqlite" -version = "0.37.0" +version = "0.38.0" dependencies = [ "diesel", "log", @@ -4796,7 +4796,7 @@ dependencies = [ [[package]] name = "tari_common_types" -version = "0.37.0" +version = "0.38.0" dependencies = [ "base64 0.13.0", "digest 0.9.0", @@ -4812,7 +4812,7 @@ dependencies = [ [[package]] name = "tari_comms" -version = "0.37.0" +version = "0.38.0" dependencies = [ "anyhow", "async-trait", @@ -4862,7 +4862,7 @@ dependencies = [ [[package]] name = "tari_comms_dht" -version = "0.37.0" +version = "0.38.0" dependencies = [ "anyhow", "bitflags 1.3.2", @@ -4909,7 +4909,7 @@ dependencies = [ [[package]] name = "tari_comms_rpc_macros" -version = "0.37.0" +version = "0.38.0" dependencies = [ "futures 0.3.21", "proc-macro2", @@ -4924,7 +4924,7 @@ dependencies = [ [[package]] name = "tari_console_wallet" -version = "0.37.0" +version = "0.38.0" dependencies = [ "base64 0.13.0", "bitflags 1.3.2", @@ -4974,7 +4974,7 @@ dependencies = [ [[package]] name = "tari_core" -version = "0.37.0" +version = "0.38.0" dependencies = [ "async-trait", "bincode", @@ -5062,7 +5062,7 @@ dependencies = [ [[package]] name = "tari_key_manager" -version = "0.37.0" +version = "0.38.0" dependencies = [ "argon2 0.2.4", "arrayvec 0.7.2", @@ -5109,7 +5109,7 @@ dependencies = [ [[package]] name = "tari_merge_mining_proxy" -version = "0.37.0" +version = "0.38.0" dependencies = [ "anyhow", "bincode", @@ -5161,7 +5161,7 @@ dependencies = [ [[package]] name = "tari_miner" -version = "0.37.0" +version = "0.38.0" dependencies = [ "base64 0.13.0", "bufstream", @@ -5197,7 +5197,7 @@ dependencies = [ [[package]] name = "tari_mining_helper_ffi" -version = "0.37.0" +version = "0.38.0" dependencies = [ "hex", "libc", @@ -5214,7 +5214,7 @@ dependencies = [ [[package]] name = "tari_mmr" -version = "0.37.0" +version = "0.38.0" dependencies = [ "bincode", "blake2 0.9.2", @@ -5233,7 +5233,7 @@ dependencies = [ [[package]] name = "tari_p2p" -version = "0.37.0" +version = "0.38.0" dependencies = [ "anyhow", "bytes 0.5.6", @@ -5292,7 +5292,7 @@ dependencies = [ [[package]] name = "tari_service_framework" -version = "0.37.0" +version = "0.38.0" dependencies = [ "anyhow", "async-trait", @@ -5309,7 +5309,7 @@ dependencies = [ [[package]] name = "tari_shutdown" -version = "0.37.0" +version = "0.38.0" dependencies = [ "futures 0.3.21", "tokio", @@ -5317,7 +5317,7 @@ dependencies = [ [[package]] name = "tari_storage" -version = "0.37.0" +version = "0.38.0" dependencies = [ "bincode", "lmdb-zero", @@ -5331,7 +5331,7 @@ dependencies = [ [[package]] name = "tari_test_utils" -version = "0.37.0" +version = "0.38.0" dependencies = [ "futures 0.3.21", "futures-test", @@ -5358,7 +5358,7 @@ dependencies = [ [[package]] name = "tari_wallet" -version = "0.37.0" +version = "0.38.0" dependencies = [ "argon2 0.2.4", "async-trait", @@ -5410,7 +5410,7 @@ dependencies = [ [[package]] name = "tari_wallet_ffi" -version = "0.37.0" +version = "0.38.0" dependencies = [ "cbindgen 0.24.3", "chrono", diff --git a/applications/tari_app_grpc/Cargo.toml b/applications/tari_app_grpc/Cargo.toml index 9c6ab17d7b..56b73c9d98 100644 --- a/applications/tari_app_grpc/Cargo.toml +++ b/applications/tari_app_grpc/Cargo.toml @@ -4,11 +4,11 @@ authors = ["The Tari Development Community"] description = "This crate is to provide a single source for all cross application grpc files and conversions to and from tari::core" repository = "https://github.com/tari-project/tari" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" [dependencies] -tari_common_types = { version = "^0.37", path = "../../base_layer/common_types" } +tari_common_types = { version = "^0.38", path = "../../base_layer/common_types" } tari_comms = { path = "../../comms/core" } tari_core = { path = "../../base_layer/core" } tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.5" } diff --git a/applications/tari_app_utilities/Cargo.toml b/applications/tari_app_utilities/Cargo.toml index 27e97a979f..fe29fab1a2 100644 --- a/applications/tari_app_utilities/Cargo.toml +++ b/applications/tari_app_utilities/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tari_app_utilities" -version = "0.37.0" +version = "0.38.0" authors = ["The Tari Development Community"] edition = "2018" license = "BSD-3-Clause" diff --git a/applications/tari_base_node/Cargo.toml b/applications/tari_base_node/Cargo.toml index d4f7548850..3d89d4c8fc 100644 --- a/applications/tari_base_node/Cargo.toml +++ b/applications/tari_base_node/Cargo.toml @@ -4,7 +4,7 @@ authors = ["The Tari Development Community"] description = "The tari full base node implementation" repository = "https://github.com/tari-project/tari" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" [dependencies] diff --git a/applications/tari_console_wallet/Cargo.toml b/applications/tari_console_wallet/Cargo.toml index af5bb691fe..6cb7a30c5f 100644 --- a/applications/tari_console_wallet/Cargo.toml +++ b/applications/tari_console_wallet/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tari_console_wallet" -version = "0.37.0" +version = "0.38.0" authors = ["The Tari Development Community"] edition = "2018" license = "BSD-3-Clause" diff --git a/applications/tari_merge_mining_proxy/Cargo.toml b/applications/tari_merge_mining_proxy/Cargo.toml index 1a3c9656d8..72c6a0fb8d 100644 --- a/applications/tari_merge_mining_proxy/Cargo.toml +++ b/applications/tari_merge_mining_proxy/Cargo.toml @@ -4,7 +4,7 @@ authors = ["The Tari Development Community"] description = "The Tari merge mining proxy for xmrig" repository = "https://github.com/tari-project/tari" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" [features] diff --git a/applications/tari_miner/Cargo.toml b/applications/tari_miner/Cargo.toml index c333cf989e..8e4ba0e58e 100644 --- a/applications/tari_miner/Cargo.toml +++ b/applications/tari_miner/Cargo.toml @@ -4,7 +4,7 @@ authors = ["The Tari Development Community"] description = "The tari miner implementation" repository = "https://github.com/tari-project/tari" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" [dependencies] diff --git a/base_layer/common_types/Cargo.toml b/base_layer/common_types/Cargo.toml index b9684681b8..31eb0a263a 100644 --- a/base_layer/common_types/Cargo.toml +++ b/base_layer/common_types/Cargo.toml @@ -3,7 +3,7 @@ name = "tari_common_types" authors = ["The Tari Development Community"] description = "Tari cryptocurrency common types" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" [dependencies] diff --git a/base_layer/core/Cargo.toml b/base_layer/core/Cargo.toml index 02907cf518..eee7d4f6e3 100644 --- a/base_layer/core/Cargo.toml +++ b/base_layer/core/Cargo.toml @@ -6,7 +6,7 @@ repository = "https://github.com/tari-project/tari" homepage = "https://tari.com" readme = "README.md" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" [features] @@ -19,20 +19,20 @@ avx2 = ["tari_crypto/simd_backend"] benches = ["base_node", "criterion"] [dependencies] -tari_common = { version = "^0.37", path = "../../common" } -tari_common_types = { version = "^0.37", path = "../../base_layer/common_types" } -tari_comms = { version = "^0.37", path = "../../comms/core" } -tari_comms_dht = { version = "^0.37", path = "../../comms/dht" } -tari_comms_rpc_macros = { version = "^0.37", path = "../../comms/rpc_macros" } +tari_common = { version = "^0.38", path = "../../common" } +tari_common_types = { version = "^0.38", path = "../../base_layer/common_types" } +tari_comms = { version = "^0.38", path = "../../comms/core" } +tari_comms_dht = { version = "^0.38", path = "../../comms/dht" } +tari_comms_rpc_macros = { version = "^0.38", path = "../../comms/rpc_macros" } tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.5" } tari_metrics = { path = "../../infrastructure/metrics" } -tari_mmr = { version = "^0.37", path = "../../base_layer/mmr", optional = true, features = ["native_bitmap"] } -tari_p2p = { version = "^0.37", path = "../../base_layer/p2p" } +tari_mmr = { version = "^0.38", path = "../../base_layer/mmr", optional = true, features = ["native_bitmap"] } +tari_p2p = { version = "^0.38", path = "../../base_layer/p2p" } tari_script = { path = "../../infrastructure/tari_script" } -tari_service_framework = { version = "^0.37", path = "../service_framework" } -tari_shutdown = { version = "^0.37", path = "../../infrastructure/shutdown" } -tari_storage = { version = "^0.37", path = "../../infrastructure/storage" } -tari_test_utils = { version = "^0.37", path = "../../infrastructure/test_utils" } +tari_service_framework = { version = "^0.38", path = "../service_framework" } +tari_shutdown = { version = "^0.38", path = "../../infrastructure/shutdown" } +tari_storage = { version = "^0.38", path = "../../infrastructure/storage" } +tari_test_utils = { version = "^0.38", path = "../../infrastructure/test_utils" } tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag = "v0.4.5" } async-trait = "0.1.50" @@ -76,15 +76,15 @@ tracing-attributes = "*" uint = { version = "0.9", default-features = false } [dev-dependencies] -tari_p2p = { version = "^0.37", path = "../../base_layer/p2p", features = ["test-mocks"] } -tari_test_utils = { version = "^0.37", path = "../../infrastructure/test_utils" } +tari_p2p = { version = "^0.38", path = "../../base_layer/p2p", features = ["test-mocks"] } +tari_test_utils = { version = "^0.38", path = "../../infrastructure/test_utils" } config = { version = "0.13.0" } env_logger = "0.7.0" tempfile = "3.1.0" [build-dependencies] -tari_common = { version = "^0.37", path = "../../common", features = ["build"] } +tari_common = { version = "^0.38", path = "../../common", features = ["build"] } [[bench]] name = "mempool" diff --git a/base_layer/key_manager/Cargo.toml b/base_layer/key_manager/Cargo.toml index eca664f75b..e7702a0a21 100644 --- a/base_layer/key_manager/Cargo.toml +++ b/base_layer/key_manager/Cargo.toml @@ -4,7 +4,7 @@ authors = ["The Tari Development Community"] description = "Tari cryptocurrency wallet key management" repository = "https://github.com/tari-project/tari" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2021" [lib] @@ -12,7 +12,7 @@ crate-type = ["lib", "cdylib"] # NB: All dependencies must support or be gated for the WASM target. [dependencies] -tari_common_types = { version = "^0.37", path = "../../base_layer/common_types" } +tari_common_types = { version = "^0.38", path = "../../base_layer/common_types" } tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.5" } tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag = "v0.4.5" } diff --git a/base_layer/mmr/Cargo.toml b/base_layer/mmr/Cargo.toml index b29522b8a3..ac2e5f1548 100644 --- a/base_layer/mmr/Cargo.toml +++ b/base_layer/mmr/Cargo.toml @@ -4,7 +4,7 @@ authors = ["The Tari Development Community"] description = "A Merkle Mountain Range implementation" repository = "https://github.com/tari-project/tari" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" [features] diff --git a/base_layer/p2p/Cargo.toml b/base_layer/p2p/Cargo.toml index 1af83fa4f1..e3fe60aeb3 100644 --- a/base_layer/p2p/Cargo.toml +++ b/base_layer/p2p/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tari_p2p" -version = "0.37.0" +version = "0.38.0" authors = ["The Tari Development community"] description = "Tari base layer-specific peer-to-peer communication features" repository = "https://github.com/tari-project/tari" @@ -10,13 +10,13 @@ license = "BSD-3-Clause" edition = "2018" [dependencies] -tari_comms = { version = "^0.37", path = "../../comms/core" } -tari_comms_dht = { version = "^0.37", path = "../../comms/dht" } -tari_common = { version = "^0.37", path = "../../common" } +tari_comms = { version = "^0.38", path = "../../comms/core" } +tari_comms_dht = { version = "^0.38", path = "../../comms/dht" } +tari_common = { version = "^0.38", path = "../../common" } tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.5" } -tari_service_framework = { version = "^0.37", path = "../service_framework" } -tari_shutdown = { version = "^0.37", path = "../../infrastructure/shutdown" } -tari_storage = { version = "^0.37", path = "../../infrastructure/storage" } +tari_service_framework = { version = "^0.38", path = "../service_framework" } +tari_shutdown = { version = "^0.38", path = "../../infrastructure/shutdown" } +tari_storage = { version = "^0.38", path = "../../infrastructure/storage" } tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag = "v0.4.5" } anyhow = "1.0.53" @@ -43,7 +43,7 @@ trust-dns-client = { version = "=0.21.0-alpha.5", features = ["dns-over-rustls"] webpki = "0.21" [dev-dependencies] -tari_test_utils = { version = "^0.37", path = "../../infrastructure/test_utils" } +tari_test_utils = { version = "^0.38", path = "../../infrastructure/test_utils" } config = "0.13.0" clap = "2.33.0" @@ -51,7 +51,7 @@ lazy_static = "1.3.0" tempfile = "3.1.0" [build-dependencies] -tari_common = { version = "^0.37", path = "../../common", features = ["build"] } +tari_common = { version = "^0.38", path = "../../common", features = ["build"] } [features] test-mocks = [] diff --git a/base_layer/service_framework/Cargo.toml b/base_layer/service_framework/Cargo.toml index f22b877229..1ae7443356 100644 --- a/base_layer/service_framework/Cargo.toml +++ b/base_layer/service_framework/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tari_service_framework" -version = "0.37.0" +version = "0.38.0" authors = ["The Tari Development Community"] description = "The Tari communication stack service framework" repository = "https://github.com/tari-project/tari" @@ -10,7 +10,7 @@ license = "BSD-3-Clause" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tari_shutdown = { version = "^0.37", path = "../../infrastructure/shutdown" } +tari_shutdown = { version = "^0.38", path = "../../infrastructure/shutdown" } anyhow = "1.0.53" async-trait = "0.1.50" @@ -21,7 +21,7 @@ tokio = { version = "1.20", features = ["rt"] } tower-service = { version = "0.3" } [dev-dependencies] -tari_test_utils = { version = "^0.37", path = "../../infrastructure/test_utils" } +tari_test_utils = { version = "^0.38", path = "../../infrastructure/test_utils" } tokio = { version = "1.20", features = ["rt-multi-thread", "macros", "time"] } futures-test = { version = "0.3.3" } diff --git a/base_layer/tari_mining_helper_ffi/Cargo.toml b/base_layer/tari_mining_helper_ffi/Cargo.toml index 72cf1520de..525f7e7887 100644 --- a/base_layer/tari_mining_helper_ffi/Cargo.toml +++ b/base_layer/tari_mining_helper_ffi/Cargo.toml @@ -3,11 +3,11 @@ name = "tari_mining_helper_ffi" authors = ["The Tari Development Community"] description = "Tari cryptocurrency miningcore C FFI bindings" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" [dependencies] -tari_comms = { version = "^0.37", path = "../../comms/core" } +tari_comms = { version = "^0.38", path = "../../comms/core" } tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.5" } tari_common = { path = "../../common" } tari_core = { path = "../core", default-features = false, features = ["transactions"]} diff --git a/base_layer/wallet/Cargo.toml b/base_layer/wallet/Cargo.toml index a8b7798aaa..3435461ecf 100644 --- a/base_layer/wallet/Cargo.toml +++ b/base_layer/wallet/Cargo.toml @@ -3,21 +3,21 @@ name = "tari_wallet" authors = ["The Tari Development Community"] description = "Tari cryptocurrency wallet library" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" [dependencies] tari_common = { path = "../../common" } -tari_common_types = { version = "^0.37", path = "../../base_layer/common_types" } -tari_comms = { version = "^0.37", path = "../../comms/core" } -tari_comms_dht = { version = "^0.37", path = "../../comms/dht" } +tari_common_types = { version = "^0.38", path = "../../base_layer/common_types" } +tari_comms = { version = "^0.38", path = "../../comms/core" } +tari_comms_dht = { version = "^0.38", path = "../../comms/dht" } tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.5" } -tari_key_manager = { version = "^0.37", path = "../key_manager" } -tari_p2p = { version = "^0.37", path = "../p2p", features = ["auto-update"] } +tari_key_manager = { version = "^0.38", path = "../key_manager" } +tari_p2p = { version = "^0.38", path = "../p2p", features = ["auto-update"] } tari_script = { path = "../../infrastructure/tari_script" } -tari_service_framework = { version = "^0.37", path = "../service_framework" } -tari_shutdown = { version = "^0.37", path = "../../infrastructure/shutdown" } -tari_storage = { version = "^0.37", path = "../../infrastructure/storage" } +tari_service_framework = { version = "^0.38", path = "../service_framework" } +tari_shutdown = { version = "^0.38", path = "../../infrastructure/shutdown" } +tari_storage = { version = "^0.38", path = "../../infrastructure/storage" } tari_common_sqlite = { path = "../../common_sqlite" } tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag = "v0.4.5" } @@ -59,14 +59,14 @@ chacha20poly1305 = "0.10.1" [dependencies.tari_core] path = "../../base_layer/core" -version = "^0.37" +version = "^0.38" default-features = false features = ["transactions", "mempool_proto", "base_node_proto", ] [dev-dependencies] -tari_p2p = { version = "^0.37", path = "../p2p", features = ["test-mocks"] } -tari_comms_dht = { version = "^0.37", path = "../../comms/dht", features = ["test-mocks"] } -tari_test_utils = { version = "^0.37", path = "../../infrastructure/test_utils" } +tari_p2p = { version = "^0.38", path = "../p2p", features = ["test-mocks"] } +tari_comms_dht = { version = "^0.38", path = "../../comms/dht", features = ["test-mocks"] } +tari_test_utils = { version = "^0.38", path = "../../infrastructure/test_utils" } env_logger = "0.7.1" prost = "0.9.0" diff --git a/base_layer/wallet_ffi/Cargo.toml b/base_layer/wallet_ffi/Cargo.toml index 4d283e4d6a..08529af92e 100644 --- a/base_layer/wallet_ffi/Cargo.toml +++ b/base_layer/wallet_ffi/Cargo.toml @@ -3,22 +3,22 @@ name = "tari_wallet_ffi" authors = ["The Tari Development Community"] description = "Tari cryptocurrency wallet C FFI bindings" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" [dependencies] -tari_core = { version = "^0.37", path = "../../base_layer/core", default-features = false, features = ["tari_mmr", "transactions"]} +tari_core = { version = "^0.38", path = "../../base_layer/core", default-features = false, features = ["tari_mmr", "transactions"]} tari_common = {path="../../common"} tari_common_types = {path="../common_types"} -tari_comms = { version = "^0.37", path = "../../comms/core", features = ["c_integration"]} -tari_comms_dht = { version = "^0.37", path = "../../comms/dht", default-features = false } +tari_comms = { version = "^0.38", path = "../../comms/core", features = ["c_integration"]} +tari_comms_dht = { version = "^0.38", path = "../../comms/dht", default-features = false } tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.5" } -tari_key_manager = { version = "^0.37", path = "../key_manager" } -tari_p2p = { version = "^0.37", path = "../p2p" } +tari_key_manager = { version = "^0.38", path = "../key_manager" } +tari_p2p = { version = "^0.38", path = "../p2p" } tari_script = { path = "../../infrastructure/tari_script" } -tari_shutdown = { version = "^0.37", path = "../../infrastructure/shutdown" } +tari_shutdown = { version = "^0.38", path = "../../infrastructure/shutdown" } tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag = "v0.4.5" } -tari_wallet = { version = "^0.37", path = "../wallet", features = ["c_integration"]} +tari_wallet = { version = "^0.38", path = "../wallet", features = ["c_integration"]} chrono = { version = "0.4.19", default-features = false, features = ["serde"] } futures = { version = "^0.3.1", features =["compat", "std"]} @@ -50,9 +50,9 @@ crate-type = ["staticlib","cdylib"] [dev-dependencies] tempfile = "3.1.0" lazy_static = "1.3.0" -tari_key_manager = { version = "^0.37", path = "../key_manager" } -tari_common_types = { version = "^0.37", path = "../../base_layer/common_types"} -tari_test_utils = { version = "^0.37", path = "../../infrastructure/test_utils"} +tari_key_manager = { version = "^0.38", path = "../key_manager" } +tari_common_types = { version = "^0.38", path = "../../base_layer/common_types"} +tari_test_utils = { version = "^0.38", path = "../../infrastructure/test_utils"} tari_service_framework = { path = "../../base_layer/service_framework" } [build-dependencies] diff --git a/changelog.md b/changelog.md index 25fe96c86c..63cd291c88 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,36 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [0.38.0](https://github.com/tari-project/tari/compare/v0.37.0...v0.38.0) (2022-08-31) + + +### ⚠ BREAKING CHANGES + +* replace AES-GCM with XChaCha20-Poly1305 (#4550) + +### Features + +* **build:** multiple targeted build types with options for docker builds ([#4540](https://github.com/tari-project/tari/issues/4540)) ([7e7d053](https://github.com/tari-project/tari/commit/7e7d05351e157b8ca6d4d5b5e1e258a6281d6375)) +* **comms/rpc:** restrict rpc session per peer [#4497](https://github.com/tari-project/tari/issues/4497) ([#4549](https://github.com/tari-project/tari/issues/4549)) ([080bccf](https://github.com/tari-project/tari/commit/080bccf1a037f5574962704947d29d8f1218d42a)) +* **console-wallet:** detect local base node and prompt ([#4557](https://github.com/tari-project/tari/issues/4557)) ([887df88](https://github.com/tari-project/tari/commit/887df88d57fb4566b8383a3e33ad5caee4df762c)) +* remove spawn blocking calls from wallet db (contacts service) ([#4575](https://github.com/tari-project/tari/issues/4575)) ([7464581](https://github.com/tari-project/tari/commit/74645813ab836b19d9d722aaa189a2d190eb5c6e)) +* remove spawn blocking calls from wallet db (key manager service) ([#4564](https://github.com/tari-project/tari/issues/4564)) ([a5d5133](https://github.com/tari-project/tari/commit/a5d5133943bb11e8509a51aeb7f3d40b67bc065b)) +* update tor seed nodes for esmeralda network ([#4572](https://github.com/tari-project/tari/issues/4572)) ([c4cfc12](https://github.com/tari-project/tari/commit/c4cfc128f786be3806f51d699d89465756f97e7b)) +* upgrade to tokio 1.20.1 ([#4566](https://github.com/tari-project/tari/issues/4566)) ([777936a](https://github.com/tari-project/tari/commit/777936a0c2783635f77549d3f23520912b87b7bf)) + + +### Bug Fixes + +* **cucumber:** handles listHeaders response correctly ([#4551](https://github.com/tari-project/tari/issues/4551)) ([3958dde](https://github.com/tari-project/tari/commit/3958dde8114e4301c33a90073c1a2e3c973e0e5d)) +* deserializer for SafePassword ([#4565](https://github.com/tari-project/tari/issues/4565)) ([ee89960](https://github.com/tari-project/tari/commit/ee899606e0b9c9877c89fa35add3dc2fe54be30f)) +* ignored consensus tests (see issue [#4559](https://github.com/tari-project/tari/issues/4559)) ([#4571](https://github.com/tari-project/tari/issues/4571)) ([397fe67](https://github.com/tari-project/tari/commit/397fe673b3b47d57422db71523d8012381980e6c)) +* potential problem with not updating the OMS database ([#4563](https://github.com/tari-project/tari/issues/4563)) ([c867279](https://github.com/tari-project/tari/commit/c86727969ef3fffc124ab706d44c8845addbf415)) +* remove assets and tokens tabs from tari console wallet (see issue [#4543](https://github.com/tari-project/tari/issues/4543)) ([#4556](https://github.com/tari-project/tari/issues/4556)) ([11af787](https://github.com/tari-project/tari/commit/11af7875acfca85d82394d82852729952d638d98)) +* removed `seed_words` and `delete_seed_words` commands ([#4567](https://github.com/tari-project/tari/issues/4567)) ([0b2a155](https://github.com/tari-project/tari/commit/0b2a15585e88240c027175a24dd9757cca4218ac)) +* replace AES-GCM with XChaCha20-Poly1305 ([#4550](https://github.com/tari-project/tari/issues/4550)) ([85acc2f](https://github.com/tari-project/tari/commit/85acc2f1a06afa4e7b184e4577c2b081691783da)) +* resolve tests in output_manager_service_tests.rs (see issue [#4561](https://github.com/tari-project/tari/issues/4561)) ([#4577](https://github.com/tari-project/tari/issues/4577)) ([c69245b](https://github.com/tari-project/tari/commit/c69245bbf5e9f212c07bc1736cedd9351f4d6eef)) +* update rest of the crates to tokio 1.20 ([#4576](https://github.com/tari-project/tari/issues/4576)) ([ad24bf7](https://github.com/tari-project/tari/commit/ad24bf71714ffc091c9fce7c1fc224235e3666a9)) + ## [0.37.0](https://github.com/tari-project/tari/compare/v0.36.0...v0.37.0) (2022-08-25) diff --git a/common/Cargo.toml b/common/Cargo.toml index 5abecd37f2..fc8b2f4f87 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -6,7 +6,7 @@ repository = "https://github.com/tari-project/tari" homepage = "https://tari.com" readme = "README.md" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" [features] @@ -38,5 +38,5 @@ blake2 = "0.9.1" sha3 = "0.9.0" [dev-dependencies] -tari_test_utils = { version = "^0.37", path = "../infrastructure/test_utils"} +tari_test_utils = { version = "^0.38", path = "../infrastructure/test_utils"} toml = "0.5.8" diff --git a/common_sqlite/Cargo.toml b/common_sqlite/Cargo.toml index 664ebc7e5f..5f2eeda9c4 100644 --- a/common_sqlite/Cargo.toml +++ b/common_sqlite/Cargo.toml @@ -3,7 +3,7 @@ name = "tari_common_sqlite" authors = ["The Tari Development Community"] description = "Tari cryptocurrency wallet library" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/comms/core/Cargo.toml b/comms/core/Cargo.toml index cf7fc5c3f6..bcad530df5 100644 --- a/comms/core/Cargo.toml +++ b/comms/core/Cargo.toml @@ -6,15 +6,15 @@ repository = "https://github.com/tari-project/tari" homepage = "https://tari.com" readme = "README.md" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" [dependencies] tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.5" } tari_common = {path = "../../common"} tari_metrics = { path = "../../infrastructure/metrics" } -tari_storage = { version = "^0.37", path = "../../infrastructure/storage" } -tari_shutdown = { version = "^0.37", path = "../../infrastructure/shutdown" } +tari_storage = { version = "^0.38", path = "../../infrastructure/storage" } +tari_shutdown = { version = "^0.38", path = "../../infrastructure/shutdown" } tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag = "v0.4.5" } anyhow = "1.0.53" @@ -52,7 +52,7 @@ tracing = "0.1.26" yamux = "=0.9.0" [dev-dependencies] -tari_test_utils = { version = "^0.37", path = "../../infrastructure/test_utils" } +tari_test_utils = { version = "^0.38", path = "../../infrastructure/test_utils" } tari_comms_rpc_macros = { version = "*", path = "../rpc_macros" } env_logger = "0.7.0" @@ -60,7 +60,7 @@ serde_json = "1.0.39" tempfile = "3.1.0" [build-dependencies] -tari_common = { version = "^0.37", path = "../../common", features = ["build"] } +tari_common = { version = "^0.38", path = "../../common", features = ["build"] } [features] c_integration = [] diff --git a/comms/dht/Cargo.toml b/comms/dht/Cargo.toml index 985e4217bd..6042dcb9af 100644 --- a/comms/dht/Cargo.toml +++ b/comms/dht/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tari_comms_dht" -version = "0.37.0" +version = "0.38.0" authors = ["The Tari Development Community"] description = "Tari comms DHT module" repository = "https://github.com/tari-project/tari" @@ -10,13 +10,13 @@ license = "BSD-3-Clause" edition = "2018" [dependencies] -tari_comms = { version = "^0.37", path = "../core", features = ["rpc"] } +tari_comms = { version = "^0.38", path = "../core", features = ["rpc"] } tari_common = { path = "../../common" } -tari_comms_rpc_macros = { version = "^0.37", path = "../rpc_macros" } +tari_comms_rpc_macros = { version = "^0.38", path = "../rpc_macros" } tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", tag = "v0.15.5" } tari_utilities = { git = "https://github.com/tari-project/tari_utilities.git", tag = "v0.4.5" } -tari_shutdown = { version = "^0.37", path = "../../infrastructure/shutdown" } -tari_storage = { version = "^0.37", path = "../../infrastructure/storage" } +tari_shutdown = { version = "^0.38", path = "../../infrastructure/shutdown" } +tari_storage = { version = "^0.38", path = "../../infrastructure/storage" } tari_common_sqlite = { path = "../../common_sqlite" } anyhow = "1.0.53" @@ -51,7 +51,7 @@ tokio = { version = "1.20", features = ["rt", "macros"] } pin-project = "0.4" [dev-dependencies] -tari_test_utils = { version = "^0.37", path = "../../infrastructure/test_utils" } +tari_test_utils = { version = "^0.38", path = "../../infrastructure/test_utils" } env_logger = "0.7.0" futures-test = { version = "0.3.5" } @@ -65,7 +65,7 @@ clap = "2.33.0" [build-dependencies] -tari_common = { version = "^0.37", path = "../../common" } +tari_common = { version = "^0.38", path = "../../common" } [features] test-mocks = [] diff --git a/comms/rpc_macros/Cargo.toml b/comms/rpc_macros/Cargo.toml index a236c74b8f..31563e2d45 100644 --- a/comms/rpc_macros/Cargo.toml +++ b/comms/rpc_macros/Cargo.toml @@ -6,7 +6,7 @@ repository = "https://github.com/tari-project/tari" homepage = "https://tari.com" readme = "README.md" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" [lib] @@ -19,8 +19,8 @@ quote = "1.0.7" syn = { version = "1.0.38", features = ["fold"] } [dev-dependencies] -tari_comms = { version = "^0.37", path = "../core", features = ["rpc"] } -tari_test_utils = { version = "^0.37", path = "../../infrastructure/test_utils" } +tari_comms = { version = "^0.38", path = "../core", features = ["rpc"] } +tari_test_utils = { version = "^0.38", path = "../../infrastructure/test_utils" } futures = "0.3.5" prost = "0.9.0" diff --git a/infrastructure/derive/Cargo.toml b/infrastructure/derive/Cargo.toml index 628b4fc64a..4c1343db00 100644 --- a/infrastructure/derive/Cargo.toml +++ b/infrastructure/derive/Cargo.toml @@ -6,7 +6,7 @@ repository = "https://github.com/tari-project/tari" homepage = "https://tari.com" readme = "README.md" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" [lib] diff --git a/infrastructure/libtor/Cargo.toml b/infrastructure/libtor/Cargo.toml index f5d91c8202..57dc45a5c2 100644 --- a/infrastructure/libtor/Cargo.toml +++ b/infrastructure/libtor/Cargo.toml @@ -15,7 +15,7 @@ multiaddr = { version = "0.14.0" } # NB: make sure this crate is not included in any other crate used by wallet_ffi [target.'cfg(unix)'.dependencies] -tari_shutdown = { version = "^0.37", path = "../shutdown"} +tari_shutdown = { version = "^0.38", path = "../shutdown"} libtor = { version = "46.9.0", optional = true } rand = "0.8" tempfile = "3.1.0" diff --git a/infrastructure/shutdown/Cargo.toml b/infrastructure/shutdown/Cargo.toml index abc044bbf9..bf9dcd7773 100644 --- a/infrastructure/shutdown/Cargo.toml +++ b/infrastructure/shutdown/Cargo.toml @@ -6,7 +6,7 @@ repository = "https://github.com/tari-project/tari" homepage = "https://tari.com" readme = "README.md" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/infrastructure/storage/Cargo.toml b/infrastructure/storage/Cargo.toml index cc4ed64a9f..ecedb02079 100644 --- a/infrastructure/storage/Cargo.toml +++ b/infrastructure/storage/Cargo.toml @@ -6,7 +6,7 @@ repository = "https://github.com/tari-project/tari" homepage = "https://tari.com" readme = "README.md" license = "BSD-3-Clause" -version = "0.37.0" +version = "0.38.0" edition = "2018" [dependencies] diff --git a/infrastructure/test_utils/Cargo.toml b/infrastructure/test_utils/Cargo.toml index bda022982c..0fe760597d 100644 --- a/infrastructure/test_utils/Cargo.toml +++ b/infrastructure/test_utils/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "tari_test_utils" description = "Utility functions used in Tari test functions" -version = "0.37.0" +version = "0.38.0" authors = ["The Tari Development Community"] edition = "2018" license = "BSD-3-Clause" diff --git a/package-lock.json b/package-lock.json index 391abd78d6..0f1602efa6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "tari", - "version": "0.37.0", + "version": "0.38.0", "lockfileVersion": 2, "requires": true, "packages": {} From 17bb64e4174549c846aa6f39ad0235cfd4d013f1 Mon Sep 17 00:00:00 2001 From: Andrei Gubarev <1062334+agubarev@users.noreply.github.com> Date: Wed, 31 Aug 2022 11:16:23 +0300 Subject: [PATCH 06/12] feat: console and FFI should have setting to not choose outputs that reveal the address #4403 (#4516) Description --- https://github.com/tari-project/tari/issues/4403 Wallet (console and FFI) should have setting to not choose outputs that reveal the address #4403 Motivation and Context --- Problem Wallets currently will choose the best outputs as inputs when spending, however since a lurking base node can generate a transaction graph of inputs to outputs with relative ease, a wallet may reveal its transaction history by including a (non-stealth address) one-sided payment. For example, an attacker wishing to know the transaction graph of a public key PK_Alice can send a one-sided payment to PK_Alice using the Tariscript Push(PK_Alice). At some point, Alice's wallet spends this transaction without realizing it. Possible solution Could change the wallet to have a config setting, to not include one-sided payments by default when spending How Has This Been Tested? --- --- .../2022-08-08-134037_initial/up.sql | 4 ++ .../src/output_manager_service/config.rs | 7 ++ .../output_manager_service/input_selection.rs | 1 + .../recovery/standard_outputs_recoverer.rs | 2 + .../src/output_manager_service/service.rs | 59 +++++++++++++--- .../src/output_manager_service/storage/mod.rs | 3 + .../output_manager_service/storage/models.rs | 10 ++- .../storage/output_source.rs | 68 +++++++++++++++++++ .../storage/sqlite_db/mod.rs | 11 +-- .../storage/sqlite_db/new_output_sql.rs | 3 + .../storage/sqlite_db/output_sql.rs | 9 ++- base_layer/wallet/src/schema.rs | 1 + .../output_manager_service_tests/storage.rs | 14 ++-- base_layer/wallet/tests/utxo_scanner.rs | 19 ++++-- common/config/presets/d_console_wallet.toml | 7 ++ 15 files changed, 188 insertions(+), 30 deletions(-) create mode 100644 base_layer/wallet/src/output_manager_service/storage/output_source.rs diff --git a/base_layer/wallet/migrations/2022-08-08-134037_initial/up.sql b/base_layer/wallet/migrations/2022-08-08-134037_initial/up.sql index a8967cb66d..e9897c669d 100644 --- a/base_layer/wallet/migrations/2022-08-08-134037_initial/up.sql +++ b/base_layer/wallet/migrations/2022-08-08-134037_initial/up.sql @@ -110,12 +110,16 @@ CREATE TABLE outputs ( spent_in_tx_id BIGINT NULL, coinbase_block_height UNSIGNED BIGINT NULL, metadata BLOB NULL, + features_parent_public_key BLOB NULL, + features_unique_id BLOB NULL, features_json TEXT NOT NULL DEFAULT '{}', spending_priority UNSIGNED INTEGER NOT NULL DEFAULT 500, covenant BLOB NOT NULL, mined_timestamp DATETIME NULL, encrypted_value BLOB NOT NULL, + contract_id BLOB NULL, minimum_value_promise BIGINT NOT NULL, + source INTEGER NOT NULL DEFAULT 0, CONSTRAINT unique_commitment UNIQUE (commitment) ); diff --git a/base_layer/wallet/src/output_manager_service/config.rs b/base_layer/wallet/src/output_manager_service/config.rs index 5c48222286..d08434de01 100644 --- a/base_layer/wallet/src/output_manager_service/config.rs +++ b/base_layer/wallet/src/output_manager_service/config.rs @@ -35,6 +35,12 @@ pub struct OutputManagerServiceConfig { pub num_confirmations_required: u64, /// The number of batches the unconfirmed outputs will be divided into before being queried from the base node pub tx_validator_batch_size: usize, + /// Wallets currently will choose the best outputs as inputs when spending, however since a lurking base node can + /// generate a transaction graph of inputs to outputs with relative ease, a wallet may reveal its transaction + /// history by including a (non-stealth address) one-sided payment. + /// If set to `true`, then outputs received via simple one-sided transactions, won't be automatically selected as + /// inputs for further transactions, but can still be selected individually as specific outputs. + pub autoignore_onesided_utxos: bool, } impl Default for OutputManagerServiceConfig { @@ -44,6 +50,7 @@ impl Default for OutputManagerServiceConfig { event_channel_size: 250, num_confirmations_required: 3, tx_validator_batch_size: 100, + autoignore_onesided_utxos: false, } } } diff --git a/base_layer/wallet/src/output_manager_service/input_selection.rs b/base_layer/wallet/src/output_manager_service/input_selection.rs index ead49139b7..933285c312 100644 --- a/base_layer/wallet/src/output_manager_service/input_selection.rs +++ b/base_layer/wallet/src/output_manager_service/input_selection.rs @@ -32,6 +32,7 @@ pub struct UtxoSelectionCriteria { pub filter: UtxoSelectionFilter, pub ordering: UtxoSelectionOrdering, pub excluding: Vec, + pub excluding_onesided: bool, } impl UtxoSelectionCriteria { diff --git a/base_layer/wallet/src/output_manager_service/recovery/standard_outputs_recoverer.rs b/base_layer/wallet/src/output_manager_service/recovery/standard_outputs_recoverer.rs index 268cc2756a..4236cf13d5 100644 --- a/base_layer/wallet/src/output_manager_service/recovery/standard_outputs_recoverer.rs +++ b/base_layer/wallet/src/output_manager_service/recovery/standard_outputs_recoverer.rs @@ -48,6 +48,7 @@ use crate::{ storage::{ database::{OutputManagerBackend, OutputManagerDatabase}, models::DbUnblindedOutput, + OutputSource, }, }, }; @@ -151,6 +152,7 @@ where &self.rewind_data, None, Some(proof), + OutputSource::Recovered, )?; let tx_id = TxId::new_random(); let output_hex = db_output.commitment.to_hex(); diff --git a/base_layer/wallet/src/output_manager_service/service.rs b/base_layer/wallet/src/output_manager_service/service.rs index 10102e07e0..6d22619620 100644 --- a/base_layer/wallet/src/output_manager_service/service.rs +++ b/base_layer/wallet/src/output_manager_service/service.rs @@ -91,6 +91,7 @@ use crate::{ storage::{ database::{OutputBackendQuery, OutputManagerBackend, OutputManagerDatabase}, models::{DbUnblindedOutput, KnownOneSidedPaymentScript, SpendingPriority}, + OutputSource, OutputStatus, }, tasks::TxoValidationTask, @@ -588,7 +589,12 @@ where "Add output of value {} to Output Manager", output.value ); - let output = DbUnblindedOutput::from_unblinded_output(output, &self.resources.factories, spend_priority)?; + let output = DbUnblindedOutput::from_unblinded_output( + output, + &self.resources.factories, + spend_priority, + OutputSource::default(), + )?; debug!( target: LOG_TARGET, "saving output of hash {} to Output Manager", @@ -625,6 +631,7 @@ where &rewind_data, spend_priority, None, + OutputSource::default(), )?; debug!( target: LOG_TARGET, @@ -660,7 +667,12 @@ where target: LOG_TARGET, "Add unvalidated output of value {} to Output Manager", output.value ); - let output = DbUnblindedOutput::from_unblinded_output(output, &self.resources.factories, spend_priority)?; + let output = DbUnblindedOutput::from_unblinded_output( + output, + &self.resources.factories, + spend_priority, + OutputSource::default(), + )?; self.resources.db.add_unvalidated_output(tx_id, output)?; Ok(()) } @@ -772,6 +784,7 @@ where &self.resources.rewind_data, None, None, + OutputSource::default(), )?; self.resources @@ -946,6 +959,7 @@ where &self.resources.rewind_data.clone(), None, None, + OutputSource::default(), )?); } @@ -1007,6 +1021,7 @@ where &self.resources.rewind_data, None, None, + OutputSource::Coinbase, )?; // If there is no existing output available, we store the one we produced. @@ -1113,6 +1128,7 @@ where &self.resources.rewind_data, None, None, + OutputSource::default(), )?) } @@ -1174,6 +1190,7 @@ where &self.resources.rewind_data, None, None, + OutputSource::default(), )?); } let tx_id = stp.get_tx_id()?; @@ -1277,6 +1294,7 @@ where &self.resources.rewind_data, None, None, + OutputSource::default(), )?; builder .with_output(utxo.unblinded_output.clone(), sender_offset_private_key.clone()) @@ -1316,6 +1334,7 @@ where &self.resources.rewind_data, None, None, + OutputSource::default(), )?; outputs.push(change_output); } @@ -1371,7 +1390,7 @@ where fee_per_gram: MicroTari, num_outputs: usize, total_output_metadata_byte_size: usize, - selection_criteria: UtxoSelectionCriteria, + mut selection_criteria: UtxoSelectionCriteria, ) -> Result { debug!( target: LOG_TARGET, @@ -1390,6 +1409,11 @@ where // Attempt to get the chain tip height let chain_metadata = self.base_node_service.get_chain_metadata().await?; + // Respecting the setting to not choose outputs that reveal the address + if self.resources.config.autoignore_onesided_utxos { + selection_criteria.excluding_onesided = self.resources.config.autoignore_onesided_utxos; + } + warn!( target: LOG_TARGET, "select_utxos selection criteria: {}", selection_criteria @@ -1761,6 +1785,7 @@ where &self.resources.rewind_data.clone(), None, None, + OutputSource::default(), )?; tx_builder @@ -1979,6 +2004,7 @@ where &self.resources.rewind_data.clone(), None, None, + OutputSource::default(), )?; tx_builder @@ -2036,6 +2062,7 @@ where &self.resources.rewind_data.clone(), None, None, + OutputSource::default(), )?); } @@ -2184,6 +2211,7 @@ where &self.resources.rewind_data.clone(), None, None, + OutputSource::default(), )?; tx_builder @@ -2348,6 +2376,7 @@ where &self.resources.rewind_data, None, None, + OutputSource::AtomicSwap, )?; outputs.push(change_output); @@ -2434,6 +2463,7 @@ where &self.resources.rewind_data, None, None, + OutputSource::Refund, )?; outputs.push(change_output); @@ -2506,9 +2536,12 @@ where ) .as_bytes(), ) { - Ok(spending_sk) => { - scanned_outputs.push((output.clone(), matched_key.private_key.clone(), spending_sk)) - }, + Ok(spending_sk) => scanned_outputs.push(( + output.clone(), + OutputSource::OneSided, + matched_key.private_key.clone(), + spending_sk, + )), Err(e) => { error!( target: LOG_TARGET, @@ -2544,9 +2577,12 @@ where match PrivateKey::from_bytes( CommsPublicKey::shared_secret(&wallet_sk, &output.sender_offset_public_key).as_bytes(), ) { - Ok(spending_sk) => { - scanned_outputs.push((output.clone(), wallet_sk.clone() + shared_secret, spending_sk)) - }, + Ok(spending_sk) => scanned_outputs.push(( + output.clone(), + OutputSource::StealthOneSided, + wallet_sk.clone() + shared_secret, + spending_sk, + )), Err(e) => { error!( target: LOG_TARGET, @@ -2567,11 +2603,11 @@ where // Imports scanned outputs into the wallet fn import_onesided_outputs( &self, - scanned_outputs: Vec<(TransactionOutput, PrivateKey, RistrettoSecretKey)>, + scanned_outputs: Vec<(TransactionOutput, OutputSource, PrivateKey, RistrettoSecretKey)>, ) -> Result, OutputManagerError> { let mut rewound_outputs = Vec::with_capacity(scanned_outputs.len()); - for (output, script_private_key, spending_sk) in scanned_outputs { + for (output, output_source, script_private_key, spending_sk) in scanned_outputs { let rewind_blinding_key = PrivateKey::from_bytes(&hash_secret_key(&spending_sk))?; let encryption_key = PrivateKey::from_bytes(&hash_secret_key(&rewind_blinding_key))?; let committed_value = @@ -2611,6 +2647,7 @@ where }, None, Some(&output.proof), + output_source, )?; let output_hex = output.commitment.to_hex(); diff --git a/base_layer/wallet/src/output_manager_service/storage/mod.rs b/base_layer/wallet/src/output_manager_service/storage/mod.rs index 8ecb04f5fe..8af28c8b4a 100644 --- a/base_layer/wallet/src/output_manager_service/storage/mod.rs +++ b/base_layer/wallet/src/output_manager_service/storage/mod.rs @@ -22,6 +22,9 @@ pub mod database; pub mod models; +pub mod output_source; pub mod output_status; pub mod sqlite_db; + +pub use output_source::OutputSource; pub use output_status::OutputStatus; diff --git a/base_layer/wallet/src/output_manager_service/storage/models.rs b/base_layer/wallet/src/output_manager_service/storage/models.rs index 9cf45b893f..45ad665a7d 100644 --- a/base_layer/wallet/src/output_manager_service/storage/models.rs +++ b/base_layer/wallet/src/output_manager_service/storage/models.rs @@ -32,7 +32,10 @@ use tari_core::transactions::{ }; use tari_script::{ExecutionStack, TariScript}; -use crate::output_manager_service::{error::OutputManagerStorageError, storage::OutputStatus}; +use crate::output_manager_service::{ + error::OutputManagerStorageError, + storage::{OutputSource, OutputStatus}, +}; #[derive(Debug, Clone)] pub struct DbUnblindedOutput { @@ -47,6 +50,7 @@ pub struct DbUnblindedOutput { pub marked_deleted_at_height: Option, pub marked_deleted_in_block: Option, pub spending_priority: SpendingPriority, + pub source: OutputSource, } impl DbUnblindedOutput { @@ -54,6 +58,7 @@ impl DbUnblindedOutput { output: UnblindedOutput, factory: &CryptoFactories, spend_priority: Option, + source: OutputSource, ) -> Result { let tx_out = output.as_transaction_output(factory)?; Ok(DbUnblindedOutput { @@ -68,6 +73,7 @@ impl DbUnblindedOutput { marked_deleted_at_height: None, marked_deleted_in_block: None, spending_priority: spend_priority.unwrap_or(SpendingPriority::Normal), + source, }) } @@ -77,6 +83,7 @@ impl DbUnblindedOutput { rewind_data: &RewindData, spending_priority: Option, proof: Option<&BulletRangeProof>, + source: OutputSource, ) -> Result { let tx_out = output.as_rewindable_transaction_output(factory, rewind_data, proof)?; Ok(DbUnblindedOutput { @@ -91,6 +98,7 @@ impl DbUnblindedOutput { marked_deleted_at_height: None, marked_deleted_in_block: None, spending_priority: spending_priority.unwrap_or(SpendingPriority::Normal), + source, }) } } diff --git a/base_layer/wallet/src/output_manager_service/storage/output_source.rs b/base_layer/wallet/src/output_manager_service/storage/output_source.rs new file mode 100644 index 0000000000..e6937e7d83 --- /dev/null +++ b/base_layer/wallet/src/output_manager_service/storage/output_source.rs @@ -0,0 +1,68 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// 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. +use core::{ + convert::TryFrom, + result::{ + Result, + Result::{Err, Ok}, + }, +}; + +use strum_macros::Display; + +use crate::output_manager_service::error::OutputManagerStorageError; + +// The source of where the output came from +#[derive(Copy, Clone, Debug, PartialEq, Display, Default)] +pub enum OutputSource { + Unknown, + Coinbase, + Recovered, + #[default] + Standard, + OneSided, + StealthOneSided, + Refund, + AtomicSwap, +} + +impl TryFrom for OutputSource { + type Error = OutputManagerStorageError; + + fn try_from(value: i32) -> Result { + Ok(match value { + 0 => OutputSource::Unknown, + 1 => OutputSource::Coinbase, + 2 => OutputSource::Recovered, + 3 => OutputSource::Standard, + 4 => OutputSource::OneSided, + 5 => OutputSource::StealthOneSided, + 6 => OutputSource::Refund, + 7 => OutputSource::AtomicSwap, + _ => { + return Err(OutputManagerStorageError::ConversionError { + reason: "Was expecting value between 0 and 7 for OutputSource".to_string(), + }) + }, + }) + } +} diff --git a/base_layer/wallet/src/output_manager_service/storage/sqlite_db/mod.rs b/base_layer/wallet/src/output_manager_service/storage/sqlite_db/mod.rs index b6a5c8dc4e..7c2ad39bab 100644 --- a/base_layer/wallet/src/output_manager_service/storage/sqlite_db/mod.rs +++ b/base_layer/wallet/src/output_manager_service/storage/sqlite_db/mod.rs @@ -1480,6 +1480,7 @@ mod test { OutputStatus, UpdateOutput, }, + OutputSource, }, storage::sqlite_utilities::wallet_db_connection::WalletDbConnection, util::encryption::Encryptable, @@ -1517,7 +1518,7 @@ mod test { for _i in 0..2 { let (_, uo) = make_input(MicroTari::from(100 + OsRng.next_u64() % 1000)); - let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None).unwrap(); + let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown).unwrap(); let o = NewOutputSql::new(uo, OutputStatus::Unspent, None, None).unwrap(); outputs.push(o.clone()); outputs_unspent.push(o.clone()); @@ -1526,7 +1527,7 @@ mod test { for _i in 0..3 { let (_, uo) = make_input(MicroTari::from(100 + OsRng.next_u64() % 1000)); - let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None).unwrap(); + let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown).unwrap(); let o = NewOutputSql::new(uo, OutputStatus::Spent, None, None).unwrap(); outputs.push(o.clone()); outputs_spent.push(o.clone()); @@ -1627,7 +1628,7 @@ mod test { let factories = CryptoFactories::default(); let (_, uo) = make_input(MicroTari::from(100 + OsRng.next_u64() % 1000)); - let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None).unwrap(); + let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown).unwrap(); let output = NewOutputSql::new(uo, OutputStatus::Unspent, None, None).unwrap(); let mut key = [0u8; size_of::()]; @@ -1694,12 +1695,12 @@ mod test { let factories = CryptoFactories::default(); let (_, uo) = make_input(MicroTari::from(100 + OsRng.next_u64() % 1000)); - let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None).unwrap(); + let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown).unwrap(); let output = NewOutputSql::new(uo, OutputStatus::Unspent, None, None).unwrap(); output.commit(&conn).unwrap(); let (_, uo2) = make_input(MicroTari::from(100 + OsRng.next_u64() % 1000)); - let uo2 = DbUnblindedOutput::from_unblinded_output(uo2, &factories, None).unwrap(); + let uo2 = DbUnblindedOutput::from_unblinded_output(uo2, &factories, None, OutputSource::Unknown).unwrap(); let output2 = NewOutputSql::new(uo2, OutputStatus::Unspent, None, None).unwrap(); output2.commit(&conn).unwrap(); } diff --git a/base_layer/wallet/src/output_manager_service/storage/sqlite_db/new_output_sql.rs b/base_layer/wallet/src/output_manager_service/storage/sqlite_db/new_output_sql.rs index 502b13c202..d3d2561ee8 100644 --- a/base_layer/wallet/src/output_manager_service/storage/sqlite_db/new_output_sql.rs +++ b/base_layer/wallet/src/output_manager_service/storage/sqlite_db/new_output_sql.rs @@ -63,6 +63,7 @@ pub struct NewOutputSql { pub covenant: Vec, pub encrypted_value: Vec, pub minimum_value_promise: i64, + pub source: i32, } impl NewOutputSql { @@ -99,6 +100,7 @@ impl NewOutputSql { covenant: output.unblinded_output.covenant.to_bytes(), encrypted_value: output.unblinded_output.encrypted_value.to_vec(), minimum_value_promise: output.unblinded_output.minimum_value_promise.as_u64() as i64, + source: output.source as i32, }) } @@ -168,6 +170,7 @@ impl From for NewOutputSql { covenant: o.covenant, encrypted_value: o.encrypted_value, minimum_value_promise: o.minimum_value_promise, + source: 0, } } } diff --git a/base_layer/wallet/src/output_manager_service/storage/sqlite_db/output_sql.rs b/base_layer/wallet/src/output_manager_service/storage/sqlite_db/output_sql.rs index 140b8a11fd..b20eac6799 100644 --- a/base_layer/wallet/src/output_manager_service/storage/sqlite_db/output_sql.rs +++ b/base_layer/wallet/src/output_manager_service/storage/sqlite_db/output_sql.rs @@ -51,6 +51,7 @@ use crate::{ database::{OutputBackendQuery, SortDirection}, models::DbUnblindedOutput, sqlite_db::{UpdateOutput, UpdateOutputSql}, + OutputSource, OutputStatus, }, UtxoSelectionFilter, @@ -102,6 +103,7 @@ pub struct OutputSql { pub mined_timestamp: Option, pub encrypted_value: Vec, pub minimum_value_promise: i64, + pub source: i32, } impl OutputSql { @@ -206,7 +208,11 @@ impl OutputSql { outputs::output_type .eq(i32::from(OutputType::Standard.as_byte())) .or(outputs::output_type.eq(i32::from(OutputType::Coinbase.as_byte()))), - ) + ); + + if selection_criteria.excluding_onesided { + query = query.filter(outputs::source.ne(OutputSource::OneSided as i32)); + } }, UtxoSelectionFilter::SpecificOutputs { commitments } => { query = match commitments.len() { @@ -739,6 +745,7 @@ impl TryFrom for DbUnblindedOutput { marked_deleted_at_height: o.marked_deleted_at_height.map(|d| d as u64), marked_deleted_in_block, spending_priority, + source: o.source.try_into()?, }) } } diff --git a/base_layer/wallet/src/schema.rs b/base_layer/wallet/src/schema.rs index e2a7fa2528..06fd45f00e 100644 --- a/base_layer/wallet/src/schema.rs +++ b/base_layer/wallet/src/schema.rs @@ -155,6 +155,7 @@ table! { mined_timestamp -> Nullable, encrypted_value -> Binary, minimum_value_promise -> BigInt, + source -> Integer, } } diff --git a/base_layer/wallet/tests/output_manager_service_tests/storage.rs b/base_layer/wallet/tests/output_manager_service_tests/storage.rs index a1dd6958b3..13009d55d2 100644 --- a/base_layer/wallet/tests/output_manager_service_tests/storage.rs +++ b/base_layer/wallet/tests/output_manager_service_tests/storage.rs @@ -33,6 +33,7 @@ use tari_wallet::output_manager_service::{ database::{OutputManagerBackend, OutputManagerDatabase}, models::DbUnblindedOutput, sqlite_db::OutputManagerSqliteDatabase, + OutputSource, }, }; use tokio::runtime::Runtime; @@ -54,7 +55,7 @@ pub fn test_db_backend(backend: T) { MicroTari::from(100 + OsRng.next_u64() % 1000), &factories.commitment, )); - let mut uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None).unwrap(); + let mut uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown).unwrap(); uo.unblinded_output.features.maturity = i; db.add_unspent_output(uo.clone()).unwrap(); unspent_outputs.push(uo); @@ -101,7 +102,7 @@ pub fn test_db_backend(backend: T) { MicroTari::from(100 + OsRng.next_u64() % 1000), &factories.commitment, )); - let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None).unwrap(); + let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown).unwrap(); db.add_unspent_output(uo.clone()).unwrap(); pending_tx.outputs_to_be_spent.push(uo); } @@ -111,7 +112,7 @@ pub fn test_db_backend(backend: T) { MicroTari::from(100 + OsRng.next_u64() % 1000), &factories.commitment, )); - let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None).unwrap(); + let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown).unwrap(); pending_tx.outputs_to_be_received.push(uo); } db.encumber_outputs( @@ -246,7 +247,8 @@ pub fn test_db_backend(backend: T) { MicroTari::from(100 + OsRng.next_u64() % 1000), &factories.commitment, )); - let output_to_be_received = DbUnblindedOutput::from_unblinded_output(uo, &factories, None).unwrap(); + let output_to_be_received = + DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown).unwrap(); db.add_output_to_be_received(TxId::from(11u64), output_to_be_received.clone(), None) .unwrap(); pending_incoming_balance += output_to_be_received.unblinded_output.value; @@ -347,7 +349,7 @@ pub async fn test_short_term_encumberance() { &factories.commitment, ) .await; - let mut uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None).unwrap(); + let mut uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown).unwrap(); uo.unblinded_output.features.maturity = i; db.add_unspent_output(uo.clone()).unwrap(); unspent_outputs.push(uo); @@ -398,7 +400,7 @@ pub async fn test_no_duplicate_outputs() { // create an output let (_ti, uo) = make_input(&mut OsRng, MicroTari::from(1000), &factories.commitment).await; - let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None).unwrap(); + let uo = DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown).unwrap(); // add it to the database let result = db.add_unspent_output(uo.clone()); diff --git a/base_layer/wallet/tests/utxo_scanner.rs b/base_layer/wallet/tests/utxo_scanner.rs index f145a7ae2a..dcef38d99e 100644 --- a/base_layer/wallet/tests/utxo_scanner.rs +++ b/base_layer/wallet/tests/utxo_scanner.rs @@ -76,6 +76,7 @@ use support::{ }; use tari_comms::types::CommsPublicKey; use tari_wallet::{ + output_manager_service::storage::OutputSource, transaction_service::handle::TransactionServiceRequest, util::watch::Watch, utxo_scanner_service::handle::UtxoScannerHandle, @@ -322,7 +323,8 @@ async fn test_utxo_scanner_recovery() { let mut total_amount_to_recover = MicroTari::from(0); for (h, outputs) in &unblinded_outputs { for output in outputs.iter().skip(outputs.len() / 2) { - let dbo = DbUnblindedOutput::from_unblinded_output(output.clone(), &factories, None).unwrap(); + let dbo = DbUnblindedOutput::from_unblinded_output(output.clone(), &factories, None, OutputSource::Unknown) + .unwrap(); // Only the outputs in blocks after the birthday should be included in the recovered total if *h >= NUM_BLOCKS.saturating_sub(BIRTHDAY_OFFSET).saturating_sub(2) { total_outputs_to_recover += 1; @@ -412,7 +414,8 @@ async fn test_utxo_scanner_recovery_with_restart() { let mut total_amount_to_recover = MicroTari::from(0); for (h, outputs) in &unblinded_outputs { for output in outputs.iter().skip(outputs.len() / 2) { - let dbo = DbUnblindedOutput::from_unblinded_output(output.clone(), &factories, None).unwrap(); + let dbo = DbUnblindedOutput::from_unblinded_output(output.clone(), &factories, None, OutputSource::Unknown) + .unwrap(); // Only the outputs in blocks after the birthday should be included in the recovered total if *h >= NUM_BLOCKS.saturating_sub(BIRTHDAY_OFFSET).saturating_sub(2) { total_outputs_to_recover += 1; @@ -566,7 +569,8 @@ async fn test_utxo_scanner_recovery_with_restart_and_reorg() { let mut db_unblinded_outputs = Vec::new(); for outputs in unblinded_outputs.values() { for output in outputs.iter().skip(outputs.len() / 2) { - let dbo = DbUnblindedOutput::from_unblinded_output(output.clone(), &factories, None).unwrap(); + let dbo = DbUnblindedOutput::from_unblinded_output(output.clone(), &factories, None, OutputSource::Unknown) + .unwrap(); db_unblinded_outputs.push(dbo); } } @@ -634,7 +638,8 @@ async fn test_utxo_scanner_recovery_with_restart_and_reorg() { let mut total_amount_to_recover = MicroTari::from(0); for (h, outputs) in &unblinded_outputs { for output in outputs.iter().skip(outputs.len() / 2) { - let dbo = DbUnblindedOutput::from_unblinded_output(output.clone(), &factories, None).unwrap(); + let dbo = DbUnblindedOutput::from_unblinded_output(output.clone(), &factories, None, OutputSource::Unknown) + .unwrap(); // Only the outputs in blocks after the birthday should be included in the recovered total if *h >= 4 { total_outputs_to_recover += 1; @@ -838,7 +843,8 @@ async fn test_utxo_scanner_one_sided_payments() { let mut total_amount_to_recover = MicroTari::from(0); for (h, outputs) in &unblinded_outputs { for output in outputs.iter().skip(outputs.len() / 2) { - let dbo = DbUnblindedOutput::from_unblinded_output(output.clone(), &factories, None).unwrap(); + let dbo = DbUnblindedOutput::from_unblinded_output(output.clone(), &factories, None, OutputSource::Unknown) + .unwrap(); // Only the outputs in blocks after the birthday should be included in the recovered total if *h >= NUM_BLOCKS.saturating_sub(BIRTHDAY_OFFSET).saturating_sub(2) { total_outputs_to_recover += 1; @@ -911,7 +917,8 @@ async fn test_utxo_scanner_one_sided_payments() { utxos_by_block.push(block11); block_headers.insert(NUM_BLOCKS, block_header11); - db_unblinded_outputs.push(DbUnblindedOutput::from_unblinded_output(uo, &factories, None).unwrap()); + db_unblinded_outputs + .push(DbUnblindedOutput::from_unblinded_output(uo, &factories, None, OutputSource::Unknown).unwrap()); test_interface .oms_mock_state .set_one_sided_payments(db_unblinded_outputs); diff --git a/common/config/presets/d_console_wallet.toml b/common/config/presets/d_console_wallet.toml index 0bada2bd9b..beb6ee206c 100644 --- a/common/config/presets/d_console_wallet.toml +++ b/common/config/presets/d_console_wallet.toml @@ -61,6 +61,13 @@ #command_send_wait_timeout = 300 #command_send_wait_stage = "Broadcast" +# Wallets currently will choose the best outputs as inputs when spending, however since a lurking base node can +# generate a transaction graph of inputs to outputs with relative ease, a wallet may reveal its transaction +# history by including a (non-stealth address) one-sided payment. +# If set to `true`, then outputs received via simple one-sided transactions, won't be automatically selected as +# further transactions, but can still be selected individually as specific outputs. +#autoignore_onesided_utxos = false + # Set to true to enable grpc. (default = false) #grpc_enabled = false # The socket to expose for the gRPC base node server (default = "/ip4/127.0.0.1/tcp/18143") From 2182c5ca567a696240fdc0c248f05efde4edd4a6 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Wed, 31 Aug 2022 14:15:05 +0200 Subject: [PATCH 07/12] fix coinbase handling (#4588) Description --- A race condition exists if more than one miner asks for a coinbase with different values. The first transaction will be canceled by the second one. Coinbase transactions should only ever be canceled by the validation process after confirming they have not been mined. --- base_layer/wallet/src/output_manager_service/service.rs | 6 +++--- base_layer/wallet/src/transaction_service/service.rs | 6 ------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/base_layer/wallet/src/output_manager_service/service.rs b/base_layer/wallet/src/output_manager_service/service.rs index 6d22619620..b22e4b35cc 100644 --- a/base_layer/wallet/src/output_manager_service/service.rs +++ b/base_layer/wallet/src/output_manager_service/service.rs @@ -1410,9 +1410,9 @@ where let chain_metadata = self.base_node_service.get_chain_metadata().await?; // Respecting the setting to not choose outputs that reveal the address - if self.resources.config.autoignore_onesided_utxos { - selection_criteria.excluding_onesided = self.resources.config.autoignore_onesided_utxos; - } + if self.resources.config.autoignore_onesided_utxos { + selection_criteria.excluding_onesided = self.resources.config.autoignore_onesided_utxos; + } warn!( target: LOG_TARGET, diff --git a/base_layer/wallet/src/transaction_service/service.rs b/base_layer/wallet/src/transaction_service/service.rs index dd621eea8c..6e57e4c8c6 100644 --- a/base_layer/wallet/src/transaction_service/service.rs +++ b/base_layer/wallet/src/transaction_service/service.rs @@ -2528,12 +2528,6 @@ where .output_manager_service .get_coinbase_transaction(tx_id, reward, fees, block_height) .await?; - - // Cancel existing unmined coinbase transactions for this blockheight - self.db - .cancel_coinbase_transaction_at_block_height(block_height) - .await?; - self.db .insert_completed_transaction( tx_id, From 095196bb684546eba00a9fd2e35c02ddda172437 Mon Sep 17 00:00:00 2001 From: Andrei Gubarev <1062334+agubarev@users.noreply.github.com> Date: Wed, 31 Aug 2022 15:16:06 +0300 Subject: [PATCH 08/12] feat: attempt to recognize the source of a recovered output (#4580) Description --- Attempts to recognize the source of a recovered output Motivation and Context --- Recovered outputs lack details of how they are received, so this is an attempt to perform at least some recognition. How Has This Been Tested? --- existing unit tests --- .../recovery/standard_outputs_recoverer.rs | 12 ++++++++++-- .../output_manager_service/storage/output_source.rs | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/base_layer/wallet/src/output_manager_service/recovery/standard_outputs_recoverer.rs b/base_layer/wallet/src/output_manager_service/recovery/standard_outputs_recoverer.rs index 4236cf13d5..00d81a9334 100644 --- a/base_layer/wallet/src/output_manager_service/recovery/standard_outputs_recoverer.rs +++ b/base_layer/wallet/src/output_manager_service/recovery/standard_outputs_recoverer.rs @@ -37,7 +37,7 @@ use tari_crypto::{ keys::{PublicKey as PublicKeyTrait, SecretKey}, tari_utilities::hex::Hex, }; -use tari_script::{inputs, script}; +use tari_script::{inputs, script, Opcode}; use crate::{ key_manager_service::KeyManagerInterface, @@ -146,13 +146,21 @@ where let mut rewound_outputs_with_tx_id: Vec = Vec::new(); for (output, proof) in &mut rewound_outputs { + // Attempting to recognize output source by i.e., standard MimbleWimble, simple or stealth one-sided + let output_source = match *output.script.as_slice() { + [Opcode::Nop] => OutputSource::Standard, + [Opcode::PushPubKey(_), Opcode::Drop, Opcode::PushPubKey(_)] => OutputSource::StealthOneSided, + [Opcode::PushPubKey(_)] => OutputSource::OneSided, + _ => OutputSource::RecoveredButUnrecognized, + }; + let db_output = DbUnblindedOutput::rewindable_from_unblinded_output( output.clone(), &self.factories, &self.rewind_data, None, Some(proof), - OutputSource::Recovered, + output_source, )?; let tx_id = TxId::new_random(); let output_hex = db_output.commitment.to_hex(); diff --git a/base_layer/wallet/src/output_manager_service/storage/output_source.rs b/base_layer/wallet/src/output_manager_service/storage/output_source.rs index e6937e7d83..51a85d03aa 100644 --- a/base_layer/wallet/src/output_manager_service/storage/output_source.rs +++ b/base_layer/wallet/src/output_manager_service/storage/output_source.rs @@ -36,7 +36,7 @@ use crate::output_manager_service::error::OutputManagerStorageError; pub enum OutputSource { Unknown, Coinbase, - Recovered, + RecoveredButUnrecognized, #[default] Standard, OneSided, @@ -52,7 +52,7 @@ impl TryFrom for OutputSource { Ok(match value { 0 => OutputSource::Unknown, 1 => OutputSource::Coinbase, - 2 => OutputSource::Recovered, + 2 => OutputSource::RecoveredButUnrecognized, 3 => OutputSource::Standard, 4 => OutputSource::OneSided, 5 => OutputSource::StealthOneSided, From 77bb10d42e8c004406d0ddd69b65575f0e111cd1 Mon Sep 17 00:00:00 2001 From: Hansie Odendaal <39146854+hansieodendaal@users.noreply.github.com> Date: Wed, 31 Aug 2022 20:39:43 +0200 Subject: [PATCH 09/12] feat: remove spawn blocking calls from wallet db (wallet storage)(#4591) Description --- Removed spawn blocking calls for db operations from the wallet in the wallet storage. (This is another PR in a couple of PRs required to implement this fully throughout the wallet code.) Motivation and Context --- As per https://github.com/tari-project/tari/pull/3982 and https://github.com/tari-project/tari/issues/4555 How Has This Been Tested? --- Unit tests Cucumber tests --- .../src/automation/commands.rs | 14 +- .../tari_console_wallet/src/init/mod.rs | 30 +- applications/tari_console_wallet/src/main.rs | 2 +- .../src/ui/state/app_state.rs | 20 +- .../tari_console_wallet/src/utils/db.rs | 25 +- .../tari_console_wallet/src/wallet_modes.rs | 2 +- .../wallet/src/base_node_service/monitor.rs | 2 +- .../wallet/src/base_node_service/service.rs | 4 +- base_layer/wallet/src/storage/database.rs | 290 +++++------------- .../src/storage/sqlite_utilities/mod.rs | 4 +- .../wallet/src/transaction_service/service.rs | 12 +- .../utxo_scanner_service/utxo_scanner_task.rs | 54 ++-- base_layer/wallet/src/wallet.rs | 30 +- .../transaction_service_tests/service.rs | 15 +- base_layer/wallet/tests/utxo_scanner.rs | 14 +- base_layer/wallet/tests/wallet.rs | 14 +- base_layer/wallet_ffi/src/lib.rs | 61 ++-- 17 files changed, 203 insertions(+), 390 deletions(-) diff --git a/applications/tari_console_wallet/src/automation/commands.rs b/applications/tari_console_wallet/src/automation/commands.rs index 4e686bb468..46b2784276 100644 --- a/applications/tari_console_wallet/src/automation/commands.rs +++ b/applications/tari_console_wallet/src/automation/commands.rs @@ -704,23 +704,17 @@ pub async fn command_runner( set_base_node_peer(wallet.clone(), args.public_key.into(), args.address).await?; wallet .db - .set_client_key_value(CUSTOM_BASE_NODE_PUBLIC_KEY_KEY.to_string(), public_key.to_string()) - .await?; + .set_client_key_value(CUSTOM_BASE_NODE_PUBLIC_KEY_KEY.to_string(), public_key.to_string())?; wallet .db - .set_client_key_value(CUSTOM_BASE_NODE_ADDRESS_KEY.to_string(), net_address.to_string()) - .await?; + .set_client_key_value(CUSTOM_BASE_NODE_ADDRESS_KEY.to_string(), net_address.to_string())?; println!("Custom base node peer saved in wallet database."); }, ClearCustomBaseNode => { wallet .db - .clear_client_value(CUSTOM_BASE_NODE_PUBLIC_KEY_KEY.to_string()) - .await?; - wallet - .db - .clear_client_value(CUSTOM_BASE_NODE_ADDRESS_KEY.to_string()) - .await?; + .clear_client_value(CUSTOM_BASE_NODE_PUBLIC_KEY_KEY.to_string())?; + wallet.db.clear_client_value(CUSTOM_BASE_NODE_ADDRESS_KEY.to_string())?; println!("Custom base node peer cleared from wallet database."); }, InitShaAtomicSwap(args) => { diff --git a/applications/tari_console_wallet/src/init/mod.rs b/applications/tari_console_wallet/src/init/mod.rs index 5f899416cd..b9f1db92da 100644 --- a/applications/tari_console_wallet/src/init/mod.rs +++ b/applications/tari_console_wallet/src/init/mod.rs @@ -158,7 +158,7 @@ pub async fn get_base_node_peer_config( Some(ref custom) => SeedPeer::from_str(custom) .map(|node| Some(Peer::from(node))) .map_err(|err| ExitError::new(ExitCode::ConfigError, &format!("Malformed custom base node: {}", err)))?, - None => get_custom_base_node_peer_from_db(wallet).await, + None => get_custom_base_node_peer_from_db(wallet), }; // If the user has not explicitly set a base node in the config, we try detect one @@ -181,7 +181,7 @@ pub async fn get_base_node_peer_config( let address = detected_node.addresses.first().ok_or_else(|| { ExitError::new(ExitCode::ConfigError, "No address found for detected base node") })?; - set_custom_base_node_peer_in_db(wallet, &detected_node.public_key, address).await?; + set_custom_base_node_peer_in_db(wallet, &detected_node.public_key, address)?; selected_base_node = Some(detected_node.into()); } }, @@ -293,13 +293,13 @@ pub async fn init_wallet( let node_address = match config.wallet.p2p.public_address.clone() { Some(addr) => addr, - None => match wallet_db.get_node_address().await? { + None => match wallet_db.get_node_address()? { Some(addr) => addr, None => Multiaddr::empty(), }, }; - let master_seed = read_or_create_master_seed(recovery_seed.clone(), &wallet_db).await?; + let master_seed = read_or_create_master_seed(recovery_seed.clone(), &wallet_db)?; let node_identity = match config.wallet.identity_file.as_ref() { Some(identity_file) => { @@ -315,12 +315,12 @@ pub async fn init_wallet( PeerFeatures::COMMUNICATION_CLIENT, )? }, - None => setup_identity_from_db(&wallet_db, &master_seed, node_address.clone()).await?, + None => setup_identity_from_db(&wallet_db, &master_seed, node_address.clone())?, }; let mut wallet_config = config.wallet.clone(); if let TransportType::Tor = config.wallet.p2p.transport.transport_type { - wallet_config.p2p.transport.tor.identity = wallet_db.get_tor_id().await?; + wallet_config.p2p.transport.tor.identity = wallet_db.get_tor_id()?; } let factories = CryptoFactories::default(); @@ -352,7 +352,6 @@ pub async fn init_wallet( wallet .db .set_tor_identity(hs.tor_identity().clone()) - .await .map_err(|e| ExitError::new(ExitCode::WalletError, format!("Problem writing tor identity. {}", e)))?; } @@ -381,7 +380,7 @@ pub async fn init_wallet( debug!(target: LOG_TARGET, "Wallet encrypted."); if interactive && recovery_seed.is_none() { - match confirm_seed_words(&mut wallet).await { + match confirm_seed_words(&mut wallet) { Ok(()) => { print!("\x1Bc"); // Clear the screen }, @@ -392,7 +391,7 @@ pub async fn init_wallet( } } if let Some(file_name) = seed_words_file_name { - let seed_words = wallet.get_seed_words(&MnemonicLanguage::English).await?.join(" "); + let seed_words = wallet.get_seed_words(&MnemonicLanguage::English)?.join(" "); let _result = fs::write(file_name, seed_words).map_err(|e| { ExitError::new( ExitCode::WalletError, @@ -416,17 +415,16 @@ async fn detect_local_base_node() -> Option { Some(SeedPeer::new(public_key, vec![address])) } -async fn setup_identity_from_db( +fn setup_identity_from_db( wallet_db: &WalletDatabase, master_seed: &CipherSeed, node_address: Multiaddr, ) -> Result, ExitError> { let node_features = wallet_db - .get_node_features() - .await? + .get_node_features()? .unwrap_or(PeerFeatures::COMMUNICATION_CLIENT); - let identity_sig = wallet_db.get_comms_identity_signature().await?; + let identity_sig = wallet_db.get_comms_identity_signature()?; let comms_secret_key = derive_comms_secret_key(master_seed)?; @@ -452,7 +450,7 @@ async fn setup_identity_from_db( .as_ref() .expect("unreachable panic") .clone(); - wallet_db.set_comms_identity_signature(sig).await?; + wallet_db.set_comms_identity_signature(sig)?; } Ok(node_identity) @@ -514,8 +512,8 @@ async fn validate_txos(wallet: &mut WalletSqlite) -> Result<(), ExitError> { Ok(()) } -async fn confirm_seed_words(wallet: &mut WalletSqlite) -> Result<(), ExitError> { - let seed_words = wallet.get_seed_words(&MnemonicLanguage::English).await?; +fn confirm_seed_words(wallet: &mut WalletSqlite) -> Result<(), ExitError> { + let seed_words = wallet.get_seed_words(&MnemonicLanguage::English)?; println!(); println!("========================="); diff --git a/applications/tari_console_wallet/src/main.rs b/applications/tari_console_wallet/src/main.rs index d11ee5593a..9eb5479dd8 100644 --- a/applications/tari_console_wallet/src/main.rs +++ b/applications/tari_console_wallet/src/main.rs @@ -167,7 +167,7 @@ fn main_inner() -> Result<(), ExitError> { ))?; // Check if there is an in progress recovery in the wallet's database - if runtime.block_on(wallet.is_recovery_in_progress())? { + if wallet.is_recovery_in_progress()? { println!("A Wallet Recovery was found to be in progress, continuing."); boot_mode = WalletBoot::Recovery; } diff --git a/applications/tari_console_wallet/src/ui/state/app_state.rs b/applications/tari_console_wallet/src/ui/state/app_state.rs index 60ad6c115d..8d3a22b6bd 100644 --- a/applications/tari_console_wallet/src/ui/state/app_state.rs +++ b/applications/tari_console_wallet/src/ui/state/app_state.rs @@ -892,15 +892,11 @@ impl AppStateInner { // persist the custom node in wallet db self.wallet .db - .set_client_key_value(CUSTOM_BASE_NODE_PUBLIC_KEY_KEY.to_string(), peer.public_key.to_string()) - .await?; - self.wallet - .db - .set_client_key_value( - CUSTOM_BASE_NODE_ADDRESS_KEY.to_string(), - peer.addresses.first().ok_or(UiError::NoAddress)?.to_string(), - ) - .await?; + .set_client_key_value(CUSTOM_BASE_NODE_PUBLIC_KEY_KEY.to_string(), peer.public_key.to_string())?; + self.wallet.db.set_client_key_value( + CUSTOM_BASE_NODE_ADDRESS_KEY.to_string(), + peer.addresses.first().ok_or(UiError::NoAddress)?.to_string(), + )?; info!( target: LOG_TARGET, "Setting custom base node peer for wallet: {}::{}", @@ -931,12 +927,10 @@ impl AppStateInner { // clear from wallet db self.wallet .db - .clear_client_value(CUSTOM_BASE_NODE_PUBLIC_KEY_KEY.to_string()) - .await?; + .clear_client_value(CUSTOM_BASE_NODE_PUBLIC_KEY_KEY.to_string())?; self.wallet .db - .clear_client_value(CUSTOM_BASE_NODE_ADDRESS_KEY.to_string()) - .await?; + .clear_client_value(CUSTOM_BASE_NODE_ADDRESS_KEY.to_string())?; Ok(()) } diff --git a/applications/tari_console_wallet/src/utils/db.rs b/applications/tari_console_wallet/src/utils/db.rs index f50d6bc89a..e06bd39d11 100644 --- a/applications/tari_console_wallet/src/utils/db.rs +++ b/applications/tari_console_wallet/src/utils/db.rs @@ -36,11 +36,10 @@ pub const CUSTOM_BASE_NODE_ADDRESS_KEY: &str = "console_wallet_custom_base_node_ /// This helper function will attempt to read a stored base node public key and address from the wallet database. /// If both are found they are used to construct and return a Peer. -pub async fn get_custom_base_node_peer_from_db(wallet: &mut WalletSqlite) -> Option { +pub fn get_custom_base_node_peer_from_db(wallet: &mut WalletSqlite) -> Option { let custom_base_node_peer_pubkey = match wallet .db .get_client_key_value(CUSTOM_BASE_NODE_PUBLIC_KEY_KEY.to_string()) - .await { Ok(val) => val, Err(e) => { @@ -48,11 +47,7 @@ pub async fn get_custom_base_node_peer_from_db(wallet: &mut WalletSqlite) -> Opt return None; }, }; - let custom_base_node_peer_address = match wallet - .db - .get_client_key_value(CUSTOM_BASE_NODE_ADDRESS_KEY.to_string()) - .await - { + let custom_base_node_peer_address = match wallet.db.get_client_key_value(CUSTOM_BASE_NODE_ADDRESS_KEY.to_string()) { Ok(val) => val, Err(e) => { warn!(target: LOG_TARGET, "Problem reading from wallet database: {}", e); @@ -91,23 +86,19 @@ pub async fn get_custom_base_node_peer_from_db(wallet: &mut WalletSqlite) -> Opt } /// Sets the base node peer in the database -pub async fn set_custom_base_node_peer_in_db( +pub fn set_custom_base_node_peer_in_db( wallet: &mut WalletSqlite, base_node_public_key: &CommsPublicKey, base_node_address: &Multiaddr, ) -> Result<(), WalletStorageError> { - wallet - .db - .set_client_key_value( - CUSTOM_BASE_NODE_PUBLIC_KEY_KEY.to_string(), - base_node_public_key.to_hex(), - ) - .await?; + wallet.db.set_client_key_value( + CUSTOM_BASE_NODE_PUBLIC_KEY_KEY.to_string(), + base_node_public_key.to_hex(), + )?; wallet .db - .set_client_key_value(CUSTOM_BASE_NODE_ADDRESS_KEY.to_string(), base_node_address.to_string()) - .await?; + .set_client_key_value(CUSTOM_BASE_NODE_ADDRESS_KEY.to_string(), base_node_address.to_string())?; Ok(()) } diff --git a/applications/tari_console_wallet/src/wallet_modes.rs b/applications/tari_console_wallet/src/wallet_modes.rs index 6d287138b8..775a27254b 100644 --- a/applications/tari_console_wallet/src/wallet_modes.rs +++ b/applications/tari_console_wallet/src/wallet_modes.rs @@ -282,7 +282,7 @@ pub fn tui_mode( let base_node_selected; if let Some(peer) = base_node_config.base_node_custom.clone() { base_node_selected = peer; - } else if let Some(peer) = handle.block_on(get_custom_base_node_peer_from_db(&mut wallet)) { + } else if let Some(peer) = get_custom_base_node_peer_from_db(&mut wallet) { base_node_selected = peer; } else if let Some(peer) = handle.block_on(wallet.get_base_node_peer()) { base_node_selected = peer; diff --git a/base_layer/wallet/src/base_node_service/monitor.rs b/base_layer/wallet/src/base_node_service/monitor.rs index ccb5f401cb..1504797205 100644 --- a/base_layer/wallet/src/base_node_service/monitor.rs +++ b/base_layer/wallet/src/base_node_service/monitor.rs @@ -163,7 +163,7 @@ where timer.elapsed().as_millis() ); - self.db.set_chain_metadata(chain_metadata.clone()).await?; + self.db.set_chain_metadata(chain_metadata.clone())?; let is_synced = tip_info.is_synced; let height_of_longest_chain = chain_metadata.height_of_longest_chain(); diff --git a/base_layer/wallet/src/base_node_service/service.rs b/base_layer/wallet/src/base_node_service/service.rs index bcb94dfa77..cdd8ba0d71 100644 --- a/base_layer/wallet/src/base_node_service/service.rs +++ b/base_layer/wallet/src/base_node_service/service.rs @@ -150,11 +150,11 @@ where T: WalletBackend + 'static "Handling Wallet Base Node Service Request: {:?}", request ); match request { - BaseNodeServiceRequest::GetChainMetadata => match self.get_state().await.chain_metadata.clone() { + BaseNodeServiceRequest::GetChainMetadata => match self.get_state().await.chain_metadata { Some(metadata) => Ok(BaseNodeServiceResponse::ChainMetadata(Some(metadata))), None => { // if we don't have live state, check if we've previously stored state in the wallet db - let metadata = self.db.get_chain_metadata().await?; + let metadata = self.db.get_chain_metadata()?; Ok(BaseNodeServiceResponse::ChainMetadata(metadata)) }, }, diff --git a/base_layer/wallet/src/storage/database.rs b/base_layer/wallet/src/storage/database.rs index 9c870e7f0e..1ff079243e 100644 --- a/base_layer/wallet/src/storage/database.rs +++ b/base_layer/wallet/src/storage/database.rs @@ -121,218 +121,143 @@ where T: WalletBackend + 'static Self { db: Arc::new(db) } } - pub async fn get_master_seed(&self) -> Result, WalletStorageError> { - let db_clone = self.db.clone(); - - let c = tokio::task::spawn_blocking(move || match db_clone.fetch(&DbKey::MasterSeed) { + pub fn get_master_seed(&self) -> Result, WalletStorageError> { + let c = match self.db.fetch(&DbKey::MasterSeed) { Ok(None) => Ok(None), Ok(Some(DbValue::MasterSeed(k))) => Ok(Some(k)), Ok(Some(other)) => unexpected_result(DbKey::MasterSeed, other), Err(e) => log_error(DbKey::MasterSeed, e), - }) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + }?; Ok(c) } - pub async fn set_master_seed(&self, seed: CipherSeed) -> Result<(), WalletStorageError> { - let db_clone = self.db.clone(); - - tokio::task::spawn_blocking(move || db_clone.write(WriteOperation::Insert(DbKeyValuePair::MasterSeed(seed)))) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + pub fn set_master_seed(&self, seed: CipherSeed) -> Result<(), WalletStorageError> { + self.db + .write(WriteOperation::Insert(DbKeyValuePair::MasterSeed(seed)))?; Ok(()) } - pub async fn clear_master_seed(&self) -> Result<(), WalletStorageError> { - let db_clone = self.db.clone(); - tokio::task::spawn_blocking(move || db_clone.write(WriteOperation::Remove(DbKey::MasterSeed))) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + pub fn clear_master_seed(&self) -> Result<(), WalletStorageError> { + self.db.write(WriteOperation::Remove(DbKey::MasterSeed))?; Ok(()) } - pub async fn get_tor_id(&self) -> Result, WalletStorageError> { - let db_clone = self.db.clone(); - - let c = tokio::task::spawn_blocking(move || match db_clone.fetch(&DbKey::TorId) { + pub fn get_tor_id(&self) -> Result, WalletStorageError> { + let c = match self.db.fetch(&DbKey::TorId) { Ok(None) => Ok(None), Ok(Some(DbValue::TorId(k))) => Ok(Some(k)), Ok(Some(other)) => unexpected_result(DbKey::TorId, other), Err(e) => log_error(DbKey::TorId, e), - }) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + }?; Ok(c) } - pub async fn set_tor_identity(&self, id: TorIdentity) -> Result<(), WalletStorageError> { - let db_clone = self.db.clone(); - - tokio::task::spawn_blocking(move || db_clone.write(WriteOperation::Insert(DbKeyValuePair::TorId(id)))) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + pub fn set_tor_identity(&self, id: TorIdentity) -> Result<(), WalletStorageError> { + self.db.write(WriteOperation::Insert(DbKeyValuePair::TorId(id)))?; Ok(()) } - pub async fn get_node_address(&self) -> Result, WalletStorageError> { - let db_clone = self.db.clone(); - - let c = tokio::task::spawn_blocking(move || match db_clone.fetch(&DbKey::CommsAddress) { + pub fn get_node_address(&self) -> Result, WalletStorageError> { + let c = match self.db.fetch(&DbKey::CommsAddress) { Ok(None) => Ok(None), Ok(Some(DbValue::CommsAddress(k))) => Ok(Some(k)), Ok(Some(other)) => unexpected_result(DbKey::CommsAddress, other), Err(e) => log_error(DbKey::CommsAddress, e), - }) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + }?; Ok(c) } - pub async fn set_node_address(&self, address: Multiaddr) -> Result<(), WalletStorageError> { - let db_clone = self.db.clone(); - - tokio::task::spawn_blocking(move || { - db_clone.write(WriteOperation::Insert(DbKeyValuePair::CommsAddress(address))) - }) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + pub fn set_node_address(&self, address: Multiaddr) -> Result<(), WalletStorageError> { + self.db + .write(WriteOperation::Insert(DbKeyValuePair::CommsAddress(address)))?; Ok(()) } - pub async fn get_node_features(&self) -> Result, WalletStorageError> { - let db_clone = self.db.clone(); - - let c = tokio::task::spawn_blocking(move || match db_clone.fetch(&DbKey::CommsFeatures) { + pub fn get_node_features(&self) -> Result, WalletStorageError> { + let c = match self.db.fetch(&DbKey::CommsFeatures) { Ok(None) => Ok(None), Ok(Some(DbValue::CommsFeatures(k))) => Ok(Some(k)), Ok(Some(other)) => unexpected_result(DbKey::CommsFeatures, other), Err(e) => log_error(DbKey::CommsFeatures, e), - }) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + }?; Ok(c) } - pub async fn set_node_features(&self, features: PeerFeatures) -> Result<(), WalletStorageError> { - let db_clone = self.db.clone(); - - tokio::task::spawn_blocking(move || { - db_clone.write(WriteOperation::Insert(DbKeyValuePair::CommsFeatures(features))) - }) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + pub fn set_node_features(&self, features: PeerFeatures) -> Result<(), WalletStorageError> { + self.db + .write(WriteOperation::Insert(DbKeyValuePair::CommsFeatures(features)))?; Ok(()) } - pub async fn get_comms_identity_signature(&self) -> Result, WalletStorageError> { - let db = self.db.clone(); - - let sig = tokio::task::spawn_blocking(move || match db.fetch(&DbKey::CommsIdentitySignature) { + pub fn get_comms_identity_signature(&self) -> Result, WalletStorageError> { + let sig = match self.db.fetch(&DbKey::CommsIdentitySignature) { Ok(None) => Ok(None), Ok(Some(DbValue::CommsIdentitySignature(k))) => Ok(Some(*k)), Ok(Some(other)) => unexpected_result(DbKey::CommsIdentitySignature, other), Err(e) => log_error(DbKey::CommsIdentitySignature, e), - }) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + }?; Ok(sig) } - pub async fn set_comms_identity_signature(&self, sig: IdentitySignature) -> Result<(), WalletStorageError> { - let db = self.db.clone(); - - tokio::task::spawn_blocking(move || { - db.write(WriteOperation::Insert(DbKeyValuePair::CommsIdentitySignature( + pub fn set_comms_identity_signature(&self, sig: IdentitySignature) -> Result<(), WalletStorageError> { + self.db + .write(WriteOperation::Insert(DbKeyValuePair::CommsIdentitySignature( Box::new(sig), - ))) - }) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + )))?; Ok(()) } - pub async fn get_chain_metadata(&self) -> Result, WalletStorageError> { - let db_clone = self.db.clone(); - - let c = tokio::task::spawn_blocking(move || match db_clone.fetch(&DbKey::BaseNodeChainMetadata) { + pub fn get_chain_metadata(&self) -> Result, WalletStorageError> { + let c = match self.db.fetch(&DbKey::BaseNodeChainMetadata) { Ok(None) => Ok(None), Ok(Some(DbValue::BaseNodeChainMetadata(metadata))) => Ok(Some(metadata)), Ok(Some(other)) => unexpected_result(DbKey::BaseNodeChainMetadata, other), Err(e) => log_error(DbKey::BaseNodeChainMetadata, e), - }) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + }?; Ok(c) } - pub async fn set_chain_metadata(&self, metadata: ChainMetadata) -> Result<(), WalletStorageError> { - let db_clone = self.db.clone(); - - tokio::task::spawn_blocking(move || { - db_clone.write(WriteOperation::Insert(DbKeyValuePair::BaseNodeChainMetadata(metadata))) - }) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + pub fn set_chain_metadata(&self, metadata: ChainMetadata) -> Result<(), WalletStorageError> { + self.db + .write(WriteOperation::Insert(DbKeyValuePair::BaseNodeChainMetadata(metadata)))?; Ok(()) } - pub async fn apply_encryption(&self, passphrase: SafePassword) -> Result { - let db_clone = self.db.clone(); - tokio::task::spawn_blocking(move || db_clone.apply_encryption(passphrase)) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string())) - .and_then(|inner_result| inner_result) + pub fn apply_encryption(&self, passphrase: SafePassword) -> Result { + self.db.apply_encryption(passphrase) } - pub async fn remove_encryption(&self) -> Result<(), WalletStorageError> { - let db_clone = self.db.clone(); - tokio::task::spawn_blocking(move || db_clone.remove_encryption()) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string())) - .and_then(|inner_result| inner_result) + pub fn remove_encryption(&self) -> Result<(), WalletStorageError> { + self.db.remove_encryption() } - pub async fn set_client_key_value(&self, key: String, value: String) -> Result<(), WalletStorageError> { - let db_clone = self.db.clone(); - - tokio::task::spawn_blocking(move || { - db_clone.write(WriteOperation::Insert(DbKeyValuePair::ClientKeyValue(key, value))) - }) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + pub fn set_client_key_value(&self, key: String, value: String) -> Result<(), WalletStorageError> { + self.db + .write(WriteOperation::Insert(DbKeyValuePair::ClientKeyValue(key, value)))?; Ok(()) } - pub async fn get_client_key_value(&self, key: String) -> Result, WalletStorageError> { - let db_clone = self.db.clone(); - - let c = tokio::task::spawn_blocking(move || match db_clone.fetch(&DbKey::ClientKey(key.clone())) { + pub fn get_client_key_value(&self, key: String) -> Result, WalletStorageError> { + let c = match self.db.fetch(&DbKey::ClientKey(key.clone())) { Ok(None) => Ok(None), Ok(Some(DbValue::ClientValue(k))) => Ok(Some(k)), Ok(Some(other)) => unexpected_result(DbKey::ClientKey(key), other), Err(e) => log_error(DbKey::ClientKey(key), e), - }) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + }?; Ok(c) } - pub async fn get_client_key_from_str(&self, key: String) -> Result, WalletStorageError> + pub fn get_client_key_from_str(&self, key: String) -> Result, WalletStorageError> where V: std::str::FromStr, V::Err: ToString, { - let db = self.db.clone(); - - let value = tokio::task::spawn_blocking(move || match db.fetch(&DbKey::ClientKey(key.clone())) { + let value = match self.db.fetch(&DbKey::ClientKey(key.clone())) { Ok(None) => Ok(None), Ok(Some(DbValue::ClientValue(k))) => Ok(Some(k)), Ok(Some(other)) => unexpected_result(DbKey::ClientKey(key), other), Err(e) => log_error(DbKey::ClientKey(key), e), - }) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + }?; match value { Some(c) => { @@ -343,89 +268,54 @@ where T: WalletBackend + 'static } } - pub async fn clear_client_value(&self, key: String) -> Result { - let db_clone = self.db.clone(); - - let c = tokio::task::spawn_blocking(move || { - match db_clone.write(WriteOperation::Remove(DbKey::ClientKey(key.clone()))) { - Ok(None) => Ok(false), - Ok(Some(DbValue::ValueCleared)) => Ok(true), - Ok(Some(other)) => unexpected_result(DbKey::ClientKey(key), other), - Err(e) => log_error(DbKey::ClientKey(key), e), - } - }) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + pub fn clear_client_value(&self, key: String) -> Result { + let c = match self.db.write(WriteOperation::Remove(DbKey::ClientKey(key.clone()))) { + Ok(None) => Ok(false), + Ok(Some(DbValue::ValueCleared)) => Ok(true), + Ok(Some(other)) => unexpected_result(DbKey::ClientKey(key), other), + Err(e) => log_error(DbKey::ClientKey(key), e), + }?; Ok(c) } - pub async fn get_wallet_birthday(&self) -> Result { - let db_clone = self.db.clone(); - - let result = tokio::task::spawn_blocking(move || match db_clone.fetch(&DbKey::WalletBirthday) { + pub fn get_wallet_birthday(&self) -> Result { + let result = match self.db.fetch(&DbKey::WalletBirthday) { Ok(None) => Err(WalletStorageError::ValueNotFound(DbKey::WalletBirthday)), Ok(Some(DbValue::WalletBirthday(b))) => Ok(b .parse::() .map_err(|_| WalletStorageError::ConversionError("Could not parse wallet birthday".to_string()))?), Ok(Some(other)) => unexpected_result(DbKey::WalletBirthday, other), Err(e) => log_error(DbKey::WalletBirthday, e), - }) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; + }?; Ok(result) } - pub async fn get_scanned_blocks(&self) -> Result, WalletStorageError> { - let db_clone = self.db.clone(); - - let result = tokio::task::spawn_blocking(move || db_clone.get_scanned_blocks()) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; - + pub fn get_scanned_blocks(&self) -> Result, WalletStorageError> { + let result = self.db.get_scanned_blocks()?; Ok(result) } - pub async fn save_scanned_block(&self, scanned_block: ScannedBlock) -> Result<(), WalletStorageError> { - let db_clone = self.db.clone(); - - tokio::task::spawn_blocking(move || db_clone.save_scanned_block(scanned_block)) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; - + pub fn save_scanned_block(&self, scanned_block: ScannedBlock) -> Result<(), WalletStorageError> { + self.db.save_scanned_block(scanned_block)?; Ok(()) } - pub async fn clear_scanned_blocks(&self) -> Result<(), WalletStorageError> { - let db_clone = self.db.clone(); - - tokio::task::spawn_blocking(move || db_clone.clear_scanned_blocks()) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; - + pub fn clear_scanned_blocks(&self) -> Result<(), WalletStorageError> { + self.db.clear_scanned_blocks()?; Ok(()) } - pub async fn clear_scanned_blocks_from_and_higher(&self, height: u64) -> Result<(), WalletStorageError> { - let db_clone = self.db.clone(); - - tokio::task::spawn_blocking(move || db_clone.clear_scanned_blocks_from_and_higher(height)) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; - + pub fn clear_scanned_blocks_from_and_higher(&self, height: u64) -> Result<(), WalletStorageError> { + self.db.clear_scanned_blocks_from_and_higher(height)?; Ok(()) } - pub async fn clear_scanned_blocks_before_height( + pub fn clear_scanned_blocks_before_height( &self, height: u64, exclude_recovered: bool, ) -> Result<(), WalletStorageError> { - let db_clone = self.db.clone(); - - tokio::task::spawn_blocking(move || db_clone.clear_scanned_blocks_before_height(height, exclude_recovered)) - .await - .map_err(|err| WalletStorageError::BlockingTaskSpawnError(err.to_string()))??; - + self.db.clear_scanned_blocks_before_height(height, exclude_recovered)?; Ok(()) } } @@ -486,7 +376,6 @@ mod test { use tari_key_manager::cipher_seed::CipherSeed; use tari_test_utils::random::string; use tempfile::tempdir; - use tokio::runtime::Runtime; use crate::storage::{ database::WalletDatabase, @@ -496,8 +385,6 @@ mod test { #[test] fn test_database_crud() { - let runtime = Runtime::new().unwrap(); - let db_name = format!("{}.sqlite3", string(8).as_str()); let db_folder = tempdir().unwrap().path().to_str().unwrap().to_string(); let connection = run_migration_and_create_sqlite_connection(&format!("{}{}", db_folder, db_name), 16).unwrap(); @@ -505,13 +392,13 @@ mod test { let db = WalletDatabase::new(WalletSqliteDatabase::new(connection, None).unwrap()); // Test wallet settings - assert!(runtime.block_on(db.get_master_seed()).unwrap().is_none()); + assert!(db.get_master_seed().unwrap().is_none()); let seed = CipherSeed::new(); - runtime.block_on(db.set_master_seed(seed.clone())).unwrap(); - let stored_seed = runtime.block_on(db.get_master_seed()).unwrap().unwrap(); + db.set_master_seed(seed.clone()).unwrap(); + let stored_seed = db.get_master_seed().unwrap().unwrap(); assert_eq!(seed, stored_seed); - runtime.block_on(db.clear_master_seed()).unwrap(); - assert!(runtime.block_on(db.get_master_seed()).unwrap().is_none()); + db.clear_master_seed().unwrap(); + assert!(db.get_master_seed().unwrap().is_none()); let client_key_values = vec![ ("key1".to_string(), "value1".to_string()), @@ -520,36 +407,25 @@ mod test { ]; for kv in &client_key_values { - runtime - .block_on(db.set_client_key_value(kv.0.clone(), kv.1.clone())) - .unwrap(); + db.set_client_key_value(kv.0.clone(), kv.1.clone()).unwrap(); } - assert!(runtime - .block_on(db.get_client_key_value("wrong".to_string())) - .unwrap() - .is_none()); + assert!(db.get_client_key_value("wrong".to_string()).unwrap().is_none()); - runtime - .block_on(db.set_client_key_value(client_key_values[0].0.clone(), "updated".to_string())) + db.set_client_key_value(client_key_values[0].0.clone(), "updated".to_string()) .unwrap(); assert_eq!( - runtime - .block_on(db.get_client_key_value(client_key_values[0].0.clone())) + db.get_client_key_value(client_key_values[0].0.clone()) .unwrap() .unwrap(), "updated".to_string() ); - assert!(!runtime.block_on(db.clear_client_value("wrong".to_string())).unwrap()); + assert!(!db.clear_client_value("wrong".to_string()).unwrap()); - assert!(runtime - .block_on(db.clear_client_value(client_key_values[0].0.clone())) - .unwrap()); + assert!(db.clear_client_value(client_key_values[0].0.clone()).unwrap()); - assert!(!runtime - .block_on(db.clear_client_value(client_key_values[0].0.clone())) - .unwrap()); + assert!(!db.clear_client_value(client_key_values[0].0.clone()).unwrap()); } } diff --git a/base_layer/wallet/src/storage/sqlite_utilities/mod.rs b/base_layer/wallet/src/storage/sqlite_utilities/mod.rs index 9802aa13c7..06984ced8d 100644 --- a/base_layer/wallet/src/storage/sqlite_utilities/mod.rs +++ b/base_layer/wallet/src/storage/sqlite_utilities/mod.rs @@ -71,7 +71,7 @@ pub fn run_migration_and_create_sqlite_connection>( /// This function will copy a wallet database to the provided path and then clear the Master Private Key from the /// database. -pub async fn partial_wallet_backup>(current_db: P, backup_path: P) -> Result<(), WalletStorageError> { +pub fn partial_wallet_backup>(current_db: P, backup_path: P) -> Result<(), WalletStorageError> { // Copy the current db to the backup path let db_path = current_db .as_ref() @@ -87,7 +87,7 @@ pub async fn partial_wallet_backup>(current_db: P, backup_path: P // open a connection and clear the Master Secret Key let connection = run_migration_and_create_sqlite_connection(backup_path, 16)?; let db = WalletDatabase::new(WalletSqliteDatabase::new(connection, None)?); - db.clear_master_seed().await?; + db.clear_master_seed()?; Ok(()) } diff --git a/base_layer/wallet/src/transaction_service/service.rs b/base_layer/wallet/src/transaction_service/service.rs index 6e57e4c8c6..f121570858 100644 --- a/base_layer/wallet/src/transaction_service/service.rs +++ b/base_layer/wallet/src/transaction_service/service.rs @@ -856,7 +856,7 @@ where if let OutputManagerEvent::TxoValidationSuccess(_) = (*event).clone() { let db = self.db.clone(); let output_manager_handle = self.output_manager_service.clone(); - let metadata = match self.wallet_db.get_chain_metadata().await { + let metadata = match self.wallet_db.get_chain_metadata() { Ok(data) => data, Err(_) => None, }; @@ -1498,7 +1498,7 @@ where recipient_reply: proto::RecipientSignedMessage, ) -> Result<(), TransactionServiceError> { // Check if a wallet recovery is in progress, if it is we will ignore this request - self.check_recovery_status().await?; + self.check_recovery_status()?; let recipient_reply: RecipientSignedMessage = recipient_reply .try_into() @@ -1827,7 +1827,7 @@ where join_handles: &mut FuturesUnordered>>>, ) -> Result<(), TransactionServiceError> { // Check if a wallet recovery is in progress, if it is we will ignore this request - self.check_recovery_status().await?; + self.check_recovery_status()?; let sender_message: TransactionSenderMessage = sender_message .try_into() @@ -1955,7 +1955,7 @@ where join_handles: &mut FuturesUnordered>>>, ) -> Result<(), TransactionServiceError> { // Check if a wallet recovery is in progress, if it is we will ignore this request - self.check_recovery_status().await?; + self.check_recovery_status()?; let tx_id = finalized_transaction.tx_id.into(); let transaction: Transaction = finalized_transaction @@ -2575,8 +2575,8 @@ where /// Check if a Recovery Status is currently stored in the databse, this indicates that a wallet recovery is in /// progress - async fn check_recovery_status(&self) -> Result<(), TransactionServiceError> { - let value = self.wallet_db.get_client_key_value(RECOVERY_KEY.to_owned()).await?; + fn check_recovery_status(&self) -> Result<(), TransactionServiceError> { + let value = self.wallet_db.get_client_key_value(RECOVERY_KEY.to_owned())?; match value { None => Ok(()), Some(_) => Err(TransactionServiceError::WalletRecoveryInProgress), diff --git a/base_layer/wallet/src/utxo_scanner_service/utxo_scanner_task.rs b/base_layer/wallet/src/utxo_scanner_service/utxo_scanner_task.rs index 2d9ceb9c65..0b576ab551 100644 --- a/base_layer/wallet/src/utxo_scanner_service/utxo_scanner_task.rs +++ b/base_layer/wallet/src/utxo_scanner_service/utxo_scanner_task.rs @@ -78,9 +78,9 @@ where TBackend: WalletBackend + 'static { pub async fn run(mut self) -> Result<(), UtxoScannerError> { if self.mode == UtxoScannerMode::Recovery { - self.set_recovery_mode().await?; + self.set_recovery_mode()?; } else { - let in_progress = self.check_recovery_mode().await?; + let in_progress = self.check_recovery_mode()?; if in_progress { warn!( target: LOG_TARGET, @@ -98,8 +98,7 @@ where TBackend: WalletBackend + 'static Some(peer) => match self.attempt_sync(peer.clone()).await { Ok((num_outputs_recovered, final_height, final_amount, elapsed)) => { debug!(target: LOG_TARGET, "Scanned to height #{}", final_height); - self.finalize(num_outputs_recovered, final_height, final_amount, elapsed) - .await?; + self.finalize(num_outputs_recovered, final_height, final_amount, elapsed)?; return Ok(()); }, Err(e) => { @@ -139,7 +138,7 @@ where TBackend: WalletBackend + 'static } } - async fn finalize( + fn finalize( &self, num_outputs_recovered: u64, final_height: u64, @@ -159,7 +158,7 @@ where TBackend: WalletBackend + 'static // Presence of scanning keys are used to determine if a wallet is busy with recovery or not. if self.mode == UtxoScannerMode::Recovery { - self.clear_recovery_mode().await?; + self.clear_recovery_mode()?; } Ok(()) } @@ -243,7 +242,7 @@ where TBackend: WalletBackend + 'static } else { // The node does not know of any of our cached headers so we will start the scan anew from the // wallet birthday - self.resources.db.clear_scanned_blocks().await?; + self.resources.db.clear_scanned_blocks()?; let birthday_height_hash = self.get_birthday_header_height_hash(&mut client).await?; ScannedBlock { @@ -314,7 +313,7 @@ where TBackend: WalletBackend + 'static current_tip_height: u64, client: &mut BaseNodeWalletRpcClient, ) -> Result, UtxoScannerError> { - let scanned_blocks = self.resources.db.get_scanned_blocks().await?; + let scanned_blocks = self.resources.db.get_scanned_blocks()?; debug!( target: LOG_TARGET, "Found {} cached previously scanned blocks", @@ -376,10 +375,7 @@ where TBackend: WalletBackend + 'static target: LOG_TARGET, "Reorg detected on base node. Removing scanned blocks from height {}", block.height ); - self.resources - .db - .clear_scanned_blocks_from_and_higher(block.height) - .await?; + self.resources.db.clear_scanned_blocks_from_and_higher(block.height)?; } if let Some(sb) = found_scanned_block { @@ -466,21 +462,17 @@ where TBackend: WalletBackend + 'static .import_utxos_to_transaction_service(found_outputs, current_height, mined_timestamp) .await?; let block_hash = current_header_hash.try_into()?; - self.resources - .db - .save_scanned_block(ScannedBlock { - header_hash: block_hash, - height: current_height, - num_outputs: Some(count), - amount: Some(amount), - timestamp: Utc::now().naive_utc(), - }) - .await?; + self.resources.db.save_scanned_block(ScannedBlock { + header_hash: block_hash, + height: current_height, + num_outputs: Some(count), + amount: Some(amount), + timestamp: Utc::now().naive_utc(), + })?; self.resources .db - .clear_scanned_blocks_before_height(current_height.saturating_sub(SCANNED_BLOCK_CACHE_SIZE), true) - .await?; + .clear_scanned_blocks_before_height(current_height.saturating_sub(SCANNED_BLOCK_CACHE_SIZE), true)?; if current_height % PROGRESS_REPORT_INTERVAL == 0 { debug!( @@ -600,25 +592,23 @@ where TBackend: WalletBackend + 'static Ok((num_recovered, total_amount)) } - async fn set_recovery_mode(&self) -> Result<(), UtxoScannerError> { + fn set_recovery_mode(&self) -> Result<(), UtxoScannerError> { self.resources .db - .set_client_key_value(RECOVERY_KEY.to_owned(), Utc::now().to_string()) - .await?; + .set_client_key_value(RECOVERY_KEY.to_owned(), Utc::now().to_string())?; Ok(()) } - async fn check_recovery_mode(&self) -> Result { + fn check_recovery_mode(&self) -> Result { self.resources .db .get_client_key_from_str::(RECOVERY_KEY.to_owned()) - .await .map(|x| x.is_some()) .map_err(UtxoScannerError::from) // in case if `get_client_key_from_str` returns not exactly that type } - async fn clear_recovery_mode(&self) -> Result<(), UtxoScannerError> { - let _ = self.resources.db.clear_client_value(RECOVERY_KEY.to_owned()).await?; + fn clear_recovery_mode(&self) -> Result<(), UtxoScannerError> { + let _ = self.resources.db.clear_client_value(RECOVERY_KEY.to_owned())?; Ok(()) } @@ -676,7 +666,7 @@ where TBackend: WalletBackend + 'static &self, client: &mut BaseNodeWalletRpcClient, ) -> Result { - let birthday = self.resources.db.get_wallet_birthday().await?; + let birthday = self.resources.db.get_wallet_birthday()?; // Calculate the unix epoch time of two days before the wallet birthday. This is to avoid any weird time zone // issues let epoch_time = u64::from(birthday.saturating_sub(2)) * 60 * 60 * 24; diff --git a/base_layer/wallet/src/wallet.rs b/base_layer/wallet/src/wallet.rs index 80bb177614..a027e57b22 100644 --- a/base_layer/wallet/src/wallet.rs +++ b/base_layer/wallet/src/wallet.rs @@ -267,15 +267,11 @@ where // Persist the comms node address and features after it has been spawned to capture any modifications made // during comms startup. In the case of a Tor Transport the public address could have been generated - wallet_database - .set_node_address(comms.node_identity().public_address()) - .await?; - wallet_database - .set_node_features(comms.node_identity().features()) - .await?; + wallet_database.set_node_address(comms.node_identity().public_address())?; + wallet_database.set_node_features(comms.node_identity().features())?; let identity_sig = comms.node_identity().identity_signature_read().as_ref().cloned(); if let Some(identity_sig) = identity_sig { - wallet_database.set_comms_identity_signature(identity_sig).await?; + wallet_database.set_comms_identity_signature(identity_sig)?; } Ok(Self { @@ -678,7 +674,7 @@ where /// in which case this will fail. pub async fn apply_encryption(&mut self, passphrase: SafePassword) -> Result<(), WalletError> { debug!(target: LOG_TARGET, "Applying wallet encryption."); - let cipher = self.db.apply_encryption(passphrase).await?; + let cipher = self.db.apply_encryption(passphrase)?; self.output_manager_service.apply_encryption(cipher.clone()).await?; self.transaction_service.apply_encryption(cipher.clone()).await?; self.key_manager_service.apply_encryption(cipher).await?; @@ -691,18 +687,18 @@ where self.output_manager_service.remove_encryption().await?; self.transaction_service.remove_encryption().await?; self.key_manager_service.remove_encryption().await?; - self.db.remove_encryption().await?; + self.db.remove_encryption()?; Ok(()) } /// Utility function to find out if there is data in the database indicating that there is an incomplete recovery /// process in progress - pub async fn is_recovery_in_progress(&self) -> Result { - Ok(self.db.get_client_key_value(RECOVERY_KEY.to_string()).await?.is_some()) + pub fn is_recovery_in_progress(&self) -> Result { + Ok(self.db.get_client_key_value(RECOVERY_KEY.to_string())?.is_some()) } - pub async fn get_seed_words(&self, language: &MnemonicLanguage) -> Result, WalletError> { - let master_seed = self.db.get_master_seed().await?.ok_or_else(|| { + pub fn get_seed_words(&self, language: &MnemonicLanguage) -> Result, WalletError> { + let master_seed = self.db.get_master_seed()?.ok_or_else(|| { WalletError::WalletStorageError(WalletStorageError::RecoverySeedError( "Cipher Seed not found".to_string(), )) @@ -713,24 +709,24 @@ where } } -pub async fn read_or_create_master_seed( +pub fn read_or_create_master_seed( recovery_seed: Option, db: &WalletDatabase, ) -> Result { - let db_master_seed = db.get_master_seed().await?; + let db_master_seed = db.get_master_seed()?; let master_seed = match recovery_seed { None => match db_master_seed { None => { let seed = CipherSeed::new(); - db.set_master_seed(seed.clone()).await?; + db.set_master_seed(seed.clone())?; seed }, Some(seed) => seed, }, Some(recovery_seed) => { if db_master_seed.is_none() { - db.set_master_seed(recovery_seed.clone()).await?; + db.set_master_seed(recovery_seed.clone())?; recovery_seed } else { error!( diff --git a/base_layer/wallet/tests/transaction_service_tests/service.rs b/base_layer/wallet/tests/transaction_service_tests/service.rs index 16de95db39..2554f8de15 100644 --- a/base_layer/wallet/tests/transaction_service_tests/service.rs +++ b/base_layer/wallet/tests/transaction_service_tests/service.rs @@ -182,7 +182,7 @@ async fn setup_transaction_service>( let db = WalletDatabase::new(WalletSqliteDatabase::new(db_connection.clone(), None).unwrap()); let metadata = ChainMetadata::new(std::i64::MAX as u64, FixedHash::zero(), 0, 0, 0, 0); - db.set_chain_metadata(metadata).await.unwrap(); + db.set_chain_metadata(metadata).unwrap(); let ts_backend = TransactionServiceSqliteDatabase::new(db_connection.clone(), None); let oms_backend = OutputManagerSqliteDatabase::new(db_connection.clone(), None); @@ -3142,7 +3142,7 @@ async fn test_coinbase_transactions_rejection_same_hash_but_accept_on_same_heigh .get_completed_transactions() .await .unwrap(); // Only one valid coinbase txn remains - assert_eq!(transactions.len(), 1); + assert_eq!(transactions.len(), 2); let _tx_id2 = transactions .values() .find(|tx| tx.amount == fees2 + reward2) @@ -3169,7 +3169,7 @@ async fn test_coinbase_transactions_rejection_same_hash_but_accept_on_same_heigh .get_completed_transactions() .await .unwrap(); - assert_eq!(transactions.len(), 2); + assert_eq!(transactions.len(), 3); let _tx_id3 = transactions .values() .find(|tx| tx.amount == fees3 + reward3) @@ -3185,7 +3185,7 @@ async fn test_coinbase_transactions_rejection_same_hash_but_accept_on_same_heigh fees1 + reward1 + fees2 + reward2 + fees3 + reward3 ); - assert!(!transactions.values().any(|tx| tx.amount == fees1 + reward1)); + assert!(transactions.values().any(|tx| tx.amount == fees1 + reward1)); assert!(transactions.values().any(|tx| tx.amount == fees2 + reward2)); assert!(transactions.values().any(|tx| tx.amount == fees3 + reward3)); } @@ -3278,7 +3278,7 @@ async fn test_coinbase_generation_and_monitoring() { .get_completed_transactions() .await .unwrap(); - assert_eq!(transactions.len(), 2); + assert_eq!(transactions.len(), 3); let tx_id2b = transactions .values() .find(|tx| tx.amount == fees2b + reward2) @@ -3396,7 +3396,7 @@ async fn test_coinbase_generation_and_monitoring() { .await .unwrap(); - assert_eq!(completed_txs.len(), 2); + assert_eq!(completed_txs.len(), 3); let tx = completed_txs.get(&tx_id1).unwrap(); assert_eq!(tx.status, TransactionStatus::Coinbase); @@ -3436,7 +3436,8 @@ async fn test_coinbase_generation_and_monitoring() { let _tx_batch_query_calls = alice_ts_interface .base_node_rpc_mock_state - .wait_pop_transaction_batch_query_calls(1, Duration::from_secs(30)) + // TODO: This is a flaky test; changing the pop count = 3 below makes the test fail often + .wait_pop_transaction_batch_query_calls(2, Duration::from_secs(30)) .await .unwrap(); diff --git a/base_layer/wallet/tests/utxo_scanner.rs b/base_layer/wallet/tests/utxo_scanner.rs index dcef38d99e..38d26c93e5 100644 --- a/base_layer/wallet/tests/utxo_scanner.rs +++ b/base_layer/wallet/tests/utxo_scanner.rs @@ -289,7 +289,7 @@ async fn test_utxo_scanner_recovery() { let cipher_seed = CipherSeed::new(); let birthday_epoch_time = u64::from(cipher_seed.birthday() - 2) * 60 * 60 * 24; - test_interface.wallet_db.set_master_seed(cipher_seed).await.unwrap(); + test_interface.wallet_db.set_master_seed(cipher_seed).unwrap(); const NUM_BLOCKS: u64 = 11; const BIRTHDAY_OFFSET: u64 = 5; @@ -372,7 +372,7 @@ async fn test_utxo_scanner_recovery_with_restart() { let cipher_seed = CipherSeed::new(); let birthday_epoch_time = u64::from(cipher_seed.birthday() - 2) * 60 * 60 * 24; - test_interface.wallet_db.set_master_seed(cipher_seed).await.unwrap(); + test_interface.wallet_db.set_master_seed(cipher_seed).unwrap(); test_interface .scanner_handle @@ -536,7 +536,7 @@ async fn test_utxo_scanner_recovery_with_restart_and_reorg() { let cipher_seed = CipherSeed::new(); let birthday_epoch_time = u64::from(cipher_seed.birthday() - 2) * 60 * 60 * 24; - test_interface.wallet_db.set_master_seed(cipher_seed).await.unwrap(); + test_interface.wallet_db.set_master_seed(cipher_seed).unwrap(); const NUM_BLOCKS: u64 = 11; const BIRTHDAY_OFFSET: u64 = 5; @@ -700,13 +700,12 @@ async fn test_utxo_scanner_scanned_block_cache_clearing() { .checked_sub_signed(ChronoDuration::days(1000)) .unwrap(), }) - .await .unwrap(); } let cipher_seed = CipherSeed::new(); let birthday_epoch_time = u64::from(cipher_seed.birthday() - 2) * 60 * 60 * 24; - test_interface.wallet_db.set_master_seed(cipher_seed).await.unwrap(); + test_interface.wallet_db.set_master_seed(cipher_seed).unwrap(); const NUM_BLOCKS: u64 = 11; const BIRTHDAY_OFFSET: u64 = 5; @@ -751,7 +750,6 @@ async fn test_utxo_scanner_scanned_block_cache_clearing() { amount: None, timestamp: Utc::now().naive_utc(), }) - .await .unwrap(); let mut scanner_event_stream = test_interface.scanner_handle.get_event_receiver(); @@ -776,7 +774,7 @@ async fn test_utxo_scanner_scanned_block_cache_clearing() { } } } - let scanned_blocks = test_interface.wallet_db.get_scanned_blocks().await.unwrap(); + let scanned_blocks = test_interface.wallet_db.get_scanned_blocks().unwrap(); use tari_wallet::utxo_scanner_service::service::SCANNED_BLOCK_CACHE_SIZE; let threshold = 800 + NUM_BLOCKS - 1 - SCANNED_BLOCK_CACHE_SIZE; @@ -809,7 +807,7 @@ async fn test_utxo_scanner_one_sided_payments() { let cipher_seed = CipherSeed::new(); let birthday_epoch_time = u64::from(cipher_seed.birthday() - 2) * 60 * 60 * 24; - test_interface.wallet_db.set_master_seed(cipher_seed).await.unwrap(); + test_interface.wallet_db.set_master_seed(cipher_seed).unwrap(); const NUM_BLOCKS: u64 = 11; const BIRTHDAY_OFFSET: u64 = 5; diff --git a/base_layer/wallet/tests/wallet.rs b/base_layer/wallet/tests/wallet.rs index 5a6147eb44..e75d5dd0f9 100644 --- a/base_layer/wallet/tests/wallet.rs +++ b/base_layer/wallet/tests/wallet.rs @@ -175,7 +175,7 @@ async fn create_wallet( let _db_value = wallet_backend.write(WriteOperation::Insert(DbKeyValuePair::BaseNodeChainMetadata(metadata))); let wallet_db = WalletDatabase::new(wallet_backend); - let master_seed = read_or_create_master_seed(recovery_seed, &wallet_db).await?; + let master_seed = read_or_create_master_seed(recovery_seed, &wallet_db)?; let output_db = OutputManagerDatabase::new(output_manager_backend.clone()); @@ -401,19 +401,17 @@ async fn test_wallet() { let alice_seed = CipherSeed::new(); - alice_wallet.db.set_master_seed(alice_seed).await.unwrap(); + alice_wallet.db.set_master_seed(alice_seed).unwrap(); shutdown_a.trigger(); alice_wallet.wait_until_shutdown().await; - partial_wallet_backup(current_wallet_path.clone(), backup_wallet_path.clone()) - .await - .unwrap(); + partial_wallet_backup(current_wallet_path.clone(), backup_wallet_path.clone()).unwrap(); let connection = run_migration_and_create_sqlite_connection(¤t_wallet_path, 16).expect("Could not open Sqlite db"); let wallet_db = WalletDatabase::new(WalletSqliteDatabase::new(connection.clone(), None).unwrap()); - let master_seed = wallet_db.get_master_seed().await.unwrap(); + let master_seed = wallet_db.get_master_seed().unwrap(); assert!(master_seed.is_some()); // Checking that the backup has had its Comms Private Key is cleared. let connection = run_migration_and_create_sqlite_connection(&backup_wallet_path, 16).expect( @@ -421,7 +419,7 @@ async fn test_wallet() { db", ); let backup_wallet_db = WalletDatabase::new(WalletSqliteDatabase::new(connection.clone(), None).unwrap()); - let master_seed = backup_wallet_db.get_master_seed().await.unwrap(); + let master_seed = backup_wallet_db.get_master_seed().unwrap(); assert!(master_seed.is_none()); shutdown_b.trigger(); @@ -811,7 +809,7 @@ async fn test_recovery_birthday() { .await .unwrap(); - let db_birthday = wallet.db.get_wallet_birthday().await.unwrap(); + let db_birthday = wallet.db.get_wallet_birthday().unwrap(); assert_eq!(birthday, db_birthday); } diff --git a/base_layer/wallet_ffi/src/lib.rs b/base_layer/wallet_ffi/src/lib.rs index 579187881d..69091c759b 100644 --- a/base_layer/wallet_ffi/src/lib.rs +++ b/base_layer/wallet_ffi/src/lib.rs @@ -4285,23 +4285,21 @@ pub unsafe extern "C" fn wallet_create( // If the transport type is Tor then check if there is a stored TorID, if there is update the Transport Type let mut comms_config = (*config).clone(); if let TransportType::Tor = comms_config.transport.transport_type { - comms_config.transport.tor.identity = runtime.block_on(wallet_database.get_tor_id()).ok().flatten(); + comms_config.transport.tor.identity = wallet_database.get_tor_id().ok().flatten(); } let result = runtime.block_on(async { let master_seed = read_or_create_master_seed(recovery_seed, &wallet_database) - .await .map_err(|err| WalletStorageError::RecoverySeedError(err.to_string()))?; let comms_secret_key = derive_comms_secret_key(&master_seed) .map_err(|err| WalletStorageError::RecoverySeedError(err.to_string()))?; - let node_features = wallet_database.get_node_features().await?.unwrap_or_default(); + let node_features = wallet_database.get_node_features()?.unwrap_or_default(); let node_address = wallet_database - .get_node_address() - .await? + .get_node_address()? .or_else(|| comms_config.public_address.clone()) .unwrap_or_else(Multiaddr::empty); - let identity_sig = wallet_database.get_comms_identity_signature().await?; + let identity_sig = wallet_database.get_comms_identity_signature()?; // This checks if anything has changed by validating the previous signature and if invalid, setting identity_sig // to None @@ -4325,7 +4323,7 @@ pub unsafe extern "C" fn wallet_create( .as_ref() .expect("unreachable panic") .clone(); - wallet_database.set_comms_identity_signature(sig).await?; + wallet_database.set_comms_identity_signature(sig)?; } Ok((master_seed, node_identity)) }); @@ -4351,7 +4349,7 @@ pub unsafe extern "C" fn wallet_create( ..Default::default() }; - let mut recovery_lookup = match runtime.block_on(wallet_database.get_client_key_value(RECOVERY_KEY.to_owned())) { + let mut recovery_lookup = match wallet_database.get_client_key_value(RECOVERY_KEY.to_owned()) { Err(_) => false, Ok(None) => false, Ok(Some(_)) => true, @@ -4386,7 +4384,7 @@ pub unsafe extern "C" fn wallet_create( Ok(mut w) => { // lets ensure the wallet tor_id is saved, this could have been changed during wallet startup if let Some(hs) = w.comms.hidden_service() { - if let Err(e) = runtime.block_on(w.db.set_tor_identity(hs.tor_identity().clone())) { + if let Err(e) = w.db.set_tor_identity(hs.tor_identity().clone()) { warn!(target: LOG_TARGET, "Could not save tor identity to db: {:?}", e); } } @@ -6655,10 +6653,7 @@ pub unsafe extern "C" fn wallet_get_seed_words(wallet: *mut TariWallet, error_ou return ptr::null_mut(); } - match (*wallet) - .runtime - .block_on((*wallet).wallet.get_seed_words(&MnemonicLanguage::English)) - { + match (*wallet).wallet.get_seed_words(&MnemonicLanguage::English) { Ok(seed_words) => Box::into_raw(Box::new(TariSeedWords(seed_words))), Err(e) => { error = LibWalletError::from(e).code; @@ -6857,10 +6852,7 @@ pub unsafe extern "C" fn wallet_set_key_value( } } - match (*wallet) - .runtime - .block_on((*wallet).wallet.db.set_client_key_value(key_string, value_string)) - { + match (*wallet).wallet.db.set_client_key_value(key_string, value_string) { Ok(_) => true, Err(e) => { error = LibWalletError::from(WalletError::WalletStorageError(e)).code; @@ -6917,10 +6909,7 @@ pub unsafe extern "C" fn wallet_get_value( } } - match (*wallet) - .runtime - .block_on((*wallet).wallet.db.get_client_key_value(key_string)) - { + match (*wallet).wallet.db.get_client_key_value(key_string) { Ok(result) => match result { None => { error = LibWalletError::from(WalletError::WalletStorageError(WalletStorageError::ValuesNotFound)).code; @@ -6987,10 +6976,7 @@ pub unsafe extern "C" fn wallet_clear_value( } } - match (*wallet) - .runtime - .block_on((*wallet).wallet.db.clear_client_value(key_string)) - { + match (*wallet).wallet.db.clear_client_value(key_string) { Ok(result) => result, Err(e) => { error = LibWalletError::from(WalletError::WalletStorageError(e)).code; @@ -7024,7 +7010,7 @@ pub unsafe extern "C" fn wallet_is_recovery_in_progress(wallet: *mut TariWallet, return false; } - match (*wallet).runtime.block_on((*wallet).wallet.is_recovery_in_progress()) { + match (*wallet).wallet.is_recovery_in_progress() { Ok(result) => result, Err(e) => { error = LibWalletError::from(e).code; @@ -7257,17 +7243,10 @@ pub unsafe extern "C" fn file_partial_backup( } let backup_path = PathBuf::from(backup_path_string); - let runtime = Runtime::new(); - match runtime { - Ok(runtime) => match runtime.block_on(partial_wallet_backup(original_path, backup_path)) { - Ok(_) => (), - Err(e) => { - error = LibWalletError::from(WalletError::WalletStorageError(e)).code; - ptr::swap(error_out, &mut error as *mut c_int); - }, - }, + match partial_wallet_backup(original_path, backup_path) { + Ok(_) => (), Err(e) => { - error = LibWalletError::from(InterfaceError::TokioError(e.to_string())).code; + error = LibWalletError::from(WalletError::WalletStorageError(e)).code; ptr::swap(error_out, &mut error as *mut c_int); }, } @@ -8511,13 +8490,11 @@ mod test { error_ptr, ); - let runtime = Runtime::new().unwrap(); - let connection = run_migration_and_create_sqlite_connection(&sql_database_path, 16).expect("Could not open Sqlite db"); let wallet_backend = WalletDatabase::new(WalletSqliteDatabase::new(connection, None).unwrap()); - let stored_seed = runtime.block_on(wallet_backend.get_master_seed()).unwrap(); + let stored_seed = wallet_backend.get_master_seed().unwrap(); drop(wallet_backend); assert!(stored_seed.is_none(), "No key should be stored yet"); @@ -8556,7 +8533,7 @@ mod test { run_migration_and_create_sqlite_connection(&sql_database_path, 16).expect("Could not open Sqlite db"); let wallet_backend = WalletDatabase::new(WalletSqliteDatabase::new(connection, None).unwrap()); - let stored_seed1 = runtime.block_on(wallet_backend.get_master_seed()).unwrap().unwrap(); + let stored_seed1 = wallet_backend.get_master_seed().unwrap().unwrap(); drop(wallet_backend); @@ -8597,7 +8574,7 @@ mod test { run_migration_and_create_sqlite_connection(&sql_database_path, 16).expect("Could not open Sqlite db"); let wallet_backend = WalletDatabase::new(WalletSqliteDatabase::new(connection, None).unwrap()); - let stored_seed2 = runtime.block_on(wallet_backend.get_master_seed()).unwrap().unwrap(); + let stored_seed2 = wallet_backend.get_master_seed().unwrap().unwrap(); assert_eq!(stored_seed1, stored_seed2); @@ -8616,7 +8593,7 @@ mod test { run_migration_and_create_sqlite_connection(&sql_database_path, 16).expect("Could not open Sqlite db"); let wallet_backend = WalletDatabase::new(WalletSqliteDatabase::new(connection, None).unwrap()); - let stored_seed = runtime.block_on(wallet_backend.get_master_seed()).unwrap(); + let stored_seed = wallet_backend.get_master_seed().unwrap(); assert!(stored_seed.is_none(), "key should be cleared"); drop(wallet_backend); From 842c933334996ac56fb99f71879b539620c52d5d Mon Sep 17 00:00:00 2001 From: Hansie Odendaal <39146854+hansieodendaal@users.noreply.github.com> Date: Thu, 1 Sep 2022 08:57:10 +0200 Subject: [PATCH 10/12] fix latent transaction service unit test errors (#4595) Description --- Fixed latent transaction service unit test errors Motivation and Context --- Some failing tests due to recent coinbase handling logic changes: ``` failures: ---- transaction_service_tests::service::test_coinbase_transaction_reused_for_same_height stdout ---- thread 'transaction_service_tests::service::test_coinbase_transaction_reused_for_same_height' panicked at 'assertion failed: `(left == right)` left: `2`, right: `1`', base_layer/wallet/tests/transaction_service_tests/service.rs:3968:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ---- transaction_service_tests::service::test_coinbase_generation_and_monitoring stdout ---- thread 'transaction_service_tests::service::test_coinbase_generation_and_monitoring' panicked at 'assertion failed: `(left == right)` left: `Coinbase`, right: `MinedUnconfirmed`', base_layer/wallet/tests/transaction_service_tests/service.rs:3405:5 ---- transaction_service_tests::service::test_transaction_resending stdout ---- thread 'transaction_service_tests::service::test_transaction_resending' panicked at 'assertion failed: alice_ts_interface.outbound_service_mock_state.wait_call_count(1,\n Duration::from_secs(5)).await.is_err()', base_layer/wallet/tests/transaction_service_tests/service.rs:4181:5 failures: transaction_service_tests::service::test_coinbase_generation_and_monitoring transaction_service_tests::service::test_coinbase_transaction_reused_for_same_height transaction_service_tests::service::test_transaction_resending test result: FAILED. 39 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 107.87s ``` How Has This Been Tested? --- Failing uni tests passed --- .../transaction_service_tests/service.rs | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/base_layer/wallet/tests/transaction_service_tests/service.rs b/base_layer/wallet/tests/transaction_service_tests/service.rs index 2554f8de15..df9dcf37ad 100644 --- a/base_layer/wallet/tests/transaction_service_tests/service.rs +++ b/base_layer/wallet/tests/transaction_service_tests/service.rs @@ -3386,7 +3386,7 @@ async fn test_coinbase_generation_and_monitoring() { let _tx_batch_query_calls = alice_ts_interface .base_node_rpc_mock_state - .wait_pop_transaction_batch_query_calls(1, Duration::from_secs(30)) + .wait_pop_transaction_batch_query_calls(2, Duration::from_secs(30)) .await .unwrap(); @@ -3937,10 +3937,13 @@ async fn test_coinbase_transaction_reused_for_same_height() { .await .unwrap(); + let expected_pending_incoming_balance = fees1 + reward1; assert_eq!(transactions.len(), 1); + let mut amount = MicroTari::zero(); for tx in transactions.values() { - assert_eq!(tx.amount, fees1 + reward1); + amount += tx.amount; } + assert_eq!(amount, expected_pending_incoming_balance); // balance should be fees1 + reward1, not double assert_eq!( ts_interface @@ -3949,7 +3952,7 @@ async fn test_coinbase_transaction_reused_for_same_height() { .await .unwrap() .pending_incoming_balance, - fees1 + reward1 + expected_pending_incoming_balance ); // a requested coinbase transaction for the same height but new amount should be different @@ -3965,10 +3968,13 @@ async fn test_coinbase_transaction_reused_for_same_height() { .get_completed_transactions() .await .unwrap(); - assert_eq!(transactions.len(), 1); // tx1 and tx2 should be cancelled + let expected_pending_incoming_balance = fees1 + reward1 + fees2 + reward2; + assert_eq!(transactions.len(), 2); + let mut amount = MicroTari::zero(); for tx in transactions.values() { - assert_eq!(tx.amount, fees2 + reward2); + amount += tx.amount; } + assert_eq!(amount, expected_pending_incoming_balance); assert_eq!( ts_interface .output_manager_service_handle @@ -3976,7 +3982,7 @@ async fn test_coinbase_transaction_reused_for_same_height() { .await .unwrap() .pending_incoming_balance, - fees1 + reward1 + fees2 + reward2 + expected_pending_incoming_balance ); // a requested coinbase transaction for a new height should be different @@ -3992,10 +3998,13 @@ async fn test_coinbase_transaction_reused_for_same_height() { .get_completed_transactions() .await .unwrap(); - assert_eq!(transactions.len(), 2); + let expected_pending_incoming_balance = fees1 + reward1 + 2 * (fees2 + reward2); + assert_eq!(transactions.len(), 3); + let mut amount = MicroTari::zero(); for tx in transactions.values() { - assert_eq!(tx.amount, fees2 + reward2); + amount += tx.amount; } + assert_eq!(amount, expected_pending_incoming_balance); assert_eq!( ts_interface .output_manager_service_handle @@ -4003,7 +4012,7 @@ async fn test_coinbase_transaction_reused_for_same_height() { .await .unwrap() .pending_incoming_balance, - fees1 + reward1 + 2 * (fees2 + reward2) + expected_pending_incoming_balance ); } @@ -4180,7 +4189,7 @@ async fn test_transaction_resending() { assert!(alice_ts_interface .outbound_service_mock_state - .wait_call_count(1, Duration::from_secs(5)) + .wait_call_count(1, Duration::from_secs(8)) .await .is_err()); From 66c80327db77a26f8370bc7bd972b8d5abcaf619 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Thu, 1 Sep 2022 09:05:36 +0200 Subject: [PATCH 11/12] fix: cleanup logs (#4590) Description --- Both wallets submit transactions. This means that for every tx created at least 1 warn!(target: LOG_TARGET, "Validation failed due to unknown inputs" will be created. This reduces the log level for this so that it does not popup by default. --- base_layer/core/src/mempool/mempool_storage.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base_layer/core/src/mempool/mempool_storage.rs b/base_layer/core/src/mempool/mempool_storage.rs index 168d2fe3e7..9fbe293060 100644 --- a/base_layer/core/src/mempool/mempool_storage.rs +++ b/base_layer/core/src/mempool/mempool_storage.rs @@ -96,12 +96,12 @@ impl MempoolStorage { self.unconfirmed_pool.insert(tx, Some(dependent_outputs), &weight)?; Ok(TxStorageResponse::UnconfirmedPool) } else { - warn!(target: LOG_TARGET, "Validation failed due to unknown inputs"); + debug!(target: LOG_TARGET, "Validation failed due to unknown inputs"); Ok(TxStorageResponse::NotStoredOrphan) } }, Err(ValidationError::ContainsSTxO) => { - warn!(target: LOG_TARGET, "Validation failed due to already spent output"); + debug!(target: LOG_TARGET, "Validation failed due to already spent output"); Ok(TxStorageResponse::NotStoredAlreadySpent) }, Err(ValidationError::MaturityError) => { From 004c219643ae42c0c1afcdb835542e53b581bfa3 Mon Sep 17 00:00:00 2001 From: jorgeantonio21 Date: Thu, 1 Sep 2022 11:49:22 +0100 Subject: [PATCH 12/12] fix: add Grpc authentication to merge mining proxy (see issue #4587) (#4592) Description --- It is desirable that the Merge mining proxy has a GRPC authenticated wallet client connection. Motivation and Context --- Contrary to the Mining wallet client connection, the merge mining proxy does not have GRPC authentication currently. This issue aims to add it to GRPC auth in the merge mining proxy. Fixes https://github.com/tari-project/tari/issues/4587. How Has This Been Tested? --- Existing unit tests --- Cargo.lock | 1 + .../tari_merge_mining_proxy/Cargo.toml | 1 + .../src/block_template_protocol.rs | 10 ++++--- .../tari_merge_mining_proxy/src/config.rs | 4 +++ .../tari_merge_mining_proxy/src/error.rs | 7 ++++- .../tari_merge_mining_proxy/src/main.rs | 27 +++++++++++++++++-- .../tari_merge_mining_proxy/src/proxy.rs | 5 ++-- .../config/presets/f_merge_mining_proxy.toml | 3 +++ 8 files changed, 50 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 86694d42ee..6717ff4a2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5133,6 +5133,7 @@ dependencies = [ "tari_app_grpc", "tari_app_utilities", "tari_common", + "tari_common_types", "tari_comms", "tari_core", "tari_crypto", diff --git a/applications/tari_merge_mining_proxy/Cargo.toml b/applications/tari_merge_mining_proxy/Cargo.toml index 72c6a0fb8d..ea22b06b8a 100644 --- a/applications/tari_merge_mining_proxy/Cargo.toml +++ b/applications/tari_merge_mining_proxy/Cargo.toml @@ -14,6 +14,7 @@ envlog = ["env_logger"] [dependencies] tari_app_grpc = { path = "../tari_app_grpc" } tari_common = { path = "../../common" } +tari_common_types = { path = "../../base_layer/common_types" } tari_comms = { path = "../../comms/core" } tari_core = { path = "../../base_layer/core", default-features = false, features = ["transactions"] } tari_app_utilities = { path = "../tari_app_utilities" } diff --git a/applications/tari_merge_mining_proxy/src/block_template_protocol.rs b/applications/tari_merge_mining_proxy/src/block_template_protocol.rs index 29a48e6f2f..d7ccc67a6e 100644 --- a/applications/tari_merge_mining_proxy/src/block_template_protocol.rs +++ b/applications/tari_merge_mining_proxy/src/block_template_protocol.rs @@ -25,7 +25,7 @@ use std::cmp; use log::*; -use tari_app_grpc::tari_rpc as grpc; +use tari_app_grpc::{authentication::ClientAuthenticationInterceptor, tari_rpc as grpc}; use tari_core::proof_of_work::{monero_rx, monero_rx::FixedByteArray, Difficulty}; use crate::{ @@ -39,13 +39,17 @@ const LOG_TARGET: &str = "tari_mm_proxy::proxy::block_template_protocol"; /// Structure holding grpc connections. pub struct BlockTemplateProtocol<'a> { base_node_client: &'a mut grpc::base_node_client::BaseNodeClient, - wallet_client: &'a mut grpc::wallet_client::WalletClient, + wallet_client: &'a mut grpc::wallet_client::WalletClient< + tonic::codegen::InterceptedService, + >, } impl<'a> BlockTemplateProtocol<'a> { pub fn new( base_node_client: &'a mut grpc::base_node_client::BaseNodeClient, - wallet_client: &'a mut grpc::wallet_client::WalletClient, + wallet_client: &'a mut grpc::wallet_client::WalletClient< + tonic::codegen::InterceptedService, + >, ) -> Self { Self { base_node_client, diff --git a/applications/tari_merge_mining_proxy/src/config.rs b/applications/tari_merge_mining_proxy/src/config.rs index 23549aab1e..0bffda2fa9 100644 --- a/applications/tari_merge_mining_proxy/src/config.rs +++ b/applications/tari_merge_mining_proxy/src/config.rs @@ -22,6 +22,7 @@ use serde::{Deserialize, Serialize}; use tari_common::{configuration::StringList, SubConfigPath}; +use tari_common_types::grpc_authentication::GrpcAuthentication; use tari_comms::multiaddr::Multiaddr; #[derive(Clone, Debug, Deserialize, Serialize)] @@ -41,6 +42,8 @@ pub struct MergeMiningProxyConfig { pub base_node_grpc_address: Multiaddr, /// The Tari console wallet's GRPC address pub console_wallet_grpc_address: Multiaddr, + /// GRPC authentication for console wallet + pub console_wallet_grpc_authentication: GrpcAuthentication, /// Address of the tari_merge_mining_proxy application pub listener_address: Multiaddr, /// In sole merged mining, the block solution is usually submitted to the Monero blockchain (monerod) as well as to @@ -69,6 +72,7 @@ impl Default for MergeMiningProxyConfig { monerod_use_auth: false, base_node_grpc_address: "/ip4/127.0.0.1/tcp/18142".parse().unwrap(), console_wallet_grpc_address: "/ip4/127.0.0.1/tcp/18143".parse().unwrap(), + console_wallet_grpc_authentication: GrpcAuthentication::default(), listener_address: "/ip4/127.0.0.1/tcp/18081".parse().unwrap(), submit_to_origin: true, wait_for_initial_sync_at_startup: true, diff --git a/applications/tari_merge_mining_proxy/src/error.rs b/applications/tari_merge_mining_proxy/src/error.rs index 92fc25651c..0d308d3bf4 100644 --- a/applications/tari_merge_mining_proxy/src/error.rs +++ b/applications/tari_merge_mining_proxy/src/error.rs @@ -26,10 +26,11 @@ use std::io; use hex::FromHexError; use hyper::header::InvalidHeaderValue; +use tari_app_grpc::authentication::BasicAuthError; use tari_common::{ConfigError, ConfigurationError}; use tari_core::{proof_of_work::monero_rx::MergeMineError, transactions::CoinbaseBuildError}; use thiserror::Error; -use tonic::transport; +use tonic::{codegen::http::uri::InvalidUri, transport}; #[derive(Debug, Error)] pub enum MmProxyError { @@ -42,6 +43,8 @@ pub enum MmProxyError { #[from] source: MergeMineError, }, + #[error("Invalid URI: {0}")] + InvalidUriError(#[from] InvalidUri), #[error("Reqwest error: {0}")] ReqwestError(#[from] reqwest::Error), #[error("Missing data:{0}")] @@ -50,6 +53,8 @@ pub enum MmProxyError { IoError(#[from] io::Error), #[error("Tonic transport error: {0}")] TonicTransportError(#[from] transport::Error), + #[error("Grpc authentication error: {0}")] + GRPCAuthenticationError(#[from] BasicAuthError), #[error("GRPC response did not contain the expected field: `{0}`")] GrpcResponseMissingField(&'static str), #[error("Hyper error: {0}")] diff --git a/applications/tari_merge_mining_proxy/src/main.rs b/applications/tari_merge_mining_proxy/src/main.rs index bb5ea7992d..a58230850d 100644 --- a/applications/tari_merge_mining_proxy/src/main.rs +++ b/applications/tari_merge_mining_proxy/src/main.rs @@ -34,6 +34,7 @@ mod test; use std::{ convert::Infallible, io::{stdout, Write}, + str::FromStr, }; use clap::Parser; @@ -42,12 +43,16 @@ use futures::future; use hyper::{service::make_service_fn, Server}; use log::*; use proxy::MergeMiningProxyService; -use tari_app_grpc::tari_rpc as grpc; +use tari_app_grpc::{authentication::ClientAuthenticationInterceptor, tari_rpc as grpc}; use tari_app_utilities::consts; use tari_common::{initialize_logging, load_configuration, DefaultConfigLoader}; use tari_comms::utils::multiaddr::multiaddr_to_socketaddr; use tari_core::proof_of_work::randomx_factory::RandomXFactory; use tokio::time::Duration; +use tonic::{ + codegen::InterceptedService, + transport::{Channel, Endpoint}, +}; use crate::{ block_template_data::BlockTemplateRepository, @@ -57,6 +62,24 @@ use crate::{ }; const LOG_TARGET: &str = "tari_mm_proxy::proxy"; +pub(crate) type WalletGrpcClient = + grpc::wallet_client::WalletClient>; + +async fn connect_wallet_with_authenticator(config: &MergeMiningProxyConfig) -> Result { + let wallet_addr = format!( + "http://{}", + multiaddr_to_socketaddr(&config.console_wallet_grpc_address)? + ); + info!(target: LOG_TARGET, "👛 Connecting to wallet at {}", wallet_addr); + let channel = Endpoint::from_str(&wallet_addr)?.connect().await?; + let wallet_conn = grpc::wallet_client::WalletClient::with_interceptor( + channel, + ClientAuthenticationInterceptor::create(&config.console_wallet_grpc_authentication)?, + ); + + Ok(wallet_conn) +} + #[tokio::main] async fn main() -> Result<(), anyhow::Error> { let terminal_title = format!("Tari Merge Mining Proxy - Version {}", consts::APP_VERSION); @@ -90,7 +113,7 @@ async fn main() -> Result<(), anyhow::Error> { let wallet = multiaddr_to_socketaddr(&config.console_wallet_grpc_address)?; info!(target: LOG_TARGET, "Connecting to wallet at {}", wallet); println!("Connecting to wallet at {}", wallet); - let wallet_client = grpc::wallet_client::WalletClient::connect(format!("http://{}", wallet)).await?; + let wallet_client = connect_wallet_with_authenticator(&config).await?; let listen_addr = multiaddr_to_socketaddr(&config.listener_address)?; let randomx_factory = RandomXFactory::new(config.max_randomx_vms); let xmrig_service = MergeMiningProxyService::new( diff --git a/applications/tari_merge_mining_proxy/src/proxy.rs b/applications/tari_merge_mining_proxy/src/proxy.rs index e67c7fbd76..667cb21320 100644 --- a/applications/tari_merge_mining_proxy/src/proxy.rs +++ b/applications/tari_merge_mining_proxy/src/proxy.rs @@ -54,6 +54,7 @@ use crate::{ common::{json_rpc, monero_rpc::CoreRpcErrorCode, proxy, proxy::convert_json_to_hyper_json_response}, config::MergeMiningProxyConfig, error::MmProxyError, + WalletGrpcClient, }; const LOG_TARGET: &str = "tari_mm_proxy::proxy"; @@ -72,7 +73,7 @@ impl MergeMiningProxyService { config: MergeMiningProxyConfig, http_client: reqwest::Client, base_node_client: grpc::base_node_client::BaseNodeClient, - wallet_client: grpc::wallet_client::WalletClient, + wallet_client: WalletGrpcClient, block_templates: BlockTemplateRepository, randomx_factory: RandomXFactory, ) -> Self { @@ -154,7 +155,7 @@ struct InnerService { block_templates: BlockTemplateRepository, http_client: reqwest::Client, base_node_client: grpc::base_node_client::BaseNodeClient, - wallet_client: grpc::wallet_client::WalletClient, + wallet_client: WalletGrpcClient, initial_sync_achieved: Arc, current_monerod_server: Arc>>, last_assigned_monerod_server: Arc>>, diff --git a/common/config/presets/f_merge_mining_proxy.toml b/common/config/presets/f_merge_mining_proxy.toml index 17935f2129..52bab71161 100644 --- a/common/config/presets/f_merge_mining_proxy.toml +++ b/common/config/presets/f_merge_mining_proxy.toml @@ -42,6 +42,9 @@ monerod_url = [# stagenet # The Tari console wallet's GRPC address. (default = "/ip4/127.0.0.1/tcp/18143") #console_wallet_grpc_address = "/ip4/127.0.0.1/tcp/18143" +# GRPC authentication for the Tari console wallet (default = "none") +#wallet_grpc_authentication = { username: "miner", password: "$argon..." } + # Address of the tari_merge_mining_proxy application. (default = "/ip4/127.0.0.1/tcp/18081") #listener_address = "/ip4/127.0.0.1/tcp/18081"