From 91f68cc6801f36eb5224f0035db87ab176e315fc Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 14 Apr 2026 21:41:59 +0700 Subject: [PATCH 01/13] feat(dpp)!: convert Signer trait to async Convert the Signer trait in rs-dpp to an async trait via #[async_trait], enabling true async signing for iOS HSM / Secure Enclave / keychain backends without blocking any thread during biometric prompts or hardware calls. - Signer::sign and Signer::sign_create_witness are now async; can_sign_with stays sync - All 9 concrete Signer implementations converted (SimpleSigner, SingleKeySigner, DummySigner, 2x TestAddressSigner, IdentitySignerWasm, PlatformAddressSignerWasm, VTableSigner, AddressSigner) - Propagate async through rs-dpp state-transition builders, rs-sdk transition builders, rs-drive-abci tests, wasm-sdk, and strategy-tests - Iterator closures calling signer.sign(...) rewritten as sequential for loops (order-preserving, borrow-friendly) - Teach #[stack_size] macro to wrap async fn bodies in a tokio current-thread runtime inside the spawned thread so integration tests keep working BREAKING CHANGE: rs-sdk-ffi Signer vtable redesigned with a completion- callback pattern. The old synchronous SignCallback + free_result_callback pair is replaced with SignAsyncCallback + SignCompletionCallback, so the iOS side can return from the sign callback immediately and invoke the Rust completion function later (from any thread) when the HSM/keychain response arrives. No thread is blocked during the wait. Migration notes for iOS consumers: - dash_sdk_signer_create no longer takes a free_result_callback - The sign callback signature changes: iOS stashes (completion_ctx, completion) and invokes completion(ctx, sig, len, err) when ready - SingleKeySigner now routes through a native (non-callback) path with no C-callback bounce, via signer_handle_from_single_key Co-Authored-By: Claude Opus 4.6 (1M context) --- Cargo.lock | 4 + packages/rs-dash-platform-macros/src/lib.rs | 41 +- packages/rs-dpp/src/identity/signer.rs | 28 +- packages/rs-dpp/src/lib.rs | 1 + .../rs-dpp/src/shielded/builder/shield.rs | 26 +- packages/rs-dpp/src/state_transition/mod.rs | 7 +- .../methods/mod.rs | 5 +- .../methods/v0/mod.rs | 2 +- .../v0/v0_methods.rs | 11 +- .../methods/mod.rs | 5 +- .../methods/v0/mod.rs | 2 +- .../v0/v0_methods.rs | 11 +- .../methods/mod.rs | 5 +- .../methods/v0/mod.rs | 2 +- .../signing_tests.rs | 110 +- .../v0/v0_methods.rs | 11 +- .../methods/mod.rs | 23 +- .../methods/v0/mod.rs | 2 +- .../v0/v0_methods.rs | 4 +- .../methods/mod.rs | 25 +- .../methods/v0/mod.rs | 2 +- .../v0/v0_methods.rs | 4 +- .../document/batch_transition/methods/mod.rs | 93 +- .../batch_transition/methods/v0/mod.rs | 24 +- .../batch_transition/methods/v1/mod.rs | 22 +- .../batch_transition/v0/v0_methods.rs | 108 +- .../batch_transition/v1/v0_methods.rs | 108 +- .../batch_transition/v1/v1_methods.rs | 308 +++-- .../methods/mod.rs | 8 +- .../methods/v0/mod.rs | 5 +- .../v0/v0_methods.rs | 35 +- .../identity_create_transition/methods/mod.rs | 5 +- .../methods/v0/mod.rs | 2 +- .../v0/v0_methods.rs | 17 +- .../methods/mod.rs | 5 +- .../methods/v0/mod.rs | 2 +- .../v0/v0_methods.rs | 15 +- .../methods/mod.rs | 5 +- .../methods/v0/mod.rs | 2 +- .../v0/v0_methods.rs | 14 +- .../methods/mod.rs | 5 +- .../methods/v0/mod.rs | 2 +- .../v1/v0_methods.rs | 14 +- .../methods/mod.rs | 5 +- .../methods/v0/mod.rs | 2 +- .../v0/v0_methods.rs | 11 +- .../identity_update_transition/methods/mod.rs | 5 +- .../methods/v0/mod.rs | 2 +- .../v0/v0_methods.rs | 30 +- .../masternode_vote_transition/methods/mod.rs | 5 +- .../methods/v0/mod.rs | 2 +- .../v0/v0_methods.rs | 14 +- .../from_public_key_signed_external/mod.rs | 3 +- .../from_public_key_signed_external/v0/mod.rs | 4 +- .../shielded/shield_transition/methods/mod.rs | 29 +- .../shield_transition/methods/v0/mod.rs | 2 +- .../shield_transition/v0/v0_methods.rs | 11 +- .../src/execution/check_tx/v0/mod.rs | 46 +- .../block_processing_end_events/tests.rs | 60 +- .../check_tx_verification/v0/mod.rs | 38 +- .../address_credit_withdrawal/tests.rs | 410 ++++--- .../address_funding_from_asset_lock/tests.rs | 692 ++++++----- .../address_funds_transfer/tests.rs | 671 ++++++----- .../batch/tests/document/creation.rs | 147 ++- .../batch/tests/document/deletion.rs | 47 +- .../batch/tests/document/dpns.rs | 20 +- .../batch/tests/document/nft.rs | 100 +- .../batch/tests/document/replacement.rs | 61 +- .../batch/tests/document/transfer.rs | 71 +- .../tests/token/additional_validation/mod.rs | 11 +- .../batch/tests/token/burn/mod.rs | 35 +- .../batch/tests/token/config_update/mod.rs | 91 +- .../tests/token/destroy_frozen_funds/mod.rs | 13 +- .../batch/tests/token/direct_selling/mod.rs | 73 +- .../distribution/perpetual/block_based.rs | 347 +++--- .../distribution/perpetual/time_based.rs | 51 +- .../token/distribution/pre_programmed.rs | 33 +- .../batch/tests/token/emergency_action/mod.rs | 24 +- .../batch/tests/token/freeze/mod.rs | 79 +- .../batch/tests/token/mint/mod.rs | 133 +- .../batch/tests/token/transfer/mod.rs | 42 +- .../data_contract_create/mod.rs | 221 ++-- .../data_contract_update/mod.rs | 124 +- .../state_transitions/identity_create/mod.rs | 46 +- .../identity_create_from_addresses/tests.rs | 1067 +++++++++-------- .../identity_credit_transfer/mod.rs | 55 +- .../tests.rs | 452 +++---- .../identity_credit_withdrawal/mod.rs | 36 +- .../identity_top_up_from_addresses/tests.rs | 361 +++--- .../state_transitions/identity_update/mod.rs | 71 +- .../state_transitions/masternode_vote/mod.rs | 822 ++++++++----- .../state_transition/state_transitions/mod.rs | 86 +- .../state_transitions/shield/tests.rs | 226 ++-- .../state_transitions/test_helpers.rs | 13 +- .../tests/strategy_tests/execution.rs | 53 +- .../tests/strategy_tests/failures.rs | 21 +- .../tests/strategy_tests/query.rs | 28 +- .../tests/strategy_tests/strategy.rs | 679 ++++++----- .../test_cases/address_tests.rs | 114 +- .../strategy_tests/test_cases/basic_tests.rs | 51 +- .../test_cases/chain_lock_update_tests.rs | 7 +- .../test_cases/core_height_increase.rs | 76 +- .../test_cases/core_update_tests.rs | 21 +- .../test_cases/data_contract_history_tests.rs | 14 +- .../test_cases/identity_and_document_tests.rs | 134 ++- .../test_cases/identity_transfer_tests.rs | 7 +- .../test_cases/shielded_tests.rs | 12 +- .../strategy_tests/test_cases/token_tests.rs | 70 +- .../strategy_tests/test_cases/top_up_tests.rs | 14 +- .../test_cases/update_identities_tests.rs | 14 +- .../test_cases/upgrade_fork_tests.rs | 65 +- .../strategy_tests/test_cases/voting_tests.rs | 86 +- .../test_cases/withdrawal_tests.rs | 73 +- packages/rs-sdk-ffi/Cargo.toml | 3 +- .../src/address/transitions/transfer.rs | 5 +- .../rs-sdk-ffi/src/dashpay/contact_request.rs | 13 +- packages/rs-sdk-ffi/src/dpns/register.rs | 14 +- packages/rs-sdk-ffi/src/identity/transfer.rs | 7 +- packages/rs-sdk-ffi/src/identity/withdraw.rs | 7 +- .../src/shielded/transitions/builders.rs | 1 + packages/rs-sdk-ffi/src/signer.rs | 882 +++++++++----- packages/rs-sdk-ffi/src/signer_simple.rs | 69 +- packages/rs-sdk-ffi/src/test_utils.rs | 94 +- packages/rs-sdk-ffi/src/token/claim.rs | 45 +- .../rs-sdk-ffi/src/token/config_update.rs | 44 +- .../src/token/destroy_frozen_funds.rs | 44 +- .../rs-sdk-ffi/src/token/emergency_action.rs | 45 +- packages/rs-sdk-ffi/src/token/freeze.rs | 45 +- packages/rs-sdk-ffi/src/token/mint.rs | 74 +- packages/rs-sdk-ffi/src/token/purchase.rs | 44 +- packages/rs-sdk-ffi/src/token/set_price.rs | 44 +- packages/rs-sdk-ffi/src/token/transfer.rs | 44 +- packages/rs-sdk-ffi/src/token/unfreeze.rs | 44 +- .../platform/documents/transitions/create.rs | 3 +- .../platform/documents/transitions/delete.rs | 3 +- .../documents/transitions/purchase.rs | 3 +- .../platform/documents/transitions/replace.rs | 3 +- .../documents/transitions/set_price.rs | 3 +- .../documents/transitions/transfer.rs | 3 +- .../src/platform/tokens/builders/burn.rs | 3 +- .../src/platform/tokens/builders/claim.rs | 3 +- .../platform/tokens/builders/config_update.rs | 3 +- .../src/platform/tokens/builders/destroy.rs | 3 +- .../tokens/builders/emergency_action.rs | 3 +- .../src/platform/tokens/builders/freeze.rs | 3 +- .../src/platform/tokens/builders/mint.rs | 3 +- .../src/platform/tokens/builders/purchase.rs | 3 +- .../src/platform/tokens/builders/set_price.rs | 3 +- .../src/platform/tokens/builders/transfer.rs | 3 +- .../src/platform/tokens/builders/unfreeze.rs | 3 +- .../transition/address_credit_withdrawal.rs | 3 +- .../platform/transition/broadcast_identity.rs | 8 +- .../platform/transition/purchase_document.rs | 3 +- .../src/platform/transition/put_contract.rs | 3 +- .../src/platform/transition/put_document.rs | 4 +- .../src/platform/transition/put_identity.rs | 17 +- .../rs-sdk/src/platform/transition/shield.rs | 3 +- .../src/platform/transition/top_up_address.rs | 6 +- .../top_up_identity_from_addresses.rs | 3 +- .../src/platform/transition/transfer.rs | 3 +- .../transition/transfer_address_funds.rs | 3 +- .../platform/transition/transfer_document.rs | 3 +- .../transition/transfer_to_addresses.rs | 3 +- .../transition/update_price_of_document.rs | 3 +- .../rs-sdk/src/platform/transition/vote.rs | 6 +- .../transition/withdraw_from_identity.rs | 3 +- packages/simple-signer/Cargo.toml | 1 + packages/simple-signer/src/signer.rs | 19 +- .../simple-signer/src/single_key_signer.rs | 8 +- packages/strategy-tests/Cargo.toml | 1 + packages/strategy-tests/src/lib.rs | 564 +++++---- packages/strategy-tests/src/transitions.rs | 235 ++-- packages/wasm-dpp2/Cargo.toml | 1 + packages/wasm-dpp2/src/identity/signer.rs | 7 +- .../wasm-dpp2/src/platform_address/signer.rs | 11 +- .../src/state_transitions/contract.rs | 1 + .../src/state_transitions/identity.rs | 1 + 177 files changed, 7067 insertions(+), 5144 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 32ca6b6a545..5d8caf8da74 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5862,6 +5862,7 @@ dependencies = [ name = "rs-sdk-ffi" version = "3.1.0-dev.1" dependencies = [ + "async-trait", "bincode", "bs58", "cbindgen 0.27.0", @@ -6623,6 +6624,7 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" name = "simple-signer" version = "3.1.0-dev.1" dependencies = [ + "async-trait", "base64 0.22.1", "bincode", "dpp", @@ -6762,6 +6764,7 @@ dependencies = [ "platform-version", "rand 0.8.5", "simple-signer", + "tokio", "tracing", ] @@ -8119,6 +8122,7 @@ name = "wasm-dpp2" version = "3.1.0-dev.1" dependencies = [ "anyhow", + "async-trait", "bincode", "dpp", "dpp-json-convertible-derive", diff --git a/packages/rs-dash-platform-macros/src/lib.rs b/packages/rs-dash-platform-macros/src/lib.rs index ff7f7568d59..dee6219fa4e 100644 --- a/packages/rs-dash-platform-macros/src/lib.rs +++ b/packages/rs-dash-platform-macros/src/lib.rs @@ -29,10 +29,43 @@ pub fn stack_size(attr: TokenStream, item: TokenStream) -> TokenStream { let attrs = function.attrs; let vis = function.vis; - let sig = function.sig; + let mut sig = function.sig; let block = function.block; let fn_ident = sig.ident.clone(); + // If the function is async, we strip async from the outer signature + // and run the body on a new tokio current-thread runtime inside the + // spawned thread. This keeps the externally-visible function sync so + // that it works with `#[test]` (and avoids needing `#[tokio::test]`). + let is_async = sig.asyncness.is_some(); + if is_async { + sig.asyncness = None; + } + + let spawned_body = if is_async { + quote! { + builder + .spawn(move || { + ::tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("failed to build tokio runtime for stack_size thread") + .block_on(async move #block) + }) + .expect("failed to spawn stack_size thread") + .join() + .expect("stack_size thread panicked") + } + } else { + quote! { + builder + .spawn(move || #block) + .expect("failed to spawn stack_size thread") + .join() + .expect("stack_size thread panicked") + } + }; + TokenStream::from(quote! { #(#attrs)* #vis #sig { @@ -40,11 +73,7 @@ pub fn stack_size(attr: TokenStream, item: TokenStream) -> TokenStream { .stack_size(#stack_size_expr) .name(::std::string::String::from(stringify!(#fn_ident))); - builder - .spawn(|| #block) - .expect("failed to spawn stack_size thread") - .join() - .expect("stack_size thread panicked") + #spawned_body } }) } diff --git a/packages/rs-dpp/src/identity/signer.rs b/packages/rs-dpp/src/identity/signer.rs index 66719f6066d..27079b3a58c 100644 --- a/packages/rs-dpp/src/identity/signer.rs +++ b/packages/rs-dpp/src/identity/signer.rs @@ -1,30 +1,42 @@ use crate::address_funds::AddressWitness; use crate::ProtocolError; +use async_trait::async_trait; use platform_value::BinaryData; use std::fmt::Debug; use std::sync::Arc; -pub trait Signer: Sync + Debug { +#[async_trait] +pub trait Signer: Send + Sync + Debug { /// the public key bytes are only used to look up the private key - fn sign(&self, key: &K, data: &[u8]) -> Result; + async fn sign(&self, key: &K, data: &[u8]) -> Result; /// the public key bytes are only used to look up the private key - fn sign_create_witness(&self, key: &K, data: &[u8]) -> Result; + async fn sign_create_witness( + &self, + key: &K, + data: &[u8], + ) -> Result; /// do we have this identity public key in the signer? fn can_sign_with(&self, key: &K) -> bool; } +#[async_trait] impl Signer for Arc where - S: Signer + ?Sized + Send, + K: Send + Sync, + S: Signer + ?Sized + Send + Sync, { - fn sign(&self, key: &K, data: &[u8]) -> Result { - (**self).sign(key, data) + async fn sign(&self, key: &K, data: &[u8]) -> Result { + (**self).sign(key, data).await } - fn sign_create_witness(&self, key: &K, data: &[u8]) -> Result { - (**self).sign_create_witness(key, data) + async fn sign_create_witness( + &self, + key: &K, + data: &[u8], + ) -> Result { + (**self).sign_create_witness(key, data).await } fn can_sign_with(&self, key: &K) -> bool { diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index e73fb05c251..cd5397f944f 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -4,6 +4,7 @@ //#![deny(missing_docs)] #![allow(dead_code)] #![allow(clippy::result_large_err)] +#![allow(async_fn_in_trait)] extern crate core; diff --git a/packages/rs-dpp/src/shielded/builder/shield.rs b/packages/rs-dpp/src/shielded/builder/shield.rs index 91eac886619..65a21fc473d 100644 --- a/packages/rs-dpp/src/shielded/builder/shield.rs +++ b/packages/rs-dpp/src/shielded/builder/shield.rs @@ -29,7 +29,7 @@ use super::{build_output_only_bundle, serialize_authorized_bundle, OrchardProver /// - `memo` - 36-byte structured memo for the recipient (4-byte type tag + 32-byte payload) /// - `platform_version` - Protocol version #[allow(clippy::too_many_arguments)] -pub fn build_shield_transition, P: OrchardProver>( +pub async fn build_shield_transition, P: OrchardProver>( recipient: &OrchardAddress, shield_amount: u64, inputs: BTreeMap, @@ -61,6 +61,7 @@ pub fn build_shield_transition, P: OrchardProver>( user_fee_increase, platform_version, ) + .await } #[cfg(test)] @@ -76,12 +77,17 @@ mod tests { #[derive(Debug)] struct DummySigner; + #[async_trait::async_trait] impl Signer for DummySigner { - fn sign(&self, _key: &PlatformAddress, _data: &[u8]) -> Result { + async fn sign( + &self, + _key: &PlatformAddress, + _data: &[u8], + ) -> Result { Ok(BinaryData::new(vec![0u8; 65])) } - fn sign_create_witness( + async fn sign_create_witness( &self, _key: &PlatformAddress, _data: &[u8], @@ -96,8 +102,8 @@ mod tests { } } - #[test] - fn test_build_shield_empty_fee_strategy() { + #[tokio::test] + async fn test_build_shield_empty_fee_strategy() { let recipient = test_orchard_address(); let platform_version = PlatformVersion::latest(); let result = build_shield_transition( @@ -110,7 +116,8 @@ mod tests { &TestProver, [0u8; 36], platform_version, - ); + ) + .await; assert!(result.is_err()); let err = result.unwrap_err().to_string(); @@ -121,8 +128,8 @@ mod tests { ); } - #[test] - fn test_build_shield_transition_valid() { + #[tokio::test] + async fn test_build_shield_transition_valid() { let recipient = test_orchard_address(); let platform_version = PlatformVersion::latest(); // Create a P2PKH address as input @@ -142,7 +149,8 @@ mod tests { &TestProver, [0u8; 36], platform_version, - ); + ) + .await; assert!(result.is_ok(), "expected Ok, got: {:?}", result.err()); match result.unwrap() { diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 93bcabe20ef..c525cac90f1 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -940,7 +940,7 @@ impl StateTransition { } #[cfg(feature = "state-transition-signing")] - pub fn sign_external>( + pub async fn sign_external>( &mut self, identity_public_key: &IdentityPublicKey, signer: &S, @@ -954,10 +954,11 @@ impl StateTransition { get_data_contract_security_level_requirement, StateTransitionSigningOptions::default(), ) + .await } #[cfg(feature = "state-transition-signing")] - pub fn sign_external_with_options>( + pub async fn sign_external_with_options>( &mut self, identity_public_key: &IdentityPublicKey, signer: &S, @@ -1107,7 +1108,7 @@ impl StateTransition { } } let data = self.signable_bytes()?; - self.set_signature(signer.sign(identity_public_key, data.as_slice())?); + self.set_signature(signer.sign(identity_public_key, data.as_slice()).await?); self.set_signature_public_key_id(identity_public_key.id()); Ok(()) } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/methods/mod.rs index 6266204e5e0..1c7e1cebc00 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/methods/mod.rs @@ -29,7 +29,7 @@ use platform_version::version::PlatformVersion; impl AddressCreditWithdrawalTransitionMethodsV0 for AddressCreditWithdrawalTransition { #[cfg(feature = "state-transition-signing")] - fn try_from_inputs_with_signer>( + async fn try_from_inputs_with_signer>( inputs: BTreeMap, output: Option<(PlatformAddress, Credits)>, fee_strategy: AddressFundsFeeStrategy, @@ -57,7 +57,8 @@ impl AddressCreditWithdrawalTransitionMethodsV0 for AddressCreditWithdrawalTrans signer, user_fee_increase, platform_version, - )?, + ) + .await?, ), version => Err(ProtocolError::UnknownVersionMismatch { method: "AddressCreditWithdrawalTransition::try_from_inputs_with_signer" diff --git a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/methods/v0/mod.rs index fa6f9aaf9ed..5448b62ef8a 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/methods/v0/mod.rs @@ -24,7 +24,7 @@ use platform_version::version::PlatformVersion; pub trait AddressCreditWithdrawalTransitionMethodsV0 { #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn try_from_inputs_with_signer>( + async fn try_from_inputs_with_signer>( inputs: BTreeMap, output: Option<(PlatformAddress, Credits)>, fee_strategy: AddressFundsFeeStrategy, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/v0/v0_methods.rs index 2aa4e223bba..696a54e7d80 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/v0/v0_methods.rs @@ -26,7 +26,7 @@ use platform_version::version::PlatformVersion; impl AddressCreditWithdrawalTransitionMethodsV0 for AddressCreditWithdrawalTransitionV0 { #[cfg(feature = "state-transition-signing")] - fn try_from_inputs_with_signer>( + async fn try_from_inputs_with_signer>( inputs: BTreeMap, output: Option<(PlatformAddress, Credits)>, fee_strategy: AddressFundsFeeStrategy, @@ -61,10 +61,11 @@ impl AddressCreditWithdrawalTransitionMethodsV0 for AddressCreditWithdrawalTrans let signable_bytes = state_transition.signable_bytes()?; - address_credit_withdrawal_transition.input_witnesses = inputs - .keys() - .map(|address| signer.sign_create_witness(address, &signable_bytes)) - .collect::, ProtocolError>>()?; + let mut input_witnesses: Vec = Vec::with_capacity(inputs.len()); + for address in inputs.keys() { + input_witnesses.push(signer.sign_create_witness(address, &signable_bytes).await?); + } + address_credit_withdrawal_transition.input_witnesses = input_witnesses; tracing::debug!("try_from_inputs_with_signer: Successfully created transition"); Ok(address_credit_withdrawal_transition.into()) diff --git a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/methods/mod.rs index 1beb98107f2..a8ccf95277d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/methods/mod.rs @@ -27,7 +27,7 @@ use platform_version::version::PlatformVersion; impl AddressFundingFromAssetLockTransitionMethodsV0 for AddressFundingFromAssetLockTransition { #[cfg(feature = "state-transition-signing")] - fn try_from_asset_lock_with_signer>( + async fn try_from_asset_lock_with_signer>( asset_lock_proof: AssetLockProof, asset_lock_proof_private_key: &[u8], inputs: BTreeMap, @@ -52,7 +52,8 @@ impl AddressFundingFromAssetLockTransitionMethodsV0 for AddressFundingFromAssetL signer, user_fee_increase, platform_version, - )?, + ) + .await?, ), version => Err(ProtocolError::UnknownVersionMismatch { method: "AddressFundingFromAssetLockTransition::try_from_asset_lock_with_signer" diff --git a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/methods/v0/mod.rs index 04fe8f04070..4be95e3be6b 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/methods/v0/mod.rs @@ -18,7 +18,7 @@ use platform_version::version::PlatformVersion; pub trait AddressFundingFromAssetLockTransitionMethodsV0 { #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn try_from_asset_lock_with_signer>( + async fn try_from_asset_lock_with_signer>( asset_lock_proof: AssetLockProof, asset_lock_proof_private_key: &[u8], inputs: BTreeMap, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/v0/v0_methods.rs index 33a824521b4..573f466aebc 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/v0/v0_methods.rs @@ -22,7 +22,7 @@ use platform_version::version::PlatformVersion; impl AddressFundingFromAssetLockTransitionMethodsV0 for AddressFundingFromAssetLockTransitionV0 { #[cfg(feature = "state-transition-signing")] - fn try_from_asset_lock_with_signer>( + async fn try_from_asset_lock_with_signer>( asset_lock_proof: AssetLockProof, asset_lock_proof_private_key: &[u8], inputs: BTreeMap, @@ -59,10 +59,11 @@ impl AddressFundingFromAssetLockTransitionMethodsV0 for AddressFundingFromAssetL address_funding_transition.signature = signature.to_vec().into(); // Sign with input witnesses - address_funding_transition.input_witnesses = inputs - .keys() - .map(|address| signer.sign_create_witness(address, &signable_bytes)) - .collect::, ProtocolError>>()?; + let mut input_witnesses: Vec = Vec::with_capacity(inputs.len()); + for address in inputs.keys() { + input_witnesses.push(signer.sign_create_witness(address, &signable_bytes).await?); + } + address_funding_transition.input_witnesses = input_witnesses; tracing::debug!("try_from_asset_lock_with_signer: Successfully created transition"); Ok(address_funding_transition.into()) diff --git a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/methods/mod.rs index 7a36a6c9d3e..3de294b30f4 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/methods/mod.rs @@ -24,7 +24,7 @@ use platform_version::version::PlatformVersion; impl AddressFundsTransferTransitionMethodsV0 for AddressFundsTransferTransition { #[cfg(feature = "state-transition-signing")] - fn try_from_inputs_with_signer>( + async fn try_from_inputs_with_signer>( inputs: BTreeMap, outputs: BTreeMap, fee_strategy: AddressFundsFeeStrategy, @@ -45,7 +45,8 @@ impl AddressFundsTransferTransitionMethodsV0 for AddressFundsTransferTransition signer, user_fee_increase, platform_version, - )?, + ) + .await?, ), version => Err(ProtocolError::UnknownVersionMismatch { method: "AddressFundsTransferTransition::try_from_inputs_with_signer".to_string(), diff --git a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/methods/v0/mod.rs index d5fa8c075fc..a6f0ff7b0cf 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/methods/v0/mod.rs @@ -19,7 +19,7 @@ use platform_version::version::PlatformVersion; pub trait AddressFundsTransferTransitionMethodsV0 { #[cfg(feature = "state-transition-signing")] - fn try_from_inputs_with_signer>( + async fn try_from_inputs_with_signer>( inputs: BTreeMap, outputs: BTreeMap, fee_strategy: AddressFundsFeeStrategy, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/signing_tests.rs b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/signing_tests.rs index 47c28a5a6b8..930d4d266f9 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/signing_tests.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/signing_tests.rs @@ -130,8 +130,9 @@ impl TestAddressSigner { } } +#[async_trait::async_trait] impl Signer for TestAddressSigner { - fn sign(&self, key: &PlatformAddress, data: &[u8]) -> Result { + async fn sign(&self, key: &PlatformAddress, data: &[u8]) -> Result { match key { PlatformAddress::P2pkh(hash) => { let entry = self.p2pkh_keys.get(hash).ok_or_else(|| { @@ -160,7 +161,7 @@ impl Signer for TestAddressSigner { } } - fn sign_create_witness( + async fn sign_create_witness( &self, key: &PlatformAddress, data: &[u8], @@ -255,8 +256,8 @@ fn verify_transition_signatures( // P2PKH Tests // ============================================================================ -#[test] -fn test_single_p2pkh_input_signing() { +#[tokio::test] +async fn test_single_p2pkh_input_signing() { let mut signer = TestAddressSigner::new(); // Create input address @@ -281,6 +282,7 @@ fn test_single_p2pkh_input_signing() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); // Extract the V0 transition @@ -301,8 +303,8 @@ fn test_single_p2pkh_input_signing() { verify_transition_signatures(&transition).expect("signatures should be valid"); } -#[test] -fn test_multiple_p2pkh_inputs_signing() { +#[tokio::test] +async fn test_multiple_p2pkh_inputs_signing() { let mut signer = TestAddressSigner::new(); // Create multiple input addresses @@ -331,6 +333,7 @@ fn test_multiple_p2pkh_inputs_signing() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); let transition = match state_transition { @@ -356,8 +359,8 @@ fn test_multiple_p2pkh_inputs_signing() { // P2SH Multisig Tests // ============================================================================ -#[test] -fn test_single_p2sh_2_of_3_multisig_input_signing() { +#[tokio::test] +async fn test_single_p2sh_2_of_3_multisig_input_signing() { let mut signer = TestAddressSigner::new(); // Create 2-of-3 multisig input @@ -381,6 +384,7 @@ fn test_single_p2sh_2_of_3_multisig_input_signing() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); let transition = match state_transition { @@ -407,8 +411,8 @@ fn test_single_p2sh_2_of_3_multisig_input_signing() { verify_transition_signatures(&transition).expect("signatures should be valid"); } -#[test] -fn test_p2sh_3_of_5_multisig_input_signing() { +#[tokio::test] +async fn test_p2sh_3_of_5_multisig_input_signing() { let mut signer = TestAddressSigner::new(); // Create 3-of-5 multisig input @@ -433,6 +437,7 @@ fn test_p2sh_3_of_5_multisig_input_signing() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); let transition = match state_transition { @@ -452,8 +457,8 @@ fn test_p2sh_3_of_5_multisig_input_signing() { verify_transition_signatures(&transition).expect("signatures should be valid"); } -#[test] -fn test_multiple_p2sh_inputs_signing() { +#[tokio::test] +async fn test_multiple_p2sh_inputs_signing() { let mut signer = TestAddressSigner::new(); // Create two different multisig addresses @@ -477,6 +482,7 @@ fn test_multiple_p2sh_inputs_signing() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); let transition = match state_transition { @@ -499,8 +505,8 @@ fn test_multiple_p2sh_inputs_signing() { // Mixed P2PKH and P2SH Tests // ============================================================================ -#[test] -fn test_mixed_p2pkh_and_p2sh_inputs() { +#[tokio::test] +async fn test_mixed_p2pkh_and_p2sh_inputs() { let mut signer = TestAddressSigner::new(); // Create mixed inputs @@ -524,6 +530,7 @@ fn test_mixed_p2pkh_and_p2sh_inputs() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); let transition = match state_transition { @@ -553,8 +560,8 @@ fn test_mixed_p2pkh_and_p2sh_inputs() { verify_transition_signatures(&transition).expect("signatures should be valid"); } -#[test] -fn test_complex_mixed_inputs_multiple_outputs() { +#[tokio::test] +async fn test_complex_mixed_inputs_multiple_outputs() { let mut signer = TestAddressSigner::new(); // Create various inputs @@ -585,6 +592,7 @@ fn test_complex_mixed_inputs_multiple_outputs() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); let transition = match state_transition { @@ -618,8 +626,8 @@ fn test_complex_mixed_inputs_multiple_outputs() { // Serialization Tests // ============================================================================ -#[test] -fn test_signed_transition_serialization_roundtrip() { +#[tokio::test] +async fn test_signed_transition_serialization_roundtrip() { let mut signer = TestAddressSigner::new(); let input = signer.add_p2pkh([1u8; 32]); @@ -639,6 +647,7 @@ fn test_signed_transition_serialization_roundtrip() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); let transition = match state_transition { @@ -663,8 +672,8 @@ fn test_signed_transition_serialization_roundtrip() { verify_transition_signatures(&deserialized).expect("signatures should still be valid"); } -#[test] -fn test_multisig_transition_serialization_roundtrip() { +#[tokio::test] +async fn test_multisig_transition_serialization_roundtrip() { let mut signer = TestAddressSigner::new(); let input = signer.add_p2sh_multisig(2, &[[10u8; 32], [11u8; 32], [12u8; 32]]); @@ -684,6 +693,7 @@ fn test_multisig_transition_serialization_roundtrip() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); let transition = match state_transition { @@ -703,8 +713,8 @@ fn test_multisig_transition_serialization_roundtrip() { verify_transition_signatures(&deserialized).expect("signatures should still be valid"); } -#[test] -fn test_mixed_transition_serialization_roundtrip() { +#[tokio::test] +async fn test_mixed_transition_serialization_roundtrip() { let mut signer = TestAddressSigner::new(); let p2pkh = signer.add_p2pkh([50u8; 32]); @@ -726,6 +736,7 @@ fn test_mixed_transition_serialization_roundtrip() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); let transition = match state_transition { @@ -749,8 +760,8 @@ fn test_mixed_transition_serialization_roundtrip() { // Verification Failure Tests // ============================================================================ -#[test] -fn test_tampered_inputs_verification_fails() { +#[tokio::test] +async fn test_tampered_inputs_verification_fails() { let mut signer = TestAddressSigner::new(); let input = signer.add_p2pkh([1u8; 32]); @@ -770,6 +781,7 @@ fn test_tampered_inputs_verification_fails() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); let mut transition = match state_transition { @@ -794,8 +806,8 @@ fn test_tampered_inputs_verification_fails() { ); } -#[test] -fn test_tampered_outputs_verification_fails() { +#[tokio::test] +async fn test_tampered_outputs_verification_fails() { let mut signer = TestAddressSigner::new(); let input = signer.add_p2pkh([1u8; 32]); @@ -815,6 +827,7 @@ fn test_tampered_outputs_verification_fails() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); let mut transition = match state_transition { @@ -835,8 +848,8 @@ fn test_tampered_outputs_verification_fails() { ); } -#[test] -fn test_wrong_witness_for_address_fails() { +#[tokio::test] +async fn test_wrong_witness_for_address_fails() { let mut signer = TestAddressSigner::new(); let input1 = signer.add_p2pkh([1u8; 32]); @@ -857,6 +870,7 @@ fn test_wrong_witness_for_address_fails() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); let mut transition = match state_transition { @@ -878,8 +892,8 @@ fn test_wrong_witness_for_address_fails() { ); } -#[test] -fn test_missing_witness_fails() { +#[tokio::test] +async fn test_missing_witness_fails() { let mut signer = TestAddressSigner::new(); let input = signer.add_p2pkh([1u8; 32]); @@ -899,6 +913,7 @@ fn test_missing_witness_fails() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); let mut transition = match state_transition { @@ -919,8 +934,8 @@ fn test_missing_witness_fails() { ); } -#[test] -fn test_p2sh_insufficient_signatures_fails() { +#[tokio::test] +async fn test_p2sh_insufficient_signatures_fails() { let mut signer = TestAddressSigner::new(); let input = signer.add_p2sh_multisig(2, &[[10u8; 32], [11u8; 32], [12u8; 32]]); @@ -940,6 +955,7 @@ fn test_p2sh_insufficient_signatures_fails() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); let mut transition = match state_transition { @@ -974,8 +990,8 @@ fn test_p2sh_insufficient_signatures_fails() { // Edge Cases // ============================================================================ -#[test] -fn test_1_of_1_multisig() { +#[tokio::test] +async fn test_1_of_1_multisig() { let mut signer = TestAddressSigner::new(); // 1-of-1 multisig is essentially a P2SH wrapped P2PK @@ -996,6 +1012,7 @@ fn test_1_of_1_multisig() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); let transition = match state_transition { @@ -1012,8 +1029,8 @@ fn test_1_of_1_multisig() { verify_transition_signatures(&transition).expect("signatures should be valid"); } -#[test] -fn test_high_threshold_multisig() { +#[tokio::test] +async fn test_high_threshold_multisig() { let mut signer = TestAddressSigner::new(); // 5-of-5 requires all signers @@ -1035,6 +1052,7 @@ fn test_high_threshold_multisig() { 0, get_platform_version(), ) + .await .expect("should create signed transition"); let transition = match state_transition { @@ -1051,8 +1069,8 @@ fn test_high_threshold_multisig() { verify_transition_signatures(&transition).expect("signatures should be valid"); } -#[test] -fn test_signer_cannot_sign_unknown_address() { +#[tokio::test] +async fn test_signer_cannot_sign_unknown_address() { let signer = TestAddressSigner::new(); // Empty signer let unknown_address = PlatformAddress::P2pkh([1u8; 20]); @@ -1072,7 +1090,8 @@ fn test_signer_cannot_sign_unknown_address() { &signer, 0, get_platform_version(), - ); + ) + .await; assert!( result.is_err(), @@ -1080,8 +1099,8 @@ fn test_signer_cannot_sign_unknown_address() { ); } -#[test] -fn test_can_sign_with_check() { +#[tokio::test] +async fn test_can_sign_with_check() { let mut signer = TestAddressSigner::new(); let known_address = signer.add_p2pkh([1u8; 32]); @@ -1091,8 +1110,8 @@ fn test_can_sign_with_check() { assert!(!signer.can_sign_with(&unknown_address)); } -#[test] -fn test_user_fee_increase_preserved() { +#[tokio::test] +async fn test_user_fee_increase_preserved() { let mut signer = TestAddressSigner::new(); let input = signer.add_p2pkh([1u8; 32]); @@ -1114,6 +1133,7 @@ fn test_user_fee_increase_preserved() { user_fee_increase, get_platform_version(), ) + .await .expect("should create signed transition"); let transition = match state_transition { @@ -1127,8 +1147,8 @@ fn test_user_fee_increase_preserved() { verify_transition_signatures(&transition).expect("signatures should be valid"); } -#[test] -fn test_different_nonces_produce_different_signable_bytes() { +#[tokio::test] +async fn test_different_nonces_produce_different_signable_bytes() { let mut signer = TestAddressSigner::new(); let input = signer.add_p2pkh([1u8; 32]); let output = PlatformAddress::P2pkh([99u8; 20]); diff --git a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/v0/v0_methods.rs index a7aa6396e34..c1582ff5cf4 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/v0/v0_methods.rs @@ -22,7 +22,7 @@ use platform_version::version::PlatformVersion; impl AddressFundsTransferTransitionMethodsV0 for AddressFundsTransferTransitionV0 { #[cfg(feature = "state-transition-signing")] - fn try_from_inputs_with_signer>( + async fn try_from_inputs_with_signer>( inputs: BTreeMap, outputs: BTreeMap, fee_strategy: AddressFundsFeeStrategy, @@ -50,10 +50,11 @@ impl AddressFundsTransferTransitionMethodsV0 for AddressFundsTransferTransitionV let signable_bytes = state_transition.signable_bytes()?; - address_funds_transition.input_witnesses = inputs - .keys() - .map(|address| signer.sign_create_witness(address, &signable_bytes)) - .collect::, ProtocolError>>()?; + let mut input_witnesses: Vec = Vec::with_capacity(inputs.len()); + for address in inputs.keys() { + input_witnesses.push(signer.sign_create_witness(address, &signable_bytes).await?); + } + address_funds_transition.input_witnesses = input_witnesses; tracing::debug!("try_from_inputs_with_signer: Successfully created transition"); Ok(address_funds_transition.into()) diff --git a/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/methods/mod.rs index 18480ca03c0..09da2887ff5 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/methods/mod.rs @@ -15,7 +15,7 @@ use crate::ProtocolError; use platform_version::version::PlatformVersion; impl DataContractCreateTransitionMethodsV0 for DataContractCreateTransition { - fn new_from_data_contract>( + async fn new_from_data_contract>( data_contract: DataContract, identity_nonce: IdentityNonce, identity: &PartialIdentity, @@ -31,15 +31,18 @@ impl DataContractCreateTransitionMethodsV0 for DataContractCreateTransition { .contract_create_state_transition .default_current_version, ) { - 0 => DataContractCreateTransitionV0::new_from_data_contract( - data_contract, - identity_nonce, - identity, - key_id, - signer, - platform_version, - feature_version, - ), + 0 => { + DataContractCreateTransitionV0::new_from_data_contract( + data_contract, + identity_nonce, + identity, + key_id, + signer, + platform_version, + feature_version, + ) + .await + } v => Err(ProtocolError::UnknownVersionError(format!( "Unknown DataContractCreateTransition version for new_from_data_contract {v}" ))), diff --git a/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/methods/v0/mod.rs index 3847e90adc3..79913026afe 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/methods/v0/mod.rs @@ -26,7 +26,7 @@ pub trait DataContractCreateTransitionMethodsV0 { /// /// If successful, returns a `Result` containing a `StateTransition` /// object. Otherwise, returns `ProtocolError`. - fn new_from_data_contract>( + async fn new_from_data_contract>( data_contract: DataContract, identity_nonce: IdentityNonce, identity: &PartialIdentity, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/v0_methods.rs index 9f62777480b..b23ff294366 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/v0_methods.rs @@ -19,7 +19,7 @@ use crate::state_transition::StateTransition; use crate::version::FeatureVersion; impl DataContractCreateTransitionMethodsV0 for DataContractCreateTransitionV0 { - fn new_from_data_contract>( + async fn new_from_data_contract>( mut data_contract: DataContract, identity_nonce: IdentityNonce, identity: &PartialIdentity, @@ -84,7 +84,7 @@ impl DataContractCreateTransitionMethodsV0 for DataContractCreateTransitionV0 { } // There was an error here where the public key supplied was not one belonging to the signer. - match signer.sign(public_key, &value) { + match signer.sign(public_key, &value).await { Ok(signature) => { state_transition.set_signature(signature); } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/methods/mod.rs index eb3366de834..c34881479ea 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/methods/mod.rs @@ -16,7 +16,7 @@ use crate::prelude::{IdentityNonce, UserFeeIncrease}; use platform_version::version::PlatformVersion; impl DataContractUpdateTransitionMethodsV0 for DataContractUpdateTransition { - fn new_from_data_contract>( + async fn new_from_data_contract>( data_contract: DataContract, identity: &PartialIdentity, key_id: KeyID, @@ -33,16 +33,19 @@ impl DataContractUpdateTransitionMethodsV0 for DataContractUpdateTransition { .contract_update_state_transition .default_current_version, ) { - 0 => DataContractUpdateTransitionV0::new_from_data_contract( - data_contract, - identity, - key_id, - identity_contract_nonce, - user_fee_increase, - signer, - platform_version, - feature_version, - ), + 0 => { + DataContractUpdateTransitionV0::new_from_data_contract( + data_contract, + identity, + key_id, + identity_contract_nonce, + user_fee_increase, + signer, + platform_version, + feature_version, + ) + .await + } v => Err(ProtocolError::UnknownVersionError(format!( "Unknown DataContractUpdateTransition version for new_from_data_contract {v}" ))), diff --git a/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/methods/v0/mod.rs index 87d326a20de..c15d804f14b 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/methods/v0/mod.rs @@ -23,7 +23,7 @@ pub trait DataContractUpdateTransitionMethodsV0 { /// * `Result` - If successful, returns an instance of `DataContractUpdateTransition`. /// In case of any error, a relevant `ProtocolError` is returned. #[allow(clippy::too_many_arguments)] - fn new_from_data_contract>( + async fn new_from_data_contract>( data_contract: DataContract, identity: &PartialIdentity, key_id: KeyID, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/v0/v0_methods.rs index 6a3eea14b3d..e6e1c5f76f3 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/v0/v0_methods.rs @@ -15,7 +15,7 @@ use platform_version::version::PlatformVersion; use platform_version::TryIntoPlatformVersioned; impl DataContractUpdateTransitionMethodsV0 for DataContractUpdateTransitionV0 { - fn new_from_data_contract>( + async fn new_from_data_contract>( data_contract: DataContract, identity: &PartialIdentity, key_id: KeyID, @@ -44,7 +44,7 @@ impl DataContractUpdateTransitionMethodsV0 for DataContractUpdateTransitionV0 { "public key did not exist".to_string(), ), ))?; - state_transition.set_signature(signer.sign(public_key, &value)?); + state_transition.set_signature(signer.sign(public_key, &value).await?); Ok(state_transition) } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs index 50f614f0627..ad8d520cdc5 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs @@ -88,9 +88,9 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { } #[cfg(feature = "state-transition-signing")] - fn new_document_creation_transition_from_document>( + async fn new_document_creation_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, entropy: [u8; 32], identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, @@ -120,7 +120,8 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { signer, platform_version, options, - )?, + ) + .await?, ), 1 => Ok( BatchTransitionV1::new_document_creation_transition_from_document( @@ -134,7 +135,8 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { signer, platform_version, options, - )?, + ) + .await?, ), version => Err(ProtocolError::UnknownVersionMismatch { method: "DocumentsBatchTransition::new_created_from_document".to_string(), @@ -145,9 +147,9 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { } #[cfg(feature = "state-transition-signing")] - fn new_document_replacement_transition_from_document>( + async fn new_document_replacement_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, @@ -175,7 +177,8 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { signer, platform_version, options, - )?, + ) + .await?, ), 1 => Ok( BatchTransitionV1::new_document_replacement_transition_from_document( @@ -188,7 +191,8 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { signer, platform_version, options, - )?, + ) + .await?, ), version => Err(ProtocolError::UnknownVersionMismatch { method: @@ -201,9 +205,9 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { } #[cfg(feature = "state-transition-signing")] - fn new_document_transfer_transition_from_document>( + async fn new_document_transfer_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, recipient_owner_id: Identifier, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, @@ -233,7 +237,8 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { signer, platform_version, options, - )?, + ) + .await?, ), 1 => Ok( BatchTransitionV1::new_document_transfer_transition_from_document( @@ -247,7 +252,8 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { signer, platform_version, options, - )?, + ) + .await?, ), version => Err(ProtocolError::UnknownVersionMismatch { method: @@ -260,9 +266,9 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { } #[cfg(feature = "state-transition-signing")] - fn new_document_deletion_transition_from_document>( + async fn new_document_deletion_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, @@ -290,7 +296,8 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { signer, platform_version, options, - )?, + ) + .await?, ), 1 => Ok( BatchTransitionV1::new_document_deletion_transition_from_document( @@ -303,7 +310,8 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { signer, platform_version, options, - )?, + ) + .await?, ), version => Err(ProtocolError::UnknownVersionMismatch { method: "DocumentsBatchTransition::new_document_deletion_transition_from_document" @@ -315,9 +323,9 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { } #[cfg(feature = "state-transition-signing")] - fn new_document_update_price_transition_from_document>( + async fn new_document_update_price_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, price: Credits, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, @@ -347,7 +355,8 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { signer, platform_version, options, - )?, + ) + .await?, ), 1 => Ok( BatchTransitionV1::new_document_update_price_transition_from_document( @@ -361,7 +370,8 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { signer, platform_version, options, - )?, + ) + .await?, ), version => Err(ProtocolError::UnknownVersionMismatch { method: @@ -374,9 +384,9 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { } #[cfg(feature = "state-transition-signing")] - fn new_document_purchase_transition_from_document>( + async fn new_document_purchase_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, new_owner_id: Identifier, price: Credits, identity_public_key: &IdentityPublicKey, @@ -408,7 +418,8 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { signer, platform_version, options, - )?, + ) + .await?, ), 1 => Ok( BatchTransitionV1::new_document_purchase_transition_from_document( @@ -423,7 +434,8 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { signer, platform_version, options, - )?, + ) + .await?, ), version => Err(ProtocolError::UnknownVersionMismatch { method: "DocumentsBatchTransition::new_document_purchase_transition_from_document" @@ -437,7 +449,7 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { impl DocumentsBatchTransitionMethodsV1 for BatchTransition { #[cfg(feature = "state-transition-signing")] - fn new_token_mint_transition>( + async fn new_token_mint_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -485,6 +497,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { platform_version, options, ) + .await } version => Err(ProtocolError::UnknownVersionMismatch { method: "DocumentsBatchTransition::new_token_mint_transition".to_string(), @@ -495,7 +508,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { } #[cfg(feature = "state-transition-signing")] - fn new_token_burn_transition>( + async fn new_token_burn_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -541,6 +554,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { platform_version, options, ) + .await } version => Err(ProtocolError::UnknownVersionMismatch { method: "DocumentsBatchTransition::new_token_burn_transition".to_string(), @@ -551,7 +565,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { } #[cfg(feature = "state-transition-signing")] - fn new_token_transfer_transition>( + async fn new_token_transfer_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -602,6 +616,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { platform_version, options, ) + .await } version => Err(ProtocolError::UnknownVersionMismatch { method: "DocumentsBatchTransition::new_token_transfer_transition".to_string(), @@ -612,7 +627,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { } #[cfg(feature = "state-transition-signing")] - fn new_token_freeze_transition>( + async fn new_token_freeze_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -659,6 +674,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { platform_version, options, ) + .await } version => Err(ProtocolError::UnknownVersionMismatch { method: "DocumentsBatchTransition::new_token_freeze_transition".to_string(), @@ -669,7 +685,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { } #[cfg(feature = "state-transition-signing")] - fn new_token_unfreeze_transition>( + async fn new_token_unfreeze_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -716,6 +732,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { platform_version, options, ) + .await } version => Err(ProtocolError::UnknownVersionMismatch { method: "DocumentsBatchTransition::new_token_unfreeze_transition".to_string(), @@ -726,7 +743,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { } #[cfg(feature = "state-transition-signing")] - fn new_token_destroy_frozen_funds_transition>( + async fn new_token_destroy_frozen_funds_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -773,6 +790,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { platform_version, options, ) + .await } version => Err(ProtocolError::UnknownVersionMismatch { method: "DocumentsBatchTransition::new_token_destroy_frozen_funds_transition" @@ -784,7 +802,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { } #[cfg(feature = "state-transition-signing")] - fn new_token_emergency_action_transition>( + async fn new_token_emergency_action_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -831,6 +849,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { platform_version, options, ) + .await } version => Err(ProtocolError::UnknownVersionMismatch { method: "DocumentsBatchTransition::new_token_emergency_action_transition" @@ -842,7 +861,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { } #[cfg(feature = "state-transition-signing")] - fn new_token_config_update_transition>( + async fn new_token_config_update_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -889,6 +908,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { platform_version, options, ) + .await } version => Err(ProtocolError::UnknownVersionMismatch { method: "DocumentsBatchTransition::new_token_config_update_transition".to_string(), @@ -899,7 +919,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { } #[cfg(feature = "state-transition-signing")] - fn new_token_claim_transition>( + async fn new_token_claim_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -944,6 +964,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { platform_version, options, ) + .await } version => Err(ProtocolError::UnknownVersionMismatch { method: "DocumentsBatchTransition::new_token_claim_transition".to_string(), @@ -955,7 +976,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_token_change_direct_purchase_price_transition>( + async fn new_token_change_direct_purchase_price_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -1002,6 +1023,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { platform_version, options, ) + .await } version => Err(ProtocolError::UnknownVersionMismatch { method: @@ -1014,7 +1036,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { } #[cfg(feature = "state-transition-signing")] - fn new_token_direct_purchase_transition>( + async fn new_token_direct_purchase_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -1059,6 +1081,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { platform_version, options, ) + .await } version => Err(ProtocolError::UnknownVersionMismatch { method: "DocumentsBatchTransition::new_token_direct_purchase_transition" diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v0/mod.rs index 2d0770cca70..01d042c7a8a 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v0/mod.rs @@ -30,9 +30,9 @@ use crate::tokens::token_payment_info::TokenPaymentInfo; pub trait DocumentsBatchTransitionMethodsV0: DocumentsBatchTransitionAccessorsV0 { #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_document_creation_transition_from_document>( + async fn new_document_creation_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, entropy: [u8; 32], identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, @@ -45,9 +45,9 @@ pub trait DocumentsBatchTransitionMethodsV0: DocumentsBatchTransitionAccessorsV0 #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_document_replacement_transition_from_document>( + async fn new_document_replacement_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, @@ -59,9 +59,9 @@ pub trait DocumentsBatchTransitionMethodsV0: DocumentsBatchTransitionAccessorsV0 #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_document_deletion_transition_from_document>( + async fn new_document_deletion_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, @@ -73,9 +73,9 @@ pub trait DocumentsBatchTransitionMethodsV0: DocumentsBatchTransitionAccessorsV0 #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_document_transfer_transition_from_document>( + async fn new_document_transfer_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, recipient_owner_id: Identifier, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, @@ -88,9 +88,9 @@ pub trait DocumentsBatchTransitionMethodsV0: DocumentsBatchTransitionAccessorsV0 #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_document_update_price_transition_from_document>( + async fn new_document_update_price_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, price: Credits, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, @@ -103,9 +103,9 @@ pub trait DocumentsBatchTransitionMethodsV0: DocumentsBatchTransitionAccessorsV0 #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_document_purchase_transition_from_document>( + async fn new_document_purchase_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, new_owner_id: Identifier, price: Credits, identity_public_key: &IdentityPublicKey, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs index b4d3902b2d9..0e3e0340ffd 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs @@ -61,7 +61,7 @@ pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 /// - `signer`: Object implementing the signer trait that much contain the private key for the identity public key. #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_token_mint_transition>( + async fn new_token_mint_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -94,7 +94,7 @@ pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 /// - `signer`: Object implementing the signer trait that must contain the private key for the identity public key. #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_token_burn_transition>( + async fn new_token_burn_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -128,7 +128,7 @@ pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 /// - `signer`: Object implementing the signer trait that must contain the private key for the identity public key. #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_token_transfer_transition>( + async fn new_token_transfer_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -164,7 +164,7 @@ pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 /// - `signer`: Object implementing the signer trait that must contain the private key for the identity public key. #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_token_freeze_transition>( + async fn new_token_freeze_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -196,7 +196,7 @@ pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 /// - `signer`: Object implementing the signer trait that must contain the private key for the identity public key. #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_token_unfreeze_transition>( + async fn new_token_unfreeze_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -228,7 +228,7 @@ pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 /// - `signer`: Object implementing the signer trait that must contain the private key for the identity public key. #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_token_destroy_frozen_funds_transition>( + async fn new_token_destroy_frozen_funds_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -263,7 +263,7 @@ pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 /// - `signer`: Object implementing the signer trait that must contain the private key for the identity public key. #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_token_emergency_action_transition>( + async fn new_token_emergency_action_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -298,7 +298,7 @@ pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 /// - `signer`: Object implementing the signer trait that must contain the private key for the identity public key. #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_token_config_update_transition>( + async fn new_token_config_update_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -332,7 +332,7 @@ pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 /// - `signer`: Object implementing the signer trait that must contain the private key for the identity public key. #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_token_claim_transition>( + async fn new_token_claim_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -366,7 +366,7 @@ pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 /// - `signer`: Object implementing the signer trait that must contain the private key for the identity public key. #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_token_change_direct_purchase_price_transition>( + async fn new_token_change_direct_purchase_price_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -401,7 +401,7 @@ pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 /// - `signer`: Object implementing the signer trait that must contain the private key for the identity public key. #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn new_token_direct_purchase_transition>( + async fn new_token_direct_purchase_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/v0_methods.rs index 6da89d4b462..c122859f31f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/v0_methods.rs @@ -90,9 +90,9 @@ impl DocumentsBatchTransitionAccessorsV0 for BatchTransitionV0 { impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV0 { #[cfg(feature = "state-transition-signing")] - fn new_document_creation_transition_from_document>( + async fn new_document_creation_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, entropy: [u8; 32], identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, @@ -124,19 +124,21 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV0 { .into(); let mut state_transition: StateTransition = documents_batch_transition.into(); let required_security_level = document_type.security_level_requirement(); - state_transition.sign_external_with_options( - identity_public_key, - signer, - Some(|_, _| Ok(required_security_level)), - resolved_options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + Some(|_, _| Ok(required_security_level)), + resolved_options.signing_options, + ) + .await?; Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_document_replacement_transition_from_document>( + async fn new_document_replacement_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, @@ -166,19 +168,21 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV0 { .into(); let mut state_transition: StateTransition = documents_batch_transition.into(); let required_security_level = document_type.security_level_requirement(); - state_transition.sign_external_with_options( - identity_public_key, - signer, - Some(|_, _| Ok(required_security_level)), - resolved_options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + Some(|_, _| Ok(required_security_level)), + resolved_options.signing_options, + ) + .await?; Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_document_transfer_transition_from_document>( + async fn new_document_transfer_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, recipient_owner_id: Identifier, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, @@ -210,19 +214,21 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV0 { .into(); let mut state_transition: StateTransition = documents_batch_transition.into(); let required_security_level = document_type.security_level_requirement(); - state_transition.sign_external_with_options( - identity_public_key, - signer, - Some(|_, _| Ok(required_security_level)), - resolved_options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + Some(|_, _| Ok(required_security_level)), + resolved_options.signing_options, + ) + .await?; Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_document_deletion_transition_from_document>( + async fn new_document_deletion_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, @@ -252,19 +258,21 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV0 { .into(); let mut state_transition: StateTransition = documents_batch_transition.into(); let required_security_level = document_type.security_level_requirement(); - state_transition.sign_external_with_options( - identity_public_key, - signer, - Some(|_, _| Ok(required_security_level)), - resolved_options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + Some(|_, _| Ok(required_security_level)), + resolved_options.signing_options, + ) + .await?; Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_document_update_price_transition_from_document>( + async fn new_document_update_price_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, price: Credits, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, @@ -296,19 +304,21 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV0 { .into(); let mut state_transition: StateTransition = documents_batch_transition.into(); let required_security_level = document_type.security_level_requirement(); - state_transition.sign_external_with_options( - identity_public_key, - signer, - Some(|_, _| Ok(required_security_level)), - resolved_options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + Some(|_, _| Ok(required_security_level)), + resolved_options.signing_options, + ) + .await?; Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_document_purchase_transition_from_document>( + async fn new_document_purchase_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, new_owner_id: Identifier, price: Credits, identity_public_key: &IdentityPublicKey, @@ -340,12 +350,14 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV0 { .into(); let mut state_transition: StateTransition = documents_batch_transition.into(); let required_security_level = document_type.security_level_requirement(); - state_transition.sign_external_with_options( - identity_public_key, - signer, - Some(|_, _| Ok(required_security_level)), - resolved_options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + Some(|_, _| Ok(required_security_level)), + resolved_options.signing_options, + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs index d16922b7f6e..ddf692e75d8 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs @@ -99,9 +99,9 @@ impl DocumentsBatchTransitionAccessorsV0 for BatchTransitionV1 { impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV1 { #[cfg(feature = "state-transition-signing")] - fn new_document_creation_transition_from_document>( + async fn new_document_creation_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, entropy: [u8; 32], identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, @@ -133,19 +133,21 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV1 { .into(); let mut state_transition: StateTransition = documents_batch_transition.into(); let required_security_level = document_type.security_level_requirement(); - state_transition.sign_external_with_options( - identity_public_key, - signer, - Some(|_, _| Ok(required_security_level)), - resolved_options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + Some(|_, _| Ok(required_security_level)), + resolved_options.signing_options, + ) + .await?; Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_document_replacement_transition_from_document>( + async fn new_document_replacement_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, @@ -175,19 +177,21 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV1 { .into(); let mut state_transition: StateTransition = documents_batch_transition.into(); let required_security_level = document_type.security_level_requirement(); - state_transition.sign_external_with_options( - identity_public_key, - signer, - Some(|_, _| Ok(required_security_level)), - resolved_options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + Some(|_, _| Ok(required_security_level)), + resolved_options.signing_options, + ) + .await?; Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_document_deletion_transition_from_document>( + async fn new_document_deletion_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, @@ -217,19 +221,21 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV1 { .into(); let mut state_transition: StateTransition = documents_batch_transition.into(); let required_security_level = document_type.security_level_requirement(); - state_transition.sign_external_with_options( - identity_public_key, - signer, - Some(|_, _| Ok(required_security_level)), - resolved_options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + Some(|_, _| Ok(required_security_level)), + resolved_options.signing_options, + ) + .await?; Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_document_transfer_transition_from_document>( + async fn new_document_transfer_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, recipient_owner_id: Identifier, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, @@ -261,19 +267,21 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV1 { .into(); let mut state_transition: StateTransition = documents_batch_transition.into(); let required_security_level = document_type.security_level_requirement(); - state_transition.sign_external_with_options( - identity_public_key, - signer, - Some(|_, _| Ok(required_security_level)), - resolved_options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + Some(|_, _| Ok(required_security_level)), + resolved_options.signing_options, + ) + .await?; Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_document_update_price_transition_from_document>( + async fn new_document_update_price_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, price: Credits, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, @@ -305,19 +313,21 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV1 { .into(); let mut state_transition: StateTransition = documents_batch_transition.into(); let required_security_level = document_type.security_level_requirement(); - state_transition.sign_external_with_options( - identity_public_key, - signer, - Some(|_, _| Ok(required_security_level)), - resolved_options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + Some(|_, _| Ok(required_security_level)), + resolved_options.signing_options, + ) + .await?; Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_document_purchase_transition_from_document>( + async fn new_document_purchase_transition_from_document>( document: Document, - document_type: DocumentTypeRef, + document_type: DocumentTypeRef<'_>, new_owner_id: Identifier, price: Credits, identity_public_key: &IdentityPublicKey, @@ -349,12 +359,14 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV1 { .into(); let mut state_transition: StateTransition = documents_batch_transition.into(); let required_security_level = document_type.security_level_requirement(); - state_transition.sign_external_with_options( - identity_public_key, - signer, - Some(|_, _| Ok(required_security_level)), - resolved_options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + Some(|_, _| Ok(required_security_level)), + resolved_options.signing_options, + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v1_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v1_methods.rs index f0dde7145c0..1b5d848c9d6 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v1_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v1_methods.rs @@ -79,7 +79,7 @@ use crate::tokens::token_pricing_schedule::TokenPricingSchedule; impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { #[cfg(feature = "state-transition-signing")] - fn new_token_mint_transition>( + async fn new_token_mint_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -139,25 +139,29 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { .into(); let mut state_transition: StateTransition = documents_batch_transition.into(); if let Some(options) = options { - state_transition.sign_external_with_options( - identity_public_key, - signer, - None::, - options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + None::, + options.signing_options, + ) + .await?; } else { - state_transition.sign_external( - identity_public_key, - signer, - None::, - )?; + state_transition + .sign_external( + identity_public_key, + signer, + None::, + ) + .await?; } Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_token_burn_transition>( + async fn new_token_burn_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -218,24 +222,28 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { // Create the state transition let mut state_transition: StateTransition = documents_batch_transition.into(); if let Some(options) = options { - state_transition.sign_external_with_options( - identity_public_key, - signer, - None::, - options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + None::, + options.signing_options, + ) + .await?; } else { - state_transition.sign_external( - identity_public_key, - signer, - None::, - )?; + state_transition + .sign_external( + identity_public_key, + signer, + None::, + ) + .await?; } Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_token_transfer_transition>( + async fn new_token_transfer_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -281,25 +289,29 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { // Create the state transition let mut state_transition: StateTransition = documents_batch_transition.into(); if let Some(options) = options { - state_transition.sign_external_with_options( - identity_public_key, - signer, - None::, - options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + None::, + options.signing_options, + ) + .await?; } else { - state_transition.sign_external( - identity_public_key, - signer, - None::, - )?; + state_transition + .sign_external( + identity_public_key, + signer, + None::, + ) + .await?; } Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_token_freeze_transition>( + async fn new_token_freeze_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -360,24 +372,28 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { let mut state_transition: StateTransition = documents_batch_transition.into(); if let Some(options) = options { - state_transition.sign_external_with_options( - identity_public_key, - signer, - None::, - options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + None::, + options.signing_options, + ) + .await?; } else { - state_transition.sign_external( - identity_public_key, - signer, - None::, - )?; + state_transition + .sign_external( + identity_public_key, + signer, + None::, + ) + .await?; } Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_token_unfreeze_transition>( + async fn new_token_unfreeze_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -438,24 +454,28 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { let mut state_transition: StateTransition = documents_batch_transition.into(); if let Some(options) = options { - state_transition.sign_external_with_options( - identity_public_key, - signer, - None::, - options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + None::, + options.signing_options, + ) + .await?; } else { - state_transition.sign_external( - identity_public_key, - signer, - None::, - )?; + state_transition + .sign_external( + identity_public_key, + signer, + None::, + ) + .await?; } Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_token_destroy_frozen_funds_transition>( + async fn new_token_destroy_frozen_funds_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -518,24 +538,28 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { .into(); let mut state_transition: StateTransition = batch_transition.into(); if let Some(options) = options { - state_transition.sign_external_with_options( - identity_public_key, - signer, - None::, - options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + None::, + options.signing_options, + ) + .await?; } else { - state_transition.sign_external( - identity_public_key, - signer, - None::, - )?; + state_transition + .sign_external( + identity_public_key, + signer, + None::, + ) + .await?; } Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_token_emergency_action_transition>( + async fn new_token_emergency_action_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -596,24 +620,28 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { .into(); let mut state_transition: StateTransition = batch_transition.into(); if let Some(options) = options { - state_transition.sign_external_with_options( - identity_public_key, - signer, - None::, - options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + None::, + options.signing_options, + ) + .await?; } else { - state_transition.sign_external( - identity_public_key, - signer, - None::, - )?; + state_transition + .sign_external( + identity_public_key, + signer, + None::, + ) + .await?; } Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_token_config_update_transition>( + async fn new_token_config_update_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -674,24 +702,28 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { .into(); let mut state_transition: StateTransition = batch_transition.into(); if let Some(options) = options { - state_transition.sign_external_with_options( - identity_public_key, - signer, - None::, - options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + None::, + options.signing_options, + ) + .await?; } else { - state_transition.sign_external( - identity_public_key, - signer, - None::, - )?; + state_transition + .sign_external( + identity_public_key, + signer, + None::, + ) + .await?; } Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_token_claim_transition>( + async fn new_token_claim_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -727,24 +759,28 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { .into(); let mut state_transition: StateTransition = batch_transition.into(); if let Some(options) = options { - state_transition.sign_external_with_options( - identity_public_key, - signer, - None::, - options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + None::, + options.signing_options, + ) + .await?; } else { - state_transition.sign_external( - identity_public_key, - signer, - None::, - )?; + state_transition + .sign_external( + identity_public_key, + signer, + None::, + ) + .await?; } Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_token_change_direct_purchase_price_transition>( + async fn new_token_change_direct_purchase_price_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -809,24 +845,28 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { .into(); let mut state_transition: StateTransition = batch_transition.into(); if let Some(options) = options { - state_transition.sign_external_with_options( - identity_public_key, - signer, - None::, - options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + None::, + options.signing_options, + ) + .await?; } else { - state_transition.sign_external( - identity_public_key, - signer, - None::, - )?; + state_transition + .sign_external( + identity_public_key, + signer, + None::, + ) + .await?; } Ok(state_transition) } #[cfg(feature = "state-transition-signing")] - fn new_token_direct_purchase_transition>( + async fn new_token_direct_purchase_transition>( token_id: Identifier, owner_id: Identifier, data_contract_id: Identifier, @@ -863,18 +903,22 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { .into(); let mut state_transition: StateTransition = batch_transition.into(); if let Some(options) = options { - state_transition.sign_external_with_options( - identity_public_key, - signer, - None::, - options.signing_options, - )?; + state_transition + .sign_external_with_options( + identity_public_key, + signer, + None::, + options.signing_options, + ) + .await?; } else { - state_transition.sign_external( - identity_public_key, - signer, - None::, - )?; + state_transition + .sign_external( + identity_public_key, + signer, + None::, + ) + .await?; } Ok(state_transition) } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/methods/mod.rs index fc9267ff58f..63c00499068 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/methods/mod.rs @@ -33,7 +33,10 @@ use crate::ProtocolError; impl IdentityCreateFromAddressesTransitionMethodsV0 for IdentityCreateFromAddressesTransition { #[cfg(feature = "state-transition-signing")] - fn try_from_inputs_with_signer, WS: Signer>( + async fn try_from_inputs_with_signer< + S: Signer, + WS: Signer, + >( identity: &Identity, inputs: BTreeMap, output: Option<(PlatformAddress, Credits)>, @@ -57,7 +60,8 @@ impl IdentityCreateFromAddressesTransitionMethodsV0 for IdentityCreateFromAddres address_signer, user_fee_increase, platform_version, - )?), + ) + .await?), v => Err(ProtocolError::UnknownVersionError(format!( "Unknown IdentityCreateFromAddressesTransition version for try_from_inputs_with_signer {v}" ))), diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/methods/v0/mod.rs index 37e616e03e8..7dca9a7edb7 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/methods/v0/mod.rs @@ -28,7 +28,10 @@ use platform_version::version::PlatformVersion; pub trait IdentityCreateFromAddressesTransitionMethodsV0 { #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn try_from_inputs_with_signer, WS: Signer>( + async fn try_from_inputs_with_signer< + S: Signer, + WS: Signer, + >( identity: &Identity, inputs: BTreeMap, output: Option<(PlatformAddress, Credits)>, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/v0/v0_methods.rs index f668b42c0cd..63ad49a8ed5 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/v0/v0_methods.rs @@ -38,7 +38,10 @@ use crate::{ impl IdentityCreateFromAddressesTransitionMethodsV0 for IdentityCreateFromAddressesTransitionV0 { #[cfg(feature = "state-transition-signing")] - fn try_from_inputs_with_signer, WS: Signer>( + async fn try_from_inputs_with_signer< + S: Signer, + WS: Signer, + >( identity: &Identity, inputs: BTreeMap, output: Option<(PlatformAddress, Credits)>, @@ -72,23 +75,29 @@ impl IdentityCreateFromAddressesTransitionMethodsV0 for IdentityCreateFromAddres let signable_bytes = state_transition.signable_bytes()?; // Sign public keys with the identity public key signer (proof of possession) - identity_create_from_addresses_transition + for (public_key_with_witness, (_, public_key)) in identity_create_from_addresses_transition .public_keys .iter_mut() .zip(identity.public_keys().iter()) - .try_for_each(|(public_key_with_witness, (_, public_key))| { - if public_key.key_type().is_unique_key_type() { - let signature = identity_public_key_signer.sign(public_key, &signable_bytes)?; - public_key_with_witness.set_signature(signature); - } - Ok::<(), ProtocolError>(()) - })?; + { + if public_key.key_type().is_unique_key_type() { + let signature = identity_public_key_signer + .sign(public_key, &signable_bytes) + .await?; + public_key_with_witness.set_signature(signature); + } + } // Create witnesses for each input address - identity_create_from_addresses_transition.input_witnesses = inputs - .keys() - .map(|address| address_signer.sign_create_witness(address, &signable_bytes)) - .collect::, ProtocolError>>()?; + let mut input_witnesses = Vec::with_capacity(inputs.len()); + for address in inputs.keys() { + input_witnesses.push( + address_signer + .sign_create_witness(address, &signable_bytes) + .await?, + ); + } + identity_create_from_addresses_transition.input_witnesses = input_witnesses; Ok(identity_create_from_addresses_transition.into()) } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/methods/mod.rs index 300e53261f6..8f622bbd0ba 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/methods/mod.rs @@ -24,7 +24,7 @@ use crate::version::PlatformVersion; use crate::{BlsModule, ProtocolError}; impl IdentityCreateTransitionMethodsV0 for IdentityCreateTransition { #[cfg(feature = "state-transition-signing")] - fn try_from_identity_with_signer>( + async fn try_from_identity_with_signer>( identity: &Identity, asset_lock_proof: AssetLockProof, asset_lock_proof_private_key: &[u8], @@ -46,7 +46,8 @@ impl IdentityCreateTransitionMethodsV0 for IdentityCreateTransition { bls, user_fee_increase, platform_version, - )?), + ) + .await?), v => Err(ProtocolError::UnknownVersionError(format!( "Unknown IdentityCreateTransition version for try_from_identity_with_signer {v}" ))), diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/methods/v0/mod.rs index 9e921136274..561feb305a1 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/methods/v0/mod.rs @@ -18,7 +18,7 @@ use platform_version::version::PlatformVersion; pub trait IdentityCreateTransitionMethodsV0 { #[cfg(feature = "state-transition-signing")] - fn try_from_identity_with_signer>( + async fn try_from_identity_with_signer>( identity: &Identity, asset_lock_proof: AssetLockProof, asset_lock_proof_private_key: &[u8], diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/v0/v0_methods.rs index 88eddbc52d5..2a342b2b8d1 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/v0/v0_methods.rs @@ -35,7 +35,7 @@ use crate::state_transition::StateTransition; use crate::version::PlatformVersion; impl IdentityCreateTransitionMethodsV0 for IdentityCreateTransitionV0 { #[cfg(feature = "state-transition-signing")] - fn try_from_identity_with_signer>( + async fn try_from_identity_with_signer>( identity: &Identity, asset_lock_proof: AssetLockProof, asset_lock_proof_private_key: &[u8], @@ -62,17 +62,16 @@ impl IdentityCreateTransitionMethodsV0 for IdentityCreateTransitionV0 { let key_signable_bytes = state_transition.signable_bytes()?; - identity_create_transition + for (public_key_with_witness, (_, public_key)) in identity_create_transition .public_keys .iter_mut() .zip(identity.public_keys().iter()) - .try_for_each(|(public_key_with_witness, (_, public_key))| { - if public_key.key_type().is_unique_key_type() { - let signature = signer.sign(public_key, &key_signable_bytes)?; - public_key_with_witness.set_signature(signature); - } - Ok::<(), ProtocolError>(()) - })?; + { + if public_key.key_type().is_unique_key_type() { + let signature = signer.sign(public_key, &key_signable_bytes).await?; + public_key_with_witness.set_signature(signature); + } + } let mut state_transition: StateTransition = identity_create_transition.into(); diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/methods/mod.rs index 57534f0428c..b6a2016fe1c 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/methods/mod.rs @@ -26,7 +26,7 @@ impl IdentityCreditTransferToAddressesTransitionMethodsV0 for IdentityCreditTransferToAddressesTransition { #[cfg(feature = "state-transition-signing")] - fn try_from_identity>( + async fn try_from_identity>( identity: &Identity, to_recipient_addresses: BTreeMap, user_fee_increase: UserFeeIncrease, @@ -52,7 +52,8 @@ impl IdentityCreditTransferToAddressesTransitionMethodsV0 nonce, platform_version, version, - )?, + ) + .await?, ), version => Err(ProtocolError::UnknownVersionMismatch { method: "IdentityCreditTransferToAddressesTransition::try_from_identity" diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/methods/v0/mod.rs index f077b180bd4..3b9a686096c 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/methods/v0/mod.rs @@ -19,7 +19,7 @@ use platform_version::version::{FeatureVersion, PlatformVersion}; pub trait IdentityCreditTransferToAddressesTransitionMethodsV0 { #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn try_from_identity>( + async fn try_from_identity>( identity: &Identity, to_recipient_addresses: BTreeMap, user_fee_increase: UserFeeIncrease, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/v0/v0_methods.rs index 6827f46d772..bdb1697bf65 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/v0/v0_methods.rs @@ -28,7 +28,7 @@ impl IdentityCreditTransferToAddressesTransitionMethodsV0 for IdentityCreditTransferToAddressesTransitionV0 { #[cfg(feature = "state-transition-signing")] - fn try_from_identity>( + async fn try_from_identity>( identity: &Identity, to_recipient_addresses: BTreeMap, user_fee_increase: UserFeeIncrease, @@ -101,11 +101,14 @@ impl IdentityCreditTransferToAddressesTransitionMethodsV0 ); tracing::debug!("try_from_identity: Calling transition.sign_external"); - match transition.sign_external( - identity_public_key, - signer, - None::, - ) { + match transition + .sign_external( + identity_public_key, + signer, + None::, + ) + .await + { Ok(_) => tracing::debug!("try_from_identity: sign_external succeeded"), Err(e) => { tracing::error!(error = ?e, "try_from_identity: sign_external failed"); diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/mod.rs index 7a0324eda50..4033cdad667 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/mod.rs @@ -19,7 +19,7 @@ use platform_version::version::{FeatureVersion, PlatformVersion}; impl IdentityCreditTransferTransitionMethodsV0 for IdentityCreditTransferTransition { #[cfg(feature = "state-transition-signing")] - fn try_from_identity>( + async fn try_from_identity>( identity: &Identity, to_identity_with_identifier: Identifier, amount: u64, @@ -46,7 +46,8 @@ impl IdentityCreditTransferTransitionMethodsV0 for IdentityCreditTransferTransit nonce, platform_version, version, - )?), + ) + .await?), version => Err(ProtocolError::UnknownVersionMismatch { method: "IdentityCreditTransferTransition::try_from_identity".to_string(), known_versions: vec![0], diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/v0/mod.rs index 4404a22d99f..43b1f6c07ae 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/v0/mod.rs @@ -15,7 +15,7 @@ use crate::state_transition::StateTransitionType; pub trait IdentityCreditTransferTransitionMethodsV0 { #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn try_from_identity>( + async fn try_from_identity>( identity: &Identity, to_identity_with_identifier: Identifier, amount: u64, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs index a35fb291e53..7f8926efe70 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs @@ -21,7 +21,7 @@ use platform_version::version::{FeatureVersion, PlatformVersion}; impl IdentityCreditTransferTransitionMethodsV0 for IdentityCreditTransferTransitionV0 { #[cfg(feature = "state-transition-signing")] - fn try_from_identity>( + async fn try_from_identity>( identity: &Identity, to_identity_with_identifier: Identifier, amount: u64, @@ -83,11 +83,13 @@ impl IdentityCreditTransferTransitionMethodsV0 for IdentityCreditTransferTransit } }; - transition.sign_external( - identity_public_key, - &signer, - None::, - )?; + transition + .sign_external( + identity_public_key, + &signer, + None::, + ) + .await?; Ok(transition) } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/methods/mod.rs index 2e2f1b8c4b8..5095d674ddf 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/methods/mod.rs @@ -29,7 +29,7 @@ use crate::ProtocolError; impl IdentityCreditWithdrawalTransitionMethodsV0 for IdentityCreditWithdrawalTransition { #[cfg(feature = "state-transition-signing")] - fn try_from_identity>( + async fn try_from_identity>( identity: &Identity, output_script: Option, amount: u64, @@ -62,7 +62,8 @@ impl IdentityCreditWithdrawalTransitionMethodsV0 for IdentityCreditWithdrawalTra nonce, platform_version, version, - )?), + ) + .await?), version => Err(ProtocolError::UnknownVersionMismatch { method: "IdentityCreditWithdrawalTransition::try_from_identity".to_string(), known_versions: vec![1], diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/methods/v0/mod.rs index 532e82c2aa5..3d6de6c8706 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/methods/v0/mod.rs @@ -29,7 +29,7 @@ pub enum PreferredKeyPurposeForSigningWithdrawal { pub trait IdentityCreditWithdrawalTransitionMethodsV0 { #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn try_from_identity>( + async fn try_from_identity>( identity: &Identity, output_script: Option, amount: u64, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v1/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v1/v0_methods.rs index 21e5df7755f..6a8e5744094 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v1/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v1/v0_methods.rs @@ -21,7 +21,7 @@ use crate::state_transition::identity_credit_withdrawal_transition::v1::Identity impl IdentityCreditWithdrawalTransitionMethodsV0 for IdentityCreditWithdrawalTransitionV1 { #[cfg(feature = "state-transition-signing")] - fn try_from_identity>( + async fn try_from_identity>( identity: &Identity, output_script: Option, amount: u64, @@ -126,11 +126,13 @@ impl IdentityCreditWithdrawalTransitionMethodsV0 for IdentityCreditWithdrawalTra } }; - transition.sign_external( - identity_public_key, - &signer, - None::, - )?; + transition + .sign_external( + identity_public_key, + &signer, + None::, + ) + .await?; Ok(transition) } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/methods/mod.rs index 5afe26ed7ed..cf12c8b06f6 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/methods/mod.rs @@ -30,7 +30,7 @@ use platform_version::version::PlatformVersion; impl IdentityTopUpFromAddressesTransitionMethodsV0 for IdentityTopUpFromAddressesTransition { #[cfg(feature = "state-transition-signing")] - fn try_from_inputs_with_signer>( + async fn try_from_inputs_with_signer>( identity: &Identity, inputs: BTreeMap, signer: &S, @@ -52,7 +52,8 @@ impl IdentityTopUpFromAddressesTransitionMethodsV0 for IdentityTopUpFromAddresse user_fee_increase, platform_version, version, - )?, + ) + .await?, ), v => Err(ProtocolError::UnknownVersionError(format!( "Unknown IdentityTopUpFromAddressesTransition version for try_from_identity {v}" diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/methods/v0/mod.rs index d34cb4b117e..01b2bdf46a9 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/methods/v0/mod.rs @@ -23,7 +23,7 @@ use { pub trait IdentityTopUpFromAddressesTransitionMethodsV0 { #[cfg(feature = "state-transition-signing")] - fn try_from_inputs_with_signer>( + async fn try_from_inputs_with_signer>( identity: &Identity, inputs: BTreeMap, signer: &S, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/v0/v0_methods.rs index 15aa6deba70..085f23837d8 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/v0/v0_methods.rs @@ -28,7 +28,7 @@ use { impl IdentityTopUpFromAddressesTransitionMethodsV0 for IdentityTopUpFromAddressesTransitionV0 { #[cfg(feature = "state-transition-signing")] - fn try_from_inputs_with_signer>( + async fn try_from_inputs_with_signer>( identity: &Identity, inputs: BTreeMap, signer: &S, @@ -53,10 +53,11 @@ impl IdentityTopUpFromAddressesTransitionMethodsV0 for IdentityTopUpFromAddresse let signable_bytes = state_transition.signable_bytes()?; - identity_top_up_from_addresses_transition.input_witnesses = inputs - .keys() - .map(|address| signer.sign_create_witness(address, &signable_bytes)) - .collect::, ProtocolError>>()?; + let mut input_witnesses: Vec = Vec::with_capacity(inputs.len()); + for address in inputs.keys() { + input_witnesses.push(signer.sign_create_witness(address, &signable_bytes).await?); + } + identity_top_up_from_addresses_transition.input_witnesses = input_witnesses; Ok(identity_top_up_from_addresses_transition.into()) } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/methods/mod.rs index ba91113021f..e578e578345 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/methods/mod.rs @@ -24,7 +24,7 @@ use platform_version::version::PlatformVersion; impl IdentityUpdateTransitionMethodsV0 for IdentityUpdateTransition { #[cfg(feature = "state-transition-signing")] - fn try_from_identity_with_signer>( + async fn try_from_identity_with_signer>( identity: &Identity, master_public_key_id: &KeyID, add_public_keys: Vec, @@ -52,7 +52,8 @@ impl IdentityUpdateTransitionMethodsV0 for IdentityUpdateTransition { signer, platform_version, version, - )?), + ) + .await?), v => Err(ProtocolError::UnknownVersionError(format!( "Unknown IdentityUpdateTransition version for try_from_identity_with_signer {v}" ))), diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/methods/v0/mod.rs index acb1bd7236d..9c0d00c3f80 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/methods/v0/mod.rs @@ -17,7 +17,7 @@ use platform_version::version::PlatformVersion; pub trait IdentityUpdateTransitionMethodsV0 { #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn try_from_identity_with_signer>( + async fn try_from_identity_with_signer>( identity: &Identity, master_public_key_id: &KeyID, add_public_keys: Vec, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/v0/v0_methods.rs index cc9a790a570..a975040c95f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/v0/v0_methods.rs @@ -41,7 +41,7 @@ use crate::{identity::SecurityLevel, ProtocolError}; impl IdentityUpdateTransitionMethodsV0 for IdentityUpdateTransitionV0 { #[cfg(feature = "state-transition-signing")] - fn try_from_identity_with_signer<'a, S: Signer>( + async fn try_from_identity_with_signer>( identity: &Identity, master_public_key_id: &KeyID, add_public_keys: Vec, @@ -73,18 +73,16 @@ impl IdentityUpdateTransitionMethodsV0 for IdentityUpdateTransitionV0 { let key_signable_bytes = state_transition.signable_bytes()?; // Sign all the keys - identity_update_transition + for (public_key_with_witness, public_key) in identity_update_transition .add_public_keys .iter_mut() .zip(add_public_keys.iter()) - .try_for_each(|(public_key_with_witness, public_key)| { - if public_key.key_type().is_unique_key_type() { - let signature = signer.sign(public_key, &key_signable_bytes)?; - public_key_with_witness.set_signature(signature); - } - - Ok::<(), ProtocolError>(()) - })?; + { + if public_key.key_type().is_unique_key_type() { + let signature = signer.sign(public_key, &key_signable_bytes).await?; + public_key_with_witness.set_signature(signature); + } + } let master_public_key = identity .public_keys() @@ -104,11 +102,13 @@ impl IdentityUpdateTransitionMethodsV0 for IdentityUpdateTransitionV0 { )) } else { let mut state_transition: StateTransition = identity_update_transition.into(); - state_transition.sign_external( - master_public_key, - signer, - None::, - )?; + state_transition + .sign_external( + master_public_key, + signer, + None::, + ) + .await?; Ok(state_transition) } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/methods/mod.rs index 048b51614ad..96526db14a2 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/methods/mod.rs @@ -25,7 +25,7 @@ use crate::voting::votes::Vote; impl MasternodeVoteTransitionMethodsV0 for MasternodeVoteTransition { #[cfg(feature = "state-transition-signing")] - fn try_from_vote_with_signer>( + async fn try_from_vote_with_signer>( vote: Vote, signer: &S, pro_tx_hash: Identifier, @@ -47,7 +47,8 @@ impl MasternodeVoteTransitionMethodsV0 for MasternodeVoteTransition { pro_tx_hash, masternode_voting_key, nonce, - )?), + ) + .await?), version => Err(ProtocolError::UnknownVersionMismatch { method: "MasternodeVoteTransition::try_from_vote_with_signer".to_string(), known_versions: vec![0], diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/methods/v0/mod.rs index fbd35d8034b..bd192063e4d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/methods/v0/mod.rs @@ -18,7 +18,7 @@ use platform_version::version::{FeatureVersion, PlatformVersion}; pub trait MasternodeVoteTransitionMethodsV0 { #[cfg(feature = "state-transition-signing")] - fn try_from_vote_with_signer>( + async fn try_from_vote_with_signer>( vote: Vote, signer: &S, pro_tx_hash: Identifier, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/v0/v0_methods.rs index 8bc9a7dc0a5..f61465de37f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/v0/v0_methods.rs @@ -23,7 +23,7 @@ use crate::state_transition::masternode_vote_transition::v0::MasternodeVoteTrans impl MasternodeVoteTransitionV0 { #[cfg(feature = "state-transition-signing")] - pub fn try_from_vote_with_signer>( + pub async fn try_from_vote_with_signer>( vote: Vote, signer: &S, pro_tx_hash: Identifier, @@ -43,11 +43,13 @@ impl MasternodeVoteTransitionV0 { } .into(); let mut state_transition: StateTransition = masternode_vote_transition.into(); - state_transition.sign_external( - masternode_voting_key, - signer, - None:: Result>, - )?; + state_transition + .sign_external( + masternode_voting_key, + signer, + None:: Result>, + ) + .await?; Ok(state_transition) } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/from_public_key_signed_external/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/from_public_key_signed_external/mod.rs index 30159b6cdbd..0485308fb52 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/from_public_key_signed_external/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/from_public_key_signed_external/mod.rs @@ -8,7 +8,7 @@ use crate::ProtocolError; use platform_version::version::PlatformVersion; impl IdentityPublicKeyInCreation { - pub fn from_public_key_signed_external>( + pub async fn from_public_key_signed_external>( public_key: IdentityPublicKey, state_transition_bytes: &[u8], signer: &S, @@ -22,6 +22,7 @@ impl IdentityPublicKeyInCreation { { 0 => { Self::from_public_key_signed_external_v0(public_key, state_transition_bytes, signer) + .await } version => Err(ProtocolError::UnknownVersionMismatch { method: "IdentityPublicKeyInCreation::from_public_key_signed_external".to_string(), diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/from_public_key_signed_external/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/from_public_key_signed_external/v0/mod.rs index 0bc2ba52a7b..0079d20241c 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/from_public_key_signed_external/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/from_public_key_signed_external/v0/mod.rs @@ -6,7 +6,7 @@ use crate::state_transition::public_key_in_creation::IdentityPublicKeyInCreation use crate::ProtocolError; impl IdentityPublicKeyInCreation { - pub(super) fn from_public_key_signed_external_v0>( + pub(super) async fn from_public_key_signed_external_v0>( public_key: IdentityPublicKey, state_transition_bytes: &[u8], signer: &S, @@ -15,7 +15,7 @@ impl IdentityPublicKeyInCreation { match public_key.key_type() { KeyType::ECDSA_SECP256K1 | KeyType::BLS12_381 => { public_key_with_witness - .set_signature(signer.sign(&public_key, state_transition_bytes)?); + .set_signature(signer.sign(&public_key, state_transition_bytes).await?); } KeyType::ECDSA_HASH160 | KeyType::BIP13_SCRIPT_HASH | KeyType::EDDSA_25519_HASH160 => { // don't sign (on purpose) diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/methods/mod.rs index d87fb75333d..219d9415b19 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/methods/mod.rs @@ -24,7 +24,7 @@ use platform_version::version::PlatformVersion; impl ShieldTransitionMethodsV0 for ShieldTransition { #[cfg(feature = "state-transition-signing")] - fn try_from_bundle_with_signer>( + async fn try_from_bundle_with_signer>( inputs: BTreeMap, actions: Vec, amount: u64, @@ -42,18 +42,21 @@ impl ShieldTransitionMethodsV0 for ShieldTransition { .shield_state_transition .default_current_version { - 0 => ShieldTransitionV0::try_from_bundle_with_signer( - inputs, - actions, - amount, - anchor, - proof, - binding_signature, - fee_strategy, - signer, - user_fee_increase, - platform_version, - ), + 0 => { + ShieldTransitionV0::try_from_bundle_with_signer( + inputs, + actions, + amount, + anchor, + proof, + binding_signature, + fee_strategy, + signer, + user_fee_increase, + platform_version, + ) + .await + } version => Err(ProtocolError::UnknownVersionMismatch { method: "ShieldTransition::try_from_bundle_with_signer".to_string(), known_versions: vec![0], diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/methods/v0/mod.rs index ea69b2a435a..d82041b5988 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/methods/v0/mod.rs @@ -22,7 +22,7 @@ use platform_version::version::PlatformVersion; pub trait ShieldTransitionMethodsV0 { #[cfg(feature = "state-transition-signing")] #[allow(clippy::too_many_arguments)] - fn try_from_bundle_with_signer>( + async fn try_from_bundle_with_signer>( inputs: BTreeMap, actions: Vec, amount: u64, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/v0/v0_methods.rs index 28565600d97..28940449e9f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/v0/v0_methods.rs @@ -24,7 +24,7 @@ use platform_version::version::PlatformVersion; impl ShieldTransitionMethodsV0 for ShieldTransitionV0 { #[cfg(feature = "state-transition-signing")] - fn try_from_bundle_with_signer>( + async fn try_from_bundle_with_signer>( inputs: BTreeMap, actions: Vec, amount: u64, @@ -54,10 +54,11 @@ impl ShieldTransitionMethodsV0 for ShieldTransitionV0 { let signable_bytes = state_transition.signable_bytes()?; // Sign each input address - shield_transition.input_witnesses = inputs - .keys() - .map(|address| signer.sign_create_witness(address, &signable_bytes)) - .collect::, ProtocolError>>()?; + let mut input_witnesses: Vec = Vec::with_capacity(inputs.len()); + for address in inputs.keys() { + input_witnesses.push(signer.sign_create_witness(address, &signable_bytes).await?); + } + shield_transition.input_witnesses = input_witnesses; Ok(shield_transition.into()) } diff --git a/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs b/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs index acacd8cb07b..522bba25dd9 100644 --- a/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs @@ -2252,8 +2252,8 @@ mod tests { )); } - #[test] - fn document_update_check_tx() { + #[tokio::test] + async fn document_update_check_tx() { let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -2327,6 +2327,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -2384,6 +2385,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -2402,6 +2404,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition = documents_batch_update_transition @@ -2448,8 +2451,8 @@ mod tests { assert_eq!(validation_result.errors.as_slice(), &[]); } - #[test] - fn identity_top_up_check_tx() { + #[tokio::test] + async fn identity_top_up_check_tx() { let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -2522,6 +2525,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -2597,8 +2601,8 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn identity_cant_double_top_up() { + #[tokio::test] + async fn identity_cant_double_top_up() { let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -2671,6 +2675,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -2882,8 +2887,8 @@ mod tests { )); } - #[test] - fn identity_cant_create_with_used_outpoint() { + #[tokio::test] + async fn identity_cant_create_with_used_outpoint() { let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -2956,6 +2961,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -3071,6 +3077,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -3110,8 +3117,8 @@ mod tests { )); } - #[test] - fn identity_can_create_with_semi_used_outpoint() { + #[tokio::test] + async fn identity_can_create_with_semi_used_outpoint() { let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -3184,6 +3191,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let valid_identity_create_transition = identity_create_transition.clone(); @@ -3261,6 +3269,7 @@ mod tests { 1, platform_version, ) + .await .expect("expected an identity create transition"); let valid_identity_create_serialized_transition = valid_identity_create_transition @@ -3373,6 +3382,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -3412,8 +3422,8 @@ mod tests { )); } - #[test] - fn identity_update_with_non_master_key_check_tx() { + #[tokio::test] + async fn identity_update_with_non_master_key_check_tx() { let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -3479,6 +3489,7 @@ mod tests { update_transition.set_signature( signer .sign(&key, data.as_slice()) + .await .expect("expected to sign"), ); @@ -3512,8 +3523,8 @@ mod tests { ); } - #[test] - fn identity_update_with_encryption_key_check_tx() { + #[tokio::test] + async fn identity_update_with_encryption_key_check_tx() { let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -3578,6 +3589,7 @@ mod tests { update_transition.set_signature( signer .sign(&key, data.as_slice()) + .await .expect("expected to sign"), ); @@ -3606,8 +3618,8 @@ mod tests { assert_eq!(validation_result.errors.len(), 0); } - #[test] - fn token_mint_confirmation_check_tx() { + #[tokio::test] + async fn token_mint_confirmation_check_tx() { let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -3679,6 +3691,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_mint_serialized_transition = token_mint_transition @@ -3743,6 +3756,7 @@ mod tests { platform_version, None, ) + .await .expect("expected to create confirmation transition"); let confirm_serialized = confirm_transition diff --git a/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/tests.rs b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/tests.rs index cd44ad02945..1f57b3a70a8 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/tests.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/tests.rs @@ -36,9 +36,9 @@ mod refund_tests { // There's a fee for the first document that a user creates on a contract as they add space // For the identity data contract nonce - fn setup_join_contract_document( + async fn setup_join_contract_document( platform: &TempPlatform, - profile: DocumentTypeRef, + profile: DocumentTypeRef<'_>, rng: &mut StdRng, identity: &Identity, key: &IdentityPublicKey, @@ -84,6 +84,7 @@ mod refund_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let (mut fee_results, processed_block_fee_outcome) = process_state_transitions( @@ -130,10 +131,10 @@ mod refund_tests { expected_user_balance_after_creation } - fn setup_initial_document( + async fn setup_initial_document( platform: &TempPlatform, dashpay: &DataContract, - profile: DocumentTypeRef, + profile: DocumentTypeRef<'_>, rng: &mut StdRng, identity: &Identity, key: &IdentityPublicKey, @@ -142,7 +143,7 @@ mod refund_tests { // Let's make another document first just so the operations of joining a contract are out of the way // (A user pays to add some data to the state on the first time they make their first document for a contract) let user_credits_left = - setup_join_contract_document(platform, profile, rng, identity, key, signer); + setup_join_contract_document(platform, profile, rng, identity, key, signer).await; let platform_version = PlatformVersion::latest(); @@ -191,6 +192,7 @@ mod refund_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let (mut fee_results, _) = process_state_transitions( @@ -260,8 +262,8 @@ mod refund_tests { (document, fee_result, expected_user_balance_after_creation) } - #[test] - fn test_document_refund_immediate() { + #[tokio::test] + async fn test_document_refund_immediate() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -303,7 +305,8 @@ mod refund_tests { &identity, &key, &signer, - ); + ) + .await; let documents_batch_delete_transition = BatchTransition::new_document_deletion_transition_from_document( @@ -317,6 +320,7 @@ mod refund_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let (mut fee_results, _) = process_state_transitions( @@ -365,8 +369,8 @@ mod refund_tests { expected_user_balance_after_deletion, ); } - #[test] - fn test_document_refund_after_an_epoch() { + #[tokio::test] + async fn test_document_refund_after_an_epoch() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -406,7 +410,8 @@ mod refund_tests { &identity, &key, &signer, - ); + ) + .await; fast_forward_to_block(&platform, 1_200_000_000, 900, 42, 1, false); //next epoch @@ -422,6 +427,7 @@ mod refund_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let platform_state = platform.state.load(); @@ -473,8 +479,8 @@ mod refund_tests { ); } - #[test] - fn test_document_refund_after_a_year() { + #[tokio::test] + async fn test_document_refund_after_a_year() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -514,7 +520,8 @@ mod refund_tests { &identity, &key, &signer, - ); + ) + .await; fast_forward_to_block(&platform, 1_200_000_000, 900, 42, 40, false); //a year later @@ -530,6 +537,7 @@ mod refund_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let platform_state = platform.state.load(); @@ -577,8 +585,8 @@ mod refund_tests { ); } - #[test] - fn test_document_refund_after_25_years() { + #[tokio::test] + async fn test_document_refund_after_25_years() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -618,7 +626,8 @@ mod refund_tests { &identity, &key, &signer, - ); + ) + .await; fast_forward_to_block(&platform, 10_200_000_000, 9000, 42, 40 * 25, false); //25 years later @@ -634,6 +643,7 @@ mod refund_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let platform_state = platform.state.load(); @@ -681,8 +691,8 @@ mod refund_tests { ); } - #[test] - fn test_document_refund_after_50_years() { + #[tokio::test] + async fn test_document_refund_after_50_years() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -722,7 +732,8 @@ mod refund_tests { &identity, &key, &signer, - ); + ) + .await; fast_forward_to_block(&platform, 10_200_000_000, 9000, 42, 40 * 50, false); //50 years later @@ -738,6 +749,7 @@ mod refund_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let platform_state = platform.state.load(); @@ -784,8 +796,8 @@ mod refund_tests { ); } - #[test] - fn test_document_refund_after_10_epochs_on_different_fee_version_increasing_fees() { + #[tokio::test] + async fn test_document_refund_after_10_epochs_on_different_fee_version_increasing_fees() { let platform_version = PlatformVersion::latest(); let platform_version_with_higher_fees = platform_version.clone(); @@ -827,7 +839,8 @@ mod refund_tests { &identity, &key, &signer, - ); + ) + .await; fast_forward_to_block(&platform, 1_200_000_000, 900, 42, 10, false); //next epoch @@ -843,6 +856,7 @@ mod refund_tests { &platform_version_with_higher_fees, None, ) + .await .expect("expect to create documents batch transition"); let mut platform_state = platform.state.load().clone().deref().clone(); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs index 112457fd596..b11c1c13b45 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs @@ -497,7 +497,7 @@ mod tests { /// Helper to build a signed DataContractCreate StateTransition and return it alongside /// the platform instance. This keeps individual tests concise. - fn setup_data_contract_create_transition( + async fn setup_data_contract_create_transition( credits: dpp::fee::Credits, ) -> ( crate::test::helpers::setup::TempPlatform, @@ -532,6 +532,7 @@ mod tests { platform_version, None, ) + .await .expect("expected to create transition"); let state_transition: StateTransition = data_contract_create_transition.into(); @@ -542,11 +543,11 @@ mod tests { mod first_time_check { use super::*; - #[test] - fn should_return_valid_result_for_data_contract_create() { + #[tokio::test] + async fn should_return_valid_result_for_data_contract_create() { let platform_version = PlatformVersion::latest(); let (platform, state_transition) = - setup_data_contract_create_transition(dash_to_credits!(2.0)); + setup_data_contract_create_transition(dash_to_credits!(2.0)).await; let platform_state = platform.state.load(); let platform_ref = PlatformRef { @@ -575,12 +576,12 @@ mod tests { assert!(validation_result.data.unwrap().is_some()); } - #[test] - fn should_return_invalid_result_for_insufficient_balance() { + #[tokio::test] + async fn should_return_invalid_result_for_insufficient_balance() { let platform_version = PlatformVersion::latest(); // Give the identity very little balance -- not enough for the data contract create. // The minimum balance pre-check should reject this. - let (platform, state_transition) = setup_data_contract_create_transition(1); + let (platform, state_transition) = setup_data_contract_create_transition(1).await; let platform_state = platform.state.load(); let platform_ref = PlatformRef { @@ -608,8 +609,8 @@ mod tests { ); } - #[test] - fn should_return_invalid_result_for_bad_signature() { + #[tokio::test] + async fn should_return_invalid_result_for_bad_signature() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -640,6 +641,7 @@ mod tests { platform_version, None, ) + .await .expect("expected to create transition"); let mut state_transition: StateTransition = data_contract_create_transition.into(); @@ -670,11 +672,11 @@ mod tests { ); } - #[test] - fn should_return_invalid_result_for_replayed_nonce() { + #[tokio::test] + async fn should_return_invalid_result_for_replayed_nonce() { let platform_version = PlatformVersion::latest(); let (platform, state_transition) = - setup_data_contract_create_transition(dash_to_credits!(2.0)); + setup_data_contract_create_transition(dash_to_credits!(2.0)).await; let serialized = state_transition .serialize_to_bytes() @@ -739,11 +741,11 @@ mod tests { mod recheck { use super::*; - #[test] - fn should_return_valid_result_for_data_contract_create_recheck() { + #[tokio::test] + async fn should_return_valid_result_for_data_contract_create_recheck() { let platform_version = PlatformVersion::latest(); let (platform, state_transition) = - setup_data_contract_create_transition(dash_to_credits!(2.0)); + setup_data_contract_create_transition(dash_to_credits!(2.0)).await; let platform_state = platform.state.load(); let platform_ref = PlatformRef { @@ -775,11 +777,11 @@ mod tests { ); } - #[test] - fn should_return_invalid_result_for_replayed_nonce_on_recheck() { + #[tokio::test] + async fn should_return_invalid_result_for_replayed_nonce_on_recheck() { let platform_version = PlatformVersion::latest(); let (platform, state_transition) = - setup_data_contract_create_transition(dash_to_credits!(2.0)); + setup_data_contract_create_transition(dash_to_credits!(2.0)).await; let serialized = state_transition .serialize_to_bytes() diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_credit_withdrawal/tests.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_credit_withdrawal/tests.rs index 4fb2b771b80..252e161ee6a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_credit_withdrawal/tests.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_credit_withdrawal/tests.rs @@ -131,7 +131,7 @@ mod tests { } /// Create a signed AddressCreditWithdrawalTransition - fn create_signed_address_credit_withdrawal_transition( + async fn create_signed_address_credit_withdrawal_transition( signer: &TestAddressSigner, inputs: BTreeMap, output: Option<(PlatformAddress, u64)>, @@ -146,9 +146,10 @@ mod tests { output_script, 0, ) + .await } - fn create_signed_address_credit_withdrawal_transition_with_fee_increase( + async fn create_signed_address_credit_withdrawal_transition_with_fee_increase( signer: &TestAddressSigner, inputs: BTreeMap, output: Option<(PlatformAddress, u64)>, @@ -167,6 +168,7 @@ mod tests { user_fee_increase, PlatformVersion::latest(), ) + .await .expect("should create signed transition") } @@ -936,8 +938,8 @@ mod tests { mod successful_transitions { use super::*; - #[test] - fn test_simple_withdrawal_from_single_address() { + #[tokio::test] + async fn test_simple_withdrawal_from_single_address() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -968,7 +970,8 @@ mod tests { None, // No change output vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1000,8 +1003,8 @@ mod tests { ); } - #[test] - fn test_withdrawal_with_change_output() { + #[tokio::test] + async fn test_withdrawal_with_change_output() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1035,7 +1038,8 @@ mod tests { output, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1067,8 +1071,8 @@ mod tests { ); } - #[test] - fn test_withdrawal_from_multiple_inputs() { + #[tokio::test] + async fn test_withdrawal_from_multiple_inputs() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1105,7 +1109,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1137,8 +1142,8 @@ mod tests { ); } - #[test] - fn test_withdrawal_with_fee_deducted_from_output() { + #[tokio::test] + async fn test_withdrawal_with_fee_deducted_from_output() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1172,7 +1177,8 @@ mod tests { output, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1204,8 +1210,8 @@ mod tests { ); } - #[test] - fn test_withdrawal_with_user_fee_increase() { + #[tokio::test] + async fn test_withdrawal_with_user_fee_increase() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1238,7 +1244,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), 100, // 1% fee increase - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1279,8 +1286,8 @@ mod tests { mod state_verification { use super::*; - #[test] - fn test_balance_decreases_after_withdrawal() { + #[tokio::test] + async fn test_balance_decreases_after_withdrawal() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1322,7 +1329,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1379,8 +1387,8 @@ mod tests { ); } - #[test] - fn test_output_address_receives_credits() { + #[tokio::test] + async fn test_output_address_receives_credits() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1426,7 +1434,8 @@ mod tests { output, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1473,8 +1482,8 @@ mod tests { ); } - #[test] - fn test_multiple_inputs_all_decremented() { + #[tokio::test] + async fn test_multiple_inputs_all_decremented() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1508,7 +1517,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1578,8 +1588,8 @@ mod tests { mod state_validation { use super::*; - #[test] - fn test_input_address_does_not_exist_returns_error() { + #[tokio::test] + async fn test_input_address_does_not_exist_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1610,7 +1620,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1644,8 +1655,8 @@ mod tests { ); } - #[test] - fn test_insufficient_balance_in_input_returns_error() { + #[tokio::test] + async fn test_insufficient_balance_in_input_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1678,7 +1689,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1712,8 +1724,8 @@ mod tests { ); } - #[test] - fn test_wrong_nonce_returns_error() { + #[tokio::test] + async fn test_wrong_nonce_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1746,7 +1758,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1788,8 +1801,8 @@ mod tests { mod signature_validation { use super::*; - #[test] - fn test_signature_from_different_key_for_input_returns_error() { + #[tokio::test] + async fn test_signature_from_different_key_for_input_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1839,7 +1852,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2015,8 +2029,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_multiple_inputs_one_wrong_signature_returns_error() { + #[tokio::test] + async fn test_multiple_inputs_one_wrong_signature_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2059,6 +2073,7 @@ mod tests { // First input: correct signature let witness = signer .sign_create_witness(key, &data_to_sign) + .await .expect("should sign"); witnesses.push(witness); } else { @@ -2121,8 +2136,8 @@ mod tests { mod p2sh_multisig { use super::*; - #[test] - fn test_withdrawal_with_p2sh_multisig_input() { + #[tokio::test] + async fn test_withdrawal_with_p2sh_multisig_input() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2154,7 +2169,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2186,8 +2202,8 @@ mod tests { ); } - #[test] - fn test_withdrawal_with_mixed_p2pkh_and_p2sh_inputs() { + #[tokio::test] + async fn test_withdrawal_with_mixed_p2pkh_and_p2sh_inputs() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2225,7 +2241,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2343,8 +2360,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_p2sh_1_of_2_multisig_succeeds() { + #[tokio::test] + async fn test_p2sh_1_of_2_multisig_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2376,7 +2393,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2408,8 +2426,8 @@ mod tests { ); } - #[test] - fn test_p2sh_3_of_3_multisig_succeeds() { + #[tokio::test] + async fn test_p2sh_3_of_3_multisig_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2441,7 +2459,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2578,8 +2597,8 @@ mod tests { mod error_type_verification { use super::*; - #[test] - fn test_address_does_not_exist_returns_specific_error() { + #[tokio::test] + async fn test_address_does_not_exist_returns_specific_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2610,7 +2629,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2641,8 +2661,8 @@ mod tests { ); } - #[test] - fn test_insufficient_balance_returns_specific_error_with_amounts() { + #[tokio::test] + async fn test_insufficient_balance_returns_specific_error_with_amounts() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2675,7 +2695,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2708,8 +2729,8 @@ mod tests { ); } - #[test] - fn test_invalid_nonce_returns_specific_error_with_values() { + #[tokio::test] + async fn test_invalid_nonce_returns_specific_error_with_values() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2741,7 +2762,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2854,8 +2876,8 @@ mod tests { mod fee_strategy_execution { use super::*; - #[test] - fn test_fee_cascade_through_multiple_inputs() { + #[tokio::test] + async fn test_fee_cascade_through_multiple_inputs() { // Test that fees cascade through inputs when first input is exhausted let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -2896,7 +2918,8 @@ mod tests { AddressFundsFeeStrategyStep::DeductFromInput(1), ], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2927,8 +2950,8 @@ mod tests { ); } - #[test] - fn test_fee_deducted_from_input_and_output_combined() { + #[tokio::test] + async fn test_fee_deducted_from_input_and_output_combined() { // Test combined fee strategy: deduct from input first, then reduce output let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -2967,7 +2990,8 @@ mod tests { AddressFundsFeeStrategyStep::ReduceOutput(0), ], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2998,8 +3022,8 @@ mod tests { ); } - #[test] - fn test_fee_exactly_depletes_input_to_zero() { + #[tokio::test] + async fn test_fee_exactly_depletes_input_to_zero() { // Edge case: fee exactly depletes an input, leaving zero balance // With the minimum balance pre-check, we need remaining balance >= required fee (~0.004 DASH) // Required fee = 400_000_000 (base) + 500_000 (1 input) = ~400.5M credits = ~0.004 DASH @@ -3038,7 +3062,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3137,8 +3162,8 @@ mod tests { ); } - #[test] - fn test_valid_p2pkh_output_script_succeeds() { + #[tokio::test] + async fn test_valid_p2pkh_output_script_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3170,7 +3195,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], CoreScript::random_p2pkh(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3201,8 +3227,8 @@ mod tests { ); } - #[test] - fn test_valid_p2sh_output_script_succeeds() { + #[tokio::test] + async fn test_valid_p2sh_output_script_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3234,7 +3260,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], CoreScript::random_p2sh(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3308,8 +3335,8 @@ mod tests { ); } - #[test] - fn test_different_core_fee_per_byte_values() { + #[tokio::test] + async fn test_different_core_fee_per_byte_values() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3348,6 +3375,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3387,8 +3415,8 @@ mod tests { mod pooling_tests { use super::*; - #[test] - fn test_pooling_if_available() { + #[tokio::test] + async fn test_pooling_if_available() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3427,6 +3455,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3446,8 +3475,8 @@ mod tests { ))); } - #[test] - fn test_pooling_standard() { + #[tokio::test] + async fn test_pooling_standard() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3486,6 +3515,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3513,8 +3543,8 @@ mod tests { mod user_fee_increase_edge_cases { use super::*; - #[test] - fn test_maximum_user_fee_increase() { + #[tokio::test] + async fn test_maximum_user_fee_increase() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3548,7 +3578,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), u16::MAX, // Maximum fee increase - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3579,8 +3610,8 @@ mod tests { ); } - #[test] - fn test_fee_increase_with_sufficient_balance_succeeds() { + #[tokio::test] + async fn test_fee_increase_with_sufficient_balance_succeeds() { // Test that reasonable fee increases work with sufficient balance // Fee base ~400M credits, even with 100% increase is ~800M credits // 0.05 DASH = 5B credits remaining >> 800M required @@ -3616,7 +3647,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), 10000, // 100% fee increase - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3635,8 +3667,8 @@ mod tests { mod system_credits_verification { use super::*; - #[test] - fn test_system_credits_decrease_after_withdrawal() { + #[tokio::test] + async fn test_system_credits_decrease_after_withdrawal() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3676,7 +3708,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3733,8 +3766,8 @@ mod tests { mod boundary_edge_cases { use super::*; - #[test] - fn test_maximum_inputs_succeeds() { + #[tokio::test] + async fn test_maximum_inputs_succeeds() { let platform_version = PlatformVersion::latest(); let max_inputs = platform_version.dpp.state_transitions.max_address_inputs as usize; @@ -3773,7 +3806,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3804,8 +3838,8 @@ mod tests { ); } - #[test] - fn test_exact_balance_withdrawal_fails_insufficient_remaining_for_fees() { + #[tokio::test] + async fn test_exact_balance_withdrawal_fails_insufficient_remaining_for_fees() { // Spending 100% of address balance should fail because there's nothing left for fees // Required fee = ~400.5M credits (~0.004 DASH), so remaining balance must be >= that let platform_version = PlatformVersion::latest(); @@ -3840,7 +3874,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3851,8 +3886,8 @@ mod tests { ); } - #[test] - fn test_high_balance_withdrawal() { + #[tokio::test] + async fn test_high_balance_withdrawal() { // Test withdrawing a large portion of balance while leaving enough for fees let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -3888,7 +3923,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3919,8 +3955,8 @@ mod tests { ); } - #[test] - fn test_large_amount_withdrawal() { + #[tokio::test] + async fn test_large_amount_withdrawal() { // Test withdrawal at the maximum allowed amount (500 Dash) let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -3956,7 +3992,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3995,8 +4032,8 @@ mod tests { mod replay_protection { use super::*; - #[test] - fn test_same_transition_replayed_fails() { + #[tokio::test] + async fn test_same_transition_replayed_fails() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4027,7 +4064,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -4105,8 +4143,8 @@ mod tests { mod block_info_effects { use super::*; - #[test] - fn test_withdrawal_with_different_block_height() { + #[tokio::test] + async fn test_withdrawal_with_different_block_height() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4137,7 +4175,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -4171,8 +4210,8 @@ mod tests { ); } - #[test] - fn test_withdrawal_at_genesis_block() { + #[tokio::test] + async fn test_withdrawal_at_genesis_block() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4203,7 +4242,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -4245,8 +4285,8 @@ mod tests { mod serialization_edge_cases { use super::*; - #[test] - fn test_transition_round_trip_serialization() { + #[tokio::test] + async fn test_transition_round_trip_serialization() { let mut signer = TestAddressSigner::new(); let input_address = signer.add_p2pkh([1u8; 32]); @@ -4261,7 +4301,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; // Serialize let serialized = transition.serialize_to_bytes().expect("should serialize"); @@ -4282,8 +4323,8 @@ mod tests { ); } - #[test] - fn test_transition_with_many_inputs_serializes() { + #[tokio::test] + async fn test_transition_with_many_inputs_serializes() { let platform_version = PlatformVersion::latest(); let max_inputs = platform_version.dpp.state_transitions.max_address_inputs as usize; @@ -4307,7 +4348,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; // Should serialize without error let serialized = transition.serialize_to_bytes().expect("should serialize"); @@ -4317,8 +4359,8 @@ mod tests { StateTransition::deserialize_from_bytes(&serialized).expect("should deserialize"); } - #[test] - fn test_corrupted_serialized_data_returns_error() { + #[tokio::test] + async fn test_corrupted_serialized_data_returns_error() { let platform_version = PlatformVersion::latest(); let mut signer = TestAddressSigner::new(); @@ -4335,7 +4377,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let mut serialized = transition.serialize_to_bytes().expect("should serialize"); @@ -4382,8 +4425,8 @@ mod tests { mod concurrent_input_usage { use super::*; - #[test] - fn test_two_transitions_same_input_address_sequential_nonces() { + #[tokio::test] + async fn test_two_transitions_same_input_address_sequential_nonces() { // Test that two withdrawals from the same address succeed with sequential nonces // when processed in separate blocks let platform_version = PlatformVersion::latest(); @@ -4417,7 +4460,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result1 = transition1.serialize_to_bytes().expect("should serialize"); @@ -4451,8 +4495,8 @@ mod tests { ); } - #[test] - fn test_second_transition_exceeds_remaining_balance() { + #[tokio::test] + async fn test_second_transition_exceeds_remaining_balance() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4485,7 +4529,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; // Second transition: try to spend 0.6 DASH again (but only ~0.4 remains after first) let mut inputs2 = BTreeMap::new(); @@ -4497,7 +4542,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result1 = transition1.serialize_to_bytes().expect("should serialize"); let result2 = transition2.serialize_to_bytes().expect("should serialize"); @@ -4715,8 +4761,8 @@ mod tests { mod fee_strategy_edge_cases { use super::*; - #[test] - fn test_fee_exceeds_entire_withdrawal_amount() { + #[tokio::test] + async fn test_fee_exceeds_entire_withdrawal_amount() { // When fees would consume the entire withdrawal, leaving nothing for output let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -4750,7 +4796,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -4939,8 +4986,8 @@ mod tests { mod nonce_boundary { use super::*; - #[test] - fn test_nonce_at_max_minus_one() { + #[tokio::test] + async fn test_nonce_at_max_minus_one() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4982,7 +5029,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -5014,8 +5062,8 @@ mod tests { ); } - #[test] - fn test_nonce_zero_for_fresh_address() { + #[tokio::test] + async fn test_nonce_zero_for_fresh_address() { // Fresh address should have nonce 0, first transaction uses nonce 1 let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -5049,7 +5097,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -5068,8 +5117,8 @@ mod tests { mod output_field_tests { use super::*; - #[test] - fn test_withdrawal_with_change_output_to_same_address_fails() { + #[tokio::test] + async fn test_withdrawal_with_change_output_to_same_address_fails() { // Test withdrawal with change output going back to the same input address // This should fail because output address cannot be the same as an input address let platform_version = PlatformVersion::latest(); @@ -5106,7 +5155,8 @@ mod tests { output, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -5117,8 +5167,8 @@ mod tests { ); } - #[test] - fn test_withdrawal_with_change_output_to_different_address() { + #[tokio::test] + async fn test_withdrawal_with_change_output_to_different_address() { // Test withdrawal with change output going to a different address let platform_version = PlatformVersion::latest(); @@ -5156,7 +5206,8 @@ mod tests { output, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -5166,8 +5217,8 @@ mod tests { ); } - #[test] - fn test_withdrawal_with_zero_change_output() { + #[tokio::test] + async fn test_withdrawal_with_zero_change_output() { // Test withdrawal with change output of zero credits (should likely be rejected) let platform_version = PlatformVersion::latest(); @@ -5203,7 +5254,8 @@ mod tests { output, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -5213,8 +5265,8 @@ mod tests { println!("Zero change output validity: {}", is_valid); } - #[test] - fn test_withdrawal_change_output_exceeds_available() { + #[tokio::test] + async fn test_withdrawal_change_output_exceeds_available() { // Test withdrawal where change output amount exceeds what's available after withdrawal let platform_version = PlatformVersion::latest(); @@ -5250,7 +5302,8 @@ mod tests { output, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -5260,8 +5313,8 @@ mod tests { ); } - #[test] - fn test_withdrawal_without_change_output() { + #[tokio::test] + async fn test_withdrawal_without_change_output() { // Test withdrawal with no change output (None) let platform_version = PlatformVersion::latest(); @@ -5295,7 +5348,8 @@ mod tests { None, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -5313,8 +5367,8 @@ mod tests { mod input_ordering_tests { use super::*; - #[test] - fn test_multiple_inputs_processed_in_btreemap_order() { + #[tokio::test] + async fn test_multiple_inputs_processed_in_btreemap_order() { // BTreeMap ensures consistent ordering by key let platform_version = PlatformVersion::latest(); @@ -5361,7 +5415,8 @@ mod tests { AddressFundsFeeStrategyStep::DeductFromInput(2), ], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -5371,8 +5426,8 @@ mod tests { ); } - #[test] - fn test_fee_deduction_follows_strategy_order() { + #[tokio::test] + async fn test_fee_deduction_follows_strategy_order() { // Verify that fee deduction happens in the order specified by fee_strategy let platform_version = PlatformVersion::latest(); @@ -5414,7 +5469,8 @@ mod tests { AddressFundsFeeStrategyStep::DeductFromInput(0), ], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -5576,7 +5632,7 @@ mod tests { use super::*; /// Helper to create signed transition with custom core_fee_per_byte - fn create_signed_withdrawal_with_core_fee( + async fn create_signed_withdrawal_with_core_fee( signer: &TestAddressSigner, inputs: BTreeMap, output_script: CoreScript, @@ -5595,11 +5651,12 @@ mod tests { 0, PlatformVersion::latest(), ) + .await .expect("should create signed transition") } - #[test] - fn test_max_core_fee_per_byte() { + #[tokio::test] + async fn test_max_core_fee_per_byte() { // Test with u32::MAX core fee per byte let platform_version = PlatformVersion::latest(); @@ -5631,7 +5688,8 @@ mod tests { inputs, create_random_output_script(&mut rng), u32::MAX, // Maximum value - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -5641,8 +5699,8 @@ mod tests { println!("Max core_fee_per_byte validity: {}", is_valid); } - #[test] - fn test_high_core_fee_affects_withdrawal_amount() { + #[tokio::test] + async fn test_high_core_fee_affects_withdrawal_amount() { // Test that high core fee affects the actual withdrawal to core let platform_version = PlatformVersion::latest(); @@ -5674,7 +5732,8 @@ mod tests { inputs, create_random_output_script(&mut rng), 987, // High fibonacci number (1000 is not fibonacci) - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -5891,8 +5950,8 @@ mod tests { /// /// Expected: the transition is rejected with an error. /// Actual: panics (debug) or produces a wrapped withdrawal amount (release). - #[test] - fn test_output_exceeds_input_rejected_by_processing() { + #[tokio::test] + async fn test_output_exceeds_input_rejected_by_processing() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -5929,7 +5988,8 @@ mod tests { Some((output_address, dash_to_credits!(0.5))), vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -5969,8 +6029,8 @@ mod tests { /// because all indices shifted down after the removal. /// /// Location: rs-dpp/.../deduct_fee_from_inputs_and_outputs/v0/mod.rs:35-45 - #[test] - fn test_fee_deduction_stable_after_entry_removal() { + #[tokio::test] + async fn test_fee_deduction_stable_after_entry_removal() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -6028,7 +6088,8 @@ mod tests { AddressFundsFeeStrategyStep::DeductFromInput(1), ], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -6144,8 +6205,8 @@ mod tests { /// AUDIT H2 (Processing): Dust withdrawal reaches processing without rejection. /// /// Signed version of the H2 test that goes through the full processing pipeline. - #[test] - fn test_withdrawal_below_min_amount_rejected_by_processing() { + #[tokio::test] + async fn test_withdrawal_below_min_amount_rejected_by_processing() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -6182,7 +6243,8 @@ mod tests { Some((output_address, output_amount)), vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], create_random_output_script(&mut rng), - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_funding_from_asset_lock/tests.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_funding_from_asset_lock/tests.rs index 090e49840ea..001debbd6cb 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_funding_from_asset_lock/tests.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_funding_from_asset_lock/tests.rs @@ -356,7 +356,7 @@ mod tests { } /// Create a signed AddressFundingFromAssetLockTransition - fn create_signed_address_funding_from_asset_lock_transition( + async fn create_signed_address_funding_from_asset_lock_transition( asset_lock_proof: dpp::identity::state_transition::asset_lock_proof::AssetLockProof, asset_lock_private_key: &[u8], signer: &TestAddressSigner, @@ -373,9 +373,10 @@ mod tests { fee_strategy, 0, ) + .await } - fn create_signed_address_funding_from_asset_lock_transition_with_fee_increase( + async fn create_signed_address_funding_from_asset_lock_transition_with_fee_increase( asset_lock_proof: AssetLockProof, asset_lock_private_key: &[u8], signer: &TestAddressSigner, @@ -394,6 +395,7 @@ mod tests { user_fee_increase, PlatformVersion::latest(), ) + .await .expect("should create signed transition") } @@ -442,8 +444,8 @@ mod tests { mod structure_validation { use super::*; - #[test] - fn test_no_outputs_returns_error() { + #[tokio::test] + async fn test_no_outputs_returns_error() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(567); @@ -502,8 +504,8 @@ mod tests { ); } - #[test] - fn test_too_many_inputs_returns_error() { + #[tokio::test] + async fn test_too_many_inputs_returns_error() { // Structure validation happens before signature validation // so we test it directly without needing valid signatures use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; @@ -554,8 +556,8 @@ mod tests { ); } - #[test] - fn test_too_many_outputs_returns_error() { + #[tokio::test] + async fn test_too_many_outputs_returns_error() { // Structure validation happens before signature validation // so we test it directly without needing valid signatures use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; @@ -606,8 +608,8 @@ mod tests { ); } - #[test] - fn test_input_witness_count_mismatch_returns_error() { + #[tokio::test] + async fn test_input_witness_count_mismatch_returns_error() { // Structure validation happens before signature validation // so we test it directly without needing valid signatures use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; @@ -657,8 +659,8 @@ mod tests { ); } - #[test] - fn test_output_address_also_input_returns_error() { + #[tokio::test] + async fn test_output_address_also_input_returns_error() { // Structure validation happens before signature validation // so we test it directly without needing valid signatures use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; @@ -702,8 +704,8 @@ mod tests { ); } - #[test] - fn test_empty_fee_strategy_returns_error() { + #[tokio::test] + async fn test_empty_fee_strategy_returns_error() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(567); @@ -763,8 +765,8 @@ mod tests { ); } - #[test] - fn test_fee_strategy_index_out_of_bounds_returns_error() { + #[tokio::test] + async fn test_fee_strategy_index_out_of_bounds_returns_error() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(567); @@ -825,8 +827,8 @@ mod tests { ); } - #[test] - fn test_no_remainder_output_returns_error() { + #[tokio::test] + async fn test_no_remainder_output_returns_error() { // Exactly one output must be None (the remainder recipient) use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; @@ -867,8 +869,8 @@ mod tests { ); } - #[test] - fn test_multiple_remainder_outputs_returns_error() { + #[tokio::test] + async fn test_multiple_remainder_outputs_returns_error() { // Exactly one output must be None (the remainder recipient) use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; @@ -911,8 +913,8 @@ mod tests { ); } - #[test] - fn test_output_below_minimum_returns_error() { + #[tokio::test] + async fn test_output_below_minimum_returns_error() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(567); @@ -980,8 +982,8 @@ mod tests { mod successful_transitions { use super::*; - #[test] - fn test_simple_asset_lock_funding_to_single_address() { + #[tokio::test] + async fn test_simple_asset_lock_funding_to_single_address() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1015,7 +1017,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1041,8 +1044,8 @@ mod tests { ); } - #[test] - fn test_asset_lock_funding_to_multiple_addresses() { + #[tokio::test] + async fn test_asset_lock_funding_to_multiple_addresses() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1076,7 +1079,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1102,8 +1106,8 @@ mod tests { ); } - #[test] - fn test_asset_lock_funding_combined_with_existing_address_input() { + #[tokio::test] + async fn test_asset_lock_funding_combined_with_existing_address_input() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1142,7 +1146,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1177,8 +1182,8 @@ mod tests { mod remainder_output_handling { use super::*; - #[test] - fn test_explicit_outputs_exceed_available_funds_returns_error() { + #[tokio::test] + async fn test_explicit_outputs_exceed_available_funds_returns_error() { // When explicit outputs sum > asset_lock + inputs, should return error let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -1214,7 +1219,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1247,8 +1253,8 @@ mod tests { assert_eq!(processing_result.invalid_paid_count(), 1); } - #[test] - fn test_exact_match_removes_remainder_output() { + #[tokio::test] + async fn test_exact_match_removes_remainder_output() { // When explicit outputs sum == asset_lock + inputs, remainder output should be removed let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -1291,7 +1297,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1340,8 +1347,8 @@ mod tests { ); } - #[test] - fn test_surplus_funds_go_to_remainder() { + #[tokio::test] + async fn test_surplus_funds_go_to_remainder() { // When explicit outputs sum < asset_lock + inputs, remainder gets the difference let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -1377,7 +1384,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1435,8 +1443,8 @@ mod tests { mod state_validation { use super::*; - #[test] - fn test_input_address_does_not_exist_returns_error() { + #[tokio::test] + async fn test_input_address_does_not_exist_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1473,7 +1481,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1502,8 +1511,8 @@ mod tests { ); } - #[test] - fn test_insufficient_balance_in_input_returns_error() { + #[tokio::test] + async fn test_insufficient_balance_in_input_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1542,7 +1551,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1571,8 +1581,8 @@ mod tests { ); } - #[test] - fn test_wrong_nonce_returns_error() { + #[tokio::test] + async fn test_wrong_nonce_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1611,7 +1621,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1648,8 +1659,8 @@ mod tests { mod signature_validation { use super::*; - #[test] - fn test_wrong_asset_lock_signature_returns_error() { + #[tokio::test] + async fn test_wrong_asset_lock_signature_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1684,7 +1695,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1714,8 +1726,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_signature_from_different_key_for_input_returns_error() { + #[tokio::test] + async fn test_signature_from_different_key_for_input_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1771,7 +1783,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1809,8 +1822,8 @@ mod tests { mod p2sh_multisig { use super::*; - #[test] - fn test_asset_lock_with_p2sh_multisig_input() { + #[tokio::test] + async fn test_asset_lock_with_p2sh_multisig_input() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1848,7 +1861,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1874,8 +1888,8 @@ mod tests { ); } - #[test] - fn test_asset_lock_with_mixed_p2pkh_and_p2sh_inputs() { + #[tokio::test] + async fn test_asset_lock_with_mixed_p2pkh_and_p2sh_inputs() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1919,7 +1933,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1945,8 +1960,8 @@ mod tests { ); } - #[test] - fn test_p2sh_with_insufficient_signatures_fails() { + #[tokio::test] + async fn test_p2sh_with_insufficient_signatures_fails() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2043,8 +2058,8 @@ mod tests { mod additional_structure_validation { use super::*; - #[test] - fn test_fee_strategy_duplicate_steps_returns_error() { + #[tokio::test] + async fn test_fee_strategy_duplicate_steps_returns_error() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(567); @@ -2108,8 +2123,8 @@ mod tests { ); } - #[test] - fn test_deduct_from_input_index_out_of_bounds_returns_error() { + #[tokio::test] + async fn test_deduct_from_input_index_out_of_bounds_returns_error() { // Structure validation happens before signature validation // so we test it directly without needing valid signatures use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; @@ -2155,8 +2170,8 @@ mod tests { ); } - #[test] - fn test_input_below_minimum_returns_error() { + #[tokio::test] + async fn test_input_below_minimum_returns_error() { // Structure validation happens before signature validation // so we test it directly without needing valid signatures use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; @@ -2205,8 +2220,8 @@ mod tests { mod edge_cases { use super::*; - #[test] - fn test_maximum_allowed_inputs_succeeds() { + #[tokio::test] + async fn test_maximum_allowed_inputs_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2246,7 +2261,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2272,8 +2288,8 @@ mod tests { ); } - #[test] - fn test_maximum_allowed_outputs_succeeds() { + #[tokio::test] + async fn test_maximum_allowed_outputs_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2310,7 +2326,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2336,8 +2353,8 @@ mod tests { ); } - #[test] - fn test_multiple_p2pkh_inputs_with_asset_lock() { + #[tokio::test] + async fn test_multiple_p2pkh_inputs_with_asset_lock() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2383,7 +2400,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2417,8 +2435,8 @@ mod tests { mod fee_strategy { use super::*; - #[test] - fn test_multiple_fee_strategy_steps_succeeds() { + #[tokio::test] + async fn test_multiple_fee_strategy_steps_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2460,7 +2478,8 @@ mod tests { AddressFundsFeeStrategyStep::ReduceOutput(0), AddressFundsFeeStrategyStep::ReduceOutput(1), ], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2486,8 +2505,8 @@ mod tests { ); } - #[test] - fn test_deduct_from_input_only_succeeds() { + #[tokio::test] + async fn test_deduct_from_input_only_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2524,7 +2543,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2558,8 +2578,8 @@ mod tests { mod asset_lock_validation { use super::*; - #[test] - fn test_asset_lock_already_spent_returns_error() { + #[tokio::test] + async fn test_asset_lock_already_spent_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2590,7 +2610,8 @@ mod tests { inputs.clone(), outputs.clone(), vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2632,7 +2653,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result2 = transition2.serialize_to_bytes().expect("should serialize"); @@ -2662,8 +2684,8 @@ mod tests { assert_eq!(processing_result2.invalid_unpaid_count(), 1); } - #[test] - fn test_invalid_signature_format_returns_error() { + #[tokio::test] + async fn test_invalid_signature_format_returns_error() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(567); @@ -2741,8 +2763,8 @@ mod tests { mod balance_verification { use super::*; - #[test] - fn test_output_address_receives_correct_balance() { + #[tokio::test] + async fn test_output_address_receives_correct_balance() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2774,7 +2796,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2821,8 +2844,8 @@ mod tests { assert!(actual_balance < dash_to_credits!(1.0)); } - #[test] - fn test_input_address_balance_reduced_correctly() { + #[tokio::test] + async fn test_input_address_balance_reduced_correctly() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2860,7 +2883,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2913,8 +2937,8 @@ mod tests { mod witness_validation { use super::*; - #[test] - fn test_p2pkh_with_wrong_signature_length_fails() { + #[tokio::test] + async fn test_p2pkh_with_wrong_signature_length_fails() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2985,8 +3009,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_p2sh_with_wrong_redeem_script_fails() { + #[tokio::test] + async fn test_p2sh_with_wrong_redeem_script_fails() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3073,8 +3097,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_witness_type_mismatch_fails() { + #[tokio::test] + async fn test_witness_type_mismatch_fails() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3151,8 +3175,8 @@ mod tests { mod fee_edge_cases { use super::*; - #[test] - fn test_fee_equals_exact_remaining_balance() { + #[tokio::test] + async fn test_fee_equals_exact_remaining_balance() { // Test where fee exactly equals the remaining balance after outputs let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -3186,7 +3210,8 @@ mod tests { BTreeMap::new(), outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -3215,8 +3240,8 @@ mod tests { ); } - #[test] - fn test_fee_exceeds_remaining_by_one_credit() { + #[tokio::test] + async fn test_fee_exceeds_remaining_by_one_credit() { // Test where the output amount equals the entire asset lock value. // The fee strategy reduces the output to cover fees. // After fee deduction, the output should be reduced, which is valid behavior. @@ -3252,7 +3277,8 @@ mod tests { BTreeMap::new(), outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -3282,8 +3308,8 @@ mod tests { ); } - #[test] - fn test_user_fee_increase_with_reduce_output_succeeds() { + #[tokio::test] + async fn test_user_fee_increase_with_reduce_output_succeeds() { // Test that the fee increase actually results in higher fees being paid. // The user_fee_increase multiplier only applies to processing fees, not storage fees. // Formula: total_fee = storage_fee + processing_fee * (1 + user_fee_increase / 100) @@ -3322,7 +3348,8 @@ mod tests { outputs.clone(), vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], 0, // No fee increase - ); + ) + .await; let result = state_transition_no_increase .serialize_to_bytes() @@ -3371,7 +3398,8 @@ mod tests { outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], u16::MAX, // Maximum fee increase (655.35% extra on processing fees) - ); + ) + .await; let result = state_transition_max_increase .serialize_to_bytes() @@ -3457,8 +3485,8 @@ mod tests { ); } - #[test] - fn test_user_fee_increase_small_amount() { + #[tokio::test] + async fn test_user_fee_increase_small_amount() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3491,7 +3519,8 @@ mod tests { outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], 100, // Small fee increase (1%) - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -3524,8 +3553,8 @@ mod tests { mod asset_lock_edge_cases { use super::*; - #[test] - fn test_asset_lock_double_spend_same_block() { + #[tokio::test] + async fn test_asset_lock_double_spend_same_block() { // Test using the same asset lock twice in the same block let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -3561,7 +3590,8 @@ mod tests { BTreeMap::new(), outputs1, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let state_transition2 = create_signed_address_funding_from_asset_lock_transition( asset_lock_proof, @@ -3570,7 +3600,8 @@ mod tests { BTreeMap::new(), outputs2, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result1 = state_transition1 .serialize_to_bytes() @@ -3609,8 +3640,8 @@ mod tests { ); } - #[test] - fn test_asset_lock_already_used_in_previous_block() { + #[tokio::test] + async fn test_asset_lock_already_used_in_previous_block() { // Test using an asset lock that was already consumed in a previous block let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -3643,7 +3674,8 @@ mod tests { BTreeMap::new(), outputs.clone(), vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result1 = state_transition1 .serialize_to_bytes() @@ -3689,7 +3721,8 @@ mod tests { BTreeMap::new(), outputs2, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result2 = state_transition2 .serialize_to_bytes() @@ -3725,8 +3758,8 @@ mod tests { mod nonce_edge_cases { use super::*; - #[test] - fn test_nonce_zero_for_new_address() { + #[tokio::test] + async fn test_nonce_zero_for_new_address() { // New address should have nonce 0, so first tx should use nonce 1 let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -3764,7 +3797,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -3792,8 +3826,8 @@ mod tests { ); } - #[test] - fn test_nonce_gap_fails() { + #[tokio::test] + async fn test_nonce_gap_fails() { // Skipping a nonce should fail let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -3829,6 +3863,7 @@ mod tests { get_signable_bytes_for_transition(&asset_lock_proof, &inputs, &outputs); let witness = signer .sign_p2pkh(input_address, &signable_bytes) + .await .expect("should sign"); let transition = AddressFundingFromAssetLockTransition::V0( @@ -3876,8 +3911,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_nonce_reuse_fails() { + #[tokio::test] + async fn test_nonce_reuse_fails() { // Using an already-used nonce should fail let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -3913,6 +3948,7 @@ mod tests { get_signable_bytes_for_transition(&asset_lock_proof, &inputs, &outputs); let witness = signer .sign_p2pkh(input_address, &signable_bytes) + .await .expect("should sign"); let transition = AddressFundingFromAssetLockTransition::V0( @@ -3960,8 +3996,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_high_nonce_value() { + #[tokio::test] + async fn test_high_nonce_value() { // Test with a very high nonce value let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -4005,7 +4041,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() .expect("should serialize"); @@ -4037,8 +4074,8 @@ mod tests { mod amount_edge_cases { use super::*; - #[test] - fn test_output_amount_near_u64_max() { + #[tokio::test] + async fn test_output_amount_near_u64_max() { // Test with amounts near u64::MAX to check overflow protection let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -4107,8 +4144,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_zero_input_amount() { + #[tokio::test] + async fn test_zero_input_amount() { // Input with zero amount let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -4142,6 +4179,7 @@ mod tests { get_signable_bytes_for_transition(&asset_lock_proof, &inputs, &outputs); let witness = signer .sign_p2pkh(input_address, &signable_bytes) + .await .expect("should sign"); let transition = AddressFundingFromAssetLockTransition::V0( @@ -4189,8 +4227,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_zero_output_amount() { + #[tokio::test] + async fn test_zero_output_amount() { // Output with zero amount let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -4263,8 +4301,8 @@ mod tests { mod platform_state_edge_cases { use super::*; - #[test] - fn test_address_with_zero_balance() { + #[tokio::test] + async fn test_address_with_zero_balance() { // Address exists but has zero balance let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -4302,7 +4340,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -4334,8 +4373,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_output_to_existing_address_adds_balance() { + #[tokio::test] + async fn test_output_to_existing_address_adds_balance() { // Sending to an address that already exists should add to balance let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -4370,7 +4409,8 @@ mod tests { BTreeMap::new(), outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -4416,8 +4456,8 @@ mod tests { ); } - #[test] - fn test_multiple_inputs_from_same_address_deduplicated_by_btreemap() { + #[tokio::test] + async fn test_multiple_inputs_from_same_address_deduplicated_by_btreemap() { // BTreeMap naturally prevents duplicate addresses in inputs // This test demonstrates that behavior - the second insert overwrites the first let platform_version = PlatformVersion::latest(); @@ -4460,7 +4500,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -4494,8 +4535,8 @@ mod tests { mod dust_and_minimum_amounts { use super::*; - #[test] - fn test_output_becomes_below_minimum_after_fee_deduction() { + #[tokio::test] + async fn test_output_becomes_below_minimum_after_fee_deduction() { // Output starts above minimum but falls below after fee deduction let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -4565,8 +4606,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_minimum_output_after_fee_deduction() { + #[tokio::test] + async fn test_minimum_output_after_fee_deduction() { // Output after fee deduction equals exactly minimum let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -4598,7 +4639,8 @@ mod tests { BTreeMap::new(), outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -4631,8 +4673,8 @@ mod tests { mod signature_recovery_edge_cases { use super::*; - #[test] - fn test_recovered_pubkey_wrong_address() { + #[tokio::test] + async fn test_recovered_pubkey_wrong_address() { // Signature is valid but recovered pubkey hashes to wrong address let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -4672,6 +4714,7 @@ mod tests { // Create signature with wrong key - the recovered pubkey won't match the address let witness = wrong_signer .sign_p2pkh(_wrong_address, &signable_bytes) + .await .expect("should sign"); let transition = AddressFundingFromAssetLockTransition::V0( @@ -4719,8 +4762,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_invalid_recovery_id() { + #[tokio::test] + async fn test_invalid_recovery_id() { // Signature with invalid recovery ID let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -4754,6 +4797,7 @@ mod tests { get_signable_bytes_for_transition(&asset_lock_proof, &inputs, &outputs); let mut witness = signer .sign_p2pkh(input_address, &signable_bytes) + .await .expect("should sign"); // Corrupt the recovery ID (last byte of signature) @@ -4810,8 +4854,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_signature_for_different_message() { + #[tokio::test] + async fn test_signature_for_different_message() { // Valid signature but for different signable bytes let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -4848,6 +4892,7 @@ mod tests { get_signable_bytes_for_transition(&asset_lock_proof, &wrong_inputs, &outputs); let witness = signer .sign_p2pkh(input_address, &wrong_signable_bytes) + .await .expect("should sign"); let transition = AddressFundingFromAssetLockTransition::V0( @@ -4899,8 +4944,8 @@ mod tests { mod complex_scenarios { use super::*; - #[test] - fn test_all_inputs_p2sh_multisig() { + #[tokio::test] + async fn test_all_inputs_p2sh_multisig() { // All inputs are P2SH multisig (no P2PKH) let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -4941,7 +4986,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -4970,8 +5016,8 @@ mod tests { ); } - #[test] - fn test_complex_fee_strategy_multiple_outputs() { + #[tokio::test] + async fn test_complex_fee_strategy_multiple_outputs() { // Complex fee strategy that deducts from multiple outputs let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -5009,7 +5055,8 @@ mod tests { AddressFundsFeeStrategyStep::ReduceOutput(0), AddressFundsFeeStrategyStep::ReduceOutput(1), ], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -5038,8 +5085,8 @@ mod tests { ); } - #[test] - fn test_self_transfer_same_input_output_address() { + #[tokio::test] + async fn test_self_transfer_same_input_output_address() { // Input and output have the same address (though this should be blocked by structure validation) let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -5076,7 +5123,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -5108,8 +5156,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_maximum_total_amount() { + #[tokio::test] + async fn test_maximum_total_amount() { // Test with maximum combined input amounts let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -5154,7 +5202,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -5187,8 +5236,8 @@ mod tests { mod chain_asset_lock { use super::*; - #[test] - fn test_chain_asset_lock_proof_basic() { + #[tokio::test] + async fn test_chain_asset_lock_proof_basic() { // Test with ChainAssetLockProof instead of InstantAssetLockProof let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -5232,7 +5281,8 @@ mod tests { BTreeMap::new(), outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -5269,8 +5319,8 @@ mod tests { ); } - #[test] - fn test_chain_asset_lock_insufficient_confirmations() { + #[tokio::test] + async fn test_chain_asset_lock_insufficient_confirmations() { // Chain lock that doesn't have enough confirmations let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -5310,7 +5360,8 @@ mod tests { BTreeMap::new(), outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -5354,8 +5405,8 @@ mod tests { mod asset_lock_signature_field { use super::*; - #[test] - fn test_empty_asset_lock_signature() { + #[tokio::test] + async fn test_empty_asset_lock_signature() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -5422,8 +5473,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_asset_lock_signature_too_short() { + #[tokio::test] + async fn test_asset_lock_signature_too_short() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -5490,8 +5541,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_asset_lock_signature_too_long() { + #[tokio::test] + async fn test_asset_lock_signature_too_long() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -5558,8 +5609,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_asset_lock_signature_wrong_key() { + #[tokio::test] + async fn test_asset_lock_signature_wrong_key() { // Signature is valid but from wrong key (doesn't match asset lock tx pubkey) let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -5634,8 +5685,8 @@ mod tests { mod witness_ordering { use super::*; - #[test] - fn test_witnesses_wrong_order() { + #[tokio::test] + async fn test_witnesses_wrong_order() { // Witnesses provided in wrong order let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -5675,9 +5726,11 @@ mod tests { let witness1 = signer .sign_p2pkh(input_address1, &signable_bytes) + .await .expect("should sign"); let witness2 = signer .sign_p2pkh(input_address2, &signable_bytes) + .await .expect("should sign"); // Provide witnesses in WRONG order (swapped) @@ -5726,8 +5779,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_missing_middle_witness() { + #[tokio::test] + async fn test_missing_middle_witness() { // 3 inputs but only witnesses 0 and 2 (missing witness 1) let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -5770,9 +5823,11 @@ mod tests { let witness1 = signer .sign_p2pkh(input_address1, &signable_bytes) + .await .expect("should sign"); let witness3 = signer .sign_p2pkh(input_address3, &signable_bytes) + .await .expect("should sign"); // Only 2 witnesses for 3 inputs @@ -5825,8 +5880,8 @@ mod tests { mod p2sh_variations { use super::*; - #[test] - fn test_p2sh_1_of_1_multisig() { + #[tokio::test] + async fn test_p2sh_1_of_1_multisig() { // Single signature wrapped in P2SH let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -5864,7 +5919,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -5893,8 +5949,8 @@ mod tests { ); } - #[test] - fn test_p2sh_3_of_3_multisig() { + #[tokio::test] + async fn test_p2sh_3_of_3_multisig() { // All signatures required let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -5932,7 +5988,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -5961,8 +6018,8 @@ mod tests { ); } - #[test] - fn test_p2sh_more_signatures_than_threshold() { + #[tokio::test] + async fn test_p2sh_more_signatures_than_threshold() { // Provide 3 signatures for a 2-of-3 multisig let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -6036,8 +6093,8 @@ mod tests { ); } - #[test] - fn test_p2sh_maximum_keys() { + #[tokio::test] + async fn test_p2sh_maximum_keys() { // 15-of-15 multisig (maximum allowed) let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -6077,7 +6134,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -6110,8 +6168,8 @@ mod tests { mod state_verification_after_success { use super::*; - #[test] - fn test_nonce_incremented_after_success() { + #[tokio::test] + async fn test_nonce_incremented_after_success() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -6153,7 +6211,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -6185,8 +6244,8 @@ mod tests { assert_eq!(new_nonce, initial_nonce + 1); } - #[test] - fn test_asset_lock_marked_as_spent() { + #[tokio::test] + async fn test_asset_lock_marked_as_spent() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -6217,7 +6276,8 @@ mod tests { BTreeMap::new(), outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -6249,8 +6309,8 @@ mod tests { assert!(is_spent); } - #[test] - fn test_exact_balance_deltas() { + #[tokio::test] + async fn test_exact_balance_deltas() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -6291,7 +6351,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -6346,8 +6407,8 @@ mod tests { use super::*; use dpp::consensus::state::state_error::StateError; - #[test] - fn test_address_not_found_error_type() { + #[tokio::test] + async fn test_address_not_found_error_type() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -6383,7 +6444,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -6430,8 +6492,8 @@ mod tests { )); } - #[test] - fn test_insufficient_balance_error_type() { + #[tokio::test] + async fn test_insufficient_balance_error_type() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -6468,7 +6530,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -6515,8 +6578,8 @@ mod tests { )); } - #[test] - fn test_invalid_nonce_error_type() { + #[tokio::test] + async fn test_invalid_nonce_error_type() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -6552,7 +6615,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -6603,8 +6667,8 @@ mod tests { mod signature_malleability { use super::*; - #[test] - fn test_high_s_signature_rejected() { + #[tokio::test] + async fn test_high_s_signature_rejected() { // High-S signatures should be rejected per BIP-62 let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -6638,6 +6702,7 @@ mod tests { get_signable_bytes_for_transition(&asset_lock_proof, &inputs, &outputs); let mut witness = signer .sign_p2pkh(input_address, &signable_bytes) + .await .expect("should sign"); // Convert signature to high-S form @@ -6705,8 +6770,8 @@ mod tests { mod block_info_edge_cases { use super::*; - #[test] - fn test_block_height_zero() { + #[tokio::test] + async fn test_block_height_zero() { // Genesis-like block let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -6737,7 +6802,8 @@ mod tests { BTreeMap::new(), outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -6776,8 +6842,8 @@ mod tests { ); } - #[test] - fn test_very_high_block_height() { + #[tokio::test] + async fn test_very_high_block_height() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -6807,7 +6873,8 @@ mod tests { BTreeMap::new(), outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -6847,8 +6914,8 @@ mod tests { mod partial_failure_scenarios { use super::*; - #[test] - fn test_one_valid_one_invalid_input_signature() { + #[tokio::test] + async fn test_one_valid_one_invalid_input_signature() { // Two inputs, one with valid signature, one with invalid - whole tx should fail let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -6888,6 +6955,7 @@ mod tests { // Create valid witness for first input let witness1 = signer .sign_p2pkh(input_address1, &signable_bytes) + .await .expect("should sign"); // Create INVALID witness for second input (wrong message) @@ -6898,6 +6966,7 @@ mod tests { get_signable_bytes_for_transition(&asset_lock_proof, &wrong_inputs, &outputs); let witness2 = signer .sign_p2pkh(input_address2, &wrong_signable_bytes) + .await .expect("should sign"); let transition = AddressFundingFromAssetLockTransition::V0( @@ -6949,8 +7018,8 @@ mod tests { mod size_limit_edge_cases { use super::*; - #[test] - fn test_minimum_valid_transition() { + #[tokio::test] + async fn test_minimum_valid_transition() { // Smallest possible valid transition let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -6982,7 +7051,8 @@ mod tests { BTreeMap::new(), // No inputs outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let serialized = state_transition .serialize_to_bytes() @@ -7018,8 +7088,8 @@ mod tests { mod address_format_edge_cases { use super::*; - #[test] - fn test_all_zero_address_hash() { + #[tokio::test] + async fn test_all_zero_address_hash() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -7053,7 +7123,8 @@ mod tests { BTreeMap::new(), // No inputs outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -7082,8 +7153,8 @@ mod tests { ); } - #[test] - fn test_all_ff_address_hash() { + #[tokio::test] + async fn test_all_ff_address_hash() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -7117,7 +7188,8 @@ mod tests { BTreeMap::new(), // No inputs outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -7150,8 +7222,8 @@ mod tests { mod fee_strategy_input_combinations { use super::*; - #[test] - fn test_deduct_from_input_and_reduce_output() { + #[tokio::test] + async fn test_deduct_from_input_and_reduce_output() { // Combined fee strategy let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -7192,7 +7264,8 @@ mod tests { AddressFundsFeeStrategyStep::ReduceOutput(0), AddressFundsFeeStrategyStep::DeductFromInput(0), ], - ); + ) + .await; let result = state_transition .serialize_to_bytes() .expect("should serialize"); @@ -7220,8 +7293,8 @@ mod tests { ); } - #[test] - fn test_deduct_from_input_exact_amount() { + #[tokio::test] + async fn test_deduct_from_input_exact_amount() { // DeductFromInput leaves exactly 0 remaining let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -7260,7 +7333,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -7297,8 +7371,8 @@ mod tests { mod replay_and_idempotency { use super::*; - #[test] - fn test_replay_same_transition_fails() { + #[tokio::test] + async fn test_replay_same_transition_fails() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -7328,7 +7402,8 @@ mod tests { BTreeMap::new(), outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let serialized = state_transition .serialize_to_bytes() @@ -7393,8 +7468,8 @@ mod tests { mod concurrent_input_usage { use super::*; - #[test] - fn test_two_transitions_same_input_address_same_block() { + #[tokio::test] + async fn test_two_transitions_same_input_address_same_block() { // Two transitions in the same block both try to use the same input address. // The second one should fail due to nonce mismatch (first uses nonce 1, // but both were created expecting nonce 1). @@ -7435,7 +7510,8 @@ mod tests { inputs1, outputs1, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; // Second transition: also uses nonce 1 (will conflict) let mut rng2 = StdRng::seed_from_u64(902); @@ -7454,7 +7530,8 @@ mod tests { inputs2, outputs2, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result1 = state_transition1 .serialize_to_bytes() @@ -7499,8 +7576,8 @@ mod tests { ); } - #[test] - fn test_two_transitions_same_input_address_sequential_nonces() { + #[tokio::test] + async fn test_two_transitions_same_input_address_sequential_nonces() { // Two transitions in the same block using same input but with sequential nonces. // First uses nonce 1, second uses nonce 2. Both should succeed. let platform_version = PlatformVersion::latest(); @@ -7540,7 +7617,8 @@ mod tests { inputs1, outputs1, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; // Second transition: uses nonce 2 (sequential) let mut rng2 = StdRng::seed_from_u64(904); @@ -7559,7 +7637,8 @@ mod tests { inputs2, outputs2, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result1 = state_transition1 .serialize_to_bytes() @@ -7603,8 +7682,8 @@ mod tests { assert_eq!(final_balance, dash_to_credits!(5.0)); } - #[test] - fn test_second_transition_exceeds_remaining_balance() { + #[tokio::test] + async fn test_second_transition_exceeds_remaining_balance() { // Two transitions in same block. First succeeds, second fails because // the first consumed balance that second was counting on. let platform_version = PlatformVersion::latest(); @@ -7644,7 +7723,8 @@ mod tests { inputs1, outputs1, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; // Second transition: tries to use 3 DASH (nonce 2) // But after first transition, only 2 DASH remains @@ -7664,7 +7744,8 @@ mod tests { inputs2, outputs2, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result1 = state_transition1 .serialize_to_bytes() @@ -7717,8 +7798,8 @@ mod tests { mod overflow_protection { use super::*; - #[test] - fn test_output_sum_overflow() { + #[tokio::test] + async fn test_output_sum_overflow() { // Multiple outputs that would overflow u64 when summed let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -7789,8 +7870,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_input_sum_overflow() { + #[tokio::test] + async fn test_input_sum_overflow() { // Multiple inputs that would overflow u64 when summed let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -7873,8 +7954,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_output_plus_fee_overflow() { + #[tokio::test] + async fn test_output_plus_fee_overflow() { // Output amount that when fee is added would overflow let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -7944,8 +8025,8 @@ mod tests { assert_eq!(processing_result.invalid_unpaid_count(), 1); } - #[test] - fn test_user_fee_increase_overflow() { + #[tokio::test] + async fn test_user_fee_increase_overflow() { // Very high fee increase that could cause overflow in fee calculation let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -7979,7 +8060,8 @@ mod tests { outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], u16::MAX, // Maximum fee increase - ); + ) + .await; let result = state_transition .serialize_to_bytes() @@ -8025,8 +8107,8 @@ mod tests { use dpp::state_transition::identity_create_transition::IdentityCreateTransition; use simple_signer::signer::SimpleSigner; - #[test] - fn test_address_funding_with_partially_used_asset_lock() { + #[tokio::test] + async fn test_address_funding_with_partially_used_asset_lock() { // This test verifies that an asset lock that was partially consumed // (due to a failed identity create with duplicate unique key) can still // be used for address funding with the remaining balance. @@ -8150,6 +8232,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -8207,7 +8290,8 @@ mod tests { BTreeMap::new(), // No additional inputs outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let address_funding_serialized = address_funding_transition .serialize_to_bytes() @@ -8235,8 +8319,8 @@ mod tests { ); } - #[test] - fn test_address_funding_with_small_output_after_partial_consumption() { + #[tokio::test] + async fn test_address_funding_with_small_output_after_partial_consumption() { // This test verifies that an asset lock that was partially consumed can still // be used for address funding with an output that fits within the remaining balance. // @@ -8364,6 +8448,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized = identity_create_transition @@ -8416,7 +8501,8 @@ mod tests { BTreeMap::new(), outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let address_funding_serialized = address_funding_transition .serialize_to_bytes() @@ -8480,8 +8566,8 @@ mod tests { .expect("should fetch asset lock info") } - #[test] - fn test_invalid_paid_fee_from_asset_lock_only() { + #[tokio::test] + async fn test_invalid_paid_fee_from_asset_lock_only() { // Scenario: No inputs provided, so the penalty must come entirely from the asset lock. // Expected: Asset lock remaining balance is reduced by at least the penalty. // @@ -8523,7 +8609,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -8606,8 +8693,8 @@ mod tests { } } - #[test] - fn test_invalid_paid_fee_from_input_only() { + #[tokio::test] + async fn test_invalid_paid_fee_from_input_only() { // Scenario: Input has enough balance to cover the entire penalty + processing fee. // Fee strategy specifies DeductFromInput first. // Expected: Input balance is reduced, asset lock remains untouched. @@ -8666,7 +8753,8 @@ mod tests { AddressFundsFeeStrategyStep::DeductFromInput(0), AddressFundsFeeStrategyStep::ReduceOutput(0), ], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -8755,8 +8843,8 @@ mod tests { } } - #[test] - fn test_invalid_paid_fee_from_input_then_asset_lock() { + #[tokio::test] + async fn test_invalid_paid_fee_from_input_then_asset_lock() { // Scenario: Input has some balance but not enough for the full fee (penalty + processing). // Fee strategy specifies DeductFromInput first. // Expected: Input contributes what it can, remainder comes from asset lock. @@ -8814,7 +8902,8 @@ mod tests { AddressFundsFeeStrategyStep::DeductFromInput(0), AddressFundsFeeStrategyStep::ReduceOutput(0), ], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -8932,8 +9021,8 @@ mod tests { /// because all indices shifted down after the removal. /// /// Location: rs-dpp/.../deduct_fee_from_inputs_and_outputs/v0/mod.rs:35-45 - #[test] - fn test_fee_deduction_stable_after_entry_removal() { + #[tokio::test] + async fn test_fee_deduction_stable_after_entry_removal() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -8998,7 +9087,8 @@ mod tests { AddressFundsFeeStrategyStep::DeductFromInput(0), AddressFundsFeeStrategyStep::DeductFromInput(1), ], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -9063,8 +9153,8 @@ mod tests { /// (so remainder is 0 and removed), with a fee strategy targeting the removed output. /// /// Location: rs-dpp/.../address_funding_from_asset_lock/advanced_structure/v0/mod.rs:84-86 - #[test] - fn test_reduce_output_index_after_remainder_removal() { + #[tokio::test] + async fn test_reduce_output_index_after_remainder_removal() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -9105,7 +9195,8 @@ mod tests { BTreeMap::new(), // No address inputs outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(2)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -9179,8 +9270,8 @@ mod tests { /// This is a standalone conservation test complementing C2. /// /// Location: rs-drive/.../address_funding_from_asset_lock_transition.rs - #[test] - fn test_credits_conservation_with_asset_lock_only() { + #[tokio::test] + async fn test_credits_conservation_with_asset_lock_only() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -9217,7 +9308,8 @@ mod tests { BTreeMap::new(), // No address inputs outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -9304,8 +9396,8 @@ mod tests { /// correct level, but notes the transformer lacks defense-in-depth. /// /// Location: rs-drive/.../address_funding_from_asset_lock/mod.rs:61,64 - #[test] - fn test_remainder_arithmetic_uses_checked_operations() { + #[tokio::test] + async fn test_remainder_arithmetic_uses_checked_operations() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -9353,8 +9445,8 @@ mod tests { /// Locations: /// - rs-drive/.../address_funding_from_asset_lock/mod.rs:64 (resolved_outputs) /// - rs-drive/.../address_funding_from_asset_lock_transition.rs:61 (operations) - #[test] - fn test_remainder_includes_input_contributions() { + #[tokio::test] + async fn test_remainder_includes_input_contributions() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -9395,7 +9487,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -9461,8 +9554,8 @@ mod tests { /// credits across all affected addresses plus the withdrawal document /// should equal the initial credits. Currently, input contributions /// vanish, violating conservation. - #[test] - fn test_credits_conservation_with_inputs() { + #[tokio::test] + async fn test_credits_conservation_with_inputs() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -9506,7 +9599,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_funds_transfer/tests.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_funds_transfer/tests.rs index 87d4c6d16ff..d3447a197e5 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_funds_transfer/tests.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_funds_transfer/tests.rs @@ -65,7 +65,7 @@ mod tests { } /// Create a simple AddressFundsTransferTransition with proper signing - fn create_signed_address_funds_transfer_transition( + async fn create_signed_address_funds_transfer_transition( signer: &TestAddressSigner, input_address: PlatformAddress, input_nonce: AddressNonce, @@ -87,6 +87,7 @@ mod tests { 0, PlatformVersion::latest(), ) + .await .expect("should create signed transition") } @@ -111,7 +112,7 @@ mod tests { } /// Create a signed transition with custom inputs/outputs and fee strategy - fn create_signed_transition_with_custom_outputs( + async fn create_signed_transition_with_custom_outputs( signer: &TestAddressSigner, inputs: BTreeMap, outputs: BTreeMap, @@ -125,6 +126,7 @@ mod tests { 0, PlatformVersion::latest(), ) + .await .expect("should create signed transition") } @@ -137,8 +139,8 @@ mod tests { mod structure_validation { use super::*; - #[test] - fn test_no_inputs_returns_error() { + #[tokio::test] + async fn test_no_inputs_returns_error() { let platform_version = PlatformVersion::latest(); // No inputs case - doesn't need address setup since there are no inputs @@ -194,8 +196,8 @@ mod tests { ); } - #[test] - fn test_no_outputs_returns_error() { + #[tokio::test] + async fn test_no_outputs_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -221,7 +223,8 @@ mod tests { // Create transition with proper signature but empty outputs let transition = - create_signed_transition_with_custom_outputs(&signer, inputs, outputs, vec![]); + create_signed_transition_with_custom_outputs(&signer, inputs, outputs, vec![]) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -250,8 +253,8 @@ mod tests { ); } - #[test] - fn test_too_many_inputs_returns_error() { + #[tokio::test] + async fn test_too_many_inputs_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -286,7 +289,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -315,8 +319,8 @@ mod tests { ); } - #[test] - fn test_input_witness_count_mismatch_returns_error() { + #[tokio::test] + async fn test_input_witness_count_mismatch_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -351,7 +355,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], - ); + ) + .await; // Remove one witness to create mismatch if let StateTransition::AddressFundsTransfer(AddressFundsTransferTransition::V0( @@ -390,8 +395,8 @@ mod tests { ); } - #[test] - fn test_output_address_also_input_returns_error() { + #[tokio::test] + async fn test_output_address_also_input_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -422,7 +427,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -451,8 +457,8 @@ mod tests { ); } - #[test] - fn test_empty_fee_strategy_returns_error() { + #[tokio::test] + async fn test_empty_fee_strategy_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -480,7 +486,8 @@ mod tests { // Empty fee strategy let transition = - create_signed_transition_with_custom_outputs(&signer, inputs, outputs, vec![]); + create_signed_transition_with_custom_outputs(&signer, inputs, outputs, vec![]) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -509,8 +516,8 @@ mod tests { ); } - #[test] - fn test_fee_strategy_too_many_steps_returns_error() { + #[tokio::test] + async fn test_fee_strategy_too_many_steps_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -548,7 +555,8 @@ mod tests { AddressFundsFeeStrategyStep::ReduceOutput(0), AddressFundsFeeStrategyStep::DeductFromInput(0), ], - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -577,8 +585,8 @@ mod tests { ); } - #[test] - fn test_fee_strategy_duplicate_returns_error() { + #[tokio::test] + async fn test_fee_strategy_duplicate_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -613,7 +621,8 @@ mod tests { AddressFundsFeeStrategyStep::DeductFromInput(0), AddressFundsFeeStrategyStep::DeductFromInput(0), // Duplicate ], - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -642,8 +651,8 @@ mod tests { ); } - #[test] - fn test_fee_strategy_input_index_out_of_bounds_returns_error() { + #[tokio::test] + async fn test_fee_strategy_input_index_out_of_bounds_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -675,7 +684,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::DeductFromInput(5)], - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -704,8 +714,8 @@ mod tests { ); } - #[test] - fn test_fee_strategy_output_index_out_of_bounds_returns_error() { + #[tokio::test] + async fn test_fee_strategy_output_index_out_of_bounds_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -737,7 +747,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::ReduceOutput(5)], - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -766,8 +777,8 @@ mod tests { ); } - #[test] - fn test_input_below_minimum_returns_error() { + #[tokio::test] + async fn test_input_below_minimum_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -799,7 +810,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -828,8 +840,8 @@ mod tests { ); } - #[test] - fn test_output_below_minimum_returns_error() { + #[tokio::test] + async fn test_output_below_minimum_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -861,7 +873,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -890,8 +903,8 @@ mod tests { ); } - #[test] - fn test_input_output_balance_mismatch_returns_error() { + #[tokio::test] + async fn test_input_output_balance_mismatch_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -922,7 +935,8 @@ mod tests { inputs, outputs, vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -961,8 +975,8 @@ mod tests { mod state_validation { use super::*; - #[test] - fn test_address_does_not_exist_returns_error() { + #[tokio::test] + async fn test_address_does_not_exist_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -992,7 +1006,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -1021,8 +1036,8 @@ mod tests { ); } - #[test] - fn test_wrong_nonce_too_high_returns_error() { + #[tokio::test] + async fn test_wrong_nonce_too_high_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1055,7 +1070,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -1084,8 +1100,8 @@ mod tests { ); } - #[test] - fn test_wrong_nonce_too_low_returns_error() { + #[tokio::test] + async fn test_wrong_nonce_too_low_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1118,7 +1134,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -1147,8 +1164,8 @@ mod tests { ); } - #[test] - fn test_max_nonce_reached_returns_error() { + #[tokio::test] + async fn test_max_nonce_reached_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1187,7 +1204,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -1216,8 +1234,8 @@ mod tests { ); } - #[test] - fn test_insufficient_balance_returns_error() { + #[tokio::test] + async fn test_insufficient_balance_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1252,7 +1270,8 @@ mod tests { requested_amount, output_address, requested_amount, - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -1283,8 +1302,8 @@ mod tests { ); } - #[test] - fn test_multiple_inputs_one_missing_returns_error() { + #[tokio::test] + async fn test_multiple_inputs_one_missing_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1325,6 +1344,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let transition_bytes = transition @@ -1363,8 +1383,8 @@ mod tests { mod success { use super::*; - #[test] - fn test_simple_transfer_success() { + #[tokio::test] + async fn test_simple_transfer_success() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1395,7 +1415,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -1422,8 +1443,8 @@ mod tests { ); } - #[test] - fn test_transfer_with_non_zero_starting_nonce_success() { + #[tokio::test] + async fn test_transfer_with_non_zero_starting_nonce_success() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1462,7 +1483,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -1500,7 +1522,7 @@ mod tests { use dpp::consensus::signature::SignatureError; /// Helper to create a transition with a tampered witness - fn create_transition_with_tampered_witness( + async fn create_transition_with_tampered_witness( signer: &TestAddressSigner, input_address: PlatformAddress, input_nonce: AddressNonce, @@ -1519,7 +1541,8 @@ mod tests { input_amount, output_address, output_amount, - ); + ) + .await; // Tamper with the witness if let StateTransition::AddressFundsTransfer(AddressFundsTransferTransition::V0( @@ -1534,8 +1557,8 @@ mod tests { transition } - #[test] - fn test_invalid_signature_bytes_returns_error() { + #[tokio::test] + async fn test_invalid_signature_bytes_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1570,7 +1593,8 @@ mod tests { *signature = BinaryData::new(vec![0xDE, 0xAD, 0xBE, 0xEF]); } }, - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -1607,8 +1631,8 @@ mod tests { // The equivalent test is test_signature_from_different_key_returns_error which tests // that a signature made with a different private key is rejected. - #[test] - fn test_empty_signature_returns_error() { + #[tokio::test] + async fn test_empty_signature_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1642,7 +1666,8 @@ mod tests { *signature = BinaryData::new(vec![]); } }, - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -1674,8 +1699,8 @@ mod tests { ); } - #[test] - fn test_signature_from_different_key_returns_error() { + #[tokio::test] + async fn test_signature_from_different_key_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1713,7 +1738,8 @@ mod tests { *signature = BinaryData::new(wrong_signature.clone()); } }, - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -1745,8 +1771,8 @@ mod tests { ); } - #[test] - fn test_tampered_transition_after_signing_returns_error() { + #[tokio::test] + async fn test_tampered_transition_after_signing_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1775,7 +1801,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; // Tamper with the transition data after signing (change output amount) if let StateTransition::AddressFundsTransfer(AddressFundsTransferTransition::V0( @@ -1816,8 +1843,8 @@ mod tests { ); } - #[test] - fn test_tampered_input_amount_returns_error() { + #[tokio::test] + async fn test_tampered_input_amount_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1846,7 +1873,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; // Tamper with the input amount after signing if let StateTransition::AddressFundsTransfer(AddressFundsTransferTransition::V0( @@ -1886,8 +1914,8 @@ mod tests { ); } - #[test] - fn test_tampered_nonce_returns_error() { + #[tokio::test] + async fn test_tampered_nonce_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1916,7 +1944,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; // Tamper with the nonce after signing if let StateTransition::AddressFundsTransfer(AddressFundsTransferTransition::V0( @@ -1957,8 +1986,8 @@ mod tests { ); } - #[test] - fn test_multiple_inputs_one_invalid_witness_returns_error() { + #[tokio::test] + async fn test_multiple_inputs_one_invalid_witness_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1997,6 +2026,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); // Corrupt the second witness @@ -2041,8 +2071,8 @@ mod tests { ); } - #[test] - fn test_swapped_witnesses_returns_error() { + #[tokio::test] + async fn test_swapped_witnesses_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2081,6 +2111,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); // Swap the witnesses (each witness is for the wrong address now) @@ -2124,8 +2155,8 @@ mod tests { ); } - #[test] - fn test_witness_for_different_address_type_returns_error() { + #[tokio::test] + async fn test_witness_for_different_address_type_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2154,7 +2185,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; // Replace P2PKH witness with a P2SH witness (wrong type for address) if let StateTransition::AddressFundsTransfer(AddressFundsTransferTransition::V0( @@ -2197,8 +2229,8 @@ mod tests { ); } - #[test] - fn test_truncated_signature_returns_error() { + #[tokio::test] + async fn test_truncated_signature_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2235,7 +2267,8 @@ mod tests { *signature = BinaryData::new(truncated); } }, - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -2267,8 +2300,8 @@ mod tests { ); } - #[test] - fn test_extra_bytes_in_signature_returns_error() { + #[tokio::test] + async fn test_extra_bytes_in_signature_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2304,7 +2337,8 @@ mod tests { *signature = BinaryData::new(extended); } }, - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -2336,8 +2370,8 @@ mod tests { ); } - #[test] - fn test_all_zero_signature_returns_error() { + #[tokio::test] + async fn test_all_zero_signature_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2371,7 +2405,8 @@ mod tests { *signature = BinaryData::new(vec![0u8; 65]); // All zeros, 65 bytes } }, - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -2403,8 +2438,8 @@ mod tests { ); } - #[test] - fn test_flipped_bit_in_signature_returns_error() { + #[tokio::test] + async fn test_flipped_bit_in_signature_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2443,7 +2478,8 @@ mod tests { *signature = BinaryData::new(bytes); } }, - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -2475,8 +2511,8 @@ mod tests { ); } - #[test] - fn test_user_fee_increase_tampered_returns_error() { + #[tokio::test] + async fn test_user_fee_increase_tampered_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2505,7 +2541,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; // Tamper with user_fee_increase after signing if let StateTransition::AddressFundsTransfer(AddressFundsTransferTransition::V0( @@ -2556,7 +2593,7 @@ mod tests { use dpp::consensus::signature::SignatureError; /// Helper to create a P2SH multisig transfer with proper signing - fn create_p2sh_multisig_transfer( + async fn create_p2sh_multisig_transfer( signer: &TestAddressSigner, input_address: PlatformAddress, input_nonce: AddressNonce, @@ -2578,6 +2615,7 @@ mod tests { 0, PlatformVersion::latest(), ) + .await .expect("should create signed transition") } @@ -2585,8 +2623,8 @@ mod tests { // SUCCESS TESTS // ========================================== - #[test] - fn test_2_of_3_multisig_success() { + #[tokio::test] + async fn test_2_of_3_multisig_success() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2616,7 +2654,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -2644,8 +2683,8 @@ mod tests { ); } - #[test] - fn test_1_of_2_multisig_success() { + #[tokio::test] + async fn test_1_of_2_multisig_success() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2675,7 +2714,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -2703,8 +2743,8 @@ mod tests { ); } - #[test] - fn test_3_of_5_multisig_success() { + #[tokio::test] + async fn test_3_of_5_multisig_success() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2735,7 +2775,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -2767,8 +2808,8 @@ mod tests { // FAILURE TESTS // ========================================== - #[test] - fn test_insufficient_signatures_returns_error() { + #[tokio::test] + async fn test_insufficient_signatures_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2799,7 +2840,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; // Remove one signature to have only 1-of-2 required if let StateTransition::AddressFundsTransfer(AddressFundsTransferTransition::V0( @@ -2848,8 +2890,8 @@ mod tests { ); } - #[test] - fn test_wrong_redeem_script_hash_returns_error() { + #[tokio::test] + async fn test_wrong_redeem_script_hash_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2878,7 +2920,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; // Replace redeem script with a different one (wrong keys) if let StateTransition::AddressFundsTransfer(AddressFundsTransferTransition::V0( @@ -2932,8 +2975,8 @@ mod tests { ); } - #[test] - fn test_corrupted_signature_in_multisig_returns_error() { + #[tokio::test] + async fn test_corrupted_signature_in_multisig_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2962,7 +3005,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; // Corrupt one of the signatures if let StateTransition::AddressFundsTransfer(AddressFundsTransferTransition::V0( @@ -3014,8 +3058,8 @@ mod tests { ); } - #[test] - fn test_signature_from_wrong_key_returns_error() { + #[tokio::test] + async fn test_signature_from_wrong_key_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3044,7 +3088,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; // Replace one signature with a signature from a different key if let StateTransition::AddressFundsTransfer(AddressFundsTransferTransition::V0( @@ -3099,8 +3144,8 @@ mod tests { ); } - #[test] - fn test_empty_signatures_returns_error() { + #[tokio::test] + async fn test_empty_signatures_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3129,7 +3174,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; // Set empty signatures if let StateTransition::AddressFundsTransfer(AddressFundsTransferTransition::V0( @@ -3174,8 +3220,8 @@ mod tests { ); } - #[test] - fn test_empty_redeem_script_returns_error() { + #[tokio::test] + async fn test_empty_redeem_script_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3204,7 +3250,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; // Set empty redeem script if let StateTransition::AddressFundsTransfer(AddressFundsTransferTransition::V0( @@ -3249,8 +3296,8 @@ mod tests { ); } - #[test] - fn test_duplicate_signatures_returns_error() { + #[tokio::test] + async fn test_duplicate_signatures_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3279,7 +3326,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; // Use duplicate signatures (same signature twice) if let StateTransition::AddressFundsTransfer(AddressFundsTransferTransition::V0( @@ -3328,8 +3376,8 @@ mod tests { ); } - #[test] - fn test_invalid_redeem_script_format_returns_error() { + #[tokio::test] + async fn test_invalid_redeem_script_format_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3358,7 +3406,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; // Set garbage redeem script if let StateTransition::AddressFundsTransfer(AddressFundsTransferTransition::V0( @@ -3403,8 +3452,8 @@ mod tests { ); } - #[test] - fn test_mixed_p2pkh_and_p2sh_inputs_success() { + #[tokio::test] + async fn test_mixed_p2pkh_and_p2sh_inputs_success() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3443,6 +3492,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let transition_bytes = transition @@ -3479,8 +3529,8 @@ mod tests { mod multiple_inputs_outputs { use super::*; - #[test] - fn test_2_inputs_1_output_success() { + #[tokio::test] + async fn test_2_inputs_1_output_success() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3519,6 +3569,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let transition_bytes = transition @@ -3547,8 +3598,8 @@ mod tests { ); } - #[test] - fn test_1_input_2_outputs_success() { + #[tokio::test] + async fn test_1_input_2_outputs_success() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3586,6 +3637,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let transition_bytes = transition @@ -3614,8 +3666,8 @@ mod tests { ); } - #[test] - fn test_2_inputs_2_outputs_success() { + #[tokio::test] + async fn test_2_inputs_2_outputs_success() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3656,6 +3708,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let transition_bytes = transition @@ -3684,8 +3737,8 @@ mod tests { ); } - #[test] - fn test_maximum_16_inputs_success() { + #[tokio::test] + async fn test_maximum_16_inputs_success() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3723,6 +3776,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let transition_bytes = transition @@ -3759,8 +3813,8 @@ mod tests { mod post_execution_state { use super::*; - #[test] - fn test_input_balance_decreased_correctly() { + #[tokio::test] + async fn test_input_balance_decreased_correctly() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3791,7 +3845,8 @@ mod tests { transfer_amount, output_address, transfer_amount, - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -3840,8 +3895,8 @@ mod tests { assert_eq!(new_nonce, 1); } - #[test] - fn test_input_nonce_incremented() { + #[tokio::test] + async fn test_input_nonce_incremented() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3876,7 +3931,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -3919,8 +3975,8 @@ mod tests { assert_eq!(new_nonce, initial_nonce + 1); } - #[test] - fn test_output_address_balance_increased() { + #[tokio::test] + async fn test_output_address_balance_increased() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3953,7 +4009,8 @@ mod tests { transfer_amount, output_address, transfer_amount, - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -3996,8 +4053,8 @@ mod tests { assert_eq!(new_balance, output_initial_balance + transfer_amount); } - #[test] - fn test_output_address_created_if_not_exists() { + #[tokio::test] + async fn test_output_address_created_if_not_exists() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4035,7 +4092,8 @@ mod tests { transfer_amount, output_address, transfer_amount, - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -4077,8 +4135,8 @@ mod tests { mod fee_strategy_execution { use super::*; - #[test] - fn test_deduct_from_input_deducts_from_input_balance() { + #[tokio::test] + async fn test_deduct_from_input_deducts_from_input_balance() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4120,6 +4178,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let transition_bytes = transition @@ -4174,8 +4233,8 @@ mod tests { assert_eq!(output_balance, output_initial_balance + transfer_amount); } - #[test] - fn test_reduce_output_reduces_output_amount() { + #[tokio::test] + async fn test_reduce_output_reduces_output_amount() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4217,6 +4276,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let transition_bytes = transition @@ -4274,8 +4334,8 @@ mod tests { ); } - #[test] - fn test_user_fee_increase_affects_fee() { + #[tokio::test] + async fn test_user_fee_increase_affects_fee() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4312,6 +4372,7 @@ mod tests { 100, // 100% fee increase platform_version, ) + .await .expect("should create signed transition"); let transition_bytes = transition @@ -4353,8 +4414,8 @@ mod tests { use super::*; use dpp::consensus::signature::SignatureError; - #[test] - fn test_p2pkh_witness_for_p2sh_address_returns_error() { + #[tokio::test] + async fn test_p2pkh_witness_for_p2sh_address_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4392,6 +4453,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); // Replace P2SH witness with P2PKH witness @@ -4434,8 +4496,8 @@ mod tests { ); } - #[test] - fn test_1_of_1_multisig_success() { + #[tokio::test] + async fn test_1_of_1_multisig_success() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4472,6 +4534,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let transition_bytes = transition @@ -4500,8 +4563,8 @@ mod tests { ); } - #[test] - fn test_multiple_p2sh_inputs_success() { + #[tokio::test] + async fn test_multiple_p2sh_inputs_success() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4540,6 +4603,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let transition_bytes = transition @@ -4568,8 +4632,8 @@ mod tests { ); } - #[test] - fn test_signature_for_wrong_message_returns_error() { + #[tokio::test] + async fn test_signature_for_wrong_message_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4609,6 +4673,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); // Replace signatures with ones for wrong message (but from correct keys) @@ -4671,8 +4736,8 @@ mod tests { mod edge_cases { use super::*; - #[test] - fn test_transfer_full_balance_with_reduce_output_fee_strategy() { + #[tokio::test] + async fn test_transfer_full_balance_with_reduce_output_fee_strategy() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4711,6 +4776,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let transition_bytes = transition @@ -4740,8 +4806,8 @@ mod tests { ); } - #[test] - fn test_input_amount_equals_minimum_exactly() { + #[tokio::test] + async fn test_input_amount_equals_minimum_exactly() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4781,6 +4847,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let transition_bytes = transition @@ -4810,8 +4877,8 @@ mod tests { ); } - #[test] - fn test_output_amount_equals_minimum_exactly() { + #[tokio::test] + async fn test_output_amount_equals_minimum_exactly() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4849,6 +4916,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let transition_bytes = transition @@ -4885,8 +4953,8 @@ mod tests { mod nonce_edge_cases { use super::*; - #[test] - fn test_first_transaction_nonce_0_to_1() { + #[tokio::test] + async fn test_first_transaction_nonce_0_to_1() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4917,7 +4985,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -4960,8 +5029,8 @@ mod tests { assert_eq!(new_nonce, 1); } - #[test] - fn test_nonce_at_max_minus_1_can_transact() { + #[tokio::test] + async fn test_nonce_at_max_minus_1_can_transact() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4998,7 +5067,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; let transition_bytes = transition .serialize_to_bytes() @@ -5026,8 +5096,8 @@ mod tests { ); } - #[test] - fn test_multiple_inputs_different_nonces() { + #[tokio::test] + async fn test_multiple_inputs_different_nonces() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -5070,6 +5140,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create signed transition"); let transition_bytes = transition @@ -5130,8 +5201,8 @@ mod tests { use super::*; use dpp::serialization::PlatformDeserializable; - #[test] - fn test_serialize_deserialize_roundtrip() { + #[tokio::test] + async fn test_serialize_deserialize_roundtrip() { let platform_version = PlatformVersion::latest(); let mut signer = TestAddressSigner::new(); @@ -5145,7 +5216,8 @@ mod tests { dash_to_credits!(0.1), output_address, dash_to_credits!(0.1), - ); + ) + .await; // Serialize let bytes = transition @@ -5202,8 +5274,8 @@ mod tests { ); } - #[test] - fn test_malformed_serialized_data_rejected() { + #[tokio::test] + async fn test_malformed_serialized_data_rejected() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -5256,8 +5328,8 @@ mod tests { mod same_block_ordering { use super::*; - #[test] - fn test_two_transactions_same_address_same_block() { + #[tokio::test] + async fn test_two_transactions_same_address_same_block() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -5288,7 +5360,8 @@ mod tests { dash_to_credits!(0.1), output_address_1, dash_to_credits!(0.1), - ); + ) + .await; // Second transaction with nonce 2 let transition2 = create_signed_address_funds_transfer_transition( @@ -5298,7 +5371,8 @@ mod tests { dash_to_credits!(0.1), output_address_2, dash_to_credits!(0.1), - ); + ) + .await; let bytes1 = transition1.serialize_to_bytes().unwrap(); let bytes2 = transition2.serialize_to_bytes().unwrap(); @@ -5333,8 +5407,8 @@ mod tests { ); } - #[test] - fn test_wrong_nonce_order_in_same_block() { + #[tokio::test] + async fn test_wrong_nonce_order_in_same_block() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -5365,7 +5439,8 @@ mod tests { dash_to_credits!(0.1), output_address_1, dash_to_credits!(0.1), - ); + ) + .await; // Second transaction with nonce 1 let transition2 = create_signed_address_funds_transfer_transition( @@ -5375,7 +5450,8 @@ mod tests { dash_to_credits!(0.1), output_address_2, dash_to_credits!(0.1), - ); + ) + .await; let bytes1 = transition1.serialize_to_bytes().unwrap(); let bytes2 = transition2.serialize_to_bytes().unwrap(); @@ -5427,8 +5503,8 @@ mod tests { // Structure Validation Security // ------------------------------------------ - #[test] - fn test_too_many_outputs_returns_error() { + #[tokio::test] + async fn test_too_many_outputs_returns_error() { // A hacker might try to create many outputs to bloat state or cause DoS let platform_version = PlatformVersion::latest(); let max_outputs = platform_version.dpp.state_transitions.max_address_outputs; @@ -5473,8 +5549,8 @@ mod tests { ); } - #[test] - fn test_input_sum_overflow_returns_error() { + #[tokio::test] + async fn test_input_sum_overflow_returns_error() { // Attacker tries to overflow input sum to bypass balance checks let platform_version = PlatformVersion::latest(); @@ -5513,8 +5589,8 @@ mod tests { ); } - #[test] - fn test_output_sum_overflow_returns_error() { + #[tokio::test] + async fn test_output_sum_overflow_returns_error() { // Attacker tries to overflow output sum let platform_version = PlatformVersion::latest(); @@ -5554,8 +5630,8 @@ mod tests { // Double-Spend and Replay Attacks // ------------------------------------------ - #[test] - fn test_double_spend_same_block_second_fails() { + #[tokio::test] + async fn test_double_spend_same_block_second_fails() { // Attacker submits two transactions in same block that together exceed balance let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -5596,6 +5672,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); // Second transaction: send 0.6 DASH with nonce 2 (should fail - insufficient balance) @@ -5613,6 +5690,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let bytes1 = transition1.serialize_to_bytes().unwrap(); @@ -5650,8 +5728,8 @@ mod tests { ); } - #[test] - fn test_replay_attack_same_transaction_twice_fails() { + #[tokio::test] + async fn test_replay_attack_same_transaction_twice_fails() { // Attacker tries to replay an already-executed transaction let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -5688,6 +5766,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -5755,8 +5834,8 @@ mod tests { // Fee Strategy Attacks // ------------------------------------------ - #[test] - fn test_fee_reduces_output_to_zero() { + #[tokio::test] + async fn test_fee_reduces_output_to_zero() { // What happens when ReduceOutput strategy reduces output to exactly 0? // The output should be removed, but is this handled correctly? let platform_version = PlatformVersion::latest(); @@ -5803,6 +5882,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -5855,8 +5935,8 @@ mod tests { } } - #[test] - fn test_fee_exhaustion_deduct_from_depleted_input() { + #[tokio::test] + async fn test_fee_exhaustion_deduct_from_depleted_input() { // DeductFromInput when input's remaining balance after transfer is 0 let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -5896,6 +5976,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -5929,8 +6010,8 @@ mod tests { // P2SH Security Tests // ------------------------------------------ - #[test] - fn test_15_of_15_multisig_success() { + #[tokio::test] + async fn test_15_of_15_multisig_success() { // Maximum standard multisig: 15-of-15 let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -5980,6 +6061,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -6006,8 +6088,8 @@ mod tests { ); } - #[test] - fn test_p2sh_with_timelock_script_fails() { + #[tokio::test] + async fn test_p2sh_with_timelock_script_fails() { // Attacker tries to use a timelock script (CHECKLOCKTIMEVERIFY) // Platform should not support timelock scripts as they require block height context let platform_version = PlatformVersion::latest(); @@ -6113,8 +6195,8 @@ mod tests { ); } - #[test] - fn test_p2sh_with_op_return_script_fails() { + #[tokio::test] + async fn test_p2sh_with_op_return_script_fails() { // Attacker tries to use a non-standard script that doesn't verify signatures let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -6192,8 +6274,8 @@ mod tests { // Same Block Edge Cases // ------------------------------------------ - #[test] - fn test_receive_and_spend_same_block() { + #[tokio::test] + async fn test_receive_and_spend_same_block() { // Can an address receive funds and spend them in the same block? // - check_tx for the second tx should FAIL (middle_address doesn't exist in mempool view) // - but block execution of both should SUCCEED (first tx creates middle_address before second runs) @@ -6237,6 +6319,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); // Transaction 2: middle -> final (middle doesn't have funds yet!) @@ -6255,6 +6338,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let bytes1 = transition1.serialize_to_bytes().unwrap(); @@ -6306,8 +6390,8 @@ mod tests { ); } - #[test] - fn test_concurrent_transfers_to_same_output() { + #[tokio::test] + async fn test_concurrent_transfers_to_same_output() { // Two different inputs send to same output in same block let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -6351,6 +6435,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let mut inputs2 = BTreeMap::new(); @@ -6366,6 +6451,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let bytes1 = transition1.serialize_to_bytes().unwrap(); @@ -6423,8 +6509,8 @@ mod tests { // Maximum Value Tests // ------------------------------------------ - #[test] - fn test_transfer_near_max_u64() { + #[tokio::test] + async fn test_transfer_near_max_u64() { // Test transfer of very large amounts (near u64::MAX) let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -6468,6 +6554,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -6499,8 +6586,8 @@ mod tests { // Script Security Tests // ------------------------------------------ - #[test] - fn test_p2sh_with_op_true_script_fails() { + #[tokio::test] + async fn test_p2sh_with_op_true_script_fails() { // CRITICAL: Attacker tries to use OP_TRUE (OP_1) script that always succeeds // This would allow anyone to spend without a valid signature let platform_version = PlatformVersion::latest(); @@ -6576,8 +6663,8 @@ mod tests { ); } - #[test] - fn test_p2sh_with_op_1_script_fails() { + #[tokio::test] + async fn test_p2sh_with_op_1_script_fails() { // Same as OP_TRUE but using explicit OP_1 (0x51) let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -6649,8 +6736,8 @@ mod tests { ); } - #[test] - fn test_p2sh_extra_signatures_beyond_threshold() { + #[tokio::test] + async fn test_p2sh_extra_signatures_beyond_threshold() { // For a 2-of-3 multisig, provide 5 signatures // System should either accept (ignoring extras) or reject let platform_version = PlatformVersion::latest(); @@ -6767,8 +6854,8 @@ mod tests { } } - #[test] - fn test_p2sh_with_disabled_opcode_op_cat_fails() { + #[tokio::test] + async fn test_p2sh_with_disabled_opcode_op_cat_fails() { // OP_CAT (0x7e) is disabled in Bitcoin/Dash let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -6840,8 +6927,8 @@ mod tests { ); } - #[test] - fn test_p2sh_with_op_ver_disabled_opcode_fails() { + #[tokio::test] + async fn test_p2sh_with_op_ver_disabled_opcode_fails() { // OP_VER (0x62) is a reserved/disabled opcode let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -6913,8 +7000,8 @@ mod tests { ); } - #[test] - fn test_very_large_redeem_script_rejected() { + #[tokio::test] + async fn test_very_large_redeem_script_rejected() { // Bitcoin limits redeem scripts to 520 bytes // Try a script larger than typical limits let platform_version = PlatformVersion::latest(); @@ -6993,8 +7080,8 @@ mod tests { ); } - #[test] - fn test_signature_with_high_s_value() { + #[tokio::test] + async fn test_signature_with_high_s_value() { // ECDSA signatures can be malleable - for any valid (r, s), (r, n-s) is also valid // Systems should enforce low-S to prevent malleability let platform_version = PlatformVersion::latest(); @@ -7033,6 +7120,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); // Extract the signature and create a high-S version @@ -7108,8 +7196,8 @@ mod tests { } } - #[test] - fn test_non_canonical_der_signature_rejected() { + #[tokio::test] + async fn test_non_canonical_der_signature_rejected() { // Test signatures with non-canonical DER encoding // e.g., extra padding bytes, wrong length prefixes let platform_version = PlatformVersion::latest(); @@ -7193,8 +7281,8 @@ mod tests { ); } - #[test] - fn test_empty_script_fails() { + #[tokio::test] + async fn test_empty_script_fails() { // Empty redeem script should fail let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -7267,8 +7355,8 @@ mod tests { ); } - #[test] - fn test_p2sh_with_op_codeseparator_fails() { + #[tokio::test] + async fn test_p2sh_with_op_codeseparator_fails() { // OP_CODESEPARATOR can affect which parts of script are signed // This is rarely used and could be a vector for confusion attacks let platform_version = PlatformVersion::latest(); @@ -7343,8 +7431,8 @@ mod tests { ); } - #[test] - fn test_zero_output_after_fee_deduction() { + #[tokio::test] + async fn test_zero_output_after_fee_deduction() { // What if fee deduction makes output exactly 0? let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -7419,8 +7507,8 @@ mod tests { } } - #[test] - fn test_fee_simple_p2pkh_1_input_1_output_deduct_from_input() { + #[tokio::test] + async fn test_fee_simple_p2pkh_1_input_1_output_deduct_from_input() { // Simple P2PKH transfer: 1 input -> 1 output, fee deducted from input let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -7458,6 +7546,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -7506,8 +7595,8 @@ mod tests { ); } - #[test] - fn test_fee_simple_p2pkh_1_input_1_output_reduce_output() { + #[tokio::test] + async fn test_fee_simple_p2pkh_1_input_1_output_reduce_output() { // Simple P2PKH transfer: 1 input -> 1 output, fee reduced from output let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -7545,6 +7634,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -7591,8 +7681,8 @@ mod tests { ); } - #[test] - fn test_fee_p2pkh_2_inputs_1_output() { + #[tokio::test] + async fn test_fee_p2pkh_2_inputs_1_output() { // P2PKH: 2 inputs -> 1 output let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -7632,6 +7722,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -7678,8 +7769,8 @@ mod tests { ); } - #[test] - fn test_fee_p2pkh_1_input_2_outputs() { + #[tokio::test] + async fn test_fee_p2pkh_1_input_2_outputs() { // P2PKH: 1 input -> 2 outputs let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -7718,6 +7809,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -7764,8 +7856,8 @@ mod tests { ); } - #[test] - fn test_fee_p2sh_2_of_3_multisig() { + #[tokio::test] + async fn test_fee_p2sh_2_of_3_multisig() { // P2SH 2-of-3 multisig: 1 input -> 1 output let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -7812,6 +7904,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -7858,8 +7951,8 @@ mod tests { ); } - #[test] - fn test_fee_p2sh_3_of_5_multisig() { + #[tokio::test] + async fn test_fee_p2sh_3_of_5_multisig() { // P2SH 3-of-5 multisig: 1 input -> 1 output let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -7906,6 +7999,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -7952,8 +8046,8 @@ mod tests { ); } - #[test] - fn test_fee_with_user_fee_increase() { + #[tokio::test] + async fn test_fee_with_user_fee_increase() { // Test that user_fee_increase adds to the processing fee let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -7993,6 +8087,7 @@ mod tests { user_fee_increase, platform_version, ) + .await .expect("should create transition"); let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -8046,8 +8141,8 @@ mod tests { ); } - #[test] - fn test_fee_maximum_16_inputs() { + #[tokio::test] + async fn test_fee_maximum_16_inputs() { // Maximum inputs (16) to verify fee scaling let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -8091,6 +8186,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -8143,8 +8239,8 @@ mod tests { ); } - #[test] - fn test_fee_new_output_address_vs_existing() { + #[tokio::test] + async fn test_fee_new_output_address_vs_existing() { // Compare fee when output address already exists vs new address let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -8182,6 +8278,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let bytes1 = transition1.serialize_to_bytes().unwrap(); @@ -8232,6 +8329,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let bytes2 = transition2.serialize_to_bytes().unwrap(); @@ -8286,8 +8384,8 @@ mod tests { ); } - #[test] - fn test_fee_simple_p2pkh_1_input_1_output_deduct_from_input_on_version_11() { + #[tokio::test] + async fn test_fee_simple_p2pkh_1_input_1_output_deduct_from_input_on_version_11() { let platform_version = PlatformVersion::get(11).expect("expected version 11"); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -8324,6 +8422,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -8369,8 +8468,8 @@ mod tests { ); } - #[test] - fn test_fee_p2pkh_2_inputs_1_output_on_version_11() { + #[tokio::test] + async fn test_fee_p2pkh_2_inputs_1_output_on_version_11() { let platform_version = PlatformVersion::get(11).expect("expected version 11"); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -8410,6 +8509,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -8455,8 +8555,8 @@ mod tests { ); } - #[test] - fn test_fee_p2sh_2_of_3_multisig_on_version_11() { + #[tokio::test] + async fn test_fee_p2sh_2_of_3_multisig_on_version_11() { let platform_version = PlatformVersion::get(11).expect("expected version 11"); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -8502,6 +8602,7 @@ mod tests { 0, platform_version, ) + .await .expect("should create transition"); let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -8564,8 +8665,8 @@ mod tests { /// witness validation stage caught it, not the structure validation stage). /// /// Location: rs-dpp/.../state_transition_witness_validation.rs:56-60 - #[test] - fn test_zero_witnesses_rejected_by_witness_validation() { + #[tokio::test] + async fn test_zero_witnesses_rejected_by_witness_validation() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -8665,8 +8766,8 @@ mod tests { /// reject such values defensively. /// /// Location: rs-drive/src/drive/address_funds/set_balance_to_address/v0/mod.rs - #[test] - fn test_balance_exceeding_i64_max_returns_overflow_error() { + #[tokio::test] + async fn test_balance_exceeding_i64_max_returns_overflow_error() { let platform_version = PlatformVersion::latest(); let platform = TestPlatformBuilder::new() @@ -8724,8 +8825,8 @@ mod tests { /// to verify the address cannot transact further. /// /// Location: rs-dpp/src/lib.rs:117 - #[test] - fn test_nonce_at_u32_max_locks_address() { + #[tokio::test] + async fn test_nonce_at_u32_max_locks_address() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -8763,7 +8864,8 @@ mod tests { dash_to_credits!(0.01), recipient, dash_to_credits!(0.01), - ); + ) + .await; let result1 = transition1.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -8816,8 +8918,8 @@ mod tests { /// because all indices shifted down after the removal. /// /// Location: rs-dpp/.../deduct_fee_from_inputs_and_outputs/v0/mod.rs:35-45 - #[test] - fn test_fee_deduction_stable_after_entry_removal() { + #[tokio::test] + async fn test_fee_deduction_stable_after_entry_removal() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -8881,7 +8983,8 @@ mod tests { inputs, outputs, fee_strategy, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/creation.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/creation.rs index 34a4cb0cdaa..65d7bf16d4b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/creation.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/creation.rs @@ -50,8 +50,8 @@ mod creation_tests { use crate::config::PlatformConfig; use crate::execution::validation::state_transition::tests::{create_card_game_external_token_contract_with_owner_identity, create_card_game_internal_token_contract_with_owner_identity_transfer_tokens, create_token_contract_with_owner_identity}; - #[test] - fn test_document_creation() { + #[tokio::test] + async fn test_document_creation() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -101,6 +101,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -135,8 +136,8 @@ mod creation_tests { .expect("expected to commit transaction"); } - #[test] - fn test_document_creation_should_fail_when_creator_id_is_provided() { + #[tokio::test] + async fn test_document_creation_should_fail_when_creator_id_is_provided() { let platform_version = PlatformVersion::latest(); let (mut platform, contract) = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -187,6 +188,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -233,8 +235,8 @@ mod creation_tests { ); } - #[test] - fn test_document_creation_should_fail_if_reusing_entropy() { + #[tokio::test] + async fn test_document_creation_should_fail_if_reusing_entropy() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -284,6 +286,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -345,6 +348,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -382,8 +386,8 @@ mod creation_tests { .expect("expected to commit transaction"); } - #[test] - fn test_document_creation_with_very_big_field() { + #[tokio::test] + async fn test_document_creation_with_very_big_field() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -452,6 +456,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -499,8 +504,8 @@ mod creation_tests { .expect("expected to commit transaction"); } - #[test] - fn test_document_creation_on_contested_unique_index() { + #[tokio::test] + async fn test_document_creation_on_contested_unique_index() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -631,6 +636,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_1 = @@ -651,6 +657,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_2 = @@ -671,6 +678,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_1 = documents_batch_create_transition_1 @@ -690,6 +698,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_2 = documents_batch_create_transition_2 @@ -951,8 +960,8 @@ mod creation_tests { assert_eq!(second_contender.vote_tally(), Some(0)); } - #[test] - fn test_document_creation_on_contested_unique_index_should_fail_if_not_paying_for_it() { + #[tokio::test] + async fn test_document_creation_on_contested_unique_index_should_fail_if_not_paying_for_it() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { network: Network::Mainnet, @@ -1047,6 +1056,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_1 = @@ -1083,6 +1093,7 @@ mod creation_tests { documents_batch_inner_create_transition_1.into(); documents_batch_create_transition_1 .sign_external(&key_1, &signer_1, Some(|_, _| Ok(SecurityLevel::HIGH))) + .await .expect("expected to sign"); let documents_batch_create_serialized_transition_1 = documents_batch_create_transition_1 @@ -1222,8 +1233,8 @@ mod creation_tests { assert!(documents.is_empty()); } - #[test] - fn test_document_creation_on_contested_unique_index_should_not_fail_if_not_paying_for_it_on_testnet_before_epoch_2080( + #[tokio::test] + async fn test_document_creation_on_contested_unique_index_should_not_fail_if_not_paying_for_it_on_testnet_before_epoch_2080( ) { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -1319,6 +1330,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_1 = @@ -1354,6 +1366,7 @@ mod creation_tests { documents_batch_inner_create_transition_1.into(); documents_batch_create_transition_1 .sign_external(&key_1, &signer_1, Some(|_, _| Ok(SecurityLevel::HIGH))) + .await .expect("expected to sign"); let documents_batch_create_serialized_transition_1 = documents_batch_create_transition_1 @@ -1490,8 +1503,8 @@ mod creation_tests { assert!(!documents.is_empty()); } - #[test] - fn test_document_creation_on_contested_unique_index_should_fail_if_reusing_entropy() { + #[tokio::test] + async fn test_document_creation_on_contested_unique_index_should_fail_if_reusing_entropy() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1665,6 +1678,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_1 = @@ -1685,6 +1699,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_2 = @@ -1705,6 +1720,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_3 = @@ -1725,6 +1741,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_1 = documents_batch_create_transition_1 @@ -1744,6 +1761,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_2 = documents_batch_create_transition_2 @@ -1763,6 +1781,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_3 = documents_batch_create_transition_3 @@ -2057,8 +2076,8 @@ mod creation_tests { assert_eq!(second_contender.vote_tally(), Some(0)); } - #[test] - fn test_that_a_contested_document_can_not_be_added_to_after_a_week() { + #[tokio::test] + async fn test_that_a_contested_document_can_not_be_added_to_after_a_week() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -2073,7 +2092,8 @@ mod creation_tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -2088,7 +2108,8 @@ mod creation_tests { 10, None, platform_version, - ); + ) + .await; let max_join_time = platform_version .dpp @@ -2107,7 +2128,8 @@ mod creation_tests { "quantum", None, // this should succeed, as we are under a week platform_version, - ); + ) + .await; let time_now = platform_version .dpp @@ -2141,11 +2163,12 @@ mod creation_tests { "quantum", Some(expected_error_message.as_str()), // this should fail, as we are over a week platform_version, - ); + ) + .await; } - #[test] - fn test_that_a_contest_can_not_be_joined_twice_by_the_same_identity() { + #[tokio::test] + async fn test_that_a_contest_can_not_be_joined_twice_by_the_same_identity() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -2170,7 +2193,8 @@ mod creation_tests { 7, "quantum", platform_version, - ); + ) + .await; let domain = dpns_contract .document_type_for_name("domain") @@ -2200,6 +2224,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_1 = documents_batch_create_transition_1 @@ -2245,8 +2270,8 @@ mod creation_tests { assert_eq!(consensus_error.to_string(), "An Identity with the id BjNejy4r9QAvLHpQ9Yq6yRMgNymeGZ46d48fJxJbMrfW is already a contestant for the vote_poll ContestedDocumentResourceVotePoll { contract_id: GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec, document_type_name: domain, index_name: parentNameAndLabel, index_values: [string dash, string quantum] }"); } - #[test] - fn test_that_a_contested_document_can_not_be_added_if_we_are_locked() { + #[tokio::test] + async fn test_that_a_contested_document_can_not_be_added_if_we_are_locked() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -2261,7 +2286,8 @@ mod creation_tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -2276,7 +2302,8 @@ mod creation_tests { 10, None, platform_version, - ); + ) + .await; fast_forward_to_block( &platform, @@ -2301,7 +2328,8 @@ mod creation_tests { "quantum", None, // this should succeed, as we are under the `platform_version.dpp.validation.voting.allow_other_contenders_time_testing_ms` platform_version, - ); + ) + .await; let time_after_distribution_limit = platform_version .dpp @@ -2353,11 +2381,12 @@ mod creation_tests { "quantum", Some(expected_error_message.as_str()), // this should fail, as it is locked platform_version, - ); + ) + .await; } - #[test] - fn test_document_creation_on_restricted_document_type_that_only_allows_contract_owner_to_create( + #[tokio::test] + async fn test_document_creation_on_restricted_document_type_that_only_allows_contract_owner_to_create( ) { let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -2434,6 +2463,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -2495,6 +2525,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -2539,8 +2570,8 @@ mod creation_tests { assert_eq!(consensus_error.to_string(), "Document Creation on 86LHvdC1Tqx5P97LQUSibGFqf2vnKFpB6VkqQ7oso86e:card is not allowed because of the document type's creation restriction mode Owner Only"); } - #[test] - fn test_document_creation_on_search_system_contract_fails_due_to_restriction() { + #[tokio::test] + async fn test_document_creation_on_search_system_contract_fails_due_to_restriction() { // Build test platform let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -2620,6 +2651,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -2678,8 +2710,8 @@ mod creation_tests { ); } - #[test] - fn test_document_creation_paid_with_a_token_burn() { + #[tokio::test] + async fn test_document_creation_paid_with_a_token_burn() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -2758,6 +2790,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -2823,8 +2856,8 @@ mod creation_tests { assert_eq!(contract_owner_token_balance, None); } - #[test] - fn test_document_creation_paid_with_a_token_transfer() { + #[tokio::test] + async fn test_document_creation_paid_with_a_token_transfer() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -2903,6 +2936,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -2967,8 +3001,8 @@ mod creation_tests { assert_eq!(contract_owner_token_balance, Some(10)); } - #[test] - fn test_document_creation_paid_with_a_token_transfer_to_ones_self() { + #[tokio::test] + async fn test_document_creation_paid_with_a_token_transfer_to_ones_self() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -3046,6 +3080,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -3097,8 +3132,8 @@ mod creation_tests { assert_eq!(token_balance, Some(15)); } - #[test] - fn test_document_creation_paid_with_a_token_not_spending_enough() { + #[tokio::test] + async fn test_document_creation_paid_with_a_token_not_spending_enough() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -3177,6 +3212,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -3229,8 +3265,8 @@ mod creation_tests { assert_eq!(token_balance, Some(15)); } - #[test] - fn test_document_creation_paid_with_a_token_minimum_cost_set_rare_scenario() { + #[tokio::test] + async fn test_document_creation_paid_with_a_token_minimum_cost_set_rare_scenario() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -3309,6 +3345,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -3361,8 +3398,8 @@ mod creation_tests { assert_eq!(token_balance, Some(15)); } - #[test] - fn test_document_creation_paid_with_a_token_agreeing_to_too_much() { + #[tokio::test] + async fn test_document_creation_paid_with_a_token_agreeing_to_too_much() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -3441,6 +3478,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -3488,8 +3526,8 @@ mod creation_tests { assert_eq!(token_balance, Some(5)); } - #[test] - fn test_document_creation_paid_with_a_token_token_info_not_set() { + #[tokio::test] + async fn test_document_creation_paid_with_a_token_token_info_not_set() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -3562,6 +3600,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -3614,8 +3653,8 @@ mod creation_tests { assert_eq!(token_balance, Some(15)); } - #[test] - fn test_document_creation_not_enough_token_balance_to_create_document() { + #[tokio::test] + async fn test_document_creation_not_enough_token_balance_to_create_document() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -3695,6 +3734,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -3747,8 +3787,8 @@ mod creation_tests { assert_eq!(token_balance, Some(8)); } - #[test] - fn test_document_creation_paid_with_an_external_token() { + #[tokio::test] + async fn test_document_creation_paid_with_an_external_token() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -3855,6 +3895,7 @@ mod creation_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); assert_matches!( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/deletion.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/deletion.rs index 1e014792631..f48ffe27f0d 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/deletion.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/deletion.rs @@ -6,8 +6,8 @@ mod deletion_tests { use dpp::tokens::token_payment_info::v0::TokenPaymentInfoV0; use dpp::tokens::token_payment_info::TokenPaymentInfo; - #[test] - fn test_document_delete_on_document_type_that_is_mutable_and_can_be_deleted() { + #[tokio::test] + async fn test_document_delete_on_document_type_that_is_mutable_and_can_be_deleted() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -65,6 +65,7 @@ mod deletion_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -107,6 +108,7 @@ mod deletion_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition = documents_batch_deletion_transition @@ -161,8 +163,8 @@ mod deletion_tests { ); } - #[test] - fn test_document_delete_on_document_type_that_is_mutable_and_can_not_be_deleted() { + #[tokio::test] + async fn test_document_delete_on_document_type_that_is_mutable_and_can_not_be_deleted() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -244,6 +246,7 @@ mod deletion_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -286,6 +289,7 @@ mod deletion_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_deletion_serialized_transition = documents_batch_deletion_transition @@ -323,8 +327,8 @@ mod deletion_tests { assert_eq!(processing_result.aggregated_fees().processing_fee, 445700); } - #[test] - fn test_document_delete_on_document_type_that_is_not_mutable_and_can_be_deleted() { + #[tokio::test] + async fn test_document_delete_on_document_type_that_is_not_mutable_and_can_be_deleted() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -406,6 +410,7 @@ mod deletion_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -448,6 +453,7 @@ mod deletion_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_deletion_serialized_transition = documents_batch_deletion_transition @@ -502,8 +508,8 @@ mod deletion_tests { ); } - #[test] - fn test_document_delete_on_document_type_that_is_not_mutable_and_can_not_be_deleted() { + #[tokio::test] + async fn test_document_delete_on_document_type_that_is_not_mutable_and_can_not_be_deleted() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -568,6 +574,7 @@ mod deletion_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -610,6 +617,7 @@ mod deletion_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_deletion_serialized_transition = documents_batch_deletion_transition @@ -647,8 +655,8 @@ mod deletion_tests { assert_eq!(processing_result.aggregated_fees().processing_fee, 445700); } - #[test] - fn test_document_delete_that_does_not_yet_exist() { + #[tokio::test] + async fn test_document_delete_that_does_not_yet_exist() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -701,6 +709,7 @@ mod deletion_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_delete_serialized_transition = documents_batch_delete_transition @@ -737,8 +746,8 @@ mod deletion_tests { assert_eq!(processing_result.aggregated_fees().processing_fee, 516040); } - #[test] - fn test_document_deletion_that_needs_a_token() { + #[tokio::test] + async fn test_document_deletion_that_needs_a_token() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -804,6 +813,7 @@ mod deletion_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -868,6 +878,7 @@ mod deletion_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition = documents_batch_deletion_transition @@ -915,8 +926,8 @@ mod deletion_tests { assert_eq!(token_balance, Some(4)); } - #[test] - fn test_document_deletion_that_needs_a_token_not_enough_balance_to_delete() { + #[tokio::test] + async fn test_document_deletion_that_needs_a_token_not_enough_balance_to_delete() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -981,6 +992,7 @@ mod deletion_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1045,6 +1057,7 @@ mod deletion_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition = documents_batch_deletion_transition @@ -1097,8 +1110,8 @@ mod deletion_tests { assert_eq!(token_balance, None); } - #[test] - fn test_document_deletion_where_we_are_not_the_owner() { + #[tokio::test] + async fn test_document_deletion_where_we_are_not_the_owner() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1155,6 +1168,7 @@ mod deletion_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1197,6 +1211,7 @@ mod deletion_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_deletion_serialized_transition = documents_batch_deletion_transition diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/dpns.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/dpns.rs index cab9899981f..36433c4df60 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/dpns.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/dpns.rs @@ -19,8 +19,8 @@ mod dpns_tests { use rand::prelude::StdRng; use std::collections::BTreeMap; - #[test] - fn test_dpns_contract_references_with_no_contested_unique_index() { + #[tokio::test] + async fn test_dpns_contract_references_with_no_contested_unique_index() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -219,6 +219,7 @@ mod dpns_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_1 = @@ -239,6 +240,7 @@ mod dpns_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_2 = @@ -259,6 +261,7 @@ mod dpns_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_3 = @@ -279,6 +282,7 @@ mod dpns_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_1 = documents_batch_create_transition_1 @@ -298,6 +302,7 @@ mod dpns_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_2 = documents_batch_create_transition_2 @@ -317,6 +322,7 @@ mod dpns_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_3 = documents_batch_create_transition_3 @@ -468,8 +474,8 @@ mod dpns_tests { assert_eq!(documents.len(), 0); } - #[test] - fn test_dpns_contract_references_with_no_contested_unique_index_null_searchable_true() { + #[tokio::test] + async fn test_dpns_contract_references_with_no_contested_unique_index_null_searchable_true() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -668,6 +674,7 @@ mod dpns_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_1 = @@ -688,6 +695,7 @@ mod dpns_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_2 = @@ -708,6 +716,7 @@ mod dpns_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_3 = @@ -728,6 +737,7 @@ mod dpns_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_1 = documents_batch_create_transition_1 @@ -747,6 +757,7 @@ mod dpns_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_2 = documents_batch_create_transition_2 @@ -766,6 +777,7 @@ mod dpns_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_3 = documents_batch_create_transition_3 diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/nft.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/nft.rs index f1909d2e061..ce43810cdd0 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/nft.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/nft.rs @@ -5,8 +5,8 @@ mod nft_tests { use crate::test::helpers::fast_forward_to_block::fast_forward_to_block; use dpp::tokens::token_payment_info::v0::TokenPaymentInfoV0; use dpp::tokens::token_payment_info::TokenPaymentInfo; - #[test] - fn test_document_set_price_on_document_without_ability_to_purchase() { + #[tokio::test] + async fn test_document_set_price_on_document_without_ability_to_purchase() { let platform_version = PlatformVersion::latest(); let (mut platform, contract) = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -54,6 +54,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -123,6 +124,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the update price"); let documents_batch_transfer_serialized_transition = @@ -164,8 +166,8 @@ mod nft_tests { assert_eq!(consensus_error.to_string(), "Document transition action card is in trade mode No Trading that does not support the seller setting the price is not supported"); } - #[test] - fn test_document_set_price() { + #[tokio::test] + async fn test_document_set_price() { let platform_version = PlatformVersion::latest(); let (mut platform, contract) = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -215,6 +217,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -307,6 +310,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the update price"); let documents_batch_transfer_serialized_transition = @@ -373,8 +377,8 @@ mod nft_tests { assert_eq!(document.revision(), Some(2)); } - #[test] - fn test_document_set_price_and_purchase() { + #[tokio::test] + async fn test_document_set_price_and_purchase() { let platform_version = PlatformVersion::latest(); let (mut platform, contract) = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -433,6 +437,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -551,6 +556,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the update price"); let documents_batch_transfer_serialized_transition = @@ -666,6 +672,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the purchase"); let documents_batch_purchase_serialized_transition = documents_batch_purchase_transition @@ -749,8 +756,8 @@ mod nft_tests { assert_eq!(buyers_balance, dash_to_credits!(0.9) - 68691480); } - #[test] - fn test_document_set_price_and_purchase_different_epoch_documents_mutable() { + #[tokio::test] + async fn test_document_set_price_and_purchase_different_epoch_documents_mutable() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -825,6 +832,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -947,6 +955,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition = documents_batch_update_transition @@ -1041,6 +1050,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the update price"); let documents_batch_transfer_serialized_transition = @@ -1168,6 +1178,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the purchase"); let documents_batch_purchase_serialized_transition = documents_batch_purchase_transition @@ -1266,8 +1277,8 @@ mod nft_tests { assert_eq!(buyers_balance, dash_to_credits!(0.9) - 68956280); } - #[test] - fn test_document_set_price_and_purchase_different_epoch() { + #[tokio::test] + async fn test_document_set_price_and_purchase_different_epoch() { let platform_version = PlatformVersion::latest(); let (mut platform, contract) = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -1326,6 +1337,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1448,6 +1460,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the update price"); let documents_batch_transfer_serialized_transition = @@ -1565,6 +1578,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the purchase"); let documents_batch_purchase_serialized_transition = documents_batch_purchase_transition @@ -1648,8 +1662,8 @@ mod nft_tests { assert_eq!(buyers_balance, dash_to_credits!(0.9) - 68691480); } - #[test] - fn test_document_set_price_and_try_purchase_at_different_amount() { + #[tokio::test] + async fn test_document_set_price_and_try_purchase_at_different_amount() { let platform_version = PlatformVersion::latest(); let (mut platform, contract) = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -1708,6 +1722,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1753,6 +1768,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the update price"); let documents_batch_transfer_serialized_transition = @@ -1802,6 +1818,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the purchase"); let documents_batch_purchase_serialized_transition = documents_batch_purchase_transition @@ -1844,8 +1861,8 @@ mod nft_tests { assert_eq!(consensus_error.to_string(), "5rJccTdtJfg6AxSKyrptWUug3PWjveEitTTLqBn9wHdk document can not be purchased for 35000000000, it's sale price is 50000000000 (in credits)"); } - #[test] - fn test_document_set_price_and_purchase_from_ones_self() { + #[tokio::test] + async fn test_document_set_price_and_purchase_from_ones_self() { let platform_version = PlatformVersion::latest(); let (mut platform, contract) = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -1901,6 +1918,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1946,6 +1964,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the update price"); let documents_batch_transfer_serialized_transition = @@ -1995,6 +2014,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the purchase"); let documents_batch_purchase_serialized_transition = documents_batch_purchase_transition @@ -2037,8 +2057,8 @@ mod nft_tests { assert_eq!(consensus_error.to_string(), "Document transition action on document type: card identity trying to purchase a document that is already owned by the purchaser is not supported"); } - #[test] - fn test_document_set_price_and_purchase_then_try_buy_back() { + #[tokio::test] + async fn test_document_set_price_and_purchase_then_try_buy_back() { // In this test we try to buy back a document after it has been sold let platform_version = PlatformVersion::latest(); @@ -2099,6 +2119,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -2144,6 +2165,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the update price"); let documents_batch_transfer_serialized_transition = @@ -2193,6 +2215,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the purchase"); let documents_batch_purchase_serialized_transition = documents_batch_purchase_transition @@ -2303,6 +2326,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the purchase"); let documents_batch_purchase_serialized_transition = documents_batch_purchase_transition @@ -2348,8 +2372,8 @@ mod nft_tests { ); } - #[test] - fn test_document_set_price_and_purchase_with_enough_credits_to_buy_but_not_enough_to_pay_for_processing( + #[tokio::test] + async fn test_document_set_price_and_purchase_with_enough_credits_to_buy_but_not_enough_to_pay_for_processing( ) { let platform_version = PlatformVersion::latest(); let (mut platform, contract) = TestPlatformBuilder::new() @@ -2401,6 +2425,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -2493,6 +2518,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the update price"); let documents_batch_transfer_serialized_transition = @@ -2586,6 +2612,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the purchase"); let documents_batch_purchase_serialized_transition = documents_batch_purchase_transition @@ -2625,8 +2652,8 @@ mod nft_tests { assert_eq!(processing_result.aggregated_fees().processing_fee, 0); } - #[test] - fn test_document_set_price_on_not_owned_document() { + #[tokio::test] + async fn test_document_set_price_on_not_owned_document() { let platform_version = PlatformVersion::latest(); let (mut platform, contract) = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -2677,6 +2704,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -2724,6 +2752,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the update price"); let documents_batch_transfer_serialized_transition = @@ -2789,8 +2818,8 @@ mod nft_tests { ); } - #[test] - fn test_document_set_price_and_purchase_with_token_costs() { + #[tokio::test] + async fn test_document_set_price_and_purchase_with_token_costs() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -2874,6 +2903,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -2975,6 +3005,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the update price"); let documents_batch_transfer_serialized_transition = @@ -3071,6 +3102,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for the purchase"); let documents_batch_purchase_serialized_transition = documents_batch_purchase_transition @@ -3146,8 +3178,8 @@ mod nft_tests { assert_eq!(gold_token_balance, Some(2)); } - #[test] - fn test_document_creator_id_unique_index_enforcement_with_purchase() { + #[tokio::test] + async fn test_document_creator_id_unique_index_enforcement_with_purchase() { // This test verifies that a unique index on creator_id is properly enforced throughout // the complete document lifecycle with purchase operations, ensuring that only one // document per creator can exist at any time. @@ -3245,6 +3277,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition1 = documents_batch_create_transition1 @@ -3294,6 +3327,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create update price transition"); let documents_batch_update_price_serialized_transition = @@ -3356,6 +3390,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition2 = documents_batch_create_transition2 @@ -3405,6 +3440,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for purchase"); let documents_batch_purchase_serialized_transition = documents_batch_purchase_transition @@ -3491,6 +3527,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition3 = documents_batch_create_transition3 @@ -3539,6 +3576,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch deletion transition"); let documents_batch_deletion_serialized_transition = documents_batch_deletion_transition @@ -3615,6 +3653,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition4 = documents_batch_create_transition4 @@ -3701,8 +3740,8 @@ mod nft_tests { ); } - #[test] - fn test_document_owner_and_creator_id_unique_index_enforcement_with_purchase() { + #[tokio::test] + async fn test_document_owner_and_creator_id_unique_index_enforcement_with_purchase() { // This test verifies that a unique compound index on (owner_id, creator_id) is properly // enforced throughout the document lifecycle with purchase operations, allowing a creator // to have multiple documents but preventing duplicate (owner, creator) combinations. @@ -3808,6 +3847,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition1 = documents_batch_create_transition1 @@ -3855,6 +3895,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create update price transition"); let documents_batch_update_price_serialized_transition1 = @@ -3917,6 +3958,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition2 = documents_batch_create_transition2 @@ -3967,6 +4009,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for purchase"); let documents_batch_purchase_serialized_transition1 = documents_batch_purchase_transition1 @@ -4029,6 +4072,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition3 = documents_batch_create_transition3 @@ -4077,6 +4121,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create update price transition"); let documents_batch_update_price_serialized_transition3 = @@ -4126,6 +4171,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for purchase"); let documents_batch_purchase_serialized_transition_buyer1 = @@ -4177,6 +4223,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for purchase"); let documents_batch_purchase_serialized_transition_buyer2 = @@ -4226,6 +4273,7 @@ mod nft_tests { platform_version, None, ) + .await .expect("expect to create documents batch deletion transition"); let documents_batch_deletion_serialized_transition = documents_batch_deletion_transition diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/replacement.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/replacement.rs index cf342b29cc9..5030d50ae4c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/replacement.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/replacement.rs @@ -9,8 +9,8 @@ mod replacement_tests { use dpp::tokens::token_payment_info::TokenPaymentInfo; use std::collections::BTreeMap; - #[test] - fn test_document_replace_on_document_type_that_is_mutable() { + #[tokio::test] + async fn test_document_replace_on_document_type_that_is_mutable() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -68,6 +68,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -110,6 +111,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition = documents_batch_update_transition @@ -164,7 +166,7 @@ mod replacement_tests { ); } - fn perform_document_replace_on_profile_after_epoch_change( + async fn perform_document_replace_on_profile_after_epoch_change( original_name: &str, new_names: Vec<(&str, StorageFlags)>, ) { @@ -218,6 +220,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -273,6 +276,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition = documents_batch_update_transition @@ -498,8 +502,8 @@ mod replacement_tests { ); } - #[test] - fn test_document_replace_on_document_type_that_is_not_mutable() { + #[tokio::test] + async fn test_document_replace_on_document_type_that_is_not_mutable() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -562,6 +566,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -604,6 +609,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition = documents_batch_update_transition @@ -641,8 +647,8 @@ mod replacement_tests { assert_eq!(processing_result.aggregated_fees().processing_fee, 41880); } - #[test] - fn test_document_replace_on_document_type_that_is_not_mutable_but_is_transferable() { + #[tokio::test] + async fn test_document_replace_on_document_type_that_is_not_mutable_but_is_transferable() { let platform_version = PlatformVersion::latest(); let (mut platform, contract) = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -690,6 +696,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -784,6 +791,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for transfer"); let documents_batch_transfer_serialized_transition = documents_batch_transfer_transition @@ -836,8 +844,8 @@ mod replacement_tests { assert_eq!(query_receiver_results.documents().len(), 0); } - #[test] - fn test_document_replace_that_does_not_yet_exist() { + #[tokio::test] + async fn test_document_replace_that_does_not_yet_exist() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -890,6 +898,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition = documents_batch_update_transition @@ -927,8 +936,8 @@ mod replacement_tests { assert_eq!(processing_result.aggregated_fees().processing_fee, 516040); } - #[test] - fn test_double_document_replace() { + #[tokio::test] + async fn test_double_document_replace() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -992,6 +1001,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1055,6 +1065,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition_1 = documents_batch_update_transition_1 @@ -1073,6 +1084,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition_2 = documents_batch_update_transition_2 @@ -1140,8 +1152,8 @@ mod replacement_tests { ); } - #[test] - fn test_double_document_replace_different_height_same_epoch() { + #[tokio::test] + async fn test_double_document_replace_different_height_same_epoch() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1205,6 +1217,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1272,6 +1285,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition_1 = documents_batch_update_transition_1 @@ -1290,6 +1304,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition_2 = documents_batch_update_transition_2 @@ -1398,8 +1413,8 @@ mod replacement_tests { ); } - #[test] - fn test_double_document_replace_no_change_different_height_same_epoch() { + #[tokio::test] + async fn test_double_document_replace_no_change_different_height_same_epoch() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1459,6 +1474,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1526,6 +1542,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition_1 = documents_batch_update_transition_1 @@ -1544,6 +1561,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition_2 = documents_batch_update_transition_2 @@ -1652,8 +1670,8 @@ mod replacement_tests { ); } - #[test] - fn test_double_document_replace_different_height_different_epoch() { + #[tokio::test] + async fn test_double_document_replace_different_height_different_epoch() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1717,6 +1735,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1784,6 +1803,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition_1 = documents_batch_update_transition_1 @@ -1802,6 +1822,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition_2 = documents_batch_update_transition_2 @@ -1910,8 +1931,8 @@ mod replacement_tests { ); } - #[test] - fn test_document_replace_on_document_type_that_requires_a_token() { + #[tokio::test] + async fn test_document_replace_on_document_type_that_requires_a_token() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1989,6 +2010,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -2040,6 +2062,7 @@ mod replacement_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_update_serialized_transition = documents_batch_update_transition diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/transfer.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/transfer.rs index 3a16933a874..da2030502df 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/transfer.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/transfer.rs @@ -5,8 +5,9 @@ mod transfer_tests { use dpp::tokens::token_payment_info::v0::TokenPaymentInfoV0; use dpp::tokens::token_payment_info::TokenPaymentInfo; - #[test] - fn test_document_transfer_on_document_type_that_is_transferable_that_has_no_owner_indices() { + #[tokio::test] + async fn test_document_transfer_on_document_type_that_is_transferable_that_has_no_owner_indices( + ) { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -76,6 +77,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -121,6 +123,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for transfer"); let documents_batch_transfer_serialized_transition = documents_batch_transfer_transition @@ -177,8 +180,8 @@ mod transfer_tests { ); } - #[test] - fn test_document_transfer_on_document_type_that_is_transferable_before_creator_id() { + #[tokio::test] + async fn test_document_transfer_on_document_type_that_is_transferable_before_creator_id() { let platform_version = PlatformVersion::get(9).unwrap(); let mut platform = TestPlatformBuilder::new() @@ -248,6 +251,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -340,6 +344,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for transfer"); let documents_batch_transfer_serialized_transition = documents_batch_transfer_transition @@ -421,8 +426,8 @@ mod transfer_tests { ); } - #[test] - fn test_document_transfer_on_document_type_that_is_transferable() { + #[tokio::test] + async fn test_document_transfer_on_document_type_that_is_transferable() { let platform_version = PlatformVersion::latest(); let (mut platform, contract) = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -472,6 +477,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -588,6 +594,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for transfer"); let documents_batch_transfer_serialized_transition = documents_batch_transfer_transition @@ -674,8 +681,8 @@ mod transfer_tests { ); } - #[test] - fn test_document_transfer_on_document_type_that_is_transferable_contract_v0() { + #[tokio::test] + async fn test_document_transfer_on_document_type_that_is_transferable_contract_v0() { // With a contract v0 we should not be adding the creator id // We do this because the creator id can not be serialized in document serialization v0 // And document serialization v0 is necessary when the data contract is v0 or the data @@ -748,6 +755,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -840,6 +848,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for transfer"); let documents_batch_transfer_serialized_transition = documents_batch_transfer_transition @@ -919,8 +928,8 @@ mod transfer_tests { ); } - #[test] - fn test_document_transfer_on_document_type_that_is_not_transferable() { + #[tokio::test] + async fn test_document_transfer_on_document_type_that_is_not_transferable() { let platform_version = PlatformVersion::latest(); let (mut platform, contract) = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -968,6 +977,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1060,6 +1070,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for transfer"); let documents_batch_transfer_serialized_transition = documents_batch_transfer_transition @@ -1112,8 +1123,8 @@ mod transfer_tests { assert_eq!(query_receiver_results.documents().len(), 0); } - #[test] - fn test_document_transfer_that_does_not_yet_exist() { + #[tokio::test] + async fn test_document_transfer_that_does_not_yet_exist() { let platform_version = PlatformVersion::latest(); let (mut platform, contract) = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -1210,6 +1221,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for transfer"); let documents_batch_transfer_serialized_transition = documents_batch_transfer_transition @@ -1262,8 +1274,8 @@ mod transfer_tests { assert_eq!(query_receiver_results.documents().len(), 0); } - #[test] - fn test_document_delete_after_transfer() { + #[tokio::test] + async fn test_document_delete_after_transfer() { let platform_version = PlatformVersion::latest(); let (mut platform, contract) = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -1314,6 +1326,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1406,6 +1419,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for transfer"); let documents_batch_transfer_serialized_transition = documents_batch_transfer_transition @@ -1473,6 +1487,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_deletion_serialized_transition = documents_batch_deletion_transition @@ -1526,8 +1541,8 @@ mod transfer_tests { .join(" | ") ); } - #[test] - fn test_document_transfer_on_document_that_needs_a_token() { + #[tokio::test] + async fn test_document_transfer_on_document_that_needs_a_token() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1609,6 +1624,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1707,6 +1723,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for transfer"); let documents_batch_transfer_serialized_transition = documents_batch_transfer_transition @@ -1773,8 +1790,8 @@ mod transfer_tests { assert_eq!(token_balance, Some(4)); } - #[test] - fn test_document_creator_id_unique_index_enforcement_during_transfer() { + #[tokio::test] + async fn test_document_creator_id_unique_index_enforcement_during_transfer() { // This test verifies that a unique index on creator_id is properly enforced throughout // the complete document lifecycle, ensuring that only one document per creator can exist // at any time, regardless of ownership changes. @@ -1877,6 +1894,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition1 = documents_batch_create_transition1 @@ -1939,6 +1957,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition2 = documents_batch_create_transition2 @@ -1987,6 +2006,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for transfer"); let documents_batch_transfer_serialized_transition = documents_batch_transfer_transition @@ -2073,6 +2093,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition3 = documents_batch_create_transition3 @@ -2121,6 +2142,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch deletion transition"); let documents_batch_deletion_serialized_transition = documents_batch_deletion_transition @@ -2197,6 +2219,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition4 = documents_batch_create_transition4 @@ -2283,8 +2306,8 @@ mod transfer_tests { ); } - #[test] - fn test_document_owner_and_creator_id_unique_index_enforcement_during_transfer() { + #[tokio::test] + async fn test_document_owner_and_creator_id_unique_index_enforcement_during_transfer() { // This test verifies that a unique compound index on (owner_id, creator_id) is properly // enforced throughout the document lifecycle, allowing a creator to have multiple documents // but preventing duplicate (owner, creator) combinations. @@ -2395,6 +2418,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition1 = documents_batch_create_transition1 @@ -2457,6 +2481,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition2 = documents_batch_create_transition2 @@ -2506,6 +2531,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for transfer"); let documents_batch_transfer_serialized_transition1 = documents_batch_transfer_transition1 @@ -2568,6 +2594,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition3 = documents_batch_create_transition3 @@ -2617,6 +2644,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for transfer"); let documents_batch_transfer_serialized_transition3 = documents_batch_transfer_transition3 @@ -2667,6 +2695,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for transfer"); let documents_batch_transfer_serialized_transition_back = @@ -2715,6 +2744,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch deletion transition"); let documents_batch_deletion_serialized_transition = documents_batch_deletion_transition @@ -2763,6 +2793,7 @@ mod transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition for transfer"); let documents_batch_transfer_serialized_transition_back2 = diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/additional_validation/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/additional_validation/mod.rs index dc00016bb93..a092051b093 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/additional_validation/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/additional_validation/mod.rs @@ -4,8 +4,8 @@ mod additional_validation_tests { use super::*; use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors; - #[test] - fn test_token_freeze_already_frozen_should_fail() { + #[tokio::test] + async fn test_token_freeze_already_frozen_should_fail() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -56,6 +56,7 @@ mod additional_validation_tests { platform_version, None, ) + .await .expect("expected to create freeze transition"); let serialized = freeze_transition @@ -117,6 +118,7 @@ mod additional_validation_tests { platform_version, None, ) + .await .expect("expected to create freeze transition"); let serialized = freeze_again_transition @@ -149,8 +151,8 @@ mod additional_validation_tests { ); } - #[test] - fn test_token_unfreeze_not_frozen_should_fail() { + #[tokio::test] + async fn test_token_unfreeze_not_frozen_should_fail() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -201,6 +203,7 @@ mod additional_validation_tests { platform_version, None, ) + .await .expect("expected to create unfreeze transition"); let serialized = unfreeze_transition diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/burn/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/burn/mod.rs index f4cedd5a8d0..7ac6a892f3b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/burn/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/burn/mod.rs @@ -4,8 +4,8 @@ mod token_burn_tests { use super::*; use dpp::state_transition::batch_transition::TokenBurnTransition; - #[test] - fn test_token_burn() { + #[tokio::test] + async fn test_token_burn() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -44,6 +44,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -90,8 +91,8 @@ mod token_burn_tests { assert_eq!(token_balance, Some(expected_amount)); } - #[test] - fn test_token_burn_entire_balance() { + #[tokio::test] + async fn test_token_burn_entire_balance() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -131,6 +132,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let burn_serialized_transition = burn_transition @@ -176,8 +178,8 @@ mod token_burn_tests { assert_eq!(token_balance, Some(0)); } - #[test] - fn test_token_burn_trying_to_burn_more_than_we_have() { + #[tokio::test] + async fn test_token_burn_trying_to_burn_more_than_we_have() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -216,6 +218,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -266,8 +269,8 @@ mod token_burn_tests { assert_eq!(token_balance, Some(100000)); // nothing was burned } - #[test] - fn test_token_burn_gives_error_if_trying_to_burn_from_not_allowed_identity() { + #[tokio::test] + async fn test_token_burn_gives_error_if_trying_to_burn_from_not_allowed_identity() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -309,6 +312,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -368,8 +372,8 @@ mod token_burn_tests { assert_eq!(token_balance, None); } - #[test] - fn test_token_burn_group_action_tokens_transferred_before_completion() { + #[tokio::test] + async fn test_token_burn_group_action_tokens_transferred_before_completion() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -433,6 +437,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create burn transition"); let token_burn_serialized_transition = burn_transition @@ -485,6 +490,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_transfer_serialized_transition = token_transfer_transition @@ -572,6 +578,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create confirmation transition"); let token_burn_confirm_serialized_transition = confirm_burn_transition @@ -630,8 +637,9 @@ mod token_burn_tests { assert_eq!(balance2, Some(1337)); // Recipient should not keep transferred tokens if burn was enforced } - #[test] - fn test_token_burn_group_action_tokens_transferred_before_completion_not_enough_balance() { + #[tokio::test] + async fn test_token_burn_group_action_tokens_transferred_before_completion_not_enough_balance() + { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -692,6 +700,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create burn transition"); let token_burn_serialized_transition = burn_transition @@ -744,6 +753,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_transfer_serialized_transition = token_transfer_transition @@ -831,6 +841,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create confirmation transition"); let token_burn_confirm_serialized_transition = confirm_burn_transition diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/config_update/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/config_update/mod.rs index bb57d705ed7..a34403210f4 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/config_update/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/config_update/mod.rs @@ -11,8 +11,8 @@ mod token_config_update_tests { use drive::drive::Drive; use super::*; - #[test] - fn test_token_config_update_by_owner_changing_total_max_supply() { + #[tokio::test] + async fn test_token_config_update_by_owner_changing_total_max_supply() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -61,6 +61,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -115,8 +116,8 @@ mod token_config_update_tests { /// Added this test to verify that adding "note" property to token history contract document types /// Makes the proof verification work - #[test] - fn test_token_config_update_by_owner_changing_total_max_supply_with_public_note() { + #[tokio::test] + async fn test_token_config_update_by_owner_changing_total_max_supply_with_public_note() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -165,6 +166,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -261,9 +263,9 @@ mod token_config_update_tests { assert_eq!(updated_token_config.max_supply(), Some(1000000)); } - #[test] - fn test_token_config_update_by_owner_changing_total_max_supply_to_less_than_current_supply() - { + #[tokio::test] + async fn test_token_config_update_by_owner_changing_total_max_supply_to_less_than_current_supply( + ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -312,6 +314,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -369,8 +372,8 @@ mod token_config_update_tests { assert_eq!(updated_token_config.max_supply(), None); } - #[test] - fn test_token_config_update_by_owner_change_admin_to_another_identity() { + #[tokio::test] + async fn test_token_config_update_by_owner_change_admin_to_another_identity() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -424,6 +427,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -472,6 +476,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -524,8 +529,8 @@ mod token_config_update_tests { assert_eq!(updated_token_config.max_supply(), Some(1000000)); } - #[test] - fn test_token_config_update_by_owner_change_admin_to_a_non_existent_identity_error() { + #[tokio::test] + async fn test_token_config_update_by_owner_change_admin_to_a_non_existent_identity_error() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -578,6 +583,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -617,8 +623,8 @@ mod token_config_update_tests { .expect("expected to commit transaction"); } - #[test] - fn test_token_config_update_by_owner_change_admin_to_a_non_existent_group_error() { + #[tokio::test] + async fn test_token_config_update_by_owner_change_admin_to_a_non_existent_group_error() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -669,6 +675,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -708,8 +715,8 @@ mod token_config_update_tests { .expect("expected to commit transaction"); } - #[test] - fn test_token_config_update_by_owner_change_admin_to_main_group_not_set_error() { + #[tokio::test] + async fn test_token_config_update_by_owner_change_admin_to_main_group_not_set_error() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -760,6 +767,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -799,8 +807,8 @@ mod token_config_update_tests { .expect("expected to commit transaction"); } - #[test] - fn test_token_config_update_by_owner_changing_main_control_group() { + #[tokio::test] + async fn test_token_config_update_by_owner_changing_main_control_group() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -855,6 +863,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -913,8 +922,8 @@ mod token_config_update_tests { use dpp::data_contract::associated_token::token_configuration_localization::v0::TokenConfigurationLocalizationV0; use dpp::data_contract::associated_token::token_distribution_rules::accessors::v0::TokenDistributionRulesV0Getters; - #[test] - fn test_token_config_update_by_group_member_changing_total_max_supply_not_using_group_gives_error( + #[tokio::test] + async fn test_token_config_update_by_group_member_changing_total_max_supply_not_using_group_gives_error( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -976,6 +985,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -1031,8 +1041,8 @@ mod token_config_update_tests { assert_eq!(updated_token_config.max_supply(), None); } - #[test] - fn test_token_config_update_by_group_member_changing_total_max_supply() { + #[tokio::test] + async fn test_token_config_update_by_group_member_changing_total_max_supply() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1102,6 +1112,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -1176,6 +1187,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -1228,8 +1240,8 @@ mod token_config_update_tests { assert_eq!(updated_token_config.max_supply(), Some(1000000)); } - #[test] - fn test_token_config_update_by_group_member_changing_minting_destination_group() { + #[tokio::test] + async fn test_token_config_update_by_group_member_changing_minting_destination_group() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1323,6 +1335,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -1405,6 +1418,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -1488,6 +1502,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -1564,6 +1579,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -1618,8 +1634,8 @@ mod token_config_update_tests { .minting_allow_choosing_destination()); } - #[test] - fn test_token_config_update_by_group_member_changing_minting_admin_group() { + #[tokio::test] + async fn test_token_config_update_by_group_member_changing_minting_admin_group() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1717,6 +1733,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -1799,6 +1816,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -1875,6 +1893,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -1943,6 +1962,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -2025,6 +2045,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -2083,8 +2104,9 @@ mod token_config_update_tests { ); } - #[test] - fn test_token_config_change_own_admin_group_give_control_power_and_change_admin_back() { + #[tokio::test] + async fn test_token_config_change_own_admin_group_give_control_power_and_change_admin_back() + { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -2181,6 +2203,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -2262,6 +2285,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -2345,6 +2369,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -2402,6 +2427,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -2469,6 +2495,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -2527,6 +2554,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -2614,6 +2642,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -2672,6 +2701,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -2760,6 +2790,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -2827,6 +2858,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition @@ -2861,8 +2893,8 @@ mod token_config_update_tests { .expect("expected to commit transaction"); } - #[test] - fn test_token_config_update_as_group_member_but_group_not_needed() { + #[tokio::test] + async fn test_token_config_update_as_group_member_but_group_not_needed() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -2923,6 +2955,7 @@ mod token_config_update_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let config_update_transition_serialized_transition = config_update_transition diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/destroy_frozen_funds/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/destroy_frozen_funds/mod.rs index fa5297ef3de..be96d075f70 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/destroy_frozen_funds/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/destroy_frozen_funds/mod.rs @@ -4,8 +4,8 @@ mod token_destroy_frozen_funds_tests { use super::*; use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors; - #[test] - fn test_token_destroy_frozen_funds_success() { + #[tokio::test] + async fn test_token_destroy_frozen_funds_success() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -78,6 +78,7 @@ mod token_destroy_frozen_funds_tests { platform_version, None, ) + .await .expect("expected to create mint transition"); let serialized = mint_transition @@ -139,6 +140,7 @@ mod token_destroy_frozen_funds_tests { platform_version, None, ) + .await .expect("expected to create freeze transition"); let serialized = freeze_transition @@ -201,6 +203,7 @@ mod token_destroy_frozen_funds_tests { platform_version, None, ) + .await .expect("expected to create destroy frozen funds transition"); let serialized = destroy_transition @@ -260,8 +263,8 @@ mod token_destroy_frozen_funds_tests { assert_eq!(token_frozen, Some(true)); } - #[test] - fn test_token_destroy_frozen_funds_on_unfrozen_account_should_fail() { + #[tokio::test] + async fn test_token_destroy_frozen_funds_on_unfrozen_account_should_fail() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -326,6 +329,7 @@ mod token_destroy_frozen_funds_tests { platform_version, None, ) + .await .expect("expected to create mint transition"); let serialized = mint_transition @@ -370,6 +374,7 @@ mod token_destroy_frozen_funds_tests { platform_version, None, ) + .await .expect("expected to create destroy frozen funds transition"); let serialized = destroy_transition diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/direct_selling/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/direct_selling/mod.rs index b5d94c129f4..20ec6ed5377 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/direct_selling/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/direct_selling/mod.rs @@ -15,8 +15,8 @@ mod token_selling_tests { use drive::verify::RootHash; use simple_signer::signer::SimpleSigner; - #[test] - fn test_successful_direct_purchase_single_price() { + #[tokio::test] + async fn test_successful_direct_purchase_single_price() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -40,7 +40,8 @@ mod token_selling_tests { &seller_key, Some(single_price.clone()), &mut identity_contract_nonce, - ); + ) + .await; // Seller sets single price let set_price_transition = @@ -59,6 +60,7 @@ mod token_selling_tests { platform_version, None, ) + .await .unwrap(); let platform_state = platform.state.load(); @@ -123,6 +125,7 @@ mod token_selling_tests { platform_version, None, ) + .await .unwrap(); let processing_result = process_test_state_transition( @@ -155,8 +158,8 @@ mod token_selling_tests { assert_eq!(buyer_credit_balance, Some(699_868_130_120)); // 10.0 - 3.0 spent - fees =~ 7 dash left } - #[test] - fn test_direct_purchase_change_using_group_without_needing_group() { + #[tokio::test] + async fn test_direct_purchase_change_using_group_without_needing_group() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -219,6 +222,7 @@ mod token_selling_tests { platform_version, None, ) + .await .unwrap(); let platform_state = platform.state.load(); @@ -238,8 +242,8 @@ mod token_selling_tests { ); } - #[test] - fn test_direct_purchase_single_price_not_paying_full_price() { + #[tokio::test] + async fn test_direct_purchase_single_price_not_paying_full_price() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -293,6 +297,7 @@ mod token_selling_tests { platform_version, None, ) + .await .unwrap(); let processing_result = process_test_state_transition( @@ -322,6 +327,7 @@ mod token_selling_tests { platform_version, None, ) + .await .unwrap(); let processing_result = process_test_state_transition( @@ -359,8 +365,8 @@ mod token_selling_tests { assert_eq!(buyer_credit_balance, Some(999_987_872_760)); // 10.0 - bump action fees } - #[test] - fn test_direct_purchase_insufficient_credits() { + #[tokio::test] + async fn test_direct_purchase_insufficient_credits() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -414,6 +420,7 @@ mod token_selling_tests { platform_version, None, ) + .await .unwrap(); let processing_result = process_test_state_transition( @@ -442,6 +449,7 @@ mod token_selling_tests { platform_version, None, ) + .await .unwrap(); let processing_result = process_test_state_transition( @@ -474,8 +482,8 @@ mod token_selling_tests { /// When I create them and set their prices, /// Then I should get the correct price for each of them /// And the price should be the same as the one set by the seller. - #[test] - fn test_successful_direct_purchase_multiple_tokens() { + #[tokio::test] + async fn test_successful_direct_purchase_multiple_tokens() { // Given 3 tokens let pricing_schedules = vec![ TokenPricingSchedule::SinglePrice(dash_to_credits!(1)), @@ -499,22 +507,21 @@ mod token_selling_tests { setup_identity(&mut platform, rng.gen(), dash_to_credits!(1.0)); let mut identity_contract_nonce = 2; - let tokens = pricing_schedules - .into_iter() - .map(|pricing| { - let (contract, token_id) = create_token_with_pricing( - platform_version, - &mut platform, - &seller, - &seller_signer, - &seller_key, - Some(pricing.clone()), - &mut identity_contract_nonce, - ); - - (token_id.to_buffer(), (pricing, contract)) - }) - .collect::>(); + let mut tokens: BTreeMap<[u8; 32], _> = BTreeMap::new(); + for pricing in pricing_schedules.into_iter() { + let (contract, token_id) = create_token_with_pricing( + platform_version, + &mut platform, + &seller, + &seller_signer, + &seller_key, + Some(pricing.clone()), + &mut identity_contract_nonce, + ) + .await; + + tokens.insert(token_id.to_buffer(), (pricing, contract)); + } // // When I fetch tokens, with or without proofs @@ -574,8 +581,8 @@ mod token_selling_tests { } } - #[test] - fn test_direct_purchase_from_yourself() { + #[tokio::test] + async fn test_direct_purchase_from_yourself() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -598,7 +605,8 @@ mod token_selling_tests { &self_trader_key, Some(single_price.clone()), &mut identity_contract_nonce, - ); + ) + .await; // Set the price let set_price_transition = @@ -617,6 +625,7 @@ mod token_selling_tests { platform_version, None, ) + .await .unwrap(); let platform_state = platform.state.load(); @@ -658,6 +667,7 @@ mod token_selling_tests { platform_version, None, ) + .await .unwrap(); let initial_credit_balance = platform @@ -757,7 +767,7 @@ mod token_selling_tests { } /// Creates a token contract with the given owner identity and configuration, and sets the price. - fn create_token_with_pricing( + async fn create_token_with_pricing( platform_version: &PlatformVersion, platform: &mut TempPlatform, seller: &Identity, @@ -807,6 +817,7 @@ mod token_selling_tests { platform_version, None, ) + .await .unwrap(); *identity_contract_nonce += 1; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/distribution/perpetual/block_based.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/distribution/perpetual/block_based.rs index c013cf6483e..b819ac4a47a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/distribution/perpetual/block_based.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/distribution/perpetual/block_based.rs @@ -23,8 +23,8 @@ mod perpetual_distribution_block { use crate::test::helpers::fast_forward_to_block::fast_forward_to_block; use super::*; - #[test] - fn test_token_perpetual_distribution_block_claim_linear_and_claim_again() { + #[tokio::test] + async fn test_token_perpetual_distribution_block_claim_linear_and_claim_again() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -76,6 +76,7 @@ mod perpetual_distribution_block { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -142,6 +143,7 @@ mod perpetual_distribution_block { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -210,6 +212,7 @@ mod perpetual_distribution_block { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -261,8 +264,8 @@ mod perpetual_distribution_block { assert_eq!(token_balance, Some(100250)); } - #[test] - fn test_token_perpetual_distribution_not_claimant() { + #[tokio::test] + async fn test_token_perpetual_distribution_not_claimant() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -320,6 +323,7 @@ mod perpetual_distribution_block { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -384,8 +388,8 @@ mod perpetual_distribution_block { assert_eq!(token_balance_2, None); } - #[test] - fn test_token_perpetual_distribution_block_claim_linear_given_to_specific_identity() { + #[tokio::test] + async fn test_token_perpetual_distribution_block_claim_linear_given_to_specific_identity() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -441,6 +445,7 @@ mod perpetual_distribution_block { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -504,8 +509,8 @@ mod fixed_amount { }; use dpp::data_contract::associated_token::token_perpetual_distribution::distribution_function::{MAX_DISTRIBUTION_CYCLES_PARAM, MAX_DISTRIBUTION_PARAM}; - #[test] - fn fixed_amount_1_interval_1() -> Result<(), String> { + #[tokio::test] + async fn fixed_amount_1_interval_1() -> Result<(), String> { check_heights( DistributionFunction::FixedAmount { amount: 1 }, &[ @@ -518,14 +523,15 @@ mod fixed_amount { 1, None, ) + .await } // Given some token configuration, // When a claim is made at block 41 and 50, // Then the claim should be successful. // If we claim again in the interval it should not be successful. - #[test] - fn fixed_amount_50_interval_10() { + #[tokio::test] + async fn fixed_amount_50_interval_10() { check_heights( DistributionFunction::FixedAmount { amount: 50 }, &[ @@ -539,6 +545,7 @@ mod fixed_amount { 10, None, ) + .await .expect("\n-> fixed amount should pass"); } @@ -547,8 +554,8 @@ mod fixed_amount { /// /// claim at height 1000000000000: claim failed: assertion 0 failed: expected SuccessfulExecution, /// got [InternalError(\"storage: protocol: overflow error: Overflow in FixedAmount evaluation\")]" - #[test] - fn fixed_amount_at_trillionth_block() { + #[tokio::test] + async fn fixed_amount_at_trillionth_block() { check_heights( DistributionFunction::FixedAmount { amount: 1_000_000_000, @@ -575,14 +582,15 @@ mod fixed_amount { 10, None, ) + .await .expect("\n-> fixed amount should pass"); } - #[test] + #[tokio::test] /// Given a fixed amount distribution with value of 0, /// When we try to claim, /// Then we always fail and the balance remains unchanged. - fn fixed_amount_0() { + async fn fixed_amount_0() { check_heights( DistributionFunction::FixedAmount { amount: 0 }, &[(41, 100000, false)], @@ -590,14 +598,15 @@ mod fixed_amount { 10, None, ) + .await .expect_err("\namount should not be 0\n"); } - #[test] + #[tokio::test] /// Given a fixed amount distribution with value of 1_000_000 and max_supply of 200_000, /// When we try to claim, /// Then we always fail and the balance remains unchanged. - fn fixed_amount_gt_max_supply() { + async fn fixed_amount_gt_max_supply() { let test = TestStep { name: "test_fixed_amount_above_max_supply".to_string(), base_height: 41, @@ -618,14 +627,15 @@ mod fixed_amount { 10, Some(Some(200_000)), ) + .await .expect("\nfixed amount zero increase\n"); } /// Given a fixed amount distribution with value of u64::MAX, /// When I claim tokens, /// Then I don't get an InternalError. - #[test] - fn test_block_based_perpetual_fixed_amount_u64_max_should_error_at_validation() { + #[tokio::test] + async fn test_block_based_perpetual_fixed_amount_u64_max_should_error_at_validation() { check_heights( DistributionFunction::FixedAmount { amount: u64::MAX }, &[TestStep::new(41, 100_000, false)], @@ -633,14 +643,15 @@ mod fixed_amount { 10, None, ) + .await .expect_err("u64::Max is too much for DistributionFunction::FixedAmount"); } /// Given a fixed amount distribution with value of u64::MAX, /// When I claim tokens, /// Then I don't get an InternalError. - #[test] - fn test_block_based_perpetual_fixed_amount_max_distribution() { + #[tokio::test] + async fn test_block_based_perpetual_fixed_amount_max_distribution() { check_heights( DistributionFunction::FixedAmount { amount: MAX_DISTRIBUTION_PARAM, @@ -654,6 +665,7 @@ mod fixed_amount { 10, None, ) + .await .expect("MAX_DISTRIBUTION_PARAM should be valid DistributionFunction::FixedAmount"); } } @@ -688,9 +700,9 @@ mod random { /// Given a random distribution function with min=0, max=100, /// When I claim tokens at various heights, /// Then I get deterministic balances at those heights. - #[test] + #[tokio::test] #[ignore] - fn test_random_max_supply() -> Result<(), String> { + async fn test_random_max_supply() -> Result<(), String> { let steps = [ TestStep::new(41, 100_192, true), TestStep::new(46, 100_192, false), @@ -706,7 +718,8 @@ mod random { None, 10, Some(max_supply), - )?; + ) + .await?; } Ok(()) } @@ -714,9 +727,9 @@ mod random { /// Given a random distribution function with min=0, max=0, /// When I claim tokens at various heights, /// Then claim fails and I get the same balance at those heights. - #[test] + #[tokio::test] #[ignore] - fn test_block_based_perpetual_random_0_0() { + async fn test_block_based_perpetual_random_0_0() { check_heights( DistributionFunction::Random { min: 0, max: 0 }, &[ @@ -728,11 +741,12 @@ mod random { 10, None, ) + .await .expect("no rewards"); } - #[test] + #[tokio::test] #[ignore] - fn test_block_based_perpetual_random_0_u64_max_should_error_at_validation() { + async fn test_block_based_perpetual_random_0_u64_max_should_error_at_validation() { check_heights( DistributionFunction::Random { min: 0, @@ -743,12 +757,13 @@ mod random { 10, None, ) + .await .expect_err("max is too much for DistributionFunction::Random"); } - #[test] + #[tokio::test] #[ignore] - fn test_block_based_perpetual_random_0_max_distribution_param() { + async fn test_block_based_perpetual_random_0_max_distribution_param() { check_heights( DistributionFunction::Random { min: 0, @@ -763,15 +778,16 @@ mod random { 10, None, ) + .await .expect("no rewards"); } /// Given a random distribution function with min=10, max=30, /// When I claim tokens at various heights, /// Then I get a distribution of balances that is close to the maximum entropy. - #[test] + #[tokio::test] #[ignore] - fn test_block_based_perpetual_random_10_30_entropy() { + async fn test_block_based_perpetual_random_10_30_entropy() { const N: u64 = 200; const MIN: u64 = 10; const MAX: u64 = 30; @@ -810,7 +826,7 @@ mod random { balances.lock().unwrap().push(balance); }); - suite.execute(&tests).expect("should execute"); + suite.execute(&tests).await.expect("should execute"); let data = balances_result.lock().unwrap(); // subtract balance from previous step (for first step, subtract initial balance of 100_000) @@ -967,8 +983,8 @@ mod step_decreasing { .collect() } - #[test] - fn claim_every_block() { + #[tokio::test] + async fn claim_every_block() { run_test( 1, 1, @@ -987,11 +1003,12 @@ mod step_decreasing { INITIAL_BALANCE + 9_900 + 9_801 + 9_702 + 9_604, ], ) + .await .expect("expected to succeed"); } - #[test] - fn claim_every_5_blocks() { + #[tokio::test] + async fn claim_every_5_blocks() { run_test( 1, 1, @@ -1020,11 +1037,12 @@ mod step_decreasing { + 8_946, ], ) + .await .expect("expected to succeed"); } - #[test] - fn claim_with_1_percent_increase_should_fail() { + #[tokio::test] + async fn claim_with_1_percent_increase_should_fail() { let result_str = run_test( 1, 101, @@ -1038,6 +1056,7 @@ mod step_decreasing { 1, vec![], ) + .await .expect_err("should not allow to increase"); assert!( result_str.contains("Invalid parameter tuple in token distribution function: `decrease_per_interval_numerator` must be smaller than `decrease_per_interval_denominator`"), @@ -1045,8 +1064,8 @@ mod step_decreasing { ); } - #[test] - fn claim_with_no_decrease_should_fail() { + #[tokio::test] + async fn claim_with_no_decrease_should_fail() { let result_str = run_test( 1, 0, @@ -1060,6 +1079,7 @@ mod step_decreasing { 1, vec![], ) + .await .expect_err("should not allow to increase"); assert!( result_str.contains("Invalid parameter `decrease_per_interval_numerator` in token distribution function. Expected range: 1 to 65535"), @@ -1067,8 +1087,8 @@ mod step_decreasing { ); } - #[test] - fn claim_every_10_blocks_on_100k() { + #[tokio::test] + async fn claim_every_10_blocks_on_100k() { let steps = (1..500).step_by(10).collect::>(); run_test( 1, @@ -1083,11 +1103,12 @@ mod step_decreasing { 1, sum_till_for_100k_step_1_interval_1(steps), ) + .await .expect("should pass"); } - #[test] - fn claim_every_block_on_100k_128_default_steps() { + #[tokio::test] + async fn claim_every_block_on_100k_128_default_steps() { let steps = (1..140).step_by(1).collect::>(); let start_steps = (1..129).step_by(1).collect::>(); let start_steps_expected_amounts = sum_till_for_100k_step_1_interval_1(start_steps.clone()); @@ -1111,11 +1132,12 @@ mod step_decreasing { 1, expected_amounts, ) + .await .expect("should pass"); } - #[test] - fn claim_every_block_on_100k_128_default_steps_with_trailing_distribution() { + #[tokio::test] + async fn claim_every_block_on_100k_128_default_steps_with_trailing_distribution() { let steps = (1..200).step_by(1).collect::>(); let start_steps = (1..129).step_by(1).collect::>(); let start_steps_expected_amounts = sum_till_for_100k_step_1_interval_1(start_steps.clone()); @@ -1140,11 +1162,12 @@ mod step_decreasing { 1, expected_amounts, ) + .await .expect("should pass"); } - #[test] - fn claim_every_10_blocks_on_100k_128_default_steps() { + #[tokio::test] + async fn claim_every_10_blocks_on_100k_128_default_steps() { let steps = (1..500).step_by(10).collect::>(); let start_steps = (1..128).step_by(10).collect::>(); let start_steps_expected_amounts = sum_till_for_100k_step_1_interval_1(start_steps); @@ -1170,11 +1193,12 @@ mod step_decreasing { 1, expected_amounts, ) + .await .expect("should pass"); } - #[test] - fn claim_128_default_steps_480_max_token_redemption_cycles() { + #[tokio::test] + async fn claim_128_default_steps_480_max_token_redemption_cycles() { // We can only claim 128 events at a time. // The step_wise distribution stops after 500 from the start. let claim_heights = vec![1, 400, 400, 400, 400, 401, 450, 500]; @@ -1197,11 +1221,12 @@ mod step_decreasing { 1, expected_amounts, ) + .await .expect("should pass"); } - #[test] - fn decrease_where_min_would_not_matter_min_1_100() { + #[tokio::test] + async fn decrease_where_min_would_not_matter_min_1_100() { let claim_heights = vec![1, 2, 3, 10, 100]; let expected_amounts = sum_till_for_100k_step_1_interval_1(claim_heights.clone()); for min in [1, 100] { @@ -1218,13 +1243,14 @@ mod step_decreasing { 1, expected_amounts.clone(), ) + .await .map_err(|e| format!("failed with min {}: {}", min, e)) .expect("should pass"); } } - #[test] - fn heavy_decrease_to_min_with_min_various_values() { + #[tokio::test] + async fn heavy_decrease_to_min_with_min_various_values() { let claim_heights = vec![1, 2, 3, 10, 100]; for min in [1, 10] { let expected_amounts = vec![ @@ -1247,13 +1273,14 @@ mod step_decreasing { 1, expected_amounts, ) + .await .map_err(|e| format!("failed with min {}: {}", min, e)) .expect("should pass"); } } - #[test] - fn full_decrease_min_eq_u64_max() { + #[tokio::test] + async fn full_decrease_min_eq_u64_max() { let result_str = run_test( 1, u16::MAX - 1, @@ -1267,14 +1294,15 @@ mod step_decreasing { 1, vec![], ) + .await .expect_err("should fail"); assert!( result_str.contains("Invalid parameter tuple in token distribution function: `n` must be greater than or equal to `min_value`"), "Unexpected panic message: {result_str}" ); } - #[test] - fn full_decrease_min_eq_max_distribution() { + #[tokio::test] + async fn full_decrease_min_eq_max_distribution() { run_test( 1, u16::MAX - 1, @@ -1292,11 +1320,12 @@ mod step_decreasing { MAX_DISTRIBUTION_PARAM * 10 + INITIAL_BALANCE, ], ) + .await .expect("should succeed"); } - #[test] - fn distribute_max_distribution_param_every_step() { + #[tokio::test] + async fn distribute_max_distribution_param_every_step() { let claim_heights = (1..65_536).step_by(128).collect::>(); let expected_balances = claim_heights .iter() @@ -1320,11 +1349,12 @@ mod step_decreasing { 1, expected_balances, ) + .await .expect("should succeed"); } - #[test] - fn start_over_max_distribution_param_should_fail() { + #[tokio::test] + async fn start_over_max_distribution_param_should_fail() { let result_str = run_test( 1, 1, @@ -1338,6 +1368,7 @@ mod step_decreasing { 1, vec![], ) + .await .expect_err("should fail"); assert!( result_str.contains("Invalid parameter `n` in token distribution function. Expected range: 1 to 281474976710655"), @@ -1345,8 +1376,8 @@ mod step_decreasing { ); } - #[test] - fn half_decrease_changing_step_5_distribution_interval_1() { + #[tokio::test] + async fn half_decrease_changing_step_5_distribution_interval_1() { let step = 5; // Every 5 blocks the amount divides by 1/2 let distribution_interval = 1; // The payout happens every block let claim_heights = vec![5, 10, 18, 22, 100]; @@ -1365,11 +1396,12 @@ mod step_decreasing { distribution_interval, expected_balances, ) + .await .expect("should pass"); } - #[test] - fn half_decrease_changing_step_5_distribution_interval_5() { + #[tokio::test] + async fn half_decrease_changing_step_5_distribution_interval_5() { let step = 5; // Every 25 blocks (5 x distribution interval) the amount divides by 1/2 let distribution_interval = 5; // The payout happens every 5 blocks let claim_heights = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, 22, 25, 26, 51, 100]; @@ -1388,11 +1420,12 @@ mod step_decreasing { distribution_interval, expected_balances, ) + .await .expect("should pass"); } - #[test] - fn half_decrease_changing_step_24_distribution_interval_1000() { + #[tokio::test] + async fn half_decrease_changing_step_24_distribution_interval_1000() { let step = 24; // Every 24000 blocks (24 x distribution interval) the amount divides by 1/2 let distribution_interval = 1000; // The payout happens every 400 blocks let claim_heights = vec![3000, 45000, 60000, 300000, 300000]; @@ -1412,11 +1445,12 @@ mod step_decreasing { distribution_interval, expected_balances, ) + .await .expect("should pass"); } - #[test] - fn half_decrease_changing_step_24_distribution_interval_1000_start_height_2000() { + #[tokio::test] + async fn half_decrease_changing_step_24_distribution_interval_1000_start_height_2000() { let step = 24; // Every 24000 blocks (24 x distribution interval) the amount divides by 1/2 let distribution_interval = 1000; // The payout happens every 400 blocks let claim_heights = vec![3000, 23000, 24000, 25000, 43000, 44000, 300000, 300000]; @@ -1450,12 +1484,13 @@ mod step_decreasing { distribution_interval, expected_balances, ) + .await .expect("should pass"); } /// Test various combinations of [DistributionFunction::StepDecreasingAmount] distribution. #[allow(clippy::too_many_arguments)] - fn run_test( + async fn run_test( step_count: u32, decrease_per_interval_numerator: u16, decrease_per_interval_denominator: u16, @@ -1505,6 +1540,7 @@ mod step_decreasing { distribution_interval, None, ) + .await .inspect_err(|e| { tracing::error!(e); }) @@ -1516,8 +1552,8 @@ mod stepwise { use dpp::data_contract::associated_token::token_perpetual_distribution::distribution_function::DistributionFunction; use std::collections::BTreeMap; - #[test] - fn distribution_stepwise_correct() { + #[tokio::test] + async fn distribution_stepwise_correct() { let distribution_interval = 10; let periods = BTreeMap::from([ (0, 10_000), // h 1-20 @@ -1559,6 +1595,7 @@ mod stepwise { distribution_interval, None, ) + .await .inspect_err(|e| { tracing::error!("{}", e); }) @@ -1570,8 +1607,8 @@ mod linear { use super::test_suite::check_heights; use dpp::data_contract::associated_token::token_perpetual_distribution::distribution_function::{DistributionFunction, MAX_LINEAR_SLOPE_A_PARAM, MIN_LINEAR_SLOPE_A_PARAM}; - #[test] - fn linear_distribution_divide_by_max() -> Result<(), String> { + #[tokio::test] + async fn linear_distribution_divide_by_max() -> Result<(), String> { // Given linear distribution with d=MAX and starting amount of 1, // We expect no claim rewards test_linear( @@ -1584,10 +1621,11 @@ mod linear { &[(1, 100_000, false), (20, 100_000, false)], // heights 1, ) + .await } - #[test] - fn linear_distribution_x_matrix() -> Result<(), String> { + #[tokio::test] + async fn linear_distribution_x_matrix() -> Result<(), String> { let steps = [ (1, 100_001, true), (2, 100_003, true), @@ -1598,14 +1636,14 @@ mod linear { for start_step in [None, Some(0)] { for min_value in [None, Some(0), Some(1)] { for max_value in [None, Some(1000)] { - test_linear(1, 1, start_step, 0, min_value, max_value, &steps, 1)?; + test_linear(1, 1, start_step, 0, min_value, max_value, &steps, 1).await?; } } } Ok(()) } - #[test] - fn linear_distribution_slopes() -> Result<(), String> { + #[tokio::test] + async fn linear_distribution_slopes() -> Result<(), String> { for (a, steps) in [ (-1, [(1, 100_000, false), (20, 100_000, false)]), (1, [(1, 100_001, true), (20, 100_210, true)]), @@ -1618,13 +1656,13 @@ mod linear { [(1, 100_256, true), (20, 153_760, true)], ), ] { - test_linear(a, 1, None, 0, None, None, &steps, 1)?; + test_linear(a, 1, None, 0, None, None, &steps, 1).await?; } Ok(()) } #[allow(clippy::too_many_arguments)] - fn test_linear( + async fn test_linear( a: i64, d: u64, start_step: Option, @@ -1659,6 +1697,7 @@ mod linear { distribution_interval, None, ) + .await .inspect_err(|e| { tracing::error!("{}", e); }) @@ -1689,20 +1728,21 @@ mod exponential { // ───────────────────────────────────────────────────────────────────────── // helper – one‑liner wrapper around `check_heights` (same as polynomial) // ───────────────────────────────────────────────────────────────────────── - fn test_exponential( + async fn test_exponential( dist: DistributionFunction, steps: &[(u64, u64, bool)], // (height, expected balance, expect‑pass) distribution_interval: u64, ) -> Result<(), String> { check_heights(dist, steps, None, distribution_interval, None) + .await .inspect_err(|e| tracing::error!("{e}")) } // ───────────────────────────────────────────────────────────────────────── // 1. Basic positive‑growth example (m > 0) // ───────────────────────────────────────────────────────────────────────── - #[test] - fn exponential_distribution_growth_basic() -> Result<(), String> { + #[tokio::test] + async fn exponential_distribution_growth_basic() -> Result<(), String> { test_exponential( Exponential { a: 1, @@ -1719,13 +1759,14 @@ mod exponential { &[(10, 112_814, true), (20, 6_799_881, true)], 1, ) + .await } // ───────────────────────────────────────────────────────────────────────── // 2. Basic negative‑decay example (m < 0) // ───────────────────────────────────────────────────────────────────────── - #[test] - fn exponential_distribution_decay_basic() -> Result<(), String> { + #[tokio::test] + async fn exponential_distribution_decay_basic() -> Result<(), String> { test_exponential( Exponential { a: 5, @@ -1741,13 +1782,14 @@ mod exponential { &[(1, 200_005, true), (4, 500_006, true)], 1, ) + .await } // ───────────────────────────────────────────────────────────────────────── // 3. o at −MAX_DISTRIBUTION_PARAM ⇒ argument very negative ▶ min / 0 // ───────────────────────────────────────────────────────────────────────── - #[test] - fn exponential_distribution_o_min() -> Result<(), String> { + #[tokio::test] + async fn exponential_distribution_o_min() -> Result<(), String> { test_exponential( Exponential { a: 1, @@ -1763,13 +1805,14 @@ mod exponential { &[(1, 100_000, false), (4, 100_000, false)], 1, ) + .await } // ───────────────────────────────────────────────────────────────────────── // 4. o at +MAX_DISTRIBUTION_PARAM (huge positive shift) // ───────────────────────────────────────────────────────────────────────── - #[test] - fn exponential_distribution_o_max() -> Result<(), String> { + #[tokio::test] + async fn exponential_distribution_o_max() -> Result<(), String> { test_exponential( Exponential { a: MAX_EXP_A_PARAM, @@ -1785,14 +1828,15 @@ mod exponential { &[(1, 100010, true), (10, 100100, true)], 1, ) + .await } // ───────────────────────────────────────────────────────────────────────── // 5. Exhaustive combination of extreme parameter values // ‑ ensure no `InternalError` // ───────────────────────────────────────────────────────────────────────── - #[test] - fn exponential_distribution_extreme_values() -> Result<(), String> { + #[tokio::test] + async fn exponential_distribution_extreme_values() -> Result<(), String> { for m in [MIN_EXP_M_PARAM, -1, 1, MAX_EXP_M_PARAM as i64] { for n in [1, MAX_EXP_N_PARAM] { for a in [1, MAX_EXP_A_PARAM] { @@ -1852,6 +1896,7 @@ mod exponential { suite .execute(&[step]) + .await .map_err(|e| format!("failed with a {a} m {m} n {n}: {e}"))?; } } @@ -1880,8 +1925,8 @@ mod polynomial { }; use dpp::data_contract::associated_token::token_perpetual_distribution::distribution_function::{MAX_DISTRIBUTION_PARAM, MAX_POL_A_PARAM, MAX_POL_M_PARAM, MAX_POL_N_PARAM, MIN_POL_A_PARAM, MIN_POL_M_PARAM}; - #[test] - fn polynomial_distribution_basic() -> Result<(), String> { + #[tokio::test] + async fn polynomial_distribution_basic() -> Result<(), String> { test_polynomial( Polynomial { a: 1, @@ -1897,10 +1942,11 @@ mod polynomial { &[(10, 100_385, true), (20, 102_870, true)], 1, ) + .await } - #[test] - fn polynomial_distribution_negative_a() -> Result<(), String> { + #[tokio::test] + async fn polynomial_distribution_negative_a() -> Result<(), String> { test_polynomial( Polynomial { a: -1, @@ -1916,10 +1962,11 @@ mod polynomial { &[(1, 199_999, true), (4, 499_900, true)], 1, ) + .await } - #[test] - fn polynomial_distribution_a_minus_1_b_0() -> Result<(), String> { + #[tokio::test] + async fn polynomial_distribution_a_minus_1_b_0() -> Result<(), String> { test_polynomial( Polynomial { a: -1, @@ -1935,12 +1982,13 @@ mod polynomial { &[(1, 100_000, false), (4, 100_000, false)], 1, ) + .await } /// Given a polynomial distribution function with o=-MAX_DISTRIBUTION_PARAM, we should /// have no rewards - #[test] - fn polynomial_distribution_o_min() -> Result<(), String> { + #[tokio::test] + async fn polynomial_distribution_o_min() -> Result<(), String> { test_polynomial( Polynomial { a: 1, @@ -1956,10 +2004,11 @@ mod polynomial { &[(1, 100_000, false), (4, 100_000, false)], 1, ) + .await } - #[test] - fn polynomial_distribution_pow_minus_1_at_h_2() -> Result<(), String> { + #[tokio::test] + async fn polynomial_distribution_pow_minus_1_at_h_2() -> Result<(), String> { test_polynomial( Polynomial { a: 1, @@ -1982,10 +2031,11 @@ mod polynomial { ], 1, ) + .await } - #[test] - fn polynomial_distribution_o_max() -> Result<(), String> { + #[tokio::test] + async fn polynomial_distribution_o_max() -> Result<(), String> { test_polynomial( Polynomial { a: 1, @@ -2001,11 +2051,12 @@ mod polynomial { &[(1, 281474976810655, true), (10, 2814749767206550, true)], 1, ) + .await } /// Test polynomial distribution function. /// /// `f(x) = (a * (x - s + o)^(m/n)) / d + b` - fn test_polynomial( + async fn test_polynomial( dist: DistributionFunction, steps: &[(u64, u64, bool)], // height, expected balance, expect pass distribution_interval: u64, @@ -2017,6 +2068,7 @@ mod polynomial { distribution_interval, None, ) + .await .inspect_err(|e| { tracing::error!("{}", e); }) @@ -2025,8 +2077,8 @@ mod polynomial { /// Test various combinations of `m/n` in `[DistributionFunction::Polynomial]` distribution. /// /// We expect this test not to end with InternalError. - #[test] - fn polynomial_distribution_power_extreme_values() -> Result<(), String> { + #[tokio::test] + async fn polynomial_distribution_power_extreme_values() -> Result<(), String> { for m in [MIN_POL_M_PARAM, MAX_POL_M_PARAM] { for n in [1, MAX_POL_N_PARAM] { for a in [MIN_POL_A_PARAM, MAX_POL_A_PARAM] { @@ -2095,6 +2147,7 @@ mod polynomial { suite .execute(&[step]) + .await .inspect_err(|e| { tracing::error!("{}", e); }) @@ -2115,8 +2168,8 @@ mod logarithmic { use dpp::data_contract::associated_token::token_perpetual_distribution::distribution_function::DistributionFunction::{self,Logarithmic}; use dpp::data_contract::associated_token::token_perpetual_distribution::distribution_function::{MAX_DISTRIBUTION_PARAM, MAX_LOG_A_PARAM, MIN_LOG_A_PARAM}; - #[test] - fn log_distribution_basic() -> Result<(), String> { + #[tokio::test] + async fn log_distribution_basic() -> Result<(), String> { test_logarithmic( Logarithmic { a: 1, // a: i64, @@ -2137,10 +2190,11 @@ mod logarithmic { ], 1, ) + .await } - #[test] - fn log_distribution_1_div_u64_max() -> Result<(), String> { + #[tokio::test] + async fn log_distribution_1_div_u64_max() -> Result<(), String> { // n is very big here, so we would expect to get 0 test_logarithmic( Logarithmic { @@ -2157,10 +2211,11 @@ mod logarithmic { &[(1, 100_000, false), (5, 100_000, false)], 1, ) + .await } - #[test] - fn log_distribution_neg_1_div_u64_max() -> Result<(), String> { + #[tokio::test] + async fn log_distribution_neg_1_div_u64_max() -> Result<(), String> { // n is very big here, so we would expect to get 0 test_logarithmic( Logarithmic { @@ -2177,10 +2232,11 @@ mod logarithmic { &[(1, 100_044, true), (5, 100_214, true)], 1, ) + .await } - #[test] - fn log_distribution_a_min() -> Result<(), String> { + #[tokio::test] + async fn log_distribution_a_min() -> Result<(), String> { test_logarithmic( Logarithmic { a: MIN_LOG_A_PARAM, // a: i64, @@ -2202,10 +2258,11 @@ mod logarithmic { ], 1, ) + .await } - #[test] - fn log_distribution_max_amounts() { + #[tokio::test] + async fn log_distribution_max_amounts() { test_logarithmic( Logarithmic { a: MAX_LOG_A_PARAM, // a: i64, @@ -2226,11 +2283,12 @@ mod logarithmic { ], 1, ) + .await .expect("expect to pass"); } - #[test] - fn log_distribution_with_b_max() -> Result<(), String> { + #[tokio::test] + async fn log_distribution_with_b_max() -> Result<(), String> { test_logarithmic( Logarithmic { a: 1, // a: i64, @@ -2250,9 +2308,10 @@ mod logarithmic { ], 1, ) + .await } /// f(x) = (a * log(m * (x - s + o) / n)) / d + b - fn test_logarithmic( + async fn test_logarithmic( dist: DistributionFunction, steps: &[(u64, u64, bool)], // height, expected balance, expect pass distribution_interval: u64, @@ -2264,6 +2323,7 @@ mod logarithmic { distribution_interval, None, ) + .await .inspect_err(|e| { tracing::error!("{}", e); }) @@ -2274,8 +2334,8 @@ mod inverted_logarithmic { use super::test_suite::check_heights; use dpp::data_contract::associated_token::token_perpetual_distribution::distribution_function::DistributionFunction::{self,InvertedLogarithmic}; - #[test] - fn inv_log_distribution_very_low_emission() -> Result<(), String> { + #[tokio::test] + async fn inv_log_distribution_very_low_emission() -> Result<(), String> { // At block 2 no more can ever be claimed because the function is decreasing let dist = InvertedLogarithmic { a: 1, // a: i64, @@ -2297,11 +2357,11 @@ mod inverted_logarithmic { assert_eq!(x_1, 1); // This is ln (1/ (1 - 1 + 1)), or basically ln(1) = 1 let x_2 = dist.evaluate(0, 2).expect("expected to evaluate"); assert_eq!(x_2, 0); // This is ln (1/ (1 - 1 + 2)), or basically ln(1/2) = 0 - run_test(dist, &steps, 1) + run_test(dist, &steps, 1).await } - #[test] - fn inv_log_distribution_reduced_emission() -> Result<(), String> { + #[tokio::test] + async fn inv_log_distribution_reduced_emission() -> Result<(), String> { // y // ↑ // 10000 |* @@ -2345,11 +2405,11 @@ mod inverted_logarithmic { (1000, 6_110_958, true), ]; - run_test(dist, &steps, 1) + run_test(dist, &steps, 1).await } - #[test] - fn inv_log_distribution_reduced_emission_passing_0() -> Result<(), String> { + #[tokio::test] + async fn inv_log_distribution_reduced_emission_passing_0() -> Result<(), String> { // y // ↑ // 350 |* @@ -2380,11 +2440,11 @@ mod inverted_logarithmic { (300, 119546, false), // past 200 we won't get any more ]; - run_test(dist, &steps, 1) + run_test(dist, &steps, 1).await } - #[test] - fn inv_log_distribution_negative_a_increase_emission() -> Result<(), String> { + #[tokio::test] + async fn inv_log_distribution_negative_a_increase_emission() -> Result<(), String> { // y // ↑ // 10000 | @@ -2426,11 +2486,11 @@ mod inverted_logarithmic { (300, 537282, true), ]; - run_test(dist, &steps, 1) + run_test(dist, &steps, 1).await } /// f(x) = (a * log( n / (m * (x - s + o)) )) / d + b - fn run_test( + async fn run_test( dist: DistributionFunction, steps: &[(u64, u64, bool)], // height, expected balance, expect pass distribution_interval: u64, @@ -2442,6 +2502,7 @@ mod inverted_logarithmic { distribution_interval, None, ) + .await .inspect_err(|e| { tracing::error!("{}", e); }) @@ -2489,7 +2550,7 @@ mod test_suite { /// * `expected_balance` - expected balance after claim was made /// * `expect_pass` - whether we expect the claim to pass or not /// - pub(super) fn check_heights + Clone>( + pub(super) async fn check_heights + Clone>( distribution_function: DistributionFunction, steps: &[C], contract_start_time: Option, @@ -2528,7 +2589,7 @@ mod test_suite { .map(|item| item.clone().into()) .collect::>(); - suite.execute(&steps) + suite.execute(&steps).await } pub(super) type TokenConfigFn = dyn FnOnce(&mut TokenConfiguration) + Send + Sync; @@ -2730,7 +2791,7 @@ mod test_suite { } /// Submit a claim transition and assert the results - pub(crate) fn claim(&mut self, assertions: Vec) -> Result<(), String> { + pub(crate) async fn claim(&mut self, assertions: Vec) -> Result<(), String> { let committed_block_info = self.block_info(); let nonce = self.next_identity_nonce(); // next block config @@ -2758,6 +2819,7 @@ mod test_suite { self.platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -2952,10 +3014,10 @@ mod test_suite { } /// execute test steps, one by one - pub(super) fn execute(&mut self, tests: &[TestStep]) -> Result<(), String> { + pub(super) async fn execute(&mut self, tests: &[TestStep]) -> Result<(), String> { let mut errors = String::new(); for test_case in tests { - let result = self.execute_step(test_case); + let result = self.execute_step(test_case).await; if let Err(e) = result { errors += format!("\n--> {}: {}\n", test_case.name, e).as_str(); } @@ -2970,7 +3032,7 @@ mod test_suite { /// Execute a single test step. It fasts forwards to the block height of the test case, /// executes the claim and checks the balance. - pub(super) fn execute_step(&mut self, test_case: &TestStep) -> Result<(), String> { + pub(super) async fn execute_step(&mut self, test_case: &TestStep) -> Result<(), String> { let current_height = self.block_info().height; let current_core_height = self.block_info().core_height; @@ -2991,7 +3053,10 @@ mod test_suite { false, ); let mut result = Vec::new(); - if let Err(e) = self.claim(test_case.claim_transition_assertions.clone()) { + if let Err(e) = self + .claim(test_case.claim_transition_assertions.clone()) + .await + { result.push(format!("claim failed: {}", e)) } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/distribution/perpetual/time_based.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/distribution/perpetual/time_based.rs index baa8b21942b..afd8112cdbb 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/distribution/perpetual/time_based.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/distribution/perpetual/time_based.rs @@ -19,8 +19,8 @@ mod perpetual_distribution_time { use dpp::data_contract::associated_token::token_perpetual_distribution::v0::TokenPerpetualDistributionV0; use crate::test::helpers::fast_forward_to_block::fast_forward_to_block; use super::*; - #[test] - fn test_token_perpetual_distribution_time_claim_linear_and_claim_again() { + #[tokio::test] + async fn test_token_perpetual_distribution_time_claim_linear_and_claim_again() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -74,6 +74,7 @@ mod perpetual_distribution_time { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -140,6 +141,7 @@ mod perpetual_distribution_time { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -208,6 +210,7 @@ mod perpetual_distribution_time { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -259,8 +262,8 @@ mod perpetual_distribution_time { assert_eq!(token_balance, Some(100300)); } - #[test] - fn test_token_perpetual_distribution_not_claimant() { + #[tokio::test] + async fn test_token_perpetual_distribution_not_claimant() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -319,6 +322,7 @@ mod perpetual_distribution_time { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -383,8 +387,8 @@ mod perpetual_distribution_time { assert_eq!(token_balance_2, None); } - #[test] - fn test_token_perpetual_distribution_time_claim_linear_given_to_specific_identity() { + #[tokio::test] + async fn test_token_perpetual_distribution_time_claim_linear_given_to_specific_identity() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -442,6 +446,7 @@ mod perpetual_distribution_time { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -493,8 +498,8 @@ mod perpetual_distribution_time { assert_eq!(token_balance, Some(250)); } - #[test] - fn test_token_perpetual_distribution_time_linear() { + #[tokio::test] + async fn test_token_perpetual_distribution_time_linear() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -560,6 +565,7 @@ mod perpetual_distribution_time { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -628,6 +634,7 @@ mod perpetual_distribution_time { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -680,8 +687,8 @@ mod perpetual_distribution_time { assert_eq!(token_balance, Some(balance as u64)); } - #[test] - fn test_token_perpetual_distribution_time_linear_every_hour() { + #[tokio::test] + async fn test_token_perpetual_distribution_time_linear_every_hour() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -747,6 +754,7 @@ mod perpetual_distribution_time { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -817,6 +825,7 @@ mod perpetual_distribution_time { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -870,8 +879,8 @@ mod perpetual_distribution_time { assert_eq!(token_balance, Some(15)); } - #[test] - fn test_token_perpetual_distribution_time_linear_verify_contract_start() { + #[tokio::test] + async fn test_token_perpetual_distribution_time_linear_verify_contract_start() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -937,6 +946,7 @@ mod perpetual_distribution_time { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -1005,6 +1015,7 @@ mod perpetual_distribution_time { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -1058,8 +1069,8 @@ mod perpetual_distribution_time { assert_eq!(token_balance, Some(6)); } - #[test] - fn test_token_perpetual_distribution_time_linear_high_values() { + #[tokio::test] + async fn test_token_perpetual_distribution_time_linear_high_values() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1125,6 +1136,7 @@ mod perpetual_distribution_time { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -1189,6 +1201,7 @@ mod perpetual_distribution_time { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -1239,8 +1252,8 @@ mod perpetual_distribution_time { assert_eq!(token_balance, Some(72057594046349056)); } - #[test] - fn test_token_perpetual_distribution_time_linear_high_values_old_contract_should_handle_overflow( + #[tokio::test] + async fn test_token_perpetual_distribution_time_linear_high_values_old_contract_should_handle_overflow( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -1308,6 +1321,7 @@ mod perpetual_distribution_time { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -1360,8 +1374,8 @@ mod perpetual_distribution_time { assert_eq!(token_balance, Some(9223372036854675807)); } - #[test] - fn test_token_perpetual_distribution_stepwise_distribution() { + #[tokio::test] + async fn test_token_perpetual_distribution_stepwise_distribution() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1440,6 +1454,7 @@ mod perpetual_distribution_time { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/distribution/pre_programmed.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/distribution/pre_programmed.rs index becd8e96899..06b241fcd15 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/distribution/pre_programmed.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/distribution/pre_programmed.rs @@ -11,8 +11,8 @@ mod pre_programmed_distribution { use dpp::data_contract::associated_token::token_pre_programmed_distribution::v0::TokenPreProgrammedDistributionV0; use crate::test::helpers::fast_forward_to_block::fast_forward_to_block; use super::*; - #[test] - fn test_token_pre_programmed_distribution_two_claims() { + #[tokio::test] + async fn test_token_pre_programmed_distribution_two_claims() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -67,6 +67,7 @@ mod pre_programmed_distribution { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -132,6 +133,7 @@ mod pre_programmed_distribution { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -182,8 +184,8 @@ mod pre_programmed_distribution { assert_eq!(token_balance, Some(1045)); } - #[test] - fn test_token_pre_programmed_distribution_claim_again_when_none_left() { + #[tokio::test] + async fn test_token_pre_programmed_distribution_claim_again_when_none_left() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -234,6 +236,7 @@ mod pre_programmed_distribution { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -299,6 +302,7 @@ mod pre_programmed_distribution { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -352,8 +356,8 @@ mod pre_programmed_distribution { assert_eq!(token_balance, Some(445)); } - #[test] - fn test_token_pre_programmed_distribution_claim_again_when_none_ready() { + #[tokio::test] + async fn test_token_pre_programmed_distribution_claim_again_when_none_ready() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -404,6 +408,7 @@ mod pre_programmed_distribution { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -457,8 +462,8 @@ mod pre_programmed_distribution { assert_eq!(token_balance, None); } - #[test] - fn test_token_pre_programmed_distribution_claim_again_when_none_ready_after_a_claim() { + #[tokio::test] + async fn test_token_pre_programmed_distribution_claim_again_when_none_ready_after_a_claim() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -513,6 +518,7 @@ mod pre_programmed_distribution { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -578,6 +584,7 @@ mod pre_programmed_distribution { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -631,8 +638,8 @@ mod pre_programmed_distribution { assert_eq!(token_balance, Some(445)); } - #[test] - fn test_token_pre_programmed_distribution_claim_no_rewards_for_recipient() { + #[tokio::test] + async fn test_token_pre_programmed_distribution_claim_no_rewards_for_recipient() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -683,6 +690,7 @@ mod pre_programmed_distribution { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -736,8 +744,8 @@ mod pre_programmed_distribution { assert_eq!(token_balance, None); } - #[test] - fn test_token_pre_programmed_distribution_claim_no_pre_programmed_rewards_for_recipient_when_they_have_perpetual( + #[tokio::test] + async fn test_token_pre_programmed_distribution_claim_no_pre_programmed_rewards_for_recipient_when_they_have_perpetual( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -803,6 +811,7 @@ mod pre_programmed_distribution { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/emergency_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/emergency_action/mod.rs index 6286af3857c..5733475d6d5 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/emergency_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/emergency_action/mod.rs @@ -6,8 +6,8 @@ mod token_emergency_action_tests { use dpp::tokens::status::v0::TokenStatusV0; use dpp::tokens::status::TokenStatus; - #[test] - fn test_token_emergency_pause() { + #[tokio::test] + async fn test_token_emergency_pause() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -56,6 +56,7 @@ mod token_emergency_action_tests { platform_version, None, ) + .await .expect("expected to create emergency action transition"); let serialized = pause_transition @@ -100,8 +101,8 @@ mod token_emergency_action_tests { ); } - #[test] - fn test_token_emergency_resume() { + #[tokio::test] + async fn test_token_emergency_resume() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -150,6 +151,7 @@ mod token_emergency_action_tests { platform_version, None, ) + .await .expect("expected to create emergency action transition"); let serialized = pause_transition @@ -209,6 +211,7 @@ mod token_emergency_action_tests { platform_version, None, ) + .await .expect("expected to create emergency action transition"); let serialized = resume_transition @@ -253,8 +256,8 @@ mod token_emergency_action_tests { ); } - #[test] - fn test_token_emergency_pause_already_paused_should_fail() { + #[tokio::test] + async fn test_token_emergency_pause_already_paused_should_fail() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -303,6 +306,7 @@ mod token_emergency_action_tests { platform_version, None, ) + .await .expect("expected to create emergency action transition"); let serialized = pause_transition @@ -352,6 +356,7 @@ mod token_emergency_action_tests { platform_version, None, ) + .await .expect("expected to create emergency action transition"); let serialized = pause_again_transition @@ -382,8 +387,8 @@ mod token_emergency_action_tests { ); } - #[test] - fn test_token_emergency_resume_not_paused_should_fail() { + #[tokio::test] + async fn test_token_emergency_resume_not_paused_should_fail() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -432,6 +437,7 @@ mod token_emergency_action_tests { platform_version, None, ) + .await .expect("expected to create emergency action transition"); let serialized = pause_transition @@ -481,6 +487,7 @@ mod token_emergency_action_tests { platform_version, None, ) + .await .expect("expected to create emergency action transition"); let serialized = resume_transition @@ -530,6 +537,7 @@ mod token_emergency_action_tests { platform_version, None, ) + .await .expect("expected to create emergency action transition"); let serialized = resume_again_transition diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/freeze/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/freeze/mod.rs index a2638e874d4..cb1f84c9d70 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/freeze/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/freeze/mod.rs @@ -5,8 +5,8 @@ mod token_freeze_tests { mod token_freeze_basic_tests { use super::*; - #[test] - fn test_token_freeze() { + #[tokio::test] + async fn test_token_freeze() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -58,6 +58,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let freeze_serialized_transition = freeze_transition @@ -104,8 +105,8 @@ mod token_freeze_tests { assert_eq!(token_frozen, Some(true)); } - #[test] - fn test_token_freeze_identity_does_not_exist() { + #[tokio::test] + async fn test_token_freeze_identity_does_not_exist() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -156,6 +157,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let freeze_serialized_transition = freeze_transition @@ -207,8 +209,8 @@ mod token_freeze_tests { assert_eq!(token_frozen, None); } - #[test] - fn test_token_freeze_and_unfreeze() { + #[tokio::test] + async fn test_token_freeze_and_unfreeze() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -269,6 +271,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let freeze_serialized_transition = freeze_transition @@ -329,6 +332,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let unfreeze_serialized_transition = unfreeze_transition @@ -375,8 +379,8 @@ mod token_freeze_tests { assert_eq!(token_frozen, Some(false)); } - #[test] - fn test_token_unfreeze_success() { + #[tokio::test] + async fn test_token_unfreeze_success() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -440,6 +444,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create token transfer transition"); let transfer_serialized = token_transfer_transition @@ -489,6 +494,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create freeze transition"); let freeze_serialized = freeze_transition @@ -553,6 +559,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create transfer transition"); let send_serialized = send_while_frozen @@ -607,6 +614,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create unfreeze transition"); let unfreeze_serialized = unfreeze_transition @@ -671,6 +679,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create transfer transition"); let send_serialized = send_after_unfreeze @@ -728,8 +737,8 @@ mod token_freeze_tests { assert_eq!(balance_identity_2, Some(5000 - 100)); } - #[test] - fn test_token_frozen_receive_balance_allowed_sending_not_allowed_till_unfrozen() { + #[tokio::test] + async fn test_token_frozen_receive_balance_allowed_sending_not_allowed_till_unfrozen() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -790,6 +799,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let freeze_serialized_transition = freeze_transition @@ -852,6 +862,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_transfer_serialized_transition = token_transfer_transition @@ -928,6 +939,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_transfer_back_serialized_transition = token_transfer_back_transition @@ -1007,6 +1019,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let unfreeze_serialized_transition = unfreeze_transition @@ -1069,6 +1082,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_transfer_serialized_transition = token_transfer_transition @@ -1127,8 +1141,8 @@ mod token_freeze_tests { assert_eq!(token_balance, Some(expected_amount)); } - #[test] - fn test_token_frozen_receive_balance_may_not_be_allowed() { + #[tokio::test] + async fn test_token_frozen_receive_balance_may_not_be_allowed() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1190,6 +1204,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let freeze_serialized_transition = freeze_transition @@ -1252,6 +1267,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_transfer_serialized_transition = token_transfer_transition @@ -1330,8 +1346,8 @@ mod token_freeze_tests { // Owner tries to freeze, but authorization is *group‑only* // and owner does NOT hold enough power alone → Error. // ────────────────────────────────────────────────────────── - #[test] - fn test_token_freeze_owner_not_authorized_group_required() { + #[tokio::test] + async fn test_token_freeze_owner_not_authorized_group_required() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1392,6 +1408,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("create freeze"); let serialized = freeze.serialize_to_bytes().expect("serialize freeze"); @@ -1423,8 +1440,8 @@ mod token_freeze_tests { // Owner alone HAS enough power in the group (5 ≥ required 5) // → freeze succeeds immediately. // ────────────────────────────────────────────────────────── - #[test] - fn test_token_freeze_owner_enough_group_power_without_group_action() { + #[tokio::test] + async fn test_token_freeze_owner_enough_group_power_without_group_action() { let version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1487,6 +1504,7 @@ mod token_freeze_tests { version, None, ) + .await .unwrap(); let freeze_ser = freeze.serialize_to_bytes().unwrap(); @@ -1533,8 +1551,8 @@ mod token_freeze_tests { // Owner alone HAS enough power in the group (5 ≥ required 5) // → freeze succeeds immediately. // ────────────────────────────────────────────────────────── - #[test] - fn test_token_freeze_owner_enough_group_power_using_group_action() { + #[tokio::test] + async fn test_token_freeze_owner_enough_group_power_using_group_action() { let version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1597,6 +1615,7 @@ mod token_freeze_tests { version, None, ) + .await .unwrap(); let freeze_ser = freeze.serialize_to_bytes().unwrap(); @@ -1652,7 +1671,9 @@ mod token_freeze_tests { // ────────────────────────────────────────────────────────── // Two‑signer scenario: proposer + second member complete freeze // ────────────────────────────────────────────────────────── - fn test_token_freeze_two_member_group_with_keeps_history(keeps_freezing_history: bool) { + async fn test_token_freeze_two_member_group_with_keeps_history( + keeps_freezing_history: bool, + ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1711,6 +1732,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create batch transition"); let token_freeze_serialized_transition = token_freeze_transition @@ -1814,6 +1836,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .unwrap(); let token_freeze_serialized_transition = token_freeze_confirm_transition @@ -1899,8 +1922,8 @@ mod token_freeze_tests { assert_eq!(frozen, Some(true)); } - #[test] - fn test_token_freeze_two_member_group_and_destroy_frozen_funds() { + #[tokio::test] + async fn test_token_freeze_two_member_group_and_destroy_frozen_funds() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1972,6 +1995,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_mint_serialized_transition = token_mint_transition @@ -2032,6 +2056,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create batch transition"); let token_freeze_serialized_transition = token_freeze_transition @@ -2094,6 +2119,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .unwrap(); let token_destroy_frozen_funds_serialized_transition = @@ -2159,6 +2185,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .unwrap(); let token_destroy_frozen_funds_serialized_confirm_transition = @@ -2249,8 +2276,8 @@ mod token_freeze_tests { assert_eq!(frozen_identity_balance, Some(0)); } - #[test] - fn test_token_freeze_two_member_group_and_destroy_frozen_funds_change_target_id_mid_group_action( + #[tokio::test] + async fn test_token_freeze_two_member_group_and_destroy_frozen_funds_change_target_id_mid_group_action( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -2324,6 +2351,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_mint_serialized_transition = token_mint_transition @@ -2373,6 +2401,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_mint_serialized_transition = token_mint_transition @@ -2432,6 +2461,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create batch transition"); let token_freeze_serialized_transition = token_freeze_transition @@ -2480,6 +2510,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .expect("expect to create batch transition"); let token_freeze_serialized_transition = token_freeze_transition @@ -2542,6 +2573,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .unwrap(); let token_destroy_frozen_funds_serialized_transition = @@ -2608,6 +2640,7 @@ mod token_freeze_tests { platform_version, None, ) + .await .unwrap(); let token_destroy_frozen_funds_serialized_confirm_transition = diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mint/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mint/mod.rs index 7c27ceea35c..bdba8a84cd8 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mint/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mint/mod.rs @@ -5,8 +5,8 @@ mod token_mint_tests { mod token_mint_tests_normal_scenarios { use super::*; - #[test] - fn test_token_mint_by_owner_allowed_sending_to_self() { + #[tokio::test] + async fn test_token_mint_by_owner_allowed_sending_to_self() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -46,6 +46,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -91,8 +92,8 @@ mod token_mint_tests { assert_eq!(token_balance, Some(101337)); } - #[test] - fn test_token_mint_with_public_note() { + #[tokio::test] + async fn test_token_mint_with_public_note() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -132,6 +133,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -177,8 +179,8 @@ mod token_mint_tests { assert_eq!(token_balance, Some(101337)); } - #[test] - fn test_token_mint_by_owner_can_not_mint_past_max_supply() { + #[tokio::test] + async fn test_token_mint_by_owner_can_not_mint_past_max_supply() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -220,6 +222,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -268,8 +271,8 @@ mod token_mint_tests { assert_eq!(token_balance, Some(100000)); } - #[test] - fn test_token_mint_by_owner_allowed_sending_to_other() { + #[tokio::test] + async fn test_token_mint_by_owner_allowed_sending_to_other() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -311,6 +314,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -356,8 +360,8 @@ mod token_mint_tests { assert_eq!(token_balance, Some(1337)); } - #[test] - fn test_token_mint_sending_to_non_existing_identity_causes_error() { + #[tokio::test] + async fn test_token_mint_sending_to_non_existing_identity_causes_error() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -399,6 +403,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -449,8 +454,8 @@ mod token_mint_tests { assert_eq!(token_balance, None); } - #[test] - fn test_token_mint_by_owner_no_destination_causes_error() { + #[tokio::test] + async fn test_token_mint_by_owner_no_destination_causes_error() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -490,6 +495,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -533,8 +539,8 @@ mod token_mint_tests { mod token_mint_tests_no_recipient_minting { use super::*; - #[test] - fn test_token_mint_by_owned_id_allowed_sending_to_self() { + #[tokio::test] + async fn test_token_mint_by_owned_id_allowed_sending_to_self() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -578,6 +584,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -628,8 +635,8 @@ mod token_mint_tests { assert_eq!(token_balance, Some(100000)); } - #[test] - fn test_token_mint_by_owned_id_allowed_sending_to_other() { + #[tokio::test] + async fn test_token_mint_by_owned_id_allowed_sending_to_other() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -675,6 +682,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -725,8 +733,8 @@ mod token_mint_tests { assert_eq!(token_balance, None); } - #[test] - fn test_token_mint_by_owned_id_no_destination_causes_error() { + #[tokio::test] + async fn test_token_mint_by_owned_id_no_destination_causes_error() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -770,6 +778,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -813,8 +822,8 @@ mod token_mint_tests { mod token_mint_tests_contract_has_recipient { use super::*; - #[test] - fn test_token_mint_by_owned_id_allowed_sending_to_self() { + #[tokio::test] + async fn test_token_mint_by_owned_id_allowed_sending_to_self() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -861,6 +870,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -911,8 +921,8 @@ mod token_mint_tests { assert_eq!(token_balance, Some(100000)); } - #[test] - fn test_token_mint_by_owned_id_allowed_sending_to_other() { + #[tokio::test] + async fn test_token_mint_by_owned_id_allowed_sending_to_other() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -961,6 +971,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1011,8 +1022,8 @@ mod token_mint_tests { assert_eq!(token_balance, None); } - #[test] - fn test_token_mint_by_owned_id_no_set_destination_should_use_contracts() { + #[tokio::test] + async fn test_token_mint_by_owned_id_no_set_destination_should_use_contracts() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1059,6 +1070,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1121,8 +1133,8 @@ mod token_mint_tests { use dpp::state_transition::proof_result::StateTransitionProofResult; use drive::drive::Drive; - #[test] - fn test_token_mint_by_owner_sending_to_self_minting_not_allowed() { + #[tokio::test] + async fn test_token_mint_by_owner_sending_to_self_minting_not_allowed() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1172,6 +1184,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1220,8 +1233,8 @@ mod token_mint_tests { assert_eq!(token_balance, Some(100000)); } - #[test] - fn test_token_mint_by_owner_sending_to_self_minting_only_allowed_by_group() { + #[tokio::test] + async fn test_token_mint_by_owner_sending_to_self_minting_only_allowed_by_group() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1283,6 +1296,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1331,8 +1345,8 @@ mod token_mint_tests { assert_eq!(token_balance, Some(100000)); } - #[test] - fn test_token_mint_by_owner_sending_to_self_minting_only_allowed_by_group_enough_member_power( + #[tokio::test] + async fn test_token_mint_by_owner_sending_to_self_minting_only_allowed_by_group_enough_member_power( ) { // We are using a group, but our member alone has enough power in the group to do the action let platform_version = PlatformVersion::latest(); @@ -1396,6 +1410,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition = documents_batch_create_transition @@ -1451,7 +1466,7 @@ mod token_mint_tests { test_token_mint_by_owner_requires_group_other_member(false); } - fn test_token_mint_by_owner_requires_group_other_member(keeps_minting_history: bool) { + async fn test_token_mint_by_owner_requires_group_other_member(keeps_minting_history: bool) { // We are using a group, and two members need to sign for the event to happen let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -1517,6 +1532,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_mint_serialized_transition = token_mint_transition @@ -1632,6 +1648,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let confirm_token_mint_serialized_transition = confirm_token_mint_transition @@ -1728,8 +1745,8 @@ mod token_mint_tests { assert_eq!(token_balance, None); } - #[test] - fn test_token_mint_by_owner_requires_group_other_member_keeps_history_with_note() { + #[tokio::test] + async fn test_token_mint_by_owner_requires_group_other_member_keeps_history_with_note() { // We are using a group, and two members need to sign for the event to happen let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -1795,6 +1812,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_mint_serialized_transition = token_mint_transition @@ -1901,6 +1919,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let confirm_token_mint_serialized_transition = confirm_token_mint_transition @@ -1964,6 +1983,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let confirm_token_mint_serialized_transition = confirm_token_mint_transition @@ -2051,8 +2071,8 @@ mod token_mint_tests { assert_eq!(token_balance, None); } - #[test] - fn test_token_mint_by_owner_requires_group_other_member_changes_minting_amount() { + #[tokio::test] + async fn test_token_mint_by_owner_requires_group_other_member_changes_minting_amount() { // We are using a group, and two members need to sign for the event to happen let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -2118,6 +2138,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_mint_serialized_transition = token_mint_transition @@ -2222,6 +2243,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let confirm_token_mint_serialized_transition = confirm_token_mint_transition @@ -2283,8 +2305,8 @@ mod token_mint_tests { assert_eq!(token_balance, None); } - #[test] - fn test_token_mint_by_owner_requires_group_resubmitting_causes_error() { + #[tokio::test] + async fn test_token_mint_by_owner_requires_group_resubmitting_causes_error() { // We are using a group, and two members need to sign for the event to happen let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -2347,6 +2369,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_mint_serialized_transition = token_mint_transition @@ -2441,6 +2464,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let confirm_token_mint_serialized_transition = confirm_token_mint_transition @@ -2513,8 +2537,8 @@ mod token_mint_tests { assert_eq!(token_balance, None); } - #[test] - fn test_token_mint_by_owner_requires_group_other_member_resubmitting_causes_error() { + #[tokio::test] + async fn test_token_mint_by_owner_requires_group_other_member_resubmitting_causes_error() { // We are using a group, and two members need to sign for the event to happen let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -2585,6 +2609,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_mint_serialized_transition = token_mint_transition @@ -2660,6 +2685,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let confirm_token_mint_serialized_transition = confirm_token_mint_transition @@ -2740,6 +2766,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let confirm_token_mint_serialized_transition = confirm_token_mint_transition @@ -2801,8 +2828,8 @@ mod token_mint_tests { assert_eq!(token_balance, None); } - #[test] - fn test_token_mint_by_owner_requires_group_other_member_submitting_after_completion_causes_error( + #[tokio::test] + async fn test_token_mint_by_owner_requires_group_other_member_submitting_after_completion_causes_error( ) { // We are using a group, and two members need to sign for the event to happen let platform_version = PlatformVersion::latest(); @@ -2874,6 +2901,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_mint_serialized_transition = token_mint_transition @@ -2949,6 +2977,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let confirm_token_mint_serialized_transition = confirm_token_mint_transition @@ -3029,6 +3058,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let confirm_token_mint_serialized_transition = confirm_token_mint_transition @@ -3108,8 +3138,8 @@ mod token_mint_tests { assert_eq!(token_balance, None); } - #[test] - fn test_token_mint_by_owner_requires_group_proposer_not_in_group() { + #[tokio::test] + async fn test_token_mint_by_owner_requires_group_proposer_not_in_group() { // We are using a group, and two members need to sign for the event to happen let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -3175,6 +3205,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_mint_serialized_transition = token_mint_transition @@ -3223,8 +3254,8 @@ mod token_mint_tests { assert_eq!(token_balance, Some(100000)); } - #[test] - fn test_token_mint_by_owner_requires_group_other_signer_not_part_of_group() { + #[tokio::test] + async fn test_token_mint_by_owner_requires_group_other_signer_not_part_of_group() { // We are using a group, and two members need to sign for the event to happen let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -3290,6 +3321,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_mint_serialized_transition = token_mint_transition @@ -3365,6 +3397,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let confirm_token_mint_serialized_transition = confirm_token_mint_transition @@ -3424,8 +3457,8 @@ mod token_mint_tests { assert_eq!(token_balance, None); } - #[test] - fn test_token_mint_other_signer_going_first_causes_error() { + #[tokio::test] + async fn test_token_mint_other_signer_going_first_causes_error() { // We are using a group, and the second member gets a bit hasty and signs first let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -3502,6 +3535,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let confirm_token_mint_serialized_transition = confirm_token_mint_transition @@ -3561,8 +3595,8 @@ mod token_mint_tests { assert_eq!(token_balance, None); } - #[test] - fn test_token_mint_by_owner_does_not_require_group_but_sends_group_info() { + #[tokio::test] + async fn test_token_mint_by_owner_does_not_require_group_but_sends_group_info() { // We are using a group, and two members need to sign for the event to happen let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -3628,6 +3662,7 @@ mod token_mint_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_mint_serialized_transition = token_mint_transition diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/transfer/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/transfer/mod.rs index d13f0051742..d162f24a9ad 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/transfer/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/transfer/mod.rs @@ -18,8 +18,8 @@ mod token_transfer_tests { use dpp::tokens::status::v0::TokenStatusV0; use super::*; - #[test] - fn test_token_transfer() { + #[tokio::test] + async fn test_token_transfer() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -62,6 +62,7 @@ mod token_transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_transfer_serialized_transition = token_transfer_transition @@ -120,8 +121,8 @@ mod token_transfer_tests { assert_eq!(token_balance, Some(expected_amount)); } - #[test] - fn test_token_transfer_to_non_existing_identity() { + #[tokio::test] + async fn test_token_transfer_to_non_existing_identity() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -163,6 +164,7 @@ mod token_transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_transfer_serialized_transition = token_transfer_transition @@ -224,8 +226,8 @@ mod token_transfer_tests { assert_eq!(token_balance, None); } - #[test] - fn test_token_transfer_should_fail_if_token_started_paused() { + #[tokio::test] + async fn test_token_transfer_should_fail_if_token_started_paused() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -279,6 +281,7 @@ mod token_transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_transfer_serialized_transition = token_transfer_transition @@ -363,6 +366,7 @@ mod token_transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let resume_transition_transition = resume_transition @@ -424,6 +428,7 @@ mod token_transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_transfer_serialized_transition = token_transfer_transition @@ -482,8 +487,8 @@ mod token_transfer_tests { assert_eq!(token_balance, Some(expected_amount)); } - #[test] - fn test_token_transfer_should_fail_if_token_becomes_paused() { + #[tokio::test] + async fn test_token_transfer_should_fail_if_token_becomes_paused() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -535,6 +540,7 @@ mod token_transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let resume_transition_transition = resume_transition @@ -594,6 +600,7 @@ mod token_transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_transfer_serialized_transition = token_transfer_transition @@ -669,6 +676,7 @@ mod token_transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let resume_transition_transition = resume_transition @@ -730,6 +738,7 @@ mod token_transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_transfer_serialized_transition = token_transfer_transition @@ -788,8 +797,8 @@ mod token_transfer_tests { assert_eq!(token_balance, Some(expected_amount)); } - #[test] - fn test_token_transfer_to_ourself_should_fail() { + #[tokio::test] + async fn test_token_transfer_to_ourself_should_fail() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -830,6 +839,7 @@ mod token_transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_transfer_serialized_transition = token_transfer_transition @@ -877,8 +887,8 @@ mod token_transfer_tests { assert_eq!(token_balance, Some(100000)); } - #[test] - fn test_token_transfer_trying_to_send_more_than_we_have() { + #[tokio::test] + async fn test_token_transfer_trying_to_send_more_than_we_have() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -921,6 +931,7 @@ mod token_transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_transfer_serialized_transition = token_transfer_transition @@ -983,8 +994,8 @@ mod token_transfer_tests { assert_eq!(token_balance, None); } - #[test] - fn test_token_transfer_adding_group_info_causes_error() { + #[tokio::test] + async fn test_token_transfer_adding_group_info_causes_error() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1047,6 +1058,7 @@ mod token_transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_mint_serialized_transition = token_mint_transition @@ -1104,6 +1116,7 @@ mod token_transfer_tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); // here we add fake info @@ -1130,6 +1143,7 @@ mod token_transfer_tests { &signer, None::, ) + .await .expect("expected to resign transaction"); let token_transfer_serialized_transition = token_transfer_transition diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs index 03bb9a21c96..997448b2b2e 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs @@ -223,8 +223,8 @@ mod tests { use platform_version::version::PlatformVersion; use std::collections::BTreeMap; - #[test] - fn test_data_contract_creation_with_contested_unique_index() { + #[tokio::test] + async fn test_data_contract_creation_with_contested_unique_index() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -256,6 +256,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -290,8 +291,8 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn test_data_contract_creation_with_contested_unique_index_old_version_has_low_fees() { + #[tokio::test] + async fn test_data_contract_creation_with_contested_unique_index_old_version_has_low_fees() { let platform_version = PlatformVersion::get(8).unwrap(); let mut platform = TestPlatformBuilder::new() .with_initial_protocol_version(8) @@ -324,6 +325,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -358,8 +360,8 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn test_dpns_contract_creation_with_contract_id_non_contested() { + #[tokio::test] + async fn test_dpns_contract_creation_with_contract_id_non_contested() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -391,6 +393,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -425,8 +428,9 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn test_data_contract_creation_with_contested_unique_index_and_unique_index_should_fail() { + #[tokio::test] + async fn test_data_contract_creation_with_contested_unique_index_and_unique_index_should_fail() + { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -458,6 +462,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -509,8 +514,8 @@ mod tests { use dpp::data_contract::associated_token::token_perpetual_distribution::TokenPerpetualDistribution; use dpp::data_contract::associated_token::token_perpetual_distribution::v0::TokenPerpetualDistributionV0; use super::*; - #[test] - fn test_data_contract_creation_with_single_token() { + #[tokio::test] + async fn test_data_contract_creation_with_single_token() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -557,6 +562,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -602,8 +608,8 @@ mod tests { assert_eq!(token_balance, None); } - #[test] - fn test_data_contract_creation_with_single_token_and_group() { + #[tokio::test] + async fn test_data_contract_creation_with_single_token_and_group() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -685,6 +691,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -730,8 +737,8 @@ mod tests { assert_eq!(token_balance, None); } - #[test] - fn test_data_contract_creation_with_single_token_with_starting_balance() { + #[tokio::test] + async fn test_data_contract_creation_with_single_token_with_starting_balance() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -776,6 +783,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_id = calculate_token_id(data_contract_id.as_bytes(), 0); @@ -823,8 +831,8 @@ mod tests { assert_eq!(token_balance, Some(base_supply_start_amount)); } - #[test] - fn test_data_contract_creation_with_single_token_setting_burn_of_internal_token_on_nft_purchase_should_be_allowed( + #[tokio::test] + async fn test_data_contract_creation_with_single_token_setting_burn_of_internal_token_on_nft_purchase_should_be_allowed( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -894,6 +902,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract create batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -928,8 +937,8 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn test_data_contract_creation_with_single_token_setting_transfer_on_nft_purchase_with_internal_token_should_be_allowed( + #[tokio::test] + async fn test_data_contract_creation_with_single_token_setting_transfer_on_nft_purchase_with_internal_token_should_be_allowed( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -1001,6 +1010,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract create batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -1035,8 +1045,9 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn test_data_contract_creation_with_single_token_setting_identifier_that_does_exist() { + #[tokio::test] + async fn test_data_contract_creation_with_single_token_setting_identifier_that_does_exist( + ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -1095,6 +1106,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -1140,8 +1152,8 @@ mod tests { assert_eq!(token_balance, Some(100_000)); } - #[test] - fn test_data_contract_creation_with_single_token_setting_transfer_on_nft_purchase_with_external_token_should_be_allowed( + #[tokio::test] + async fn test_data_contract_creation_with_single_token_setting_transfer_on_nft_purchase_with_external_token_should_be_allowed( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -1231,6 +1243,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract create batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -1265,8 +1278,9 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn test_data_contract_creation_with_single_token_with_valid_perpetual_distribution() { + #[tokio::test] + async fn test_data_contract_creation_with_single_token_with_valid_perpetual_distribution( + ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -1332,6 +1346,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_id = calculate_token_id(data_contract_id.as_bytes(), 0); @@ -1385,8 +1400,8 @@ mod tests { use dpp::data_contract::associated_token::token_pre_programmed_distribution::TokenPreProgrammedDistribution; use drive::drive::Drive; - #[test] - fn test_data_contract_pre_programmed_distribution() { + #[tokio::test] + async fn test_data_contract_pre_programmed_distribution() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -1471,6 +1486,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -1568,8 +1584,8 @@ mod tests { use dpp::data_contract::associated_token::token_pre_programmed_distribution::TokenPreProgrammedDistribution; use dpp::data_contract::associated_token::token_pre_programmed_distribution::v0::TokenPreProgrammedDistributionV0; - #[test] - fn test_data_contract_creation_with_single_token_with_starting_balance_over_limit_should_cause_error( + #[tokio::test] + async fn test_data_contract_creation_with_single_token_with_starting_balance_over_limit_should_cause_error( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -1615,6 +1631,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_id = calculate_token_id(data_contract_id.as_bytes(), 0); @@ -1663,8 +1680,9 @@ mod tests { assert_eq!(token_balance, None); } - #[test] - fn test_data_contract_creation_with_single_token_needing_group_that_does_not_exist() { + #[tokio::test] + async fn test_data_contract_creation_with_single_token_needing_group_that_does_not_exist( + ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -1728,6 +1746,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -1775,8 +1794,8 @@ mod tests { assert_eq!(token_balance, None); } - #[test] - fn test_data_contract_creation_with_single_token_setting_main_group_that_does_not_exist( + #[tokio::test] + async fn test_data_contract_creation_with_single_token_setting_main_group_that_does_not_exist( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -1842,6 +1861,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -1889,8 +1909,8 @@ mod tests { assert_eq!(token_balance, None); } - #[test] - fn test_data_contract_creation_with_single_token_setting_authorization_to_non_defined_main_group( + #[tokio::test] + async fn test_data_contract_creation_with_single_token_setting_authorization_to_non_defined_main_group( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -1955,6 +1975,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -2002,8 +2023,8 @@ mod tests { assert_eq!(token_balance, None); } - #[test] - fn test_data_contract_creation_with_single_token_setting_identifier_that_does_not_exist( + #[tokio::test] + async fn test_data_contract_creation_with_single_token_setting_identifier_that_does_not_exist( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -2060,6 +2081,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -2110,8 +2132,8 @@ mod tests { assert_eq!(token_balance, None); } - #[test] - fn test_data_contract_creation_with_single_token_setting_minting_recipient_to_identity_that_does_not_exist( + #[tokio::test] + async fn test_data_contract_creation_with_single_token_setting_minting_recipient_to_identity_that_does_not_exist( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -2159,6 +2181,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -2209,8 +2232,8 @@ mod tests { assert_eq!(token_balance, None); } - #[test] - fn test_data_contract_creation_with_single_token_setting_pre_programmed_distribution_to_identity_that_does_not_exist( + #[tokio::test] + async fn test_data_contract_creation_with_single_token_setting_pre_programmed_distribution_to_identity_that_does_not_exist( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -2294,6 +2317,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -2344,8 +2368,8 @@ mod tests { assert_eq!(token_balance, None); } - #[test] - fn test_data_contract_creation_with_single_token_setting_burn_of_external_token_not_allowed( + #[tokio::test] + async fn test_data_contract_creation_with_single_token_setting_burn_of_external_token_not_allowed( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -2433,6 +2457,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract create batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -2472,8 +2497,8 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn test_data_contract_creation_with_single_token_setting_transfer_of_external_token_that_does_not_exist( + #[tokio::test] + async fn test_data_contract_creation_with_single_token_setting_transfer_of_external_token_that_does_not_exist( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -2548,6 +2573,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract create batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -2585,8 +2611,8 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn test_data_contract_creation_with_single_token_setting_transfer_of_external_token_that_does_not_exist_in_contract_that_does_exist( + #[tokio::test] + async fn test_data_contract_creation_with_single_token_setting_transfer_of_external_token_that_does_not_exist_in_contract_that_does_exist( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -2676,6 +2702,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract create batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -2715,8 +2742,8 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn test_data_contract_creation_with_single_token_with_invalid_perpetual_distribution_should_cause_error( + #[tokio::test] + async fn test_data_contract_creation_with_single_token_with_invalid_perpetual_distribution_should_cause_error( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -2783,6 +2810,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_id = calculate_token_id(data_contract_id.as_bytes(), 0); @@ -2833,8 +2861,8 @@ mod tests { assert_eq!(token_balance, None); } - #[test] - fn test_data_contract_creation_with_single_token_with_random_perpetual_distribution_should_cause_error( + #[tokio::test] + async fn test_data_contract_creation_with_single_token_with_random_perpetual_distribution_should_cause_error( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -2891,6 +2919,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let token_id = calculate_token_id(data_contract_id.as_bytes(), 0); @@ -2943,8 +2972,8 @@ mod tests { mod group_errors { use super::*; - #[test] - fn test_data_contract_creation_with_non_contiguous_groups_should_error() { + #[tokio::test] + async fn test_data_contract_creation_with_non_contiguous_groups_should_error() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -3025,6 +3054,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -3074,8 +3104,8 @@ mod tests { assert_eq!(token_balance, None); } - #[test] - fn test_data_contract_creation_with_group_with_member_with_zero_power_should_error() { + #[tokio::test] + async fn test_data_contract_creation_with_group_with_member_with_zero_power_should_error() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -3155,6 +3185,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -3202,8 +3233,8 @@ mod tests { assert_eq!(token_balance, None); } - #[test] - fn test_data_contract_creation_with_group_with_single_member_should_error() { + #[tokio::test] + async fn test_data_contract_creation_with_group_with_single_member_should_error() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -3267,6 +3298,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -3314,8 +3346,9 @@ mod tests { assert_eq!(token_balance, None); } - #[test] - fn test_data_contract_creation_with_group_with_member_with_too_big_power_should_error() { + #[tokio::test] + async fn test_data_contract_creation_with_group_with_member_with_too_big_power_should_error( + ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -3395,6 +3428,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -3442,8 +3476,8 @@ mod tests { assert_eq!(token_balance, None); } - #[test] - fn test_data_contract_creation_with_group_with_member_with_power_over_required_should_error( + #[tokio::test] + async fn test_data_contract_creation_with_group_with_member_with_power_over_required_should_error( ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -3524,6 +3558,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -3571,8 +3606,8 @@ mod tests { assert_eq!(token_balance, None); } - #[test] - fn test_dcc_group_with_member_power_not_reaching_threshold() { + #[tokio::test] + async fn test_dcc_group_with_member_power_not_reaching_threshold() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -3652,6 +3687,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -3699,8 +3735,8 @@ mod tests { assert_eq!(token_balance, None); } - #[test] - fn test_dcc_group_with_non_unilateral_member_power_not_reaching_threshold() { + #[tokio::test] + async fn test_dcc_group_with_non_unilateral_member_power_not_reaching_threshold() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -3780,6 +3816,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -3842,8 +3879,8 @@ mod tests { drive::document::query::QueryDocumentsOutcomeV0Methods, query::DriveDocumentQuery, }; - #[test] - fn test_data_contract_creation_fails_with_more_than_fifty_keywords() { + #[tokio::test] + async fn test_data_contract_creation_fails_with_more_than_fifty_keywords() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -3892,6 +3929,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract transition"); // Serialize the transition @@ -3924,8 +3962,8 @@ mod tests { ); } - #[test] - fn test_data_contract_creation_fails_with_duplicate_keywords() { + #[tokio::test] + async fn test_data_contract_creation_fails_with_duplicate_keywords() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -3976,6 +4014,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract transition"); // Serialize the transition @@ -4008,8 +4047,8 @@ mod tests { ); } - #[test] - fn test_data_contract_creation_fails_with_keyword_too_short() { + #[tokio::test] + async fn test_data_contract_creation_fails_with_keyword_too_short() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -4054,6 +4093,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create transition"); // Process @@ -4084,8 +4124,8 @@ mod tests { ); } - #[test] - fn test_data_contract_creation_fails_with_keyword_too_long() { + #[tokio::test] + async fn test_data_contract_creation_fails_with_keyword_too_long() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -4125,6 +4165,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -4153,8 +4194,8 @@ mod tests { ); } - #[test] - fn test_data_contract_creation_succeeds_with_valid_keywords() { + #[tokio::test] + async fn test_data_contract_creation_succeeds_with_valid_keywords() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -4205,6 +4246,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract transition"); // Serialize the transition @@ -4354,8 +4396,8 @@ mod tests { contract_value } - #[test] - fn test_data_contract_creation_fails_with_description_too_short() { + #[tokio::test] + async fn test_data_contract_creation_fails_with_description_too_short() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -4381,6 +4423,7 @@ mod tests { platform_version, None, ) + .await .expect("expected to create transition"); let serialized = transition @@ -4409,8 +4452,8 @@ mod tests { ); } - #[test] - fn test_data_contract_creation_fails_with_description_too_long() { + #[tokio::test] + async fn test_data_contract_creation_fails_with_description_too_long() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -4438,6 +4481,7 @@ mod tests { platform_version, None, ) + .await .expect("expected to create transition"); let serialized = transition @@ -4466,8 +4510,8 @@ mod tests { ); } - #[test] - fn test_data_contract_creation_succeeds_with_valid_description() { + #[tokio::test] + async fn test_data_contract_creation_succeeds_with_valid_description() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -4493,6 +4537,7 @@ mod tests { platform_version, None, ) + .await .expect("expected to create transition"); let serialized = transition @@ -4647,8 +4692,8 @@ mod tests { use dpp::tests::json_document::json_document_to_contract_with_ids; use platform_version::version::PlatformVersion; - #[test] - fn test_data_contract_creation_with_creator_id_index() { + #[tokio::test] + async fn test_data_contract_creation_with_creator_id_index() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -4677,6 +4722,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -4711,8 +4757,9 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn test_data_contract_creation_with_creator_id_index_not_available_on_protocol_version_9() { + #[tokio::test] + async fn test_data_contract_creation_with_creator_id_index_not_available_on_protocol_version_9( + ) { let platform_version = PlatformVersion::get(9).unwrap(); let mut platform = TestPlatformBuilder::new() .with_initial_protocol_version(9) @@ -4742,6 +4789,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_create_serialized_transition = data_contract_create_transition @@ -4780,8 +4828,8 @@ mod tests { } } - #[test] - fn test_data_contract_creation_with_countable_index() { + #[tokio::test] + async fn test_data_contract_creation_with_countable_index() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -4813,6 +4861,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract create transition"); let data_contract_create_serialized_transition = data_contract_create_transition diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs index 36d429bf4dd..f373bc03fb5 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs @@ -615,8 +615,8 @@ mod tests { } } - #[test] - fn test_data_contract_update_changing_various_document_type_options() { + #[tokio::test] + async fn test_data_contract_update_changing_various_document_type_options() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -674,6 +674,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let data_contract_update_serialized_transition = data_contract_update_transition @@ -724,8 +725,8 @@ mod tests { use super::*; use crate::platform_types::state_transitions_processing_result::StateTransitionExecutionResult::UnpaidConsensusError; - #[test] - fn test_data_contract_update_can_not_remove_groups() { + #[tokio::test] + async fn test_data_contract_update_can_not_remove_groups() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -798,6 +799,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract update transition"); let data_contract_update_serialized_transition = data_contract_update_transition @@ -850,8 +852,8 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn test_data_contract_update_can_not_alter_group() { + #[tokio::test] + async fn test_data_contract_update_can_not_alter_group() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -930,6 +932,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract update transition"); let data_contract_update_serialized_transition = data_contract_update_transition @@ -982,8 +985,8 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn test_data_contract_update_can_not_add_new_group_with_gap() { + #[tokio::test] + async fn test_data_contract_update_can_not_add_new_group_with_gap() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -1060,6 +1063,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract update transition"); let data_contract_update_serialized_transition = data_contract_update_transition @@ -1096,8 +1100,8 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn test_data_contract_update_can_add_new_group() { + #[tokio::test] + async fn test_data_contract_update_can_add_new_group() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -1193,6 +1197,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract update transition"); let data_contract_update_serialized_transition = data_contract_update_transition @@ -1252,8 +1257,8 @@ mod tests { use dpp::state_transition::proof_result::StateTransitionProofResult; use drive::drive::Drive; - #[test] - fn test_data_contract_update_can_add_new_token() { + #[tokio::test] + async fn test_data_contract_update_can_add_new_token() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -1321,6 +1326,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract update transition"); let tx_bytes = data_contract_update_transition @@ -1375,8 +1381,8 @@ mod tests { assert_matches!(result, StateTransitionProofResult::VerifiedDataContract(_)); } - #[test] - fn test_data_contract_update_with_token_setting_identifier_that_does_exist() { + #[tokio::test] + async fn test_data_contract_update_with_token_setting_identifier_that_does_exist() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -1445,6 +1451,7 @@ mod tests { platform_version, None, ) + .await .expect("expected update transition"); let serialized = transition.serialize_to_bytes().expect("serialize"); @@ -1475,8 +1482,8 @@ mod tests { .unwrap() .expect("commit"); } - #[test] - fn test_data_contract_update_with_token_setting_identifier_that_does_not_exist() { + #[tokio::test] + async fn test_data_contract_update_with_token_setting_identifier_that_does_not_exist() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -1545,6 +1552,7 @@ mod tests { platform_version, None, ) + .await .expect("expected update transition"); let serialized = transition.serialize_to_bytes().expect("serialize"); @@ -1581,8 +1589,8 @@ mod tests { .expect("commit"); } - #[test] - fn test_data_contract_update_can_not_add_new_token_with_gap() { + #[tokio::test] + async fn test_data_contract_update_can_not_add_new_token_with_gap() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -1651,6 +1659,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract update transition"); let tx_bytes = data_contract_update_transition @@ -1686,8 +1695,8 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn test_data_contract_update_can_not_add_new_token_with_large_base_supply() { + #[tokio::test] + async fn test_data_contract_update_can_not_add_new_token_with_large_base_supply() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -1738,6 +1747,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract update transition"); let tx_bytes = data_contract_update_transition @@ -1773,8 +1783,8 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn test_data_contract_update_can_not_add_new_token_with_invalid_localization() { + #[tokio::test] + async fn test_data_contract_update_can_not_add_new_token_with_invalid_localization() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -1833,6 +1843,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract update transition"); let tx_bytes = data_contract_update_transition @@ -1868,8 +1879,8 @@ mod tests { .expect("expected to commit transaction"); } - #[test] - fn update_token_with_missing_main_group_should_fail() { + #[tokio::test] + async fn update_token_with_missing_main_group_should_fail() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -1932,6 +1943,7 @@ mod tests { platform_version, None, ) + .await .unwrap(); let tx = platform.drive.grove.start_transaction(); let result = platform @@ -1955,8 +1967,8 @@ mod tests { ); } - #[test] - fn update_token_with_invalid_distribution_function_should_fail() { + #[tokio::test] + async fn update_token_with_invalid_distribution_function_should_fail() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -2032,6 +2044,7 @@ mod tests { platform_version, None, ) + .await .unwrap(); let tx = platform.drive.grove.start_transaction(); let result = platform @@ -2055,8 +2068,8 @@ mod tests { ); } - #[test] - fn update_token_with_random_distribution_should_fail() { + #[tokio::test] + async fn update_token_with_random_distribution_should_fail() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -2122,6 +2135,7 @@ mod tests { platform_version, None, ) + .await .unwrap(); let tx = platform.drive.grove.start_transaction(); let result = platform @@ -2145,8 +2159,8 @@ mod tests { ); } - #[test] - fn update_token_overwriting_existing_position_should_fail() { + #[tokio::test] + async fn update_token_overwriting_existing_position_should_fail() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -2218,6 +2232,7 @@ mod tests { platform_version, None, ) + .await .unwrap(); let tx = platform.drive.grove.start_transaction(); let result = platform @@ -2244,8 +2259,8 @@ mod tests { ); } - #[test] - fn test_data_contract_update_token_without_minting_destination_should_fail() { + #[tokio::test] + async fn test_data_contract_update_token_without_minting_destination_should_fail() { let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_initial_state_structure(); @@ -2330,6 +2345,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create data contract update transition"); let tx_bytes = data_contract_update_transition @@ -2393,7 +2409,7 @@ mod tests { /// Creates a contract with the supplied keywords and commits it to Drive. /// Returns `(contract_id, create_transition)`. - fn create_contract_with_keywords( + async fn create_contract_with_keywords( platform: &mut TempPlatform, identity: &Identity, signer: &SimpleSigner, @@ -2431,6 +2447,7 @@ mod tests { platform_version, None, ) + .await .expect("create transition"); let tx_bytes = create.serialize_to_bytes().expect("serialize"); @@ -2482,7 +2499,7 @@ mod tests { /// Convenience for building and applying an **update** transition that /// only changes the `keywords` array. - fn apply_keyword_update( + async fn apply_keyword_update( platform: &mut TempPlatform, contract_id: Identifier, identity: &Identity, @@ -2522,6 +2539,7 @@ mod tests { platform_version, None, ) + .await .expect("build update"); let bytes = update.serialize_to_bytes().unwrap(); @@ -2608,8 +2626,8 @@ mod tests { macro_rules! invalid_update_test { ($name:ident, $keywords:expr, $error:pat_param) => { - #[test] - fn $name() { + #[tokio::test] + async fn $name() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -2626,7 +2644,8 @@ mod tests { &key, &["orig"], &platform_version, - ); + ) + .await; // try invalid update let err = apply_keyword_update( @@ -2638,6 +2657,7 @@ mod tests { &$keywords, &platform_version, ) + .await .unwrap_err(); assert_matches!( @@ -2689,8 +2709,8 @@ mod tests { // positive case – old docs removed, new docs inserted // ──────────────────────────────────────────────────────────────────────── - #[test] - fn update_keywords_replaces_search_docs() { + #[tokio::test] + async fn update_keywords_replaces_search_docs() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -2706,7 +2726,8 @@ mod tests { &key, &["old1", "old2"], platform_version, - ); + ) + .await; // verify initial docs let initial_docs = keyword_docs_for_contract(&platform, cid, &platform_version); @@ -2722,6 +2743,7 @@ mod tests { &["newA", "newB", "newC"], platform_version, ) + .await .expect("update should succeed"); // fetch contract – keywords updated? @@ -2779,7 +2801,7 @@ mod tests { /// Creates a contract with the supplied description and commits it to Drive. /// Returns `(contract_id, create_transition)`. - fn create_contract_with_description( + async fn create_contract_with_description( platform: &mut TempPlatform, identity: &Identity, signer: &SimpleSigner, @@ -2812,6 +2834,7 @@ mod tests { platform_version, None, ) + .await .expect("create transition"); let tx_bytes = create.serialize_to_bytes().expect("serialize"); @@ -2863,7 +2886,7 @@ mod tests { /// Convenience for building and applying an **update** transition that /// only changes the `description` string. - fn apply_description_update( + async fn apply_description_update( platform: &mut TempPlatform, contract_id: Identifier, identity: &Identity, @@ -2898,6 +2921,7 @@ mod tests { platform_version, None, ) + .await .expect("build update"); let bytes = update.serialize_to_bytes().unwrap(); @@ -2991,8 +3015,8 @@ mod tests { macro_rules! invalid_update_test { ($name:ident, $description:expr, $error:pat_param) => { - #[test] - fn $name() { + #[tokio::test] + async fn $name() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -3009,7 +3033,8 @@ mod tests { &key, &"orig", &platform_version, - ); + ) + .await; // try invalid update let err = apply_description_update( @@ -3021,6 +3046,7 @@ mod tests { &$description, &platform_version, ) + .await .unwrap_err(); assert_matches!( @@ -3054,8 +3080,8 @@ mod tests { // positive case – old docs removed, new docs inserted // ──────────────────────────────────────────────────────────────────────── - #[test] - fn update_description_replaces_search_docs() { + #[tokio::test] + async fn update_description_replaces_search_docs() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() @@ -3071,7 +3097,8 @@ mod tests { &key, "old1", platform_version, - ); + ) + .await; // verify initial docs let initial_docs = description_docs_for_contract(&platform, cid, platform_version); @@ -3087,6 +3114,7 @@ mod tests { "newA", platform_version, ) + .await .expect("update should succeed"); // fetch contract – description updated? diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/mod.rs index 34b17fd0adc..3ad20f558cf 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/mod.rs @@ -217,8 +217,8 @@ mod tests { use std::collections::BTreeMap; use std::ops::Div; - #[test] - fn test_identity_create_validation_first_protocol_version() { + #[tokio::test] + async fn test_identity_create_validation_first_protocol_version() { let platform_version = PlatformVersion::first(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -290,6 +290,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -331,8 +332,8 @@ mod tests { assert_eq!(identity_balance, 99913915760); } - #[test] - fn test_identity_create_validation_latest_protocol_version() { + #[tokio::test] + async fn test_identity_create_validation_latest_protocol_version() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -403,6 +404,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -444,8 +446,8 @@ mod tests { assert_eq!(identity_balance, 99913867460); } - #[test] - fn test_identity_create_asset_lock_reuse_after_issue_first_protocol_version() { + #[tokio::test] + async fn test_identity_create_asset_lock_reuse_after_issue_first_protocol_version() { let platform_version = PlatformVersion::first(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -558,6 +560,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -622,6 +625,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -667,8 +671,8 @@ mod tests { assert_eq!(identity_balance, 99909310400); // The identity balance is smaller than if there hadn't been any issue } - #[test] - fn test_identity_create_asset_lock_reuse_after_issue_latest_protocol_version() { + #[tokio::test] + async fn test_identity_create_asset_lock_reuse_after_issue_latest_protocol_version() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -780,6 +784,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -844,6 +849,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -889,8 +895,8 @@ mod tests { assert_eq!(identity_balance, 99909262100); // The identity balance is smaller than if there hadn't been any issue } - #[test] - fn test_identity_create_asset_lock_reuse_after_max_issues() { + #[tokio::test] + async fn test_identity_create_asset_lock_reuse_after_max_issues() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1013,6 +1019,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -1080,6 +1087,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -1117,8 +1125,8 @@ mod tests { .expect("expected to commit"); } - #[test] - fn test_identity_create_asset_lock_use_all_funds() { + #[tokio::test] + async fn test_identity_create_asset_lock_use_all_funds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1247,6 +1255,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -1314,6 +1323,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -1351,8 +1361,8 @@ mod tests { .expect("expected to commit"); } - #[test] - fn test_identity_create_asset_lock_replay_attack_first_protocol_version() { + #[tokio::test] + async fn test_identity_create_asset_lock_replay_attack_first_protocol_version() { let platform_version = PlatformVersion::first(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1465,6 +1475,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -1554,6 +1565,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -1599,8 +1611,8 @@ mod tests { assert_eq!(identity_balance, 99909310400); // The identity balance is smaller than if there hadn't been any issue } - #[test] - fn test_identity_create_asset_lock_replay_attack_latest_protocol_version() { + #[tokio::test] + async fn test_identity_create_asset_lock_replay_attack_latest_protocol_version() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1712,6 +1724,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition @@ -1801,6 +1814,7 @@ mod tests { 0, platform_version, ) + .await .expect("expected an identity create transition"); let identity_create_serialized_transition = identity_create_transition diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create_from_addresses/tests.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create_from_addresses/tests.rs index 8544139cf3a..158c4263aa0 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create_from_addresses/tests.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create_from_addresses/tests.rs @@ -149,7 +149,7 @@ mod tests { } /// Create a signed IdentityCreateFromAddressesTransition using the proper method - fn create_signed_identity_create_from_addresses_transition( + async fn create_signed_identity_create_from_addresses_transition( identity: &Identity, address_signer: &TestAddressSigner, identity_signer: &SimpleSigner, @@ -171,11 +171,12 @@ mod tests { 0, // user_fee_increase platform_version, ) + .await .expect("should create transition") } /// Create a signed identity create from addresses transition with optional output - fn create_signed_identity_create_from_addresses_transition_with_output( + async fn create_signed_identity_create_from_addresses_transition_with_output( identity: &Identity, address_signer: &TestAddressSigner, identity_signer: &SimpleSigner, @@ -217,26 +218,28 @@ mod tests { if public_key.key_type().is_unique_key_type() { let signature = identity_signer .sign(public_key, &signable_bytes) + .await .expect("should sign"); public_key_in_creation.set_signature(signature); } } // Create witnesses for each input address - transition.input_witnesses = inputs - .keys() - .map(|address| { - address_signer - .sign_create_witness(address, &signable_bytes) - .expect("should create witness") - }) - .collect(); + let mut witnesses = Vec::with_capacity(inputs.len()); + for address in inputs.keys() { + let witness = address_signer + .sign_create_witness(address, &signable_bytes) + .await + .expect("should create witness"); + witnesses.push(witness); + } + transition.input_witnesses = witnesses; transition.into() } /// Create a signed identity create from addresses transition with output and fee strategy - fn create_signed_identity_create_from_addresses_transition_full( + async fn create_signed_identity_create_from_addresses_transition_full( identity: &Identity, address_signer: &TestAddressSigner, identity_signer: &SimpleSigner, @@ -277,20 +280,22 @@ mod tests { if public_key.key_type().is_unique_key_type() { let signature = identity_signer .sign(public_key, &signable_bytes) + .await .expect("should sign"); public_key_in_creation.set_signature(signature); } } // Create witnesses for each input address - transition.input_witnesses = inputs - .keys() - .map(|address| { - address_signer - .sign_create_witness(address, &signable_bytes) - .expect("should create witness") - }) - .collect(); + let mut witnesses = Vec::with_capacity(inputs.len()); + for address in inputs.keys() { + let witness = address_signer + .sign_create_witness(address, &signable_bytes) + .await + .expect("should create witness"); + witnesses.push(witness); + } + transition.input_witnesses = witnesses; transition.into() } @@ -318,8 +323,8 @@ mod tests { mod structure_validation { use super::*; - #[test] - fn test_no_inputs_returns_error() { + #[tokio::test] + async fn test_no_inputs_returns_error() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(567); @@ -379,8 +384,8 @@ mod tests { ); } - #[test] - fn test_no_public_keys_returns_error() { + #[tokio::test] + async fn test_no_public_keys_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -425,14 +430,15 @@ mod tests { // Create witnesses for each input address let mut transition = transition; - transition.input_witnesses = inputs - .keys() - .map(|addr| { - address_signer - .sign_create_witness(addr, &signable_bytes) - .expect("should create witness") - }) - .collect(); + let mut witnesses = Vec::with_capacity(inputs.len()); + for addr in inputs.keys() { + let witness = address_signer + .sign_create_witness(addr, &signable_bytes) + .await + .expect("should create witness"); + witnesses.push(witness); + } + transition.input_witnesses = witnesses; let state_transition: StateTransition = transition.into(); let raw_tx = state_transition @@ -450,8 +456,8 @@ mod tests { ); } - #[test] - fn test_too_many_inputs_returns_error() { + #[tokio::test] + async fn test_too_many_inputs_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -497,7 +503,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); @@ -511,8 +518,8 @@ mod tests { ); } - #[test] - fn test_input_witness_count_mismatch_returns_error() { + #[tokio::test] + async fn test_input_witness_count_mismatch_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -579,6 +586,7 @@ mod tests { if public_key.key_type().is_unique_key_type() { let signature = identity_signer .sign(public_key, &signable_bytes) + .await .expect("should sign"); public_key_in_creation.set_signature(signature); } @@ -587,6 +595,7 @@ mod tests { // Only create 1 witness for 2 inputs (this is the mismatch!) transition.input_witnesses = vec![address_signer .sign_create_witness(&address1, &signable_bytes) + .await .expect("should create witness")]; let state_transition: StateTransition = transition.into(); @@ -609,8 +618,8 @@ mod tests { ); } - #[test] - fn test_input_below_minimum_returns_error() { + #[tokio::test] + async fn test_input_below_minimum_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -650,7 +659,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); @@ -664,8 +674,8 @@ mod tests { ); } - #[test] - fn test_output_address_same_as_input_returns_error() { + #[tokio::test] + async fn test_output_address_same_as_input_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -703,7 +713,8 @@ mod tests { inputs, Some((address, dash_to_credits!(0.1))), platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); @@ -717,8 +728,8 @@ mod tests { ); } - #[test] - fn test_output_below_minimum_returns_error() { + #[tokio::test] + async fn test_output_below_minimum_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -757,7 +768,8 @@ mod tests { inputs, Some((output_address, 100)), platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); @@ -771,8 +783,8 @@ mod tests { ); } - #[test] - fn test_empty_fee_strategy_returns_error() { + #[tokio::test] + async fn test_empty_fee_strategy_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -811,7 +823,8 @@ mod tests { None, AddressFundsFeeStrategy::from(vec![]), platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); @@ -825,8 +838,8 @@ mod tests { ); } - #[test] - fn test_fee_strategy_index_out_of_bounds_returns_error() { + #[tokio::test] + async fn test_fee_strategy_index_out_of_bounds_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -867,7 +880,8 @@ mod tests { 5, )]), platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); @@ -881,8 +895,8 @@ mod tests { ); } - #[test] - fn test_inputs_not_covering_minimum_identity_funding_returns_error() { + #[tokio::test] + async fn test_inputs_not_covering_minimum_identity_funding_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -938,7 +952,8 @@ mod tests { inputs, Some((output_address, min_output)), platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); @@ -965,8 +980,8 @@ mod tests { mod successful_transitions { use super::*; - #[test] - fn test_simple_identity_create_from_single_address() { + #[tokio::test] + async fn test_simple_identity_create_from_single_address() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1013,7 +1028,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1039,8 +1055,8 @@ mod tests { ); } - #[test] - fn test_identity_create_from_multiple_addresses() { + #[tokio::test] + async fn test_identity_create_from_multiple_addresses() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1112,7 +1128,8 @@ mod tests { None, Some(fee_strategy), platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1138,8 +1155,8 @@ mod tests { ); } - #[test] - fn test_identity_create_with_maximum_allowed_inputs() { + #[tokio::test] + async fn test_identity_create_with_maximum_allowed_inputs() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1217,7 +1234,8 @@ mod tests { None, Some(fee_strategy), platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1252,8 +1270,8 @@ mod tests { mod state_verification { use super::*; - #[test] - fn test_identity_created_with_correct_balance() { + #[tokio::test] + async fn test_identity_created_with_correct_balance() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1300,7 +1318,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1361,8 +1380,8 @@ mod tests { ); } - #[test] - fn test_input_address_balance_decreases_after_identity_creation() { + #[tokio::test] + async fn test_input_address_balance_decreases_after_identity_creation() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1418,7 +1437,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1467,8 +1487,8 @@ mod tests { } } - #[test] - fn test_identity_has_correct_public_keys() { + #[tokio::test] + async fn test_identity_has_correct_public_keys() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1515,7 +1535,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1588,8 +1609,8 @@ mod tests { mod state_validation { use super::*; - #[test] - fn test_address_does_not_exist_returns_error() { + #[tokio::test] + async fn test_address_does_not_exist_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1630,7 +1651,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1659,8 +1681,8 @@ mod tests { ); } - #[test] - fn test_insufficient_address_balance_returns_error() { + #[tokio::test] + async fn test_insufficient_address_balance_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1705,7 +1727,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1734,8 +1757,8 @@ mod tests { ); } - #[test] - fn test_invalid_address_nonce_returns_error() { + #[tokio::test] + async fn test_invalid_address_nonce_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1782,7 +1805,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1823,8 +1847,8 @@ mod tests { // // The duplicate test `test_duplicate_public_key_in_state_returns_error` exists below // and properly tests duplicate public keys in state. - #[test] - fn test_identity_keys_already_exist_returns_error() { + #[tokio::test] + async fn test_identity_keys_already_exist_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1875,7 +1899,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result1 = transition1.serialize_to_bytes().expect("should serialize"); @@ -1926,7 +1951,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result2 = transition2.serialize_to_bytes().expect("should serialize"); @@ -1960,8 +1986,8 @@ mod tests { ); } - #[test] - fn test_duplicate_public_key_in_state_returns_error() { + #[tokio::test] + async fn test_duplicate_public_key_in_state_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2012,7 +2038,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result1 = transition1.serialize_to_bytes().expect("should serialize"); @@ -2068,7 +2095,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result2 = transition2.serialize_to_bytes().expect("should serialize"); @@ -2108,8 +2136,8 @@ mod tests { mod signature_validation { use super::*; - #[test] - fn test_invalid_address_witness_returns_error() { + #[tokio::test] + async fn test_invalid_address_witness_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2200,8 +2228,8 @@ mod tests { mod edge_cases { use super::*; - #[test] - fn test_minimum_valid_input_amount() { + #[tokio::test] + async fn test_minimum_valid_input_amount() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2271,7 +2299,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2300,8 +2329,8 @@ mod tests { // The identity funding amount should be the input amount minus the processing fees } - #[test] - fn test_check_tx_rejects_invalid_transition() { + #[tokio::test] + async fn test_check_tx_rejects_invalid_transition() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2339,8 +2368,8 @@ mod tests { assert!(!is_valid, "check_tx should reject invalid transition"); } - #[test] - fn test_check_tx_accepts_valid_transition() { + #[tokio::test] + async fn test_check_tx_accepts_valid_transition() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2387,7 +2416,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2405,8 +2435,8 @@ mod tests { mod additional_structure_validation { use super::*; - #[test] - fn test_too_many_public_keys_returns_error() { + #[tokio::test] + async fn test_too_many_public_keys_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2471,14 +2501,15 @@ mod tests { // Create witnesses let mut transition = transition; - transition.input_witnesses = inputs - .keys() - .map(|addr| { - address_signer - .sign_create_witness(addr, &signable_bytes) - .expect("should create witness") - }) - .collect(); + let mut witnesses = Vec::with_capacity(inputs.len()); + for addr in inputs.keys() { + let witness = address_signer + .sign_create_witness(addr, &signable_bytes) + .await + .expect("should create witness"); + witnesses.push(witness); + } + transition.input_witnesses = witnesses; let state_transition: StateTransition = transition.into(); let raw_tx = state_transition @@ -2495,8 +2526,8 @@ mod tests { ); } - #[test] - fn test_fee_strategy_too_many_steps_returns_error() { + #[tokio::test] + async fn test_fee_strategy_too_many_steps_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2548,7 +2579,8 @@ mod tests { None, AddressFundsFeeStrategy::from(fee_steps), platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); @@ -2562,8 +2594,8 @@ mod tests { ); } - #[test] - fn test_fee_strategy_duplicate_returns_error() { + #[tokio::test] + async fn test_fee_strategy_duplicate_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2605,7 +2637,8 @@ mod tests { AddressFundsFeeStrategyStep::DeductFromInput(0), // Duplicate ]), platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); @@ -2619,8 +2652,8 @@ mod tests { ); } - #[test] - fn test_reduce_output_index_out_of_bounds_no_output_returns_error() { + #[tokio::test] + async fn test_reduce_output_index_out_of_bounds_no_output_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2659,7 +2692,8 @@ mod tests { None, // No output AddressFundsFeeStrategy::from(vec![AddressFundsFeeStrategyStep::ReduceOutput(0)]), platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); @@ -2673,8 +2707,8 @@ mod tests { ); } - #[test] - fn test_reduce_output_index_out_of_bounds_with_output_returns_error() { + #[tokio::test] + async fn test_reduce_output_index_out_of_bounds_with_output_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2714,7 +2748,8 @@ mod tests { Some((output_address, dash_to_credits!(0.1))), AddressFundsFeeStrategy::from(vec![AddressFundsFeeStrategyStep::ReduceOutput(1)]), // Index 1 doesn't exist platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); @@ -2728,8 +2763,8 @@ mod tests { ); } - #[test] - fn test_valid_reduce_output_fee_strategy() { + #[tokio::test] + async fn test_valid_reduce_output_fee_strategy() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2776,7 +2811,8 @@ mod tests { inputs, Some((output_address, dash_to_credits!(0.5))), platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2804,8 +2840,8 @@ mod tests { ); } - #[test] - fn test_multiple_fee_strategy_steps_valid() { + #[tokio::test] + async fn test_multiple_fee_strategy_steps_valid() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2855,7 +2891,8 @@ mod tests { AddressFundsFeeStrategyStep::ReduceOutput(0), ]), platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); let check_result = run_check_tx(&platform, &raw_tx, platform_version); @@ -2867,8 +2904,8 @@ mod tests { ); } - #[test] - fn test_input_amounts_very_high_should_succeed() { + #[tokio::test] + async fn test_input_amounts_very_high_should_succeed() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2918,7 +2955,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); let check_result = run_check_tx(&platform, &raw_tx, platform_version); @@ -2926,8 +2964,8 @@ mod tests { assert!(check_result.is_valid()); } - #[test] - fn test_valid_structure_with_output() { + #[tokio::test] + async fn test_valid_structure_with_output() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2974,7 +3012,8 @@ mod tests { inputs, Some((output_address, dash_to_credits!(0.5))), platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3002,8 +3041,8 @@ mod tests { ); } - #[test] - fn test_exactly_maximum_inputs_is_valid() { + #[tokio::test] + async fn test_exactly_maximum_inputs_is_valid() { let platform_version = PlatformVersion::latest(); let max_inputs = platform_version.dpp.state_transitions.max_address_inputs as usize; @@ -3047,7 +3086,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); let check_result = run_check_tx(&platform, &raw_tx, platform_version); @@ -3059,8 +3099,8 @@ mod tests { ); } - #[test] - fn test_single_minimum_input_amount_fails_due_to_insufficient_funding() { + #[tokio::test] + async fn test_single_minimum_input_amount_fails_due_to_insufficient_funding() { // A single input at min_input_amount (100k) fails because identity creation // requires at least min_identity_funding_amount (200k) worth of credits. let platform_version = PlatformVersion::latest(); @@ -3108,7 +3148,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); let check_result = run_check_tx(&platform, &raw_tx, platform_version); @@ -3123,8 +3164,8 @@ mod tests { ); } - #[test] - fn test_two_minimum_inputs_meet_identity_funding_requirement() { + #[tokio::test] + async fn test_two_minimum_inputs_meet_identity_funding_requirement() { // Two inputs at min_input_amount (100k each = 200k total) should succeed // because it meets min_identity_funding_amount (200k). let platform_version = PlatformVersion::latest(); @@ -3184,7 +3225,8 @@ mod tests { AddressFundsFeeStrategyStep::DeductFromInput(address1_index), ])), platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3212,8 +3254,8 @@ mod tests { ); } - #[test] - fn test_exactly_minimum_output_amount_is_valid() { + #[tokio::test] + async fn test_exactly_minimum_output_amount_is_valid() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3260,7 +3302,8 @@ mod tests { inputs, Some((output_address, min_output)), platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); let check_result = run_check_tx(&platform, &raw_tx, platform_version); @@ -3272,8 +3315,8 @@ mod tests { ); } - #[test] - fn test_one_below_minimum_input_returns_error() { + #[tokio::test] + async fn test_one_below_minimum_input_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3319,7 +3362,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); let check_result = run_check_tx(&platform, &raw_tx, platform_version); @@ -3333,8 +3377,8 @@ mod tests { ); } - #[test] - fn test_one_below_minimum_output_returns_error() { + #[tokio::test] + async fn test_one_below_minimum_output_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3381,7 +3425,8 @@ mod tests { inputs, Some((output_address, min_output - 1)), platform_version, - ); + ) + .await; let raw_tx = transition.serialize_to_bytes().expect("should serialize"); let check_result = run_check_tx(&platform, &raw_tx, platform_version); @@ -3404,8 +3449,8 @@ mod tests { mod p2sh_multisig_tests { use super::*; - #[test] - fn test_p2sh_multisig_address_structure_validation() { + #[tokio::test] + async fn test_p2sh_multisig_address_structure_validation() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -3460,8 +3505,8 @@ mod tests { ); } - #[test] - fn test_mixed_p2pkh_and_p2sh_addresses_structure() { + #[tokio::test] + async fn test_mixed_p2pkh_and_p2sh_addresses_structure() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -3525,8 +3570,8 @@ mod tests { mod public_key_validation { use super::*; - #[test] - fn test_single_master_key_is_valid() { + #[tokio::test] + async fn test_single_master_key_is_valid() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3572,7 +3617,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3600,8 +3646,8 @@ mod tests { ); } - #[test] - fn test_multiple_public_keys_is_valid() { + #[tokio::test] + async fn test_multiple_public_keys_is_valid() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3647,7 +3693,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3675,8 +3722,8 @@ mod tests { ); } - #[test] - fn test_exactly_max_public_keys_is_valid() { + #[tokio::test] + async fn test_exactly_max_public_keys_is_valid() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3722,7 +3769,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3759,8 +3807,8 @@ mod tests { mod nonce_handling { use super::*; - #[test] - fn test_zero_nonce_is_valid_structure() { + #[tokio::test] + async fn test_zero_nonce_is_valid_structure() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -3796,8 +3844,8 @@ mod tests { ); } - #[test] - fn test_high_nonce_is_valid_structure() { + #[tokio::test] + async fn test_high_nonce_is_valid_structure() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -3832,8 +3880,8 @@ mod tests { ); } - #[test] - fn test_multiple_inputs_different_nonces_valid_structure() { + #[tokio::test] + async fn test_multiple_inputs_different_nonces_valid_structure() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -3884,8 +3932,8 @@ mod tests { mod user_fee_increase { use super::*; - #[test] - fn test_zero_user_fee_increase() { + #[tokio::test] + async fn test_zero_user_fee_increase() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(1000); @@ -3912,8 +3960,8 @@ mod tests { assert_eq!(state_transition.user_fee_increase(), 0); } - #[test] - fn test_nonzero_user_fee_increase() { + #[tokio::test] + async fn test_nonzero_user_fee_increase() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(1001); @@ -3940,8 +3988,8 @@ mod tests { assert_eq!(state_transition.user_fee_increase(), 100); } - #[test] - fn test_max_user_fee_increase() { + #[tokio::test] + async fn test_max_user_fee_increase() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(1002); @@ -3976,8 +4024,8 @@ mod tests { mod serialization { use super::*; - #[test] - fn test_transition_serializes_and_deserializes() { + #[tokio::test] + async fn test_transition_serializes_and_deserializes() { use dpp::serialization::PlatformDeserializable; let platform_version = PlatformVersion::latest(); @@ -4018,8 +4066,8 @@ mod tests { ); } - #[test] - fn test_transition_with_output_serializes() { + #[tokio::test] + async fn test_transition_with_output_serializes() { use dpp::serialization::PlatformDeserializable; let platform_version = PlatformVersion::latest(); @@ -4056,8 +4104,8 @@ mod tests { assert_eq!(serialized, reserialized); } - #[test] - fn test_transition_with_multiple_inputs_serializes() { + #[tokio::test] + async fn test_transition_with_multiple_inputs_serializes() { use dpp::serialization::PlatformDeserializable; let platform_version = PlatformVersion::latest(); @@ -4110,8 +4158,8 @@ mod tests { use super::*; use dpp::state_transition::StateTransitionLike; - #[test] - fn test_unique_identifiers_contains_all_inputs() { + #[tokio::test] + async fn test_unique_identifiers_contains_all_inputs() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(1200); @@ -4159,8 +4207,8 @@ mod tests { ); } - #[test] - fn test_unique_identifiers_include_nonce() { + #[tokio::test] + async fn test_unique_identifiers_include_nonce() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(1201); @@ -4213,8 +4261,8 @@ mod tests { ); } - #[test] - fn test_unique_identifiers_differ_by_address() { + #[tokio::test] + async fn test_unique_identifiers_differ_by_address() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(1202); @@ -4279,8 +4327,8 @@ mod tests { use super::*; use dpp::state_transition::{StateTransitionLike, StateTransitionType}; - #[test] - fn test_state_transition_type_is_identity_create_from_addresses() { + #[tokio::test] + async fn test_state_transition_type_is_identity_create_from_addresses() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(1300); @@ -4312,8 +4360,8 @@ mod tests { ); } - #[test] - fn test_modified_data_ids_is_empty() { + #[tokio::test] + async fn test_modified_data_ids_is_empty() { use dpp::state_transition::StateTransitionLike; let platform_version = PlatformVersion::latest(); @@ -4354,8 +4402,8 @@ mod tests { use super::*; use dpp::state_transition::StateTransitionIdentityIdFromInputs; - #[test] - fn test_identity_id_is_deterministic() { + #[tokio::test] + async fn test_identity_id_is_deterministic() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(1400); @@ -4403,8 +4451,8 @@ mod tests { assert_eq!(id1, id2, "Same inputs should produce same identity ID"); } - #[test] - fn test_different_inputs_produce_different_identity_id() { + #[tokio::test] + async fn test_different_inputs_produce_different_identity_id() { // Identity ID is derived from INPUTS (addresses and nonces), not public keys. // Different inputs should produce different identity IDs. let platform_version = PlatformVersion::latest(); @@ -4474,8 +4522,8 @@ mod tests { use super::*; use dpp::state_transition::StateTransitionWitnessSigned; - #[test] - fn test_inputs_accessor() { + #[tokio::test] + async fn test_inputs_accessor() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(1500); @@ -4506,8 +4554,8 @@ mod tests { assert_eq!(transition.inputs().len(), 2); } - #[test] - fn test_witnesses_accessor() { + #[tokio::test] + async fn test_witnesses_accessor() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(1501); @@ -4535,8 +4583,8 @@ mod tests { assert_eq!(transition.witnesses().len(), 1); } - #[test] - fn test_set_witnesses() { + #[tokio::test] + async fn test_set_witnesses() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(1502); @@ -4576,8 +4624,8 @@ mod tests { use super::*; use dpp::state_transition::identity_create_from_addresses_transition::accessors::IdentityCreateFromAddressesTransitionAccessorsV0; - #[test] - fn test_public_keys_accessor() { + #[tokio::test] + async fn test_public_keys_accessor() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(1600); @@ -4606,8 +4654,8 @@ mod tests { assert_eq!(transition.public_keys().len(), public_keys_count); } - #[test] - fn test_output_accessor_none() { + #[tokio::test] + async fn test_output_accessor_none() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(1601); @@ -4635,8 +4683,8 @@ mod tests { assert!(transition.output().is_none()); } - #[test] - fn test_output_accessor_some() { + #[tokio::test] + async fn test_output_accessor_some() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(1602); @@ -4671,8 +4719,8 @@ mod tests { assert_eq!(*amount, output_amount); } - #[test] - fn test_fee_strategy_accessor() { + #[tokio::test] + async fn test_fee_strategy_accessor() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(1603); @@ -4711,8 +4759,8 @@ mod tests { mod boundary_values { use super::*; - #[test] - fn test_zero_amount_in_input_returns_error() { + #[tokio::test] + async fn test_zero_amount_in_input_returns_error() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -4752,8 +4800,8 @@ mod tests { ); } - #[test] - fn test_zero_amount_in_output_returns_error() { + #[tokio::test] + async fn test_zero_amount_in_output_returns_error() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -4795,8 +4843,8 @@ mod tests { ); } - #[test] - fn test_max_u64_input_amount() { + #[tokio::test] + async fn test_max_u64_input_amount() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -4830,8 +4878,8 @@ mod tests { ); } - #[test] - fn test_max_u64_output_amount() { + #[tokio::test] + async fn test_max_u64_output_amount() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -4877,8 +4925,8 @@ mod tests { use dpp::identity::KeyType; use dpp::state_transition::public_key_in_creation::accessors::IdentityPublicKeyInCreationV0Getters; - #[test] - fn test_ecdsa_secp256k1_key_structure() { + #[tokio::test] + async fn test_ecdsa_secp256k1_key_structure() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -4922,8 +4970,8 @@ mod tests { ); } - #[test] - fn test_bls_key_structure() { + #[tokio::test] + async fn test_bls_key_structure() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -4971,8 +5019,8 @@ mod tests { ); } - #[test] - fn test_mixed_key_types_structure() { + #[tokio::test] + async fn test_mixed_key_types_structure() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -5035,8 +5083,8 @@ mod tests { mod fee_strategy_combinations { use super::*; - #[test] - fn test_deduct_from_all_inputs() { + #[tokio::test] + async fn test_deduct_from_all_inputs() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -5082,8 +5130,8 @@ mod tests { ); } - #[test] - fn test_reduce_output_only_fee_strategy() { + #[tokio::test] + async fn test_reduce_output_only_fee_strategy() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -5119,8 +5167,8 @@ mod tests { ); } - #[test] - fn test_mixed_deduct_and_reduce_fee_strategy() { + #[tokio::test] + async fn test_mixed_deduct_and_reduce_fee_strategy() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -5163,8 +5211,8 @@ mod tests { ); } - #[test] - fn test_single_fee_strategy_step() { + #[tokio::test] + async fn test_single_fee_strategy_step() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -5208,8 +5256,8 @@ mod tests { mod protocol_version { use super::*; - #[test] - fn test_state_transition_protocol_version() { + #[tokio::test] + async fn test_state_transition_protocol_version() { use dpp::state_transition::StateTransitionLike; let platform_version = PlatformVersion::latest(); @@ -5250,8 +5298,8 @@ mod tests { mod address_types { use super::*; - #[test] - fn test_p2pkh_address_in_input() { + #[tokio::test] + async fn test_p2pkh_address_in_input() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -5287,8 +5335,8 @@ mod tests { ); } - #[test] - fn test_p2sh_address_in_input() { + #[tokio::test] + async fn test_p2sh_address_in_input() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -5324,8 +5372,8 @@ mod tests { ); } - #[test] - fn test_p2pkh_address_in_output() { + #[tokio::test] + async fn test_p2pkh_address_in_output() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -5364,8 +5412,8 @@ mod tests { ); } - #[test] - fn test_p2sh_address_in_output() { + #[tokio::test] + async fn test_p2sh_address_in_output() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -5412,8 +5460,8 @@ mod tests { mod concurrent_transitions { use super::*; - #[test] - fn test_same_address_used_in_multiple_transitions_same_block() { + #[tokio::test] + async fn test_same_address_used_in_multiple_transitions_same_block() { // Tests that using the same address in multiple transitions within the same block // should be handled correctly (the nonce should prevent double-spending) let platform_version = PlatformVersion::latest(); @@ -5454,8 +5502,8 @@ mod tests { // Both transitions should be structurally valid; state validation would catch nonce issues } - #[test] - fn test_multiple_identities_from_same_address_sequential() { + #[tokio::test] + async fn test_multiple_identities_from_same_address_sequential() { // Tests creating multiple identities from the same address over time let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(2201); @@ -5491,8 +5539,8 @@ mod tests { mod input_ordering { use super::*; - #[test] - fn test_input_ordering_determinism() { + #[tokio::test] + async fn test_input_ordering_determinism() { // Tests that BTreeMap ordering is deterministic let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(2300); @@ -5524,8 +5572,8 @@ mod tests { ); } - #[test] - fn test_fee_strategy_index_refers_to_btreemap_ordering() { + #[tokio::test] + async fn test_fee_strategy_index_refers_to_btreemap_ordering() { // Tests that fee strategy indices refer to BTreeMap ordering use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; @@ -5579,8 +5627,8 @@ mod tests { mod witness_validation { use super::*; - #[test] - fn test_empty_p2pkh_signature_in_witness() { + #[tokio::test] + async fn test_empty_p2pkh_signature_in_witness() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(2400); @@ -5612,8 +5660,8 @@ mod tests { let _state_transition: StateTransition = transition.into(); } - #[test] - fn test_p2pkh_witness_with_valid_signature_format() { + #[tokio::test] + async fn test_p2pkh_witness_with_valid_signature_format() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(2401); @@ -5645,8 +5693,8 @@ mod tests { let _state_transition: StateTransition = transition.into(); } - #[test] - fn test_p2sh_witness_with_empty_signatures() { + #[tokio::test] + async fn test_p2sh_witness_with_empty_signatures() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(2402); @@ -5679,8 +5727,8 @@ mod tests { let _state_transition: StateTransition = transition.into(); } - #[test] - fn test_p2sh_witness_with_multiple_signatures() { + #[tokio::test] + async fn test_p2sh_witness_with_multiple_signatures() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(2403); @@ -5716,8 +5764,8 @@ mod tests { let _state_transition: StateTransition = transition.into(); } - #[test] - fn test_p2sh_witness_with_empty_redeem_script() { + #[tokio::test] + async fn test_p2sh_witness_with_empty_redeem_script() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(2404); @@ -5758,8 +5806,8 @@ mod tests { mod balance_calculations { use super::*; - #[test] - fn test_total_input_balance_calculation() { + #[tokio::test] + async fn test_total_input_balance_calculation() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(2500); @@ -5793,8 +5841,8 @@ mod tests { ); } - #[test] - fn test_output_cannot_exceed_total_inputs() { + #[tokio::test] + async fn test_output_cannot_exceed_total_inputs() { // This should fail state validation (not basic structure) let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(2501); @@ -5821,8 +5869,8 @@ mod tests { // This should fail during state validation when we check actual balances } - #[test] - fn test_fee_deduction_leaves_identity_with_remaining_balance() { + #[tokio::test] + async fn test_fee_deduction_leaves_identity_with_remaining_balance() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(2502); @@ -5854,8 +5902,8 @@ mod tests { mod nonce_edge_cases { use super::*; - #[test] - fn test_nonce_at_max_u64() { + #[tokio::test] + async fn test_nonce_at_max_u64() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -5891,8 +5939,8 @@ mod tests { ); } - #[test] - fn test_different_nonces_for_different_addresses() { + #[tokio::test] + async fn test_different_nonces_for_different_addresses() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -5944,8 +5992,8 @@ mod tests { use super::*; use dpp::identity::SecurityLevel; - #[test] - fn test_all_keys_at_master_level() { + #[tokio::test] + async fn test_all_keys_at_master_level() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -5991,8 +6039,8 @@ mod tests { ); } - #[test] - fn test_keys_at_different_security_levels() { + #[tokio::test] + async fn test_keys_at_different_security_levels() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(2701); @@ -6052,8 +6100,8 @@ mod tests { mod replay_attack_prevention { use super::*; - #[test] - fn test_same_transition_cannot_be_applied_twice() { + #[tokio::test] + async fn test_same_transition_cannot_be_applied_twice() { // This is handled by nonce checking in state validation let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(2800); @@ -6083,8 +6131,8 @@ mod tests { let _ = transition; } - #[test] - fn test_identity_id_derived_from_first_input_prevents_replay() { + #[tokio::test] + async fn test_identity_id_derived_from_first_input_prevents_replay() { // Identity ID is derived from the first public key // This means the identity created is deterministic based on the public keys let platform_version = PlatformVersion::latest(); @@ -6145,8 +6193,8 @@ mod tests { mod error_messages { use super::*; - #[test] - fn test_no_inputs_error_is_descriptive() { + #[tokio::test] + async fn test_no_inputs_error_is_descriptive() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -6182,8 +6230,8 @@ mod tests { ); } - #[test] - fn test_no_public_keys_error_is_descriptive() { + #[tokio::test] + async fn test_no_public_keys_error_is_descriptive() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -6232,8 +6280,8 @@ mod tests { mod conversions { use super::*; - #[test] - fn test_transition_to_state_transition_conversion() { + #[tokio::test] + async fn test_transition_to_state_transition_conversion() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(3000); @@ -6271,8 +6319,8 @@ mod tests { ); } - #[test] - fn test_v0_wrapper_conversion() { + #[tokio::test] + async fn test_v0_wrapper_conversion() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(3001); @@ -6314,8 +6362,8 @@ mod tests { mod minimum_balance_constants { use super::*; - #[test] - fn test_minimum_input_balance_is_enforced() { + #[tokio::test] + async fn test_minimum_input_balance_is_enforced() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -6345,8 +6393,8 @@ mod tests { assert!(!result.is_valid(), "1 credit input should be below minimum"); } - #[test] - fn test_minimum_output_balance_is_enforced() { + #[tokio::test] + async fn test_minimum_output_balance_is_enforced() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -6390,8 +6438,8 @@ mod tests { mod advanced_structure_validation_edge_cases { use super::*; - #[test] - fn test_p2pkh_witness_with_invalid_signature() { + #[tokio::test] + async fn test_p2pkh_witness_with_invalid_signature() { // P2PKH witness with an invalid signature (wrong format) let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4000); @@ -6424,8 +6472,8 @@ mod tests { let _state_transition: StateTransition = transition.into(); } - #[test] - fn test_p2sh_witness_redeem_script_hash_mismatch() { + #[tokio::test] + async fn test_p2sh_witness_redeem_script_hash_mismatch() { // P2SH witness where redeem script hash doesn't match the address let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4001); @@ -6461,8 +6509,8 @@ mod tests { let _state_transition: StateTransition = transition.into(); } - #[test] - fn test_invalid_der_signature_format() { + #[tokio::test] + async fn test_invalid_der_signature_format() { // Signature that's not valid DER encoding let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4002); @@ -6498,8 +6546,8 @@ mod tests { let _state_transition: StateTransition = transition.into(); } - #[test] - fn test_signature_for_wrong_message() { + #[tokio::test] + async fn test_signature_for_wrong_message() { // Valid signature format but for different message/signable bytes let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4003); @@ -6534,8 +6582,8 @@ mod tests { let _state_transition: StateTransition = transition.into(); } - #[test] - fn test_p2sh_with_incorrect_signature_count() { + #[tokio::test] + async fn test_p2sh_with_incorrect_signature_count() { // P2SH multisig where we don't have enough signatures let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4004); @@ -6571,8 +6619,8 @@ mod tests { let _state_transition: StateTransition = transition.into(); } - #[test] - fn test_p2sh_signatures_in_wrong_order() { + #[tokio::test] + async fn test_p2sh_signatures_in_wrong_order() { // P2SH where signatures might not match expected public key order let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4005); @@ -6620,8 +6668,8 @@ mod tests { use super::*; use crate::execution::validation::state_transition::state_transitions::identity_create_from_addresses::StateTransitionActionTransformerForIdentityCreateFromAddressesTransitionV0; - #[test] - fn test_transform_into_action_basic() { + #[tokio::test] + async fn test_transform_into_action_basic() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4100); @@ -6682,8 +6730,8 @@ mod tests { ); } - #[test] - fn test_transform_into_action_with_output() { + #[tokio::test] + async fn test_transform_into_action_with_output() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4101); @@ -6748,8 +6796,8 @@ mod tests { ); } - #[test] - fn test_transform_into_action_multiple_inputs() { + #[tokio::test] + async fn test_transform_into_action_multiple_inputs() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4102); @@ -6829,8 +6877,8 @@ mod tests { mod public_key_signature_validation { use super::*; - #[test] - fn test_validate_public_key_signatures_with_valid_ecdsa() { + #[tokio::test] + async fn test_validate_public_key_signatures_with_valid_ecdsa() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4200); @@ -6867,8 +6915,8 @@ mod tests { // This is separate from address witness validation } - #[test] - fn test_public_key_with_invalid_signature() { + #[tokio::test] + async fn test_public_key_with_invalid_signature() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4201); @@ -6906,8 +6954,8 @@ mod tests { ); } - #[test] - fn test_multiple_keys_some_with_signatures() { + #[tokio::test] + async fn test_multiple_keys_some_with_signatures() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4202); @@ -6952,8 +7000,8 @@ mod tests { mod state_validation_with_platform { use super::*; - #[test] - fn test_identity_already_exists_with_same_id() { + #[tokio::test] + async fn test_identity_already_exists_with_same_id() { // For IdentityCreateFromAddresses, the identity ID is derived from inputs (addresses + nonces). // This test verifies that trying to create an identity with the same inputs // (which would produce the same ID) after one already exists returns an error. @@ -7041,7 +7089,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -7070,8 +7119,8 @@ mod tests { ); } - #[test] - fn test_address_balance_exact_match() { + #[tokio::test] + async fn test_address_balance_exact_match() { // Address has exactly the balance claimed in the transition let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4301); @@ -7114,8 +7163,8 @@ mod tests { ); } - #[test] - fn test_multiple_inputs_partial_existence() { + #[tokio::test] + async fn test_multiple_inputs_partial_existence() { // Some input addresses exist, some don't let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4302); @@ -7172,8 +7221,8 @@ mod tests { // State validation should fail because non_existing_address doesn't exist } - #[test] - fn test_address_balance_less_than_claimed() { + #[tokio::test] + async fn test_address_balance_less_than_claimed() { // Address has less balance than claimed in the transition let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4303); @@ -7218,8 +7267,8 @@ mod tests { // State validation should fail with insufficient balance error } - #[test] - fn test_nonce_already_used() { + #[tokio::test] + async fn test_nonce_already_used() { // Address exists but nonce has already been used let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4304); @@ -7272,8 +7321,8 @@ mod tests { mod fee_calculation_edge_cases { use super::*; - #[test] - fn test_fee_exactly_equals_available_balance() { + #[tokio::test] + async fn test_fee_exactly_equals_available_balance() { // After fees, zero credits remain for identity let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4400); @@ -7320,8 +7369,8 @@ mod tests { // This might or might not be allowed depending on rules } - #[test] - fn test_reduce_output_to_negative_should_fail() { + #[tokio::test] + async fn test_reduce_output_to_negative_should_fail() { // ReduceOutput that would make output go negative use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; @@ -7360,8 +7409,8 @@ mod tests { // Multiple ReduceOutput steps for tiny output should fail } - #[test] - fn test_multiple_fee_steps_exceed_total_funds() { + #[tokio::test] + async fn test_multiple_fee_steps_exceed_total_funds() { // Multiple DeductFromInput steps that together exceed available funds use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; @@ -7393,8 +7442,8 @@ mod tests { // At execution time, this might fail if fees exceed input balance } - #[test] - fn test_fee_strategy_deduct_from_multiple_inputs_in_sequence() { + #[tokio::test] + async fn test_fee_strategy_deduct_from_multiple_inputs_in_sequence() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -7440,8 +7489,8 @@ mod tests { ); } - #[test] - fn test_mixed_deduct_and_reduce_fee_strategy() { + #[tokio::test] + async fn test_mixed_deduct_and_reduce_fee_strategy() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -7487,8 +7536,8 @@ mod tests { use super::*; use dpp::serialization::{PlatformDeserializable, PlatformSerializable}; - #[test] - fn test_full_roundtrip_serialization() { + #[tokio::test] + async fn test_full_roundtrip_serialization() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4500); @@ -7542,8 +7591,8 @@ mod tests { } } - #[test] - fn test_roundtrip_with_output() { + #[tokio::test] + async fn test_roundtrip_with_output() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4501); @@ -7590,8 +7639,8 @@ mod tests { } } - #[test] - fn test_roundtrip_with_p2sh_witness() { + #[tokio::test] + async fn test_roundtrip_with_p2sh_witness() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4502); @@ -7655,8 +7704,8 @@ mod tests { } } - #[test] - fn test_roundtrip_complex_fee_strategy() { + #[tokio::test] + async fn test_roundtrip_complex_fee_strategy() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4503); @@ -7708,16 +7757,16 @@ mod tests { } } - #[test] - fn test_deserialize_invalid_bytes() { + #[tokio::test] + async fn test_deserialize_invalid_bytes() { let invalid_bytes = vec![0xFF, 0xFF, 0xFF, 0xFF]; let result = StateTransition::deserialize_from_bytes(&invalid_bytes); assert!(result.is_err(), "Invalid bytes should fail deserialization"); } - #[test] - fn test_deserialize_truncated_data() { + #[tokio::test] + async fn test_deserialize_truncated_data() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4504); @@ -7765,8 +7814,8 @@ mod tests { mod platform_version_handling { use super::*; - #[test] - fn test_validation_with_latest_version() { + #[tokio::test] + async fn test_validation_with_latest_version() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -7801,8 +7850,8 @@ mod tests { ); } - #[test] - fn test_validation_with_first_version() { + #[tokio::test] + async fn test_validation_with_first_version() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::first(); @@ -7848,8 +7897,8 @@ mod tests { } } - #[test] - fn test_transform_action_version_check() { + #[tokio::test] + async fn test_transform_action_version_check() { use crate::execution::validation::state_transition::state_transitions::identity_create_from_addresses::StateTransitionActionTransformerForIdentityCreateFromAddressesTransitionV0; let platform_version = PlatformVersion::latest(); @@ -7919,8 +7968,8 @@ mod tests { /// Tests that duplicate key IDs are rejected during state transition processing. /// This validation happens in advanced_structure via validate_identity_public_keys_structure. - #[test] - fn test_duplicate_key_ids() { + #[tokio::test] + async fn test_duplicate_key_ids() { use dpp::serialization::Signable; let platform_version = PlatformVersion::latest(); @@ -7993,14 +8042,15 @@ mod tests { .expect("should get signable bytes"); // Create proper witness for the address - transition_v0.input_witnesses = inputs - .keys() - .map(|addr| { - address_signer - .sign_create_witness(addr, &signable_bytes) - .expect("should create witness") - }) - .collect(); + let mut witnesses = Vec::with_capacity(inputs.len()); + for addr in inputs.keys() { + let witness = address_signer + .sign_create_witness(addr, &signable_bytes) + .await + .expect("should create witness"); + witnesses.push(witness); + } + transition_v0.input_witnesses = witnesses; let transition: StateTransition = transition_v0.into(); @@ -8037,8 +8087,8 @@ mod tests { /// Tests that ECDSA keys with invalid data (wrong length) are rejected. /// This validation happens in advanced_structure via validate_identity_public_keys_structure. - #[test] - fn test_invalid_key_data_for_ecdsa() { + #[tokio::test] + async fn test_invalid_key_data_for_ecdsa() { use dpp::serialization::Signable; let platform_version = PlatformVersion::latest(); @@ -8107,14 +8157,15 @@ mod tests { .expect("should get signable bytes"); // Create proper witness for the address - transition_v0.input_witnesses = inputs - .keys() - .map(|addr| { - address_signer - .sign_create_witness(addr, &signable_bytes) - .expect("should create witness") - }) - .collect(); + let mut witnesses = Vec::with_capacity(inputs.len()); + for addr in inputs.keys() { + let witness = address_signer + .sign_create_witness(addr, &signable_bytes) + .await + .expect("should create witness"); + witnesses.push(witness); + } + transition_v0.input_witnesses = witnesses; let transition: StateTransition = transition_v0.into(); @@ -8149,8 +8200,8 @@ mod tests { /// Tests that BLS keys with invalid data (wrong length) are rejected. /// This validation happens in advanced_structure via validate_identity_public_keys_structure. - #[test] - fn test_invalid_key_data_for_bls() { + #[tokio::test] + async fn test_invalid_key_data_for_bls() { use dpp::serialization::Signable; let platform_version = PlatformVersion::latest(); @@ -8219,14 +8270,15 @@ mod tests { .expect("should get signable bytes"); // Create proper witness for the address - transition_v0.input_witnesses = inputs - .keys() - .map(|addr| { - address_signer - .sign_create_witness(addr, &signable_bytes) - .expect("should create witness") - }) - .collect(); + let mut witnesses = Vec::with_capacity(inputs.len()); + for addr in inputs.keys() { + let witness = address_signer + .sign_create_witness(addr, &signable_bytes) + .await + .expect("should create witness"); + witnesses.push(witness); + } + transition_v0.input_witnesses = witnesses; let transition: StateTransition = transition_v0.into(); @@ -8259,8 +8311,8 @@ mod tests { ); } - #[test] - fn test_key_with_wrong_purpose() { + #[tokio::test] + async fn test_key_with_wrong_purpose() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -8304,8 +8356,8 @@ mod tests { // Should require at least one authentication key } - #[test] - fn test_no_master_level_key() { + #[tokio::test] + async fn test_no_master_level_key() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -8345,8 +8397,8 @@ mod tests { // Identity creation might require at least one master key } - #[test] - fn test_disabled_key_at_creation() { + #[tokio::test] + async fn test_disabled_key_at_creation() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -8382,8 +8434,8 @@ mod tests { ); } - #[test] - fn test_read_only_authentication_key() { + #[tokio::test] + async fn test_read_only_authentication_key() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -8436,8 +8488,8 @@ mod tests { use super::*; use dpp::dashcore::Network; - #[test] - fn test_validation_on_mainnet() { + #[tokio::test] + async fn test_validation_on_mainnet() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -8468,8 +8520,8 @@ mod tests { // Should work on mainnet } - #[test] - fn test_validation_on_testnet() { + #[tokio::test] + async fn test_validation_on_testnet() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -8504,8 +8556,8 @@ mod tests { ); } - #[test] - fn test_validation_on_devnet() { + #[tokio::test] + async fn test_validation_on_devnet() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -8536,8 +8588,8 @@ mod tests { // Should work on devnet } - #[test] - fn test_validation_on_regtest() { + #[tokio::test] + async fn test_validation_on_regtest() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -8577,8 +8629,8 @@ mod tests { use super::*; use dpp::state_transition::StateTransitionIdentityIdFromInputs; - #[test] - fn test_same_identity_id_from_different_transitions() { + #[tokio::test] + async fn test_same_identity_id_from_different_transitions() { // Two transitions that would create the same identity ID // This should be caught by mempool deduplication // Note: Identity ID is derived from input addresses and nonces, NOT public keys @@ -8639,8 +8691,8 @@ mod tests { ); } - #[test] - fn test_nonce_gap_detection() { + #[tokio::test] + async fn test_nonce_gap_detection() { // Using nonce 3 when nonce should be 1 (gap of 2) let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4901); @@ -8685,8 +8737,8 @@ mod tests { // State validation should fail due to nonce gap } - #[test] - fn test_multiple_transitions_same_address_increasing_nonces() { + #[tokio::test] + async fn test_multiple_transitions_same_address_increasing_nonces() { // Multiple valid transitions from same address with incrementing nonces let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(4902); @@ -8733,8 +8785,8 @@ mod tests { mod output_address_edge_cases { use super::*; - #[test] - fn test_output_to_same_address_as_input() { + #[tokio::test] + async fn test_output_to_same_address_as_input() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -8769,8 +8821,8 @@ mod tests { ); } - #[test] - fn test_output_to_one_of_multiple_input_addresses() { + #[tokio::test] + async fn test_output_to_one_of_multiple_input_addresses() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -8807,8 +8859,8 @@ mod tests { ); } - #[test] - fn test_output_address_at_maximum_balance() { + #[tokio::test] + async fn test_output_address_at_maximum_balance() { // Output to address that already has near-maximum balance let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(5002); @@ -8869,8 +8921,8 @@ mod tests { // This should fail during execution due to balance overflow } - #[test] - fn test_output_to_new_address() { + #[tokio::test] + async fn test_output_to_new_address() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -8920,8 +8972,8 @@ mod tests { StateTransitionStateValidationForIdentityCreateFromAddressesTransitionV0, }; - #[test] - fn test_full_flow_single_input_no_output() { + #[tokio::test] + async fn test_full_flow_single_input_no_output() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(5100); @@ -9004,8 +9056,8 @@ mod tests { ); } - #[test] - fn test_full_flow_multiple_inputs_with_output() { + #[tokio::test] + async fn test_full_flow_multiple_inputs_with_output() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(5101); @@ -9063,8 +9115,8 @@ mod tests { ); } - #[test] - fn test_full_flow_with_p2sh_multisig() { + #[tokio::test] + async fn test_full_flow_with_p2sh_multisig() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(5102); @@ -9137,8 +9189,8 @@ mod tests { ); } - #[test] - fn test_verify_identity_created_after_execution() { + #[tokio::test] + async fn test_verify_identity_created_after_execution() { // This test would verify that after full execution, the identity exists in state let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(5103); @@ -9194,8 +9246,8 @@ mod tests { // This is a template for what full integration would test } - #[test] - fn test_verify_address_balance_updated_after_execution() { + #[tokio::test] + async fn test_verify_address_balance_updated_after_execution() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(5104); @@ -9246,8 +9298,8 @@ mod tests { // 3. Identity balance = remaining after fees and output } - #[test] - fn test_verify_nonce_incremented_after_execution() { + #[tokio::test] + async fn test_verify_nonce_incremented_after_execution() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(5105); @@ -9335,8 +9387,8 @@ mod tests { (address, witness) } - #[test] - fn test_create_transition_with_real_p2pkh_signature() { + #[tokio::test] + async fn test_create_transition_with_real_p2pkh_signature() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(6000); @@ -9411,8 +9463,8 @@ mod tests { ); } - #[test] - fn test_signature_verification_with_wrong_secret_key() { + #[tokio::test] + async fn test_signature_verification_with_wrong_secret_key() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(6001); @@ -9479,8 +9531,8 @@ mod tests { // Advanced structure validation should fail because recovered key doesn't match address } - #[test] - fn test_multiple_inputs_all_correctly_signed() { + #[tokio::test] + async fn test_multiple_inputs_all_correctly_signed() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(6002); @@ -9567,8 +9619,8 @@ mod tests { // All signatures should verify correctly } - #[test] - fn test_p2sh_multisig_real_signatures() { + #[tokio::test] + async fn test_p2sh_multisig_real_signatures() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(6003); @@ -9668,8 +9720,8 @@ mod tests { use super::*; use dpp::fee::fee_result::FeeResult; - #[test] - fn test_fee_increases_with_more_inputs() { + #[tokio::test] + async fn test_fee_increases_with_more_inputs() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(6200); @@ -9726,8 +9778,8 @@ mod tests { ); } - #[test] - fn test_fee_increases_with_more_public_keys() { + #[tokio::test] + async fn test_fee_increases_with_more_public_keys() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(6201); @@ -9791,8 +9843,8 @@ mod tests { ); } - #[test] - fn test_fee_with_p2sh_vs_p2pkh_witness() { + #[tokio::test] + async fn test_fee_with_p2sh_vs_p2pkh_witness() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(6202); @@ -9856,8 +9908,8 @@ mod tests { ); } - #[test] - fn test_user_fee_increase_effect() { + #[tokio::test] + async fn test_user_fee_increase_effect() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(6203); @@ -9921,8 +9973,8 @@ mod tests { mod consensus_error_types { use super::*; - #[test] - fn test_no_inputs_returns_correct_error_type() { + #[tokio::test] + async fn test_no_inputs_returns_correct_error_type() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -9964,8 +10016,8 @@ mod tests { ); } - #[test] - fn test_no_public_keys_returns_correct_error_type() { + #[tokio::test] + async fn test_no_public_keys_returns_correct_error_type() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -10005,8 +10057,8 @@ mod tests { ); } - #[test] - fn test_witness_count_mismatch_returns_correct_error_type() { + #[tokio::test] + async fn test_witness_count_mismatch_returns_correct_error_type() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -10054,8 +10106,8 @@ mod tests { ); } - #[test] - fn test_fee_strategy_index_out_of_bounds_error() { + #[tokio::test] + async fn test_fee_strategy_index_out_of_bounds_error() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -10096,8 +10148,8 @@ mod tests { ); } - #[test] - fn test_output_same_as_input_error() { + #[tokio::test] + async fn test_output_same_as_input_error() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -10136,8 +10188,8 @@ mod tests { ); } - #[test] - fn test_duplicate_key_ids_error() { + #[tokio::test] + async fn test_duplicate_key_ids_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -10231,8 +10283,8 @@ mod tests { mod asset_lock_interaction { use super::*; - #[test] - fn test_address_funded_from_asset_lock_can_create_identity() { + #[tokio::test] + async fn test_address_funded_from_asset_lock_can_create_identity() { // When an address was funded via asset lock, it should be able // to create identities just like any other funded address let platform_version = PlatformVersion::latest(); @@ -10283,8 +10335,8 @@ mod tests { assert!(result.is_valid()); } - #[test] - fn test_remaining_balance_after_identity_creation() { + #[tokio::test] + async fn test_remaining_balance_after_identity_creation() { // After creating identity, remaining funds stay in the address let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(6501); @@ -10340,8 +10392,8 @@ mod tests { mod event_verification { use super::*; - #[test] - fn test_tracing_logs_on_transition_creation() { + #[tokio::test] + async fn test_tracing_logs_on_transition_creation() { // The v0_methods.rs has tracing::debug calls // This test verifies the code path is exercised let platform_version = PlatformVersion::latest(); @@ -10373,8 +10425,8 @@ mod tests { // which we can't easily test since sign_by_private_key returns false } - #[test] - fn test_validation_produces_meaningful_errors() { + #[tokio::test] + async fn test_validation_produces_meaningful_errors() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -10432,8 +10484,8 @@ mod tests { use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use platform_version::DefaultForPlatformVersion; - #[test] - fn test_execution_context_tracks_operations() { + #[tokio::test] + async fn test_execution_context_tracks_operations() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(6800); @@ -10480,8 +10532,8 @@ mod tests { // and track operations performed } - #[test] - fn test_dry_run_does_not_modify_state() { + #[tokio::test] + async fn test_dry_run_does_not_modify_state() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(6801); @@ -10529,8 +10581,8 @@ mod tests { mod recovery_and_error_handling { use super::*; - #[test] - fn test_transaction_rollback_on_validation_failure() { + #[tokio::test] + async fn test_transaction_rollback_on_validation_failure() { let platform_version = PlatformVersion::latest(); let config = PlatformConfig { @@ -10597,8 +10649,8 @@ mod tests { assert_eq!(nonce, 0, "Nonce should be unchanged after rollback"); } - #[test] - fn test_partial_execution_cleanup() { + #[tokio::test] + async fn test_partial_execution_cleanup() { // If execution fails midway, earlier changes should be rolled back let platform_version = PlatformVersion::latest(); @@ -10677,8 +10729,8 @@ mod tests { ); } - #[test] - fn test_graceful_handling_of_missing_address() { + #[tokio::test] + async fn test_graceful_handling_of_missing_address() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(6902); @@ -10718,8 +10770,8 @@ mod tests { mod maximum_limits_at_boundary { use super::*; - #[test] - fn test_exactly_max_inputs() { + #[tokio::test] + async fn test_exactly_max_inputs() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -10765,8 +10817,8 @@ mod tests { ); } - #[test] - fn test_exactly_max_public_keys() { + #[tokio::test] + async fn test_exactly_max_public_keys() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -10817,8 +10869,8 @@ mod tests { ); } - #[test] - fn test_exactly_max_fee_strategy_steps() { + #[tokio::test] + async fn test_exactly_max_fee_strategy_steps() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -10865,8 +10917,8 @@ mod tests { ); } - #[test] - fn test_minimum_input_balance_exactly() { + #[tokio::test] + async fn test_minimum_input_balance_exactly() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -10905,8 +10957,8 @@ mod tests { ); } - #[test] - fn test_minimum_output_balance_exactly() { + #[tokio::test] + async fn test_minimum_output_balance_exactly() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -10948,8 +11000,8 @@ mod tests { ); } - #[test] - fn test_one_below_max_inputs() { + #[tokio::test] + async fn test_one_below_max_inputs() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -11007,8 +11059,8 @@ mod tests { use crate::execution::validation::state_transition::state_transitions::identity_create_from_addresses::advanced_structure::v0::IdentityCreateFromAddressesStateTransitionAdvancedStructureValidationV0; use platform_version::DefaultForPlatformVersion; - #[test] - fn test_public_key_signatures_validation_trait() { + #[tokio::test] + async fn test_public_key_signatures_validation_trait() { use dpp::serialization::Signable; use dpp::state_transition::public_key_in_creation::accessors::IdentityPublicKeyInCreationV0Setters; @@ -11056,6 +11108,7 @@ mod tests { if public_key.key_type().is_unique_key_type() { let signature = identity_signer .sign(public_key, &signable_bytes) + .await .expect("should sign"); public_key_in_creation.set_signature(signature); } @@ -11087,8 +11140,8 @@ mod tests { ); } - #[test] - fn test_advanced_structure_validation_trait() { + #[tokio::test] + async fn test_advanced_structure_validation_trait() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(7101); @@ -11137,8 +11190,8 @@ mod tests { ); } - #[test] - fn test_witness_validation_with_mismatched_address_type() { + #[tokio::test] + async fn test_witness_validation_with_mismatched_address_type() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(7102); @@ -11192,8 +11245,8 @@ mod tests { } } - #[test] - fn test_p2sh_witness_with_correct_script_hash() { + #[tokio::test] + async fn test_p2sh_witness_with_correct_script_hash() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(7103); @@ -11263,8 +11316,8 @@ mod tests { ); } - #[test] - fn test_multiple_witnesses_validation_order() { + #[tokio::test] + async fn test_multiple_witnesses_validation_order() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(7104); @@ -11333,8 +11386,8 @@ mod tests { /// because all indices shifted down after the removal. /// /// Location: rs-dpp/.../deduct_fee_from_inputs_and_outputs/v0/mod.rs:35-45 - #[test] - fn test_fee_deduction_stable_after_entry_removal() { + #[tokio::test] + async fn test_fee_deduction_stable_after_entry_removal() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -11401,7 +11454,8 @@ mod tests { None, // No output fee_strategy, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -11475,8 +11529,8 @@ mod tests { /// correct level, but notes the transformer lacks defense-in-depth. /// /// Location: rs-drive/.../identity_create_from_addresses/v0/transformer.rs:39,43 - #[test] - fn test_transformer_subtraction_uses_checked_arithmetic() { + #[tokio::test] + async fn test_transformer_subtraction_uses_checked_arithmetic() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); @@ -11521,8 +11575,8 @@ mod tests { /// enough for the transfer amount but insufficient to cover fees. /// /// Location: rs-drive-abci/.../identity_create_from_addresses (fee deduction logic) - #[test] - fn test_partial_fee_payment_rejected() { + #[tokio::test] + async fn test_partial_fee_payment_rejected() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -11571,7 +11625,8 @@ mod tests { AddressFundsFeeStrategyStep::DeductFromInput(0), ])), platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -11639,8 +11694,8 @@ mod tests { /// the same identity ID, creating potential cross-transition collisions. /// /// Location: rs-dpp/.../state_transition_identity_id_from_inputs.rs - #[test] - fn test_identity_id_has_no_domain_separator() { + #[tokio::test] + async fn test_identity_id_has_no_domain_separator() { use dpp::state_transition::StateTransitionIdentityIdFromInputs; let platform_version = PlatformVersion::latest(); @@ -11665,7 +11720,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; // Get the identity ID from the transition let create_id = match &transition { @@ -11689,7 +11745,8 @@ mod tests { None, None, platform_version, - ); + ) + .await; let create_id_2 = match &transition2 { StateTransition::IdentityCreateFromAddresses(t) => t diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer/mod.rs index 1a56a8cc63c..e0aeb60b421 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer/mod.rs @@ -218,7 +218,7 @@ mod tests { (identity, signer, transfer_key) } - fn create_signed_transfer( + async fn create_signed_transfer( identity_id: dpp::prelude::Identifier, recipient_id: dpp::prelude::Identifier, amount: u64, @@ -239,12 +239,17 @@ mod tests { let mut st: StateTransition = transfer.into(); let data = st.signable_bytes().expect("expected signable bytes"); - st.set_signature(signer.sign(key, data.as_slice()).expect("expected to sign")); + st.set_signature( + signer + .sign(key, data.as_slice()) + .await + .expect("expected to sign"), + ); st.serialize_to_bytes().expect("expected to serialize") } - #[test] - fn test_identity_credit_transfer_to_self_rejected() { + #[tokio::test] + async fn test_identity_credit_transfer_to_self_rejected() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -272,7 +277,8 @@ mod tests { 1, &signer, &transfer_key, - ); + ) + .await; let transaction = platform.drive.grove.start_transaction(); @@ -297,8 +303,8 @@ mod tests { ); } - #[test] - fn test_identity_credit_transfer_below_minimum_amount_rejected() { + #[tokio::test] + async fn test_identity_credit_transfer_below_minimum_amount_rejected() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -326,7 +332,8 @@ mod tests { 1, &signer, &transfer_key, - ); + ) + .await; let transaction = platform.drive.grove.start_transaction(); @@ -351,8 +358,8 @@ mod tests { ); } - #[test] - fn test_identity_credit_transfer_sender_not_found() { + #[tokio::test] + async fn test_identity_credit_transfer_sender_not_found() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -389,7 +396,12 @@ mod tests { let mut st: StateTransition = transfer.into(); let data = st.signable_bytes().expect("signable bytes"); - st.set_signature(signer.sign(&transfer_key, data.as_slice()).expect("sign")); + st.set_signature( + signer + .sign(&transfer_key, data.as_slice()) + .await + .expect("sign"), + ); let transfer_bytes = st.serialize_to_bytes().expect("serialize"); let transaction = platform.drive.grove.start_transaction(); @@ -416,8 +428,8 @@ mod tests { ); } - #[test] - fn test_identity_credit_transfer_insufficient_balance() { + #[tokio::test] + async fn test_identity_credit_transfer_insufficient_balance() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -449,7 +461,8 @@ mod tests { 1, &signer, &transfer_key, - ); + ) + .await; let transaction = platform.drive.grove.start_transaction(); @@ -476,8 +489,8 @@ mod tests { ); } - #[test] - fn test_identity_credit_transfer_recipient_not_found() { + #[tokio::test] + async fn test_identity_credit_transfer_recipient_not_found() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -506,7 +519,8 @@ mod tests { 1, &signer, &transfer_key, - ); + ) + .await; let transaction = platform.drive.grove.start_transaction(); @@ -534,8 +548,8 @@ mod tests { ); } - #[test] - fn test_identity_credit_transfer_successful() { + #[tokio::test] + async fn test_identity_credit_transfer_successful() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -566,7 +580,8 @@ mod tests { 1, &signer, &transfer_key, - ); + ) + .await; let transaction = platform.drive.grove.start_transaction(); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer_to_addresses/tests.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer_to_addresses/tests.rs index c1135c18003..4b2ef35eb78 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer_to_addresses/tests.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer_to_addresses/tests.rs @@ -110,7 +110,7 @@ mod tests { } /// Create a signed IdentityCreditTransferToAddressesTransition - fn create_signed_transition( + async fn create_signed_transition( identity: &Identity, signer: &SimpleSigner, recipient_addresses: BTreeMap, @@ -126,6 +126,7 @@ mod tests { PlatformVersion::latest(), None, ) + .await .expect("should create signed transition") } @@ -138,8 +139,8 @@ mod tests { use super::*; use dpp::state_transition::StateTransitionStructureValidation; - #[test] - fn test_no_recipient_addresses_returns_error() { + #[tokio::test] + async fn test_no_recipient_addresses_returns_error() { let platform_version = PlatformVersion::latest(); // Create a raw transition V0 with no recipient addresses @@ -167,8 +168,8 @@ mod tests { ); } - #[test] - fn test_too_many_recipient_addresses_returns_error() { + #[tokio::test] + async fn test_too_many_recipient_addresses_returns_error() { let platform_version = PlatformVersion::latest(); let max_outputs = platform_version.dpp.state_transitions.max_address_outputs; @@ -203,8 +204,8 @@ mod tests { ); } - #[test] - fn test_recipient_amount_below_minimum_returns_error() { + #[tokio::test] + async fn test_recipient_amount_below_minimum_returns_error() { let platform_version = PlatformVersion::latest(); let mut recipient_addresses = BTreeMap::new(); @@ -252,8 +253,8 @@ mod tests { /// This test verifies structure validation catches the overflow. /// /// Location: rs-drive/.../identity_credit_transfer_to_addresses_transition.rs:38 - #[test] - fn test_recipient_sum_overflow_returns_error() { + #[tokio::test] + async fn test_recipient_sum_overflow_returns_error() { let platform_version = PlatformVersion::latest(); // Create two recipients whose amounts sum to > u64::MAX @@ -302,8 +303,8 @@ mod tests { /// This test demonstrates that any data passes through unchecked. /// /// Location: rs-drive-abci/.../identity_credit_transfer_to_addresses/transform_into_action/v0/mod.rs:16-23 - #[test] - fn test_transform_into_action_passes_without_validation() { + #[tokio::test] + async fn test_transform_into_action_passes_without_validation() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -335,7 +336,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(create_platform_address(1), dash_to_credits!(1.0)); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -376,8 +378,8 @@ mod tests { /// transition to pass fee estimation but fail structure validation. /// /// Location: rs-drive-abci/.../state_transition_estimated_fee_validation.rs:19 - #[test] - fn test_fee_estimation_saturating_add_matches_structure_validation() { + #[tokio::test] + async fn test_fee_estimation_saturating_add_matches_structure_validation() { let platform_version = PlatformVersion::latest(); // Create recipients whose sum overflows u64 @@ -434,8 +436,8 @@ mod tests { mod successful_transitions { use super::*; - #[test] - fn test_simple_transfer_to_single_address() { + #[tokio::test] + async fn test_simple_transfer_to_single_address() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -468,7 +470,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(create_platform_address(1), dash_to_credits!(0.1)); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -494,8 +497,8 @@ mod tests { ); } - #[test] - fn test_transfer_to_multiple_addresses() { + #[tokio::test] + async fn test_transfer_to_multiple_addresses() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -530,7 +533,8 @@ mod tests { recipient_addresses.insert(create_platform_address(2), dash_to_credits!(0.2)); recipient_addresses.insert(create_platform_address(3), dash_to_credits!(0.3)); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -556,8 +560,8 @@ mod tests { ); } - #[test] - fn test_transfer_with_user_fee_increase() { + #[tokio::test] + async fn test_transfer_with_user_fee_increase() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -601,6 +605,7 @@ mod tests { platform_version, None, ) + .await .expect("should create signed transition"); let result = transition.serialize_to_bytes().expect("should serialize"); @@ -627,8 +632,8 @@ mod tests { ); } - #[test] - fn test_transfer_maximum_allowed_outputs() { + #[tokio::test] + async fn test_transfer_maximum_allowed_outputs() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -670,7 +675,8 @@ mod tests { recipient_addresses.insert(create_platform_address(i), min_output); } - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -705,8 +711,8 @@ mod tests { mod state_verification { use super::*; - #[test] - fn test_identity_balance_decreases_after_transfer() { + #[tokio::test] + async fn test_identity_balance_decreases_after_transfer() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -749,7 +755,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(create_platform_address(1), transfer_amount); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -800,8 +807,8 @@ mod tests { ); } - #[test] - fn test_recipient_address_receives_credits() { + #[tokio::test] + async fn test_recipient_address_receives_credits() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -846,7 +853,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(recipient_address, transfer_amount); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -893,8 +901,8 @@ mod tests { ); } - #[test] - fn test_multiple_recipients_all_receive_credits() { + #[tokio::test] + async fn test_multiple_recipients_all_receive_credits() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -937,7 +945,8 @@ mod tests { recipient_addresses.insert(recipient2, amount2); recipient_addresses.insert(recipient3, amount3); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1002,8 +1011,8 @@ mod tests { ); } - #[test] - fn test_identity_nonce_increments_after_transfer() { + #[tokio::test] + async fn test_identity_nonce_increments_after_transfer() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1037,7 +1046,8 @@ mod tests { recipient_addresses.insert(create_platform_address(1), dash_to_credits!(0.1)); // First transfer with nonce 1 - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1074,7 +1084,8 @@ mod tests { let mut recipient_addresses2 = BTreeMap::new(); recipient_addresses2.insert(create_platform_address(2), dash_to_credits!(0.1)); - let transition2 = create_signed_transition(&identity, &signer, recipient_addresses2, 2); + let transition2 = + create_signed_transition(&identity, &signer, recipient_addresses2, 2).await; let result2 = transition2.serialize_to_bytes().expect("should serialize"); @@ -1109,8 +1120,8 @@ mod tests { mod state_validation { use super::*; - #[test] - fn test_identity_does_not_exist_returns_error() { + #[tokio::test] + async fn test_identity_does_not_exist_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1140,7 +1151,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(create_platform_address(1), dash_to_credits!(0.1)); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1170,8 +1182,8 @@ mod tests { ); } - #[test] - fn test_insufficient_balance_returns_error() { + #[tokio::test] + async fn test_insufficient_balance_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1204,7 +1216,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(create_platform_address(1), dash_to_credits!(1.0)); // More than balance - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1234,8 +1247,8 @@ mod tests { ); } - #[test] - fn test_invalid_nonce_too_low_returns_error() { + #[tokio::test] + async fn test_invalid_nonce_too_low_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1268,7 +1281,8 @@ mod tests { let mut recipient_addresses1 = BTreeMap::new(); recipient_addresses1.insert(create_platform_address(1), dash_to_credits!(0.1)); - let transition1 = create_signed_transition(&identity, &signer, recipient_addresses1, 1); + let transition1 = + create_signed_transition(&identity, &signer, recipient_addresses1, 1).await; let result1 = transition1.serialize_to_bytes().expect("should serialize"); @@ -1305,7 +1319,8 @@ mod tests { let mut recipient_addresses2 = BTreeMap::new(); recipient_addresses2.insert(create_platform_address(2), dash_to_credits!(0.1)); - let transition2 = create_signed_transition(&identity, &signer, recipient_addresses2, 1); // Same nonce! + let transition2 = + create_signed_transition(&identity, &signer, recipient_addresses2, 1).await; // Same nonce! let result2 = transition2.serialize_to_bytes().expect("should serialize"); @@ -1334,8 +1349,8 @@ mod tests { ); } - #[test] - fn test_invalid_nonce_too_high_returns_error() { + #[tokio::test] + async fn test_invalid_nonce_too_high_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1368,7 +1383,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(create_platform_address(1), dash_to_credits!(0.1)); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 100); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 100).await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1405,8 +1421,8 @@ mod tests { mod signature_validation { use super::*; - #[test] - fn test_invalid_signature_returns_error() { + #[tokio::test] + async fn test_invalid_signature_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1488,8 +1504,8 @@ mod tests { ); } - #[test] - fn test_wrong_key_type_for_signing_returns_error() { + #[tokio::test] + async fn test_wrong_key_type_for_signing_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1549,7 +1565,8 @@ mod tests { 1, platform_version, None, - ); + ) + .await; assert!( result.is_err(), @@ -1565,8 +1582,8 @@ mod tests { mod edge_cases { use super::*; - #[test] - fn test_transfer_entire_balance_minus_fees() { + #[tokio::test] + async fn test_transfer_entire_balance_minus_fees() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1601,7 +1618,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(create_platform_address(1), transfer_amount); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1627,8 +1645,8 @@ mod tests { ); } - #[test] - fn test_transfer_to_same_address_twice() { + #[tokio::test] + async fn test_transfer_to_same_address_twice() { // Since recipient_addresses is a BTreeMap, adding the same address twice // just updates the amount. This test verifies that behavior. let platform_version = PlatformVersion::latest(); @@ -1664,7 +1682,8 @@ mod tests { recipient_addresses.insert(same_address, dash_to_credits!(0.1)); // In BTreeMap, inserting same key again would overwrite, so we only have one entry - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1690,8 +1709,8 @@ mod tests { ); } - #[test] - fn test_transfer_minimum_valid_amount() { + #[tokio::test] + async fn test_transfer_minimum_valid_amount() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1730,7 +1749,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(create_platform_address(1), min_output_amount); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1756,8 +1776,8 @@ mod tests { ); } - #[test] - fn test_transfer_to_p2sh_address() { + #[tokio::test] + async fn test_transfer_to_p2sh_address() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1795,7 +1815,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(p2sh_address, dash_to_credits!(0.1)); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -1821,8 +1842,8 @@ mod tests { ); } - #[test] - fn test_transfer_to_existing_address_accumulates_balance() { + #[tokio::test] + async fn test_transfer_to_existing_address_accumulates_balance() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1858,7 +1879,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(recipient_address, first_transfer); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -1901,7 +1923,8 @@ mod tests { let mut recipient_addresses2 = BTreeMap::new(); recipient_addresses2.insert(recipient_address, second_transfer); - let transition2 = create_signed_transition(&identity, &signer, recipient_addresses2, 2); + let transition2 = + create_signed_transition(&identity, &signer, recipient_addresses2, 2).await; let result2 = transition2.serialize_to_bytes().expect("should serialize"); let platform_state2 = platform.state.load(); @@ -1946,8 +1969,8 @@ mod tests { ); } - #[test] - fn test_multiple_sequential_transfers_from_same_identity() { + #[tokio::test] + async fn test_multiple_sequential_transfers_from_same_identity() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1983,7 +2006,7 @@ mod tests { .insert(create_platform_address(60 + i as u8), dash_to_credits!(0.1)); let transition = - create_signed_transition(&identity, &signer, recipient_addresses, i); + create_signed_transition(&identity, &signer, recipient_addresses, i).await; let result = transition.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -2027,8 +2050,8 @@ mod tests { use super::*; use dpp::state_transition::StateTransitionStructureValidation; - #[test] - fn test_balance_exactly_covers_transfer_and_fees() { + #[tokio::test] + async fn test_balance_exactly_covers_transfer_and_fees() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2067,7 +2090,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(create_platform_address(1), transfer_amount); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -2092,8 +2116,8 @@ mod tests { ); } - #[test] - fn test_amount_exactly_at_minimum() { + #[tokio::test] + async fn test_amount_exactly_at_minimum() { let platform_version = PlatformVersion::latest(); let min_output = platform_version .dpp @@ -2120,8 +2144,8 @@ mod tests { ); } - #[test] - fn test_amount_one_below_minimum_returns_error() { + #[tokio::test] + async fn test_amount_one_below_minimum_returns_error() { let platform_version = PlatformVersion::latest(); let min_output = platform_version .dpp @@ -2152,8 +2176,8 @@ mod tests { ); } - #[test] - fn test_outputs_exactly_at_maximum() { + #[tokio::test] + async fn test_outputs_exactly_at_maximum() { let platform_version = PlatformVersion::latest(); let max_outputs = platform_version.dpp.state_transitions.max_address_outputs; let min_output = platform_version @@ -2180,8 +2204,8 @@ mod tests { assert!(result.is_valid(), "Exactly max outputs should be valid"); } - #[test] - fn test_outputs_one_over_maximum_returns_error() { + #[tokio::test] + async fn test_outputs_one_over_maximum_returns_error() { let platform_version = PlatformVersion::latest(); let max_outputs = platform_version.dpp.state_transitions.max_address_outputs; let min_output = platform_version @@ -2215,8 +2239,8 @@ mod tests { ); } - #[test] - fn test_mixed_valid_and_invalid_output_amounts() { + #[tokio::test] + async fn test_mixed_valid_and_invalid_output_amounts() { let platform_version = PlatformVersion::latest(); let min_output = platform_version .dpp @@ -2254,8 +2278,8 @@ mod tests { use super::*; use dpp::identity::identity_public_key::accessors::v0::IdentityPublicKeySettersV0; - #[test] - fn test_transfer_with_disabled_key_fails_at_creation() { + #[tokio::test] + async fn test_transfer_with_disabled_key_fails_at_creation() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(588); @@ -2297,7 +2321,8 @@ mod tests { 1, platform_version, None, - ); + ) + .await; assert!( result.is_err(), @@ -2305,8 +2330,8 @@ mod tests { ); } - #[test] - fn test_transfer_with_non_transfer_purpose_key_fails_at_creation() { + #[tokio::test] + async fn test_transfer_with_non_transfer_purpose_key_fails_at_creation() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(589); let mut signer = SimpleSigner::default(); @@ -2346,7 +2371,8 @@ mod tests { 1, platform_version, None, - ); + ) + .await; assert!( result.is_err(), @@ -2354,8 +2380,8 @@ mod tests { ); } - #[test] - fn test_transfer_with_high_security_level_transfer_key_fails_at_creation() { + #[tokio::test] + async fn test_transfer_with_high_security_level_transfer_key_fails_at_creation() { // Transfer keys for credit transfer to addresses require CRITICAL security level let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(590); @@ -2412,7 +2438,8 @@ mod tests { 1, platform_version, None, - ); + ) + .await; assert!( result.is_err(), @@ -2428,8 +2455,8 @@ mod tests { mod user_fee_increase_tests { use super::*; - #[test] - fn test_maximum_user_fee_increase() { + #[tokio::test] + async fn test_maximum_user_fee_increase() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2471,6 +2498,7 @@ mod tests { platform_version, None, ) + .await .expect("should create transition"); let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2497,8 +2525,8 @@ mod tests { ); } - #[test] - fn test_zero_user_fee_increase() { + #[tokio::test] + async fn test_zero_user_fee_increase() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2539,6 +2567,7 @@ mod tests { platform_version, None, ) + .await .expect("should create transition"); let result = transition.serialize_to_bytes().expect("should serialize"); @@ -2573,8 +2602,8 @@ mod tests { mod nonce_edge_cases { use super::*; - #[test] - fn test_nonce_zero_is_invalid() { + #[tokio::test] + async fn test_nonce_zero_is_invalid() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2605,7 +2634,8 @@ mod tests { recipient_addresses.insert(create_platform_address(1), dash_to_credits!(0.1)); // Use nonce 0 (should be invalid, nonces start at 1) - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 0); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 0).await; let result = transition.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -2633,8 +2663,8 @@ mod tests { ); } - #[test] - fn test_nonce_skipping_one_ahead_may_be_valid() { + #[tokio::test] + async fn test_nonce_skipping_one_ahead_may_be_valid() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2665,7 +2695,8 @@ mod tests { recipient_addresses.insert(create_platform_address(1), dash_to_credits!(0.1)); // Use nonce 2 (skipping nonce 1) - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 2); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 2).await; let result = transition.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -2710,8 +2741,8 @@ mod tests { /// Test that multiple different identities can transfer to the same recipient address /// and the balance accumulates correctly - #[test] - fn test_multiple_identities_transfer_to_same_address() { + #[tokio::test] + async fn test_multiple_identities_transfer_to_same_address() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2765,7 +2796,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(shared_recipient, transfer_amount); - let transition = create_signed_transition(identity, signer, recipient_addresses, 1); + let transition = + create_signed_transition(identity, signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -2814,8 +2846,8 @@ mod tests { } /// Test that two identities can transfer to each other's derived addresses - #[test] - fn test_cross_identity_transfers() { + #[tokio::test] + async fn test_cross_identity_transfers() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2857,12 +2889,12 @@ mod tests { // Identity 1 transfers to recipient 2 let mut addresses1 = BTreeMap::new(); addresses1.insert(recipient2, dash_to_credits!(0.5)); - let transition1 = create_signed_transition(&identity1, &signer1, addresses1, 1); + let transition1 = create_signed_transition(&identity1, &signer1, addresses1, 1).await; // Identity 2 transfers to recipient 1 let mut addresses2 = BTreeMap::new(); addresses2.insert(recipient1, dash_to_credits!(0.3)); - let transition2 = create_signed_transition(&identity2, &signer2, addresses2, 1); + let transition2 = create_signed_transition(&identity2, &signer2, addresses2, 1).await; // Process both transitions let result1 = transition1.serialize_to_bytes().expect("should serialize"); @@ -2914,8 +2946,8 @@ mod tests { use dpp::state_transition::StateTransitionSingleSigned; /// Test that a transition can be serialized and deserialized correctly - #[test] - fn test_serialization_roundtrip() { + #[tokio::test] + async fn test_serialization_roundtrip() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(602); @@ -2932,7 +2964,7 @@ mod tests { recipient_addresses.insert(create_platform_address(3), dash_to_credits!(0.15)); let original_transition = - create_signed_transition(&identity, &signer, recipient_addresses.clone(), 42); + create_signed_transition(&identity, &signer, recipient_addresses.clone(), 42).await; // Serialize let serialized = original_transition @@ -2964,8 +2996,8 @@ mod tests { } /// Test serialization with maximum outputs - #[test] - fn test_serialization_with_max_outputs() { + #[tokio::test] + async fn test_serialization_with_max_outputs() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(603); let max_outputs = platform_version.dpp.state_transitions.max_address_outputs; @@ -2988,7 +3020,7 @@ mod tests { } let transition = - create_signed_transition(&identity, &signer, recipient_addresses.clone(), 1); + create_signed_transition(&identity, &signer, recipient_addresses.clone(), 1).await; // Should serialize successfully let serialized = transition.serialize_to_bytes().expect("should serialize"); @@ -3010,8 +3042,8 @@ mod tests { } /// Test that serialized bytes are deterministic - #[test] - fn test_serialization_is_deterministic() { + #[tokio::test] + async fn test_serialization_is_deterministic() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(604); @@ -3026,9 +3058,9 @@ mod tests { recipient_addresses.insert(create_platform_address(1), dash_to_credits!(0.1)); let transition1 = - create_signed_transition(&identity, &signer, recipient_addresses.clone(), 1); + create_signed_transition(&identity, &signer, recipient_addresses.clone(), 1).await; let transition2 = - create_signed_transition(&identity, &signer, recipient_addresses.clone(), 1); + create_signed_transition(&identity, &signer, recipient_addresses.clone(), 1).await; let bytes1 = transition1.serialize_to_bytes().expect("should serialize"); let bytes2 = transition2.serialize_to_bytes().expect("should serialize"); @@ -3049,8 +3081,8 @@ mod tests { use dpp::state_transition::StateTransitionIdentitySigned; /// Test explicitly specifying which transfer key to use when identity has multiple - #[test] - fn test_explicit_transfer_key_selection() { + #[tokio::test] + async fn test_explicit_transfer_key_selection() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(605); let mut signer = SimpleSigner::default(); @@ -3120,6 +3152,7 @@ mod tests { platform_version, None, ) + .await .expect("should create transition with explicit key"); // Verify that key 2 was used @@ -3136,8 +3169,8 @@ mod tests { } /// Test that identity with multiple transfer keys uses the first one by default - #[test] - fn test_multiple_transfer_keys_default_selection() { + #[tokio::test] + async fn test_multiple_transfer_keys_default_selection() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(606); let mut signer = SimpleSigner::default(); @@ -3207,6 +3240,7 @@ mod tests { platform_version, None, ) + .await .expect("should create transition"); // The transition should be created successfully with one of the transfer keys @@ -3224,8 +3258,8 @@ mod tests { } /// Test specifying a key that the signer cannot sign with - #[test] - fn test_explicit_key_not_in_signer_fails() { + #[tokio::test] + async fn test_explicit_key_not_in_signer_fails() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(607); let mut signer = SimpleSigner::default(); @@ -3294,7 +3328,8 @@ mod tests { 1, platform_version, None, - ); + ) + .await; assert!( result.is_err(), @@ -3312,8 +3347,8 @@ mod tests { use dpp::identity::identity_public_key::accessors::v0::IdentityPublicKeySettersV0; /// Test that a key disabled at a future block height can still be used - #[test] - fn test_key_disabled_at_future_block_still_works() { + #[tokio::test] + async fn test_key_disabled_at_future_block_still_works() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3374,7 +3409,8 @@ mod tests { 1, platform_version, None, - ); + ) + .await; // The key is considered disabled regardless of when, so this should fail assert!( @@ -3384,8 +3420,8 @@ mod tests { } /// Test transfer at a specific block height - #[test] - fn test_transfer_at_specific_block_height() { + #[tokio::test] + async fn test_transfer_at_specific_block_height() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3415,7 +3451,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(create_platform_address(1), dash_to_credits!(0.1)); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); // Use a specific block height instead of default @@ -3457,8 +3494,8 @@ mod tests { use super::*; /// Test that fees are correctly deducted from the identity balance - #[test] - fn test_fee_deduction_verification() { + #[tokio::test] + async fn test_fee_deduction_verification() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3490,7 +3527,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(create_platform_address(1), transfer_amount); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -3552,8 +3590,8 @@ mod tests { } /// Test that user_fee_increase actually increases the fee paid - #[test] - fn test_user_fee_increase_affects_total_fee() { + #[tokio::test] + async fn test_user_fee_increase_affects_total_fee() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3601,6 +3639,7 @@ mod tests { platform_version, None, ) + .await .expect("should create transition"); // Identity 2: 100% fee increase (10000 = 100%) @@ -3616,6 +3655,7 @@ mod tests { platform_version, None, ) + .await .expect("should create transition"); let result1 = transition1.serialize_to_bytes().expect("should serialize"); @@ -3696,8 +3736,8 @@ mod tests { use super::*; /// Test transition with empty signature field - #[test] - fn test_empty_signature_returns_error() { + #[tokio::test] + async fn test_empty_signature_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3777,8 +3817,8 @@ mod tests { } /// Test transition with truncated signature - #[test] - fn test_truncated_signature_returns_error() { + #[tokio::test] + async fn test_truncated_signature_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3866,8 +3906,8 @@ mod tests { use super::*; /// Test many small transfers near the minimum amount - #[test] - fn test_many_minimum_amount_transfers() { + #[tokio::test] + async fn test_many_minimum_amount_transfers() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3906,7 +3946,8 @@ mod tests { recipient_addresses.insert(create_platform_address(i), min_output); } - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -3952,8 +3993,8 @@ mod tests { } /// Test processing multiple transitions in a single block - #[test] - fn test_batch_processing_multiple_transitions() { + #[tokio::test] + async fn test_batch_processing_multiple_transitions() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3989,7 +4030,7 @@ mod tests { recipient_addresses.insert(create_platform_address(200 + i), dash_to_credits!(0.1)); let transition = - create_signed_transition(&identity, &signer, recipient_addresses, 1); + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; transitions.push(transition.serialize_to_bytes().expect("should serialize")); } @@ -4034,8 +4075,8 @@ mod tests { use super::*; /// Test that balance can reach zero after transfer - #[test] - fn test_balance_reaches_zero() { + #[tokio::test] + async fn test_balance_reaches_zero() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4079,7 +4120,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(create_platform_address(1), min_output); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -4135,8 +4177,8 @@ mod tests { /// Test that a read-only transfer key can still be used for signing /// (read_only affects whether the key can be updated, not whether it can sign) - #[test] - fn test_read_only_transfer_key_can_sign() { + #[tokio::test] + async fn test_read_only_transfer_key_can_sign() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(618); let mut signer = SimpleSigner::default(); @@ -4200,7 +4242,8 @@ mod tests { 1, platform_version, None, - ); + ) + .await; assert!( result.is_ok(), @@ -4218,8 +4261,8 @@ mod tests { use super::*; /// Test that IdentityInsufficientBalanceError contains correct values - #[test] - fn test_insufficient_balance_error_details() { + #[tokio::test] + async fn test_insufficient_balance_error_details() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4251,7 +4294,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(create_platform_address(1), transfer_amount); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -4292,8 +4336,8 @@ mod tests { } /// Test that InvalidIdentityNonceError contains correct nonce values - #[test] - fn test_invalid_nonce_error_details() { + #[tokio::test] + async fn test_invalid_nonce_error_details() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4324,7 +4368,8 @@ mod tests { recipient_addresses.insert(create_platform_address(1), dash_to_credits!(0.1)); // Use nonce 0 which is invalid - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 0); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 0).await; let result = transition.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -4364,8 +4409,8 @@ mod tests { } /// Test that TransitionOverMaxOutputsError contains correct counts - #[test] - fn test_over_max_outputs_error_details() { + #[tokio::test] + async fn test_over_max_outputs_error_details() { use dpp::state_transition::StateTransitionStructureValidation; let platform_version = PlatformVersion::latest(); @@ -4407,8 +4452,8 @@ mod tests { } /// Test that OutputBelowMinimumError contains correct amount information - #[test] - fn test_below_minimum_error_details() { + #[tokio::test] + async fn test_below_minimum_error_details() { use dpp::state_transition::StateTransitionStructureValidation; let platform_version = PlatformVersion::latest(); @@ -4460,8 +4505,8 @@ mod tests { use super::*; /// Test two transitions from same identity in same block (should fail for second due to nonce) - #[test] - fn test_same_identity_two_transitions_same_block_same_nonce_fails() { + #[tokio::test] + async fn test_same_identity_two_transitions_same_block_same_nonce_fails() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4491,11 +4536,11 @@ mod tests { // Create two transitions with the SAME nonce let mut addresses1 = BTreeMap::new(); addresses1.insert(create_platform_address(1), dash_to_credits!(0.1)); - let transition1 = create_signed_transition(&identity, &signer, addresses1, 1); + let transition1 = create_signed_transition(&identity, &signer, addresses1, 1).await; let mut addresses2 = BTreeMap::new(); addresses2.insert(create_platform_address(2), dash_to_credits!(0.1)); - let transition2 = create_signed_transition(&identity, &signer, addresses2, 1); // Same nonce! + let transition2 = create_signed_transition(&identity, &signer, addresses2, 1).await; // Same nonce! let result1 = transition1.serialize_to_bytes().expect("should serialize"); let result2 = transition2.serialize_to_bytes().expect("should serialize"); @@ -4537,8 +4582,8 @@ mod tests { } /// Test two transitions from same identity with sequential nonces in same block - #[test] - fn test_same_identity_sequential_nonces_same_block() { + #[tokio::test] + async fn test_same_identity_sequential_nonces_same_block() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4568,11 +4613,11 @@ mod tests { // Create two transitions with sequential nonces let mut addresses1 = BTreeMap::new(); addresses1.insert(create_platform_address(1), dash_to_credits!(0.1)); - let transition1 = create_signed_transition(&identity, &signer, addresses1, 1); + let transition1 = create_signed_transition(&identity, &signer, addresses1, 1).await; let mut addresses2 = BTreeMap::new(); addresses2.insert(create_platform_address(2), dash_to_credits!(0.1)); - let transition2 = create_signed_transition(&identity, &signer, addresses2, 2); // Next nonce + let transition2 = create_signed_transition(&identity, &signer, addresses2, 2).await; // Next nonce let result1 = transition1.serialize_to_bytes().expect("should serialize"); let result2 = transition2.serialize_to_bytes().expect("should serialize"); @@ -4616,8 +4661,8 @@ mod tests { use super::*; /// Test transfer to mixed P2PKH and P2SH addresses in a single transition - #[test] - fn test_mixed_p2pkh_and_p2sh_addresses_in_single_transition() { + #[tokio::test] + async fn test_mixed_p2pkh_and_p2sh_addresses_in_single_transition() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4656,7 +4701,8 @@ mod tests { recipient_addresses.insert(p2sh_address1, dash_to_credits!(0.2)); recipient_addresses.insert(p2sh_address2, dash_to_credits!(0.12)); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -4718,8 +4764,8 @@ mod tests { } /// Test raw transition with signature_public_key_id pointing to non-existent key - #[test] - fn test_raw_transition_with_nonexistent_key_id() { + #[tokio::test] + async fn test_raw_transition_with_nonexistent_key_id() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4791,8 +4837,8 @@ mod tests { } /// Test raw transition where signature_public_key_id points to AUTHENTICATION key - #[test] - fn test_raw_transition_with_authentication_key_id() { + #[tokio::test] + async fn test_raw_transition_with_authentication_key_id() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4877,8 +4923,8 @@ mod tests { /// fails with IdentityInsufficientBalanceError because fee estimation uses a higher /// worst-case estimate than the actual fee. This demonstrates that users need slightly /// more than (output + actual_fee) to pass validation. - #[test] - fn test_exact_actual_fee_balance_fails_due_to_fee_estimation() { + #[tokio::test] + async fn test_exact_actual_fee_balance_fails_due_to_fee_estimation() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -4919,7 +4965,7 @@ mod tests { // Create the transition once - we'll reuse it for both runs let transition = - create_signed_transition(&identity, &signer, recipient_addresses.clone(), 1); + create_signed_transition(&identity, &signer, recipient_addresses.clone(), 1).await; let transition_bytes = transition.serialize_to_bytes().expect("should serialize"); // First run in a transaction to measure actual fee (then rollback) @@ -5013,8 +5059,8 @@ mod tests { /// Test that when balance equals (total_outputs + actual_fee_from_first_run) with 128 outputs, /// the second run succeeds because fee estimation is now accurate enough with count sum trees. /// (Previously this would fail because fee estimation used a higher worst-case estimate.) - #[test] - fn test_exact_actual_fee_balance_succeeds_with_128_outputs() { + #[tokio::test] + async fn test_exact_actual_fee_balance_succeeds_with_128_outputs() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -5063,7 +5109,7 @@ mod tests { // Create the transition once - we'll reuse it for both runs let transition = - create_signed_transition(&identity, &signer, recipient_addresses.clone(), 1); + create_signed_transition(&identity, &signer, recipient_addresses.clone(), 1).await; let transition_bytes = transition.serialize_to_bytes().expect("should serialize"); // First run in a transaction to measure actual fee (then rollback) @@ -5144,8 +5190,8 @@ mod tests { } /// Test that 129 outputs exceeds the maximum allowed outputs and returns an error. - #[test] - fn test_129_outputs_exceeds_maximum() { + #[tokio::test] + async fn test_129_outputs_exceeds_maximum() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -5190,7 +5236,7 @@ mod tests { } let transition = - create_signed_transition(&identity, &signer, recipient_addresses.clone(), 1); + create_signed_transition(&identity, &signer, recipient_addresses.clone(), 1).await; let transition_bytes = transition.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -5219,8 +5265,8 @@ mod tests { } /// Test with a very large single output (near u64::MAX / 2) - #[test] - fn test_very_large_single_output() { + #[tokio::test] + async fn test_very_large_single_output() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -5256,7 +5302,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(create_platform_address(1), large_output); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -5301,8 +5348,8 @@ mod tests { } /// Test identity with no public keys at all - #[test] - fn test_identity_with_no_public_keys() { + #[tokio::test] + async fn test_identity_with_no_public_keys() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -5374,8 +5421,8 @@ mod tests { } /// Test identity with non-zero revision - #[test] - fn test_identity_with_different_revision() { + #[tokio::test] + async fn test_identity_with_different_revision() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -5436,7 +5483,8 @@ mod tests { let mut recipient_addresses = BTreeMap::new(); recipient_addresses.insert(create_platform_address(1), dash_to_credits!(0.1)); - let transition = create_signed_transition(&identity, &signer, recipient_addresses, 1); + let transition = + create_signed_transition(&identity, &signer, recipient_addresses, 1).await; let result = transition.serialize_to_bytes().expect("should serialize"); let platform_state = platform.state.load(); @@ -5463,8 +5511,8 @@ mod tests { } /// Test overflow when adding fee to transfer amount during balance check - #[test] - fn test_overflow_transfer_plus_fee() { + #[tokio::test] + async fn test_overflow_transfer_plus_fee() { use dpp::state_transition::StateTransitionStructureValidation; let platform_version = PlatformVersion::latest(); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_withdrawal/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_withdrawal/mod.rs index 51ac0dfe636..48bd8344e1c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_withdrawal/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_withdrawal/mod.rs @@ -127,8 +127,8 @@ mod tests { use rand::prelude::StdRng; use rand::{Rng, SeedableRng}; - #[test] - fn test_identity_credit_withdrawal_is_disabled_on_release() { + #[tokio::test] + async fn test_identity_credit_withdrawal_is_disabled_on_release() { let platform_version = PlatformVersion::first(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -174,6 +174,7 @@ mod tests { platform_version, Some(1), ) + .await .expect("expected a credit withdrawal transition"); let credit_withdrawal_transition_serialized_transition = credit_withdrawal_transition @@ -203,8 +204,8 @@ mod tests { ); } - #[test] - fn test_identity_credit_withdrawal_with_withdrawal_address_creates_withdrawal_document() { + #[tokio::test] + async fn test_identity_credit_withdrawal_with_withdrawal_address_creates_withdrawal_document() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -250,6 +251,7 @@ mod tests { platform_version, None, ) + .await .expect("expected a credit withdrawal transition"); let credit_withdrawal_transition_serialized_transition = credit_withdrawal_transition @@ -277,8 +279,8 @@ mod tests { ); } - #[test] - fn test_identity_credit_withdrawal_without_withdrawal_address_creates_withdrawal_document_when_signing_with_withdrawal_key( + #[tokio::test] + async fn test_identity_credit_withdrawal_without_withdrawal_address_creates_withdrawal_document_when_signing_with_withdrawal_key( ) { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -325,6 +327,7 @@ mod tests { platform_version, None, ) + .await .expect("expected a credit withdrawal transition"); let credit_withdrawal_transition_serialized_transition = credit_withdrawal_transition @@ -352,8 +355,8 @@ mod tests { ); } - #[test] - fn test_masternode_credit_withdrawal_without_withdrawal_address_creates_withdrawal_document_when_signing_with_withdrawal_key( + #[tokio::test] + async fn test_masternode_credit_withdrawal_without_withdrawal_address_creates_withdrawal_document_when_signing_with_withdrawal_key( ) { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -399,6 +402,7 @@ mod tests { platform_version, None, ) + .await .expect("expected a credit withdrawal transition"); let credit_withdrawal_transition_serialized_transition = credit_withdrawal_transition @@ -426,8 +430,8 @@ mod tests { ); } - #[test] - fn test_masternode_credit_withdrawal_without_withdrawal_address_creates_withdrawal_document_when_signing_with_owner_key( + #[tokio::test] + async fn test_masternode_credit_withdrawal_without_withdrawal_address_creates_withdrawal_document_when_signing_with_owner_key( ) { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -473,6 +477,7 @@ mod tests { platform_version, None, ) + .await .expect("expected a credit withdrawal transition"); let credit_withdrawal_transition_serialized_transition = credit_withdrawal_transition @@ -503,8 +508,9 @@ mod tests { mod errors { use super::*; use dpp::consensus::state::state_error::StateError; - #[test] - fn test_credit_withdrawal_without_withdrawal_address_with_a_non_payable_transfer_key() { + #[tokio::test] + async fn test_credit_withdrawal_without_withdrawal_address_with_a_non_payable_transfer_key() + { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -551,6 +557,7 @@ mod tests { platform_version, None, ) + .await .expect("expected a credit withdrawal transition"); let credit_withdrawal_transition_serialized_transition = credit_withdrawal_transition @@ -581,8 +588,8 @@ mod tests { ); } - #[test] - fn test_masternode_credit_withdrawal_with_withdrawal_address_creates_when_signing_with_owner_key_should_fail( + #[tokio::test] + async fn test_masternode_credit_withdrawal_with_withdrawal_address_creates_when_signing_with_owner_key_should_fail( ) { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { @@ -629,6 +636,7 @@ mod tests { platform_version, None, ) + .await .expect("expected a credit withdrawal transition"); let credit_withdrawal_transition_serialized_transition = credit_withdrawal_transition diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_top_up_from_addresses/tests.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_top_up_from_addresses/tests.rs index fbf1d17bf99..635394a501e 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_top_up_from_addresses/tests.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_top_up_from_addresses/tests.rs @@ -134,7 +134,7 @@ mod tests { } /// Create a signed IdentityTopUpFromAddressesTransition - fn create_signed_transition( + async fn create_signed_transition( identity: &Identity, signer: &TestAddressSigner, inputs: BTreeMap, @@ -148,11 +148,12 @@ mod tests { platform_version, None, ) + .await .expect("should create signed transition") } /// Create a signed IdentityTopUpFromAddressesTransition with custom options - fn create_signed_transition_with_options( + async fn create_signed_transition_with_options( identity: &Identity, signer: &TestAddressSigner, inputs: BTreeMap, @@ -177,11 +178,15 @@ mod tests { .signable_bytes() .expect("should get signable bytes"); - transition.input_witnesses = inputs - .iter() - .map(|(address, _)| signer.sign_create_witness(address, &signable_bytes)) - .collect::, ProtocolError>>() - .expect("should create witnesses"); + let mut witnesses = Vec::with_capacity(inputs.len()); + for (address, _) in inputs.iter() { + let witness = signer + .sign_create_witness(address, &signable_bytes) + .await + .expect("should create witness"); + witnesses.push(witness); + } + transition.input_witnesses = witnesses; IdentityTopUpFromAddressesTransition::V0(transition).into() } @@ -205,8 +210,8 @@ mod tests { mod structure_validation { use super::*; - #[test] - fn test_no_inputs_returns_error() { + #[tokio::test] + async fn test_no_inputs_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -263,8 +268,8 @@ mod tests { ); } - #[test] - fn test_too_many_inputs_returns_error() { + #[tokio::test] + async fn test_too_many_inputs_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -292,7 +297,8 @@ mod tests { inputs.insert(addr, (1 as AddressNonce, dash_to_credits!(0.01))); } - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -324,8 +330,8 @@ mod tests { // Note: Some structure validation tests use dummy witnesses since // structure validation runs before witness validation for certain error types. - #[test] - fn test_fee_strategy_too_many_steps_returns_error() { + #[tokio::test] + async fn test_fee_strategy_too_many_steps_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -367,7 +373,8 @@ mod tests { ], 0, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -396,8 +403,8 @@ mod tests { ); } - #[test] - fn test_fee_strategy_duplicate_returns_error() { + #[tokio::test] + async fn test_fee_strategy_duplicate_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -434,7 +441,8 @@ mod tests { ], 0, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -463,8 +471,8 @@ mod tests { ); } - #[test] - fn test_fee_strategy_deduct_from_input_out_of_bounds_returns_error() { + #[tokio::test] + async fn test_fee_strategy_deduct_from_input_out_of_bounds_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -498,7 +506,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(5)], // Out of bounds 0, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -527,8 +536,8 @@ mod tests { ); } - #[test] - fn test_fee_strategy_reduce_output_without_output_returns_error() { + #[tokio::test] + async fn test_fee_strategy_reduce_output_without_output_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -562,7 +571,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], // But trying to reduce output 0, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -591,8 +601,8 @@ mod tests { ); } - #[test] - fn test_input_below_minimum_returns_error() { + #[tokio::test] + async fn test_input_below_minimum_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -626,7 +636,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], 0, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -655,8 +666,8 @@ mod tests { ); } - #[test] - fn test_output_below_minimum_returns_error() { + #[tokio::test] + async fn test_output_below_minimum_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -691,7 +702,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], 0, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -720,8 +732,8 @@ mod tests { ); } - #[test] - fn test_inputs_not_exceeding_outputs_plus_min_funding_returns_error() { + #[tokio::test] + async fn test_inputs_not_exceeding_outputs_plus_min_funding_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -759,7 +771,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], 0, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -788,8 +801,8 @@ mod tests { ); } - #[test] - fn test_inputs_equal_outputs_returns_error() { + #[tokio::test] + async fn test_inputs_equal_outputs_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -827,7 +840,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], 0, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -857,8 +871,8 @@ mod tests { ); } - #[test] - fn test_empty_fee_strategy_returns_error() { + #[tokio::test] + async fn test_empty_fee_strategy_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -892,7 +906,8 @@ mod tests { vec![], // Empty fee strategy 0, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -921,8 +936,8 @@ mod tests { ); } - #[test] - fn test_input_witness_count_mismatch_more_witnesses_returns_signature_error() { + #[tokio::test] + async fn test_input_witness_count_mismatch_more_witnesses_returns_signature_error() { // NOTE: When there are MORE witnesses than inputs with dummy/invalid signatures, // signature validation fails before the structure validation mismatch check. // This is expected behavior - signatures are validated before structure. @@ -989,8 +1004,8 @@ mod tests { ); } - #[test] - fn test_input_witness_count_mismatch_zero_witnesses_returns_error() { + #[tokio::test] + async fn test_input_witness_count_mismatch_zero_witnesses_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1053,8 +1068,8 @@ mod tests { ); } - #[test] - fn test_input_sum_overflow_caught_by_state_validation() { + #[tokio::test] + async fn test_input_sum_overflow_caught_by_state_validation() { // NOTE: This test verifies that attempting to claim more funds than exist // is caught by state validation (AddressNotEnoughFundsError) BEFORE // structure validation has a chance to check for overflow. @@ -1108,7 +1123,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], 0, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -1139,8 +1155,8 @@ mod tests { ); } - #[test] - fn test_required_input_overflow_returns_error() { + #[tokio::test] + async fn test_required_input_overflow_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1178,7 +1194,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], 0, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -1215,8 +1232,8 @@ mod tests { mod state_validation { use super::*; - #[test] - fn test_identity_not_found_returns_error() { + #[tokio::test] + async fn test_identity_not_found_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1249,7 +1266,7 @@ mod tests { inputs.insert(input_address, (1 as AddressNonce, dash_to_credits!(0.5))); let transition = - create_signed_transition(&fake_identity, &signer, inputs, platform_version); + create_signed_transition(&fake_identity, &signer, inputs, platform_version).await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -1282,8 +1299,8 @@ mod tests { ); } - #[test] - fn test_address_not_found_returns_error() { + #[tokio::test] + async fn test_address_not_found_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1308,7 +1325,8 @@ mod tests { let mut inputs = BTreeMap::new(); inputs.insert(input_address, (1 as AddressNonce, dash_to_credits!(0.5))); - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -1337,8 +1355,8 @@ mod tests { ); } - #[test] - fn test_insufficient_balance_returns_error() { + #[tokio::test] + async fn test_insufficient_balance_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1364,7 +1382,8 @@ mod tests { let mut inputs = BTreeMap::new(); inputs.insert(input_address, (1 as AddressNonce, dash_to_credits!(0.5))); // More than available - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -1393,8 +1412,8 @@ mod tests { ); } - #[test] - fn test_invalid_nonce_returns_error() { + #[tokio::test] + async fn test_invalid_nonce_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1419,7 +1438,8 @@ mod tests { let mut inputs = BTreeMap::new(); inputs.insert(input_address, (1 as AddressNonce, dash_to_credits!(0.5))); // nonce 1, but should be 6 - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let result = transition.serialize_to_bytes(); assert!(result.is_ok()); @@ -1456,8 +1476,8 @@ mod tests { mod successful_execution { use super::*; - #[test] - fn test_simple_topup_succeeds() { + #[tokio::test] + async fn test_simple_topup_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1485,7 +1505,8 @@ mod tests { let mut inputs = BTreeMap::new(); inputs.insert(input_address, (1 as AddressNonce, topup_amount)); - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -1511,8 +1532,8 @@ mod tests { ); } - #[test] - fn test_topup_with_multiple_inputs_succeeds() { + #[tokio::test] + async fn test_topup_with_multiple_inputs_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1541,7 +1562,8 @@ mod tests { inputs.insert(input1, (1 as AddressNonce, dash_to_credits!(0.3))); inputs.insert(input2, (1 as AddressNonce, dash_to_credits!(0.3))); - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -1567,8 +1589,8 @@ mod tests { ); } - #[test] - fn test_topup_with_p2sh_multisig_succeeds() { + #[tokio::test] + async fn test_topup_with_p2sh_multisig_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1602,7 +1624,8 @@ mod tests { let mut inputs = BTreeMap::new(); inputs.insert(input_address, (1 as AddressNonce, dash_to_credits!(0.5))); - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -1628,8 +1651,8 @@ mod tests { ); } - #[test] - fn test_check_tx_accepts_valid_topup() { + #[tokio::test] + async fn test_check_tx_accepts_valid_topup() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1654,7 +1677,8 @@ mod tests { let mut inputs = BTreeMap::new(); inputs.insert(input_address, (1 as AddressNonce, dash_to_credits!(0.5))); - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); assert!(check_tx_is_valid( @@ -1664,8 +1688,8 @@ mod tests { )); } - #[test] - fn test_check_tx_rejects_invalid_nonce() { + #[tokio::test] + async fn test_check_tx_rejects_invalid_nonce() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1690,7 +1714,8 @@ mod tests { let mut inputs = BTreeMap::new(); inputs.insert(input_address, (1 as AddressNonce, dash_to_credits!(0.5))); // Wrong nonce - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); assert!(!check_tx_is_valid( @@ -1700,8 +1725,8 @@ mod tests { )); } - #[test] - fn test_consecutive_topups_from_same_address() { + #[tokio::test] + async fn test_consecutive_topups_from_same_address() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1728,7 +1753,7 @@ mod tests { inputs1.insert(input_address, (1 as AddressNonce, dash_to_credits!(0.3))); let transition1 = - create_signed_transition(&identity, &signer, inputs1, platform_version); + create_signed_transition(&identity, &signer, inputs1, platform_version).await; let bytes1 = transition1.serialize_to_bytes().unwrap(); let platform_state = platform.state.load(); @@ -1765,7 +1790,7 @@ mod tests { inputs2.insert(input_address, (2 as AddressNonce, dash_to_credits!(0.3))); let transition2 = - create_signed_transition(&identity, &signer, inputs2, platform_version); + create_signed_transition(&identity, &signer, inputs2, platform_version).await; let bytes2 = transition2.serialize_to_bytes().unwrap(); let platform_state = platform.state.load(); @@ -1798,8 +1823,8 @@ mod tests { mod signature_validation { use super::*; - #[test] - fn test_invalid_signature_returns_error() { + #[tokio::test] + async fn test_invalid_signature_returns_error() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1872,8 +1897,8 @@ mod tests { use super::*; /// Output address cannot be the same as an input address - this is validated - #[test] - fn test_topup_with_output_to_same_address_fails() { + #[tokio::test] + async fn test_topup_with_output_to_same_address_fails() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1912,7 +1937,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], 0, platform_version, - ); + ) + .await; let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -1941,8 +1967,8 @@ mod tests { ); } - #[test] - fn test_topup_with_output_to_different_address_succeeds() { + #[tokio::test] + async fn test_topup_with_output_to_different_address_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1979,7 +2005,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], 0, platform_version, - ); + ) + .await; let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -2005,8 +2032,8 @@ mod tests { ); } - #[test] - fn test_topup_with_output_to_p2sh_address_succeeds() { + #[tokio::test] + async fn test_topup_with_output_to_p2sh_address_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2052,7 +2079,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], 0, platform_version, - ); + ) + .await; let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -2086,8 +2114,8 @@ mod tests { mod fee_strategy { use super::*; - #[test] - fn test_deduct_from_second_input_succeeds() { + #[tokio::test] + async fn test_deduct_from_second_input_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2124,7 +2152,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(1)], 0, platform_version, - ); + ) + .await; let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -2150,8 +2179,8 @@ mod tests { ); } - #[test] - fn test_reduce_output_fee_strategy_succeeds() { + #[tokio::test] + async fn test_reduce_output_fee_strategy_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2187,7 +2216,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::ReduceOutput(0)], 0, platform_version, - ); + ) + .await; let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -2213,8 +2243,8 @@ mod tests { ); } - #[test] - fn test_multiple_fee_strategy_steps_succeeds() { + #[tokio::test] + async fn test_multiple_fee_strategy_steps_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2254,7 +2284,8 @@ mod tests { ], 0, platform_version, - ); + ) + .await; let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -2288,8 +2319,8 @@ mod tests { mod user_fee_increase { use super::*; - #[test] - fn test_topup_with_user_fee_increase_succeeds() { + #[tokio::test] + async fn test_topup_with_user_fee_increase_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2323,7 +2354,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], 50, // 5% fee increase platform_version, - ); + ) + .await; let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -2349,8 +2381,8 @@ mod tests { ); } - #[test] - fn test_topup_with_zero_fee_increase_succeeds() { + #[tokio::test] + async fn test_topup_with_zero_fee_increase_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2384,7 +2416,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], 0, platform_version, - ); + ) + .await; let transition_bytes = transition.serialize_to_bytes().unwrap(); @@ -2418,8 +2451,8 @@ mod tests { mod balance_verification { use super::*; - #[test] - fn test_identity_balance_increases_after_topup() { + #[tokio::test] + async fn test_identity_balance_increases_after_topup() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2446,7 +2479,8 @@ mod tests { let mut inputs = BTreeMap::new(); inputs.insert(input_address, (1 as AddressNonce, topup_amount)); - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); let platform_state = platform.state.load(); @@ -2491,8 +2525,8 @@ mod tests { /// Test that nonce correctly progresses by doing two consecutive topups. /// If the first topup didn't increment the nonce, the second topup would fail. - #[test] - fn test_nonce_increments_after_topup_verified_by_consecutive_tx() { + #[tokio::test] + async fn test_nonce_increments_after_topup_verified_by_consecutive_tx() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2528,7 +2562,7 @@ mod tests { ); let transition1 = - create_signed_transition(&identity, &signer, inputs1, platform_version); + create_signed_transition(&identity, &signer, inputs1, platform_version).await; let transition_bytes1 = transition1.serialize_to_bytes().unwrap(); let platform_state = platform.state.load(); @@ -2568,7 +2602,7 @@ mod tests { ); let transition2 = - create_signed_transition(&identity, &signer, inputs2, platform_version); + create_signed_transition(&identity, &signer, inputs2, platform_version).await; let transition_bytes2 = transition2.serialize_to_bytes().unwrap(); let platform_state = platform.state.load(); @@ -2602,8 +2636,8 @@ mod tests { mod edge_cases { use super::*; - #[test] - fn test_exactly_16_inputs_succeeds() { + #[tokio::test] + async fn test_exactly_16_inputs_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2630,7 +2664,8 @@ mod tests { inputs.insert(addr, (1 as AddressNonce, dash_to_credits!(0.1))); } - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); let platform_state = platform.state.load(); @@ -2655,8 +2690,8 @@ mod tests { ); } - #[test] - fn test_minimum_funding_amount_succeeds() { + #[tokio::test] + async fn test_minimum_funding_amount_succeeds() { // min_identity_funding_amount is 200,000 credits // Inputs must exceed outputs + 200,000 to provide minimum funding let platform_version = PlatformVersion::latest(); @@ -2686,7 +2721,8 @@ mod tests { let mut inputs = BTreeMap::new(); inputs.insert(input_address, (1 as AddressNonce, input_amount)); - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); let platform_state = platform.state.load(); @@ -2711,8 +2747,8 @@ mod tests { ); } - #[test] - fn test_large_topup_amount_succeeds() { + #[tokio::test] + async fn test_large_topup_amount_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2739,7 +2775,8 @@ mod tests { let mut inputs = BTreeMap::new(); inputs.insert(input_address, (1 as AddressNonce, large_topup)); - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); let platform_state = platform.state.load(); @@ -2764,8 +2801,8 @@ mod tests { ); } - #[test] - fn test_mixed_p2pkh_and_p2sh_inputs_succeeds() { + #[tokio::test] + async fn test_mixed_p2pkh_and_p2sh_inputs_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2804,7 +2841,8 @@ mod tests { inputs.insert(p2pkh_input, (1 as AddressNonce, dash_to_credits!(0.3))); inputs.insert(p2sh_input, (1 as AddressNonce, dash_to_credits!(0.3))); - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); let platform_state = platform.state.load(); @@ -2832,8 +2870,8 @@ mod tests { /// Identity with zero balance CAN process topup because fees are paid from /// the address funds (via fee strategy), not from identity balance. /// This is the correct behavior for address-based state transitions. - #[test] - fn test_identity_with_zero_balance_topup_succeeds() { + #[tokio::test] + async fn test_identity_with_zero_balance_topup_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2859,7 +2897,8 @@ mod tests { let mut inputs = BTreeMap::new(); inputs.insert(input_address, (1 as AddressNonce, dash_to_credits!(0.5))); - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); let platform_state = platform.state.load(); @@ -2886,8 +2925,8 @@ mod tests { } /// Identity with low but non-zero balance can topup if it has enough to pay fees - #[test] - fn test_identity_with_low_balance_topup_succeeds() { + #[tokio::test] + async fn test_identity_with_low_balance_topup_succeeds() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2913,7 +2952,8 @@ mod tests { let mut inputs = BTreeMap::new(); inputs.insert(input_address, (1 as AddressNonce, dash_to_credits!(0.5))); - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); let platform_state = platform.state.load(); @@ -2946,8 +2986,8 @@ mod tests { mod multiple_addresses { use super::*; - #[test] - fn test_multiple_addresses_one_invalid_nonce_fails() { + #[tokio::test] + async fn test_multiple_addresses_one_invalid_nonce_fails() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -2975,7 +3015,8 @@ mod tests { inputs.insert(input1, (1 as AddressNonce, dash_to_credits!(0.3))); // correct: 1 inputs.insert(input2, (1 as AddressNonce, dash_to_credits!(0.3))); // wrong: should be 6 - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); let platform_state = platform.state.load(); @@ -3002,8 +3043,8 @@ mod tests { ); } - #[test] - fn test_multiple_addresses_one_insufficient_balance_fails() { + #[tokio::test] + async fn test_multiple_addresses_one_insufficient_balance_fails() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3031,7 +3072,8 @@ mod tests { inputs.insert(input1, (1 as AddressNonce, dash_to_credits!(0.3))); inputs.insert(input2, (1 as AddressNonce, dash_to_credits!(0.5))); // More than available - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); let platform_state = platform.state.load(); @@ -3058,8 +3100,8 @@ mod tests { ); } - #[test] - fn test_multiple_addresses_one_not_found_fails() { + #[tokio::test] + async fn test_multiple_addresses_one_not_found_fails() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3087,7 +3129,8 @@ mod tests { inputs.insert(input1, (1 as AddressNonce, dash_to_credits!(0.3))); inputs.insert(input2, (1 as AddressNonce, dash_to_credits!(0.3))); - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); let platform_state = platform.state.load(); @@ -3122,8 +3165,8 @@ mod tests { mod check_tx_additional { use super::*; - #[test] - fn test_check_tx_rejects_nonexistent_identity() { + #[tokio::test] + async fn test_check_tx_rejects_nonexistent_identity() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3156,7 +3199,7 @@ mod tests { inputs.insert(input_address, (1 as AddressNonce, dash_to_credits!(0.5))); let transition = - create_signed_transition(&fake_identity, &signer, inputs, platform_version); + create_signed_transition(&fake_identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); assert!(!check_tx_is_valid( @@ -3166,8 +3209,8 @@ mod tests { )); } - #[test] - fn test_check_tx_rejects_nonexistent_address() { + #[tokio::test] + async fn test_check_tx_rejects_nonexistent_address() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3192,7 +3235,8 @@ mod tests { let mut inputs = BTreeMap::new(); inputs.insert(input_address, (1 as AddressNonce, dash_to_credits!(0.5))); - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); assert!(!check_tx_is_valid( @@ -3202,8 +3246,8 @@ mod tests { )); } - #[test] - fn test_check_tx_rejects_insufficient_balance() { + #[tokio::test] + async fn test_check_tx_rejects_insufficient_balance() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3228,7 +3272,8 @@ mod tests { let mut inputs = BTreeMap::new(); inputs.insert(input_address, (1 as AddressNonce, dash_to_credits!(0.5))); // More than available - let transition = create_signed_transition(&identity, &signer, inputs, platform_version); + let transition = + create_signed_transition(&identity, &signer, inputs, platform_version).await; let transition_bytes = transition.serialize_to_bytes().unwrap(); assert!(!check_tx_is_valid( @@ -3238,8 +3283,8 @@ mod tests { )); } - #[test] - fn test_check_tx_accepts_valid_with_output() { + #[tokio::test] + async fn test_check_tx_accepts_valid_with_output() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3273,7 +3318,8 @@ mod tests { vec![AddressFundsFeeStrategyStep::DeductFromInput(0)], 0, platform_version, - ); + ) + .await; let transition_bytes = transition.serialize_to_bytes().unwrap(); assert!(check_tx_is_valid( @@ -3295,8 +3341,8 @@ mod tests { /// because all indices shifted down after the removal. /// /// Location: rs-dpp/.../deduct_fee_from_inputs_and_outputs/v0/mod.rs:35-45 - #[test] - fn test_fee_deduction_stable_after_entry_removal() { + #[tokio::test] + async fn test_fee_deduction_stable_after_entry_removal() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -3358,7 +3404,8 @@ mod tests { fee_strategy, 0, platform_version, - ); + ) + .await; let result = transition.serialize_to_bytes().expect("should serialize"); @@ -3421,8 +3468,8 @@ mod tests { /// the transformer lacks defense-in-depth. /// /// Location: rs-drive/.../identity_top_up_from_addresses/v0/transformer.rs:24,28 - #[test] - fn test_transformer_subtraction_uses_checked_arithmetic() { + #[tokio::test] + async fn test_transformer_subtraction_uses_checked_arithmetic() { use crate::execution::validation::state_transition::processor::traits::basic_structure::StateTransitionBasicStructureValidationV0; let platform_version = PlatformVersion::latest(); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs index a3da69bbddf..77e0d67c340 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs @@ -151,8 +151,8 @@ mod tests { use rand::rngs::StdRng; use rand::SeedableRng; - #[test] - fn test_identity_update_that_disables_an_authentication_key() { + #[tokio::test] + async fn test_identity_update_that_disables_an_authentication_key() { let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -193,6 +193,7 @@ mod tests { update_transition.set_signature( signer .sign(&key, data.as_slice()) + .await .expect("expected to sign"), ); @@ -233,8 +234,8 @@ mod tests { assert_eq!(issues.len(), 0); } - #[test] - fn test_identity_update_that_adds_an_authentication_key() { + #[tokio::test] + async fn test_identity_update_that_adds_an_authentication_key() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -304,6 +305,7 @@ mod tests { update_transition.set_signature( signer .sign(&key, signable_bytes.as_slice()) + .await .expect("expected to sign"), ); @@ -373,8 +375,8 @@ mod tests { }; } - #[test] - fn test_identity_update_that_disables_an_encryption_key() { + #[tokio::test] + async fn test_identity_update_that_disables_an_encryption_key() { let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -449,6 +451,7 @@ mod tests { update_transition.set_signature( signer .sign(&master_key, data.as_slice()) + .await .expect("expected to sign"), ); @@ -498,8 +501,8 @@ mod tests { ); } - #[test] - fn test_identity_update_adding_owner_key_not_allowed() { + #[tokio::test] + async fn test_identity_update_adding_owner_key_not_allowed() { let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -557,6 +560,7 @@ mod tests { update_transition.set_signature( signer .sign(&key, data.as_slice()) + .await .expect("expected to sign"), ); @@ -603,8 +607,8 @@ mod tests { assert_eq!(issues.len(), 0); } - #[test] - fn test_identity_update_adding_contract_bound_key() { + #[tokio::test] + async fn test_identity_update_adding_contract_bound_key() { use crate::execution::validation::state_transition::tests::{ register_contract_from_bytes, IdentityTestInfo, }; @@ -705,7 +709,8 @@ mod tests { identity_nonce: 1, }, platform_version, - ); + ) + .await; let secp = Secp256k1::new(); @@ -770,6 +775,7 @@ mod tests { update_transition.set_signature( signer .sign(&master_key, signable_bytes.as_slice()) + .await .expect("expected to sign"), ); @@ -836,8 +842,8 @@ mod tests { ); } - #[test] - fn test_identity_update_adding_contract_bound_key_on_document_level() { + #[tokio::test] + async fn test_identity_update_adding_contract_bound_key_on_document_level() { use crate::execution::validation::state_transition::tests::{ register_contract_from_bytes, IdentityTestInfo, }; @@ -1132,7 +1138,8 @@ mod tests { identity_nonce: 1, }, platform_version, - ); + ) + .await; let secp = Secp256k1::new(); @@ -1198,6 +1205,7 @@ mod tests { update_transition.set_signature( signer .sign(&master_key, signable_bytes.as_slice()) + .await .expect("expected to sign"), ); @@ -1265,8 +1273,8 @@ mod tests { ); } - #[test] - fn test_identity_update_empty_transition_rejected() { + #[tokio::test] + async fn test_identity_update_empty_transition_rejected() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1306,6 +1314,7 @@ mod tests { update_transition.set_signature( signer .sign(&key, data.as_slice()) + .await .expect("expected to sign"), ); @@ -1337,8 +1346,8 @@ mod tests { ); } - #[test] - fn test_identity_update_too_many_keys_to_disable() { + #[tokio::test] + async fn test_identity_update_too_many_keys_to_disable() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1380,6 +1389,7 @@ mod tests { update_transition.set_signature( signer .sign(&key, data.as_slice()) + .await .expect("expected to sign"), ); @@ -1411,8 +1421,8 @@ mod tests { ); } - #[test] - fn test_identity_update_duplicate_key_ids_to_disable() { + #[tokio::test] + async fn test_identity_update_duplicate_key_ids_to_disable() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1452,6 +1462,7 @@ mod tests { update_transition.set_signature( signer .sign(&key, data.as_slice()) + .await .expect("expected to sign"), ); @@ -1483,8 +1494,8 @@ mod tests { ); } - #[test] - fn test_identity_update_disabling_key_id_also_being_added() { + #[tokio::test] + async fn test_identity_update_disabling_key_id_also_being_added() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1539,6 +1550,7 @@ mod tests { update_transition.set_signature( signer .sign(&key, data.as_slice()) + .await .expect("expected to sign"), ); @@ -1570,8 +1582,8 @@ mod tests { ); } - #[test] - fn test_identity_update_wrong_revision() { + #[tokio::test] + async fn test_identity_update_wrong_revision() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1611,6 +1623,7 @@ mod tests { update_transition.set_signature( signer .sign(&key, data.as_slice()) + .await .expect("expected to sign"), ); @@ -1640,8 +1653,8 @@ mod tests { ); } - #[test] - fn test_identity_update_disabling_nonexistent_key() { + #[tokio::test] + async fn test_identity_update_disabling_nonexistent_key() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1681,6 +1694,7 @@ mod tests { update_transition.set_signature( signer .sign(&key, data.as_slice()) + .await .expect("expected to sign"), ); @@ -1710,8 +1724,8 @@ mod tests { ); } - #[test] - fn test_identity_update_adding_key_with_existing_id() { + #[tokio::test] + async fn test_identity_update_adding_key_with_existing_id() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -1796,6 +1810,7 @@ mod tests { update_transition.set_signature( signer .sign(&key, signable_bytes.as_slice()) + .await .expect("expected to sign"), ); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/masternode_vote/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/masternode_vote/mod.rs index e5839713859..3707d37c101 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/masternode_vote/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/masternode_vote/mod.rs @@ -181,8 +181,8 @@ mod tests { use super::*; use dapi_grpc::platform::v0::get_contested_resources_request::get_contested_resources_request_v0; - #[test] - fn test_not_proved_contests_request() { + #[tokio::test] + async fn test_not_proved_contests_request() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -197,7 +197,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; verify_dpns_name_contest( &mut platform, @@ -215,7 +216,8 @@ mod tests { 8, "cooldog", platform_version, - ); + ) + .await; verify_dpns_name_contest( &mut platform, @@ -283,8 +285,8 @@ mod tests { assert_eq!(contested_resource_values.len(), 2); } - #[test] - fn test_proved_contests_request() { + #[tokio::test] + async fn test_proved_contests_request() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -299,7 +301,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let (_identity_3, _identity_4, dpns_contract) = create_dpns_identity_name_contest( &mut platform, @@ -307,7 +310,8 @@ mod tests { 8, "cooldog", platform_version, - ); + ) + .await; let domain = dpns_contract .document_type_for_name("domain") @@ -378,8 +382,8 @@ mod tests { assert_eq!(contests.len(), 2); } - #[test] - fn test_empty_string_start_index_value() { + #[tokio::test] + async fn test_empty_string_start_index_value() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -388,13 +392,15 @@ mod tests { let platform_state = platform.state.load(); - let (_contender_1, _contender_2, dpns_contract) = create_dpns_identity_name_contest( - &mut platform, - &platform_state, - 7, - "quantum", - platform_version, - ); + let (_contender_1, _contender_2, dpns_contract) = + create_dpns_identity_name_contest( + &mut platform, + &platform_state, + 7, + "quantum", + platform_version, + ) + .await; let domain = dpns_contract .document_type_for_name("domain") @@ -512,8 +518,8 @@ mod tests { } } - #[test] - fn test_no_start_index_value() { + #[tokio::test] + async fn test_no_start_index_value() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -522,13 +528,15 @@ mod tests { let platform_state = platform.state.load(); - let (_contender_1, _contender_2, dpns_contract) = create_dpns_identity_name_contest( - &mut platform, - &platform_state, - 7, - "quantum", - platform_version, - ); + let (_contender_1, _contender_2, dpns_contract) = + create_dpns_identity_name_contest( + &mut platform, + &platform_state, + 7, + "quantum", + platform_version, + ) + .await; let domain = dpns_contract .document_type_for_name("domain") @@ -653,8 +661,8 @@ mod tests { } } - #[test] - fn test_existing_end_index_value() { + #[tokio::test] + async fn test_existing_end_index_value() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -663,13 +671,15 @@ mod tests { let platform_state = platform.state.load(); - let (_contender_1, _contender_2, dpns_contract) = create_dpns_identity_name_contest( - &mut platform, - &platform_state, - 7, - "quantum", - platform_version, - ); + let (_contender_1, _contender_2, dpns_contract) = + create_dpns_identity_name_contest( + &mut platform, + &platform_state, + 7, + "quantum", + platform_version, + ) + .await; let domain = dpns_contract .document_type_for_name("domain") @@ -798,8 +808,8 @@ mod tests { } } - #[test] - fn test_non_existing_end_index_value() { + #[tokio::test] + async fn test_non_existing_end_index_value() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -808,13 +818,15 @@ mod tests { let platform_state = platform.state.load(); - let (_contender_1, _contender_2, dpns_contract) = create_dpns_identity_name_contest( - &mut platform, - &platform_state, - 7, - "quantum", - platform_version, - ); + let (_contender_1, _contender_2, dpns_contract) = + create_dpns_identity_name_contest( + &mut platform, + &platform_state, + 7, + "quantum", + platform_version, + ) + .await; let domain = dpns_contract .document_type_for_name("domain") @@ -933,8 +945,8 @@ mod tests { } } - #[test] - fn test_non_existing_end_index_value_many_values() { + #[tokio::test] + async fn test_non_existing_end_index_value_many_values() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -943,13 +955,15 @@ mod tests { let platform_state = platform.state.load(); - let (_contender_1, _contender_2, dpns_contract) = create_dpns_identity_name_contest( - &mut platform, - &platform_state, - 7, - "quantum", - platform_version, - ); + let (_contender_1, _contender_2, dpns_contract) = + create_dpns_identity_name_contest( + &mut platform, + &platform_state, + 7, + "quantum", + platform_version, + ) + .await; let domain = dpns_contract .document_type_for_name("domain") @@ -1032,8 +1046,8 @@ mod tests { } } - #[test] - fn test_limit() { + #[tokio::test] + async fn test_limit() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1049,7 +1063,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let (_contender_3, _contender_4, _dpns_contract) = create_dpns_identity_name_contest( @@ -1058,15 +1073,18 @@ mod tests { 8, "coya", platform_version, - ); + ) + .await; - let (_contender_5, _contender_6, dpns_contract) = create_dpns_identity_name_contest( - &mut platform, - &platform_state, - 9, - "tobe", - platform_version, - ); + let (_contender_5, _contender_6, dpns_contract) = + create_dpns_identity_name_contest( + &mut platform, + &platform_state, + 9, + "tobe", + platform_version, + ) + .await; let domain = dpns_contract .document_type_for_name("domain") @@ -1184,8 +1202,8 @@ mod tests { } } - #[test] - fn test_start_at() { + #[tokio::test] + async fn test_start_at() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1201,7 +1219,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let (_contender_3, _contender_4, _dpns_contract) = create_dpns_identity_name_contest( @@ -1210,15 +1229,18 @@ mod tests { 8, "coya", platform_version, - ); + ) + .await; - let (_contender_5, _contender_6, dpns_contract) = create_dpns_identity_name_contest( - &mut platform, - &platform_state, - 9, - "tobe", - platform_version, - ); + let (_contender_5, _contender_6, dpns_contract) = + create_dpns_identity_name_contest( + &mut platform, + &platform_state, + 9, + "tobe", + platform_version, + ) + .await; let domain = dpns_contract .document_type_for_name("domain") @@ -1366,8 +1388,8 @@ mod tests { get_contested_resource_vote_state_request, GetContestedResourceVoteStateRequest, }; - #[test] - fn test_not_proved_vote_state_query_request_after_vote() { + #[tokio::test] + async fn test_not_proved_vote_state_query_request_after_vote() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1382,7 +1404,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let (pro_tx_hash_1, _masternode_1, signer_1, voting_key_1) = setup_masternode_voting_identity(&mut platform, 29, platform_version); @@ -1401,7 +1424,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; // Documents and Tally { @@ -1517,8 +1541,8 @@ mod tests { } } - #[test] - fn test_proved_vote_state_query_request_after_vote() { + #[tokio::test] + async fn test_proved_vote_state_query_request_after_vote() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1533,7 +1557,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let (pro_tx_hash_1, _masternode_1, signer_1, voting_key_1) = setup_masternode_voting_identity(&mut platform, 29, platform_version); @@ -1552,7 +1577,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; { let (contenders, abstaining, locking, finished_info) = get_proved_vote_states( @@ -1665,8 +1691,8 @@ mod tests { } } - #[test] - fn test_not_proved_vote_state_query_request_after_many_votes() { + #[tokio::test] + async fn test_not_proved_vote_state_query_request_after_many_votes() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1681,7 +1707,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -1696,7 +1723,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; // DocumentsAndVoteTally { @@ -1922,8 +1950,8 @@ mod tests { } } - #[test] - fn test_proved_vote_state_query_request_after_many_votes() { + #[tokio::test] + async fn test_proved_vote_state_query_request_after_many_votes() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1938,7 +1966,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -1953,7 +1982,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; // DocumentsAndVoteTally { @@ -2234,8 +2264,8 @@ mod tests { ); } - #[test] - fn test_vote_state_query_request_with_no_index_values_should_return_error() { + #[tokio::test] + async fn test_vote_state_query_request_with_no_index_values_should_return_error() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -2250,7 +2280,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -2265,7 +2296,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; // DocumentsAndVoteTally { @@ -2361,8 +2393,8 @@ mod tests { } } - #[test] - fn test_vote_state_query_request_with_limit_too_high_should_return_error() { + #[tokio::test] + async fn test_vote_state_query_request_with_limit_too_high_should_return_error() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -2377,7 +2409,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -2392,7 +2425,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; let config = bincode::config::standard() .with_big_endian() @@ -2503,8 +2537,8 @@ mod tests { } } - #[test] - fn test_vote_state_query_request_with_limit_4_should_return_4_contenders() { + #[tokio::test] + async fn test_vote_state_query_request_with_limit_4_should_return_4_contenders() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -2519,23 +2553,28 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; - let (contender_3, _contender_4, _dpns_contract) = create_dpns_identity_name_contest( - &mut platform, - &platform_state, - 8, - "quantum", - platform_version, - ); + let (contender_3, _contender_4, _dpns_contract) = + create_dpns_identity_name_contest( + &mut platform, + &platform_state, + 8, + "quantum", + platform_version, + ) + .await; - let (_contender_5, _contender_6, dpns_contract) = create_dpns_identity_name_contest( - &mut platform, - &platform_state, - 9, - "quantum", - platform_version, - ); + let (_contender_5, _contender_6, dpns_contract) = + create_dpns_identity_name_contest( + &mut platform, + &platform_state, + 9, + "quantum", + platform_version, + ) + .await; perform_votes_multi( &mut platform, @@ -2551,7 +2590,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; // DocumentsAndVoteTally { @@ -2665,8 +2705,9 @@ mod tests { } } - #[test] - fn test_proved_vote_state_query_request_with_limit_4_should_return_4_contenders() { + #[tokio::test] + async fn test_proved_vote_state_query_request_with_limit_4_should_return_4_contenders() + { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -2681,23 +2722,28 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; - let (contender_3, _contender_4, _dpns_contract) = create_dpns_identity_name_contest( - &mut platform, - &platform_state, - 8, - "quantum", - platform_version, - ); + let (contender_3, _contender_4, _dpns_contract) = + create_dpns_identity_name_contest( + &mut platform, + &platform_state, + 8, + "quantum", + platform_version, + ) + .await; - let (_contender_5, _contender_6, dpns_contract) = create_dpns_identity_name_contest( - &mut platform, - &platform_state, - 9, - "quantum", - platform_version, - ); + let (_contender_5, _contender_6, dpns_contract) = + create_dpns_identity_name_contest( + &mut platform, + &platform_state, + 9, + "quantum", + platform_version, + ) + .await; perform_votes_multi( &mut platform, @@ -2713,7 +2759,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; // DocumentsAndVoteTally { @@ -3028,8 +3075,8 @@ mod tests { voters } - #[test] - fn test_non_proved_contestant_votes_query_request() { + #[tokio::test] + async fn test_non_proved_contestant_votes_query_request() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -3044,7 +3091,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let (contender_3, _, _) = create_dpns_identity_name_contest( &mut platform, @@ -3052,7 +3100,8 @@ mod tests { 9, "quantum", platform_version, - ); + ) + .await; for i in 0..50 { let (pro_tx_hash, _masternode, signer, voting_key) = @@ -3072,7 +3121,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; } for i in 0..5 { @@ -3093,7 +3143,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; } for i in 0..8 { @@ -3114,7 +3165,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; } let voters = get_contestant_votes( &platform, @@ -3196,7 +3248,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; } let voters = get_contestant_votes( @@ -3232,7 +3285,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; } let voters = get_contestant_votes( @@ -3272,8 +3326,8 @@ mod tests { assert_eq!(voters_reversed_30, reversed_last_30_from_100_query); } - #[test] - fn test_proved_contestant_votes_query_request() { + #[tokio::test] + async fn test_proved_contestant_votes_query_request() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -3288,7 +3342,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let (contender_3, _, _) = create_dpns_identity_name_contest( &mut platform, @@ -3296,7 +3351,8 @@ mod tests { 9, "quantum", platform_version, - ); + ) + .await; for i in 0..50 { let (pro_tx_hash, _masternode, signer, voting_key) = @@ -3316,7 +3372,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; } for i in 0..5 { @@ -3337,7 +3394,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; } for i in 0..8 { @@ -3358,7 +3416,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; } let voters_1 = get_proved_contestant_votes( @@ -3580,8 +3639,8 @@ mod tests { .collect() } - #[test] - fn test_not_proved_identity_given_votes_query_request() { + #[tokio::test] + async fn test_not_proved_identity_given_votes_query_request() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -3597,7 +3656,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let (_contender_1_cooldog, contender_2_cooldog, _dpns_contract) = create_dpns_identity_name_contest( @@ -3606,7 +3666,8 @@ mod tests { 8, "cooldog", platform_version, - ); + ) + .await; let (_contender_1_superman, _contender_2_superman, dpns_contract) = create_dpns_identity_name_contest( @@ -3615,7 +3676,8 @@ mod tests { 9, "superman", platform_version, - ); + ) + .await; let (pro_tx_hash, _masternode, signer, voting_key) = setup_masternode_voting_identity(&mut platform, 10, platform_version); @@ -3636,7 +3698,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -3652,7 +3715,8 @@ mod tests { 2, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -3668,7 +3732,8 @@ mod tests { 3, None, platform_version, - ); + ) + .await; let mut votes = get_identity_given_votes( &platform, @@ -3743,8 +3808,8 @@ mod tests { ); } - #[test] - fn test_proved_identity_given_votes_query_request() { + #[tokio::test] + async fn test_proved_identity_given_votes_query_request() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -3760,7 +3825,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let (_contender_1_cooldog, contender_2_cooldog, _dpns_contract) = create_dpns_identity_name_contest( @@ -3769,7 +3835,8 @@ mod tests { 8, "cooldog", platform_version, - ); + ) + .await; let (_contender_1_superman, _contender_2_superman, dpns_contract) = create_dpns_identity_name_contest( @@ -3778,7 +3845,8 @@ mod tests { 9, "superman", platform_version, - ); + ) + .await; let (pro_tx_hash, _masternode, signer, voting_key) = setup_masternode_voting_identity(&mut platform, 10, platform_version); @@ -3799,7 +3867,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -3815,7 +3884,8 @@ mod tests { 2, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -3831,7 +3901,8 @@ mod tests { 3, None, platform_version, - ); + ) + .await; let mut votes = get_proved_identity_given_votes( &platform, @@ -3910,8 +3981,8 @@ mod tests { use super::*; use crate::config::PlatformConfig; - #[test] - fn test_not_proved_end_date_query_request() { + #[tokio::test] + async fn test_not_proved_end_date_query_request() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_config(PlatformConfig::default_mainnet()) @@ -3927,7 +3998,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let GetVotePollsByEndDateResponse { version } = platform .query_vote_polls_by_end_date_query( @@ -4013,8 +4085,8 @@ mod tests { ); } - #[test] - fn test_proved_end_date_query_request() { + #[tokio::test] + async fn test_proved_end_date_query_request() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_config(PlatformConfig::default_mainnet()) @@ -4030,7 +4102,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let GetVotePollsByEndDateResponse { version } = platform .query_vote_polls_by_end_date_query( @@ -4103,8 +4176,8 @@ mod tests { ); } - #[test] - fn test_not_proved_end_date_query_multiple_contests() { + #[tokio::test] + async fn test_not_proved_end_date_query_multiple_contests() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_config(PlatformConfig::default_mainnet()) @@ -4121,7 +4194,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; platform_state.set_last_committed_block_info(Some( ExtendedBlockInfoV0 { @@ -4153,7 +4227,8 @@ mod tests { 8, "quantum", platform_version, - ); + ) + .await; // we create a new contest create_dpns_identity_name_contest( @@ -4162,7 +4237,8 @@ mod tests { 9, "coolio", platform_version, - ); + ) + .await; let GetVotePollsByEndDateResponse { version } = platform .query_vote_polls_by_end_date_query( @@ -4292,8 +4368,8 @@ mod tests { ); } - #[test] - fn test_proved_end_date_query_multiple_contests() { + #[tokio::test] + async fn test_proved_end_date_query_multiple_contests() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_config(PlatformConfig::default_mainnet()) @@ -4310,7 +4386,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; platform_state.set_last_committed_block_info(Some( ExtendedBlockInfoV0 { @@ -4342,7 +4419,8 @@ mod tests { 8, "quantum", platform_version, - ); + ) + .await; // we create a new contest create_dpns_identity_name_contest( @@ -4351,7 +4429,8 @@ mod tests { 9, "coolio", platform_version, - ); + ) + .await; let GetVotePollsByEndDateResponse { version } = platform .query_vote_polls_by_end_date_query( @@ -4444,8 +4523,8 @@ mod tests { ); } - #[test] - fn test_not_proved_end_date_query_multiple_contests_with_start_at() { + #[tokio::test] + async fn test_not_proved_end_date_query_multiple_contests_with_start_at() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_config(PlatformConfig::default_mainnet()) @@ -4462,7 +4541,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; platform_state.set_last_committed_block_info(Some( ExtendedBlockInfoV0 { @@ -4494,7 +4574,8 @@ mod tests { 8, "quantum", platform_version, - ); + ) + .await; // we create a new contest create_dpns_identity_name_contest( @@ -4503,7 +4584,8 @@ mod tests { 9, "coolio", platform_version, - ); + ) + .await; platform_state.set_last_committed_block_info(Some( ExtendedBlockInfoV0 { @@ -4535,7 +4617,8 @@ mod tests { 10, "crazyman", platform_version, - ); + ) + .await; // ascending order { @@ -4702,8 +4785,8 @@ mod tests { } } - #[test] - fn test_not_proved_end_date_query_multiple_contests_with_end_at() { + #[tokio::test] + async fn test_not_proved_end_date_query_multiple_contests_with_end_at() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_config(PlatformConfig::default_mainnet()) @@ -4720,7 +4803,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; platform_state.set_last_committed_block_info(Some( ExtendedBlockInfoV0 { @@ -4752,7 +4836,8 @@ mod tests { 8, "quantum", platform_version, - ); + ) + .await; // we create a new contest create_dpns_identity_name_contest( @@ -4761,7 +4846,8 @@ mod tests { 9, "coolio", platform_version, - ); + ) + .await; platform_state.set_last_committed_block_info(Some( ExtendedBlockInfoV0 { @@ -4793,7 +4879,8 @@ mod tests { 10, "crazyman", platform_version, - ); + ) + .await; let GetVotePollsByEndDateResponse { version } = platform .query_vote_polls_by_end_date_query( @@ -4862,8 +4949,9 @@ mod tests { ); } - #[test] - fn test_not_proved_end_date_query_multiple_contests_with_end_at_before_start_at() { + #[tokio::test] + async fn test_not_proved_end_date_query_multiple_contests_with_end_at_before_start_at() + { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -4879,7 +4967,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; platform_state.set_last_committed_block_info(Some( ExtendedBlockInfoV0 { @@ -4911,7 +5000,8 @@ mod tests { 8, "quantum", platform_version, - ); + ) + .await; // we create a new contest create_dpns_identity_name_contest( @@ -4920,7 +5010,8 @@ mod tests { 9, "coolio", platform_version, - ); + ) + .await; platform_state.set_last_committed_block_info(Some( ExtendedBlockInfoV0 { @@ -4952,7 +5043,8 @@ mod tests { 10, "crazyman", platform_version, - ); + ) + .await; platform .query_vote_polls_by_end_date_query( @@ -5017,8 +5109,9 @@ mod tests { .expect_err("expected query to be invalid"); } - #[test] - fn test_not_proved_end_date_query_multiple_contests_with_start_at_ascending_false() { + #[tokio::test] + async fn test_not_proved_end_date_query_multiple_contests_with_start_at_ascending_false( + ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_config(PlatformConfig::default_mainnet()) @@ -5035,7 +5128,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; platform_state.set_last_committed_block_info(Some( ExtendedBlockInfoV0 { @@ -5067,7 +5161,8 @@ mod tests { 8, "quantum", platform_version, - ); + ) + .await; // we create a new contest create_dpns_identity_name_contest( @@ -5076,7 +5171,8 @@ mod tests { 9, "coolio", platform_version, - ); + ) + .await; platform_state.set_last_committed_block_info(Some( ExtendedBlockInfoV0 { @@ -5108,7 +5204,8 @@ mod tests { 10, "crazyman", platform_version, - ); + ) + .await; let GetVotePollsByEndDateResponse { version } = platform .query_vote_polls_by_end_date_query( @@ -5190,8 +5287,8 @@ mod tests { ); } - #[test] - fn test_proved_end_date_query_multiple_contests_with_start_at() { + #[tokio::test] + async fn test_proved_end_date_query_multiple_contests_with_start_at() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_config(PlatformConfig::default_mainnet()) @@ -5208,7 +5305,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; platform_state.set_last_committed_block_info(Some( ExtendedBlockInfoV0 { @@ -5240,7 +5338,8 @@ mod tests { 8, "quantum", platform_version, - ); + ) + .await; // we create a new contest create_dpns_identity_name_contest( @@ -5249,7 +5348,8 @@ mod tests { 9, "coolio", platform_version, - ); + ) + .await; // ascending order { @@ -5561,8 +5661,8 @@ mod tests { .expect("expected balance to exist") } - #[test] - fn test_non_proved_prefunded_specialized_balance_request_after_many_votes() { + #[tokio::test] + async fn test_non_proved_prefunded_specialized_balance_request_after_many_votes() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -5577,7 +5677,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let start_balance = get_specialized_balance( &platform, @@ -5595,7 +5696,8 @@ mod tests { 9, "quantum", platform_version, - ); + ) + .await; let start_balance_after_more_contenders = get_specialized_balance( &platform, @@ -5625,7 +5727,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; } let balance_after_50_votes = get_specialized_balance( @@ -5656,7 +5759,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; } let balance_after_55_votes = get_specialized_balance( @@ -5670,8 +5774,8 @@ mod tests { assert_eq!(balance_after_55_votes, dash_to_credits!(0.7945)); } - #[test] - fn test_proved_prefunded_specialized_balance_request_after_many_votes() { + #[tokio::test] + async fn test_proved_prefunded_specialized_balance_request_after_many_votes() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -5686,7 +5790,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let start_balance = get_proved_specialized_balance( &platform, @@ -5704,7 +5809,8 @@ mod tests { 9, "quantum", platform_version, - ); + ) + .await; let start_balance_after_more_contenders = get_proved_specialized_balance( &platform, @@ -5734,7 +5840,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; } let balance_after_50_votes = get_proved_specialized_balance( @@ -5765,7 +5872,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; } let balance_after_55_votes = get_proved_specialized_balance( @@ -5795,8 +5903,8 @@ mod tests { use dpp::dashcore::Network; use platform_version::version::INITIAL_PROTOCOL_VERSION; - #[test] - fn test_document_distribution() { + #[tokio::test] + async fn test_document_distribution() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -5811,7 +5919,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -5826,7 +5935,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -6011,8 +6121,8 @@ mod tests { } } - #[test] - fn test_document_distribution_many_votes() { + #[tokio::test] + async fn test_document_distribution_many_votes() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -6032,7 +6142,8 @@ mod tests { 7 + i, name.as_str(), platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -6047,7 +6158,8 @@ mod tests { i * 500 + 10, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -6235,8 +6347,8 @@ mod tests { } } - #[test] - fn test_document_distribution_many_votes_two_contests_same_time() { + #[tokio::test] + async fn test_document_distribution_many_votes_two_contests_same_time() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -6256,7 +6368,8 @@ mod tests { 7 + i, name.as_str(), platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -6271,7 +6384,8 @@ mod tests { i * 500 + 50, None, platform_version, - ); + ) + .await; let name2 = format!("alpha{}", (b'A' + i as u8) as char); let (contender_3, contender_4, dpns_contract) = @@ -6281,7 +6395,8 @@ mod tests { 100007 + i, name2.as_str(), platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -6296,7 +6411,8 @@ mod tests { i * 750 + 500000, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -6616,8 +6732,8 @@ mod tests { } } - #[test] - fn test_document_distribution_many_votes_three_contests_same_time() { + #[tokio::test] + async fn test_document_distribution_many_votes_three_contests_same_time() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -6637,7 +6753,8 @@ mod tests { 7 + i, name.as_str(), platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -6652,7 +6769,8 @@ mod tests { i * 500 + 50, None, platform_version, - ); + ) + .await; let name2 = format!("alpha{}", (b'A' + i as u8) as char); let (contender_3, contender_4, dpns_contract) = @@ -6662,7 +6780,8 @@ mod tests { 100007 + i, name2.as_str(), platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -6677,7 +6796,8 @@ mod tests { i * 750 + 500000, None, platform_version, - ); + ) + .await; let name3 = format!("beta{}", (b'A' + i as u8) as char); let (contender_5, contender_6, dpns_contract) = @@ -6687,7 +6807,8 @@ mod tests { 200007 + i, name3.as_str(), platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -6702,7 +6823,8 @@ mod tests { i * 500 + 600000, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -7220,8 +7342,8 @@ mod tests { } } - #[test] - fn test_document_distribution_abstain_very_high() { + #[tokio::test] + async fn test_document_distribution_abstain_very_high() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -7236,7 +7358,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -7251,7 +7374,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -7436,8 +7560,8 @@ mod tests { } } - #[test] - fn test_document_distribution_low_votes() { + #[tokio::test] + async fn test_document_distribution_low_votes() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -7452,7 +7576,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -7467,7 +7592,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -7652,8 +7778,8 @@ mod tests { } } - #[test] - fn test_document_distribution_single_vote() { + #[tokio::test] + async fn test_document_distribution_single_vote() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -7668,7 +7794,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -7678,7 +7805,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -7863,8 +7991,8 @@ mod tests { } } - #[test] - fn test_document_distribution_no_votes() { + #[tokio::test] + async fn test_document_distribution_no_votes() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -7879,7 +8007,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -8064,8 +8193,8 @@ mod tests { } } - #[test] - fn test_document_locking() { + #[tokio::test] + async fn test_document_locking() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -8080,7 +8209,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -8095,7 +8225,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -8276,8 +8407,8 @@ mod tests { } } - #[test] - fn test_new_vote_after_document_distribution() { + #[tokio::test] + async fn test_new_vote_after_document_distribution() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -8292,7 +8423,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -8307,7 +8439,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -8416,7 +8549,8 @@ mod tests { 2, Some("VotePoll ContestedDocumentResourceVotePoll(ContestedDocumentResourceVotePoll { contract_id: GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec, document_type_name: domain, index_name: parentNameAndLabel, index_values: [string dash, string quantum] }) not available for voting: Awarded(BjNejy4r9QAvLHpQ9Yq6yRMgNymeGZ46d48fJxJbMrfW)"), platform_version, - ); + ) + .await; { let (contenders, abstaining, locking, finished_vote_info) = get_vote_states( @@ -8468,8 +8602,8 @@ mod tests { } } - #[test] - fn test_new_vote_after_lock() { + #[tokio::test] + async fn test_new_vote_after_lock() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -8484,7 +8618,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -8499,7 +8634,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -8608,7 +8744,8 @@ mod tests { 2, Some("VotePoll ContestedDocumentResourceVotePoll(ContestedDocumentResourceVotePoll { contract_id: GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec, document_type_name: domain, index_name: parentNameAndLabel, index_values: [string dash, string quantum] }) not available for voting: Locked"), platform_version, - ); + ) + .await; { let (contenders, abstaining, locking, finished_vote_info) = get_vote_states( @@ -8660,8 +8797,8 @@ mod tests { } } - #[test] - fn test_queries_after_document_distribution() { + #[tokio::test] + async fn test_queries_after_document_distribution() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -8676,7 +8813,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -8691,7 +8829,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -8962,8 +9101,8 @@ mod tests { } } - #[test] - fn test_document_distribution_to_contract() { + #[tokio::test] + async fn test_document_distribution_to_contract() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -8978,7 +9117,8 @@ mod tests { 600, "cards", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -8993,7 +9133,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -9178,8 +9319,8 @@ mod tests { } } - #[test] - fn test_document_distribution_does_not_affect_other_contests() { + #[tokio::test] + async fn test_document_distribution_does_not_affect_other_contests() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -9194,7 +9335,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -9209,7 +9351,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; let max_join_time = platform_version .dpp @@ -9256,7 +9399,8 @@ mod tests { 9, "alpha", platform_version, - ); + ) + .await; let transaction = platform.drive.grove.start_transaction(); @@ -9509,8 +9653,8 @@ mod tests { } } - #[test] - fn test_document_distribution_fix_for_testnet_no_votes_v1() { + #[tokio::test] + async fn test_document_distribution_fix_for_testnet_no_votes_v1() { // There was an issue that we need to repair on testnet. // Documents will have been deleted // Let's verify that the fix works as intended @@ -9532,7 +9676,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -9547,7 +9692,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -9588,7 +9734,8 @@ mod tests { 9, "alpha", platform_version, - ); + ) + .await; let transaction = platform.drive.grove.start_transaction(); @@ -10100,7 +10247,8 @@ mod tests { "alpha", Some(2), // We need a nonce offset platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -10115,7 +10263,8 @@ mod tests { 658, Some(1), platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -10266,8 +10415,8 @@ mod tests { } } - #[test] - fn test_document_distribution_fix_for_testnet_with_votes_v1() { + #[tokio::test] + async fn test_document_distribution_fix_for_testnet_with_votes_v1() { // There was an issue that we need to repair on testnet. // Documents will have been deleted // Let's verify that the fix works as intended @@ -10289,7 +10438,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -10304,7 +10454,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -10347,7 +10498,8 @@ mod tests { 9, "alpha", platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -10362,7 +10514,8 @@ mod tests { 540500, None, platform_version, - ); + ) + .await; let transaction = platform.drive.grove.start_transaction(); @@ -10787,7 +10940,8 @@ mod tests { "alpha", Some(2), // We need a nonce offset platform_version, - ); + ) + .await; perform_votes_multi( &mut platform, @@ -10802,7 +10956,8 @@ mod tests { 658, Some(1), platform_version, - ); + ) + .await; let platform_state = platform.state.load(); @@ -10958,8 +11113,8 @@ mod tests { mod changing_vote { use super::*; use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice::Abstain; - #[test] - fn test_masternode_vote_again_same_vote_should_return_error() { + #[tokio::test] + async fn test_masternode_vote_again_same_vote_should_return_error() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -10974,7 +11129,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let (pro_tx_hash, _masternode, signer, voting_key) = setup_masternode_voting_identity(&mut platform, 10, platform_version); @@ -10993,7 +11149,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; perform_vote( &mut platform, @@ -11007,11 +11164,12 @@ mod tests { 2, Some("Masternode vote is already present for masternode 4iroeiNBeBYZetCt21kW7FGyczE8WqoqzZ48YAHwyV7R voting for ContestedDocumentResourceVotePoll(ContestedDocumentResourceVotePoll { contract_id: GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec, document_type_name: domain, index_name: parentNameAndLabel, index_values: [string dash, string quantum] })"), platform_version, - ); + ) + .await; } - #[test] - fn test_masternode_vote_again_different_choice() { + #[tokio::test] + async fn test_masternode_vote_again_different_choice() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -11026,7 +11184,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let (pro_tx_hash, _masternode, signer, voting_key) = setup_masternode_voting_identity(&mut platform, 10, platform_version); @@ -11045,7 +11204,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; perform_vote( &mut platform, @@ -11059,7 +11219,8 @@ mod tests { 2, None, platform_version, - ); + ) + .await; let (contenders, _abstaining, _locking, finished_vote_info) = get_vote_states( &platform, @@ -11092,8 +11253,8 @@ mod tests { assert_eq!(second_contender.vote_tally(), Some(1)); } - #[test] - fn test_masternode_vote_again_different_choice_too_many_times() { + #[tokio::test] + async fn test_masternode_vote_again_different_choice_too_many_times() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -11108,7 +11269,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let (pro_tx_hash, _masternode, signer, voting_key) = setup_masternode_voting_identity(&mut platform, 10, platform_version); @@ -11127,7 +11289,8 @@ mod tests { 1, None, platform_version, - ); + ) + .await; perform_vote( &mut platform, @@ -11141,7 +11304,8 @@ mod tests { 2, None, platform_version, - ); + ) + .await; perform_vote( &mut platform, @@ -11155,7 +11319,8 @@ mod tests { 3, None, platform_version, - ); + ) + .await; perform_vote( &mut platform, @@ -11169,7 +11334,8 @@ mod tests { 4, None, platform_version, - ); + ) + .await; perform_vote( &mut platform, @@ -11183,7 +11349,8 @@ mod tests { 5, None, platform_version, - ); + ) + .await; perform_vote( &mut platform, @@ -11197,15 +11364,16 @@ mod tests { 6, Some("Masternode with id: 4iroeiNBeBYZetCt21kW7FGyczE8WqoqzZ48YAHwyV7R already voted 5 times and is trying to vote again, they can only vote 5 times"), platform_version, - ); + ) + .await; } } mod masternodes_being_removed { use super::*; use crate::execution::validation::state_transition::state_transitions::tests::take_down_masternode_identities; - #[test] - fn test_masternode_vote_removals() { + #[tokio::test] + async fn test_masternode_vote_removals() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -11220,7 +11388,8 @@ mod tests { 7, "quantum", platform_version, - ); + ) + .await; let masternodes_by_vote_choice = perform_votes_multi( &mut platform, @@ -11235,7 +11404,8 @@ mod tests { 10, None, platform_version, - ); + ) + .await; let platform_state = platform.state.load(); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/mod.rs index 5ec952feba8..ec3d9731baf 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/mod.rs @@ -819,11 +819,11 @@ pub(in crate::execution) mod tests { UseRng(&'a mut StdRng), } - pub(in crate::execution) fn register_contract_from_bytes( + pub(in crate::execution) async fn register_contract_from_bytes( platform: &mut TempPlatform, platform_state: &PlatformState, contract_bytes: Vec, - identity_info: IdentityTestInfo, + identity_info: IdentityTestInfo<'_>, platform_version: &PlatformVersion, ) -> DataContract { // Deserialize the data contract from bytes @@ -869,6 +869,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("expected to create and sign data contract create transition"); // Serialize the state transition @@ -904,7 +905,7 @@ pub(in crate::execution) mod tests { data_contract } - pub(in crate::execution) fn create_dpns_name_contest_give_key_info( + pub(in crate::execution) async fn create_dpns_name_contest_give_key_info( platform: &mut TempPlatform, platform_state: &PlatformState, seed: u64, @@ -952,7 +953,8 @@ pub(in crate::execution) mod tests { None, false, platform_version, - ); + ) + .await; let (identity_1, signer_1, identity_key_1) = identity_1_info; @@ -977,7 +979,7 @@ pub(in crate::execution) mod tests { ) } - pub(in crate::execution) fn create_dpns_identity_name_contest( + pub(in crate::execution) async fn create_dpns_identity_name_contest( platform: &mut TempPlatform, platform_state: &PlatformState, seed: u64, @@ -1008,12 +1010,13 @@ pub(in crate::execution) mod tests { None, false, platform_version, - ); + ) + .await; (identity_1_info.0, identity_2_info.0, dpns_contract) } /// This can be useful if we already created the identities and we reuse the seed - pub(in crate::execution) fn create_dpns_identity_name_contest_skip_creating_identities( + pub(in crate::execution) async fn create_dpns_identity_name_contest_skip_creating_identities( platform: &mut TempPlatform, platform_state: &PlatformState, seed: u64, @@ -1045,11 +1048,12 @@ pub(in crate::execution) mod tests { nonce_offset, true, //we should also skip preorder platform_version, - ); + ) + .await; (identity_1_info.0, identity_2_info.0, dpns_contract) } - pub(in crate::execution) fn create_dpns_contract_name_contest( + pub(in crate::execution) async fn create_dpns_contract_name_contest( platform: &mut TempPlatform, platform_state: &PlatformState, seed: u64, @@ -1100,12 +1104,13 @@ pub(in crate::execution) mod tests { rng, name, platform_version, - ); + ) + .await; (identity_1_info.0, identity_2_info.0, dpns_contract) } #[allow(clippy::too_many_arguments)] - fn create_dpns_name_contest_on_identities( + async fn create_dpns_name_contest_on_identities( platform: &mut TempPlatform, identity_1: &(Identity, SimpleSigner, IdentityPublicKey), identity_2: &(Identity, SimpleSigner, IdentityPublicKey), @@ -1244,6 +1249,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_1 = @@ -1264,6 +1270,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_2 = @@ -1284,6 +1291,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_1 = documents_batch_create_transition_1 @@ -1303,6 +1311,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_2 = documents_batch_create_transition_2 @@ -1406,7 +1415,7 @@ pub(in crate::execution) mod tests { } #[allow(clippy::too_many_arguments)] - fn create_dpns_name_contest_on_identities_for_contract_records( + async fn create_dpns_name_contest_on_identities_for_contract_records( platform: &mut TempPlatform, identity_1: &(Identity, SimpleSigner, IdentityPublicKey), identity_2: &(Identity, SimpleSigner, IdentityPublicKey), @@ -1554,6 +1563,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_1 = @@ -1574,6 +1584,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_2 = @@ -1594,6 +1605,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_1 = documents_batch_create_transition_1 @@ -1613,6 +1625,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_2 = documents_batch_create_transition_2 @@ -1689,7 +1702,7 @@ pub(in crate::execution) mod tests { ) } - pub(in crate::execution) fn add_contender_to_dpns_name_contest( + pub(in crate::execution) async fn add_contender_to_dpns_name_contest( platform: &mut TempPlatform, platform_state: &PlatformState, seed: u64, @@ -1772,6 +1785,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_preorder_transition_1 = @@ -1792,6 +1806,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let documents_batch_create_serialized_transition_1 = documents_batch_create_transition_1 @@ -2080,7 +2095,7 @@ pub(in crate::execution) mod tests { } #[allow(clippy::too_many_arguments)] - pub(in crate::execution) fn perform_vote( + pub(in crate::execution) async fn perform_vote( platform: &mut TempPlatform, platform_state: &Guard>, dpns_contract: &DataContract, @@ -2119,6 +2134,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("expected to make transition vote"); let masternode_vote_serialized_transition = masternode_vote_transition @@ -2160,7 +2176,7 @@ pub(in crate::execution) mod tests { } #[allow(clippy::too_many_arguments)] - pub(in crate::execution) fn perform_votes( + pub(in crate::execution) async fn perform_votes( platform: &mut TempPlatform, dpns_contract: &DataContract, resource_vote_choice: ResourceVoteChoice, @@ -2189,14 +2205,15 @@ pub(in crate::execution) mod tests { 1 + nonce_offset.unwrap_or_default(), None, platform_version, - ); + ) + .await; masternode_infos.push((pro_tx_hash_bytes, voting_identity, signer, voting_key)); } masternode_infos } - pub(in crate::execution) fn perform_votes_multi( + pub(in crate::execution) async fn perform_votes_multi( platform: &mut TempPlatform, dpns_contract: &DataContract, resource_vote_choices: Vec<(ResourceVoteChoice, u64)>, @@ -2218,7 +2235,8 @@ pub(in crate::execution) mod tests { count_aggregate, nonce_offset, platform_version, - ); + ) + .await; masternodes_by_vote_choice.insert(resource_vote_choice, masternode_infos); count_aggregate += count; } @@ -2677,8 +2695,8 @@ pub(in crate::execution) mod tests { (doc, entropy) } - #[test] - fn should_err_when_creating_contract_keywords_document() { + #[tokio::test] + async fn should_err_when_creating_contract_keywords_document() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -2714,6 +2732,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("batch transition"); let serialized = transition.serialize_to_bytes().unwrap(); @@ -2740,8 +2759,8 @@ pub(in crate::execution) mod tests { ); } - #[test] - fn should_err_when_creating_short_description_document() { + #[tokio::test] + async fn should_err_when_creating_short_description_document() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -2777,6 +2796,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("batch transition"); let serialized = transition.serialize_to_bytes().unwrap(); @@ -2803,8 +2823,8 @@ pub(in crate::execution) mod tests { ); } - #[test] - fn should_err_when_creating_full_description_document() { + #[tokio::test] + async fn should_err_when_creating_full_description_document() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -2840,6 +2860,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("batch transition"); let serialized = transition.serialize_to_bytes().unwrap(); @@ -2872,7 +2893,7 @@ pub(in crate::execution) mod tests { // ────────────────────────────────────────────────────────────────────────── // - fn create_contract_with_keywords_and_description( + async fn create_contract_with_keywords_and_description( platform: &mut TempPlatform, ) -> (Identity, SimpleSigner, IdentityPublicKey) { let platform_version = PlatformVersion::latest(); @@ -2905,6 +2926,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("build transition"); let serialized = create_transition.serialize_to_bytes().unwrap(); @@ -2939,15 +2961,15 @@ pub(in crate::execution) mod tests { (owner_identity, signer, key) } - #[test] - fn owner_can_update_short_description_document() { + #[tokio::test] + async fn owner_can_update_short_description_document() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_genesis_state(); let (_owner, signer, key) = - create_contract_with_keywords_and_description(&mut platform); + create_contract_with_keywords_and_description(&mut platform).await; // 🔎 fetch shortDescription doc through query let search_contract = @@ -2985,6 +3007,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("replace"); let serialized = transition.serialize_to_bytes().unwrap(); @@ -3009,15 +3032,15 @@ pub(in crate::execution) mod tests { ); } - #[test] - fn owner_can_not_delete_keyword_document() { + #[tokio::test] + async fn owner_can_not_delete_keyword_document() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .build_with_mock_rpc() .set_genesis_state(); let (_owner, signer, key) = - create_contract_with_keywords_and_description(&mut platform); + create_contract_with_keywords_and_description(&mut platform).await; let search_contract = load_system_data_contract(SystemDataContract::KeywordSearch, platform_version) @@ -3051,6 +3074,7 @@ pub(in crate::execution) mod tests { platform_version, None, ) + .await .expect("delete"); let serialized = transition.serialize_to_bytes().unwrap(); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/tests.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/tests.rs index c1c68667c4c..702ca158634 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/tests.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/tests.rs @@ -65,7 +65,7 @@ mod tests { /// Builds a `ShieldTransitionV0` and signs it with the provided signer. /// The transition will have valid witnesses for all inputs. - fn create_signed_shield_transition( + async fn create_signed_shield_transition( signer: &TestAddressSigner, inputs: BTreeMap, actions: Vec, @@ -91,14 +91,14 @@ mod tests { let signable_bytes = st.signable_bytes().expect("should compute signable bytes"); // Sign each input with the signer - let witnesses: Vec = inputs - .keys() - .map(|address| { - signer - .sign_create_witness(address, &signable_bytes) - .expect("should sign") - }) - .collect(); + let mut witnesses: Vec = Vec::with_capacity(inputs.len()); + for address in inputs.keys() { + let witness = signer + .sign_create_witness(address, &signable_bytes) + .await + .expect("should sign"); + witnesses.push(witness); + } // Inject witnesses if let StateTransition::Shield(ShieldTransition::V0(ref mut v0)) = st { @@ -109,7 +109,7 @@ mod tests { /// Shorthand for creating a structurally valid (but cryptographically invalid) signed shield /// transition with a single input address. The ZK proof data is random/dummy. - fn create_default_signed_shield_transition( + async fn create_default_signed_shield_transition( signer: &TestAddressSigner, input_address: PlatformAddress, input_nonce: AddressNonce, @@ -127,6 +127,7 @@ mod tests { [0u8; 64], // dummy binding signature AddressFundsFeeStrategy::from(vec![AddressFundsFeeStrategyStep::DeductFromInput(0)]), ) + .await } // (Orchard ProvingKey and serialize_authorized_bundle are now shared @@ -139,8 +140,8 @@ mod tests { mod structure_validation { use super::*; - #[test] - fn test_empty_actions_returns_error() { + #[tokio::test] + async fn test_empty_actions_returns_error() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -163,7 +164,8 @@ mod tests { AddressFundsFeeStrategy::from(vec![AddressFundsFeeStrategyStep::DeductFromInput( 0, )]), - ); + ) + .await; let processing_result = process_transition(&platform, transition, platform_version); @@ -175,8 +177,8 @@ mod tests { ); } - #[test] - fn test_no_inputs_returns_error() { + #[tokio::test] + async fn test_no_inputs_returns_error() { let platform_version = PlatformVersion::latest(); let platform = setup_platform(); @@ -203,8 +205,8 @@ mod tests { ); } - #[test] - fn test_witness_count_mismatch_returns_error() { + #[tokio::test] + async fn test_witness_count_mismatch_returns_error() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -218,7 +220,8 @@ mod tests { input_address, 1, dash_to_credits!(0.5), - ); + ) + .await; // Add an extra dummy witness to cause mismatch (1 input, 2 witnesses) if let StateTransition::Shield(ShieldTransition::V0(ref mut v0)) = transition { @@ -239,8 +242,8 @@ mod tests { ); } - #[test] - fn test_input_below_minimum_returns_error() { + #[tokio::test] + async fn test_input_below_minimum_returns_error() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -261,7 +264,8 @@ mod tests { AddressFundsFeeStrategy::from(vec![AddressFundsFeeStrategyStep::DeductFromInput( 0, )]), - ); + ) + .await; let processing_result = process_transition(&platform, transition, platform_version); @@ -276,8 +280,8 @@ mod tests { /// Tests validate_structure directly because 101 actions exceed the /// max_state_transition_size (20KB) before reaching the actions count check /// in the full pipeline. - #[test] - fn test_too_many_actions_returns_error() { + #[tokio::test] + async fn test_too_many_actions_returns_error() { use dpp::state_transition::StateTransitionStructureValidation; let platform_version = PlatformVersion::latest(); @@ -310,8 +314,8 @@ mod tests { ); } - #[test] - fn test_amount_exceeding_i64_max_returns_error() { + #[tokio::test] + async fn test_amount_exceeding_i64_max_returns_error() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -332,7 +336,8 @@ mod tests { AddressFundsFeeStrategy::from(vec![AddressFundsFeeStrategyStep::DeductFromInput( 0, )]), - ); + ) + .await; let processing_result = process_transition(&platform, transition, platform_version); @@ -344,8 +349,8 @@ mod tests { ); } - #[test] - fn test_zero_value_balance_returns_error() { + #[tokio::test] + async fn test_zero_value_balance_returns_error() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -366,7 +371,8 @@ mod tests { AddressFundsFeeStrategy::from(vec![AddressFundsFeeStrategyStep::DeductFromInput( 0, )]), - ); + ) + .await; let processing_result = process_transition(&platform, transition, platform_version); @@ -378,8 +384,8 @@ mod tests { ); } - #[test] - fn test_empty_proof_returns_error() { + #[tokio::test] + async fn test_empty_proof_returns_error() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -400,7 +406,8 @@ mod tests { AddressFundsFeeStrategy::from(vec![AddressFundsFeeStrategyStep::DeductFromInput( 0, )]), - ); + ) + .await; let processing_result = process_transition(&platform, transition, platform_version); @@ -412,8 +419,8 @@ mod tests { ); } - #[test] - fn test_empty_fee_strategy_returns_error() { + #[tokio::test] + async fn test_empty_fee_strategy_returns_error() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -432,7 +439,8 @@ mod tests { vec![0u8; 100], [0u8; 64], AddressFundsFeeStrategy::from(vec![]), // Empty fee strategy - ); + ) + .await; let processing_result = process_transition(&platform, transition, platform_version); @@ -444,8 +452,8 @@ mod tests { ); } - #[test] - fn test_fee_strategy_too_many_steps_returns_error() { + #[tokio::test] + async fn test_fee_strategy_too_many_steps_returns_error() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -471,7 +479,8 @@ mod tests { AddressFundsFeeStrategyStep::DeductFromInput(3), AddressFundsFeeStrategyStep::DeductFromInput(4), ]), - ); + ) + .await; let processing_result = process_transition(&platform, transition, platform_version); @@ -483,8 +492,8 @@ mod tests { ); } - #[test] - fn test_fee_strategy_duplicate_returns_error() { + #[tokio::test] + async fn test_fee_strategy_duplicate_returns_error() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -506,7 +515,8 @@ mod tests { AddressFundsFeeStrategyStep::DeductFromInput(0), AddressFundsFeeStrategyStep::DeductFromInput(0), // Duplicate ]), - ); + ) + .await; let processing_result = process_transition(&platform, transition, platform_version); @@ -526,8 +536,8 @@ mod tests { mod witness_validation { use super::*; - #[test] - fn test_invalid_witness_returns_error() { + #[tokio::test] + async fn test_invalid_witness_returns_error() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -541,7 +551,8 @@ mod tests { input_address, 1, dash_to_credits!(0.5), - ); + ) + .await; // Tamper the witness signature if let StateTransition::Shield(ShieldTransition::V0(ref mut v0)) = transition { @@ -567,8 +578,8 @@ mod tests { ); } - #[test] - fn test_wrong_key_witness_returns_error() { + #[tokio::test] + async fn test_wrong_key_witness_returns_error() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -595,7 +606,8 @@ mod tests { AddressFundsFeeStrategy::from(vec![AddressFundsFeeStrategyStep::DeductFromInput( 0, )]), - ); + ) + .await; // Replace the valid witness with one signed by a different key let signable_bytes = transition @@ -603,6 +615,7 @@ mod tests { .expect("should compute signable bytes"); let wrong_witness = wrong_signer .sign_create_witness(&_wrong_address, &signable_bytes) + .await .expect("should sign"); if let StateTransition::Shield(ShieldTransition::V0(ref mut v0)) = transition { @@ -629,8 +642,8 @@ mod tests { mod address_state_validation { use super::*; - #[test] - fn test_address_not_found_returns_error() { + #[tokio::test] + async fn test_address_not_found_returns_error() { let platform_version = PlatformVersion::latest(); let platform = setup_platform(); @@ -643,7 +656,8 @@ mod tests { input_address, 1, dash_to_credits!(0.5), - ); + ) + .await; let processing_result = process_transition(&platform, transition, platform_version); @@ -655,8 +669,8 @@ mod tests { ); } - #[test] - fn test_wrong_nonce_returns_error() { + #[tokio::test] + async fn test_wrong_nonce_returns_error() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -671,7 +685,8 @@ mod tests { input_address, 5, // Wrong nonce — state has 0, expected next is 1 dash_to_credits!(0.5), - ); + ) + .await; let processing_result = process_transition(&platform, transition, platform_version); @@ -683,8 +698,8 @@ mod tests { ); } - #[test] - fn test_insufficient_balance_returns_error() { + #[tokio::test] + async fn test_insufficient_balance_returns_error() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -699,7 +714,8 @@ mod tests { input_address, 1, dash_to_credits!(1.0), // Way more than 0.001 Dash balance - ); + ) + .await; let processing_result = process_transition(&platform, transition, platform_version); @@ -719,8 +735,8 @@ mod tests { mod proof_verification { use super::*; - #[test] - fn test_invalid_proof_returns_shielded_proof_error() { + #[tokio::test] + async fn test_invalid_proof_returns_shielded_proof_error() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -736,7 +752,8 @@ mod tests { input_address, 1, dash_to_credits!(0.5), - ); + ) + .await; let processing_result = process_transition(&platform, transition, platform_version); @@ -752,8 +769,8 @@ mod tests { ); } - #[test] - fn test_valid_shield_proof_succeeds() { + #[tokio::test] + async fn test_valid_shield_proof_succeeds() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -825,14 +842,14 @@ mod tests { })); let signable_bytes = st.signable_bytes().expect("should compute signable bytes"); - let witnesses: Vec = inputs - .keys() - .map(|address| { - signer - .sign_create_witness(address, &signable_bytes) - .expect("should sign") - }) - .collect(); + let mut witnesses: Vec = Vec::with_capacity(inputs.len()); + for address in inputs.keys() { + let witness = signer + .sign_create_witness(address, &signable_bytes) + .await + .expect("should sign"); + witnesses.push(witness); + } if let StateTransition::Shield(ShieldTransition::V0(ref mut v0)) = st { v0.input_witnesses = witnesses; @@ -846,8 +863,8 @@ mod tests { ); } - #[test] - fn test_wrong_encrypted_note_size_returns_error() { + #[tokio::test] + async fn test_wrong_encrypted_note_size_returns_error() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -872,7 +889,8 @@ mod tests { AddressFundsFeeStrategy::from(vec![AddressFundsFeeStrategyStep::DeductFromInput( 0, )]), - ); + ) + .await; let processing_result = process_transition(&platform, transition, platform_version); @@ -899,8 +917,8 @@ mod tests { /// Zero anchor is rejected at structure validation. /// Tests validate_structure directly because witness verification runs before /// structure validation in the full pipeline. - #[test] - fn test_zero_anchor_returns_error() { + #[tokio::test] + async fn test_zero_anchor_returns_error() { use dpp::state_transition::StateTransitionStructureValidation; let platform_version = PlatformVersion::latest(); @@ -941,8 +959,8 @@ mod tests { /// value_balance from -5000 to -100000 was accepted. Now with /// BatchValidator, the changed value_balance produces a different /// bundle commitment (sighash), causing signature verification to fail. - #[test] - fn test_valid_proof_with_mutated_value_balance_is_rejected() { + #[tokio::test] + async fn test_valid_proof_with_mutated_value_balance_is_rejected() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -1012,14 +1030,14 @@ mod tests { })); let signable_bytes = st.signable_bytes().expect("should compute signable bytes"); - let witnesses: Vec = inputs - .keys() - .map(|address| { - signer - .sign_create_witness(address, &signable_bytes) - .expect("should sign") - }) - .collect(); + let mut witnesses: Vec = Vec::with_capacity(inputs.len()); + for address in inputs.keys() { + let witness = signer + .sign_create_witness(address, &signable_bytes) + .await + .expect("should sign"); + witnesses.push(witness); + } if let StateTransition::Shield(ShieldTransition::V0(ref mut v0)) = st { v0.input_witnesses = witnesses; @@ -1048,8 +1066,8 @@ mod tests { /// With the fix, the transition is rejected at structure validation. /// /// Based on reproducer by pasta (commit a85f4b74). - #[test] - fn test_rejects_shield_when_inputs_less_than_amount() { + #[tokio::test] + async fn test_rejects_shield_when_inputs_less_than_amount() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); @@ -1119,14 +1137,14 @@ mod tests { })); let signable_bytes = st.signable_bytes().expect("should compute signable bytes"); - let witnesses: Vec = inputs - .keys() - .map(|address| { - signer - .sign_create_witness(address, &signable_bytes) - .expect("should sign") - }) - .collect(); + let mut witnesses: Vec = Vec::with_capacity(inputs.len()); + for address in inputs.keys() { + let witness = signer + .sign_create_witness(address, &signable_bytes) + .await + .expect("should sign"); + witnesses.push(witness); + } if let StateTransition::Shield(ShieldTransition::V0(ref mut v0)) = st { v0.input_witnesses = witnesses; @@ -1161,8 +1179,8 @@ mod tests { }; use rand::rngs::OsRng; - #[test] - fn test_shield_prove_and_verify_address_balances() { + #[tokio::test] + async fn test_shield_prove_and_verify_address_balances() { let platform_version = PlatformVersion::latest(); let mut platform = setup_platform(); let mut rng = OsRng; @@ -1233,14 +1251,14 @@ mod tests { })); let signable_bytes = st.signable_bytes().expect("should compute signable bytes"); - let witnesses: Vec = inputs - .keys() - .map(|address| { - signer - .sign_create_witness(address, &signable_bytes) - .expect("should sign") - }) - .collect(); + let mut witnesses: Vec = Vec::with_capacity(inputs.len()); + for address in inputs.keys() { + let witness = signer + .sign_create_witness(address, &signable_bytes) + .await + .expect("should sign"); + witnesses.push(witness); + } if let StateTransition::Shield(ShieldTransition::V0(ref mut v0)) = st { v0.input_witnesses = witnesses; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/test_helpers.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/test_helpers.rs index 293789c0a35..ac89889853f 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/test_helpers.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/test_helpers.rs @@ -175,22 +175,22 @@ impl TestAddressSigner { } /// Sign P2PKH and create witness - pub fn sign_p2pkh( + pub async fn sign_p2pkh( &self, address: PlatformAddress, data: &[u8], ) -> Result { - self.sign_create_witness(&address, data) + Signer::sign_create_witness(self, &address, data).await } /// Sign P2SH and create witness #[allow(dead_code)] - pub fn sign_p2sh( + pub async fn sign_p2sh( &self, address: PlatformAddress, data: &[u8], ) -> Result { - self.sign_create_witness(&address, data) + Signer::sign_create_witness(self, &address, data).await } /// Sign P2SH with ALL keys (not just threshold) @@ -229,8 +229,9 @@ impl TestAddressSigner { } } +#[async_trait::async_trait] impl Signer for TestAddressSigner { - fn sign(&self, key: &PlatformAddress, data: &[u8]) -> Result { + async fn sign(&self, key: &PlatformAddress, data: &[u8]) -> Result { match key { PlatformAddress::P2pkh(hash) => { let entry = self.p2pkh_keys.get(hash).ok_or_else(|| { @@ -258,7 +259,7 @@ impl Signer for TestAddressSigner { } } - fn sign_create_witness( + async fn sign_create_witness( &self, key: &PlatformAddress, data: &[u8], diff --git a/packages/rs-drive-abci/tests/strategy_tests/execution.rs b/packages/rs-drive-abci/tests/strategy_tests/execution.rs index ea10c6eb6a1..3860d10c567 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/execution.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/execution.rs @@ -48,7 +48,7 @@ use tenderdash_abci::Application; pub const GENESIS_TIME_MS: u64 = 1681094380000; -pub(crate) fn run_chain_for_strategy<'a>( +pub(crate) async fn run_chain_for_strategy<'a>( platform: &'a mut Platform, block_count: u64, strategy: NetworkStrategy, @@ -781,10 +781,11 @@ pub(crate) fn run_chain_for_strategy<'a>( config, rng, ) + .await } -pub(crate) fn create_chain_for_strategy( - platform: &Platform, +pub(crate) async fn create_chain_for_strategy<'a>( + platform: &'a Platform, block_count: u64, proposers_with_updates: Vec, validator_quorums: BTreeMap, @@ -792,7 +793,7 @@ pub(crate) fn create_chain_for_strategy( strategy: NetworkStrategy, config: PlatformConfig, rng: StdRng, -) -> ChainExecutionOutcome<'_> { +) -> ChainExecutionOutcome<'a> { let abci_application = FullAbciApplication::new(platform); let seed = strategy @@ -811,10 +812,11 @@ pub(crate) fn create_chain_for_strategy( config, seed, ) + .await } -pub(crate) fn start_chain_for_strategy( - abci_application: FullAbciApplication, +pub(crate) async fn start_chain_for_strategy<'a>( + abci_application: FullAbciApplication<'a, MockCoreRPCLike>, block_count: u64, proposers_with_updates: Vec, validator_quorums: BTreeMap, @@ -822,7 +824,7 @@ pub(crate) fn start_chain_for_strategy( strategy: NetworkStrategy, config: PlatformConfig, seed: StrategyRandomness, -) -> ChainExecutionOutcome { +) -> ChainExecutionOutcome<'a> { let mut rng = match seed { StrategyRandomness::SeedEntropy(seed) => StdRng::seed_from_u64(seed), StrategyRandomness::RNGEntropy(rng) => rng, @@ -915,15 +917,16 @@ pub(crate) fn start_chain_for_strategy( config, StrategyRandomness::RNGEntropy(rng), ) + .await } -pub(crate) fn continue_chain_for_strategy( - abci_app: FullAbciApplication, +pub(crate) async fn continue_chain_for_strategy<'a>( + abci_app: FullAbciApplication<'a, MockCoreRPCLike>, chain_execution_parameters: ChainExecutionParameters, mut strategy: NetworkStrategy, config: PlatformConfig, seed: StrategyRandomness, -) -> ChainExecutionOutcome { +) -> ChainExecutionOutcome<'a> { let platform = abci_app.platform; let ChainExecutionParameters { block_start, @@ -1012,20 +1015,22 @@ pub(crate) fn continue_chain_for_strategy( .values() .nth(i as usize) .unwrap(); - let (state_transitions, finalize_block_operations) = strategy.state_transitions_for_block( - platform, - block_start, - &block_info, - &mut current_identities, - &mut current_addresses_with_balance, - &mut current_identity_nonce_counter, - &mut current_identity_contract_nonce_counter, - &mut current_votes, - &mut signer, - &mut rng, - &instant_lock_quorums, - &mut shielded_state, - ); + let (state_transitions, finalize_block_operations) = strategy + .state_transitions_for_block( + platform, + block_start, + &block_info, + &mut current_identities, + &mut current_addresses_with_balance, + &mut current_identity_nonce_counter, + &mut current_identity_contract_nonce_counter, + &mut current_votes, + &mut signer, + &mut rng, + &instant_lock_quorums, + &mut shielded_state, + ) + .await; state_transitions_per_block.insert(block_height, state_transitions.clone()); diff --git a/packages/rs-drive-abci/tests/strategy_tests/failures.rs b/packages/rs-drive-abci/tests/strategy_tests/failures.rs index d13a93d16e7..f29b8b705bb 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/failures.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/failures.rs @@ -21,9 +21,9 @@ mod tests { use dpp::version::PlatformVersion; use drive_abci::test::helpers::setup::TestPlatformBuilder; - #[test] #[stack_size(4*1024*1024)] - fn run_chain_insert_one_new_identity_and_a_contract_with_bad_update() { + #[test] + async fn run_chain_insert_one_new_identity_and_a_contract_with_bad_update() { let platform_version = PlatformVersion::latest(); let contract = json_document_to_created_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", @@ -103,7 +103,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; outcome .abci_app @@ -130,8 +131,8 @@ mod tests { .expect("expected to get a contract"); } - #[test] - fn run_chain_block_failure_on_genesis_block_correctly_fixes_itself() { + #[tokio::test] + async fn run_chain_block_failure_on_genesis_block_correctly_fixes_itself() { let mut strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -202,7 +203,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; //platform block didn't complete, so it should get another init chain @@ -216,7 +218,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; } // #[test] @@ -272,7 +275,7 @@ mod tests { // &mut simple_signer, // &mut rng, // platform_version, - // ); + // ).await; // let dpns_contract = platform // .drive @@ -382,7 +385,7 @@ mod tests { // // On the first block we only have identities and contracts // let outcome = - // run_chain_for_strategy(&mut platform, 2, strategy.clone(), config.clone(), 15); + // run_chain_for_strategy(&mut platform, 2, strategy.clone(), config.clone(), 15).await; // let state_transitions_block_2 = &outcome // .state_transition_results_per_block diff --git a/packages/rs-drive-abci/tests/strategy_tests/query.rs b/packages/rs-drive-abci/tests/strategy_tests/query.rs index 9f6b51b7539..d9881724b46 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/query.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/query.rs @@ -349,8 +349,8 @@ mod tests { }; } - #[test] - fn run_chain_query_epoch_info() { + #[tokio::test] + async fn run_chain_query_epoch_info() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -403,7 +403,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome.masternode_identity_balances.len(), 100); let nodes_with_no_balance = outcome .masternode_identity_balances @@ -459,8 +460,8 @@ mod tests { assert_eq!(epoch_infos.epoch_infos.len(), 5) } - #[test] - fn run_chain_query_epoch_info_latest() { + #[tokio::test] + async fn run_chain_query_epoch_info_latest() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -513,7 +514,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome.masternode_identity_balances.len(), 100); let all_have_balances = outcome .masternode_identity_balances @@ -565,8 +567,8 @@ mod tests { assert_eq!(epoch_infos.epoch_infos.first().unwrap().number, 4); } - #[test] - fn run_chain_prove_epoch_info() { + #[tokio::test] + async fn run_chain_prove_epoch_info() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -619,7 +621,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome.masternode_identity_balances.len(), 100); let all_have_balances = outcome .masternode_identity_balances @@ -727,8 +730,8 @@ mod tests { assert_eq!(epoch_infos.first().unwrap().index(), 4); } - #[test] - fn run_chain_prove_finalized_epoch_infos() { + #[tokio::test] + async fn run_chain_prove_finalized_epoch_infos() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -781,7 +784,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome.masternode_identity_balances.len(), 100); let all_have_balances = outcome .masternode_identity_balances diff --git a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs index c1908a2bbef..82a7374d9d1 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs @@ -467,7 +467,7 @@ impl NetworkStrategy { } } - pub fn identity_state_transitions_for_block( + pub async fn identity_state_transitions_for_block( &self, block_info: &BlockInfo, signer: &mut SimpleSigner, @@ -479,18 +479,20 @@ impl NetworkStrategy { let mut state_transitions = vec![]; if block_info.height == 1 { if self.strategy.start_identities.number_of_identities > 0 { - let mut new_transitions = self.create_identities_state_transitions( - self.strategy.start_identities.number_of_identities, - self.strategy.start_identities.keys_per_identity as KeyID, - &self.strategy.start_identities.extra_keys, - &(self.strategy.start_identities.starting_balances - ..=self.strategy.start_identities.starting_balances), - signer, - rng, - instant_lock_quorums, - platform_config, - platform_version, - ); + let mut new_transitions = self + .create_identities_state_transitions( + self.strategy.start_identities.number_of_identities, + self.strategy.start_identities.keys_per_identity as KeyID, + &self.strategy.start_identities.extra_keys, + &(self.strategy.start_identities.starting_balances + ..=self.strategy.start_identities.starting_balances), + signer, + rng, + instant_lock_quorums, + platform_config, + platform_version, + ) + .await; state_transitions.append(&mut new_transitions); } // Extend the state transitions with the strategy's hard coded start identities @@ -510,23 +512,25 @@ impl NetworkStrategy { let frequency = &self.strategy.identity_inserts.frequency; if frequency.check_hit(rng) { let count = frequency.events(rng); - let mut new_transitions = self.create_identities_state_transitions( - count, - self.strategy.identity_inserts.start_keys as KeyID, - &self.strategy.identity_inserts.extra_keys, - &self.strategy.identity_inserts.start_balance_range, - signer, - rng, - instant_lock_quorums, - platform_config, - platform_version, - ); + let mut new_transitions = self + .create_identities_state_transitions( + count, + self.strategy.identity_inserts.start_keys as KeyID, + &self.strategy.identity_inserts.extra_keys, + &self.strategy.identity_inserts.start_balance_range, + signer, + rng, + instant_lock_quorums, + platform_config, + platform_version, + ) + .await; state_transitions.append(&mut new_transitions); } Ok(state_transitions) } - pub fn initial_contract_state_transitions( + pub async fn initial_contract_state_transitions( &mut self, current_identities: &Vec, signer: &SimpleSigner, @@ -534,79 +538,80 @@ impl NetworkStrategy { rng: &mut StdRng, platform_version: &PlatformVersion, ) -> Vec { - self.strategy - .start_contracts - .iter_mut() - .map(|(created_contract, contract_updates)| { - let identity_num = rng.gen_range(0..current_identities.len()); - let identity = current_identities - .get(identity_num) - .unwrap() - .clone() - .into_partial_identity_info(); - - let identity_nonce = created_contract.identity_nonce(); - - let contract = created_contract.data_contract_mut(); - - contract.set_owner_id(identity.id); - let old_id = contract.id(); - let new_id = - DataContract::generate_data_contract_id_v0(identity.id, identity_nonce); - contract.set_id(new_id); + let mut result = Vec::with_capacity(self.strategy.start_contracts.len()); + // Need to avoid borrow conflict on self.strategy. Drain start_contracts + // temporarily so we can also mutate self.strategy.operations inside the loop. + let mut start_contracts = std::mem::take(&mut self.strategy.start_contracts); + for (created_contract, contract_updates) in start_contracts.iter_mut() { + let identity_num = rng.gen_range(0..current_identities.len()); + let identity = current_identities + .get(identity_num) + .unwrap() + .clone() + .into_partial_identity_info(); + + let identity_nonce = created_contract.identity_nonce(); + + let contract = created_contract.data_contract_mut(); + + contract.set_owner_id(identity.id); + let old_id = contract.id(); + let new_id = DataContract::generate_data_contract_id_v0(identity.id, identity_nonce); + contract.set_id(new_id); + + if let Some(contract_updates) = contract_updates { + for (_, updated_contract) in contract_updates.iter_mut() { + updated_contract.data_contract_mut().set_id(contract.id()); + updated_contract + .data_contract_mut() + .set_owner_id(contract.owner_id()); + } + } - if let Some(contract_updates) = contract_updates { - for (_, updated_contract) in contract_updates.iter_mut() { - updated_contract.data_contract_mut().set_id(contract.id()); - updated_contract - .data_contract_mut() - .set_owner_id(contract.owner_id()); + // since we are changing the id, we need to update all the strategy + for operation in self.strategy.operations.iter_mut() { + if let OperationType::Document(document_op) = &mut operation.op_type { + if document_op.contract.id() == old_id { + document_op.contract.set_id(contract.id()); + document_op.document_type = document_op + .contract + .document_type_for_name(document_op.document_type.name()) + .expect("document type must exist") + .to_owned_document_type(); + } + } else if let OperationType::Token(token_op) = &mut operation.op_type { + if token_op.contract.id() == old_id { + token_op.contract.set_id(contract.id()); + token_op.token_id = + calculate_token_id(contract.id_ref().as_bytes(), token_op.token_pos) + .into(); } } + } - // since we are changing the id, we need to update all the strategy - self.strategy.operations.iter_mut().for_each(|operation| { - if let OperationType::Document(document_op) = &mut operation.op_type { - if document_op.contract.id() == old_id { - document_op.contract.set_id(contract.id()); - document_op.document_type = document_op - .contract - .document_type_for_name(document_op.document_type.name()) - .expect("document type must exist") - .to_owned_document_type(); - } - } else if let OperationType::Token(token_op) = &mut operation.op_type { - if token_op.contract.id() == old_id { - token_op.contract.set_id(contract.id()); - token_op.token_id = calculate_token_id( - contract.id_ref().as_bytes(), - token_op.token_pos, - ) - .into(); - } - } - }); - - let identity_contract_nonce = contract_nonce_counter - .entry((identity.id, contract.id())) - .or_default(); - *identity_contract_nonce += 1; - - DataContractCreateTransition::new_from_data_contract( - contract.clone(), - identity_nonce, - &identity, - 1, //key id 1 should always be a high or critical auth key in these tests - signer, - platform_version, - None, - ) - .expect("expected to create a create state transition from a data contract") - }) - .collect() + let identity_contract_nonce = contract_nonce_counter + .entry((identity.id, contract.id())) + .or_default(); + *identity_contract_nonce += 1; + + let state_transition = DataContractCreateTransition::new_from_data_contract( + contract.clone(), + identity_nonce, + &identity, + 1, //key id 1 should always be a high or critical auth key in these tests + signer, + platform_version, + None, + ) + .await + .expect("expected to create a create state transition from a data contract"); + result.push(state_transition); + } + self.strategy.start_contracts = start_contracts; + result } - pub fn initial_contract_update_state_transitions( + pub async fn initial_contract_update_state_transitions( &mut self, current_identities: &Vec, block_height: u64, @@ -614,47 +619,46 @@ impl NetworkStrategy { contract_nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, platform_version: &PlatformVersion, ) -> Vec { - self.strategy - .start_contracts - .iter_mut() - .filter_map(|(_, contract_updates)| { - let Some(contract_updates) = contract_updates else { - return None; - }; - let Some(contract_update) = contract_updates.get(&block_height) else { - return None; - }; - let identity = current_identities - .iter() - .find(|identity| identity.id() == contract_update.data_contract().owner_id()) - .expect("expected to find an identity") - .clone() - .into_partial_identity_info(); - - let identity_contract_nonce = contract_nonce_counter - .entry((identity.id, contract_update.data_contract().id())) - .or_default(); - *identity_contract_nonce += 1; - - let state_transition = DataContractUpdateTransition::new_from_data_contract( - contract_update.data_contract().clone(), - &identity, - 1, //key id 1 should always be a high or critical auth key in these tests - *identity_contract_nonce, - 0, - signer, - platform_version, - None, - ) - .expect("expected to create a create state transition from a data contract"); - Some(state_transition) - }) - .collect() + let mut result = Vec::new(); + for (_, contract_updates) in self.strategy.start_contracts.iter_mut() { + let Some(contract_updates) = contract_updates else { + continue; + }; + let Some(contract_update) = contract_updates.get(&block_height) else { + continue; + }; + let identity = current_identities + .iter() + .find(|identity| identity.id() == contract_update.data_contract().owner_id()) + .expect("expected to find an identity") + .clone() + .into_partial_identity_info(); + + let identity_contract_nonce = contract_nonce_counter + .entry((identity.id, contract_update.data_contract().id())) + .or_default(); + *identity_contract_nonce += 1; + + let state_transition = DataContractUpdateTransition::new_from_data_contract( + contract_update.data_contract().clone(), + &identity, + 1, //key id 1 should always be a high or critical auth key in these tests + *identity_contract_nonce, + 0, + signer, + platform_version, + None, + ) + .await + .expect("expected to create a create state transition from a data contract"); + result.push(state_transition); + } + result } // TODO: this belongs to `DocumentOp`, also randomization details are common for all operations // and could be moved out of here - pub fn operations_based_transitions( + pub async fn operations_based_transitions( &mut self, platform: &Platform, block_info: &BlockInfo, @@ -714,83 +718,70 @@ impl NetworkStrategy { platform_version, ) .expect("expected random_documents_with_params"); - documents - .into_iter() - .for_each(|(document, identity, entropy)| { - let identity_contract_nonce = contract_nonce_counter - .entry((identity.id(), contract.id())) - .or_default(); - let gap = self - .strategy - .identity_contract_nonce_gaps - .as_ref() - .map_or(0, |gap_amount| gap_amount.events_if_hit(rng)) - as u64; - *identity_contract_nonce += 1 + gap; - - let prefunded_voting_balances = document_type - .prefunded_voting_balances_for_document( - &document, - platform_version, - ) - .expect( - "expected to get prefunded voting balances for document", - ); - - let document_create_transition: DocumentCreateTransition = - DocumentCreateTransitionV0 { - base: DocumentBaseTransitionV0 { - id: document.id(), - identity_contract_nonce: *identity_contract_nonce, - document_type_name: document_type.name().clone(), - data_contract_id: contract.id(), - } - .into(), - entropy: entropy.to_buffer(), - data: document.properties_consumed(), - prefunded_voting_balance: prefunded_voting_balances, - } - .into(); - - let document_batch_transition: BatchTransition = - BatchTransitionV0 { - owner_id: identity.id(), - transitions: vec![document_create_transition.into()], - user_fee_increase: 0, - signature_public_key_id: 0, - signature: BinaryData::default(), + for (document, identity, entropy) in documents.into_iter() { + let identity_contract_nonce = contract_nonce_counter + .entry((identity.id(), contract.id())) + .or_default(); + let gap = self + .strategy + .identity_contract_nonce_gaps + .as_ref() + .map_or(0, |gap_amount| gap_amount.events_if_hit(rng)) + as u64; + *identity_contract_nonce += 1 + gap; + + let prefunded_voting_balances = document_type + .prefunded_voting_balances_for_document(&document, platform_version) + .expect("expected to get prefunded voting balances for document"); + + let document_create_transition: DocumentCreateTransition = + DocumentCreateTransitionV0 { + base: DocumentBaseTransitionV0 { + id: document.id(), + identity_contract_nonce: *identity_contract_nonce, + document_type_name: document_type.name().clone(), + data_contract_id: contract.id(), } - .into(); - let mut document_batch_transition: StateTransition = - document_batch_transition.into(); - - let identity_public_key = identity - .get_first_public_key_matching( - Purpose::AUTHENTICATION, - HashSet::from([ - SecurityLevel::HIGH, - SecurityLevel::CRITICAL, - ]), - HashSet::from([ - KeyType::ECDSA_SECP256K1, - KeyType::BLS12_381, - ]), - false, - ) - .expect("expected to get a signing key"); + .into(), + entropy: entropy.to_buffer(), + data: document.properties_consumed(), + prefunded_voting_balance: prefunded_voting_balances, + } + .into(); - document_batch_transition - .sign_external( - identity_public_key, - signer, - Some(|_data_contract_id, _document_type_name| { - Ok(SecurityLevel::HIGH) - }), - ) - .expect("expected to sign"); + let document_batch_transition: BatchTransition = BatchTransitionV0 { + owner_id: identity.id(), + transitions: vec![document_create_transition.into()], + user_fee_increase: 0, + signature_public_key_id: 0, + signature: BinaryData::default(), + } + .into(); + let mut document_batch_transition: StateTransition = + document_batch_transition.into(); - operations.push(document_batch_transition); - }); + let identity_public_key = identity + .get_first_public_key_matching( + Purpose::AUTHENTICATION, + HashSet::from([SecurityLevel::HIGH, SecurityLevel::CRITICAL]), + HashSet::from([KeyType::ECDSA_SECP256K1, KeyType::BLS12_381]), + false, + ) + .expect("expected to get a signing key"); + + document_batch_transition + .sign_external( + identity_public_key, + signer, + Some(|_data_contract_id, _document_type_name| { + Ok(SecurityLevel::HIGH) + }), + ) + .await + .expect("expected to sign"); + + operations.push(document_batch_transition); + } } OperationType::Document(DocumentOp { action: @@ -846,81 +837,68 @@ impl NetworkStrategy { .expect("expected random_documents_with_params") }; - documents - .into_iter() - .for_each(|(mut document, identity, entropy)| { - document - .properties_mut() - .append(&mut specific_document_key_value_pairs.clone()); - - let identity_contract_nonce = contract_nonce_counter - .entry((identity.id(), contract.id())) - .or_default(); - *identity_contract_nonce += 1; - - let prefunded_voting_balances = document_type - .prefunded_voting_balances_for_document( - &document, - platform_version, - ) - .expect( - "expected to get prefunded voting balances for document", - ); + for (mut document, identity, entropy) in documents.into_iter() { + document + .properties_mut() + .append(&mut specific_document_key_value_pairs.clone()); - let document_create_transition: DocumentCreateTransition = - DocumentCreateTransitionV0 { - base: DocumentBaseTransitionV0 { - id: document.id(), - identity_contract_nonce: *identity_contract_nonce, - document_type_name: document_type.name().clone(), - data_contract_id: contract.id(), - } - .into(), - entropy: entropy.to_buffer(), - data: document.properties_consumed(), - prefunded_voting_balance: prefunded_voting_balances, - } - .into(); - - let document_batch_transition: BatchTransition = - BatchTransitionV0 { - owner_id: identity.id(), - transitions: vec![document_create_transition.into()], - user_fee_increase: 0, - signature_public_key_id: 0, - signature: BinaryData::default(), + let identity_contract_nonce = contract_nonce_counter + .entry((identity.id(), contract.id())) + .or_default(); + *identity_contract_nonce += 1; + + let prefunded_voting_balances = document_type + .prefunded_voting_balances_for_document(&document, platform_version) + .expect("expected to get prefunded voting balances for document"); + + let document_create_transition: DocumentCreateTransition = + DocumentCreateTransitionV0 { + base: DocumentBaseTransitionV0 { + id: document.id(), + identity_contract_nonce: *identity_contract_nonce, + document_type_name: document_type.name().clone(), + data_contract_id: contract.id(), } - .into(); - let mut document_batch_transition: StateTransition = - document_batch_transition.into(); - - let identity_public_key = identity - .get_first_public_key_matching( - Purpose::AUTHENTICATION, - HashSet::from([ - SecurityLevel::HIGH, - SecurityLevel::CRITICAL, - ]), - HashSet::from([ - KeyType::ECDSA_SECP256K1, - KeyType::BLS12_381, - ]), - false, - ) - .expect("expected to get a signing key"); + .into(), + entropy: entropy.to_buffer(), + data: document.properties_consumed(), + prefunded_voting_balance: prefunded_voting_balances, + } + .into(); - document_batch_transition - .sign_external( - identity_public_key, - signer, - Some(|_data_contract_id, _document_type_name| { - Ok(SecurityLevel::HIGH) - }), - ) - .expect("expected to sign"); + let document_batch_transition: BatchTransition = BatchTransitionV0 { + owner_id: identity.id(), + transitions: vec![document_create_transition.into()], + user_fee_increase: 0, + signature_public_key_id: 0, + signature: BinaryData::default(), + } + .into(); + let mut document_batch_transition: StateTransition = + document_batch_transition.into(); - operations.push(document_batch_transition); - }); + let identity_public_key = identity + .get_first_public_key_matching( + Purpose::AUTHENTICATION, + HashSet::from([SecurityLevel::HIGH, SecurityLevel::CRITICAL]), + HashSet::from([KeyType::ECDSA_SECP256K1, KeyType::BLS12_381]), + false, + ) + .expect("expected to get a signing key"); + + document_batch_transition + .sign_external( + identity_public_key, + signer, + Some(|_data_contract_id, _document_type_name| { + Ok(SecurityLevel::HIGH) + }), + ) + .await + .expect("expected to sign"); + + operations.push(document_batch_transition); + } } OperationType::Document(DocumentOp { action: DocumentAction::DocumentActionDelete, @@ -1014,6 +992,7 @@ impl NetworkStrategy { Ok(SecurityLevel::HIGH) }), ) + .await .expect("expected to sign"); operations.push(document_batch_transition); @@ -1116,6 +1095,7 @@ impl NetworkStrategy { Ok(SecurityLevel::HIGH) }), ) + .await .expect("expected to sign"); operations.push(document_batch_transition); @@ -1226,6 +1206,7 @@ impl NetworkStrategy { Ok(SecurityLevel::HIGH) }), ) + .await .expect("expected to sign"); operations.push(document_batch_transition); @@ -1270,6 +1251,7 @@ impl NetworkStrategy { rng, platform_version, ) + .await else { // no funds left break; @@ -1297,6 +1279,7 @@ impl NetworkStrategy { rng, platform_version, ) + .await else { // no funds left break; @@ -1318,6 +1301,7 @@ impl NetworkStrategy { &platform.config, platform_version, ) + .await else { // no funds left break; @@ -1332,16 +1316,19 @@ impl NetworkStrategy { fee_strategy, ) => { for _i in 0..count { - let Some(state_transition) = self.create_address_transfer_transition( - current_addresses_with_balance, - amount_range, - output_count_range, - *use_existing_outputs_chance, - fee_strategy, - signer, - rng, - platform_version, - ) else { + let Some(state_transition) = self + .create_address_transfer_transition( + current_addresses_with_balance, + amount_range, + output_count_range, + *use_existing_outputs_chance, + fee_strategy, + signer, + rng, + platform_version, + ) + .await + else { tracing::debug!( block_height = block_info.height, ?amount_range, @@ -1365,15 +1352,18 @@ impl NetworkStrategy { fee_strategy, ) => { for _i in 0..count { - let Some(state_transition) = self.create_address_withdrawal_transition( - current_addresses_with_balance, - amount_range, - maybe_output_range, - fee_strategy, - signer, - rng, - platform_version, - ) else { + let Some(state_transition) = self + .create_address_withdrawal_transition( + current_addresses_with_balance, + amount_range, + maybe_output_range, + fee_strategy, + signer, + rng, + platform_version, + ) + .await + else { // no funds left break; }; @@ -1396,7 +1386,7 @@ impl NetworkStrategy { signer, rng, platform_version, - ); + ).await; operations.push(state_transition); finalize_block_operations.push(IdentityAddKeys( keys_to_add_at_end_block.0, @@ -1413,7 +1403,7 @@ impl NetworkStrategy { signer, rng, platform_version, - ); + ).await; if let Some(state_transition) = state_transition { operations.push(state_transition); } @@ -1433,7 +1423,8 @@ impl NetworkStrategy { identity_nonce_counter, signer, rng, - ); + ) + .await; operations.push(state_transition); } } @@ -1462,7 +1453,8 @@ impl NetworkStrategy { identity_nonce_counter, signer, // This means in the TUI, the loaded identity must always be the sender since we're always signing with it for now transfer_info.amount, - ); + ) + .await; operations.push(state_transition); } else if current_identities.len() > 1 { // Handle the case where no sender, recipient, and amount are provided @@ -1494,7 +1486,8 @@ impl NetworkStrategy { identity_nonce_counter, signer, 300000, - ); + ) + .await; operations.push(state_transition); } } @@ -1522,7 +1515,7 @@ impl NetworkStrategy { signer, transfer_info.outputs.clone(), platform_version, - ); + ).await; operations.push(state_transition); } else { // Handle the case where no sender/outputs are provided - generate random ones @@ -1550,7 +1543,8 @@ impl NetworkStrategy { output_count, rng, platform_version, - ); + ) + .await; operations.push(state_transition); } } @@ -1646,13 +1640,20 @@ impl NetworkStrategy { .expect("Expected to get identity public key in ContractCreate"); let mut state_transition = StateTransition::DataContractCreate(transition); - if let Err(e) = state_transition.sign_external( - public_key, - signer, - None::< - fn(Identifier, String) -> Result, - >, - ) { + if let Err(e) = state_transition + .sign_external( + public_key, + signer, + None::< + fn( + Identifier, + String, + ) + -> Result, + >, + ) + .await + { panic!("Error signing state transition: {:?}", e); } @@ -1722,6 +1723,7 @@ impl NetworkStrategy { platform_version, None, ) + .await .expect("expected to make a masternode vote transition"); vote_poll_votes.insert(voting_identifier, resource_vote_choice); @@ -1800,6 +1802,7 @@ impl NetworkStrategy { Ok(SecurityLevel::HIGH) }), ) + .await .expect("expected to sign"); operations.push(batch_transition); @@ -1885,6 +1888,7 @@ impl NetworkStrategy { Ok(SecurityLevel::HIGH) }), ) + .await .expect("expected to sign"); operations.push(batch_transition); @@ -1993,7 +1997,7 @@ impl NetworkStrategy { (operations, finalize_block_operations) } - pub fn state_transitions_for_block( + pub async fn state_transitions_for_block( &mut self, platform: &Platform, start_block_height: BlockHeight, @@ -2014,14 +2018,16 @@ impl NetworkStrategy { .current_platform_version() .expect("expected platform version"); - let identity_state_transitions_result = self.identity_state_transitions_for_block( - block_info, - signer, - rng, - instant_lock_quorums, - &platform.config, - platform_version, - ); + let identity_state_transitions_result = self + .identity_state_transitions_for_block( + block_info, + signer, + rng, + instant_lock_quorums, + &platform.config, + platform_version, + ) + .await; // Handle the Result returned by identity_state_transitions_for_block let (mut identities, mut state_transitions) = match identity_state_transitions_result { @@ -2034,13 +2040,15 @@ impl NetworkStrategy { let should_do_operation_transitions = if block_info.height == start_block_height && !current_identities.is_empty() { // add contracts on block 1 - let mut contract_state_transitions = self.initial_contract_state_transitions( - current_identities, - signer, - contract_nonce_counter, - rng, - platform_version, - ); + let mut contract_state_transitions = self + .initial_contract_state_transitions( + current_identities, + signer, + contract_nonce_counter, + rng, + platform_version, + ) + .await; state_transitions.append(&mut contract_state_transitions); block_info.height != 1 } else { @@ -2062,7 +2070,8 @@ impl NetworkStrategy { rng, platform_version, shielded_state, - ); + ) + .await; finalize_block_operations.append(&mut add_to_finalize_block_operations); state_transitions.append(&mut operation_based_state_transitions); @@ -2075,7 +2084,8 @@ impl NetworkStrategy { signer, contract_nonce_counter, platform_version, - ); + ) + .await; state_transitions.append(&mut contract_update_state_transitions); } @@ -2083,7 +2093,7 @@ impl NetworkStrategy { } // add this because strategy tests library now requires a callback and uses the actual chain. - fn create_identities_state_transitions( + async fn create_identities_state_transitions( &self, count: u16, key_count: KeyID, @@ -2139,6 +2149,7 @@ impl NetworkStrategy { signer, platform_version, ) + .await } else { create_state_transitions_for_identities( &mut identities, @@ -2147,6 +2158,7 @@ impl NetworkStrategy { rng, platform_version, ) + .await } } @@ -2287,7 +2299,7 @@ impl NetworkStrategy { ) } - fn create_identity_top_up_from_addresses_transitions>( + async fn create_identity_top_up_from_addresses_transitions>( &mut self, current_addresses_with_balance: &mut AddressesWithBalance, recipient: &Identity, @@ -2312,6 +2324,7 @@ impl NetworkStrategy { platform_version, None, ) + .await .expect("expected to create top up from addresses transition"); // if you need to upcast to StateTransition tracing::debug!( @@ -2322,7 +2335,7 @@ impl NetworkStrategy { Some(top_up_transition) } - fn create_identity_from_addresses_transition( + async fn create_identity_from_addresses_transition( &mut self, current_addresses_with_balance: &mut AddressesWithBalance, amount_range: &AmountRange, @@ -2398,6 +2411,7 @@ impl NetworkStrategy { 0, // user_fee_increase platform_version, ) + .await .expect("expected to create identity from addresses transition"); tracing::debug!( @@ -2408,7 +2422,7 @@ impl NetworkStrategy { Some((identity, transition)) } - fn create_address_transfer_transition( + async fn create_address_transfer_transition( &mut self, current_addresses_with_balance: &mut AddressesWithBalance, amount_range: &AmountRange, @@ -2495,6 +2509,7 @@ impl NetworkStrategy { 0, platform_version, ) + .await .expect("expected to create address funds transfer transition"); tracing::debug!( @@ -2505,7 +2520,7 @@ impl NetworkStrategy { Some(transfer_transition) } - fn create_address_withdrawal_transition( + async fn create_address_withdrawal_transition( &mut self, current_addresses_with_balance: &mut AddressesWithBalance, amount_range: &AmountRange, @@ -2553,6 +2568,7 @@ impl NetworkStrategy { 0, platform_version, ) + .await .expect("expected to create address credit withdrawal transition"); tracing::debug!( @@ -2563,7 +2579,7 @@ impl NetworkStrategy { Some(withdrawal_transition) } - fn create_address_funding_from_asset_lock_transitions( + async fn create_address_funding_from_asset_lock_transitions( &mut self, current_addresses_with_balance: &mut AddressesWithBalance, amount_range: &AmountRange, @@ -2603,6 +2619,7 @@ impl NetworkStrategy { 0, platform_version, ) + .await .ok()?; Some(funding_transition) diff --git a/packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs index ccb4d2c4016..5918016b0a6 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs @@ -127,8 +127,8 @@ mod tests { } } - #[test] - fn run_chain_address_transitions() { + #[tokio::test] + async fn run_chain_address_transitions() { drive_abci::logging::init_for_tests(LogLevel::Debug); let strategy = NetworkStrategy { @@ -208,7 +208,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; // Build expected address changes from state transitions // For each block, collect: @@ -485,8 +486,8 @@ mod tests { } } - #[test] - fn run_chain_identity_to_addresses_transitions() { + #[tokio::test] + async fn run_chain_identity_to_addresses_transitions() { drive_abci::logging::init_for_tests(LogLevel::Debug); let strategy = NetworkStrategy { @@ -561,7 +562,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let executed = outcome .state_transition_results_per_block @@ -598,8 +600,8 @@ mod tests { } } - #[test] - fn run_chain_identity_create_from_addresses_transitions() { + #[tokio::test] + async fn run_chain_identity_create_from_addresses_transitions() { let _platform_version = PlatformVersion::latest(); drive_abci::logging::init_for_tests(LogLevel::Debug); @@ -681,7 +683,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let executed = outcome .state_transition_results_per_block @@ -714,8 +717,8 @@ mod tests { ); } - #[test] - fn run_chain_address_transitions_with_checkpoints() { + #[tokio::test] + async fn run_chain_address_transitions_with_checkpoints() { drive_abci::logging::init_for_tests(LogLevel::Debug); let strategy = NetworkStrategy { @@ -798,7 +801,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let executed = outcome .state_transition_results_per_block @@ -895,8 +899,8 @@ mod tests { ); } - #[test] - fn run_chain_address_transitions_with_checkpoints_stop_and_restart() { + #[tokio::test] + async fn run_chain_address_transitions_with_checkpoints_stop_and_restart() { drive_abci::logging::init_for_tests(LogLevel::Debug); let strategy = NetworkStrategy { @@ -979,7 +983,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let executed = outcome .state_transition_results_per_block @@ -1092,8 +1097,8 @@ mod tests { ); } - #[test] - fn run_chain_address_withdrawal_transitions() { + #[tokio::test] + async fn run_chain_address_withdrawal_transitions() { use dpp::dashcore::Txid; drive_abci::logging::init_for_tests(LogLevel::Debug); @@ -1178,7 +1183,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; // Count successful AddressCreditWithdrawal state transitions let withdrawal_count = outcome @@ -1380,8 +1386,8 @@ mod tests { /// Test for IdentityCreditTransferToAddresses with pre-configured identities /// that have transfer keys - #[test] - fn run_chain_identity_credit_transfer_to_addresses() { + #[tokio::test] + async fn run_chain_identity_credit_transfer_to_addresses() { drive_abci::logging::init_for_tests(LogLevel::Debug); // Create start identities with transfer keys @@ -1470,7 +1476,8 @@ mod tests { 89, &mut None, &mut None, - ); + ) + .await; // Count IdentityCreditTransferToAddresses transitions let mut transfer_to_addresses_count = 0u32; @@ -1650,8 +1657,8 @@ mod tests { /// 4. IdentityCreateFromAddresses - Creates identity from address funds /// 5. IdentityTopUpFromAddresses - Tops up identity from address funds /// Note: IdentityCreditTransferToAddresses requires identities with transfer keys (special setup) - #[test] - fn run_chain_all_address_transitions() { + #[tokio::test] + async fn run_chain_all_address_transitions() { use dpp::dashcore::Txid; drive_abci::logging::init_for_tests(LogLevel::Debug); @@ -1784,7 +1791,8 @@ mod tests { 89, &mut None, &mut None, - ); + ) + .await; // Count each type of state transition let mut funding_count = 0u32; @@ -2058,8 +2066,8 @@ mod tests { /// 1. Running the chain with quorum signing enabled /// 2. Using a test ContextProvider that knows the quorum public keys /// 3. Verifying proofs using the FromProof trait which includes signature verification - #[test] - fn run_chain_address_transitions_with_proof_signature_verification() { + #[tokio::test] + async fn run_chain_address_transitions_with_proof_signature_verification() { use dpp::dashcore::Network; use drive::grovedb::GroveTrunkQueryResult; @@ -2151,7 +2159,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let executed = outcome .state_transition_results_per_block @@ -2278,8 +2287,8 @@ mod tests { /// Test for querying compacted address balance changes. /// This test runs enough blocks with checkpoints enabled to trigger compaction, /// then verifies the compacted data can be queried correctly. - #[test] - fn run_chain_query_compacted_address_balance_changes() { + #[tokio::test] + async fn run_chain_query_compacted_address_balance_changes() { drive_abci::logging::init_for_tests(LogLevel::Debug); let strategy = NetworkStrategy { @@ -2367,7 +2376,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; // Verify we had some address activity let executed = outcome @@ -2627,8 +2637,8 @@ mod tests { /// Test that verifies there is no overlap between compacted and non-compacted /// address balance changes. Compacted entries should cover older blocks that have /// been merged, while non-compacted entries should cover newer blocks. - #[test] - fn run_chain_verify_no_overlap_between_compacted_and_recent_changes() { + #[tokio::test] + async fn run_chain_verify_no_overlap_between_compacted_and_recent_changes() { drive_abci::logging::init_for_tests(LogLevel::Debug); let strategy = NetworkStrategy { @@ -2715,7 +2725,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; // Verify we had address activity let executed = outcome @@ -2936,9 +2947,9 @@ mod tests { /// - Block 128: Compaction #2 → expires at block 135 → still valid at 135! /// /// So at block 135, we should see 1 compacted entry (from block 128) - #[test] #[stack_size(4 * 1024 * 1024)] - fn run_chain_cleanup_expired_compacted_address_balances() { + #[test] + async fn run_chain_cleanup_expired_compacted_address_balances() { // drive_abci::logging::init_for_tests(LogLevel::Debug); let strategy = NetworkStrategy { @@ -3032,7 +3043,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; // Verify we had address activity let executed = outcome @@ -3234,9 +3246,9 @@ mod tests { /// 2. Runs 70+ blocks to trigger compaction (threshold is 64 blocks) /// 3. Verifies the compacted data has AddToCreditsOperations with preserved block heights /// 4. Simulates a client sync scenario where we filter by block height - #[test] #[stack_size(4 * 1024 * 1024)] - fn run_chain_verify_add_to_credits_operations_for_partial_sync() { + #[test] + async fn run_chain_verify_add_to_credits_operations_for_partial_sync() { // drive_abci::logging::init_for_tests(LogLevel::Debug); // Only use AddressFundingFromAssetLock - no transfers that spend from addresses @@ -3304,7 +3316,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; // Verify we had some successful address fundings let successful_fundings = outcome @@ -3521,9 +3534,9 @@ mod tests { /// Key insight: Each address can only be used ONCE per block (to avoid nonce conflicts). /// Funding operations create new addresses in "staged" state. After block commit, /// they become "committed" and available for transfers in subsequent blocks. - #[test] #[stack_size(4 * 1024 * 1024)] - fn run_chain_high_throughput_address_operations() { + #[test] + async fn run_chain_high_throughput_address_operations() { drive_abci::logging::init_for_tests(LogLevel::Silent); let strategy = NetworkStrategy { @@ -3612,7 +3625,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; // Count executed operations by type let mut funding_ops = 0; @@ -3726,9 +3740,9 @@ mod tests { /// Phase 3: Compaction triggers; catch-up through compacted + recent /// Phase 4: No-op query when already at tip /// Phase 5: Compaction with no address activity (empty blocks) - #[test] #[stack_size(8000000)] - fn run_chain_blast_sync_full_flow() { + #[test] + async fn run_chain_blast_sync_full_flow() { use crate::execution::{continue_chain_for_strategy, GENESIS_TIME_MS}; use crate::strategy::{ ChainExecutionOutcome, ChainExecutionParameters, StrategyRandomness, @@ -3822,7 +3836,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; // Verify some address operations executed let phase1_funding_count = outcome @@ -4002,7 +4017,8 @@ mod tests { phase2_strategy, config.clone(), StrategyRandomness::SeedEntropy(42), - ); + ) + .await; // Query recent (non-compacted) changes from phase1 tip let platform_ref2 = &phase2_outcome.abci_app.platform; @@ -4161,7 +4177,8 @@ mod tests { phase3_strategy, config.clone(), StrategyRandomness::SeedEntropy(99), - ); + ) + .await; let platform_ref3 = &phase3_outcome.abci_app.platform; let platform_state3 = platform_ref3.state.load(); @@ -4405,7 +4422,8 @@ mod tests { empty_strategy, config.clone(), StrategyRandomness::SeedEntropy(200), - ); + ) + .await; let platform_ref5 = &phase5_outcome.abci_app.platform; let platform_state5 = platform_ref5.state.load(); diff --git a/packages/rs-drive-abci/tests/strategy_tests/test_cases/basic_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/test_cases/basic_tests.rs index 0873efb6803..8447a00afbd 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/test_cases/basic_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/test_cases/basic_tests.rs @@ -26,8 +26,8 @@ mod tests { use strategy_tests::frequency::Frequency; use tenderdash_abci::Application; - #[test] - fn run_chain_nothing_happening() { + #[tokio::test] + async fn run_chain_nothing_happening() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -76,11 +76,12 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; } - #[test] - fn run_chain_block_signing() { + #[tokio::test] + async fn run_chain_block_signing() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -130,11 +131,12 @@ mod tests { 13, &mut None, &mut None, - ); + ) + .await; } - #[test] - fn run_chain_stop_and_restart() { + #[tokio::test] + async fn run_chain_stop_and_restart() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -198,7 +200,8 @@ mod tests { 40, &mut None, &mut None, - ); + ) + .await; let state = abci_app.platform.state.load(); @@ -270,11 +273,12 @@ mod tests { strategy, config, StrategyRandomness::SeedEntropy(7), - ); + ) + .await; } - #[test] - fn run_chain_stop_and_restart_multiround() { + #[tokio::test] + async fn run_chain_stop_and_restart_multiround() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -344,7 +348,8 @@ mod tests { 40, &mut None, &mut None, - ); + ) + .await; let state = abci_app.platform.state.load(); @@ -416,11 +421,12 @@ mod tests { strategy, config, StrategyRandomness::SeedEntropy(7), - ); + ) + .await; } - #[test] - fn run_chain_stop_and_restart_with_rotation() { + #[tokio::test] + async fn run_chain_stop_and_restart_with_rotation() { drive_abci::logging::init_for_tests(LogLevel::Silent); let strategy = NetworkStrategy { @@ -501,7 +507,8 @@ mod tests { 89, &mut None, &mut None, - ); + ) + .await; let state = abci_app.platform.state.load(); let protocol_version = state.current_protocol_version_in_consensus(); @@ -571,12 +578,13 @@ mod tests { strategy, config, StrategyRandomness::SeedEntropy(block_start), - ); + ) + .await; } // Test should filter out transactions exceeding max tx bytes per block - #[test] - fn run_transactions_exceeding_max_block_size() { + #[tokio::test] + async fn run_transactions_exceeding_max_block_size() { let strategy = NetworkStrategy { strategy: Strategy { identity_inserts: IdentityInsertInfo { @@ -612,7 +620,8 @@ mod tests { .build_with_mock_rpc(); let outcome = - run_chain_for_strategy(&mut platform, 1, strategy, config, 15, &mut None, &mut None); + run_chain_for_strategy(&mut platform, 1, strategy, config, 15, &mut None, &mut None) + .await; let state_transitions = outcome .state_transition_results_per_block .get(&1) diff --git a/packages/rs-drive-abci/tests/strategy_tests/test_cases/chain_lock_update_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/test_cases/chain_lock_update_tests.rs index 293951d5fea..45c815ff6a6 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/test_cases/chain_lock_update_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/test_cases/chain_lock_update_tests.rs @@ -11,8 +11,8 @@ mod tests { use strategy_tests::frequency::Frequency; use strategy_tests::{IdentityInsertInfo, StartAddresses, StartIdentities, Strategy}; - #[test] - fn run_chain_lock_update_quorums_not_changing() { + #[tokio::test] + async fn run_chain_lock_update_quorums_not_changing() { // The point of this test is to check that chain locks can be validated in the // simple case where quorums do not change let strategy = NetworkStrategy { @@ -81,6 +81,7 @@ mod tests { 13, &mut None, &mut None, - ); + ) + .await; } } diff --git a/packages/rs-drive-abci/tests/strategy_tests/test_cases/core_height_increase.rs b/packages/rs-drive-abci/tests/strategy_tests/test_cases/core_height_increase.rs index b5278a1ac56..19b1b861005 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/test_cases/core_height_increase.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/test_cases/core_height_increase.rs @@ -22,8 +22,8 @@ mod tests { use platform_version::version::PlatformVersion; use strategy_tests::frequency::Frequency; use strategy_tests::{IdentityInsertInfo, StartAddresses, StartIdentities, Strategy}; - #[test] - fn run_chain_core_height_randomly_increasing() { + #[tokio::test] + async fn run_chain_core_height_randomly_increasing() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -76,11 +76,12 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; } - #[test] - fn run_chain_core_height_randomly_increasing_with_epoch_change() { + #[tokio::test] + async fn run_chain_core_height_randomly_increasing_with_epoch_change() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -135,7 +136,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome.masternode_identity_balances.len(), 100); let all_have_balances = outcome .masternode_identity_balances @@ -144,9 +146,9 @@ mod tests { assert!(all_have_balances, "all masternodes should have a balance"); } - #[test] #[stack_size(4 * 1024 * 1024)] - fn run_chain_core_height_randomly_increasing_with_quick_epoch_change() { + #[test] + async fn run_chain_core_height_randomly_increasing_with_quick_epoch_change() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -203,7 +205,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome.masternode_identity_balances.len(), 100); let all_have_balances = outcome .masternode_identity_balances @@ -214,8 +217,8 @@ mod tests { assert_eq!(outcome.end_epoch_index, 49); } - #[test] - fn run_chain_core_height_randomly_increasing_with_quorum_updates() { + #[tokio::test] + async fn run_chain_core_height_randomly_increasing_with_quorum_updates() { let platform_version = PlatformVersion::latest(); let strategy = NetworkStrategy { strategy: Strategy { @@ -284,7 +287,8 @@ mod tests { 40, &mut None, &mut None, - ); + ) + .await; // With these params if we didn't rotate we would have at most 240 // of the 500 hpmns that could get paid, however we are expecting that most @@ -318,8 +322,8 @@ mod tests { ); } - #[test] - fn run_chain_core_height_randomly_increasing_with_quorum_updates_new_proposers() { + #[tokio::test] + async fn run_chain_core_height_randomly_increasing_with_quorum_updates_new_proposers() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -394,7 +398,8 @@ mod tests { 43, &mut None, &mut None, - ); + ) + .await; // With these params if we add new mns the hpmn masternode list would be 100, but we // can expect it to be much higher. @@ -405,8 +410,8 @@ mod tests { assert!(platform_state.hpmn_masternode_list().len() > 100); } - #[test] - fn run_chain_core_height_randomly_increasing_with_quorum_updates_changing_proposers() { + #[tokio::test] + async fn run_chain_core_height_randomly_increasing_with_quorum_updates_changing_proposers() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -485,7 +490,8 @@ mod tests { 43, &mut None, &mut None, - ); + ) + .await; // With these params if we add new mns the hpmn masternode list would be randomly different from 100. @@ -495,8 +501,8 @@ mod tests { assert_ne!(platform_state.hpmn_masternode_list().len(), 100); } - #[test] - fn run_chain_core_height_randomly_increasing_with_quorum_updates_updating_proposers() { + #[tokio::test] + async fn run_chain_core_height_randomly_increasing_with_quorum_updates_updating_proposers() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -575,7 +581,8 @@ mod tests { 43, &mut None, &mut None, - ); + ) + .await; // With these params if we add new mns the hpmn masternode list would be randomly different from 100. @@ -612,8 +619,8 @@ mod tests { assert!(has_disabled_keys); } - #[test] - fn run_chain_rotation_is_deterministic_1_block() { + #[tokio::test] + async fn run_chain_rotation_is_deterministic_1_block() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -709,7 +716,8 @@ mod tests { 7, &mut None, &mut None, - ); + ) + .await; outcomes.push(outcome); } @@ -807,9 +815,9 @@ mod tests { })); } - #[test] #[stack_size(4*1024*1024)] - fn run_chain_heavy_rotation_deterministic_before_payout() { + #[test] + async fn run_chain_heavy_rotation_deterministic_before_payout() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -910,7 +918,8 @@ mod tests { 7, &mut None, &mut None, - ); + ) + .await; let outcome_b = run_chain_for_strategy( &mut platform_b, 18, @@ -919,7 +928,8 @@ mod tests { 7, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome_a.end_epoch_index, outcome_b.end_epoch_index); // 100/18 assert_eq!(outcome_a.masternode_identity_balances.len(), 500); // 500 nodes assert_eq!(outcome_b.masternode_identity_balances.len(), 500); // 500 nodes @@ -980,9 +990,9 @@ mod tests { assert_eq!(balance_count, 0); } - #[test] #[stack_size(4*1024*1024)] - fn run_chain_proposer_proposes_a_chainlock_that_would_remove_themselves_from_the_list_deterministic( + #[test] + async fn run_chain_proposer_proposes_a_chainlock_that_would_remove_themselves_from_the_list_deterministic( ) { let strategy = NetworkStrategy { strategy: Strategy { @@ -1083,7 +1093,8 @@ mod tests { 7, &mut None, &mut None, - ); + ) + .await; let outcome_b = run_chain_for_strategy( &mut platform_b, 100, @@ -1092,7 +1103,8 @@ mod tests { 7, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome_a.end_epoch_index, outcome_b.end_epoch_index); // 100/18 assert_eq!(outcome_a.masternode_identity_balances.len(), 500); // 500 nodes assert_eq!(outcome_b.masternode_identity_balances.len(), 500); // 500 nodes diff --git a/packages/rs-drive-abci/tests/strategy_tests/test_cases/core_update_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/test_cases/core_update_tests.rs index 40ba85ee6aa..d27cda290be 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/test_cases/core_update_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/test_cases/core_update_tests.rs @@ -14,8 +14,8 @@ mod tests { use strategy_tests::frequency::Frequency; use strategy_tests::{IdentityInsertInfo, StartAddresses, StartIdentities, Strategy}; - #[test] - fn run_chain_random_bans() { + #[tokio::test] + async fn run_chain_random_bans() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -90,7 +90,8 @@ mod tests { 13, &mut None, &mut None, - ); + ) + .await; // we expect to see quorums with banned members @@ -122,8 +123,8 @@ mod tests { assert!(has_smaller_validator_sets); } - #[test] - fn run_chain_random_removals() { + #[tokio::test] + async fn run_chain_random_removals() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -198,7 +199,8 @@ mod tests { 13, &mut None, &mut None, - ); + ) + .await; // we expect to see quorums with banned members @@ -216,8 +218,8 @@ mod tests { assert!(has_smaller_validator_sets); } - #[test] - fn run_chain_random_bans_and_unbans() { + #[tokio::test] + async fn run_chain_random_bans_and_unbans() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -297,7 +299,8 @@ mod tests { 13, &mut None, &mut None, - ); + ) + .await; // We should also see validator sets with less than the quorum size diff --git a/packages/rs-drive-abci/tests/strategy_tests/test_cases/data_contract_history_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/test_cases/data_contract_history_tests.rs index e0baefc7522..53e9de9c06f 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/test_cases/data_contract_history_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/test_cases/data_contract_history_tests.rs @@ -37,8 +37,8 @@ mod tests { /// Root cause: In `prove_state_transition_v0`, the code always used /// `contract_ids_to_non_historical_path_query` regardless of whether /// the contract had `keeps_history=true`. - #[test] - fn run_chain_create_contract_with_keeps_history_true() { + #[tokio::test] + async fn run_chain_create_contract_with_keeps_history_true() { let platform_version = PlatformVersion::latest(); // Load a base contract and modify it to enable keeps_history @@ -107,7 +107,8 @@ mod tests { // Run the chain - this will create identities and the contract with keeps_history=true // The verify_state_transition_results flag ensures proofs are verified let outcome = - run_chain_for_strategy(&mut platform, 2, strategy, config, 15, &mut None, &mut None); + run_chain_for_strategy(&mut platform, 2, strategy, config, 15, &mut None, &mut None) + .await; // Verify all state transitions succeeded (including contract creation) for (block_height, tx_results) in outcome.state_transition_results_per_block.iter() { @@ -162,8 +163,8 @@ mod tests { /// Test both historical and non-historical contract creation in the same chain /// to ensure both paths work correctly. - #[test] - fn run_chain_create_contracts_with_and_without_history() { + #[tokio::test] + async fn run_chain_create_contracts_with_and_without_history() { let platform_version = PlatformVersion::latest(); // Contract 1: keeps_history = true @@ -239,7 +240,8 @@ mod tests { .build_with_mock_rpc(); let outcome = - run_chain_for_strategy(&mut platform, 3, strategy, config, 15, &mut None, &mut None); + run_chain_for_strategy(&mut platform, 3, strategy, config, 15, &mut None, &mut None) + .await; // Verify all state transitions succeeded for tx_results_per_block in outcome.state_transition_results_per_block.values() { diff --git a/packages/rs-drive-abci/tests/strategy_tests/test_cases/identity_and_document_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/test_cases/identity_and_document_tests.rs index 69e502a0735..c5348471b14 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/test_cases/identity_and_document_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/test_cases/identity_and_document_tests.rs @@ -38,8 +38,8 @@ mod tests { use strategy_tests::transitions::create_state_transitions_for_identities; use strategy_tests::{IdentityInsertInfo, StartAddresses, StartIdentities, Strategy}; - #[test] - fn run_chain_one_identity_in_solitude_first_protocol_version() { + #[tokio::test] + async fn run_chain_one_identity_in_solitude_first_protocol_version() { let platform_version = PlatformVersion::first(); let strategy = NetworkStrategy { strategy: Strategy { @@ -90,7 +90,8 @@ mod tests { .build_with_mock_rpc(); let outcome = - run_chain_for_strategy(&mut platform, 2, strategy, config, 15, &mut None, &mut None); + run_chain_for_strategy(&mut platform, 2, strategy, config, 15, &mut None, &mut None) + .await; let balance = outcome .abci_app @@ -107,8 +108,8 @@ mod tests { assert_eq!(balance, 99864012200) } - #[test] - fn run_chain_one_identity_in_solitude_latest_protocol_version() { + #[tokio::test] + async fn run_chain_one_identity_in_solitude_latest_protocol_version() { // This is different because in the root tree we added GroupActions // DataContract_Documents 64 // / \ @@ -170,7 +171,8 @@ mod tests { .build_with_mock_rpc(); let outcome = - run_chain_for_strategy(&mut platform, 2, strategy, config, 15, &mut None, &mut None); + run_chain_for_strategy(&mut platform, 2, strategy, config, 15, &mut None, &mut None) + .await; let balance = outcome .abci_app @@ -187,8 +189,8 @@ mod tests { assert_eq!(balance, 99864009940) } - #[test] - fn run_chain_insert_one_new_identity_per_block_with_block_signing() { + #[tokio::test] + async fn run_chain_insert_one_new_identity_per_block_with_block_signing() { drive_abci::logging::init_for_tests(LogLevel::Silent); let strategy = NetworkStrategy { @@ -252,13 +254,14 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome.identities.len(), 100); } - #[test] - fn run_chain_insert_one_new_identity_per_block_with_epoch_change() { + #[tokio::test] + async fn run_chain_insert_one_new_identity_per_block_with_epoch_change() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -317,7 +320,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome.identities.len(), 150); assert_eq!(outcome.masternode_identity_balances.len(), 100); let all_have_balances = outcome @@ -346,8 +350,8 @@ mod tests { ) } - #[test] - fn run_chain_insert_one_new_identity_and_a_contract() { + #[tokio::test] + async fn run_chain_insert_one_new_identity_and_a_contract() { let platform_version = PlatformVersion::latest(); let contract = json_document_to_created_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", @@ -405,7 +409,8 @@ mod tests { .build_with_mock_rpc(); let outcome = - run_chain_for_strategy(&mut platform, 1, strategy, config, 15, &mut None, &mut None); + run_chain_for_strategy(&mut platform, 1, strategy, config, 15, &mut None, &mut None) + .await; for tx_results_per_block in outcome.state_transition_results_per_block.values() { for (state_transition, result) in tx_results_per_block { @@ -442,8 +447,8 @@ mod tests { .expect("expected to get a contract"); } - #[test] - fn run_chain_insert_one_new_identity_and_many_big_contracts() { + #[tokio::test] + async fn run_chain_insert_one_new_identity_and_many_big_contracts() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -543,12 +548,13 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; } - #[test] #[stack_size(4 * 1024 * 1024)] - fn run_chain_insert_one_new_identity_and_a_contract_with_updates() { + #[test] + async fn run_chain_insert_one_new_identity_and_a_contract_with_updates() { let platform_version = PlatformVersion::latest(); let contract = json_document_to_created_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", @@ -640,7 +646,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; outcome .abci_app @@ -667,9 +674,9 @@ mod tests { .expect("expected to get a contract"); } - #[test] #[stack_size(4 * 1024 * 1024)] - fn run_chain_insert_one_new_identity_per_block_and_one_new_document() { + #[test] + async fn run_chain_insert_one_new_identity_per_block_and_one_new_document() { let platform_version = PlatformVersion::latest(); let created_contract = json_document_to_created_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", @@ -754,12 +761,13 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; } - #[test] #[stack_size(4 * 1024 * 1024)] - fn run_chain_insert_one_new_identity_per_block_and_a_document_with_epoch_change() { + #[test] + async fn run_chain_insert_one_new_identity_per_block_and_a_document_with_epoch_change() { let platform_version = PlatformVersion::latest(); let created_contract = json_document_to_created_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", @@ -846,7 +854,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome.identities.len() as u64, block_count); assert_eq!(outcome.masternode_identity_balances.len(), 100); let all_have_balances = outcome @@ -856,9 +865,9 @@ mod tests { assert!(all_have_balances, "all masternodes should have a balance"); } - #[test] #[stack_size(4 * 1024 * 1024)] - fn run_chain_insert_one_new_identity_per_block_document_insertions_and_deletions_with_epoch_change( + #[test] + async fn run_chain_insert_one_new_identity_per_block_document_insertions_and_deletions_with_epoch_change( ) { let platform_version = PlatformVersion::latest(); let created_contract = json_document_to_created_contract( @@ -964,7 +973,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome.identities.len() as u64, block_count); assert_eq!(outcome.masternode_identity_balances.len(), 20); let all_have_balances = outcome @@ -993,8 +1003,8 @@ mod tests { ); } - #[test] - fn run_chain_insert_one_new_identity_per_block_many_document_insertions_and_deletions_with_epoch_change( + #[tokio::test] + async fn run_chain_insert_one_new_identity_per_block_many_document_insertions_and_deletions_with_epoch_change( ) { let platform_version = PlatformVersion::latest(); let created_contract = json_document_to_created_contract( @@ -1102,7 +1112,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome.identities.len() as u64, block_count); assert_eq!(outcome.masternode_identity_balances.len(), 20); let all_have_balances = outcome @@ -1112,8 +1123,8 @@ mod tests { assert!(all_have_balances, "all masternodes should have a balance"); } - #[test] - fn run_chain_insert_one_new_identity_per_block_many_document_insertions_and_deletions_with_nonce_gaps_with_epoch_change( + #[tokio::test] + async fn run_chain_insert_one_new_identity_per_block_many_document_insertions_and_deletions_with_nonce_gaps_with_epoch_change( ) { let platform_version = PlatformVersion::latest(); let created_contract = json_document_to_created_contract( @@ -1224,7 +1235,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome.identities.len() as u64, block_count); assert_eq!(outcome.masternode_identity_balances.len(), 20); let all_have_balances = outcome @@ -1234,8 +1246,8 @@ mod tests { assert!(all_have_balances, "all masternodes should have a balance"); } - #[test] - fn run_chain_insert_one_new_identity_per_block_many_document_insertions_and_deletions_with_max_nonce_gaps_with_epoch_change( + #[tokio::test] + async fn run_chain_insert_one_new_identity_per_block_many_document_insertions_and_deletions_with_max_nonce_gaps_with_epoch_change( ) { let platform_version = PlatformVersion::latest(); let created_contract = json_document_to_created_contract( @@ -1345,7 +1357,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; for tx_results_per_block in outcome.state_transition_results_per_block.values() { for (state_transition, result) in tx_results_per_block { assert_eq!( @@ -1357,8 +1370,8 @@ mod tests { } } - #[test] - fn run_chain_insert_one_new_identity_per_block_many_document_insertions_and_deletions_with_higher_than_max_nonce_gaps_with_epoch_change( + #[tokio::test] + async fn run_chain_insert_one_new_identity_per_block_many_document_insertions_and_deletions_with_higher_than_max_nonce_gaps_with_epoch_change( ) { let platform_version = PlatformVersion::latest(); let created_contract = json_document_to_created_contract( @@ -1468,7 +1481,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; for tx_results_per_block in outcome.state_transition_results_per_block.values() { for (state_transition, _unused_result) in tx_results_per_block { // We can't ever get a documents batch transition, because the proposer will remove it from a block @@ -1477,9 +1491,9 @@ mod tests { } } - #[test] #[stack_size(4 * 1024 * 1024)] - fn run_chain_insert_many_new_identity_per_block_many_document_insertions_and_deletions_with_epoch_change( + #[test] + async fn run_chain_insert_many_new_identity_per_block_many_document_insertions_and_deletions_with_epoch_change( ) { let platform_version = PlatformVersion::latest(); let created_contract = json_document_to_created_contract( @@ -1590,7 +1604,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome.identities.len() as u64, 174); assert_eq!(outcome.masternode_identity_balances.len(), 100); let balance_count = outcome @@ -1620,9 +1635,9 @@ mod tests { ); } - #[test] #[stack_size(4 * 1024 * 1024)] - fn run_chain_insert_many_new_identity_per_block_many_document_insertions_and_updates_with_epoch_change( + #[test] + async fn run_chain_insert_many_new_identity_per_block_many_document_insertions_and_updates_with_epoch_change( ) { let platform_version = PlatformVersion::latest(); let created_contract = json_document_to_created_contract( @@ -1733,7 +1748,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let issues = outcome .abci_app @@ -1755,9 +1771,9 @@ mod tests { ); } - #[test] #[stack_size(4 * 1024 * 1024)] - fn run_chain_insert_many_document_updates_with_epoch_change() { + #[test] + async fn run_chain_insert_many_document_updates_with_epoch_change() { let platform_version = PlatformVersion::latest(); let created_contract = json_document_to_created_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", @@ -1815,6 +1831,7 @@ mod tests { &mut rng, platform_version, ) + .await .into_iter() .map(|(identity, transition)| (identity, Some(transition))) .collect(); @@ -1891,7 +1908,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let issues = outcome .abci_app @@ -1913,9 +1931,9 @@ mod tests { ); } - #[test] #[stack_size(4 * 1024 * 1024)] - fn run_chain_insert_many_new_identity_per_block_many_document_insertions_updates_and_deletions_with_epoch_change( + #[test] + async fn run_chain_insert_many_new_identity_per_block_many_document_insertions_updates_and_deletions_with_epoch_change( ) { let platform_version = PlatformVersion::latest(); let created_contract = json_document_to_created_contract( @@ -2042,7 +2060,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome.identities.len() as u64, 72); assert_eq!(outcome.masternode_identity_balances.len(), 100); let balance_count = outcome @@ -2072,9 +2091,9 @@ mod tests { ); } - #[test] #[stack_size(4 * 1024 * 1024)] - fn run_chain_insert_many_new_identity_per_block_many_document_insertions_updates_transfers_and_deletions_with_epoch_change( + #[test] + async fn run_chain_insert_many_new_identity_per_block_many_document_insertions_updates_transfers_and_deletions_with_epoch_change( ) { let platform_version = PlatformVersion::latest(); let created_contract = json_document_to_created_contract( @@ -2217,7 +2236,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; assert_eq!(outcome.masternode_identity_balances.len(), 20); } } diff --git a/packages/rs-drive-abci/tests/strategy_tests/test_cases/identity_transfer_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/test_cases/identity_transfer_tests.rs index 6d2a00c79a0..150088b3768 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/test_cases/identity_transfer_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/test_cases/identity_transfer_tests.rs @@ -16,8 +16,8 @@ mod tests { use strategy_tests::operations::{Operation, OperationType}; use strategy_tests::{IdentityInsertInfo, StartAddresses, StartIdentities, Strategy}; - #[test] - fn run_chain_transfer_between_identities() { + #[tokio::test] + async fn run_chain_transfer_between_identities() { let platform_version = PlatformVersion::latest(); let strategy = NetworkStrategy { strategy: Strategy { @@ -89,7 +89,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let _balances = &outcome .abci_app diff --git a/packages/rs-drive-abci/tests/strategy_tests/test_cases/shielded_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/test_cases/shielded_tests.rs index 96e0cf4c792..403c5bb4c7f 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/test_cases/shielded_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/test_cases/shielded_tests.rs @@ -105,7 +105,7 @@ mod tests { .build_with_mock_rpc(); let outcome = - run_chain_for_strategy(&mut platform, 5, strategy, config, 15, &mut None, &mut None); + run_chain_for_strategy(&mut platform, 5, strategy, config, 15, &mut None, &mut None).await; // Count successful shield transitions across all blocks let shield_count = outcome @@ -156,7 +156,7 @@ mod tests { .build_with_mock_rpc(); let outcome = - run_chain_for_strategy(&mut platform, 5, strategy, config, 15, &mut None, &mut None); + run_chain_for_strategy(&mut platform, 5, strategy, config, 15, &mut None, &mut None).await; let shield_from_asset_lock_count = outcome .state_transition_results_per_block @@ -230,7 +230,7 @@ mod tests { .build_with_mock_rpc(); let outcome = - run_chain_for_strategy(&mut platform, 8, strategy, config, 15, &mut None, &mut None); + run_chain_for_strategy(&mut platform, 8, strategy, config, 15, &mut None, &mut None).await; // Count all shielded transitions let shield_count = outcome @@ -317,7 +317,7 @@ mod tests { .build_with_mock_rpc(); let outcome = - run_chain_for_strategy(&mut platform, 8, strategy, config, 15, &mut None, &mut None); + run_chain_for_strategy(&mut platform, 8, strategy, config, 15, &mut None, &mut None).await; let shield_count = outcome .state_transition_results_per_block @@ -404,7 +404,7 @@ mod tests { 15, &mut None, &mut None, - ); + ).await; // Verify at least one shield succeeded (prerequisite for anchors) let shield_count = outcome @@ -625,7 +625,7 @@ mod tests { .build_with_mock_rpc(); let outcome = - run_chain_for_strategy(&mut platform, 8, strategy, config, 15, &mut None, &mut None); + run_chain_for_strategy(&mut platform, 8, strategy, config, 15, &mut None, &mut None).await; let shield_count = outcome .state_transition_results_per_block diff --git a/packages/rs-drive-abci/tests/strategy_tests/test_cases/token_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/test_cases/token_tests.rs index 28087e31fc3..0e5f674e042 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/test_cases/token_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/test_cases/token_tests.rs @@ -50,8 +50,8 @@ mod tests { use strategy_tests::{IdentityInsertInfo, StartIdentities, StartAddresses, Strategy}; use crate::addresses_with_balance::AddressesWithBalance; - #[test] - fn run_chain_insert_one_token_mint_per_block() { + #[tokio::test] + async fn run_chain_insert_one_token_mint_per_block() { let platform_version = PlatformVersion::latest(); let mut created_contract = json_document_to_created_contract( "tests/supporting_files/contract/basic-token/basic-token.json", @@ -86,6 +86,7 @@ mod tests { &mut rng, platform_version, ) + .await .into_iter() .map(|(identity, transition)| (identity, Some(transition))) .collect(); @@ -168,7 +169,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let drive = &outcome.abci_app.platform.drive; let identity_ids = vec![identity1.id().to_buffer(), identity2.id().to_buffer()]; @@ -206,8 +208,8 @@ mod tests { assert_eq!(identity_2_token_balance, Some(11000)); // 11 blocks of 1000 } - #[test] - fn run_chain_insert_one_token_transfer_per_block() { + #[tokio::test] + async fn run_chain_insert_one_token_transfer_per_block() { let platform_version = PlatformVersion::latest(); let mut created_contract = json_document_to_created_contract( "tests/supporting_files/contract/basic-token/basic-token.json", @@ -242,6 +244,7 @@ mod tests { &mut rng, platform_version, ) + .await .into_iter() .map(|(identity, transition)| (identity, Some(transition))) .collect(); @@ -324,7 +327,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let drive = &outcome.abci_app.platform.drive; let identity_ids = vec![identity1.id().to_buffer(), identity2.id().to_buffer()]; @@ -366,8 +370,8 @@ mod tests { assert_eq!(identity_2_token_balance, Some(11000)); // 11 blocks of 1000 } - #[test] - fn run_chain_token_perpetual_distribution_to_evonodes_fixed_distribution() { + #[tokio::test] + async fn run_chain_token_perpetual_distribution_to_evonodes_fixed_distribution() { let platform_version = PlatformVersion::latest(); let mut created_contract = json_document_to_created_contract( "tests/supporting_files/contract/basic-token/basic-token.json", @@ -396,6 +400,7 @@ mod tests { &mut rng, platform_version, ) + .await .into_iter() .map(|(identity, transition)| (identity, Some(transition))) .collect(); @@ -476,7 +481,8 @@ mod tests { 13, &mut None, &mut transfer_key_signer, - ); + ) + .await; let platform = abci_app.platform; let state = platform.state.load(); @@ -572,6 +578,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -631,8 +638,8 @@ mod tests { assert_eq!(token_balance, Some(222)); } - #[test] - fn run_chain_token_perpetual_distribution_to_evonodes_linear_distribution() { + #[tokio::test] + async fn run_chain_token_perpetual_distribution_to_evonodes_linear_distribution() { let platform_version = PlatformVersion::latest(); let mut created_contract = json_document_to_created_contract( "tests/supporting_files/contract/basic-token/basic-token.json", @@ -661,6 +668,7 @@ mod tests { &mut rng, platform_version, ) + .await .into_iter() .map(|(identity, transition)| (identity, Some(transition))) .collect(); @@ -760,7 +768,8 @@ mod tests { 13, &mut None, &mut transfer_key_signer, - ); + ) + .await; for (block, tx_results_per_block) in state_transition_results_per_block.iter() { for (state_transition, result) in tx_results_per_block { @@ -866,6 +875,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -993,7 +1003,8 @@ mod tests { }, config.clone(), StrategyRandomness::SeedEntropy(23), - ); + ) + .await; let platform = abci_app.platform; let state = platform.state.load(); @@ -1056,6 +1067,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -1122,8 +1134,8 @@ mod tests { assert_eq!(token_balance, Some(303)); } - #[test] - fn run_chain_token_perpetual_distribution_to_evonodes_linear_distribution_non_genesis() { + #[tokio::test] + async fn run_chain_token_perpetual_distribution_to_evonodes_linear_distribution_non_genesis() { let platform_version = PlatformVersion::latest(); let mut created_contract = json_document_to_created_contract( "tests/supporting_files/contract/basic-token/basic-token.json", @@ -1152,6 +1164,7 @@ mod tests { &mut rng, platform_version, ) + .await .into_iter() .map(|(identity, transition)| (identity, Some(transition))) .collect(); @@ -1253,7 +1266,8 @@ mod tests { 13, &mut None, &mut transfer_key_signer, - ); + ) + .await; for (block, tx_results_per_block) in state_transition_results_per_block.iter() { for (state_transition, result) in tx_results_per_block { @@ -1369,7 +1383,8 @@ mod tests { }, config.clone(), StrategyRandomness::SeedEntropy(23), - ); + ) + .await; let platform = abci_app.platform; let state = platform.state.load(); @@ -1462,6 +1477,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -1588,7 +1604,8 @@ mod tests { }, config.clone(), StrategyRandomness::SeedEntropy(23), - ); + ) + .await; let platform = abci_app.platform; let state = platform.state.load(); @@ -1651,6 +1668,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -1717,8 +1735,8 @@ mod tests { assert_eq!(token_balance, Some(344)); } - #[test] - fn run_chain_token_perpetual_distribution_to_evonodes_linear_distribution_non_genesis_with_start_offset_in_past( + #[tokio::test] + async fn run_chain_token_perpetual_distribution_to_evonodes_linear_distribution_non_genesis_with_start_offset_in_past( ) { let platform_version = PlatformVersion::latest(); let mut created_contract = json_document_to_created_contract( @@ -1748,6 +1766,7 @@ mod tests { &mut rng, platform_version, ) + .await .into_iter() .map(|(identity, transition)| (identity, Some(transition))) .collect(); @@ -1849,7 +1868,8 @@ mod tests { 13, &mut None, &mut transfer_key_signer, - ); + ) + .await; for (block, tx_results_per_block) in state_transition_results_per_block.iter() { for (state_transition, result) in tx_results_per_block { @@ -1965,7 +1985,8 @@ mod tests { }, config.clone(), StrategyRandomness::SeedEntropy(23), - ); + ) + .await; let platform = abci_app.platform; let state = platform.state.load(); @@ -2058,6 +2079,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition @@ -2184,7 +2206,8 @@ mod tests { }, config.clone(), StrategyRandomness::SeedEntropy(23), - ); + ) + .await; let platform = abci_app.platform; let state = platform.state.load(); @@ -2247,6 +2270,7 @@ mod tests { platform_version, None, ) + .await .expect("expect to create documents batch transition"); let claim_serialized_transition = claim_transition diff --git a/packages/rs-drive-abci/tests/strategy_tests/test_cases/top_up_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/test_cases/top_up_tests.rs index 4f5a1d975d5..a8d395aede4 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/test_cases/top_up_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/test_cases/top_up_tests.rs @@ -16,8 +16,8 @@ mod tests { use strategy_tests::operations::{Operation, OperationType}; use strategy_tests::{IdentityInsertInfo, StartAddresses, StartIdentities, Strategy}; - #[test] - fn run_chain_top_up_identities() { + #[tokio::test] + async fn run_chain_top_up_identities() { let platform_version = PlatformVersion::latest(); drive_abci::logging::init_for_tests(LogLevel::Silent); @@ -83,7 +83,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let max_initial_balance = 100000000000u64; // TODO: some centralized way for random test data (`arbitrary` maybe?) let balances = outcome @@ -106,8 +107,8 @@ mod tests { .any(|(_, balance)| balance > max_initial_balance)); } - #[test] - fn run_chain_top_up_identities_from_addresses() { + #[tokio::test] + async fn run_chain_top_up_identities_from_addresses() { drive_abci::logging::init_for_tests(LogLevel::Debug); let strategy = NetworkStrategy { @@ -184,7 +185,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let executed = outcome .state_transition_results_per_block diff --git a/packages/rs-drive-abci/tests/strategy_tests/test_cases/update_identities_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/test_cases/update_identities_tests.rs index d5e32dc71d0..0bb4833a89a 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/test_cases/update_identities_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/test_cases/update_identities_tests.rs @@ -14,8 +14,8 @@ mod tests { use strategy_tests::frequency::Frequency; use strategy_tests::operations::{IdentityUpdateOp, Operation, OperationType}; use strategy_tests::{IdentityInsertInfo, StartAddresses, StartIdentities, Strategy}; - #[test] - fn run_chain_update_identities_add_keys() { + #[tokio::test] + async fn run_chain_update_identities_add_keys() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -81,7 +81,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let state = outcome.abci_app.platform.state.load(); let protocol_version = state.current_protocol_version_in_consensus(); let platform_version = PlatformVersion::get(protocol_version).unwrap(); @@ -107,8 +108,8 @@ mod tests { .any(|(_, identity)| { identity.expect("expected identity").public_keys().len() > 7 })); } - #[test] - fn run_chain_update_identities_remove_keys() { + #[tokio::test] + async fn run_chain_update_identities_remove_keys() { let platform_version = PlatformVersion::latest(); let strategy = NetworkStrategy { strategy: Strategy { @@ -175,7 +176,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let identities = outcome .abci_app diff --git a/packages/rs-drive-abci/tests/strategy_tests/test_cases/upgrade_fork_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/test_cases/upgrade_fork_tests.rs index b3bf45bd302..4311dac5e6b 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/test_cases/upgrade_fork_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/test_cases/upgrade_fork_tests.rs @@ -29,10 +29,10 @@ mod tests { use std::collections::BTreeMap; use strategy_tests::{IdentityInsertInfo, StartAddresses, StartIdentities, Strategy}; + #[stack_size(4 * 1024 * 1024)] #[test] #[ignore] // Long-running: runs in nightly CI only - #[stack_size(4 * 1024 * 1024)] - fn run_chain_version_upgrade() { + async fn run_chain_version_upgrade() { let platform_version = PlatformVersion::first(); let strategy = NetworkStrategy { strategy: Strategy { @@ -111,7 +111,8 @@ mod tests { 13, &mut None, &mut None, - ); + ) + .await; let platform = abci_app.platform; let state = platform.state.load(); @@ -191,7 +192,8 @@ mod tests { strategy.clone(), config.clone(), StrategyRandomness::SeedEntropy(7), - ); + ) + .await; let state = platform.state.load(); { @@ -245,7 +247,8 @@ mod tests { strategy, config, StrategyRandomness::SeedEntropy(18), - ); + ) + .await; let state = platform.state.load(); @@ -307,9 +310,9 @@ mod tests { assert_eq!(epoch_proposers_0.len(), 0); } - #[test] #[stack_size(4 * 1024 * 1024)] - fn run_chain_quick_version_upgrade() { + #[test] + async fn run_chain_quick_version_upgrade() { let platform_version = PlatformVersion::first(); let strategy = NetworkStrategy { strategy: Strategy { @@ -388,7 +391,8 @@ mod tests { 13, &mut None, &mut None, - ); + ) + .await; let platform = abci_app.platform; let state = platform.state.load(); @@ -465,7 +469,8 @@ mod tests { strategy.clone(), config.clone(), StrategyRandomness::SeedEntropy(7), - ); + ) + .await; let state = platform.state.load(); { @@ -519,7 +524,8 @@ mod tests { strategy, config, StrategyRandomness::SeedEntropy(18), - ); + ) + .await; let state = platform.state.load(); { let counter = &platform.drive.cache.protocol_versions_counter.read(); @@ -544,10 +550,10 @@ mod tests { } } + #[stack_size(4 * 1024 * 1024)] #[test] #[ignore] // Long-running: runs in nightly CI only - #[stack_size(4 * 1024 * 1024)] - fn run_chain_version_upgrade_slow_upgrade() { + async fn run_chain_version_upgrade_slow_upgrade() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -629,7 +635,8 @@ mod tests { 16, &mut None, &mut None, - ); + ) + .await; let platform = abci_app.platform; let state = platform.state.load(); { @@ -698,7 +705,8 @@ mod tests { strategy.clone(), config.clone(), StrategyRandomness::SeedEntropy(7), - ); + ) + .await; let state = platform.state.load(); { let counter = &platform.drive.cache.protocol_versions_counter.read(); @@ -751,7 +759,8 @@ mod tests { strategy, config, StrategyRandomness::SeedEntropy(8), - ); + ) + .await; let state = platform.state.load(); @@ -771,10 +780,10 @@ mod tests { ); } + #[stack_size(4 * 1024 * 1024)] #[test] #[ignore] // Long-running: runs in nightly CI only - #[stack_size(4 * 1024 * 1024)] - fn run_chain_version_upgrade_slow_upgrade_quick_reversion_after_lock_in() { + async fn run_chain_version_upgrade_slow_upgrade_quick_reversion_after_lock_in() { drive_abci::logging::init_for_tests(LogLevel::Silent); let strategy = NetworkStrategy { @@ -857,7 +866,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let platform = abci_app.platform; let state = platform.state.load(); @@ -918,7 +928,8 @@ mod tests { strategy, config.clone(), StrategyRandomness::SeedEntropy(99), - ); + ) + .await; let state = platform.state.load(); { let counter = &platform.drive.cache.protocol_versions_counter.read(); @@ -1014,7 +1025,8 @@ mod tests { strategy.clone(), config.clone(), StrategyRandomness::SeedEntropy(40), - ); + ) + .await; let state = platform.state.load(); { let counter = &platform.drive.cache.protocol_versions_counter.read(); @@ -1073,7 +1085,8 @@ mod tests { strategy, config, StrategyRandomness::SeedEntropy(40), - ); + ) + .await; let state = platform.state.load(); { let counter = &platform.drive.cache.protocol_versions_counter.read(); @@ -1099,10 +1112,10 @@ mod tests { } } + #[stack_size(4 * 1024 * 1024)] #[test] #[ignore] // Long-running: runs in nightly CI only - #[stack_size(4 * 1024 * 1024)] - fn run_chain_version_upgrade_multiple_versions() { + async fn run_chain_version_upgrade_multiple_versions() { let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -1185,7 +1198,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let state = abci_app.platform.state.load(); { let platform = abci_app.platform; @@ -1295,7 +1309,8 @@ mod tests { strategy, config, StrategyRandomness::SeedEntropy(7), - ); + ) + .await; let state = platform.state.load(); { let counter = &platform.drive.cache.protocol_versions_counter.read(); diff --git a/packages/rs-drive-abci/tests/strategy_tests/test_cases/voting_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/test_cases/voting_tests.rs index d783b4f1af1..0e291083d65 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/test_cases/voting_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/test_cases/voting_tests.rs @@ -41,9 +41,9 @@ mod tests { const STACK_SIZE: usize = 4 * 1024 * 1024; // 4 MB - #[test] #[stack_size(STACK_SIZE)] - fn run_chain_with_temporarily_disabled_contested_documents() { + #[test] + async fn run_chain_with_temporarily_disabled_contested_documents() { let epoch_time_length_s = 60; let config = PlatformConfig { @@ -91,6 +91,7 @@ mod tests { &mut rng, platform_version, ) + .await .into_iter() .map(|(identity, transition)| (identity, Some(transition))) .collect(); @@ -184,7 +185,8 @@ mod tests { 15, &mut voting_signer, &mut None, - ); + ) + .await; let platform_state = abci_app.platform.state.load(); @@ -243,7 +245,8 @@ mod tests { NetworkStrategy::default(), config.clone(), StrategyRandomness::SeedEntropy(7), - ); + ) + .await; let platform_state = abci_app.platform.state.load(); @@ -310,7 +313,8 @@ mod tests { strategy, config.clone(), StrategyRandomness::SeedEntropy(7), - ); + ) + .await; let state_transitions_block_6 = state_transition_results_per_block .get(&6) @@ -328,9 +332,9 @@ mod tests { assert_eq!(execution_result.code, 0); } - #[test] #[stack_size(STACK_SIZE)] - fn run_chain_block_two_state_transitions_conflicting_unique_index_inserted_same_block_version_8( + #[test] + async fn run_chain_block_two_state_transitions_conflicting_unique_index_inserted_same_block_version_8( ) { // In this test we try to insert two state transitions with the same unique index // We use the DPNS contract, and we insert two documents both with the same "name" @@ -380,6 +384,7 @@ mod tests { &mut rng, platform_version, ) + .await .into_iter() .map(|(identity, transition)| (identity, Some(transition))) .collect(); @@ -492,7 +497,8 @@ mod tests { 15, &mut None, &mut None, - ); + ) + .await; let platform = outcome.abci_app.platform; @@ -602,9 +608,9 @@ mod tests { assert_eq!(second_contender.vote_count, Some(0)); } - #[test] #[stack_size(STACK_SIZE)] - fn run_chain_with_voting_on_conflicting_index_just_abstain_votes() { + #[test] + async fn run_chain_with_voting_on_conflicting_index_just_abstain_votes() { // In this test we try to insert two state transitions with the same unique index // We use the DPNS contract, and we insert two documents both with the same "name" // This is a common scenario we should see quite often @@ -652,6 +658,7 @@ mod tests { &mut rng, platform_version, ) + .await .into_iter() .map(|(identity, transition)| (identity, Some(transition))) .collect(); @@ -778,7 +785,8 @@ mod tests { 15, &mut voting_signer, &mut None, - ); + ) + .await; let platform = abci_app.platform; @@ -871,7 +879,8 @@ mod tests { }, config.clone(), StrategyRandomness::SeedEntropy(7), - ); + ) + .await; let platform = outcome.abci_app.platform; @@ -955,9 +964,9 @@ mod tests { assert_eq!(abstain_vote_tally, Some(124)); } - #[test] #[stack_size(STACK_SIZE)] - fn run_chain_with_voting_on_conflicting_index_various_votes() { + #[test] + async fn run_chain_with_voting_on_conflicting_index_various_votes() { // In this test we try to insert two state transitions with the same unique index // We use the DPNS contract, and we insert two documents both with the same "name" // This is a common scenario we should see quite often @@ -1005,6 +1014,7 @@ mod tests { &mut rng, platform_version, ) + .await .into_iter() .map(|(identity, transition)| (identity, Some(transition))) .collect(); @@ -1131,7 +1141,8 @@ mod tests { 15, &mut voting_signer, &mut None, - ); + ) + .await; let platform = abci_app.platform; @@ -1229,7 +1240,8 @@ mod tests { }, config.clone(), StrategyRandomness::SeedEntropy(7), - ); + ) + .await; let platform = outcome.abci_app.platform; @@ -1319,9 +1331,9 @@ mod tests { assert_eq!(finished_vote_info, None); } - #[test] #[stack_size(STACK_SIZE)] - fn run_chain_with_voting_after_won_by_identity_no_specialized_funds_distribution() { + #[test] + async fn run_chain_with_voting_after_won_by_identity_no_specialized_funds_distribution() { // In this test we try to insert two state transitions with the same unique index // We use the DPNS contract, and we insert two documents both with the same "name" // This is a common scenario we should see quite often @@ -1370,6 +1382,7 @@ mod tests { &mut rng, platform_version, ) + .await .into_iter() .map(|(identity, transition)| (identity, Some(transition))) .collect(); @@ -1495,7 +1508,8 @@ mod tests { 15, &mut voting_signer, &mut None, - ); + ) + .await; let platform = abci_app.platform; @@ -1606,7 +1620,8 @@ mod tests { }, config.clone(), StrategyRandomness::SeedEntropy(9), - ); + ) + .await; let platform = outcome.abci_app.platform; @@ -1717,9 +1732,9 @@ mod tests { assert_eq!(processing_fees, 50_000_000); } - #[test] #[stack_size(STACK_SIZE)] - fn run_chain_with_voting_after_won_by_identity_with_specialized_funds_distribution() { + #[test] + async fn run_chain_with_voting_after_won_by_identity_with_specialized_funds_distribution() { // In this test we try to insert two state transitions with the same unique index // We use the DPNS contract, and we insert two documents both with the same "name" // This is a common scenario we should see quite often @@ -1767,6 +1782,7 @@ mod tests { &mut rng, platform_version, ) + .await .into_iter() .map(|(identity, transition)| (identity, Some(transition))) .collect(); @@ -1892,7 +1908,8 @@ mod tests { 15, &mut voting_signer, &mut None, - ); + ) + .await; let platform = abci_app.platform; @@ -2003,7 +2020,8 @@ mod tests { }, config.clone(), StrategyRandomness::SeedEntropy(9), - ); + ) + .await; let platform = outcome.abci_app.platform; @@ -2118,9 +2136,9 @@ mod tests { assert_eq!(processing_fees, 39_860_000_000); } - #[test] #[stack_size(STACK_SIZE)] - fn run_chain_with_voting_after_won_by_identity_no_specialized_funds_distribution_until_version_8( + #[test] + async fn run_chain_with_voting_after_won_by_identity_no_specialized_funds_distribution_until_version_8( ) { // In this test the goal is to verify that when we hit version 8 that the specialized balances // that hadn't been properly distributed are distributed. @@ -2173,6 +2191,7 @@ mod tests { &mut rng, platform_version, ) + .await .into_iter() .map(|(identity, transition)| (identity, Some(transition))) .collect(); @@ -2304,7 +2323,8 @@ mod tests { 15, &mut voting_signer, &mut None, - ); + ) + .await; let platform = abci_app.platform; @@ -2430,7 +2450,8 @@ mod tests { }, config.clone(), StrategyRandomness::SeedEntropy(9), - ); + ) + .await; let platform = abci_app.platform; @@ -2628,7 +2649,8 @@ mod tests { }, config.clone(), StrategyRandomness::SeedEntropy(9203), - ); + ) + .await; let platform = abci_app.platform; @@ -2756,7 +2778,8 @@ mod tests { }, config.clone(), StrategyRandomness::SeedEntropy(9203), - ); + ) + .await; block_start += 1; @@ -2808,7 +2831,8 @@ mod tests { }, config.clone(), StrategyRandomness::SeedEntropy(9203), - ); + ) + .await; let platform = outcome.abci_app.platform; platform diff --git a/packages/rs-drive-abci/tests/strategy_tests/test_cases/withdrawal_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/test_cases/withdrawal_tests.rs index 40549f7859b..34166e37cb0 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/test_cases/withdrawal_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/test_cases/withdrawal_tests.rs @@ -44,8 +44,8 @@ mod tests { chain_lock: ChainLock, } - #[test] - fn run_chain_withdraw_from_identities() { + #[tokio::test] + async fn run_chain_withdraw_from_identities() { // TEST_PLATFORM_V3 is like v4, but without the single quorum can sign withdrawals restriction let platform_version = PlatformVersion::get(TEST_PLATFORM_V3.protocol_version) .expect("expected to get platform version"); @@ -184,7 +184,8 @@ mod tests { 1, &mut None, &mut None, - ); + ) + .await; for tx_results_per_block in outcome.state_transition_results_per_block.values() { for (state_transition, result) in tx_results_per_block { @@ -332,7 +333,8 @@ mod tests { continue_strategy_only_withdrawal.clone(), config.clone(), StrategyRandomness::SeedEntropy(2), - ); + ) + .await; for tx_results_per_block in outcome.state_transition_results_per_block.values() { assert_eq!(tx_results_per_block.len(), 1); @@ -422,7 +424,8 @@ mod tests { continue_strategy_no_operations.clone(), config.clone(), StrategyRandomness::SeedEntropy(3), - ); + ) + .await; // Withdrawal documents with pooled status should exist. let withdrawal_documents_broadcasted = outcome @@ -522,7 +525,8 @@ mod tests { continue_strategy_no_operations.clone(), config.clone(), StrategyRandomness::SeedEntropy(4), - ); + ) + .await; let withdrawal_documents_completed = outcome .abci_app @@ -633,7 +637,8 @@ mod tests { continue_strategy_no_operations.clone(), config.clone(), StrategyRandomness::SeedEntropy(5), - ); + ) + .await; let withdrawal_documents_pooled = outcome .abci_app @@ -718,7 +723,8 @@ mod tests { continue_strategy_no_operations.clone(), config.clone(), StrategyRandomness::SeedEntropy(6), - ); + ) + .await; // We should have unlocked the amounts by now let locked_amount = outcome @@ -738,8 +744,8 @@ mod tests { assert_eq!(locked_amount, 0); } - #[test] - fn run_chain_withdrawal_expired() { + #[tokio::test] + async fn run_chain_withdrawal_expired() { // TEST_PLATFORM_V3 is like v4, but without the single quorum can sign withdrawals restriction let platform_version = PlatformVersion::get(TEST_PLATFORM_V3.protocol_version) .expect("expected to get platform version"); @@ -876,7 +882,8 @@ mod tests { 1, &mut None, &mut None, - ); + ) + .await; for tx_results_per_block in outcome.state_transition_results_per_block.values() { for (state_transition, result) in tx_results_per_block { @@ -1024,7 +1031,8 @@ mod tests { continue_strategy_only_withdrawal.clone(), config.clone(), StrategyRandomness::SeedEntropy(2), - ); + ) + .await; for tx_results_per_block in outcome.state_transition_results_per_block.values() { assert_eq!(tx_results_per_block.len(), 1); @@ -1114,7 +1122,8 @@ mod tests { continue_strategy_no_operations.clone(), config.clone(), StrategyRandomness::SeedEntropy(2), - ); + ) + .await; // Withdrawal documents with pooled status should exist. let withdrawal_documents_broadcasted = outcome @@ -1200,7 +1209,8 @@ mod tests { continue_strategy_no_operations.clone(), config.clone(), StrategyRandomness::SeedEntropy(5), - ); + ) + .await; let withdrawal_documents_pooled = outcome .abci_app @@ -1298,7 +1308,8 @@ mod tests { continue_strategy_no_operations.clone(), config.clone(), StrategyRandomness::SeedEntropy(2), - ); + ) + .await; let withdrawal_documents_pooled = outcome .abci_app @@ -1399,7 +1410,8 @@ mod tests { continue_strategy_no_operations.clone(), config.clone(), StrategyRandomness::SeedEntropy(2), - ); + ) + .await; let withdrawal_documents_pooled = outcome .abci_app @@ -1455,8 +1467,8 @@ mod tests { assert!(withdrawal_documents_expired.is_empty()); } - #[test] - fn run_chain_withdraw_from_identities_too_many_withdrawals_within_a_day_hitting_limit() { + #[tokio::test] + async fn run_chain_withdraw_from_identities_too_many_withdrawals_within_a_day_hitting_limit() { // TEST_PLATFORM_V3 is like v4, but without the single quorum can sign withdrawals restriction let platform_version = PlatformVersion::get(TEST_PLATFORM_V3.protocol_version) .expect("expected to get platform version"); @@ -1595,7 +1607,8 @@ mod tests { 1, &mut None, &mut None, - ); + ) + .await; for tx_results_per_block in outcome.state_transition_results_per_block.values() { for (state_transition, result) in tx_results_per_block { @@ -1773,7 +1786,8 @@ mod tests { continue_strategy_only_withdrawal.clone(), config.clone(), StrategyRandomness::SeedEntropy(2), - ); + ) + .await; for tx_results_per_block in outcome.state_transition_results_per_block.values() { assert_eq!(tx_results_per_block.len(), 4); @@ -1944,7 +1958,8 @@ mod tests { ..Default::default() }, StrategyRandomness::SeedEntropy(9), - ); + ) + .await; // We should have unlocked the amounts by now let locked_amount = outcome @@ -2078,7 +2093,8 @@ mod tests { ..Default::default() }, StrategyRandomness::SeedEntropy(9), - ); + ) + .await; // We should have unlocked the amounts by now let locked_amount = outcome @@ -2178,8 +2194,8 @@ mod tests { assert_eq!(withdrawal_documents_broadcasted.len(), 80); } - #[test] - fn run_chain_withdraw_from_identities_many_small_withdrawals() { + #[tokio::test] + async fn run_chain_withdraw_from_identities_many_small_withdrawals() { // TEST_PLATFORM_V3 is like v4, but without the single quorum can sign withdrawals restriction let platform_version = PlatformVersion::get(TEST_PLATFORM_V3.protocol_version) .expect("expected to get platform version"); @@ -2318,7 +2334,8 @@ mod tests { 1, &mut None, &mut None, - ); + ) + .await; for tx_results_per_block in outcome.state_transition_results_per_block.values() { for (state_transition, result) in tx_results_per_block { @@ -2496,7 +2513,8 @@ mod tests { continue_strategy_only_withdrawal.clone(), config.clone(), StrategyRandomness::SeedEntropy(2), - ); + ) + .await; for tx_results_per_block in outcome.state_transition_results_per_block.values() { assert_eq!(tx_results_per_block.len(), 20); @@ -2644,7 +2662,8 @@ mod tests { ..Default::default() }, StrategyRandomness::SeedEntropy(9), - ); + ) + .await; // We should have unlocked the amounts by now let locked_amount = outcome diff --git a/packages/rs-sdk-ffi/Cargo.toml b/packages/rs-sdk-ffi/Cargo.toml index 7ba7d20a4a0..342afca58a7 100644 --- a/packages/rs-sdk-ffi/Cargo.toml +++ b/packages/rs-sdk-ffi/Cargo.toml @@ -31,7 +31,8 @@ serde_json = "1.0" bincode = { version = "=2.0.1", features = ["serde"] } # Async runtime -tokio = { version = "1.41", features = ["rt-multi-thread", "macros"] } +tokio = { version = "1.41", features = ["rt-multi-thread", "macros", "sync"] } +async-trait = "0.1" # Error handling thiserror = "2.0" diff --git a/packages/rs-sdk-ffi/src/address/transitions/transfer.rs b/packages/rs-sdk-ffi/src/address/transitions/transfer.rs index c62605f2c4b..3922e5a067e 100644 --- a/packages/rs-sdk-ffi/src/address/transitions/transfer.rs +++ b/packages/rs-sdk-ffi/src/address/transitions/transfer.rs @@ -43,8 +43,9 @@ impl AddressSigner { } } +#[async_trait::async_trait] impl Signer for AddressSigner { - fn sign(&self, key: &PlatformAddress, data: &[u8]) -> Result { + async fn sign(&self, key: &PlatformAddress, data: &[u8]) -> Result { let hash = match key { PlatformAddress::P2pkh(hash) => hash, PlatformAddress::P2sh(hash) => hash, @@ -64,7 +65,7 @@ impl Signer for AddressSigner { Ok(BinaryData::new(signature.to_vec())) } - fn sign_create_witness( + async fn sign_create_witness( &self, key: &PlatformAddress, data: &[u8], diff --git a/packages/rs-sdk-ffi/src/dashpay/contact_request.rs b/packages/rs-sdk-ffi/src/dashpay/contact_request.rs index 93ebbebd62c..0a8d79c69b7 100644 --- a/packages/rs-sdk-ffi/src/dashpay/contact_request.rs +++ b/packages/rs-sdk-ffi/src/dashpay/contact_request.rs @@ -1,8 +1,8 @@ //! DashPay contact request operations use crate::{ - signer::VTableSigner, utils, DashSDKError, DashSDKErrorCode, DashSDKResult, FFIError, - SDKHandle, SDKWrapper, + signer::{VTableSigner, VTableSignerRef}, + utils, DashSDKError, DashSDKErrorCode, DashSDKResult, FFIError, SDKHandle, SDKWrapper, }; use dash_sdk::dpp::dashcore::secp256k1::{PublicKey, SecretKey}; use dash_sdk::dpp::identity::{Identity, IdentityPublicKey}; @@ -559,10 +559,9 @@ pub unsafe extern "C" fn dash_sdk_dashpay_send_contact_request( let key_clone = (*key_arc).clone(); std::mem::forget(key_arc); - // Get signer from handle - let signer_arc = Arc::from_raw(signer as *const VTableSigner); - let signer_clone = *signer_arc; - std::mem::forget(signer_arc); + // Get signer from handle (non-owning reference — the handle remains + // owned by the caller and is freed via `dash_sdk_signer_destroy`). + let signer_ref = VTableSignerRef(&*(signer as *const VTableSigner)); // Create contact request input let contact_request_input = ContactRequestInput { @@ -579,7 +578,7 @@ pub unsafe extern "C" fn dash_sdk_dashpay_send_contact_request( let send_input = SendContactRequestInput { contact_request: contact_request_input, identity_public_key: key_clone, - signer: signer_clone, + signer: signer_ref, }; // Send contact request based on ECDH mode diff --git a/packages/rs-sdk-ffi/src/dpns/register.rs b/packages/rs-sdk-ffi/src/dpns/register.rs index 886d5194856..e3ed6a4f544 100644 --- a/packages/rs-sdk-ffi/src/dpns/register.rs +++ b/packages/rs-sdk-ffi/src/dpns/register.rs @@ -1,8 +1,8 @@ //! DPNS name registration operations use crate::{ - signer::VTableSigner, utils, DashSDKError, DashSDKErrorCode, DashSDKResult, FFIError, - SDKHandle, SDKWrapper, + signer::{VTableSigner, VTableSignerRef}, + utils, DashSDKError, DashSDKErrorCode, DashSDKResult, FFIError, SDKHandle, SDKWrapper, }; use dash_sdk::dpp::identity::{Identity, IdentityPublicKey}; use dash_sdk::platform::dpns_usernames::RegisterDpnsNameInput; @@ -95,18 +95,16 @@ pub unsafe extern "C" fn dash_sdk_dpns_register_name( // Don't drop the Arc, just forget it std::mem::forget(key_arc); - // Get signer from handle - let signer_arc = Arc::from_raw(signer as *const VTableSigner); - let signer_clone = *signer_arc; - // Don't drop the Arc, just forget it - std::mem::forget(signer_arc); + // Get signer from handle (non-owning reference — the handle remains + // owned by the caller and is freed via `dash_sdk_signer_destroy`). + let signer_ref = VTableSignerRef(&*(signer as *const VTableSigner)); // Create registration input let input = RegisterDpnsNameInput { label: label_str.clone(), identity: identity_clone, identity_public_key: key_clone, - signer: signer_clone, + signer: signer_ref, preorder_callback: None, }; diff --git a/packages/rs-sdk-ffi/src/identity/transfer.rs b/packages/rs-sdk-ffi/src/identity/transfer.rs index 82989138722..d9e925c556c 100644 --- a/packages/rs-sdk-ffi/src/identity/transfer.rs +++ b/packages/rs-sdk-ffi/src/identity/transfer.rs @@ -99,7 +99,8 @@ pub unsafe extern "C" fn dash_sdk_identity_transfer_credits( // and points to a live Identity. We cannot detect dangling pointers without a handle // registry; null checks are the only sound validation available. let from_identity = &*(from_identity_handle as *const Identity); - let signer = &*(signer_handle as *const crate::signer::VTableSigner); + let signer = + crate::signer::VTableSignerRef(&*(signer_handle as *const crate::signer::VTableSigner)); eprintln!( "🔵 dash_sdk_identity_transfer_credits: public_key_id = {}", @@ -201,7 +202,7 @@ pub unsafe extern "C" fn dash_sdk_identity_transfer_credits( eprintln!(" - to_id: {:?}", to_id); eprintln!(" - amount: {}", amount); eprintln!(" - signing_key present: {}", signing_key.is_some()); - eprintln!(" - signer: {:p}", signer as *const _); + eprintln!(" - signer: {:p}", signer.0 as *const _); // Additional defensive checks before calling transfer_credits eprintln!("🔵 dash_sdk_identity_transfer_credits: Performing defensive checks..."); @@ -238,7 +239,7 @@ pub unsafe extern "C" fn dash_sdk_identity_transfer_credits( eprintln!("🔵 dash_sdk_identity_transfer_credits: This will internally call IdentityCreditTransferTransition::try_from_identity"); let transfer_result = from_identity - .transfer_credits(&wrapper.sdk, to_id, amount, signing_key, *signer, settings) + .transfer_credits(&wrapper.sdk, to_id, amount, signing_key, signer, settings) .await; eprintln!("🔵 dash_sdk_identity_transfer_credits: transfer_credits returned: {:?}", transfer_result.is_ok()); diff --git a/packages/rs-sdk-ffi/src/identity/withdraw.rs b/packages/rs-sdk-ffi/src/identity/withdraw.rs index 2ca14d2a0f7..fff0ae2e6ad 100644 --- a/packages/rs-sdk-ffi/src/identity/withdraw.rs +++ b/packages/rs-sdk-ffi/src/identity/withdraw.rs @@ -89,7 +89,8 @@ pub unsafe extern "C" fn dash_sdk_identity_withdraw( // and points to a live Identity. We cannot detect dangling pointers without a handle // registry; null checks are the only sound validation available. let identity = &*(identity_handle as *const Identity); - let signer = &*(signer_handle as *const crate::signer::VTableSigner); + let signer = + crate::signer::VTableSignerRef(&*(signer_handle as *const crate::signer::VTableSigner)); debug!("dash_sdk_identity_withdraw: handles dereferenced successfully"); debug!(id = ?identity.id(), balance = identity.balance(), keys = identity.public_keys().len(), "dash_sdk_identity_withdraw: identity summary"); @@ -192,7 +193,7 @@ pub unsafe extern "C" fn dash_sdk_identity_withdraw( use dash_sdk::platform::transition::withdraw_from_identity::WithdrawFromIdentity; debug!("dash_sdk_identity_withdraw: trait imported"); - debug!(?withdraw_address, amount, ?core_fee, has_signing_key = signing_key.is_some(), signer_ptr = ?(signer as *const _), "dash_sdk_identity_withdraw: calling withdraw method"); + debug!(?withdraw_address, amount, ?core_fee, has_signing_key = signing_key.is_some(), signer_ptr = ?(signer.0 as *const _), "dash_sdk_identity_withdraw: calling withdraw method"); // Log signing key details for diagnostics if let Some(key) = signing_key { @@ -216,7 +217,7 @@ pub unsafe extern "C" fn dash_sdk_identity_withdraw( amount, core_fee, signing_key, - *signer, + signer, settings, ) .await diff --git a/packages/rs-sdk-ffi/src/shielded/transitions/builders.rs b/packages/rs-sdk-ffi/src/shielded/transitions/builders.rs index f3ba6dc7012..cc13fcea547 100644 --- a/packages/rs-sdk-ffi/src/shielded/transitions/builders.rs +++ b/packages/rs-sdk-ffi/src/shielded/transitions/builders.rs @@ -337,6 +337,7 @@ pub unsafe extern "C" fn dash_sdk_shielded_build_shield( user_fee_increase, wrapper.sdk.version(), ) + .await .map_err(|e| { FFIError::InternalError(format!("Failed to build shield transition: {}", e)) })?; diff --git a/packages/rs-sdk-ffi/src/signer.rs b/packages/rs-sdk-ffi/src/signer.rs index 90068f20fc3..b73743ce961 100644 --- a/packages/rs-sdk-ffi/src/signer.rs +++ b/packages/rs-sdk-ffi/src/signer.rs @@ -1,254 +1,512 @@ //! Signer interface for iOS FFI +//! +//! # Async completion-callback signer (BREAKING CHANGE from the pre-async design) +//! +//! The `Signer` trait in `rs-dpp` is now `async`, which means iOS (or any +//! FFI caller) can implement *truly* async signing — for example, calling the +//! iOS Secure Enclave or showing a biometric prompt — without blocking any +//! Tokio worker thread. +//! +//! To make this work across the C ABI we use a **completion-callback** pattern +//! instead of the old synchronous `sign` return-value pattern: +//! +//! 1. Rust calls `SignAsyncCallback` with a `completion_ctx` token and a +//! `SignCompletionCallback` function pointer. +//! 2. The C / Swift / Kotlin implementation returns **immediately** from the +//! `SignAsyncCallback` — it has not signed yet. It stashes the `completion_ctx` +//! and `completion` callback somewhere (e.g. captured in a Swift closure). +//! 3. When signing finishes (possibly on another thread, possibly minutes +//! later after a biometric prompt), the caller invokes `completion(ctx, ...)` +//! with either a signature or an error message. +//! 4. The Rust side (see `dash_sdk_sign_async_completion` below) converts the completion +//! args to a `Result` and wakes the awaiting +//! `async fn sign` via a `tokio::sync::oneshot`. No thread is blocked during +//! the wait. +//! +//! ## iOS migration notes (from the old vtable) +//! +//! The old sync vtable returned a `*mut u8` signature buffer directly and took +//! a `free_result` deallocator slot. Both of those are gone: +//! +//! - `SignerVTable::sign` → replaced with `SignerVTable::sign_async` +//! - `SignerVTable::free_result` → **removed**. The Rust side now *copies* the +//! signature bytes out of the completion call before returning, so the iOS +//! side owns its buffer start-to-finish and frees it with its own allocator. +//! - `SignCallback` type → replaced with `SignAsyncCallback` +//! - `dash_sdk_signer_create` signature changed — see the function docs below. +//! +//! Callers of `dash_sdk_signer_create` (notably the Swift SDK) **must** be +//! updated before they will compile. Until then, iOS HSM signing from the +//! old Swift code will not work. use crate::types::SignerHandle; +use async_trait::async_trait; use dash_sdk::dpp::identity::signer::Signer; use dash_sdk::dpp::platform_value::BinaryData; use dash_sdk::dpp::prelude::{IdentityPublicKey, ProtocolError}; use simple_signer::SingleKeySigner; +use std::ffi::{c_void, CStr}; +use std::os::raw::c_char; +use std::sync::Arc; +use tokio::sync::oneshot; -/// C-compatible vtable for signers +/// C-compatible async vtable for signers. +/// +/// `sign_async` returns immediately; the caller is expected to eventually +/// invoke the supplied `SignCompletionCallback` with the signing result. +/// `can_sign_with` remains synchronous — checking whether a key is available +/// is fast and doesn't need async. #[repr(C)] pub struct SignerVTable { - /// Sign function pointer - pub sign: unsafe extern "C" fn( - signer: *const std::os::raw::c_void, - identity_public_key_bytes: *const u8, - identity_public_key_len: usize, - data: *const u8, - data_len: usize, - result_len: *mut usize, - ) -> *mut u8, - - /// Can sign with function pointer - pub can_sign_with: unsafe extern "C" fn( - signer: *const std::os::raw::c_void, - identity_public_key_bytes: *const u8, - identity_public_key_len: usize, - ) -> bool, - - /// Destructor function pointer - pub destroy: unsafe extern "C" fn(signer: *mut std::os::raw::c_void), - - /// Optional custom deallocator for sign result buffers. - /// - /// When the `sign` callback returns a buffer, this function will be called - /// to free it. If `None`, `libc::free` is used as a fallback (which requires - /// the buffer to have been allocated with `malloc`/`calloc`). + /// Async sign function pointer. /// - /// **Swift / Kotlin callers** that allocate with their own allocator (e.g. - /// `UnsafeMutablePointer.allocate`) **must** supply a matching - /// deallocator here to avoid undefined behavior. - pub free_result: Option, + /// Implementations MUST eventually call the supplied `completion` exactly + /// once with the supplied `completion_ctx`. Failing to call it will cause + /// the awaiting `async fn sign` on the Rust side to hang forever. + pub sign_async: SignAsyncCallback, + + /// Can-sign-with function pointer. Synchronous. + pub can_sign_with: CanSignCallback, + + /// Destructor function pointer for the `signer_ptr` state. + pub destroy: unsafe extern "C" fn(signer: *mut c_void), } -/// Generic signer that uses vtable for dynamic dispatch -#[repr(C)] -#[derive(Clone, Copy)] +/// Function pointer type for the async sign callback. +/// +/// Invoked by the Rust side whenever a signature is needed. Implementations +/// MUST return immediately and MUST arrange for `completion` to be called +/// exactly once with the matching `completion_ctx`. It is valid (and +/// expected, for things like biometric-gated HSM signing) for the completion +/// to run on a different thread than `SignAsyncCallback` itself. +/// +/// # Safety +/// - `key_bytes` / `data` are only valid for the duration of this call. +/// If the implementation needs them after returning, it must copy them. +/// - `completion_ctx` is opaque; it must be passed verbatim to `completion`. +/// - `completion` must be called exactly once. +pub type SignAsyncCallback = unsafe extern "C" fn( + signer: *const c_void, + key_bytes: *const u8, + key_len: usize, + data: *const u8, + data_len: usize, + completion_ctx: *mut c_void, + completion: SignCompletionCallback, +); + +/// Completion callback invoked by the C / iOS side when a signature is ready. +/// +/// # Parameters +/// - `completion_ctx`: the exact token passed in by the Rust side. +/// - `signature` / `signature_len`: signature bytes on success. Ignored when +/// `error_message` is non-null. May be null with `signature_len == 0` if +/// `error_message` is non-null. +/// - `error_message`: null-terminated UTF-8 error string on failure, null on +/// success. Ownership is *not* transferred — the Rust side copies the string +/// before returning, so the caller can free/reuse the buffer immediately +/// after the completion returns. +/// +/// # Safety +/// - Must be called at most once per `completion_ctx`. +/// - The `signature` buffer may be freed/reused as soon as this function +/// returns — the Rust side copies the bytes into an owned `Vec` before +/// the call returns. +pub type SignCompletionCallback = unsafe extern "C" fn( + completion_ctx: *mut c_void, + signature: *const u8, + signature_len: usize, + error_message: *const c_char, +); + +/// Function pointer type for the synchronous `can_sign_with` callback. +pub type CanSignCallback = + unsafe extern "C" fn(signer: *const c_void, key_bytes: *const u8, key_len: usize) -> bool; + +/// Optional destructor callback (may be NULL from C). +pub type DestroyCallback = Option; + +/// Payload passed through `completion_ctx`. Sent over the oneshot channel +/// back to the awaiting Rust `async fn sign`. +type SignResult = Result, ProtocolError>; + +/// Generic signer that dispatches to either: +/// - a C-ABI async vtable (for iOS HSM / keychain / external signers), or +/// - a native Rust `Signer` implementation (e.g. `SingleKeySigner`), which +/// avoids the C callback bounce entirely. pub struct VTableSigner { - /// Pointer to the actual signer implementation - pub signer_ptr: *mut std::os::raw::c_void, - /// Pointer to the vtable - pub vtable: *const SignerVTable, + inner: Inner, +} + +enum Inner { + /// C-ABI callback signer. `signer_ptr` and `vtable` are opaque FFI + /// pointers owned by this `VTableSigner` (or pointing at a static + /// vtable — see `owns_vtable`). + Callback { + signer_ptr: *mut c_void, + vtable: *const SignerVTable, + /// When true, the vtable was heap-allocated by + /// `dash_sdk_signer_create` and must be freed on destroy. + owns_vtable: bool, + }, + /// Native Rust signer. No C callbacks involved at all. + Native(Arc>), } // SAFETY: VTableSigner can be sent between threads because: -// 1. The vtable is immutable (static) -// 2. The actual signer implementations must handle their own thread safety +// 1. The vtable is immutable (static or heap-allocated once, never mutated). +// 2. The actual signer implementations must handle their own thread safety. +// 3. Native variant stores an Arc. unsafe impl Send for VTableSigner {} - -// SAFETY: VTableSigner can be shared between threads because: -// 1. The vtable functions are thread-safe (they take immutable references) -// 2. The actual signer implementations must handle their own thread safety unsafe impl Sync for VTableSigner {} impl std::fmt::Debug for VTableSigner { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("VTableSigner") - .field("signer_ptr", &self.signer_ptr) - .field("vtable", &self.vtable) - .finish() + match &self.inner { + Inner::Callback { + signer_ptr, + vtable, + owns_vtable, + } => f + .debug_struct("VTableSigner::Callback") + .field("signer_ptr", signer_ptr) + .field("vtable", vtable) + .field("owns_vtable", owns_vtable) + .finish(), + Inner::Native(_) => f + .debug_struct("VTableSigner::Native") + .finish_non_exhaustive(), + } } } +impl VTableSigner { + /// Create a new callback-based signer. The caller retains responsibility + /// for the underlying vtable (is it static? heap? does it need freeing?). + /// + /// When `owns_vtable` is true, dropping / destroying this signer will + /// `Box::from_raw` the vtable pointer. When false, the vtable is assumed + /// to be `'static` or otherwise owned externally. + /// + /// # Safety + /// - `vtable` must point at a valid, properly-initialized `SignerVTable` + /// for the entire lifetime of this signer. + /// - If `owns_vtable == true`, `vtable` must have been produced by + /// `Box::into_raw(Box::new(...))`. + /// - `signer_ptr` must remain valid for the entire lifetime of this + /// signer, and must be compatible with the vtable's `destroy`. + pub unsafe fn from_callback( + signer_ptr: *mut c_void, + vtable: *const SignerVTable, + owns_vtable: bool, + ) -> Self { + Self { + inner: Inner::Callback { + signer_ptr, + vtable, + owns_vtable, + }, + } + } + + /// Create a new signer that wraps a native Rust `Signer` implementation. + /// No C callbacks are involved — the trait impl delegates directly. + pub fn from_native(signer: Arc>) -> Self { + Self { + inner: Inner::Native(signer), + } + } +} + +impl Drop for VTableSigner { + fn drop(&mut self) { + if let Inner::Callback { + signer_ptr, + vtable, + owns_vtable, + } = &self.inner + { + // SAFETY: vtable is still valid here (we haven't freed it yet). + // The destructor is responsible for cleaning up `signer_ptr`. + let signer_ptr = *signer_ptr; + let vtable = *vtable; + let owns_vtable = *owns_vtable; + unsafe { + if !vtable.is_null() { + ((*vtable).destroy)(signer_ptr); + if owns_vtable { + let _ = Box::from_raw(vtable as *mut SignerVTable); + } + } + } + } + // Inner::Native drops its Arc automatically. + } +} + +#[async_trait] impl Signer for VTableSigner { - fn sign( + async fn sign( &self, identity_public_key: &IdentityPublicKey, data: &[u8], ) -> Result { - unsafe { - // Serialize the public key - let key_bytes = - bincode::encode_to_vec(identity_public_key, bincode::config::standard()) - .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; - - let mut result_len: usize = 0; - let result_ptr = ((*self.vtable).sign)( - self.signer_ptr, - key_bytes.as_ptr(), - key_bytes.len(), - data.as_ptr(), - data.len(), - &mut result_len, - ); - - if result_ptr.is_null() { - return Err(ProtocolError::Generic("Signing failed".to_string())); + match &self.inner { + Inner::Native(signer) => signer.sign(identity_public_key, data).await, + Inner::Callback { + signer_ptr, vtable, .. + } => { + // Serialize the public key for the C side. + let key_bytes = + bincode::encode_to_vec(identity_public_key, bincode::config::standard()) + .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; + + // Build a oneshot channel so the async fn can await the + // completion callback without blocking any thread. + let (tx, rx) = oneshot::channel::(); + let tx_box: Box> = Box::new(tx); + let completion_ctx = Box::into_raw(tx_box) as *mut c_void; + + // SAFETY: vtable is non-null for the Callback variant by + // construction, and sign_async is required to eventually call + // `completion` with `completion_ctx`. + unsafe { + ((*(*vtable)).sign_async)( + *signer_ptr as *const c_void, + key_bytes.as_ptr(), + key_bytes.len(), + data.as_ptr(), + data.len(), + completion_ctx, + dash_sdk_sign_async_completion, + ); + } + + // Await the completion. The oneshot receiver is a real async + // point — the Tokio worker is free to run other tasks. + match rx.await { + Ok(Ok(sig)) => Ok(BinaryData::from(sig)), + Ok(Err(e)) => Err(e), + Err(_recv_err) => { + // Sender dropped without sending. This can only + // happen if the iOS side forgot to call completion. + // See the note on `SignAsyncCallback` — that is a + // contract violation, but we surface it as a + // recoverable protocol error rather than hang forever. + Err(ProtocolError::Generic( + "Signer completion channel dropped without a result; \ + the FFI signer did not call its completion callback" + .to_string(), + )) + } + } } + } + } - // Convert result to BinaryData (copy before freeing) - let signature = std::slice::from_raw_parts(result_ptr, result_len).to_vec(); - - // Free the result using the vtable's custom deallocator if provided, - // otherwise fall back to libc::free (which requires malloc-allocated memory). - if let Some(free_fn) = (*self.vtable).free_result { - free_fn(result_ptr, result_len); - } else { - dash_sdk_bytes_free(result_ptr); + async fn sign_create_witness( + &self, + identity_public_key: &IdentityPublicKey, + data: &[u8], + ) -> Result { + // For callback-based iOS signers we always produce a P2PKH witness + // from the raw signature — matching the pre-async behavior. Native + // signers get to use their own `sign_create_witness` impl. + match &self.inner { + Inner::Native(signer) => signer.sign_create_witness(identity_public_key, data).await, + Inner::Callback { .. } => { + let signature = self.sign(identity_public_key, data).await?; + Ok(dash_sdk::dpp::address_funds::AddressWitness::P2pkh { signature }) } + } + } - Ok(BinaryData::from(signature)) + fn can_sign_with(&self, identity_public_key: &IdentityPublicKey) -> bool { + match &self.inner { + Inner::Native(signer) => signer.can_sign_with(identity_public_key), + Inner::Callback { + signer_ptr, vtable, .. + } => { + // SAFETY: vtable is non-null for the Callback variant. + unsafe { + match bincode::encode_to_vec(identity_public_key, bincode::config::standard()) { + Ok(key_bytes) => ((*(*vtable)).can_sign_with)( + *signer_ptr as *const c_void, + key_bytes.as_ptr(), + key_bytes.len(), + ), + Err(_) => false, + } + } + } } } +} + +/// Non-owning reference wrapper around a `VTableSigner` that itself +/// implements `Signer`. Several rs-sdk APIs +/// (`transfer_credits`, `withdraw`, `register_dpns_name`, ...) take the +/// signer by value (`S: Signer`). Since `VTableSigner` +/// is neither `Copy` nor `Clone` — the `Inner::Callback` variant owns a +/// vtable pointer whose destructor must not run twice — the FFI layer +/// passes this lightweight reference wrapper instead. It forwards every +/// `Signer` method to the underlying `VTableSigner`. +#[derive(Debug)] +pub struct VTableSignerRef<'a>(pub &'a VTableSigner); + +#[async_trait] +impl<'a> Signer for VTableSignerRef<'a> { + async fn sign( + &self, + identity_public_key: &IdentityPublicKey, + data: &[u8], + ) -> Result { + self.0.sign(identity_public_key, data).await + } - fn sign_create_witness( + async fn sign_create_witness( &self, identity_public_key: &IdentityPublicKey, data: &[u8], ) -> Result { - // Sign the data first - let signature = self.sign(identity_public_key, data)?; - // Create P2PKH witness from signature (the most common case for single key signers) - Ok(dash_sdk::dpp::address_funds::AddressWitness::P2pkh { signature }) + self.0.sign_create_witness(identity_public_key, data).await } fn can_sign_with(&self, identity_public_key: &IdentityPublicKey) -> bool { - unsafe { - // Serialize the public key - match bincode::encode_to_vec(identity_public_key, bincode::config::standard()) { - Ok(key_bytes) => ((*self.vtable).can_sign_with)( - self.signer_ptr, - key_bytes.as_ptr(), - key_bytes.len(), - ), - Err(_) => false, - } - } + self.0.can_sign_with(identity_public_key) } } -/// Function pointer type for signing callback from iOS/external code -/// Returns pointer to allocated byte array (caller must free with dash_sdk_bytes_free) -/// Returns null on error -pub type SignCallback = unsafe extern "C" fn( - signer: *const std::os::raw::c_void, - identity_public_key_bytes: *const u8, - identity_public_key_len: usize, - data: *const u8, - data_len: usize, - result_len: *mut usize, -) -> *mut u8; - -/// Function pointer type for can_sign_with callback from iOS/external code -pub type CanSignCallback = unsafe extern "C" fn( - signer: *const std::os::raw::c_void, - identity_public_key_bytes: *const u8, - identity_public_key_len: usize, -) -> bool; - -/// Function pointer type for destructor callback -/// This is an Option to allow for NULL pointers from C -pub type DestroyCallback = Option; - -/// Optional custom deallocator for sign result buffers. -/// When provided, this function is called to free the buffer returned by the -/// `sign` callback instead of the default `libc::free`. This is an `Option` so -/// that passing `NULL` from C selects the default behavior. -pub type FreeResultCallback = Option; - -/// Create a new signer with callbacks from iOS/external code +/// Rust-side completion callback. Exported so the iOS side can call it via +/// the `SignCompletionCallback` function pointer that Rust hands to the C +/// `sign_async` callback. You do not need to look this symbol up — the +/// pointer is passed directly. +/// +/// # Safety +/// - `completion_ctx` must be the exact pointer that was passed to +/// `SignAsyncCallback`, and must not have been used in a previous +/// completion call. +/// - If `error_message` is non-null it must point to a valid null-terminated +/// UTF-8 (or at least CStr-safe) string. The string is copied into an owned +/// `String` before this function returns, so the caller may free it +/// immediately afterwards. +/// - If `signature` is non-null it must point to at least `signature_len` +/// readable bytes. The bytes are copied into an owned `Vec` before this +/// function returns. +#[no_mangle] +pub unsafe extern "C" fn dash_sdk_sign_async_completion( + completion_ctx: *mut c_void, + signature: *const u8, + signature_len: usize, + error_message: *const c_char, +) { + if completion_ctx.is_null() { + // Nothing we can do — the Rust side will time out via channel drop + // if it ever receives no completion at all. + return; + } + + // Reconstruct the Sender box. From here on we OWN the oneshot sender + // and must either send or drop it. + let tx: Box> = + Box::from_raw(completion_ctx as *mut oneshot::Sender); + + let result: SignResult = if !error_message.is_null() { + let msg = CStr::from_ptr(error_message).to_string_lossy().into_owned(); + Err(ProtocolError::Generic(msg)) + } else if signature.is_null() { + Err(ProtocolError::Generic( + "Signer completion returned null signature with no error message".to_string(), + )) + } else { + // Copy out the signature bytes — the iOS side owns its buffer. + let bytes = std::slice::from_raw_parts(signature, signature_len).to_vec(); + Ok(bytes) + }; + + // `oneshot::Sender::send` is non-blocking and thread-safe; it returns + // Err if the receiver was already dropped, which we ignore because the + // awaiting task is gone anyway. + let _ = tx.send(result); +} + +/// Create a new signer with async callbacks from iOS / external code. /// -/// This creates a VTableSigner that can be used for all state transitions. -/// The callbacks should handle the actual signing logic. +/// # Breaking change from the pre-async design +/// The `SignCallback` + `free_result_callback` pair has been replaced with a +/// single `SignAsyncCallback`. See the top-of-file docs for migration notes. /// /// # Parameters -/// - `sign_callback`: Function to sign data -/// - `can_sign_callback`: Function to check if can sign with a key -/// - `destroy_callback`: Optional destructor (can be NULL) -/// - `free_result_callback`: Optional custom deallocator for buffers returned by -/// `sign_callback`. When NULL, `libc::free` is used. Swift/Kotlin callers that -/// allocate with their own allocator **must** supply a matching deallocator. +/// - `sign_async_callback`: async sign function (must call its completion). +/// - `can_sign_callback`: synchronous key-availability check. +/// - `destroy_callback`: optional destructor for the `signer` state. Pass NULL +/// if there is nothing to clean up. +/// +/// Note: there is intentionally no `signer_ptr` parameter here because the +/// pre-async iOS path never used it — the signing state was captured by the +/// C function pointers themselves. If you need a signer context pointer, +/// construct a `VTableSigner` from Rust using `VTableSigner::from_callback`. +/// /// # Safety -/// - Callback function pointers must be valid and follow the required ABI and lifetime for the duration of use. -/// - The returned `SignerHandle` must be destroyed with `dash_sdk_signer_destroy` to avoid leaks. +/// - Callback function pointers must be valid and follow the required ABI +/// for the duration of use. +/// - The returned `SignerHandle` must be destroyed with +/// `dash_sdk_signer_destroy` to avoid leaks. #[no_mangle] pub unsafe extern "C" fn dash_sdk_signer_create( - sign_callback: SignCallback, + sign_async_callback: SignAsyncCallback, can_sign_callback: CanSignCallback, - destroy_callback: DestroyCallback, // Option type handles NULL automatically - free_result_callback: FreeResultCallback, // Option type handles NULL automatically + destroy_callback: DestroyCallback, ) -> *mut SignerHandle { - // Create a vtable on the heap so it persists + // Create a vtable on the heap so it persists for the life of the signer. let vtable = Box::new(SignerVTable { - sign: sign_callback, + sign_async: sign_async_callback, can_sign_with: can_sign_callback, destroy: destroy_callback.unwrap_or(default_destroy), - free_result: free_result_callback, }); let vtable_ptr = Box::into_raw(vtable); - // Create the VTableSigner - let vtable_signer = VTableSigner { - signer_ptr: std::ptr::null_mut(), // iOS doesn't need a separate signer_ptr since callbacks handle everything - vtable: vtable_ptr, - }; + // SAFETY: vtable_ptr was just produced by Box::into_raw, so it is valid + // and we own it (owns_vtable = true). + let vtable_signer = VTableSigner::from_callback(std::ptr::null_mut(), vtable_ptr, true); Box::into_raw(Box::new(vtable_signer)) as *mut SignerHandle } -/// Default destroy function that does nothing -unsafe extern "C" fn default_destroy(_signer: *mut std::os::raw::c_void) { - // No-op for iOS signers that don't need cleanup +/// Default destroy function that does nothing — used when the C caller +/// passes a NULL destroy callback. +unsafe extern "C" fn default_destroy(_signer: *mut c_void) { + // No-op. } -/// Destroy a signer +/// Destroy a signer. +/// /// # Safety -/// - `handle` must be a valid pointer previously returned by this SDK and not yet destroyed. -/// - It may be null (no-op). After this call the handle must not be used again. +/// - `handle` must be a valid pointer previously returned by this SDK and +/// not yet destroyed. +/// - It may be null (no-op). After this call the handle must not be used +/// again. #[no_mangle] pub unsafe extern "C" fn dash_sdk_signer_destroy(handle: *mut SignerHandle) { - if !handle.is_null() { - let vtable_signer = Box::from_raw(handle as *mut VTableSigner); - - // Call the destructor through the vtable - if !vtable_signer.vtable.is_null() { - ((*vtable_signer.vtable).destroy)(vtable_signer.signer_ptr); - - // Only free the vtable if it's not a static vtable - // Static vtables (like SINGLE_KEY_SIGNER_VTABLE) should not be freed - // We can check if it's the static vtable by comparing the address - let static_vtable_ptr = &SINGLE_KEY_SIGNER_VTABLE as *const SignerVTable; - if vtable_signer.vtable != static_vtable_ptr { - // This is a heap-allocated vtable from dash_sdk_signer_create - let _ = Box::from_raw(vtable_signer.vtable as *mut SignerVTable); - } - } - - // The VTableSigner itself is dropped here + if handle.is_null() { + return; } + // Drop the box — Drop impl calls the vtable destructor and frees the + // vtable if we own it (or drops the Arc for the Native variant). + let _ = Box::from_raw(handle as *mut VTableSigner); } /// Free bytes that were allocated with `malloc`/`calloc`. /// -/// This is the **default** deallocator used when `SignerVTable::free_result` is -/// `None`. If your callback allocates memory with a different allocator (e.g. -/// Swift's `UnsafeMutablePointer.allocate`), supply a custom `free_result` -/// function in the vtable instead of relying on this function. +/// Kept for backwards compatibility with older FFI code that exchanges +/// opaque byte buffers over the ABI. The signer path no longer uses this — +/// signature bytes are copied via the completion callback, not malloc'd. /// /// # Safety /// - `bytes` must be a pointer allocated with `malloc` or `calloc`, or null. -/// - It may be null (no-op). After this call the pointer must not be used again. +/// - It may be null (no-op). After this call the pointer must not be used +/// again. #[no_mangle] pub unsafe extern "C" fn dash_sdk_bytes_free(bytes: *mut u8) { if !bytes.is_null() { @@ -256,145 +514,104 @@ pub unsafe extern "C" fn dash_sdk_bytes_free(bytes: *mut u8) { } } -// Vtable implementation for SingleKeySigner -unsafe extern "C" fn single_key_signer_sign( - signer: *const std::os::raw::c_void, - identity_public_key_bytes: *const u8, - identity_public_key_len: usize, - data: *const u8, - data_len: usize, - result_len: *mut usize, -) -> *mut u8 { - let signer = &*(signer as *const SingleKeySigner); - - // Deserialize the public key - let key_bytes = std::slice::from_raw_parts(identity_public_key_bytes, identity_public_key_len); - let identity_public_key = match bincode::decode_from_slice::( - key_bytes, - bincode::config::standard(), - ) { - Ok((key, _)) => key, - Err(_) => return std::ptr::null_mut(), - }; - - let data_slice = std::slice::from_raw_parts(data, data_len); - - match signer.sign(&identity_public_key, data_slice) { - Ok(signature) => { - let sig_vec = signature.to_vec(); - *result_len = sig_vec.len(); - let result_ptr = libc::malloc(sig_vec.len()) as *mut u8; - if !result_ptr.is_null() { - std::ptr::copy_nonoverlapping(sig_vec.as_ptr(), result_ptr, sig_vec.len()); - } - result_ptr - } - Err(_) => std::ptr::null_mut(), - } -} - -unsafe extern "C" fn single_key_signer_can_sign_with( - signer: *const std::os::raw::c_void, - identity_public_key_bytes: *const u8, - identity_public_key_len: usize, -) -> bool { - let signer = &*(signer as *const SingleKeySigner); - - // Deserialize the public key - let key_bytes = std::slice::from_raw_parts(identity_public_key_bytes, identity_public_key_len); - match bincode::decode_from_slice::(key_bytes, bincode::config::standard()) - { - Ok((identity_public_key, _)) => signer.can_sign_with(&identity_public_key), - Err(_) => false, - } -} - -unsafe extern "C" fn single_key_signer_destroy(signer: *mut std::os::raw::c_void) { - if !signer.is_null() { - let _ = Box::from_raw(signer as *mut SingleKeySigner); - } -} - -/// Static vtable for SingleKeySigner +/// Build a native-Rust signer handle backed by a `SingleKeySigner`. This +/// replaces the old `SINGLE_KEY_SIGNER_VTABLE` static — there is no C +/// callback bounce on this path; the async trait impl calls +/// `SingleKeySigner::sign` directly. /// -/// `free_result` is `None` because `single_key_signer_sign` allocates its -/// result buffer with `libc::malloc`, so `libc::free` (the default) is correct. -pub static SINGLE_KEY_SIGNER_VTABLE: SignerVTable = SignerVTable { - sign: single_key_signer_sign, - can_sign_with: single_key_signer_can_sign_with, - destroy: single_key_signer_destroy, - free_result: None, -}; +/// The returned handle must be destroyed with `dash_sdk_signer_destroy`. +pub fn signer_handle_from_single_key(signer: SingleKeySigner) -> *mut SignerHandle { + let vtable_signer = VTableSigner::from_native(Arc::new(signer)); + Box::into_raw(Box::new(vtable_signer)) as *mut SignerHandle +} #[cfg(test)] mod tests { use super::*; use std::sync::atomic::{AtomicBool, Ordering}; - /// Global flag set by the custom free callback during tests. - static CUSTOM_FREE_CALLED: AtomicBool = AtomicBool::new(false); + /// Global flag set by the completion invocation during tests so we can + /// verify the async bridge actually wired up end-to-end. + static COMPLETION_CALLED: AtomicBool = AtomicBool::new(false); - /// Custom deallocator that records that it was called and then delegates to - /// `libc::free` (valid because the test sign callback allocates with - /// `libc::malloc`). - unsafe extern "C" fn test_custom_free(data: *mut u8, _len: usize) { - CUSTOM_FREE_CALLED.store(true, Ordering::SeqCst); - libc::free(data as *mut libc::c_void); + /// Test sign callback: immediately completes synchronously with a fake + /// 64-byte signature. This simulates the simplest possible iOS signer. + unsafe extern "C" fn test_sign_async_sync( + _signer: *const c_void, + _key_bytes: *const u8, + _key_len: usize, + _data: *const u8, + _data_len: usize, + completion_ctx: *mut c_void, + completion: SignCompletionCallback, + ) { + COMPLETION_CALLED.store(true, Ordering::SeqCst); + let sig = [0xABu8; 64]; + // Null error_message = success. + completion(completion_ctx, sig.as_ptr(), sig.len(), std::ptr::null()); } - /// Sign callback for tests -- allocates the result with `libc::malloc`. - unsafe extern "C" fn test_sign( - _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + /// Test sign callback that reports an error via the completion callback. + unsafe extern "C" fn test_sign_async_error( + _signer: *const c_void, + _key_bytes: *const u8, + _key_len: usize, _data: *const u8, _data_len: usize, - result_len: *mut usize, - ) -> *mut u8 { - let sig = [0xABu8; 64]; - *result_len = sig.len(); - let ptr = libc::malloc(sig.len()) as *mut u8; - if !ptr.is_null() { - std::ptr::copy_nonoverlapping(sig.as_ptr(), ptr, sig.len()); - } - ptr + completion_ctx: *mut c_void, + completion: SignCompletionCallback, + ) { + let msg = c"simulated hsm error"; + completion(completion_ctx, std::ptr::null(), 0, msg.as_ptr()); + } + + /// Test sign callback that spawns a *different thread* to invoke the + /// completion — exercising the thread-safety of `oneshot::Sender`. + unsafe extern "C" fn test_sign_async_threaded( + _signer: *const c_void, + _key_bytes: *const u8, + _key_len: usize, + _data: *const u8, + _data_len: usize, + completion_ctx: *mut c_void, + completion: SignCompletionCallback, + ) { + // Move the raw pointer over thread boundary. This is exactly what + // the iOS side will do for a biometric prompt. + let ctx_usize = completion_ctx as usize; + std::thread::spawn(move || { + // Small delay to make sure the await is actually suspending. + std::thread::sleep(std::time::Duration::from_millis(20)); + let sig = [0x55u8; 64]; + unsafe { + completion( + ctx_usize as *mut c_void, + sig.as_ptr(), + sig.len(), + std::ptr::null(), + ); + } + }); } - /// Can-sign callback for tests. + /// Test can-sign callback. unsafe extern "C" fn test_can_sign( - _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _signer: *const c_void, + _key_bytes: *const u8, + _key_len: usize, ) -> bool { true } - /// Destroy callback for tests (no-op). - unsafe extern "C" fn test_destroy(_signer: *mut std::os::raw::c_void) {} - - #[test] - fn custom_free_result_callback_is_invoked() { - // Reset global flag - CUSTOM_FREE_CALLED.store(false, Ordering::SeqCst); - - let vtable = SignerVTable { - sign: test_sign, - can_sign_with: test_can_sign, - destroy: test_destroy, - free_result: Some(test_custom_free), - }; - - let signer = VTableSigner { - signer_ptr: std::ptr::null_mut(), - vtable: &vtable, - }; + /// Test destroy callback (no-op). + unsafe extern "C" fn test_destroy(_signer: *mut c_void) {} - // Build a minimal identity public key to satisfy the Signer trait. + fn make_dummy_key() -> IdentityPublicKey { use dash_sdk::dpp::identity::identity_public_key::v0::IdentityPublicKeyV0; use dash_sdk::dpp::identity::{KeyType, Purpose, SecurityLevel}; use dash_sdk::dpp::platform_value::BinaryData; - let ipk = IdentityPublicKey::V0(IdentityPublicKeyV0 { + IdentityPublicKey::V0(IdentityPublicKeyV0 { id: 0, purpose: Purpose::AUTHENTICATION, security_level: SecurityLevel::MASTER, @@ -403,50 +620,67 @@ mod tests { data: BinaryData::new(vec![0u8; 33]), disabled_at: None, contract_bounds: None, - }); - - let result = signer.sign(&ipk, &[1, 2, 3]); - assert!(result.is_ok(), "sign should succeed"); - assert_eq!(result.unwrap().len(), 64); - assert!( - CUSTOM_FREE_CALLED.load(Ordering::SeqCst), - "custom free_result callback must have been invoked" - ); + }) } - #[test] - fn default_free_result_when_none() { - // When free_result is None, VTableSigner::sign should fall back to - // dash_sdk_bytes_free (libc::free) without crashing. - let vtable = SignerVTable { - sign: test_sign, + fn make_signer(sign_async: SignAsyncCallback) -> VTableSigner { + let vtable = Box::new(SignerVTable { + sign_async, can_sign_with: test_can_sign, destroy: test_destroy, - free_result: None, - }; + }); + let vtable_ptr = Box::into_raw(vtable); + // SAFETY: we just produced the vtable with Box::into_raw and we take + // ownership of it here (owns_vtable = true) so it will be freed on drop. + unsafe { VTableSigner::from_callback(std::ptr::null_mut(), vtable_ptr, true) } + } - let signer = VTableSigner { - signer_ptr: std::ptr::null_mut(), - vtable: &vtable, - }; + #[tokio::test] + async fn completion_callback_same_thread_success() { + COMPLETION_CALLED.store(false, Ordering::SeqCst); + let signer = make_signer(test_sign_async_sync); + let key = make_dummy_key(); + + let sig = signer + .sign(&key, &[1, 2, 3]) + .await + .expect("sign should succeed"); + assert_eq!(sig.len(), 64); + assert!( + COMPLETION_CALLED.load(Ordering::SeqCst), + "completion callback must have been invoked" + ); + } - use dash_sdk::dpp::identity::identity_public_key::v0::IdentityPublicKeyV0; - use dash_sdk::dpp::identity::{KeyType, Purpose, SecurityLevel}; - use dash_sdk::dpp::platform_value::BinaryData; + #[tokio::test] + async fn completion_callback_error_path() { + let signer = make_signer(test_sign_async_error); + let key = make_dummy_key(); - let ipk = IdentityPublicKey::V0(IdentityPublicKeyV0 { - id: 0, - purpose: Purpose::AUTHENTICATION, - security_level: SecurityLevel::MASTER, - key_type: KeyType::ECDSA_SECP256K1, - read_only: false, - data: BinaryData::new(vec![0u8; 33]), - disabled_at: None, - contract_bounds: None, - }); + let err = signer + .sign(&key, &[4, 5, 6]) + .await + .expect_err("sign should fail"); + let msg = err.to_string(); + assert!( + msg.contains("simulated hsm error"), + "error message should propagate: got {msg}" + ); + } - let result = signer.sign(&ipk, &[4, 5, 6]); - assert!(result.is_ok(), "sign with None free_result should succeed"); - assert_eq!(result.unwrap().len(), 64); + #[tokio::test] + async fn completion_callback_cross_thread() { + // Exercises the realistic case: completion runs on a different + // thread than sign_async was called from. tokio::sync::oneshot + // handles this without blocking our worker. + let signer = make_signer(test_sign_async_threaded); + let key = make_dummy_key(); + + let sig = signer + .sign(&key, &[7, 8, 9]) + .await + .expect("sign should succeed from another thread"); + assert_eq!(sig.len(), 64); + assert_eq!(sig.as_slice()[0], 0x55); } } diff --git a/packages/rs-sdk-ffi/src/signer_simple.rs b/packages/rs-sdk-ffi/src/signer_simple.rs index 67bff492ff8..e44e5c12c0b 100644 --- a/packages/rs-sdk-ffi/src/signer_simple.rs +++ b/packages/rs-sdk-ffi/src/signer_simple.rs @@ -1,5 +1,6 @@ //! Simple private key signer for iOS FFI +use crate::signer::{signer_handle_from_single_key, VTableSigner}; use crate::types::SignerHandle; use crate::{DashSDKError, DashSDKErrorCode, DashSDKResult}; use dash_sdk::dpp::dashcore::Network; @@ -8,12 +9,19 @@ use dash_sdk::dpp::identity::{IdentityPublicKey, KeyType, Purpose, SecurityLevel use simple_signer::SingleKeySigner; use zeroize::Zeroizing; -/// Create a signer from a private key +/// Create a signer from a private key. +/// +/// Internally wraps a `SingleKeySigner` as a native (non-callback) FFI +/// signer — there is no C-callback bounce on this path. The returned +/// handle still conforms to `Signer` via the unified +/// `VTableSigner` wrapper so it can be passed to every other FFI entry +/// point that takes a `SignerHandle`. /// /// # Safety /// - `private_key` must be a valid pointer to at least 32 readable bytes. /// - The function reads exactly `private_key_len` bytes; it must be 32. -/// - The returned handle inside DashSDKResult must be freed using the appropriate SDK destroy function. +/// - The returned handle inside DashSDKResult must be freed with +/// `dash_sdk_signer_destroy`. #[no_mangle] pub unsafe extern "C" fn dash_sdk_signer_create_from_private_key( private_key: *const u8, @@ -33,12 +41,13 @@ pub unsafe extern "C" fn dash_sdk_signer_create_from_private_key( )); } - // Convert the pointer to an array (zeroized on drop to avoid key material lingering on stack) + // Copy into a zeroizing buffer so the key material doesn't linger on + // the stack after we hand it off to SingleKeySigner. let key_slice = std::slice::from_raw_parts(private_key, 32); let mut key_array = Zeroizing::new([0u8; 32]); key_array.copy_from_slice(key_slice); - // network won't matter here + // Network doesn't matter for signing purposes. let signer = match SingleKeySigner::new_from_slice(key_array.as_slice(), Network::Mainnet) { Ok(s) => s, Err(e) => { @@ -46,29 +55,25 @@ pub unsafe extern "C" fn dash_sdk_signer_create_from_private_key( } }; - // Create a VTableSigner that wraps the SingleKeySigner - let vtable_signer = crate::signer::VTableSigner { - signer_ptr: Box::into_raw(Box::new(signer)) as *mut std::os::raw::c_void, - vtable: &crate::signer::SINGLE_KEY_SIGNER_VTABLE, - }; - - let handle = Box::into_raw(Box::new(vtable_signer)) as *mut SignerHandle; + let handle = signer_handle_from_single_key(signer); DashSDKResult::success(handle as *mut std::os::raw::c_void) } -/// Signature result structure +/// Signature result structure. #[repr(C)] pub struct DashSDKSignature { pub signature: *mut u8, pub signature_len: usize, } -/// Sign data with a signer +/// Sign data with a signer. /// /// # Safety -/// - `signer_handle` must be a valid pointer obtained from this SDK and not previously destroyed. +/// - `signer_handle` must be a valid pointer obtained from this SDK and not +/// previously destroyed. /// - `data` must be a valid pointer to `data_len` readable bytes. -/// - The returned signature pointer inside DashSDKResult must be freed with `dash_sdk_signature_free`. +/// - The returned signature pointer inside DashSDKResult must be freed with +/// `dash_sdk_signature_free`. #[no_mangle] pub unsafe extern "C" fn dash_sdk_signer_sign( signer_handle: *mut SignerHandle, @@ -89,12 +94,12 @@ pub unsafe extern "C" fn dash_sdk_signer_sign( )); } - // Treat the handle as a VTableSigner and use its Signer impl - let signer = &*(signer_handle as *const crate::signer::VTableSigner); + let signer = &*(signer_handle as *const VTableSigner); let data_slice = std::slice::from_raw_parts(data, data_len); - // Create a dummy identity public key for signing - // The SingleKeySigner doesn't actually use the key data, just needs one to satisfy the trait + // Create a dummy identity public key for signing. SingleKeySigner + // doesn't actually use the key data, just needs one to satisfy the + // trait contract. let dummy_key = IdentityPublicKey::V0( dash_sdk::dpp::identity::identity_public_key::v0::IdentityPublicKeyV0 { id: 0, @@ -108,7 +113,24 @@ pub unsafe extern "C" fn dash_sdk_signer_sign( }, ); - match signer.sign(&dummy_key, data_slice) { + // The signer trait is async. This function is a synchronous C entry + // point, so we bridge by spinning up a current-thread runtime just + // long enough to drive the signing future. This is safe because + // SingleKeySigner's async fn is non-blocking (pure CPU work). + let runtime = match tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + { + Ok(rt) => rt, + Err(e) => { + return DashSDKResult::error(DashSDKError::new( + DashSDKErrorCode::InternalError, + format!("Failed to create runtime for signing: {}", e), + )); + } + }; + + match runtime.block_on(signer.sign(&dummy_key, data_slice)) { Ok(signature) => { let sig_vec = signature.to_vec(); let sig_len = sig_vec.len(); @@ -128,17 +150,18 @@ pub unsafe extern "C" fn dash_sdk_signer_sign( } } -/// Free a signature +/// Free a signature. /// /// # Safety -/// - `signature` must be a valid pointer returned by this SDK, or null for no-op. +/// - `signature` must be a valid pointer returned by this SDK, or null for +/// no-op. /// - After this call the pointer must not be used again. #[no_mangle] pub unsafe extern "C" fn dash_sdk_signature_free(signature: *mut DashSDKSignature) { if !signature.is_null() { let sig = Box::from_raw(signature); if !sig.signature.is_null() { - // Reconstruct the Vec to properly deallocate + // Reconstruct the Vec to properly deallocate. let _ = Vec::from_raw_parts(sig.signature, sig.signature_len, sig.signature_len); } } diff --git a/packages/rs-sdk-ffi/src/test_utils.rs b/packages/rs-sdk-ffi/src/test_utils.rs index 249b803f004..67ec952b729 100644 --- a/packages/rs-sdk-ffi/src/test_utils.rs +++ b/packages/rs-sdk-ffi/src/test_utils.rs @@ -2,7 +2,7 @@ #[allow(clippy::module_inception, dead_code)] pub mod test_utils { use crate::sdk::SDKWrapper; - use crate::signer::VTableSigner; + use crate::signer::{SignCompletionCallback, SignerVTable, VTableSigner}; use crate::types::{DashSDKPutSettings, SDKHandle}; use dash_sdk::dpp::data_contract::DataContractFactory; use dash_sdk::dpp::identity::identity_public_key::v0::IdentityPublicKeyV0; @@ -12,6 +12,7 @@ pub mod test_utils { use dash_sdk::dpp::prelude::{DataContract, Identifier}; use dash_sdk::platform::transition::put_settings::PutSettings; use std::ffi::CString; + use std::os::raw::c_void; // Helper function to create a mock SDK handle pub fn create_mock_sdk_handle() -> *mut SDKHandle { @@ -45,77 +46,52 @@ pub mod test_utils { })) } - // Mock sign callback for testing - pub unsafe extern "C" fn mock_sign_callback( - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + // Mock async sign callback for testing. Immediately invokes the + // completion callback with a fake 64-byte all-zero signature, which is + // enough to drive FFI entry points that only care that "a signer ran". + pub unsafe extern "C" fn mock_sign_async_callback( + _signer: *const c_void, + _key_bytes: *const u8, + _key_len: usize, _data: *const u8, _data_len: usize, - result_len: *mut usize, - ) -> *mut u8 { + completion_ctx: *mut c_void, + completion: SignCompletionCallback, + ) { let signature = [0u8; 64]; - *result_len = signature.len(); - let ptr = libc::malloc(signature.len()) as *mut u8; - if !ptr.is_null() { - std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len()); - } - ptr + completion( + completion_ctx, + signature.as_ptr(), + signature.len(), + std::ptr::null(), + ); } - // Mock can sign callback for testing + // Mock can sign callback for vtable pub unsafe extern "C" fn mock_can_sign_callback( - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _signer: *const c_void, + _key_bytes: *const u8, + _key_len: usize, ) -> bool { true } - // Helper function to create a mock signer + // Mock destroy callback (no-op). + pub unsafe extern "C" fn mock_destroy_callback(_signer: *mut c_void) {} + + // Helper function to create a mock signer that exercises the C-callback + // path of VTableSigner. The vtable is heap-allocated and owned by the + // VTableSigner (it will free itself on drop). pub fn create_mock_signer() -> Box { - // Create a mock signer vtable - let vtable = Box::new(crate::signer::SignerVTable { - sign: mock_sign_vtable_callback, - can_sign_with: mock_can_sign_vtable_callback, + let vtable = Box::new(SignerVTable { + sign_async: mock_sign_async_callback, + can_sign_with: mock_can_sign_callback, destroy: mock_destroy_callback, - free_result: None, }); - - Box::new(VTableSigner { - signer_ptr: std::ptr::null_mut(), - vtable: Box::into_raw(vtable), - }) - } - - // Mock sign callback for vtable - unsafe extern "C" fn mock_sign_vtable_callback( - _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, - _data: *const u8, - _data_len: usize, - result_len: *mut usize, - ) -> *mut u8 { - let signature = [0u8; 64]; - *result_len = signature.len(); - let ptr = libc::malloc(signature.len()) as *mut u8; - if !ptr.is_null() { - std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len()); - } - ptr - } - - // Mock can sign callback for vtable - unsafe extern "C" fn mock_can_sign_vtable_callback( - _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, - ) -> bool { - true - } - - // Mock destroy callback - unsafe extern "C" fn mock_destroy_callback(_signer: *mut std::os::raw::c_void) { - // No-op for mock + let vtable_ptr = Box::into_raw(vtable); + // SAFETY: we just produced the vtable via Box::into_raw and take + // ownership of it here (owns_vtable = true). + Box::new(unsafe { VTableSigner::from_callback(std::ptr::null_mut(), vtable_ptr, true) }) } // Helper function to create a valid transition owner ID diff --git a/packages/rs-sdk-ffi/src/token/claim.rs b/packages/rs-sdk-ffi/src/token/claim.rs index 2e89b5e44bc..0c7c3db616b 100644 --- a/packages/rs-sdk-ffi/src/token/claim.rs +++ b/packages/rs-sdk-ffi/src/token/claim.rs @@ -232,46 +232,47 @@ mod tests { Box::new(IdentityPublicKey::V0(key_v0)) } - // Mock signer callbacks + // Mock async sign callback for the completion-callback signer vtable. unsafe extern "C" fn mock_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, _data: *const u8, _data_len: usize, - result_len: *mut usize, - ) -> *mut u8 { - // Return a mock signature (64 bytes for ECDSA) allocated with libc::malloc + completion_ctx: *mut std::os::raw::c_void, + completion: crate::signer::SignCompletionCallback, + ) { + // Fake 64-byte signature. Completion is invoked synchronously here; + // that's legal — nothing in VTableSigner requires async completion. let signature = [0u8; 64]; - *result_len = signature.len(); - let ptr = libc::malloc(signature.len()) as *mut u8; - if !ptr.is_null() { - std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len()); - } - ptr + completion( + completion_ctx, + signature.as_ptr(), + signature.len(), + std::ptr::null(), + ); } unsafe extern "C" fn mock_can_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, ) -> bool { true } - // Helper function to create a mock signer + // Helper function to create a mock signer. fn create_mock_signer() -> Box { - // Create a mock signer vtable let vtable = Box::new(crate::signer::SignerVTable { - sign: mock_sign_callback, + sign_async: mock_sign_callback, can_sign_with: mock_can_sign_callback, destroy: mock_destroy_callback, - free_result: None, }); - - Box::new(crate::signer::VTableSigner { - signer_ptr: std::ptr::null_mut(), - vtable: Box::into_raw(vtable), + let vtable_ptr = Box::into_raw(vtable); + // SAFETY: vtable_ptr was just produced by Box::into_raw and we take + // ownership of it (owns_vtable = true). + Box::new(unsafe { + crate::signer::VTableSigner::from_callback(std::ptr::null_mut(), vtable_ptr, true) }) } diff --git a/packages/rs-sdk-ffi/src/token/config_update.rs b/packages/rs-sdk-ffi/src/token/config_update.rs index 28110925ddb..bc6500f3b03 100644 --- a/packages/rs-sdk-ffi/src/token/config_update.rs +++ b/packages/rs-sdk-ffi/src/token/config_update.rs @@ -278,45 +278,47 @@ mod tests { } // Mock callbacks for signer + // Mock async sign callback for the completion-callback signer vtable. unsafe extern "C" fn mock_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, _data: *const u8, _data_len: usize, - result_len: *mut usize, - ) -> *mut u8 { - // Return a mock signature (64 bytes for ECDSA) allocated with libc::malloc + completion_ctx: *mut std::os::raw::c_void, + completion: crate::signer::SignCompletionCallback, + ) { + // Fake 64-byte signature. Completion is invoked synchronously here; + // that's legal — nothing in VTableSigner requires async completion. let signature = [0u8; 64]; - *result_len = signature.len(); - let ptr = libc::malloc(signature.len()) as *mut u8; - if !ptr.is_null() { - std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len()); - } - ptr + completion( + completion_ctx, + signature.as_ptr(), + signature.len(), + std::ptr::null(), + ); } unsafe extern "C" fn mock_can_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, ) -> bool { true } - // Helper function to create a mock signer + // Helper function to create a mock signer. fn create_mock_signer() -> Box { - // Create a mock signer vtable let vtable = Box::new(crate::signer::SignerVTable { - sign: mock_sign_callback, + sign_async: mock_sign_callback, can_sign_with: mock_can_sign_callback, destroy: mock_destroy_callback, - free_result: None, }); - - Box::new(crate::signer::VTableSigner { - signer_ptr: std::ptr::null_mut(), - vtable: Box::into_raw(vtable), + let vtable_ptr = Box::into_raw(vtable); + // SAFETY: vtable_ptr was just produced by Box::into_raw and we take + // ownership of it (owns_vtable = true). + Box::new(unsafe { + crate::signer::VTableSigner::from_callback(std::ptr::null_mut(), vtable_ptr, true) }) } diff --git a/packages/rs-sdk-ffi/src/token/destroy_frozen_funds.rs b/packages/rs-sdk-ffi/src/token/destroy_frozen_funds.rs index 1d7813c777a..679f62dcb5f 100644 --- a/packages/rs-sdk-ffi/src/token/destroy_frozen_funds.rs +++ b/packages/rs-sdk-ffi/src/token/destroy_frozen_funds.rs @@ -224,45 +224,47 @@ mod tests { } // Mock callbacks for signer + // Mock async sign callback for the completion-callback signer vtable. unsafe extern "C" fn mock_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, _data: *const u8, _data_len: usize, - result_len: *mut usize, - ) -> *mut u8 { - // Return a mock signature (64 bytes for ECDSA) allocated with libc::malloc + completion_ctx: *mut std::os::raw::c_void, + completion: crate::signer::SignCompletionCallback, + ) { + // Fake 64-byte signature. Completion is invoked synchronously here; + // that's legal — nothing in VTableSigner requires async completion. let signature = [0u8; 64]; - *result_len = signature.len(); - let ptr = libc::malloc(signature.len()) as *mut u8; - if !ptr.is_null() { - std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len()); - } - ptr + completion( + completion_ctx, + signature.as_ptr(), + signature.len(), + std::ptr::null(), + ); } unsafe extern "C" fn mock_can_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, ) -> bool { true } - // Helper function to create a mock signer + // Helper function to create a mock signer. fn create_mock_signer() -> Box { - // Create a mock signer vtable let vtable = Box::new(crate::signer::SignerVTable { - sign: mock_sign_callback, + sign_async: mock_sign_callback, can_sign_with: mock_can_sign_callback, destroy: mock_destroy_callback, - free_result: None, }); - - Box::new(crate::signer::VTableSigner { - signer_ptr: std::ptr::null_mut(), - vtable: Box::into_raw(vtable), + let vtable_ptr = Box::into_raw(vtable); + // SAFETY: vtable_ptr was just produced by Box::into_raw and we take + // ownership of it (owns_vtable = true). + Box::new(unsafe { + crate::signer::VTableSigner::from_callback(std::ptr::null_mut(), vtable_ptr, true) }) } diff --git a/packages/rs-sdk-ffi/src/token/emergency_action.rs b/packages/rs-sdk-ffi/src/token/emergency_action.rs index 3582fce50c5..bb312614edc 100644 --- a/packages/rs-sdk-ffi/src/token/emergency_action.rs +++ b/packages/rs-sdk-ffi/src/token/emergency_action.rs @@ -239,46 +239,47 @@ mod tests { Box::new(IdentityPublicKey::V0(key_v0)) } - // Mock signer callbacks + // Mock async sign callback for the completion-callback signer vtable. unsafe extern "C" fn mock_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, _data: *const u8, _data_len: usize, - result_len: *mut usize, - ) -> *mut u8 { - // Return a mock signature (64 bytes for ECDSA) allocated with libc::malloc + completion_ctx: *mut std::os::raw::c_void, + completion: crate::signer::SignCompletionCallback, + ) { + // Fake 64-byte signature. Completion is invoked synchronously here; + // that's legal — nothing in VTableSigner requires async completion. let signature = [0u8; 64]; - *result_len = signature.len(); - let ptr = libc::malloc(signature.len()) as *mut u8; - if !ptr.is_null() { - std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len()); - } - ptr + completion( + completion_ctx, + signature.as_ptr(), + signature.len(), + std::ptr::null(), + ); } unsafe extern "C" fn mock_can_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, ) -> bool { true } - // Helper function to create a mock signer + // Helper function to create a mock signer. fn create_mock_signer() -> Box { - // Create a mock signer vtable let vtable = Box::new(crate::signer::SignerVTable { - sign: mock_sign_callback, + sign_async: mock_sign_callback, can_sign_with: mock_can_sign_callback, destroy: mock_destroy_callback, - free_result: None, }); - - Box::new(crate::signer::VTableSigner { - signer_ptr: std::ptr::null_mut(), - vtable: Box::into_raw(vtable), + let vtable_ptr = Box::into_raw(vtable); + // SAFETY: vtable_ptr was just produced by Box::into_raw and we take + // ownership of it (owns_vtable = true). + Box::new(unsafe { + crate::signer::VTableSigner::from_callback(std::ptr::null_mut(), vtable_ptr, true) }) } diff --git a/packages/rs-sdk-ffi/src/token/freeze.rs b/packages/rs-sdk-ffi/src/token/freeze.rs index e598bf8eee4..4ffb9cde828 100644 --- a/packages/rs-sdk-ffi/src/token/freeze.rs +++ b/packages/rs-sdk-ffi/src/token/freeze.rs @@ -241,46 +241,47 @@ mod tests { Box::new(IdentityPublicKey::V0(key_v0)) } - // Mock signer callbacks + // Mock async sign callback for the completion-callback signer vtable. unsafe extern "C" fn mock_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, _data: *const u8, _data_len: usize, - result_len: *mut usize, - ) -> *mut u8 { - // Return a mock signature (64 bytes for ECDSA) allocated with libc::malloc + completion_ctx: *mut std::os::raw::c_void, + completion: crate::signer::SignCompletionCallback, + ) { + // Fake 64-byte signature. Completion is invoked synchronously here; + // that's legal — nothing in VTableSigner requires async completion. let signature = [0u8; 64]; - *result_len = signature.len(); - let ptr = libc::malloc(signature.len()) as *mut u8; - if !ptr.is_null() { - std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len()); - } - ptr + completion( + completion_ctx, + signature.as_ptr(), + signature.len(), + std::ptr::null(), + ); } unsafe extern "C" fn mock_can_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, ) -> bool { true } - // Helper function to create a mock signer + // Helper function to create a mock signer. fn create_mock_signer() -> Box { - // Create a mock signer vtable let vtable = Box::new(crate::signer::SignerVTable { - sign: mock_sign_callback, + sign_async: mock_sign_callback, can_sign_with: mock_can_sign_callback, destroy: mock_destroy_callback, - free_result: None, }); - - Box::new(crate::signer::VTableSigner { - signer_ptr: std::ptr::null_mut(), - vtable: Box::into_raw(vtable), + let vtable_ptr = Box::into_raw(vtable); + // SAFETY: vtable_ptr was just produced by Box::into_raw and we take + // ownership of it (owns_vtable = true). + Box::new(unsafe { + crate::signer::VTableSigner::from_callback(std::ptr::null_mut(), vtable_ptr, true) }) } diff --git a/packages/rs-sdk-ffi/src/token/mint.rs b/packages/rs-sdk-ffi/src/token/mint.rs index 81feca1a393..55c8aeb6f06 100644 --- a/packages/rs-sdk-ffi/src/token/mint.rs +++ b/packages/rs-sdk-ffi/src/token/mint.rs @@ -332,76 +332,50 @@ mod tests { // Mock callbacks for signer #[allow(dead_code)] + // Mock async sign callback for the completion-callback signer vtable. unsafe extern "C" fn mock_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, _data: *const u8, _data_len: usize, - result_len: *mut usize, - ) -> *mut u8 { - // Return a mock signature (64 bytes for ECDSA), allocated with libc::malloc + completion_ctx: *mut std::os::raw::c_void, + completion: crate::signer::SignCompletionCallback, + ) { + // Fake 64-byte signature. Completion is invoked synchronously here; + // that's legal — nothing in VTableSigner requires async completion. let signature = [0u8; 64]; - *result_len = signature.len(); - let ptr = libc::malloc(signature.len()) as *mut u8; - if !ptr.is_null() { - std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len()); - } - ptr + completion( + completion_ctx, + signature.as_ptr(), + signature.len(), + std::ptr::null(), + ); } - #[allow(dead_code)] unsafe extern "C" fn mock_can_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, ) -> bool { true } - // Helper function to create a mock signer + // Helper function to create a mock signer. fn create_mock_signer() -> Box { - // Create a mock signer vtable let vtable = Box::new(crate::signer::SignerVTable { - sign: mock_sign_vtable_callback, - can_sign_with: mock_can_sign_vtable_callback, + sign_async: mock_sign_callback, + can_sign_with: mock_can_sign_callback, destroy: mock_destroy_callback, - free_result: None, }); - - Box::new(crate::signer::VTableSigner { - signer_ptr: std::ptr::null_mut(), - vtable: Box::into_raw(vtable), + let vtable_ptr = Box::into_raw(vtable); + // SAFETY: vtable_ptr was just produced by Box::into_raw and we take + // ownership of it (owns_vtable = true). + Box::new(unsafe { + crate::signer::VTableSigner::from_callback(std::ptr::null_mut(), vtable_ptr, true) }) } - // Mock sign callback for vtable - unsafe extern "C" fn mock_sign_vtable_callback( - _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, - _data: *const u8, - _data_len: usize, - result_len: *mut usize, - ) -> *mut u8 { - let signature = [0u8; 64]; - *result_len = signature.len(); - let ptr = libc::malloc(signature.len()) as *mut u8; - if !ptr.is_null() { - std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len()); - } - ptr - } - - // Mock can sign callback for vtable - unsafe extern "C" fn mock_can_sign_vtable_callback( - _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, - ) -> bool { - true - } - // Mock destroy callback unsafe extern "C" fn mock_destroy_callback(_signer: *mut std::os::raw::c_void) { // No-op for mock diff --git a/packages/rs-sdk-ffi/src/token/purchase.rs b/packages/rs-sdk-ffi/src/token/purchase.rs index 7269cd27c2d..0bbc8925927 100644 --- a/packages/rs-sdk-ffi/src/token/purchase.rs +++ b/packages/rs-sdk-ffi/src/token/purchase.rs @@ -215,45 +215,47 @@ mod tests { } // Mock callbacks for signer + // Mock async sign callback for the completion-callback signer vtable. unsafe extern "C" fn mock_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, _data: *const u8, _data_len: usize, - result_len: *mut usize, - ) -> *mut u8 { - // Return a mock signature (64 bytes for ECDSA) allocated with libc::malloc + completion_ctx: *mut std::os::raw::c_void, + completion: crate::signer::SignCompletionCallback, + ) { + // Fake 64-byte signature. Completion is invoked synchronously here; + // that's legal — nothing in VTableSigner requires async completion. let signature = [0u8; 64]; - *result_len = signature.len(); - let ptr = libc::malloc(signature.len()) as *mut u8; - if !ptr.is_null() { - std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len()); - } - ptr + completion( + completion_ctx, + signature.as_ptr(), + signature.len(), + std::ptr::null(), + ); } unsafe extern "C" fn mock_can_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, ) -> bool { true } - // Helper function to create a mock signer + // Helper function to create a mock signer. fn create_mock_signer() -> Box { - // Create a mock signer vtable let vtable = Box::new(crate::signer::SignerVTable { - sign: mock_sign_callback, + sign_async: mock_sign_callback, can_sign_with: mock_can_sign_callback, destroy: mock_destroy_callback, - free_result: None, }); - - Box::new(crate::signer::VTableSigner { - signer_ptr: std::ptr::null_mut(), - vtable: Box::into_raw(vtable), + let vtable_ptr = Box::into_raw(vtable); + // SAFETY: vtable_ptr was just produced by Box::into_raw and we take + // ownership of it (owns_vtable = true). + Box::new(unsafe { + crate::signer::VTableSigner::from_callback(std::ptr::null_mut(), vtable_ptr, true) }) } diff --git a/packages/rs-sdk-ffi/src/token/set_price.rs b/packages/rs-sdk-ffi/src/token/set_price.rs index 3c9c5160d14..38dca9218df 100644 --- a/packages/rs-sdk-ffi/src/token/set_price.rs +++ b/packages/rs-sdk-ffi/src/token/set_price.rs @@ -263,45 +263,47 @@ mod tests { } // Mock callbacks for signer + // Mock async sign callback for the completion-callback signer vtable. unsafe extern "C" fn mock_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, _data: *const u8, _data_len: usize, - result_len: *mut usize, - ) -> *mut u8 { - // Return a mock signature (64 bytes for ECDSA) allocated with libc::malloc + completion_ctx: *mut std::os::raw::c_void, + completion: crate::signer::SignCompletionCallback, + ) { + // Fake 64-byte signature. Completion is invoked synchronously here; + // that's legal — nothing in VTableSigner requires async completion. let signature = [0u8; 64]; - *result_len = signature.len(); - let ptr = libc::malloc(signature.len()) as *mut u8; - if !ptr.is_null() { - std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len()); - } - ptr + completion( + completion_ctx, + signature.as_ptr(), + signature.len(), + std::ptr::null(), + ); } unsafe extern "C" fn mock_can_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, ) -> bool { true } - // Helper function to create a mock signer + // Helper function to create a mock signer. fn create_mock_signer() -> Box { - // Create a mock signer vtable let vtable = Box::new(crate::signer::SignerVTable { - sign: mock_sign_callback, + sign_async: mock_sign_callback, can_sign_with: mock_can_sign_callback, destroy: mock_destroy_callback, - free_result: None, }); - - Box::new(crate::signer::VTableSigner { - signer_ptr: std::ptr::null_mut(), - vtable: Box::into_raw(vtable), + let vtable_ptr = Box::into_raw(vtable); + // SAFETY: vtable_ptr was just produced by Box::into_raw and we take + // ownership of it (owns_vtable = true). + Box::new(unsafe { + crate::signer::VTableSigner::from_callback(std::ptr::null_mut(), vtable_ptr, true) }) } diff --git a/packages/rs-sdk-ffi/src/token/transfer.rs b/packages/rs-sdk-ffi/src/token/transfer.rs index e3345203f25..18ded7517d4 100644 --- a/packages/rs-sdk-ffi/src/token/transfer.rs +++ b/packages/rs-sdk-ffi/src/token/transfer.rs @@ -232,45 +232,47 @@ mod tests { } // Mock callbacks for signer + // Mock async sign callback for the completion-callback signer vtable. unsafe extern "C" fn mock_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, _data: *const u8, _data_len: usize, - result_len: *mut usize, - ) -> *mut u8 { - // Return a mock signature (64 bytes for ECDSA) allocated with libc::malloc + completion_ctx: *mut std::os::raw::c_void, + completion: crate::signer::SignCompletionCallback, + ) { + // Fake 64-byte signature. Completion is invoked synchronously here; + // that's legal — nothing in VTableSigner requires async completion. let signature = [0u8; 64]; - *result_len = signature.len(); - let ptr = libc::malloc(signature.len()) as *mut u8; - if !ptr.is_null() { - std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len()); - } - ptr + completion( + completion_ctx, + signature.as_ptr(), + signature.len(), + std::ptr::null(), + ); } unsafe extern "C" fn mock_can_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, ) -> bool { true } - // Helper function to create a mock signer + // Helper function to create a mock signer. fn create_mock_signer() -> Box { - // Create a mock signer vtable let vtable = Box::new(crate::signer::SignerVTable { - sign: mock_sign_callback, + sign_async: mock_sign_callback, can_sign_with: mock_can_sign_callback, destroy: mock_destroy_callback, - free_result: None, }); - - Box::new(crate::signer::VTableSigner { - signer_ptr: std::ptr::null_mut(), - vtable: Box::into_raw(vtable), + let vtable_ptr = Box::into_raw(vtable); + // SAFETY: vtable_ptr was just produced by Box::into_raw and we take + // ownership of it (owns_vtable = true). + Box::new(unsafe { + crate::signer::VTableSigner::from_callback(std::ptr::null_mut(), vtable_ptr, true) }) } diff --git a/packages/rs-sdk-ffi/src/token/unfreeze.rs b/packages/rs-sdk-ffi/src/token/unfreeze.rs index b3a6e23879d..5e987c94b95 100644 --- a/packages/rs-sdk-ffi/src/token/unfreeze.rs +++ b/packages/rs-sdk-ffi/src/token/unfreeze.rs @@ -223,45 +223,47 @@ mod tests { } // Mock callbacks for signer + // Mock async sign callback for the completion-callback signer vtable. unsafe extern "C" fn mock_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, _data: *const u8, _data_len: usize, - result_len: *mut usize, - ) -> *mut u8 { - // Return a mock signature (64 bytes for ECDSA) allocated with libc::malloc + completion_ctx: *mut std::os::raw::c_void, + completion: crate::signer::SignCompletionCallback, + ) { + // Fake 64-byte signature. Completion is invoked synchronously here; + // that's legal — nothing in VTableSigner requires async completion. let signature = [0u8; 64]; - *result_len = signature.len(); - let ptr = libc::malloc(signature.len()) as *mut u8; - if !ptr.is_null() { - std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len()); - } - ptr + completion( + completion_ctx, + signature.as_ptr(), + signature.len(), + std::ptr::null(), + ); } unsafe extern "C" fn mock_can_sign_callback( _signer: *const std::os::raw::c_void, - _identity_public_key_bytes: *const u8, - _identity_public_key_len: usize, + _key_bytes: *const u8, + _key_len: usize, ) -> bool { true } - // Helper function to create a mock signer + // Helper function to create a mock signer. fn create_mock_signer() -> Box { - // Create a mock signer vtable let vtable = Box::new(crate::signer::SignerVTable { - sign: mock_sign_callback, + sign_async: mock_sign_callback, can_sign_with: mock_can_sign_callback, destroy: mock_destroy_callback, - free_result: None, }); - - Box::new(crate::signer::VTableSigner { - signer_ptr: std::ptr::null_mut(), - vtable: Box::into_raw(vtable), + let vtable_ptr = Box::into_raw(vtable); + // SAFETY: vtable_ptr was just produced by Box::into_raw and we take + // ownership of it (owns_vtable = true). + Box::new(unsafe { + crate::signer::VTableSigner::from_callback(std::ptr::null_mut(), vtable_ptr, true) }) } diff --git a/packages/rs-sdk/src/platform/documents/transitions/create.rs b/packages/rs-sdk/src/platform/documents/transitions/create.rs index 450836ae167..bfcb7bc43be 100644 --- a/packages/rs-sdk/src/platform/documents/transitions/create.rs +++ b/packages/rs-sdk/src/platform/documents/transitions/create.rs @@ -164,7 +164,8 @@ impl DocumentCreateTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/documents/transitions/delete.rs b/packages/rs-sdk/src/platform/documents/transitions/delete.rs index 2f1a8c005c3..2d44ec735a5 100644 --- a/packages/rs-sdk/src/platform/documents/transitions/delete.rs +++ b/packages/rs-sdk/src/platform/documents/transitions/delete.rs @@ -205,7 +205,8 @@ impl DocumentDeleteTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/documents/transitions/purchase.rs b/packages/rs-sdk/src/platform/documents/transitions/purchase.rs index b7832cb7782..fa6be76a464 100644 --- a/packages/rs-sdk/src/platform/documents/transitions/purchase.rs +++ b/packages/rs-sdk/src/platform/documents/transitions/purchase.rs @@ -219,7 +219,8 @@ impl DocumentPurchaseTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/documents/transitions/replace.rs b/packages/rs-sdk/src/platform/documents/transitions/replace.rs index aacfc2f9624..b40d27c15ea 100644 --- a/packages/rs-sdk/src/platform/documents/transitions/replace.rs +++ b/packages/rs-sdk/src/platform/documents/transitions/replace.rs @@ -158,7 +158,8 @@ impl DocumentReplaceTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/documents/transitions/set_price.rs b/packages/rs-sdk/src/platform/documents/transitions/set_price.rs index 61316f3b5c5..6750a6700cc 100644 --- a/packages/rs-sdk/src/platform/documents/transitions/set_price.rs +++ b/packages/rs-sdk/src/platform/documents/transitions/set_price.rs @@ -206,7 +206,8 @@ impl DocumentSetPriceTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/documents/transitions/transfer.rs b/packages/rs-sdk/src/platform/documents/transitions/transfer.rs index ae1f2afbb04..490380cc3fa 100644 --- a/packages/rs-sdk/src/platform/documents/transitions/transfer.rs +++ b/packages/rs-sdk/src/platform/documents/transitions/transfer.rs @@ -205,7 +205,8 @@ impl DocumentTransferTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/tokens/builders/burn.rs b/packages/rs-sdk/src/platform/tokens/builders/burn.rs index e714a1d4a27..eeb92c51877 100644 --- a/packages/rs-sdk/src/platform/tokens/builders/burn.rs +++ b/packages/rs-sdk/src/platform/tokens/builders/burn.rs @@ -177,7 +177,8 @@ impl TokenBurnTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/tokens/builders/claim.rs b/packages/rs-sdk/src/platform/tokens/builders/claim.rs index bde33938446..e4269ae5089 100644 --- a/packages/rs-sdk/src/platform/tokens/builders/claim.rs +++ b/packages/rs-sdk/src/platform/tokens/builders/claim.rs @@ -163,7 +163,8 @@ impl TokenClaimTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/tokens/builders/config_update.rs b/packages/rs-sdk/src/platform/tokens/builders/config_update.rs index 960ad87470c..ce10f74c7bd 100644 --- a/packages/rs-sdk/src/platform/tokens/builders/config_update.rs +++ b/packages/rs-sdk/src/platform/tokens/builders/config_update.rs @@ -184,7 +184,8 @@ impl TokenConfigUpdateTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/tokens/builders/destroy.rs b/packages/rs-sdk/src/platform/tokens/builders/destroy.rs index b1686785a9b..5c614374223 100644 --- a/packages/rs-sdk/src/platform/tokens/builders/destroy.rs +++ b/packages/rs-sdk/src/platform/tokens/builders/destroy.rs @@ -183,7 +183,8 @@ impl TokenDestroyFrozenFundsTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/tokens/builders/emergency_action.rs b/packages/rs-sdk/src/platform/tokens/builders/emergency_action.rs index 00b052b1145..21cbeb32275 100644 --- a/packages/rs-sdk/src/platform/tokens/builders/emergency_action.rs +++ b/packages/rs-sdk/src/platform/tokens/builders/emergency_action.rs @@ -211,7 +211,8 @@ impl TokenEmergencyActionTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/tokens/builders/freeze.rs b/packages/rs-sdk/src/platform/tokens/builders/freeze.rs index 12c4c9ad229..eef7ecd01a1 100644 --- a/packages/rs-sdk/src/platform/tokens/builders/freeze.rs +++ b/packages/rs-sdk/src/platform/tokens/builders/freeze.rs @@ -183,7 +183,8 @@ impl TokenFreezeTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/tokens/builders/mint.rs b/packages/rs-sdk/src/platform/tokens/builders/mint.rs index 45614d06bd3..350032f4119 100644 --- a/packages/rs-sdk/src/platform/tokens/builders/mint.rs +++ b/packages/rs-sdk/src/platform/tokens/builders/mint.rs @@ -204,7 +204,8 @@ impl TokenMintTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/tokens/builders/purchase.rs b/packages/rs-sdk/src/platform/tokens/builders/purchase.rs index 67771fc1ae9..e7037326fef 100644 --- a/packages/rs-sdk/src/platform/tokens/builders/purchase.rs +++ b/packages/rs-sdk/src/platform/tokens/builders/purchase.rs @@ -152,7 +152,8 @@ impl TokenDirectPurchaseTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/tokens/builders/set_price.rs b/packages/rs-sdk/src/platform/tokens/builders/set_price.rs index 57c298d3b61..de761c5fa57 100644 --- a/packages/rs-sdk/src/platform/tokens/builders/set_price.rs +++ b/packages/rs-sdk/src/platform/tokens/builders/set_price.rs @@ -228,7 +228,8 @@ impl TokenChangeDirectPurchasePriceTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/tokens/builders/transfer.rs b/packages/rs-sdk/src/platform/tokens/builders/transfer.rs index a8cf0514e5c..a8e93f54be6 100644 --- a/packages/rs-sdk/src/platform/tokens/builders/transfer.rs +++ b/packages/rs-sdk/src/platform/tokens/builders/transfer.rs @@ -209,7 +209,8 @@ impl TokenTransferTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/tokens/builders/unfreeze.rs b/packages/rs-sdk/src/platform/tokens/builders/unfreeze.rs index 8cf605f36a9..83a1dd2f8b6 100644 --- a/packages/rs-sdk/src/platform/tokens/builders/unfreeze.rs +++ b/packages/rs-sdk/src/platform/tokens/builders/unfreeze.rs @@ -183,7 +183,8 @@ impl TokenUnfreezeTransitionBuilder { signer, platform_version, self.state_transition_creation_options, - )?; + ) + .await?; Ok(state_transition) } diff --git a/packages/rs-sdk/src/platform/transition/address_credit_withdrawal.rs b/packages/rs-sdk/src/platform/transition/address_credit_withdrawal.rs index ea28bf89408..9e75fba3293 100644 --- a/packages/rs-sdk/src/platform/transition/address_credit_withdrawal.rs +++ b/packages/rs-sdk/src/platform/transition/address_credit_withdrawal.rs @@ -104,7 +104,8 @@ impl> WithdrawAddressFunds for Sdk { signer, user_fee_increase, self.version(), - )?; + ) + .await?; ensure_valid_state_transition_structure(&state_transition, self.version())?; match state_transition diff --git a/packages/rs-sdk/src/platform/transition/broadcast_identity.rs b/packages/rs-sdk/src/platform/transition/broadcast_identity.rs index e9ea967971b..7763bb12412 100644 --- a/packages/rs-sdk/src/platform/transition/broadcast_identity.rs +++ b/packages/rs-sdk/src/platform/transition/broadcast_identity.rs @@ -87,7 +87,8 @@ pub(crate) trait BroadcastRequestForNewIdentity> BroadcastRequestForNewIdentity for Identity { - fn broadcast_request_for_new_identity( + async fn broadcast_request_for_new_identity( &self, asset_lock_proof: AssetLockProof, asset_lock_proof_private_key: &PrivateKey, @@ -114,7 +115,8 @@ impl> &NativeBlsModule, 0, platform_version, - )?; + ) + .await?; ensure_valid_state_transition_structure(&identity_create_transition, platform_version)?; let request = identity_create_transition.broadcast_request_for_state_transition()?; Ok((identity_create_transition, request)) diff --git a/packages/rs-sdk/src/platform/transition/purchase_document.rs b/packages/rs-sdk/src/platform/transition/purchase_document.rs index 860613e05f9..f581c60cecc 100644 --- a/packages/rs-sdk/src/platform/transition/purchase_document.rs +++ b/packages/rs-sdk/src/platform/transition/purchase_document.rs @@ -84,7 +84,8 @@ impl> PurchaseDocument for Document { signer, sdk.version(), settings.state_transition_creation_options, - )?; + ) + .await?; ensure_valid_state_transition_structure(&transition, sdk.version())?; transition.broadcast(sdk, Some(settings)).await?; diff --git a/packages/rs-sdk/src/platform/transition/put_contract.rs b/packages/rs-sdk/src/platform/transition/put_contract.rs index a608c3f6566..19e0ec51182 100644 --- a/packages/rs-sdk/src/platform/transition/put_contract.rs +++ b/packages/rs-sdk/src/platform/transition/put_contract.rs @@ -69,7 +69,8 @@ impl> PutContract for DataContract { signer, sdk.version(), None, - )?; + ) + .await?; ensure_valid_state_transition_structure(&transition, sdk.version())?; transition.broadcast(sdk, settings).await?; diff --git a/packages/rs-sdk/src/platform/transition/put_document.rs b/packages/rs-sdk/src/platform/transition/put_document.rs index 20b45a8900a..80c4c7cb70b 100644 --- a/packages/rs-sdk/src/platform/transition/put_document.rs +++ b/packages/rs-sdk/src/platform/transition/put_document.rs @@ -82,6 +82,7 @@ impl> PutDocument for Document { sdk.version(), settings.state_transition_creation_options, ) + .await? } else { let (document, document_state_transition_entropy) = document_state_transition_entropy .map(|entropy| (self.clone(), entropy)) @@ -109,7 +110,8 @@ impl> PutDocument for Document { sdk.version(), settings.state_transition_creation_options, ) - }?; + .await? + }; ensure_valid_state_transition_structure(&transition, sdk.version())?; // response is empty for a broadcast, result comes from the stream wait for state transition result diff --git a/packages/rs-sdk/src/platform/transition/put_identity.rs b/packages/rs-sdk/src/platform/transition/put_identity.rs index ae738714d32..733969acf3c 100644 --- a/packages/rs-sdk/src/platform/transition/put_identity.rs +++ b/packages/rs-sdk/src/platform/transition/put_identity.rs @@ -136,12 +136,14 @@ async fn put_identity_with_asset_lock>( signer: &S, settings: Option, ) -> Result { - let (state_transition, _) = identity.broadcast_request_for_new_identity( - asset_lock_proof, - asset_lock_proof_private_key, - signer, - sdk.version(), - )?; + let (state_transition, _) = identity + .broadcast_request_for_new_identity( + asset_lock_proof, + asset_lock_proof_private_key, + signer, + sdk.version(), + ) + .await?; ensure_valid_state_transition_structure(&state_transition, sdk.version())?; state_transition.broadcast(sdk, settings).await?; Ok(state_transition) @@ -185,7 +187,8 @@ async fn put_identity_with_address_funding< input_signer, user_fee_increase, sdk.version(), - )?; + ) + .await?; ensure_valid_state_transition_structure(&state_transition, sdk.version())?; diff --git a/packages/rs-sdk/src/platform/transition/shield.rs b/packages/rs-sdk/src/platform/transition/shield.rs index 634fe7b4567..e6085f8303c 100644 --- a/packages/rs-sdk/src/platform/transition/shield.rs +++ b/packages/rs-sdk/src/platform/transition/shield.rs @@ -95,7 +95,8 @@ impl> ShieldFunds for Sdk { signer, user_fee_increase, self.version(), - )?; + ) + .await?; ensure_valid_state_transition_structure(&state_transition, self.version())?; state_transition.broadcast(self, settings).await?; diff --git a/packages/rs-sdk/src/platform/transition/top_up_address.rs b/packages/rs-sdk/src/platform/transition/top_up_address.rs index 097b7685d00..9317f1e65f5 100644 --- a/packages/rs-sdk/src/platform/transition/top_up_address.rs +++ b/packages/rs-sdk/src/platform/transition/top_up_address.rs @@ -94,7 +94,8 @@ impl> TopUpAddress for AddressesWithBalances { signer, user_fee_increase, sdk, - )?; + ) + .await?; ensure_valid_state_transition_structure(&state_transition, sdk.version())?; let st_result = state_transition @@ -115,7 +116,7 @@ impl> TopUpAddress for AddressesWithBalances { } #[allow(clippy::too_many_arguments)] -fn create_address_funding_from_asset_lock_transition>( +async fn create_address_funding_from_asset_lock_transition>( asset_lock_proof: AssetLockProof, asset_lock_private_key: &[u8], inputs: BTreeMap, @@ -135,4 +136,5 @@ fn create_address_funding_from_asset_lock_transition> user_fee_increase, sdk.version(), ) + .await } diff --git a/packages/rs-sdk/src/platform/transition/top_up_identity_from_addresses.rs b/packages/rs-sdk/src/platform/transition/top_up_identity_from_addresses.rs index e0a61362a05..0eca0ea7ffa 100644 --- a/packages/rs-sdk/src/platform/transition/top_up_identity_from_addresses.rs +++ b/packages/rs-sdk/src/platform/transition/top_up_identity_from_addresses.rs @@ -78,7 +78,8 @@ impl> TopUpIdentityFromAddresses for Identity { user_fee_increase, sdk.version(), None, - )?; + ) + .await?; ensure_valid_state_transition_structure(&state_transition, sdk.version())?; match state_transition diff --git a/packages/rs-sdk/src/platform/transition/transfer.rs b/packages/rs-sdk/src/platform/transition/transfer.rs index 158f1220de7..4241cfabd5b 100644 --- a/packages/rs-sdk/src/platform/transition/transfer.rs +++ b/packages/rs-sdk/src/platform/transition/transfer.rs @@ -58,7 +58,8 @@ impl TransferToIdentity for Identity { new_identity_nonce, sdk.version(), None, - )?; + ) + .await?; ensure_valid_state_transition_structure(&state_transition, sdk.version())?; let (sender, receiver): (PartialIdentity, PartialIdentity) = diff --git a/packages/rs-sdk/src/platform/transition/transfer_address_funds.rs b/packages/rs-sdk/src/platform/transition/transfer_address_funds.rs index 4990ba59edd..4890f0e2cd1 100644 --- a/packages/rs-sdk/src/platform/transition/transfer_address_funds.rs +++ b/packages/rs-sdk/src/platform/transition/transfer_address_funds.rs @@ -87,7 +87,8 @@ impl> TransferAddressFunds for Sdk { signer, user_fee_increase, self.version(), - )?; + ) + .await?; ensure_valid_state_transition_structure(&state_transition, self.version())?; let expected_addresses: BTreeSet = diff --git a/packages/rs-sdk/src/platform/transition/transfer_document.rs b/packages/rs-sdk/src/platform/transition/transfer_document.rs index af5cbdd2c5a..874eebc1f4c 100644 --- a/packages/rs-sdk/src/platform/transition/transfer_document.rs +++ b/packages/rs-sdk/src/platform/transition/transfer_document.rs @@ -80,7 +80,8 @@ impl> TransferDocument for Document { signer, sdk.version(), settings.state_transition_creation_options, - )?; + ) + .await?; ensure_valid_state_transition_structure(&transition, sdk.version())?; let request = transition.broadcast_request_for_state_transition()?; diff --git a/packages/rs-sdk/src/platform/transition/transfer_to_addresses.rs b/packages/rs-sdk/src/platform/transition/transfer_to_addresses.rs index d1eec49ab7d..ee95e309997 100644 --- a/packages/rs-sdk/src/platform/transition/transfer_to_addresses.rs +++ b/packages/rs-sdk/src/platform/transition/transfer_to_addresses.rs @@ -66,7 +66,8 @@ impl TransferToAddresses for Identity { new_identity_nonce, sdk.version(), None, - )?; + ) + .await?; ensure_valid_state_transition_structure(&state_transition, sdk.version())?; let expected_addresses: BTreeSet = diff --git a/packages/rs-sdk/src/platform/transition/update_price_of_document.rs b/packages/rs-sdk/src/platform/transition/update_price_of_document.rs index 680dc1283ad..b699efdfd97 100644 --- a/packages/rs-sdk/src/platform/transition/update_price_of_document.rs +++ b/packages/rs-sdk/src/platform/transition/update_price_of_document.rs @@ -80,7 +80,8 @@ impl> UpdatePriceOfDocument for Document { signer, sdk.version(), settings.state_transition_creation_options, - )?; + ) + .await?; ensure_valid_state_transition_structure(&transition, sdk.version())?; // response is empty for a broadcast, result comes from the stream wait for state transition result diff --git a/packages/rs-sdk/src/platform/transition/vote.rs b/packages/rs-sdk/src/platform/transition/vote.rs index 30abf33e6bf..a19a7199a0a 100644 --- a/packages/rs-sdk/src/platform/transition/vote.rs +++ b/packages/rs-sdk/src/platform/transition/vote.rs @@ -66,7 +66,8 @@ impl> PutVote for Vote { new_masternode_voting_nonce, sdk.version(), None, - )?; + ) + .await?; ensure_valid_state_transition_structure(&masternode_vote_transition, sdk.version())?; let request = masternode_vote_transition.broadcast_request_for_state_transition()?; @@ -105,7 +106,8 @@ impl> PutVote for Vote { new_masternode_voting_nonce, sdk.version(), None, - )?; + ) + .await?; ensure_valid_state_transition_structure(&masternode_vote_transition, sdk.version())?; let request = masternode_vote_transition.broadcast_request_for_state_transition()?; // TODO: Implement retry logic diff --git a/packages/rs-sdk/src/platform/transition/withdraw_from_identity.rs b/packages/rs-sdk/src/platform/transition/withdraw_from_identity.rs index 841c04c0fbb..38343d0159a 100644 --- a/packages/rs-sdk/src/platform/transition/withdraw_from_identity.rs +++ b/packages/rs-sdk/src/platform/transition/withdraw_from_identity.rs @@ -62,7 +62,8 @@ impl WithdrawFromIdentity for Identity { new_identity_nonce, sdk.version(), None, - )?; + ) + .await?; ensure_valid_state_transition_structure(&state_transition, sdk.version())?; let result = state_transition.broadcast_and_wait(sdk, settings).await?; diff --git a/packages/simple-signer/Cargo.toml b/packages/simple-signer/Cargo.toml index d4817d32a91..4bb9d4aa765 100644 --- a/packages/simple-signer/Cargo.toml +++ b/packages/simple-signer/Cargo.toml @@ -19,6 +19,7 @@ state-transitions = [ dpp = { path = "../rs-dpp", default-features = false, features = [ "ed25519-dalek", ] } +async-trait = { version = "0.1.79" } bincode = { version = "=2.0.1", features = ["serde"] } base64 = { version = "0.22.1" } hex = { version = "0.4.3" } diff --git a/packages/simple-signer/src/signer.rs b/packages/simple-signer/src/signer.rs index a8ad0f0587d..c7fc229e551 100644 --- a/packages/simple-signer/src/signer.rs +++ b/packages/simple-signer/src/signer.rs @@ -1,3 +1,4 @@ +use async_trait::async_trait; use base64::prelude::BASE64_STANDARD; use base64::Engine; use dpp::address_funds::{AddressWitness, PlatformAddress}; @@ -115,8 +116,9 @@ impl SimpleSigner { } } +#[async_trait] impl Signer for SimpleSigner { - fn sign( + async fn sign( &self, identity_public_key: &IdentityPublicKey, data: &[u8], @@ -163,13 +165,13 @@ impl Signer for SimpleSigner { } } - fn sign_create_witness( + async fn sign_create_witness( &self, key: &IdentityPublicKey, data: &[u8], ) -> Result { // First, sign the data to get the signature - let signature = self.sign(key, data)?; + let signature = self.sign(key, data).await?; // Create the appropriate AddressWitness based on the key type match key.key_type() { @@ -207,8 +209,13 @@ impl Signer for SimpleSigner { } } +#[async_trait] impl Signer for SimpleSigner { - fn sign(&self, address: &PlatformAddress, data: &[u8]) -> Result { + async fn sign( + &self, + address: &PlatformAddress, + data: &[u8], + ) -> Result { let hash = match address { PlatformAddress::P2pkh(hash) => hash, PlatformAddress::P2sh(_) => { @@ -227,13 +234,13 @@ impl Signer for SimpleSigner { Ok(signature.to_vec().into()) } - fn sign_create_witness( + async fn sign_create_witness( &self, key: &PlatformAddress, data: &[u8], ) -> Result { // First, sign the data to get the signature - let signature = self.sign(key, data)?; + let signature = self.sign(key, data).await?; match key { PlatformAddress::P2pkh(_) => Ok(AddressWitness::P2pkh { signature }), PlatformAddress::P2sh(_) => Err(ProtocolError::Generic( diff --git a/packages/simple-signer/src/single_key_signer.rs b/packages/simple-signer/src/single_key_signer.rs index 0da5d48f627..4abac3244a6 100644 --- a/packages/simple-signer/src/single_key_signer.rs +++ b/packages/simple-signer/src/single_key_signer.rs @@ -1,3 +1,4 @@ +use async_trait::async_trait; use dpp::address_funds::AddressWitness; use dpp::dashcore; use dpp::dashcore::signer; @@ -78,8 +79,9 @@ impl SingleKeySigner { } } +#[async_trait] impl Signer for SingleKeySigner { - fn sign( + async fn sign( &self, identity_public_key: &IdentityPublicKey, data: &[u8], @@ -102,13 +104,13 @@ impl Signer for SingleKeySigner { } } - fn sign_create_witness( + async fn sign_create_witness( &self, key: &IdentityPublicKey, data: &[u8], ) -> Result { // First, sign the data to get the signature - let signature = self.sign(key, data)?; + let signature = self.sign(key, data).await?; // Create the appropriate AddressWitness based on the key type // SingleKeySigner only supports ECDSA keys diff --git a/packages/strategy-tests/Cargo.toml b/packages/strategy-tests/Cargo.toml index f2625315f8b..5e7b2b71a1b 100644 --- a/packages/strategy-tests/Cargo.toml +++ b/packages/strategy-tests/Cargo.toml @@ -39,3 +39,4 @@ platform-version = { path = "../rs-platform-version" } platform-version = { path = "../rs-platform-version", features = [ "mock-versions", ] } +tokio = { version = "1.45", features = ["macros", "rt"] } diff --git a/packages/strategy-tests/src/lib.rs b/packages/strategy-tests/src/lib.rs index 3a66119b895..3dbfbf8e4a1 100644 --- a/packages/strategy-tests/src/lib.rs +++ b/packages/strategy-tests/src/lib.rs @@ -667,7 +667,7 @@ impl Strategy { /// on the Dash Platform. It encapsulates the complexity of transaction generation, identity management, /// and contract dynamics within a block's context. #[allow(clippy::too_many_arguments)] - pub fn state_transitions_for_block( + pub async fn state_transitions_for_block<'c>( &mut self, document_query_callback: &mut impl FnMut(LocalDocumentQuery) -> Vec, identity_fetch_callback: &mut impl FnMut( @@ -682,7 +682,7 @@ impl Strategy { signer: &mut SimpleSigner, identity_nonce_counter: &mut BTreeMap, contract_nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, - mempool_document_counter: &MempoolDocumentCounter, + mempool_document_counter: &MempoolDocumentCounter<'c>, rng: &mut StdRng, config: &StrategyConfig, platform_version: &PlatformVersion, @@ -695,15 +695,18 @@ impl Strategy { // Get identity state transitions // Start identities are done on the 1st block, identity inserts are done on 3rd+ blocks - let identity_state_transitions = match self.identity_state_transitions_for_block( - block_info, - self.start_identities.starting_balances, - signer, - rng, - asset_lock_proofs, - config, - platform_version, - ) { + let identity_state_transitions = match self + .identity_state_transitions_for_block( + block_info, + self.start_identities.starting_balances, + signer, + rng, + asset_lock_proofs, + config, + platform_version, + ) + .await + { Ok(transitions) => transitions, Err(e) => { tracing::error!("identity_state_transitions_for_block error: {}", e); @@ -765,7 +768,8 @@ impl Strategy { signer, 0, platform_version, - ); + ) + .await; match funding_transition { Ok(transition) => state_transitions.push(transition), @@ -790,13 +794,15 @@ impl Strategy { // Add initial contracts for contracts_with_updates on 2nd block of strategy #[allow(clippy::comparison_chain)] if block_info.height == config.start_block_height + 1 { - let mut contract_state_transitions = self.initial_contract_state_transitions( - current_identities, - identity_nonce_counter, - signer, - rng, - platform_version, - ); + let mut contract_state_transitions = self + .initial_contract_state_transitions( + current_identities, + identity_nonce_counter, + signer, + rng, + platform_version, + ) + .await; state_transitions.append(&mut contract_state_transitions); } else if block_info.height > config.start_block_height + 1 { let (mut operations_state_transitions, mut add_to_finalize_block_operations) = self @@ -814,7 +820,8 @@ impl Strategy { mempool_document_counter, rng, platform_version, - ); + ) + .await; finalize_block_operations.append(&mut add_to_finalize_block_operations); state_transitions.append(&mut operations_state_transitions); @@ -827,7 +834,8 @@ impl Strategy { signer, contract_nonce_counter, platform_version, - ); + ) + .await; state_transitions.append(&mut initial_contract_update_state_transitions); } @@ -891,7 +899,7 @@ impl Strategy { /// This function plays a pivotal role in simulating realistic blockchain operations, allowing for the /// detailed and nuanced execution of a wide range of actions on the Dash Platform as defined by the strategy. #[allow(clippy::too_many_arguments)] - pub fn operations_based_transitions( + pub async fn operations_based_transitions<'c>( &self, document_query_callback: &mut impl FnMut(LocalDocumentQuery) -> Vec, identity_fetch_callback: &mut impl FnMut( @@ -906,7 +914,7 @@ impl Strategy { signer: &mut SimpleSigner, identity_nonce_counter: &mut BTreeMap, contract_nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, - mempool_document_counter: &MempoolDocumentCounter, + mempool_document_counter: &MempoolDocumentCounter<'c>, rng: &mut StdRng, platform_version: &PlatformVersion, ) -> (Vec, Vec) { @@ -961,78 +969,74 @@ impl Strategy { Err(e) => tracing::warn!("Failed to create random documents: {}", e), } - documents_with_identity_and_entropy.into_iter().for_each( - |(document, identity, entropy)| { - let identity_contract_nonce = - if contract.owner_id() == identity.id() { - contract_nonce_counter - .entry((identity.id(), contract.id())) - .or_insert(1) - } else { - contract_nonce_counter - .entry((identity.id(), contract.id())) - .or_default() - }; + for (document, identity, entropy) in + documents_with_identity_and_entropy.into_iter() + { + let identity_contract_nonce = if contract.owner_id() == identity.id() { + contract_nonce_counter + .entry((identity.id(), contract.id())) + .or_insert(1) + } else { + contract_nonce_counter + .entry((identity.id(), contract.id())) + .or_default() + }; - let gap = self - .identity_contract_nonce_gaps - .as_ref() - .map_or(0, |gap_amount| gap_amount.events_if_hit(rng)) - as u64; - *identity_contract_nonce += 1 + gap; - - let document_create_transition: DocumentCreateTransition = - DocumentCreateTransitionV0 { - base: DocumentBaseTransitionV0 { - id: document.id(), - identity_contract_nonce: *identity_contract_nonce, - document_type_name: document_type.name().clone(), - data_contract_id: contract.id(), - } - .into(), - entropy: entropy.to_buffer(), - data: document.properties_consumed(), - prefunded_voting_balance: Default::default(), - } - .into(); - - let document_batch_transition: BatchTransition = - BatchTransitionV0 { - owner_id: identity.id(), - transitions: vec![document_create_transition.into()], - user_fee_increase: 0, - signature_public_key_id: 2, - signature: BinaryData::default(), + let gap = self + .identity_contract_nonce_gaps + .as_ref() + .map_or(0, |gap_amount| gap_amount.events_if_hit(rng)) + as u64; + *identity_contract_nonce += 1 + gap; + + let document_create_transition: DocumentCreateTransition = + DocumentCreateTransitionV0 { + base: DocumentBaseTransitionV0 { + id: document.id(), + identity_contract_nonce: *identity_contract_nonce, + document_type_name: document_type.name().clone(), + data_contract_id: contract.id(), } - .into(); - let mut document_batch_transition: StateTransition = - document_batch_transition.into(); - - let identity_public_key = identity - .get_first_public_key_matching( - Purpose::AUTHENTICATION, - HashSet::from([SecurityLevel::CRITICAL]), - HashSet::from([ - KeyType::ECDSA_SECP256K1, - KeyType::BLS12_381, - ]), - false, - ) - .expect("expected to get a signing key"); - - document_batch_transition - .sign_external( - identity_public_key, - signer, - Some(|_data_contract_id, _document_type_name| { - Ok(SecurityLevel::CRITICAL) - }), - ) - .expect("expected to sign"); - - operations.push(document_batch_transition); - }, - ); + .into(), + entropy: entropy.to_buffer(), + data: document.properties_consumed(), + prefunded_voting_balance: Default::default(), + } + .into(); + + let document_batch_transition: BatchTransition = BatchTransitionV0 { + owner_id: identity.id(), + transitions: vec![document_create_transition.into()], + user_fee_increase: 0, + signature_public_key_id: 2, + signature: BinaryData::default(), + } + .into(); + let mut document_batch_transition: StateTransition = + document_batch_transition.into(); + + let identity_public_key = identity + .get_first_public_key_matching( + Purpose::AUTHENTICATION, + HashSet::from([SecurityLevel::CRITICAL]), + HashSet::from([KeyType::ECDSA_SECP256K1, KeyType::BLS12_381]), + false, + ) + .expect("expected to get a signing key"); + + document_batch_transition + .sign_external( + identity_public_key, + signer, + Some(|_data_contract_id, _document_type_name| { + Ok(SecurityLevel::CRITICAL) + }), + ) + .await + .expect("expected to sign"); + + operations.push(document_batch_transition); + } } // Generate state transition for specific document insert operation @@ -1095,72 +1099,64 @@ impl Strategy { .expect("expected random_documents_with_params") }; - documents - .into_iter() - .for_each(|(mut document, identity, entropy)| { - document - .properties_mut() - .append(&mut specific_document_key_value_pairs.clone()); + for (mut document, identity, entropy) in documents.into_iter() { + document + .properties_mut() + .append(&mut specific_document_key_value_pairs.clone()); - let identity_contract_nonce = contract_nonce_counter - .entry((identity.id(), contract.id())) - .or_default(); - *identity_contract_nonce += 1; - - let document_create_transition: DocumentCreateTransition = - DocumentCreateTransitionV0 { - base: DocumentBaseTransitionV0 { - id: document.id(), - identity_contract_nonce: *identity_contract_nonce, - document_type_name: document_type.name().clone(), - data_contract_id: contract.id(), - } - .into(), - entropy: entropy.to_buffer(), - data: document.properties_consumed(), - prefunded_voting_balance: Default::default(), - } - .into(); - - let document_batch_transition: BatchTransition = - BatchTransitionV0 { - owner_id: identity.id(), - transitions: vec![document_create_transition.into()], - user_fee_increase: 0, - signature_public_key_id: 1, - signature: BinaryData::default(), + let identity_contract_nonce = contract_nonce_counter + .entry((identity.id(), contract.id())) + .or_default(); + *identity_contract_nonce += 1; + + let document_create_transition: DocumentCreateTransition = + DocumentCreateTransitionV0 { + base: DocumentBaseTransitionV0 { + id: document.id(), + identity_contract_nonce: *identity_contract_nonce, + document_type_name: document_type.name().clone(), + data_contract_id: contract.id(), } - .into(); - let mut document_batch_transition: StateTransition = - document_batch_transition.into(); - - let identity_public_key = identity - .get_first_public_key_matching( - Purpose::AUTHENTICATION, - HashSet::from([ - SecurityLevel::HIGH, - SecurityLevel::CRITICAL, - ]), - HashSet::from([ - KeyType::ECDSA_SECP256K1, - KeyType::BLS12_381, - ]), - false, - ) - .expect("expected to get a signing key"); - - document_batch_transition - .sign_external( - identity_public_key, - signer, - Some(|_data_contract_id, _document_type_name| { - Ok(SecurityLevel::HIGH) - }), - ) - .expect("expected to sign"); + .into(), + entropy: entropy.to_buffer(), + data: document.properties_consumed(), + prefunded_voting_balance: Default::default(), + } + .into(); - operations.push(document_batch_transition); - }); + let document_batch_transition: BatchTransition = BatchTransitionV0 { + owner_id: identity.id(), + transitions: vec![document_create_transition.into()], + user_fee_increase: 0, + signature_public_key_id: 1, + signature: BinaryData::default(), + } + .into(); + let mut document_batch_transition: StateTransition = + document_batch_transition.into(); + + let identity_public_key = identity + .get_first_public_key_matching( + Purpose::AUTHENTICATION, + HashSet::from([SecurityLevel::HIGH, SecurityLevel::CRITICAL]), + HashSet::from([KeyType::ECDSA_SECP256K1, KeyType::BLS12_381]), + false, + ) + .expect("expected to get a signing key"); + + document_batch_transition + .sign_external( + identity_public_key, + signer, + Some(|_data_contract_id, _document_type_name| { + Ok(SecurityLevel::HIGH) + }), + ) + .await + .expect("expected to sign"); + + operations.push(document_batch_transition); + } } // Generate state transition for document delete operation @@ -1241,6 +1237,7 @@ impl Strategy { Ok(SecurityLevel::HIGH) }), ) + .await .expect("expected to sign"); operations.push(document_batch_transition); @@ -1335,6 +1332,7 @@ impl Strategy { Ok(SecurityLevel::HIGH) }), ) + .await .expect("expected to sign"); operations.push(document_batch_transition); @@ -1438,6 +1436,7 @@ impl Strategy { Ok(SecurityLevel::HIGH) }), ) + .await .expect("expected to sign"); operations.push(document_batch_transition); @@ -1494,6 +1493,7 @@ impl Strategy { platform_version, None, ) + .await .expect("expected to create top up from addresses transition"); operations.push(state_transition); } @@ -1533,7 +1533,7 @@ impl Strategy { signer, rng, platform_version, - ); + ).await; // Push to operations vectors operations.push(state_transition); @@ -1550,9 +1550,13 @@ impl Strategy { } } IdentityUpdateOp::IdentityUpdateDisableKey(keys_count) => { - (0..count).for_each(|_| { - current_identities.iter_mut().enumerate().for_each(|(i, random_identity)| { - if i >= count.into() { return; } + for _ in 0..count { + for (i, random_identity) in + current_identities.iter_mut().enumerate() + { + if i >= count.into() { + break; + } if let Some(state_transition) = crate::transitions::create_identity_update_transition_disable_keys( @@ -1563,11 +1567,12 @@ impl Strategy { signer, rng, platform_version, - ) { - operations.push(state_transition); + ).await + { + operations.push(state_transition); } - }); - }); + } + } } } } @@ -1586,7 +1591,8 @@ impl Strategy { identity_nonce_counter, signer, rng, - ); + ) + .await; operations.push(state_transition); } } @@ -1615,7 +1621,8 @@ impl Strategy { identity_nonce_counter, signer, // This means in the TUI, the loaded identity must always be the sender since we're always signing with it for now transfer_info.amount, - ); + ) + .await; operations.push(state_transition); } else if current_identities.len() > 1 { // Handle the case where no sender, recipient, and amount are provided @@ -1647,7 +1654,8 @@ impl Strategy { identity_nonce_counter, signer, 300000, - ); + ) + .await; operations.push(state_transition); } } @@ -1750,13 +1758,20 @@ impl Strategy { .expect("Expected to get identity public key in ContractCreate"); let mut state_transition = StateTransition::DataContractCreate(transition); - if let Err(e) = state_transition.sign_external( - public_key, - signer, - None::< - fn(Identifier, String) -> Result, - >, - ) { + if let Err(e) = state_transition + .sign_external( + public_key, + signer, + None::< + fn( + Identifier, + String, + ) + -> Result, + >, + ) + .await + { tracing::error!("Error signing state transition: {:?}", e); } @@ -1823,6 +1838,7 @@ impl Strategy { Ok(SecurityLevel::CRITICAL) }), ) + .await .expect("expected to sign the contract update transition with a CRITICAL level key"); operations.push(state_transition); @@ -1869,7 +1885,7 @@ impl Strategy { transfer_info.outputs.len(), rng, platform_version, - ); + ).await; operations.push(state_transition); } else { // Handle the case where no specific sender is provided @@ -1948,7 +1964,7 @@ impl Strategy { signer, recipient_addresses, platform_version, - ); + ).await; operations.push(state_transition); } } @@ -2103,6 +2119,7 @@ impl Strategy { 0, // user_fee_increase platform_version, ) + .await .expect("expected to create identity from addresses transition"); operations.push(state_transition); @@ -2175,7 +2192,7 @@ impl Strategy { signer, 0, platform_version, - ); + ).await; match funding_transition { Ok(state_transition) => operations.push(state_transition), @@ -2483,6 +2500,7 @@ impl Strategy { 0, platform_version, ) + .await .expect("expected to create address funds transfer transition"); operations.push(transfer_transition); @@ -2609,6 +2627,7 @@ impl Strategy { 0, platform_version, ) + .await .expect("expected to create address credit withdrawal transition"); operations.push(withdrawal_transition); @@ -2662,7 +2681,7 @@ impl Strategy { /// This function plays a crucial role in simulating the dynamic nature of identity management on the Dash Platform, /// allowing for a nuanced and detailed representation of identity-related activities within a blockchain simulation environment. #[allow(clippy::too_many_arguments)] - pub fn identity_state_transitions_for_block( + pub async fn identity_state_transitions_for_block( &self, block_info: &BlockInfo, amount: u64, @@ -2687,7 +2706,8 @@ impl Strategy { rng, asset_lock_proofs, platform_version, - )?; + ) + .await?; state_transitions.append(&mut new_transitions); } @@ -2707,7 +2727,8 @@ impl Strategy { rng, asset_lock_proofs, platform_version, - )?; + ) + .await?; state_transitions.append(&mut new_transitions); } } @@ -2750,7 +2771,7 @@ impl Strategy { /// /// This function is pivotal for setting up the simulated environment's initial state, providing a foundation for /// subsequent operations and updates within the strategy. - pub fn initial_contract_state_transitions( + pub async fn initial_contract_state_transitions( &mut self, current_identities: &[Identity], identity_nonce_counter: &mut BTreeMap, @@ -2760,41 +2781,54 @@ impl Strategy { ) -> Vec { let mut id_mapping = HashMap::new(); // Maps old IDs to new IDs - self.start_contracts - .iter_mut() - .map(|(created_contract, contract_updates)| { - // Select a random identity from current_identities to be the contract owner - let identity_num = rng.gen_range(0..current_identities.len()); + let mut results: Vec = Vec::new(); + // Collect the indices and do sequential processing to allow .await + let contract_count = self.start_contracts.len(); + for contract_idx in 0..contract_count { + // Select a random identity from current_identities to be the contract owner + let identity_num = rng.gen_range(0..current_identities.len()); - let identity = current_identities - .get(identity_num) - .expect("Expected to find the identity in the current_identities"); + let identity = current_identities + .get(identity_num) + .expect("Expected to find the identity in the current_identities"); - let identity_public_key = identity.get_first_public_key_matching( + let identity_public_key = identity + .get_first_public_key_matching( Purpose::AUTHENTICATION, HashSet::from([SecurityLevel::HIGH, SecurityLevel::CRITICAL]), HashSet::from([KeyType::ECDSA_SECP256K1]), - false + false, ) - .expect("Expected to get identity public key in initial_contract_state_transitions"); - let key_id = identity_public_key.id(); - - let partial_identity = identity.clone().into_partial_identity_info(); - let partial_identity_public_key = partial_identity.loaded_public_keys.values() - .find(|&public_key| public_key.id() == key_id) - .expect("No public key with matching id found"); - + .expect( + "Expected to get identity public key in initial_contract_state_transitions", + ); + let key_id = identity_public_key.id(); + + let partial_identity = identity.clone().into_partial_identity_info(); + let partial_identity_public_key_id = partial_identity + .loaded_public_keys + .values() + .find(|&public_key| public_key.id() == key_id) + .expect("No public key with matching id found") + .id(); + + let (contract_clone, identity_nonce_value, old_id, new_id) = { + let (created_contract, contract_updates) = &mut self.start_contracts[contract_idx]; let contract = created_contract.data_contract_mut(); // Get and bump the identity nonce - let identity_nonce = identity_nonce_counter.entry(partial_identity.id).or_default(); + let identity_nonce = identity_nonce_counter + .entry(partial_identity.id) + .or_default(); *identity_nonce += 1; // Set the contract ID and owner ID with the random identity contract.set_owner_id(partial_identity.id); let old_id = contract.id(); - let new_id = - DataContract::generate_data_contract_id_v0(partial_identity.id, *identity_nonce); + let new_id = DataContract::generate_data_contract_id_v0( + partial_identity.id, + *identity_nonce, + ); contract.set_id(new_id); id_mapping.insert(old_id, new_id); // Store the mapping @@ -2803,7 +2837,6 @@ impl Strategy { if let Some(contract_updates) = contract_updates { for (_, updated_contract) in contract_updates.iter_mut() { let updated_contract_data = updated_contract.data_contract_mut(); - // Use the new ID from the mapping if let Some(new_updated_id) = id_mapping.get(&updated_contract_data.id()) { updated_contract_data.set_id(*new_updated_id); } @@ -2811,35 +2844,42 @@ impl Strategy { } } - // Update any document transitions that registered to the old contract id - for op in self.operations.iter_mut() { - if let OperationType::Document(document_op) = &mut op.op_type { - if document_op.contract.id() == old_id { - document_op.contract = contract.clone(); - let document_type = contract.document_type_cloned_for_name(document_op.document_type.name()) - .expect("Expected to get a document type for name while creating initial strategy contracts"); - document_op.document_type = document_type; - } + (contract.clone(), *identity_nonce, old_id, new_id) + }; + let _ = new_id; + + // Update any document transitions that registered to the old contract id + for op in self.operations.iter_mut() { + if let OperationType::Document(document_op) = &mut op.op_type { + if document_op.contract.id() == old_id { + document_op.contract = contract_clone.clone(); + let document_type = contract_clone + .document_type_cloned_for_name(document_op.document_type.name()) + .expect("Expected to get a document type for name while creating initial strategy contracts"); + document_op.document_type = document_type; } } + } - match DataContractCreateTransition::new_from_data_contract( - contract.clone(), - *identity_nonce, - &partial_identity, - partial_identity_public_key.id(), - signer, - platform_version, - None, - ) { - Ok(transition) => transition, - Err(e) => { - tracing::error!("Error creating DataContractCreateTransition: {e}"); - panic!(); - } + match DataContractCreateTransition::new_from_data_contract( + contract_clone, + identity_nonce_value, + &partial_identity, + partial_identity_public_key_id, + signer, + platform_version, + None, + ) + .await + { + Ok(transition) => results.push(transition), + Err(e) => { + tracing::error!("Error creating DataContractCreateTransition: {e}"); + panic!(); } - }) - .collect() + } + } + results } /// Generates state transitions for updating contracts based on the current set of identities and the block height. @@ -2877,7 +2917,7 @@ impl Strategy { /// /// Through these updates, the simulation accurately mirrors the lifecycle of contracts on the Dash Platform, incorporating /// changes that may occur over time. - pub fn initial_contract_update_state_transitions( + pub async fn initial_contract_update_state_transitions( &mut self, current_identities: &[Identity], block_height: u64, @@ -2918,35 +2958,36 @@ impl Strategy { .collect(); // Increment nonce counter, update data contract version, and create state transitions - updates - .into_iter() - .map(|(identity, update_height, contract_update)| { - let identity_info = identity.into_partial_identity_info(); - let contract_id = contract_update.data_contract().id(); - let nonce = contract_nonce_counter - .entry((identity_info.id, contract_id)) - .and_modify(|e| *e += 1) - .or_insert(1); - - // Set the version number on the data contract - let mut contract_update_clone = contract_update.clone(); - let data_contract = contract_update_clone.data_contract_mut(); - data_contract.set_version(update_height as u32); - - // Create the state transition - DataContractUpdateTransition::new_from_data_contract( - data_contract.clone(), - &identity_info, - 2, // Assuming key id 2 is a high or critical auth key - *nonce, - 0, - signer, - platform_version, - None, - ) - .expect("expected to create a state transition from a data contract") - }) - .collect() + let mut results: Vec = Vec::with_capacity(updates.len()); + for (identity, update_height, contract_update) in updates.into_iter() { + let identity_info = identity.into_partial_identity_info(); + let contract_id = contract_update.data_contract().id(); + let nonce = contract_nonce_counter + .entry((identity_info.id, contract_id)) + .and_modify(|e| *e += 1) + .or_insert(1); + + // Set the version number on the data contract + let mut contract_update_clone = contract_update.clone(); + let data_contract = contract_update_clone.data_contract_mut(); + data_contract.set_version(update_height as u32); + + // Create the state transition + let transition = DataContractUpdateTransition::new_from_data_contract( + data_contract.clone(), + &identity_info, + 2, // Assuming key id 2 is a high or critical auth key + *nonce, + 0, + signer, + platform_version, + None, + ) + .await + .expect("expected to create a state transition from a data contract"); + results.push(transition); + } + results } /// Returns all contract IDs referenced by operations in this strategy. @@ -2992,8 +3033,8 @@ mod tests { use simple_signer::signer::SimpleSigner; use std::collections::BTreeMap; - #[test] - fn serialize_deserialize_strategy() { + #[tokio::test] + async fn serialize_deserialize_strategy() { let platform_version = PlatformVersion::latest(); let mut rng = StdRng::seed_from_u64(567); @@ -3020,7 +3061,8 @@ mod tests { &mut simple_signer, &mut rng, platform_version, - ); + ) + .await; let dpns_contract = load_system_data_contract(SystemDataContract::DPNS, platform_version) .expect("data contract"); diff --git a/packages/strategy-tests/src/transitions.rs b/packages/strategy-tests/src/transitions.rs index ea71765f991..96e873e7ba7 100644 --- a/packages/strategy-tests/src/transitions.rs +++ b/packages/strategy-tests/src/transitions.rs @@ -436,7 +436,7 @@ pub fn create_identity_top_up_transition( /// - If the identity does not have a master key. /// - If there's an error during the random key generation. /// - If there's an error during the creation of the identity update transition. -pub fn create_identity_update_transition_add_keys( +pub async fn create_identity_update_transition_add_keys( identity: &mut Identity, count: u16, keys_already_added_this_block_count: u32, @@ -488,6 +488,7 @@ pub fn create_identity_update_transition_add_keys( platform_version, None, ) + .await .expect("expected to create an AddKeys transition"); (state_transition, (identity.id(), add_public_keys)) @@ -532,7 +533,7 @@ pub fn create_identity_update_transition_add_keys( /// This function may panic under the following conditions: /// - If the identity does not have a master key. /// - If there's an error during the creation of the identity update transition. -pub fn create_identity_update_transition_disable_keys( +pub async fn create_identity_update_transition_disable_keys( identity: &mut Identity, count: u16, identity_nonce_counter: &mut BTreeMap, @@ -599,6 +600,7 @@ pub fn create_identity_update_transition_disable_keys( platform_version, None, ) + .await .expect("expected to create a DisableKeys transition"); Some(state_transition) @@ -638,7 +640,7 @@ pub fn create_identity_update_transition_disable_keys( /// # Panics /// This function may panic under the following conditions: /// - If the identity does not have a suitable withdrawal address or key for signing. -pub fn create_identity_withdrawal_transition( +pub async fn create_identity_withdrawal_transition( identity: &mut Identity, amount_range: AmountRange, identity_nonce_counter: &mut BTreeMap, @@ -662,6 +664,7 @@ pub fn create_identity_withdrawal_transition( signer, rng, ) + .await } else { create_identity_withdrawal_transition_with_output_address( identity, @@ -670,6 +673,7 @@ pub fn create_identity_withdrawal_transition( signer, rng, ) + .await } } @@ -705,7 +709,7 @@ pub fn create_identity_withdrawal_transition( /// This function may panic under the following conditions: /// - If the identity does not have a suitable authentication key for signing. /// - If there's an error during the signing process. -pub fn create_identity_withdrawal_transition_sent_to_identity_transfer_key( +pub async fn create_identity_withdrawal_transition_sent_to_identity_transfer_key( identity: &mut Identity, amount_range: AmountRange, identity_nonce_counter: &mut BTreeMap, @@ -748,6 +752,7 @@ pub fn create_identity_withdrawal_transition_sent_to_identity_transfer_key( signer, None::, ) + .await .expect("expected to sign withdrawal"); withdrawal @@ -788,7 +793,7 @@ pub fn create_identity_withdrawal_transition_sent_to_identity_transfer_key( /// This function may panic under the following conditions: /// - If the identity does not have a suitable transfer key for signing. /// - If there's an error during the signing process. -pub fn create_identity_withdrawal_transition_with_output_address( +pub async fn create_identity_withdrawal_transition_with_output_address( identity: &mut Identity, amount_range: AmountRange, identity_nonce_counter: &mut BTreeMap, @@ -835,6 +840,7 @@ pub fn create_identity_withdrawal_transition_with_output_address( signer, None::, ) + .await .expect("expected to sign withdrawal"); withdrawal @@ -872,7 +878,7 @@ pub fn create_identity_withdrawal_transition_with_output_address( /// This function may panic under the following conditions: /// - If the sender's identity does not have a suitable authentication key available for signing. /// - If there's an error during the signing process. -pub fn create_identity_credit_transfer_transition( +pub async fn create_identity_credit_transfer_transition( identity: &Identity, recipient: &Identity, identity_nonce_counter: &mut BTreeMap, @@ -907,6 +913,7 @@ pub fn create_identity_credit_transfer_transition( signer, None::, ) + .await .expect("expected to sign transfer"); transition @@ -935,7 +942,7 @@ pub fn create_identity_credit_transfer_transition( /// - The sender's identity does not have a suitable transfer key available for signing. /// - There's an error during the signing process. #[allow(clippy::too_many_arguments)] -pub fn create_identity_credit_transfer_to_addresses_transition( +pub async fn create_identity_credit_transfer_to_addresses_transition( identity: &Identity, identity_nonce_counter: &mut BTreeMap, current_addresses_with_balance: &mut AddressesWithBalance, @@ -969,6 +976,7 @@ pub fn create_identity_credit_transfer_to_addresses_transition( platform_version, None, // version ) + .await .expect("expected to create transfer to addresses transition"); (transition, recipient_addresses) @@ -992,7 +1000,7 @@ pub fn create_identity_credit_transfer_to_addresses_transition( /// This function may panic if: /// - The sender's identity does not have a suitable transfer key available for signing. /// - There's an error during the signing process. -pub fn create_identity_credit_transfer_to_addresses_transition_with_outputs( +pub async fn create_identity_credit_transfer_to_addresses_transition_with_outputs( identity: &Identity, identity_nonce_counter: &mut BTreeMap, signer: &mut SimpleSigner, @@ -1012,6 +1020,7 @@ pub fn create_identity_credit_transfer_to_addresses_transition_with_outputs( platform_version, None, // version ) + .await .expect("expected to create transfer to addresses transition") } @@ -1053,7 +1062,7 @@ pub fn create_identity_credit_transfer_to_addresses_transition_with_outputs( /// - When unable to generate random cryptographic keys or identities. /// - Conversion and encoding errors related to the cryptographic data. #[allow(clippy::too_many_arguments)] -pub fn create_identities_state_transitions( +pub async fn create_identities_state_transitions( count: u16, key_count: KeyID, extra_keys: &KeyMaps, @@ -1109,56 +1118,56 @@ pub fn create_identities_state_transitions( } signer.add_identity_public_keys(keys); - // Generate state transitions for each identity - identities - .into_iter() - .enumerate() - .map(|(index, mut identity)| { - // Calculate the starting KeyID for this identity - let identity_starting_id = - starting_id_num + index as u32 * (key_count + extra_keys.len() as u32); - - // Update the identity with the new KeyIDs - let public_keys_map = identity.public_keys_mut(); - public_keys_map - .values_mut() - .enumerate() - .for_each(|(key_index, public_key)| { - let IdentityPublicKey::V0(ref mut id_pub_key_v0) = public_key; - let new_id = identity_starting_id + key_index as u32; - id_pub_key_v0.set_id(new_id); - }); - - if let Some(proof_and_pk) = asset_lock_proofs.pop() { - let (asset_lock_proof, private_key) = proof_and_pk; - let pk = private_key.to_bytes(); - match IdentityCreateTransition::try_from_identity_with_signer( - &identity, - asset_lock_proof, - &pk, - signer, - &NativeBlsModule, - 0, - platform_version, - ) { - Ok(identity_create_transition) => { - identity.set_id( - identity_create_transition - .owner_id() - .expect("identity create transitions have an identity id"), - ); - Ok((identity, identity_create_transition)) - } - Err(e) => Err(e), + // Generate state transitions for each identity (sequentially) + let mut results: Vec<(Identity, StateTransition)> = Vec::with_capacity(identities.len()); + for (index, mut identity) in identities.into_iter().enumerate() { + // Calculate the starting KeyID for this identity + let identity_starting_id = + starting_id_num + index as u32 * (key_count + extra_keys.len() as u32); + + // Update the identity with the new KeyIDs + let public_keys_map = identity.public_keys_mut(); + public_keys_map + .values_mut() + .enumerate() + .for_each(|(key_index, public_key)| { + let IdentityPublicKey::V0(ref mut id_pub_key_v0) = public_key; + let new_id = identity_starting_id + key_index as u32; + id_pub_key_v0.set_id(new_id); + }); + + if let Some(proof_and_pk) = asset_lock_proofs.pop() { + let (asset_lock_proof, private_key) = proof_and_pk; + let pk = private_key.to_bytes(); + match IdentityCreateTransition::try_from_identity_with_signer( + &identity, + asset_lock_proof, + &pk, + signer, + &NativeBlsModule, + 0, + platform_version, + ) + .await + { + Ok(identity_create_transition) => { + identity.set_id( + identity_create_transition + .owner_id() + .expect("identity create transitions have an identity id"), + ); + results.push((identity, identity_create_transition)); } - } else { - Err(ProtocolError::Generic( - "No asset lock proofs available for create_identities_state_transitions" - .to_string(), - )) + Err(e) => return Err(e), } - }) - .collect::, ProtocolError>>() + } else { + return Err(ProtocolError::Generic( + "No asset lock proofs available for create_identities_state_transitions" + .to_string(), + )); + } + } + Ok(results) } /// Generates state transitions for the creation of new identities. @@ -1197,7 +1206,7 @@ pub fn create_identities_state_transitions( /// - When unable to generate random cryptographic keys. /// - When failing to transform an identity into its corresponding state transition. /// - Conversion and encoding errors related to the cryptographic data. -pub fn create_state_transitions_for_identities<'a, I>( +pub async fn create_state_transitions_for_identities<'a, I>( identities: I, amount_range: &AmountRange, signer: &SimpleSigner, @@ -1207,38 +1216,37 @@ pub fn create_state_transitions_for_identities<'a, I>( where I: IntoIterator, { - identities - .into_iter() - .map(|identity| { - let (_, pk) = ECDSA_SECP256K1 - .random_public_and_private_key_data(rng, platform_version) - .unwrap(); - let secret_key = SecretKey::from_str(hex::encode(pk).as_str()).unwrap(); - let asset_lock_proof = instant_asset_lock_proof_fixture_with_dynamic_range( - PrivateKey::new(secret_key, Network::Mainnet), - amount_range, - rng, - ); - let identity_create_transition = - IdentityCreateTransition::try_from_identity_with_signer( - &identity.clone(), - asset_lock_proof, - &pk, - signer, - &NativeBlsModule, - 0, - platform_version, - ) - .expect("expected to transform identity into identity create transition"); - identity.set_id( - identity_create_transition - .owner_id() - .expect("identity create transitions have an identity id"), - ); - - (identity.clone(), identity_create_transition) - }) - .collect() + let mut results = Vec::new(); + for identity in identities.into_iter() { + let (_, pk) = ECDSA_SECP256K1 + .random_public_and_private_key_data(rng, platform_version) + .unwrap(); + let secret_key = SecretKey::from_str(hex::encode(pk).as_str()).unwrap(); + let asset_lock_proof = instant_asset_lock_proof_fixture_with_dynamic_range( + PrivateKey::new(secret_key, Network::Mainnet), + amount_range, + rng, + ); + let identity_create_transition = IdentityCreateTransition::try_from_identity_with_signer( + &identity.clone(), + asset_lock_proof, + &pk, + signer, + &NativeBlsModule, + 0, + platform_version, + ) + .await + .expect("expected to transform identity into identity create transition"); + identity.set_id( + identity_create_transition + .owner_id() + .expect("identity create transitions have an identity id"), + ); + + results.push((identity.clone(), identity_create_transition)); + } + results } /// Creates state transitions for identities with pre-generated asset lock proofs. @@ -1261,32 +1269,31 @@ where /// /// # Panics /// Panics if unable to create the identity creation transition. -pub fn create_state_transitions_for_identities_and_proofs( +pub async fn create_state_transitions_for_identities_and_proofs( identities_with_proofs: Vec<(Identity, [u8; 32], AssetLockProof)>, signer: &mut SimpleSigner, platform_version: &PlatformVersion, ) -> Vec<(Identity, StateTransition)> { - identities_with_proofs - .into_iter() - .map(|(mut identity, private_key, asset_lock_proof)| { - let identity_create_transition = - IdentityCreateTransition::try_from_identity_with_signer( - &identity.clone(), - asset_lock_proof, - &private_key, - signer, - &NativeBlsModule, - 0, - platform_version, - ) - .expect("expected to transform identity into identity create transition"); - identity.set_id( - identity_create_transition - .owner_id() - .expect("identity create transitions have an identity id"), - ); - - (identity, identity_create_transition) - }) - .collect() + let mut results = Vec::with_capacity(identities_with_proofs.len()); + for (mut identity, private_key, asset_lock_proof) in identities_with_proofs.into_iter() { + let identity_create_transition = IdentityCreateTransition::try_from_identity_with_signer( + &identity.clone(), + asset_lock_proof, + &private_key, + signer, + &NativeBlsModule, + 0, + platform_version, + ) + .await + .expect("expected to transform identity into identity create transition"); + identity.set_id( + identity_create_transition + .owner_id() + .expect("identity create transitions have an identity id"), + ); + + results.push((identity, identity_create_transition)); + } + results } diff --git a/packages/wasm-dpp2/Cargo.toml b/packages/wasm-dpp2/Cargo.toml index 5aa1a33f213..7af47f47f09 100644 --- a/packages/wasm-dpp2/Cargo.toml +++ b/packages/wasm-dpp2/Cargo.toml @@ -9,6 +9,7 @@ crate-type = ["cdylib", "lib"] [dependencies] # TODO: Consider to use talc allocator #talc = { version = "=4.4.2", default-features = false, features = ["lock_api"] } +async-trait = { version = "0.1.79" } bincode = "=2.0.1" wasm-bindgen = { version = "=0.2.108", default-features = false, features = [ "serde-serialize", diff --git a/packages/wasm-dpp2/src/identity/signer.rs b/packages/wasm-dpp2/src/identity/signer.rs index 0add01a6c60..8c5956d610c 100644 --- a/packages/wasm-dpp2/src/identity/signer.rs +++ b/packages/wasm-dpp2/src/identity/signer.rs @@ -131,8 +131,9 @@ impl IdentitySignerWasm { } } +#[async_trait::async_trait] impl Signer for IdentitySignerWasm { - fn sign( + async fn sign( &self, identity_public_key: &IdentityPublicKey, data: &[u8], @@ -150,12 +151,12 @@ impl Signer for IdentitySignerWasm { Ok(signature.to_vec().into()) } - fn sign_create_witness( + async fn sign_create_witness( &self, key: &IdentityPublicKey, data: &[u8], ) -> Result { - let signature = self.sign(key, data)?; + let signature = self.sign(key, data).await?; match key.key_type() { KeyType::ECDSA_HASH160 | KeyType::ECDSA_SECP256K1 => { diff --git a/packages/wasm-dpp2/src/platform_address/signer.rs b/packages/wasm-dpp2/src/platform_address/signer.rs index e7e288ade5f..af45fdd6ddd 100644 --- a/packages/wasm-dpp2/src/platform_address/signer.rs +++ b/packages/wasm-dpp2/src/platform_address/signer.rs @@ -94,8 +94,13 @@ impl PlatformAddressSignerWasm { } } +#[async_trait::async_trait] impl Signer for PlatformAddressSignerWasm { - fn sign(&self, address: &PlatformAddress, data: &[u8]) -> Result { + async fn sign( + &self, + address: &PlatformAddress, + data: &[u8], + ) -> Result { let wasm_address = PlatformAddressWasm::from(*address); let private_key = self.private_keys.get(&wasm_address).ok_or_else(|| { @@ -110,12 +115,12 @@ impl Signer for PlatformAddressSignerWasm { Ok(signature.to_vec().into()) } - fn sign_create_witness( + async fn sign_create_witness( &self, address: &PlatformAddress, data: &[u8], ) -> Result { - let signature = self.sign(address, data)?; + let signature = self.sign(address, data).await?; match address { PlatformAddress::P2pkh(_) => Ok(AddressWitness::P2pkh { signature }), diff --git a/packages/wasm-sdk/src/state_transitions/contract.rs b/packages/wasm-sdk/src/state_transitions/contract.rs index 23deb5aedff..a6da24b0d14 100644 --- a/packages/wasm-sdk/src/state_transitions/contract.rs +++ b/packages/wasm-sdk/src/state_transitions/contract.rs @@ -221,6 +221,7 @@ impl WasmSdk { self.inner_sdk().version(), None, ) + .await .map_err(|e| WasmSdkError::generic(format!("Failed to create update transition: {}", e)))?; // Broadcast the transition diff --git a/packages/wasm-sdk/src/state_transitions/identity.rs b/packages/wasm-sdk/src/state_transitions/identity.rs index 9d1bdb1b8a9..edf90726745 100644 --- a/packages/wasm-sdk/src/state_transitions/identity.rs +++ b/packages/wasm-sdk/src/state_transitions/identity.rs @@ -684,6 +684,7 @@ impl WasmSdk { self.inner_sdk().version(), None, ) + .await .map_err(|e| WasmSdkError::generic(format!("Failed to create update transition: {}", e)))?; // Broadcast the transition From e3cc4fc1d68cf558d23a67658eb7b5fb07faad38 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 15 Apr 2026 14:37:54 +0700 Subject: [PATCH 02/13] fix(sdk-ffi): timeout signer completion to prevent hang on missing callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the FFI signer's sign_async returns without ever invoking completion, the oneshot Sender sits inside a Box handed to the C side and never drops, so the previous `rx.await` match arm `Err(_recv_err)` could never fire and the awaiting async fn would hang forever. Bound the wait with tokio::time::timeout (5 min — generous enough for biometric + HSM round-trips). On timeout we surface a recoverable ProtocolError and leak the one Box rather than risk a use-after-free if the caller eventually does invoke completion. Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/scheduled_tasks.lock | 1 + packages/rs-sdk-ffi/Cargo.toml | 2 +- packages/rs-sdk-ffi/src/signer.rs | 50 +++++++++++++++++++++++++------ 3 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 .claude/scheduled_tasks.lock diff --git a/.claude/scheduled_tasks.lock b/.claude/scheduled_tasks.lock new file mode 100644 index 00000000000..0d6ca00ac20 --- /dev/null +++ b/.claude/scheduled_tasks.lock @@ -0,0 +1 @@ +{"sessionId":"8b5252b1-86d1-41ad-9ed3-a4c0912697e6","pid":33228,"acquiredAt":1776177761144} \ No newline at end of file diff --git a/packages/rs-sdk-ffi/Cargo.toml b/packages/rs-sdk-ffi/Cargo.toml index 342afca58a7..742a8969ed0 100644 --- a/packages/rs-sdk-ffi/Cargo.toml +++ b/packages/rs-sdk-ffi/Cargo.toml @@ -31,7 +31,7 @@ serde_json = "1.0" bincode = { version = "=2.0.1", features = ["serde"] } # Async runtime -tokio = { version = "1.41", features = ["rt-multi-thread", "macros", "sync"] } +tokio = { version = "1.41", features = ["rt-multi-thread", "macros", "sync", "time"] } async-trait = "0.1" # Error handling diff --git a/packages/rs-sdk-ffi/src/signer.rs b/packages/rs-sdk-ffi/src/signer.rs index b73743ce961..51a4eb0b575 100644 --- a/packages/rs-sdk-ffi/src/signer.rs +++ b/packages/rs-sdk-ffi/src/signer.rs @@ -48,8 +48,23 @@ use simple_signer::SingleKeySigner; use std::ffi::{c_void, CStr}; use std::os::raw::c_char; use std::sync::Arc; +use std::time::Duration; use tokio::sync::oneshot; +/// Upper bound on how long the Rust side will wait for an iOS / FFI signer +/// to invoke its completion callback after `sign_async` is called. +/// +/// If the caller never invokes `completion` (a contract violation) the +/// awaiting `async fn sign` would otherwise hang forever because the +/// `oneshot::Sender` is inside a `Box` that was handed to the C side and +/// never dropped. This timeout bounds the damage to a single leaked +/// `Box>` per stuck request and surfaces a recoverable +/// `ProtocolError` to the caller instead of wedging the runtime. +/// +/// Five minutes is generous enough for biometric prompts + HSM round-trips +/// while still being short enough that runaway tasks eventually fail. +const SIGN_ASYNC_COMPLETION_TIMEOUT: Duration = Duration::from_secs(300); + /// C-compatible async vtable for signers. /// /// `sign_async` returns immediately; the caller is expected to eventually @@ -284,21 +299,38 @@ impl Signer for VTableSigner { // Await the completion. The oneshot receiver is a real async // point — the Tokio worker is free to run other tasks. - match rx.await { - Ok(Ok(sig)) => Ok(BinaryData::from(sig)), - Ok(Err(e)) => Err(e), - Err(_recv_err) => { - // Sender dropped without sending. This can only - // happen if the iOS side forgot to call completion. - // See the note on `SignAsyncCallback` — that is a - // contract violation, but we surface it as a - // recoverable protocol error rather than hang forever. + // + // A non-conforming FFI signer that never invokes `completion` + // would otherwise hang forever: the `Sender` lives inside a + // `Box` we handed to C, so it never drops and `rx` never + // receives `RecvError`. Bound the wait with a timeout so the + // caller gets a recoverable error instead of a deadlock. + match tokio::time::timeout(SIGN_ASYNC_COMPLETION_TIMEOUT, rx).await { + Ok(Ok(Ok(sig))) => Ok(BinaryData::from(sig)), + Ok(Ok(Err(e))) => Err(e), + Ok(Err(_recv_err)) => { + // Sender was dropped without sending. Only possible + // if the FFI caller took custody of the completion + // context and then freed it without invoking the + // completion callback. Contract violation, but + // surface as a recoverable protocol error. Err(ProtocolError::Generic( "Signer completion channel dropped without a result; \ the FFI signer did not call its completion callback" .to_string(), )) } + Err(_elapsed) => { + // Timed out waiting for `completion`. The Sender box + // is still held by the FFI caller — we leak it + // rather than risk a use-after-free if the caller + // eventually does invoke the completion. + Err(ProtocolError::Generic(format!( + "Signer completion callback not invoked within {:?}; \ + the FFI signer is unresponsive", + SIGN_ASYNC_COMPLETION_TIMEOUT + ))) + } } } } From ccabca7a9582f75b8481da51ffb4d7583985c03a Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 15 Apr 2026 14:38:11 +0700 Subject: [PATCH 03/13] chore: gitignore .claude/ and remove stale lock --- .claude/scheduled_tasks.lock | 1 - .gitignore | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 .claude/scheduled_tasks.lock diff --git a/.claude/scheduled_tasks.lock b/.claude/scheduled_tasks.lock deleted file mode 100644 index 0d6ca00ac20..00000000000 --- a/.claude/scheduled_tasks.lock +++ /dev/null @@ -1 +0,0 @@ -{"sessionId":"8b5252b1-86d1-41ad-9ed3-a4c0912697e6","pid":33228,"acquiredAt":1776177761144} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6803d4a3177..4d059194c43 100644 --- a/.gitignore +++ b/.gitignore @@ -90,7 +90,7 @@ book/book/ grpc-coverage-report.txt __pycache__/ -.claude/worktrees/ +.claude/ # Security audit reports (local-only, not committed) audits/ From 91693821ce4b3d591dd15e59eb7aba16d4383fe1 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 15 Apr 2026 18:42:28 +0700 Subject: [PATCH 04/13] chore: restore original .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4d059194c43..6803d4a3177 100644 --- a/.gitignore +++ b/.gitignore @@ -90,7 +90,7 @@ book/book/ grpc-coverage-report.txt __pycache__/ -.claude/ +.claude/worktrees/ # Security audit reports (local-only, not committed) audits/ From ecf35cf91b0ab479ecaaaaf7aa1deb29483443eb Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 24 Apr 2026 13:29:39 +0200 Subject: [PATCH 05/13] refactor(sdk-ffi): use dash-async block_on in signer_simple MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the ad-hoc inline `tokio::runtime::Builder::new_current_thread()` in `dash_sdk_signer_sign` with the workspace-canonical `dash_async::block_on` (rs-dash-async). `block_on` is runtime-aware and handles the no-runtime, current-thread, and multi-thread flavors safely — avoiding the deadlocks that motivated PR #3432/#3497. Because `block_on` requires `Send + 'static` futures, the signing future now owns its inputs: the data slice is copied into a `Vec` up front and `&VTableSigner` is reconstructed from a pointer-sized integer inside the future (safe because `block_on` blocks the caller for the duration of the FFI call and `VTableSigner: Send + Sync`). The async-bridge error is surfaced as a distinct `InternalError` so callers can distinguish bridging failures from signing failures. Co-Authored-By: Claude Opus 4.7 (1M context) --- packages/rs-sdk-ffi/Cargo.toml | 1 + packages/rs-sdk-ffi/src/signer_simple.rs | 60 ++++++++++++++---------- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/packages/rs-sdk-ffi/Cargo.toml b/packages/rs-sdk-ffi/Cargo.toml index f3115a8f2bb..a423d87f280 100644 --- a/packages/rs-sdk-ffi/Cargo.toml +++ b/packages/rs-sdk-ffi/Cargo.toml @@ -22,6 +22,7 @@ rs-sdk-trusted-context-provider = { path = "../rs-sdk-trusted-context-provider", ] } simple-signer = { path = "../simple-signer" } async-trait = { version = "0.1.83" } +dash-async = { path = "../rs-dash-async" } # Serialization serde = { version = "1.0", features = ["derive"] } diff --git a/packages/rs-sdk-ffi/src/signer_simple.rs b/packages/rs-sdk-ffi/src/signer_simple.rs index e44e5c12c0b..888390dcb1e 100644 --- a/packages/rs-sdk-ffi/src/signer_simple.rs +++ b/packages/rs-sdk-ffi/src/signer_simple.rs @@ -9,6 +9,11 @@ use dash_sdk::dpp::identity::{IdentityPublicKey, KeyType, Purpose, SecurityLevel use simple_signer::SingleKeySigner; use zeroize::Zeroizing; +// Use the workspace-canonical async-sync bridge from `dash-async` instead of +// spinning up an ad-hoc tokio runtime. `block_on` handles no-runtime, +// current-thread, and multi-thread flavors correctly (see PR #3497/#3432). +use dash_async::block_on; + /// Create a signer from a private key. /// /// Internally wraps a `SingleKeySigner` as a native (non-callback) FFI @@ -94,8 +99,10 @@ pub unsafe extern "C" fn dash_sdk_signer_sign( )); } - let signer = &*(signer_handle as *const VTableSigner); - let data_slice = std::slice::from_raw_parts(data, data_len); + // Copy the input data into an owned buffer so the signing future has no + // borrowed references and can satisfy `dash_async::block_on`'s + // `Send + 'static` bounds. + let data_owned: Vec = std::slice::from_raw_parts(data, data_len).to_vec(); // Create a dummy identity public key for signing. SingleKeySigner // doesn't actually use the key data, just needs one to satisfy the @@ -113,40 +120,45 @@ pub unsafe extern "C" fn dash_sdk_signer_sign( }, ); - // The signer trait is async. This function is a synchronous C entry - // point, so we bridge by spinning up a current-thread runtime just - // long enough to drive the signing future. This is safe because - // SingleKeySigner's async fn is non-blocking (pure CPU work). - let runtime = match tokio::runtime::Builder::new_current_thread() - .enable_all() - .build() - { - Ok(rt) => rt, - Err(e) => { - return DashSDKResult::error(DashSDKError::new( - DashSDKErrorCode::InternalError, - format!("Failed to create runtime for signing: {}", e), - )); - } - }; - - match runtime.block_on(signer.sign(&dummy_key, data_slice)) { - Ok(signature) => { + // Bridge the async Signer API into this synchronous FFI entry point via + // the workspace's canonical async-sync bridge (`dash_async::block_on`), + // which is runtime-aware and safe regardless of whether a tokio runtime + // is already active. `block_on` requires `Send + 'static` futures, so + // we hand ownership of the key and data buffer into the future and + // reconstruct the `&VTableSigner` from a pointer-sized integer inside + // the future body. + // + // SAFETY: `signer_handle` is a valid `*const VTableSigner` for the + // duration of this FFI call, and `block_on` blocks the caller until the + // future completes, so the underlying allocation cannot be freed by the + // C caller while we hold the reference. `VTableSigner` is `Send + Sync`. + let signer_addr = signer_handle as usize; + let result = block_on(async move { + let signer: &VTableSigner = unsafe { &*(signer_addr as *const VTableSigner) }; + signer.sign(&dummy_key, &data_owned).await + }); + + match result { + Ok(Ok(signature)) => { let sig_vec = signature.to_vec(); let sig_len = sig_vec.len(); let sig_ptr = sig_vec.leak().as_mut_ptr(); - let result = Box::new(DashSDKSignature { + let boxed = Box::new(DashSDKSignature { signature: sig_ptr, signature_len: sig_len, }); - DashSDKResult::success(Box::into_raw(result) as *mut std::os::raw::c_void) + DashSDKResult::success(Box::into_raw(boxed) as *mut std::os::raw::c_void) } - Err(e) => DashSDKResult::error(DashSDKError::new( + Ok(Err(e)) => DashSDKResult::error(DashSDKError::new( DashSDKErrorCode::CryptoError, format!("Failed to sign: {}", e), )), + Err(e) => DashSDKResult::error(DashSDKError::new( + DashSDKErrorCode::InternalError, + format!("Async bridge failed during signing: {}", e), + )), } } From eaacc64d8141f241b54f9ea262f6fd4c72ce98cd Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 24 Apr 2026 13:49:48 +0200 Subject: [PATCH 06/13] test(drive-abci): await async Signer calls in upstream test fixtures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New tests landed on `v3.1-dev` while this branch converted `Signer::sign` and `sign_create_witness` to `async fn`. The upstream tests were written against the pre-async API and called `BatchTransition::new_token_*_transition` (and `perform_document_replace_on_profile_after_epoch_change`) synchronously, producing `impl Future` values that were then chained with `.expect(...)` / `.unwrap(...)`. After the merge this compiled as `E0599: no method named 'expect' found for opaque type 'impl Future<...>'` (54 sites across `token/burn` and `token/unfreeze`) and triggered `unused implementer of Future` warnings in wrapper tests across `token/freeze`, `token/mint`, `token/unfreeze`, and `document/replacement` (13 sites) — i.e. tests that compiled but silently did nothing. This commit mechanically fixes all affected sites: - Converts enclosing `#[test] fn test_...` to `#[tokio::test] async fn test_...` - Inserts `.await` before every `.expect(...)` / `.unwrap(...)` that followed an async signer-dependent call - Inserts `.await` before the terminating `;` of wrapper test bodies that invoke async helpers (`test_token_*_two_member_group_with_keeps_history`, `test_token_mint_by_owner_requires_group_other_member`, `perform_document_replace_on_profile_after_epoch_change`) - Updates `Cargo.lock` with the new `dash-async` dependency of `rs-sdk-ffi` introduced in the preceding commit Verified: `cargo check -p drive-abci --tests` and `cargo check --workspace --tests` both clean (warnings unchanged from pre-merge baseline). Co-Authored-By: Claude Opus 4.6 --- Cargo.lock | 1 + .../batch/tests/document/replacement.rs | 49 ++++---- .../batch/tests/token/burn/mod.rs | 114 +++++++++++------- .../batch/tests/token/freeze/mod.rs | 12 +- .../batch/tests/token/mint/mod.rs | 12 +- .../batch/tests/token/unfreeze/mod.rs | 76 ++++++++---- 6 files changed, 164 insertions(+), 100 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7288c5fe7ba..5366c9ebfc3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5867,6 +5867,7 @@ dependencies = [ "bincode", "bs58", "cbindgen 0.27.0", + "dash-async", "dash-sdk", "dotenvy", "drive-proof-verifier", diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/replacement.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/replacement.rs index 5030d50ae4c..759a1f0f13f 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/replacement.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/replacement.rs @@ -357,8 +357,8 @@ mod replacement_tests { ); } - #[test] - fn test_document_replace_on_document_type_that_is_mutable_different_epoch_bigger_size() { + #[tokio::test] + async fn test_document_replace_on_document_type_that_is_mutable_different_epoch_bigger_size() { perform_document_replace_on_profile_after_epoch_change( "Sam", vec![( @@ -369,33 +369,36 @@ mod replacement_tests { Identifier::default().to_buffer(), ), )], - ); + ) + .await; } - #[test] - fn test_document_replace_on_document_type_that_is_mutable_different_epoch_smaller_size() { + #[tokio::test] + async fn test_document_replace_on_document_type_that_is_mutable_different_epoch_smaller_size() { perform_document_replace_on_profile_after_epoch_change( "Sam", vec![( "S", StorageFlags::SingleEpochOwned(0, Identifier::default().to_buffer()), )], - ); + ) + .await; } - #[test] - fn test_document_replace_on_document_type_that_is_mutable_different_epoch_same_size() { + #[tokio::test] + async fn test_document_replace_on_document_type_that_is_mutable_different_epoch_same_size() { perform_document_replace_on_profile_after_epoch_change( "Sam", vec![( "Max", StorageFlags::SingleEpochOwned(0, Identifier::default().to_buffer()), )], - ); + ) + .await; } - #[test] - fn test_document_replace_on_document_type_that_is_mutable_different_epoch_bigger_size_then_bigger_size( + #[tokio::test] + async fn test_document_replace_on_document_type_that_is_mutable_different_epoch_bigger_size_then_bigger_size( ) { perform_document_replace_on_profile_after_epoch_change( "Sam", @@ -417,11 +420,12 @@ mod replacement_tests { ), ), ], - ); + ) + .await; } - #[test] - fn test_document_replace_on_document_type_that_is_mutable_different_epoch_bigger_size_then_bigger_size_by_3_bytes( + #[tokio::test] + async fn test_document_replace_on_document_type_that_is_mutable_different_epoch_bigger_size_then_bigger_size_by_3_bytes( ) { perform_document_replace_on_profile_after_epoch_change( "Sam", @@ -443,11 +447,12 @@ mod replacement_tests { ), ), ], - ); + ) + .await; } - #[test] - fn test_document_replace_on_document_type_that_is_mutable_different_epoch_bigger_size_then_smaller_size( + #[tokio::test] + async fn test_document_replace_on_document_type_that_is_mutable_different_epoch_bigger_size_then_smaller_size( ) { // In this case we start with the size Samuell Base epoch 0 epoch 1 added 7 bytes // Then we try to update it to Sami Base epoch 2 @@ -477,11 +482,12 @@ mod replacement_tests { ), ), ], - ); + ) + .await; } - #[test] - fn test_document_replace_on_document_type_that_is_mutable_different_epoch_bigger_size_then_back_to_original( + #[tokio::test] + async fn test_document_replace_on_document_type_that_is_mutable_different_epoch_bigger_size_then_back_to_original( ) { perform_document_replace_on_profile_after_epoch_change( "Sam", @@ -499,7 +505,8 @@ mod replacement_tests { StorageFlags::SingleEpochOwned(0, Identifier::default().to_buffer()), ), ], - ); + ) + .await; } #[tokio::test] diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/burn/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/burn/mod.rs index 1bd09ca3f15..b6ddfa1b53e 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/burn/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/burn/mod.rs @@ -911,8 +911,8 @@ mod token_burn_tests { // Expanded coverage tests // -------------------------------------------------------------- - #[test] - fn test_token_burn_updates_total_supply_correctly() { + #[tokio::test] + async fn test_token_burn_updates_total_supply_correctly() { // Burn should decrement the token's total supply by the same amount removed // from the identity's balance. let platform_version = PlatformVersion::latest(); @@ -959,6 +959,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create burn transition"); let serialized = burn_transition @@ -1010,8 +1011,8 @@ mod token_burn_tests { assert_eq!(total_supply_after, Some(75000)); } - #[test] - fn test_token_burn_with_public_note_succeeds() { + #[tokio::test] + async fn test_token_burn_with_public_note_succeeds() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1049,6 +1050,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create burn transition"); let serialized = burn_transition @@ -1094,8 +1096,8 @@ mod token_burn_tests { assert_eq!(balance, Some(99500)); } - #[test] - fn test_token_burn_with_public_note_too_big_fails() { + #[tokio::test] + async fn test_token_burn_with_public_note_too_big_fails() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1134,6 +1136,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create burn transition"); let serialized = burn_transition @@ -1175,8 +1178,8 @@ mod token_burn_tests { assert_eq!(balance, Some(100000)); } - #[test] - fn test_token_burn_zero_amount_fails() { + #[tokio::test] + async fn test_token_burn_zero_amount_fails() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1214,6 +1217,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create burn transition"); let serialized = burn_transition @@ -1263,8 +1267,8 @@ mod token_burn_tests { assert_eq!(total_supply, Some(100000)); } - #[test] - fn test_token_burn_allowed_when_rule_is_contract_owner_explicit() { + #[tokio::test] + async fn test_token_burn_allowed_when_rule_is_contract_owner_explicit() { // Explicitly set the burning rule to ContractOwner and verify the contract // owner can still burn (distinct from the default-rules happy path). let platform_version = PlatformVersion::latest(); @@ -1314,6 +1318,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create burn transition"); let serialized = burn_transition @@ -1365,8 +1370,8 @@ mod token_burn_tests { assert_eq!(total_supply, Some(98500)); } - #[test] - fn test_token_burn_allowed_by_specific_identity_rule() { + #[tokio::test] + async fn test_token_burn_allowed_by_specific_identity_rule() { // Allow burning only by a specific (non-owner) identity. let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -1421,6 +1426,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create burn transition"); let serialized = burn_transition @@ -1485,8 +1491,8 @@ mod token_burn_tests { assert_eq!(total_supply, Some(125000)); } - #[test] - fn test_token_burn_specific_identity_rule_rejects_other_identity() { + #[tokio::test] + async fn test_token_burn_specific_identity_rule_rejects_other_identity() { // Burning rule is Identity(burner); owner attempts to burn -> unauthorized. let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -1537,6 +1543,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create burn transition"); let serialized = burn_transition @@ -1585,8 +1592,8 @@ mod token_burn_tests { assert_eq!(owner_balance, Some(100000)); } - #[test] - fn test_token_burn_rule_no_one_blocks_even_owner() { + #[tokio::test] + async fn test_token_burn_rule_no_one_blocks_even_owner() { // With NoOne rule, even the contract owner cannot burn. let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -1635,6 +1642,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create burn transition"); let serialized = burn_transition @@ -1689,8 +1697,8 @@ mod token_burn_tests { assert_eq!(total_supply, Some(100000)); } - #[test] - fn test_token_burn_from_frozen_account_succeeds() { + #[tokio::test] + async fn test_token_burn_from_frozen_account_succeeds() { // Burn validation does NOT check freeze status (only transfer does), // so a frozen account can still have its tokens burned. This test locks // in the current behavior and covers the removal path for frozen @@ -1743,6 +1751,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create freeze transition"); let freeze_serialized = freeze_transition @@ -1789,6 +1798,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create burn transition"); let burn_serialized = burn_transition @@ -1837,8 +1847,8 @@ mod token_burn_tests { assert_eq!(total_supply, Some(80000)); } - #[test] - fn test_token_burn_from_identity_with_no_token_balance_record() { + #[tokio::test] + async fn test_token_burn_from_identity_with_no_token_balance_record() { // Authorized by rule but the burning identity has no token balance record at all. // Should yield IdentityDoesNotHaveEnoughTokenBalanceError. let platform_version = PlatformVersion::latest(); @@ -1891,6 +1901,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create burn transition"); let serialized = burn_transition @@ -1949,8 +1960,8 @@ mod token_burn_tests { assert_eq!(total_supply, Some(100000)); } - #[test] - fn test_token_burn_sequential_depletes_balance_and_supply() { + #[tokio::test] + async fn test_token_burn_sequential_depletes_balance_and_supply() { // Two successful burns in sequence should correctly decrement both // the identity's balance and the total supply. let platform_version = PlatformVersion::latest(); @@ -1994,6 +2005,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create burn transition"); let serialized = burn_transition @@ -2046,8 +2058,8 @@ mod token_burn_tests { } } - #[test] - fn test_token_burn_by_group_single_member_sufficient_power() { + #[tokio::test] + async fn test_token_burn_by_group_single_member_sufficient_power() { // Group rule, but the proposer alone has enough power to finalize the // action in one shot (mirrors the analogous mint test). let platform_version = PlatformVersion::latest(); @@ -2107,6 +2119,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create burn transition"); let serialized = burn_transition @@ -2158,8 +2171,8 @@ mod token_burn_tests { assert_eq!(total_supply, Some(97500)); } - #[test] - fn test_token_burn_group_action_resubmit_same_signer_fails() { + #[tokio::test] + async fn test_token_burn_group_action_resubmit_same_signer_fails() { // Proposer + confirmer path, then proposer tries to submit the confirmation // again -> GroupActionAlreadySignedByIdentityError. let platform_version = PlatformVersion::latest(); @@ -2219,6 +2232,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create burn transition"); let serialized = burn_transition @@ -2279,6 +2293,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create resubmit transition"); let serialized = resubmit_transition @@ -2328,8 +2343,8 @@ mod token_burn_tests { assert_eq!(balance, Some(100000)); } - #[test] - fn test_token_burn_group_action_submit_after_completion_fails() { + #[tokio::test] + async fn test_token_burn_group_action_submit_after_completion_fails() { // Three-member group with required power 2: proposer + one confirmer completes // the action, then a third member tries to confirm -> AlreadyCompleted. let platform_version = PlatformVersion::latest(); @@ -2398,6 +2413,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create burn transition"); let serialized = burn_transition @@ -2458,6 +2474,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create confirm transition"); let serialized = confirm_transition @@ -2523,6 +2540,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create late transition"); let serialized = late_transition @@ -2564,8 +2582,8 @@ mod token_burn_tests { assert_eq!(total_supply, Some(99000)); } - #[test] - fn test_token_burn_group_proposer_not_in_group_fails() { + #[tokio::test] + async fn test_token_burn_group_proposer_not_in_group_fails() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -2625,6 +2643,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create burn transition"); let serialized = burn_transition @@ -2670,8 +2689,8 @@ mod token_burn_tests { assert_eq!(balance, Some(100000)); } - #[test] - fn test_token_burn_group_other_signer_not_in_group_fails() { + #[tokio::test] + async fn test_token_burn_group_other_signer_not_in_group_fails() { // Proposer succeeds, but a non-member tries to confirm. let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -2733,6 +2752,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create burn transition"); let serialized = burn_transition @@ -2793,6 +2813,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create confirm transition"); let serialized = confirm_transition @@ -2839,8 +2860,8 @@ mod token_burn_tests { assert_eq!(balance, Some(100000)); } - #[test] - fn test_token_burn_group_confirmer_with_note_fails() { + #[tokio::test] + async fn test_token_burn_group_confirmer_with_note_fails() { // Only the proposer may attach a note. The confirmer attempting to attach // a note is rejected with TokenNoteOnlyAllowedWhenProposerError. let platform_version = PlatformVersion::latest(); @@ -2902,6 +2923,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create burn transition"); let serialized = burn_transition @@ -2962,6 +2984,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create confirm transition"); let serialized = confirm_with_note @@ -3007,8 +3030,8 @@ mod token_burn_tests { assert_eq!(balance, Some(100000)); } - #[test] - fn test_token_burn_group_confirmer_modifies_amount_fails() { + #[tokio::test] + async fn test_token_burn_group_confirmer_modifies_amount_fails() { // Confirmer attempts to burn a different amount than the proposer -> modification // of main parameters is rejected. let platform_version = PlatformVersion::latest(); @@ -3070,6 +3093,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create burn transition"); let serialized = burn_transition @@ -3130,6 +3154,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create confirm transition"); let serialized = mismatched_confirm @@ -3178,8 +3203,8 @@ mod token_burn_tests { assert_eq!(balance, Some(100000)); } - #[test] - fn test_token_burn_by_main_group_rule() { + #[tokio::test] + async fn test_token_burn_by_main_group_rule() { // Verify the MainGroup authorization path: the rule says MainGroup, and the // main_control_group is set to 0. A member of group 0 proposes the burn. let platform_version = PlatformVersion::latest(); @@ -3242,6 +3267,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create burn transition"); let serialized = burn_transition @@ -3302,6 +3328,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expected to create confirm transition"); let serialized = confirm_transition @@ -3349,8 +3376,8 @@ mod token_burn_tests { assert_eq!(total_supply, Some(99500)); } - #[test] - fn test_token_burn_after_full_depletion_fails_with_insufficient_balance() { + #[tokio::test] + async fn test_token_burn_after_full_depletion_fails_with_insufficient_balance() { // Burn entire balance, then try to burn more -> insufficient balance. let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() @@ -3390,6 +3417,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create burn transition"); let serialized = burn_all @@ -3436,6 +3464,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create burn transition"); let serialized = burn_again @@ -3490,8 +3519,8 @@ mod token_burn_tests { assert_eq!(total_supply, Some(0)); } - #[test] - fn test_token_burn_by_one_then_by_another_both_independent() { + #[tokio::test] + async fn test_token_burn_by_one_then_by_another_both_independent() { // Two identities both authorized via ContractOwner + Identity rules? The // AuthorizedActionTakers enum only has a single variant per rule, so we // pick Identity() for a second holder and verify bursts from distinct @@ -3540,6 +3569,7 @@ mod token_burn_tests { platform_version, None, ) + .await .expect("expect to create burn transition"); let serialized = burn1.serialize_to_bytes().expect("expected serialized"); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/freeze/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/freeze/mod.rs index cb1f84c9d70..a15e5fee7ab 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/freeze/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/freeze/mod.rs @@ -1658,14 +1658,14 @@ mod token_freeze_tests { assert_eq!(frozen, Some(true)); } - #[test] - fn test_token_freeze_two_member_group_no_keeping_history() { - test_token_freeze_two_member_group_with_keeps_history(false); + #[tokio::test] + async fn test_token_freeze_two_member_group_no_keeping_history() { + test_token_freeze_two_member_group_with_keeps_history(false).await; } - #[test] - fn test_token_freeze_two_member_group_keeping_history() { - test_token_freeze_two_member_group_with_keeps_history(true); + #[tokio::test] + async fn test_token_freeze_two_member_group_keeping_history() { + test_token_freeze_two_member_group_with_keeps_history(true).await; } // ────────────────────────────────────────────────────────── diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mint/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mint/mod.rs index bdba8a84cd8..0e6f1737710 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mint/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mint/mod.rs @@ -1456,14 +1456,14 @@ mod token_mint_tests { assert_eq!(token_balance, Some(101337)); } - #[test] - fn test_token_mint_by_owner_requires_group_other_member_with_history() { - test_token_mint_by_owner_requires_group_other_member(true); + #[tokio::test] + async fn test_token_mint_by_owner_requires_group_other_member_with_history() { + test_token_mint_by_owner_requires_group_other_member(true).await; } - #[test] - fn test_token_mint_by_owner_requires_group_other_member_no_history() { - test_token_mint_by_owner_requires_group_other_member(false); + #[tokio::test] + async fn test_token_mint_by_owner_requires_group_other_member_no_history() { + test_token_mint_by_owner_requires_group_other_member(false).await; } async fn test_token_mint_by_owner_requires_group_other_member(keeps_minting_history: bool) { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/unfreeze/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/unfreeze/mod.rs index e07e013df08..14199dc93d8 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/unfreeze/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/unfreeze/mod.rs @@ -9,8 +9,8 @@ mod token_unfreeze_tests { // ────────────────────────────────────────────────────────── // Successfully unfreeze a previously-frozen identity's balance. // ────────────────────────────────────────────────────────── - #[test] - fn test_token_unfreeze_previously_frozen_identity() { + #[tokio::test] + async fn test_token_unfreeze_previously_frozen_identity() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -72,6 +72,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create freeze transition"); let freeze_serialized = freeze_transition @@ -134,6 +135,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create unfreeze transition"); let unfreeze_serialized = unfreeze_transition @@ -184,8 +186,8 @@ mod token_unfreeze_tests { // Unfreeze when the identity was never frozen → Error. // The validator returns IdentityTokenAccountNotFrozenError. // ────────────────────────────────────────────────────────── - #[test] - fn test_token_unfreeze_never_frozen_identity_fails() { + #[tokio::test] + async fn test_token_unfreeze_never_frozen_identity_fails() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -237,6 +239,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create unfreeze transition"); let unfreeze_serialized = unfreeze_transition @@ -293,8 +296,8 @@ mod token_unfreeze_tests { // Unfreezing an already-unfrozen identity → Error // (no-op not allowed by the spec). // ────────────────────────────────────────────────────────── - #[test] - fn test_token_unfreeze_already_unfrozen_fails() { + #[tokio::test] + async fn test_token_unfreeze_already_unfrozen_fails() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -356,6 +359,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create freeze transition"); let freeze_serialized = freeze_transition @@ -401,6 +405,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create unfreeze transition"); let unfreeze_serialized = unfreeze_transition @@ -447,6 +452,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create unfreeze transition"); let second_unfreeze_serialized = second_unfreeze @@ -490,8 +496,8 @@ mod token_unfreeze_tests { // Unfreeze is restricted to the contract owner, and a second // identity tries to unfreeze → UnauthorizedTokenActionError. // ────────────────────────────────────────────────────────── - #[test] - fn test_token_unfreeze_non_authorized_identity_fails() { + #[tokio::test] + async fn test_token_unfreeze_non_authorized_identity_fails() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -556,6 +562,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create freeze transition"); let freeze_serialized = freeze_transition @@ -602,6 +609,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create unfreeze transition"); let unfreeze_serialized = unfreeze_transition @@ -655,8 +663,8 @@ mod token_unfreeze_tests { // After unfreezing, a previously-frozen account can send tokens // (verifying unfrozen state is truly effective). // ────────────────────────────────────────────────────────── - #[test] - fn test_token_unfreeze_allows_subsequent_transfer() { + #[tokio::test] + async fn test_token_unfreeze_allows_subsequent_transfer() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -720,6 +728,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create transfer transition"); let transfer_serialized = transfer_in @@ -766,6 +775,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create freeze transition"); let freeze_serialized = freeze_transition @@ -814,6 +824,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create transfer transition"); let blocked_send_serialized = blocked_send @@ -865,6 +876,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create unfreeze transition"); let unfreeze_serialized = unfreeze_transition @@ -913,6 +925,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create transfer transition"); let allowed_send_serialized = allowed_send @@ -973,8 +986,8 @@ mod token_unfreeze_tests { // unfreeze. This exercises the Identity(...) branch of // AuthorizedActionTakers during unfreeze. // ────────────────────────────────────────────────────────── - #[test] - fn test_token_unfreeze_authorized_identity() { + #[tokio::test] + async fn test_token_unfreeze_authorized_identity() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1037,6 +1050,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create freeze transition"); let freeze_serialized = freeze_transition.serialize_to_bytes().unwrap(); let transaction = platform.drive.grove.start_transaction(); @@ -1079,6 +1093,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create unfreeze transition"); let owner_unfreeze_serialized = owner_unfreeze.serialize_to_bytes().unwrap(); let transaction = platform.drive.grove.start_transaction(); @@ -1124,6 +1139,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create unfreeze transition"); let unfreeze_serialized = unfreeze_transition.serialize_to_bytes().unwrap(); let transaction = platform.drive.grove.start_transaction(); @@ -1166,8 +1182,8 @@ mod token_unfreeze_tests { // ────────────────────────────────────────────────────────── // Unfreeze with an attached public note. // ────────────────────────────────────────────────────────── - #[test] - fn test_token_unfreeze_with_public_note() { + #[tokio::test] + async fn test_token_unfreeze_with_public_note() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1220,6 +1236,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create freeze transition"); let freeze_serialized = freeze_transition.serialize_to_bytes().unwrap(); let transaction = platform.drive.grove.start_transaction(); @@ -1262,6 +1279,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create unfreeze transition"); let unfreeze_serialized = unfreeze_transition.serialize_to_bytes().unwrap(); @@ -1307,8 +1325,8 @@ mod token_unfreeze_tests { // This confirms the contract lookup path rejects unknown contracts // before hitting unfreeze logic. // ────────────────────────────────────────────────────────── - #[test] - fn test_token_unfreeze_nonexistent_contract_fails() { + #[tokio::test] + async fn test_token_unfreeze_nonexistent_contract_fails() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1343,6 +1361,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create unfreeze transition"); let unfreeze_serialized = unfreeze_transition @@ -1394,8 +1413,8 @@ mod token_unfreeze_tests { // Owner alone does NOT have enough group power → unfreeze fails // with UnauthorizedTokenActionError. // ────────────────────────────────────────────────────────── - #[test] - fn test_token_unfreeze_owner_not_authorized_group_required() { + #[tokio::test] + async fn test_token_unfreeze_owner_not_authorized_group_required() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1458,6 +1477,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("create freeze"); let freeze_ser = freeze.serialize_to_bytes().unwrap(); @@ -1501,6 +1521,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("create unfreeze"); let unfreeze_ser = unfreeze.serialize_to_bytes().unwrap(); @@ -1547,21 +1568,23 @@ mod token_unfreeze_tests { assert_eq!(frozen, Some(true)); } - #[test] - fn test_token_unfreeze_two_member_group_no_keeping_history() { - test_token_unfreeze_two_member_group_with_keeps_history(false); + #[tokio::test] + async fn test_token_unfreeze_two_member_group_no_keeping_history() { + test_token_unfreeze_two_member_group_with_keeps_history(false).await; } - #[test] - fn test_token_unfreeze_two_member_group_keeping_history() { - test_token_unfreeze_two_member_group_with_keeps_history(true); + #[tokio::test] + async fn test_token_unfreeze_two_member_group_keeping_history() { + test_token_unfreeze_two_member_group_with_keeps_history(true).await; } // ────────────────────────────────────────────────────────── // Two‑signer scenario: proposer + second member complete unfreeze. // Verifies GroupStateTransitionInfo flow for unfreeze. // ────────────────────────────────────────────────────────── - fn test_token_unfreeze_two_member_group_with_keeps_history(keeps_freezing_history: bool) { + async fn test_token_unfreeze_two_member_group_with_keeps_history( + keeps_freezing_history: bool, + ) { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -1626,6 +1649,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("create freeze"); let freeze_ser = freeze.serialize_to_bytes().unwrap(); let tx = platform.drive.grove.start_transaction(); @@ -1668,6 +1692,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .expect("expect to create batch transition"); let unfreeze_propose_ser = unfreeze_propose @@ -1770,6 +1795,7 @@ mod token_unfreeze_tests { platform_version, None, ) + .await .unwrap(); let unfreeze_confirm_ser = unfreeze_confirm From acd9c44311e96c97b17dcdb303abc38ffbbef108 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 24 Apr 2026 14:29:53 +0200 Subject: [PATCH 07/13] fix(sdk-ffi): make dash_sdk_sign_async_completion duplicate-call safe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses @thepastaclaw review (PR #3492, thread r3128065543). Previously `dash_sdk_sign_async_completion` unconditionally reconstructed `Box>` from the C-supplied `completion_ctx` on every call. A single-shot guarantee only as documentation made the function a latent use-after-free / double-free if the foreign signer ever invoked completion more than once — a realistic failure mode for biometric retries, success/error races, or duplicate platform callbacks. Introduce a leaked `CompletionSlot { sender: AtomicPtr }` as the completion context. The first call atomically swaps the inner sender pointer to null (`AcqRel`) and wraps it back into a `Box` that is dropped exactly once at end of scope; subsequent calls observe null and return without touching freed memory. The slot itself is intentionally leaked — a small bounded cost per sign_async call — because the FFI boundary cannot guarantee when (or whether) the foreign caller stops invoking completion. Adds a regression test `completion_callback_duplicate_is_no_op` that invokes completion three times and asserts only the first result is observed and no crash occurs. Co-Authored-By: Claude Opus 4.6 --- packages/rs-sdk-ffi/src/signer.rs | 138 ++++++++++++++++++++++++++---- 1 file changed, 121 insertions(+), 17 deletions(-) diff --git a/packages/rs-sdk-ffi/src/signer.rs b/packages/rs-sdk-ffi/src/signer.rs index 51a4eb0b575..4bd62f56e82 100644 --- a/packages/rs-sdk-ffi/src/signer.rs +++ b/packages/rs-sdk-ffi/src/signer.rs @@ -47,6 +47,7 @@ use dash_sdk::dpp::prelude::{IdentityPublicKey, ProtocolError}; use simple_signer::SingleKeySigner; use std::ffi::{c_void, CStr}; use std::os::raw::c_char; +use std::sync::atomic::{AtomicPtr, Ordering}; use std::sync::Arc; use std::time::Duration; use tokio::sync::oneshot; @@ -145,6 +146,27 @@ pub type DestroyCallback = Option; /// back to the awaiting Rust `async fn sign`. type SignResult = Result, ProtocolError>; +/// Heap-allocated context handed to C as `completion_ctx`. +/// +/// Holds an `AtomicPtr` to the boxed `oneshot::Sender`. The first +/// completion call atomically swaps the pointer to null and claims ownership +/// of the sender; subsequent calls observe null and return without touching +/// freed memory, making duplicate or racing completion invocations a safe +/// no-op instead of a use-after-free. +/// +/// The `CompletionSlot` itself is intentionally never freed — it is leaked +/// once for the lifetime of the process per `sign_async` call. This is a +/// small, bounded leak (one `AtomicPtr`, 8 bytes on 64-bit) per sign, and is +/// the price for ABI-boundary safety: because we cannot enforce that C stops +/// calling `completion` after the Rust side has returned (or timed out), we +/// keep the slot alive so late or duplicate completions remain defined +/// behaviour. The `Sender` inside is freed on first completion or leaked on +/// timeout, matching the pre-existing `SIGN_ASYNC_COMPLETION_TIMEOUT` trade. +struct CompletionSlot { + /// Null once the sender has been consumed (or never populated). + sender: AtomicPtr>, +} + /// Generic signer that dispatches to either: /// - a C-ABI async vtable (for iOS HSM / keychain / external signers), or /// - a native Rust `Signer` implementation (e.g. `SingleKeySigner`), which @@ -277,10 +299,21 @@ impl Signer for VTableSigner { .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; // Build a oneshot channel so the async fn can await the - // completion callback without blocking any thread. + // completion callback without blocking any thread. The sender + // lives inside a leaked `CompletionSlot` whose `AtomicPtr` + // enforces single-shot semantics on the C side: the first + // completion callback atomically claims the sender, any + // subsequent calls (duplicate delivery, retry races, + // double-invocation bugs) observe null and become a defined + // no-op — no use-after-free, no double drop. let (tx, rx) = oneshot::channel::(); let tx_box: Box> = Box::new(tx); - let completion_ctx = Box::into_raw(tx_box) as *mut c_void; + let tx_ptr = Box::into_raw(tx_box); + let slot = Box::new(CompletionSlot { + sender: AtomicPtr::new(tx_ptr), + }); + // Leaked on purpose — see `CompletionSlot` docs for rationale. + let completion_ctx = Box::into_raw(slot) as *mut c_void; // SAFETY: vtable is non-null for the Callback variant by // construction, and sign_async is required to eventually call @@ -309,11 +342,13 @@ impl Signer for VTableSigner { Ok(Ok(Ok(sig))) => Ok(BinaryData::from(sig)), Ok(Ok(Err(e))) => Err(e), Ok(Err(_recv_err)) => { - // Sender was dropped without sending. Only possible - // if the FFI caller took custody of the completion - // context and then freed it without invoking the - // completion callback. Contract violation, but - // surface as a recoverable protocol error. + // Sender was dropped without sending. With the + // `CompletionSlot` design the slot itself is + // intentionally leaked, so this branch is only + // reachable via exotic contract violations (e.g. a + // bridge that calls completion with a null signature, + // null error, and somehow drops the sender box). + // Surface as a recoverable protocol error. Err(ProtocolError::Generic( "Signer completion channel dropped without a result; \ the FFI signer did not call its completion callback" @@ -321,10 +356,12 @@ impl Signer for VTableSigner { )) } Err(_elapsed) => { - // Timed out waiting for `completion`. The Sender box - // is still held by the FFI caller — we leak it - // rather than risk a use-after-free if the caller - // eventually does invoke the completion. + // Timed out waiting for `completion`. The + // `CompletionSlot` (and the sender it still holds) + // remain alive so that a late or duplicate FFI + // invocation of the completion callback remains + // defined — it will swap the sender out and drop it, + // with the receiver already gone. Err(ProtocolError::Generic(format!( "Signer completion callback not invoked within {:?}; \ the FFI signer is unresponsive", @@ -414,10 +451,20 @@ impl<'a> Signer for VTableSignerRef<'a> { /// `sign_async` callback. You do not need to look this symbol up — the /// pointer is passed directly. /// +/// # Single-shot guarantee +/// +/// The single-shot contract ("must be called exactly once") is enforced by a +/// runtime guard inside the `CompletionSlot`: the first invocation atomically +/// claims the boxed sender via an `AtomicPtr::swap`; any subsequent +/// invocations (duplicate delivery, retry races, buggy bridges) observe null +/// and return without touching freed memory. This makes double / triple / +/// spurious completion calls a safe no-op instead of a use-after-free. +/// /// # Safety /// - `completion_ctx` must be the exact pointer that was passed to -/// `SignAsyncCallback`, and must not have been used in a previous -/// completion call. +/// `SignAsyncCallback`. Reusing another pointer, or a pointer from a +/// different process, is UB — but reusing the same valid pointer more than +/// once is defined: subsequent calls after the first are no-ops. /// - If `error_message` is non-null it must point to a valid null-terminated /// UTF-8 (or at least CStr-safe) string. The string is copied into an owned /// `String` before this function returns, so the caller may free it @@ -438,10 +485,23 @@ pub unsafe extern "C" fn dash_sdk_sign_async_completion( return; } - // Reconstruct the Sender box. From here on we OWN the oneshot sender - // and must either send or drop it. - let tx: Box> = - Box::from_raw(completion_ctx as *mut oneshot::Sender); + // SAFETY: `completion_ctx` came from `Box::into_raw(Box::)` + // in `VTableSigner::sign` and the slot is intentionally never freed (see + // the `CompletionSlot` doc comment), so this reference is valid for any + // number of calls. + let slot = &*(completion_ctx as *const CompletionSlot); + + // Atomically claim the sender. Only the first caller gets a non-null + // pointer; duplicate callers observe null and bail out without dropping + // the sender twice. + let tx_ptr = slot.sender.swap(std::ptr::null_mut(), Ordering::AcqRel); + if tx_ptr.is_null() { + return; + } + + // We are the sole owner of this sender now. Wrap it back into a Box so + // that it is dropped exactly once at the end of this call. + let tx: Box> = Box::from_raw(tx_ptr); let result: SignResult = if !error_message.is_null() { let msg = CStr::from_ptr(error_message).to_string_lossy().into_owned(); @@ -715,4 +775,48 @@ mod tests { assert_eq!(sig.len(), 64); assert_eq!(sig.as_slice()[0], 0x55); } + + /// Test sign callback that invokes the completion callback **twice** to + /// exercise the single-shot guard in `CompletionSlot`. The second call + /// must be a defined no-op (no use-after-free, no double-drop). + unsafe extern "C" fn test_sign_async_double_complete( + _signer: *const c_void, + _key_bytes: *const u8, + _key_len: usize, + _data: *const u8, + _data_len: usize, + completion_ctx: *mut c_void, + completion: SignCompletionCallback, + ) { + let sig = [0x42u8; 64]; + // First call: legitimate success. + completion(completion_ctx, sig.as_ptr(), sig.len(), std::ptr::null()); + // Second call with an error payload: must be observed as a no-op, + // NOT overwrite the first result and NOT crash. + let err_msg = c"duplicate completion — should be ignored"; + completion(completion_ctx, std::ptr::null(), 0, err_msg.as_ptr()); + // Third call with yet another success: still a no-op. + let sig2 = [0x99u8; 64]; + completion(completion_ctx, sig2.as_ptr(), sig2.len(), std::ptr::null()); + } + + #[tokio::test] + async fn completion_callback_duplicate_is_no_op() { + // Regression test for the one-shot guard: a buggy FFI signer that + // invokes completion more than once must NOT cause UAF, and the + // Rust side must observe only the first result. + let signer = make_signer(test_sign_async_double_complete); + let key = make_dummy_key(); + + let sig = signer + .sign(&key, &[10, 11, 12]) + .await + .expect("first completion wins — sign should succeed"); + assert_eq!(sig.len(), 64); + assert_eq!( + sig.as_slice()[0], + 0x42, + "first completion's signature must win; duplicate overwrite must be ignored" + ); + } } From 6bd02130706eb13f0197d16a3ef9170360fcf35a Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 24 Apr 2026 14:29:53 +0200 Subject: [PATCH 08/13] docs(dpp): clarify async_trait vs #![allow(async_fn_in_trait)] rationale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses @lklimek review (PR #3492, threads r3085996493 / r3086015077). The crate-root `#![allow(async_fn_in_trait)]` is not a replacement for `#[async_trait]` — it simply permits native `async fn` in traits that are used only through static dispatch. `Signer` must keep the `#[async_trait]` attribute because it is object-safe and stored as `Arc>` (see `VTableSigner::Inner::Native` in packages/rs-sdk-ffi/src/signer.rs). Add short comments above both the crate-level allow and the `Signer` trait declaration so future readers don't mistake the mix for inconsistency. Co-Authored-By: Claude Opus 4.6 --- packages/rs-dpp/src/identity/signer.rs | 3 +++ packages/rs-dpp/src/lib.rs | 2 ++ 2 files changed, 5 insertions(+) diff --git a/packages/rs-dpp/src/identity/signer.rs b/packages/rs-dpp/src/identity/signer.rs index 27079b3a58c..b162f6bbe3b 100644 --- a/packages/rs-dpp/src/identity/signer.rs +++ b/packages/rs-dpp/src/identity/signer.rs @@ -5,6 +5,9 @@ use platform_value::BinaryData; use std::fmt::Debug; use std::sync::Arc; +// `#[async_trait]` is required here (not native `async fn` in trait) because +// `Signer` is object-safe and stored as `Arc>` +// (see `VTableSigner::Inner::Native` in `packages/rs-sdk-ffi/src/signer.rs`). #[async_trait] pub trait Signer: Send + Sync + Debug { /// the public key bytes are only used to look up the private key diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index cd5397f944f..e9a68e5830a 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -4,6 +4,8 @@ //#![deny(missing_docs)] #![allow(dead_code)] #![allow(clippy::result_large_err)] +// Allowed for traits used via static dispatch only; dyn-safe async traits +// (e.g. `Signer`, stored as `Arc>`) still require `#[async_trait]`. #![allow(async_fn_in_trait)] extern crate core; From e3efb53185ebe24af75ab2fcaf2f0d35d7c1910a Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 24 Apr 2026 14:29:53 +0200 Subject: [PATCH 09/13] refactor(simple-signer): drop misleading network arg from new_from_slice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses @lklimek review (PR #3492, thread r3086203435). `SingleKeySigner::new_from_slice(&[u8], Network)` exposed a network parameter that only affected WIF encoding (via the wrapped `PrivateKey`), never signing itself — and the only caller in `rs-sdk-ffi` papered over this by hardcoding `Network::Mainnet` with a "network doesn't matter for signing" comment, leaning on internal `SingleKeySigner` behaviour. Drop the parameter: the constructor now tags the key with `Network::Mainnet` as an arbitrary placeholder and callers that care about WIF formatting use `from_hex` / `new` which still accept the network explicitly. `new_from_slice` has only a single caller in the workspace (`packages/rs-sdk-ffi/src/signer_simple.rs`), which also drops the now- unused `Network` import. Co-Authored-By: Claude Opus 4.6 --- packages/rs-sdk-ffi/src/signer_simple.rs | 4 +--- packages/simple-signer/src/single_key_signer.rs | 12 ++++++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/rs-sdk-ffi/src/signer_simple.rs b/packages/rs-sdk-ffi/src/signer_simple.rs index 888390dcb1e..751cdbc193b 100644 --- a/packages/rs-sdk-ffi/src/signer_simple.rs +++ b/packages/rs-sdk-ffi/src/signer_simple.rs @@ -3,7 +3,6 @@ use crate::signer::{signer_handle_from_single_key, VTableSigner}; use crate::types::SignerHandle; use crate::{DashSDKError, DashSDKErrorCode, DashSDKResult}; -use dash_sdk::dpp::dashcore::Network; use dash_sdk::dpp::identity::signer::Signer; use dash_sdk::dpp::identity::{IdentityPublicKey, KeyType, Purpose, SecurityLevel}; use simple_signer::SingleKeySigner; @@ -52,8 +51,7 @@ pub unsafe extern "C" fn dash_sdk_signer_create_from_private_key( let mut key_array = Zeroizing::new([0u8; 32]); key_array.copy_from_slice(key_slice); - // Network doesn't matter for signing purposes. - let signer = match SingleKeySigner::new_from_slice(key_array.as_slice(), Network::Mainnet) { + let signer = match SingleKeySigner::new_from_slice(key_array.as_slice()) { Ok(s) => s, Err(e) => { return DashSDKResult::error(DashSDKError::new(DashSDKErrorCode::InvalidParameter, e)); diff --git a/packages/simple-signer/src/single_key_signer.rs b/packages/simple-signer/src/single_key_signer.rs index 4abac3244a6..44e489a9e85 100644 --- a/packages/simple-signer/src/single_key_signer.rs +++ b/packages/simple-signer/src/single_key_signer.rs @@ -26,13 +26,21 @@ impl SingleKeySigner { Ok(Self { private_key }) } - pub fn new_from_slice(private_key_data: &[u8], network: Network) -> Result { + /// Create a new SingleKeySigner from raw 32 private-key bytes. + /// + /// The network is not part of this constructor because it only affects + /// WIF encoding — signing itself is network-independent. The wrapped + /// `PrivateKey` is tagged with `Network::Mainnet` as an arbitrary + /// placeholder; use `from_hex` (or another constructor that takes the + /// network explicitly) if WIF formatting on a non-mainnet network + /// matters. + pub fn new_from_slice(private_key_data: &[u8]) -> Result { if private_key_data.len() != 32 { return Err("Private key must be 32 bytes".to_string()); } let mut arr = [0u8; 32]; arr.copy_from_slice(private_key_data); - let private_key = PrivateKey::from_byte_array(&arr, network) + let private_key = PrivateKey::from_byte_array(&arr, Network::Mainnet) .map_err(|e| format!("Invalid private key: {}", e))?; Ok(Self { private_key }) } From b82b9fdd275aae54b1b4f7753ca0805183b8ee8b Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 24 Apr 2026 14:29:53 +0200 Subject: [PATCH 10/13] chore(macros): TODO for dash-async migration in #[stack_size] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses @lklimek review (PR #3492, thread r3085919989), deferred to issue #3535. The `#[stack_size]` proc-macro currently expands async function bodies to an inline `tokio::runtime::Builder::new_current_thread().build() .block_on(async move #block)` on a spawned thread — the same pattern PR #3490 / #3497 identified as runtime-within-runtime deadlock-prone. Adding a `dash-async` dependency to this macro crate is cross-cutting and out of scope for the async-signer PR, so the migration is tracked in issue #3535 with a `TODO(CMT-002)` marker at the call site. Issue #3535 body updated to include this site alongside the rs-sdk-ffi FFI bridging sites. Co-Authored-By: Claude Opus 4.6 --- packages/rs-dash-platform-macros/src/lib.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/rs-dash-platform-macros/src/lib.rs b/packages/rs-dash-platform-macros/src/lib.rs index dee6219fa4e..104d8041a8f 100644 --- a/packages/rs-dash-platform-macros/src/lib.rs +++ b/packages/rs-dash-platform-macros/src/lib.rs @@ -42,6 +42,15 @@ pub fn stack_size(attr: TokenStream, item: TokenStream) -> TokenStream { sig.asyncness = None; } + // TODO(CMT-002, issue #3535): migrate this inline + // `Builder::new_current_thread()...block_on(...)` pattern to + // `dash_async::block_on(...)` from `packages/rs-dash-async`. The + // workspace-canonical bridge is runtime-aware (handles no-runtime, + // current-thread, and multi-thread tokio flavors) and avoids the class + // of "runtime within runtime" deadlocks that PR #3490/#3497 addressed. + // Deferred from PR #3492 (async Signer) because this crate is used only + // as a test helper and the migration adds a cross-crate dependency that + // is out of scope for the signer-async change. let spawned_body = if is_async { quote! { builder From dcf80f67afc2836c723edfa6362a63fae6f15664 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 24 Apr 2026 14:29:53 +0200 Subject: [PATCH 11/13] test(dpp): await async build_shield_transition in upstream unit tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upstream PR #3506 landed three new unit tests in `shielded/builder/shield.rs` (test_build_shield_multiple_inputs_all_plumbed, test_build_shield_user_fee_increase_non_zero_succeeds, test_build_shield_memo_is_fully_plumbed) that call `build_shield_transition` synchronously and chain `.is_ok()` / `.err()` onto the returned `impl Future>`. After this branch made the builder async these sites fail to compile with E0599 on the opaque Future. Convert the three `#[test] fn` wrappers to `#[tokio::test] async fn` and add `.await` to the `build_shield_transition(...)` call in each (the two pre-existing async tests already did this correctly). `cargo test -p dpp --all-features shield` — 145 passed. Co-Authored-By: Claude Opus 4.6 --- .../rs-dpp/src/shielded/builder/shield.rs | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/packages/rs-dpp/src/shielded/builder/shield.rs b/packages/rs-dpp/src/shielded/builder/shield.rs index 11eac9550f4..e1197f18242 100644 --- a/packages/rs-dpp/src/shielded/builder/shield.rs +++ b/packages/rs-dpp/src/shielded/builder/shield.rs @@ -163,8 +163,8 @@ mod tests { // Extra coverage: error/edge paths not exercised above. // ------------------------------------------------------------ - #[test] - fn test_build_shield_multiple_inputs_all_plumbed() { + #[tokio::test] + async fn test_build_shield_multiple_inputs_all_plumbed() { // Multiple input addresses should each produce their own witness // signature and flow through the downstream Shield transition. let recipient = test_orchard_address(); @@ -187,7 +187,8 @@ mod tests { &TestProver, [0u8; 36], platform_version, - ); + ) + .await; assert!( result.is_ok(), "multi-input shield should succeed: {:?}", @@ -195,8 +196,8 @@ mod tests { ); } - #[test] - fn test_build_shield_user_fee_increase_non_zero_succeeds() { + #[tokio::test] + async fn test_build_shield_user_fee_increase_non_zero_succeeds() { // The user_fee_increase param just flows through as metadata. // A non-zero value should not fail the bundle build. let recipient = test_orchard_address(); @@ -217,7 +218,8 @@ mod tests { &TestProver, [9u8; 36], platform_version, - ); + ) + .await; assert!( result.is_ok(), "non-zero user_fee_increase should succeed: {:?}", @@ -225,8 +227,8 @@ mod tests { ); } - #[test] - fn test_build_shield_memo_is_fully_plumbed() { + #[tokio::test] + async fn test_build_shield_memo_is_fully_plumbed() { // Any 36-byte memo should be accepted — this test is a guard // against accidental panics/regressions in memo handling. let recipient = test_orchard_address(); @@ -251,7 +253,8 @@ mod tests { &TestProver, memo, platform_version, - ); + ) + .await; assert!( result.is_ok(), "varied memo should succeed: {:?}", From 416869514b50dacb70aaa241210fdc0bd8e8e418 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 24 Apr 2026 14:56:52 +0200 Subject: [PATCH 12/13] docs: trim verbose comments; document clippy::result_large_err allow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trim multi-line commentary added in this session down to 2-3 lines per block per coding-best-practices ("1 line is great, 2 lines are good, 3 is mediocre"). No behavioural change — comments only. Also add a one-block rationale on the (intentional, crate-wide) `#![allow(clippy::result_large_err)]` in rs-dpp — verified as still actively used: removing it produces 642 warnings on `ProtocolError`. `#![allow(async_fn_in_trait)]` kept for the same reason (31 warnings without it on new state-transition async method traits). Net: 46 insertions vs 120 deletions. Co-Authored-By: Claude Opus 4.6 --- packages/rs-dash-platform-macros/src/lib.rs | 12 +- packages/rs-dpp/src/identity/signer.rs | 5 +- packages/rs-dpp/src/lib.rs | 7 +- packages/rs-sdk-ffi/src/signer.rs | 109 +++++------------- packages/rs-sdk-ffi/src/signer_simple.rs | 25 ++-- .../simple-signer/src/single_key_signer.rs | 9 +- 6 files changed, 46 insertions(+), 121 deletions(-) diff --git a/packages/rs-dash-platform-macros/src/lib.rs b/packages/rs-dash-platform-macros/src/lib.rs index 104d8041a8f..7ee5f0623fc 100644 --- a/packages/rs-dash-platform-macros/src/lib.rs +++ b/packages/rs-dash-platform-macros/src/lib.rs @@ -42,15 +42,9 @@ pub fn stack_size(attr: TokenStream, item: TokenStream) -> TokenStream { sig.asyncness = None; } - // TODO(CMT-002, issue #3535): migrate this inline - // `Builder::new_current_thread()...block_on(...)` pattern to - // `dash_async::block_on(...)` from `packages/rs-dash-async`. The - // workspace-canonical bridge is runtime-aware (handles no-runtime, - // current-thread, and multi-thread tokio flavors) and avoids the class - // of "runtime within runtime" deadlocks that PR #3490/#3497 addressed. - // Deferred from PR #3492 (async Signer) because this crate is used only - // as a test helper and the migration adds a cross-crate dependency that - // is out of scope for the signer-async change. + // TODO(issue #3535): migrate to `dash_async::block_on` — the + // inline `Builder::new_current_thread().block_on(...)` pattern can + // deadlock inside a running runtime. let spawned_body = if is_async { quote! { builder diff --git a/packages/rs-dpp/src/identity/signer.rs b/packages/rs-dpp/src/identity/signer.rs index b162f6bbe3b..7e0b87a8abc 100644 --- a/packages/rs-dpp/src/identity/signer.rs +++ b/packages/rs-dpp/src/identity/signer.rs @@ -5,9 +5,8 @@ use platform_value::BinaryData; use std::fmt::Debug; use std::sync::Arc; -// `#[async_trait]` is required here (not native `async fn` in trait) because -// `Signer` is object-safe and stored as `Arc>` -// (see `VTableSigner::Inner::Native` in `packages/rs-sdk-ffi/src/signer.rs`). +// `#[async_trait]` is required: `Signer` is used dyn — stored as +// `Arc>` in `VTableSigner` (rs-sdk-ffi/src/signer.rs). #[async_trait] pub trait Signer: Send + Sync + Debug { /// the public key bytes are only used to look up the private key diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index e9a68e5830a..7a7c90a8080 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -3,9 +3,12 @@ #![forbid(unsafe_code)] //#![deny(missing_docs)] #![allow(dead_code)] +// `ProtocolError` is the Err type of hundreds of fns here; boxing it +// would add indirection to every return. Removing the allow needs a +// crate-wide error refactor. #![allow(clippy::result_large_err)] -// Allowed for traits used via static dispatch only; dyn-safe async traits -// (e.g. `Signer`, stored as `Arc>`) still require `#[async_trait]`. +// Covers static-dispatch async trait methods; dyn-safe traits like +// `Signer` still use `#[async_trait]` at their own declaration. #![allow(async_fn_in_trait)] extern crate core; diff --git a/packages/rs-sdk-ffi/src/signer.rs b/packages/rs-sdk-ffi/src/signer.rs index 4bd62f56e82..d1c2f74b8ac 100644 --- a/packages/rs-sdk-ffi/src/signer.rs +++ b/packages/rs-sdk-ffi/src/signer.rs @@ -146,24 +146,10 @@ pub type DestroyCallback = Option; /// back to the awaiting Rust `async fn sign`. type SignResult = Result, ProtocolError>; -/// Heap-allocated context handed to C as `completion_ctx`. -/// -/// Holds an `AtomicPtr` to the boxed `oneshot::Sender`. The first -/// completion call atomically swaps the pointer to null and claims ownership -/// of the sender; subsequent calls observe null and return without touching -/// freed memory, making duplicate or racing completion invocations a safe -/// no-op instead of a use-after-free. -/// -/// The `CompletionSlot` itself is intentionally never freed — it is leaked -/// once for the lifetime of the process per `sign_async` call. This is a -/// small, bounded leak (one `AtomicPtr`, 8 bytes on 64-bit) per sign, and is -/// the price for ABI-boundary safety: because we cannot enforce that C stops -/// calling `completion` after the Rust side has returned (or timed out), we -/// keep the slot alive so late or duplicate completions remain defined -/// behaviour. The `Sender` inside is freed on first completion or leaked on -/// timeout, matching the pre-existing `SIGN_ASYNC_COMPLETION_TIMEOUT` trade. +/// `completion_ctx` payload. First call swaps `sender` to null and sends; +/// duplicates see null and are no-ops. Slot is leaked per `sign_async` call +/// (small bounded cost) so late / duplicate FFI completions stay defined. struct CompletionSlot { - /// Null once the sender has been consumed (or never populated). sender: AtomicPtr>, } @@ -298,21 +284,13 @@ impl Signer for VTableSigner { bincode::encode_to_vec(identity_public_key, bincode::config::standard()) .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; - // Build a oneshot channel so the async fn can await the - // completion callback without blocking any thread. The sender - // lives inside a leaked `CompletionSlot` whose `AtomicPtr` - // enforces single-shot semantics on the C side: the first - // completion callback atomically claims the sender, any - // subsequent calls (duplicate delivery, retry races, - // double-invocation bugs) observe null and become a defined - // no-op — no use-after-free, no double drop. + // oneshot + leaked `CompletionSlot` — the slot's `AtomicPtr` + // makes duplicate C completions a no-op (see `CompletionSlot`). let (tx, rx) = oneshot::channel::(); - let tx_box: Box> = Box::new(tx); - let tx_ptr = Box::into_raw(tx_box); + let tx_ptr = Box::into_raw(Box::new(tx)); let slot = Box::new(CompletionSlot { sender: AtomicPtr::new(tx_ptr), }); - // Leaked on purpose — see `CompletionSlot` docs for rationale. let completion_ctx = Box::into_raw(slot) as *mut c_void; // SAFETY: vtable is non-null for the Callback variant by @@ -342,13 +320,8 @@ impl Signer for VTableSigner { Ok(Ok(Ok(sig))) => Ok(BinaryData::from(sig)), Ok(Ok(Err(e))) => Err(e), Ok(Err(_recv_err)) => { - // Sender was dropped without sending. With the - // `CompletionSlot` design the slot itself is - // intentionally leaked, so this branch is only - // reachable via exotic contract violations (e.g. a - // bridge that calls completion with a null signature, - // null error, and somehow drops the sender box). - // Surface as a recoverable protocol error. + // Sender dropped without sending — only reachable via + // exotic contract violations; surface as recoverable. Err(ProtocolError::Generic( "Signer completion channel dropped without a result; \ the FFI signer did not call its completion callback" @@ -356,12 +329,8 @@ impl Signer for VTableSigner { )) } Err(_elapsed) => { - // Timed out waiting for `completion`. The - // `CompletionSlot` (and the sender it still holds) - // remain alive so that a late or duplicate FFI - // invocation of the completion callback remains - // defined — it will swap the sender out and drop it, - // with the receiver already gone. + // Timeout: slot stays alive so a late duplicate FFI + // completion remains a defined no-op. Err(ProtocolError::Generic(format!( "Signer completion callback not invoked within {:?}; \ the FFI signer is unresponsive", @@ -447,31 +416,19 @@ impl<'a> Signer for VTableSignerRef<'a> { } /// Rust-side completion callback. Exported so the iOS side can call it via -/// the `SignCompletionCallback` function pointer that Rust hands to the C -/// `sign_async` callback. You do not need to look this symbol up — the -/// pointer is passed directly. +/// the `SignCompletionCallback` function pointer handed to `sign_async`. /// -/// # Single-shot guarantee -/// -/// The single-shot contract ("must be called exactly once") is enforced by a -/// runtime guard inside the `CompletionSlot`: the first invocation atomically -/// claims the boxed sender via an `AtomicPtr::swap`; any subsequent -/// invocations (duplicate delivery, retry races, buggy bridges) observe null -/// and return without touching freed memory. This makes double / triple / -/// spurious completion calls a safe no-op instead of a use-after-free. +/// Single-shot is enforced at runtime by `CompletionSlot`'s `AtomicPtr`: +/// first call claims the sender, duplicates are a safe no-op. /// /// # Safety -/// - `completion_ctx` must be the exact pointer that was passed to -/// `SignAsyncCallback`. Reusing another pointer, or a pointer from a -/// different process, is UB — but reusing the same valid pointer more than -/// once is defined: subsequent calls after the first are no-ops. -/// - If `error_message` is non-null it must point to a valid null-terminated -/// UTF-8 (or at least CStr-safe) string. The string is copied into an owned -/// `String` before this function returns, so the caller may free it -/// immediately afterwards. -/// - If `signature` is non-null it must point to at least `signature_len` -/// readable bytes. The bytes are copied into an owned `Vec` before this -/// function returns. +/// - `completion_ctx` must be the exact pointer passed to `SignAsyncCallback`. +/// Reusing another pointer is UB; reusing the same valid pointer is defined +/// (duplicates become no-ops). +/// - `error_message`, if non-null, must be a valid CStr-safe string; copied +/// before return. +/// - `signature`, if non-null, must point to `signature_len` readable bytes; +/// copied before return. #[no_mangle] pub unsafe extern "C" fn dash_sdk_sign_async_completion( completion_ctx: *mut c_void, @@ -485,22 +442,14 @@ pub unsafe extern "C" fn dash_sdk_sign_async_completion( return; } - // SAFETY: `completion_ctx` came from `Box::into_raw(Box::)` - // in `VTableSigner::sign` and the slot is intentionally never freed (see - // the `CompletionSlot` doc comment), so this reference is valid for any - // number of calls. + // SAFETY: slot is leaked per `sign_async` call — always valid. let slot = &*(completion_ctx as *const CompletionSlot); - // Atomically claim the sender. Only the first caller gets a non-null - // pointer; duplicate callers observe null and bail out without dropping - // the sender twice. + // Single-shot: only the first caller wins the sender; duplicates exit. let tx_ptr = slot.sender.swap(std::ptr::null_mut(), Ordering::AcqRel); if tx_ptr.is_null() { return; } - - // We are the sole owner of this sender now. Wrap it back into a Box so - // that it is dropped exactly once at the end of this call. let tx: Box> = Box::from_raw(tx_ptr); let result: SignResult = if !error_message.is_null() { @@ -776,9 +725,8 @@ mod tests { assert_eq!(sig.as_slice()[0], 0x55); } - /// Test sign callback that invokes the completion callback **twice** to - /// exercise the single-shot guard in `CompletionSlot`. The second call - /// must be a defined no-op (no use-after-free, no double-drop). + /// Calls completion three times to exercise the `CompletionSlot` + /// single-shot guard; second and third calls must be no-ops. unsafe extern "C" fn test_sign_async_double_complete( _signer: *const c_void, _key_bytes: *const u8, @@ -789,22 +737,17 @@ mod tests { completion: SignCompletionCallback, ) { let sig = [0x42u8; 64]; - // First call: legitimate success. completion(completion_ctx, sig.as_ptr(), sig.len(), std::ptr::null()); - // Second call with an error payload: must be observed as a no-op, - // NOT overwrite the first result and NOT crash. + // Duplicate error payload — must not overwrite the first result. let err_msg = c"duplicate completion — should be ignored"; completion(completion_ctx, std::ptr::null(), 0, err_msg.as_ptr()); - // Third call with yet another success: still a no-op. + // Duplicate success payload — still a no-op. let sig2 = [0x99u8; 64]; completion(completion_ctx, sig2.as_ptr(), sig2.len(), std::ptr::null()); } #[tokio::test] async fn completion_callback_duplicate_is_no_op() { - // Regression test for the one-shot guard: a buggy FFI signer that - // invokes completion more than once must NOT cause UAF, and the - // Rust side must observe only the first result. let signer = make_signer(test_sign_async_double_complete); let key = make_dummy_key(); diff --git a/packages/rs-sdk-ffi/src/signer_simple.rs b/packages/rs-sdk-ffi/src/signer_simple.rs index 751cdbc193b..d47aeeeb3f0 100644 --- a/packages/rs-sdk-ffi/src/signer_simple.rs +++ b/packages/rs-sdk-ffi/src/signer_simple.rs @@ -8,9 +8,8 @@ use dash_sdk::dpp::identity::{IdentityPublicKey, KeyType, Purpose, SecurityLevel use simple_signer::SingleKeySigner; use zeroize::Zeroizing; -// Use the workspace-canonical async-sync bridge from `dash-async` instead of -// spinning up an ad-hoc tokio runtime. `block_on` handles no-runtime, -// current-thread, and multi-thread flavors correctly (see PR #3497/#3432). +// Runtime-aware sync/async bridge (PR #3497/#3432); safer than an inline +// `Runtime::new().block_on(...)`. use dash_async::block_on; /// Create a signer from a private key. @@ -97,9 +96,7 @@ pub unsafe extern "C" fn dash_sdk_signer_sign( )); } - // Copy the input data into an owned buffer so the signing future has no - // borrowed references and can satisfy `dash_async::block_on`'s - // `Send + 'static` bounds. + // Own the data so the future satisfies `block_on`'s `Send + 'static`. let data_owned: Vec = std::slice::from_raw_parts(data, data_len).to_vec(); // Create a dummy identity public key for signing. SingleKeySigner @@ -118,18 +115,10 @@ pub unsafe extern "C" fn dash_sdk_signer_sign( }, ); - // Bridge the async Signer API into this synchronous FFI entry point via - // the workspace's canonical async-sync bridge (`dash_async::block_on`), - // which is runtime-aware and safe regardless of whether a tokio runtime - // is already active. `block_on` requires `Send + 'static` futures, so - // we hand ownership of the key and data buffer into the future and - // reconstruct the `&VTableSigner` from a pointer-sized integer inside - // the future body. - // - // SAFETY: `signer_handle` is a valid `*const VTableSigner` for the - // duration of this FFI call, and `block_on` blocks the caller until the - // future completes, so the underlying allocation cannot be freed by the - // C caller while we hold the reference. `VTableSigner` is `Send + Sync`. + // SAFETY: `signer_handle` is valid for the call; `block_on` blocks the + // caller so the allocation can't be freed mid-sign. `VTableSigner: Send + + // Sync`. The usize round-trip gives the `async move` a `Send + 'static` + // capture of the !Clone handle. let signer_addr = signer_handle as usize; let result = block_on(async move { let signer: &VTableSigner = unsafe { &*(signer_addr as *const VTableSigner) }; diff --git a/packages/simple-signer/src/single_key_signer.rs b/packages/simple-signer/src/single_key_signer.rs index 44e489a9e85..f7e51763b6b 100644 --- a/packages/simple-signer/src/single_key_signer.rs +++ b/packages/simple-signer/src/single_key_signer.rs @@ -28,12 +28,9 @@ impl SingleKeySigner { /// Create a new SingleKeySigner from raw 32 private-key bytes. /// - /// The network is not part of this constructor because it only affects - /// WIF encoding — signing itself is network-independent. The wrapped - /// `PrivateKey` is tagged with `Network::Mainnet` as an arbitrary - /// placeholder; use `from_hex` (or another constructor that takes the - /// network explicitly) if WIF formatting on a non-mainnet network - /// matters. + /// Network is not exposed because it only affects WIF encoding, not + /// signing. Use `from_hex` / `new` if you need a specific network for + /// WIF formatting. pub fn new_from_slice(private_key_data: &[u8]) -> Result { if private_key_data.len() != 32 { return Err("Private key must be 32 bytes".to_string()); From 2366428be4df57fac6c7400a97166841b2a690e3 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 24 Apr 2026 15:23:56 +0200 Subject: [PATCH 13/13] refactor(signer)!: thread network through SingleKeySigner::new_from_slice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously `SingleKeySigner::new_from_slice` hardcoded `Network::Mainnet` because its only caller — the FFI entry point — didn't expose a network parameter. Network only affects WIF encoding and address derivation (not signing), but the caller should still pass the correct value. - `simple-signer`: `new_from_slice(data, network)` now takes network. - `rs-sdk-ffi`: `dash_sdk_signer_create_from_private_key` gains a trailing `DashSDKNetwork` parameter, mapped to `dashcore::Network` via the same pattern as `sdk.rs` (ABI-breaking for C callers). - swift-sdk: `KeyManager` signer-creation APIs accept a `network` parameter (testnet default mirrors existing `SDK(network:)` usage); `Addresses` helpers pass `sdk.network` through; test targets updated. Co-Authored-By: Claude Opus 4.6 --- packages/rs-sdk-ffi/src/signer_simple.rs | 17 ++++- .../simple-signer/src/single_key_signer.rs | 28 ++++++-- .../SwiftDashSDK/Address/Addresses.swift | 6 +- .../SwiftDashSDK/KeyWallet/KeyManager.swift | 67 ++++++++++++++----- .../SwiftExampleAppTests/SDKMethodTests.swift | 3 +- .../SimpleTransitionTests.swift | 3 +- .../StateTransitionTests.swift | 15 +++-- 7 files changed, 105 insertions(+), 34 deletions(-) diff --git a/packages/rs-sdk-ffi/src/signer_simple.rs b/packages/rs-sdk-ffi/src/signer_simple.rs index d47aeeeb3f0..04e818bcd49 100644 --- a/packages/rs-sdk-ffi/src/signer_simple.rs +++ b/packages/rs-sdk-ffi/src/signer_simple.rs @@ -1,8 +1,9 @@ //! Simple private key signer for iOS FFI use crate::signer::{signer_handle_from_single_key, VTableSigner}; -use crate::types::SignerHandle; +use crate::types::{DashSDKNetwork, SignerHandle}; use crate::{DashSDKError, DashSDKErrorCode, DashSDKResult}; +use dash_sdk::dpp::dashcore::Network; use dash_sdk::dpp::identity::signer::Signer; use dash_sdk::dpp::identity::{IdentityPublicKey, KeyType, Purpose, SecurityLevel}; use simple_signer::SingleKeySigner; @@ -23,12 +24,15 @@ use dash_async::block_on; /// # Safety /// - `private_key` must be a valid pointer to at least 32 readable bytes. /// - The function reads exactly `private_key_len` bytes; it must be 32. +/// - `network` selects the network used for WIF encoding / address +/// derivation; it does not affect signing. /// - The returned handle inside DashSDKResult must be freed with /// `dash_sdk_signer_destroy`. #[no_mangle] pub unsafe extern "C" fn dash_sdk_signer_create_from_private_key( private_key: *const u8, private_key_len: usize, + network: DashSDKNetwork, ) -> DashSDKResult { if private_key.is_null() { return DashSDKResult::error(DashSDKError::new( @@ -44,13 +48,22 @@ pub unsafe extern "C" fn dash_sdk_signer_create_from_private_key( )); } + // Map the C-ABI network enum to dashcore::Network (mirrors sdk.rs). + let network = match network { + DashSDKNetwork::SDKMainnet => Network::Mainnet, + DashSDKNetwork::SDKTestnet => Network::Testnet, + DashSDKNetwork::SDKRegtest => Network::Regtest, + DashSDKNetwork::SDKDevnet => Network::Devnet, + DashSDKNetwork::SDKLocal => Network::Regtest, + }; + // Copy into a zeroizing buffer so the key material doesn't linger on // the stack after we hand it off to SingleKeySigner. let key_slice = std::slice::from_raw_parts(private_key, 32); let mut key_array = Zeroizing::new([0u8; 32]); key_array.copy_from_slice(key_slice); - let signer = match SingleKeySigner::new_from_slice(key_array.as_slice()) { + let signer = match SingleKeySigner::new_from_slice(key_array.as_slice(), network) { Ok(s) => s, Err(e) => { return DashSDKResult::error(DashSDKError::new(DashSDKErrorCode::InvalidParameter, e)); diff --git a/packages/simple-signer/src/single_key_signer.rs b/packages/simple-signer/src/single_key_signer.rs index f7e51763b6b..c42a431f4e5 100644 --- a/packages/simple-signer/src/single_key_signer.rs +++ b/packages/simple-signer/src/single_key_signer.rs @@ -28,16 +28,15 @@ impl SingleKeySigner { /// Create a new SingleKeySigner from raw 32 private-key bytes. /// - /// Network is not exposed because it only affects WIF encoding, not - /// signing. Use `from_hex` / `new` if you need a specific network for - /// WIF formatting. - pub fn new_from_slice(private_key_data: &[u8]) -> Result { + /// `network` controls WIF encoding and address derivation; it does not + /// affect signing itself. + pub fn new_from_slice(private_key_data: &[u8], network: Network) -> Result { if private_key_data.len() != 32 { return Err("Private key must be 32 bytes".to_string()); } let mut arr = [0u8; 32]; arr.copy_from_slice(private_key_data); - let private_key = PrivateKey::from_byte_array(&arr, Network::Mainnet) + let private_key = PrivateKey::from_byte_array(&arr, network) .map_err(|e| format!("Invalid private key: {}", e))?; Ok(Self { private_key }) } @@ -203,6 +202,25 @@ mod tests { Ok(()) } + #[test] + fn test_single_key_signer_from_slice_threads_network() -> Result<(), String> { + let bytes = [0x03u8; 32]; + let testnet_signer = SingleKeySigner::new_from_slice(&bytes, Network::Testnet) + .map_err(|e| format!("signer init failed: {}", e))?; + assert!(testnet_signer.private_key().to_wif().starts_with('c')); + + let mainnet_signer = SingleKeySigner::new_from_slice(&bytes, Network::Mainnet) + .map_err(|e| format!("signer init failed: {}", e))?; + assert!(!mainnet_signer.private_key().to_wif().starts_with('c')); + Ok(()) + } + + #[test] + fn test_single_key_signer_from_slice_rejects_wrong_length() { + let bytes = [0x01u8; 16]; + assert!(SingleKeySigner::new_from_slice(&bytes, Network::Testnet).is_err()); + } + #[test] fn test_single_key_signer_auto_detect() -> Result<(), String> { // Test hex detection diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/Address/Addresses.swift b/packages/swift-sdk/Sources/SwiftDashSDK/Address/Addresses.swift index 22971d7dd50..c88ec266f91 100644 --- a/packages/swift-sdk/Sources/SwiftDashSDK/Address/Addresses.swift +++ b/packages/swift-sdk/Sources/SwiftDashSDK/Address/Addresses.swift @@ -1440,7 +1440,8 @@ public class Addresses: @unchecked Sendable { let signerResult = identityPrivateKey.withUnsafeBytes { keyBytes in dash_sdk_signer_create_from_private_key( keyBytes.bindMemory(to: UInt8.self).baseAddress!, - UInt(identityPrivateKey.count) + UInt(identityPrivateKey.count), + sdk.network ) } @@ -1593,7 +1594,8 @@ public class Addresses: @unchecked Sendable { let signerResult = identityPrivateKey.withUnsafeBytes { keyBytes in dash_sdk_signer_create_from_private_key( keyBytes.bindMemory(to: UInt8.self).baseAddress!, - UInt(identityPrivateKey.count) + UInt(identityPrivateKey.count), + sdk.network ) } diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/KeyManager.swift b/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/KeyManager.swift index 341bee03d91..667b67c7e7e 100644 --- a/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/KeyManager.swift +++ b/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/KeyManager.swift @@ -236,11 +236,17 @@ public final class KeyManager: Sendable { // MARK: - Signer Creation /// Create a signer from private key data - /// - Parameter privateKeyData: The private key data (32 bytes) + /// - Parameters: + /// - privateKeyData: The private key data (32 bytes) + /// - network: The network to associate with the key (affects WIF / address + /// derivation only; does not affect signing). Defaults to testnet. /// - Returns: An OpaquePointer to the signer handle /// - Throws: `KeyManagerError.signerCreationFailed` if signer creation fails /// - Note: The returned signer must be destroyed with `destroySigner(_:)` when done - public func createSigner(from privateKeyData: Data) throws -> OpaquePointer { + public func createSigner( + from privateKeyData: Data, + network: Network = DashSDKNetwork(rawValue: 1) + ) throws -> OpaquePointer { // Validate private key length guard privateKeyData.count == 32 else { throw KeyManagerError.invalidKeyFormat("Private key must be 32 bytes, got \(privateKeyData.count)") @@ -249,7 +255,8 @@ public final class KeyManager: Sendable { let signerResult = privateKeyData.withUnsafeBytes { keyBytes in dash_sdk_signer_create_from_private_key( keyBytes.bindMemory(to: UInt8.self).baseAddress!, - UInt(privateKeyData.count) + UInt(privateKeyData.count), + network ) } @@ -271,48 +278,63 @@ public final class KeyManager: Sendable { /// - Parameters: /// - identity: The identity /// - keyIndex: The key index to create a signer for + /// - network: The network to associate with the key (default: testnet) /// - Returns: An OpaquePointer to the signer handle /// - Throws: `KeyManagerError.privateKeyNotFound` if private key is not available /// - Throws: `KeyManagerError.signerCreationFailed` if signer creation fails /// - Note: The returned signer must be destroyed with `destroySigner(_:)` when done /// - Note: This method must be called from a MainActor context @MainActor - public func createSigner(for identity: DPPIdentity, keyIndex: KeyID) throws -> OpaquePointer { + public func createSigner( + for identity: DPPIdentity, + keyIndex: KeyID, + network: Network = DashSDKNetwork(rawValue: 1) + ) throws -> OpaquePointer { let privateKeyData = try getPrivateKey(for: identity, keyIndex: keyIndex) - return try createSigner(from: privateKeyData) + return try createSigner(from: privateKeyData, network: network) } /// Create a transfer signer for an identity (convenience method) - /// - Parameter identity: The identity to create a transfer signer for + /// - Parameters: + /// - identity: The identity to create a transfer signer for + /// - network: The network to associate with the key (default: testnet) /// - Returns: A tuple containing the transfer key and signer handle /// - Throws: `KeyManagerError.noSuitableKey` if no transfer key with private key is found /// - Throws: `KeyManagerError.signerCreationFailed` if signer creation fails /// - Note: The returned signer must be destroyed with `destroySigner(_:)` when done /// - Note: This method must be called from a MainActor context @MainActor - public func createTransferSigner(for identity: DPPIdentity) throws -> (key: IdentityPublicKey, signer: OpaquePointer) { + public func createTransferSigner( + for identity: DPPIdentity, + network: Network = DashSDKNetwork(rawValue: 1) + ) throws -> (key: IdentityPublicKey, signer: OpaquePointer) { guard let transferKey = getTransferKey(for: identity) else { throw KeyManagerError.noSuitableKey("No transfer key found for identity") } - let signer = try createSigner(for: identity, keyIndex: transferKey.id) + let signer = try createSigner(for: identity, keyIndex: transferKey.id, network: network) return (transferKey, signer) } /// Create an authentication signer for an identity (convenience method) - /// - Parameter identity: The identity to create an authentication signer for + /// - Parameters: + /// - identity: The identity to create an authentication signer for + /// - network: The network to associate with the key (default: testnet) /// - Returns: A tuple containing the authentication key and signer handle /// - Throws: `KeyManagerError.noSuitableKey` if no authentication key with private key is found /// - Throws: `KeyManagerError.signerCreationFailed` if signer creation fails /// - Note: The returned signer must be destroyed with `destroySigner(_:)` when done /// - Note: This method must be called from a MainActor context @MainActor - public func createAuthenticationSigner(for identity: DPPIdentity) throws -> (key: IdentityPublicKey, signer: OpaquePointer) { + public func createAuthenticationSigner( + for identity: DPPIdentity, + network: Network = DashSDKNetwork(rawValue: 1) + ) throws -> (key: IdentityPublicKey, signer: OpaquePointer) { guard let authKey = getAuthenticationKey(for: identity) else { throw KeyManagerError.noSuitableKey("No authentication key found for identity") } - let signer = try createSigner(for: identity, keyIndex: authKey.id) + let signer = try createSigner(for: identity, keyIndex: authKey.id, network: network) return (authKey, signer) } @@ -332,7 +354,8 @@ public final class KeyManager: Sendable { for identity: DPPIdentity, purpose: KeyPurpose? = nil, minimumSecurityLevel: SecurityLevel? = nil, - preferCritical: Bool = true + preferCritical: Bool = true, + network: Network = DashSDKNetwork(rawValue: 1) ) throws -> (key: IdentityPublicKey, signer: OpaquePointer) { guard let (key, privateKey) = findKeyWithPrivateKey( for: identity, @@ -345,7 +368,7 @@ public final class KeyManager: Sendable { throw KeyManagerError.noSuitableKey("No suitable key\(purposeDesc)\(securityDesc) with available private key found") } - let signer = try createSigner(from: privateKey) + let signer = try createSigner(from: privateKey, network: network) return (key, signer) } @@ -431,29 +454,37 @@ extension KeyManager { @MainActor public func createDocumentSigner( for identity: DPPIdentity, - minimumSecurityLevel: SecurityLevel = .high + minimumSecurityLevel: SecurityLevel = .high, + network: Network = DashSDKNetwork(rawValue: 1) ) throws -> (key: IdentityPublicKey, signer: OpaquePointer) { return try createSignerForKey( for: identity, purpose: .authentication, minimumSecurityLevel: minimumSecurityLevel, - preferCritical: true + preferCritical: true, + network: network ) } /// Create a signer for contract operations (requires CRITICAL + AUTHENTICATION) - /// - Parameter identity: The identity to create a signer for + /// - Parameters: + /// - identity: The identity to create a signer for + /// - network: The network to associate with the key (default: testnet) /// - Returns: A tuple containing the selected key and signer handle /// - Throws: `KeyManagerError.noSuitableKey` if no suitable key with private key is found /// - Note: The returned signer must be destroyed with `destroySigner(_:)` when done /// - Note: This method must be called from a MainActor context @MainActor - public func createContractSigner(for identity: DPPIdentity) throws -> (key: IdentityPublicKey, signer: OpaquePointer) { + public func createContractSigner( + for identity: DPPIdentity, + network: Network = DashSDKNetwork(rawValue: 1) + ) throws -> (key: IdentityPublicKey, signer: OpaquePointer) { return try createSignerForKey( for: identity, purpose: .authentication, minimumSecurityLevel: .critical, - preferCritical: true + preferCritical: true, + network: network ) } } diff --git a/packages/swift-sdk/SwiftExampleApp/SwiftExampleAppTests/SDKMethodTests.swift b/packages/swift-sdk/SwiftExampleApp/SwiftExampleAppTests/SDKMethodTests.swift index aa9f0e45438..9255e39a9b8 100644 --- a/packages/swift-sdk/SwiftExampleApp/SwiftExampleAppTests/SDKMethodTests.swift +++ b/packages/swift-sdk/SwiftExampleApp/SwiftExampleAppTests/SDKMethodTests.swift @@ -60,7 +60,8 @@ final class SDKMethodTests: XCTestCase { let signerResult = key.withUnsafeBytes { keyBytes in dash_sdk_signer_create_from_private_key( keyBytes.bindMemory(to: UInt8.self).baseAddress!, - UInt(key.count) + UInt(key.count), + DashSDKNetwork(rawValue: 1) ) } diff --git a/packages/swift-sdk/SwiftExampleApp/SwiftExampleAppTests/SimpleTransitionTests.swift b/packages/swift-sdk/SwiftExampleApp/SwiftExampleAppTests/SimpleTransitionTests.swift index 1bf6b0887c3..2aa67278328 100644 --- a/packages/swift-sdk/SwiftExampleApp/SwiftExampleAppTests/SimpleTransitionTests.swift +++ b/packages/swift-sdk/SwiftExampleApp/SwiftExampleAppTests/SimpleTransitionTests.swift @@ -84,7 +84,8 @@ final class SimpleTransitionTests: XCTestCase { let signerResult = key3Private.withUnsafeBytes { keyBytes in dash_sdk_signer_create_from_private_key( keyBytes.bindMemory(to: UInt8.self).baseAddress!, - UInt(key3Private.count) + UInt(key3Private.count), + DashSDKNetwork(rawValue: 1) ) } diff --git a/packages/swift-sdk/SwiftExampleApp/SwiftExampleAppTests/StateTransitionTests.swift b/packages/swift-sdk/SwiftExampleApp/SwiftExampleAppTests/StateTransitionTests.swift index fec70c25a2f..4c22c4c10d8 100644 --- a/packages/swift-sdk/SwiftExampleApp/SwiftExampleAppTests/StateTransitionTests.swift +++ b/packages/swift-sdk/SwiftExampleApp/SwiftExampleAppTests/StateTransitionTests.swift @@ -125,7 +125,8 @@ final class StateTransitionTests: XCTestCase { let signerResult = key3Private.withUnsafeBytes { keyBytes in dash_sdk_signer_create_from_private_key( keyBytes.bindMemory(to: UInt8.self).baseAddress!, - UInt(key3Private.count) + UInt(key3Private.count), + DashSDKNetwork(rawValue: 1) ) } @@ -266,7 +267,8 @@ final class StateTransitionTests: XCTestCase { let signerResult = key3Private.withUnsafeBytes { keyBytes in dash_sdk_signer_create_from_private_key( keyBytes.bindMemory(to: UInt8.self).baseAddress!, - UInt(key3Private.count) + UInt(key3Private.count), + DashSDKNetwork(rawValue: 1) ) } @@ -358,7 +360,8 @@ final class StateTransitionTests: XCTestCase { let signerResult = key3Private.withUnsafeBytes { keyBytes in dash_sdk_signer_create_from_private_key( keyBytes.bindMemory(to: UInt8.self).baseAddress!, - UInt(key3Private.count) + UInt(key3Private.count), + DashSDKNetwork(rawValue: 1) ) } @@ -445,7 +448,8 @@ final class StateTransitionTests: XCTestCase { let signerResult = key3Private.withUnsafeBytes { keyBytes in dash_sdk_signer_create_from_private_key( keyBytes.bindMemory(to: UInt8.self).baseAddress!, - UInt(key3Private.count) + UInt(key3Private.count), + DashSDKNetwork(rawValue: 1) ) } @@ -522,7 +526,8 @@ final class StateTransitionTests: XCTestCase { let signerResult = key3Private.withUnsafeBytes { keyBytes in dash_sdk_signer_create_from_private_key( keyBytes.bindMemory(to: UInt8.self).baseAddress!, - UInt(key3Private.count) + UInt(key3Private.count), + DashSDKNetwork(rawValue: 1) ) }