diff --git a/Cargo.lock b/Cargo.lock index 3e83ee851f..c73620bca2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -460,7 +460,7 @@ dependencies = [ "serde_repr", "tokio", "url", - "zbus 5.7.1", + "zbus 5.8.0", ] [[package]] @@ -2938,7 +2938,7 @@ dependencies = [ "libc", "log", "rustversion", - "windows 0.61.1", + "windows 0.61.3", ] [[package]] @@ -2981,7 +2981,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -4228,7 +4228,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.53.0", + "windows-targets 0.53.2", ] [[package]] @@ -4669,7 +4669,7 @@ checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.59.0", ] @@ -9024,6 +9024,7 @@ dependencies = [ name = "wallet" version = "1.0.2" dependencies = [ + "async-trait", "bip39", "chainstate", "chainstate-test-framework", @@ -9031,6 +9032,7 @@ dependencies = [ "consensus", "crypto", "ctor", + "futures", "hex", "itertools 0.14.0", "lazy_static", @@ -9050,6 +9052,7 @@ dependencies = [ "tempfile", "test-utils", "thiserror", + "tokio", "trezor-client", "tx-verifier", "utils", @@ -9398,9 +9401,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" @@ -9849,9 +9852,9 @@ dependencies = [ [[package]] name = "windows" -version = "0.61.1" +version = "0.61.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ "windows-collections", "windows-core 0.61.2", @@ -9926,9 +9929,9 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] name = "windows-numerics" @@ -10042,9 +10045,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.0" +version = "0.53.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" dependencies = [ "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", @@ -10299,9 +10302,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.10" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" +checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" dependencies = [ "memchr", ] @@ -10404,9 +10407,9 @@ dependencies = [ [[package]] name = "xcursor" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" +checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b" [[package]] name = "xdg-home" @@ -10439,9 +10442,9 @@ checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] name = "xml-rs" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62ce76d9b56901b19a74f19431b0d8b3bc7ca4ad685a746dfd78ca8f4fc6bda" +checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7" [[package]] name = "yansi" @@ -10519,9 +10522,9 @@ dependencies = [ [[package]] name = "zbus" -version = "5.7.1" +version = "5.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a7c7cee313d044fca3f48fa782cb750c79e4ca76ba7bc7718cd4024cdf6f68" +checksum = "597f45e98bc7e6f0988276012797855613cd8269e23b5be62cc4e5d28b7e515d" dependencies = [ "async-broadcast", "async-recursion", @@ -10540,9 +10543,9 @@ dependencies = [ "uds_windows", "windows-sys 0.59.0", "winnow", - "zbus_macros 5.7.1", + "zbus_macros 5.8.0", "zbus_names 4.2.0", - "zvariant 5.5.3", + "zvariant 5.6.0", ] [[package]] @@ -10560,16 +10563,16 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.7.1" +version = "5.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17e7e5eec1550f747e71a058df81a9a83813ba0f6a95f39c4e218bdc7ba366a" +checksum = "e5c8e4e14dcdd9d97a98b189cd1220f30e8394ad271e8c987da84f73693862c2" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.101", "zbus_names 4.2.0", - "zvariant 5.5.3", + "zvariant 5.6.0", "zvariant_utils 3.2.0", ] @@ -10593,7 +10596,7 @@ dependencies = [ "serde", "static_assertions", "winnow", - "zvariant 5.5.3", + "zvariant 5.6.0", ] [[package]] @@ -10604,18 +10607,18 @@ checksum = "dd15f8e0dbb966fd9245e7498c7e9e5055d9e5c8b676b95bd67091cd11a1e697" [[package]] name = "zerocopy" -version = "0.8.25" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.25" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", @@ -10711,16 +10714,16 @@ dependencies = [ [[package]] name = "zvariant" -version = "5.5.3" +version = "5.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d30786f75e393ee63a21de4f9074d4c038d52c5b1bb4471f955db249f9dffb1" +checksum = "d91b3680bb339216abd84714172b5138a4edac677e641ef17e1d8cb1b3ca6e6f" dependencies = [ "endi", "enumflags2", "serde", "url", "winnow", - "zvariant_derive 5.5.3", + "zvariant_derive 5.6.0", "zvariant_utils 3.2.0", ] @@ -10739,9 +10742,9 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "5.5.3" +version = "5.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75fda702cd42d735ccd48117b1630432219c0e9616bf6cb0f8350844ee4d9580" +checksum = "3a8c68501be459a8dbfffbe5d792acdd23b4959940fc87785fb013b32edbc208" dependencies = [ "proc-macro-crate", "proc-macro2", diff --git a/wallet/Cargo.toml b/wallet/Cargo.toml index fce4026c06..a6357b52f6 100644 --- a/wallet/Cargo.toml +++ b/wallet/Cargo.toml @@ -27,10 +27,12 @@ utxo = { path = "../utxo" } wallet-storage = { path = "./storage" } wallet-types = { path = "./types" } +async-trait.workspace = true bip39 = { workspace = true, default-features = false, features = [ "std", "zeroize", ] } +futures = { workspace = true, default-features = false } hex.workspace = true itertools.workspace = true parity-scale-codec.workspace = true @@ -42,6 +44,13 @@ zeroize.workspace = true [dev-dependencies] chainstate-test-framework = { path = "../chainstate/test-framework" } test-utils = { path = "../test-utils" } +tokio = { workspace = true, default-features = false, features = [ + "io-util", + "macros", + "net", + "rt", + "sync", +] } ctor.workspace = true lazy_static.workspace = true diff --git a/wallet/src/account/mod.rs b/wallet/src/account/mod.rs index 741fd9bf15..c717767bcb 100644 --- a/wallet/src/account/mod.rs +++ b/wallet/src/account/mod.rs @@ -124,7 +124,7 @@ pub struct Account { account_info: AccountInfo, } -impl Account { +impl Account { /// Create a new account by providing a key chain pub fn new( chain_config: Arc, @@ -690,7 +690,7 @@ impl Account { pub fn process_send_request_and_sign( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, request: SendRequest, inputs: SelectedInputs, change_addresses: BTreeMap>, @@ -712,7 +712,7 @@ impl Account { fn decommission_stake_pool_impl( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, pool_id: PoolId, pool_balance: Amount, output_address: Option, @@ -776,7 +776,7 @@ impl Account { pub fn decommission_stake_pool( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, pool_id: PoolId, pool_balance: Amount, output_address: Option, @@ -793,7 +793,7 @@ impl Account { pub fn decommission_stake_pool_request( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, pool_id: PoolId, pool_balance: Amount, output_address: Option, @@ -944,7 +944,7 @@ impl Account { pub fn create_htlc_tx( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, output_value: OutputValue, htlc: HashedTimelockContract, median_time: BlockTimestamp, @@ -967,7 +967,7 @@ impl Account { pub fn create_order_tx( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, ask_value: OutputValue, give_value: OutputValue, conclude_address: Address, @@ -993,7 +993,7 @@ impl Account { pub fn create_conclude_order_tx( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, order_id: OrderId, order_info: RpcOrderInfo, output_address: Option, @@ -1063,7 +1063,7 @@ impl Account { #[allow(clippy::too_many_arguments)] pub fn create_fill_order_tx( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, order_id: OrderId, order_info: RpcOrderInfo, fill_amount_in_ask_currency: Amount, @@ -1152,7 +1152,7 @@ impl Account { pub fn create_freeze_order_tx( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, order_id: OrderId, order_info: RpcOrderInfo, median_time: BlockTimestamp, @@ -1177,7 +1177,7 @@ impl Account { pub fn create_issue_nft_tx( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, nft_issue_arguments: IssueNftArguments, median_time: BlockTimestamp, fee_rate: CurrentFeeRate, @@ -1242,7 +1242,7 @@ impl Account { pub fn mint_tokens( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, token_info: &UnconfirmedTokenInfo, address: Address, amount: Amount, @@ -1270,7 +1270,7 @@ impl Account { pub fn unmint_tokens( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, token_info: &UnconfirmedTokenInfo, amount: Amount, median_time: BlockTimestamp, @@ -1297,7 +1297,7 @@ impl Account { pub fn lock_token_supply( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, token_info: &UnconfirmedTokenInfo, median_time: BlockTimestamp, fee_rate: CurrentFeeRate, @@ -1321,7 +1321,7 @@ impl Account { pub fn freeze_token( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, token_info: &UnconfirmedTokenInfo, is_token_unfreezable: IsTokenUnfreezable, median_time: BlockTimestamp, @@ -1348,7 +1348,7 @@ impl Account { pub fn unfreeze_token( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, token_info: &UnconfirmedTokenInfo, median_time: BlockTimestamp, fee_rate: CurrentFeeRate, @@ -1372,7 +1372,7 @@ impl Account { pub fn change_token_authority( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, token_info: &UnconfirmedTokenInfo, address: Address, median_time: BlockTimestamp, @@ -1399,7 +1399,7 @@ impl Account { pub fn change_token_metadata_uri( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, token_info: &UnconfirmedTokenInfo, metadata_uri: Vec, median_time: BlockTimestamp, @@ -1427,7 +1427,7 @@ impl Account { authority: Destination, tx_input: TxInput, outputs: Vec, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, median_time: BlockTimestamp, fee_rate: CurrentFeeRate, ) -> Result { @@ -1449,7 +1449,7 @@ impl Account { pub fn create_stake_pool_with_vrf_key( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, mut stake_pool_arguments: StakePoolCreationArguments, median_time: BlockTimestamp, fee_rate: CurrentFeeRate, @@ -1470,7 +1470,7 @@ impl Account { fn create_stake_pool_impl( &mut self, stake_pool_arguments: StakePoolCreationArguments, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, vrf_public_key: VRFPublicKey, median_time: BlockTimestamp, fee_rate: CurrentFeeRate, @@ -2429,7 +2429,7 @@ struct PreselectedInputs { total_input_fees: Amount, } -impl Account { +impl Account { fn get_vrf_public_key( &mut self, db_tx: &mut impl WalletStorageWriteLocked, @@ -2500,7 +2500,7 @@ impl Account { pub fn create_stake_pool( &mut self, - db_tx: &mut impl WalletStorageWriteUnlocked, + db_tx: &mut impl WalletStorageWriteLocked, mut stake_pool_arguments: StakePoolCreationArguments, median_time: BlockTimestamp, fee_rate: CurrentFeeRate, diff --git a/wallet/src/signer/mod.rs b/wallet/src/signer/mod.rs index 66bf418b2a..6bd6218376 100644 --- a/wallet/src/signer/mod.rs +++ b/wallet/src/signer/mod.rs @@ -18,6 +18,7 @@ mod tests; use std::sync::Arc; +use async_trait::async_trait; use common::{ address::AddressError, chain::{ @@ -106,13 +107,14 @@ type SignerResult = Result; /// Signer trait responsible for signing transactions or challenges using a software or hardware /// wallet +#[async_trait] pub trait Signer { /// Sign a partially signed transaction and return the before and after signature statuses. - fn sign_tx( + async fn sign_tx( &mut self, tx: PartiallySignedTransaction, - key_chain: &impl AccountKeyChains, - db_tx: &impl WalletStorageReadUnlocked, + key_chain: &(impl AccountKeyChains + Sync), + db_tx: &(impl WalletStorageReadUnlocked + Sync), block_height: BlockHeight, ) -> SignerResult<( PartiallySignedTransaction, @@ -121,30 +123,30 @@ pub trait Signer { )>; /// Sign an arbitrary message for a destination known to this key chain. - fn sign_challenge( + async fn sign_challenge( &mut self, message: &[u8], destination: &Destination, - key_chain: &impl AccountKeyChains, - db_tx: &impl WalletStorageReadUnlocked, + key_chain: &(impl AccountKeyChains + Sync), + db_tx: &(impl WalletStorageReadUnlocked + Sync), ) -> SignerResult; /// Sign a transaction intent. The number of `input_destinations` must be the same as /// the number of inputs in the transaction; all of the destinations must be known /// to this key chain. - fn sign_transaction_intent( + async fn sign_transaction_intent( &mut self, transaction: &Transaction, input_destinations: &[Destination], intent: &str, - key_chain: &impl AccountKeyChains, - db_tx: &impl WalletStorageReadUnlocked, + key_chain: &(impl AccountKeyChains + Sync), + db_tx: &(impl WalletStorageReadUnlocked + Sync), ) -> SignerResult; } pub trait SignerProvider { - type S: Signer; - type K: AccountKeyChains; + type S: Signer + Send; + type K: AccountKeyChains + Sync + Send; fn provide(&mut self, chain_config: Arc, account_index: U31) -> Self::S; diff --git a/wallet/src/signer/software_signer/mod.rs b/wallet/src/signer/software_signer/mod.rs index 58299b03d4..a5cb846575 100644 --- a/wallet/src/signer/software_signer/mod.rs +++ b/wallet/src/signer/software_signer/mod.rs @@ -17,6 +17,7 @@ use std::sync::{Arc, Mutex}; use itertools::Itertools; +use async_trait::async_trait; use common::{ chain::{ htlc::HtlcSecret, @@ -71,7 +72,7 @@ use super::{Signer, SignerError, SignerProvider, SignerResult}; pub struct SoftwareSigner { chain_config: Arc, account_index: U31, - sig_aux_data_provider: Mutex>, + sig_aux_data_provider: Mutex>, } impl SoftwareSigner { @@ -82,7 +83,7 @@ impl SoftwareSigner { pub fn new_with_sig_aux_data_provider( chain_config: Arc, account_index: U31, - sig_aux_data_provider: Box, + sig_aux_data_provider: Box, ) -> Self { Self { chain_config, @@ -269,12 +270,13 @@ impl SoftwareSigner { } } +#[async_trait] impl Signer for SoftwareSigner { - fn sign_tx( + async fn sign_tx( &mut self, ptx: PartiallySignedTransaction, - key_chain: &impl AccountKeyChains, - db_tx: &impl WalletStorageReadUnlocked, + key_chain: &(impl AccountKeyChains + Sync), + db_tx: &(impl WalletStorageReadUnlocked + Sync), block_height: BlockHeight, ) -> SignerResult<( PartiallySignedTransaction, @@ -382,12 +384,12 @@ impl Signer for SoftwareSigner { Ok((ptx.with_witnesses(witnesses)?, prev_statuses, new_statuses)) } - fn sign_challenge( + async fn sign_challenge( &mut self, message: &[u8], destination: &Destination, - key_chain: &impl AccountKeyChains, - db_tx: &impl WalletStorageReadUnlocked, + key_chain: &(impl AccountKeyChains + Sync), + db_tx: &(impl WalletStorageReadUnlocked + Sync), ) -> SignerResult { let private_key = self .get_private_key_for_destination(destination, key_chain, db_tx)? @@ -403,13 +405,13 @@ impl Signer for SoftwareSigner { Ok(sig) } - fn sign_transaction_intent( + async fn sign_transaction_intent( &mut self, transaction: &Transaction, input_destinations: &[Destination], intent: &str, - key_chain: &impl AccountKeyChains, - db_tx: &impl WalletStorageReadUnlocked, + key_chain: &(impl AccountKeyChains + Sync), + db_tx: &(impl WalletStorageReadUnlocked + Sync), ) -> SignerResult { SignedTransactionIntent::produce_from_transaction( transaction, diff --git a/wallet/src/signer/software_signer/tests.rs b/wallet/src/signer/software_signer/tests.rs index 751dded723..b4448e6bfe 100644 --- a/wallet/src/signer/software_signer/tests.rs +++ b/wallet/src/signer/software_signer/tests.rs @@ -32,19 +32,21 @@ use crate::signer::tests::{ #[rstest] #[trace] #[case(Seed::from_entropy())] -fn test_sign_message(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn test_sign_message(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); - test_sign_message_generic(&mut rng, make_software_signer, no_another_signer()); + test_sign_message_generic(&mut rng, make_software_signer, no_another_signer()).await; } #[rstest] #[trace] #[case(Seed::from_entropy())] -fn test_sign_transaction_intent(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn test_sign_transaction_intent(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); - test_sign_transaction_intent_generic(&mut rng, make_software_signer, no_another_signer()); + test_sign_transaction_intent_generic(&mut rng, make_software_signer, no_another_signer()).await; } #[rstest] @@ -52,7 +54,8 @@ fn test_sign_transaction_intent(#[case] seed: Seed) { #[case(Seed::from_entropy(), SighashInputCommitmentVersion::V0)] #[trace] #[case(Seed::from_entropy(), SighashInputCommitmentVersion::V1)] -fn test_sign_transaction( +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn test_sign_transaction( #[case] seed: Seed, #[case] input_commitments_version: SighashInputCommitmentVersion, ) { @@ -63,16 +66,18 @@ fn test_sign_transaction( input_commitments_version, make_software_signer, no_another_signer(), - ); + ) + .await; } #[rstest] #[trace] #[case(Seed::from_entropy())] -fn test_fixed_signatures(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn test_fixed_signatures(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); - test_fixed_signatures_generic(&mut rng, make_deterministic_software_signer); + test_fixed_signatures_generic(&mut rng, make_deterministic_software_signer).await; } #[rstest] @@ -80,7 +85,8 @@ fn test_fixed_signatures(#[case] seed: Seed) { #[case(Seed::from_entropy(), SighashInputCommitmentVersion::V0)] #[trace] #[case(Seed::from_entropy(), SighashInputCommitmentVersion::V1)] -fn test_fixed_signatures2( +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn test_fixed_signatures2( #[case] seed: Seed, #[case] input_commitments_version: SighashInputCommitmentVersion, ) { @@ -90,5 +96,6 @@ fn test_fixed_signatures2( &mut rng, input_commitments_version, make_deterministic_software_signer, - ); + ) + .await; } diff --git a/wallet/src/signer/tests/generic_fixed_signature_tests.rs b/wallet/src/signer/tests/generic_fixed_signature_tests.rs index d063227ded..ccf4d6d306 100644 --- a/wallet/src/signer/tests/generic_fixed_signature_tests.rs +++ b/wallet/src/signer/tests/generic_fixed_signature_tests.rs @@ -122,8 +122,10 @@ lazy_static::lazy_static! { }; } -pub fn test_fixed_signatures_generic(rng: &mut (impl Rng + CryptoRng), make_signer: MkS) -where +pub async fn test_fixed_signatures_generic( + rng: &mut (impl Rng + CryptoRng), + make_signer: MkS, +) where MkS: Fn(Arc, U31) -> S, S: Signer, { @@ -370,9 +372,18 @@ where ); let orig_ptx = req.into_partially_signed_tx(additional_info).unwrap(); + db_tx.commit().unwrap(); + let db_tx = db.local_rw_unlocked(); let mut signer = make_signer(chain_config.clone(), account.account_index()); - let (ptx, _, _) = - signer.sign_tx(orig_ptx, account.key_chain(), &db_tx, tx_block_height).unwrap(); + let (ptx, _, _) = signer + .sign_tx( + orig_ptx, + account.key_chain(), + &db_tx.read_only_store(), + tx_block_height, + ) + .await + .unwrap(); assert!(ptx.all_signatures_available()); let input_commitments = ptx @@ -423,7 +434,7 @@ where /// 2) v1 order inputs; /// 3) htlc inputs; /// 4) v1 input commitments. -pub fn test_fixed_signatures_generic2( +pub async fn test_fixed_signatures_generic2( rng: &mut (impl Rng + CryptoRng), input_commitments_version: SighashInputCommitmentVersion, make_signer: MkS, @@ -906,13 +917,31 @@ pub fn test_fixed_signatures_generic2( .map(|comm| comm.deep_clone()) .collect_vec(); + db_tx.commit().unwrap(); + let db_tx = db.local_rw_unlocked(); let mut signer = make_signer(chain_config.clone(), account1.account_index()); - let (ptx, _, _) = signer.sign_tx(ptx, account1.key_chain(), &db_tx, tx_block_height).unwrap(); + let (ptx, _, _) = signer + .sign_tx( + ptx, + account1.key_chain(), + &db_tx.read_only_store(), + tx_block_height, + ) + .await + .unwrap(); assert!(ptx.all_signatures_available()); // Fully sign multisig inputs. let mut signer = make_signer(chain_config.clone(), account2.account_index()); - let (ptx, _, _) = signer.sign_tx(ptx, account2.key_chain(), &db_tx, tx_block_height).unwrap(); + let (ptx, _, _) = signer + .sign_tx( + ptx, + account2.key_chain(), + &db_tx.read_only_store(), + tx_block_height, + ) + .await + .unwrap(); assert!(ptx.all_signatures_available()); for (i, dest) in destinations.iter().enumerate() { @@ -1218,7 +1247,7 @@ fn make_htlc_multisig_spend_sig<'a>( StandardInputSignature::new(sighash_type, spend.encode()) } -fn new_dest_from_account( +fn new_dest_from_account( account: &mut Account, db_tx: &mut impl TransactionRwUnlocked, purpose: KeyPurpose, @@ -1226,7 +1255,7 @@ fn new_dest_from_account( account.get_new_address(db_tx, purpose).unwrap().1.into_object() } -fn new_pub_key_from_account( +fn new_pub_key_from_account( account: &mut Account, db_tx: &mut impl TransactionRwUnlocked, purpose: KeyPurpose, @@ -1235,7 +1264,7 @@ fn new_pub_key_from_account( find_pub_key_for_pkh_dest(&dest, &*account) } -fn find_pub_key_for_pkh_dest( +fn find_pub_key_for_pkh_dest( dest: &Destination, account: &Account, ) -> PublicKey { diff --git a/wallet/src/signer/tests/generic_tests.rs b/wallet/src/signer/tests/generic_tests.rs index 690d95d99d..6e65e8d4bd 100644 --- a/wallet/src/signer/tests/generic_tests.rs +++ b/wallet/src/signer/tests/generic_tests.rs @@ -69,7 +69,7 @@ use crate::{ Account, SendRequest, }; -pub fn test_sign_message_generic( +pub async fn test_sign_message_generic( rng: &mut (impl Rng + CryptoRng), make_signer: MkS1, make_another_signer: Option, @@ -105,6 +105,9 @@ pub fn test_sign_message_generic( .unwrap(); let standalone_pk_destination = Destination::PublicKey(standalone_pk); + db_tx.commit().unwrap(); + let db_tx = db.local_rw_unlocked().read_only_store(); + for destination in [pkh_destination, pk_destination, standalone_pk_destination] { let message = vec![rng.gen::(), rng.gen::(), rng.gen::()]; let message_challenge = produce_message_challenge(&message); @@ -112,6 +115,7 @@ pub fn test_sign_message_generic( let mut signer = make_signer(chain_config.clone(), account.account_index()); let res = signer .sign_challenge(&message, &destination, account.key_chain(), &db_tx) + .await .unwrap(); res.verify_signature(&chain_config, &destination, &message_challenge).unwrap(); @@ -121,6 +125,7 @@ pub fn test_sign_message_generic( let another_res = another_signer .sign_challenge(&message, &destination, account.key_chain(), &db_tx) + .await .unwrap(); another_res .verify_signature(&chain_config, &destination, &message_challenge) @@ -144,12 +149,13 @@ pub fn test_sign_message_generic( account.key_chain(), &db_tx, ) + .await .unwrap_err(); assert_eq!(err, SignerError::DestinationNotFromThisWallet); } -pub fn test_sign_transaction_intent_generic( +pub async fn test_sign_transaction_intent_generic( rng: &mut (impl Rng + CryptoRng), make_signer: MkS1, make_another_signer: Option, @@ -215,6 +221,9 @@ pub fn test_sign_transaction_intent_generic( ) .unwrap(); + db_tx.commit().unwrap(); + let db_tx = db.local_rw_unlocked().read_only_store(); + let intent: String = [rng.gen::(), rng.gen::(), rng.gen::()].iter().collect(); log::debug!("Generated intent: `{intent}`"); let expected_signed_message = @@ -229,6 +238,7 @@ pub fn test_sign_transaction_intent_generic( account.key_chain(), &db_tx, ) + .await .unwrap(); res.verify(&chain_config, &input_destinations, &expected_signed_message) .unwrap(); @@ -243,6 +253,7 @@ pub fn test_sign_transaction_intent_generic( account.key_chain(), &db_tx, ) + .await .unwrap(); another_res .verify(&chain_config, &input_destinations, &expected_signed_message) @@ -264,12 +275,13 @@ pub fn test_sign_transaction_intent_generic( account.key_chain(), &db_tx, ) + .await .unwrap_err(); assert_eq!(err, SignerError::DestinationNotFromThisWallet); } -pub fn test_sign_transaction_generic( +pub async fn test_sign_transaction_generic( rng: &mut (impl Rng + CryptoRng), input_commitments_version: SighashInputCommitmentVersion, make_signer: MkS1, @@ -693,6 +705,9 @@ pub fn test_sign_transaction_generic( ); let orig_ptx = req.into_partially_signed_tx(additional_info).unwrap(); + db_tx.commit().unwrap(); + let db_tx = db.local_rw_unlocked().read_only_store(); + let mut signer = make_signer(chain_config.clone(), account.account_index()); let (ptx, _, _) = signer .sign_tx( @@ -701,13 +716,16 @@ pub fn test_sign_transaction_generic( &db_tx, tx_block_height, ) + .await .unwrap(); + assert!(ptx.all_signatures_available()); if let Some(make_another_signer) = &make_another_signer { let mut another_signer = make_another_signer(chain_config.clone(), account.account_index()); let (another_ptx, _, _) = another_signer .sign_tx(orig_ptx, account.key_chain(), &db_tx, tx_block_height) + .await .unwrap(); assert!(another_ptx.all_signatures_available()); @@ -772,6 +790,7 @@ pub fn test_sign_transaction_generic( &db_tx, tx_block_height, ) + .await .unwrap(); assert!(ptx.all_signatures_available()); @@ -780,6 +799,7 @@ pub fn test_sign_transaction_generic( make_another_signer(chain_config.clone(), account2.account_index()); let (another_ptx, _, _) = another_signer .sign_tx(orig_ptx, account2.key_chain(), &db_tx, tx_block_height) + .await .unwrap(); assert!(another_ptx.all_signatures_available()); @@ -825,7 +845,7 @@ fn random_destination(rng: &mut (impl Rng + CryptoRng)) -> Destination { Destination::PublicKey(pk) } -fn destination_from_account( +fn destination_from_account( account: &mut Account, db_tx: &mut impl TransactionRwUnlocked, rng: &mut impl Rng, diff --git a/wallet/src/signer/trezor_signer/mod.rs b/wallet/src/signer/trezor_signer/mod.rs index 02bd8b5fff..978f7b895b 100644 --- a/wallet/src/signer/trezor_signer/mod.rs +++ b/wallet/src/signer/trezor_signer/mod.rs @@ -20,6 +20,7 @@ use std::{ use itertools::{izip, Itertools}; +use async_trait::async_trait; use common::{ address::Address, chain::{ @@ -167,7 +168,7 @@ pub struct TrezorSigner { chain_config: Arc, client: Arc>, session_id: Vec, - sig_aux_data_provider: Mutex>, + sig_aux_data_provider: Mutex>, } impl TrezorSigner { @@ -188,7 +189,7 @@ impl TrezorSigner { chain_config: Arc, client: Arc>, session_id: Vec, - sig_aux_data_provider: Box, + sig_aux_data_provider: Box, ) -> Self { Self { chain_config, @@ -482,12 +483,13 @@ fn find_trezor_device_from_db( } } +#[async_trait] impl Signer for TrezorSigner { - fn sign_tx( + async fn sign_tx( &mut self, ptx: PartiallySignedTransaction, - key_chain: &impl AccountKeyChains, - db_tx: &impl WalletStorageReadUnlocked, + key_chain: &(impl AccountKeyChains + Sync), + db_tx: &(impl WalletStorageReadUnlocked + Sync), block_height: BlockHeight, ) -> SignerResult<( PartiallySignedTransaction, @@ -715,12 +717,12 @@ impl Signer for TrezorSigner { Ok((ptx.with_witnesses(witnesses)?, prev_statuses, new_statuses)) } - fn sign_challenge( + async fn sign_challenge( &mut self, message: &[u8], destination: &Destination, - key_chain: &impl AccountKeyChains, - db_tx: &impl WalletStorageReadUnlocked, + key_chain: &(impl AccountKeyChains + Sync), + db_tx: &(impl WalletStorageReadUnlocked + Sync), ) -> SignerResult { let data = match key_chain.find_public_key(destination) { Some(FoundPubKey::Hierarchy(xpub)) => { @@ -812,13 +814,13 @@ impl Signer for TrezorSigner { Ok(sig) } - fn sign_transaction_intent( + async fn sign_transaction_intent( &mut self, transaction: &Transaction, input_destinations: &[Destination], intent: &str, - key_chain: &impl AccountKeyChains, - db_tx: &impl WalletStorageReadUnlocked, + key_chain: &(impl AccountKeyChains + Sync), + db_tx: &(impl WalletStorageReadUnlocked + Sync), ) -> SignerResult { let tx_id = transaction.get_id(); let message_to_sign = SignedTransactionIntent::get_message_to_sign(intent, &tx_id); @@ -826,7 +828,8 @@ impl Signer for TrezorSigner { let mut signatures = Vec::with_capacity(input_destinations.len()); for dest in input_destinations { let dest = SignedTransactionIntent::normalize_destination(dest); - let sig = self.sign_challenge(message_to_sign.as_bytes(), &dest, key_chain, db_tx)?; + let sig = + self.sign_challenge(message_to_sign.as_bytes(), &dest, key_chain, db_tx).await?; signatures.push(sig.into_raw()); } diff --git a/wallet/src/signer/trezor_signer/tests.rs b/wallet/src/signer/trezor_signer/tests.rs index 34ac4cb185..7a6687686a 100644 --- a/wallet/src/signer/trezor_signer/tests.rs +++ b/wallet/src/signer/trezor_signer/tests.rs @@ -75,28 +75,30 @@ pub fn make_deterministic_trezor_signer( #[trace] #[serial] #[case(Seed::from_entropy())] -fn test_sign_message(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn test_sign_message(#[case] seed: Seed) { log::debug!("test_sign_message, seed = {seed:?}"); let _join_guard = maybe_spawn_auto_confirmer(); let mut rng = make_seedable_rng(seed); - test_sign_message_generic(&mut rng, make_trezor_signer, no_another_signer()); + test_sign_message_generic(&mut rng, make_trezor_signer, no_another_signer()).await; } #[rstest] #[trace] #[serial] #[case(Seed::from_entropy())] -fn test_sign_transaction_intent(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn test_sign_transaction_intent(#[case] seed: Seed) { log::debug!("test_sign_transaction_intent, seed = {seed:?}"); let _join_guard = maybe_spawn_auto_confirmer(); let mut rng = make_seedable_rng(seed); - test_sign_transaction_intent_generic(&mut rng, make_trezor_signer, no_another_signer()); + test_sign_transaction_intent_generic(&mut rng, make_trezor_signer, no_another_signer()).await; } #[rstest] @@ -106,7 +108,8 @@ fn test_sign_transaction_intent(#[case] seed: Seed) { #[trace] #[serial] #[case(Seed::from_entropy(), SighashInputCommitmentVersion::V1)] -fn test_sign_transaction( +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn test_sign_transaction( #[case] seed: Seed, #[case] input_commitments_version: SighashInputCommitmentVersion, ) { @@ -121,21 +124,23 @@ fn test_sign_transaction( input_commitments_version, make_trezor_signer, no_another_signer(), - ); + ) + .await; } #[rstest] #[trace] #[serial] #[case(Seed::from_entropy())] -fn test_fixed_signatures(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn test_fixed_signatures(#[case] seed: Seed) { log::debug!("test_fixed_signatures, seed = {seed:?}"); let _join_guard = maybe_spawn_auto_confirmer(); let mut rng = make_seedable_rng(seed); - test_fixed_signatures_generic(&mut rng, make_deterministic_trezor_signer); + test_fixed_signatures_generic(&mut rng, make_deterministic_trezor_signer).await; } #[rstest] @@ -145,7 +150,8 @@ fn test_fixed_signatures(#[case] seed: Seed) { #[trace] #[serial] #[case(Seed::from_entropy(), SighashInputCommitmentVersion::V1)] -fn test_fixed_signatures2( +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn test_fixed_signatures2( #[case] seed: Seed, #[case] input_commitments_version: SighashInputCommitmentVersion, ) { @@ -159,14 +165,16 @@ fn test_fixed_signatures2( &mut rng, input_commitments_version, make_deterministic_trezor_signer, - ); + ) + .await; } #[rstest] #[trace] #[serial] #[case(Seed::from_entropy())] -fn test_sign_message_sig_consistency(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn test_sign_message_sig_consistency(#[case] seed: Seed) { log::debug!("test_sign_message_sig_consistency, seed = {seed:?}"); let _join_guard = maybe_spawn_auto_confirmer(); @@ -177,14 +185,16 @@ fn test_sign_message_sig_consistency(#[case] seed: Seed) { &mut rng, make_deterministic_trezor_signer, Some(make_deterministic_software_signer), - ); + ) + .await; } #[rstest] #[trace] #[serial] #[case(Seed::from_entropy())] -fn test_sign_transaction_intent_sig_consistency(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn test_sign_transaction_intent_sig_consistency(#[case] seed: Seed) { log::debug!("test_sign_transaction_intent_sig_consistency, seed = {seed:?}"); let _join_guard = maybe_spawn_auto_confirmer(); @@ -195,7 +205,8 @@ fn test_sign_transaction_intent_sig_consistency(#[case] seed: Seed) { &mut rng, make_deterministic_trezor_signer, Some(make_deterministic_software_signer), - ); + ) + .await; } #[rstest] @@ -205,7 +216,8 @@ fn test_sign_transaction_intent_sig_consistency(#[case] seed: Seed) { #[trace] #[serial] #[case(Seed::from_entropy(), SighashInputCommitmentVersion::V1)] -fn test_sign_transaction_sig_consistency( +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn test_sign_transaction_sig_consistency( #[case] seed: Seed, #[case] input_commitments_version: SighashInputCommitmentVersion, ) { @@ -220,5 +232,6 @@ fn test_sign_transaction_sig_consistency( input_commitments_version, make_deterministic_trezor_signer, Some(make_deterministic_software_signer), - ); + ) + .await; } diff --git a/wallet/src/wallet/mod.rs b/wallet/src/wallet/mod.rs index 2af79918df..6b7addeb8d 100644 --- a/wallet/src/wallet/mod.rs +++ b/wallet/src/wallet/mod.rs @@ -71,9 +71,10 @@ use tx_verifier::{check_transaction, CheckTransactionError}; use utils::{debug_panic_or_log, ensure}; pub use wallet_storage::Error; use wallet_storage::{ - DefaultBackend, Store, StoreTxRo, StoreTxRw, StoreTxRwUnlocked, TransactionRoLocked, - TransactionRwLocked, TransactionRwUnlocked, Transactional, WalletStorageReadLocked, - WalletStorageReadUnlocked, WalletStorageWriteLocked, WalletStorageWriteUnlocked, + DefaultBackend, Store, StoreLocalReadOnlyUnlocked, StoreLocalReadWriteUnlocked, StoreTxRo, + StoreTxRw, StoreTxRwUnlocked, TransactionRoLocked, TransactionRwLocked, TransactionRwUnlocked, + Transactional, WalletStorageReadLocked, WalletStorageReadUnlocked, WalletStorageWriteLocked, + WalletStorageWriteUnlocked, }; use wallet_types::account_info::{StandaloneAddressDetails, StandaloneAddresses}; use wallet_types::chain_info::ChainInfo; @@ -1111,8 +1112,9 @@ where } Err(err) => { db_tx.abort(); - // In case of an error reload the keys in case the operation issued new ones and - // are saved in the cache but not in the DB + // In case of an error we should reload the keys, in the case that the operation has issued new ones keys + // we do this to prevent exhausting the keys from many failed operations, and to + // keep the cache in sync with the DB, as the DB transaction will roll back. let db_tx = self.db.transaction_ro()?; account.reload_keys(&db_tx)?; Err(err) @@ -1120,34 +1122,102 @@ where } } - fn for_account_rw_unlocked_and_check_tx_generic( + async fn async_for_account_rw_unlocked( + &mut self, + account_index: U31, + create_request: impl FnOnce(&mut Account, &mut StoreLocalReadWriteUnlocked) -> R, + sign_request: impl AsyncFnOnce( + R, + &P::K, + StoreLocalReadOnlyUnlocked, + Arc, +

::S, + ) -> WalletResult + + Send, + ) -> WalletResult { + let account = Self::get_account_mut(&mut self.accounts, account_index)?; + let mut local_db_tx = self.db.local_rw_unlocked(); + let result = create_request(account, &mut local_db_tx); + let signer = self.signer_provider.provide(self.chain_config.clone(), account_index); + let config = self.chain_config.clone(); + let result = sign_request( + result, + account.key_chain(), + local_db_tx.read_only_store(), + config, + signer, + ) + .await; + + match result { + Ok(value) => { + let mut db_tx = self.db.transaction_rw(None)?; + local_db_tx.perform_operations(&mut db_tx)?; + // Abort the process if the DB transaction fails. See `for_account_rw` for more information. + db_tx.commit().expect("RW transaction commit failed unexpectedly"); + Ok(value) + } + Err(err) => { + // In case of an error we should reload the keys, in the case that the operation has issued new ones keys + // we do this to prevent exhausting the keys from many failed operations, and to + // keep the cache in sync with the DB, as the DB transaction will roll back. + let db_tx = self.db.transaction_ro()?; + account.reload_keys(&db_tx)?; + Err(err) + } + } + } + + async fn async_for_account_key_chain_rw_unlocked( + &mut self, + account_index: U31, + f: impl AsyncFnOnce( + &P::K, + StoreLocalReadOnlyUnlocked, + Arc, +

::S, + ) -> WalletResult + + Send, + ) -> WalletResult { + self.async_for_account_rw_unlocked( + account_index, + |_, _| (), + async move |_, key_chain, db_tx, chain_config, signer| { + f(key_chain, db_tx, chain_config, signer).await + }, + ) + .await + } + + async fn async_for_account_rw_unlocked_and_check_tx_custom_error( &mut self, account_index: U31, additional_info: TxAdditionalInfo, f: impl FnOnce( &mut Account, - &mut StoreTxRwUnlocked, + &mut StoreLocalReadWriteUnlocked, ) -> WalletResult<(SendRequest, AddlData)>, - error_mapper: impl FnOnce(WalletError) -> WalletError, + error_mapper: impl FnOnce(WalletError) -> WalletError + Send, ) -> WalletResult<(SignedTxWithFees, AddlData)> { let (_, best_block_height) = self.get_best_block_for_account(account_index)?; let next_block_height = best_block_height.next_height(); - self.for_account_rw_unlocked( + self.async_for_account_rw_unlocked( account_index, - |account, db_tx, chain_config, signer_provider| { - let (mut request, additional_data) = f(account, db_tx)?; + f, + async move |request, key_chain, store, chain_config, mut signer| { + let (mut request, additional_data) = request?; + let fees = request.get_fees(); let ptx = request.into_partially_signed_tx(additional_info)?; - let mut signer = - signer_provider.provide(Arc::new(chain_config.clone()), account_index); let ptx = signer - .sign_tx(ptx, account.key_chain(), db_tx, next_block_height) + .sign_tx(ptx, key_chain, &store, next_block_height) + .await .map(|(ptx, _, _)| ptx)?; let input_commitments = - ptx.make_sighash_input_commitments_at_height(chain_config, next_block_height)?; + ptx.make_sighash_input_commitments_at_height(&chain_config, next_block_height)?; let is_fully_signed = ptx.destinations().iter().enumerate().zip(ptx.witnesses()).all( @@ -1157,7 +1227,7 @@ where let input_utxo = ptx.input_utxos()[i].clone(); tx_verifier::input_check::signature_only_check::verify_tx_signature( - chain_config, + &chain_config, destination, &ptx, &input_commitments, @@ -1177,27 +1247,31 @@ where let tx = ptx.into_signed_tx().map_err(|e| error_mapper(e.into()))?; - check_transaction(chain_config, next_block_height, &tx)?; + check_transaction(&chain_config, next_block_height, &tx)?; let tx = SignedTxWithFees { tx, fees }; Ok((tx, additional_data)) }, ) + .await } - fn for_account_rw_unlocked_and_check_tx_with_fees( + async fn async_for_account_rw_unlocked_and_check_tx( &mut self, account_index: U31, additional_info: TxAdditionalInfo, - f: impl FnOnce(&mut Account, &mut StoreTxRwUnlocked) -> WalletResult, + f: impl FnOnce( + &mut Account, + &mut StoreLocalReadWriteUnlocked, + ) -> WalletResult, ) -> WalletResult { - Ok(self - .for_account_rw_unlocked_and_check_tx_generic( - account_index, - additional_info, - |account, db_tx| Ok((f(account, db_tx)?, ())), - |err| err, - )? - .0) + self.async_for_account_rw_unlocked_and_check_tx_custom_error( + account_index, + additional_info, + |account, db_tx| Ok((f(account, db_tx)?, ())), + |err| err, + ) + .await + .map(|(tx, _)| tx) } fn get_account(&self, account_index: U31) -> WalletResult<&Account> { @@ -1537,7 +1611,7 @@ where /// /// A `WalletResult` containing the signed transaction if successful, or an error indicating the reason for failure. #[allow(clippy::too_many_arguments)] - pub fn create_transaction_to_addresses( + pub async fn create_transaction_to_addresses( &mut self, account_index: U31, outputs: impl IntoIterator, @@ -1557,14 +1631,15 @@ where consolidate_fee_rate, |_s| (), additional_info, - )? + ) + .await? .0) } /// Same as `create_transaction_to_addresses`, but it also allows to specify the "intent" for the transaction, /// which will be concatenated with the transaction id and signed with all the keys used to sign the transaction's inputs. #[allow(clippy::too_many_arguments)] - pub fn create_transaction_to_addresses_with_intent( + pub async fn create_transaction_to_addresses_with_intent( &mut self, account_index: U31, outputs: impl IntoIterator, @@ -1575,38 +1650,43 @@ where consolidate_fee_rate: FeeRate, additional_info: TxAdditionalInfo, ) -> WalletResult<(SignedTxWithFees, SignedTransactionIntent)> { - let (signed_tx, input_destinations) = self.create_transaction_to_addresses_impl( - account_index, - outputs, - inputs, - change_addresses, - current_fee_rate, - consolidate_fee_rate, - |send_request| send_request.destinations().to_owned(), - additional_info, - )?; + let (signed_tx, input_destinations) = self + .create_transaction_to_addresses_impl( + account_index, + outputs, + inputs, + change_addresses, + current_fee_rate, + consolidate_fee_rate, + |send_request| send_request.destinations().to_owned(), + additional_info, + ) + .await?; - let signed_intent = self.for_account_rw_unlocked( - account_index, - |account, db_tx, chain_config, signer_provider| { - let mut signer = - signer_provider.provide(Arc::new(chain_config.clone()), account_index); - - Ok(signer.sign_transaction_intent( - signed_tx.tx.transaction(), - &input_destinations, - &intent, - account.key_chain(), - db_tx, - )?) - }, - )?; + let transaction = signed_tx.transaction(); + let signed_intent = self + .async_for_account_key_chain_rw_unlocked( + account_index, + async move |key_chain, store, _chain_config, mut signer| { + signer + .sign_transaction_intent( + transaction, + &input_destinations, + &intent, + key_chain, + &store, + ) + .await + .map_err(Into::into) + }, + ) + .await?; Ok((signed_tx, signed_intent)) } #[allow(clippy::too_many_arguments)] - fn create_transaction_to_addresses_impl( + async fn create_transaction_to_addresses_impl( &mut self, account_index: U31, outputs: impl IntoIterator, @@ -1619,7 +1699,7 @@ where ) -> WalletResult<(SignedTxWithFees, AddlData)> { let request = SendRequest::new().with_outputs(outputs); let latest_median_time = self.latest_median_time; - self.for_account_rw_unlocked_and_check_tx_generic( + self.async_for_account_rw_unlocked_and_check_tx_custom_error( account_index, additional_info, |account, db_tx| { @@ -1640,6 +1720,7 @@ where }, |err| err, ) + .await } #[allow(clippy::too_many_arguments)] @@ -1673,7 +1754,7 @@ where }) } - pub fn create_sweep_transaction( + pub async fn create_sweep_transaction( &mut self, account_index: U31, destination: Destination, @@ -1688,14 +1769,15 @@ where &|_| None, )?; - self.for_account_rw_unlocked_and_check_tx_with_fees( + self.async_for_account_rw_unlocked_and_check_tx( account_index, additional_info, |account, _| account.sweep_addresses(destination, request, current_fee_rate), ) + .await } - pub fn create_sweep_from_delegation_transaction( + pub async fn create_sweep_from_delegation_transaction( &mut self, account_index: U31, address: Address, @@ -1703,16 +1785,17 @@ where delegation_share: Amount, current_fee_rate: FeeRate, ) -> WalletResult { - self.for_account_rw_unlocked_and_check_tx_with_fees( + self.async_for_account_rw_unlocked_and_check_tx( account_index, TxAdditionalInfo::new(), |account, _| { account.sweep_delegation(address, delegation_id, delegation_share, current_fee_rate) }, ) + .await } - pub fn create_transaction_to_addresses_from_delegation( + pub async fn create_transaction_to_addresses_from_delegation( &mut self, account_index: U31, address: Address, @@ -1721,7 +1804,7 @@ where delegation_share: Amount, current_fee_rate: FeeRate, ) -> WalletResult { - self.for_account_rw_unlocked_and_check_tx_with_fees( + self.async_for_account_rw_unlocked_and_check_tx( account_index, TxAdditionalInfo::new(), |account, _| { @@ -1734,9 +1817,10 @@ where ) }, ) + .await } - pub fn mint_tokens( + pub async fn mint_tokens( &mut self, account_index: U31, token_info: &UnconfirmedTokenInfo, @@ -1747,7 +1831,7 @@ where ) -> WalletResult { let latest_median_time = self.latest_median_time; let additional_info = to_token_additional_info(token_info); - self.for_account_rw_unlocked_and_check_tx_with_fees( + self.async_for_account_rw_unlocked_and_check_tx( account_index, additional_info, |account, db_tx| { @@ -1764,9 +1848,10 @@ where ) }, ) + .await } - pub fn unmint_tokens( + pub async fn unmint_tokens( &mut self, account_index: U31, token_info: &UnconfirmedTokenInfo, @@ -1776,7 +1861,7 @@ where ) -> WalletResult { let latest_median_time = self.latest_median_time; let additional_info = to_token_additional_info(token_info); - self.for_account_rw_unlocked_and_check_tx_with_fees( + self.async_for_account_rw_unlocked_and_check_tx( account_index, additional_info, |account, db_tx| { @@ -1792,9 +1877,10 @@ where ) }, ) + .await } - pub fn lock_token_supply( + pub async fn lock_token_supply( &mut self, account_index: U31, token_info: &UnconfirmedTokenInfo, @@ -1803,7 +1889,7 @@ where ) -> WalletResult { let latest_median_time = self.latest_median_time; let additional_info = to_token_additional_info(token_info); - self.for_account_rw_unlocked_and_check_tx_with_fees( + self.async_for_account_rw_unlocked_and_check_tx( account_index, additional_info, |account, db_tx| { @@ -1818,9 +1904,10 @@ where ) }, ) + .await } - pub fn freeze_token( + pub async fn freeze_token( &mut self, account_index: U31, token_info: &UnconfirmedTokenInfo, @@ -1830,7 +1917,7 @@ where ) -> WalletResult { let latest_median_time = self.latest_median_time; let additional_info = to_token_additional_info(token_info); - self.for_account_rw_unlocked_and_check_tx_with_fees( + self.async_for_account_rw_unlocked_and_check_tx( account_index, additional_info, |account, db_tx| { @@ -1846,9 +1933,10 @@ where ) }, ) + .await } - pub fn unfreeze_token( + pub async fn unfreeze_token( &mut self, account_index: U31, token_info: &UnconfirmedTokenInfo, @@ -1857,7 +1945,7 @@ where ) -> WalletResult { let latest_median_time = self.latest_median_time; let additional_info = to_token_additional_info(token_info); - self.for_account_rw_unlocked_and_check_tx_with_fees( + self.async_for_account_rw_unlocked_and_check_tx( account_index, additional_info, |account, db_tx| { @@ -1872,9 +1960,10 @@ where ) }, ) + .await } - pub fn change_token_authority( + pub async fn change_token_authority( &mut self, account_index: U31, token_info: &UnconfirmedTokenInfo, @@ -1884,7 +1973,7 @@ where ) -> WalletResult { let latest_median_time = self.latest_median_time; let additional_info = to_token_additional_info(token_info); - self.for_account_rw_unlocked_and_check_tx_with_fees( + self.async_for_account_rw_unlocked_and_check_tx( account_index, additional_info, |account, db_tx| { @@ -1900,9 +1989,10 @@ where ) }, ) + .await } - pub fn change_token_metadata_uri( + pub async fn change_token_metadata_uri( &mut self, account_index: U31, token_info: &UnconfirmedTokenInfo, @@ -1912,7 +2002,7 @@ where ) -> WalletResult { let latest_median_time = self.latest_median_time; let additional_info = to_token_additional_info(token_info); - self.for_account_rw_unlocked_and_check_tx_with_fees( + self.async_for_account_rw_unlocked_and_check_tx( account_index, additional_info, |account, db_tx| { @@ -1928,6 +2018,7 @@ where ) }, ) + .await } pub fn find_used_tokens( @@ -1947,27 +2038,29 @@ where self.get_account(account_index)?.get_token_unconfirmed_info(token_info) } - pub fn create_delegation( + pub async fn create_delegation( &mut self, account_index: U31, outputs: Vec, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, ) -> WalletResult<(DelegationId, SignedTxWithFees)> { - let tx = self.create_transaction_to_addresses( - account_index, - outputs, - SelectedInputs::Utxos(vec![]), - BTreeMap::new(), - current_fee_rate, - consolidate_fee_rate, - TxAdditionalInfo::new(), - )?; + let tx = self + .create_transaction_to_addresses( + account_index, + outputs, + SelectedInputs::Utxos(vec![]), + BTreeMap::new(), + current_fee_rate, + consolidate_fee_rate, + TxAdditionalInfo::new(), + ) + .await?; let delegation_id = make_delegation_id(tx.transaction().inputs())?; Ok((delegation_id, tx)) } - pub fn issue_new_token( + pub async fn issue_new_token( &mut self, account_index: U31, token_issuance: TokenIssuance, @@ -1976,15 +2069,17 @@ where ) -> WalletResult<(TokenId, SignedTxWithFees)> { let outputs = make_issue_token_outputs(token_issuance, self.chain_config.as_ref())?; - let tx = self.create_transaction_to_addresses( - account_index, - outputs, - SelectedInputs::Utxos(vec![]), - BTreeMap::new(), - current_fee_rate, - consolidate_fee_rate, - TxAdditionalInfo::new(), - )?; + let tx = self + .create_transaction_to_addresses( + account_index, + outputs, + SelectedInputs::Utxos(vec![]), + BTreeMap::new(), + current_fee_rate, + consolidate_fee_rate, + TxAdditionalInfo::new(), + ) + .await?; let token_id = make_token_id( self.chain_config.as_ref(), self.get_best_block_for_account(account_index)?.1.next_height(), @@ -1993,7 +2088,7 @@ where Ok((token_id, tx)) } - pub fn issue_new_nft( + pub async fn issue_new_nft( &mut self, account_index: U31, address: Address, @@ -2004,24 +2099,26 @@ where let destination = address.into_object(); let latest_median_time = self.latest_median_time; - let signed_transaction = self.for_account_rw_unlocked_and_check_tx_with_fees( - account_index, - TxAdditionalInfo::new(), - |account, db_tx| { - account.create_issue_nft_tx( - db_tx, - IssueNftArguments { - metadata, - destination, - }, - latest_median_time, - CurrentFeeRate { - current_fee_rate, - consolidate_fee_rate, - }, - ) - }, - )?; + let signed_transaction = self + .async_for_account_rw_unlocked_and_check_tx( + account_index, + TxAdditionalInfo::new(), + |account, db_tx| { + account.create_issue_nft_tx( + db_tx, + IssueNftArguments { + metadata, + destination, + }, + latest_median_time, + CurrentFeeRate { + current_fee_rate, + consolidate_fee_rate, + }, + ) + }, + ) + .await?; let token_id = make_token_id( self.chain_config.as_ref(), @@ -2031,7 +2128,7 @@ where Ok((token_id, signed_transaction)) } - pub fn create_stake_pool_with_vrf_key( + pub async fn create_stake_pool_with_vrf_key( &mut self, account_index: U31, current_fee_rate: FeeRate, @@ -2039,7 +2136,7 @@ where stake_pool_arguments: StakePoolCreationArguments, ) -> WalletResult { let latest_median_time = self.latest_median_time; - self.for_account_rw_unlocked_and_check_tx_with_fees( + self.async_for_account_rw_unlocked_and_check_tx( account_index, TxAdditionalInfo::new(), |account, db_tx| { @@ -2054,9 +2151,10 @@ where ) }, ) + .await } - pub fn decommission_stake_pool( + pub async fn decommission_stake_pool( &mut self, account_index: U31, pool_id: PoolId, @@ -2066,28 +2164,27 @@ where ) -> WalletResult { let additional_info = TxAdditionalInfo::new().with_pool_info(pool_id, PoolAdditionalInfo { staker_balance }); - Ok(self - .for_account_rw_unlocked_and_check_tx_generic( - account_index, - additional_info, - |account, db_tx| { - Ok(( - account.decommission_stake_pool( - db_tx, - pool_id, - staker_balance, - output_address, - current_fee_rate, - )?, - (), - )) - }, - |_err| WalletError::PartiallySignedTransactionInDecommissionCommand, - )? - .0) + self.async_for_account_rw_unlocked_and_check_tx_custom_error( + account_index, + additional_info, + |account: &mut Account<

::K>, db_tx| { + account + .decommission_stake_pool( + db_tx, + pool_id, + staker_balance, + output_address, + current_fee_rate, + ) + .map(|r| (r, ())) + }, + |_err| WalletError::PartiallySignedTransactionInDecommissionCommand, + ) + .await + .map(|(tx, _)| tx) } - pub fn decommission_stake_pool_request( + pub async fn decommission_stake_pool_request( &mut self, account_index: U31, pool_id: PoolId, @@ -2100,34 +2197,57 @@ where let additional_info = TxAdditionalInfo::new().with_pool_info(pool_id, PoolAdditionalInfo { staker_balance }); - self.for_account_rw_unlocked( + self.async_for_account_rw_unlocked( account_index, - |account, db_tx, chain_config, signer_provider| { - let request = account.decommission_stake_pool_request( + |account, db_tx| { + account.decommission_stake_pool_request( db_tx, pool_id, staker_balance, output_address, current_fee_rate, - )?; - - let ptx = request.into_partially_signed_tx(additional_info)?; + ) + }, + async move |request, key_chain, store, chain_config, mut signer| { + let ptx = request?.into_partially_signed_tx(additional_info)?; - let mut signer = - signer_provider.provide(Arc::new(chain_config.clone()), account_index); let ptx = signer - .sign_tx(ptx, account.key_chain(), db_tx, next_block_height) + .sign_tx(ptx, key_chain, &store, next_block_height) + .await .map(|(ptx, _, _)| ptx)?; + let input_commitments = + ptx.make_sighash_input_commitments_at_height(&chain_config, next_block_height)?; + let is_fully_signed = + ptx.destinations().iter().enumerate().zip(ptx.witnesses()).all( + |((i, destination), witness)| match (witness, destination) { + (None | Some(_), None) | (None, Some(_)) => false, + (Some(_), Some(destination)) => { + let input_utxo = ptx.input_utxos()[i].clone(); - if ptx.all_signatures_available() { + tx_verifier::input_check::signature_only_check::verify_tx_signature( + &chain_config, + destination, + &ptx, + &input_commitments, + i, + input_utxo, + ) + .is_ok() + } + }, + ); + + if is_fully_signed { return Err(WalletError::FullySignedTransactionInDecommissionReq); } + Ok(ptx) }, ) + .await } - pub fn create_htlc_tx( + pub async fn create_htlc_tx( &mut self, account_index: U31, output_value: OutputValue, @@ -2137,7 +2257,7 @@ where additional_info: TxAdditionalInfo, ) -> WalletResult { let latest_median_time = self.latest_median_time; - self.for_account_rw_unlocked_and_check_tx_with_fees( + self.async_for_account_rw_unlocked_and_check_tx( account_index, additional_info, |account, db_tx| { @@ -2153,6 +2273,7 @@ where ) }, ) + .await } pub fn get_orders( @@ -2164,7 +2285,7 @@ where } #[allow(clippy::too_many_arguments)] - pub fn create_order_tx( + pub async fn create_order_tx( &mut self, account_index: U31, ask_value: OutputValue, @@ -2175,29 +2296,31 @@ where additional_info: TxAdditionalInfo, ) -> WalletResult<(OrderId, SignedTxWithFees)> { let latest_median_time = self.latest_median_time; - let tx = self.for_account_rw_unlocked_and_check_tx_with_fees( - account_index, - additional_info, - |account, db_tx| { - account.create_order_tx( - db_tx, - ask_value, - give_value, - conclude_key, - latest_median_time, - CurrentFeeRate { - current_fee_rate, - consolidate_fee_rate, - }, - ) - }, - )?; + let tx = self + .async_for_account_rw_unlocked_and_check_tx( + account_index, + additional_info, + |account, db_tx| { + account.create_order_tx( + db_tx, + ask_value, + give_value, + conclude_key, + latest_median_time, + CurrentFeeRate { + current_fee_rate, + consolidate_fee_rate, + }, + ) + }, + ) + .await?; let order_id = make_order_id(tx.tx.inputs())?; Ok((order_id, tx)) } #[allow(clippy::too_many_arguments)] - pub fn create_conclude_order_tx( + pub async fn create_conclude_order_tx( &mut self, account_index: U31, order_id: OrderId, @@ -2208,7 +2331,7 @@ where additional_info: TxAdditionalInfo, ) -> WalletResult { let latest_median_time = self.latest_median_time; - self.for_account_rw_unlocked_and_check_tx_with_fees( + self.async_for_account_rw_unlocked_and_check_tx( account_index, additional_info, |account, db_tx| { @@ -2225,10 +2348,11 @@ where ) }, ) + .await } #[allow(clippy::too_many_arguments)] - pub fn create_fill_order_tx( + pub async fn create_fill_order_tx( &mut self, account_index: U31, order_id: OrderId, @@ -2240,7 +2364,7 @@ where additional_info: TxAdditionalInfo, ) -> WalletResult { let latest_median_time = self.latest_median_time; - self.for_account_rw_unlocked_and_check_tx_with_fees( + self.async_for_account_rw_unlocked_and_check_tx( account_index, additional_info, |account, db_tx| { @@ -2258,9 +2382,10 @@ where ) }, ) + .await } - pub fn create_freeze_order_tx( + pub async fn create_freeze_order_tx( &mut self, account_index: U31, order_id: OrderId, @@ -2270,7 +2395,7 @@ where additional_info: TxAdditionalInfo, ) -> WalletResult { let latest_median_time = self.latest_median_time; - self.for_account_rw_unlocked_and_check_tx_with_fees( + self.async_for_account_rw_unlocked_and_check_tx( account_index, additional_info, |account, db_tx| { @@ -2286,9 +2411,10 @@ where ) }, ) + .await } - pub fn sign_raw_transaction( + pub async fn sign_raw_transaction( &mut self, account_index: U31, ptx: PartiallySignedTransaction, @@ -2300,34 +2426,34 @@ where let (_, best_block_height) = self.get_best_block_for_account(account_index)?; let next_block_height = best_block_height.next_height(); - self.for_account_rw_unlocked( + self.async_for_account_key_chain_rw_unlocked( account_index, - |account, db_tx, chain_config, signer_provider| { - let mut signer = - signer_provider.provide(Arc::new(chain_config.clone()), account_index); - - let res = signer.sign_tx(ptx, account.key_chain(), db_tx, next_block_height)?; - Ok(res) + async move |key_chain, store, _chain_config, mut signer| { + signer + .sign_tx(ptx, key_chain, &store, next_block_height) + .await + .map_err(Into::into) }, ) + .await } - pub fn sign_challenge( + pub async fn sign_challenge( &mut self, account_index: U31, challenge: &[u8], destination: &Destination, ) -> WalletResult { - self.for_account_rw_unlocked( + self.async_for_account_key_chain_rw_unlocked( account_index, - |account, db_tx, chain_config, signer_provider| { - let mut signer = - signer_provider.provide(Arc::new(chain_config.clone()), account_index); - let msg = - signer.sign_challenge(challenge, destination, account.key_chain(), db_tx)?; - Ok(msg) + async move |key_chain, store, _chain_config, mut signer| { + signer + .sign_challenge(challenge, destination, key_chain, &store) + .await + .map_err(Into::into) }, ) + .await } /// Returns the last scanned block hash and height for all accounts. @@ -2537,7 +2663,7 @@ where Ok(account.get_legacy_vrf_public_key()) } - pub fn create_stake_pool( + pub async fn create_stake_pool( &mut self, account_index: U31, current_fee_rate: FeeRate, @@ -2545,7 +2671,7 @@ where stake_pool_arguments: StakePoolCreationArguments, ) -> WalletResult { let latest_median_time = self.latest_median_time; - self.for_account_rw_unlocked_and_check_tx_with_fees( + self.async_for_account_rw_unlocked_and_check_tx( account_index, TxAdditionalInfo::new(), |account, db_tx| { @@ -2560,6 +2686,7 @@ where ) }, ) + .await } pub fn get_pos_gen_block_data( diff --git a/wallet/src/wallet/tests.rs b/wallet/src/wallet/tests.rs index fec31701b3..fd16fe9678 100644 --- a/wallet/src/wallet/tests.rs +++ b/wallet/src/wallet/tests.rs @@ -1042,8 +1042,8 @@ fn test_wallet_accounts( assert_eq!(accounts, expected_accounts); } -#[test] -fn wallet_accounts_creation() { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn wallet_accounts_creation() { let chain_config = Arc::new(create_mainnet()); let mut wallet = create_wallet(chain_config.clone()); @@ -1079,6 +1079,7 @@ fn wallet_accounts_creation() { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; @@ -1203,7 +1204,8 @@ fn wallet_recover_new_account(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn locked_wallet_cant_sign_transaction(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn locked_wallet_cant_sign_transaction(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_mainnet()); @@ -1231,18 +1233,20 @@ fn locked_wallet_cant_sign_transaction(#[case] seed: Seed) { ); assert_eq!( - wallet.create_transaction_to_addresses( - DEFAULT_ACCOUNT_INDEX, - [new_output.clone()], - SelectedInputs::Utxos(vec![]), - BTreeMap::new(), - FeeRate::from_amount_per_kb(Amount::ZERO), - FeeRate::from_amount_per_kb(Amount::ZERO), - TxAdditionalInfo::new(), - ), - Err(WalletError::DatabaseError( - wallet_storage::Error::WalletLocked - )) + wallet + .create_transaction_to_addresses( + DEFAULT_ACCOUNT_INDEX, + [new_output.clone()], + SelectedInputs::Utxos(vec![]), + BTreeMap::new(), + FeeRate::from_amount_per_kb(Amount::ZERO), + FeeRate::from_amount_per_kb(Amount::ZERO), + TxAdditionalInfo::new(), + ) + .await, + Err(WalletError::SignerError(SignerError::KeyChainError( + KeyChainError::DatabaseError(wallet_storage::Error::WalletLocked) + ))) ); // success after unlock @@ -1258,6 +1262,7 @@ fn locked_wallet_cant_sign_transaction(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap(); } else { // check if we remove the password it should fail to lock @@ -1288,13 +1293,15 @@ fn locked_wallet_cant_sign_transaction(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap(); } } #[rstest] #[trace] #[case(Seed::from_entropy())] -fn wallet_get_transaction(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn wallet_get_transaction(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_mainnet()); @@ -1316,6 +1323,7 @@ fn wallet_get_transaction(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; @@ -1353,7 +1361,8 @@ fn wallet_get_transaction(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn wallet_list_mainchain_transactions(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn wallet_list_mainchain_transactions(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_regtest()); @@ -1377,6 +1386,7 @@ fn wallet_list_mainchain_transactions(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; @@ -1401,6 +1411,7 @@ fn wallet_list_mainchain_transactions(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; let spend_from_tx_id = tx.transaction().get_id(); @@ -1433,7 +1444,8 @@ fn wallet_list_mainchain_transactions(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn wallet_transactions_with_fees(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn wallet_transactions_with_fees(#[case] seed: Seed) { use crate::destination_getters::{get_tx_output_destination, HtlcSpendingCondition}; let mut rng = make_seedable_rng(seed); @@ -1469,6 +1481,7 @@ fn wallet_transactions_with_fees(#[case] seed: Seed) { very_big_feerate, TxAdditionalInfo::new(), ) + .await .unwrap_err(); match err { @@ -1510,6 +1523,7 @@ fn wallet_transactions_with_fees(#[case] seed: Seed) { feerate, TxAdditionalInfo::new(), ) + .await .unwrap(); let tx_size = serialization::Encode::encoded_size(&tx); @@ -1566,6 +1580,7 @@ fn wallet_transactions_with_fees(#[case] seed: Seed) { feerate, TxAdditionalInfo::new(), ) + .await .unwrap(); let tx_size = serialization::Encode::encoded_size(&tx); @@ -1618,7 +1633,8 @@ fn lock_wallet_fail_empty_password() { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn spend_from_user_specified_utxos(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn spend_from_user_specified_utxos(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_mainnet()); @@ -1671,6 +1687,7 @@ fn spend_from_user_specified_utxos(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap_err(); assert_eq!(err, WalletError::CannotFindUtxo(missing_utxo.clone())); @@ -1698,6 +1715,7 @@ fn spend_from_user_specified_utxos(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; @@ -1737,6 +1755,7 @@ fn spend_from_user_specified_utxos(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap_err(); assert_eq!( @@ -1749,7 +1768,10 @@ fn spend_from_user_specified_utxos(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn create_stake_pool_and_list_pool_ids(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn create_stake_pool_and_list_pool_ids(#[case] seed: Seed) { + use crypto::vrf::transcript::no_rng::VRFTranscript; + let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_regtest()); @@ -1791,6 +1813,7 @@ fn create_stake_pool_and_list_pool_ids(#[case] seed: Seed) { vrf_public_key: None, }, ) + .await .unwrap_err(); assert_eq!(err, WalletError::VrfKeyMustBeProvided); @@ -1808,8 +1831,10 @@ fn create_stake_pool_and_list_pool_ids(#[case] seed: Seed) { vrf_public_key: None, }, ) + .await .unwrap() .tx; + let stake_pool_transaction_id = stake_pool_transaction.transaction().get_id(); let (addr, block2) = create_block( &chain_config, @@ -1907,6 +1932,7 @@ fn create_stake_pool_and_list_pool_ids(#[case] seed: Seed) { None, FeeRate::from_amount_per_kb(Amount::from_atoms(0)), ) + .await .unwrap() .tx; @@ -1938,7 +1964,8 @@ fn create_stake_pool_and_list_pool_ids(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn create_stake_pool_for_different_wallet_and_list_pool_ids(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn create_stake_pool_for_different_wallet_and_list_pool_ids(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_regtest()); @@ -1996,6 +2023,7 @@ fn create_stake_pool_for_different_wallet_and_list_pool_ids(#[case] seed: Seed) vrf_public_key: Some(staker_vrf_public_key.clone()), }, ) + .await .unwrap_err(); assert_eq!(err, WalletError::StakerDestinationMustBePublicKey); @@ -2019,6 +2047,7 @@ fn create_stake_pool_for_different_wallet_and_list_pool_ids(#[case] seed: Seed) vrf_public_key: Some(staker_vrf_public_key.clone()), }, ) + .await .unwrap() .tx; let stake_pool_transaction_id = stake_pool_transaction.transaction().get_id(); @@ -2037,6 +2066,7 @@ fn create_stake_pool_for_different_wallet_and_list_pool_ids(#[case] seed: Seed) vrf_public_key: Some(staker_vrf_public_key.clone()), }, ) + .await .unwrap() .tx; let stake_pool_transaction_id2 = stake_pool_transaction2.transaction().get_id(); @@ -2178,6 +2208,7 @@ fn create_stake_pool_for_different_wallet_and_list_pool_ids(#[case] seed: Seed) None, FeeRate::from_amount_per_kb(Amount::from_atoms(0)), ) + .await .unwrap() .tx; @@ -2204,7 +2235,8 @@ fn create_stake_pool_for_different_wallet_and_list_pool_ids(#[case] seed: Seed) #[rstest] #[trace] #[case(Seed::from_entropy())] -fn reset_keys_after_failed_transaction(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn reset_keys_after_failed_transaction(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_mainnet()); @@ -2227,19 +2259,21 @@ fn reset_keys_after_failed_transaction(#[case] seed: Seed) { .unwrap() .last_issued(); - let result = wallet.create_stake_pool( - DEFAULT_ACCOUNT_INDEX, - FeeRate::from_amount_per_kb(Amount::ZERO), - FeeRate::from_amount_per_kb(Amount::ZERO), - StakePoolCreationArguments { - amount: not_enough, - margin_ratio_per_thousand: PerThousand::new_from_rng(&mut rng), - cost_per_block: Amount::ZERO, - decommission_key: Destination::AnyoneCanSpend, - staker_key: None, - vrf_public_key: None, - }, - ); + let result = wallet + .create_stake_pool( + DEFAULT_ACCOUNT_INDEX, + FeeRate::from_amount_per_kb(Amount::ZERO), + FeeRate::from_amount_per_kb(Amount::ZERO), + StakePoolCreationArguments { + amount: not_enough, + margin_ratio_per_thousand: PerThousand::new_from_rng(&mut rng), + cost_per_block: Amount::ZERO, + decommission_key: Destination::AnyoneCanSpend, + staker_key: None, + vrf_public_key: None, + }, + ) + .await; // check that result is an error and we last issued address is still the same assert!(result.is_err()); assert_eq!( @@ -2254,7 +2288,8 @@ fn reset_keys_after_failed_transaction(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn send_to_unknown_delegation(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn send_to_unknown_delegation(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_mainnet()); @@ -2319,6 +2354,7 @@ fn send_to_unknown_delegation(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -2353,6 +2389,7 @@ fn send_to_unknown_delegation(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; @@ -2394,6 +2431,7 @@ fn send_to_unknown_delegation(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -2419,7 +2457,8 @@ fn send_to_unknown_delegation(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn create_spend_from_delegations(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn create_spend_from_delegations(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_mainnet()); @@ -2455,6 +2494,7 @@ fn create_spend_from_delegations(#[case] seed: Seed) { vrf_public_key: None, }, ) + .await .unwrap() .tx; @@ -2483,6 +2523,7 @@ fn create_spend_from_delegations(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -2513,6 +2554,7 @@ fn create_spend_from_delegations(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; @@ -2533,6 +2575,7 @@ fn create_spend_from_delegations(#[case] seed: Seed) { Amount::from_atoms(2), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -2566,6 +2609,7 @@ fn create_spend_from_delegations(#[case] seed: Seed) { Amount::from_atoms(1), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; wallet @@ -2638,6 +2682,7 @@ fn create_spend_from_delegations(#[case] seed: Seed) { Amount::from_atoms(1), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; wallet @@ -2665,7 +2710,8 @@ fn create_spend_from_delegations(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn issue_and_transfer_tokens(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn issue_and_transfer_tokens(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_mainnet()); @@ -2739,6 +2785,7 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -2785,6 +2832,7 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; wallet @@ -2807,6 +2855,7 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -2834,6 +2883,7 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); random_issuing_wallet @@ -2853,6 +2903,7 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; (issued_token_id, vec![nft_issuance_transaction, transfer_tx]) @@ -2907,6 +2958,7 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info.clone(), ) + .await .unwrap() .tx; wallet @@ -2962,6 +3014,7 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) + .await .unwrap_err(); let remaining_tokens = (token_amount_to_issue - tokens_to_transfer).unwrap(); @@ -2984,7 +3037,8 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn check_tokens_v0_are_ignored(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn check_tokens_v0_are_ignored(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_regtest()); @@ -3006,25 +3060,27 @@ fn check_tokens_v0_are_ignored(#[case] seed: Seed) { let address2 = wallet.get_new_address(DEFAULT_ACCOUNT_INDEX).unwrap().1; let token_ticker = "XXXX".as_bytes().to_vec(); let number_of_decimals = rng.gen_range(1..18); - let result = wallet.create_transaction_to_addresses( - DEFAULT_ACCOUNT_INDEX, - [TxOutput::Transfer( - OutputValue::TokenV0(Box::new(TokenData::TokenIssuance(Box::new( - TokenIssuanceV0 { - token_ticker, - number_of_decimals, - metadata_uri: "http://uri".as_bytes().to_vec(), - amount_to_issue: Amount::from_atoms(rng.gen_range(1..10000)), - }, - )))), - address2.into_object(), - )], - SelectedInputs::Utxos(vec![]), - BTreeMap::new(), - FeeRate::from_amount_per_kb(Amount::ZERO), - FeeRate::from_amount_per_kb(Amount::ZERO), - TxAdditionalInfo::new(), - ); + let result = wallet + .create_transaction_to_addresses( + DEFAULT_ACCOUNT_INDEX, + [TxOutput::Transfer( + OutputValue::TokenV0(Box::new(TokenData::TokenIssuance(Box::new( + TokenIssuanceV0 { + token_ticker, + number_of_decimals, + metadata_uri: "http://uri".as_bytes().to_vec(), + amount_to_issue: Amount::from_atoms(rng.gen_range(1..10000)), + }, + )))), + address2.into_object(), + )], + SelectedInputs::Utxos(vec![]), + BTreeMap::new(), + FeeRate::from_amount_per_kb(Amount::ZERO), + FeeRate::from_amount_per_kb(Amount::ZERO), + TxAdditionalInfo::new(), + ) + .await; matches!( result.unwrap_err(), @@ -3042,7 +3098,8 @@ fn check_tokens_v0_are_ignored(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_regtest()); @@ -3079,6 +3136,7 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -3118,6 +3176,7 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -3135,6 +3194,7 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -3164,6 +3224,7 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -3236,6 +3297,7 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -3263,6 +3325,7 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) + .await .unwrap() .tx; @@ -3298,6 +3361,7 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap_err(); assert_eq!(err, WalletError::CannotFreezeAlreadyFrozenToken); @@ -3309,6 +3373,7 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap_err(); assert_eq!(err, WalletError::CannotUnfreezeToken); @@ -3347,7 +3412,8 @@ fn freeze_and_unfreeze_tokens(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn change_token_supply_fixed(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn change_token_supply_fixed(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_mainnet()); @@ -3383,6 +3449,7 @@ fn change_token_supply_fixed(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -3437,6 +3504,7 @@ fn change_token_supply_fixed(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -3459,6 +3527,7 @@ fn change_token_supply_fixed(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap_err(); assert_eq!( @@ -3537,6 +3606,7 @@ fn change_token_supply_fixed(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap_err(); assert_eq!( err, @@ -3553,6 +3623,7 @@ fn change_token_supply_fixed(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -3597,6 +3668,7 @@ fn change_token_supply_fixed(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap_err(); assert_eq!(err, WalletError::CannotLockTokenSupply("Fixed")); } @@ -3604,7 +3676,8 @@ fn change_token_supply_fixed(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn change_token_supply_unlimited(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn change_token_supply_unlimited(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_mainnet()); @@ -3639,6 +3712,7 @@ fn change_token_supply_unlimited(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -3694,6 +3768,7 @@ fn change_token_supply_unlimited(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -3735,6 +3810,7 @@ fn change_token_supply_unlimited(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap_err(); assert_eq!( err, @@ -3751,6 +3827,7 @@ fn change_token_supply_unlimited(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; wallet @@ -3794,6 +3871,7 @@ fn change_token_supply_unlimited(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap_err(); assert_eq!(err, WalletError::CannotLockTokenSupply("Unlimited")); } @@ -3801,7 +3879,8 @@ fn change_token_supply_unlimited(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn change_and_lock_token_supply_lockable(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn change_and_lock_token_supply_lockable(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_mainnet()); @@ -3836,6 +3915,7 @@ fn change_and_lock_token_supply_lockable(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -3891,6 +3971,7 @@ fn change_and_lock_token_supply_lockable(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; wallet.add_unconfirmed_tx(mint_transaction.clone(), &WalletEventsNoOp).unwrap(); @@ -3931,6 +4012,7 @@ fn change_and_lock_token_supply_lockable(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap_err(); assert_eq!( err, @@ -3947,6 +4029,7 @@ fn change_and_lock_token_supply_lockable(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -3988,6 +4071,7 @@ fn change_and_lock_token_supply_lockable(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -4028,6 +4112,7 @@ fn change_and_lock_token_supply_lockable(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap_err(); assert_eq!(err, WalletError::CannotChangeLockedTokenSupply); let err = wallet @@ -4038,6 +4123,7 @@ fn change_and_lock_token_supply_lockable(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap_err(); assert_eq!(err, WalletError::CannotChangeLockedTokenSupply); @@ -4048,6 +4134,7 @@ fn change_and_lock_token_supply_lockable(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap_err(); assert_eq!(err, WalletError::CannotLockTokenSupply("Locked")); } @@ -4055,7 +4142,8 @@ fn change_and_lock_token_supply_lockable(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn lock_then_transfer(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn lock_then_transfer(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_mainnet()); @@ -4125,6 +4213,7 @@ fn lock_then_transfer(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; wallet @@ -4199,7 +4288,8 @@ fn lock_then_transfer(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn wallet_multiple_transactions_in_single_block(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn wallet_multiple_transactions_in_single_block(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_mainnet()); @@ -4247,6 +4337,7 @@ fn wallet_multiple_transactions_in_single_block(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; wallet.add_unconfirmed_tx(transaction.clone(), &WalletEventsNoOp).unwrap(); @@ -4275,7 +4366,8 @@ fn wallet_multiple_transactions_in_single_block(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn wallet_scan_multiple_transactions_from_mempool(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn wallet_scan_multiple_transactions_from_mempool(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_mainnet()); @@ -4336,6 +4428,7 @@ fn wallet_scan_multiple_transactions_from_mempool(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; @@ -4372,6 +4465,7 @@ fn wallet_scan_multiple_transactions_from_mempool(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; wallet.add_unconfirmed_tx(transaction.clone(), &WalletEventsNoOp).unwrap(); @@ -4412,6 +4506,7 @@ fn wallet_scan_multiple_transactions_from_mempool(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap_err(); assert_eq!( err, @@ -4438,6 +4533,7 @@ fn wallet_scan_multiple_transactions_from_mempool(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; wallet.add_unconfirmed_tx(transaction.clone(), &WalletEventsNoOp).unwrap(); @@ -4461,7 +4557,8 @@ fn wallet_scan_multiple_transactions_from_mempool(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn wallet_abandon_transactions(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn wallet_abandon_transactions(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_mainnet()); @@ -4520,6 +4617,7 @@ fn wallet_abandon_transactions(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; wallet @@ -4713,7 +4811,8 @@ fn wallet_set_lookahead_size(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn decommission_pool_wrong_account(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn decommission_pool_wrong_account(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_regtest()); @@ -4756,6 +4855,7 @@ fn decommission_pool_wrong_account(#[case] seed: Seed) { vrf_public_key: None, }, ) + .await .unwrap() .tx; let _ = create_block( @@ -4771,13 +4871,15 @@ fn decommission_pool_wrong_account(#[case] seed: Seed) { // Try to decommission the pool with default account let pool_id = pool_ids.first().unwrap().0; - let decommission_cmd_res = wallet.decommission_stake_pool( - acc_0_index, - pool_id, - pool_amount, - None, - FeeRate::from_amount_per_kb(Amount::from_atoms(0)), - ); + let decommission_cmd_res = wallet + .decommission_stake_pool( + acc_0_index, + pool_id, + pool_amount, + None, + FeeRate::from_amount_per_kb(Amount::from_atoms(0)), + ) + .await; assert_eq!( decommission_cmd_res.unwrap_err(), WalletError::PartiallySignedTransactionInDecommissionCommand @@ -4792,6 +4894,7 @@ fn decommission_pool_wrong_account(#[case] seed: Seed) { None, FeeRate::from_amount_per_kb(Amount::from_atoms(0)), ) + .await .unwrap() .tx; @@ -4810,7 +4913,8 @@ fn decommission_pool_wrong_account(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn decommission_pool_request_wrong_account(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn decommission_pool_request_wrong_account(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_mainnet()); @@ -4853,6 +4957,7 @@ fn decommission_pool_request_wrong_account(#[case] seed: Seed) { vrf_public_key: None, }, ) + .await .unwrap() .tx; let _ = create_block( @@ -4868,13 +4973,15 @@ fn decommission_pool_request_wrong_account(#[case] seed: Seed) { // Try to create decommission request from account that holds the key let pool_id = pool_ids.first().unwrap().0; - let decommission_req_res = wallet.decommission_stake_pool_request( - acc_1_index, - pool_id, - pool_amount, - None, - FeeRate::from_amount_per_kb(Amount::from_atoms(0)), - ); + let decommission_req_res = wallet + .decommission_stake_pool_request( + acc_1_index, + pool_id, + pool_amount, + None, + FeeRate::from_amount_per_kb(Amount::from_atoms(0)), + ) + .await; assert_eq!( decommission_req_res.unwrap_err(), WalletError::FullySignedTransactionInDecommissionReq @@ -4888,6 +4995,7 @@ fn decommission_pool_request_wrong_account(#[case] seed: Seed) { None, FeeRate::from_amount_per_kb(Amount::from_atoms(0)), ) + .await .unwrap(); assert!(!decommission_partial_tx.all_signatures_available()); matches!( @@ -4899,7 +5007,8 @@ fn decommission_pool_request_wrong_account(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn sign_decommission_pool_request_between_accounts(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn sign_decommission_pool_request_between_accounts(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_regtest()); @@ -4943,6 +5052,7 @@ fn sign_decommission_pool_request_between_accounts(#[case] seed: Seed) { vrf_public_key: None, }, ) + .await .unwrap() .tx; @@ -4960,6 +5070,7 @@ fn sign_decommission_pool_request_between_accounts(#[case] seed: Seed) { .unwrap(); let stake_pool_transaction = wallet .sign_raw_transaction(acc_0_index, ptx) + .await .unwrap() .0 .into_signed_tx() @@ -4987,11 +5098,13 @@ fn sign_decommission_pool_request_between_accounts(#[case] seed: Seed) { None, FeeRate::from_amount_per_kb(Amount::from_atoms(0)), ) + .await .unwrap(); // Try to sign decommission request with wrong account let sign_from_acc0_res = wallet .sign_raw_transaction(acc_0_index, decommission_partial_tx.clone()) + .await .unwrap() .0; // the tx is still not fully signed @@ -4999,6 +5112,7 @@ fn sign_decommission_pool_request_between_accounts(#[case] seed: Seed) { let signed_tx = wallet .sign_raw_transaction(acc_1_index, decommission_partial_tx) + .await .unwrap() .0 .into_signed_tx() @@ -5014,7 +5128,8 @@ fn sign_decommission_pool_request_between_accounts(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn sign_decommission_pool_request_cold_wallet(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn sign_decommission_pool_request_cold_wallet(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_regtest()); @@ -5058,6 +5173,7 @@ fn sign_decommission_pool_request_cold_wallet(#[case] seed: Seed) { vrf_public_key: None, }, ) + .await .unwrap() .tx; let _ = create_block( @@ -5080,11 +5196,13 @@ fn sign_decommission_pool_request_cold_wallet(#[case] seed: Seed) { None, FeeRate::from_amount_per_kb(Amount::from_atoms(0)), ) + .await .unwrap(); // sign the tx with cold wallet let partially_signed_transaction = cold_wallet .sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, decommission_partial_tx) + .await .unwrap() .0; assert!(partially_signed_transaction.all_signatures_available()); @@ -5093,6 +5211,7 @@ fn sign_decommission_pool_request_cold_wallet(#[case] seed: Seed) { // destinations for the inputs let partially_signed_transaction = hot_wallet .sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, partially_signed_transaction) + .await .unwrap() .0; assert!(partially_signed_transaction.all_signatures_available()); @@ -5114,7 +5233,8 @@ fn sign_decommission_pool_request_cold_wallet(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn filter_pools(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn filter_pools(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_regtest()); @@ -5156,6 +5276,7 @@ fn filter_pools(#[case] seed: Seed) { vrf_public_key: None, }, ) + .await .unwrap() .tx; // sync for wallet1 @@ -5203,7 +5324,8 @@ fn filter_pools(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn sign_send_request_cold_wallet(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn sign_send_request_cold_wallet(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_regtest()); @@ -5258,6 +5380,7 @@ fn sign_send_request_cold_wallet(#[case] seed: Seed) { // Try to sign request with the hot wallet let tx = hot_wallet .sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, send_req.clone()) + .await .unwrap() .0; // the tx is not fully signed @@ -5266,6 +5389,7 @@ fn sign_send_request_cold_wallet(#[case] seed: Seed) { // sign the tx with cold wallet let signed_tx = cold_wallet .sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, send_req) + .await .unwrap() .0 .into_signed_tx() @@ -5314,7 +5438,8 @@ fn sign_send_request_cold_wallet(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn test_not_exhaustion_of_keys(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn test_not_exhaustion_of_keys(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_regtest()); @@ -5356,6 +5481,7 @@ fn test_not_exhaustion_of_keys(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap(); } } @@ -5416,7 +5542,8 @@ fn test_add_standalone_private_key(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn test_add_standalone_multisig(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn test_add_standalone_multisig(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_regtest()); @@ -5499,28 +5626,32 @@ fn test_add_standalone_multisig(#[case] seed: Seed) { .unwrap(); // sign it with wallet1 - let (ptx, _, statuses) = - wallet1.sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, spend_multisig_tx).unwrap(); + let (ptx, _, statuses) = wallet1 + .sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, spend_multisig_tx) + .await + .unwrap(); // check it is still not fully signed assert!(ptx.all_signatures_available()); assert!(!statuses.iter().all(|s| *s == SignatureStatus::FullySigned)); // try to sign it with wallet1 again - let (ptx, _, statuses) = wallet1.sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, ptx).unwrap(); + let (ptx, _, statuses) = + wallet1.sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, ptx).await.unwrap(); // check it is still not fully signed assert!(ptx.all_signatures_available()); assert!(!statuses.iter().all(|s| *s == SignatureStatus::FullySigned)); // try to sign it with wallet2 but wallet2 does not have the multisig added as standalone - let ptx = wallet2.sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, ptx).unwrap().0; + let ptx = wallet2.sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, ptx).await.unwrap().0; // add it to wallet2 as well wallet2.add_standalone_multisig(DEFAULT_ACCOUNT_INDEX, challenge, None).unwrap(); // now we can sign it - let (ptx, _, statuses) = wallet2.sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, ptx).unwrap(); + let (ptx, _, statuses) = + wallet2.sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, ptx).await.unwrap(); // now it is fully signed assert!(ptx.all_signatures_available()); @@ -5530,7 +5661,8 @@ fn test_add_standalone_multisig(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn create_htlc_and_spend(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn create_htlc_and_spend(#[case] seed: Seed) { use common::chain::htlc::HtlcSecret; let mut rng = make_seedable_rng(seed); @@ -5590,6 +5722,7 @@ fn create_htlc_and_spend(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; let create_htlc_tx_id = create_htlc_tx.transaction().get_id(); @@ -5653,7 +5786,7 @@ fn create_htlc_and_spend(#[case] seed: Seed) { .unwrap(); let (spend_ptx, _, new_statuses) = - wallet2.sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, spend_ptx).unwrap(); + wallet2.sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, spend_ptx).await.unwrap(); assert_eq!(vec![SignatureStatus::FullySigned], new_statuses); let spend_tx = spend_ptx.into_signed_tx().unwrap(); @@ -5669,7 +5802,8 @@ fn create_htlc_and_spend(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn create_htlc_and_refund(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn create_htlc_and_refund(#[case] seed: Seed) { use common::chain::htlc::HtlcSecret; let mut rng = make_seedable_rng(seed); @@ -5731,6 +5865,7 @@ fn create_htlc_and_refund(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; let create_htlc_tx_id = create_htlc_tx.transaction().get_id(); @@ -5785,7 +5920,7 @@ fn create_htlc_and_refund(#[case] seed: Seed) { assert_eq!(wallet2_multisig_utxos.len(), 1); let (refund_ptx, prev_statuses, new_statuses) = - wallet2.sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, refund_ptx).unwrap(); + wallet2.sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, refund_ptx).await.unwrap(); assert_eq!(vec![SignatureStatus::NotSigned], prev_statuses); assert_eq!( @@ -5797,7 +5932,7 @@ fn create_htlc_and_refund(#[case] seed: Seed) { ); let (refund_ptx, prev_statuses, new_statuses) = - wallet1.sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, refund_ptx).unwrap(); + wallet1.sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, refund_ptx).await.unwrap(); assert_eq!( vec![SignatureStatus::PartialMultisig { required_signatures: 2, @@ -5826,7 +5961,8 @@ fn create_htlc_and_refund(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn create_order(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn create_order(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_unit_test_config()); @@ -5857,6 +5993,7 @@ fn create_order(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -5897,6 +6034,7 @@ fn create_order(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -5936,6 +6074,7 @@ fn create_order(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -5955,7 +6094,8 @@ fn create_order(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn create_order_and_conclude(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn create_order_and_conclude(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_unit_test_config()); @@ -5986,6 +6126,7 @@ fn create_order_and_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -6026,6 +6167,7 @@ fn create_order_and_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -6065,6 +6207,7 @@ fn create_order_and_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); let order_info = RpcOrderInfo { @@ -6120,6 +6263,7 @@ fn create_order_and_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) + .await .unwrap() .tx; @@ -6142,7 +6286,8 @@ fn create_order_and_conclude(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn create_order_fill_completely_conclude(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn create_order_fill_completely_conclude(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_unit_test_config()); @@ -6175,6 +6320,7 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -6218,6 +6364,7 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -6268,6 +6415,7 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); let order_info = RpcOrderInfo { @@ -6340,6 +6488,7 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) + .await .unwrap() .tx; @@ -6415,6 +6564,7 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) + .await .unwrap() .tx; @@ -6482,6 +6632,7 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) + .await .unwrap() .tx; @@ -6515,7 +6666,8 @@ fn create_order_fill_completely_conclude(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn create_order_fill_partially_conclude(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn create_order_fill_partially_conclude(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_unit_test_config()); @@ -6548,6 +6700,7 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -6591,6 +6744,7 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -6641,6 +6795,7 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); let order_info = RpcOrderInfo { @@ -6713,6 +6868,7 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) + .await .unwrap() .tx; @@ -6787,6 +6943,7 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), additional_info, ) + .await .unwrap() .tx; @@ -6833,7 +6990,8 @@ fn create_order_fill_partially_conclude(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn conflicting_delegation_account_nonce(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn conflicting_delegation_account_nonce(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_unit_test_config()); @@ -6872,6 +7030,7 @@ fn conflicting_delegation_account_nonce(#[case] seed: Seed) { vrf_public_key: None, }, ) + .await .unwrap() .tx; @@ -6902,6 +7061,7 @@ fn conflicting_delegation_account_nonce(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -6934,6 +7094,7 @@ fn conflicting_delegation_account_nonce(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; @@ -6963,6 +7124,7 @@ fn conflicting_delegation_account_nonce(#[case] seed: Seed) { delegation_amount, FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; let spend_from_delegation_tx_1_id = spend_from_delegation_tx_1.transaction().get_id(); @@ -6985,6 +7147,7 @@ fn conflicting_delegation_account_nonce(#[case] seed: Seed) { delegation_amount, FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; let spend_from_delegation_tx_2_id = spend_from_delegation_tx_2.transaction().get_id(); @@ -7015,6 +7178,7 @@ fn conflicting_delegation_account_nonce(#[case] seed: Seed) { delegation_amount, FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; let spend_from_delegation_tx_3_id = spend_from_delegation_tx_3.transaction().get_id(); @@ -7128,7 +7292,8 @@ fn conflicting_delegation_account_nonce(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn conflicting_delegation_account_nonce_same_wallet(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn conflicting_delegation_account_nonce_same_wallet(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_unit_test_config()); @@ -7165,6 +7330,7 @@ fn conflicting_delegation_account_nonce_same_wallet(#[case] seed: Seed) { vrf_public_key: None, }, ) + .await .unwrap() .tx; @@ -7194,6 +7360,7 @@ fn conflicting_delegation_account_nonce_same_wallet(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -7225,6 +7392,7 @@ fn conflicting_delegation_account_nonce_same_wallet(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; @@ -7253,6 +7421,7 @@ fn conflicting_delegation_account_nonce_same_wallet(#[case] seed: Seed) { delegation_amount, FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -7275,6 +7444,7 @@ fn conflicting_delegation_account_nonce_same_wallet(#[case] seed: Seed) { delegation_amount, FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -7363,7 +7533,8 @@ fn conflicting_delegation_account_nonce_same_wallet(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn conflicting_order_account_nonce(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn conflicting_order_account_nonce(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = common::chain::config::create_unit_test_config_builder() .chainstate_upgrades( @@ -7399,6 +7570,7 @@ fn conflicting_order_account_nonce(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -7443,6 +7615,7 @@ fn conflicting_order_account_nonce(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; @@ -7470,6 +7643,7 @@ fn conflicting_order_account_nonce(#[case] seed: Seed) { TxAdditionalInfo::new() .with_token_info(issued_token_id, token_additional_info_for_ptx.clone()), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -7529,6 +7703,7 @@ fn conflicting_order_account_nonce(#[case] seed: Seed) { .with_order_info(order_id, order_additional_info_for_ptx.clone()) .with_token_info(issued_token_id, token_additional_info_for_ptx.clone()), ) + .await .unwrap() .tx; @@ -7561,6 +7736,7 @@ fn conflicting_order_account_nonce(#[case] seed: Seed) { .with_order_info(order_id, order_additional_info_for_ptx) .with_token_info(issued_token_id, token_additional_info_for_ptx), ) + .await .unwrap() .tx; @@ -7647,7 +7823,8 @@ fn conflicting_order_account_nonce(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn conflicting_delegation_account_nonce_multiple_inputs(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn conflicting_delegation_account_nonce_multiple_inputs(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_unit_test_config()); @@ -7686,6 +7863,7 @@ fn conflicting_delegation_account_nonce_multiple_inputs(#[case] seed: Seed) { vrf_public_key: None, }, ) + .await .unwrap() .tx; @@ -7716,6 +7894,7 @@ fn conflicting_delegation_account_nonce_multiple_inputs(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -7749,6 +7928,7 @@ fn conflicting_delegation_account_nonce_multiple_inputs(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; @@ -7800,6 +7980,7 @@ fn conflicting_delegation_account_nonce_multiple_inputs(#[case] seed: Seed) { let spend_from_delegation_signed_tx = wallet .sign_raw_transaction(DEFAULT_ACCOUNT_INDEX, spend_from_delegation_ptx) + .await .unwrap() .0 .into_signed_tx() @@ -7832,6 +8013,7 @@ fn conflicting_delegation_account_nonce_multiple_inputs(#[case] seed: Seed) { delegation_amount, FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; let spend_from_delegation_confirmed_tx_id = @@ -7922,7 +8104,8 @@ fn conflicting_delegation_account_nonce_multiple_inputs(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn conflicting_delegation_account_with_reorg(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn conflicting_delegation_account_with_reorg(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_unit_test_config()); @@ -7961,6 +8144,7 @@ fn conflicting_delegation_account_with_reorg(#[case] seed: Seed) { vrf_public_key: None, }, ) + .await .unwrap() .tx; @@ -7991,6 +8175,7 @@ fn conflicting_delegation_account_with_reorg(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -8023,6 +8208,7 @@ fn conflicting_delegation_account_with_reorg(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; @@ -8054,6 +8240,7 @@ fn conflicting_delegation_account_with_reorg(#[case] seed: Seed) { delegation_amount, FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; let spend_from_delegation_tx_id_1 = spend_from_delegation_tx_1.transaction().get_id(); @@ -8087,6 +8274,7 @@ fn conflicting_delegation_account_with_reorg(#[case] seed: Seed) { delegation_amount, FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .unwrap() .tx; let spend_from_delegation_tx_id_2 = spend_from_delegation_tx_2.transaction().get_id(); @@ -8154,7 +8342,8 @@ fn conflicting_delegation_account_with_reorg(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn rollback_utxos_after_abandon(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn rollback_utxos_after_abandon(#[case] seed: Seed) { let mut rng = make_seedable_rng(seed); let chain_config = Arc::new(create_mainnet()); @@ -8212,6 +8401,7 @@ fn rollback_utxos_after_abandon(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), TxAdditionalInfo::new(), ) + .await .unwrap() .tx; let tx_id = tx.transaction().get_id(); @@ -8266,7 +8456,8 @@ fn rollback_utxos_after_abandon(#[case] seed: Seed) { #[rstest] #[trace] #[case(Seed::from_entropy())] -fn token_id_generation_v1_uses_first_tx_input(#[case] seed: Seed) { +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn token_id_generation_v1_uses_first_tx_input(#[case] seed: Seed) { use common::chain::{self, TokenIdGenerationVersion}; let mut rng = make_seedable_rng(seed); @@ -8354,6 +8545,7 @@ fn token_id_generation_v1_uses_first_tx_input(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); @@ -8380,6 +8572,7 @@ fn token_id_generation_v1_uses_first_tx_input(#[case] seed: Seed) { FeeRate::from_amount_per_kb(Amount::ZERO), FeeRate::from_amount_per_kb(Amount::ZERO), ) + .await .map(|(id, tx)| (id, tx.tx)) .unwrap(); diff --git a/wallet/storage/src/internal/mod.rs b/wallet/storage/src/internal/mod.rs index e3b045e9c5..52849d7269 100644 --- a/wallet/storage/src/internal/mod.rs +++ b/wallet/storage/src/internal/mod.rs @@ -24,7 +24,10 @@ mod password; use password::{challenge_to_sym_key, password_to_sym_key}; mod store_tx; -pub use store_tx::{StoreTxRo, StoreTxRoUnlocked, StoreTxRw, StoreTxRwUnlocked}; +pub use store_tx::{ + StoreLocalReadOnlyUnlocked, StoreLocalReadWriteUnlocked, StoreTxRo, StoreTxRoUnlocked, + StoreTxRw, StoreTxRwUnlocked, +}; use self::store_tx::EncryptionState; @@ -151,6 +154,10 @@ impl Store { pub fn dump_raw(&self) -> crate::Result> { self.storage.transaction_ro()?.dump_raw().map_err(crate::Error::from) } + + pub fn local_rw_unlocked(&self) -> StoreLocalReadWriteUnlocked { + StoreLocalReadWriteUnlocked::new(self.clone()) + } } impl Clone for Store diff --git a/wallet/storage/src/internal/store_tx.rs b/wallet/storage/src/internal/store_tx.rs index 0f4b123bf4..a4492de96d 100644 --- a/wallet/storage/src/internal/store_tx.rs +++ b/wallet/storage/src/internal/store_tx.rs @@ -17,8 +17,9 @@ use std::collections::BTreeMap; use crate::{ schema::{self as db, Schema}, - WalletStorageEncryptionRead, WalletStorageEncryptionWrite, WalletStorageReadLocked, - WalletStorageReadUnlocked, WalletStorageWriteLocked, WalletStorageWriteUnlocked, + Transactional, WalletStorageEncryptionRead, WalletStorageEncryptionWrite, + WalletStorageReadLocked, WalletStorageReadUnlocked, WalletStorageWriteLocked, + WalletStorageWriteUnlocked, }; use common::{ address::Address, @@ -30,7 +31,7 @@ use crypto::{ symkey::SymmetricKey, }; use serialization::{Codec, DecodeAll, Encode, EncodeLike}; -use storage::{schema, MakeMapRef}; +use storage::{schema, Backend, MakeMapRef}; use utils::{ ensure, maybe_encrypted::{MaybeEncrypted, MaybeEncryptedError}, @@ -50,6 +51,7 @@ use wallet_types::{ use wallet_types::hw_data; +use super::Store; mod well_known { use common::chain::block::timestamp::BlockTimestamp; use crypto::kdf::KdfChallenge; @@ -158,6 +160,578 @@ impl<'st, B: storage::Backend> StoreTxRwUnlocked<'st, B> { } } +type TxOperation = dyn FnOnce(&mut StoreTxRw<'_, B>) -> crate::Result<()> + 'static + Send; + +/// A local read/write object, stores each write operation and performs them only at the end +/// Avoids references to avoid lifetime issues in async functions +pub struct StoreLocalReadWriteUnlocked { + operations: Vec>>, + local_read: Store, +} + +/// A wrapper around the store itself that opens a new read only transaction on each read operation +/// Can be used in async contexts +pub struct StoreLocalReadOnlyUnlocked { + local_read: Store, +} + +impl StoreLocalReadWriteUnlocked { + pub fn new(local_read: Store) -> Self { + Self { + operations: vec![], + local_read, + } + } + + pub fn add_operation(&mut self, op: Box>) { + self.operations.push(op); + } + + /// perform the local operations + pub fn perform_operations(self, dbtx: &mut StoreTxRw<'_, B>) -> crate::Result<()> { + for op in self.operations { + op(dbtx)?; + } + + Ok(()) + } + + pub fn read_only_store(&self) -> StoreLocalReadOnlyUnlocked { + StoreLocalReadOnlyUnlocked { + local_read: self.local_read.clone(), + } + } + + pub fn transaction_ro_unlocked(&self) -> crate::Result> { + self.local_read.transaction_ro_unlocked() + } +} + +impl WalletStorageReadLocked for StoreLocalReadWriteUnlocked { + fn get_storage_version(&self) -> crate::Result { + self.local_read.transaction_ro()?.get_storage_version() + } + + fn get_wallet_type(&self) -> crate::Result { + self.local_read.transaction_ro()?.get_wallet_type() + } + + fn get_chain_info(&self) -> crate::Result { + self.local_read.transaction_ro()?.get_chain_info() + } + + fn get_transaction(&self, id: &AccountWalletTxId) -> crate::Result> { + self.local_read.transaction_ro()?.get_transaction(id) + } + + fn get_accounts_info(&self) -> crate::Result> { + self.local_read.transaction_ro()?.get_accounts_info() + } + + fn get_address(&self, id: &AccountDerivationPathId) -> crate::Result> { + self.local_read.transaction_ro()?.get_address(id) + } + + fn get_addresses( + &self, + account_id: &AccountId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_addresses(account_id) + } + + fn check_root_keys_sanity(&self) -> crate::Result<()> { + self.local_read.transaction_ro()?.check_root_keys_sanity() + } + + /// Collect and return all transactions from the storage + fn get_transactions( + &self, + account_id: &AccountId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_transactions(account_id) + } + + /// Collect and return all signed transactions from the storage + fn get_user_transactions(&self) -> crate::Result> { + self.local_read.transaction_ro()?.get_user_transactions() + } + + fn get_account_unconfirmed_tx_counter( + &self, + account_id: &AccountId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_account_unconfirmed_tx_counter(account_id) + } + + fn get_account_vrf_public_keys( + &self, + account_id: &AccountId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_account_vrf_public_keys(account_id) + } + + fn get_account_standalone_watch_only_keys( + &self, + account_id: &AccountId, + ) -> crate::Result> { + self.local_read + .transaction_ro()? + .get_account_standalone_watch_only_keys(account_id) + } + fn get_account_standalone_multisig_keys( + &self, + account_id: &AccountId, + ) -> crate::Result> { + self.local_read + .transaction_ro()? + .get_account_standalone_multisig_keys(account_id) + } + + fn get_account_standalone_private_keys( + &self, + account_id: &AccountId, + ) -> crate::Result)>> { + self.local_read + .transaction_ro()? + .get_account_standalone_private_keys(account_id) + } + + fn get_keychain_usage_state( + &self, + id: &AccountKeyPurposeId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_keychain_usage_state(id) + } + + fn get_vrf_keychain_usage_state( + &self, + id: &AccountId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_vrf_keychain_usage_state(id) + } + + fn get_keychain_usage_states( + &self, + account_id: &AccountId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_keychain_usage_states(account_id) + } + + fn get_public_key( + &self, + id: &AccountDerivationPathId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_public_key(id) + } + + fn get_public_keys( + &self, + account_id: &AccountId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_public_keys(account_id) + } + + fn get_median_time(&self) -> crate::Result> { + self.local_read.transaction_ro()?.get_median_time() + } + + fn get_lookahead_size(&self) -> crate::Result { + self.local_read.transaction_ro()?.get_lookahead_size() + } + + fn get_hardware_wallet_data(&self) -> crate::Result> { + self.local_read.transaction_ro()?.get_hardware_wallet_data() + } +} + +impl WalletStorageReadUnlocked for StoreLocalReadWriteUnlocked { + fn get_root_key(&self) -> crate::Result> { + self.local_read.transaction_ro_unlocked()?.get_root_key() + } + fn get_seed_phrase(&self) -> crate::Result> { + self.local_read.transaction_ro_unlocked()?.get_seed_phrase() + } + + fn get_account_standalone_private_key( + &self, + account_pubkey: &AccountPublicKey, + ) -> crate::Result> { + self.local_read + .transaction_ro_unlocked()? + .get_account_standalone_private_key(account_pubkey) + } +} + +impl WalletStorageReadLocked for StoreLocalReadOnlyUnlocked { + fn get_storage_version(&self) -> crate::Result { + self.local_read.transaction_ro()?.get_storage_version() + } + + fn get_wallet_type(&self) -> crate::Result { + self.local_read.transaction_ro()?.get_wallet_type() + } + + fn get_chain_info(&self) -> crate::Result { + self.local_read.transaction_ro()?.get_chain_info() + } + + fn get_transaction(&self, id: &AccountWalletTxId) -> crate::Result> { + self.local_read.transaction_ro()?.get_transaction(id) + } + + fn get_accounts_info(&self) -> crate::Result> { + self.local_read.transaction_ro()?.get_accounts_info() + } + + fn get_address(&self, id: &AccountDerivationPathId) -> crate::Result> { + self.local_read.transaction_ro()?.get_address(id) + } + + fn get_addresses( + &self, + account_id: &AccountId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_addresses(account_id) + } + + fn check_root_keys_sanity(&self) -> crate::Result<()> { + self.local_read.transaction_ro()?.check_root_keys_sanity() + } + + /// Collect and return all transactions from the storage + fn get_transactions( + &self, + account_id: &AccountId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_transactions(account_id) + } + + /// Collect and return all signed transactions from the storage + fn get_user_transactions(&self) -> crate::Result> { + self.local_read.transaction_ro()?.get_user_transactions() + } + + fn get_account_unconfirmed_tx_counter( + &self, + account_id: &AccountId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_account_unconfirmed_tx_counter(account_id) + } + + fn get_account_vrf_public_keys( + &self, + account_id: &AccountId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_account_vrf_public_keys(account_id) + } + + fn get_account_standalone_watch_only_keys( + &self, + account_id: &AccountId, + ) -> crate::Result> { + self.local_read + .transaction_ro()? + .get_account_standalone_watch_only_keys(account_id) + } + fn get_account_standalone_multisig_keys( + &self, + account_id: &AccountId, + ) -> crate::Result> { + self.local_read + .transaction_ro()? + .get_account_standalone_multisig_keys(account_id) + } + + fn get_account_standalone_private_keys( + &self, + account_id: &AccountId, + ) -> crate::Result)>> { + self.local_read + .transaction_ro()? + .get_account_standalone_private_keys(account_id) + } + + fn get_keychain_usage_state( + &self, + id: &AccountKeyPurposeId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_keychain_usage_state(id) + } + + fn get_vrf_keychain_usage_state( + &self, + id: &AccountId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_vrf_keychain_usage_state(id) + } + + fn get_keychain_usage_states( + &self, + account_id: &AccountId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_keychain_usage_states(account_id) + } + + fn get_public_key( + &self, + id: &AccountDerivationPathId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_public_key(id) + } + + fn get_public_keys( + &self, + account_id: &AccountId, + ) -> crate::Result> { + self.local_read.transaction_ro()?.get_public_keys(account_id) + } + + fn get_median_time(&self) -> crate::Result> { + self.local_read.transaction_ro()?.get_median_time() + } + + fn get_lookahead_size(&self) -> crate::Result { + self.local_read.transaction_ro()?.get_lookahead_size() + } + + fn get_hardware_wallet_data(&self) -> crate::Result> { + self.local_read.transaction_ro()?.get_hardware_wallet_data() + } +} + +impl WalletStorageReadUnlocked for StoreLocalReadOnlyUnlocked { + fn get_root_key(&self) -> crate::Result> { + self.local_read.transaction_ro_unlocked()?.get_root_key() + } + fn get_seed_phrase(&self) -> crate::Result> { + self.local_read.transaction_ro_unlocked()?.get_seed_phrase() + } + + fn get_account_standalone_private_key( + &self, + account_pubkey: &AccountPublicKey, + ) -> crate::Result> { + self.local_read + .transaction_ro_unlocked()? + .get_account_standalone_private_key(account_pubkey) + } +} + +impl WalletStorageWriteLocked for StoreLocalReadWriteUnlocked { + fn set_storage_version(&mut self, version: u32) -> crate::Result<()> { + self.add_operation(Box::new(move |dbtx| dbtx.set_storage_version(version))); + Ok(()) + } + + fn set_wallet_type(&mut self, wallet_type: WalletType) -> crate::Result<()> { + self.add_operation(Box::new(move |dbtx| dbtx.set_wallet_type(wallet_type))); + Ok(()) + } + + fn set_chain_info(&mut self, chain_info: &ChainInfo) -> crate::Result<()> { + let chain_info = chain_info.clone(); + self.add_operation(Box::new(move |dbtx| dbtx.set_chain_info(&chain_info))); + Ok(()) + } + + fn set_transaction(&mut self, id: &AccountWalletTxId, tx: &WalletTx) -> crate::Result<()> { + let id = id.clone(); + let tx = tx.clone(); + self.add_operation(Box::new(move |dbtx| dbtx.set_transaction(&id, &tx))); + Ok(()) + } + + fn del_transaction(&mut self, id: &AccountWalletTxId) -> crate::Result<()> { + let id = id.clone(); + self.add_operation(Box::new(move |dbtx| dbtx.del_transaction(&id))); + Ok(()) + } + + fn clear_transactions(&mut self) -> crate::Result<()> { + self.add_operation(Box::new(|dbtx| dbtx.clear_transactions())); + Ok(()) + } + + fn clear_public_keys(&mut self) -> crate::Result<()> { + self.add_operation(Box::new(|dbtx| dbtx.clear_public_keys())); + Ok(()) + } + + fn clear_addresses(&mut self) -> crate::Result<()> { + self.add_operation(Box::new(|dbtx| dbtx.clear_addresses())); + Ok(()) + } + + fn set_account_unconfirmed_tx_counter( + &mut self, + id: &AccountId, + counter: u64, + ) -> crate::Result<()> { + let id = id.clone(); + self.add_operation(Box::new(move |dbtx| { + dbtx.set_account_unconfirmed_tx_counter(&id, counter) + })); + Ok(()) + } + + fn set_account_vrf_public_keys( + &mut self, + id: &AccountId, + account_vrf_keys: &AccountVrfKeys, + ) -> crate::Result<()> { + let id = id.clone(); + let account_vrf_keys = account_vrf_keys.clone(); + self.add_operation(Box::new(move |dbtx| { + dbtx.set_account_vrf_public_keys(&id, &account_vrf_keys) + })); + Ok(()) + } + + fn set_user_transaction( + &mut self, + id: &AccountWalletCreatedTxId, + tx: &SignedTransaction, + ) -> crate::Result<()> { + let id = id.clone(); + let tx = tx.clone(); + self.add_operation(Box::new(move |dbtx| dbtx.set_user_transaction(&id, &tx))); + Ok(()) + } + + fn del_user_transaction(&mut self, id: &AccountWalletCreatedTxId) -> crate::Result<()> { + let id = id.clone(); + self.add_operation(Box::new(move |dbtx| dbtx.del_user_transaction(&id))); + Ok(()) + } + + fn set_standalone_watch_only_key( + &mut self, + id: &AccountAddress, + key: &StandaloneWatchOnlyKey, + ) -> crate::Result<()> { + let id = id.clone(); + let key = key.clone(); + self.add_operation(Box::new(move |dbtx| { + dbtx.set_standalone_watch_only_key(&id, &key) + })); + Ok(()) + } + fn set_standalone_multisig_key( + &mut self, + id: &AccountAddress, + key: &StandaloneMultisig, + ) -> crate::Result<()> { + let id = id.clone(); + let key = key.clone(); + self.add_operation(Box::new(move |dbtx| { + dbtx.set_standalone_multisig_key(&id, &key) + })); + Ok(()) + } + + fn set_account(&mut self, id: &AccountId, tx: &AccountInfo) -> crate::Result<()> { + let id = id.clone(); + let tx = tx.clone(); + self.add_operation(Box::new(move |dbtx| dbtx.set_account(&id, &tx))); + Ok(()) + } + + fn del_account(&mut self, id: &AccountId) -> crate::Result<()> { + let id = id.clone(); + self.add_operation(Box::new(move |dbtx| dbtx.del_account(&id))); + Ok(()) + } + + fn set_address( + &mut self, + id: &AccountDerivationPathId, + address: &Address, + ) -> crate::Result<()> { + let id = id.clone(); + let address = address.clone(); + self.add_operation(Box::new(move |dbtx| dbtx.set_address(&id, &address))); + Ok(()) + } + + fn del_address(&mut self, id: &AccountDerivationPathId) -> crate::Result<()> { + let id = id.clone(); + self.add_operation(Box::new(move |dbtx| dbtx.del_address(&id))); + Ok(()) + } + + fn set_keychain_usage_state( + &mut self, + id: &AccountKeyPurposeId, + usage_state: &KeychainUsageState, + ) -> crate::Result<()> { + let id = id.clone(); + let usage_state = usage_state.clone(); + self.add_operation(Box::new(move |dbtx| { + dbtx.set_keychain_usage_state(&id, &usage_state) + })); + Ok(()) + } + + fn set_vrf_keychain_usage_state( + &mut self, + id: &AccountId, + usage_state: &KeychainUsageState, + ) -> crate::Result<()> { + let id = id.clone(); + let usage_state = usage_state.clone(); + self.add_operation(Box::new(move |dbtx| { + dbtx.set_vrf_keychain_usage_state(&id, &usage_state) + })); + Ok(()) + } + + fn del_keychain_usage_state(&mut self, id: &AccountKeyPurposeId) -> crate::Result<()> { + let id = id.clone(); + self.add_operation(Box::new(move |dbtx| dbtx.del_keychain_usage_state(&id))); + Ok(()) + } + + fn del_vrf_keychain_usage_state(&mut self, id: &AccountId) -> crate::Result<()> { + let id = id.clone(); + self.add_operation(Box::new(move |dbtx| dbtx.del_vrf_keychain_usage_state(&id))); + Ok(()) + } + + fn set_public_key( + &mut self, + id: &AccountDerivationPathId, + pub_key: &ExtendedPublicKey, + ) -> crate::Result<()> { + let id = id.clone(); + let pub_key = pub_key.clone(); + self.add_operation(Box::new(move |dbtx| dbtx.set_public_key(&id, &pub_key))); + Ok(()) + } + + fn del_public_key(&mut self, id: &AccountDerivationPathId) -> crate::Result<()> { + let id = id.clone(); + self.add_operation(Box::new(move |dbtx| dbtx.del_public_key(&id))); + Ok(()) + } + + fn set_median_time(&mut self, median_time: BlockTimestamp) -> crate::Result<()> { + self.add_operation(Box::new(move |dbtx| dbtx.set_median_time(median_time))); + Ok(()) + } + + fn set_lookahead_size(&mut self, lookahead_size: u32) -> crate::Result<()> { + self.add_operation(Box::new(move |dbtx| { + dbtx.set_lookahead_size(lookahead_size) + })); + Ok(()) + } + + fn set_hardware_wallet_data(&mut self, data: hw_data::HardwareWalletData) -> crate::Result<()> { + self.add_operation(Box::new(move |dbtx| dbtx.set_hardware_wallet_data(data))); + Ok(()) + } +} + macro_rules! impl_read_ops { ($TxType:ident) => { /// Wallet data storage transaction @@ -600,7 +1174,7 @@ macro_rules! impl_write_ops { self.write::(id, pub_key) } - fn det_public_key(&mut self, id: &AccountDerivationPathId) -> crate::Result<()> { + fn del_public_key(&mut self, id: &AccountDerivationPathId) -> crate::Result<()> { self.storage.get_mut::().del(id).map_err(Into::into) } @@ -772,3 +1346,4 @@ impl crate::IsTransaction for StoreTxRo<'_, B> {} impl crate::IsTransaction for StoreTxRw<'_, B> {} impl crate::IsTransaction for StoreTxRoUnlocked<'_, B> {} impl crate::IsTransaction for StoreTxRwUnlocked<'_, B> {} +impl crate::IsTransaction for StoreLocalReadWriteUnlocked {} diff --git a/wallet/storage/src/is_transaction_seal.rs b/wallet/storage/src/is_transaction_seal.rs index d95f54e7f6..45ab48bce9 100644 --- a/wallet/storage/src/is_transaction_seal.rs +++ b/wallet/storage/src/is_transaction_seal.rs @@ -20,3 +20,4 @@ impl Seal for crate::internal::StoreTxRo<'_, B> {} impl Seal for crate::internal::StoreTxRw<'_, B> {} impl Seal for crate::internal::StoreTxRoUnlocked<'_, B> {} impl Seal for crate::internal::StoreTxRwUnlocked<'_, B> {} +impl Seal for crate::internal::StoreLocalReadWriteUnlocked {} diff --git a/wallet/storage/src/lib.rs b/wallet/storage/src/lib.rs index b1cf8bb69f..ac4465c005 100644 --- a/wallet/storage/src/lib.rs +++ b/wallet/storage/src/lib.rs @@ -28,7 +28,10 @@ use crypto::{ key::{extended::ExtendedPublicKey, PrivateKey}, symkey::SymmetricKey, }; -pub use internal::{Store, StoreTxRo, StoreTxRoUnlocked, StoreTxRw, StoreTxRwUnlocked}; +pub use internal::{ + Store, StoreLocalReadOnlyUnlocked, StoreLocalReadWriteUnlocked, StoreTxRo, StoreTxRoUnlocked, + StoreTxRw, StoreTxRwUnlocked, +}; use std::collections::BTreeMap; use wallet_types::{ @@ -194,7 +197,7 @@ pub trait WalletStorageWriteLocked: WalletStorageReadLocked { id: &AccountDerivationPathId, content: &ExtendedPublicKey, ) -> Result<()>; - fn det_public_key(&mut self, id: &AccountDerivationPathId) -> Result<()>; + fn del_public_key(&mut self, id: &AccountDerivationPathId) -> Result<()>; fn set_median_time(&mut self, median_time: BlockTimestamp) -> Result<()>; fn set_lookahead_size(&mut self, lookahead_size: u32) -> Result<()>; fn clear_public_keys(&mut self) -> Result<()>; diff --git a/wallet/wallet-controller/src/runtime_wallet.rs b/wallet/wallet-controller/src/runtime_wallet.rs index d8ffb12874..a336094421 100644 --- a/wallet/wallet-controller/src/runtime_wallet.rs +++ b/wallet/wallet-controller/src/runtime_wallet.rs @@ -622,7 +622,7 @@ impl RuntimeWallet { } } - pub fn issue_new_token( + pub async fn issue_new_token( &mut self, account_index: U31, token_issuance: TokenIssuance, @@ -630,23 +630,29 @@ impl RuntimeWallet { consolidate_fee_rate: FeeRate, ) -> WalletResult<(TokenId, SignedTxWithFees)> { match self { - RuntimeWallet::Software(w) => w.issue_new_token( - account_index, - token_issuance, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Software(w) => { + w.issue_new_token( + account_index, + token_issuance, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.issue_new_token( - account_index, - token_issuance, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Trezor(w) => { + w.issue_new_token( + account_index, + token_issuance, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } } } - pub fn issue_new_nft( + pub async fn issue_new_nft( &mut self, account_index: U31, address: Address, @@ -655,212 +661,260 @@ impl RuntimeWallet { consolidate_fee_rate: FeeRate, ) -> WalletResult<(TokenId, SignedTxWithFees)> { match self { - RuntimeWallet::Software(w) => w.issue_new_nft( - account_index, - address, - metadata, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Software(w) => { + w.issue_new_nft( + account_index, + address, + metadata, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.issue_new_nft( - account_index, - address, - metadata, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Trezor(w) => { + w.issue_new_nft( + account_index, + address, + metadata, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } } } - pub fn mint_tokens( + pub async fn mint_tokens( &mut self, account_index: U31, - token_info: &UnconfirmedTokenInfo, + token_info: UnconfirmedTokenInfo, amount: Amount, address: Address, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, ) -> Result { match self { - RuntimeWallet::Software(w) => w.mint_tokens( - account_index, - token_info, - amount, - address, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Software(w) => { + w.mint_tokens( + account_index, + &token_info, + amount, + address, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.mint_tokens( - account_index, - token_info, - amount, - address, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Trezor(w) => { + w.mint_tokens( + account_index, + &token_info, + amount, + address, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } } } - pub fn unmint_tokens( + pub async fn unmint_tokens( &mut self, account_index: U31, - token_info: &UnconfirmedTokenInfo, + token_info: UnconfirmedTokenInfo, amount: Amount, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, ) -> Result { match self { - RuntimeWallet::Software(w) => w.unmint_tokens( - account_index, - token_info, - amount, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Software(w) => { + w.unmint_tokens( + account_index, + &token_info, + amount, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.unmint_tokens( - account_index, - token_info, - amount, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Trezor(w) => { + w.unmint_tokens( + account_index, + &token_info, + amount, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } } } - pub fn lock_token_supply( + pub async fn lock_token_supply( &mut self, account_index: U31, - token_info: &UnconfirmedTokenInfo, + token_info: UnconfirmedTokenInfo, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, ) -> Result { match self { - RuntimeWallet::Software(w) => w.lock_token_supply( - account_index, - token_info, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Software(w) => { + w.lock_token_supply( + account_index, + &token_info, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.lock_token_supply( - account_index, - token_info, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Trezor(w) => { + w.lock_token_supply( + account_index, + &token_info, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } } } - pub fn freeze_token( + pub async fn freeze_token( &mut self, account_index: U31, - token_info: &UnconfirmedTokenInfo, + token_info: UnconfirmedTokenInfo, is_token_unfreezable: IsTokenUnfreezable, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, ) -> Result { match self { - RuntimeWallet::Software(w) => w.freeze_token( - account_index, - token_info, - is_token_unfreezable, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Software(w) => { + w.freeze_token( + account_index, + &token_info, + is_token_unfreezable, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.freeze_token( - account_index, - token_info, - is_token_unfreezable, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Trezor(w) => { + w.freeze_token( + account_index, + &token_info, + is_token_unfreezable, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } } } - pub fn unfreeze_token( + pub async fn unfreeze_token( &mut self, account_index: U31, - token_info: &UnconfirmedTokenInfo, + token_info: UnconfirmedTokenInfo, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, ) -> Result { match self { - RuntimeWallet::Software(w) => w.unfreeze_token( - account_index, - token_info, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Software(w) => { + w.unfreeze_token( + account_index, + &token_info, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.unfreeze_token( - account_index, - token_info, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Trezor(w) => { + w.unfreeze_token( + account_index, + &token_info, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } } } - pub fn change_token_authority( + pub async fn change_token_authority( &mut self, account_index: U31, - token_info: &UnconfirmedTokenInfo, + token_info: UnconfirmedTokenInfo, address: Address, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, ) -> Result { match self { - RuntimeWallet::Software(w) => w.change_token_authority( - account_index, - token_info, - address, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Software(w) => { + w.change_token_authority( + account_index, + &token_info, + address, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.change_token_authority( - account_index, - token_info, - address, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Trezor(w) => { + w.change_token_authority( + account_index, + &token_info, + address, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } } } - pub fn change_token_metadata_uri( + pub async fn change_token_metadata_uri( &mut self, account_index: U31, - token_info: &UnconfirmedTokenInfo, + token_info: UnconfirmedTokenInfo, metadata_uri: Vec, current_fee_rate: FeeRate, consolidate_fee_rate: FeeRate, ) -> Result { match self { - RuntimeWallet::Software(w) => w.change_token_metadata_uri( - account_index, - token_info, - metadata_uri, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Software(w) => { + w.change_token_metadata_uri( + account_index, + &token_info, + metadata_uri, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.change_token_metadata_uri( - account_index, - token_info, - metadata_uri, - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Trezor(w) => { + w.change_token_metadata_uri( + account_index, + &token_info, + metadata_uri, + current_fee_rate, + consolidate_fee_rate, + ) + .await + } } } #[allow(clippy::too_many_arguments)] - pub fn create_transaction_to_addresses( + pub async fn create_transaction_to_addresses( &mut self, account_index: U31, outputs: impl IntoIterator, @@ -871,29 +925,35 @@ impl RuntimeWallet { additional_info: TxAdditionalInfo, ) -> WalletResult { match self { - RuntimeWallet::Software(w) => w.create_transaction_to_addresses( - account_index, - outputs, - inputs, - change_addresses, - current_fee_rate, - consolidate_fee_rate, - additional_info, - ), + RuntimeWallet::Software(w) => { + w.create_transaction_to_addresses( + account_index, + outputs, + inputs, + change_addresses, + current_fee_rate, + consolidate_fee_rate, + additional_info, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.create_transaction_to_addresses( - account_index, - outputs, - inputs, - change_addresses, - current_fee_rate, - consolidate_fee_rate, - additional_info, - ), + RuntimeWallet::Trezor(w) => { + w.create_transaction_to_addresses( + account_index, + outputs, + inputs, + change_addresses, + current_fee_rate, + consolidate_fee_rate, + additional_info, + ) + .await + } } } - pub fn create_sweep_transaction( + pub async fn create_sweep_transaction( &mut self, account_index: U31, destination_address: Destination, @@ -902,21 +962,27 @@ impl RuntimeWallet { additional_info: TxAdditionalInfo, ) -> WalletResult { match self { - RuntimeWallet::Software(w) => w.create_sweep_transaction( - account_index, - destination_address, - filtered_inputs, - current_fee_rate, - additional_info, - ), + RuntimeWallet::Software(w) => { + w.create_sweep_transaction( + account_index, + destination_address, + filtered_inputs, + current_fee_rate, + additional_info, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.create_sweep_transaction( - account_index, - destination_address, - filtered_inputs, - current_fee_rate, - additional_info, - ), + RuntimeWallet::Trezor(w) => { + w.create_sweep_transaction( + account_index, + destination_address, + filtered_inputs, + current_fee_rate, + additional_info, + ) + .await + } } } @@ -932,7 +998,7 @@ impl RuntimeWallet { } } - pub fn create_sweep_from_delegation_transaction( + pub async fn create_sweep_from_delegation_transaction( &mut self, account_index: U31, destination_address: Address, @@ -941,21 +1007,27 @@ impl RuntimeWallet { current_fee_rate: FeeRate, ) -> WalletResult { match self { - RuntimeWallet::Software(w) => w.create_sweep_from_delegation_transaction( - account_index, - destination_address, - delegation_id, - delegation_share, - current_fee_rate, - ), + RuntimeWallet::Software(w) => { + w.create_sweep_from_delegation_transaction( + account_index, + destination_address, + delegation_id, + delegation_share, + current_fee_rate, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.create_sweep_from_delegation_transaction( - account_index, - destination_address, - delegation_id, - delegation_share, - current_fee_rate, - ), + RuntimeWallet::Trezor(w) => { + w.create_sweep_from_delegation_transaction( + account_index, + destination_address, + delegation_id, + delegation_share, + current_fee_rate, + ) + .await + } } } @@ -996,7 +1068,7 @@ impl RuntimeWallet { } } - pub fn create_delegation( + pub async fn create_delegation( &mut self, account_index: U31, output: TxOutput, @@ -1004,23 +1076,29 @@ impl RuntimeWallet { consolidate_fee_rate: FeeRate, ) -> WalletResult<(DelegationId, SignedTxWithFees)> { match self { - RuntimeWallet::Software(w) => w.create_delegation( - account_index, - vec![output], - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Software(w) => { + w.create_delegation( + account_index, + vec![output], + current_fee_rate, + consolidate_fee_rate, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.create_delegation( - account_index, - vec![output], - current_fee_rate, - consolidate_fee_rate, - ), + RuntimeWallet::Trezor(w) => { + w.create_delegation( + account_index, + vec![output], + current_fee_rate, + consolidate_fee_rate, + ) + .await + } } } - pub fn create_transaction_to_addresses_from_delegation( + pub async fn create_transaction_to_addresses_from_delegation( &mut self, account_index: U31, address: Address, @@ -1030,27 +1108,33 @@ impl RuntimeWallet { current_fee_rate: FeeRate, ) -> WalletResult { match self { - RuntimeWallet::Software(w) => w.create_transaction_to_addresses_from_delegation( - account_index, - address, - amount, - delegation_id, - delegation_share, - current_fee_rate, - ), + RuntimeWallet::Software(w) => { + w.create_transaction_to_addresses_from_delegation( + account_index, + address, + amount, + delegation_id, + delegation_share, + current_fee_rate, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.create_transaction_to_addresses_from_delegation( - account_index, - address, - amount, - delegation_id, - delegation_share, - current_fee_rate, - ), + RuntimeWallet::Trezor(w) => { + w.create_transaction_to_addresses_from_delegation( + account_index, + address, + amount, + delegation_id, + delegation_share, + current_fee_rate, + ) + .await + } } } - pub fn create_stake_pool( + pub async fn create_stake_pool( &mut self, account_index: U31, current_fee_rate: FeeRate, @@ -1058,23 +1142,29 @@ impl RuntimeWallet { stake_pool_arguments: StakePoolCreationArguments, ) -> WalletResult { match self { - RuntimeWallet::Software(w) => w.create_stake_pool( - account_index, - current_fee_rate, - consolidate_fee_rate, - stake_pool_arguments, - ), + RuntimeWallet::Software(w) => { + w.create_stake_pool( + account_index, + current_fee_rate, + consolidate_fee_rate, + stake_pool_arguments, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.create_stake_pool_with_vrf_key( - account_index, - current_fee_rate, - consolidate_fee_rate, - stake_pool_arguments, - ), + RuntimeWallet::Trezor(w) => { + w.create_stake_pool_with_vrf_key( + account_index, + current_fee_rate, + consolidate_fee_rate, + stake_pool_arguments, + ) + .await + } } } - pub fn decommission_stake_pool( + pub async fn decommission_stake_pool( &mut self, account_index: U31, pool_id: PoolId, @@ -1083,25 +1173,31 @@ impl RuntimeWallet { current_fee_rate: FeeRate, ) -> WalletResult { match self { - RuntimeWallet::Software(w) => w.decommission_stake_pool( - account_index, - pool_id, - staker_balance, - output_address, - current_fee_rate, - ), + RuntimeWallet::Software(w) => { + w.decommission_stake_pool( + account_index, + pool_id, + staker_balance, + output_address, + current_fee_rate, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.decommission_stake_pool( - account_index, - pool_id, - staker_balance, - output_address, - current_fee_rate, - ), + RuntimeWallet::Trezor(w) => { + w.decommission_stake_pool( + account_index, + pool_id, + staker_balance, + output_address, + current_fee_rate, + ) + .await + } } } - pub fn decommission_stake_pool_request( + pub async fn decommission_stake_pool_request( &mut self, account_index: U31, pool_id: PoolId, @@ -1110,25 +1206,31 @@ impl RuntimeWallet { current_fee_rate: FeeRate, ) -> WalletResult { match self { - RuntimeWallet::Software(w) => w.decommission_stake_pool_request( - account_index, - pool_id, - staker_balance, - output_address, - current_fee_rate, - ), + RuntimeWallet::Software(w) => { + w.decommission_stake_pool_request( + account_index, + pool_id, + staker_balance, + output_address, + current_fee_rate, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.decommission_stake_pool_request( - account_index, - pool_id, - staker_balance, - output_address, - current_fee_rate, - ), + RuntimeWallet::Trezor(w) => { + w.decommission_stake_pool_request( + account_index, + pool_id, + staker_balance, + output_address, + current_fee_rate, + ) + .await + } } } - pub fn create_htlc_tx( + pub async fn create_htlc_tx( &mut self, account_index: U31, output_value: OutputValue, @@ -1138,28 +1240,34 @@ impl RuntimeWallet { additional_info: TxAdditionalInfo, ) -> WalletResult { match self { - RuntimeWallet::Software(w) => w.create_htlc_tx( - account_index, - output_value, - htlc, - current_fee_rate, - consolidate_fee_rate, - additional_info, - ), + RuntimeWallet::Software(w) => { + w.create_htlc_tx( + account_index, + output_value, + htlc, + current_fee_rate, + consolidate_fee_rate, + additional_info, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.create_htlc_tx( - account_index, - output_value, - htlc, - current_fee_rate, - consolidate_fee_rate, - additional_info, - ), + RuntimeWallet::Trezor(w) => { + w.create_htlc_tx( + account_index, + output_value, + htlc, + current_fee_rate, + consolidate_fee_rate, + additional_info, + ) + .await + } } } #[allow(clippy::too_many_arguments)] - pub fn create_order_tx( + pub async fn create_order_tx( &mut self, account_index: U31, ask_value: OutputValue, @@ -1170,30 +1278,36 @@ impl RuntimeWallet { additional_info: TxAdditionalInfo, ) -> WalletResult<(OrderId, SignedTxWithFees)> { match self { - RuntimeWallet::Software(w) => w.create_order_tx( - account_index, - ask_value, - give_value, - conclude_key, - current_fee_rate, - consolidate_fee_rate, - additional_info, - ), + RuntimeWallet::Software(w) => { + w.create_order_tx( + account_index, + ask_value, + give_value, + conclude_key, + current_fee_rate, + consolidate_fee_rate, + additional_info, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.create_order_tx( - account_index, - ask_value, - give_value, - conclude_key, - current_fee_rate, - consolidate_fee_rate, - additional_info, - ), + RuntimeWallet::Trezor(w) => { + w.create_order_tx( + account_index, + ask_value, + give_value, + conclude_key, + current_fee_rate, + consolidate_fee_rate, + additional_info, + ) + .await + } } } #[allow(clippy::too_many_arguments)] - pub fn create_conclude_order_tx( + pub async fn create_conclude_order_tx( &mut self, account_index: U31, order_id: OrderId, @@ -1204,30 +1318,36 @@ impl RuntimeWallet { additional_info: TxAdditionalInfo, ) -> WalletResult { match self { - RuntimeWallet::Software(w) => w.create_conclude_order_tx( - account_index, - order_id, - order_info, - output_address, - current_fee_rate, - consolidate_fee_rate, - additional_info, - ), + RuntimeWallet::Software(w) => { + w.create_conclude_order_tx( + account_index, + order_id, + order_info, + output_address, + current_fee_rate, + consolidate_fee_rate, + additional_info, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.create_conclude_order_tx( - account_index, - order_id, - order_info, - output_address, - current_fee_rate, - consolidate_fee_rate, - additional_info, - ), + RuntimeWallet::Trezor(w) => { + w.create_conclude_order_tx( + account_index, + order_id, + order_info, + output_address, + current_fee_rate, + consolidate_fee_rate, + additional_info, + ) + .await + } } } #[allow(clippy::too_many_arguments)] - pub fn create_fill_order_tx( + pub async fn create_fill_order_tx( &mut self, account_index: U31, order_id: OrderId, @@ -1239,31 +1359,37 @@ impl RuntimeWallet { additional_info: TxAdditionalInfo, ) -> WalletResult { match self { - RuntimeWallet::Software(w) => w.create_fill_order_tx( - account_index, - order_id, - order_info, - fill_amount_in_ask_currency, - output_address, - current_fee_rate, - consolidate_fee_rate, - additional_info, - ), + RuntimeWallet::Software(w) => { + w.create_fill_order_tx( + account_index, + order_id, + order_info, + fill_amount_in_ask_currency, + output_address, + current_fee_rate, + consolidate_fee_rate, + additional_info, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.create_fill_order_tx( - account_index, - order_id, - order_info, - fill_amount_in_ask_currency, - output_address, - current_fee_rate, - consolidate_fee_rate, - additional_info, - ), + RuntimeWallet::Trezor(w) => { + w.create_fill_order_tx( + account_index, + order_id, + order_info, + fill_amount_in_ask_currency, + output_address, + current_fee_rate, + consolidate_fee_rate, + additional_info, + ) + .await + } } } - pub fn create_freeze_order_tx( + pub async fn create_freeze_order_tx( &mut self, account_index: U31, order_id: OrderId, @@ -1273,27 +1399,33 @@ impl RuntimeWallet { additional_info: TxAdditionalInfo, ) -> WalletResult { match self { - RuntimeWallet::Software(w) => w.create_freeze_order_tx( - account_index, - order_id, - order_info, - current_fee_rate, - consolidate_fee_rate, - additional_info, - ), + RuntimeWallet::Software(w) => { + w.create_freeze_order_tx( + account_index, + order_id, + order_info, + current_fee_rate, + consolidate_fee_rate, + additional_info, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.create_freeze_order_tx( - account_index, - order_id, - order_info, - current_fee_rate, - consolidate_fee_rate, - additional_info, - ), + RuntimeWallet::Trezor(w) => { + w.create_freeze_order_tx( + account_index, + order_id, + order_info, + current_fee_rate, + consolidate_fee_rate, + additional_info, + ) + .await + } } } - pub fn sign_raw_transaction( + pub async fn sign_raw_transaction( &mut self, account_index: U31, ptx: PartiallySignedTransaction, @@ -1303,27 +1435,31 @@ impl RuntimeWallet { Vec, )> { match self { - RuntimeWallet::Software(w) => w.sign_raw_transaction(account_index, ptx), + RuntimeWallet::Software(w) => w.sign_raw_transaction(account_index, ptx).await, #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.sign_raw_transaction(account_index, ptx), + RuntimeWallet::Trezor(w) => w.sign_raw_transaction(account_index, ptx).await, } } - pub fn sign_challenge( + pub async fn sign_challenge( &mut self, account_index: U31, challenge: &[u8], destination: &Destination, ) -> WalletResult { match self { - RuntimeWallet::Software(w) => w.sign_challenge(account_index, challenge, destination), + RuntimeWallet::Software(w) => { + w.sign_challenge(account_index, challenge, destination).await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.sign_challenge(account_index, challenge, destination), + RuntimeWallet::Trezor(w) => { + w.sign_challenge(account_index, challenge, destination).await + } } } #[allow(clippy::too_many_arguments)] - pub fn create_transaction_to_addresses_with_intent( + pub async fn create_transaction_to_addresses_with_intent( &mut self, account_index: U31, outputs: impl IntoIterator, @@ -1335,27 +1471,33 @@ impl RuntimeWallet { additional_info: TxAdditionalInfo, ) -> WalletResult<(SignedTxWithFees, SignedTransactionIntent)> { match self { - RuntimeWallet::Software(w) => w.create_transaction_to_addresses_with_intent( - account_index, - outputs, - inputs, - change_addresses, - intent, - current_fee_rate, - consolidate_fee_rate, - additional_info, - ), + RuntimeWallet::Software(w) => { + w.create_transaction_to_addresses_with_intent( + account_index, + outputs, + inputs, + change_addresses, + intent, + current_fee_rate, + consolidate_fee_rate, + additional_info, + ) + .await + } #[cfg(feature = "trezor")] - RuntimeWallet::Trezor(w) => w.create_transaction_to_addresses_with_intent( - account_index, - outputs, - inputs, - change_addresses, - intent, - current_fee_rate, - consolidate_fee_rate, - additional_info, - ), + RuntimeWallet::Trezor(w) => { + w.create_transaction_to_addresses_with_intent( + account_index, + outputs, + inputs, + change_addresses, + intent, + current_fee_rate, + consolidate_fee_rate, + additional_info, + ) + .await + } } } diff --git a/wallet/wallet-controller/src/synced_controller.rs b/wallet/wallet-controller/src/synced_controller.rs index 5e8a2fcd82..2fb3d42b6a 100644 --- a/wallet/wallet-controller/src/synced_controller.rs +++ b/wallet/wallet-controller/src/synced_controller.rs @@ -295,23 +295,25 @@ where is_freezable: IsTokenFreezable, ) -> Result<(NewTransaction, TokenId), ControllerError> { self.create_and_send_tx_with_id( - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31| { - wallet.issue_new_token( - account_index, - TokenIssuance::V1(TokenIssuanceV1 { - token_ticker, - number_of_decimals, - metadata_uri, - total_supply: token_total_supply, - authority: address.into_object(), - is_freezable, - }), - current_fee_rate, - consolidate_fee_rate, - ) + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31| { + wallet + .issue_new_token( + account_index, + TokenIssuance::V1(TokenIssuanceV1 { + token_ticker, + number_of_decimals, + metadata_uri, + total_supply: token_total_supply, + authority: address.into_object(), + is_freezable, + }), + current_fee_rate, + consolidate_fee_rate, + ) + .await }, ) .await @@ -323,17 +325,19 @@ where metadata: Metadata, ) -> Result<(NewTransaction, TokenId), ControllerError> { self.create_and_send_tx_with_id( - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31| { - wallet.issue_new_nft( - account_index, - address, - metadata, - current_fee_rate, - consolidate_fee_rate, - ) + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31| { + wallet + .issue_new_nft( + account_index, + address, + metadata, + current_fee_rate, + consolidate_fee_rate, + ) + .await }, ) .await @@ -347,20 +351,23 @@ where ) -> Result> { self.create_and_send_token_tx( token_info, - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31, - token_info: &UnconfirmedTokenInfo| { + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31, + token_info: UnconfirmedTokenInfo| { token_info.check_can_be_used()?; - wallet.mint_tokens( - account_index, - token_info, - amount, - address, - current_fee_rate, - consolidate_fee_rate, - ) + + wallet + .mint_tokens( + account_index, + token_info, + amount, + address, + current_fee_rate, + consolidate_fee_rate, + ) + .await }, ) .await @@ -372,19 +379,22 @@ where ) -> Result> { self.create_and_send_token_tx( token_info, - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31, - token_info: &UnconfirmedTokenInfo| { + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31, + token_info: UnconfirmedTokenInfo| { token_info.check_can_be_used()?; - wallet.unmint_tokens( - account_index, - token_info, - amount, - current_fee_rate, - consolidate_fee_rate, - ) + + wallet + .unmint_tokens( + account_index, + token_info, + amount, + current_fee_rate, + consolidate_fee_rate, + ) + .await }, ) .await @@ -396,18 +406,21 @@ where ) -> Result> { self.create_and_send_token_tx( token_info, - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31, - token_info: &UnconfirmedTokenInfo| { + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31, + token_info: UnconfirmedTokenInfo| { token_info.check_can_be_used()?; - wallet.lock_token_supply( - account_index, - token_info, - current_fee_rate, - consolidate_fee_rate, - ) + + wallet + .lock_token_supply( + account_index, + token_info, + current_fee_rate, + consolidate_fee_rate, + ) + .await }, ) .await @@ -422,18 +435,22 @@ where ) -> Result> { self.create_and_send_token_tx( token_info, - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31, - token_info: &UnconfirmedTokenInfo| { - wallet.freeze_token( - account_index, - token_info, - is_token_unfreezable, - current_fee_rate, - consolidate_fee_rate, - ) + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31, + token_info: UnconfirmedTokenInfo| { + token_info.check_can_be_used()?; + + wallet + .freeze_token( + account_index, + token_info, + is_token_unfreezable, + current_fee_rate, + consolidate_fee_rate, + ) + .await }, ) .await @@ -446,17 +463,19 @@ where ) -> Result> { self.create_and_send_token_tx( token_info, - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31, - token_info: &UnconfirmedTokenInfo| { - wallet.unfreeze_token( - account_index, - token_info, - current_fee_rate, - consolidate_fee_rate, - ) + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31, + token_info: UnconfirmedTokenInfo| { + wallet + .unfreeze_token( + account_index, + token_info, + current_fee_rate, + consolidate_fee_rate, + ) + .await }, ) .await @@ -471,18 +490,22 @@ where ) -> Result> { self.create_and_send_token_tx( token_info, - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31, - token_info: &UnconfirmedTokenInfo| { - wallet.change_token_authority( - account_index, - token_info, - address, - current_fee_rate, - consolidate_fee_rate, - ) + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31, + token_info: UnconfirmedTokenInfo| { + token_info.check_can_be_used()?; + + wallet + .change_token_authority( + account_index, + token_info, + address, + current_fee_rate, + consolidate_fee_rate, + ) + .await }, ) .await @@ -495,18 +518,22 @@ where ) -> Result> { self.create_and_send_token_tx( token_info, - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31, - token_info: &UnconfirmedTokenInfo| { - wallet.change_token_metadata_uri( - account_index, - token_info, - metadata_uri, - current_fee_rate, - consolidate_fee_rate, - ) + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31, + token_info: UnconfirmedTokenInfo| { + token_info.check_can_be_used()?; + + wallet + .change_token_metadata_uri( + account_index, + token_info, + metadata_uri, + current_fee_rate, + consolidate_fee_rate, + ) + .await }, ) .await @@ -520,19 +547,21 @@ where let outputs = make_data_deposit_output(self.chain_config, data, best_block_height)?; self.create_and_send_tx( - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31| { - wallet.create_transaction_to_addresses( - account_index, - outputs, - SelectedInputs::Utxos(vec![]), - BTreeMap::new(), - current_fee_rate, - consolidate_fee_rate, - TxAdditionalInfo::new(), - ) + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31| { + wallet + .create_transaction_to_addresses( + account_index, + outputs, + SelectedInputs::Utxos(vec![]), + BTreeMap::new(), + current_fee_rate, + consolidate_fee_rate, + TxAdditionalInfo::new(), + ) + .await }, ) .await @@ -558,19 +587,21 @@ where let output = make_address_output(address.into_object(), amount); self.create_and_send_tx( - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31| { - wallet.create_transaction_to_addresses( - account_index, - [output], - SelectedInputs::Utxos(selected_utxos), - BTreeMap::new(), - current_fee_rate, - consolidate_fee_rate, - TxAdditionalInfo::new(), - ) + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31| { + wallet + .create_transaction_to_addresses( + account_index, + [output], + SelectedInputs::Utxos(selected_utxos), + BTreeMap::new(), + current_fee_rate, + consolidate_fee_rate, + TxAdditionalInfo::new(), + ) + .await }, ) .await @@ -602,17 +633,19 @@ where .collect::>(); self.create_and_send_tx( - move |current_fee_rate: FeeRate, - _consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31| { - wallet.create_sweep_transaction( - account_index, - destination_address, - filtered_inputs, - current_fee_rate, - additional_info, - ) + async move |current_fee_rate: FeeRate, + _consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31| { + wallet + .create_sweep_transaction( + account_index, + destination_address, + filtered_inputs, + current_fee_rate, + additional_info, + ) + .await }, ) .await @@ -641,17 +674,19 @@ where ))?; self.create_and_send_tx( - move |current_fee_rate: FeeRate, - _consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31| { - wallet.create_sweep_from_delegation_transaction( - account_index, - destination_address, - delegation_id, - delegation_share, - current_fee_rate, - ) + async move |current_fee_rate: FeeRate, + _consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31| { + wallet + .create_sweep_from_delegation_transaction( + account_index, + destination_address, + delegation_id, + delegation_share, + current_fee_rate, + ) + .await }, ) .await @@ -870,16 +905,18 @@ where ) -> Result<(NewTransaction, DelegationId), ControllerError> { let output = make_create_delegation_output(address, pool_id); self.create_and_send_tx_with_id( - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31| { - wallet.create_delegation( - account_index, - output, - current_fee_rate, - consolidate_fee_rate, - ) + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31| { + wallet + .create_delegation( + account_index, + output, + current_fee_rate, + consolidate_fee_rate, + ) + .await }, ) .await @@ -894,19 +931,21 @@ where ) -> Result> { let output = TxOutput::DelegateStaking(amount, delegation_id); self.create_and_send_tx( - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31| { - wallet.create_transaction_to_addresses( - account_index, - [output], - SelectedInputs::Utxos(vec![]), - BTreeMap::new(), - current_fee_rate, - consolidate_fee_rate, - TxAdditionalInfo::new(), - ) + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31| { + wallet + .create_transaction_to_addresses( + account_index, + [output], + SelectedInputs::Utxos(vec![]), + BTreeMap::new(), + current_fee_rate, + consolidate_fee_rate, + TxAdditionalInfo::new(), + ) + .await }, ) .await @@ -932,18 +971,20 @@ where ))?; self.create_and_send_tx( - move |current_fee_rate: FeeRate, - _consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31| { - wallet.create_transaction_to_addresses_from_delegation( - account_index, - address, - amount, - delegation_id, - delegation_share, - current_fee_rate, - ) + async move |current_fee_rate: FeeRate, + _consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31| { + wallet + .create_transaction_to_addresses_from_delegation( + account_index, + address, + amount, + delegation_id, + delegation_share, + current_fee_rate, + ) + .await }, ) .await @@ -961,11 +1002,11 @@ where make_address_output_token(address.into_object(), amount, token_info.token_id()); self.create_and_send_token_tx( token_info, - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31, - token_info: &UnconfirmedTokenInfo| { + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31, + token_info: UnconfirmedTokenInfo| { token_info.check_can_be_used()?; let additional_info = TxAdditionalInfo::new().with_token_info( token_info.token_id(), @@ -974,15 +1015,17 @@ where ticker: token_info.token_ticker().to_vec(), }, ); - wallet.create_transaction_to_addresses( - account_index, - [output], - SelectedInputs::Utxos(vec![]), - BTreeMap::new(), - current_fee_rate, - consolidate_fee_rate, - additional_info, - ) + wallet + .create_transaction_to_addresses( + account_index, + [output], + SelectedInputs::Utxos(vec![]), + BTreeMap::new(), + current_fee_rate, + consolidate_fee_rate, + additional_info, + ) + .await }, ) .await @@ -1000,11 +1043,11 @@ where make_address_output_token(address.into_object(), amount, token_info.token_id()); self.create_token_tx( token_info, - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31, - token_info: &UnconfirmedTokenInfo| { + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31, + token_info: UnconfirmedTokenInfo| { token_info.check_can_be_used()?; let additional_info = TxAdditionalInfo::new().with_token_info( token_info.token_id(), @@ -1013,16 +1056,18 @@ where ticker: token_info.token_ticker().to_vec(), }, ); - wallet.create_transaction_to_addresses_with_intent( - account_index, - [output], - SelectedInputs::Utxos(vec![]), - BTreeMap::new(), - intent, - current_fee_rate, - consolidate_fee_rate, - additional_info, - ) + wallet + .create_transaction_to_addresses_with_intent( + account_index, + [output], + SelectedInputs::Utxos(vec![]), + BTreeMap::new(), + intent, + current_fee_rate, + consolidate_fee_rate, + additional_info, + ) + .await }, ) .await @@ -1039,23 +1084,25 @@ where vrf_public_key: Option, ) -> Result> { self.create_and_send_tx( - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31| { - wallet.create_stake_pool( - account_index, - current_fee_rate, - consolidate_fee_rate, - StakePoolCreationArguments { - amount, - margin_ratio_per_thousand, - cost_per_block, - decommission_key, - staker_key, - vrf_public_key, - }, - ) + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31| { + wallet + .create_stake_pool( + account_index, + current_fee_rate, + consolidate_fee_rate, + StakePoolCreationArguments { + amount, + margin_ratio_per_thousand, + cost_per_block, + decommission_key, + staker_key, + vrf_public_key, + }, + ) + .await }, ) .await @@ -1077,17 +1124,19 @@ where )))?; self.create_and_send_tx( - move |current_fee_rate: FeeRate, - _consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31| { - wallet.decommission_stake_pool( - account_index, - pool_id, - staker_balance, - output_address, - current_fee_rate, - ) + async move |current_fee_rate: FeeRate, + _consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31| { + wallet + .decommission_stake_pool( + account_index, + pool_id, + staker_balance, + output_address, + current_fee_rate, + ) + .await }, ) .await @@ -1118,6 +1167,7 @@ where output_address, current_fee_rate, ) + .await .map_err(ControllerError::WalletError) } @@ -1134,14 +1184,17 @@ where let (current_fee_rate, consolidate_fee_rate) = self.get_current_and_consolidation_fee_rate().await?; - let SignedTxWithFees { tx, fees } = self.wallet.create_htlc_tx( - self.account_index, - output_value, - htlc, - current_fee_rate, - consolidate_fee_rate, - tx_additional_info, - )?; + let SignedTxWithFees { tx, fees } = self + .wallet + .create_htlc_tx( + self.account_index, + output_value, + htlc, + current_fee_rate, + consolidate_fee_rate, + tx_additional_info, + ) + .await?; let fees = into_balances(&self.rpc_client, self.chain_config, fees).await?; @@ -1172,19 +1225,21 @@ where let give_value = convert_value(give_value).await?; self.create_and_send_tx_with_id( - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31| { - wallet.create_order_tx( - account_index, - ask_value, - give_value, - conclude_key, - current_fee_rate, - consolidate_fee_rate, - tx_additional_info, - ) + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31| { + wallet + .create_order_tx( + account_index, + ask_value, + give_value, + conclude_key, + current_fee_rate, + consolidate_fee_rate, + tx_additional_info, + ) + .await }, ) .await @@ -1200,19 +1255,21 @@ where self.additional_info_for_order_update_tx(order_id, &order_info).await?; self.create_and_send_tx( - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31| { - wallet.create_conclude_order_tx( - account_index, - order_id, - order_info, - output_address, - current_fee_rate, - consolidate_fee_rate, - tx_additional_info, - ) + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31| { + wallet + .create_conclude_order_tx( + account_index, + order_id, + order_info, + output_address, + current_fee_rate, + consolidate_fee_rate, + tx_additional_info, + ) + .await }, ) .await @@ -1243,20 +1300,22 @@ where .ok_or(ControllerError::InvalidCoinAmount)?; self.create_and_send_tx( - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31| { - wallet.create_fill_order_tx( - account_index, - order_id, - order_info, - fill_amount_in_ask_currency, - output_address, - current_fee_rate, - consolidate_fee_rate, - tx_additional_info, - ) + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31| { + wallet + .create_fill_order_tx( + account_index, + order_id, + order_info, + fill_amount_in_ask_currency, + output_address, + current_fee_rate, + consolidate_fee_rate, + tx_additional_info, + ) + .await }, ) .await @@ -1271,18 +1330,20 @@ where self.additional_info_for_order_update_tx(order_id, &order_info).await?; self.create_and_send_tx( - move |current_fee_rate: FeeRate, - consolidate_fee_rate: FeeRate, - wallet: &mut RuntimeWallet, - account_index: U31| { - wallet.create_freeze_order_tx( - account_index, - order_id, - order_info, - current_fee_rate, - consolidate_fee_rate, - tx_additional_info, - ) + async move |current_fee_rate: FeeRate, + consolidate_fee_rate: FeeRate, + wallet: &mut RuntimeWallet, + account_index: U31| { + wallet + .create_freeze_order_tx( + account_index, + order_id, + order_info, + current_fee_rate, + consolidate_fee_rate, + tx_additional_info, + ) + .await }, ) .await @@ -1381,16 +1442,18 @@ where self.wallet .sign_raw_transaction(self.account_index, ptx) + .await .map_err(ControllerError::WalletError) } - pub fn sign_challenge( + pub async fn sign_challenge( &mut self, challenge: &[u8], destination: &Destination, ) -> Result> { self.wallet .sign_challenge(self.account_index, challenge, destination) + .await .map_err(ControllerError::WalletError) } @@ -1449,12 +1512,17 @@ where } /// Create a transaction and broadcast it if needed - async fn create_and_send_tx( + async fn create_and_send_tx( &mut self, - tx_maker: F, + tx_maker: Fun, ) -> Result> where - F: FnOnce(FeeRate, FeeRate, &mut RuntimeWallet, U31) -> Result, + Fun: AsyncFnOnce( + FeeRate, + FeeRate, + &mut RuntimeWallet, + U31, + ) -> Result, ControllerError: From, { let (current_fee_rate, consolidate_fee_rate) = @@ -1465,7 +1533,8 @@ where consolidate_fee_rate, self.wallet, self.account_index, - )?; + ) + .await?; let (tx, broadcasted) = self.broadcast_to_mempool_if_needed(tx).await?; let fees = into_balances(&self.rpc_client, self.chain_config, fees).await?; @@ -1484,12 +1553,12 @@ where tx_maker: F, ) -> Result> where - F: FnOnce( + F: AsyncFnOnce( FeeRate, FeeRate, &mut RuntimeWallet, U31, - &UnconfirmedTokenInfo, + UnconfirmedTokenInfo, ) -> WalletResult, { let token_freezable_info = self.unconfirmed_token_info(token_info)?; @@ -1502,8 +1571,9 @@ where consolidate_fee_rate, self.wallet, self.account_index, - &token_freezable_info, + token_freezable_info, ) + .await .map_err(ControllerError::WalletError)?; Ok(tx) @@ -1511,19 +1581,20 @@ where /// Create and broadcast a transaction that uses a token, /// check if that token can be used i.e. not frozen. - async fn create_and_send_token_tx< - F: FnOnce( + async fn create_and_send_token_tx( + &mut self, + token_info: RPCTokenInfo, + tx_maker: F, + ) -> Result> + where + F: AsyncFnOnce( FeeRate, FeeRate, &mut RuntimeWallet, U31, - &UnconfirmedTokenInfo, + UnconfirmedTokenInfo, ) -> WalletResult, - >( - &mut self, - token_info: RPCTokenInfo, - tx_maker: F, - ) -> Result> { + { let SignedTxWithFees { tx, fees } = self.create_token_tx(token_info, tx_maker).await?; let (tx, broadcasted) = self.broadcast_to_mempool_if_needed(tx).await?; let fees = into_balances(&self.rpc_client, self.chain_config, fees).await?; @@ -1554,7 +1625,7 @@ where /// e.g. newly issued token, nft or delegation id async fn create_and_send_tx_with_id< ID, - F: FnOnce( + F: AsyncFnOnce( FeeRate, FeeRate, &mut RuntimeWallet, @@ -1573,6 +1644,7 @@ where self.wallet, self.account_index, ) + .await .map_err(ControllerError::WalletError)?; let (tx, broadcasted) = self.broadcast_to_mempool_if_needed(tx).await?; diff --git a/wallet/wallet-rpc-lib/src/rpc/mod.rs b/wallet/wallet-rpc-lib/src/rpc/mod.rs index b557b3910d..b53c3df09f 100644 --- a/wallet/wallet-rpc-lib/src/rpc/mod.rs +++ b/wallet/wallet-rpc-lib/src/rpc/mod.rs @@ -902,6 +902,7 @@ where .synced_controller(account_index, config) .await? .sign_challenge(&challenge, &destination) + .await .map_err(RpcError::Controller) }) })