From 7f47d39f9964dcf37fad84d92c4fba121296b591 Mon Sep 17 00:00:00 2001 From: Mike the Tike Date: Mon, 18 Oct 2021 11:02:26 +0200 Subject: [PATCH 1/2] test: simplify cucumber tests (#3457) Description --- * removed cucumber 'I expect all transactions to succeed' steps * better logging of warnings * added default profile for cucumber tests Motivation and Context --- I wanted to remove long running tests from someone who runs a default `npm test` or `run-tests.sh`. Also, there was a number of times where the base node would stall not output, while generating many warnings in the logs. This would cause circle ci to eventually kill it with "too long with no output". This looks like the problem was a bad block template getting created. How Has This Been Tested? --- npm test --- .circleci/config.yml | 4 +- integration_tests/cucumber.js | 4 +- integration_tests/features/Mempool.feature | 1 - integration_tests/features/Reorgs.feature | 2 - integration_tests/features/Sync.feature | 3 +- .../features/WalletMonitoring.feature | 1 - .../features/WalletTransactions.feature | 2 - integration_tests/features/support/steps.js | 18 +--- integration_tests/features/support/world.js | 37 ++++---- integration_tests/log4rs/base_node.yml | 92 +++++++++---------- 10 files changed, 70 insertions(+), 94 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index af2c0a0d9b..f57cac5b56 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -129,7 +129,7 @@ commands: - run: name: Run cucumber scenarios no_output_timeout: 20m - command: cd integration_tests && mkdir -p cucumber_output && node_modules/.bin/cucumber-js --tags "not @long-running and not @broken and not @wallet-ffi" --format json:cucumber_output/tests.cucumber --exit --retry 2 --retryTagFilter "@flaky and not @broken" + command: cd integration_tests && mkdir -p cucumber_output && node_modules/.bin/cucumber-js --profile "ci" --tags "not @long-running and not @broken and not @wallet-ffi" --format json:cucumber_output/tests.cucumber --exit --retry 2 --retryTagFilter "@flaky and not @broken" - run: name: Generate report command: cd integration_tests && node ./generate_report.js @@ -137,7 +137,7 @@ commands: # Below step requires NodeJS v12 to run correctly, see explanation in WalletFFI.feature - run: name: Run FFI wallet library cucumber scenarios - command: cd integration_tests && mkdir -p cucumber_output && node_modules/.bin/cucumber-js --tags "not @long-running and not @broken and not @flaky and @wallet-ffi" --format json:cucumber_output/tests_ffi.cucumber --exit + command: cd integration_tests && mkdir -p cucumber_output && node_modules/.bin/cucumber-js --profile "ci" --tags "not @long-running and not @broken and not @flaky and @wallet-ffi" --format json:cucumber_output/tests_ffi.cucumber --exit when: always - run: name: Generate report (ffi) diff --git a/integration_tests/cucumber.js b/integration_tests/cucumber.js index 988c7217a3..ed54e8a506 100644 --- a/integration_tests/cucumber.js +++ b/integration_tests/cucumber.js @@ -1,4 +1,6 @@ module.exports = { - default: "", + default: + "--tags 'not @long-running and not @wallet-ffi and not @broken' --fail-fast", + ci: " ", critical: "--format @cucumber/pretty-formatter --tags @critical", }; diff --git a/integration_tests/features/Mempool.feature b/integration_tests/features/Mempool.feature index 1e13586097..2365be2ae8 100644 --- a/integration_tests/features/Mempool.feature +++ b/integration_tests/features/Mempool.feature @@ -98,7 +98,6 @@ Feature: Mempool @critical @flaky Scenario: Mempool clearing out invalid transactions after a reorg - Given I do not expect all automated transactions to succeed Given I have a seed node SEED_A And I have a base node NODE_A connected to seed SEED_A When I mine a block on NODE_A with coinbase CB_A diff --git a/integration_tests/features/Reorgs.feature b/integration_tests/features/Reorgs.feature index 1303ce5610..34338bc6d2 100644 --- a/integration_tests/features/Reorgs.feature +++ b/integration_tests/features/Reorgs.feature @@ -96,7 +96,6 @@ Feature: Reorgs @critical @reorg Scenario: Zero-conf reorg with spending - Given I do not expect all automated transactions to succeed Given I have a base node NODE1 connected to all seed nodes Given I have a base node NODE2 connected to node NODE1 When I mine 14 blocks on NODE1 @@ -143,7 +142,6 @@ Feature: Reorgs # Chain 1a: # Mine X1 blocks (orphan_storage_capacity default set to 10) # - Given I do not expect all automated transactions to succeed Given I have a seed node SEED_A1 # Add multiple base nodes to ensure more robust comms And I have a base node NODE_A1 connected to seed SEED_A1 diff --git a/integration_tests/features/Sync.feature b/integration_tests/features/Sync.feature index 089492a467..224c868873 100644 --- a/integration_tests/features/Sync.feature +++ b/integration_tests/features/Sync.feature @@ -75,7 +75,6 @@ Feature: Block Sync When I stop node NODE1 Given I have a base node NODE2 connected to node PNODE1 Given I have a pruned node PNODE2 connected to node PNODE1 with pruning horizon set to 5 - Given I do not expect all automated transactions to succeed When I mine 5 blocks on NODE2 Then node NODE2 is at height 5 Then node PNODE2 is at height 40 @@ -84,8 +83,8 @@ Feature: Block Sync And I connect node NODE2 to node NODE1 and wait 1 seconds # NODE2 may initially try to sync from PNODE1 and PNODE2, then eventually try to sync from NODE1; mining blocks # on NODE1 will make this test less flaky and force NODE2 to sync from NODE1 much quicker - Given I expect all automated transactions to succeed When I mine 10 blocks on NODE1 + Then all transactions must have succeeded Then all nodes are at height 50 Scenario Outline: Syncing node while also mining before tip sync diff --git a/integration_tests/features/WalletMonitoring.feature b/integration_tests/features/WalletMonitoring.feature index bba4738b99..48c664fd34 100644 --- a/integration_tests/features/WalletMonitoring.feature +++ b/integration_tests/features/WalletMonitoring.feature @@ -51,7 +51,6 @@ Feature: Wallet Monitoring # 18+ mins on circle ci @long-running Scenario: Wallets monitoring normal transactions after a reorg - Given I do not expect all automated transactions to succeed # # Chain 1: # Collects 10 coinbases into one wallet, send 7 transactions diff --git a/integration_tests/features/WalletTransactions.feature b/integration_tests/features/WalletTransactions.feature index 79994176ef..fc75f4bc1a 100644 --- a/integration_tests/features/WalletTransactions.feature +++ b/integration_tests/features/WalletTransactions.feature @@ -183,7 +183,6 @@ Feature: Wallet Transactions # Collects 7 coinbases into one wallet, send 7 transactions # Stronger chain # - Given I do not expect all automated transactions to succeed Given I have a seed node SEED_A And I have a base node NODE_A1 connected to seed SEED_A And I have wallet WALLET_A1 connected to seed node SEED_A @@ -238,7 +237,6 @@ Feature: Wallet Transactions # Collects 7 coinbases into one wallet, send 7 transactions # Stronger chain # - Given I do not expect all automated transactions to succeed Given I have a seed node SEED_A And I have a base node NODE_A1 connected to seed SEED_A And I have wallet WALLET_A1 connected to seed node SEED_A diff --git a/integration_tests/features/support/steps.js b/integration_tests/features/support/steps.js index cb69cd0738..7ba479aa51 100644 --- a/integration_tests/features/support/steps.js +++ b/integration_tests/features/support/steps.js @@ -39,21 +39,9 @@ Given("I have {int} seed nodes", { timeout: 20 * 1000 }, async function (n) { await Promise.all(promises); }); -Given( - /I do not expect all automated transactions to succeed/, - { timeout: 20 * 1000 }, - async function () { - this.checkAutoTransactions = false; - } -); - -Given( - /I expect all automated transactions to succeed/, - { timeout: 20 * 1000 }, - async function () { - this.checkAutoTransactions = true; - } -); +Then(/all transactions must have succeeded/, function () { + expect(this.lastTransactionsSucceeded).to.be(true); +}); Given( /I have a base node (.*) connected to all seed nodes/, diff --git a/integration_tests/features/support/world.js b/integration_tests/features/support/world.js index 801b35d591..97100cfccf 100644 --- a/integration_tests/features/support/world.js +++ b/integration_tests/features/support/world.js @@ -16,7 +16,6 @@ class CustomWorld { constructor({ attach, parameters }) { // this.variable = 0; this.attach = attach; - this.checkAutoTransactions = true; this.seeds = {}; this.nodes = {}; this.proxies = {}; @@ -139,44 +138,37 @@ class CustomWorld { } async createTransactions(name, height) { + this.lastTransactionsSucceeded = true; let result = true; const txInputs = this.transactionOutputs[height]; if (txInputs == null) { return result; } - // This function is called from steps with timeout = -1. So we need to - // write something to the console from time to time. Because otherwise - // it will timeout and the tests will be killed. - let keepAlive = setInterval(() => { - console.log("."); - }, 1000 * 60 * 10); let i = 0; + const client = this.getClient(name); for (const input of txInputs) { + // console.log(input); + // console.log(await client.fetchMatchingUtxos(input.hash)); + const txn = new TransactionBuilder(); txn.addInput(input); const txOutput = txn.addOutput(txn.getSpendableAmount()); const completedTx = txn.build(); - const submitResult = await this.getClient(name).submitTransaction( - completedTx - ); - if (this.checkAutoTransactions && submitResult.result != "ACCEPTED") { - console.log( - "Automated transaction failed. If this is not intended add step :", - "`I do not expect all automated transactions to succeed` !" - ); - result = false; - } - if (submitResult.result == "ACCEPTED") { - i++; - // we should only add a spendable output if the transaction is added to the blockchain + + const submitResult = await client.submitTransaction(completedTx); + if (submitResult.result != "ACCEPTED") { + this.lastTransactionsSucceeded = false; + // result = false; + } else { + // Add the output to be spent... assumes it has been mined. this.addTransactionOutput(height + 1, txOutput); } + i++; if (i > 9) { //this is to make sure the blocks stay relatively empty so that the tests don't take too long break; } } - clearInterval(keepAlive); console.log( `Created ${i} transactions for node: ${name} at height: ${height}` ); @@ -364,6 +356,9 @@ class CustomWorld { setWorldConstructor(CustomWorld); BeforeAll({ timeout: 2400000 }, async function () { + console.log( + "NOTE: Some tests may be excluded based on the profile used in /integration_tests/cucumber.js. If none was specified, `default` profile is used." + ); const baseNode = new BaseNodeProcess("compile"); console.log("Compiling base node..."); await baseNode.init(); diff --git a/integration_tests/log4rs/base_node.yml b/integration_tests/log4rs/base_node.yml index 78802da9cc..4d44f9aeb3 100644 --- a/integration_tests/log4rs/base_node.yml +++ b/integration_tests/log4rs/base_node.yml @@ -14,8 +14,13 @@ appenders: # An appender named "stdout" that writes to stdout stdout: kind: console + # Put all errors and warns on stderr so that it gets printed in circle ci + target: stderr encoder: - pattern: "{d(%Y-%m-%d %H:%M:%S.%f)} [{t}] {h({l}):5} {m}{n}" + pattern: "{d(%H:%M)} {h({l}):5} {m}{n}" + filters: + - kind: threshold + level: warn # An appender named "network" that writes to a file with a custom pattern encoder network: @@ -92,82 +97,75 @@ root: - stdout loggers: - # base_layer - c: - level: debug - appenders: - - base_layer - additive: false - c::cs::lmdb_db::lmdb_db: - level: debug + # Route log events common to every application to all appenders + tari::application: + level: info appenders: - base_layer + - network + - other additive: false - c::pow::lwma_diff: - level: debug + + # Route log events sent to the "core" logger to the "base_layer" appender + c: + level: info appenders: - base_layer - additive: false - c::bn::pow::sha3: - level: debug + tari: + level: info appenders: - base_layer - additive: false - base_node: - level: debug + + # Route log events sent to the "wallet" logger to the "base_layer" appender + wallet: + level: info appenders: - base_layer - additive: false - # network + # Route log events sent to the "comms" logger to the "network" appender comms: - level: debug - appenders: - - network - additive: false - comms::noise: - level: error + level: info appenders: - network - additive: false + # Route log events sent to the "p2p" logger to the "network" appender p2p: - level: debug + level: info appenders: - network - additive: false + + # Route log events sent to the "yamux" logger to the "network" appender yamux: - level: warn + level: info appenders: - network - additive: false + # Route log events sent to the "mio" logger to the "network" appender mio: - level: warn - appenders: - - network - additive: false - tracing: level: error appenders: - network - additive: false - # other + # Route log events sent to the "rustyline" logger to the "other" appender rustyline: - level: warn + level: error appenders: - other additive: false + + # Route log events sent to the "tokio_util" logger to the "other" appender tokio_util: - level: warn + level: error appenders: - other - additive: false - h2: - level: error + # Route PGP log events + pgp: + level: warn appenders: - other - additive: false - # stress_test + # Route log events sent to the "tari_mm_proxy" logger to the "base_layer" appender + tari_mm_proxy: + level: info + appenders: + - base_layer + # Route log events sent to the "stress_test" logger to the "base_layer" appender stress_test: - level: debug + level: info appenders: - - stress_test - additive: false + - base_layer From 07c2c693c7ee155deafd94171a8a346d7c3706ba Mon Sep 17 00:00:00 2001 From: Denis Kolodin Date: Mon, 18 Oct 2021 15:28:16 +0300 Subject: [PATCH 2/2] fix: remove unnecessary wallet dependency (#3438) Description --- Removes `wallet` dependency from `tari_app_grpc` and `tari_app_utilities`. Motivation and Context --- `grpc` and `utilities` are common and don't contain relations with the wallet. Dependency has been removed because it affects building time and complicates maintenance. How Has This Been Tested? --- CI only, because the changes don't affect any feature and change locations of some types only. --- Cargo.lock | 12 +- applications/tari_app_grpc/Cargo.toml | 4 - .../src/conversions/transaction.rs | 59 ++++--- applications/tari_app_utilities/Cargo.toml | 5 - .../src/identity_management.rs | 3 +- .../tari_app_utilities/src/initialization.rs | 3 +- .../tari_app_utilities/src/utilities.rs | 150 +----------------- applications/tari_base_node/src/main.rs | 4 +- applications/tari_base_node/src/recovery.rs | 3 +- applications/tari_console_wallet/Cargo.toml | 4 +- .../src/automation/commands.rs | 4 +- .../src/automation/error.rs | 2 +- .../tari_console_wallet/src/init/mod.rs | 4 +- applications/tari_console_wallet/src/main.rs | 4 +- .../tari_console_wallet/src/notifier/mod.rs | 2 +- .../tari_console_wallet/src/recovery.rs | 2 +- .../src/ui/components/transactions_tab.rs | 2 +- .../tari_console_wallet/src/ui/mod.rs | 2 +- .../src/ui/state/app_state.rs | 18 +-- .../src/ui/state/wallet_event_monitor.rs | 3 +- .../tari_console_wallet/src/wallet_modes.rs | 3 +- applications/tari_mining_node/src/main.rs | 11 +- base_layer/common_types/Cargo.toml | 1 + base_layer/common_types/src/lib.rs | 1 + base_layer/common_types/src/transaction.rs | 108 +++++++++++++ base_layer/wallet/src/error.rs | 22 +++ .../src/output_manager_service/error.rs | 8 + .../src/output_manager_service/handle.rs | 3 +- .../wallet/src/output_manager_service/mod.rs | 2 - .../src/output_manager_service/service.rs | 6 +- .../storage/database.rs | 6 +- .../storage/sqlite_db.rs | 6 +- .../wallet/src/transaction_service/error.rs | 26 ++- .../wallet/src/transaction_service/handle.rs | 10 +- .../transaction_broadcast_protocol.rs | 11 +- .../protocols/transaction_receive_protocol.rs | 34 ++-- .../protocols/transaction_send_protocol.rs | 21 +-- .../transaction_validation_protocol.rs | 4 +- .../wallet/src/transaction_service/service.rs | 17 +- .../transaction_service/storage/database.rs | 20 +-- .../src/transaction_service/storage/models.rs | 100 +----------- .../transaction_service/storage/sqlite_db.rs | 66 ++++---- .../tasks/send_finalized_transaction.rs | 12 +- .../tasks/send_transaction_cancelled.rs | 3 +- .../tasks/send_transaction_reply.rs | 2 +- .../transaction_service/tasks/wait_on_dial.rs | 2 +- .../src/utxo_scanner_service/utxo_scanning.rs | 4 +- base_layer/wallet/src/wallet.rs | 2 +- .../tests/output_manager_service/service.rs | 6 +- .../tests/transaction_service/service.rs | 9 +- .../tests/transaction_service/storage.rs | 14 +- .../transaction_protocols.rs | 4 +- base_layer/wallet_ffi/src/callback_handler.rs | 19 +-- base_layer/wallet_ffi/src/lib.rs | 16 +- common/Cargo.toml | 1 + common/src/exit_codes.rs | 93 +++++++++++ common/src/lib.rs | 1 + comms/Cargo.toml | 1 + comms/src/peer_manager/error.rs | 7 + 59 files changed, 466 insertions(+), 506 deletions(-) create mode 100644 base_layer/common_types/src/transaction.rs create mode 100644 common/src/exit_codes.rs diff --git a/Cargo.lock b/Cargo.lock index 0264fd4ec6..92f0f03fe3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4185,7 +4185,6 @@ dependencies = [ "tari_comms", "tari_core", "tari_crypto", - "tari_wallet", "tonic", "tonic-build", ] @@ -4210,7 +4209,6 @@ dependencies = [ "tari_core", "tari_crypto", "tari_p2p", - "tari_wallet", "thiserror", "tokio 1.11.0", "tonic", @@ -4296,6 +4294,7 @@ dependencies = [ "tari_storage", "tari_test_utils", "tempfile", + "thiserror", "toml 0.5.8", "tracing", "tracing-opentelemetry", @@ -4312,6 +4311,7 @@ dependencies = [ "rand 0.8.4", "serde 1.0.130", "tari_crypto", + "thiserror", "tokio 1.11.0", ] @@ -4947,18 +4947,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "283d5230e63df9608ac7d9691adc1dfb6e701225436eb64d0b9a7f0a5a04f6ec" +checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa3884228611f5cd3608e2d409bf7dce832e4eb3135e3f11addbd7e41bd68e71" +checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" dependencies = [ "proc-macro2 1.0.28", "quote 1.0.9", diff --git a/applications/tari_app_grpc/Cargo.toml b/applications/tari_app_grpc/Cargo.toml index a50d866dc7..d4bd0436bd 100644 --- a/applications/tari_app_grpc/Cargo.toml +++ b/applications/tari_app_grpc/Cargo.toml @@ -10,7 +10,6 @@ edition = "2018" [dependencies] tari_common_types = { version = "^0.11", path = "../../base_layer/common_types"} tari_core = { path = "../../base_layer/core"} -tari_wallet = { path = "../../base_layer/wallet", optional = true} tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", branch = "main" } tari_comms = { path = "../../comms"} @@ -21,6 +20,3 @@ tonic = "0.5.2" [build-dependencies] tonic-build = "0.5.2" - -[features] -wallet = ["tari_wallet"] \ No newline at end of file diff --git a/applications/tari_app_grpc/src/conversions/transaction.rs b/applications/tari_app_grpc/src/conversions/transaction.rs index cb9e91f63a..b3401226bb 100644 --- a/applications/tari_app_grpc/src/conversions/transaction.rs +++ b/applications/tari_app_grpc/src/conversions/transaction.rs @@ -22,6 +22,7 @@ use crate::tari_rpc as grpc; use std::convert::{TryFrom, TryInto}; +use tari_common_types::transaction::{self as tx, TxId}; use tari_core::{ crypto::{ristretto::RistrettoSecretKey, tari_utilities::ByteArray}, transactions::transaction::Transaction, @@ -54,44 +55,38 @@ impl TryFrom for Transaction { } } -#[cfg(feature = "wallet")] -mod wallet { - use super::*; - use tari_wallet::{output_manager_service::TxId, transaction_service::storage::models}; - - impl From for grpc::TransactionStatus { - fn from(status: models::TransactionStatus) -> Self { - use models::TransactionStatus::*; - match status { - Completed => grpc::TransactionStatus::Completed, - Broadcast => grpc::TransactionStatus::Broadcast, - MinedUnconfirmed => grpc::TransactionStatus::MinedUnconfirmed, - MinedConfirmed => grpc::TransactionStatus::MinedConfirmed, - Imported => grpc::TransactionStatus::Imported, - Pending => grpc::TransactionStatus::Pending, - Coinbase => grpc::TransactionStatus::Coinbase, - } +impl From for grpc::TransactionDirection { + fn from(status: tx::TransactionDirection) -> Self { + use tx::TransactionDirection::*; + match status { + Unknown => grpc::TransactionDirection::Unknown, + Inbound => grpc::TransactionDirection::Inbound, + Outbound => grpc::TransactionDirection::Outbound, } } +} - impl From for grpc::TransactionDirection { - fn from(status: models::TransactionDirection) -> Self { - use models::TransactionDirection::*; - match status { - Unknown => grpc::TransactionDirection::Unknown, - Inbound => grpc::TransactionDirection::Inbound, - Outbound => grpc::TransactionDirection::Outbound, - } +impl From for grpc::TransactionStatus { + fn from(status: tx::TransactionStatus) -> Self { + use tx::TransactionStatus::*; + match status { + Completed => grpc::TransactionStatus::Completed, + Broadcast => grpc::TransactionStatus::Broadcast, + MinedUnconfirmed => grpc::TransactionStatus::MinedUnconfirmed, + MinedConfirmed => grpc::TransactionStatus::MinedConfirmed, + Imported => grpc::TransactionStatus::Imported, + Pending => grpc::TransactionStatus::Pending, + Coinbase => grpc::TransactionStatus::Coinbase, } } +} - impl grpc::TransactionInfo { - pub fn not_found(tx_id: TxId) -> Self { - Self { - tx_id, - status: grpc::TransactionStatus::NotFound as i32, - ..Default::default() - } +impl grpc::TransactionInfo { + pub fn not_found(tx_id: TxId) -> Self { + Self { + tx_id, + status: grpc::TransactionStatus::NotFound as i32, + ..Default::default() } } } diff --git a/applications/tari_app_utilities/Cargo.toml b/applications/tari_app_utilities/Cargo.toml index fcdc4ba8ff..8c55b72f0c 100644 --- a/applications/tari_app_utilities/Cargo.toml +++ b/applications/tari_app_utilities/Cargo.toml @@ -10,7 +10,6 @@ tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", branch tari_common = { path = "../../common" } tari_common_types = { path = "../../base_layer/common_types" } tari_p2p = { path = "../../base_layer/p2p", features = ["auto-update"] } -tari_wallet = { path = "../../base_layer/wallet", optional = true } config = { version = "0.9.3" } futures = { version = "^0.3.16", default-features = false, features = ["alloc"] } @@ -33,7 +32,3 @@ features = ["transactions"] [build-dependencies] tari_common = { path = "../../common", features = ["build", "static-application-info"] } - -[features] -# TODO: This crate is supposed to hold common logic. Move code from this feature into the crate that is more specific to the wallet -wallet = ["tari_wallet"] diff --git a/applications/tari_app_utilities/src/identity_management.rs b/applications/tari_app_utilities/src/identity_management.rs index 013a0e8fc8..f8bb2893d7 100644 --- a/applications/tari_app_utilities/src/identity_management.rs +++ b/applications/tari_app_utilities/src/identity_management.rs @@ -20,11 +20,10 @@ // 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 crate::utilities::ExitCodes; use log::*; use rand::rngs::OsRng; use std::{clone::Clone, fs, path::Path, string::ToString, sync::Arc}; -use tari_common::configuration::bootstrap::prompt; +use tari_common::{configuration::bootstrap::prompt, exit_codes::ExitCodes}; use tari_common_types::types::PrivateKey; use tari_comms::{multiaddr::Multiaddr, peer_manager::PeerFeatures, NodeIdentity}; use tari_crypto::{ diff --git a/applications/tari_app_utilities/src/initialization.rs b/applications/tari_app_utilities/src/initialization.rs index 85c711d4e3..ead5b89f4b 100644 --- a/applications/tari_app_utilities/src/initialization.rs +++ b/applications/tari_app_utilities/src/initialization.rs @@ -1,9 +1,10 @@ -use crate::{consts, utilities::ExitCodes}; +use crate::consts; use config::Config; use std::{path::PathBuf, str::FromStr}; use structopt::StructOpt; use tari_common::{ configuration::{bootstrap::ApplicationType, Network}, + exit_codes::ExitCodes, ConfigBootstrap, DatabaseType, GlobalConfig, diff --git a/applications/tari_app_utilities/src/utilities.rs b/applications/tari_app_utilities/src/utilities.rs index 989c871841..8392e20e45 100644 --- a/applications/tari_app_utilities/src/utilities.rs +++ b/applications/tari_app_utilities/src/utilities.rs @@ -23,14 +23,11 @@ use futures::future::Either; use log::*; use std::sync::Arc; -use thiserror::Error; use tokio::{runtime, runtime::Runtime}; use tari_common::{CommsTransport, GlobalConfig, SocksAuthentication, TorControlAuthentication}; use tari_comms::{ - connectivity::ConnectivityError, - peer_manager::{NodeId, PeerManagerError}, - protocol::rpc::RpcError, + peer_manager::NodeId, socks, tor, tor::TorIdentity, @@ -47,151 +44,6 @@ use tari_comms::transports::predicate::FalsePredicate; pub const LOG_TARGET: &str = "tari::application"; -/// Enum to show failure information -#[derive(Debug, Clone, Error)] -pub enum ExitCodes { - #[error("There is an error in the wallet configuration: {0}")] - ConfigError(String), - #[error("The application exited because an unknown error occurred: {0}. Check the logs for more details.")] - UnknownError(String), - #[error("The application exited because an interface error occurred. Check the logs for details.")] - InterfaceError, - #[error("The application exited. {0}")] - WalletError(String), - #[error("The wallet was not able to start the GRPC server. {0}")] - GrpcError(String), - #[error("The application did not accept the command input: {0}")] - InputError(String), - #[error("Invalid command: {0}")] - CommandError(String), - #[error("IO error: {0}")] - IOError(String), - #[error("Recovery failed: {0}")] - RecoveryError(String), - #[error("The wallet exited because of an internal network error: {0}")] - NetworkError(String), - #[error("The wallet exited because it received a message it could not interpret: {0}")] - ConversionError(String), - #[error("Your password was incorrect.")] - IncorrectPassword, - #[error("Your application is encrypted but no password was provided.")] - NoPassword, - #[error("Tor connection is offline")] - TorOffline, - #[error("Database is in inconsistent state: {0}")] - DbInconsistentState(String), -} - -impl ExitCodes { - pub fn as_i32(&self) -> i32 { - match self { - Self::ConfigError(_) => 101, - Self::UnknownError(_) => 102, - Self::InterfaceError => 103, - Self::WalletError(_) => 104, - Self::GrpcError(_) => 105, - Self::InputError(_) => 106, - Self::CommandError(_) => 107, - Self::IOError(_) => 108, - Self::RecoveryError(_) => 109, - Self::NetworkError(_) => 110, - Self::ConversionError(_) => 111, - Self::IncorrectPassword | Self::NoPassword => 112, - Self::TorOffline => 113, - Self::DbInconsistentState(_) => 115, - } - } - - pub fn eprint_details(&self) { - use ExitCodes::*; - match self { - TorOffline => { - eprintln!("Unable to connect to the Tor control port."); - eprintln!( - "Please check that you have the Tor proxy running and that access to the Tor control port is \ - turned on.", - ); - eprintln!("If you are unsure of what to do, use the following command to start the Tor proxy:"); - eprintln!( - "tor --allow-missing-torrc --ignore-missing-torrc --clientonly 1 --socksport 9050 --controlport \ - 127.0.0.1:9051 --log \"notice stdout\" --clientuseipv6 1", - ); - }, - - e => { - eprintln!("{}", e); - }, - } - } -} - -impl From for ExitCodes { - fn from(err: tari_common::ConfigError) -> Self { - error!(target: LOG_TARGET, "{}", err); - Self::ConfigError(err.to_string()) - } -} - -impl From for ExitCodes { - fn from(err: ConnectivityError) -> Self { - error!(target: LOG_TARGET, "{}", err); - Self::NetworkError(err.to_string()) - } -} - -impl From for ExitCodes { - fn from(err: RpcError) -> Self { - error!(target: LOG_TARGET, "{}", err); - Self::NetworkError(err.to_string()) - } -} - -#[cfg(feature = "wallet")] -mod wallet { - use super::*; - use tari_wallet::{ - error::{WalletError, WalletStorageError}, - output_manager_service::error::OutputManagerError, - }; - - impl From for ExitCodes { - fn from(err: WalletError) -> Self { - error!(target: LOG_TARGET, "{}", err); - Self::WalletError(err.to_string()) - } - } - - impl From for ExitCodes { - fn from(err: OutputManagerError) -> Self { - error!(target: LOG_TARGET, "{}", err); - Self::WalletError(err.to_string()) - } - } - - impl From for ExitCodes { - fn from(err: WalletStorageError) -> Self { - use WalletStorageError::*; - match err { - NoPasswordError => ExitCodes::NoPassword, - IncorrectPassword => ExitCodes::IncorrectPassword, - e => ExitCodes::WalletError(e.to_string()), - } - } - } -} - -impl From for ExitCodes { - fn from(err: PeerManagerError) -> Self { - ExitCodes::NetworkError(err.to_string()) - } -} - -impl ExitCodes { - pub fn grpc(err: M) -> Self { - ExitCodes::GrpcError(format!("GRPC connection error: {}", err)) - } -} - /// Creates a transport type from the given configuration /// /// ## Paramters diff --git a/applications/tari_base_node/src/main.rs b/applications/tari_base_node/src/main.rs index 6c8d10475d..a3342dd1dd 100644 --- a/applications/tari_base_node/src/main.rs +++ b/applications/tari_base_node/src/main.rs @@ -111,9 +111,9 @@ use tari_app_utilities::{ consts, identity_management::setup_node_identity, initialization::init_configuration, - utilities::{setup_runtime, ExitCodes}, + utilities::setup_runtime, }; -use tari_common::{configuration::bootstrap::ApplicationType, ConfigBootstrap, GlobalConfig}; +use tari_common::{configuration::bootstrap::ApplicationType, exit_codes::ExitCodes, ConfigBootstrap, GlobalConfig}; use tari_comms::{peer_manager::PeerFeatures, tor::HiddenServiceControllerError}; use tari_core::chain_storage::ChainStorageError; use tari_shutdown::{Shutdown, ShutdownSignal}; diff --git a/applications/tari_base_node/src/recovery.rs b/applications/tari_base_node/src/recovery.rs index 391423c12e..21a29f3a68 100644 --- a/applications/tari_base_node/src/recovery.rs +++ b/applications/tari_base_node/src/recovery.rs @@ -31,8 +31,7 @@ use std::{ use anyhow::anyhow; use log::*; -use tari_app_utilities::utilities::ExitCodes; -use tari_common::{configuration::Network, DatabaseType, GlobalConfig}; +use tari_common::{configuration::Network, exit_codes::ExitCodes, DatabaseType, GlobalConfig}; use tari_core::{ chain_storage::{ async_db::AsyncBlockchainDb, diff --git a/applications/tari_console_wallet/Cargo.toml b/applications/tari_console_wallet/Cargo.toml index cb57928049..a16e3e8e6a 100644 --- a/applications/tari_console_wallet/Cargo.toml +++ b/applications/tari_console_wallet/Cargo.toml @@ -8,12 +8,12 @@ edition = "2018" tari_wallet = { path = "../../base_layer/wallet", features = ["bundled_sqlite"] } tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", branch = "main" } tari_common = { path = "../../common" } -tari_app_utilities = { path = "../tari_app_utilities", features = ["wallet"] } +tari_app_utilities = { path = "../tari_app_utilities" } tari_comms = { path = "../../comms" } tari_comms_dht = { path = "../../comms/dht" } tari_common_types = { path = "../../base_layer/common_types" } tari_p2p = { path = "../../base_layer/p2p", features = ["auto-update"] } -tari_app_grpc = { path = "../tari_app_grpc", features = ["wallet"] } +tari_app_grpc = { path = "../tari_app_grpc" } tari_shutdown = { path = "../../infrastructure/shutdown" } tari_key_manager = { path = "../../base_layer/key_manager" } diff --git a/applications/tari_console_wallet/src/automation/commands.rs b/applications/tari_console_wallet/src/automation/commands.rs index dde91c74f4..6b2a9cc027 100644 --- a/applications/tari_console_wallet/src/automation/commands.rs +++ b/applications/tari_console_wallet/src/automation/commands.rs @@ -40,7 +40,7 @@ use crate::{ utils::db::{CUSTOM_BASE_NODE_ADDRESS_KEY, CUSTOM_BASE_NODE_PUBLIC_KEY_KEY}, }; use tari_common::GlobalConfig; -use tari_common_types::{emoji::EmojiId, types::PublicKey}; +use tari_common_types::{emoji::EmojiId, transaction::TxId, types::PublicKey}; use tari_comms::{ connectivity::{ConnectivityEvent, ConnectivityRequester}, multiaddr::Multiaddr, @@ -55,7 +55,7 @@ use tari_core::{ }, }; use tari_wallet::{ - output_manager_service::{handle::OutputManagerHandle, TxId}, + output_manager_service::handle::OutputManagerHandle, transaction_service::handle::{TransactionEvent, TransactionServiceHandle}, WalletSqlite, }; diff --git a/applications/tari_console_wallet/src/automation/error.rs b/applications/tari_console_wallet/src/automation/error.rs index df4974d899..483d2ae371 100644 --- a/applications/tari_console_wallet/src/automation/error.rs +++ b/applications/tari_console_wallet/src/automation/error.rs @@ -24,7 +24,7 @@ use std::num::{ParseFloatError, ParseIntError}; use chrono_english::DateError; use log::*; -use tari_app_utilities::utilities::ExitCodes; +use tari_common::exit_codes::ExitCodes; use tari_core::transactions::{ tari_amount::{MicroTariError, TariConversionError}, transaction::TransactionError, diff --git a/applications/tari_console_wallet/src/init/mod.rs b/applications/tari_console_wallet/src/init/mod.rs index e99289be5d..1a68dd7a88 100644 --- a/applications/tari_console_wallet/src/init/mod.rs +++ b/applications/tari_console_wallet/src/init/mod.rs @@ -26,8 +26,8 @@ use log::*; use rpassword::prompt_password_stdout; use rustyline::Editor; -use tari_app_utilities::utilities::{create_transport_type, ExitCodes}; -use tari_common::{ConfigBootstrap, GlobalConfig}; +use tari_app_utilities::utilities::create_transport_type; +use tari_common::{exit_codes::ExitCodes, ConfigBootstrap, GlobalConfig}; use tari_common_types::types::PrivateKey; use tari_comms::{ peer_manager::{Peer, PeerFeatures}, diff --git a/applications/tari_console_wallet/src/main.rs b/applications/tari_console_wallet/src/main.rs index 23b917fb16..59b857eaef 100644 --- a/applications/tari_console_wallet/src/main.rs +++ b/applications/tari_console_wallet/src/main.rs @@ -22,8 +22,8 @@ use log::*; use opentelemetry::{self, global, KeyValue}; use recovery::prompt_private_key_from_seed_words; use std::{env, process}; -use tari_app_utilities::{consts, initialization::init_configuration, utilities::ExitCodes}; -use tari_common::{configuration::bootstrap::ApplicationType, ConfigBootstrap}; +use tari_app_utilities::{consts, initialization::init_configuration}; +use tari_common::{configuration::bootstrap::ApplicationType, exit_codes::ExitCodes, ConfigBootstrap}; use tari_common_types::types::PrivateKey; use tari_shutdown::Shutdown; use tracing_subscriber::{layer::SubscriberExt, Registry}; diff --git a/applications/tari_console_wallet/src/notifier/mod.rs b/applications/tari_console_wallet/src/notifier/mod.rs index 08cefc3ad6..1ec8bc7d84 100644 --- a/applications/tari_console_wallet/src/notifier/mod.rs +++ b/applications/tari_console_wallet/src/notifier/mod.rs @@ -26,9 +26,9 @@ use std::{ path::PathBuf, process::{Command, Output}, }; +use tari_common_types::transaction::TxId; use tari_core::tari_utilities::hex::Hex; use tari_wallet::{ - output_manager_service::TxId, transaction_service::storage::models::{ CompletedTransaction, InboundTransaction, diff --git a/applications/tari_console_wallet/src/recovery.rs b/applications/tari_console_wallet/src/recovery.rs index 370d399ff5..dde9f8a769 100644 --- a/applications/tari_console_wallet/src/recovery.rs +++ b/applications/tari_console_wallet/src/recovery.rs @@ -24,7 +24,7 @@ use chrono::offset::Local; use futures::FutureExt; use log::*; use rustyline::Editor; -use tari_app_utilities::utilities::ExitCodes; +use tari_common::exit_codes::ExitCodes; use tari_common_types::types::PrivateKey; use tari_crypto::tari_utilities::hex::Hex; use tari_key_manager::mnemonic::to_secretkey; diff --git a/applications/tari_console_wallet/src/ui/components/transactions_tab.rs b/applications/tari_console_wallet/src/ui/components/transactions_tab.rs index 1baf29065f..3b4331f28d 100644 --- a/applications/tari_console_wallet/src/ui/components/transactions_tab.rs +++ b/applications/tari_console_wallet/src/ui/components/transactions_tab.rs @@ -7,7 +7,7 @@ use crate::ui::{ MAX_WIDTH, }; use chrono::{DateTime, Local}; -use tari_wallet::transaction_service::storage::models::{TransactionDirection, TransactionStatus}; +use tari_common_types::transaction::{TransactionDirection, TransactionStatus}; use tokio::runtime::Handle; use tui::{ backend::Backend, diff --git a/applications/tari_console_wallet/src/ui/mod.rs b/applications/tari_console_wallet/src/ui/mod.rs index ac01ec6d75..18c952fcbf 100644 --- a/applications/tari_console_wallet/src/ui/mod.rs +++ b/applications/tari_console_wallet/src/ui/mod.rs @@ -22,7 +22,7 @@ use crate::utils::crossterm_events::CrosstermEvents; use log::error; -use tari_app_utilities::utilities::ExitCodes; +use tari_common::exit_codes::ExitCodes; mod app; mod components; 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 e3a61b10db..8bd616df4d 100644 --- a/applications/tari_console_wallet/src/ui/state/app_state.rs +++ b/applications/tari_console_wallet/src/ui/state/app_state.rs @@ -38,7 +38,11 @@ use tokio::{ }; use tari_common::{configuration::Network, GlobalConfig}; -use tari_common_types::{emoji::EmojiId, types::PublicKey}; +use tari_common_types::{ + emoji::EmojiId, + transaction::{TransactionDirection, TransactionStatus, TxId}, + types::PublicKey, +}; use tari_comms::{ connectivity::ConnectivityEventRx, multiaddr::Multiaddr, @@ -52,11 +56,8 @@ use tari_wallet::{ base_node_service::{handle::BaseNodeEventReceiver, service::BaseNodeState}, connectivity_service::WalletConnectivityHandle, contacts_service::storage::database::Contact, - output_manager_service::{handle::OutputManagerEventReceiver, service::Balance, TxId}, - transaction_service::{ - handle::TransactionEventReceiver, - storage::models::{CompletedTransaction, TransactionStatus}, - }, + output_manager_service::{handle::OutputManagerEventReceiver, service::Balance}, + transaction_service::{handle::TransactionEventReceiver, storage::models::CompletedTransaction}, WalletSqlite, }; @@ -74,10 +75,7 @@ use crate::{ utils::db::{CUSTOM_BASE_NODE_ADDRESS_KEY, CUSTOM_BASE_NODE_PUBLIC_KEY_KEY}, wallet_modes::PeerConfig, }; -use tari_wallet::{ - output_manager_service::handle::OutputManagerHandle, - transaction_service::storage::models::TransactionDirection, -}; +use tari_wallet::output_manager_service::handle::OutputManagerHandle; const LOG_TARGET: &str = "wallet::console_wallet::app_state"; diff --git a/applications/tari_console_wallet/src/ui/state/wallet_event_monitor.rs b/applications/tari_console_wallet/src/ui/state/wallet_event_monitor.rs index ed42ceaeb0..4f9e8da173 100644 --- a/applications/tari_console_wallet/src/ui/state/wallet_event_monitor.rs +++ b/applications/tari_console_wallet/src/ui/state/wallet_event_monitor.rs @@ -23,11 +23,12 @@ use crate::{notifier::Notifier, ui::state::AppStateInner}; use log::*; use std::sync::Arc; +use tari_common_types::transaction::TxId; use tari_comms::{connectivity::ConnectivityEvent, peer_manager::Peer}; use tari_wallet::{ base_node_service::{handle::BaseNodeEvent, service::BaseNodeState}, connectivity_service::WalletConnectivityInterface, - output_manager_service::{handle::OutputManagerEvent, TxId}, + output_manager_service::handle::OutputManagerEvent, transaction_service::handle::TransactionEvent, }; use tokio::sync::{broadcast, RwLock}; diff --git a/applications/tari_console_wallet/src/wallet_modes.rs b/applications/tari_console_wallet/src/wallet_modes.rs index 0fbc183cbb..2193021b02 100644 --- a/applications/tari_console_wallet/src/wallet_modes.rs +++ b/applications/tari_console_wallet/src/wallet_modes.rs @@ -31,8 +31,7 @@ use crate::{ use log::*; use rand::{rngs::OsRng, seq::SliceRandom}; use std::{fs, io::Stdout, net::SocketAddr, path::PathBuf}; -use tari_app_utilities::utilities::ExitCodes; -use tari_common::{ConfigBootstrap, GlobalConfig}; +use tari_common::{exit_codes::ExitCodes, ConfigBootstrap, GlobalConfig}; use tari_comms::peer_manager::Peer; use tari_wallet::WalletSqlite; use tokio::runtime::Handle; diff --git a/applications/tari_mining_node/src/main.rs b/applications/tari_mining_node/src/main.rs index bb36f4bf5c..687b1ce52b 100644 --- a/applications/tari_mining_node/src/main.rs +++ b/applications/tari_mining_node/src/main.rs @@ -47,11 +47,14 @@ use std::{ time::Instant, }; use tari_app_grpc::tari_rpc::{base_node_client::BaseNodeClient, wallet_client::WalletClient}; -use tari_app_utilities::{ - initialization::init_configuration, - utilities::{ExitCodes, ExitCodes::ConfigError}, +use tari_app_utilities::initialization::init_configuration; +use tari_common::{ + configuration::bootstrap::ApplicationType, + exit_codes::{ExitCodes, ExitCodes::ConfigError}, + ConfigBootstrap, + DefaultConfigLoader, + GlobalConfig, }; -use tari_common::{configuration::bootstrap::ApplicationType, ConfigBootstrap, DefaultConfigLoader, GlobalConfig}; use tari_core::blocks::BlockHeader; use tari_crypto::{ristretto::RistrettoPublicKey, tari_utilities::hex::Hex}; use tokio::{runtime::Runtime, time::sleep}; diff --git a/base_layer/common_types/Cargo.toml b/base_layer/common_types/Cargo.toml index b8fa94d970..b9ec3b9800 100644 --- a/base_layer/common_types/Cargo.toml +++ b/base_layer/common_types/Cargo.toml @@ -14,3 +14,4 @@ serde = { version = "1.0.106", features = ["derive"] } tokio = { version = "1.11", features = ["time", "sync"] } lazy_static = "1.4.0" digest = "0.9.0" +thiserror = "1.0.29" diff --git a/base_layer/common_types/src/lib.rs b/base_layer/common_types/src/lib.rs index df01ae7302..7281ebba2a 100644 --- a/base_layer/common_types/src/lib.rs +++ b/base_layer/common_types/src/lib.rs @@ -23,6 +23,7 @@ pub mod chain_metadata; pub mod emoji; pub mod luhn; +pub mod transaction; pub mod types; pub mod waiting_requests; diff --git a/base_layer/common_types/src/transaction.rs b/base_layer/common_types/src/transaction.rs new file mode 100644 index 0000000000..16b3fba350 --- /dev/null +++ b/base_layer/common_types/src/transaction.rs @@ -0,0 +1,108 @@ +use serde::{Deserialize, Serialize}; +use std::{ + convert::TryFrom, + fmt::{Display, Error, Formatter}, +}; +use thiserror::Error; + +pub type TxId = u64; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum TransactionStatus { + /// This transaction has been completed between the parties but has not been broadcast to the base layer network. + Completed, + /// This transaction has been broadcast to the base layer network and is currently in one or more base node + /// mempools. + Broadcast, + /// This transaction has been mined and included in a block. + MinedUnconfirmed, + /// This transaction was generated as part of importing a spendable UTXO + Imported, + /// This transaction is still being negotiated by the parties + Pending, + /// This is a created Coinbase Transaction + Coinbase, + /// This transaction is mined and confirmed at the current base node's height + MinedConfirmed, +} + +#[derive(Debug, Error)] +#[error("Invalid TransactionStatus: {code}")] +pub struct TransactionConversionError { + pub code: i32, +} + +impl TryFrom for TransactionStatus { + type Error = TransactionConversionError; + + fn try_from(value: i32) -> Result { + match value { + 0 => Ok(TransactionStatus::Completed), + 1 => Ok(TransactionStatus::Broadcast), + 2 => Ok(TransactionStatus::MinedUnconfirmed), + 3 => Ok(TransactionStatus::Imported), + 4 => Ok(TransactionStatus::Pending), + 5 => Ok(TransactionStatus::Coinbase), + 6 => Ok(TransactionStatus::MinedConfirmed), + code => Err(TransactionConversionError { code }), + } + } +} + +impl Default for TransactionStatus { + fn default() -> Self { + TransactionStatus::Pending + } +} + +impl Display for TransactionStatus { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { + // No struct or tuple variants + match self { + TransactionStatus::Completed => write!(f, "Completed"), + TransactionStatus::Broadcast => write!(f, "Broadcast"), + TransactionStatus::MinedUnconfirmed => write!(f, "Mined Unconfirmed"), + TransactionStatus::MinedConfirmed => write!(f, "Mined Confirmed"), + TransactionStatus::Imported => write!(f, "Imported"), + TransactionStatus::Pending => write!(f, "Pending"), + TransactionStatus::Coinbase => write!(f, "Coinbase"), + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub enum TransactionDirection { + Inbound, + Outbound, + Unknown, +} + +#[derive(Debug, Error)] +#[error("Invalid TransactionDirection: {code}")] +pub struct TransactionDirectionError { + pub code: i32, +} + +impl TryFrom for TransactionDirection { + type Error = TransactionDirectionError; + + fn try_from(value: i32) -> Result { + match value { + 0 => Ok(TransactionDirection::Inbound), + 1 => Ok(TransactionDirection::Outbound), + 2 => Ok(TransactionDirection::Unknown), + code => Err(TransactionDirectionError { code }), + } + } +} + +impl Display for TransactionDirection { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { + // No struct or tuple variants + match self { + TransactionDirection::Inbound => write!(f, "Inbound"), + TransactionDirection::Outbound => write!(f, "Outbound"), + TransactionDirection::Unknown => write!(f, "Unknown"), + } + } +} diff --git a/base_layer/wallet/src/error.rs b/base_layer/wallet/src/error.rs index bfd57766c4..a79548ac0e 100644 --- a/base_layer/wallet/src/error.rs +++ b/base_layer/wallet/src/error.rs @@ -31,6 +31,7 @@ use crate::{ use diesel::result::Error as DieselError; use log::SetLoggerError; use serde_json::Error as SerdeJsonError; +use tari_common::exit_codes::ExitCodes; use tari_comms::{ connectivity::ConnectivityError, multiaddr, @@ -85,6 +86,16 @@ pub enum WalletError { UtxoScannerError(#[from] UtxoScannerError), } +pub const LOG_TARGET: &str = "tari::application"; + +impl From for ExitCodes { + fn from(err: WalletError) -> Self { + // TODO: Log that outside + log::error!(target: LOG_TARGET, "{}", err); + Self::WalletError(err.to_string()) + } +} + #[derive(Debug, Error)] pub enum WalletStorageError { #[error("Tried to insert an output that already exists in the database")] @@ -142,3 +153,14 @@ pub enum WalletStorageError { #[error("Deprecated operation error")] DeprecatedOperation, } + +impl From for ExitCodes { + fn from(err: WalletStorageError) -> Self { + use WalletStorageError::*; + match err { + NoPasswordError => ExitCodes::NoPassword, + IncorrectPassword => ExitCodes::IncorrectPassword, + e => ExitCodes::WalletError(e.to_string()), + } + } +} diff --git a/base_layer/wallet/src/output_manager_service/error.rs b/base_layer/wallet/src/output_manager_service/error.rs index 87c87f7bae..8d6d8a20ac 100644 --- a/base_layer/wallet/src/output_manager_service/error.rs +++ b/base_layer/wallet/src/output_manager_service/error.rs @@ -22,6 +22,7 @@ use crate::base_node_service::error::BaseNodeServiceError; use diesel::result::Error as DieselError; +use tari_common::exit_codes::ExitCodes; use tari_comms::{connectivity::ConnectivityError, peer_manager::node_id::NodeIdError, protocol::rpc::RpcError}; use tari_comms_dht::outbound::DhtOutboundError; use tari_core::transactions::{ @@ -168,6 +169,13 @@ pub enum OutputManagerStorageError { ScriptError(#[from] ScriptError), } +impl From for ExitCodes { + fn from(err: OutputManagerError) -> Self { + log::error!(target: crate::error::LOG_TARGET, "{}", err); + Self::WalletError(err.to_string()) + } +} + /// This error type is used to return OutputManagerError from inside a Output Manager Service protocol but also /// include the ID of the protocol #[derive(Debug)] diff --git a/base_layer/wallet/src/output_manager_service/handle.rs b/base_layer/wallet/src/output_manager_service/handle.rs index 4c9fd40498..39f31aefea 100644 --- a/base_layer/wallet/src/output_manager_service/handle.rs +++ b/base_layer/wallet/src/output_manager_service/handle.rs @@ -24,11 +24,10 @@ use crate::output_manager_service::{ error::OutputManagerError, service::Balance, storage::models::KnownOneSidedPaymentScript, - TxId, }; use aes_gcm::Aes256Gcm; use std::{fmt, sync::Arc}; -use tari_common_types::types::PublicKey; +use tari_common_types::{transaction::TxId, types::PublicKey}; use tari_core::transactions::{ tari_amount::MicroTari, transaction::{Transaction, TransactionOutput, UnblindedOutput}, diff --git a/base_layer/wallet/src/output_manager_service/mod.rs b/base_layer/wallet/src/output_manager_service/mod.rs index cd13c3ecb1..0858229578 100644 --- a/base_layer/wallet/src/output_manager_service/mod.rs +++ b/base_layer/wallet/src/output_manager_service/mod.rs @@ -61,8 +61,6 @@ mod tasks; const LOG_TARGET: &str = "wallet::output_manager_service::initializer"; -pub type TxId = u64; - pub struct OutputManagerServiceInitializer where T: OutputManagerBackend { diff --git a/base_layer/wallet/src/output_manager_service/service.rs b/base_layer/wallet/src/output_manager_service/service.rs index 238e3dd476..242aa0f0d2 100644 --- a/base_layer/wallet/src/output_manager_service/service.rs +++ b/base_layer/wallet/src/output_manager_service/service.rs @@ -35,7 +35,6 @@ use crate::{ }, tasks::TxoValidationTask, MasterKeyManager, - TxId, }, transaction_service::handle::TransactionServiceHandle, types::HashDigest, @@ -50,7 +49,10 @@ use std::{ fmt::{self, Display}, sync::Arc, }; -use tari_common_types::types::{PrivateKey, PublicKey}; +use tari_common_types::{ + transaction::TxId, + types::{PrivateKey, PublicKey}, +}; use tari_comms::types::{CommsPublicKey, CommsSecretKey}; use tari_core::{ consensus::ConsensusConstants, diff --git a/base_layer/wallet/src/output_manager_service/storage/database.rs b/base_layer/wallet/src/output_manager_service/storage/database.rs index f70197c95e..0a232aec44 100644 --- a/base_layer/wallet/src/output_manager_service/storage/database.rs +++ b/base_layer/wallet/src/output_manager_service/storage/database.rs @@ -24,7 +24,6 @@ use crate::output_manager_service::{ error::OutputManagerStorageError, service::Balance, storage::models::{DbUnblindedOutput, KnownOneSidedPaymentScript, OutputStatus}, - TxId, }; use aes_gcm::Aes256Gcm; use log::*; @@ -32,7 +31,10 @@ use std::{ fmt::{Display, Error, Formatter}, sync::Arc, }; -use tari_common_types::types::{BlindingFactor, Commitment, HashOutput, PrivateKey}; +use tari_common_types::{ + transaction::TxId, + types::{BlindingFactor, Commitment, HashOutput, PrivateKey}, +}; use tari_core::transactions::transaction::TransactionOutput; const LOG_TARGET: &str = "wallet::output_manager_service::database"; diff --git a/base_layer/wallet/src/output_manager_service/storage/sqlite_db.rs b/base_layer/wallet/src/output_manager_service/storage/sqlite_db.rs index 6b0a7ea43d..f74966522e 100644 --- a/base_layer/wallet/src/output_manager_service/storage/sqlite_db.rs +++ b/base_layer/wallet/src/output_manager_service/storage/sqlite_db.rs @@ -28,7 +28,6 @@ use crate::{ database::{DbKey, DbKeyValuePair, DbValue, KeyManagerState, OutputManagerBackend, WriteOperation}, models::{DbUnblindedOutput, KnownOneSidedPaymentScript, OutputStatus}, }, - TxId, }, schema::{key_manager_states, known_one_sided_payment_scripts, outputs}, storage::sqlite_utilities::WalletDbConnection, @@ -46,7 +45,10 @@ use std::{ str::from_utf8, sync::{Arc, RwLock}, }; -use tari_common_types::types::{ComSignature, Commitment, PrivateKey, PublicKey}; +use tari_common_types::{ + transaction::TxId, + types::{ComSignature, Commitment, PrivateKey, PublicKey}, +}; use tari_core::{ tari_utilities::hash::Hashable, transactions::{ diff --git a/base_layer/wallet/src/transaction_service/error.rs b/base_layer/wallet/src/transaction_service/error.rs index d3984aa25c..6eac17cfac 100644 --- a/base_layer/wallet/src/transaction_service/error.rs +++ b/base_layer/wallet/src/transaction_service/error.rs @@ -22,15 +22,17 @@ use crate::{ error::WalletStorageError, - output_manager_service::{error::OutputManagerError, TxId}, - transaction_service::storage::database::DbKey, + output_manager_service::error::OutputManagerError, + transaction_service::storage::{database::DbKey, sqlite_db::CompletedTransactionConversionError}, }; use diesel::result::Error as DieselError; use futures::channel::oneshot::Canceled; use serde_json::Error as SerdeJsonError; +use tari_common_types::transaction::{TransactionConversionError, TransactionDirectionError, TxId}; use tari_comms::{connectivity::ConnectivityError, peer_manager::node_id::NodeIdError, protocol::rpc::RpcError}; use tari_comms_dht::outbound::DhtOutboundError; use tari_core::transactions::{transaction::TransactionError, transaction_protocol::TransactionProtocolError}; +use tari_crypto::tari_utilities::ByteArrayError; use tari_p2p::services::liveness::error::LivenessError; use tari_service_framework::reply_channel::TransportChannelError; use thiserror::Error; @@ -110,7 +112,9 @@ pub enum TransactionServiceError { #[error("Transaction error: `{0}`")] TransactionError(#[from] TransactionError), #[error("Conversion error: `{0}`")] - ConversionError(String), + ConversionError(#[from] TransactionConversionError), + #[error("duration::OutOfRangeError: {0}")] + DurationOutOfRange(#[from] OutOfRangeError), #[error("Node ID error: `{0}`")] NodeIdError(#[from] NodeIdError), #[error("Broadcast recv error: `{0}`")] @@ -156,6 +160,14 @@ pub enum TransactionServiceError { BaseNodeNotSynced, } +#[derive(Debug, Error)] +pub enum TransactionKeyError { + #[error("Invalid source Publickey")] + Source(ByteArrayError), + #[error("Invalid destination PublicKey")] + Destination(ByteArrayError), +} + #[derive(Debug, Error)] pub enum TransactionStorageError { #[error("Tried to insert an output that already exists in the database")] @@ -171,9 +183,15 @@ pub enum TransactionStorageError { #[error("Transaction is already present in the database")] TransactionAlreadyExists, #[error("Out of range error: `{0}`")] + TransactionKeyError(#[from] TransactionKeyError), + #[error("Transaction direction error: `{0}`")] + TransactionDirectionError(#[from] TransactionDirectionError), + #[error("Error converting a type: `{0}`")] OutOfRangeError(#[from] OutOfRangeError), #[error("Error converting a type: `{0}`")] - ConversionError(String), + ConversionError(#[from] TransactionConversionError), + #[error("Completed transaction conversion error: `{0}`")] + CompletedConversionError(#[from] CompletedTransactionConversionError), #[error("Serde json error: `{0}`")] SerdeJsonError(#[from] SerdeJsonError), #[error("R2d2 error")] diff --git a/base_layer/wallet/src/transaction_service/handle.rs b/base_layer/wallet/src/transaction_service/handle.rs index 852b4e89ba..0d5b279094 100644 --- a/base_layer/wallet/src/transaction_service/handle.rs +++ b/base_layer/wallet/src/transaction_service/handle.rs @@ -20,15 +20,13 @@ // 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 crate::{ - output_manager_service::TxId, - transaction_service::{ - error::TransactionServiceError, - storage::models::{CompletedTransaction, InboundTransaction, OutboundTransaction, WalletTransaction}, - }, +use crate::transaction_service::{ + error::TransactionServiceError, + storage::models::{CompletedTransaction, InboundTransaction, OutboundTransaction, WalletTransaction}, }; use aes_gcm::Aes256Gcm; use std::{collections::HashMap, fmt, sync::Arc}; +use tari_common_types::transaction::TxId; use tari_comms::types::CommsPublicKey; use tari_core::transactions::{tari_amount::MicroTari, transaction::Transaction}; use tari_service_framework::reply_channel::SenderService; diff --git a/base_layer/wallet/src/transaction_service/protocols/transaction_broadcast_protocol.rs b/base_layer/wallet/src/transaction_service/protocols/transaction_broadcast_protocol.rs index 61b83891de..ec32c5e2af 100644 --- a/base_layer/wallet/src/transaction_service/protocols/transaction_broadcast_protocol.rs +++ b/base_layer/wallet/src/transaction_service/protocols/transaction_broadcast_protocol.rs @@ -22,15 +22,11 @@ use crate::{ connectivity_service::WalletConnectivityInterface, - output_manager_service::TxId, transaction_service::{ error::{TransactionServiceError, TransactionServiceProtocolError}, handle::TransactionEvent, service::TransactionServiceResources, - storage::{ - database::TransactionBackend, - models::{CompletedTransaction, TransactionStatus}, - }, + storage::{database::TransactionBackend, models::CompletedTransaction}, }, }; use futures::FutureExt; @@ -40,7 +36,10 @@ use std::{ sync::Arc, time::{Duration, Instant}, }; -use tari_common_types::types::Signature; +use tari_common_types::{ + transaction::{TransactionStatus, TxId}, + types::Signature, +}; use tari_core::{ base_node::{ proto::wallet_rpc::{TxLocation, TxQueryResponse, TxSubmissionRejectionReason, TxSubmissionResponse}, diff --git a/base_layer/wallet/src/transaction_service/protocols/transaction_receive_protocol.rs b/base_layer/wallet/src/transaction_service/protocols/transaction_receive_protocol.rs index fe3ac75d50..8709acb120 100644 --- a/base_layer/wallet/src/transaction_service/protocols/transaction_receive_protocol.rs +++ b/base_layer/wallet/src/transaction_service/protocols/transaction_receive_protocol.rs @@ -20,23 +20,21 @@ // 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 crate::{ - output_manager_service::TxId, - transaction_service::{ - error::{TransactionServiceError, TransactionServiceProtocolError}, - handle::TransactionEvent, - service::TransactionServiceResources, - storage::{ - database::TransactionBackend, - models::{CompletedTransaction, InboundTransaction, TransactionDirection, TransactionStatus}, - }, - tasks::send_transaction_reply::send_transaction_reply, +use crate::transaction_service::{ + error::{TransactionServiceError, TransactionServiceProtocolError}, + handle::TransactionEvent, + service::TransactionServiceResources, + storage::{ + database::TransactionBackend, + models::{CompletedTransaction, InboundTransaction}, }, + tasks::send_transaction_reply::send_transaction_reply, }; use chrono::Utc; use futures::future::FutureExt; use log::*; use std::sync::Arc; +use tari_common_types::transaction::{TransactionDirection, TransactionStatus, TxId}; use tari_comms::types::CommsPublicKey; use tokio::sync::{mpsc, oneshot}; @@ -242,12 +240,7 @@ where .naive_utc() .signed_duration_since(inbound_tx.timestamp) .to_std() - .map_err(|_| { - TransactionServiceProtocolError::new( - self.id, - TransactionServiceError::ConversionError("duration::OutOfRangeError".to_string()), - ) - })?; + .map_err(|e| TransactionServiceProtocolError::new(self.id, e.into()))?; let timeout_duration = match self .resources @@ -272,12 +265,7 @@ where .naive_utc() .signed_duration_since(timestamp) .to_std() - .map_err(|_| { - TransactionServiceProtocolError::new( - self.id, - TransactionServiceError::ConversionError("duration::OutOfRangeError".to_string()), - ) - })?; + .map_err(|e| TransactionServiceProtocolError::new(self.id, e.into()))?; elapsed_time > self.resources.config.transaction_resend_period }, }; diff --git a/base_layer/wallet/src/transaction_service/protocols/transaction_send_protocol.rs b/base_layer/wallet/src/transaction_service/protocols/transaction_send_protocol.rs index c4e3db99bc..87036b199c 100644 --- a/base_layer/wallet/src/transaction_service/protocols/transaction_send_protocol.rs +++ b/base_layer/wallet/src/transaction_service/protocols/transaction_send_protocol.rs @@ -29,7 +29,7 @@ use crate::{ service::TransactionServiceResources, storage::{ database::TransactionBackend, - models::{CompletedTransaction, OutboundTransaction, TransactionDirection, TransactionStatus}, + models::{CompletedTransaction, OutboundTransaction}, }, tasks::{ send_finalized_transaction::send_finalized_transaction_message, @@ -42,6 +42,7 @@ use chrono::Utc; use futures::FutureExt; use log::*; use std::sync::Arc; +use tari_common_types::transaction::{TransactionDirection, TransactionStatus}; use tari_comms::{peer_manager::NodeId, types::CommsPublicKey}; use tari_comms_dht::{ domain_message::OutboundDomainMessage, @@ -328,12 +329,7 @@ where .naive_utc() .signed_duration_since(outbound_tx.timestamp) .to_std() - .map_err(|_| { - TransactionServiceProtocolError::new( - self.id, - TransactionServiceError::ConversionError("duration::OutOfRangeError".to_string()), - ) - })?; + .map_err(|e| TransactionServiceProtocolError::new(self.id, e.into()))?; let timeout_duration = match self .resources @@ -358,12 +354,7 @@ where .naive_utc() .signed_duration_since(timestamp) .to_std() - .map_err(|_| { - TransactionServiceProtocolError::new( - self.id, - TransactionServiceError::ConversionError("duration::OutOfRangeError".to_string()), - ) - })?; + .map_err(|e| TransactionServiceProtocolError::new(self.id, e.into()))?; elapsed_time > self.resources.config.transaction_resend_period }, }; @@ -374,7 +365,7 @@ where outbound_tx .sender_protocol .get_single_round_message() - .map_err(|e| TransactionServiceProtocolError::new(self.id, TransactionServiceError::from(e)))?, + .map_err(|e| TransactionServiceProtocolError::new(self.id, e.into()))?, ) .await { @@ -387,7 +378,7 @@ where .db .increment_send_count(self.id) .await - .map_err(|e| TransactionServiceProtocolError::new(self.id, TransactionServiceError::from(e)))?; + .map_err(|e| TransactionServiceProtocolError::new(self.id, e.into()))?; } let mut shutdown = self.resources.shutdown_signal.clone(); diff --git a/base_layer/wallet/src/transaction_service/protocols/transaction_validation_protocol.rs b/base_layer/wallet/src/transaction_service/protocols/transaction_validation_protocol.rs index 3f09efa2a3..3d758f6d77 100644 --- a/base_layer/wallet/src/transaction_service/protocols/transaction_validation_protocol.rs +++ b/base_layer/wallet/src/transaction_service/protocols/transaction_validation_protocol.rs @@ -29,7 +29,7 @@ use crate::{ handle::{TransactionEvent, TransactionEventSender}, storage::{ database::{TransactionBackend, TransactionDatabase}, - models::{CompletedTransaction, TransactionStatus}, + models::CompletedTransaction, }, }, }; @@ -39,7 +39,7 @@ use std::{ convert::{TryFrom, TryInto}, sync::Arc, }; -use tari_common_types::types::BlockHash; +use tari_common_types::{transaction::TransactionStatus, types::BlockHash}; use tari_comms::protocol::rpc::{RpcError::RequestFailed, RpcStatusCode::NotFound}; use tari_core::{ base_node::{ diff --git a/base_layer/wallet/src/transaction_service/service.rs b/base_layer/wallet/src/transaction_service/service.rs index 9ff5169477..cca61d66e9 100644 --- a/base_layer/wallet/src/transaction_service/service.rs +++ b/base_layer/wallet/src/transaction_service/service.rs @@ -23,7 +23,7 @@ use crate::{ base_node_service::handle::{BaseNodeEvent, BaseNodeServiceHandle}, connectivity_service::WalletConnectivityInterface, - output_manager_service::{handle::OutputManagerHandle, TxId}, + output_manager_service::handle::OutputManagerHandle, storage::database::{WalletBackend, WalletDatabase}, transaction_service::{ config::TransactionServiceConfig, @@ -37,7 +37,7 @@ use crate::{ }, storage::{ database::{TransactionBackend, TransactionDatabase}, - models::{CompletedTransaction, TransactionDirection, TransactionStatus}, + models::CompletedTransaction, }, tasks::{ send_finalized_transaction::send_finalized_transaction_message, @@ -60,7 +60,10 @@ use std::{ sync::Arc, time::{Duration, Instant}, }; -use tari_common_types::types::PrivateKey; +use tari_common_types::{ + transaction::{TransactionDirection, TransactionStatus, TxId}, + types::PrivateKey, +}; use tari_comms::{peer_manager::NodeIdentity, types::CommsPublicKey}; use tari_comms_dht::outbound::OutboundMessageRequester; use tari_core::{ @@ -1258,13 +1261,7 @@ where } // Check if the last reply is beyond the resend cooldown if let Some(timestamp) = inbound_tx.last_send_timestamp { - let elapsed_time = Utc::now() - .naive_utc() - .signed_duration_since(timestamp) - .to_std() - .map_err(|_| { - TransactionServiceError::ConversionError("duration::OutOfRangeError".to_string()) - })?; + let elapsed_time = Utc::now().naive_utc().signed_duration_since(timestamp).to_std()?; if elapsed_time < self.resources.config.resend_response_cooldown { trace!( target: LOG_TARGET, diff --git a/base_layer/wallet/src/transaction_service/storage/database.rs b/base_layer/wallet/src/transaction_service/storage/database.rs index 93574b9965..52e2f51292 100644 --- a/base_layer/wallet/src/transaction_service/storage/database.rs +++ b/base_layer/wallet/src/transaction_service/storage/database.rs @@ -20,18 +20,9 @@ // 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 crate::{ - output_manager_service::TxId, - transaction_service::{ - error::TransactionStorageError, - storage::models::{ - CompletedTransaction, - InboundTransaction, - OutboundTransaction, - TransactionDirection, - TransactionStatus, - }, - }, +use crate::transaction_service::{ + error::TransactionStorageError, + storage::models::{CompletedTransaction, InboundTransaction, OutboundTransaction}, }; use aes_gcm::Aes256Gcm; use chrono::Utc; @@ -44,7 +35,10 @@ use std::{ fmt::{Display, Error, Formatter}, sync::Arc, }; -use tari_common_types::types::{BlindingFactor, BlockHash}; +use tari_common_types::{ + transaction::{TransactionDirection, TransactionStatus, TxId}, + types::{BlindingFactor, BlockHash}, +}; use tari_comms::types::CommsPublicKey; use tari_core::transactions::{tari_amount::MicroTari, transaction::Transaction}; diff --git a/base_layer/wallet/src/transaction_service/storage/models.rs b/base_layer/wallet/src/transaction_service/storage/models.rs index c3fbd274b6..2125081a0b 100644 --- a/base_layer/wallet/src/transaction_service/storage/models.rs +++ b/base_layer/wallet/src/transaction_service/storage/models.rs @@ -20,14 +20,12 @@ // 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 crate::{output_manager_service::TxId, transaction_service::error::TransactionStorageError}; use chrono::NaiveDateTime; use serde::{Deserialize, Serialize}; -use std::{ - convert::TryFrom, - fmt::{Display, Error, Formatter}, +use tari_common_types::{ + transaction::{TransactionDirection, TransactionStatus, TxId}, + types::{BlockHash, PrivateKey}, }; -use tari_common_types::types::{BlockHash, PrivateKey}; use tari_comms::types::CommsPublicKey; use tari_core::transactions::{ tari_amount::MicroTari, @@ -36,65 +34,6 @@ use tari_core::transactions::{ SenderTransactionProtocol, }; -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub enum TransactionStatus { - /// This transaction has been completed between the parties but has not been broadcast to the base layer network. - Completed, - /// This transaction has been broadcast to the base layer network and is currently in one or more base node - /// mempools. - Broadcast, - /// This transaction has been mined and included in a block. - MinedUnconfirmed, - /// This transaction was generated as part of importing a spendable UTXO - Imported, - /// This transaction is still being negotiated by the parties - Pending, - /// This is a created Coinbase Transaction - Coinbase, - /// This transaction is mined and confirmed at the current base node's height - MinedConfirmed, -} - -impl TryFrom for TransactionStatus { - type Error = TransactionStorageError; - - fn try_from(value: i32) -> Result { - match value { - 0 => Ok(TransactionStatus::Completed), - 1 => Ok(TransactionStatus::Broadcast), - 2 => Ok(TransactionStatus::MinedUnconfirmed), - 3 => Ok(TransactionStatus::Imported), - 4 => Ok(TransactionStatus::Pending), - 5 => Ok(TransactionStatus::Coinbase), - 6 => Ok(TransactionStatus::MinedConfirmed), - _ => Err(TransactionStorageError::ConversionError( - "Invalid TransactionStatus".to_string(), - )), - } - } -} - -impl Default for TransactionStatus { - fn default() -> Self { - TransactionStatus::Pending - } -} - -impl Display for TransactionStatus { - fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { - // No struct or tuple variants - match self { - TransactionStatus::Completed => write!(f, "Completed"), - TransactionStatus::Broadcast => write!(f, "Broadcast"), - TransactionStatus::MinedUnconfirmed => write!(f, "Mined Unconfirmed"), - TransactionStatus::MinedConfirmed => write!(f, "Mined Confirmed"), - TransactionStatus::Imported => write!(f, "Imported"), - TransactionStatus::Pending => write!(f, "Pending"), - TransactionStatus::Coinbase => write!(f, "Coinbase"), - } - } -} - #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct InboundTransaction { pub tx_id: TxId, @@ -246,39 +185,6 @@ impl CompletedTransaction { } } -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub enum TransactionDirection { - Inbound, - Outbound, - Unknown, -} - -impl TryFrom for TransactionDirection { - type Error = TransactionStorageError; - - fn try_from(value: i32) -> Result { - match value { - 0 => Ok(TransactionDirection::Inbound), - 1 => Ok(TransactionDirection::Outbound), - 2 => Ok(TransactionDirection::Unknown), - _ => Err(TransactionStorageError::ConversionError( - "Invalid TransactionDirection".to_string(), - )), - } - } -} - -impl Display for TransactionDirection { - fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { - // No struct or tuple variants - match self { - TransactionDirection::Inbound => write!(f, "Inbound"), - TransactionDirection::Outbound => write!(f, "Outbound"), - TransactionDirection::Unknown => write!(f, "Unknown"), - } - } -} - impl From for InboundTransaction { fn from(ct: CompletedTransaction) -> Self { Self { diff --git a/base_layer/wallet/src/transaction_service/storage/sqlite_db.rs b/base_layer/wallet/src/transaction_service/storage/sqlite_db.rs index 3778f9a7c2..83c30f0c04 100644 --- a/base_layer/wallet/src/transaction_service/storage/sqlite_db.rs +++ b/base_layer/wallet/src/transaction_service/storage/sqlite_db.rs @@ -21,21 +21,13 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use crate::{ - output_manager_service::TxId, schema::{completed_transactions, inbound_transactions, outbound_transactions}, storage::sqlite_utilities::WalletDbConnection, transaction_service::{ - error::TransactionStorageError, + error::{TransactionKeyError, TransactionStorageError}, storage::{ database::{DbKey, DbKeyValuePair, DbValue, TransactionBackend, WriteOperation}, - models::{ - CompletedTransaction, - InboundTransaction, - OutboundTransaction, - TransactionDirection, - TransactionStatus, - WalletTransaction, - }, + models::{CompletedTransaction, InboundTransaction, OutboundTransaction, WalletTransaction}, }, }, util::{ @@ -53,13 +45,23 @@ use std::{ str::from_utf8, sync::{Arc, MutexGuard, RwLock}, }; -use tari_common_types::types::{BlockHash, PublicKey}; +use tari_common_types::{ + transaction::{ + TransactionConversionError, + TransactionDirection, + TransactionDirectionError, + TransactionStatus, + TxId, + }, + types::{BlockHash, PublicKey}, +}; use tari_comms::types::CommsPublicKey; use tari_core::transactions::tari_amount::MicroTari; use tari_crypto::tari_utilities::{ hex::{from_hex, Hex}, ByteArray, }; +use thiserror::Error; use tokio::time::Instant; const LOG_TARGET: &str = "wallet::transaction_service::database::sqlite_db"; @@ -876,10 +878,7 @@ impl TransactionBackend for TransactionServiceSqliteDatabase { let mut coinbase_txs = CompletedTransactionSql::index_coinbase_at_block_height(block_height as i64, &conn)?; for c in coinbase_txs.iter_mut() { self.decrypt_if_necessary(c)?; - let completed_tx = CompletedTransaction::try_from(c.clone()).map_err(|_| { - TransactionStorageError::ConversionError("Error converting to CompletedTransaction".to_string()) - })?; - + let completed_tx = CompletedTransaction::try_from(c.clone())?; if completed_tx.amount == amount { return Ok(Some(completed_tx)); } @@ -1216,8 +1215,7 @@ impl TryFrom for InboundTransaction { fn try_from(i: InboundTransactionSql) -> Result { Ok(Self { tx_id: i.tx_id as u64, - source_public_key: PublicKey::from_vec(&i.source_public_key) - .map_err(|_| TransactionStorageError::ConversionError("Invalid Source Publickey".to_string()))?, + source_public_key: PublicKey::from_vec(&i.source_public_key).map_err(TransactionKeyError::Source)?, amount: MicroTari::from(i.amount as u64), receiver_protocol: serde_json::from_str(&i.receiver_protocol)?, status: TransactionStatus::Pending, @@ -1389,7 +1387,7 @@ impl TryFrom for OutboundTransaction { Ok(Self { tx_id: o.tx_id as u64, destination_public_key: PublicKey::from_vec(&o.destination_public_key) - .map_err(|_| TransactionStorageError::ConversionError("Invalid destination PublicKey".to_string()))?, + .map_err(TransactionKeyError::Destination)?, amount: MicroTari::from(o.amount as u64), fee: MicroTari::from(o.fee as u64), sender_protocol: serde_json::from_str(&o.sender_protocol)?, @@ -1643,16 +1641,27 @@ impl TryFrom for CompletedTransactionSql { } } +#[derive(Debug, Error)] +pub enum CompletedTransactionConversionError { + #[error("CompletedTransaction conversion failed by wrong direction: {0}")] + DirectionError(#[from] TransactionDirectionError), + #[error("CompletedTransaction conversion failed with transaction conversion: {0}")] + ConversionError(#[from] TransactionConversionError), + #[error("CompletedTransaction conversion failed with json error: {0}")] + JsonError(#[from] serde_json::Error), + #[error("CompletedTransaction conversion failed with key error: {0}")] + KeyError(#[from] TransactionKeyError), +} + impl TryFrom for CompletedTransaction { - type Error = TransactionStorageError; + type Error = CompletedTransactionConversionError; fn try_from(c: CompletedTransactionSql) -> Result { Ok(Self { tx_id: c.tx_id as u64, - source_public_key: PublicKey::from_vec(&c.source_public_key) - .map_err(|_| TransactionStorageError::ConversionError("Invalid source Publickey".to_string()))?, + source_public_key: PublicKey::from_vec(&c.source_public_key).map_err(TransactionKeyError::Source)?, destination_public_key: PublicKey::from_vec(&c.destination_public_key) - .map_err(|_| TransactionStorageError::ConversionError("Invalid destination PublicKey".to_string()))?, + .map_err(TransactionKeyError::Destination)?, amount: MicroTari::from(c.amount as u64), fee: MicroTari::from(c.fee as u64), transaction: serde_json::from_str(&c.transaction_protocol)?, @@ -1706,7 +1715,10 @@ mod test { }; use tempfile::tempdir; - use tari_common_types::types::{HashDigest, PrivateKey, PublicKey}; + use tari_common_types::{ + transaction::{TransactionDirection, TransactionStatus}, + types::{HashDigest, PrivateKey, PublicKey}, + }; use tari_core::transactions::{ helpers::{create_unblinded_output, TestParams}, tari_amount::MicroTari, @@ -1722,13 +1734,7 @@ mod test { storage::sqlite_utilities::WalletDbConnection, transaction_service::storage::{ database::{DbKey, TransactionBackend}, - models::{ - CompletedTransaction, - InboundTransaction, - OutboundTransaction, - TransactionDirection, - TransactionStatus, - }, + models::{CompletedTransaction, InboundTransaction, OutboundTransaction}, sqlite_db::{ CompletedTransactionSql, InboundTransactionSql, diff --git a/base_layer/wallet/src/transaction_service/tasks/send_finalized_transaction.rs b/base_layer/wallet/src/transaction_service/tasks/send_finalized_transaction.rs index db28a7db58..cf723bbfad 100644 --- a/base_layer/wallet/src/transaction_service/tasks/send_finalized_transaction.rs +++ b/base_layer/wallet/src/transaction_service/tasks/send_finalized_transaction.rs @@ -19,16 +19,14 @@ // 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 crate::{ - output_manager_service::TxId, - transaction_service::{ - config::TransactionRoutingMechanism, - error::TransactionServiceError, - tasks::wait_on_dial::wait_on_dial, - }, +use crate::transaction_service::{ + config::TransactionRoutingMechanism, + error::TransactionServiceError, + tasks::wait_on_dial::wait_on_dial, }; use log::*; use std::time::Duration; +use tari_common_types::transaction::TxId; use tari_comms::{peer_manager::NodeId, types::CommsPublicKey}; use tari_comms_dht::{ domain_message::OutboundDomainMessage, diff --git a/base_layer/wallet/src/transaction_service/tasks/send_transaction_cancelled.rs b/base_layer/wallet/src/transaction_service/tasks/send_transaction_cancelled.rs index 326093d986..f7049db69a 100644 --- a/base_layer/wallet/src/transaction_service/tasks/send_transaction_cancelled.rs +++ b/base_layer/wallet/src/transaction_service/tasks/send_transaction_cancelled.rs @@ -19,7 +19,8 @@ // 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 crate::{output_manager_service::TxId, transaction_service::error::TransactionServiceError}; +use crate::transaction_service::error::TransactionServiceError; +use tari_common_types::transaction::TxId; use tari_comms::{peer_manager::NodeId, types::CommsPublicKey}; use tari_comms_dht::{ domain_message::OutboundDomainMessage, diff --git a/base_layer/wallet/src/transaction_service/tasks/send_transaction_reply.rs b/base_layer/wallet/src/transaction_service/tasks/send_transaction_reply.rs index fb9a44b5d2..adc26c4ab2 100644 --- a/base_layer/wallet/src/transaction_service/tasks/send_transaction_reply.rs +++ b/base_layer/wallet/src/transaction_service/tasks/send_transaction_reply.rs @@ -20,7 +20,6 @@ // 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 crate::output_manager_service::TxId; use log::*; use tari_comms_dht::{domain_message::OutboundDomainMessage, outbound::SendMessageResponse}; use tari_p2p::tari_message::TariMessageType; @@ -32,6 +31,7 @@ use crate::transaction_service::{ tasks::wait_on_dial::wait_on_dial, }; use std::time::Duration; +use tari_common_types::transaction::TxId; use tari_comms::{peer_manager::NodeId, types::CommsPublicKey}; use tari_comms_dht::outbound::{OutboundEncryption, OutboundMessageRequester}; use tari_core::transactions::transaction_protocol::proto; diff --git a/base_layer/wallet/src/transaction_service/tasks/wait_on_dial.rs b/base_layer/wallet/src/transaction_service/tasks/wait_on_dial.rs index d9c6328dbb..9d881701e4 100644 --- a/base_layer/wallet/src/transaction_service/tasks/wait_on_dial.rs +++ b/base_layer/wallet/src/transaction_service/tasks/wait_on_dial.rs @@ -20,9 +20,9 @@ // 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 crate::output_manager_service::TxId; use log::*; use std::time::Duration; +use tari_common_types::transaction::TxId; use tari_comms::types::CommsPublicKey; use tari_comms_dht::outbound::MessageSendStates; diff --git a/base_layer/wallet/src/utxo_scanner_service/utxo_scanning.rs b/base_layer/wallet/src/utxo_scanner_service/utxo_scanning.rs index c12d1bdcce..d5afe96fd1 100644 --- a/base_layer/wallet/src/utxo_scanner_service/utxo_scanning.rs +++ b/base_layer/wallet/src/utxo_scanner_service/utxo_scanning.rs @@ -35,7 +35,7 @@ use log::*; use serde::{Deserialize, Serialize}; use tokio::{sync::broadcast, task, time}; -use tari_common_types::types::HashOutput; +use tari_common_types::{transaction::TxId, types::HashOutput}; use tari_comms::{ peer_manager::NodeId, protocol::rpc::{RpcError, RpcStatus}, @@ -61,7 +61,7 @@ use tari_shutdown::ShutdownSignal; use crate::{ connectivity_service::WalletConnectivityInterface, error::WalletError, - output_manager_service::{handle::OutputManagerHandle, TxId}, + output_manager_service::handle::OutputManagerHandle, storage::{ database::{WalletBackend, WalletDatabase}, sqlite_db::WalletSqliteDatabase, diff --git a/base_layer/wallet/src/wallet.rs b/base_layer/wallet/src/wallet.rs index 01c55ab3e6..ab34f91a9d 100644 --- a/base_layer/wallet/src/wallet.rs +++ b/base_layer/wallet/src/wallet.rs @@ -76,7 +76,6 @@ use crate::{ handle::OutputManagerHandle, storage::{database::OutputManagerBackend, models::KnownOneSidedPaymentScript}, OutputManagerServiceInitializer, - TxId, }, storage::database::{WalletBackend, WalletDatabase}, transaction_service::{ @@ -87,6 +86,7 @@ use crate::{ types::KeyDigest, utxo_scanner_service::{handle::UtxoScannerHandle, UtxoScannerServiceInitializer}, }; +use tari_common_types::transaction::TxId; const LOG_TARGET: &str = "wallet"; diff --git a/base_layer/wallet/tests/output_manager_service/service.rs b/base_layer/wallet/tests/output_manager_service/service.rs index 46f781d45c..4fec5916c5 100644 --- a/base_layer/wallet/tests/output_manager_service/service.rs +++ b/base_layer/wallet/tests/output_manager_service/service.rs @@ -26,7 +26,10 @@ use crate::support::{ }; use rand::{rngs::OsRng, RngCore}; use std::{collections::HashMap, sync::Arc, time::Duration}; -use tari_common_types::types::{PrivateKey, PublicKey}; +use tari_common_types::{ + transaction::TxId, + types::{PrivateKey, PublicKey}, +}; use tari_comms::{ peer_manager::{NodeIdentity, PeerFeatures}, protocol::rpc::{mock::MockRpcServer, NamedProtocolService}, @@ -75,7 +78,6 @@ use tari_wallet::{ database::{OutputManagerBackend, OutputManagerDatabase}, sqlite_db::OutputManagerSqliteDatabase, }, - TxId, }, transaction_service::handle::TransactionServiceHandle, }; diff --git a/base_layer/wallet/tests/transaction_service/service.rs b/base_layer/wallet/tests/transaction_service/service.rs index b7cff07ba9..64b8254189 100644 --- a/base_layer/wallet/tests/transaction_service/service.rs +++ b/base_layer/wallet/tests/transaction_service/service.rs @@ -42,6 +42,7 @@ use std::{ }; use tari_common_types::{ chain_metadata::ChainMetadata, + transaction::{TransactionDirection, TransactionStatus}, types::{PrivateKey, PublicKey, Signature}, }; use tari_comms::{ @@ -137,13 +138,7 @@ use tari_wallet::{ service::TransactionService, storage::{ database::{DbKeyValuePair, TransactionBackend, TransactionDatabase, WriteOperation}, - models::{ - CompletedTransaction, - InboundTransaction, - OutboundTransaction, - TransactionDirection, - TransactionStatus, - }, + models::{CompletedTransaction, InboundTransaction, OutboundTransaction}, sqlite_db::TransactionServiceSqliteDatabase, }, TransactionServiceInitializer, diff --git a/base_layer/wallet/tests/transaction_service/storage.rs b/base_layer/wallet/tests/transaction_service/storage.rs index 662c265eb7..b0262ef810 100644 --- a/base_layer/wallet/tests/transaction_service/storage.rs +++ b/base_layer/wallet/tests/transaction_service/storage.rs @@ -34,7 +34,10 @@ use tari_crypto::{ use tempfile::tempdir; use tokio::runtime::Runtime; -use tari_common_types::types::{HashDigest, PrivateKey, PublicKey}; +use tari_common_types::{ + transaction::{TransactionDirection, TransactionStatus}, + types::{HashDigest, PrivateKey, PublicKey}, +}; use tari_core::transactions::{ helpers::{create_unblinded_output, TestParams}, tari_amount::{uT, MicroTari}, @@ -49,14 +52,7 @@ use tari_wallet::{ storage::sqlite_utilities::run_migration_and_create_sqlite_connection, transaction_service::storage::{ database::{TransactionBackend, TransactionDatabase}, - models::{ - CompletedTransaction, - InboundTransaction, - OutboundTransaction, - TransactionDirection, - TransactionStatus, - WalletTransaction, - }, + models::{CompletedTransaction, InboundTransaction, OutboundTransaction, WalletTransaction}, sqlite_db::TransactionServiceSqliteDatabase, }, }; diff --git a/base_layer/wallet/tests/transaction_service/transaction_protocols.rs b/base_layer/wallet/tests/transaction_service/transaction_protocols.rs index f8582a3b85..a0b3e8b3d1 100644 --- a/base_layer/wallet/tests/transaction_service/transaction_protocols.rs +++ b/base_layer/wallet/tests/transaction_service/transaction_protocols.rs @@ -28,6 +28,7 @@ use chrono::Utc; use futures::StreamExt; use rand::rngs::OsRng; use std::{collections::HashMap, sync::Arc, time::Duration}; +use tari_common_types::transaction::{TransactionDirection, TransactionStatus, TxId}; use tari_comms::{ peer_manager::PeerFeatures, protocol::rpc::{mock::MockRpcServer, NamedProtocolService}, @@ -66,7 +67,6 @@ use tari_wallet::{ output_manager_service::{ error::OutputManagerError, handle::{OutputManagerHandle, OutputManagerRequest, OutputManagerResponse}, - TxId, }, storage::sqlite_utilities::run_migration_and_create_sqlite_connection, transaction_service::{ @@ -80,7 +80,7 @@ use tari_wallet::{ service::TransactionServiceResources, storage::{ database::TransactionDatabase, - models::{CompletedTransaction, TransactionDirection, TransactionStatus}, + models::CompletedTransaction, sqlite_db::TransactionServiceSqliteDatabase, }, }, diff --git a/base_layer/wallet_ffi/src/callback_handler.rs b/base_layer/wallet_ffi/src/callback_handler.rs index 42067d555a..dff1e1c175 100644 --- a/base_layer/wallet_ffi/src/callback_handler.rs +++ b/base_layer/wallet_ffi/src/callback_handler.rs @@ -49,14 +49,12 @@ //! and false that the process timed out and new one will be started use log::*; +use tari_common_types::transaction::TxId; use tari_comms::types::CommsPublicKey; use tari_comms_dht::event::{DhtEvent, DhtEventReceiver}; use tari_shutdown::ShutdownSignal; use tari_wallet::{ - output_manager_service::{ - handle::{OutputManagerEvent, OutputManagerEventReceiver}, - TxId, - }, + output_manager_service::handle::{OutputManagerEvent, OutputManagerEventReceiver}, transaction_service::{ handle::{TransactionEvent, TransactionEventReceiver}, storage::{ @@ -520,7 +518,10 @@ mod test { thread, time::Duration, }; - use tari_common_types::types::{BlindingFactor, PrivateKey, PublicKey}; + use tari_common_types::{ + transaction::{TransactionDirection, TransactionStatus}, + types::{BlindingFactor, PrivateKey, PublicKey}, + }; use tari_comms_dht::event::DhtEvent; use tari_core::transactions::{ tari_amount::{uT, MicroTari}, @@ -537,13 +538,7 @@ mod test { handle::TransactionEvent, storage::{ database::TransactionDatabase, - models::{ - CompletedTransaction, - InboundTransaction, - OutboundTransaction, - TransactionDirection, - TransactionStatus, - }, + models::{CompletedTransaction, InboundTransaction, OutboundTransaction}, sqlite_db::TransactionServiceSqliteDatabase, }, }, diff --git a/base_layer/wallet_ffi/src/lib.rs b/base_layer/wallet_ffi/src/lib.rs index 571561e48c..dd9c52c7c4 100644 --- a/base_layer/wallet_ffi/src/lib.rs +++ b/base_layer/wallet_ffi/src/lib.rs @@ -146,6 +146,7 @@ use tokio::runtime::Runtime; use error::LibWalletError; use tari_common_types::{ emoji::{emoji_set, EmojiId, EmojiIdError}, + transaction::{TransactionDirection, TransactionStatus}, types::{ComSignature, PublicKey}, }; use tari_comms::{ @@ -176,13 +177,7 @@ use tari_wallet::{ error::TransactionServiceError, storage::{ database::TransactionDatabase, - models::{ - CompletedTransaction, - InboundTransaction, - OutboundTransaction, - TransactionDirection, - TransactionStatus, - }, + models::{CompletedTransaction, InboundTransaction, OutboundTransaction}, }, }, utxo_scanner_service::utxo_scanning::{UtxoScannerService, RECOVERY_KEY}, @@ -5152,12 +5147,9 @@ mod test { use libc::{c_char, c_uchar, c_uint}; use tempfile::tempdir; - use tari_common_types::emoji; + use tari_common_types::{emoji, transaction::TransactionStatus}; use tari_test_utils::random; - use tari_wallet::{ - storage::sqlite_utilities::run_migration_and_create_sqlite_connection, - transaction_service::storage::models::TransactionStatus, - }; + use tari_wallet::storage::sqlite_utilities::run_migration_and_create_sqlite_connection; use crate::*; diff --git a/common/Cargo.toml b/common/Cargo.toml index 0aff89b6e0..9e9033bb12 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -38,6 +38,7 @@ anyhow = { version = "1.0", optional = true } git2 = { version = "0.8", optional = true } prost-build = { version = "0.8.0", optional = true } toml = { version = "0.5", optional = true } +thiserror = "1.0.29" [dev-dependencies] tari_test_utils = { version = "^0.11", path = "../infrastructure/test_utils"} diff --git a/common/src/exit_codes.rs b/common/src/exit_codes.rs new file mode 100644 index 0000000000..ffd4790406 --- /dev/null +++ b/common/src/exit_codes.rs @@ -0,0 +1,93 @@ +use thiserror::Error; + +/// Enum to show failure information +#[derive(Debug, Clone, Error)] +pub enum ExitCodes { + #[error("There is an error in the wallet configuration: {0}")] + ConfigError(String), + #[error("The application exited because an unknown error occurred: {0}. Check the logs for more details.")] + UnknownError(String), + #[error("The application exited because an interface error occurred. Check the logs for details.")] + InterfaceError, + #[error("The application exited. {0}")] + WalletError(String), + #[error("The wallet was not able to start the GRPC server. {0}")] + GrpcError(String), + #[error("The application did not accept the command input: {0}")] + InputError(String), + #[error("Invalid command: {0}")] + CommandError(String), + #[error("IO error: {0}")] + IOError(String), + #[error("Recovery failed: {0}")] + RecoveryError(String), + #[error("The wallet exited because of an internal network error: {0}")] + NetworkError(String), + #[error("The wallet exited because it received a message it could not interpret: {0}")] + ConversionError(String), + #[error("Your password was incorrect.")] + IncorrectPassword, + #[error("Your application is encrypted but no password was provided.")] + NoPassword, + #[error("Tor connection is offline")] + TorOffline, + #[error("Database is in inconsistent state: {0}")] + DbInconsistentState(String), +} + +impl ExitCodes { + pub fn as_i32(&self) -> i32 { + match self { + Self::ConfigError(_) => 101, + Self::UnknownError(_) => 102, + Self::InterfaceError => 103, + Self::WalletError(_) => 104, + Self::GrpcError(_) => 105, + Self::InputError(_) => 106, + Self::CommandError(_) => 107, + Self::IOError(_) => 108, + Self::RecoveryError(_) => 109, + Self::NetworkError(_) => 110, + Self::ConversionError(_) => 111, + Self::IncorrectPassword | Self::NoPassword => 112, + Self::TorOffline => 113, + Self::DbInconsistentState(_) => 115, + } + } + + pub fn eprint_details(&self) { + use ExitCodes::*; + match self { + TorOffline => { + eprintln!("Unable to connect to the Tor control port."); + eprintln!( + "Please check that you have the Tor proxy running and that access to the Tor control port is \ + turned on.", + ); + eprintln!("If you are unsure of what to do, use the following command to start the Tor proxy:"); + eprintln!( + "tor --allow-missing-torrc --ignore-missing-torrc --clientonly 1 --socksport 9050 --controlport \ + 127.0.0.1:9051 --log \"notice stdout\" --clientuseipv6 1", + ); + }, + + e => { + eprintln!("{}", e); + }, + } + } +} + +impl From for ExitCodes { + fn from(err: super::ConfigError) -> Self { + // TODO: Move it out + // error!(target: LOG_TARGET, "{}", err); + Self::ConfigError(err.to_string()) + } +} + +impl ExitCodes { + pub fn grpc(err: M) -> Self { + ExitCodes::GrpcError(format!("GRPC connection error: {}", err)) + } +} diff --git a/common/src/lib.rs b/common/src/lib.rs index cb2c99d0c1..12a47d62fd 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -78,6 +78,7 @@ #[cfg(any(feature = "build", feature = "static-application-info"))] pub mod build; +pub mod exit_codes; #[macro_use] mod logging; diff --git a/comms/Cargo.toml b/comms/Cargo.toml index 60c3abb410..b7015b8f1d 100644 --- a/comms/Cargo.toml +++ b/comms/Cargo.toml @@ -10,6 +10,7 @@ version = "0.11.0" edition = "2018" [dependencies] +tari_common = { path = "../common" } tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", branch = "main" } tari_storage = { version = "^0.11", path = "../infrastructure/storage" } tari_shutdown = { version = "^0.11", path = "../infrastructure/shutdown" } diff --git a/comms/src/peer_manager/error.rs b/comms/src/peer_manager/error.rs index 07db078b4f..5f5a493e31 100644 --- a/comms/src/peer_manager/error.rs +++ b/comms/src/peer_manager/error.rs @@ -21,6 +21,7 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE use std::sync::PoisonError; +use tari_common::exit_codes::ExitCodes; use tari_storage::KeyValStoreError; use thiserror::Error; @@ -36,6 +37,12 @@ pub enum PeerManagerError { MigrationError(String), } +impl From for ExitCodes { + fn from(err: PeerManagerError) -> Self { + ExitCodes::NetworkError(err.to_string()) + } +} + impl PeerManagerError { /// Returns true if this error indicates that the peer is not found, otherwise false pub fn is_peer_not_found(&self) -> bool {