From 24c193f7af26ae98ddfec2bcc66c927547eab86a Mon Sep 17 00:00:00 2001 From: Mike the Tike Date: Fri, 19 Nov 2021 16:53:34 +0200 Subject: [PATCH 1/6] add get balance call --- Cargo.lock | 13 + applications/tari_app_grpc/build.rs | 1 + .../tari_app_grpc/proto/validator_node.proto | 15 +- .../tari_collectibles/src-tauri/Cargo.toml | 3 + .../2021-11-10-113031_init_schema/down.sql | 1 - .../2021-11-10-113031_init_schema/up.sql | 9 - .../2021-11-15-124424_wallet/up.sql | 42 +++- .../src-tauri/src/app_state.rs | 5 +- .../src/clients/validator_node_client.rs | 26 ++ .../{accounts => asset_wallets}/mod.rs | 82 ++++-- .../src-tauri/src/commands/mod.rs | 2 +- .../src-tauri/src/commands/wallets/mod.rs | 28 +-- .../tari_collectibles/src-tauri/src/main.rs | 6 +- .../src-tauri/src/models/mod.rs | 2 - .../src-tauri/src/providers/mod.rs | 21 ++ .../tari_collectibles/src-tauri/src/schema.rs | 53 +++- .../src-tauri/src/storage/mod.rs | 40 ++- .../models/asset_row.rs} | 12 +- .../src-tauri/src/storage/models/mod.rs | 24 ++ .../src/storage/models/wallet_row.rs | 32 +++ .../src-tauri/src/storage/sqlite/mod.rs | 238 +----------------- .../src/storage/sqlite/models/address.rs | 33 +++ .../sqlite/models/{account.rs => asset.rs} | 2 +- .../src/storage/sqlite/models/asset_wallet.rs | 31 +++ .../src/storage/sqlite/models/mod.rs | 10 +- .../storage/sqlite/models/tip002_address.rs | 30 +++ .../sqlite/sqlite_addresses_table_gateway.rs | 27 ++ .../sqlite_asset_wallets_table_gateway.rs | 27 ++ .../sqlite/sqlite_assets_table_gateway.rs | 115 +++++++++ .../sqlite/sqlite_collectibles_storage.rs | 83 ++++++ .../src/storage/sqlite/sqlite_db_factory.rs | 65 +++++ .../sqlite_issued_assets_table_gateway.rs | 27 ++ .../sqlite_tip002_addresses_table_gateway.rs | 27 ++ .../sqlite/sqlite_wallets_table_gateway.rs | 112 +++++++++ .../tari_collectibles/src-tauri/temp.sqlite | Bin 0 -> 69632 bytes .../web-app/public/proto/tip002.proto | 32 ++- .../web-app/src/AccountDashboard.js | 25 +- .../tari_collectibles/web-app/src/App.js | 14 +- .../tari_collectibles/web-app/src/Create.js | 2 +- .../web-app/src/NewAccount.js | 2 +- .../tari_collectibles/web-app/src/binding.js | 17 +- .../proto/p2p/dan_consensus.proto | 2 +- .../proto/p2p/validator_node.proto | 2 +- .../src/grpc/validator_node_grpc_server.rs | 10 + dan_layer/common_types/Cargo.toml | 13 + dan_layer/{core => common_types}/build.rs | 0 .../proto/tips/tip002.proto | 30 ++- .../common_types/proto/tips/tip721.proto | 15 ++ dan_layer/common_types/src/lib.rs | 1 + .../src}/proto/mod.rs | 0 dan_layer/core/Cargo.toml | 1 + dan_layer/core/src/models/instruction.rs | 17 +- .../core/src/services/asset_processor.rs | 4 +- dan_layer/core/src/templates/mod.rs | 1 - .../core/src/templates/tip002_template.rs | 8 +- 55 files changed, 1075 insertions(+), 365 deletions(-) delete mode 100644 applications/tari_collectibles/src-tauri/migrations/2021-11-10-113031_init_schema/down.sql delete mode 100644 applications/tari_collectibles/src-tauri/migrations/2021-11-10-113031_init_schema/up.sql rename applications/tari_collectibles/src-tauri/src/commands/{accounts => asset_wallets}/mod.rs (59%) create mode 100644 applications/tari_collectibles/src-tauri/src/providers/mod.rs rename applications/tari_collectibles/src-tauri/src/{models/account.rs => storage/models/asset_row.rs} (87%) create mode 100644 applications/tari_collectibles/src-tauri/src/storage/models/mod.rs create mode 100644 applications/tari_collectibles/src-tauri/src/storage/models/wallet_row.rs create mode 100644 applications/tari_collectibles/src-tauri/src/storage/sqlite/models/address.rs rename applications/tari_collectibles/src-tauri/src/storage/sqlite/models/{account.rs => asset.rs} (98%) create mode 100644 applications/tari_collectibles/src-tauri/src/storage/sqlite/models/asset_wallet.rs create mode 100644 applications/tari_collectibles/src-tauri/src/storage/sqlite/models/tip002_address.rs create mode 100644 applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_addresses_table_gateway.rs create mode 100644 applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs create mode 100644 applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs create mode 100644 applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_collectibles_storage.rs create mode 100644 applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_db_factory.rs create mode 100644 applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_issued_assets_table_gateway.rs create mode 100644 applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_tip002_addresses_table_gateway.rs create mode 100644 applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs create mode 100644 applications/tari_collectibles/src-tauri/temp.sqlite create mode 100644 dan_layer/common_types/Cargo.toml rename dan_layer/{core => common_types}/build.rs (100%) rename dan_layer/{core => common_types}/proto/tips/tip002.proto (54%) create mode 100644 dan_layer/common_types/proto/tips/tip721.proto create mode 100644 dan_layer/common_types/src/lib.rs rename dan_layer/{core/src/templates => common_types/src}/proto/mod.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 504a7e4164..bea8ae7442 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6100,12 +6100,15 @@ dependencies = [ "diesel", "diesel_migrations", "futures 0.3.17", + "prost", + "prost-types", "rand 0.8.4", "serde 1.0.130", "serde_json", "tari_app_grpc", "tari_common_types", "tari_crypto", + "tari_dan_common_types", "tari_key_manager", "tari_mmr", "tari_utilities", @@ -6397,6 +6400,15 @@ dependencies = [ "thiserror", ] +[[package]] +name = "tari_dan_common_types" +version = "0.1.0" +dependencies = [ + "prost", + "prost-types", + "tari_common", +] + [[package]] name = "tari_dan_core" version = "0.1.0" @@ -6421,6 +6433,7 @@ dependencies = [ "tari_comms_rpc_macros", "tari_core", "tari_crypto", + "tari_dan_common_types", "tari_mmr", "tari_p2p", "tari_service_framework", diff --git a/applications/tari_app_grpc/build.rs b/applications/tari_app_grpc/build.rs index bff25c2e61..740658034b 100644 --- a/applications/tari_app_grpc/build.rs +++ b/applications/tari_app_grpc/build.rs @@ -11,5 +11,6 @@ fn main() -> Result<(), Box> { ], &["proto"], )?; + Ok(()) } diff --git a/applications/tari_app_grpc/proto/validator_node.proto b/applications/tari_app_grpc/proto/validator_node.proto index bda36b219f..218ff1c817 100644 --- a/applications/tari_app_grpc/proto/validator_node.proto +++ b/applications/tari_app_grpc/proto/validator_node.proto @@ -28,6 +28,7 @@ service ValidatorNode { rpc GetMetadata(GetMetadataRequest) returns (GetMetadataResponse); rpc GetTokenData(GetTokenDataRequest) returns (GetTokenDataResponse); rpc ExecuteInstruction(ExecuteInstructionRequest) returns (ExecuteInstructionResponse); + rpc InvokeReadMethod(InvokeReadMethodRequest) returns (InvokeReadMethodResponse); } message GetMetadataRequest { @@ -57,11 +58,23 @@ message ExecuteInstructionRequest{ bytes asset_public_key = 1; uint32 template_id = 2; string method = 3; - repeated bytes args = 4; + bytes args = 4; // bytes token_id = 5; // bytes signature = 6; } message ExecuteInstructionResponse { string status = 1; + optional bytes result = 2; } + +message InvokeReadMethodRequest{ + bytes asset_public_key = 1; + uint32 template_id = 2; + string method = 3; + bytes args = 4; +} + +message InvokeReadMethodResponse { + optional bytes result = 1; +} \ No newline at end of file diff --git a/applications/tari_collectibles/src-tauri/Cargo.toml b/applications/tari_collectibles/src-tauri/Cargo.toml index 9fe17342d2..74cb780f47 100644 --- a/applications/tari_collectibles/src-tauri/Cargo.toml +++ b/applications/tari_collectibles/src-tauri/Cargo.toml @@ -21,6 +21,7 @@ tari_crypto = { git = "https://github.com/tari-project/tari-crypto.git", branch tari_key_manager = { path = "../../../base_layer/key_manager" } tari_mmr = { path = "../../../base_layer/mmr"} tari_utilities = "*" +tari_dan_common_types = { path = "../../../dan_layer/common_types"} blake2 = "^0.9.0" futures = "0.3.17" @@ -33,6 +34,8 @@ diesel = { version = "1.4.8", features = ["sqlite"] } diesel_migrations = "1.4.0" thiserror = "1.0.30" uuid = { version = "0.8.2", features = ["serde"] } +prost = "0.8" +prost-types = "0.8" [features] default = [ "custom-protocol" ] diff --git a/applications/tari_collectibles/src-tauri/migrations/2021-11-10-113031_init_schema/down.sql b/applications/tari_collectibles/src-tauri/migrations/2021-11-10-113031_init_schema/down.sql deleted file mode 100644 index 3af2f77426..0000000000 --- a/applications/tari_collectibles/src-tauri/migrations/2021-11-10-113031_init_schema/down.sql +++ /dev/null @@ -1 +0,0 @@ --- lol, no \ No newline at end of file diff --git a/applications/tari_collectibles/src-tauri/migrations/2021-11-10-113031_init_schema/up.sql b/applications/tari_collectibles/src-tauri/migrations/2021-11-10-113031_init_schema/up.sql deleted file mode 100644 index f764251842..0000000000 --- a/applications/tari_collectibles/src-tauri/migrations/2021-11-10-113031_init_schema/up.sql +++ /dev/null @@ -1,9 +0,0 @@ -create table accounts ( - id blob not null primary key, - asset_public_key blob not null unique, - name text, - description text, - image text, - committee_length integer not null, - committee_pub_keys blob not null -); \ No newline at end of file diff --git a/applications/tari_collectibles/src-tauri/migrations/2021-11-15-124424_wallet/up.sql b/applications/tari_collectibles/src-tauri/migrations/2021-11-15-124424_wallet/up.sql index a04d981226..1502e896f5 100644 --- a/applications/tari_collectibles/src-tauri/migrations/2021-11-15-124424_wallet/up.sql +++ b/applications/tari_collectibles/src-tauri/migrations/2021-11-15-124424_wallet/up.sql @@ -1,6 +1,44 @@ --- Your SQL goes here +create table assets ( + id blob not null primary key, + asset_public_key blob not null unique, + name text, + description text, + image text, + committee_length integer not null, + committee_pub_keys blob not null +); + create table wallets ( id blob not null primary key, name text, cipher_seed blob not null unique -); \ No newline at end of file +); + +create table asset_wallets ( + id blob not null primary key, + asset_id blob not null references assets(id), + wallet_id blob not null references wallets(id) +); + +create table addresses ( + id blob not null primary key, + asset_wallet_id blob not null references asset_wallets (id), + name text, + public_key blob not null, + key_manager_path TEXT not null + ); + +create table tip002_address ( + id blob not null primary key, + address_id blob not null references addresses(id), + balance bigint not null +); + +create table issued_assets ( + id blob not null primary key, + wallet_id blob not null references wallets (id), + public_key blob not null, + key_manager_path text not null, + is_draft boolean not null +); + diff --git a/applications/tari_collectibles/src-tauri/src/app_state.rs b/applications/tari_collectibles/src-tauri/src/app_state.rs index 6274adb2cc..b23e3da2ff 100644 --- a/applications/tari_collectibles/src-tauri/src/app_state.rs +++ b/applications/tari_collectibles/src-tauri/src/app_state.rs @@ -74,10 +74,7 @@ impl ConcurrentAppState { Ok(client) } - pub async fn connect_validator_node_client( - &self, - _public_key: PublicKey, - ) -> Result { + pub async fn connect_validator_node_client(&self) -> Result { // todo: convert this GRPC to tari comms let lock = self.inner.read().await; let client = GrpcValidatorNodeClient::connect(format!( diff --git a/applications/tari_collectibles/src-tauri/src/clients/validator_node_client.rs b/applications/tari_collectibles/src-tauri/src/clients/validator_node_client.rs index 5beabd74fe..76e17511a6 100644 --- a/applications/tari_collectibles/src-tauri/src/clients/validator_node_client.rs +++ b/applications/tari_collectibles/src-tauri/src/clients/validator_node_client.rs @@ -20,6 +20,8 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use tari_app_grpc::tari_rpc as grpc; +use tari_common_types::types::PublicKey; +use tari_utilities::ByteArray; pub trait ValidatorNodeClient {} @@ -41,4 +43,28 @@ impl GrpcValidatorNodeClient { }; Ok(s) } + + pub async fn invoke_read_method( + &mut self, + asset_public_key: PublicKey, + template_id: u32, + method: String, + args: Vec, + ) -> Result>, String> { + let req = grpc::InvokeReadMethodRequest { + asset_public_key: Vec::from(asset_public_key.as_bytes()), + template_id, + method, + args, + }; + dbg!(&req); + let response = self + .client + .invoke_read_method(req) + .await + .map(|resp| resp.into_inner()) + .map_err(|s| format!("Could not invoke read method: {}", s))?; + dbg!(&response); + Ok(response.result) + } } diff --git a/applications/tari_collectibles/src-tauri/src/commands/accounts/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs similarity index 59% rename from applications/tari_collectibles/src-tauri/src/commands/accounts/mod.rs rename to applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs index b5df2e7c78..ac3c454332 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/accounts/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs @@ -21,21 +21,27 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use crate::{ app_state::ConcurrentAppState, - models::{Account, NewAccount, NewWallet, Wallet}, - storage::{AccountsTableGateway, CollectiblesStorage, WalletsTableGateway}, + models::{NewWallet, Wallet}, + storage::{ + models::asset_row::AssetRow, AssetsTableGateway, CollectiblesStorage, WalletsTableGateway, + }, }; +use prost::Message; use tari_common_types::types::PublicKey; -use tari_utilities::hex::Hex; +use tari_dan_common_types::proto::tips::tip002; +use tari_utilities::{hex::Hex, ByteArray}; +use uuid::Uuid; #[tauri::command] -pub(crate) async fn accounts_create( - asset_pub_key: String, +pub(crate) async fn asset_wallets_create( + asset_public_key: String, state: tauri::State<'_, ConcurrentAppState>, -) -> Result { - let asset_pub_key = - PublicKey::from_hex(asset_pub_key.as_str()).map_err(|e| format!("Invalid public key:{}", e))?; - let mut new_account = NewAccount { - asset_public_key: asset_pub_key.clone(), +) -> Result<(), String> { + let asset_public_key = PublicKey::from_hex(asset_public_key.as_str()) + .map_err(|e| format!("Invalid public key:{}", e))?; + let mut new_account = AssetRow { + id: Uuid::new_v4(), + asset_public_key: asset_public_key.clone(), name: None, description: None, image: None, @@ -43,12 +49,12 @@ pub(crate) async fn accounts_create( }; let mut client = state.connect_base_node_client().await?; - let chain_registration_data = client.get_asset_metadata(&asset_pub_key).await?; + let chain_registration_data = client.get_asset_metadata(&asset_public_key).await?; new_account.name = chain_registration_data.name.clone(); new_account.description = chain_registration_data.description.clone(); new_account.image = chain_registration_data.image.clone(); - let sidechain_committee = match client.get_sidechain_committee(&asset_pub_key).await { + let sidechain_committee = match client.get_sidechain_committee(&asset_public_key).await { Ok(s) => { if s.is_empty() { None @@ -63,26 +69,66 @@ pub(crate) async fn accounts_create( }; new_account.committee = sidechain_committee; - let result = state + state .create_db() .await .map_err(|e| format!("Could not connect to DB:{}", e))? - .accounts() + .assets() .insert(new_account) .map_err(|e| format!("Could not save account: {}", e))?; - Ok(result) + Ok(()) +} + +#[tauri::command] +pub(crate) async fn asset_wallets_get_balance( + asset_public_key: String, + state: tauri::State<'_, ConcurrentAppState>, +) -> Result { + dbg!(&asset_public_key); + let asset_public_key = + PublicKey::from_hex(&asset_public_key).map_err(|s| format!("Not a valid public key:{}", s))?; + + let owner = PublicKey::default(); + + let mut client = state.connect_validator_node_client().await?; + let args = tip002::BalanceOfRequest { + owner: Vec::from(owner.as_bytes()), + }; + dbg!(&args); + let mut args_bytes = vec![]; + args.encode(&mut args_bytes).unwrap(); + // let req = grpc::InvokeReadMethodRequest{ + // asset_public_key: Vec::from(asset_public_key.as_bytes()), + // template_id: 2, + // method: "BalanceOf", + // args + // }; + + let resp = client + .invoke_read_method(asset_public_key, 2, "BalanceOf".to_string(), args_bytes) + .await?; + + dbg!(&resp); + match resp { + Some(mut resp) => { + let proto_resp: tip002::BalanceOfResponse = + Message::decode(&*resp).map_err(|e| format!("Invalid proto:{}", e))?; + Ok(proto_resp.balance) + } + None => Ok(0), + } } #[tauri::command] -pub(crate) async fn accounts_list( +pub(crate) async fn asset_wallets_list( state: tauri::State<'_, ConcurrentAppState>, -) -> Result, String> { +) -> Result, String> { let db = state .create_db() .await .map_err(|e| format!("Could not connect to DB:{}", e))?; let result = db - .accounts() + .assets() .list() .map_err(|e| format!("Could list accounts from DB: {}", e))?; Ok(result) diff --git a/applications/tari_collectibles/src-tauri/src/commands/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/mod.rs index 5189f00bb3..ff23137c79 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/mod.rs @@ -22,7 +22,7 @@ use crate::app_state::ConcurrentAppState; -pub mod accounts; +pub mod asset_wallets; pub mod assets; pub mod tips; pub mod wallets; diff --git a/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs index ca5d78f547..11452ff3e9 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs @@ -23,7 +23,7 @@ use crate::{ app_state::ConcurrentAppState, models::{NewWallet, Wallet, WalletInfo}, - storage::{CollectiblesStorage, WalletsTableGateway}, + storage::{models::wallet_row::WalletRow, CollectiblesStorage, WalletsTableGateway}, }; use tari_key_manager::{ cipher_seed::CipherSeed, @@ -36,10 +36,11 @@ pub(crate) async fn wallets_create( name: Option, passphrase: Option, state: tauri::State<'_, ConcurrentAppState>, -) -> Result { - let new_wallet = NewWallet { +) -> Result<(), String> { + let new_wallet = WalletRow { + id: Uuid::new_v4(), name, - cipher_seed: CipherSeed::new(), + // cipher_seed: CipherSeed::new(), }; let result = state @@ -49,13 +50,13 @@ pub(crate) async fn wallets_create( .wallets() .insert(new_wallet, passphrase) .map_err(|e| format!("Could not save wallet: {}", e))?; - Ok(result) + Ok(()) } #[tauri::command] pub(crate) async fn wallets_list( state: tauri::State<'_, ConcurrentAppState>, -) -> Result, String> { +) -> Result, String> { let db = state .create_db() .await @@ -71,9 +72,8 @@ pub(crate) async fn wallets_list( #[tauri::command] pub(crate) async fn wallets_find( id: String, - passphrase: Option, state: tauri::State<'_, ConcurrentAppState>, -) -> Result { +) -> Result { let db = state .create_db() .await @@ -81,10 +81,7 @@ pub(crate) async fn wallets_find( let uuid = Uuid::parse_str(&id).map_err(|e| format!("Failed to parse UUID: {}", e))?; - let result = db - .wallets() - .find(uuid, passphrase) - .map_err(|e| e.to_string())?; + let result = db.wallets().find(uuid).map_err(|e| e.to_string())?; Ok(result) } @@ -102,13 +99,12 @@ pub(crate) async fn wallets_seed_words( let uuid = Uuid::parse_str(&id).map_err(|e| format!("Failed to parse UUID: {}", e))?; - let wallet = db + let cipher_seed = db .wallets() - .find(uuid, passphrase.clone()) + .get_cipher_seed(uuid, passphrase.clone()) .map_err(|e| e.to_string())?; - let seed_words = wallet - .cipher_seed + let seed_words = cipher_seed .to_mnemonic(&MnemonicLanguage::English, passphrase) .map_err(|e| format!("Failed to convert cipher seed to seed words: {}", e))?; diff --git a/applications/tari_collectibles/src-tauri/src/main.rs b/applications/tari_collectibles/src-tauri/src/main.rs index 908a33bf59..1ca3fdc54a 100644 --- a/applications/tari_collectibles/src-tauri/src/main.rs +++ b/applications/tari_collectibles/src-tauri/src/main.rs @@ -16,6 +16,7 @@ mod app_state; mod clients; mod commands; mod models; +mod providers; mod schema; mod settings; mod storage; @@ -32,8 +33,9 @@ fn main() { commands::assets::assets_list_registered_assets, commands::assets::assets_create_initial_checkpoint, commands::assets::assets_get_registration, - commands::accounts::accounts_create, - commands::accounts::accounts_list, + commands::asset_wallets::asset_wallets_create, + commands::asset_wallets::asset_wallets_list, + commands::asset_wallets::asset_wallets_get_balance, commands::wallets::wallets_create, commands::wallets::wallets_list, commands::wallets::wallets_find, diff --git a/applications/tari_collectibles/src-tauri/src/models/mod.rs b/applications/tari_collectibles/src-tauri/src/models/mod.rs index a14aff91c1..bf414b32aa 100644 --- a/applications/tari_collectibles/src-tauri/src/models/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/models/mod.rs @@ -24,8 +24,6 @@ mod asset_info; pub use asset_info::AssetInfo; mod registered_asset_info; pub use registered_asset_info::RegisteredAssetInfo; -mod account; -pub use account::{Account, NewAccount}; mod wallet; pub use wallet::{NewWallet, Wallet, WalletInfo}; mod tip002_info; diff --git a/applications/tari_collectibles/src-tauri/src/providers/mod.rs b/applications/tari_collectibles/src-tauri/src/providers/mod.rs new file mode 100644 index 0000000000..6878410277 --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/providers/mod.rs @@ -0,0 +1,21 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/applications/tari_collectibles/src-tauri/src/schema.rs b/applications/tari_collectibles/src-tauri/src/schema.rs index 282fa09015..3c89a4926a 100644 --- a/applications/tari_collectibles/src-tauri/src/schema.rs +++ b/applications/tari_collectibles/src-tauri/src/schema.rs @@ -1,5 +1,23 @@ table! { - accounts (id) { + addresses (id) { + id -> Binary, + asset_wallet_id -> Binary, + name -> Nullable, + public_key -> Binary, + key_manager_path -> Text, + } +} + +table! { + asset_wallets (id) { + id -> Binary, + asset_id -> Binary, + wallet_id -> Binary, + } +} + +table! { + assets (id) { id -> Binary, asset_public_key -> Binary, name -> Nullable, @@ -10,6 +28,24 @@ table! { } } +table! { + issued_assets (id) { + id -> Binary, + wallet_id -> Binary, + public_key -> Binary, + key_manager_path -> Text, + is_draft -> Bool, + } +} + +table! { + tip002_address (id) { + id -> Binary, + address_id -> Binary, + balance -> BigInt, + } +} + table! { wallets (id) { id -> Binary, @@ -17,3 +53,18 @@ table! { cipher_seed -> Binary, } } + +joinable!(addresses -> asset_wallets (asset_wallet_id)); +joinable!(asset_wallets -> assets (asset_id)); +joinable!(asset_wallets -> wallets (wallet_id)); +joinable!(issued_assets -> wallets (wallet_id)); +joinable!(tip002_address -> addresses (address_id)); + +allow_tables_to_appear_in_same_query!( + addresses, + asset_wallets, + assets, + issued_assets, + tip002_address, + wallets, +); diff --git a/applications/tari_collectibles/src-tauri/src/storage/mod.rs b/applications/tari_collectibles/src-tauri/src/storage/mod.rs index d3d49c185e..476fc512ed 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/mod.rs @@ -20,30 +20,50 @@ // 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::models::{Account, NewAccount, NewWallet, Wallet, WalletInfo}; +pub mod models; pub mod sqlite; mod storage_error; + +use crate::storage::models::{asset_row::AssetRow, wallet_row::WalletRow}; pub use storage_error::StorageError; +use tari_key_manager::cipher_seed::CipherSeed; use uuid::Uuid; pub trait CollectiblesStorage { - type Accounts: AccountsTableGateway; + type Addresses: AddressesTableGateway; + type Assets: AssetsTableGateway; + type AssetWallets: AssetWalletsTableGateway; + type IssuedAssets: IssuedAssetsTableGateway; + type Tip002Addresses: Tip002AddressesTableGateway; type Wallets: WalletsTableGateway; - fn accounts(&self) -> Self::Accounts; + fn addresses(&self) -> Self::Addresses; + fn assets(&self) -> Self::Assets; + fn asset_wallets(&self) -> Self::AssetWallets; + fn issued_assets(&self) -> Self::IssuedAssets; + fn tip002_addresses(&self) -> Self::Tip002Addresses; fn wallets(&self) -> Self::Wallets; } -pub trait AccountsTableGateway { - fn list(&self) -> Result, StorageError>; - fn insert(&self, account: NewAccount) -> Result; - fn find(&self, account_id: Uuid) -> Result; +pub trait AssetsTableGateway { + fn list(&self) -> Result, StorageError>; + fn insert(&self, asset: AssetRow) -> Result<(), StorageError>; + fn find(&self, asset_id: Uuid) -> Result; } pub trait WalletsTableGateway { type Passphrase; - fn list(&self) -> Result, StorageError>; - fn insert(&self, wallet: NewWallet, pass: Self::Passphrase) -> Result; - fn find(&self, id: Uuid, pass: Self::Passphrase) -> Result; + fn list(&self) -> Result, StorageError>; + fn insert(&self, wallet: WalletRow, pass: Self::Passphrase) -> Result<(), StorageError>; + fn find(&self, id: Uuid) -> Result; + fn get_cipher_seed(&self, id: Uuid, pass: Self::Passphrase) -> Result; } + +pub trait AssetWalletsTableGateway {} + +pub trait AddressesTableGateway {} + +pub trait IssuedAssetsTableGateway {} + +pub trait Tip002AddressesTableGateway {} diff --git a/applications/tari_collectibles/src-tauri/src/models/account.rs b/applications/tari_collectibles/src-tauri/src/storage/models/asset_row.rs similarity index 87% rename from applications/tari_collectibles/src-tauri/src/models/account.rs rename to applications/tari_collectibles/src-tauri/src/storage/models/asset_row.rs index ce9f1f71e6..f60c158bc3 100644 --- a/applications/tari_collectibles/src-tauri/src/models/account.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/models/asset_row.rs @@ -24,8 +24,8 @@ use serde::{Deserialize, Serialize}; use tari_common_types::types::PublicKey; use uuid::Uuid; -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct Account { +#[derive(Serialize, Deserialize)] +pub struct AssetRow { pub id: Uuid, pub asset_public_key: PublicKey, pub name: Option, @@ -33,11 +33,3 @@ pub struct Account { pub image: Option, pub committee: Option>, } - -pub struct NewAccount { - pub asset_public_key: PublicKey, - pub name: Option, - pub description: Option, - pub image: Option, - pub committee: Option>, -} diff --git a/applications/tari_collectibles/src-tauri/src/storage/models/mod.rs b/applications/tari_collectibles/src-tauri/src/storage/models/mod.rs new file mode 100644 index 0000000000..48c96e9abf --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/models/mod.rs @@ -0,0 +1,24 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +pub mod asset_row; +pub mod wallet_row; diff --git a/applications/tari_collectibles/src-tauri/src/storage/models/wallet_row.rs b/applications/tari_collectibles/src-tauri/src/storage/models/wallet_row.rs new file mode 100644 index 0000000000..7931f58d88 --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/models/wallet_row.rs @@ -0,0 +1,32 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use serde::{Deserialize, Serialize}; +use tari_key_manager::cipher_seed::CipherSeed; +use uuid::Uuid; + +#[derive(Serialize, Deserialize)] +pub struct WalletRow { + pub id: Uuid, + pub name: Option, + // pub cipher_seed: CipherSeed, +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/mod.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/mod.rs index af7bfa5996..ae0433de82 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/mod.rs @@ -20,229 +20,17 @@ // 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::{ - models::{Account, NewAccount, NewWallet, Wallet, WalletInfo}, - schema::{self, *}, - storage::{AccountsTableGateway, CollectiblesStorage, StorageError, WalletsTableGateway}, -}; -use diesel::{prelude::*, Connection, SqliteConnection}; -use std::{fs, path::Path}; -use tari_common_types::types::PublicKey; -use tari_key_manager::{cipher_seed::CipherSeed, error::KeyManagerError}; -use tari_utilities::ByteArray; -use uuid::Uuid; - pub mod models; - -pub struct SqliteDbFactory { - database_url: String, -} - -impl SqliteDbFactory { - pub fn new(data_dir: &Path) -> Self { - fs::create_dir_all(data_dir) - .unwrap_or_else(|_| panic!("Could not create data directory: {:?}", data_dir)); - let database_url = data_dir - .join("collectibles.sqlite") - .into_os_string() - .into_string() - .unwrap(); - - Self { database_url } - } - - pub fn create_db(&self) -> Result { - let connection = SqliteConnection::establish(self.database_url.as_str())?; - connection.execute("PRAGMA foreign_keys = ON;")?; - // Create the db - embed_migrations!("./migrations"); - embedded_migrations::run(&connection)?; - Ok(SqliteCollectiblesStorage { - database_url: self.database_url.clone(), - }) - } -} - -pub struct SqliteCollectiblesStorage { - database_url: String, -} - -impl CollectiblesStorage for SqliteCollectiblesStorage { - type Accounts = SqliteAccountsTableGateway; - type Wallets = SqliteWalletsTableGateway; - - fn accounts(&self) -> Self::Accounts { - SqliteAccountsTableGateway { - database_url: self.database_url.clone(), - } - } - - fn wallets(&self) -> Self::Wallets { - SqliteWalletsTableGateway { - database_url: self.database_url.clone(), - } - } -} - -pub struct SqliteAccountsTableGateway { - database_url: String, -} - -impl AccountsTableGateway for SqliteAccountsTableGateway { - fn list(&self) -> Result, StorageError> { - let conn = SqliteConnection::establish(self.database_url.as_str())?; - let results: Vec = schema::accounts::table - .order_by(schema::accounts::name.asc()) - .load(&conn)?; - results - .iter() - .map(SqliteAccountsTableGateway::convert_account) - .collect::>() - } - - fn insert(&self, account: NewAccount) -> Result { - let id = Uuid::new_v4(); - let mut committee_pub_keys = vec![]; - if let Some(pub_keys) = account.committee.as_ref() { - for key in pub_keys { - committee_pub_keys.extend_from_slice(key.as_bytes()); - } - } - // let committee_pub_keys = if committee_pub_keys.is_empty() { None} else {Some(committee_pub_keys)}; - - let sql_model = models::Account { - id: Vec::from(id.as_bytes().as_slice()), - asset_public_key: Vec::from(account.asset_public_key.as_bytes()), - name: account.name.clone(), - description: account.description.clone(), - image: account.image.clone(), - committee_length: account - .committee - .as_ref() - .map(|s| s.len() as i32) - .unwrap_or(0i32), - committee_pub_keys, - }; - let conn = SqliteConnection::establish(self.database_url.as_str())?; - - diesel::insert_into(accounts::table) - .values(sql_model) - .execute(&conn)?; - let result = Account { - id, - asset_public_key: account.asset_public_key, - name: account.name, - description: account.description, - image: account.image, - committee: account.committee, - }; - Ok(result) - } - - fn find(&self, account_id: Uuid) -> Result { - let conn = SqliteConnection::establish(self.database_url.as_str())?; - let db_account = schema::accounts::table - .find(Vec::from(account_id.as_bytes().as_slice())) - .get_result(&conn)?; - - SqliteAccountsTableGateway::convert_account(&db_account) - } -} - -impl SqliteAccountsTableGateway { - fn convert_account(r: &models::Account) -> Result { - let mut committee = Vec::with_capacity(r.committee_length as usize); - for i in 0..r.committee_length as usize { - committee.push(PublicKey::from_bytes(&r.committee_pub_keys[i * 32..(i + 1) * 32]).unwrap()); - } - Ok(Account { - id: Uuid::from_slice(&r.id).unwrap(), - asset_public_key: PublicKey::from_bytes(&r.asset_public_key).unwrap(), - name: r.name.clone(), - description: r.description.clone(), - image: r.image.clone(), - committee: if committee.is_empty() { - None - } else { - Some(committee) - }, - }) - } -} - -pub struct SqliteWalletsTableGateway { - database_url: String, -} - -impl SqliteWalletsTableGateway { - fn convert_wallet(w: &models::Wallet, pass: Option) -> Result { - let cipher_seed = match CipherSeed::from_enciphered_bytes(&w.cipher_seed, pass) { - Ok(seed) => seed, - Err(e) if matches!(e, KeyManagerError::DecryptionFailed) => { - return Err(StorageError::WrongPassword) - } - Err(e) => return Err(e.into()), - }; - - Ok(Wallet { - id: Uuid::from_slice(&w.id)?, - name: w.name.clone(), - cipher_seed, - }) - } -} - -impl WalletsTableGateway for SqliteWalletsTableGateway { - type Passphrase = Option; - - fn list(&self) -> Result, StorageError> { - let conn = SqliteConnection::establish(self.database_url.as_str())?; - let results: Vec = schema::wallets::table.load(&conn)?; - Ok( - results - .iter() - .map(|w| WalletInfo { - id: Uuid::from_slice(&w.id).unwrap(), - name: w.name.clone(), - }) - .collect(), - ) - } - - fn insert( - &self, - wallet: NewWallet, - passphrase: Self::Passphrase, - ) -> Result { - let id = Uuid::new_v4(); - - // todo: error - let sql_model = models::Wallet { - id: Vec::from(id.as_bytes().as_slice()), - name: wallet.name.clone(), - cipher_seed: wallet.cipher_seed.encipher(passphrase).unwrap(), - }; - let conn = SqliteConnection::establish(self.database_url.as_str())?; - - // use crate::schema::wallets; - diesel::insert_into(wallets::table) - .values(sql_model) - .execute(&conn)?; - - let result = Wallet { - id, - name: wallet.name, - cipher_seed: wallet.cipher_seed, - }; - Ok(result) - } - - fn find(&self, id: Uuid, passphrase: Self::Passphrase) -> Result { - let conn = SqliteConnection::establish(self.database_url.as_str())?; - let db_wallet = schema::wallets::table - .find(Vec::from(id.as_bytes().as_slice())) - .get_result(&conn)?; - - SqliteWalletsTableGateway::convert_wallet(&db_wallet, passphrase) - } -} +mod sqlite_addresses_table_gateway; +mod sqlite_asset_wallets_table_gateway; +mod sqlite_assets_table_gateway; +mod sqlite_collectibles_storage; +mod sqlite_db_factory; +mod sqlite_issued_assets_table_gateway; +mod sqlite_tip002_addresses_table_gateway; +mod sqlite_wallets_table_gateway; + +pub use sqlite_assets_table_gateway::SqliteAssetsTableGateway; +pub use sqlite_collectibles_storage::SqliteCollectiblesStorage; +pub use sqlite_db_factory::SqliteDbFactory; +pub use sqlite_wallets_table_gateway::SqliteWalletsTableGateway; diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/address.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/address.rs new file mode 100644 index 0000000000..1b1d541d5b --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/address.rs @@ -0,0 +1,33 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +use crate::schema::*; +use diesel::prelude::*; + +#[derive(Queryable, Insertable, Identifiable)] +#[table_name = "addresses"] +pub struct Address { + pub id: Vec, + pub asset_wallet_id: Vec, + pub name: Option, + pub public_key: Vec, + pub key_manager_path: String, +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/account.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/asset.rs similarity index 98% rename from applications/tari_collectibles/src-tauri/src/storage/sqlite/models/account.rs rename to applications/tari_collectibles/src-tauri/src/storage/sqlite/models/asset.rs index d7ace4fe49..44f6629ca2 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/account.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/asset.rs @@ -24,7 +24,7 @@ use crate::schema::*; use diesel::prelude::*; #[derive(Queryable, Insertable, Identifiable)] -pub struct Account { +pub struct Asset { pub id: Vec, pub asset_public_key: Vec, pub name: Option, diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/asset_wallet.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/asset_wallet.rs new file mode 100644 index 0000000000..330188b335 --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/asset_wallet.rs @@ -0,0 +1,31 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use crate::schema::*; +use diesel::prelude::*; + +#[derive(Queryable, Insertable, Identifiable)] +pub struct AssetWallet { + pub id: Vec, + pub asset_id: Vec, + pub wallet_id: Vec, +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/mod.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/mod.rs index 0811e140f7..7d50e7c45c 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/mod.rs @@ -20,8 +20,14 @@ // 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. -mod account; +mod address; +mod asset; +mod asset_wallet; +mod tip002_address; mod wallet; -pub use account::Account; +pub use address::Address; +pub use asset::Asset; +pub use asset_wallet::AssetWallet; +pub use tip002_address::Tip002Address; pub use wallet::Wallet; diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/tip002_address.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/tip002_address.rs new file mode 100644 index 0000000000..00cabfe0e8 --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/tip002_address.rs @@ -0,0 +1,30 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +use crate::schema::*; +use diesel::prelude::*; +#[derive(Queryable, Insertable, Identifiable)] +#[table_name = "tip002_address"] +pub struct Tip002Address { + pub id: Vec, + pub address_id: Vec, + pub balance: i64, +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_addresses_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_addresses_table_gateway.rs new file mode 100644 index 0000000000..0ed2a2d08c --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_addresses_table_gateway.rs @@ -0,0 +1,27 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use crate::storage::AddressesTableGateway; + +pub struct SqliteAddressesTableGateway {} + +impl AddressesTableGateway for SqliteAddressesTableGateway {} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs new file mode 100644 index 0000000000..6c34739907 --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs @@ -0,0 +1,27 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use crate::storage::AssetWalletsTableGateway; + +pub struct SqliteAssetWalletsTableGateway {} + +impl AssetWalletsTableGateway for SqliteAssetWalletsTableGateway {} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs new file mode 100644 index 0000000000..21b859a745 --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs @@ -0,0 +1,115 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +use crate::{ + models::{NewWallet, Wallet, WalletInfo}, + schema::{self, *}, + storage::{ + models::{asset_row::AssetRow, wallet_row::WalletRow}, + sqlite::models, + AssetsTableGateway, CollectiblesStorage, StorageError, WalletsTableGateway, + }, +}; +use diesel::{prelude::*, Connection, SqliteConnection}; +use std::{fs, path::Path}; +use tari_common_types::types::PublicKey; +use tari_key_manager::{cipher_seed::CipherSeed, error::KeyManagerError}; +use tari_utilities::ByteArray; +use uuid::Uuid; + +pub struct SqliteAssetsTableGateway { + pub database_url: String, +} + +impl AssetsTableGateway for SqliteAssetsTableGateway { + fn list(&self) -> Result, StorageError> { + let conn = SqliteConnection::establish(self.database_url.as_str())?; + let results: Vec = schema::assets::table + .order_by(schema::assets::name.asc()) + .load(&conn)?; + results + .iter() + .map(SqliteAssetsTableGateway::convert_asset) + .collect::>() + } + + fn insert(&self, asset: AssetRow) -> Result<(), StorageError> { + let id = Uuid::new_v4(); + let mut committee_pub_keys = vec![]; + if let Some(pub_keys) = asset.committee.as_ref() { + for key in pub_keys { + committee_pub_keys.extend_from_slice(key.as_bytes()); + } + } + // let committee_pub_keys = if committee_pub_keys.is_empty() { None} else {Some(committee_pub_keys)}; + + let sql_model = models::Asset { + id: Vec::from(id.as_bytes().as_slice()), + asset_public_key: Vec::from(asset.asset_public_key.as_bytes()), + name: asset.name.clone(), + description: asset.description.clone(), + image: asset.image.clone(), + committee_length: asset + .committee + .as_ref() + .map(|s| s.len() as i32) + .unwrap_or(0i32), + committee_pub_keys, + }; + let conn = SqliteConnection::establish(self.database_url.as_str())?; + + diesel::insert_into(assets::table) + .values(sql_model) + .execute(&conn)?; + + Ok(()) + } + + fn find(&self, asset_id: Uuid) -> Result { + let conn = SqliteConnection::establish(self.database_url.as_str())?; + let db_account = schema::assets::table + .find(Vec::from(asset_id.as_bytes().as_slice())) + .get_result(&conn)?; + + SqliteAssetsTableGateway::convert_asset(&db_account) + } +} + +impl SqliteAssetsTableGateway { + fn convert_asset(r: &models::Asset) -> Result { + let mut committee = Vec::with_capacity(r.committee_length as usize); + for i in 0..r.committee_length as usize { + committee.push(PublicKey::from_bytes(&r.committee_pub_keys[i * 32..(i + 1) * 32]).unwrap()); + } + Ok(AssetRow { + id: Uuid::from_slice(&r.id).unwrap(), + asset_public_key: PublicKey::from_bytes(&r.asset_public_key).unwrap(), + name: r.name.clone(), + description: r.description.clone(), + image: r.image.clone(), + committee: if committee.is_empty() { + None + } else { + Some(committee) + }, + }) + } +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_collectibles_storage.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_collectibles_storage.rs new file mode 100644 index 0000000000..2f05380b29 --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_collectibles_storage.rs @@ -0,0 +1,83 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +use crate::{ + models::{NewWallet, Wallet, WalletInfo}, + schema::{self, *}, + storage::{ + models::{asset_row::AssetRow, wallet_row::WalletRow}, + sqlite::{ + sqlite_addresses_table_gateway::SqliteAddressesTableGateway, + sqlite_asset_wallets_table_gateway::SqliteAssetWalletsTableGateway, + sqlite_issued_assets_table_gateway::SqliteIssuedAssetsTableGateway, + sqlite_tip002_addresses_table_gateway::SqliteTip002AddressesTableGateway, + SqliteAssetsTableGateway, SqliteWalletsTableGateway, + }, + AssetsTableGateway, CollectiblesStorage, StorageError, WalletsTableGateway, + }, +}; +use diesel::{prelude::*, Connection, SqliteConnection}; +use std::{fs, path::Path}; +use tari_common_types::types::PublicKey; +use tari_key_manager::{cipher_seed::CipherSeed, error::KeyManagerError}; +use tari_utilities::ByteArray; +use uuid::Uuid; + +pub struct SqliteCollectiblesStorage { + pub database_url: String, +} + +impl CollectiblesStorage for SqliteCollectiblesStorage { + type Addresses = SqliteAddressesTableGateway; + type Assets = SqliteAssetsTableGateway; + type AssetWallets = SqliteAssetWalletsTableGateway; + type IssuedAssets = SqliteIssuedAssetsTableGateway; + type Tip002Addresses = SqliteTip002AddressesTableGateway; + type Wallets = SqliteWalletsTableGateway; + + fn addresses(&self) -> Self::Addresses { + SqliteAddressesTableGateway {} + } + + fn assets(&self) -> Self::Assets { + SqliteAssetsTableGateway { + database_url: self.database_url.clone(), + } + } + + fn asset_wallets(&self) -> Self::AssetWallets { + SqliteAssetWalletsTableGateway {} + } + + fn issued_assets(&self) -> Self::IssuedAssets { + SqliteIssuedAssetsTableGateway {} + } + + fn tip002_addresses(&self) -> Self::Tip002Addresses { + SqliteTip002AddressesTableGateway {} + } + + fn wallets(&self) -> Self::Wallets { + SqliteWalletsTableGateway { + database_url: self.database_url.clone(), + } + } +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_db_factory.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_db_factory.rs new file mode 100644 index 0000000000..07c1d093d4 --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_db_factory.rs @@ -0,0 +1,65 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +use crate::{ + models::{NewWallet, Wallet, WalletInfo}, + schema::{self, *}, + storage::{ + models::{asset_row::AssetRow, wallet_row::WalletRow}, + sqlite::SqliteCollectiblesStorage, + AssetsTableGateway, CollectiblesStorage, StorageError, WalletsTableGateway, + }, +}; +use diesel::{prelude::*, Connection, SqliteConnection}; +use std::{fs, path::Path}; +use tari_common_types::types::PublicKey; +use tari_key_manager::{cipher_seed::CipherSeed, error::KeyManagerError}; +use tari_utilities::ByteArray; +use uuid::Uuid; + +pub struct SqliteDbFactory { + database_url: String, +} + +impl SqliteDbFactory { + pub fn new(data_dir: &Path) -> Self { + fs::create_dir_all(data_dir) + .unwrap_or_else(|_| panic!("Could not create data directory: {:?}", data_dir)); + let database_url = data_dir + .join("collectibles.sqlite") + .into_os_string() + .into_string() + .unwrap(); + + Self { database_url } + } + + pub fn create_db(&self) -> Result { + let connection = SqliteConnection::establish(self.database_url.as_str())?; + connection.execute("PRAGMA foreign_keys = ON;")?; + // Create the db + embed_migrations!("./migrations"); + embedded_migrations::run(&connection)?; + Ok(SqliteCollectiblesStorage { + database_url: self.database_url.clone(), + }) + } +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_issued_assets_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_issued_assets_table_gateway.rs new file mode 100644 index 0000000000..b921974776 --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_issued_assets_table_gateway.rs @@ -0,0 +1,27 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use crate::storage::IssuedAssetsTableGateway; + +pub struct SqliteIssuedAssetsTableGateway {} + +impl IssuedAssetsTableGateway for SqliteIssuedAssetsTableGateway {} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_tip002_addresses_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_tip002_addresses_table_gateway.rs new file mode 100644 index 0000000000..6a0497f184 --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_tip002_addresses_table_gateway.rs @@ -0,0 +1,27 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use crate::storage::Tip002AddressesTableGateway; + +pub struct SqliteTip002AddressesTableGateway {} + +impl Tip002AddressesTableGateway for SqliteTip002AddressesTableGateway {} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs new file mode 100644 index 0000000000..1f69c87c50 --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs @@ -0,0 +1,112 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +use crate::{ + models::{NewWallet, Wallet, WalletInfo}, + schema::{self, *}, + storage::{ + models::{asset_row::AssetRow, wallet_row::WalletRow}, + sqlite::models, + AssetsTableGateway, CollectiblesStorage, StorageError, WalletsTableGateway, + }, +}; +use diesel::{prelude::*, Connection, SqliteConnection}; +use std::{fs, path::Path}; +use tari_common_types::types::PublicKey; +use tari_key_manager::{cipher_seed::CipherSeed, error::KeyManagerError}; +use tari_utilities::ByteArray; +use uuid::Uuid; + +pub struct SqliteWalletsTableGateway { + pub database_url: String, +} + +impl SqliteWalletsTableGateway { + fn convert_wallet(w: &models::Wallet) -> Result { + Ok(WalletRow { + id: Uuid::from_slice(&w.id)?, + name: w.name.clone(), + }) + } +} + +impl WalletsTableGateway for SqliteWalletsTableGateway { + type Passphrase = Option; + + fn list(&self) -> Result, StorageError> { + let conn = SqliteConnection::establish(self.database_url.as_str())?; + let results: Vec = schema::wallets::table.load(&conn)?; + Ok( + results + .iter() + .map(|w| WalletRow { + id: Uuid::from_slice(&w.id).unwrap(), + name: w.name.clone(), + // cipher_seed: CipherSeed::w.cipher_seed.clone(), + }) + .collect(), + ) + } + + fn insert(&self, wallet: WalletRow, passphrase: Self::Passphrase) -> Result<(), StorageError> { + let id = Uuid::new_v4(); + let cipher_seed = CipherSeed::new(); + // todo: error + let sql_model = models::Wallet { + id: Vec::from(id.as_bytes().as_slice()), + name: wallet.name.clone(), + cipher_seed: cipher_seed.encipher(passphrase).unwrap(), + }; + let conn = SqliteConnection::establish(self.database_url.as_str())?; + + // use crate::schema::wallets; + diesel::insert_into(wallets::table) + .values(sql_model) + .execute(&conn)?; + + Ok(()) + } + + fn find(&self, id: Uuid) -> Result { + let conn = SqliteConnection::establish(self.database_url.as_str())?; + let db_wallet = schema::wallets::table + .find(Vec::from(id.as_bytes().as_slice())) + .get_result(&conn)?; + + SqliteWalletsTableGateway::convert_wallet(&db_wallet) + } + + fn get_cipher_seed(&self, id: Uuid, pass: Self::Passphrase) -> Result { + let conn = SqliteConnection::establish(self.database_url.as_str())?; + let w: models::Wallet = schema::wallets::table + .find(Vec::from(id.as_bytes().as_slice())) + .get_result(&conn)?; + let cipher_seed = match CipherSeed::from_enciphered_bytes(&w.cipher_seed, pass) { + Ok(seed) => seed, + Err(e) if matches!(e, KeyManagerError::DecryptionFailed) => { + return Err(StorageError::WrongPassword) + } + Err(e) => return Err(e.into()), + }; + + Ok(cipher_seed) + } +} diff --git a/applications/tari_collectibles/src-tauri/temp.sqlite b/applications/tari_collectibles/src-tauri/temp.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..b5c6c85aef9e03a1b6d812547486490e08468c36 GIT binary patch literal 69632 zcmeI&!B5*(9KdlKXaa!{*u_E|c!x<4wM--hO=~rE9?Q0BKv^25^<+88BUp8uGP@)!$4G9Emzv!Xn!`7|6n0y?5^sX^^v4jZ zwreY3QFR)QcgCZ_zdxTc9_8c0k6x%%h_-XR=d)>JWko-^KL8lL@@Qo)6832GO(O1B zqjina8I*0_>TouDScfTE0}(<=L>TwqqGvIHj2|Kj8?O~{h7gFJGO>a zV{!SBYtKZ@#{1pa?W(ah9Oq+2at-8geD)9O51q_aLnjiHk{AzUwwFnzjpb#%_jI5U zo;Q3-M+Cx+VeA(ox^SO4m+zX>K2rAvU&`}$sIKQc>q-^J`gF=Lm*cV-zP?oqS7z4J z*XdpeyHB6IGnqD)mh^95oh5#laepcj=rAFtIquil`Q_h(KYzraJ*1Djk&2;1I65vn z!8y^(x`?{;YaOQ@I4y5{uwB+yy)QH(Bl5CNwN|s~1c8*6E4_xgudDl(R5$t2NW9{D z&yH0w_uo1E=v#+M`R!XNY-io@sB?Wt>Y9u~NNtM{3nHcV4LUK*s^vg(fX zrEB@MBiXdArqk%yeI-AB&qSmw;`@oU=d$DX#lJGk+n<}|wXKc3*e^faHOo)L7o{g+ z?@>kU9qjDf>2y6y^{YJGEj_N7yZfU(;*-*+=D|)yY#)@%rM-$Z>XLsvkun-)oKgH` zS%vt0lj?KSbpNwdRz39GZ<_jJK>z^+5I_I{1Q0*~0R#|00D=FVz`Ocn{%&!jSWwGW zp}4tO-0Zj33x)M!Q4}`sZM}bQvyf47>A62N^~Zt$0tg_000IagfB*srAbz^+5I_I{1Q0*~0R#|00D%Mx^ymNi{-59k6B+^tAb + {this.state.error ? ( + {this.state.error} + ) : ( + + )} Asset Details + + { this.state.assetPubKey } + Balance: diff --git a/applications/tari_collectibles/web-app/src/App.js b/applications/tari_collectibles/web-app/src/App.js index aad4c741c8..802aefa4e3 100644 --- a/applications/tari_collectibles/web-app/src/App.js +++ b/applications/tari_collectibles/web-app/src/App.js @@ -119,7 +119,7 @@ const AccountsMenu = (props) => { useEffect(() => { binding - .command_accounts_list() + .command_asset_wallets_list() .then((accounts) => { console.log("accounts", accounts); setAccounts(accounts); @@ -198,11 +198,7 @@ function App() { - - - Hello world - - + @@ -212,7 +208,7 @@ function App() { } /> @@ -266,9 +262,9 @@ function App() { > - + - + { diff --git a/applications/tari_collectibles/web-app/src/Create.js b/applications/tari_collectibles/web-app/src/Create.js index a03970c25e..78654b1c99 100644 --- a/applications/tari_collectibles/web-app/src/Create.js +++ b/applications/tari_collectibles/web-app/src/Create.js @@ -93,7 +93,7 @@ class Create extends React.Component { let description = this.state.description; let image = this.state.image; try { - let templateIds = []; + let templateIds = [1]; let templateParameters = []; if (this.state.tip002) { console.log("tip002"); diff --git a/applications/tari_collectibles/web-app/src/NewAccount.js b/applications/tari_collectibles/web-app/src/NewAccount.js index ea7e865098..5a2adbd0d4 100644 --- a/applications/tari_collectibles/web-app/src/NewAccount.js +++ b/applications/tari_collectibles/web-app/src/NewAccount.js @@ -52,7 +52,7 @@ class NewAccount extends React.Component { console.log(this.state.assetPublicKey); this.setState({ isSaving: true, error: null }); try { - await binding.command_accounts_create(this.state.assetPublicKey); + await binding.command_asset_wallets_create(this.state.assetPublicKey); let history = this.props.history; let path = `/assets/watched/details/${this.state.assetPublicKey}`; console.log(path); diff --git a/applications/tari_collectibles/web-app/src/binding.js b/applications/tari_collectibles/web-app/src/binding.js index b404929b72..15cb6d35e0 100644 --- a/applications/tari_collectibles/web-app/src/binding.js +++ b/applications/tari_collectibles/web-app/src/binding.js @@ -65,18 +65,22 @@ async function command_wallets_list() { return await invoke("wallets_list"); } -async function command_accounts_create(assetPubKey) { - return await invoke("accounts_create", { assetPubKey }); +async function command_asset_wallets_create(assetPublicKey) { + return await invoke("asset_wallets_create", { assetPublicKey }); } -async function command_accounts_list() { - return await invoke("accounts_list", {}); +async function command_asset_wallets_list() { + return await invoke("asset_wallets_list", {}); } async function command_create_db() { return await invoke("create_db", {}); } +async function command_asset_wallets_get_balance(assetPublicKey) { + return await invoke("asset_wallets_get_balance", {assetPublicKey}); +} + const commands = { command_create_db, command_assets_create, @@ -84,8 +88,9 @@ const commands = { command_assets_list_owned, command_assets_list_registered_assets, command_asset_create_initial_checkpoint, - command_accounts_create, - command_accounts_list, + command_asset_wallets_create, + command_asset_wallets_get_balance, + command_asset_wallets_list, command_wallets_create, command_wallets_list, command_wallets_find, diff --git a/applications/tari_validator_node/proto/p2p/dan_consensus.proto b/applications/tari_validator_node/proto/p2p/dan_consensus.proto index 2eeca051a1..012d0103be 100644 --- a/applications/tari_validator_node/proto/p2p/dan_consensus.proto +++ b/applications/tari_validator_node/proto/p2p/dan_consensus.proto @@ -54,7 +54,7 @@ message Instruction { bytes asset_public_key = 1; uint32 template_id = 2; string method = 3; - repeated bytes args = 4; + bytes args = 4; // bytes token_id = 5; // bytes signature = 6; } diff --git a/applications/tari_validator_node/proto/p2p/validator_node.proto b/applications/tari_validator_node/proto/p2p/validator_node.proto index b48a4d6275..1b5e278e43 100644 --- a/applications/tari_validator_node/proto/p2p/validator_node.proto +++ b/applications/tari_validator_node/proto/p2p/validator_node.proto @@ -39,7 +39,7 @@ message SubmitInstructionRequest { bytes asset_public_key = 1; uint32 template_id = 2; string method = 3; - repeated bytes args = 4; + bytes args = 4; // bytes token_id = 5; // bytes signature = 6; } diff --git a/applications/tari_validator_node/src/grpc/validator_node_grpc_server.rs b/applications/tari_validator_node/src/grpc/validator_node_grpc_server.rs index d05b2faf3d..4bece65eef 100644 --- a/applications/tari_validator_node/src/grpc/validator_node_grpc_server.rs +++ b/applications/tari_validator_node/src/grpc/validator_node_grpc_server.rs @@ -80,11 +80,13 @@ where Ok(_) => { return Ok(Response::new(rpc::ExecuteInstructionResponse { status: "Accepted".to_string(), + result: None, })) }, Err(_) => { return Ok(Response::new(rpc::ExecuteInstructionResponse { status: "Errored".to_string(), + result: None, })) }, } @@ -104,4 +106,12 @@ where // sidechains: vec![metadata.into()], // })) } + + async fn invoke_read_method( + &self, + request: Request, + ) -> Result, Status> { + dbg!(&request); + todo!() + } } diff --git a/dan_layer/common_types/Cargo.toml b/dan_layer/common_types/Cargo.toml new file mode 100644 index 0000000000..449d05bb84 --- /dev/null +++ b/dan_layer/common_types/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "tari_dan_common_types" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +prost = "0.8" +prost-types = "0.8" + +[build-dependencies] +tari_common = { path = "../../common", features = ["build"] } diff --git a/dan_layer/core/build.rs b/dan_layer/common_types/build.rs similarity index 100% rename from dan_layer/core/build.rs rename to dan_layer/common_types/build.rs diff --git a/dan_layer/core/proto/tips/tip002.proto b/dan_layer/common_types/proto/tips/tip002.proto similarity index 54% rename from dan_layer/core/proto/tips/tip002.proto rename to dan_layer/common_types/proto/tips/tip002.proto index 918ff755ef..0ff330fae3 100644 --- a/dan_layer/core/proto/tips/tip002.proto +++ b/dan_layer/common_types/proto/tips/tip002.proto @@ -6,7 +6,8 @@ package tari.dan.tips.tip002; service Tip002 { rpc Init(InitRequest) returns (Empty); // rpc Info(InfoRequest) returns (InfoResponse); - // rpc BalanceOf(BalanceOfRequest) returns (BalanceOfResponse); + rpc BalanceOf(BalanceOfRequest) returns (BalanceOfResponse); + rpc Tranfer(TransferRequest) returns (TransferResponse); } @@ -19,6 +20,17 @@ message Empty{ } +message TransferRequest { + bytes to = 1; + uint64 amount = 2; + bytes from = 3; + bytes caller = 4; +} + +message TransferResponse { + // TODO? maybe errors? +} + //message InfoRequest { // //} @@ -28,11 +40,11 @@ message Empty{ // byte decimals = 2; // uint256 total_supply = 3; //} -// -//message BalanceOfRequest { -// uint256 owner = 1; -//} -// -//message BalanceOfResponse { -// uint256 balance = 1; -//} \ No newline at end of file + +message BalanceOfRequest { + bytes owner = 1; +} + +message BalanceOfResponse { + uint64 balance = 1; +} \ No newline at end of file diff --git a/dan_layer/common_types/proto/tips/tip721.proto b/dan_layer/common_types/proto/tips/tip721.proto new file mode 100644 index 0000000000..ca00d4b6b7 --- /dev/null +++ b/dan_layer/common_types/proto/tips/tip721.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package tari.dan.tips.tip721; + +service Tip721 { + rpc Init(InitRequest) returns (Empty); + // rpc Transfer(TransferRequest) returns (TransferResponse); +} + +message InitRequest{ + +} + +message Empty { + +} \ No newline at end of file diff --git a/dan_layer/common_types/src/lib.rs b/dan_layer/common_types/src/lib.rs new file mode 100644 index 0000000000..febacec69e --- /dev/null +++ b/dan_layer/common_types/src/lib.rs @@ -0,0 +1 @@ +pub mod proto; diff --git a/dan_layer/core/src/templates/proto/mod.rs b/dan_layer/common_types/src/proto/mod.rs similarity index 100% rename from dan_layer/core/src/templates/proto/mod.rs rename to dan_layer/common_types/src/proto/mod.rs diff --git a/dan_layer/core/Cargo.toml b/dan_layer/core/Cargo.toml index 7f7b994dae..0bfa980987 100644 --- a/dan_layer/core/Cargo.toml +++ b/dan_layer/core/Cargo.toml @@ -17,6 +17,7 @@ tari_service_framework = { path = "../../base_layer/service_framework" } tari_shutdown = { path = "../../infrastructure/shutdown" } tari_storage = { path = "../../infrastructure/storage" } tari_core = {path = "../../base_layer/core"} +tari_dan_common_types = {path = "../common_types"} anyhow = "1.0.32" async-trait = "0.1.50" diff --git a/dan_layer/core/src/models/instruction.rs b/dan_layer/core/src/models/instruction.rs index 28a1499fed..8745cce96d 100644 --- a/dan_layer/core/src/models/instruction.rs +++ b/dan_layer/core/src/models/instruction.rs @@ -20,10 +20,7 @@ // 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::{ - models::{TemplateId}, - types::{PublicKey}, -}; +use crate::{models::TemplateId, types::PublicKey}; use digest::Digest; use tari_crypto::{common::Blake256, tari_utilities::ByteArray}; @@ -32,7 +29,7 @@ pub struct Instruction { asset_id: PublicKey, template_id: TemplateId, method: String, - args: Vec>, + args: Vec, // from: TokenId, // signature: ComSig, hash: Vec, @@ -49,7 +46,7 @@ impl Instruction { asset_id: PublicKey, template_id: TemplateId, method: String, - args: Vec>, + args: Vec, /* from: TokenId, * _signature: ComSig, */ ) -> Self { @@ -79,7 +76,7 @@ impl Instruction { &self.method } - pub fn args(&self) -> &[Vec] { + pub fn args(&self) -> &[u8] { &self.args } @@ -99,10 +96,8 @@ impl Instruction { pub fn calculate_hash(&self) -> Vec { let mut b = Blake256::new() .chain(self.asset_id.as_bytes()) - .chain(self.method.as_bytes()); - for a in &self.args { - b = b.chain(a); - } + .chain(self.method.as_bytes()) + .chain(&self.args); // b.chain(self.from.as_bytes()) // .chain(com_sig_to_bytes(&self.signature)) b.finalize().to_vec() diff --git a/dan_layer/core/src/services/asset_processor.rs b/dan_layer/core/src/services/asset_processor.rs index 33e7141925..35541e684e 100644 --- a/dan_layer/core/src/services/asset_processor.rs +++ b/dan_layer/core/src/services/asset_processor.rs @@ -73,7 +73,7 @@ impl AssetProcessor for ConcreteAssetPro self.execute( instruction.template_id(), instruction.method().to_owned(), - instruction.args().to_vec().into(), + instruction.args().into(), // InstructionCaller { // owner_token_id: instruction.from_owner().to_owned(), // }, @@ -96,7 +96,7 @@ impl ConcreteAssetProcessor { &self, _template_id: TemplateId, _method: String, - _args: VecDeque>, + _args: Vec, // caller: InstructionCaller, _hash: Vec, _db: TUnitOfWork, diff --git a/dan_layer/core/src/templates/mod.rs b/dan_layer/core/src/templates/mod.rs index 0f90c2e888..248ffd08cb 100644 --- a/dan_layer/core/src/templates/mod.rs +++ b/dan_layer/core/src/templates/mod.rs @@ -20,5 +20,4 @@ // 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. -pub mod proto; pub mod tip002_template; diff --git a/dan_layer/core/src/templates/tip002_template.rs b/dan_layer/core/src/templates/tip002_template.rs index b3082d520d..76134d17d2 100644 --- a/dan_layer/core/src/templates/tip002_template.rs +++ b/dan_layer/core/src/templates/tip002_template.rs @@ -19,15 +19,11 @@ // 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::{ - models::AssetDefinition, - storage::state::StateDbUnitOfWork, - templates::proto::tips::tip002, - DigitalAssetError, -}; +use crate::{models::AssetDefinition, storage::state::StateDbUnitOfWork, DigitalAssetError}; use prost::Message; use tari_core::transactions::transaction::TemplateParameter; use tari_crypto::tari_utilities::ByteArray; +use tari_dan_common_types::proto::tips::tip002; pub fn init( template_parameter: &TemplateParameter, From 72715cb803bd7c8dd256c326695e9c4c968d49e6 Mon Sep 17 00:00:00 2001 From: Mike the Tike Date: Tue, 23 Nov 2021 17:29:49 +0200 Subject: [PATCH 2/6] add get balance call --- .../src-tauri/src/app_state.rs | 12 ++++ .../src/commands/asset_wallets/mod.rs | 19 ++++--- .../src-tauri/src/commands/assets/mod.rs | 56 ++++++++++++++++++- .../src-tauri/src/commands/wallets/mod.rs | 22 +++++--- .../src/providers/key_manager_provider.rs | 29 ++++++++++ .../src-tauri/src/providers/mod.rs | 18 ++++++ .../src-tauri/src/storage/mod.rs | 43 +++++++++----- .../src/storage/models/asset_wallet_row.rs | 31 ++++++++++ .../src-tauri/src/storage/models/mod.rs | 1 + .../src-tauri/src/storage/sqlite/mod.rs | 1 + .../sqlite_asset_wallets_table_gateway.rs | 11 +++- .../sqlite/sqlite_assets_table_gateway.rs | 10 ++-- .../sqlite/sqlite_collectibles_storage.rs | 11 +++- .../src/storage/sqlite/sqlite_transaction.rs | 42 ++++++++++++++ .../sqlite/sqlite_wallets_table_gateway.rs | 22 ++++++-- 15 files changed, 285 insertions(+), 43 deletions(-) create mode 100644 applications/tari_collectibles/src-tauri/src/providers/key_manager_provider.rs create mode 100644 applications/tari_collectibles/src-tauri/src/storage/models/asset_wallet_row.rs create mode 100644 applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_transaction.rs diff --git a/applications/tari_collectibles/src-tauri/src/app_state.rs b/applications/tari_collectibles/src-tauri/src/app_state.rs index b23e3da2ff..441be3c374 100644 --- a/applications/tari_collectibles/src-tauri/src/app_state.rs +++ b/applications/tari_collectibles/src-tauri/src/app_state.rs @@ -22,6 +22,7 @@ use crate::{ clients::{BaseNodeClient, GrpcValidatorNodeClient, WalletClient}, + providers::{mocks::MockKeyManagerProvider, KeyManagerProvider}, settings::Settings, storage::{ sqlite::{SqliteCollectiblesStorage, SqliteDbFactory}, @@ -31,11 +32,13 @@ use crate::{ use std::sync::Arc; use tari_common_types::types::PublicKey; use tauri::async_runtime::RwLock; +use uuid::Uuid; pub struct AppState { config: Settings, db_factory: SqliteDbFactory, passphrase: Option, + current_wallet_id: Option, } #[derive(Clone)] @@ -51,6 +54,7 @@ impl ConcurrentAppState { db_factory: SqliteDbFactory::new(settings.data_dir.as_path()), config: settings, passphrase: None, + current_wallet_id: None, })), } } @@ -88,4 +92,12 @@ impl ConcurrentAppState { pub async fn create_db(&self) -> Result { self.inner.read().await.db_factory.create_db() } + + pub async fn key_manager(&self) -> impl KeyManagerProvider { + MockKeyManagerProvider {} + } + + pub async fn current_wallet_id(&self) -> Option { + self.inner.read().await.current_wallet_id + } } diff --git a/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs index ac3c454332..91d85d338c 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs @@ -23,7 +23,8 @@ use crate::{ app_state::ConcurrentAppState, models::{NewWallet, Wallet}, storage::{ - models::asset_row::AssetRow, AssetsTableGateway, CollectiblesStorage, WalletsTableGateway, + models::asset_row::AssetRow, AssetsTableGateway, CollectiblesStorage, StorageTransaction, + WalletsTableGateway, }, }; use prost::Message; @@ -68,14 +69,18 @@ pub(crate) async fn asset_wallets_create( } }; new_account.committee = sidechain_committee; - - state + let db = state .create_db() .await - .map_err(|e| format!("Could not connect to DB:{}", e))? - .assets() - .insert(new_account) + .map_err(|e| format!("Could not connect to DB:{}", e))?; + let tx = db + .create_transaction() + .map_err(|e| format!("Could not start transaction:{}", e))?; + db.assets() + .insert(new_account, &tx) .map_err(|e| format!("Could not save account: {}", e))?; + tx.commit() + .map_err(|e| format!("Could not commit transaction:{}", e))?; Ok(()) } @@ -129,7 +134,7 @@ pub(crate) async fn asset_wallets_list( .map_err(|e| format!("Could not connect to DB:{}", e))?; let result = db .assets() - .list() + .list(None) .map_err(|e| format!("Could list accounts from DB: {}", e))?; Ok(result) } diff --git a/applications/tari_collectibles/src-tauri/src/commands/assets/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/assets/mod.rs index 2c4b36cf40..2b25f7e066 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/assets/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/assets/mod.rs @@ -23,6 +23,11 @@ use crate::{ app_state::ConcurrentAppState, models::{AssetInfo, RegisteredAssetInfo, TemplateParameter}, + providers::KeyManagerProvider, + storage::{ + models::{asset_row::AssetRow, asset_wallet_row::AssetWalletRow}, + AssetWalletsTableGateway, AssetsTableGateway, CollectiblesStorage, StorageTransaction, + }, }; use rand::rngs::OsRng; use tari_app_grpc::tari_rpc::{self}; @@ -32,6 +37,7 @@ use tari_crypto::{ }; use tari_mmr::{MemBackendVec, MerkleMountainRange}; use tari_utilities::{hex::Hex, ByteArray, Hashable}; +use uuid::Uuid; #[tauri::command] pub(crate) async fn assets_create( @@ -52,10 +58,58 @@ pub(crate) async fn assets_create( template_id: t.template_id, }) .collect(); + + // TODO: Generate and pass public key to wallet.... + let (key_manager_path, asset_public_key) = state + .key_manager() + .await + .generate_asset_public_key() + .map_err(|e| format!("could not generate asset public key: {}", e))?; + let res = client - .register_asset(name, description, image, template_ids, tp) + .register_asset( + name.clone(), + description.clone(), + image.clone(), + template_ids, + tp, + ) .await?; + let db = state + .create_db() + .await + .map_err(|e| format!("Could not create db:{}", e))?; + let transaction = db + .create_transaction() + .map_err(|e| format!("Could not start transaction: {}", e))?; + let asset_id = Uuid::new_v4(); + let asset_row = AssetRow { + id: asset_id, + asset_public_key, + name: Some(name), + description: Some(description), + image: Some(image), + committee: None, + }; + db.assets() + .insert(asset_row, &transaction) + .map_err(|e| format!("Could not insert asset:{}", e))?; + let asset_wallet_row = AssetWalletRow { + id: Uuid::new_v4(), + asset_id, + wallet_id: state + .current_wallet_id() + .await + .ok_or_else(|| "Current wallet not set".to_string())?, + }; + db.asset_wallets() + .insert(asset_wallet_row, &transaction) + .map_err(|e| format!("Could not insert asset wallet:{}", e))?; + transaction + .commit() + .map_err(|e| format!("Could not commit transaction: {}", e))?; + Ok(res) } diff --git a/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs index 11452ff3e9..296a52230a 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs @@ -23,7 +23,9 @@ use crate::{ app_state::ConcurrentAppState, models::{NewWallet, Wallet, WalletInfo}, - storage::{models::wallet_row::WalletRow, CollectiblesStorage, WalletsTableGateway}, + storage::{ + models::wallet_row::WalletRow, CollectiblesStorage, StorageTransaction, WalletsTableGateway, + }, }; use tari_key_manager::{ cipher_seed::CipherSeed, @@ -43,13 +45,19 @@ pub(crate) async fn wallets_create( // cipher_seed: CipherSeed::new(), }; - let result = state + let db = state .create_db() .await - .map_err(|e| format!("Could not connect to DB: {}", e))? + .map_err(|e| format!("Could not connect to DB: {}", e))?; + let tx = db + .create_transaction() + .map_err(|e| format!("Could not start transaction:{}", e))?; + let result = db .wallets() - .insert(new_wallet, passphrase) + .insert(new_wallet, passphrase, &tx) .map_err(|e| format!("Could not save wallet: {}", e))?; + tx.commit() + .map_err(|e| format!("Could not commit transaction:{}", e))?; Ok(()) } @@ -64,7 +72,7 @@ pub(crate) async fn wallets_list( let result = db .wallets() - .list() + .list(None) .map_err(|e| format!("Could list wallets from DB: {}", e))?; Ok(result) } @@ -81,7 +89,7 @@ pub(crate) async fn wallets_find( let uuid = Uuid::parse_str(&id).map_err(|e| format!("Failed to parse UUID: {}", e))?; - let result = db.wallets().find(uuid).map_err(|e| e.to_string())?; + let result = db.wallets().find(uuid, None).map_err(|e| e.to_string())?; Ok(result) } @@ -101,7 +109,7 @@ pub(crate) async fn wallets_seed_words( let cipher_seed = db .wallets() - .get_cipher_seed(uuid, passphrase.clone()) + .get_cipher_seed(uuid, passphrase.clone(), None) .map_err(|e| e.to_string())?; let seed_words = cipher_seed diff --git a/applications/tari_collectibles/src-tauri/src/providers/key_manager_provider.rs b/applications/tari_collectibles/src-tauri/src/providers/key_manager_provider.rs new file mode 100644 index 0000000000..8b2a1555bf --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/providers/key_manager_provider.rs @@ -0,0 +1,29 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use std::fmt::Display; +use tari_common_types::types::PublicKey; + +pub trait KeyManagerProvider { + type Error: Display; + fn generate_asset_public_key(&self) -> Result<(String, PublicKey), Self::Error>; +} diff --git a/applications/tari_collectibles/src-tauri/src/providers/mod.rs b/applications/tari_collectibles/src-tauri/src/providers/mod.rs index 6878410277..4f16b2725c 100644 --- a/applications/tari_collectibles/src-tauri/src/providers/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/providers/mod.rs @@ -19,3 +19,21 @@ // 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. +mod key_manager_provider; + +pub use key_manager_provider::KeyManagerProvider; + +pub mod mocks { + use crate::providers::KeyManagerProvider; + use tari_common_types::types::PublicKey; + + pub struct MockKeyManagerProvider {} + + impl KeyManagerProvider for MockKeyManagerProvider { + type Error = String; + + fn generate_asset_public_key(&self) -> Result<(String, PublicKey), Self::Error> { + todo!() + } + } +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/mod.rs b/applications/tari_collectibles/src-tauri/src/storage/mod.rs index 476fc512ed..339cc33a88 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/mod.rs @@ -24,19 +24,27 @@ pub mod models; pub mod sqlite; mod storage_error; -use crate::storage::models::{asset_row::AssetRow, wallet_row::WalletRow}; +use crate::storage::models::{ + asset_row::AssetRow, asset_wallet_row::AssetWalletRow, wallet_row::WalletRow, +}; pub use storage_error::StorageError; use tari_key_manager::cipher_seed::CipherSeed; use uuid::Uuid; +pub trait StorageTransaction { + fn commit(self) -> Result<(), StorageError>; +} + pub trait CollectiblesStorage { type Addresses: AddressesTableGateway; - type Assets: AssetsTableGateway; - type AssetWallets: AssetWalletsTableGateway; + type Assets: AssetsTableGateway; + type AssetWallets: AssetWalletsTableGateway; type IssuedAssets: IssuedAssetsTableGateway; type Tip002Addresses: Tip002AddressesTableGateway; - type Wallets: WalletsTableGateway; + type Wallets: WalletsTableGateway; + type Transaction: StorageTransaction; + fn create_transaction(&self) -> Result; fn addresses(&self) -> Self::Addresses; fn assets(&self) -> Self::Assets; fn asset_wallets(&self) -> Self::AssetWallets; @@ -45,22 +53,29 @@ pub trait CollectiblesStorage { fn wallets(&self) -> Self::Wallets; } -pub trait AssetsTableGateway { - fn list(&self) -> Result, StorageError>; - fn insert(&self, asset: AssetRow) -> Result<(), StorageError>; - fn find(&self, asset_id: Uuid) -> Result; +pub trait AssetsTableGateway { + fn list(&self, tx: Option<&T>) -> Result, StorageError>; + fn insert(&self, asset: AssetRow, tx: &T) -> Result<(), StorageError>; + fn find(&self, asset_id: Uuid, tx: Option<&T>) -> Result; } -pub trait WalletsTableGateway { +pub trait WalletsTableGateway { type Passphrase; - fn list(&self) -> Result, StorageError>; - fn insert(&self, wallet: WalletRow, pass: Self::Passphrase) -> Result<(), StorageError>; - fn find(&self, id: Uuid) -> Result; - fn get_cipher_seed(&self, id: Uuid, pass: Self::Passphrase) -> Result; + fn list(&self, tx: Option<&T>) -> Result, StorageError>; + fn insert(&self, wallet: WalletRow, pass: Self::Passphrase, tx: &T) -> Result<(), StorageError>; + fn find(&self, id: Uuid, tx: Option<&T>) -> Result; + fn get_cipher_seed( + &self, + id: Uuid, + pass: Self::Passphrase, + tx: Option<&T>, + ) -> Result; } -pub trait AssetWalletsTableGateway {} +pub trait AssetWalletsTableGateway { + fn insert(&self, row: AssetWalletRow, tx: &T) -> Result<(), StorageError>; +} pub trait AddressesTableGateway {} diff --git a/applications/tari_collectibles/src-tauri/src/storage/models/asset_wallet_row.rs b/applications/tari_collectibles/src-tauri/src/storage/models/asset_wallet_row.rs new file mode 100644 index 0000000000..2278a36734 --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/models/asset_wallet_row.rs @@ -0,0 +1,31 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +#[derive(Serialize, Deserialize)] +pub struct AssetWalletRow { + pub id: Uuid, + pub asset_id: Uuid, + pub wallet_id: Uuid, +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/models/mod.rs b/applications/tari_collectibles/src-tauri/src/storage/models/mod.rs index 48c96e9abf..6dbeebfdeb 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/models/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/models/mod.rs @@ -21,4 +21,5 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. pub mod asset_row; +pub mod asset_wallet_row; pub mod wallet_row; diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/mod.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/mod.rs index ae0433de82..5b620858c7 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/mod.rs @@ -28,6 +28,7 @@ mod sqlite_collectibles_storage; mod sqlite_db_factory; mod sqlite_issued_assets_table_gateway; mod sqlite_tip002_addresses_table_gateway; +mod sqlite_transaction; mod sqlite_wallets_table_gateway; pub use sqlite_assets_table_gateway::SqliteAssetsTableGateway; diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs index 6c34739907..01d2a76f1d 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs @@ -20,8 +20,15 @@ // 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::storage::AssetWalletsTableGateway; +use crate::storage::{ + models::asset_wallet_row::AssetWalletRow, sqlite::sqlite_transaction::SqliteTransaction, + AssetWalletsTableGateway, StorageError, +}; pub struct SqliteAssetWalletsTableGateway {} -impl AssetWalletsTableGateway for SqliteAssetWalletsTableGateway {} +impl AssetWalletsTableGateway for SqliteAssetWalletsTableGateway { + fn insert(&self, row: AssetWalletRow, tx: &SqliteTransaction) -> Result<(), StorageError> { + todo!() + } +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs index 21b859a745..fae02f9263 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs @@ -24,7 +24,7 @@ use crate::{ schema::{self, *}, storage::{ models::{asset_row::AssetRow, wallet_row::WalletRow}, - sqlite::models, + sqlite::{models, sqlite_transaction::SqliteTransaction}, AssetsTableGateway, CollectiblesStorage, StorageError, WalletsTableGateway, }, }; @@ -39,8 +39,8 @@ pub struct SqliteAssetsTableGateway { pub database_url: String, } -impl AssetsTableGateway for SqliteAssetsTableGateway { - fn list(&self) -> Result, StorageError> { +impl AssetsTableGateway for SqliteAssetsTableGateway { + fn list(&self, tx: Option<&SqliteTransaction>) -> Result, StorageError> { let conn = SqliteConnection::establish(self.database_url.as_str())?; let results: Vec = schema::assets::table .order_by(schema::assets::name.asc()) @@ -51,7 +51,7 @@ impl AssetsTableGateway for SqliteAssetsTableGateway { .collect::>() } - fn insert(&self, asset: AssetRow) -> Result<(), StorageError> { + fn insert(&self, asset: AssetRow, tx: &SqliteTransaction) -> Result<(), StorageError> { let id = Uuid::new_v4(); let mut committee_pub_keys = vec![]; if let Some(pub_keys) = asset.committee.as_ref() { @@ -83,7 +83,7 @@ impl AssetsTableGateway for SqliteAssetsTableGateway { Ok(()) } - fn find(&self, asset_id: Uuid) -> Result { + fn find(&self, asset_id: Uuid, tx: Option<&SqliteTransaction>) -> Result { let conn = SqliteConnection::establish(self.database_url.as_str())?; let db_account = schema::assets::table .find(Vec::from(asset_id.as_bytes().as_slice())) diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_collectibles_storage.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_collectibles_storage.rs index 2f05380b29..7334e7cf1d 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_collectibles_storage.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_collectibles_storage.rs @@ -29,7 +29,7 @@ use crate::{ sqlite_asset_wallets_table_gateway::SqliteAssetWalletsTableGateway, sqlite_issued_assets_table_gateway::SqliteIssuedAssetsTableGateway, sqlite_tip002_addresses_table_gateway::SqliteTip002AddressesTableGateway, - SqliteAssetsTableGateway, SqliteWalletsTableGateway, + sqlite_transaction::SqliteTransaction, SqliteAssetsTableGateway, SqliteWalletsTableGateway, }, AssetsTableGateway, CollectiblesStorage, StorageError, WalletsTableGateway, }, @@ -52,6 +52,15 @@ impl CollectiblesStorage for SqliteCollectiblesStorage { type IssuedAssets = SqliteIssuedAssetsTableGateway; type Tip002Addresses = SqliteTip002AddressesTableGateway; type Wallets = SqliteWalletsTableGateway; + type Transaction = SqliteTransaction; + + fn create_transaction(&self) -> Result { + let conn = SqliteConnection::establish(self.database_url.as_str())?; + conn.execute("PRAGMA foreign_keys = ON;")?; + conn.execute("BEGIN EXCLUSIVE TRANSACTION;")?; + + Ok(SqliteTransaction::new(conn)) + } fn addresses(&self) -> Self::Addresses { SqliteAddressesTableGateway {} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_transaction.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_transaction.rs new file mode 100644 index 0000000000..60d77c98a0 --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_transaction.rs @@ -0,0 +1,42 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use crate::storage::{StorageError, StorageTransaction}; +use diesel::{prelude::*, SqliteConnection}; + +pub struct SqliteTransaction { + connection: SqliteConnection, +} + +impl SqliteTransaction { + pub fn new(connection: SqliteConnection) -> Self { + Self { connection } + } +} + +impl StorageTransaction for SqliteTransaction { + fn commit(self) -> Result<(), StorageError> { + self.connection.execute("COMMIT TRANSACTION;")?; + + Ok(()) + } +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs index 1f69c87c50..0ee564ca13 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs @@ -24,7 +24,7 @@ use crate::{ schema::{self, *}, storage::{ models::{asset_row::AssetRow, wallet_row::WalletRow}, - sqlite::models, + sqlite::{models, sqlite_transaction::SqliteTransaction}, AssetsTableGateway, CollectiblesStorage, StorageError, WalletsTableGateway, }, }; @@ -48,10 +48,10 @@ impl SqliteWalletsTableGateway { } } -impl WalletsTableGateway for SqliteWalletsTableGateway { +impl WalletsTableGateway for SqliteWalletsTableGateway { type Passphrase = Option; - fn list(&self) -> Result, StorageError> { + fn list(&self, tx: Option<&SqliteTransaction>) -> Result, StorageError> { let conn = SqliteConnection::establish(self.database_url.as_str())?; let results: Vec = schema::wallets::table.load(&conn)?; Ok( @@ -66,7 +66,12 @@ impl WalletsTableGateway for SqliteWalletsTableGateway { ) } - fn insert(&self, wallet: WalletRow, passphrase: Self::Passphrase) -> Result<(), StorageError> { + fn insert( + &self, + wallet: WalletRow, + passphrase: Self::Passphrase, + tx: &SqliteTransaction, + ) -> Result<(), StorageError> { let id = Uuid::new_v4(); let cipher_seed = CipherSeed::new(); // todo: error @@ -85,7 +90,7 @@ impl WalletsTableGateway for SqliteWalletsTableGateway { Ok(()) } - fn find(&self, id: Uuid) -> Result { + fn find(&self, id: Uuid, tx: Option<&SqliteTransaction>) -> Result { let conn = SqliteConnection::establish(self.database_url.as_str())?; let db_wallet = schema::wallets::table .find(Vec::from(id.as_bytes().as_slice())) @@ -94,7 +99,12 @@ impl WalletsTableGateway for SqliteWalletsTableGateway { SqliteWalletsTableGateway::convert_wallet(&db_wallet) } - fn get_cipher_seed(&self, id: Uuid, pass: Self::Passphrase) -> Result { + fn get_cipher_seed( + &self, + id: Uuid, + pass: Self::Passphrase, + tx: Option<&SqliteTransaction>, + ) -> Result { let conn = SqliteConnection::establish(self.database_url.as_str())?; let w: models::Wallet = schema::wallets::table .find(Vec::from(id.as_bytes().as_slice())) From 1585985251c4d50440f7d90fa96215e843eff1c7 Mon Sep 17 00:00:00 2001 From: Mike the Tike Date: Wed, 24 Nov 2021 19:17:34 +0200 Subject: [PATCH 3/6] add get balance call --- .../2021-11-15-124424_wallet/up.sql | 3 +- .../2021-11-22-132431_key_indices/up.sql | 2 +- .../src-tauri/src/app_state.rs | 11 +- .../src-tauri/src/clients/base_node_client.rs | 31 ++++-- .../src/clients/validator_node_client.rs | 19 ++-- .../src-tauri/src/clients/wallet_client.rs | 42 +++++--- .../src/commands/asset_wallets/mod.rs | 63 +++++------ .../src-tauri/src/commands/assets/mod.rs | 84 ++++++++------- .../src-tauri/src/commands/keys/mod.rs | 38 +++---- .../src-tauri/src/commands/wallets/mod.rs | 83 ++++---------- .../tari_collectibles/src-tauri/src/error.rs | 35 ++++++ .../tari_collectibles/src-tauri/src/main.rs | 4 +- .../src-tauri/src/models/mod.rs | 2 - .../src/providers/key_manager_provider.rs | 8 +- .../src-tauri/src/providers/mod.rs | 10 +- .../tari_collectibles/src-tauri/src/schema.rs | 30 +++--- .../tari_collectibles/src-tauri/src/status.rs | 92 ++++++++++++++++ .../src-tauri/src/storage/mod.rs | 36 ++++--- .../src/storage/models/address_row.rs | 34 ++++++ .../models/key_index_row.rs} | 7 +- .../src-tauri/src/storage/models/mod.rs | 3 + .../src/storage/models/tip002_address_row.rs | 30 ++++++ .../src-tauri/src/storage/sqlite/mod.rs | 1 + .../storage/sqlite/models/tip002_address.rs | 1 + .../sqlite/sqlite_addresses_table_gateway.rs | 11 +- .../sqlite_asset_wallets_table_gateway.rs | 11 +- .../sqlite/sqlite_assets_table_gateway.rs | 2 +- .../sqlite/sqlite_collectibles_storage.rs | 8 ++ .../sqlite_key_indices_table_gateway.rs | 102 ++++++++++++++++++ .../sqlite_tip002_addresses_table_gateway.rs | 25 ++++- .../src/storage/sqlite/sqlite_transaction.rs | 3 + .../sqlite/sqlite_wallets_table_gateway.rs | 8 +- .../tari_collectibles/src-tauri/temp.sqlite | Bin 69632 -> 81920 bytes .../tari_collectibles/web-app/src/App.js | 11 +- .../tari_collectibles/web-app/src/Setup.js | 36 +++++-- .../tari_collectibles/web-app/src/binding.js | 6 +- 36 files changed, 641 insertions(+), 251 deletions(-) create mode 100644 applications/tari_collectibles/src-tauri/src/error.rs create mode 100644 applications/tari_collectibles/src-tauri/src/status.rs create mode 100644 applications/tari_collectibles/src-tauri/src/storage/models/address_row.rs rename applications/tari_collectibles/src-tauri/src/{models/key_indices.rs => storage/models/key_index_row.rs} (94%) create mode 100644 applications/tari_collectibles/src-tauri/src/storage/models/tip002_address_row.rs create mode 100644 applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_key_indices_table_gateway.rs diff --git a/applications/tari_collectibles/src-tauri/migrations/2021-11-15-124424_wallet/up.sql b/applications/tari_collectibles/src-tauri/migrations/2021-11-15-124424_wallet/up.sql index 1502e896f5..b2bf582d93 100644 --- a/applications/tari_collectibles/src-tauri/migrations/2021-11-15-124424_wallet/up.sql +++ b/applications/tari_collectibles/src-tauri/migrations/2021-11-15-124424_wallet/up.sql @@ -31,7 +31,8 @@ create table addresses ( create table tip002_address ( id blob not null primary key, address_id blob not null references addresses(id), - balance bigint not null + balance bigint not null, + at_height bigint ); create table issued_assets ( diff --git a/applications/tari_collectibles/src-tauri/migrations/2021-11-22-132431_key_indices/up.sql b/applications/tari_collectibles/src-tauri/migrations/2021-11-22-132431_key_indices/up.sql index 123d9e5f12..32930237f6 100644 --- a/applications/tari_collectibles/src-tauri/migrations/2021-11-22-132431_key_indices/up.sql +++ b/applications/tari_collectibles/src-tauri/migrations/2021-11-22-132431_key_indices/up.sql @@ -1,5 +1,5 @@ create table key_indices ( id blob not null primary key, branch_seed text not null unique, - last_index integer not null + last_index BigInt not null ); \ No newline at end of file diff --git a/applications/tari_collectibles/src-tauri/src/app_state.rs b/applications/tari_collectibles/src-tauri/src/app_state.rs index 8dec684842..fe753f3f77 100644 --- a/applications/tari_collectibles/src-tauri/src/app_state.rs +++ b/applications/tari_collectibles/src-tauri/src/app_state.rs @@ -22,6 +22,7 @@ use crate::{ clients::{BaseNodeClient, GrpcValidatorNodeClient, WalletClient}, + error::CollectiblesError, providers::{mocks::MockKeyManagerProvider, KeyManagerProvider}, settings::Settings, storage::{ @@ -94,14 +95,16 @@ impl ConcurrentAppState { WalletClient::new(self.inner.read().await.config.wallet_grpc_address.clone()) } - pub async fn connect_base_node_client(&self) -> Result { + pub async fn connect_base_node_client(&self) -> Result { let lock = self.inner.read().await; let client = BaseNodeClient::connect(format!("http://{}", lock.config.base_node_grpc_address)).await?; Ok(client) } - pub async fn connect_validator_node_client(&self) -> Result { + pub async fn connect_validator_node_client( + &self, + ) -> Result { // todo: convert this GRPC to tari comms let lock = self.inner.read().await; let client = GrpcValidatorNodeClient::connect(format!( @@ -123,4 +126,8 @@ impl ConcurrentAppState { pub async fn current_wallet_id(&self) -> Option { self.inner.read().await.current_wallet_id } + + pub async fn set_current_wallet_id(&self, wallet_id: Uuid) { + self.inner.write().await.current_wallet_id = Some(wallet_id) + } } diff --git a/applications/tari_collectibles/src-tauri/src/clients/base_node_client.rs b/applications/tari_collectibles/src-tauri/src/clients/base_node_client.rs index d94fb4afd2..19147a1748 100644 --- a/applications/tari_collectibles/src-tauri/src/clients/base_node_client.rs +++ b/applications/tari_collectibles/src-tauri/src/clients/base_node_client.rs @@ -20,6 +20,7 @@ // 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::error::CollectiblesError; use futures::StreamExt; use tari_app_grpc::tari_rpc as grpc; use tari_common_types::types::PublicKey; @@ -30,14 +31,13 @@ pub struct BaseNodeClient { } impl BaseNodeClient { - pub async fn connect(endpoint: String) -> Result { + pub async fn connect(endpoint: String) -> Result { let client = grpc::base_node_client::BaseNodeClient::connect(endpoint.clone()) .await - .map_err(|err| { - format!( - "No connection to wallet. Is it running with grpc on '{}' ? Error: {}", - endpoint, err - ) + .map_err(|err| CollectiblesError::ClientConnectionError { + client: "wallet", + address: endpoint, + error: err.to_string(), })?; Ok(Self { client }) @@ -47,18 +47,24 @@ impl BaseNodeClient { &mut self, offset: u64, count: u64, - ) -> Result, String> { + ) -> Result, CollectiblesError> { let client = self.client_mut(); let request = grpc::ListAssetRegistrationsRequest { offset, count }; let mut stream = client .list_asset_registrations(request) .await .map(|response| response.into_inner()) - .map_err(|s| format!("Could not get register assets: {}", s))?; + .map_err(|source| CollectiblesError::ClientRequestError { + request: "list_asset_registrations".to_string(), + source, + })?; let mut assets = vec![]; while let Some(result) = stream.next().await { - let asset = result.map_err(|err| err.to_string())?; + let asset = result.map_err(|source| CollectiblesError::ClientRequestError { + request: "list_asset_registrations".to_string(), + source, + })?; assets.push(asset); } @@ -68,7 +74,7 @@ impl BaseNodeClient { pub async fn get_asset_metadata( &mut self, asset_public_key: &PublicKey, - ) -> Result { + ) -> Result { let client = self.client_mut(); let request = grpc::GetAssetMetadataRequest { asset_public_key: Vec::from(asset_public_key.as_bytes()), @@ -78,7 +84,10 @@ impl BaseNodeClient { .get_asset_metadata(request) .await .map(|response| response.into_inner()) - .map_err(|s| format!("Could not get asset metadata: {}", s))?; + .map_err(|s| CollectiblesError::ClientRequestError { + request: "get_asset_metadata".to_string(), + source: s, + })?; dbg!(&response); Ok(response) } diff --git a/applications/tari_collectibles/src-tauri/src/clients/validator_node_client.rs b/applications/tari_collectibles/src-tauri/src/clients/validator_node_client.rs index 76e17511a6..6c89d1b4c6 100644 --- a/applications/tari_collectibles/src-tauri/src/clients/validator_node_client.rs +++ b/applications/tari_collectibles/src-tauri/src/clients/validator_node_client.rs @@ -19,6 +19,7 @@ // 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::error::CollectiblesError; use tari_app_grpc::tari_rpc as grpc; use tari_common_types::types::PublicKey; use tari_utilities::ByteArray; @@ -30,15 +31,14 @@ pub struct GrpcValidatorNodeClient { } impl GrpcValidatorNodeClient { - pub async fn connect(endpoint: String) -> Result { + pub async fn connect(endpoint: String) -> Result { let s = Self { client: grpc::validator_node_client::ValidatorNodeClient::connect(endpoint.clone()) .await - .map_err(|e| { - format!( - "No connection to validator node. Is it running with gRPC on '{}'? Error: {}", - endpoint, e - ) + .map_err(|e| CollectiblesError::ClientConnectionError { + client: "validator_node", + address: endpoint, + error: e.to_string(), })?, }; Ok(s) @@ -50,7 +50,7 @@ impl GrpcValidatorNodeClient { template_id: u32, method: String, args: Vec, - ) -> Result>, String> { + ) -> Result>, CollectiblesError> { let req = grpc::InvokeReadMethodRequest { asset_public_key: Vec::from(asset_public_key.as_bytes()), template_id, @@ -63,7 +63,10 @@ impl GrpcValidatorNodeClient { .invoke_read_method(req) .await .map(|resp| resp.into_inner()) - .map_err(|s| format!("Could not invoke read method: {}", s))?; + .map_err(|e| CollectiblesError::ClientRequestError { + source: e, + request: "invoke_read_method".to_string(), + })?; dbg!(&response); Ok(response.result) } diff --git a/applications/tari_collectibles/src-tauri/src/clients/wallet_client.rs b/applications/tari_collectibles/src-tauri/src/clients/wallet_client.rs index 23039cddac..ca4ffc16cf 100644 --- a/applications/tari_collectibles/src-tauri/src/clients/wallet_client.rs +++ b/applications/tari_collectibles/src-tauri/src/clients/wallet_client.rs @@ -20,6 +20,7 @@ // 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::error::CollectiblesError; use tari_app_grpc::{tari_rpc as grpc, tari_rpc::RegisterAssetRequest}; use tari_common_types::types::PublicKey; use tari_utilities::{hex::Hex, ByteArray}; @@ -37,15 +38,14 @@ impl WalletClient { } } - pub async fn connect(&mut self) -> Result<(), String> { + pub async fn connect(&mut self) -> Result<(), CollectiblesError> { let dst = format!("http://{}", self.endpoint); let client = grpc::wallet_client::WalletClient::connect(dst) .await - .map_err(|err| { - format!( - "No connection to wallet. Is it running with grpc on '{}' ? Error: {}", - self.endpoint, err - ) + .map_err(|err| CollectiblesError::ClientConnectionError { + client: "wallet", + address: self.endpoint.clone(), + error: err.to_string(), })?; self.inner = Some(client); @@ -60,7 +60,7 @@ impl WalletClient { image: String, template_ids_implemented: Vec, template_parameters: Vec, - ) -> Result { + ) -> Result { let inner = self.inner.as_mut().unwrap(); let request = RegisterAssetRequest { name, @@ -70,18 +70,27 @@ impl WalletClient { image, template_parameters, }; - let result = inner - .register_asset(request) - .await - .map_err(|s| format!("Could not register asset: {}", s))?; + let result = inner.register_asset(request).await.map_err(|error| { + CollectiblesError::ClientRequestError { + request: "register_asset".to_string(), + source: error, + } + })?; dbg!(&result); Ok(result.into_inner().public_key.to_hex()) } - pub async fn list_owned_assets(&mut self) -> Result { + pub async fn list_owned_assets( + &mut self, + ) -> Result { let inner = self.inner.as_mut().unwrap(); let request = grpc::Empty {}; - let result = inner.get_owned_assets(request).await.unwrap(); + let result = inner.get_owned_assets(request).await.map_err(|source| { + CollectiblesError::ClientRequestError { + request: "get_owned_assets".to_string(), + source, + } + })?; dbg!(&result); Ok(result.into_inner()) } @@ -91,7 +100,7 @@ impl WalletClient { asset_public_key: String, merkle_root: Vec, committee: Vec, - ) -> Result { + ) -> Result { let inner = self.inner.as_mut().unwrap(); let request = grpc::CreateInitialAssetCheckpointRequest { asset_public_key: Vec::from_hex(&asset_public_key).unwrap(), @@ -104,7 +113,10 @@ impl WalletClient { let result = inner .create_initial_asset_checkpoint(request) .await - .unwrap(); + .map_err(|source| CollectiblesError::ClientRequestError { + request: "create_initial_asset_checkpoint".to_string(), + source, + })?; dbg!(&result); Ok(result.into_inner()) } diff --git a/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs index 91d85d338c..cb78ae4ca9 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs @@ -19,11 +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::{ app_state::ConcurrentAppState, models::{NewWallet, Wallet}, + status::Status, storage::{ - models::asset_row::AssetRow, AssetsTableGateway, CollectiblesStorage, StorageTransaction, + models::{asset_row::AssetRow, asset_wallet_row::AssetWalletRow}, + AssetWalletsTableGateway, AssetsTableGateway, CollectiblesStorage, StorageTransaction, WalletsTableGateway, }, }; @@ -37,9 +40,12 @@ use uuid::Uuid; pub(crate) async fn asset_wallets_create( asset_public_key: String, state: tauri::State<'_, ConcurrentAppState>, -) -> Result<(), String> { - let asset_public_key = PublicKey::from_hex(asset_public_key.as_str()) - .map_err(|e| format!("Invalid public key:{}", e))?; +) -> Result<(), Status> { + let wallet_id = state + .current_wallet_id() + .await + .ok_or_else(Status::unauthorized)?; + let asset_public_key = PublicKey::from_hex(asset_public_key.as_str())?; let mut new_account = AssetRow { id: Uuid::new_v4(), asset_public_key: asset_public_key.clone(), @@ -69,18 +75,16 @@ pub(crate) async fn asset_wallets_create( } }; new_account.committee = sidechain_committee; - let db = state - .create_db() - .await - .map_err(|e| format!("Could not connect to DB:{}", e))?; - let tx = db - .create_transaction() - .map_err(|e| format!("Could not start transaction:{}", e))?; - db.assets() - .insert(new_account, &tx) - .map_err(|e| format!("Could not save account: {}", e))?; - tx.commit() - .map_err(|e| format!("Could not commit transaction:{}", e))?; + let db = state.create_db().await?; + let tx = db.create_transaction()?; + db.assets().insert(&new_account, &tx)?; + let new_asset_wallet = AssetWalletRow { + id: Uuid::new_v4(), + asset_id: new_account.id, + wallet_id, + }; + db.asset_wallets().insert(&new_asset_wallet, &tx)?; + tx.commit()?; Ok(()) } @@ -88,10 +92,9 @@ pub(crate) async fn asset_wallets_create( pub(crate) async fn asset_wallets_get_balance( asset_public_key: String, state: tauri::State<'_, ConcurrentAppState>, -) -> Result { +) -> Result { dbg!(&asset_public_key); - let asset_public_key = - PublicKey::from_hex(&asset_public_key).map_err(|s| format!("Not a valid public key:{}", s))?; + let asset_public_key = PublicKey::from_hex(&asset_public_key)?; let owner = PublicKey::default(); @@ -101,7 +104,7 @@ pub(crate) async fn asset_wallets_get_balance( }; dbg!(&args); let mut args_bytes = vec![]; - args.encode(&mut args_bytes).unwrap(); + args.encode(&mut args_bytes)?; // let req = grpc::InvokeReadMethodRequest{ // asset_public_key: Vec::from(asset_public_key.as_bytes()), // template_id: 2, @@ -116,8 +119,7 @@ pub(crate) async fn asset_wallets_get_balance( dbg!(&resp); match resp { Some(mut resp) => { - let proto_resp: tip002::BalanceOfResponse = - Message::decode(&*resp).map_err(|e| format!("Invalid proto:{}", e))?; + let proto_resp: tip002::BalanceOfResponse = Message::decode(&*resp)?; Ok(proto_resp.balance) } None => Ok(0), @@ -127,14 +129,15 @@ pub(crate) async fn asset_wallets_get_balance( #[tauri::command] pub(crate) async fn asset_wallets_list( state: tauri::State<'_, ConcurrentAppState>, -) -> Result, String> { - let db = state - .create_db() +) -> Result, Status> { + let wallet_id = state + .current_wallet_id() .await - .map_err(|e| format!("Could not connect to DB:{}", e))?; - let result = db - .assets() - .list(None) - .map_err(|e| format!("Could list accounts from DB: {}", e))?; + .ok_or_else(Status::unauthorized)?; + let db = state.create_db().await?; + let mut result = vec![]; + for asset_wallet in db.asset_wallets().find_by_wallet_id(wallet_id, None)? { + result.push(db.assets().find(asset_wallet.asset_id, None)?); + } Ok(result) } diff --git a/applications/tari_collectibles/src-tauri/src/commands/assets/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/assets/mod.rs index 7c6e30a3da..9010b513d1 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/assets/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/assets/mod.rs @@ -24,9 +24,14 @@ use crate::{ app_state::ConcurrentAppState, models::{AssetInfo, RegisteredAssetInfo, TemplateParameter}, providers::KeyManagerProvider, + status::Status, storage::{ - models::{asset_row::AssetRow, asset_wallet_row::AssetWalletRow}, - AssetWalletsTableGateway, AssetsTableGateway, CollectiblesStorage, StorageTransaction, + models::{ + address_row::AddressRow, asset_row::AssetRow, asset_wallet_row::AssetWalletRow, + tip002_address_row::Tip002AddressRow, + }, + AddressesTableGateway, AssetWalletsTableGateway, AssetsTableGateway, CollectiblesStorage, + StorageTransaction, Tip002AddressesTableGateway, }, }; use rand::rngs::OsRng; @@ -48,9 +53,12 @@ pub(crate) async fn assets_create( template_ids: Vec, template_parameters: Vec, state: tauri::State<'_, ConcurrentAppState>, -) -> Result { - let public_key = - PublicKey::from_hex(&public_key).map_err(|e| format!("Failed to parse public key: {}", e))?; +) -> Result { + let wallet_id = state + .current_wallet_id() + .await + .ok_or_else(|| Status::unauthorized())?; + let public_key = PublicKey::from_hex(&public_key)?; let mut client = state.create_wallet_client().await; client.connect().await?; @@ -63,57 +71,60 @@ pub(crate) async fn assets_create( }) .collect(); - // TODO: Generate and pass public key to wallet.... + let db = state.create_db().await?; + let transaction = db.create_transaction()?; let (key_manager_path, asset_public_key) = state .key_manager() .await - .generate_asset_public_key() - .map_err(|e| format!("could not generate asset public key: {}", e))?; + .generate_asset_public_key(wallet_id, &transaction) + .map_err(|e| Status::internal(format!("could not generate asset public key: {}", e)))?; + // NOTE: we are blocking the database during this time.... let res = client .register_asset( name.clone(), public_key.clone(), description.clone(), image.clone(), - template_ids, + template_ids.clone(), tp, ) .await?; - let db = state - .create_db() - .await - .map_err(|e| format!("Could not create db:{}", e))?; - let transaction = db - .create_transaction() - .map_err(|e| format!("Could not start transaction: {}", e))?; let asset_id = Uuid::new_v4(); let asset_row = AssetRow { id: asset_id, - asset_public_key, + asset_public_key: public_key.clone(), name: Some(name), description: Some(description), image: Some(image), committee: None, }; - db.assets() - .insert(asset_row, &transaction) - .map_err(|e| format!("Could not insert asset:{}", e))?; + db.assets().insert(&asset_row, &transaction)?; let asset_wallet_row = AssetWalletRow { id: Uuid::new_v4(), asset_id, - wallet_id: state - .current_wallet_id() - .await - .ok_or_else(|| "Current wallet not set".to_string())?, + wallet_id, + }; + db.asset_wallets().insert(&asset_wallet_row, &transaction)?; + let address = AddressRow { + id: Uuid::new_v4(), + asset_wallet_id: asset_wallet_row.id, + name: "Issuer wallet".to_string(), + public_key, + key_manager_path: "".to_string(), }; - db.asset_wallets() - .insert(asset_wallet_row, &transaction) - .map_err(|e| format!("Could not insert asset wallet:{}", e))?; - transaction - .commit() - .map_err(|e| format!("Could not commit transaction: {}", e))?; + db.addresses().insert(&address, &transaction)?; + if template_ids.contains(&2) { + let row = Tip002AddressRow { + id: Uuid::new_v4(), + address_id: address.id, + balance: 0, + at_height: None, + }; + db.tip002_addresses().insert(&row, &transaction)?; + } + transaction.commit()?; Ok(res) } @@ -121,8 +132,7 @@ pub(crate) async fn assets_create( #[tauri::command] pub(crate) async fn assets_list_owned( state: tauri::State<'_, ConcurrentAppState>, -) -> Result, String> { - println!("Hello list owned assets"); +) -> Result, Status> { let mut client = state.create_wallet_client().await; client.connect().await?; let assets = client.list_owned_assets().await?; @@ -145,7 +155,7 @@ pub(crate) async fn assets_list_registered_assets( offset: u64, count: u64, state: tauri::State<'_, ConcurrentAppState>, -) -> Result, String> { +) -> Result, Status> { let mut client = state.connect_base_node_client().await?; let assets = client.list_registered_assets(offset, count).await?; assets @@ -168,7 +178,7 @@ pub(crate) async fn assets_create_initial_checkpoint( asset_pub_key: String, committee: Vec, state: tauri::State<'_, ConcurrentAppState>, -) -> Result<(), String> { +) -> Result<(), Status> { let mut mmr = MerkleMountainRange::::new(MemBackendVec::new()); let root = mmr.get_merkle_root().unwrap(); @@ -188,11 +198,9 @@ pub(crate) async fn assets_create_initial_checkpoint( pub(crate) async fn assets_get_registration( asset_pub_key: String, state: tauri::State<'_, ConcurrentAppState>, -) -> Result { - dbg!("assets_get_registration"); +) -> Result { let mut client = state.connect_base_node_client().await?; - let asset_pub_key = - PublicKey::from_hex(&asset_pub_key).map_err(|e| format!("Not a valid public key:{}", e))?; + let asset_pub_key = PublicKey::from_hex(&asset_pub_key)?; let asset = client.get_asset_metadata(&asset_pub_key).await?; dbg!(&asset); diff --git a/applications/tari_collectibles/src-tauri/src/commands/keys/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/keys/mod.rs index 680ead8476..538bfe0b95 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/keys/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/keys/mod.rs @@ -22,30 +22,32 @@ use crate::{ app_state::ConcurrentAppState, - models::NewKeyIndex, - storage::{CollectiblesStorage, KeyIndicesTableGateway}, + providers::KeyManagerProvider, + status::Status, + storage::{ + models::key_index_row::KeyIndexRow, CollectiblesStorage, KeyIndicesTableGateway, + StorageTransaction, + }, }; use tari_common_types::types::PublicKey; use tari_crypto::keys::PublicKey as PublicKeyTrait; +use uuid::Uuid; #[tauri::command] pub(crate) async fn next_asset_public_key( state: tauri::State<'_, ConcurrentAppState>, -) -> Result { - let key = state.next_asset_secret_key().await?; - - let key_index = NewKeyIndex { - branch_seed: "assets".into(), - index: key.key_index, - }; - - state - .create_db() +) -> Result { + let wallet_id = state + .current_wallet_id() .await - .map_err(|e| format!("Could not connect to DB: {}", e))? - .key_indices() - .insert(key_index) - .map_err(|e| format!("Could not save key index: {}", e))?; - - Ok(PublicKey::from_secret_key(&key.k)) + .ok_or_else(Status::unauthorized)?; + let db = state.create_db().await?; + let tx = db.create_transaction()?; + let (_path, key) = state + .key_manager() + .await + .generate_asset_public_key(wallet_id, &tx) + .map_err(|e| Status::internal(format!("Could not generate asset key: {}", e)))?; + tx.commit()?; + Ok(key) } diff --git a/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs index 0fca621341..3c29807324 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs @@ -23,6 +23,7 @@ use crate::{ app_state::ConcurrentAppState, models::{NewWallet, Wallet, WalletInfo}, + status::Status, storage::{ models::wallet_row::WalletRow, CollectiblesStorage, StorageTransaction, WalletsTableGateway, }, @@ -38,95 +39,57 @@ pub(crate) async fn wallets_create( name: Option, passphrase: Option, state: tauri::State<'_, ConcurrentAppState>, -) -> Result<(), String> { +) -> Result { let new_wallet = WalletRow { id: Uuid::new_v4(), name, // cipher_seed: CipherSeed::new(), }; - let db = state - .create_db() - .await - .map_err(|e| format!("Could not connect to DB: {}", e))?; - let tx = db - .create_transaction() - .map_err(|e| format!("Could not start transaction:{}", e))?; - let result = db - .wallets() - .insert(new_wallet, passphrase, &tx) - .map_err(|e| format!("Could not save wallet: {}", e))?; - tx.commit() - .map_err(|e| format!("Could not commit transaction:{}", e))?; - Ok(()) + let db = state.create_db().await?; + let tx = db.create_transaction()?; + let result = db.wallets().insert(&new_wallet, passphrase, &tx)?; + tx.commit()?; + state.set_current_wallet_id(new_wallet.id).await; + Ok(new_wallet) } #[tauri::command] pub(crate) async fn wallets_list( state: tauri::State<'_, ConcurrentAppState>, -) -> Result, String> { - let db = state - .create_db() - .await - .map_err(|e| format!("Could not connect to DB: {}", e))?; +) -> Result, Status> { + let db = state.create_db().await?; - let result = db - .wallets() - .list(None) - .map_err(|e| format!("Could list wallets from DB: {}", e))?; + let result = db.wallets().list(None)?; Ok(result) } #[tauri::command] -pub(crate) async fn wallets_find( - id: String, +pub(crate) async fn wallets_unlock( + id: Uuid, state: tauri::State<'_, ConcurrentAppState>, -) -> Result { - let db = state - .create_db() - .await - .map_err(|e| format!("Could not connect to DB: {}", e))?; - - let uuid = Uuid::parse_str(&id).map_err(|e| format!("Failed to parse UUID: {}", e))?; - - let result = db.wallets().find(uuid, None).map_err(|e| e.to_string())?; - - let k = db - .key_indices() - .find("assets".into()) - .map_err(|e| e.to_string())?; - let index = if let Some(k) = k { k.last_index } else { 0 }; - - // update the assets key manager for this wallet - state - .set_asset_key_manager(result.cipher_seed.clone(), "assets".into(), index) - .await - .map_err(|e| e.to_string())?; +) -> Result { + let db = state.create_db().await?; + let result = db.wallets().find(id, None)?; + // TODO: decrypt using wallet password + state.set_current_wallet_id(id).await; Ok(result) } #[tauri::command] pub(crate) async fn wallets_seed_words( - id: String, + id: Uuid, passphrase: Option, state: tauri::State<'_, ConcurrentAppState>, -) -> Result, String> { - let db = state - .create_db() - .await - .map_err(|e| format!("Could not connect to DB: {}", e))?; - - let uuid = Uuid::parse_str(&id).map_err(|e| format!("Failed to parse UUID: {}", e))?; +) -> Result, Status> { + let db = state.create_db().await?; - let cipher_seed = db - .wallets() - .get_cipher_seed(uuid, passphrase.clone(), None) - .map_err(|e| e.to_string())?; + let cipher_seed = db.wallets().get_cipher_seed(id, passphrase.clone(), None)?; let seed_words = cipher_seed .to_mnemonic(&MnemonicLanguage::English, passphrase) - .map_err(|e| format!("Failed to convert cipher seed to seed words: {}", e))?; + .map_err(|e| Status::internal(format!("Could not get seed words:{}", e)))?; Ok(seed_words) } diff --git a/applications/tari_collectibles/src-tauri/src/error.rs b/applications/tari_collectibles/src-tauri/src/error.rs new file mode 100644 index 0000000000..21f99cee27 --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/error.rs @@ -0,0 +1,35 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use tonic::Status; + +#[derive(Debug, thiserror::Error)] +pub enum CollectiblesError { + #[error("No connection to {client}. Is it running with grpc on '{address}' ? Error: {error}")] + ClientConnectionError { + client: &'static str, + address: String, + error: String, + }, + #[error("Error invoking operation: {request}: {source}")] + ClientRequestError { request: String, source: Status }, +} diff --git a/applications/tari_collectibles/src-tauri/src/main.rs b/applications/tari_collectibles/src-tauri/src/main.rs index d3e425d355..80888a6e15 100644 --- a/applications/tari_collectibles/src-tauri/src/main.rs +++ b/applications/tari_collectibles/src-tauri/src/main.rs @@ -15,10 +15,12 @@ extern crate diesel_migrations; mod app_state; mod clients; mod commands; +mod error; mod models; mod providers; mod schema; mod settings; +mod status; mod storage; fn main() { @@ -39,7 +41,7 @@ fn main() { commands::keys::next_asset_public_key, commands::wallets::wallets_create, commands::wallets::wallets_list, - commands::wallets::wallets_find, + commands::wallets::wallets_unlock, commands::wallets::wallets_seed_words, ]) .run(tauri::generate_context!()) diff --git a/applications/tari_collectibles/src-tauri/src/models/mod.rs b/applications/tari_collectibles/src-tauri/src/models/mod.rs index f6e4243494..bf414b32aa 100644 --- a/applications/tari_collectibles/src-tauri/src/models/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/models/mod.rs @@ -32,5 +32,3 @@ mod template_parameter; pub use template_parameter::TemplateParameter; mod output_features; pub use output_features::OutputFeatures; -mod key_indices; -pub use key_indices::{KeyIndex, NewKeyIndex}; diff --git a/applications/tari_collectibles/src-tauri/src/providers/key_manager_provider.rs b/applications/tari_collectibles/src-tauri/src/providers/key_manager_provider.rs index 8b2a1555bf..0b2b8e2c2e 100644 --- a/applications/tari_collectibles/src-tauri/src/providers/key_manager_provider.rs +++ b/applications/tari_collectibles/src-tauri/src/providers/key_manager_provider.rs @@ -20,10 +20,16 @@ // 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::storage::StorageTransaction; use std::fmt::Display; use tari_common_types::types::PublicKey; +use uuid::Uuid; pub trait KeyManagerProvider { type Error: Display; - fn generate_asset_public_key(&self) -> Result<(String, PublicKey), Self::Error>; + fn generate_asset_public_key( + &self, + wallet_id: Uuid, + transaction: &T, + ) -> Result<(String, PublicKey), Self::Error>; } diff --git a/applications/tari_collectibles/src-tauri/src/providers/mod.rs b/applications/tari_collectibles/src-tauri/src/providers/mod.rs index 4f16b2725c..5b2416d2c1 100644 --- a/applications/tari_collectibles/src-tauri/src/providers/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/providers/mod.rs @@ -20,19 +20,23 @@ // 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. mod key_manager_provider; - pub use key_manager_provider::KeyManagerProvider; pub mod mocks { - use crate::providers::KeyManagerProvider; + use crate::{providers::KeyManagerProvider, storage::StorageTransaction}; use tari_common_types::types::PublicKey; + use uuid::Uuid; pub struct MockKeyManagerProvider {} impl KeyManagerProvider for MockKeyManagerProvider { type Error = String; - fn generate_asset_public_key(&self) -> Result<(String, PublicKey), Self::Error> { + fn generate_asset_public_key( + &self, + wallet_id: Uuid, + transaction: &T, + ) -> Result<(String, PublicKey), Self::Error> { todo!() } } diff --git a/applications/tari_collectibles/src-tauri/src/schema.rs b/applications/tari_collectibles/src-tauri/src/schema.rs index 3a561635cd..ee34260fba 100644 --- a/applications/tari_collectibles/src-tauri/src/schema.rs +++ b/applications/tari_collectibles/src-tauri/src/schema.rs @@ -38,11 +38,20 @@ table! { } } +table! { + key_indices (id) { + id -> Binary, + branch_seed -> Text, + last_index -> BigInt, + } +} + table! { tip002_address (id) { id -> Binary, address_id -> Binary, balance -> BigInt, + at_height -> Nullable, } } @@ -54,14 +63,6 @@ table! { } } -table! { - key_indices (id) { - id -> Binary, - branch_seed -> Text, - last_index -> BigInt, - } -} - joinable!(addresses -> asset_wallets (asset_wallet_id)); joinable!(asset_wallets -> assets (asset_id)); joinable!(asset_wallets -> wallets (wallet_id)); @@ -69,10 +70,11 @@ joinable!(issued_assets -> wallets (wallet_id)); joinable!(tip002_address -> addresses (address_id)); allow_tables_to_appear_in_same_query!( - addresses, - asset_wallets, - assets, - issued_assets, - tip002_address, - wallets, + addresses, + asset_wallets, + assets, + issued_assets, + key_indices, + tip002_address, + wallets, ); diff --git a/applications/tari_collectibles/src-tauri/src/status.rs b/applications/tari_collectibles/src-tauri/src/status.rs new file mode 100644 index 0000000000..3d41cf6ccc --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/status.rs @@ -0,0 +1,92 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use crate::{error::CollectiblesError, storage::StorageError}; +use prost::{DecodeError, EncodeError}; +use serde::{Deserialize, Serialize}; +use tari_utilities::hex::HexError; + +#[derive(Serialize, Deserialize)] +#[serde(tag = "status")] +pub enum Status { + BadRequest { code: u16, message: String }, + Unauthorized { code: u16, message: String }, + Internal { code: u16, message: String }, +} + +impl Status { + pub fn unauthorized() -> Self { + Self::Unauthorized { + code: 401, + message: "Unauthorized".to_string(), + } + } + + pub fn internal(message: String) -> Self { + Self::Internal { code: 500, message } + } +} + +impl From for Status { + fn from(source: StorageError) -> Self { + Self::Internal { + code: 501, + message: format!("Internal storage error:{}", source), + } + } +} + +impl From for Status { + fn from(he: HexError) -> Self { + Self::BadRequest { + code: 400, + message: format!("Bad request: {}", he), + } + } +} + +impl From for Status { + fn from(de: DecodeError) -> Self { + Self::Internal { + code: 502, + message: format!("Could not decode data: {}", de), + } + } +} + +impl From for Status { + fn from(e: EncodeError) -> Self { + Self::Internal { + code: 503, + message: format!("Could not encode data: {}", e), + } + } +} + +impl From for Status { + fn from(ce: CollectiblesError) -> Self { + Self::Internal { + code: 504, + message: format!("Error:{}", ce), + } + } +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/mod.rs b/applications/tari_collectibles/src-tauri/src/storage/mod.rs index 41f00201ad..2d6a5e7b47 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/mod.rs @@ -25,7 +25,8 @@ pub mod sqlite; mod storage_error; use crate::storage::models::{ - asset_row::AssetRow, asset_wallet_row::AssetWalletRow, wallet_row::WalletRow, + address_row::AddressRow, asset_row::AssetRow, asset_wallet_row::AssetWalletRow, + key_index_row::KeyIndexRow, tip002_address_row::Tip002AddressRow, wallet_row::WalletRow, }; pub use storage_error::StorageError; use tari_key_manager::cipher_seed::CipherSeed; @@ -36,12 +37,12 @@ pub trait StorageTransaction { } pub trait CollectiblesStorage { - type Addresses: AddressesTableGateway; + type Addresses: AddressesTableGateway; type Assets: AssetsTableGateway; type AssetWallets: AssetWalletsTableGateway; type IssuedAssets: IssuedAssetsTableGateway; - type Tip002Addresses: Tip002AddressesTableGateway; - type KeyIndices: KeyIndicesTableGateway; + type Tip002Addresses: Tip002AddressesTableGateway; + type KeyIndices: KeyIndicesTableGateway; type Wallets: WalletsTableGateway; type Transaction: StorageTransaction; @@ -57,7 +58,7 @@ pub trait CollectiblesStorage { pub trait AssetsTableGateway { fn list(&self, tx: Option<&T>) -> Result, StorageError>; - fn insert(&self, asset: AssetRow, tx: &T) -> Result<(), StorageError>; + fn insert(&self, asset: &AssetRow, tx: &T) -> Result<(), StorageError>; fn find(&self, asset_id: Uuid, tx: Option<&T>) -> Result; } @@ -65,7 +66,7 @@ pub trait WalletsTableGateway { type Passphrase; fn list(&self, tx: Option<&T>) -> Result, StorageError>; - fn insert(&self, wallet: WalletRow, pass: Self::Passphrase, tx: &T) -> Result<(), StorageError>; + fn insert(&self, wallet: &WalletRow, pass: Self::Passphrase, tx: &T) -> Result<(), StorageError>; fn find(&self, id: Uuid, tx: Option<&T>) -> Result; fn get_cipher_seed( &self, @@ -75,18 +76,27 @@ pub trait WalletsTableGateway { ) -> Result; } -pub trait KeyIndicesTableGateway { - fn list(&self) -> Result, StorageError>; - fn insert(&self, key_index: NewKeyIndex) -> Result; - fn find(&self, branch_seed: String) -> Result, StorageError>; +pub trait KeyIndicesTableGateway { + fn list(&self, tx: Option<&T>) -> Result, StorageError>; + fn insert(&self, key_index: KeyIndexRow, tx: &T) -> Result<(), StorageError>; + fn find(&self, branch_seed: String, tx: Option<&T>) -> Result, StorageError>; } pub trait AssetWalletsTableGateway { - fn insert(&self, row: AssetWalletRow, tx: &T) -> Result<(), StorageError>; + fn insert(&self, row: &AssetWalletRow, tx: &T) -> Result<(), StorageError>; + fn find_by_wallet_id( + &self, + wallet_id: Uuid, + tx: Option<&T>, + ) -> Result, StorageError>; } -pub trait AddressesTableGateway {} +pub trait AddressesTableGateway { + fn insert(&self, row: &AddressRow, tx: &T) -> Result<(), StorageError>; +} pub trait IssuedAssetsTableGateway {} -pub trait Tip002AddressesTableGateway {} +pub trait Tip002AddressesTableGateway { + fn insert(&self, row: &Tip002AddressRow, tx: &T) -> Result<(), StorageError>; +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/models/address_row.rs b/applications/tari_collectibles/src-tauri/src/storage/models/address_row.rs new file mode 100644 index 0000000000..2489394b0a --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/models/address_row.rs @@ -0,0 +1,34 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use serde::{Deserialize, Serialize}; +use tari_common_types::types::PublicKey; +use uuid::Uuid; + +#[derive(Serialize, Deserialize)] +pub struct AddressRow { + pub id: Uuid, + pub asset_wallet_id: Uuid, + pub name: String, + pub public_key: PublicKey, + pub key_manager_path: String, +} diff --git a/applications/tari_collectibles/src-tauri/src/models/key_indices.rs b/applications/tari_collectibles/src-tauri/src/storage/models/key_index_row.rs similarity index 94% rename from applications/tari_collectibles/src-tauri/src/models/key_indices.rs rename to applications/tari_collectibles/src-tauri/src/storage/models/key_index_row.rs index 10a752591d..75fef97d77 100644 --- a/applications/tari_collectibles/src-tauri/src/models/key_indices.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/models/key_index_row.rs @@ -24,13 +24,8 @@ use serde::{Deserialize, Serialize}; use uuid::Uuid; #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct KeyIndex { +pub struct KeyIndexRow { pub id: Uuid, pub branch_seed: String, pub last_index: u64, } - -pub struct NewKeyIndex { - pub branch_seed: String, - pub index: u64, -} diff --git a/applications/tari_collectibles/src-tauri/src/storage/models/mod.rs b/applications/tari_collectibles/src-tauri/src/storage/models/mod.rs index 6dbeebfdeb..31236566f5 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/models/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/models/mod.rs @@ -20,6 +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. +pub mod address_row; pub mod asset_row; pub mod asset_wallet_row; +pub mod key_index_row; +pub mod tip002_address_row; pub mod wallet_row; diff --git a/applications/tari_collectibles/src-tauri/src/storage/models/tip002_address_row.rs b/applications/tari_collectibles/src-tauri/src/storage/models/tip002_address_row.rs new file mode 100644 index 0000000000..ea911dc4a4 --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/models/tip002_address_row.rs @@ -0,0 +1,30 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use uuid::Uuid; + +pub struct Tip002AddressRow { + pub id: Uuid, + pub address_id: Uuid, + pub balance: u64, + pub at_height: Option, +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/mod.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/mod.rs index 5b620858c7..d88d6f7aaf 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/mod.rs @@ -27,6 +27,7 @@ mod sqlite_assets_table_gateway; mod sqlite_collectibles_storage; mod sqlite_db_factory; mod sqlite_issued_assets_table_gateway; +mod sqlite_key_indices_table_gateway; mod sqlite_tip002_addresses_table_gateway; mod sqlite_transaction; mod sqlite_wallets_table_gateway; diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/tip002_address.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/tip002_address.rs index 00cabfe0e8..36076569cd 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/tip002_address.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/tip002_address.rs @@ -27,4 +27,5 @@ pub struct Tip002Address { pub id: Vec, pub address_id: Vec, pub balance: i64, + pub at_height: Option, } diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_addresses_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_addresses_table_gateway.rs index 0ed2a2d08c..1e7d009d93 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_addresses_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_addresses_table_gateway.rs @@ -20,8 +20,15 @@ // 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::storage::AddressesTableGateway; +use crate::storage::{ + models::address_row::AddressRow, sqlite::sqlite_transaction::SqliteTransaction, + AddressesTableGateway, StorageError, +}; pub struct SqliteAddressesTableGateway {} -impl AddressesTableGateway for SqliteAddressesTableGateway {} +impl AddressesTableGateway for SqliteAddressesTableGateway { + fn insert(&self, row: &AddressRow, tx: &SqliteTransaction) -> Result<(), StorageError> { + todo!() + } +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs index 01d2a76f1d..cbef2c2c8c 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs @@ -24,11 +24,20 @@ use crate::storage::{ models::asset_wallet_row::AssetWalletRow, sqlite::sqlite_transaction::SqliteTransaction, AssetWalletsTableGateway, StorageError, }; +use uuid::Uuid; pub struct SqliteAssetWalletsTableGateway {} impl AssetWalletsTableGateway for SqliteAssetWalletsTableGateway { - fn insert(&self, row: AssetWalletRow, tx: &SqliteTransaction) -> Result<(), StorageError> { + fn insert(&self, row: &AssetWalletRow, tx: &SqliteTransaction) -> Result<(), StorageError> { + todo!() + } + + fn find_by_wallet_id( + &self, + wallet_id: Uuid, + tx: Option<&SqliteTransaction>, + ) -> Result, StorageError> { todo!() } } diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs index fae02f9263..e1440c41d5 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs @@ -51,7 +51,7 @@ impl AssetsTableGateway for SqliteAssetsTableGateway { .collect::>() } - fn insert(&self, asset: AssetRow, tx: &SqliteTransaction) -> Result<(), StorageError> { + fn insert(&self, asset: &AssetRow, tx: &SqliteTransaction) -> Result<(), StorageError> { let id = Uuid::new_v4(); let mut committee_pub_keys = vec![]; if let Some(pub_keys) = asset.committee.as_ref() { diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_collectibles_storage.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_collectibles_storage.rs index 7334e7cf1d..cd1106bdea 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_collectibles_storage.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_collectibles_storage.rs @@ -28,6 +28,7 @@ use crate::{ sqlite_addresses_table_gateway::SqliteAddressesTableGateway, sqlite_asset_wallets_table_gateway::SqliteAssetWalletsTableGateway, sqlite_issued_assets_table_gateway::SqliteIssuedAssetsTableGateway, + sqlite_key_indices_table_gateway::SqliteKeyIndicesTableGateway, sqlite_tip002_addresses_table_gateway::SqliteTip002AddressesTableGateway, sqlite_transaction::SqliteTransaction, SqliteAssetsTableGateway, SqliteWalletsTableGateway, }, @@ -51,6 +52,7 @@ impl CollectiblesStorage for SqliteCollectiblesStorage { type AssetWallets = SqliteAssetWalletsTableGateway; type IssuedAssets = SqliteIssuedAssetsTableGateway; type Tip002Addresses = SqliteTip002AddressesTableGateway; + type KeyIndices = SqliteKeyIndicesTableGateway; type Wallets = SqliteWalletsTableGateway; type Transaction = SqliteTransaction; @@ -84,6 +86,12 @@ impl CollectiblesStorage for SqliteCollectiblesStorage { SqliteTip002AddressesTableGateway {} } + fn key_indices(&self) -> Self::KeyIndices { + SqliteKeyIndicesTableGateway { + database_url: self.database_url.clone(), + } + } + fn wallets(&self) -> Self::Wallets { SqliteWalletsTableGateway { database_url: self.database_url.clone(), diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_key_indices_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_key_indices_table_gateway.rs new file mode 100644 index 0000000000..206953d360 --- /dev/null +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_key_indices_table_gateway.rs @@ -0,0 +1,102 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use crate::{ + schema, + schema::key_indices, + storage::{ + models::key_index_row::KeyIndexRow, + sqlite::{models, sqlite_transaction::SqliteTransaction}, + KeyIndicesTableGateway, StorageError, + }, +}; +use diesel::{prelude::*, Connection, SqliteConnection}; +use uuid::Uuid; + +pub struct SqliteKeyIndicesTableGateway { + pub database_url: String, +} + +impl KeyIndicesTableGateway for SqliteKeyIndicesTableGateway { + fn list(&self, tx: Option<&SqliteTransaction>) -> Result, StorageError> { + let conn = SqliteConnection::establish(self.database_url.as_str())?; + let results: Vec = schema::key_indices::table.load(&conn)?; + Ok( + results + .iter() + .map(|k| KeyIndexRow { + id: Uuid::from_slice(&k.id).unwrap(), + branch_seed: k.branch_seed.clone(), + last_index: k.last_index as u64, + }) + .collect(), + ) + } + + fn insert(&self, key_index: KeyIndexRow, tx: &SqliteTransaction) -> Result<(), StorageError> { + let conn = SqliteConnection::establish(self.database_url.as_str())?; + let find_result: Option = schema::key_indices::table + .filter(key_indices::branch_seed.eq(key_index.branch_seed.clone())) + .first(&conn) + .optional()?; + + let result = match find_result { + Some(k) => { + // update existing + let id = k.id.clone(); + diesel::update(key_indices::table.filter(key_indices::id.eq(id))) + .set(key_indices::last_index.eq(key_index.last_index as i64)) + .execute(&conn)?; + } + None => { + let sql_model = models::KeyIndex { + id: Vec::from(key_index.id.as_bytes().as_slice()), + branch_seed: key_index.branch_seed.clone(), + last_index: key_index.last_index as i64, + }; + diesel::insert_into(key_indices::table) + .values(sql_model) + .execute(&conn)?; + } + }; + + Ok(()) + } + + fn find( + &self, + branch_seed: String, + tx: Option<&SqliteTransaction>, + ) -> Result, StorageError> { + let conn = SqliteConnection::establish(self.database_url.as_str())?; + let result: Option = schema::key_indices::table + .filter(key_indices::branch_seed.eq(branch_seed)) + .first(&conn) + .optional()?; + + Ok(result.map(|k| KeyIndexRow { + id: Uuid::from_slice(&k.id).unwrap(), + branch_seed: k.branch_seed.clone(), + last_index: k.last_index as u64, + })) + } +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_tip002_addresses_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_tip002_addresses_table_gateway.rs index 6a0497f184..22abec931a 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_tip002_addresses_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_tip002_addresses_table_gateway.rs @@ -20,8 +20,29 @@ // 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::storage::Tip002AddressesTableGateway; +use crate::{ + schema::tip002_address::dsl::tip002_address, + storage::{ + models::tip002_address_row::Tip002AddressRow, + sqlite::{models::Tip002Address, sqlite_transaction::SqliteTransaction}, + StorageError, Tip002AddressesTableGateway, + }, +}; +use diesel::RunQueryDsl; pub struct SqliteTip002AddressesTableGateway {} -impl Tip002AddressesTableGateway for SqliteTip002AddressesTableGateway {} +impl Tip002AddressesTableGateway for SqliteTip002AddressesTableGateway { + fn insert(&self, row: &Tip002AddressRow, tx: &SqliteTransaction) -> Result<(), StorageError> { + let db_row = Tip002Address { + id: Vec::from(row.id.as_bytes().as_slice()), + address_id: Vec::from(row.address_id.as_bytes().as_slice()), + balance: 0, + at_height: None, + }; + diesel::insert_into(tip002_address) + .values(db_row) + .execute(tx.connection())?; + Ok(()) + } +} diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_transaction.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_transaction.rs index 60d77c98a0..d55dd39081 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_transaction.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_transaction.rs @@ -31,6 +31,9 @@ impl SqliteTransaction { pub fn new(connection: SqliteConnection) -> Self { Self { connection } } + pub fn connection(&self) -> &SqliteConnection { + &self.connection + } } impl StorageTransaction for SqliteTransaction { diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs index 0ee564ca13..6d9783a8de 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs @@ -68,24 +68,22 @@ impl WalletsTableGateway for SqliteWalletsTableGateway { fn insert( &self, - wallet: WalletRow, + wallet: &WalletRow, passphrase: Self::Passphrase, tx: &SqliteTransaction, ) -> Result<(), StorageError> { - let id = Uuid::new_v4(); let cipher_seed = CipherSeed::new(); // todo: error let sql_model = models::Wallet { - id: Vec::from(id.as_bytes().as_slice()), + id: Vec::from(wallet.id.as_bytes().as_slice()), name: wallet.name.clone(), cipher_seed: cipher_seed.encipher(passphrase).unwrap(), }; - let conn = SqliteConnection::establish(self.database_url.as_str())?; // use crate::schema::wallets; diesel::insert_into(wallets::table) .values(sql_model) - .execute(&conn)?; + .execute(tx.connection())?; Ok(()) } diff --git a/applications/tari_collectibles/src-tauri/temp.sqlite b/applications/tari_collectibles/src-tauri/temp.sqlite index b5c6c85aef9e03a1b6d812547486490e08468c36..59394d00266f2b8263ad8ebb1a27558943d1fd6d 100644 GIT binary patch delta 426 zcmZozz|zpbIzd{HnSp^p1c+gPW1@~R4>N1lW0j|Qch}iYGr(8UP@+iYB3U1$T`T>F~n6N#L>yeRRJL} z*?>n&AgL%ZFF7N=I5jmzp(M4UWO5^~m~u{HaS6zv)CvWs%yiGZ5{0~cATG_x;pNga z6=oCnRGxg0M?xN9R&l%$5=X>T2&P67NjTmRi6gwZh24>nGlG|0TvL;=DSPrcj_nFM zyj%)EkXRC*k(!yFQKFEPnVy+f0<_hdk4@ZP6J+b=Wt?$r98COM82E4TZ`mv;u!3Jr zg^5|y*vP=h(9qDx$k5ox#MltT(={~IH8N2!G`BJ|u`)55d`n(N48i3B1~wD_Z3g~# c{I@p?DxBvR7Gl<9L^XwJ^E-W^2a6I609-eCrvLx| delta 143 zcmZo@U~O2yGC^99iGhJZ5Qt%beWH#r4-6#>U8hi-G^vWF|asjPkc;Kn1v diff --git a/applications/tari_collectibles/web-app/src/App.js b/applications/tari_collectibles/web-app/src/App.js index 802aefa4e3..303731708e 100644 --- a/applications/tari_collectibles/web-app/src/App.js +++ b/applications/tari_collectibles/web-app/src/App.js @@ -163,7 +163,7 @@ const AccountsMenu = (props) => { // only allow access to a Protected Route if the wallet is unlocked const ProtectedRoute = ({ authenticated, path, children }) => { - if (!authenticated) return ; + if (!authenticated) return ; return {children}; }; @@ -262,9 +262,7 @@ function App() { > - - - + { @@ -274,9 +272,12 @@ function App() { }} /> - + + + + diff --git a/applications/tari_collectibles/web-app/src/Setup.js b/applications/tari_collectibles/web-app/src/Setup.js index c9682e36b8..645d55ca61 100644 --- a/applications/tari_collectibles/web-app/src/Setup.js +++ b/applications/tari_collectibles/web-app/src/Setup.js @@ -26,7 +26,7 @@ import { TextField, Stack, Typography, - FormGroup, + FormGroup, Alert, } from "@mui/material"; import React, { useState, useEffect } from "react"; import { Spinner } from "./components"; @@ -47,11 +47,16 @@ const chunk = (arr, len) => { const SeedWords = ({ wallet, password, history }) => { const [seedWords, setSeedWords] = useState([]); + const [error, setError] = useState(""); useEffect(() => { binding .command_wallets_seed_words(wallet.id, password) .then((words) => setSeedWords(words)) - .catch((e) => console.error("error: ", e)); + .catch((e) => { + + console.error("error: ", e); + setError(e); + }); }, [wallet.id, password]); const display = (seedWords) => { @@ -73,6 +78,11 @@ const SeedWords = ({ wallet, password, history }) => { Seed words + {error ? ( + {error} + ) : ( + + )}

Save these seed words securely. This is the recovery phrase for this wallet. @@ -80,7 +90,7 @@ const SeedWords = ({ wallet, password, history }) => { {display(seedWords)} @@ -93,6 +103,7 @@ const CreateWallet = ({ history }) => { const [password2, setPassword2] = useState(""); const [creating, setCreating] = useState(false); const [wallet, setWallet] = useState(undefined); + const [error, setError] = useState(""); if (wallet) return ; @@ -106,10 +117,14 @@ const CreateWallet = ({ history }) => { const create = async () => { setCreating(true); - // todo: error handle - const wallet = await binding.command_wallets_create(password, "main"); - console.log("wallet", wallet); - setWallet(wallet); + try { + const wallet = await binding.command_wallets_create(password, "main"); + console.log("wallet", wallet); + setWallet(wallet); + } + catch(err) { + setError(err); + } }; return ( @@ -118,6 +133,11 @@ const CreateWallet = ({ history }) => { Create new wallet + {error ? ( + {error} + ) : ( + + )} { const unlock = async () => { setUnlocking(true); try { - await binding.command_wallets_find(id, password); + await binding.command_wallets_unlock(id, password); setAuthenticated(id, password); history.push("/dashboard"); } catch (e) { diff --git a/applications/tari_collectibles/web-app/src/binding.js b/applications/tari_collectibles/web-app/src/binding.js index 4c969bada6..f8674f9cf8 100644 --- a/applications/tari_collectibles/web-app/src/binding.js +++ b/applications/tari_collectibles/web-app/src/binding.js @@ -69,8 +69,8 @@ async function command_wallets_create(passphrase, name) { return await invoke("wallets_create", { passphrase, name }); } -async function command_wallets_find(id, passphrase) { - return await invoke("wallets_find", { id, passphrase }); +async function command_wallets_unlock(id, passphrase) { + return await invoke("wallets_unlock", { id, passphrase }); } async function command_wallets_seed_words(id, passphrase) { @@ -110,7 +110,7 @@ const commands = { command_asset_wallets_list, command_wallets_create, command_wallets_list, - command_wallets_find, + command_wallets_unlock, command_wallets_seed_words, }; From 69b32aa63c47c49b9599f79da39b187c71a88eda Mon Sep 17 00:00:00 2001 From: Mike the Tike Date: Thu, 25 Nov 2021 09:40:56 +0200 Subject: [PATCH 4/6] save asset_wallet and asset on create --- .../src-tauri/src/app_state.rs | 43 +++------- .../src/commands/asset_wallets/mod.rs | 5 +- .../src-tauri/src/commands/assets/mod.rs | 17 ++-- .../src-tauri/src/commands/keys/mod.rs | 4 +- .../src-tauri/src/commands/wallets/mod.rs | 2 +- .../src/providers/key_manager_provider.rs | 84 +++++++++++++++++-- .../src-tauri/src/providers/mod.rs | 22 +---- .../src-tauri/src/storage/mod.rs | 32 ++++--- .../src/storage/models/address_row.rs | 2 +- .../src-tauri/src/storage/models/asset_row.rs | 2 +- .../src/storage/models/asset_wallet_row.rs | 2 +- .../src-tauri/src/storage/sqlite/mod.rs | 1 + .../sqlite/sqlite_addresses_table_gateway.rs | 24 +++++- .../sqlite_asset_wallets_table_gateway.rs | 21 +++-- .../sqlite/sqlite_assets_table_gateway.rs | 16 ++-- .../src/storage/sqlite/sqlite_db_factory.rs | 7 +- .../sqlite_key_indices_table_gateway.rs | 67 ++++++++------- .../sqlite/sqlite_wallets_table_gateway.rs | 21 +++-- .../src-tauri/src/storage/storage_error.rs | 6 ++ .../tari_collectibles/web-app/src/Create.js | 19 +---- .../tari_collectibles/web-app/src/Setup.js | 6 +- .../tari_collectibles/web-app/src/binding.js | 2 - 22 files changed, 241 insertions(+), 164 deletions(-) diff --git a/applications/tari_collectibles/src-tauri/src/app_state.rs b/applications/tari_collectibles/src-tauri/src/app_state.rs index fe753f3f77..4ab4ccd15b 100644 --- a/applications/tari_collectibles/src-tauri/src/app_state.rs +++ b/applications/tari_collectibles/src-tauri/src/app_state.rs @@ -23,7 +23,7 @@ use crate::{ clients::{BaseNodeClient, GrpcValidatorNodeClient, WalletClient}, error::CollectiblesError, - providers::{mocks::MockKeyManagerProvider, KeyManagerProvider}, + providers::{ConcreteKeyManagerProvider, KeyManagerProvider}, settings::Settings, storage::{ sqlite::{SqliteCollectiblesStorage, SqliteDbFactory}, @@ -40,14 +40,9 @@ use tari_key_manager::{ use tauri::async_runtime::RwLock; use uuid::Uuid; -type KeyDigest = Blake256; -pub type DerivedKey = DerivedKeyGeneric; -pub type KeyManager = GenericKeyManager; - pub struct AppState { config: Settings, db_factory: SqliteDbFactory, - asset_key_manager: KeyManager, current_wallet_id: Option, } @@ -59,38 +54,17 @@ pub struct ConcurrentAppState { impl ConcurrentAppState { pub fn new() -> Self { let settings = Settings::new(); + let db_factory = SqliteDbFactory::new(settings.data_dir.as_path()); + Self { inner: Arc::new(RwLock::new(AppState { - db_factory: SqliteDbFactory::new(settings.data_dir.as_path()), + db_factory, config: settings, - asset_key_manager: KeyManager::new(), current_wallet_id: None, })), } } - pub async fn set_asset_key_manager( - &self, - seed: CipherSeed, - branch_seed: String, - primary_key_index: u64, - ) -> Result { - self.inner.write().await.asset_key_manager = - KeyManager::from(seed, branch_seed, primary_key_index); - - Ok(true) - } - - pub async fn next_asset_secret_key(&self) -> Result { - self - .inner - .write() - .await - .asset_key_manager - .next_key() - .map_err(|e| e.to_string()) - } - pub async fn create_wallet_client(&self) -> WalletClient { WalletClient::new(self.inner.read().await.config.wallet_grpc_address.clone()) } @@ -116,11 +90,14 @@ impl ConcurrentAppState { } pub async fn create_db(&self) -> Result { - self.inner.read().await.db_factory.create_db() + let inner = self.inner.read().await; + inner.db_factory.migrate()?; + inner.db_factory.create_db() } - pub async fn key_manager(&self) -> impl KeyManagerProvider { - MockKeyManagerProvider {} + pub async fn key_manager(&self) -> ConcreteKeyManagerProvider { + let db_factory = self.inner.read().await.db_factory.clone(); + ConcreteKeyManagerProvider::new(db_factory) } pub async fn current_wallet_id(&self) -> Option { diff --git a/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs index cb78ae4ca9..189ffa9955 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs @@ -135,9 +135,10 @@ pub(crate) async fn asset_wallets_list( .await .ok_or_else(Status::unauthorized)?; let db = state.create_db().await?; + let tx = db.create_transaction()?; let mut result = vec![]; - for asset_wallet in db.asset_wallets().find_by_wallet_id(wallet_id, None)? { - result.push(db.assets().find(asset_wallet.asset_id, None)?); + for asset_wallet in db.asset_wallets().find_by_wallet_id(wallet_id, &tx)? { + result.push(db.assets().find(asset_wallet.asset_id, &tx)?); } Ok(result) } diff --git a/applications/tari_collectibles/src-tauri/src/commands/assets/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/assets/mod.rs index 9010b513d1..66f7e5a0cc 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/assets/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/assets/mod.rs @@ -47,7 +47,6 @@ use uuid::Uuid; #[tauri::command] pub(crate) async fn assets_create( name: String, - public_key: String, description: String, image: String, template_ids: Vec, @@ -58,7 +57,6 @@ pub(crate) async fn assets_create( .current_wallet_id() .await .ok_or_else(|| Status::unauthorized())?; - let public_key = PublicKey::from_hex(&public_key)?; let mut client = state.create_wallet_client().await; client.connect().await?; @@ -73,17 +71,17 @@ pub(crate) async fn assets_create( let db = state.create_db().await?; let transaction = db.create_transaction()?; - let (key_manager_path, asset_public_key) = state + let (key_manager_path, _, asset_public_key) = state .key_manager() .await - .generate_asset_public_key(wallet_id, &transaction) + .generate_asset_public_key(wallet_id, None, &transaction) .map_err(|e| Status::internal(format!("could not generate asset public key: {}", e)))?; // NOTE: we are blocking the database during this time.... let res = client .register_asset( name.clone(), - public_key.clone(), + asset_public_key.clone(), description.clone(), image.clone(), template_ids.clone(), @@ -94,26 +92,29 @@ pub(crate) async fn assets_create( let asset_id = Uuid::new_v4(); let asset_row = AssetRow { id: asset_id, - asset_public_key: public_key.clone(), + asset_public_key: asset_public_key.clone(), name: Some(name), description: Some(description), image: Some(image), committee: None, }; + dbg!(&asset_row); db.assets().insert(&asset_row, &transaction)?; let asset_wallet_row = AssetWalletRow { id: Uuid::new_v4(), asset_id, wallet_id, }; + dbg!(&asset_wallet_row); db.asset_wallets().insert(&asset_wallet_row, &transaction)?; let address = AddressRow { id: Uuid::new_v4(), asset_wallet_id: asset_wallet_row.id, name: "Issuer wallet".to_string(), - public_key, - key_manager_path: "".to_string(), + public_key: asset_public_key, + key_manager_path: key_manager_path.clone(), }; + dbg!(&address); db.addresses().insert(&address, &transaction)?; if template_ids.contains(&2) { let row = Tip002AddressRow { diff --git a/applications/tari_collectibles/src-tauri/src/commands/keys/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/keys/mod.rs index 538bfe0b95..fbb01cc1a1 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/keys/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/keys/mod.rs @@ -43,10 +43,10 @@ pub(crate) async fn next_asset_public_key( .ok_or_else(Status::unauthorized)?; let db = state.create_db().await?; let tx = db.create_transaction()?; - let (_path, key) = state + let (_path, _, key) = state .key_manager() .await - .generate_asset_public_key(wallet_id, &tx) + .generate_asset_public_key(wallet_id, None, &tx) .map_err(|e| Status::internal(format!("Could not generate asset key: {}", e)))?; tx.commit()?; Ok(key) diff --git a/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs index 3c29807324..4a441fe4e2 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs @@ -48,7 +48,7 @@ pub(crate) async fn wallets_create( let db = state.create_db().await?; let tx = db.create_transaction()?; - let result = db.wallets().insert(&new_wallet, passphrase, &tx)?; + let result = db.wallets().insert(&new_wallet, None, &tx)?; tx.commit()?; state.set_current_wallet_id(new_wallet.id).await; Ok(new_wallet) diff --git a/applications/tari_collectibles/src-tauri/src/providers/key_manager_provider.rs b/applications/tari_collectibles/src-tauri/src/providers/key_manager_provider.rs index 0b2b8e2c2e..d710b1a5f6 100644 --- a/applications/tari_collectibles/src-tauri/src/providers/key_manager_provider.rs +++ b/applications/tari_collectibles/src-tauri/src/providers/key_manager_provider.rs @@ -20,16 +20,90 @@ // 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::storage::StorageTransaction; +use crate::{ + error::CollectiblesError, + storage::{ + models::key_index_row::KeyIndexRow, + sqlite::{SqliteDbFactory, SqliteTransaction}, + CollectiblesStorage, KeyIndicesTableGateway, StorageError, StorageTransaction, + WalletsTableGateway, + }, +}; use std::fmt::Display; -use tari_common_types::types::PublicKey; +use tari_common_types::types::{PrivateKey, PublicKey}; +use tari_crypto::{common::Blake256, keys::PublicKey as PublicKeyTrait}; +use tari_key_manager::key_manager::KeyManager; +use tari_utilities::ByteArrayError; use uuid::Uuid; -pub trait KeyManagerProvider { +pub trait KeyManagerProvider { type Error: Display; - fn generate_asset_public_key( + fn generate_asset_public_key( &self, wallet_id: Uuid, + passphrase: Option, transaction: &T, - ) -> Result<(String, PublicKey), Self::Error>; + ) -> Result<(String, PrivateKey, PublicKey), Self::Error>; +} + +pub struct ConcreteKeyManagerProvider { + db_factory: SqliteDbFactory, +} + +impl ConcreteKeyManagerProvider { + pub fn new(db_factory: SqliteDbFactory) -> Self { + Self { db_factory } + } +} + +#[derive(Debug, thiserror::Error)] +pub enum KeyManagerProviderError { + #[error("Could not derive key:{0}")] + CouldNotDeriveKey(#[from] ByteArrayError), + #[error("Storage error:{0}")] + StorageError(#[from] StorageError), +} + +impl KeyManagerProvider for ConcreteKeyManagerProvider { + type Error = KeyManagerProviderError; + + fn generate_asset_public_key( + &self, + wallet_id: Uuid, + passphrase: Option, + transaction: &SqliteTransaction, + ) -> Result<(String, PrivateKey, PublicKey), Self::Error> { + let db = self.db_factory.create_db()?; + let cipher_seed = db + .wallets() + .get_cipher_seed(wallet_id, passphrase, Some(&transaction))?; + let row = match db.key_indices().find("assets".to_string(), &transaction)? { + Some(row) => row, + None => { + let row = KeyIndexRow { + id: Uuid::new_v4(), + branch_seed: "assets".to_string(), + last_index: 0, + }; + + db.key_indices().insert(&row, &transaction)?; + row + } + }; + + let mut key_manager = KeyManager::::from( + cipher_seed, + row.branch_seed.clone(), + row.last_index, + ); + let new_key = key_manager + .next_key() + .map_err(KeyManagerProviderError::CouldNotDeriveKey)?; + + db.key_indices() + .update_last_index(&row, new_key.key_index, transaction)?; + + let pub_key = PublicKey::from_secret_key(&new_key.k); + Ok((format!("assets:{}", new_key.key_index), new_key.k, pub_key)) + } } diff --git a/applications/tari_collectibles/src-tauri/src/providers/mod.rs b/applications/tari_collectibles/src-tauri/src/providers/mod.rs index 5b2416d2c1..f2cd4bde0e 100644 --- a/applications/tari_collectibles/src-tauri/src/providers/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/providers/mod.rs @@ -20,24 +20,4 @@ // 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. mod key_manager_provider; -pub use key_manager_provider::KeyManagerProvider; - -pub mod mocks { - use crate::{providers::KeyManagerProvider, storage::StorageTransaction}; - use tari_common_types::types::PublicKey; - use uuid::Uuid; - - pub struct MockKeyManagerProvider {} - - impl KeyManagerProvider for MockKeyManagerProvider { - type Error = String; - - fn generate_asset_public_key( - &self, - wallet_id: Uuid, - transaction: &T, - ) -> Result<(String, PublicKey), Self::Error> { - todo!() - } - } -} +pub use key_manager_provider::{ConcreteKeyManagerProvider, KeyManagerProvider}; diff --git a/applications/tari_collectibles/src-tauri/src/storage/mod.rs b/applications/tari_collectibles/src-tauri/src/storage/mod.rs index 2d6a5e7b47..20456be3c6 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/mod.rs @@ -57,38 +57,46 @@ pub trait CollectiblesStorage { } pub trait AssetsTableGateway { - fn list(&self, tx: Option<&T>) -> Result, StorageError>; + fn list(&self, tx: &T) -> Result, StorageError>; fn insert(&self, asset: &AssetRow, tx: &T) -> Result<(), StorageError>; - fn find(&self, asset_id: Uuid, tx: Option<&T>) -> Result; + fn find(&self, asset_id: Uuid, tx: &T) -> Result; } pub trait WalletsTableGateway { type Passphrase; fn list(&self, tx: Option<&T>) -> Result, StorageError>; - fn insert(&self, wallet: &WalletRow, pass: Self::Passphrase, tx: &T) -> Result<(), StorageError>; + fn insert( + &self, + wallet: &WalletRow, + pass: Option, + tx: &T, + ) -> Result<(), StorageError>; fn find(&self, id: Uuid, tx: Option<&T>) -> Result; fn get_cipher_seed( &self, id: Uuid, - pass: Self::Passphrase, + pass: Option, tx: Option<&T>, ) -> Result; } pub trait KeyIndicesTableGateway { - fn list(&self, tx: Option<&T>) -> Result, StorageError>; - fn insert(&self, key_index: KeyIndexRow, tx: &T) -> Result<(), StorageError>; - fn find(&self, branch_seed: String, tx: Option<&T>) -> Result, StorageError>; + fn list(&self, tx: &T) -> Result, StorageError>; + fn insert(&self, key_index: &KeyIndexRow, tx: &T) -> Result<(), StorageError>; + fn update_last_index( + &self, + old_row: &KeyIndexRow, + new_last_index: u64, + tx: &T, + ) -> Result<(), StorageError>; + fn find(&self, branch_seed: String, tx: &T) -> Result, StorageError>; } pub trait AssetWalletsTableGateway { fn insert(&self, row: &AssetWalletRow, tx: &T) -> Result<(), StorageError>; - fn find_by_wallet_id( - &self, - wallet_id: Uuid, - tx: Option<&T>, - ) -> Result, StorageError>; + fn find_by_wallet_id(&self, wallet_id: Uuid, tx: &T) + -> Result, StorageError>; } pub trait AddressesTableGateway { diff --git a/applications/tari_collectibles/src-tauri/src/storage/models/address_row.rs b/applications/tari_collectibles/src-tauri/src/storage/models/address_row.rs index 2489394b0a..2e990aa7fa 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/models/address_row.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/models/address_row.rs @@ -24,7 +24,7 @@ use serde::{Deserialize, Serialize}; use tari_common_types::types::PublicKey; use uuid::Uuid; -#[derive(Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct AddressRow { pub id: Uuid, pub asset_wallet_id: Uuid, diff --git a/applications/tari_collectibles/src-tauri/src/storage/models/asset_row.rs b/applications/tari_collectibles/src-tauri/src/storage/models/asset_row.rs index f60c158bc3..f8993df14f 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/models/asset_row.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/models/asset_row.rs @@ -24,7 +24,7 @@ use serde::{Deserialize, Serialize}; use tari_common_types::types::PublicKey; use uuid::Uuid; -#[derive(Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct AssetRow { pub id: Uuid, pub asset_public_key: PublicKey, diff --git a/applications/tari_collectibles/src-tauri/src/storage/models/asset_wallet_row.rs b/applications/tari_collectibles/src-tauri/src/storage/models/asset_wallet_row.rs index 2278a36734..390f3486a6 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/models/asset_wallet_row.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/models/asset_wallet_row.rs @@ -23,7 +23,7 @@ use serde::{Deserialize, Serialize}; use uuid::Uuid; -#[derive(Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct AssetWalletRow { pub id: Uuid, pub asset_id: Uuid, diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/mod.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/mod.rs index d88d6f7aaf..f5f8e9537d 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/mod.rs @@ -35,4 +35,5 @@ mod sqlite_wallets_table_gateway; pub use sqlite_assets_table_gateway::SqliteAssetsTableGateway; pub use sqlite_collectibles_storage::SqliteCollectiblesStorage; pub use sqlite_db_factory::SqliteDbFactory; +pub use sqlite_transaction::SqliteTransaction; pub use sqlite_wallets_table_gateway::SqliteWalletsTableGateway; diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_addresses_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_addresses_table_gateway.rs index 1e7d009d93..5356fc9985 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_addresses_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_addresses_table_gateway.rs @@ -20,15 +20,31 @@ // 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::storage::{ - models::address_row::AddressRow, sqlite::sqlite_transaction::SqliteTransaction, - AddressesTableGateway, StorageError, +use crate::{ + schema::addresses, + storage::{ + models::address_row::AddressRow, + sqlite::{models, sqlite_transaction::SqliteTransaction}, + AddressesTableGateway, StorageError, + }, }; +use diesel::RunQueryDsl; +use tari_utilities::ByteArray; pub struct SqliteAddressesTableGateway {} impl AddressesTableGateway for SqliteAddressesTableGateway { fn insert(&self, row: &AddressRow, tx: &SqliteTransaction) -> Result<(), StorageError> { - todo!() + let model = models::Address { + id: Vec::from(row.id.as_bytes().as_slice()), + asset_wallet_id: Vec::from(row.asset_wallet_id.as_bytes().as_slice()), + name: Some(row.name.clone()), + public_key: Vec::from(row.public_key.as_bytes()), + key_manager_path: row.key_manager_path.clone(), + }; + diesel::insert_into(addresses::table) + .values(model) + .execute(tx.connection())?; + Ok(()) } } diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs index cbef2c2c8c..0a76cea008 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs @@ -20,23 +20,34 @@ // 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::storage::{ - models::asset_wallet_row::AssetWalletRow, sqlite::sqlite_transaction::SqliteTransaction, - AssetWalletsTableGateway, StorageError, +use crate::{ + schema::asset_wallets, + storage::{ + models::asset_wallet_row::AssetWalletRow, sqlite::sqlite_transaction::SqliteTransaction, + AssetWalletsTableGateway, StorageError, + }, }; +use diesel::{prelude::*, RunQueryDsl}; use uuid::Uuid; pub struct SqliteAssetWalletsTableGateway {} impl AssetWalletsTableGateway for SqliteAssetWalletsTableGateway { fn insert(&self, row: &AssetWalletRow, tx: &SqliteTransaction) -> Result<(), StorageError> { - todo!() + diesel::insert_into(asset_wallets::table) + .values(( + asset_wallets::id.eq(Vec::from(row.id.as_bytes().as_slice())), + asset_wallets::wallet_id.eq(Vec::from(row.wallet_id.as_bytes().as_slice())), + asset_wallets::asset_id.eq(Vec::from(row.asset_id.as_bytes().as_slice())), + )) + .execute(tx.connection())?; + Ok(()) } fn find_by_wallet_id( &self, wallet_id: Uuid, - tx: Option<&SqliteTransaction>, + tx: &SqliteTransaction, ) -> Result, StorageError> { todo!() } diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs index e1440c41d5..da3fe9e36f 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs @@ -40,11 +40,10 @@ pub struct SqliteAssetsTableGateway { } impl AssetsTableGateway for SqliteAssetsTableGateway { - fn list(&self, tx: Option<&SqliteTransaction>) -> Result, StorageError> { - let conn = SqliteConnection::establish(self.database_url.as_str())?; + fn list(&self, tx: &SqliteTransaction) -> Result, StorageError> { let results: Vec = schema::assets::table .order_by(schema::assets::name.asc()) - .load(&conn)?; + .load(tx.connection())?; results .iter() .map(SqliteAssetsTableGateway::convert_asset) @@ -52,7 +51,6 @@ impl AssetsTableGateway for SqliteAssetsTableGateway { } fn insert(&self, asset: &AssetRow, tx: &SqliteTransaction) -> Result<(), StorageError> { - let id = Uuid::new_v4(); let mut committee_pub_keys = vec![]; if let Some(pub_keys) = asset.committee.as_ref() { for key in pub_keys { @@ -62,7 +60,7 @@ impl AssetsTableGateway for SqliteAssetsTableGateway { // let committee_pub_keys = if committee_pub_keys.is_empty() { None} else {Some(committee_pub_keys)}; let sql_model = models::Asset { - id: Vec::from(id.as_bytes().as_slice()), + id: Vec::from(asset.id.as_bytes().as_slice()), asset_public_key: Vec::from(asset.asset_public_key.as_bytes()), name: asset.name.clone(), description: asset.description.clone(), @@ -74,20 +72,18 @@ impl AssetsTableGateway for SqliteAssetsTableGateway { .unwrap_or(0i32), committee_pub_keys, }; - let conn = SqliteConnection::establish(self.database_url.as_str())?; diesel::insert_into(assets::table) .values(sql_model) - .execute(&conn)?; + .execute(tx.connection())?; Ok(()) } - fn find(&self, asset_id: Uuid, tx: Option<&SqliteTransaction>) -> Result { - let conn = SqliteConnection::establish(self.database_url.as_str())?; + fn find(&self, asset_id: Uuid, tx: &SqliteTransaction) -> Result { let db_account = schema::assets::table .find(Vec::from(asset_id.as_bytes().as_slice())) - .get_result(&conn)?; + .get_result(tx.connection())?; SqliteAssetsTableGateway::convert_asset(&db_account) } diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_db_factory.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_db_factory.rs index 07c1d093d4..f3a29b2613 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_db_factory.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_db_factory.rs @@ -35,6 +35,7 @@ use tari_key_manager::{cipher_seed::CipherSeed, error::KeyManagerError}; use tari_utilities::ByteArray; use uuid::Uuid; +#[derive(Clone)] pub struct SqliteDbFactory { database_url: String, } @@ -52,12 +53,16 @@ impl SqliteDbFactory { Self { database_url } } - pub fn create_db(&self) -> Result { + pub fn migrate(&self) -> Result<(), StorageError> { let connection = SqliteConnection::establish(self.database_url.as_str())?; connection.execute("PRAGMA foreign_keys = ON;")?; // Create the db embed_migrations!("./migrations"); embedded_migrations::run(&connection)?; + + Ok(()) + } + pub fn create_db(&self) -> Result { Ok(SqliteCollectiblesStorage { database_url: self.database_url.clone(), }) diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_key_indices_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_key_indices_table_gateway.rs index 206953d360..07c79eb91e 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_key_indices_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_key_indices_table_gateway.rs @@ -37,9 +37,8 @@ pub struct SqliteKeyIndicesTableGateway { } impl KeyIndicesTableGateway for SqliteKeyIndicesTableGateway { - fn list(&self, tx: Option<&SqliteTransaction>) -> Result, StorageError> { - let conn = SqliteConnection::establish(self.database_url.as_str())?; - let results: Vec = schema::key_indices::table.load(&conn)?; + fn list(&self, tx: &SqliteTransaction) -> Result, StorageError> { + let results: Vec = schema::key_indices::table.load(tx.connection())?; Ok( results .iter() @@ -52,32 +51,39 @@ impl KeyIndicesTableGateway for SqliteKeyIndicesTableGateway ) } - fn insert(&self, key_index: KeyIndexRow, tx: &SqliteTransaction) -> Result<(), StorageError> { - let conn = SqliteConnection::establish(self.database_url.as_str())?; - let find_result: Option = schema::key_indices::table - .filter(key_indices::branch_seed.eq(key_index.branch_seed.clone())) - .first(&conn) - .optional()?; - - let result = match find_result { - Some(k) => { - // update existing - let id = k.id.clone(); - diesel::update(key_indices::table.filter(key_indices::id.eq(id))) - .set(key_indices::last_index.eq(key_index.last_index as i64)) - .execute(&conn)?; - } - None => { - let sql_model = models::KeyIndex { - id: Vec::from(key_index.id.as_bytes().as_slice()), - branch_seed: key_index.branch_seed.clone(), - last_index: key_index.last_index as i64, - }; - diesel::insert_into(key_indices::table) - .values(sql_model) - .execute(&conn)?; - } + fn insert(&self, key_index: &KeyIndexRow, tx: &SqliteTransaction) -> Result<(), StorageError> { + let sql_model = models::KeyIndex { + id: Vec::from(key_index.id.as_bytes().as_slice()), + branch_seed: key_index.branch_seed.clone(), + last_index: key_index.last_index as i64, }; + diesel::insert_into(key_indices::table) + .values(sql_model) + .execute(tx.connection())?; + + Ok(()) + } + + fn update_last_index( + &self, + old_row: &KeyIndexRow, + new_last_index: u64, + tx: &SqliteTransaction, + ) -> Result<(), StorageError> { + let rows_affected = diesel::update( + key_indices::table + .filter(key_indices::id.eq(Vec::from(old_row.id.as_bytes().as_slice()))) + .filter(key_indices::last_index.eq(old_row.last_index as i64)), + ) + .set(key_indices::last_index.eq(new_last_index as i64)) + .execute(tx.connection())?; + if rows_affected != 1 { + return Err(StorageError::ConcurrencyError { + table: "key_indices", + old_value: old_row.last_index.to_string(), + new_value: new_last_index.to_string(), + }); + } Ok(()) } @@ -85,12 +91,11 @@ impl KeyIndicesTableGateway for SqliteKeyIndicesTableGateway fn find( &self, branch_seed: String, - tx: Option<&SqliteTransaction>, + tx: &SqliteTransaction, ) -> Result, StorageError> { - let conn = SqliteConnection::establish(self.database_url.as_str())?; let result: Option = schema::key_indices::table .filter(key_indices::branch_seed.eq(branch_seed)) - .first(&conn) + .first(tx.connection()) .optional()?; Ok(result.map(|k| KeyIndexRow { diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs index 6d9783a8de..8130241b3a 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs @@ -31,7 +31,10 @@ use crate::{ use diesel::{prelude::*, Connection, SqliteConnection}; use std::{fs, path::Path}; use tari_common_types::types::PublicKey; -use tari_key_manager::{cipher_seed::CipherSeed, error::KeyManagerError}; +use tari_key_manager::{ + cipher_seed::{CipherSeed, DEFAULT_CIPHER_SEED_PASSPHRASE}, + error::KeyManagerError, +}; use tari_utilities::ByteArray; use uuid::Uuid; @@ -49,7 +52,7 @@ impl SqliteWalletsTableGateway { } impl WalletsTableGateway for SqliteWalletsTableGateway { - type Passphrase = Option; + type Passphrase = String; fn list(&self, tx: Option<&SqliteTransaction>) -> Result, StorageError> { let conn = SqliteConnection::establish(self.database_url.as_str())?; @@ -69,7 +72,7 @@ impl WalletsTableGateway for SqliteWalletsTableGateway { fn insert( &self, wallet: &WalletRow, - passphrase: Self::Passphrase, + passphrase: Option, tx: &SqliteTransaction, ) -> Result<(), StorageError> { let cipher_seed = CipherSeed::new(); @@ -100,13 +103,19 @@ impl WalletsTableGateway for SqliteWalletsTableGateway { fn get_cipher_seed( &self, id: Uuid, - pass: Self::Passphrase, + pass: Option, tx: Option<&SqliteTransaction>, ) -> Result { - let conn = SqliteConnection::establish(self.database_url.as_str())?; + let mut other_conn = None; + if tx.is_none() { + other_conn = Some(SqliteConnection::establish(self.database_url.as_str())?); + } let w: models::Wallet = schema::wallets::table .find(Vec::from(id.as_bytes().as_slice())) - .get_result(&conn)?; + .get_result( + tx.map(|t| t.connection()) + .unwrap_or_else(|| other_conn.as_ref().unwrap()), + )?; let cipher_seed = match CipherSeed::from_enciphered_bytes(&w.cipher_seed, pass) { Ok(seed) => seed, Err(e) if matches!(e, KeyManagerError::DecryptionFailed) => { diff --git a/applications/tari_collectibles/src-tauri/src/storage/storage_error.rs b/applications/tari_collectibles/src-tauri/src/storage/storage_error.rs index 9afc30ca25..31eb2e6d42 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/storage_error.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/storage_error.rs @@ -49,4 +49,10 @@ pub enum StorageError { }, #[error("The password is incorrect")] WrongPassword, + #[error("Could not update value in database because another thread has already updated it. Table:{table}, old_value: {old_value}, new_value:{new_value}")] + ConcurrencyError { + table: &'static str, + old_value: String, + new_value: String, + }, } diff --git a/applications/tari_collectibles/web-app/src/Create.js b/applications/tari_collectibles/web-app/src/Create.js index c018ea2f6d..ef5e216de7 100644 --- a/applications/tari_collectibles/web-app/src/Create.js +++ b/applications/tari_collectibles/web-app/src/Create.js @@ -48,7 +48,6 @@ class Create extends React.Component { this.state = { name: "Asset1", - publicKey: "", description: "", image: "", cid: "", @@ -74,15 +73,7 @@ class Create extends React.Component { componentDidMount() { this.cleanup = appWindow.listen("tauri://file-drop", this.dropFile); console.log("didmount"); - if (!this.state.publicKey) { - binding - .command_next_asset_public_key() - .then((publicKey) => { - console.log("public key", publicKey); - this.setState({ publicKey }); - }) - .catch((e) => console.error(e)); - } + } dropFile = async ({ payload }) => { @@ -100,7 +91,7 @@ class Create extends React.Component { save = async () => { this.setState({ isSaving: true }); - let { name, publicKey, description, image } = this.state; + let { name, description, image } = this.state; try { let templateIds = [1]; let templateParameters = []; @@ -135,15 +126,13 @@ class Create extends React.Component { }); } - let pk = await binding.command_assets_create( + let publicKey = await binding.command_assets_create( name, - publicKey, description, image, templateIds, templateParameters ); - console.log("pk", pk); // TODO: How to create the initial checkpoint? if (this.state.tip003) { @@ -159,7 +148,7 @@ class Create extends React.Component { history.push(`/assets/manage/${publicKey}`); } catch (err) { this.setState({ - error: "Could not create asset: " + err, + error: "Could not create asset: " + err.message, }); console.log(err); } diff --git a/applications/tari_collectibles/web-app/src/Setup.js b/applications/tari_collectibles/web-app/src/Setup.js index 645d55ca61..f32606c2d0 100644 --- a/applications/tari_collectibles/web-app/src/Setup.js +++ b/applications/tari_collectibles/web-app/src/Setup.js @@ -55,7 +55,7 @@ const SeedWords = ({ wallet, password, history }) => { .catch((e) => { console.error("error: ", e); - setError(e); + setError(e.message); }); }, [wallet.id, password]); @@ -123,7 +123,7 @@ const CreateWallet = ({ history }) => { setWallet(wallet); } catch(err) { - setError(err); + setError(err.message); } }; @@ -184,7 +184,7 @@ const OpenWallet = ({ history, setAuthenticated }) => { } catch (e) { console.error("error: ", e); setUnlocking(false); - setError(e); + setError(e.message); } }; diff --git a/applications/tari_collectibles/web-app/src/binding.js b/applications/tari_collectibles/web-app/src/binding.js index f8674f9cf8..cee4eb1cd0 100644 --- a/applications/tari_collectibles/web-app/src/binding.js +++ b/applications/tari_collectibles/web-app/src/binding.js @@ -24,7 +24,6 @@ import { invoke } from "@tauri-apps/api/tauri"; async function command_assets_create( name, - publicKey, description, image, templateIds, @@ -33,7 +32,6 @@ async function command_assets_create( console.log("command_assets_create:", templateParameters); return await invoke("assets_create", { name, - publicKey, description, image, templateIds, From 656d5fc9778ef6a3f88683d36bab09b744c704eb Mon Sep 17 00:00:00 2001 From: Mike the Tike Date: Thu, 25 Nov 2021 14:27:41 +0200 Subject: [PATCH 5/6] save asset_wallet and asset on create --- .../sqlite/sqlite_asset_wallets_table_gateway.rs | 16 ++++++++++++++-- .../web-app/src/AccountDashboard.js | 2 +- .../tari_collectibles/web-app/src/App.js | 9 +++++++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs index 0a76cea008..a7f5e3cf45 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_asset_wallets_table_gateway.rs @@ -23,7 +23,8 @@ use crate::{ schema::asset_wallets, storage::{ - models::asset_wallet_row::AssetWalletRow, sqlite::sqlite_transaction::SqliteTransaction, + models::asset_wallet_row::AssetWalletRow, + sqlite::{models, sqlite_transaction::SqliteTransaction}, AssetWalletsTableGateway, StorageError, }, }; @@ -49,6 +50,17 @@ impl AssetWalletsTableGateway for SqliteAssetWalletsTableGate wallet_id: Uuid, tx: &SqliteTransaction, ) -> Result, StorageError> { - todo!() + let asset_wallets: Vec = asset_wallets::table + .filter(asset_wallets::wallet_id.eq(Vec::from(wallet_id.as_bytes().as_slice()))) + .get_results(tx.connection())?; + let mut result = vec![]; + for aw in asset_wallets { + result.push(AssetWalletRow { + id: Uuid::from_slice(aw.id.as_slice())?, + asset_id: Uuid::from_slice(aw.asset_id.as_slice())?, + wallet_id: Uuid::from_slice(aw.wallet_id.as_slice())?, + }); + } + Ok(result) } } diff --git a/applications/tari_collectibles/web-app/src/AccountDashboard.js b/applications/tari_collectibles/web-app/src/AccountDashboard.js index f5e6f389c4..b048aa39bf 100644 --- a/applications/tari_collectibles/web-app/src/AccountDashboard.js +++ b/applications/tari_collectibles/web-app/src/AccountDashboard.js @@ -46,7 +46,7 @@ class AccountDashboard extends React.Component { console.log("balance", balance); } catch(err) { - this.setState({error: err}); + this.setState({error: err.message}); } } diff --git a/applications/tari_collectibles/web-app/src/App.js b/applications/tari_collectibles/web-app/src/App.js index 303731708e..e853d907e9 100644 --- a/applications/tari_collectibles/web-app/src/App.js +++ b/applications/tari_collectibles/web-app/src/App.js @@ -116,8 +116,11 @@ ListItemLink.propTypes = { const AccountsMenu = (props) => { const [accounts, setAccounts] = useState([]); + const [error, setError] = useState(""); useEffect(() => { + console.log("refreshing accounts"); + setError(""); binding .command_asset_wallets_list() .then((accounts) => { @@ -127,8 +130,9 @@ const AccountsMenu = (props) => { .catch((e) => { // todo error handling console.error("accounts_list error:", e); + setError(e.message); }); - }, []); + }, [props.walletId]); // todo: hide accounts when not authenticated return ( @@ -147,6 +151,7 @@ const AccountsMenu = (props) => { My Assets + { error ? {error} : ""} {accounts.map((item) => { return ( @@ -212,7 +217,7 @@ function App() { icon={} /> - + Issued Assets Date: Thu, 25 Nov 2021 15:55:59 +0200 Subject: [PATCH 6/6] save asset_wallet and asset on create --- .../src-tauri/src/app_state.rs | 9 +--- .../src/commands/asset_wallets/mod.rs | 4 +- .../src-tauri/src/commands/assets/mod.rs | 12 ++--- .../src-tauri/src/commands/keys/mod.rs | 7 +-- .../src-tauri/src/commands/mod.rs | 1 - .../src-tauri/src/commands/tips/mod.rs | 23 --------- .../src-tauri/src/commands/tips/tip002.rs | 49 ------------------- .../src-tauri/src/commands/wallets/mod.rs | 10 ++-- .../src-tauri/src/models/mod.rs | 2 +- .../src-tauri/src/models/wallet.rs | 5 -- .../src/providers/key_manager_provider.rs | 19 +++---- .../tari_collectibles/src-tauri/src/schema.rs | 14 +++--- .../src/storage/models/wallet_row.rs | 2 +- .../src/storage/sqlite/models/address.rs | 1 - .../src/storage/sqlite/models/asset.rs | 1 - .../src/storage/sqlite/models/asset_wallet.rs | 1 - .../storage/sqlite/models/tip002_address.rs | 1 - .../sqlite/sqlite_assets_table_gateway.rs | 11 ++--- .../sqlite/sqlite_collectibles_storage.rs | 30 ++++-------- .../src/storage/sqlite/sqlite_db_factory.rs | 16 +----- .../sqlite_key_indices_table_gateway.rs | 2 +- .../sqlite/sqlite_wallets_table_gateway.rs | 18 +++---- .../tari_validator_node/src/dan_node.rs | 14 +++--- .../src/grpc/conversions.rs | 4 +- .../src/grpc/validator_node_grpc_server.rs | 15 +++--- applications/tari_validator_node/src/main.rs | 4 +- .../src/p2p/proto/conversions/dan.rs | 7 ++- .../src/p2p/rpc/service_impl.rs | 6 +-- .../services/inbound_connection_service.rs | 5 +- .../services/outbound_connection_service.rs | 2 +- base_layer/wallet/src/assets/asset_manager.rs | 11 ++--- .../infrastructure/asset_manager_service.rs | 5 +- base_layer/wallet/src/types.rs | 23 +-------- dan_layer/core/src/models/committee.rs | 4 ++ dan_layer/core/src/models/instruction.rs | 2 +- dan_layer/core/src/models/mod.rs | 1 - dan_layer/core/src/models/tari_dan_payload.rs | 15 ++---- .../core/src/services/asset_processor.rs | 27 +++++----- .../core/src/services/events_publisher.rs | 5 +- .../core/src/services/mempool_service.rs | 13 ++--- .../core/src/services/payload_processor.rs | 24 +++------ dan_layer/core/src/storage/chain/chain_db.rs | 10 +--- .../storage/chain/chain_db_unit_of_work.rs | 9 ++-- dan_layer/core/src/storage/chain/mod.rs | 2 - .../core/src/storage/chain_storage_service.rs | 2 +- dan_layer/core/src/storage/mod.rs | 24 +-------- dan_layer/core/src/storage/state/state_db.rs | 1 - .../storage/state/state_db_unit_of_work.rs | 5 +- .../core/src/templates/tip002_template.rs | 2 +- .../core/src/workers/consensus_worker.rs | 10 ++-- .../core/src/workers/states/commit_state.rs | 2 +- .../core/src/workers/states/decide_state.rs | 2 +- .../core/src/workers/states/idle_state.rs | 5 +- .../core/src/workers/states/next_view.rs | 7 +-- .../src/workers/states/pre_commit_state.rs | 2 +- dan_layer/core/src/workers/states/prepare.rs | 19 ++----- dan_layer/core/src/workers/states/starting.rs | 24 ++++----- .../src/sqlite_chain_backend_adapter.rs | 34 +++++++------ .../storage_sqlite/src/sqlite_db_factory.rs | 24 +++++---- .../src/sqlite_state_db_backend_adapter.rs | 16 ++++-- .../src/sqlite_storage_service.rs | 4 +- 61 files changed, 202 insertions(+), 427 deletions(-) delete mode 100644 applications/tari_collectibles/src-tauri/src/commands/tips/mod.rs delete mode 100644 applications/tari_collectibles/src-tauri/src/commands/tips/tip002.rs diff --git a/applications/tari_collectibles/src-tauri/src/app_state.rs b/applications/tari_collectibles/src-tauri/src/app_state.rs index 4ab4ccd15b..f2f81edef4 100644 --- a/applications/tari_collectibles/src-tauri/src/app_state.rs +++ b/applications/tari_collectibles/src-tauri/src/app_state.rs @@ -23,7 +23,7 @@ use crate::{ clients::{BaseNodeClient, GrpcValidatorNodeClient, WalletClient}, error::CollectiblesError, - providers::{ConcreteKeyManagerProvider, KeyManagerProvider}, + providers::ConcreteKeyManagerProvider, settings::Settings, storage::{ sqlite::{SqliteCollectiblesStorage, SqliteDbFactory}, @@ -31,12 +31,7 @@ use crate::{ }, }; use std::sync::Arc; -use tari_common_types::types::{PrivateKey, PublicKey}; -use tari_crypto::common::Blake256; -use tari_key_manager::{ - cipher_seed::CipherSeed, - key_manager::{DerivedKey as DerivedKeyGeneric, KeyManager as GenericKeyManager}, -}; + use tauri::async_runtime::RwLock; use uuid::Uuid; diff --git a/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs index 189ffa9955..0d9ea11bd2 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/asset_wallets/mod.rs @@ -22,12 +22,10 @@ use crate::{ app_state::ConcurrentAppState, - models::{NewWallet, Wallet}, status::Status, storage::{ models::{asset_row::AssetRow, asset_wallet_row::AssetWalletRow}, AssetWalletsTableGateway, AssetsTableGateway, CollectiblesStorage, StorageTransaction, - WalletsTableGateway, }, }; use prost::Message; @@ -118,7 +116,7 @@ pub(crate) async fn asset_wallets_get_balance( dbg!(&resp); match resp { - Some(mut resp) => { + Some(resp) => { let proto_resp: tip002::BalanceOfResponse = Message::decode(&*resp)?; Ok(proto_resp.balance) } diff --git a/applications/tari_collectibles/src-tauri/src/commands/assets/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/assets/mod.rs index 66f7e5a0cc..82ed348a24 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/assets/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/assets/mod.rs @@ -34,14 +34,12 @@ use crate::{ StorageTransaction, Tip002AddressesTableGateway, }, }; -use rand::rngs::OsRng; + use tari_app_grpc::tari_rpc::{self}; use tari_common_types::types::{Commitment, PublicKey}; -use tari_crypto::{ - hash::blake2::Blake256, keys::PublicKey as PublicKeyTrait, ristretto::RistrettoPublicKey, -}; +use tari_crypto::{hash::blake2::Blake256, ristretto::RistrettoPublicKey}; use tari_mmr::{MemBackendVec, MerkleMountainRange}; -use tari_utilities::{hex::Hex, ByteArray, Hashable}; +use tari_utilities::{hex::Hex, ByteArray}; use uuid::Uuid; #[tauri::command] @@ -56,7 +54,7 @@ pub(crate) async fn assets_create( let wallet_id = state .current_wallet_id() .await - .ok_or_else(|| Status::unauthorized())?; + .ok_or_else(Status::unauthorized)?; let mut client = state.create_wallet_client().await; client.connect().await?; @@ -180,7 +178,7 @@ pub(crate) async fn assets_create_initial_checkpoint( committee: Vec, state: tauri::State<'_, ConcurrentAppState>, ) -> Result<(), Status> { - let mut mmr = MerkleMountainRange::::new(MemBackendVec::new()); + let mmr = MerkleMountainRange::::new(MemBackendVec::new()); let root = mmr.get_merkle_root().unwrap(); diff --git a/applications/tari_collectibles/src-tauri/src/commands/keys/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/keys/mod.rs index fbb01cc1a1..dafe42ec5b 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/keys/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/keys/mod.rs @@ -24,14 +24,9 @@ use crate::{ app_state::ConcurrentAppState, providers::KeyManagerProvider, status::Status, - storage::{ - models::key_index_row::KeyIndexRow, CollectiblesStorage, KeyIndicesTableGateway, - StorageTransaction, - }, + storage::{CollectiblesStorage, StorageTransaction}, }; use tari_common_types::types::PublicKey; -use tari_crypto::keys::PublicKey as PublicKeyTrait; -use uuid::Uuid; #[tauri::command] pub(crate) async fn next_asset_public_key( diff --git a/applications/tari_collectibles/src-tauri/src/commands/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/mod.rs index dd077bb1fc..de36a51008 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/mod.rs @@ -25,7 +25,6 @@ use crate::app_state::ConcurrentAppState; pub mod asset_wallets; pub mod assets; pub mod keys; -pub mod tips; pub mod wallets; #[tauri::command] diff --git a/applications/tari_collectibles/src-tauri/src/commands/tips/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/tips/mod.rs deleted file mode 100644 index e1cc5afffa..0000000000 --- a/applications/tari_collectibles/src-tauri/src/commands/tips/mod.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2021. The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -pub mod tip002; diff --git a/applications/tari_collectibles/src-tauri/src/commands/tips/tip002.rs b/applications/tari_collectibles/src-tauri/src/commands/tips/tip002.rs deleted file mode 100644 index 3ad800a3c9..0000000000 --- a/applications/tari_collectibles/src-tauri/src/commands/tips/tip002.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2021. The Tari Project -// -// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -// following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -use crate::{app_state::ConcurrentAppState, models::Tip002Info}; -use uuid::Uuid; - -#[tauri::command] -pub async fn tip002_get_info( - _account_id: Uuid, - _asset_public_key: String, - _state: tauri::State<'_, ConcurrentAppState>, -) -> Result, String> { - // let db = state - // .create_db() - // .await - // .map_err(|e| format!("Could not open DB:{}", e))?; - // let account = db - // .accounts() - // .find(account_id) - // .map_err(|e| format!("Could not find account: {}", e))?; - // let committee = account.committee; - // let validator_client = state.connect_validator_node_client(committee[0]).await?; - // let asset_public_key = PublicKey::from_hex(asset_public_key - // let template_data = tari_tips::tip002::InfoRequest{ - // - // }; - // let template_data = template_data.encode_to_vec(); - // validator_client.call(comittee[0], "tip002", ) - todo!() -} diff --git a/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs b/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs index 4a441fe4e2..e27fb3abe3 100644 --- a/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/commands/wallets/mod.rs @@ -22,22 +22,18 @@ use crate::{ app_state::ConcurrentAppState, - models::{NewWallet, Wallet, WalletInfo}, status::Status, storage::{ models::wallet_row::WalletRow, CollectiblesStorage, StorageTransaction, WalletsTableGateway, }, }; -use tari_key_manager::{ - cipher_seed::CipherSeed, - mnemonic::{Mnemonic, MnemonicLanguage}, -}; +use tari_key_manager::mnemonic::{Mnemonic, MnemonicLanguage}; use uuid::Uuid; #[tauri::command] pub(crate) async fn wallets_create( name: Option, - passphrase: Option, + _passphrase: Option, state: tauri::State<'_, ConcurrentAppState>, ) -> Result { let new_wallet = WalletRow { @@ -48,7 +44,7 @@ pub(crate) async fn wallets_create( let db = state.create_db().await?; let tx = db.create_transaction()?; - let result = db.wallets().insert(&new_wallet, None, &tx)?; + let _result = db.wallets().insert(&new_wallet, None, &tx)?; tx.commit()?; state.set_current_wallet_id(new_wallet.id).await; Ok(new_wallet) diff --git a/applications/tari_collectibles/src-tauri/src/models/mod.rs b/applications/tari_collectibles/src-tauri/src/models/mod.rs index bf414b32aa..8436eef565 100644 --- a/applications/tari_collectibles/src-tauri/src/models/mod.rs +++ b/applications/tari_collectibles/src-tauri/src/models/mod.rs @@ -25,7 +25,7 @@ pub use asset_info::AssetInfo; mod registered_asset_info; pub use registered_asset_info::RegisteredAssetInfo; mod wallet; -pub use wallet::{NewWallet, Wallet, WalletInfo}; +pub use wallet::{Wallet, WalletInfo}; mod tip002_info; pub use tip002_info::Tip002Info; mod template_parameter; diff --git a/applications/tari_collectibles/src-tauri/src/models/wallet.rs b/applications/tari_collectibles/src-tauri/src/models/wallet.rs index 39bcc2462f..772a4bc710 100644 --- a/applications/tari_collectibles/src-tauri/src/models/wallet.rs +++ b/applications/tari_collectibles/src-tauri/src/models/wallet.rs @@ -31,11 +31,6 @@ pub struct Wallet { pub cipher_seed: CipherSeed, } -pub struct NewWallet { - pub name: Option, - pub cipher_seed: CipherSeed, -} - #[derive(Serialize, Deserialize, Debug, Clone)] pub struct WalletInfo { pub id: Uuid, diff --git a/applications/tari_collectibles/src-tauri/src/providers/key_manager_provider.rs b/applications/tari_collectibles/src-tauri/src/providers/key_manager_provider.rs index d710b1a5f6..9dfbcf280b 100644 --- a/applications/tari_collectibles/src-tauri/src/providers/key_manager_provider.rs +++ b/applications/tari_collectibles/src-tauri/src/providers/key_manager_provider.rs @@ -20,14 +20,11 @@ // 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::{ - error::CollectiblesError, - storage::{ - models::key_index_row::KeyIndexRow, - sqlite::{SqliteDbFactory, SqliteTransaction}, - CollectiblesStorage, KeyIndicesTableGateway, StorageError, StorageTransaction, - WalletsTableGateway, - }, +use crate::storage::{ + models::key_index_row::KeyIndexRow, + sqlite::{SqliteDbFactory, SqliteTransaction}, + CollectiblesStorage, KeyIndicesTableGateway, StorageError, StorageTransaction, + WalletsTableGateway, }; use std::fmt::Display; use tari_common_types::types::{PrivateKey, PublicKey}; @@ -76,8 +73,8 @@ impl KeyManagerProvider for ConcreteKeyManagerProvider { let db = self.db_factory.create_db()?; let cipher_seed = db .wallets() - .get_cipher_seed(wallet_id, passphrase, Some(&transaction))?; - let row = match db.key_indices().find("assets".to_string(), &transaction)? { + .get_cipher_seed(wallet_id, passphrase, Some(transaction))?; + let row = match db.key_indices().find("assets".to_string(), transaction)? { Some(row) => row, None => { let row = KeyIndexRow { @@ -86,7 +83,7 @@ impl KeyManagerProvider for ConcreteKeyManagerProvider { last_index: 0, }; - db.key_indices().insert(&row, &transaction)?; + db.key_indices().insert(&row, transaction)?; row } }; diff --git a/applications/tari_collectibles/src-tauri/src/schema.rs b/applications/tari_collectibles/src-tauri/src/schema.rs index ee34260fba..37ffed483c 100644 --- a/applications/tari_collectibles/src-tauri/src/schema.rs +++ b/applications/tari_collectibles/src-tauri/src/schema.rs @@ -70,11 +70,11 @@ joinable!(issued_assets -> wallets (wallet_id)); joinable!(tip002_address -> addresses (address_id)); allow_tables_to_appear_in_same_query!( - addresses, - asset_wallets, - assets, - issued_assets, - key_indices, - tip002_address, - wallets, + addresses, + asset_wallets, + assets, + issued_assets, + key_indices, + tip002_address, + wallets, ); diff --git a/applications/tari_collectibles/src-tauri/src/storage/models/wallet_row.rs b/applications/tari_collectibles/src-tauri/src/storage/models/wallet_row.rs index 7931f58d88..49b0f79707 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/models/wallet_row.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/models/wallet_row.rs @@ -21,7 +21,7 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use serde::{Deserialize, Serialize}; -use tari_key_manager::cipher_seed::CipherSeed; + use uuid::Uuid; #[derive(Serialize, Deserialize)] diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/address.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/address.rs index 1b1d541d5b..c3cecbeebc 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/address.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/address.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::schema::*; -use diesel::prelude::*; #[derive(Queryable, Insertable, Identifiable)] #[table_name = "addresses"] diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/asset.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/asset.rs index 44f6629ca2..66fa648123 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/asset.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/asset.rs @@ -21,7 +21,6 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use crate::schema::*; -use diesel::prelude::*; #[derive(Queryable, Insertable, Identifiable)] pub struct Asset { diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/asset_wallet.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/asset_wallet.rs index 330188b335..e853b0a04c 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/asset_wallet.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/asset_wallet.rs @@ -21,7 +21,6 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use crate::schema::*; -use diesel::prelude::*; #[derive(Queryable, Insertable, Identifiable)] pub struct AssetWallet { diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/tip002_address.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/tip002_address.rs index 36076569cd..0bd0421781 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/tip002_address.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/models/tip002_address.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::schema::*; -use diesel::prelude::*; #[derive(Queryable, Insertable, Identifiable)] #[table_name = "tip002_address"] pub struct Tip002Address { diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs index da3fe9e36f..7d0b926a22 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_assets_table_gateway.rs @@ -20,18 +20,17 @@ // 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::{ - models::{NewWallet, Wallet, WalletInfo}, schema::{self, *}, storage::{ - models::{asset_row::AssetRow, wallet_row::WalletRow}, + models::asset_row::AssetRow, sqlite::{models, sqlite_transaction::SqliteTransaction}, - AssetsTableGateway, CollectiblesStorage, StorageError, WalletsTableGateway, + AssetsTableGateway, StorageError, }, }; -use diesel::{prelude::*, Connection, SqliteConnection}; -use std::{fs, path::Path}; +use diesel::prelude::*; + use tari_common_types::types::PublicKey; -use tari_key_manager::{cipher_seed::CipherSeed, error::KeyManagerError}; + use tari_utilities::ByteArray; use uuid::Uuid; diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_collectibles_storage.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_collectibles_storage.rs index cd1106bdea..61aff2a978 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_collectibles_storage.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_collectibles_storage.rs @@ -19,28 +19,18 @@ // 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::{ - models::{NewWallet, Wallet, WalletInfo}, - schema::{self, *}, - storage::{ - models::{asset_row::AssetRow, wallet_row::WalletRow}, - sqlite::{ - sqlite_addresses_table_gateway::SqliteAddressesTableGateway, - sqlite_asset_wallets_table_gateway::SqliteAssetWalletsTableGateway, - sqlite_issued_assets_table_gateway::SqliteIssuedAssetsTableGateway, - sqlite_key_indices_table_gateway::SqliteKeyIndicesTableGateway, - sqlite_tip002_addresses_table_gateway::SqliteTip002AddressesTableGateway, - sqlite_transaction::SqliteTransaction, SqliteAssetsTableGateway, SqliteWalletsTableGateway, - }, - AssetsTableGateway, CollectiblesStorage, StorageError, WalletsTableGateway, +use crate::storage::{ + sqlite::{ + sqlite_addresses_table_gateway::SqliteAddressesTableGateway, + sqlite_asset_wallets_table_gateway::SqliteAssetWalletsTableGateway, + sqlite_issued_assets_table_gateway::SqliteIssuedAssetsTableGateway, + sqlite_key_indices_table_gateway::SqliteKeyIndicesTableGateway, + sqlite_tip002_addresses_table_gateway::SqliteTip002AddressesTableGateway, + sqlite_transaction::SqliteTransaction, SqliteAssetsTableGateway, SqliteWalletsTableGateway, }, + CollectiblesStorage, StorageError, }; -use diesel::{prelude::*, Connection, SqliteConnection}; -use std::{fs, path::Path}; -use tari_common_types::types::PublicKey; -use tari_key_manager::{cipher_seed::CipherSeed, error::KeyManagerError}; -use tari_utilities::ByteArray; -use uuid::Uuid; +use diesel::{Connection, SqliteConnection}; pub struct SqliteCollectiblesStorage { pub database_url: String, diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_db_factory.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_db_factory.rs index f3a29b2613..a9d8427815 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_db_factory.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_db_factory.rs @@ -19,21 +19,9 @@ // 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::{ - models::{NewWallet, Wallet, WalletInfo}, - schema::{self, *}, - storage::{ - models::{asset_row::AssetRow, wallet_row::WalletRow}, - sqlite::SqliteCollectiblesStorage, - AssetsTableGateway, CollectiblesStorage, StorageError, WalletsTableGateway, - }, -}; -use diesel::{prelude::*, Connection, SqliteConnection}; +use crate::storage::{sqlite::SqliteCollectiblesStorage, StorageError}; +use diesel::{Connection, SqliteConnection}; use std::{fs, path::Path}; -use tari_common_types::types::PublicKey; -use tari_key_manager::{cipher_seed::CipherSeed, error::KeyManagerError}; -use tari_utilities::ByteArray; -use uuid::Uuid; #[derive(Clone)] pub struct SqliteDbFactory { diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_key_indices_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_key_indices_table_gateway.rs index 07c79eb91e..25847e5e79 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_key_indices_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_key_indices_table_gateway.rs @@ -29,7 +29,7 @@ use crate::{ KeyIndicesTableGateway, StorageError, }, }; -use diesel::{prelude::*, Connection, SqliteConnection}; +use diesel::prelude::*; use uuid::Uuid; pub struct SqliteKeyIndicesTableGateway { diff --git a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs index 8130241b3a..a1648b860e 100644 --- a/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs +++ b/applications/tari_collectibles/src-tauri/src/storage/sqlite/sqlite_wallets_table_gateway.rs @@ -20,22 +20,16 @@ // 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::{ - models::{NewWallet, Wallet, WalletInfo}, schema::{self, *}, storage::{ - models::{asset_row::AssetRow, wallet_row::WalletRow}, + models::wallet_row::WalletRow, sqlite::{models, sqlite_transaction::SqliteTransaction}, - AssetsTableGateway, CollectiblesStorage, StorageError, WalletsTableGateway, + StorageError, WalletsTableGateway, }, }; use diesel::{prelude::*, Connection, SqliteConnection}; -use std::{fs, path::Path}; -use tari_common_types::types::PublicKey; -use tari_key_manager::{ - cipher_seed::{CipherSeed, DEFAULT_CIPHER_SEED_PASSPHRASE}, - error::KeyManagerError, -}; -use tari_utilities::ByteArray; + +use tari_key_manager::{cipher_seed::CipherSeed, error::KeyManagerError}; use uuid::Uuid; pub struct SqliteWalletsTableGateway { @@ -54,7 +48,7 @@ impl SqliteWalletsTableGateway { impl WalletsTableGateway for SqliteWalletsTableGateway { type Passphrase = String; - fn list(&self, tx: Option<&SqliteTransaction>) -> Result, StorageError> { + fn list(&self, _tx: Option<&SqliteTransaction>) -> Result, StorageError> { let conn = SqliteConnection::establish(self.database_url.as_str())?; let results: Vec = schema::wallets::table.load(&conn)?; Ok( @@ -91,7 +85,7 @@ impl WalletsTableGateway for SqliteWalletsTableGateway { Ok(()) } - fn find(&self, id: Uuid, tx: Option<&SqliteTransaction>) -> Result { + fn find(&self, id: Uuid, _tx: Option<&SqliteTransaction>) -> Result { let conn = SqliteConnection::establish(self.database_url.as_str())?; let db_wallet = schema::wallets::table .find(Vec::from(id.as_bytes().as_slice())) diff --git a/applications/tari_validator_node/src/dan_node.rs b/applications/tari_validator_node/src/dan_node.rs index 77f8cc0d6c..dd0665ae5a 100644 --- a/applications/tari_validator_node/src/dan_node.rs +++ b/applications/tari_validator_node/src/dan_node.rs @@ -54,7 +54,7 @@ use tari_comms::{ use tari_comms_dht::{store_forward::SafConfig, DbConnectionUrl, Dht, DhtConfig}; use tari_crypto::tari_utilities::hex::Hex; use tari_dan_core::{ - models::{AssetDefinition, Committee, TariDanPayload}, + models::{AssetDefinition, Committee}, services::{ ConcreteAssetProcessor, ConcreteCommitteeManager, @@ -66,7 +66,7 @@ use tari_dan_core::{ TariDanPayloadProcessor, TariDanPayloadProvider, }, - storage::{AssetDataStore, DbFactory, LmdbAssetStore}, + storage::{DbFactory, LmdbAssetStore}, workers::ConsensusWorker, }; use tari_dan_storage_sqlite::{SqliteDbFactory, SqliteStorageService}; @@ -204,16 +204,16 @@ impl DanNode { let payload_provider = TariDanPayloadProvider::new(mempool_service.clone()); - let events_publisher = LoggingEventsPublisher::new(); + let events_publisher = LoggingEventsPublisher::default(); let signing_service = NodeIdentitySigningService::new(node_identity.clone()); - let backend = LmdbAssetStore::initialize(self.config.data_dir.join("asset_data"), Default::default()) + let _backend = LmdbAssetStore::initialize(self.config.data_dir.join("asset_data"), Default::default()) .map_err(|err| ExitCodes::DatabaseError(err.to_string()))?; - let data_store = AssetDataStore::new(backend); + // let data_store = AssetDataStore::new(backend); let instruction_log = MemoryInstructionLog::default(); - let asset_processor = ConcreteAssetProcessor::new(instruction_log, asset_definition.clone()); + let asset_processor = ConcreteAssetProcessor::new(instruction_log); - let payload_processor = TariDanPayloadProcessor::new(asset_processor, mempool_service); + let payload_processor = TariDanPayloadProcessor::new(asset_processor); let mut inbound = TariCommsInboundConnectionService::new(); let receiver = inbound.take_receiver().unwrap(); diff --git a/applications/tari_validator_node/src/grpc/conversions.rs b/applications/tari_validator_node/src/grpc/conversions.rs index ff60b743fd..f8b08201f6 100644 --- a/applications/tari_validator_node/src/grpc/conversions.rs +++ b/applications/tari_validator_node/src/grpc/conversions.rs @@ -23,9 +23,9 @@ use tari_app_grpc::tari_rpc; use tari_crypto::tari_utilities::ByteArray; use tari_dan_core::models::SidechainMetadata; -pub struct _st(tari_rpc::SidechainMetadata); +pub struct St(tari_rpc::SidechainMetadata); -impl From for _st { +impl From for St { fn from(source: SidechainMetadata) -> Self { Self(tari_rpc::SidechainMetadata { asset_public_key: source.asset_public_key().as_bytes().to_vec(), diff --git a/applications/tari_validator_node/src/grpc/validator_node_grpc_server.rs b/applications/tari_validator_node/src/grpc/validator_node_grpc_server.rs index 4bece65eef..96e745bf2b 100644 --- a/applications/tari_validator_node/src/grpc/validator_node_grpc_server.rs +++ b/applications/tari_validator_node/src/grpc/validator_node_grpc_server.rs @@ -19,25 +19,22 @@ // 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 std::marker::PhantomData; use tari_app_grpc::tari_rpc as rpc; use tari_crypto::tari_utilities::ByteArray; -use tari_dan_core::{ - models::{Instruction, TemplateId, TokenId}, - services::MempoolService, - storage::{ChainStorageService, DbFactory}, - types::{ComSig, PublicKey}, -}; +use tari_dan_core::{models::Instruction, services::MempoolService, storage::DbFactory, types::PublicKey}; use tonic::{Request, Response, Status}; pub struct ValidatorNodeGrpcServer { mempool: TMempoolService, - db_factory: TDbFactory, + _db_factory: TDbFactory, } impl ValidatorNodeGrpcServer { pub fn new(mempool: TMempoolService, db_factory: TDbFactory) -> Self { - Self { mempool, db_factory } + Self { + mempool, + _db_factory: db_factory, + } } } diff --git a/applications/tari_validator_node/src/main.rs b/applications/tari_validator_node/src/main.rs index 506a79fae4..da1b093b50 100644 --- a/applications/tari_validator_node/src/main.rs +++ b/applications/tari_validator_node/src/main.rs @@ -37,7 +37,7 @@ use tari_app_utilities::initialization::init_configuration; use tari_common::{configuration::bootstrap::ApplicationType, exit_codes::ExitCodes, GlobalConfig}; use tari_dan_core::{ services::{MempoolService, MempoolServiceHandle}, - storage::{ChainStorageService, DbFactory}, + storage::DbFactory, }; use tari_dan_storage_sqlite::SqliteDbFactory; use tari_shutdown::{Shutdown, ShutdownSignal}; @@ -76,7 +76,7 @@ fn main_inner() -> Result<(), ExitCodes> { async fn run_node(config: GlobalConfig) -> Result<(), ExitCodes> { let shutdown = Shutdown::new(); - let mempool_service = MempoolServiceHandle::new(); + let mempool_service = MempoolServiceHandle::default(); let db_factory = SqliteDbFactory::new(&config); let grpc_server = ValidatorNodeGrpcServer::new(mempool_service.clone(), db_factory); diff --git a/applications/tari_validator_node/src/p2p/proto/conversions/dan.rs b/applications/tari_validator_node/src/p2p/proto/conversions/dan.rs index 9b137040a4..b397da43b7 100644 --- a/applications/tari_validator_node/src/p2p/proto/conversions/dan.rs +++ b/applications/tari_validator_node/src/p2p/proto/conversions/dan.rs @@ -34,11 +34,10 @@ use tari_dan_core::{ QuorumCertificate, Signature, TariDanPayload, - TokenId, TreeNodeHash, ViewId, }, - types::{create_com_sig_from_bytes, PublicKey}, + types::PublicKey, }; impl From> for dan_proto::HotStuffMessage { @@ -124,7 +123,7 @@ impl TryFrom for HotStuffMessage { HotStuffMessageType::try_from(value.message_type as u8)?, value.justify.map(|j| j.try_into()).transpose()?, value.node.map(|n| n.try_into()).transpose()?, - value.node_hash.map(|v| TreeNodeHash(v.clone())), + value.node_hash.map(TreeNodeHash), value.partial_sig.map(|p| p.try_into()).transpose()?, )) } @@ -215,6 +214,6 @@ impl TryFrom for CheckpointData { type Error = String; fn try_from(_value: dan_proto::CheckpointData) -> Result { - Ok(Self::new()) + Ok(Self::default()) } } diff --git a/applications/tari_validator_node/src/p2p/rpc/service_impl.rs b/applications/tari_validator_node/src/p2p/rpc/service_impl.rs index a9e1efa0e5..6ce872f4cd 100644 --- a/applications/tari_validator_node/src/p2p/rpc/service_impl.rs +++ b/applications/tari_validator_node/src/p2p/rpc/service_impl.rs @@ -22,11 +22,7 @@ use crate::p2p::{proto::validator_node as proto, rpc::ValidatorNodeRpcService}; use tari_comms::protocol::rpc::{Request, Response, RpcStatus}; use tari_crypto::tari_utilities::ByteArray; -use tari_dan_core::{ - models::{Instruction, TokenId}, - services::MempoolService, - types::{ComSig, PublicKey}, -}; +use tari_dan_core::{models::Instruction, services::MempoolService, types::PublicKey}; pub struct ValidatorNodeRpcServiceImpl { mempool_service: TMempoolService, diff --git a/applications/tari_validator_node/src/p2p/services/inbound_connection_service.rs b/applications/tari_validator_node/src/p2p/services/inbound_connection_service.rs index d40655dcc6..2dcea19bde 100644 --- a/applications/tari_validator_node/src/p2p/services/inbound_connection_service.rs +++ b/applications/tari_validator_node/src/p2p/services/inbound_connection_service.rs @@ -26,10 +26,7 @@ use async_trait::async_trait; use futures::{self, pin_mut, Stream, StreamExt}; use std::{convert::TryInto, sync::Arc}; use tari_comms::types::CommsPublicKey; -use tari_dan_core::{ - services::infrastructure_services::{InboundConnectionService, NodeAddressable}, - DigitalAssetError, -}; +use tari_dan_core::{services::infrastructure_services::InboundConnectionService, DigitalAssetError}; use tari_p2p::comms_connector::PeerMessage; use tari_shutdown::ShutdownSignal; use tokio::sync::mpsc::{channel, Receiver, Sender}; diff --git a/applications/tari_validator_node/src/p2p/services/outbound_connection_service.rs b/applications/tari_validator_node/src/p2p/services/outbound_connection_service.rs index 68fa32a807..eb15d8cd9a 100644 --- a/applications/tari_validator_node/src/p2p/services/outbound_connection_service.rs +++ b/applications/tari_validator_node/src/p2p/services/outbound_connection_service.rs @@ -27,7 +27,7 @@ use tari_comms::types::CommsPublicKey; use tari_comms_dht::{domain_message::OutboundDomainMessage, outbound::OutboundMessageRequester}; use tari_dan_core::{ models::{HotStuffMessage, Payload, TariDanPayload}, - services::infrastructure_services::{NodeAddressable, OutboundService}, + services::infrastructure_services::OutboundService, DigitalAssetError, }; use tari_p2p::tari_message::TariMessageType; diff --git a/base_layer/wallet/src/assets/asset_manager.rs b/base_layer/wallet/src/assets/asset_manager.rs index c00260ca81..c6dec74b8f 100644 --- a/base_layer/wallet/src/assets/asset_manager.rs +++ b/base_layer/wallet/src/assets/asset_manager.rs @@ -30,7 +30,6 @@ use crate::{ models::DbUnblindedOutput, }, }, - types::PersistentKeyManager, }; use log::*; use tari_common_types::{ @@ -41,19 +40,15 @@ use tari_core::transactions::transaction::{OutputFeatures, OutputFlags, Template const LOG_TARGET: &str = "wallet::assets::asset_manager"; -pub(crate) struct AssetManager { +pub(crate) struct AssetManager { output_database: OutputManagerDatabase, output_manager: OutputManagerHandle, - assets_key_manager: TPersistentKeyManager, // transaction_service: TransactionServiceHandle } -impl - AssetManager -{ - pub fn new(backend: T, output_manager: OutputManagerHandle, assets_key_manager: TPersistentKeyManager) -> Self { +impl AssetManager { + pub fn new(backend: T, output_manager: OutputManagerHandle) -> Self { Self { output_database: OutputManagerDatabase::new(backend), output_manager, - assets_key_manager, } } diff --git a/base_layer/wallet/src/assets/infrastructure/asset_manager_service.rs b/base_layer/wallet/src/assets/infrastructure/asset_manager_service.rs index 5d8f903b9c..ca60fee8d5 100644 --- a/base_layer/wallet/src/assets/infrastructure/asset_manager_service.rs +++ b/base_layer/wallet/src/assets/infrastructure/asset_manager_service.rs @@ -27,7 +27,6 @@ use crate::{ }, error::WalletError, output_manager_service::{handle::OutputManagerHandle, storage::database::OutputManagerBackend}, - types::MockPersistentKeyManager, }; use futures::{pin_mut, StreamExt}; use log::*; @@ -37,13 +36,13 @@ use tari_shutdown::ShutdownSignal; const LOG_TARGET: &str = "wallet::assets::infrastructure::asset_manager_service"; pub struct AssetManagerService { - manager: AssetManager, + manager: AssetManager, } impl AssetManagerService { pub fn new(backend: T, output_manager: OutputManagerHandle) -> Self { Self { - manager: AssetManager::::new(backend, output_manager, MockPersistentKeyManager::new()), + manager: AssetManager::::new(backend, output_manager), } } diff --git a/base_layer/wallet/src/types.rs b/base_layer/wallet/src/types.rs index 05490828df..b9fb1d883a 100644 --- a/base_layer/wallet/src/types.rs +++ b/base_layer/wallet/src/types.rs @@ -21,9 +21,8 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use crate::error::WalletError; -use tari_common_types::types::{PrivateKey, PublicKey}; -use tari_crypto::{common::Blake256, keys::PublicKey as OtherPublicKey}; -use tari_key_manager::key_manager::KeyManager; +use tari_common_types::types::PublicKey; +use tari_crypto::common::Blake256; /// Specify the Hash function used by the key manager pub type KeyDigest = Blake256; @@ -34,21 +33,3 @@ pub type HashDigest = Blake256; pub(crate) trait PersistentKeyManager { fn create_and_store_new(&mut self) -> Result; } - -pub(crate) struct MockPersistentKeyManager { - key_manager: KeyManager, -} - -impl MockPersistentKeyManager { - pub fn new() -> Self { - Self { - key_manager: KeyManager::new(), - } - } -} - -impl PersistentKeyManager for MockPersistentKeyManager { - fn create_and_store_new(&mut self) -> Result { - Ok(PublicKey::from_secret_key(&self.key_manager.next_key().unwrap().k)) - } -} diff --git a/dan_layer/core/src/models/committee.rs b/dan_layer/core/src/models/committee.rs index a02961069c..b65c68429a 100644 --- a/dan_layer/core/src/models/committee.rs +++ b/dan_layer/core/src/models/committee.rs @@ -44,6 +44,10 @@ impl Committee { len - max_failures } + pub fn is_empty(&self) -> bool { + self.members.is_empty() + } + pub fn len(&self) -> usize { self.members.len() } diff --git a/dan_layer/core/src/models/instruction.rs b/dan_layer/core/src/models/instruction.rs index 8745cce96d..3bdcc41e03 100644 --- a/dan_layer/core/src/models/instruction.rs +++ b/dan_layer/core/src/models/instruction.rs @@ -94,7 +94,7 @@ impl Instruction { } pub fn calculate_hash(&self) -> Vec { - let mut b = Blake256::new() + let b = Blake256::new() .chain(self.asset_id.as_bytes()) .chain(self.method.as_bytes()) .chain(&self.args); diff --git a/dan_layer/core/src/models/mod.rs b/dan_layer/core/src/models/mod.rs index f41b25d2f4..0332e26f31 100644 --- a/dan_layer/core/src/models/mod.rs +++ b/dan_layer/core/src/models/mod.rs @@ -39,7 +39,6 @@ mod view_id; pub use asset_definition::AssetDefinition; pub use base_layer_metadata::BaseLayerMetadata; pub use base_layer_output::BaseLayerOutput; -use blake2::Digest; pub use committee::Committee; pub use hot_stuff_message::HotStuffMessage; pub use hot_stuff_tree_node::HotStuffTreeNode; diff --git a/dan_layer/core/src/models/tari_dan_payload.rs b/dan_layer/core/src/models/tari_dan_payload.rs index 68fb5a90ba..2b9a3e7e1a 100644 --- a/dan_layer/core/src/models/tari_dan_payload.rs +++ b/dan_layer/core/src/models/tari_dan_payload.rs @@ -22,11 +22,8 @@ use crate::models::{ConsensusHash, Instruction, InstructionSet, Payload, StateRoot}; use digest::Digest; -use std::{ - fmt::Debug, - hash::{Hash, Hasher}, -}; -use tari_crypto::{common::Blake256, tari_utilities::ByteArray}; +use std::fmt::Debug; +use tari_crypto::common::Blake256; #[derive(Debug, Clone)] pub struct TariDanPayload { @@ -76,17 +73,11 @@ impl Payload for TariDanPayload { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct CheckpointData { hash: Vec, } -impl CheckpointData { - pub fn new() -> Self { - Self { hash: vec![] } - } -} - impl ConsensusHash for CheckpointData { fn consensus_hash(&self) -> &[u8] { self.hash.as_slice() diff --git a/dan_layer/core/src/services/asset_processor.rs b/dan_layer/core/src/services/asset_processor.rs index 35541e684e..11c3301016 100644 --- a/dan_layer/core/src/services/asset_processor.rs +++ b/dan_layer/core/src/services/asset_processor.rs @@ -28,7 +28,6 @@ use crate::{ templates::tip002_template, }; -use std::collections::VecDeque; use tari_core::transactions::transaction::TemplateParameter; pub trait AssetProcessor { @@ -49,9 +48,8 @@ pub trait AssetProcessor { } pub struct ConcreteAssetProcessor { - asset_definition: AssetDefinition, template_factory: TemplateFactory, - instruction_log: TInstructionLog, + _instruction_log: TInstructionLog, } impl AssetProcessor for ConcreteAssetProcessor { @@ -84,11 +82,10 @@ impl AssetProcessor for ConcreteAssetPro } impl ConcreteAssetProcessor { - pub fn new(instruction_log: TInstructionLog, asset_definition: AssetDefinition) -> Self { + pub fn new(instruction_log: TInstructionLog) -> Self { Self { template_factory: TemplateFactory {}, - instruction_log, - asset_definition, + _instruction_log: instruction_log, } } @@ -127,15 +124,15 @@ impl TemplateFactory { Ok(()) } - pub fn create_command( - &self, - _template: TemplateId, - _method: String, - _args: VecDeque>, - // caller: InstructionCaller, - ) -> Result<(), DigitalAssetError> { - todo!() - } + // pub fn create_command( + // &self, + // _template: TemplateId, + // _method: String, + // _args: VecDeque>, + // // caller: InstructionCaller, + // ) -> Result<(), DigitalAssetError> { + // todo!() + // } } pub trait InstructionLog { diff --git a/dan_layer/core/src/services/events_publisher.rs b/dan_layer/core/src/services/events_publisher.rs index 9c95653aa3..9fd6afac16 100644 --- a/dan_layer/core/src/services/events_publisher.rs +++ b/dan_layer/core/src/services/events_publisher.rs @@ -38,11 +38,12 @@ pub struct LoggingEventsPublisher { phantom: PhantomData, } -impl LoggingEventsPublisher { - pub fn new() -> Self { +impl Default for LoggingEventsPublisher { + fn default() -> Self { Self { phantom: PhantomData } } } + impl EventsPublisher for LoggingEventsPublisher { fn publish(&mut self, event: TEvent) { info!(target: LOG_TARGET, "[Event] Event received:{}", event); diff --git a/dan_layer/core/src/services/mempool_service.rs b/dan_layer/core/src/services/mempool_service.rs index c453e33661..334c575f73 100644 --- a/dan_layer/core/src/services/mempool_service.rs +++ b/dan_layer/core/src/services/mempool_service.rs @@ -33,16 +33,11 @@ pub trait MempoolService: Sync + Send + 'static { async fn size(&self) -> usize; } +#[derive(Default)] pub struct ConcreteMempoolService { instructions: Vec, } -impl ConcreteMempoolService { - pub fn new() -> Self { - Self { instructions: vec![] } - } -} - #[async_trait] impl MempoolService for ConcreteMempoolService { async fn submit_instruction(&mut self, instruction: Instruction) -> Result<(), DigitalAssetError> { @@ -75,10 +70,10 @@ pub struct MempoolServiceHandle { mempool: Arc>, } -impl MempoolServiceHandle { - pub fn new() -> Self { +impl Default for MempoolServiceHandle { + fn default() -> Self { Self { - mempool: Arc::new(Mutex::new(ConcreteMempoolService::new())), + mempool: Arc::new(Mutex::new(ConcreteMempoolService::default())), } } } diff --git a/dan_layer/core/src/services/payload_processor.rs b/dan_layer/core/src/services/payload_processor.rs index 728a7724b5..b8db2ef0fa 100644 --- a/dan_layer/core/src/services/payload_processor.rs +++ b/dan_layer/core/src/services/payload_processor.rs @@ -23,7 +23,7 @@ use crate::{ digital_assets_error::DigitalAssetError, models::{Payload, StateRoot, TariDanPayload}, - services::{AssetProcessor, MempoolService}, + services::AssetProcessor, storage::state::StateDbUnitOfWork, }; use async_trait::async_trait; @@ -46,29 +46,21 @@ pub trait PayloadProcessor { ) -> Result; } -pub struct TariDanPayloadProcessor -where - TAssetProcessor: AssetProcessor, - TMempoolService: MempoolService, +pub struct TariDanPayloadProcessor +where TAssetProcessor: AssetProcessor { asset_processor: TAssetProcessor, - mempool_service: TMempoolService, } -impl - TariDanPayloadProcessor -{ - pub fn new(asset_processor: TAssetProcessor, mempool_service: TMempoolService) -> Self { - Self { - asset_processor, - mempool_service, - } +impl TariDanPayloadProcessor { + pub fn new(asset_processor: TAssetProcessor) -> Self { + Self { asset_processor } } } #[async_trait] -impl - PayloadProcessor for TariDanPayloadProcessor +impl PayloadProcessor + for TariDanPayloadProcessor { fn init_template( &self, diff --git a/dan_layer/core/src/storage/chain/chain_db.rs b/dan_layer/core/src/storage/chain/chain_db.rs index 3580855735..35354ca50e 100644 --- a/dan_layer/core/src/storage/chain/chain_db.rs +++ b/dan_layer/core/src/storage/chain/chain_db.rs @@ -21,18 +21,12 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use crate::{ - models::{HotStuffMessageType, HotStuffTreeNode, Instruction, QuorumCertificate, Signature, TreeNodeHash, ViewId}, + models::QuorumCertificate, storage::{ - chain::{chain_db_unit_of_work::ChainDbUnitOfWorkImpl, ChainDbBackendAdapter, ChainDbUnitOfWork}, + chain::{chain_db_unit_of_work::ChainDbUnitOfWorkImpl, ChainDbBackendAdapter}, StorageError, - UnitOfWorkTracker, }, }; -use std::{ - fmt::{Debug, Formatter}, - ops::{Deref, DerefMut}, - sync::{Arc, RwLock}, -}; pub struct ChainDb { adapter: TBackendAdapter, diff --git a/dan_layer/core/src/storage/chain/chain_db_unit_of_work.rs b/dan_layer/core/src/storage/chain/chain_db_unit_of_work.rs index d1c8ae2432..e111d2786b 100644 --- a/dan_layer/core/src/storage/chain/chain_db_unit_of_work.rs +++ b/dan_layer/core/src/storage/chain/chain_db_unit_of_work.rs @@ -97,7 +97,7 @@ impl ChainDbUnitOfWork for ChainDbUnitOf for (id, item) in &inner.instructions { if item.is_dirty() { match id { - Some(i) => { + Some(_i) => { unimplemented!("Cannot update instructions"); }, None => inner @@ -113,7 +113,7 @@ impl ChainDbUnitOfWork for ChainDbUnitOf inner .backend_adapter .update_locked_qc(&*locked_qc.get(), &tx) - .map_err(TBackendAdapter::Error::into); + .map_err(TBackendAdapter::Error::into)?; } } @@ -122,7 +122,7 @@ impl ChainDbUnitOfWork for ChainDbUnitOf inner .backend_adapter .update_prepare_qc(&*prepare_qc.get(), &tx) - .map_err(TBackendAdapter::Error::into); + .map_err(TBackendAdapter::Error::into)?; } } @@ -214,7 +214,6 @@ impl ChainDbUnitOfWork for ChainDbUnitOf let mut node = found_node.1.get_mut(); let mut n = node.deref_mut(); n.is_committed = true; - dbg!(inner); Ok(()) } @@ -251,7 +250,7 @@ impl ChainDbUnitOfWork for ChainDbUnitOf fn set_prepare_qc(&mut self, qc: &QuorumCertificate) -> Result<(), StorageError> { // put it in the tracker let _ = self.get_prepare_qc()?; - let mut inner = self.inner.write().unwrap(); + let inner = self.inner.write().unwrap(); let mut db_locked = inner.prepare_qc.as_ref().unwrap().get_mut(); db_locked.message_type = qc.message_type(); db_locked.view_number = qc.view_number(); diff --git a/dan_layer/core/src/storage/chain/mod.rs b/dan_layer/core/src/storage/chain/mod.rs index c31e03abfc..9cd991c70d 100644 --- a/dan_layer/core/src/storage/chain/mod.rs +++ b/dan_layer/core/src/storage/chain/mod.rs @@ -20,8 +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::models::{HotStuffMessageType, Instruction, Signature, TreeNodeHash, ViewId}; - mod chain_db; mod chain_db_backend_adapter; mod chain_db_unit_of_work; diff --git a/dan_layer/core/src/storage/chain_storage_service.rs b/dan_layer/core/src/storage/chain_storage_service.rs index c92850243f..ea6d1e63fe 100644 --- a/dan_layer/core/src/storage/chain_storage_service.rs +++ b/dan_layer/core/src/storage/chain_storage_service.rs @@ -21,7 +21,7 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use crate::{ - models::{HotStuffTreeNode, Payload, QuorumCertificate, SidechainMetadata}, + models::{HotStuffTreeNode, Payload, SidechainMetadata}, storage::{chain::ChainDbUnitOfWork, StorageError}, }; use async_trait::async_trait; diff --git a/dan_layer/core/src/storage/mod.rs b/dan_layer/core/src/storage/mod.rs index 57020d8daf..a3e1cb9b1e 100644 --- a/dan_layer/core/src/storage/mod.rs +++ b/dan_layer/core/src/storage/mod.rs @@ -20,31 +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::models::{ - HotStuffMessageType, - Instruction, - Payload, - QuorumCertificate, - Signature, - StateRoot, - TreeNodeHash, - ViewId, -}; pub use chain_storage_service::ChainStorageService; pub use error::StorageError; pub use lmdb::{LmdbAssetBackend, LmdbAssetStore}; -use std::{ - fmt::Debug, - marker::PhantomData, - ops::Deref, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, - RwLock, - RwLockReadGuard, - RwLockWriteGuard, - }, -}; + pub use store::{AssetDataStore, AssetStore}; pub mod chain; mod chain_storage_service; @@ -55,6 +34,5 @@ pub mod state; mod store; mod unit_of_work_tracker; -use crate::storage::chain::{DbInstruction, DbNode, DbQc}; pub use db_factory::DbFactory; pub use unit_of_work_tracker::UnitOfWorkTracker; diff --git a/dan_layer/core/src/storage/state/state_db.rs b/dan_layer/core/src/storage/state/state_db.rs index cb50e9929b..4efbce10b1 100644 --- a/dan_layer/core/src/storage/state/state_db.rs +++ b/dan_layer/core/src/storage/state/state_db.rs @@ -21,7 +21,6 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use crate::storage::state::{state_db_unit_of_work::StateDbUnitOfWorkImpl, StateDbBackendAdapter}; -use std::marker::PhantomData; pub struct StateDb { backend_adapter: TStateDbBackendAdapter, diff --git a/dan_layer/core/src/storage/state/state_db_unit_of_work.rs b/dan_layer/core/src/storage/state/state_db_unit_of_work.rs index 313cdecc23..e61d922322 100644 --- a/dan_layer/core/src/storage/state/state_db_unit_of_work.rs +++ b/dan_layer/core/src/storage/state/state_db_unit_of_work.rs @@ -74,7 +74,10 @@ impl StateDbUnitOfWork for StateDbUnitOf .map_err(TBackendAdapter::Error::into)?; for item in &inner.updates { let i = item.get(); - inner.backend_adapter.update_key_value(&i.schema, &i.key, &i.value, &tx); + inner + .backend_adapter + .update_key_value(&i.schema, &i.key, &i.value, &tx) + .map_err(TBackendAdapter::Error::into)?; } inner diff --git a/dan_layer/core/src/templates/tip002_template.rs b/dan_layer/core/src/templates/tip002_template.rs index 76134d17d2..a1b4be5815 100644 --- a/dan_layer/core/src/templates/tip002_template.rs +++ b/dan_layer/core/src/templates/tip002_template.rs @@ -41,6 +41,6 @@ pub fn init( "owners".to_string(), asset_definition.public_key.to_vec(), Vec::from(params.total_supply.to_le_bytes()), - ); + )?; Ok(()) } diff --git a/dan_layer/core/src/workers/consensus_worker.rs b/dan_layer/core/src/workers/consensus_worker.rs index 079d4e445d..19f3fa6014 100644 --- a/dan_layer/core/src/workers/consensus_worker.rs +++ b/dan_layer/core/src/workers/consensus_worker.rs @@ -33,7 +33,7 @@ use crate::{ SigningService, }, storage::{ - chain::{ChainDbBackendAdapter, ChainDbUnitOfWork}, + chain::ChainDbUnitOfWork, state::{StateDbBackendAdapter, StateDbUnitOfWork, StateDbUnitOfWorkImpl}, ChainStorageService, DbFactory, @@ -231,7 +231,7 @@ where use ConsensusWorkerState::*; match &mut self.state { Starting => { - states::Starting::new() + states::Starting::default() .next_event( &mut self.base_node_client, &self.asset_definition, @@ -248,7 +248,7 @@ where let db = self.db_factory.create_chain_db()?; let mut unit_of_work = db.new_unit_of_work(); let mut state_tx = self.db_factory.create_state_db()?.new_unit_of_work(); - let mut p = states::Prepare::new(self.node_id.clone(), self.db_factory.clone()); + let mut p = states::Prepare::new(self.node_id.clone()); let res = p .next_event( &self.get_current_view()?, @@ -348,7 +348,7 @@ where self.payload_provider.get_payload_queue().await, ); self.state_db_unit_of_work = None; - let mut state = states::NextViewState::new(); + let mut state = states::NextViewState::default(); state .next_event( &self.get_current_view()?, @@ -362,7 +362,7 @@ where }, Idle => { info!(target: LOG_TARGET, "No work to do, idling"); - let state = states::IdleState::new(); + let state = states::IdleState::default(); state.next_event().await }, } diff --git a/dan_layer/core/src/workers/states/commit_state.rs b/dan_layer/core/src/workers/states/commit_state.rs index c708a41f95..0239063759 100644 --- a/dan_layer/core/src/workers/states/commit_state.rs +++ b/dan_layer/core/src/workers/states/commit_state.rs @@ -237,7 +237,7 @@ where return Ok(None); } - unit_of_work.set_locked_qc(justify); + unit_of_work.set_locked_qc(justify)?; self.send_vote_to_leader( justify.node_hash().clone(), outbound, diff --git a/dan_layer/core/src/workers/states/decide_state.rs b/dan_layer/core/src/workers/states/decide_state.rs index 4acd3a2c6b..ec4301d0f4 100644 --- a/dan_layer/core/src/workers/states/decide_state.rs +++ b/dan_layer/core/src/workers/states/decide_state.rs @@ -223,7 +223,7 @@ where return Ok(None); } - unit_of_work.commit_node(justify.node_hash()); + unit_of_work.commit_node(justify.node_hash())?; Ok(Some(ConsensusWorkerStateEvent::Decided)) } else { dbg!("received non justify message"); diff --git a/dan_layer/core/src/workers/states/idle_state.rs b/dan_layer/core/src/workers/states/idle_state.rs index a1d7d51cb7..bfa58e7b7d 100644 --- a/dan_layer/core/src/workers/states/idle_state.rs +++ b/dan_layer/core/src/workers/states/idle_state.rs @@ -23,13 +23,10 @@ use crate::{digital_assets_error::DigitalAssetError, workers::states::ConsensusWorkerStateEvent}; use tokio::time::{sleep, Duration}; +#[derive(Default)] pub struct IdleState {} impl IdleState { - pub fn new() -> Self { - Self {} - } - pub async fn next_event(&self) -> Result { sleep(Duration::from_secs(10)).await; Ok(ConsensusWorkerStateEvent::TimedOut) diff --git a/dan_layer/core/src/workers/states/next_view.rs b/dan_layer/core/src/workers/states/next_view.rs index f131ef9777..f62447eb7e 100644 --- a/dan_layer/core/src/workers/states/next_view.rs +++ b/dan_layer/core/src/workers/states/next_view.rs @@ -24,7 +24,7 @@ use crate::{ digital_assets_error::DigitalAssetError, models::{Committee, HotStuffMessage, Payload, View}, services::infrastructure_services::{NodeAddressable, OutboundService}, - storage::{chain::ChainDbBackendAdapter, DbFactory}, + storage::DbFactory, workers::states::ConsensusWorkerStateEvent, }; use log::*; @@ -32,13 +32,10 @@ use tari_shutdown::ShutdownSignal; const LOG_TARGET: &str = "tari::dan::workers::states::next_view"; +#[derive(Default)] pub struct NextViewState {} impl NextViewState { - pub fn new() -> Self { - Self {} - } - pub async fn next_event< TPayload: Payload, TOutboundService: OutboundService, diff --git a/dan_layer/core/src/workers/states/pre_commit_state.rs b/dan_layer/core/src/workers/states/pre_commit_state.rs index 414e30087c..44f952a6f9 100644 --- a/dan_layer/core/src/workers/states/pre_commit_state.rs +++ b/dan_layer/core/src/workers/states/pre_commit_state.rs @@ -241,7 +241,7 @@ where return Ok(None); } - unit_of_work.set_prepare_qc(justify); + unit_of_work.set_prepare_qc(justify)?; self.send_vote_to_leader( justify.node_hash().clone(), outbound, diff --git a/dan_layer/core/src/workers/states/prepare.rs b/dan_layer/core/src/workers/states/prepare.rs index 6f787a96e4..4309e89544 100644 --- a/dan_layer/core/src/workers/states/prepare.rs +++ b/dan_layer/core/src/workers/states/prepare.rs @@ -45,13 +45,7 @@ use std::{collections::HashMap, marker::PhantomData, time::Instant}; use crate::{ models::TreeNodeHash, services::PayloadProcessor, - storage::{ - chain::{ChainDbBackendAdapter, ChainDbUnitOfWork}, - state::StateDbUnitOfWork, - ChainStorageService, - DbFactory, - StorageError, - }, + storage::{chain::ChainDbUnitOfWork, state::StateDbUnitOfWork, ChainStorageService, StorageError}, }; use tokio::time::{sleep, Duration}; @@ -65,7 +59,6 @@ pub struct Prepare< TPayloadProvider, TPayload, TPayloadProcessor, - TDbFactory, > where TInboundConnectionService: InboundConnectionService + Send, TOutboundService: OutboundService, @@ -74,7 +67,6 @@ pub struct Prepare< TPayload: Payload, TPayloadProvider: PayloadProvider, TPayloadProcessor: PayloadProcessor, - TDbFactory: DbFactory, { node_id: TAddr, // bft_service: Box, @@ -85,7 +77,6 @@ pub struct Prepare< phantom_signing: PhantomData, phantom_processor: PhantomData, received_new_view_messages: HashMap>, - db_factory: TDbFactory, } impl< @@ -96,7 +87,6 @@ impl< TPayloadProvider, TPayload, TPayloadProcessor, - TDbFactory, > Prepare< TInboundConnectionService, @@ -106,7 +96,6 @@ impl< TPayloadProvider, TPayload, TPayloadProcessor, - TDbFactory, > where TInboundConnectionService: InboundConnectionService + Send, @@ -116,9 +105,8 @@ where TPayload: Payload, TPayloadProvider: PayloadProvider, TPayloadProcessor: PayloadProcessor, - TDbFactory: DbFactory + Clone, { - pub fn new(node_id: TAddr, db_factory: TDbFactory) -> Self { + pub fn new(node_id: TAddr) -> Self { Self { node_id, phantom: PhantomData, @@ -127,7 +115,6 @@ where phantom_signing: PhantomData, received_new_view_messages: HashMap::new(), phantom_processor: PhantomData, - db_factory, } } @@ -376,7 +363,7 @@ where } fn does_extend(&self, node: &HotStuffTreeNode, from: &TreeNodeHash) -> bool { - &from == &node.parent() + from == node.parent() } fn is_safe_node( diff --git a/dan_layer/core/src/workers/states/starting.rs b/dan_layer/core/src/workers/states/starting.rs index 7df1fccb85..d1c899f6d3 100644 --- a/dan_layer/core/src/workers/states/starting.rs +++ b/dan_layer/core/src/workers/states/starting.rs @@ -25,18 +25,12 @@ use crate::{ models::{AssetDefinition, HotStuffTreeNode, Payload, QuorumCertificate}, services::{ infrastructure_services::NodeAddressable, - AssetProcessor, BaseNodeClient, CommitteeManager, PayloadProcessor, PayloadProvider, }, - storage::{ - chain::{ChainDbBackendAdapter, ChainDbUnitOfWork}, - state::StateDbUnitOfWork, - ChainStorageService, - DbFactory, - }, + storage::{chain::ChainDbUnitOfWork, state::StateDbUnitOfWork, ChainStorageService, DbFactory}, workers::states::ConsensusWorkerStateEvent, }; use log::*; @@ -48,15 +42,17 @@ pub struct Starting { base_node_client: PhantomData, } -impl Starting -where TBaseNodeClient: BaseNodeClient -{ - pub fn new() -> Self { +impl Default for Starting { + fn default() -> Self { Self { - base_node_client: Default::default(), + base_node_client: PhantomData, } } +} +impl Starting +where TBaseNodeClient: BaseNodeClient +{ pub async fn next_event< TAddr: NodeAddressable, TCommitteeManager: CommitteeManager, @@ -121,7 +117,7 @@ where TBaseNodeClient: BaseNodeClient target: LOG_TARGET, "Setting {:?} = {:?}", key_value.key, key_value.value ); - state_tx.set_value(schema.name.clone(), key_value.key.clone(), key_value.value.clone()); + state_tx.set_value(schema.name.clone(), key_value.key.clone(), key_value.value.clone())?; } } dbg!(&asset_definition); @@ -130,7 +126,7 @@ where TBaseNodeClient: BaseNodeClient target: LOG_TARGET, "Setting template parameters for: {}", template.template_id ); - payload_processor.init_template(template, &asset_definition, &mut state_tx); + payload_processor.init_template(template, asset_definition, &mut state_tx)?; } info!(target: LOG_TARGET, "Saving genesis node"); let node = HotStuffTreeNode::genesis(payload_provider.create_genesis_payload()); diff --git a/dan_layer/storage_sqlite/src/sqlite_chain_backend_adapter.rs b/dan_layer/storage_sqlite/src/sqlite_chain_backend_adapter.rs index bf69709a2e..0398bf35d7 100644 --- a/dan_layer/storage_sqlite/src/sqlite_chain_backend_adapter.rs +++ b/dan_layer/storage_sqlite/src/sqlite_chain_backend_adapter.rs @@ -31,16 +31,11 @@ use crate::{ SqliteTransaction, }; use diesel::{prelude::*, Connection, SqliteConnection}; -use diesel_migrations::embed_migrations; use log::*; use std::convert::TryFrom; use tari_dan_core::{ - models::{HotStuffMessageType, Payload, QuorumCertificate, Signature, TariDanPayload, TreeNodeHash, ViewId}, - storage::{ - chain::{ChainDbBackendAdapter, DbInstruction, DbNode, DbQc}, - StorageError, - UnitOfWorkTracker, - }, + models::{HotStuffMessageType, QuorumCertificate, Signature, TariDanPayload, TreeNodeHash, ViewId}, + storage::chain::{ChainDbBackendAdapter, DbInstruction, DbNode, DbQc}, }; const LOG_TARGET: &str = "tari::dan_layer::storage_sqlite::sqlite_chain_backend_adapter"; @@ -77,8 +72,18 @@ impl ChainDbBackendAdapter for SqliteChainBackendAdapter { fn create_transaction(&self) -> Result { let connection = SqliteConnection::establish(self.database_url.as_str())?; - connection.execute("PRAGMA foreign_keys = ON;"); - connection.execute("BEGIN EXCLUSIVE TRANSACTION;"); + connection + .execute("PRAGMA foreign_keys = ON;") + .map_err(|source| SqliteStorageError::DieselError { + source, + operation: "set pragma".to_string(), + })?; + connection + .execute("BEGIN EXCLUSIVE TRANSACTION;") + .map_err(|source| SqliteStorageError::DieselError { + source, + operation: "begin transaction".to_string(), + })?; Ok(SqliteTransaction::new(connection)) } @@ -124,11 +129,10 @@ impl ChainDbBackendAdapter for SqliteChainBackendAdapter { } fn update_locked_qc(&self, item: &DbQc, transaction: &Self::BackendTransaction) -> Result<(), Self::Error> { - use crate::schema::locked_qc::dsl; let message_type = item.message_type.as_u8() as i32; let existing: Result = dsl::locked_qc.find(1).first(transaction.connection()); match existing { - Ok(x) => { + Ok(_) => { diesel::update(dsl::locked_qc.find(1)) .set(( dsl::message_type.eq(message_type), @@ -166,7 +170,7 @@ impl ChainDbBackendAdapter for SqliteChainBackendAdapter { let message_type = item.message_type.as_u8() as i32; let existing: Result = dsl::prepare_qc.find(1).first(transaction.connection()); match existing { - Ok(x) => { + Ok(_) => { diesel::update(dsl::prepare_qc.find(1)) .set(( dsl::message_type.eq(message_type), @@ -265,7 +269,7 @@ impl ChainDbBackendAdapter for SqliteChainBackendAdapter { message_type: l.message_type, view_number: l.view_number, node_hash: l.node_hash.clone(), - signature: l.signature.clone(), + signature: l.signature, } }, }; @@ -315,8 +319,8 @@ impl ChainDbBackendAdapter for SqliteChainBackendAdapter { fn insert_instruction( &self, - item: &DbInstruction, - transaction: &Self::BackendTransaction, + _item: &DbInstruction, + _transaction: &Self::BackendTransaction, ) -> Result<(), Self::Error> { todo!() } diff --git a/dan_layer/storage_sqlite/src/sqlite_db_factory.rs b/dan_layer/storage_sqlite/src/sqlite_db_factory.rs index 31949de59b..b15d9f45d6 100644 --- a/dan_layer/storage_sqlite/src/sqlite_db_factory.rs +++ b/dan_layer/storage_sqlite/src/sqlite_db_factory.rs @@ -25,16 +25,10 @@ use crate::{ sqlite_state_db_backend_adapter::SqliteStateDbBackendAdapter, SqliteChainBackendAdapter, }; -use diesel::{prelude::*, Connection, SqliteConnection}; +use diesel::{Connection, SqliteConnection}; use diesel_migrations::embed_migrations; -use std::fs::create_dir_all; use tari_common::GlobalConfig; -use tari_dan_core::storage::{ - chain::ChainDb, - state::{StateDb, StateDbUnitOfWorkImpl}, - DbFactory, - StorageError, -}; +use tari_dan_core::storage::{chain::ChainDb, state::StateDb, DbFactory, StorageError}; #[derive(Clone)] pub struct SqliteDbFactory { @@ -62,7 +56,12 @@ impl DbFactory for SqliteDbFactory { fn create_chain_db(&self) -> Result, StorageError> { // create_dir_all(&self.database_url).map_err(|e| StorageError::FileSystemPathDoesNotExist)?; let connection = SqliteConnection::establish(self.database_url.as_str()).map_err(SqliteStorageError::from)?; - connection.execute("PRAGMA foreign_keys = ON;"); + connection + .execute("PRAGMA foreign_keys = ON;") + .map_err(|source| SqliteStorageError::DieselError { + source, + operation: "set pragma".to_string(), + })?; embed_migrations!("./migrations"); embedded_migrations::run(&connection).map_err(SqliteStorageError::from)?; Ok(ChainDb::new(SqliteChainBackendAdapter::new(self.database_url.clone()))) @@ -71,7 +70,12 @@ impl DbFactory for SqliteDbFactory { fn create_state_db(&self) -> Result, StorageError> { // create_dir_all(&self.database_url).map_err(|e| StorageError::FileSystemPathDoesNotExist)?; let connection = SqliteConnection::establish(self.database_url.as_str()).map_err(SqliteStorageError::from)?; - connection.execute("PRAGMA foreign_keys = ON;"); + connection + .execute("PRAGMA foreign_keys = ON;") + .map_err(|source| SqliteStorageError::DieselError { + source, + operation: "set pragma".to_string(), + })?; embed_migrations!("./migrations"); embedded_migrations::run(&connection).map_err(SqliteStorageError::from)?; Ok(StateDb::new(SqliteStateDbBackendAdapter::new( diff --git a/dan_layer/storage_sqlite/src/sqlite_state_db_backend_adapter.rs b/dan_layer/storage_sqlite/src/sqlite_state_db_backend_adapter.rs index dfdc9075d0..1e148dd769 100644 --- a/dan_layer/storage_sqlite/src/sqlite_state_db_backend_adapter.rs +++ b/dan_layer/storage_sqlite/src/sqlite_state_db_backend_adapter.rs @@ -44,8 +44,18 @@ impl StateDbBackendAdapter for SqliteStateDbBackendAdapter { fn create_transaction(&self) -> Result { let connection = SqliteConnection::establish(self.database_url.as_str())?; - connection.execute("PRAGMA foreign_keys = ON;"); - connection.execute("BEGIN EXCLUSIVE TRANSACTION;"); + connection + .execute("PRAGMA foreign_keys = ON;") + .map_err(|source| SqliteStorageError::DieselError { + source, + operation: "set pragma".to_string(), + })?; + connection + .execute("BEGIN EXCLUSIVE TRANSACTION;") + .map_err(|source| SqliteStorageError::DieselError { + source, + operation: "begin transaction".to_string(), + })?; Ok(SqliteTransaction::new(connection)) } @@ -81,7 +91,7 @@ impl StateDbBackendAdapter for SqliteStateDbBackendAdapter { operation: "update::state_key".to_string(), })?, None => diesel::insert_into(state_keys::table) - .values(upsert_data.clone()) + .values(upsert_data) .execute(tx.connection()) .map_err(|source| SqliteStorageError::DieselError { source, diff --git a/dan_layer/storage_sqlite/src/sqlite_storage_service.rs b/dan_layer/storage_sqlite/src/sqlite_storage_service.rs index 8ded31dad6..16188aedda 100644 --- a/dan_layer/storage_sqlite/src/sqlite_storage_service.rs +++ b/dan_layer/storage_sqlite/src/sqlite_storage_service.rs @@ -21,12 +21,10 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use async_trait::async_trait; -use std::sync::Arc; use tari_dan_core::{ - models::{HotStuffTreeNode, QuorumCertificate, SidechainMetadata, TariDanPayload}, + models::{HotStuffTreeNode, SidechainMetadata, TariDanPayload}, storage::{chain::ChainDbUnitOfWork, ChainStorageService, StorageError}, }; -use tokio::sync::RwLock; pub struct SqliteStorageService {}