diff --git a/.github/actions/deps-install/action.yml b/.github/actions/deps-install/action.yml
index 25ed15bf50..02b0ffbec4 100644
--- a/.github/actions/deps-install/action.yml
+++ b/.github/actions/deps-install/action.yml
@@ -12,33 +12,54 @@ inputs:
runs:
using: 'composite'
steps:
+ - name: Download protoc (Linux)
+ if: runner.os == 'Linux' && contains(inputs.deps, 'protoc')
+ uses: ./.github/actions/download-and-verify
+ with:
+ url: "https://github.com/protocolbuffers/protobuf/releases/download/v25.3/protoc-25.3-linux-x86_64.zip"
+ output_file: "protoc-25.3-linux-x86_64.zip"
+ checksum: "f853e691868d0557425ea290bf7ba6384eef2fa9b04c323afab49a770ba9da80"
+
- name: Install protoc (Linux)
env:
TMP: ${{ inputs.temp || runner.temp }}
if: runner.os == 'Linux' && contains(inputs.deps, 'protoc')
shell: bash
run: |
- wget https://github.com/protocolbuffers/protobuf/releases/download/v25.3/protoc-25.3-linux-x86_64.zip
- unzip protoc-25.3-linux-x86_64 -d "$TMP/protobuf"
+ unzip protoc-25.3-linux-x86_64.zip -d "$TMP/protobuf"
echo "$TMP/protobuf/bin" >> $GITHUB_PATH
+ - name: Download protoc (MacOS)
+ if: runner.os == 'macOS' && contains(inputs.deps, 'protoc')
+ uses: ./.github/actions/download-and-verify
+ with:
+ url: "https://github.com/protocolbuffers/protobuf/releases/download/v25.3/protoc-25.3-osx-x86_64.zip"
+ output_file: "protoc-25.3-osx-x86_64.zip"
+ checksum: "247e003b8e115405172eacc50bd19825209d85940728e766f0848eee7c80e2a1"
+
- name: Install protoc (MacOS)
env:
TMP: ${{ inputs.temp || runner.temp }}
if: runner.os == 'macOS' && contains(inputs.deps, 'protoc')
shell: bash
run: |
- wget https://github.com/protocolbuffers/protobuf/releases/download/v25.3/protoc-25.3-osx-x86_64.zip
unzip protoc-25.3-osx-x86_64.zip -d "$TMP/protobuf"
echo "$TMP/protobuf/bin" >> $GITHUB_PATH
+
+ - name: Download protoc (Windows)
+ uses: ./.github/actions/download-and-verify
+ with:
+ url: "https://github.com/protocolbuffers/protobuf/releases/download/v25.3/protoc-25.3-win64.zip"
+ output_file: "protoc-25.3-win64.zip"
+ checksum: "d6b336b852726364313330631656b7f395dde5b1141b169f5c4b8d43cdf01482"
+
- name: Install protoc (Windows)
env:
TMP: ${{ inputs.temp || runner.temp }}
if: runner.os == 'Windows' && contains(inputs.deps, 'protoc')
shell: powershell
run: |
- Invoke-WebRequest -Uri https://github.com/protocolbuffers/protobuf/releases/download/v25.3/protoc-25.3-win64.zip -OutFile protoc-25.3-win64.zip
7z x protoc-25.3-win64.zip -o"$TMP\protobuf"
echo "$TMP\protobuf\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
diff --git a/.github/actions/download-and-verify/action.yml b/.github/actions/download-and-verify/action.yml
new file mode 100644
index 0000000000..198601f486
--- /dev/null
+++ b/.github/actions/download-and-verify/action.yml
@@ -0,0 +1,46 @@
+name: "Download and verify remote files"
+
+runs:
+ using: "composite"
+ steps:
+ - name: Download (Unix)
+ if: runner.os != 'Windows'
+ shell: bash
+ run: curl -L -o ${{ inputs.output_file }} ${{ inputs.url }}
+
+ - name: Download (Windows)
+ if: runner.os == 'Windows'
+ shell: powershell
+ run: Invoke-WebRequest -Uri ${{ inputs.url }} -OutFile ${{ inputs.output_file }}
+
+ - name: Verify (Unix)
+ if: runner.os != 'Windows'
+ shell: bash
+ run: |
+ if [[ "$RUNNER_OS" == "macOS" ]]; then
+ echo "${{ inputs.checksum }} *${{ inputs.output_file }}" | shasum -a 256 -c
+ else
+ echo "${{ inputs.checksum }} ${{ inputs.output_file }}" | sha256sum -c
+ fi
+
+ - name: Verify (Windows)
+ if: runner.os == 'Windows'
+ shell: powershell
+ run: |
+ $expectedChecksum = "${{ inputs.checksum }}"
+ $actualChecksum = (Get-FileHash -Path "${{ inputs.output_file }}" -Algorithm SHA256).Hash
+ if ($expectedChecksum -ne $actualChecksum) {
+ Write-Output "Checksum did not match! Expected: $expectedChecksum, Found: $actualChecksum"
+ exit 1
+ }
+
+inputs:
+ url:
+ description: "URL of the remote file."
+ required: true
+ output_file:
+ description: "Output path."
+ required: true
+ checksum:
+ description: "Expected checksum of the downloaded file."
+ required: true
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index a9790f9b13..12a60bbc3c 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -122,7 +122,7 @@ jobs:
- name: Test
run: |
- wget -O - https://raw.githubusercontent.com/KomodoPlatform/komodo/master/zcutil/fetch-params-alt.sh | bash
+ wget -O - https://raw.githubusercontent.com/KomodoPlatform/komodo/0adeeabdd484ef40539d1275c6a765f5c530ea79/zcutil/fetch-params-alt.sh | bash
cargo test --test 'mm2_tests_main' --no-fail-fast
mac-x86-64-kdf-integration:
@@ -154,7 +154,7 @@ jobs:
- name: Test
run: |
- wget -O - https://raw.githubusercontent.com/KomodoPlatform/komodo/master/zcutil/fetch-params-alt.sh | bash
+ wget -O - https://raw.githubusercontent.com/KomodoPlatform/komodo/0adeeabdd484ef40539d1275c6a765f5c530ea79/zcutil/fetch-params-alt.sh | bash
cargo test --test 'mm2_tests_main' --no-fail-fast
win-x86-64-kdf-integration:
@@ -181,10 +181,16 @@ jobs:
- name: Cargo cache
uses: ./.github/actions/cargo-cache
+ - name: Download wget64
+ uses: ./.github/actions/download-and-verify
+ with:
+ url: "https://github.com/KomodoPlatform/komodo/raw/d456be35acd1f8584e1e4f971aea27bd0644d5c5/zcutil/wget64.exe"
+ output_file: "/wget64.exe"
+ checksum: "d80719431dc22b0e4a070f61fab982b113a4ed9a6d4cf25e64b5be390dcadb94"
+
- name: Test
run: |
- Invoke-WebRequest -Uri https://github.com/KomodoPlatform/komodo/raw/d456be35acd1f8584e1e4f971aea27bd0644d5c5/zcutil/wget64.exe -OutFile \wget64.exe
- Invoke-WebRequest -Uri https://raw.githubusercontent.com/KomodoPlatform/komodo/master/zcutil/fetch-params-alt.bat -OutFile \cmd.bat && \cmd.bat
+ Invoke-WebRequest -Uri https://raw.githubusercontent.com/KomodoPlatform/komodo/0adeeabdd484ef40539d1275c6a765f5c530ea79/zcutil/fetch-params-alt.bat -OutFile \cmd.bat && \cmd.bat
cargo test --test 'mm2_tests_main' --no-fail-fast
docker-tests:
@@ -213,7 +219,7 @@ jobs:
- name: Test
run: |
- wget -O - https://raw.githubusercontent.com/KomodoPlatform/komodo/v0.8.1/zcutil/fetch-params-alt.sh | bash
+ wget -O - https://raw.githubusercontent.com/KomodoPlatform/komodo/v0.8.1//zcutil/fetch-params-alt.sh | bash
cargo test --test 'docker_tests_main' --features run-docker-tests --no-fail-fast
wasm:
@@ -241,11 +247,17 @@ jobs:
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
+ - name: Download geckodriver
+ uses: ./.github/actions/download-and-verify
+ with:
+ url: "https://github.com/mozilla/geckodriver/releases/download/v0.32.2/geckodriver-v0.32.2-linux64.tar.gz"
+ output_file: "geckodriver-v0.32.2-linux64.tar.gz"
+ checksum: "1eab226bf009599f5aa1d77d9ed4c374e10a03fd848b500be1b32cefd2cbec64"
+
- name: Install firefox and geckodriver
run: |
sudo apt-get update -y
sudo apt-get install -y firefox
- wget https://github.com/mozilla/geckodriver/releases/download/v0.32.2/geckodriver-v0.32.2-linux64.tar.gz
sudo tar -xzvf geckodriver-v0.32.2-linux64.tar.gz -C /bin
sudo chmod +x /bin/geckodriver
diff --git a/Cargo.toml b/Cargo.toml
index deec6b843f..f6f7f67e61 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -59,7 +59,7 @@ opt-level = 3
strip = true
codegen-units = 1
# lto = true
-panic = "abort"
+panic = 'unwind'
[profile.dev]
opt-level = 0
diff --git a/README.md b/README.md
index 0d91d3cded..441c23ba8c 100755
--- a/README.md
+++ b/README.md
@@ -48,7 +48,7 @@
## What is the Komodo DeFi Framework?
-The Komodo DeFi Framework is open-source [atomic-swap](https://komodoplatform.com/en/academy/atomic-swaps/) software for seamless, decentralised, peer to peer trading between almost every blockchain asset in existence. This software works with propagation of orderbooks and swap states through the [libp2p](https://libp2p.io/) protocol and uses [Hash Time Lock Contracts (HTLCs)](https://en.bitcoinwiki.org/wiki/Hashed_Timelock_Contracts) for ensuring that the two parties in a swap either mutually complete a trade, or funds return to thier original owner.
+The Komodo DeFi Framework is open-source [atomic-swap](https://komodoplatform.com/en/academy/atomic-swaps/) software for seamless, decentralized, peer to peer trading between almost every blockchain asset in existence. This software works with propagation of orderbooks and swap states through the [libp2p](https://libp2p.io/) protocol and uses [Hash Time Lock Contracts (HTLCs)](https://en.bitcoinwiki.org/wiki/Hashed_Timelock_Contracts) for ensuring that the two parties in a swap either mutually complete a trade, or funds return to thier original owner.
There is no 3rd party intermediary, no proxy tokens, and at all times users remain in sole possession of their private keys.
@@ -172,7 +172,7 @@ Refer to the [Komodo Developer Docs](https://developers.komodoplatform.com/basic
## Project structure
-[mm2src](mm2src) - Rust code, contains some parts ported from C `as is` (e.g. `lp_ordermatch`) to reach the most essential/error prone code. Some other modules/crates are reimplemented from scratch.
+[mm2src](mm2src) - Rust code, contains some parts ported from C `as is` (e.g. `lp_ordermatch`) to reach the most essential/error-prone code. Some other modules/crates are reimplemented from scratch.
## Additional docs for developers
@@ -185,12 +185,13 @@ Refer to the [Komodo Developer Docs](https://developers.komodoplatform.com/basic
## Disclaimer
-This repository contains the `work in progress` code of the brand new Komodo DeFi Framework (kdf) built mainly on Rust.
-The current state can be considered as a alpha version.
+This repository contains the `work in progress` code of the brand-new Komodo DeFi Framework (kdf) built mainly on Rust.
+The current state can be considered as an alpha version.
**WARNING: Use with test coins only or with assets which value does not exceed an amount you are willing to lose. This is alpha stage software! **
## Help and troubleshooting
-If you have any question/want to report a bug/suggest an improvement feel free to [open an issue](https://github.com/artemii235/SuperNET/issues/new) or join the [Komodo Platform Discord](https://discord.gg/PGxVm2y) `dev-marketmaker` channel.
+If you have any question/want to report a bug/suggest an improvement feel free to [open an issue](https://github.com/KomodoPlatform/komodo-defi-framework/issues/new/choose) or join the [Komodo Platform Discord](https://discord.gg/PGxVm2y) `dev-marketmaker` channel.
+
diff --git a/clippy.toml b/clippy.toml
new file mode 100644
index 0000000000..068d7e886b
--- /dev/null
+++ b/clippy.toml
@@ -0,0 +1,4 @@
+[[disallowed-methods]]
+path = "futures::future::Future::wait"
+replacement = "common::block_on_f01"
+reason = "Use the default KDF async executor."
\ No newline at end of file
diff --git a/mm2src/coins/eth/eth_tests.rs b/mm2src/coins/eth/eth_tests.rs
index 9332594931..03705ff4ca 100644
--- a/mm2src/coins/eth/eth_tests.rs
+++ b/mm2src/coins/eth/eth_tests.rs
@@ -1,27 +1,31 @@
use super::*;
-use crate::eth::for_tests::{eth_coin_for_test, eth_coin_from_keypair};
-use crate::{DexFee, IguanaPrivKey};
-use common::{block_on, now_sec};
-#[cfg(not(target_arch = "wasm32"))]
-use ethkey::{Generator, Random};
+use crate::IguanaPrivKey;
+use common::{block_on, block_on_f01};
use mm2_core::mm_ctx::MmCtxBuilder;
-use mm2_test_helpers::for_tests::{ETH_MAINNET_CHAIN_ID, ETH_MAINNET_NODE, ETH_SEPOLIA_CHAIN_ID, ETH_SEPOLIA_NODES,
+
+cfg_native!(
+ use crate::eth::for_tests::{eth_coin_for_test, eth_coin_from_keypair};
+ use crate::DexFee;
+
+ use common::now_sec;
+ use ethkey::{Generator, Random};
+ use mm2_test_helpers::for_tests::{ETH_MAINNET_CHAIN_ID, ETH_MAINNET_NODE, ETH_SEPOLIA_CHAIN_ID, ETH_SEPOLIA_NODES,
ETH_SEPOLIA_TOKEN_CONTRACT};
-use mocktopus::mocking::*;
-
-/// The gas price for the tests
-const GAS_PRICE: u64 = 50_000_000_000;
-// `GAS_PRICE` increased by 3%
-const GAS_PRICE_APPROXIMATION_ON_START_SWAP: u64 = 51_500_000_000;
-// `GAS_PRICE` increased by 5%
-const GAS_PRICE_APPROXIMATION_ON_ORDER_ISSUE: u64 = 52_500_000_000;
-// `GAS_PRICE` increased by 7%
-const GAS_PRICE_APPROXIMATION_ON_TRADE_PREIMAGE: u64 = 53_500_000_000;
+ use mocktopus::mocking::*;
+
+ /// The gas price for the tests
+ const GAS_PRICE: u64 = 50_000_000_000;
+ /// `GAS_PRICE` increased by 3%
+ const GAS_PRICE_APPROXIMATION_ON_START_SWAP: u64 = 51_500_000_000;
+ /// `GAS_PRICE` increased by 5%
+ const GAS_PRICE_APPROXIMATION_ON_ORDER_ISSUE: u64 = 52_500_000_000;
+ /// `GAS_PRICE` increased by 7%
+ const GAS_PRICE_APPROXIMATION_ON_TRADE_PREIMAGE: u64 = 53_500_000_000;
+);
+
// old way to add some extra gas to the returned value from gas station (non-existent now), still used in tests
const GAS_PRICE_PERCENT: u64 = 10;
-const TAKER_PAYMENT_SPEND_SEARCH_INTERVAL: f64 = 1.;
-
fn check_sum(addr: &str, expected: &str) {
let actual = checksum_address(addr);
assert_eq!(expected, actual);
@@ -154,8 +158,11 @@ fn test_wei_from_big_decimal() {
assert_eq!(expected_wei, wei);
}
+#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_wait_for_payment_spend_timeout() {
+ const TAKER_PAYMENT_SPEND_SEARCH_INTERVAL: f64 = 1.;
+
EthCoin::spend_events.mock_safe(|_, _, _, _| MockResult::Return(Box::new(futures01::future::ok(vec![]))));
EthCoin::current_block.mock_safe(|_| MockResult::Return(Box::new(futures01::future::ok(900))));
@@ -184,18 +191,16 @@ fn test_wait_for_payment_spend_timeout() {
184, 42, 106,
];
- assert!(coin
- .wait_for_htlc_tx_spend(WaitForHTLCTxSpendArgs {
- tx_bytes: &tx_bytes,
- secret_hash: &[],
- wait_until,
- from_block,
- swap_contract_address: &coin.swap_contract_address(),
- check_every: TAKER_PAYMENT_SPEND_SEARCH_INTERVAL,
- watcher_reward: false
- })
- .wait()
- .is_err());
+ assert!(block_on_f01(coin.wait_for_htlc_tx_spend(WaitForHTLCTxSpendArgs {
+ tx_bytes: &tx_bytes,
+ secret_hash: &[],
+ wait_until,
+ from_block,
+ swap_contract_address: &coin.swap_contract_address(),
+ check_every: TAKER_PAYMENT_SPEND_SEARCH_INTERVAL,
+ watcher_reward: false
+ }))
+ .is_err());
}
#[cfg(not(target_arch = "wasm32"))]
@@ -222,7 +227,7 @@ fn test_withdraw_impl_manual_fee() {
memo: None,
ibc_source_channel: None,
};
- coin.get_balance().wait().unwrap();
+ block_on_f01(coin.get_balance()).unwrap();
let tx_details = block_on(withdraw_impl(coin, withdraw_req)).unwrap();
let expected = Some(
@@ -271,7 +276,7 @@ fn test_withdraw_impl_fee_details() {
memo: None,
ibc_source_channel: None,
};
- coin.get_balance().wait().unwrap();
+ block_on_f01(coin.get_balance()).unwrap();
let tx_details = block_on(withdraw_impl(coin, withdraw_req)).unwrap();
let expected = Some(
@@ -306,6 +311,7 @@ fn test_add_ten_pct_one_gwei() {
assert_eq!(expected, actual);
}
+#[cfg(not(target_arch = "wasm32"))]
#[test]
fn get_sender_trade_preimage() {
/// Trade fee for the ETH coin is `2 * 150_000 * gas_price` always.
@@ -361,6 +367,7 @@ fn get_sender_trade_preimage() {
assert_eq!(actual, expected);
}
+#[cfg(not(target_arch = "wasm32"))]
#[test]
fn get_erc20_sender_trade_preimage() {
const APPROVE_GAS_LIMIT: u64 = 60_000;
@@ -463,6 +470,7 @@ fn get_erc20_sender_trade_preimage() {
);
}
+#[cfg(not(target_arch = "wasm32"))]
#[test]
fn get_receiver_trade_preimage() {
EthCoin::get_gas_price.mock_safe(|_| MockResult::Return(Box::pin(futures::future::ok(GAS_PRICE.into()))));
@@ -476,13 +484,12 @@ fn get_receiver_trade_preimage() {
paid_from_trading_vol: false,
};
- let actual = coin
- .get_receiver_trade_fee(FeeApproxStage::WithoutApprox)
- .wait()
- .expect("!get_sender_trade_fee");
+ let actual =
+ block_on_f01(coin.get_receiver_trade_fee(FeeApproxStage::WithoutApprox)).expect("!get_sender_trade_fee");
assert_eq!(actual, expected_fee);
}
+#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_get_fee_to_send_taker_fee() {
const DEX_FEE_AMOUNT: u64 = 100_000;
@@ -533,6 +540,7 @@ fn test_get_fee_to_send_taker_fee() {
///
/// Please note this test doesn't work correctly now,
/// because as of now [`EthCoin::get_fee_to_send_taker_fee`] doesn't process the `Exception` web3 error correctly.
+#[cfg(not(target_arch = "wasm32"))]
#[test]
#[ignore]
fn test_get_fee_to_send_taker_fee_insufficient_balance() {
@@ -562,6 +570,7 @@ fn test_get_fee_to_send_taker_fee_insufficient_balance() {
);
}
+#[cfg(not(target_arch = "wasm32"))]
#[test]
fn validate_dex_fee_invalid_sender_eth() {
let (_ctx, coin) = eth_coin_for_test(EthCoinType::Eth, &[ETH_MAINNET_NODE], None, ETH_MAINNET_CHAIN_ID);
@@ -582,13 +591,16 @@ fn validate_dex_fee_invalid_sender_eth() {
min_block_number: 0,
uuid: &[],
};
- let error = coin.validate_fee(validate_fee_args).wait().unwrap_err().into_inner();
+ let error = block_on_f01(coin.validate_fee(validate_fee_args))
+ .unwrap_err()
+ .into_inner();
match error {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("was sent from wrong address")),
_ => panic!("Expected `WrongPaymentTx` wrong sender address, found {:?}", error),
}
}
+#[cfg(not(target_arch = "wasm32"))]
#[test]
fn validate_dex_fee_invalid_sender_erc() {
let (_ctx, coin) = eth_coin_for_test(
@@ -617,13 +629,16 @@ fn validate_dex_fee_invalid_sender_erc() {
min_block_number: 0,
uuid: &[],
};
- let error = coin.validate_fee(validate_fee_args).wait().unwrap_err().into_inner();
+ let error = block_on_f01(coin.validate_fee(validate_fee_args))
+ .unwrap_err()
+ .into_inner();
match error {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("was sent from wrong address")),
_ => panic!("Expected `WrongPaymentTx` wrong sender address, found {:?}", error),
}
}
+#[cfg(not(target_arch = "wasm32"))]
fn sender_compressed_pub(tx: &SignedEthTx) -> [u8; 33] {
let tx_pubkey = tx.public.unwrap();
let mut raw_pubkey = [0; 65];
@@ -633,6 +648,7 @@ fn sender_compressed_pub(tx: &SignedEthTx) -> [u8; 33] {
secp_public.serialize()
}
+#[cfg(not(target_arch = "wasm32"))]
#[test]
fn validate_dex_fee_eth_confirmed_before_min_block() {
let (_ctx, coin) = eth_coin_for_test(EthCoinType::Eth, &[ETH_MAINNET_NODE], None, ETH_MAINNET_CHAIN_ID);
@@ -655,13 +671,16 @@ fn validate_dex_fee_eth_confirmed_before_min_block() {
min_block_number: 11784793,
uuid: &[],
};
- let error = coin.validate_fee(validate_fee_args).wait().unwrap_err().into_inner();
+ let error = block_on_f01(coin.validate_fee(validate_fee_args))
+ .unwrap_err()
+ .into_inner();
match error {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("confirmed before min_block")),
_ => panic!("Expected `WrongPaymentTx` early confirmation, found {:?}", error),
}
}
+#[cfg(not(target_arch = "wasm32"))]
#[test]
fn validate_dex_fee_erc_confirmed_before_min_block() {
let (_ctx, coin) = eth_coin_for_test(
@@ -693,13 +712,16 @@ fn validate_dex_fee_erc_confirmed_before_min_block() {
min_block_number: 11823975,
uuid: &[],
};
- let error = coin.validate_fee(validate_fee_args).wait().unwrap_err().into_inner();
+ let error = block_on_f01(coin.validate_fee(validate_fee_args))
+ .unwrap_err()
+ .into_inner();
match error {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("confirmed before min_block")),
_ => panic!("Expected `WrongPaymentTx` early confirmation, found {:?}", error),
}
}
+#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_negotiate_swap_contract_addr_no_fallback() {
let (_, coin) = eth_coin_for_test(EthCoinType::Eth, &[ETH_MAINNET_NODE], None, ETH_MAINNET_CHAIN_ID);
@@ -727,6 +749,7 @@ fn test_negotiate_swap_contract_addr_no_fallback() {
assert_eq!(Some(slice.to_vec().into()), result);
}
+#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_negotiate_swap_contract_addr_has_fallback() {
let fallback = Address::from_str("0x8500AFc0bc5214728082163326C2FF0C73f4a871").unwrap();
@@ -815,15 +838,14 @@ fn polygon_check_if_my_payment_sent() {
amount: &BigDecimal::default(),
payment_instructions: &None,
};
- let my_payment = coin
- .check_if_my_payment_sent(if_my_payment_sent_args)
- .wait()
+ let my_payment = block_on_f01(coin.check_if_my_payment_sent(if_my_payment_sent_args))
.unwrap()
.unwrap();
let expected_hash = BytesJson::from("69a20008cea0c15ee483b5bbdff942752634aa072dfd2ff715fe87eec302de11");
assert_eq!(expected_hash, my_payment.tx_hash_as_bytes());
}
+#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_message_hash() {
let key_pair = Random.generate().unwrap();
@@ -842,6 +864,7 @@ fn test_message_hash() {
);
}
+#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_sign_verify_message() {
let key_pair = KeyPair::from_secret_slice(
@@ -866,6 +889,7 @@ fn test_sign_verify_message() {
assert!(is_valid);
}
+#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_eth_extract_secret() {
let key_pair = Random.generate().unwrap();
diff --git a/mm2src/coins/lightning/ln_platform.rs b/mm2src/coins/lightning/ln_platform.rs
index 4d0573af95..0a5fae0a4f 100644
--- a/mm2src/coins/lightning/ln_platform.rs
+++ b/mm2src/coins/lightning/ln_platform.rs
@@ -15,7 +15,7 @@ use bitcoin::hash_types::{BlockHash, TxMerkleNode, Txid};
use bitcoin_hashes::{sha256d, Hash};
use common::executor::{abortable_queue::AbortableQueue, AbortableSystem, SpawnFuture, Timer};
use common::log::{debug, error, info};
-use common::wait_until_sec;
+use common::{block_on_f01, wait_until_sec};
use futures::compat::Future01CompatExt;
use futures::future::join_all;
use keys::hash::H256;
@@ -570,17 +570,15 @@ impl FeeEstimator for Platform {
ConfirmationTarget::HighPriority => self.confirmations_targets.high_priority,
};
let fee_per_kb = tokio::task::block_in_place(move || {
- self.rpc_client()
- .estimate_fee_sat(
- platform_coin.decimals(),
- // Todo: when implementing Native client detect_fee_method should be used for Native and
- // EstimateFeeMethod::Standard for Electrum
- &EstimateFeeMethod::Standard,
- &conf.estimate_fee_mode,
- n_blocks,
- )
- .wait()
- .unwrap_or(latest_fees)
+ block_on_f01(self.rpc_client().estimate_fee_sat(
+ platform_coin.decimals(),
+ // Todo: when implementing Native client detect_fee_method should be used for Native and
+ // EstimateFeeMethod::Standard for Electrum
+ &EstimateFeeMethod::Standard,
+ &conf.estimate_fee_mode,
+ n_blocks,
+ ))
+ .unwrap_or(latest_fees)
});
// Set default fee to last known fee for the corresponding confirmation target
diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs
index 59febe5a4c..1d9c11e3b9 100644
--- a/mm2src/coins/lp_coins.rs
+++ b/mm2src/coins/lp_coins.rs
@@ -124,7 +124,7 @@ macro_rules! try_f {
};
}
-#[cfg(feature = "enable-solana")]
+#[cfg(all(feature = "enable-solana", not(target_arch = "wasm32")))]
macro_rules! try_tx_fus_err {
($err: expr) => {
return Box::new(futures01::future::err(crate::TransactionErr::Plain(ERRL!(
@@ -133,7 +133,7 @@ macro_rules! try_tx_fus_err {
};
}
-#[cfg(feature = "enable-solana")]
+#[cfg(all(feature = "enable-solana", not(target_arch = "wasm32")))]
macro_rules! try_tx_fus_opt {
($e: expr, $err: expr) => {
match $e {
diff --git a/mm2src/coins/qrc20/qrc20_tests.rs b/mm2src/coins/qrc20/qrc20_tests.rs
index 2caf87c3bf..d77afa2f9b 100644
--- a/mm2src/coins/qrc20/qrc20_tests.rs
+++ b/mm2src/coins/qrc20/qrc20_tests.rs
@@ -1,6 +1,6 @@
use super::*;
use crate::{DexFee, TxFeeDetails, WaitForHTLCTxSpendArgs};
-use common::{block_on, wait_until_sec, DEX_FEE_ADDR_RAW_PUBKEY};
+use common::{block_on, block_on_f01, wait_until_sec, DEX_FEE_ADDR_RAW_PUBKEY};
use crypto::Secp256k1Secret;
use itertools::Itertools;
use keys::Address;
@@ -96,7 +96,7 @@ fn test_withdraw_to_p2sh_address_should_fail() {
memo: None,
ibc_source_channel: None,
};
- let err = coin.withdraw(req).wait().unwrap_err().into_inner();
+ let err = block_on_f01(coin.withdraw(req)).unwrap_err().into_inner();
let expect = WithdrawError::InvalidAddress("QRC20 can be sent to P2PKH addresses only".to_owned());
assert_eq!(err, expect);
}
@@ -112,19 +112,22 @@ fn test_withdraw_impl_fee_details() {
let (_ctx, coin) = qrc20_coin_for_test(priv_key, None);
Qrc20Coin::get_unspent_ordered_list.mock_safe(|coin, _| {
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- let unspents = vec![UnspentInfo {
- outpoint: OutPoint {
- hash: 1.into(),
- index: 0,
- },
- value: 1000000000,
- height: Default::default(),
- script: coin
- .script_for_address(&block_on(coin.as_ref().derivation_method.unwrap_single_addr()))
- .unwrap(),
- }];
- MockResult::Return(Box::pin(futures::future::ok((unspents, cache))))
+ let fut = async move {
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ let unspents = vec![UnspentInfo {
+ outpoint: OutPoint {
+ hash: 1.into(),
+ index: 0,
+ },
+ value: 1000000000,
+ height: Default::default(),
+ script: coin
+ .script_for_address(&coin.as_ref().derivation_method.unwrap_single_addr().await)
+ .unwrap(),
+ }];
+ Ok((unspents, cache))
+ };
+ MockResult::Return(fut.boxed())
});
let withdraw_req = WithdrawRequest {
@@ -140,7 +143,7 @@ fn test_withdraw_impl_fee_details() {
memo: None,
ibc_source_channel: None,
};
- let tx_details = coin.withdraw(withdraw_req).wait().unwrap();
+ let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap();
let expected: Qrc20FeeDetails = json::from_value(json!({
"coin": "QTUM",
@@ -287,7 +290,7 @@ fn test_wait_for_confirmations_excepted() {
wait_until,
check_every,
};
- coin.wait_for_confirmations(confirm_payment_input).wait().unwrap();
+ block_on_f01(coin.wait_for_confirmations(confirm_payment_input)).unwrap();
// tx_hash: ed53b97deb2ad76974c972cb084f6ba63bd9f16c91c4a39106a20c6d14599b2a
// `erc20Payment` contract call excepted
@@ -299,7 +302,7 @@ fn test_wait_for_confirmations_excepted() {
wait_until,
check_every,
};
- let error = coin.wait_for_confirmations(confirm_payment_input).wait().unwrap_err();
+ let error = block_on_f01(coin.wait_for_confirmations(confirm_payment_input)).unwrap_err();
log!("error: {:?}", error);
assert!(error.contains("Contract call failed with an error: Revert"));
@@ -313,7 +316,7 @@ fn test_wait_for_confirmations_excepted() {
wait_until,
check_every,
};
- let error = coin.wait_for_confirmations(confirm_payment_input).wait().unwrap_err();
+ let error = block_on_f01(coin.wait_for_confirmations(confirm_payment_input)).unwrap_err();
log!("error: {:?}", error);
assert!(error.contains("Contract call failed with an error: Revert"));
}
@@ -333,67 +336,59 @@ fn test_validate_fee() {
let amount = BigDecimal::from_str("0.01").unwrap();
- let result = coin
- .validate_fee(ValidateFeeArgs {
- fee_tx: &tx,
- expected_sender: &sender_pub,
- fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
- dex_fee: &DexFee::Standard(amount.clone().into()),
- min_block_number: 0,
- uuid: &[],
- })
- .wait();
+ let result = block_on_f01(coin.validate_fee(ValidateFeeArgs {
+ fee_tx: &tx,
+ expected_sender: &sender_pub,
+ fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
+ dex_fee: &DexFee::Standard(amount.clone().into()),
+ min_block_number: 0,
+ uuid: &[],
+ }));
assert!(result.is_ok());
let fee_addr_dif = hex::decode("03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc05").unwrap();
- let err = coin
- .validate_fee(ValidateFeeArgs {
- fee_tx: &tx,
- expected_sender: &sender_pub,
- fee_addr: &fee_addr_dif,
- dex_fee: &DexFee::Standard(amount.clone().into()),
- min_block_number: 0,
- uuid: &[],
- })
- .wait()
- .expect_err("Expected an error")
- .into_inner();
+ let err = block_on_f01(coin.validate_fee(ValidateFeeArgs {
+ fee_tx: &tx,
+ expected_sender: &sender_pub,
+ fee_addr: &fee_addr_dif,
+ dex_fee: &DexFee::Standard(amount.clone().into()),
+ min_block_number: 0,
+ uuid: &[],
+ }))
+ .expect_err("Expected an error")
+ .into_inner();
log!("error: {:?}", err);
match err {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("QRC20 Fee tx was sent to wrong address")),
_ => panic!("Expected `WrongPaymentTx` wrong receiver address, found {:?}", err),
}
- let err = coin
- .validate_fee(ValidateFeeArgs {
- fee_tx: &tx,
- expected_sender: &DEX_FEE_ADDR_RAW_PUBKEY,
- fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
- dex_fee: &DexFee::Standard(amount.clone().into()),
- min_block_number: 0,
- uuid: &[],
- })
- .wait()
- .expect_err("Expected an error")
- .into_inner();
+ let err = block_on_f01(coin.validate_fee(ValidateFeeArgs {
+ fee_tx: &tx,
+ expected_sender: &DEX_FEE_ADDR_RAW_PUBKEY,
+ fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
+ dex_fee: &DexFee::Standard(amount.clone().into()),
+ min_block_number: 0,
+ uuid: &[],
+ }))
+ .expect_err("Expected an error")
+ .into_inner();
log!("error: {:?}", err);
match err {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("was sent from wrong address")),
_ => panic!("Expected `WrongPaymentTx` wrong sender address, found {:?}", err),
}
- let err = coin
- .validate_fee(ValidateFeeArgs {
- fee_tx: &tx,
- expected_sender: &sender_pub,
- fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
- dex_fee: &DexFee::Standard(amount.clone().into()),
- min_block_number: 2000000,
- uuid: &[],
- })
- .wait()
- .expect_err("Expected an error")
- .into_inner();
+ let err = block_on_f01(coin.validate_fee(ValidateFeeArgs {
+ fee_tx: &tx,
+ expected_sender: &sender_pub,
+ fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
+ dex_fee: &DexFee::Standard(amount.clone().into()),
+ min_block_number: 2000000,
+ uuid: &[],
+ }))
+ .expect_err("Expected an error")
+ .into_inner();
log!("error: {:?}", err);
match err {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("confirmed before min_block")),
@@ -401,18 +396,16 @@ fn test_validate_fee() {
}
let amount_dif = BigDecimal::from_str("0.02").unwrap();
- let err = coin
- .validate_fee(ValidateFeeArgs {
- fee_tx: &tx,
- expected_sender: &sender_pub,
- fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
- dex_fee: &DexFee::Standard(amount_dif.into()),
- min_block_number: 0,
- uuid: &[],
- })
- .wait()
- .expect_err("Expected an error")
- .into_inner();
+ let err = block_on_f01(coin.validate_fee(ValidateFeeArgs {
+ fee_tx: &tx,
+ expected_sender: &sender_pub,
+ fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
+ dex_fee: &DexFee::Standard(amount_dif.into()),
+ min_block_number: 0,
+ uuid: &[],
+ }))
+ .expect_err("Expected an error")
+ .into_inner();
log!("error: {:?}", err);
match err {
ValidatePaymentError::WrongPaymentTx(err) => {
@@ -424,18 +417,16 @@ fn test_validate_fee() {
// QTUM tx "8a51f0ffd45f34974de50f07c5bf2f0949da4e88433f8f75191953a442cf9310"
let tx = TransactionEnum::UtxoTx("020000000113640281c9332caeddd02a8dd0d784809e1ad87bda3c972d89d5ae41f5494b85010000006a47304402207c5c904a93310b8672f4ecdbab356b65dd869a426e92f1064a567be7ccfc61ff02203e4173b9467127f7de4682513a21efb5980e66dbed4da91dff46534b8e77c7ef012102baefe72b3591de2070c0da3853226b00f082d72daa417688b61cb18c1d543d1afeffffff020001b2c4000000001976a9149e032d4b0090a11dc40fe6c47601499a35d55fbb88acbc4dd20c2f0000001976a9144208fa7be80dcf972f767194ad365950495064a488ac76e70800".into());
let sender_pub = hex::decode("02baefe72b3591de2070c0da3853226b00f082d72daa417688b61cb18c1d543d1a").unwrap();
- let err = coin
- .validate_fee(ValidateFeeArgs {
- fee_tx: &tx,
- expected_sender: &sender_pub,
- fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
- dex_fee: &DexFee::Standard(amount.into()),
- min_block_number: 0,
- uuid: &[],
- })
- .wait()
- .expect_err("Expected an error")
- .into_inner();
+ let err = block_on_f01(coin.validate_fee(ValidateFeeArgs {
+ fee_tx: &tx,
+ expected_sender: &sender_pub,
+ fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
+ dex_fee: &DexFee::Standard(amount.into()),
+ min_block_number: 0,
+ uuid: &[],
+ }))
+ .expect_err("Expected an error")
+ .into_inner();
log!("error: {:?}", err);
match err {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("Expected 'transfer' contract call")),
@@ -462,18 +453,16 @@ fn test_wait_for_tx_spend_malicious() {
let payment_tx = hex::decode("01000000016601daa208531d20532c460d0c86b74a275f4a126bbffcf4eafdf33835af2859010000006a47304402205825657548bc1b5acf3f4bb2f89635a02b04f3228cd08126e63c5834888e7ac402207ca05fa0a629a31908a97a508e15076e925f8e621b155312b7526a6666b06a76012103693bff1b39e8b5a306810023c29b95397eb395530b106b1820ea235fd81d9ce9ffffffff020000000000000000e35403a0860101284cc49b415b2a8620ad3b72361a5aeba5dffd333fb64750089d935a1ec974d6a91ef4f24ff6ba0000000000000000000000000000000000000000000000000000000001312d00000000000000000000000000d362e096e873eb7907e205fadc6175c6fec7bc44000000000000000000000000783cf0be521101942da509846ea476e683aad8324b6b2e5444c2639cc0fb7bcea5afba3f3cdce239000000000000000000000000000000000000000000000000000000000000000000000000000000005f855c7614ba8b71f3544b93e2f681f996da519a98ace0107ac2203de400000000001976a9149e032d4b0090a11dc40fe6c47601499a35d55fbb88ac415d855f").unwrap();
let wait_until = now_sec() + 1;
let from_block = 696245;
- let found = coin
- .wait_for_htlc_tx_spend(WaitForHTLCTxSpendArgs {
- tx_bytes: &payment_tx,
- secret_hash: &[],
- wait_until,
- from_block,
- swap_contract_address: &coin.swap_contract_address(),
- check_every: TAKER_PAYMENT_SPEND_SEARCH_INTERVAL,
- watcher_reward: false,
- })
- .wait()
- .unwrap();
+ let found = block_on_f01(coin.wait_for_htlc_tx_spend(WaitForHTLCTxSpendArgs {
+ tx_bytes: &payment_tx,
+ secret_hash: &[],
+ wait_until,
+ from_block,
+ swap_contract_address: &coin.swap_contract_address(),
+ check_every: TAKER_PAYMENT_SPEND_SEARCH_INTERVAL,
+ watcher_reward: false,
+ }))
+ .unwrap();
let spend_tx = match found {
TransactionEnum::UtxoTx(tx) => tx,
@@ -731,7 +720,7 @@ fn test_get_trade_fee() {
// check if the coin's tx fee is expected
check_tx_fee(&coin, ActualTxFee::FixedPerKb(EXPECTED_TX_FEE as u64));
- let actual_trade_fee = coin.get_trade_fee().wait().unwrap();
+ let actual_trade_fee = block_on_f01(coin.get_trade_fee()).unwrap();
let expected_trade_fee_amount = big_decimal_from_sat(
2 * CONTRACT_CALL_GAS_FEE + SWAP_PAYMENT_GAS_FEE + EXPECTED_TX_FEE,
coin.utxo.decimals,
@@ -905,10 +894,8 @@ fn test_receiver_trade_preimage() {
// check if the coin's tx fee is expected
check_tx_fee(&coin, ActualTxFee::FixedPerKb(EXPECTED_TX_FEE as u64));
- let actual = coin
- .get_receiver_trade_fee(FeeApproxStage::WithoutApprox)
- .wait()
- .expect("!get_receiver_trade_fee");
+ let actual =
+ block_on_f01(coin.get_receiver_trade_fee(FeeApproxStage::WithoutApprox)).expect("!get_receiver_trade_fee");
// only one contract call should be included into the expected trade fee
let expected_receiver_fee = big_decimal_from_sat(CONTRACT_CALL_GAS_FEE + EXPECTED_TX_FEE, coin.utxo.decimals);
let expected = TradeFee {
@@ -935,7 +922,7 @@ fn test_taker_fee_tx_fee() {
spendable: BigDecimal::from(5u32),
unspendable: BigDecimal::from(0u32),
};
- assert_eq!(coin.my_balance().wait().expect("!my_balance"), expected_balance);
+ assert_eq!(block_on_f01(coin.my_balance()).expect("!my_balance"), expected_balance);
let dex_fee_amount = BigDecimal::from(5u32);
let actual = block_on(coin.get_fee_to_send_taker_fee(
diff --git a/mm2src/coins/solana/solana_tests.rs b/mm2src/coins/solana/solana_tests.rs
index fe2b104293..d4126f35c0 100644
--- a/mm2src/coins/solana/solana_tests.rs
+++ b/mm2src/coins/solana/solana_tests.rs
@@ -1,5 +1,5 @@
use base58::ToBase58;
-use common::{block_on, Future01CompatExt};
+use common::{block_on, block_on_f01, Future01CompatExt};
use rpc::v1::types::Bytes;
use solana_client::rpc_request::TokenAccountsFilter;
use solana_sdk::{bs58,
@@ -367,7 +367,7 @@ fn solana_coin_send_and_refund_maker_payment() {
watcher_reward: None,
wait_for_confirmation_until: 0,
};
- let tx = coin.send_maker_payment(args).wait().unwrap();
+ let tx = block_on_f01(coin.send_maker_payment(args)).unwrap();
log!("swap tx {:?}", tx);
let refund_args = RefundPaymentArgs {
@@ -415,7 +415,7 @@ fn solana_coin_send_and_spend_maker_payment() {
wait_for_confirmation_until: 0,
};
- let tx = coin.send_maker_payment(maker_payment_args).wait().unwrap();
+ let tx = block_on_f01(coin.send_maker_payment(maker_payment_args)).unwrap();
log!("swap tx {:?}", tx);
let maker_pub = taker_pub;
diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs
index bc5e12f6ff..9c7a1c1d96 100644
--- a/mm2src/coins/tendermint/tendermint_coin.rs
+++ b/mm2src/coins/tendermint/tendermint_coin.rs
@@ -3313,7 +3313,7 @@ fn parse_expected_sequence_number(e: &str) -> MmResult {
@@ -3725,18 +3723,16 @@ pub mod tendermint_coin_tests {
data: TxRaw::decode(random_transfer_tx_bytes.as_slice()).unwrap(),
});
- let error = coin
- .validate_fee(ValidateFeeArgs {
- fee_tx: &random_transfer_tx,
- expected_sender: &[],
- fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
- dex_fee: &DexFee::Standard(invalid_amount.clone()),
- min_block_number: 0,
- uuid: &[1; 16],
- })
- .wait()
- .unwrap_err()
- .into_inner();
+ let error = block_on_f01(coin.validate_fee(ValidateFeeArgs {
+ fee_tx: &random_transfer_tx,
+ expected_sender: &[],
+ fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
+ dex_fee: &DexFee::Standard(invalid_amount.clone()),
+ min_block_number: 0,
+ uuid: &[1; 16],
+ }))
+ .unwrap_err()
+ .into_inner();
println!("{}", error);
match error {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("sent to wrong address")),
@@ -3758,18 +3754,16 @@ pub mod tendermint_coin_tests {
data: TxRaw::decode(dex_fee_tx.encode_to_vec().as_slice()).unwrap(),
});
- let error = coin
- .validate_fee(ValidateFeeArgs {
- fee_tx: &dex_fee_tx,
- expected_sender: &[],
- fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
- dex_fee: &DexFee::Standard(invalid_amount),
- min_block_number: 0,
- uuid: &[1; 16],
- })
- .wait()
- .unwrap_err()
- .into_inner();
+ let error = block_on_f01(coin.validate_fee(ValidateFeeArgs {
+ fee_tx: &dex_fee_tx,
+ expected_sender: &[],
+ fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
+ dex_fee: &DexFee::Standard(invalid_amount),
+ min_block_number: 0,
+ uuid: &[1; 16],
+ }))
+ .unwrap_err()
+ .into_inner();
println!("{}", error);
match error {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("Invalid amount")),
@@ -3778,18 +3772,16 @@ pub mod tendermint_coin_tests {
let valid_amount: BigDecimal = "0.0001".parse().unwrap();
// valid amount but invalid sender
- let error = coin
- .validate_fee(ValidateFeeArgs {
- fee_tx: &dex_fee_tx,
- expected_sender: &DEX_FEE_ADDR_RAW_PUBKEY,
- fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
- dex_fee: &DexFee::Standard(valid_amount.clone().into()),
- min_block_number: 0,
- uuid: &[1; 16],
- })
- .wait()
- .unwrap_err()
- .into_inner();
+ let error = block_on_f01(coin.validate_fee(ValidateFeeArgs {
+ fee_tx: &dex_fee_tx,
+ expected_sender: &DEX_FEE_ADDR_RAW_PUBKEY,
+ fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
+ dex_fee: &DexFee::Standard(valid_amount.clone().into()),
+ min_block_number: 0,
+ uuid: &[1; 16],
+ }))
+ .unwrap_err()
+ .into_inner();
println!("{}", error);
match error {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("Invalid sender")),
@@ -3797,18 +3789,16 @@ pub mod tendermint_coin_tests {
}
// invalid memo
- let error = coin
- .validate_fee(ValidateFeeArgs {
- fee_tx: &dex_fee_tx,
- expected_sender: &pubkey,
- fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
- dex_fee: &DexFee::Standard(valid_amount.into()),
- min_block_number: 0,
- uuid: &[1; 16],
- })
- .wait()
- .unwrap_err()
- .into_inner();
+ let error = block_on_f01(coin.validate_fee(ValidateFeeArgs {
+ fee_tx: &dex_fee_tx,
+ expected_sender: &pubkey,
+ fee_addr: &DEX_FEE_ADDR_RAW_PUBKEY,
+ dex_fee: &DexFee::Standard(valid_amount.into()),
+ min_block_number: 0,
+ uuid: &[1; 16],
+ }))
+ .unwrap_err()
+ .into_inner();
println!("{}", error);
match error {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("Invalid memo")),
diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs
index c559449c22..503611445e 100644
--- a/mm2src/coins/utxo/slp.rs
+++ b/mm2src/coins/utxo/slp.rs
@@ -1945,6 +1945,7 @@ mod slp_tests {
use crate::utxo::GetUtxoListOps;
use crate::{utxo::bch::tbch_coin_for_test, TransactionErr};
use common::block_on;
+ use common::block_on_f01;
use mocktopus::mocking::{MockResult, Mockable};
use std::mem::discriminant;
@@ -2206,11 +2207,11 @@ mod slp_tests {
];
let tx_bytes_str = hex::encode(tx_bytes);
- let err = fusd.send_raw_tx(&tx_bytes_str).wait().unwrap_err();
+ let err = block_on_f01(fusd.send_raw_tx(&tx_bytes_str)).unwrap_err();
println!("{:?}", err);
assert!(err.contains("is not valid with reason outputs greater than inputs"));
- let err2 = fusd.send_raw_tx_bytes(tx_bytes).wait().unwrap_err();
+ let err2 = block_on_f01(fusd.send_raw_tx_bytes(tx_bytes)).unwrap_err();
println!("{:?}", err2);
assert!(err2.contains("is not valid with reason outputs greater than inputs"));
assert_eq!(err, err2);
diff --git a/mm2src/coins/utxo/utxo_tests.rs b/mm2src/coins/utxo/utxo_tests.rs
index 868f558f1f..9456361c64 100644
--- a/mm2src/coins/utxo/utxo_tests.rs
+++ b/mm2src/coins/utxo/utxo_tests.rs
@@ -34,13 +34,12 @@ use crate::{BlockHeightAndTime, CoinBalance, ConfirmPaymentInput, DexFee, Iguana
use crate::{WaitForHTLCTxSpendArgs, WithdrawFee};
use chain::{BlockHeader, BlockHeaderBits, OutPoint};
use common::executor::Timer;
-use common::{block_on, wait_until_sec, OrdRange, PagingOptionsEnum, DEX_FEE_ADDR_RAW_PUBKEY};
+use common::{block_on, block_on_f01, wait_until_sec, OrdRange, PagingOptionsEnum, DEX_FEE_ADDR_RAW_PUBKEY};
use crypto::{privkey::key_pair_from_seed, Bip44Chain, HDPathToAccount, RpcDerivationPath, Secp256k1Secret};
#[cfg(not(target_arch = "wasm32"))]
use db_common::sqlite::rusqlite::Connection;
use futures::channel::mpsc::channel;
-use futures::future::join_all;
-use futures::TryFutureExt;
+use futures::future::{join_all, Either, FutureExt, TryFutureExt};
use keys::prefixes::*;
use mm2_core::mm_ctx::MmCtxBuilder;
use mm2_number::bigdecimal::{BigDecimal, Signed};
@@ -438,18 +437,16 @@ fn test_wait_for_payment_spend_timeout_native() {
let wait_until = now_sec() - 1;
let from_block = 1000;
- assert!(coin
- .wait_for_htlc_tx_spend(WaitForHTLCTxSpendArgs {
- tx_bytes: &transaction,
- secret_hash: &[],
- wait_until,
- from_block,
- swap_contract_address: &None,
- check_every: TAKER_PAYMENT_SPEND_SEARCH_INTERVAL,
- watcher_reward: false
- })
- .wait()
- .is_err());
+ assert!(block_on_f01(coin.wait_for_htlc_tx_spend(WaitForHTLCTxSpendArgs {
+ tx_bytes: &transaction,
+ secret_hash: &[],
+ wait_until,
+ from_block,
+ swap_contract_address: &None,
+ check_every: TAKER_PAYMENT_SPEND_SEARCH_INTERVAL,
+ watcher_reward: false
+ }))
+ .is_err());
assert!(unsafe { OUTPUT_SPEND_CALLED });
}
@@ -486,18 +483,16 @@ fn test_wait_for_payment_spend_timeout_electrum() {
let wait_until = now_sec() - 1;
let from_block = 1000;
- assert!(coin
- .wait_for_htlc_tx_spend(WaitForHTLCTxSpendArgs {
- tx_bytes: &transaction,
- secret_hash: &[],
- wait_until,
- from_block,
- swap_contract_address: &None,
- check_every: TAKER_PAYMENT_SPEND_SEARCH_INTERVAL,
- watcher_reward: false
- })
- .wait()
- .is_err());
+ assert!(block_on_f01(coin.wait_for_htlc_tx_spend(WaitForHTLCTxSpendArgs {
+ tx_bytes: &transaction,
+ secret_hash: &[],
+ wait_until,
+ from_block,
+ swap_contract_address: &None,
+ check_every: TAKER_PAYMENT_SPEND_SEARCH_INTERVAL,
+ watcher_reward: false
+ }))
+ .is_err());
assert!(unsafe { OUTPUT_SPEND_CALLED });
}
@@ -575,19 +570,22 @@ fn test_search_for_swap_tx_spend_electrum_was_refunded() {
#[cfg(not(target_arch = "wasm32"))]
fn test_withdraw_impl_set_fixed_fee() {
UtxoStandardCoin::get_unspent_ordered_list.mock_safe(|coin, _| {
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- let unspents = vec![UnspentInfo {
- outpoint: OutPoint {
- hash: 1.into(),
- index: 0,
- },
- value: 1000000000,
- height: Default::default(),
- script: coin
- .script_for_address(&block_on(coin.as_ref().derivation_method.unwrap_single_addr()))
- .unwrap(),
- }];
- MockResult::Return(Box::pin(futures::future::ok((unspents, cache))))
+ let fut = async move {
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ let unspents = vec![UnspentInfo {
+ outpoint: OutPoint {
+ hash: 1.into(),
+ index: 0,
+ },
+ value: 1000000000,
+ height: Default::default(),
+ script: coin
+ .script_for_address(&coin.as_ref().derivation_method.unwrap_single_addr().await)
+ .unwrap(),
+ }];
+ Ok((unspents, cache))
+ };
+ MockResult::Return(fut.boxed())
});
let client = NativeClient(Arc::new(NativeClientImpl::default()));
@@ -613,7 +611,7 @@ fn test_withdraw_impl_set_fixed_fee() {
}
.into(),
);
- let tx_details = coin.withdraw(withdraw_req).wait().unwrap();
+ let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap();
assert_eq!(expected, tx_details.fee_details);
}
@@ -621,19 +619,22 @@ fn test_withdraw_impl_set_fixed_fee() {
#[cfg(not(target_arch = "wasm32"))]
fn test_withdraw_impl_sat_per_kb_fee() {
UtxoStandardCoin::get_unspent_ordered_list.mock_safe(|coin, _| {
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- let unspents = vec![UnspentInfo {
- outpoint: OutPoint {
- hash: 1.into(),
- index: 0,
- },
- value: 1000000000,
- height: Default::default(),
- script: coin
- .script_for_address(&block_on(coin.as_ref().derivation_method.unwrap_single_addr()))
- .unwrap(),
- }];
- MockResult::Return(Box::pin(futures::future::ok((unspents, cache))))
+ let fut = async move {
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ let unspents = vec![UnspentInfo {
+ outpoint: OutPoint {
+ hash: 1.into(),
+ index: 0,
+ },
+ value: 1000000000,
+ height: Default::default(),
+ script: coin
+ .script_for_address(&coin.as_ref().derivation_method.unwrap_single_addr().await)
+ .unwrap(),
+ }];
+ Ok((unspents, cache))
+ };
+ MockResult::Return(fut.boxed())
});
let client = NativeClient(Arc::new(NativeClientImpl::default()));
@@ -662,7 +663,7 @@ fn test_withdraw_impl_sat_per_kb_fee() {
}
.into(),
);
- let tx_details = coin.withdraw(withdraw_req).wait().unwrap();
+ let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap();
assert_eq!(expected, tx_details.fee_details);
}
@@ -670,19 +671,22 @@ fn test_withdraw_impl_sat_per_kb_fee() {
#[cfg(not(target_arch = "wasm32"))]
fn test_withdraw_impl_sat_per_kb_fee_amount_equal_to_max() {
UtxoStandardCoin::get_unspent_ordered_list.mock_safe(|coin, _| {
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- let unspents = vec![UnspentInfo {
- outpoint: OutPoint {
- hash: 1.into(),
- index: 0,
- },
- value: 1000000000,
- height: Default::default(),
- script: coin
- .script_for_address(&block_on(coin.as_ref().derivation_method.unwrap_single_addr()))
- .unwrap(),
- }];
- MockResult::Return(Box::pin(futures::future::ok((unspents, cache))))
+ let fut = async move {
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ let unspents = vec![UnspentInfo {
+ outpoint: OutPoint {
+ hash: 1.into(),
+ index: 0,
+ },
+ value: 1000000000,
+ height: Default::default(),
+ script: coin
+ .script_for_address(&coin.as_ref().derivation_method.unwrap_single_addr().await)
+ .unwrap(),
+ }];
+ Ok((unspents, cache))
+ };
+ MockResult::Return(fut.boxed())
});
let client = NativeClient(Arc::new(NativeClientImpl::default()));
@@ -701,7 +705,7 @@ fn test_withdraw_impl_sat_per_kb_fee_amount_equal_to_max() {
memo: None,
ibc_source_channel: None,
};
- let tx_details = coin.withdraw(withdraw_req).wait().unwrap();
+ let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap();
// The resulting transaction size might be 210 or 211 bytes depending on signature size
// MM2 always expects the worst case during fee calculation
// 0.1 * 211 / 1000 = 0.0211
@@ -721,19 +725,22 @@ fn test_withdraw_impl_sat_per_kb_fee_amount_equal_to_max() {
#[cfg(not(target_arch = "wasm32"))]
fn test_withdraw_impl_sat_per_kb_fee_amount_equal_to_max_dust_included_to_fee() {
UtxoStandardCoin::get_unspent_ordered_list.mock_safe(|coin, _| {
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- let unspents = vec![UnspentInfo {
- outpoint: OutPoint {
- hash: 1.into(),
- index: 0,
- },
- value: 1000000000,
- height: Default::default(),
- script: coin
- .script_for_address(&block_on(coin.as_ref().derivation_method.unwrap_single_addr()))
- .unwrap(),
- }];
- MockResult::Return(Box::pin(futures::future::ok((unspents, cache))))
+ let fut = async move {
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ let unspents = vec![UnspentInfo {
+ outpoint: OutPoint {
+ hash: 1.into(),
+ index: 0,
+ },
+ value: 1000000000,
+ height: Default::default(),
+ script: coin
+ .script_for_address(&coin.as_ref().derivation_method.unwrap_single_addr().await)
+ .unwrap(),
+ }];
+ Ok((unspents, cache))
+ };
+ MockResult::Return(fut.boxed())
});
let client = NativeClient(Arc::new(NativeClientImpl::default()));
@@ -752,7 +759,7 @@ fn test_withdraw_impl_sat_per_kb_fee_amount_equal_to_max_dust_included_to_fee()
memo: None,
ibc_source_channel: None,
};
- let tx_details = coin.withdraw(withdraw_req).wait().unwrap();
+ let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap();
// The resulting transaction size might be 210 or 211 bytes depending on signature size
// MM2 always expects the worst case during fee calculation
// 0.1 * 211 / 1000 = 0.0211
@@ -772,19 +779,22 @@ fn test_withdraw_impl_sat_per_kb_fee_amount_equal_to_max_dust_included_to_fee()
#[cfg(not(target_arch = "wasm32"))]
fn test_withdraw_impl_sat_per_kb_fee_amount_over_max() {
UtxoStandardCoin::get_unspent_ordered_list.mock_safe(|coin, _| {
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- let unspents = vec![UnspentInfo {
- outpoint: OutPoint {
- hash: 1.into(),
- index: 0,
- },
- value: 1000000000,
- height: Default::default(),
- script: coin
- .script_for_address(&block_on(coin.as_ref().derivation_method.unwrap_single_addr()))
- .unwrap(),
- }];
- MockResult::Return(Box::pin(futures::future::ok((unspents, cache))))
+ let fut = async move {
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ let unspents = vec![UnspentInfo {
+ outpoint: OutPoint {
+ hash: 1.into(),
+ index: 0,
+ },
+ value: 1000000000,
+ height: Default::default(),
+ script: coin
+ .script_for_address(&coin.as_ref().derivation_method.unwrap_single_addr().await)
+ .unwrap(),
+ }];
+ Ok((unspents, cache))
+ };
+ MockResult::Return(fut.boxed())
});
let client = NativeClient(Arc::new(NativeClientImpl::default()));
@@ -803,26 +813,29 @@ fn test_withdraw_impl_sat_per_kb_fee_amount_over_max() {
memo: None,
ibc_source_channel: None,
};
- coin.withdraw(withdraw_req).wait().unwrap_err();
+ block_on_f01(coin.withdraw(withdraw_req)).unwrap_err();
}
#[test]
#[cfg(not(target_arch = "wasm32"))]
fn test_withdraw_impl_sat_per_kb_fee_max() {
UtxoStandardCoin::get_unspent_ordered_list.mock_safe(|coin, _| {
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- let unspents = vec![UnspentInfo {
- outpoint: OutPoint {
- hash: 1.into(),
- index: 0,
- },
- value: 1000000000,
- height: Default::default(),
- script: coin
- .script_for_address(&block_on(coin.as_ref().derivation_method.unwrap_single_addr()))
- .unwrap(),
- }];
- MockResult::Return(Box::pin(futures::future::ok((unspents, cache))))
+ let fut = async move {
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ let unspents = vec![UnspentInfo {
+ outpoint: OutPoint {
+ hash: 1.into(),
+ index: 0,
+ },
+ value: 1000000000,
+ height: Default::default(),
+ script: coin
+ .script_for_address(&coin.as_ref().derivation_method.unwrap_single_addr().await)
+ .unwrap(),
+ }];
+ Ok((unspents, cache))
+ };
+ MockResult::Return(fut.boxed())
});
let client = NativeClient(Arc::new(NativeClientImpl::default()));
@@ -851,7 +864,7 @@ fn test_withdraw_impl_sat_per_kb_fee_max() {
}
.into(),
);
- let tx_details = coin.withdraw(withdraw_req).wait().unwrap();
+ let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap();
assert_eq!(expected, tx_details.fee_details);
}
@@ -866,20 +879,23 @@ fn test_withdraw_kmd_rewards_impl(
let verbose: RpcTransaction = json::from_str(verbose_serialized).unwrap();
let unspent_height = verbose.height;
UtxoStandardCoin::get_unspent_ordered_list.mock_safe(move |coin: &UtxoStandardCoin, _| {
- let tx: UtxoTx = tx_hex.into();
- let unspents = vec![UnspentInfo {
- outpoint: OutPoint {
- hash: tx.hash(),
- index: 0,
- },
- value: tx.outputs[0].value,
- height: unspent_height,
- script: coin
- .script_for_address(&block_on(coin.as_ref().derivation_method.unwrap_single_addr()))
- .unwrap(),
- }];
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- MockResult::Return(Box::pin(futures::future::ok((unspents, cache))))
+ let fut = async move {
+ let tx: UtxoTx = tx_hex.into();
+ let unspents = vec![UnspentInfo {
+ outpoint: OutPoint {
+ hash: tx.hash(),
+ index: 0,
+ },
+ value: tx.outputs[0].value,
+ height: unspent_height,
+ script: coin
+ .script_for_address(&coin.as_ref().derivation_method.unwrap_single_addr().await)
+ .unwrap(),
+ }];
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ Ok((unspents, cache))
+ };
+ MockResult::Return(fut.boxed())
});
UtxoStandardCoin::get_current_mtp
.mock_safe(move |_fields| MockResult::Return(Box::pin(futures::future::ok(current_mtp))));
@@ -909,7 +925,7 @@ fn test_withdraw_kmd_rewards_impl(
coin: Some("KMD".into()),
amount: "0.00001".parse().unwrap(),
});
- let tx_details = coin.withdraw(withdraw_req).wait().unwrap();
+ let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap();
assert_eq!(tx_details.fee_details, Some(expected_fee));
let expected_rewards = expected_rewards.map(|amount| KmdRewardsDetails {
@@ -958,20 +974,23 @@ fn test_withdraw_rick_rewards_none() {
const TX_HEX: &str = "0400008085202f8901df8119c507aa61d32332cd246dbfeb3818a4f96e76492454c1fbba5aa097977e000000004847304402205a7e229ea6929c97fd6dde254c19e4eb890a90353249721701ae7a1c477d99c402206a8b7c5bf42b5095585731d6b4c589ce557f63c20aed69ff242eca22ecfcdc7a01feffffff02d04d1bffbc050000232102afdbba3e3c90db5f0f4064118f79cf308f926c68afd64ea7afc930975663e4c4ac402dd913000000001976a9143e17014eca06281ee600adffa34b4afb0922a22288ac2bdab86035a00e000000000000000000000000";
UtxoStandardCoin::get_unspent_ordered_list.mock_safe(move |coin, _| {
- let tx: UtxoTx = TX_HEX.into();
- let unspents = vec![UnspentInfo {
- outpoint: OutPoint {
- hash: tx.hash(),
- index: 0,
- },
- value: tx.outputs[0].value,
- height: Some(1431628),
- script: coin
- .script_for_address(&block_on(coin.as_ref().derivation_method.unwrap_single_addr()))
- .unwrap(),
- }];
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- MockResult::Return(Box::pin(futures::future::ok((unspents, cache))))
+ let fut = async move {
+ let tx: UtxoTx = TX_HEX.into();
+ let unspents = vec![UnspentInfo {
+ outpoint: OutPoint {
+ hash: tx.hash(),
+ index: 0,
+ },
+ value: tx.outputs[0].value,
+ height: Some(1431628),
+ script: coin
+ .script_for_address(&coin.as_ref().derivation_method.unwrap_single_addr().await)
+ .unwrap(),
+ }];
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ Ok((unspents, cache))
+ };
+ MockResult::Return(fut.boxed())
});
let withdraw_req = WithdrawRequest {
@@ -988,7 +1007,7 @@ fn test_withdraw_rick_rewards_none() {
coin: Some(TEST_COIN_NAME.into()),
amount: "0.00001".parse().unwrap(),
});
- let tx_details = coin.withdraw(withdraw_req).wait().unwrap();
+ let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap();
assert_eq!(tx_details.fee_details, Some(expected_fee));
assert_eq!(tx_details.kmd_rewards, None);
}
@@ -1066,7 +1085,7 @@ fn test_electrum_rpc_client_error() {
let client = electrum_client_for_test(&["electrum1.cipig.net:10060"]);
let empty_hash = H256Json::default();
- let err = client.get_verbose_transaction(&empty_hash).wait().unwrap_err();
+ let err = block_on_f01(client.get_verbose_transaction(&empty_hash)).unwrap_err();
// use the static string instead because the actual error message cannot be obtain
// by serde_json serialization
@@ -1305,10 +1324,7 @@ fn test_get_median_time_past_from_electrum_kmd() {
"electrum3.cipig.net:10001",
]);
- let mtp = client
- .get_median_time_past(1773390, KMD_MTP_BLOCK_COUNT, CoinVariant::Standard)
- .wait()
- .unwrap();
+ let mtp = block_on_f01(client.get_median_time_past(1773390, KMD_MTP_BLOCK_COUNT, CoinVariant::Standard)).unwrap();
// the MTP is block time of 1773385 in this case
assert_eq!(1583159915, mtp);
}
@@ -1321,10 +1337,7 @@ fn test_get_median_time_past_from_electrum_btc() {
"electrum3.cipig.net:10000",
]);
- let mtp = client
- .get_median_time_past(632858, KMD_MTP_BLOCK_COUNT, CoinVariant::Standard)
- .wait()
- .unwrap();
+ let mtp = block_on_f01(client.get_median_time_past(632858, KMD_MTP_BLOCK_COUNT, CoinVariant::Standard)).unwrap();
assert_eq!(1591173041, mtp);
}
@@ -1348,10 +1361,7 @@ fn test_get_median_time_past_from_native_has_median_in_get_block() {
)
});
- let mtp = client
- .get_median_time_past(632858, KMD_MTP_BLOCK_COUNT, CoinVariant::Standard)
- .wait()
- .unwrap();
+ let mtp = block_on_f01(client.get_median_time_past(632858, KMD_MTP_BLOCK_COUNT, CoinVariant::Standard)).unwrap();
assert_eq!(1591173041, mtp);
}
@@ -1394,10 +1404,7 @@ fn test_get_median_time_past_from_native_does_not_have_median_in_get_block() {
MockResult::Return(Box::new(futures01::future::ok(block)))
});
- let mtp = client
- .get_median_time_past(632858, KMD_MTP_BLOCK_COUNT, CoinVariant::Standard)
- .wait()
- .unwrap();
+ let mtp = block_on_f01(client.get_median_time_past(632858, KMD_MTP_BLOCK_COUNT, CoinVariant::Standard)).unwrap();
assert_eq!(1591173041, mtp);
}
@@ -1597,13 +1604,11 @@ fn test_spam_rick() {
fn test_one_unavailable_electrum_proto_version() {
// check if the electrum-mona.bitbank.cc:50001 doesn't support the protocol version 1.4
let client = electrum_client_for_test(&["electrum-mona.bitbank.cc:50001"]);
- let result = client
- .server_version(
- "electrum-mona.bitbank.cc:50001",
- "AtomicDEX",
- &OrdRange::new(1.4, 1.4).unwrap(),
- )
- .wait();
+ let result = block_on_f01(client.server_version(
+ "electrum-mona.bitbank.cc:50001",
+ "AtomicDEX",
+ &OrdRange::new(1.4, 1.4).unwrap(),
+ ));
assert!(result
.err()
.unwrap()
@@ -1628,7 +1633,7 @@ fn test_one_unavailable_electrum_proto_version() {
block_on(async { Timer::sleep(0.5).await });
- assert!(coin.as_ref().rpc_client.get_block_count().wait().is_ok());
+ assert!(block_on_f01(coin.as_ref().rpc_client.get_block_count()).is_ok());
}
#[test]
@@ -1685,7 +1690,7 @@ fn test_qtum_add_delegation() {
address: address.to_string(),
fee: Some(10),
};
- let res = coin.add_delegation(request).wait().unwrap();
+ let res = block_on_f01(coin.add_delegation(request)).unwrap();
// Eligible for delegation
assert!(res.my_balance_change.is_negative());
assert_eq!(res.total_amount, res.spent_by_me);
@@ -1695,7 +1700,7 @@ fn test_qtum_add_delegation() {
address: "fake_address".to_string(),
fee: Some(10),
};
- let res = coin.add_delegation(request).wait();
+ let res = block_on_f01(coin.add_delegation(request));
// Wrong address
assert!(res.is_err());
}
@@ -1728,7 +1733,7 @@ fn test_qtum_add_delegation_on_already_delegating() {
address: address.to_string(),
fee: Some(10),
};
- let res = coin.add_delegation(request).wait();
+ let res = block_on_f01(coin.add_delegation(request));
// Already Delegating
assert!(res.is_err());
}
@@ -1754,7 +1759,7 @@ fn test_qtum_get_delegation_infos() {
keypair.private().secret,
))
.unwrap();
- let staking_infos = coin.get_delegation_infos().wait().unwrap();
+ let staking_infos = block_on_f01(coin.get_delegation_infos()).unwrap();
match staking_infos.staking_infos_details {
StakingInfosDetails::Qtum(staking_details) => {
assert!(staking_details.am_i_staking);
@@ -1784,49 +1789,49 @@ fn test_qtum_remove_delegation() {
keypair.private().secret,
))
.unwrap();
- let res = coin.remove_delegation().wait();
+ let res = block_on_f01(coin.remove_delegation());
assert!(res.is_ok());
}
#[test]
fn test_qtum_my_balance() {
QtumCoin::get_mature_unspent_ordered_list.mock_safe(move |coin, _address| {
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- // spendable balance (66.0)
- let mature = vec![
- UnspentInfo {
- outpoint: OutPoint {
- hash: 1.into(),
- index: 0,
+ let fut = async move {
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ // spendable balance (66.0)
+ let mature = vec![
+ UnspentInfo {
+ outpoint: OutPoint {
+ hash: 1.into(),
+ index: 0,
+ },
+ value: 5000000000,
+ height: Default::default(),
+ script: Vec::new().into(),
},
- value: 5000000000,
- height: Default::default(),
- script: Vec::new().into(),
- },
- UnspentInfo {
+ UnspentInfo {
+ outpoint: OutPoint {
+ hash: 1.into(),
+ index: 0,
+ },
+ value: 1600000000,
+ height: Default::default(),
+ script: Vec::new().into(),
+ },
+ ];
+ // unspendable (2.0)
+ let immature = vec![UnspentInfo {
outpoint: OutPoint {
hash: 1.into(),
index: 0,
},
- value: 1600000000,
+ value: 200000000,
height: Default::default(),
script: Vec::new().into(),
- },
- ];
- // unspendable (2.0)
- let immature = vec![UnspentInfo {
- outpoint: OutPoint {
- hash: 1.into(),
- index: 0,
- },
- value: 200000000,
- height: Default::default(),
- script: Vec::new().into(),
- }];
- MockResult::Return(Box::pin(futures::future::ok((
- MatureUnspentList { mature, immature },
- cache,
- ))))
+ }];
+ Ok((MatureUnspentList { mature, immature }, cache))
+ };
+ MockResult::Return(fut.boxed())
});
let conf = json!({"coin":"tQTUM","rpcport":13889,"pubtype":120,"p2shtype":110});
@@ -1845,7 +1850,7 @@ fn test_qtum_my_balance() {
let params = UtxoActivationParams::from_legacy_req(&req).unwrap();
let coin = block_on(qtum_coin_with_priv_key(&ctx, "tQTUM", &conf, ¶ms, priv_key)).unwrap();
- let CoinBalance { spendable, unspendable } = coin.my_balance().wait().unwrap();
+ let CoinBalance { spendable, unspendable } = block_on_f01(coin.my_balance()).unwrap();
let expected_spendable = BigDecimal::from(66);
let expected_unspendable = BigDecimal::from(2);
assert_eq!(spendable, expected_spendable);
@@ -1881,7 +1886,7 @@ fn test_qtum_my_balance_with_check_utxo_maturity_false() {
let params = UtxoActivationParams::from_legacy_req(&req).unwrap();
let coin = block_on(qtum_coin_with_priv_key(&ctx, "tQTUM", &conf, ¶ms, priv_key)).unwrap();
- let CoinBalance { spendable, unspendable } = coin.my_balance().wait().unwrap();
+ let CoinBalance { spendable, unspendable } = block_on_f01(coin.my_balance()).unwrap();
let expected_spendable = BigDecimal::from(DISPLAY_BALANCE);
let expected_unspendable = BigDecimal::from(0);
assert_eq!(spendable, expected_spendable);
@@ -1899,7 +1904,7 @@ fn test_get_mature_unspent_ordered_map_from_cache_impl(
const TX_HASH: &str = "b43f9ed47f7b97d4766b6f1614136fa0c55b9a52c97342428333521fa13ad714";
let tx_hash: H256Json = hex::decode(TX_HASH).unwrap().as_slice().into();
let client = electrum_client_for_test(DOC_ELECTRUM_ADDRS);
- let mut verbose = client.get_verbose_transaction(&tx_hash).wait().unwrap();
+ let mut verbose = block_on_f01(client.get_verbose_transaction(&tx_hash)).unwrap();
verbose.confirmations = cached_confs;
verbose.height = cached_height;
@@ -2517,15 +2522,13 @@ fn test_find_output_spend_skips_conflicting_transactions() {
let tx: UtxoTx = "0400008085202f89027f57730fcbbc2c72fb18bcc3766a713044831a117bb1cade3ed88644864f7333020000006a47304402206e3737b2fcf078b61b16fa67340cc3e79c5d5e2dc9ffda09608371552a3887450220460a332aa1b8ad8f2de92d319666f70751078b221199951f80265b4f7cef8543012102d8c948c6af848c588517288168faa397d6ba3ea924596d03d1d84f224b5123c2ffffffff42b916a80430b80a77e114445b08cf120735447a524de10742fac8f6a9d4170f000000006a473044022004aa053edafb9d161ea8146e0c21ed1593aa6b9404dd44294bcdf920a1695fd902202365eac15dbcc5e9f83e2eed56a8f2f0e5aded36206f9c3fabc668fd4665fa2d012102d8c948c6af848c588517288168faa397d6ba3ea924596d03d1d84f224b5123c2ffffffff03547b16000000000017a9143e8ad0e2bf573d32cb0b3d3a304d9ebcd0c2023b870000000000000000166a144e2b3c0323ab3c2dc6f86dc5ec0729f11e42f56103970400000000001976a91450f4f098306f988d8843004689fae28c83ef16e888ac89c5925f000000000000000000000000000000".into();
let vout = 0;
let from_block = 0;
- let actual = client
- .find_output_spend(
- tx.hash(),
- &tx.outputs[vout].script_pubkey,
- vout,
- BlockHashOrHeight::Height(from_block),
- TxHashAlgo::DSHA256,
- )
- .wait();
+ let actual = block_on_f01(client.find_output_spend(
+ tx.hash(),
+ &tx.outputs[vout].script_pubkey,
+ vout,
+ BlockHashOrHeight::Height(from_block),
+ TxHashAlgo::DSHA256,
+ ));
assert_eq!(actual, Ok(None));
assert_eq!(unsafe { GET_RAW_TRANSACTION_BYTES_CALLED }, 1);
}
@@ -2609,7 +2612,7 @@ fn test_get_sender_trade_fee_dynamic_tx_fee() {
);
coin_fields.tx_fee = TxFee::Dynamic(EstimateFeeMethod::Standard);
let coin = utxo_coin_from_fields(coin_fields);
- let my_balance = coin.my_spendable_balance().wait().expect("!my_balance");
+ let my_balance = block_on_f01(coin.my_spendable_balance()).expect("!my_balance");
let expected_balance = BigDecimal::from_str("2.22222").expect("!BigDecimal::from_str");
assert_eq!(my_balance, expected_balance);
@@ -2657,7 +2660,9 @@ fn test_validate_fee_wrong_sender() {
min_block_number: 0,
uuid: &[],
};
- let error = coin.validate_fee(validate_fee_args).wait().unwrap_err().into_inner();
+ let error = block_on_f01(coin.validate_fee(validate_fee_args))
+ .unwrap_err()
+ .into_inner();
log!("error: {:?}", error);
match error {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains(INVALID_SENDER_ERR_LOG)),
@@ -2682,7 +2687,9 @@ fn test_validate_fee_min_block() {
min_block_number: 278455,
uuid: &[],
};
- let error = coin.validate_fee(validate_fee_args).wait().unwrap_err().into_inner();
+ let error = block_on_f01(coin.validate_fee(validate_fee_args))
+ .unwrap_err()
+ .into_inner();
match error {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("confirmed before min_block")),
_ => panic!("Expected `WrongPaymentTx` early confirmation, found {:?}", error),
@@ -2711,7 +2718,7 @@ fn test_validate_fee_bch_70_bytes_signature() {
min_block_number: 0,
uuid: &[],
};
- coin.validate_fee(validate_fee_args).wait().unwrap();
+ block_on_f01(coin.validate_fee(validate_fee_args)).unwrap();
}
#[test]
@@ -2766,7 +2773,7 @@ fn firo_lelantus_tx() {
"electrumx02.firo.org:50001",
"electrumx03.firo.org:50001",
]);
- let _tx = electrum.get_verbose_transaction(&tx_hash).wait().unwrap();
+ let _tx = block_on_f01(electrum.get_verbose_transaction(&tx_hash)).unwrap();
}
#[test]
@@ -2903,9 +2910,7 @@ fn doge_mtp() {
"electrum2.cipig.net:10060",
"electrum3.cipig.net:10060",
]);
- let mtp = electrum
- .get_median_time_past(3631820, NonZeroU64::new(11).unwrap(), CoinVariant::Standard)
- .wait()
+ let mtp = block_on_f01(electrum.get_median_time_past(3631820, NonZeroU64::new(11).unwrap(), CoinVariant::Standard))
.unwrap();
assert_eq!(mtp, 1614849084);
}
@@ -2917,9 +2922,7 @@ fn firo_mtp() {
"electrumx02.firo.org:50001",
"electrumx03.firo.org:50001",
]);
- let mtp = electrum
- .get_median_time_past(356730, NonZeroU64::new(11).unwrap(), CoinVariant::Standard)
- .wait()
+ let mtp = block_on_f01(electrum.get_median_time_past(356730, NonZeroU64::new(11).unwrap(), CoinVariant::Standard))
.unwrap();
assert_eq!(mtp, 1616492629);
}
@@ -2927,9 +2930,7 @@ fn firo_mtp() {
#[test]
fn verus_mtp() {
let electrum = electrum_client_for_test(&["el0.verus.io:17485", "el1.verus.io:17485", "el2.verus.io:17485"]);
- let mtp = electrum
- .get_median_time_past(1480113, NonZeroU64::new(11).unwrap(), CoinVariant::Standard)
- .wait()
+ let mtp = block_on_f01(electrum.get_median_time_past(1480113, NonZeroU64::new(11).unwrap(), CoinVariant::Standard))
.unwrap();
assert_eq!(mtp, 1618579909);
}
@@ -2941,9 +2942,7 @@ fn sys_mtp() {
"electrum2.cipig.net:10064",
"electrum3.cipig.net:10064",
]);
- let mtp = electrum
- .get_median_time_past(1006678, NonZeroU64::new(11).unwrap(), CoinVariant::Standard)
- .wait()
+ let mtp = block_on_f01(electrum.get_median_time_past(1006678, NonZeroU64::new(11).unwrap(), CoinVariant::Standard))
.unwrap();
assert_eq!(mtp, 1620019628);
}
@@ -2955,9 +2954,7 @@ fn btc_mtp() {
"electrum2.cipig.net:10000",
"electrum3.cipig.net:10000",
]);
- let mtp = electrum
- .get_median_time_past(681659, NonZeroU64::new(11).unwrap(), CoinVariant::Standard)
- .wait()
+ let mtp = block_on_f01(electrum.get_median_time_past(681659, NonZeroU64::new(11).unwrap(), CoinVariant::Standard))
.unwrap();
assert_eq!(mtp, 1620019527);
}
@@ -2969,9 +2966,7 @@ fn rvn_mtp() {
"electrum2.cipig.net:10051",
"electrum3.cipig.net:10051",
]);
- let mtp = electrum
- .get_median_time_past(1968120, NonZeroU64::new(11).unwrap(), CoinVariant::Standard)
- .wait()
+ let mtp = block_on_f01(electrum.get_median_time_past(1968120, NonZeroU64::new(11).unwrap(), CoinVariant::Standard))
.unwrap();
assert_eq!(mtp, 1633946264);
}
@@ -2983,10 +2978,8 @@ fn qtum_mtp() {
"electrum2.cipig.net:10050",
"electrum3.cipig.net:10050",
]);
- let mtp = electrum
- .get_median_time_past(681659, NonZeroU64::new(11).unwrap(), CoinVariant::Qtum)
- .wait()
- .unwrap();
+ let mtp =
+ block_on_f01(electrum.get_median_time_past(681659, NonZeroU64::new(11).unwrap(), CoinVariant::Qtum)).unwrap();
assert_eq!(mtp, 1598854128);
}
@@ -2997,9 +2990,7 @@ fn zer_mtp() {
"electrum2.cipig.net:10065",
"electrum3.cipig.net:10065",
]);
- let mtp = electrum
- .get_median_time_past(1130915, NonZeroU64::new(11).unwrap(), CoinVariant::Standard)
- .wait()
+ let mtp = block_on_f01(electrum.get_median_time_past(1130915, NonZeroU64::new(11).unwrap(), CoinVariant::Standard))
.unwrap();
assert_eq!(mtp, 1623240214);
}
@@ -3196,7 +3187,7 @@ fn test_withdraw_to_p2pk_fails() {
};
assert!(matches!(
- coin.withdraw(withdraw_req).wait().unwrap_err().into_inner(),
+ block_on_f01(coin.withdraw(withdraw_req)).unwrap_err().into_inner(),
WithdrawError::InvalidAddress(..)
))
}
@@ -3209,19 +3200,22 @@ fn test_withdraw_to_p2pkh() {
let coin = utxo_coin_for_test(UtxoRpcClientEnum::Native(client), None, false);
UtxoStandardCoin::get_unspent_ordered_list.mock_safe(|coin, _| {
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- let unspents = vec![UnspentInfo {
- outpoint: OutPoint {
- hash: 1.into(),
- index: 0,
- },
- value: 1000000000,
- height: Default::default(),
- script: coin
- .script_for_address(&block_on(coin.as_ref().derivation_method.unwrap_single_addr()))
- .unwrap(),
- }];
- MockResult::Return(Box::pin(futures::future::ok((unspents, cache))))
+ let fut = async move {
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ let unspents = vec![UnspentInfo {
+ outpoint: OutPoint {
+ hash: 1.into(),
+ index: 0,
+ },
+ value: 1000000000,
+ height: Default::default(),
+ script: coin
+ .script_for_address(&coin.as_ref().derivation_method.unwrap_single_addr().await)
+ .unwrap(),
+ }];
+ Ok((unspents, cache))
+ };
+ MockResult::Return(fut.boxed())
});
// Create a p2pkh address for the test coin
@@ -3249,7 +3243,7 @@ fn test_withdraw_to_p2pkh() {
memo: None,
ibc_source_channel: None,
};
- let tx_details = coin.withdraw(withdraw_req).wait().unwrap();
+ let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap();
let transaction: UtxoTx = deserialize(tx_details.tx.tx_hex().unwrap().as_slice()).unwrap();
let output_script: Script = transaction.outputs[0].script_pubkey.clone().into();
@@ -3266,19 +3260,22 @@ fn test_withdraw_to_p2sh() {
let coin = utxo_coin_for_test(UtxoRpcClientEnum::Native(client), None, false);
UtxoStandardCoin::get_unspent_ordered_list.mock_safe(|coin, _| {
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- let unspents = vec![UnspentInfo {
- outpoint: OutPoint {
- hash: 1.into(),
- index: 0,
- },
- value: 1000000000,
- height: Default::default(),
- script: coin
- .script_for_address(&block_on(coin.as_ref().derivation_method.unwrap_single_addr()))
- .unwrap(),
- }];
- MockResult::Return(Box::pin(futures::future::ok((unspents, cache))))
+ let fut = async move {
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ let unspents = vec![UnspentInfo {
+ outpoint: OutPoint {
+ hash: 1.into(),
+ index: 0,
+ },
+ value: 1000000000,
+ height: Default::default(),
+ script: coin
+ .script_for_address(&coin.as_ref().derivation_method.unwrap_single_addr().await)
+ .unwrap(),
+ }];
+ Ok((unspents, cache))
+ };
+ MockResult::Return(fut.boxed())
});
// Create a p2sh address for the test coin
@@ -3306,7 +3303,7 @@ fn test_withdraw_to_p2sh() {
memo: None,
ibc_source_channel: None,
};
- let tx_details = coin.withdraw(withdraw_req).wait().unwrap();
+ let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap();
let transaction: UtxoTx = deserialize(tx_details.tx.tx_hex().unwrap().as_slice()).unwrap();
let output_script: Script = transaction.outputs[0].script_pubkey.clone().into();
@@ -3323,19 +3320,22 @@ fn test_withdraw_to_p2wpkh() {
let coin = utxo_coin_for_test(UtxoRpcClientEnum::Native(client), None, true);
UtxoStandardCoin::get_unspent_ordered_list.mock_safe(|coin, _| {
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- let unspents = vec![UnspentInfo {
- outpoint: OutPoint {
- hash: 1.into(),
- index: 0,
- },
- value: 1000000000,
- height: Default::default(),
- script: coin
- .script_for_address(&block_on(coin.as_ref().derivation_method.unwrap_single_addr()))
- .unwrap(),
- }];
- MockResult::Return(Box::pin(futures::future::ok((unspents, cache))))
+ let fut = async move {
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ let unspents = vec![UnspentInfo {
+ outpoint: OutPoint {
+ hash: 1.into(),
+ index: 0,
+ },
+ value: 1000000000,
+ height: Default::default(),
+ script: coin
+ .script_for_address(&coin.as_ref().derivation_method.unwrap_single_addr().await)
+ .unwrap(),
+ }];
+ Ok((unspents, cache))
+ };
+ MockResult::Return(fut.boxed())
});
// Create a p2wpkh address for the test coin
@@ -3363,7 +3363,7 @@ fn test_withdraw_to_p2wpkh() {
memo: None,
ibc_source_channel: None,
};
- let tx_details = coin.withdraw(withdraw_req).wait().unwrap();
+ let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap();
let transaction: UtxoTx = deserialize(tx_details.tx.tx_hex().unwrap().as_slice()).unwrap();
let output_script: Script = transaction.outputs[0].script_pubkey.clone().into();
@@ -3380,22 +3380,29 @@ fn test_withdraw_p2pk_balance() {
let coin = utxo_coin_for_test(UtxoRpcClientEnum::Native(client), None, false);
UtxoStandardCoin::get_unspent_ordered_list.mock_safe(|coin, _| {
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- let unspents = vec![UnspentInfo {
- outpoint: OutPoint {
- hash: 1.into(),
- index: 0,
- },
- value: 1000000000,
- height: Default::default(),
- // Use a p2pk output script for this UTXO
- script: output_script_p2pk(
- &block_on(coin.as_ref().derivation_method.unwrap_single_addr())
- .pubkey()
- .unwrap(),
- ),
- }];
- MockResult::Return(Box::pin(futures::future::ok((unspents, cache))))
+ let fut = async move {
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ let unspents = vec![UnspentInfo {
+ outpoint: OutPoint {
+ hash: 1.into(),
+ index: 0,
+ },
+ value: 1000000000,
+ height: Default::default(),
+ // Use a p2pk output script for this UTXO
+ script: output_script_p2pk(
+ &coin
+ .as_ref()
+ .derivation_method
+ .unwrap_single_addr()
+ .await
+ .pubkey()
+ .unwrap(),
+ ),
+ }];
+ Ok((unspents, cache))
+ };
+ MockResult::Return(fut.boxed())
});
// Create a dummy p2pkh address to withdraw the coins to.
@@ -3411,7 +3418,7 @@ fn test_withdraw_p2pk_balance() {
memo: None,
ibc_source_channel: None,
};
- let tx_details = coin.withdraw(withdraw_req).wait().unwrap();
+ let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap();
let transaction: UtxoTx = deserialize(tx_details.tx.tx_hex().unwrap().as_slice()).unwrap();
// The change should be in a p2pkh script.
@@ -3432,8 +3439,11 @@ fn test_utxo_standard_with_check_utxo_maturity_true() {
UtxoStandardCoin::get_mature_unspent_ordered_list.mock_safe(|coin, _| {
unsafe { GET_MATURE_UNSPENT_ORDERED_LIST_CALLED = true };
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- MockResult::Return(Box::pin(futures::future::ok((MatureUnspentList::default(), cache))))
+ let fut = async move {
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ Ok((MatureUnspentList::default(), cache))
+ };
+ MockResult::Return(fut.boxed())
});
let conf = json!({"coin":"RICK","asset":"RICK","rpcport":25435,"txversion":4,"overwintered":1,"mm2":1,"protocol":{"type":"UTXO"}});
@@ -3451,7 +3461,7 @@ fn test_utxo_standard_with_check_utxo_maturity_true() {
let address = Address::from_legacyaddress("R9o9xTocqr6CeEDGDH6mEYpwLoMz6jNjMW", &KMD_PREFIXES).unwrap();
// Don't use `block_on` here because it's used within a mock of [`GetUtxoListOps::get_mature_unspent_ordered_list`].
- coin.get_unspent_ordered_list(&address).compat().wait().unwrap();
+ block_on_f01(coin.get_unspent_ordered_list(&address).compat()).unwrap();
assert!(unsafe { GET_MATURE_UNSPENT_ORDERED_LIST_CALLED });
}
@@ -3464,9 +3474,11 @@ fn test_utxo_standard_without_check_utxo_maturity() {
UtxoStandardCoin::get_all_unspent_ordered_list.mock_safe(|coin, _| {
unsafe { GET_ALL_UNSPENT_ORDERED_LIST_CALLED = true };
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- let unspents = Vec::new();
- MockResult::Return(Box::pin(futures::future::ok((unspents, cache))))
+ let fut = async move {
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ Ok((Vec::new(), cache))
+ };
+ MockResult::Return(fut.boxed())
});
UtxoStandardCoin::get_mature_unspent_ordered_list.mock_safe(|_, _| {
@@ -3487,7 +3499,7 @@ fn test_utxo_standard_without_check_utxo_maturity() {
let address = Address::from_legacyaddress("R9o9xTocqr6CeEDGDH6mEYpwLoMz6jNjMW", &KMD_PREFIXES).unwrap();
// Don't use `block_on` here because it's used within a mock of [`UtxoStandardCoin::get_all_unspent_ordered_list`].
- coin.get_unspent_ordered_list(&address).compat().wait().unwrap();
+ block_on_f01(coin.get_unspent_ordered_list(&address).compat()).unwrap();
assert!(unsafe { GET_ALL_UNSPENT_ORDERED_LIST_CALLED });
}
@@ -3500,8 +3512,11 @@ fn test_qtum_without_check_utxo_maturity() {
QtumCoin::get_mature_unspent_ordered_list.mock_safe(|coin, _| {
unsafe { GET_MATURE_UNSPENT_ORDERED_LIST_CALLED = true };
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- MockResult::Return(Box::pin(futures::future::ok((MatureUnspentList::default(), cache))))
+ let fut = async move {
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ Ok((MatureUnspentList::default(), cache))
+ };
+ MockResult::Return(fut.boxed())
});
let conf = json!({"coin":"tQTUM","rpcport":13889,"pubtype":120,"p2shtype":110});
@@ -3526,7 +3541,7 @@ fn test_qtum_without_check_utxo_maturity() {
)
.unwrap();
// Don't use `block_on` here because it's used within a mock of [`QtumCoin::get_mature_unspent_ordered_list`].
- coin.get_unspent_ordered_list(&address).compat().wait().unwrap();
+ block_on_f01(coin.get_unspent_ordered_list(&address).compat()).unwrap();
assert!(unsafe { GET_MATURE_UNSPENT_ORDERED_LIST_CALLED });
}
@@ -3604,9 +3619,12 @@ fn test_qtum_with_check_utxo_maturity_false() {
QtumCoin::get_all_unspent_ordered_list.mock_safe(|coin, _address| {
unsafe { GET_ALL_UNSPENT_ORDERED_LIST_CALLED = true };
- let cache = block_on(coin.as_ref().recently_spent_outpoints.lock());
- let unspents = Vec::new();
- MockResult::Return(Box::pin(futures::future::ok((unspents, cache))))
+ let fut = async move {
+ let cache = coin.as_ref().recently_spent_outpoints.lock().await;
+ let unspents = Vec::new();
+ Ok((unspents, cache))
+ };
+ MockResult::Return(fut.boxed())
});
QtumCoin::get_mature_unspent_ordered_list.mock_safe(|_, _| {
panic!(
@@ -3637,7 +3655,7 @@ fn test_qtum_with_check_utxo_maturity_false() {
)
.unwrap();
// Don't use `block_on` here because it's used within a mock of [`QtumCoin::get_all_unspent_ordered_list`].
- coin.get_unspent_ordered_list(&address).compat().wait().unwrap();
+ block_on_f01(coin.get_unspent_ordered_list(&address).compat()).unwrap();
assert!(unsafe { GET_ALL_UNSPENT_ORDERED_LIST_CALLED });
}
@@ -4365,7 +4383,9 @@ fn test_for_non_existent_tx_hex_utxo_electrum() {
wait_until: timeout,
check_every: 1,
};
- let actual = coin.wait_for_confirmations(confirm_payment_input).wait().err().unwrap();
+ let actual = block_on_f01(coin.wait_for_confirmations(confirm_payment_input))
+ .err()
+ .unwrap();
assert!(actual.contains(
"Tx d342ff9da528a2e262bddf2b6f9a27d1beb7aeb03f0fc8d9eac2987266447e44 was not found on chain after 10 tries"
));
@@ -4408,10 +4428,7 @@ fn test_native_display_balances() {
Address::from_legacyaddress("RJeDDtDRtKUoL8BCKdH7TNCHqUKr7kQRsi", &KMD_PREFIXES).unwrap(),
Address::from_legacyaddress("RQHn9VPHBqNjYwyKfJbZCiaxVrWPKGQjeF", &KMD_PREFIXES).unwrap(),
];
- let actual = rpc_client
- .display_balances(addresses, TEST_COIN_DECIMALS)
- .wait()
- .unwrap();
+ let actual = block_on_f01(rpc_client.display_balances(addresses, TEST_COIN_DECIMALS)).unwrap();
let expected: Vec<(Address, BigDecimal)> = vec![
(
@@ -4549,7 +4566,6 @@ fn test_utxo_validate_valid_and_invalid_pubkey() {
#[test]
fn test_block_header_utxo_loop() {
use crate::utxo::utxo_builder::{block_header_utxo_loop, BlockHeaderUtxoLoopExtraArgs};
- use futures::future::{Either, FutureExt};
use keys::hash::H256 as H256Json;
static mut CURRENT_BLOCK_COUNT: u64 = 13;
diff --git a/mm2src/coins/z_coin/storage/walletdb/wasm/mod.rs b/mm2src/coins/z_coin/storage/walletdb/wasm/mod.rs
index 907a007c55..4c68fec22c 100644
--- a/mm2src/coins/z_coin/storage/walletdb/wasm/mod.rs
+++ b/mm2src/coins/z_coin/storage/walletdb/wasm/mod.rs
@@ -253,7 +253,12 @@ mod wasm_test {
// scan the cache
let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
blockdb
- .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ .process_blocks_with_mode(
+ consensus_params.clone(),
+ BlockProcessingMode::Scan(scan, None),
+ None,
+ None,
+ )
.await
.unwrap();
@@ -293,7 +298,12 @@ mod wasm_test {
// Scan the cache again
let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
blockdb
- .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ .process_blocks_with_mode(
+ consensus_params.clone(),
+ BlockProcessingMode::Scan(scan, None),
+ None,
+ None,
+ )
.await
.unwrap();
@@ -347,7 +357,12 @@ mod wasm_test {
// Scan the cache again
let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
blockdb
- .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ .process_blocks_with_mode(
+ consensus_params.clone(),
+ BlockProcessingMode::Scan(scan, None),
+ None,
+ None,
+ )
.await
.unwrap();
@@ -436,7 +451,12 @@ mod wasm_test {
// Scan the cache again
let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
blockdb
- .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ .process_blocks_with_mode(
+ consensus_params.clone(),
+ BlockProcessingMode::Scan(scan, None),
+ None,
+ None,
+ )
.await
.unwrap();
@@ -520,7 +540,12 @@ mod wasm_test {
// Scan the cache
let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
blockdb
- .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ .process_blocks_with_mode(
+ consensus_params.clone(),
+ BlockProcessingMode::Scan(scan, None),
+ None,
+ None,
+ )
.await
.unwrap();
@@ -545,7 +570,12 @@ mod wasm_test {
// Scan the cache again
let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
blockdb
- .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ .process_blocks_with_mode(
+ consensus_params.clone(),
+ BlockProcessingMode::Scan(scan, None),
+ None,
+ None,
+ )
.await
.unwrap();
@@ -579,7 +609,12 @@ mod wasm_test {
// Scan cache
let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
blockdb
- .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ .process_blocks_with_mode(
+ consensus_params.clone(),
+ BlockProcessingMode::Scan(scan, None),
+ None,
+ None,
+ )
.await
.unwrap();
@@ -592,7 +627,12 @@ mod wasm_test {
// Scan the cache again
let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
let scan = blockdb
- .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ .process_blocks_with_mode(
+ consensus_params.clone(),
+ BlockProcessingMode::Scan(scan, None),
+ None,
+ None,
+ )
.await
.unwrap_err();
match scan.get_inner() {
@@ -611,7 +651,12 @@ mod wasm_test {
blockdb.insert_block(cb2.height as u32, cb2_bytes).await.unwrap();
let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
assert!(blockdb
- .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ .process_blocks_with_mode(
+ consensus_params.clone(),
+ BlockProcessingMode::Scan(scan, None),
+ None,
+ None
+ )
.await
.is_ok());
@@ -650,7 +695,12 @@ mod wasm_test {
// Scan the cache
let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
assert!(blockdb
- .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ .process_blocks_with_mode(
+ consensus_params.clone(),
+ BlockProcessingMode::Scan(scan, None),
+ None,
+ None
+ )
.await
.is_ok());
@@ -666,7 +716,12 @@ mod wasm_test {
// Scan the cache again
let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
assert!(blockdb
- .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ .process_blocks_with_mode(
+ consensus_params.clone(),
+ BlockProcessingMode::Scan(scan, None),
+ None,
+ None
+ )
.await
.is_ok());
@@ -703,7 +758,12 @@ mod wasm_test {
// Scan the cache
let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
assert!(blockdb
- .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ .process_blocks_with_mode(
+ consensus_params.clone(),
+ BlockProcessingMode::Scan(scan, None),
+ None,
+ None
+ )
.await
.is_ok());
@@ -728,7 +788,12 @@ mod wasm_test {
// Scan the cache again
let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
let scan = blockdb
- .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ .process_blocks_with_mode(
+ consensus_params.clone(),
+ BlockProcessingMode::Scan(scan, None),
+ None,
+ None,
+ )
.await;
assert!(scan.is_ok());
@@ -767,7 +832,7 @@ mod wasm_test {
// // Scan the cache
// let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
// assert!(blockdb
- // .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ // .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan, None), None, None)
// .await
// .is_ok());
//
@@ -787,7 +852,7 @@ mod wasm_test {
// // Scan the cache
// let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
// assert!(blockdb
- // .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ // .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan, None), None, None)
// .await
// .is_ok());
//
@@ -832,7 +897,7 @@ mod wasm_test {
// // Scan the cache
// let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
// assert!(blockdb
- // .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ // .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan, None), None, None)
// .await
// .is_ok());
//
@@ -863,7 +928,7 @@ mod wasm_test {
// // Scan the cache
// let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
// assert!(blockdb
- // .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ // .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan, None), None, None)
// .await
// .is_ok());
//
@@ -1033,7 +1098,7 @@ mod wasm_test {
// // Scan the cache
// let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
// blockdb
- // .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ // .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan, None), None, None)
// .await
// .unwrap();
// assert_eq!(walletdb.get_balance(AccountId(0)).await.unwrap(), value);
@@ -1090,7 +1155,7 @@ mod wasm_test {
// // Scan the cache
// let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
// blockdb
- // .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ // .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan, None), None, None)
// .await
// .unwrap();
//
@@ -1126,7 +1191,7 @@ mod wasm_test {
// // Scan the cache
// let scan = DataConnStmtCacheWrapper::new(DataConnStmtCacheWasm(walletdb.clone()));
// blockdb
- // .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan), None, None)
+ // .process_blocks_with_mode(consensus_params.clone(), BlockProcessingMode::Scan(scan, None), None, None)
// .await
// .unwrap();
//
diff --git a/mm2src/coins/z_coin/z_coin_native_tests.rs b/mm2src/coins/z_coin/z_coin_native_tests.rs
index 9e4358727d..790f42818f 100644
--- a/mm2src/coins/z_coin/z_coin_native_tests.rs
+++ b/mm2src/coins/z_coin/z_coin_native_tests.rs
@@ -1,14 +1,13 @@
use bitcrypto::dhash160;
-use common::{block_on, now_sec};
+use common::{block_on, block_on_f01, now_sec};
use mm2_core::mm_ctx::MmCtxBuilder;
use mm2_test_helpers::for_tests::zombie_conf;
use std::path::PathBuf;
use std::time::Duration;
use zcash_client_backend::encoding::decode_extended_spending_key;
-use super::{z_coin_from_conf_and_params_with_z_key, z_mainnet_constants, Future, PrivKeyBuildPolicy,
- RefundPaymentArgs, SendPaymentArgs, SpendPaymentArgs, SwapOps, ValidateFeeArgs, ValidatePaymentError,
- ZTransaction};
+use super::{z_coin_from_conf_and_params_with_z_key, z_mainnet_constants, PrivKeyBuildPolicy, RefundPaymentArgs,
+ SendPaymentArgs, SpendPaymentArgs, SwapOps, ValidateFeeArgs, ValidatePaymentError, ZTransaction};
use crate::z_coin::{z_htlc::z_send_dex_fee, ZcoinActivationParams, ZcoinRpcMode};
use crate::DexFee;
use crate::{CoinProtocol, SwapTxTypeWithSecretHash};
@@ -55,7 +54,7 @@ fn zombie_coin_send_and_refund_maker_payment() {
watcher_reward: None,
wait_for_confirmation_until: 0,
};
- let tx = coin.send_maker_payment(args).wait().unwrap();
+ let tx = block_on_f01(coin.send_maker_payment(args)).unwrap();
log!("swap tx {}", hex::encode(tx.tx_hash_as_bytes().0));
let refund_args = RefundPaymentArgs {
@@ -116,7 +115,7 @@ fn zombie_coin_send_and_spend_maker_payment() {
wait_for_confirmation_until: 0,
};
- let tx = coin.send_maker_payment(maker_payment_args).wait().unwrap();
+ let tx = block_on_f01(coin.send_maker_payment(maker_payment_args)).unwrap();
log!("swap tx {}", hex::encode(tx.tx_hash_as_bytes().0));
let maker_pub = taker_pub;
@@ -234,7 +233,9 @@ fn zombie_coin_validate_dex_fee() {
uuid: &[1; 16],
};
// Invalid amount should return an error
- let err = coin.validate_fee(validate_fee_args).wait().unwrap_err().into_inner();
+ let err = block_on_f01(coin.validate_fee(validate_fee_args))
+ .unwrap_err()
+ .into_inner();
match err {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("Dex fee has invalid amount")),
_ => panic!("Expected `WrongPaymentTx`: {:?}", err),
@@ -249,7 +250,9 @@ fn zombie_coin_validate_dex_fee() {
min_block_number: 12000,
uuid: &[2; 16],
};
- let err = coin.validate_fee(validate_fee_args).wait().unwrap_err().into_inner();
+ let err = block_on_f01(coin.validate_fee(validate_fee_args))
+ .unwrap_err()
+ .into_inner();
match err {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("Dex fee has invalid memo")),
_ => panic!("Expected `WrongPaymentTx`: {:?}", err),
@@ -264,7 +267,9 @@ fn zombie_coin_validate_dex_fee() {
min_block_number: 14000,
uuid: &[1; 16],
};
- let err = coin.validate_fee(validate_fee_args).wait().unwrap_err().into_inner();
+ let err = block_on_f01(coin.validate_fee(validate_fee_args))
+ .unwrap_err()
+ .into_inner();
match err {
ValidatePaymentError::WrongPaymentTx(err) => assert!(err.contains("confirmed before min block")),
_ => panic!("Expected `WrongPaymentTx`: {:?}", err),
@@ -279,7 +284,7 @@ fn zombie_coin_validate_dex_fee() {
min_block_number: 12000,
uuid: &[1; 16],
};
- coin.validate_fee(validate_fee_args).wait().unwrap();
+ block_on_f01(coin.validate_fee(validate_fee_args)).unwrap();
}
fn default_zcoin_activation_params() -> ZcoinActivationParams {
diff --git a/mm2src/common/common.rs b/mm2src/common/common.rs
index 13ec32bcb9..8eac389e58 100644
--- a/mm2src/common/common.rs
+++ b/mm2src/common/common.rs
@@ -518,19 +518,6 @@ pub fn set_panic_hook() {
}))
}
-/// Simulates the panic-in-panic crash.
-pub fn double_panic_crash() {
- struct Panicker;
- impl Drop for Panicker {
- fn drop(&mut self) { panic!("panic in drop") }
- }
- let panicker = Panicker;
- if 1 < 2 {
- panic!("first panic")
- }
- drop(panicker) // Delays the drop.
-}
-
/// RPC response, returned by the RPC handlers.
/// NB: By default the future is executed on the shared asynchronous reactor (`CORE`),
/// the handler is responsible for spawning the future on another reactor if it doesn't fit the `CORE` well.
@@ -634,7 +621,20 @@ pub fn var(name: &str) -> Result {
#[cfg(target_arch = "wasm32")]
pub fn var(_name: &str) -> Result { ERR!("Environment variable not supported in WASM") }
+/// Runs the given future on MM2's executor and waits for the result.
+///
+/// This is compatible with futures 0.1.
+pub fn block_on_f01(f: F) -> Result
+where
+ F: Future,
+{
+ block_on(f.compat())
+}
+
#[cfg(not(target_arch = "wasm32"))]
+/// Runs the given future on MM2's executor and waits for the result.
+///
+/// This is compatible with futures 0.3.
pub fn block_on(f: F) -> F::Output
where
F: Future03,
diff --git a/mm2src/mm2_bin_lib/src/lib.rs b/mm2src/mm2_bin_lib/src/lib.rs
index 81c532419f..c78233e64a 100644
--- a/mm2src/mm2_bin_lib/src/lib.rs
+++ b/mm2src/mm2_bin_lib/src/lib.rs
@@ -99,5 +99,5 @@ fn prepare_for_mm2_stop() -> PrepareForStopResult {
async fn finalize_mm2_stop(ctx: MmArc) {
dispatch_lp_event(ctx.clone(), StopCtxEvent.into()).await;
- let _ = ctx.stop();
+ let _ = ctx.stop().await;
}
diff --git a/mm2src/mm2_core/src/lib.rs b/mm2src/mm2_core/src/lib.rs
index 62e4bef09c..88b0fd5c81 100644
--- a/mm2src/mm2_core/src/lib.rs
+++ b/mm2src/mm2_core/src/lib.rs
@@ -1,10 +1,11 @@
-use derive_more::Display;
-use rand::{thread_rng, Rng};
+#[cfg(target_arch = "wasm32")] use derive_more::Display;
+#[cfg(target_arch = "wasm32")] use rand::{thread_rng, Rng};
pub mod data_asker;
pub mod event_dispatcher;
pub mod mm_ctx;
+#[cfg(target_arch = "wasm32")]
#[derive(Clone, Copy, Display, PartialEq, Default)]
pub enum DbNamespaceId {
#[display(fmt = "MAIN")]
@@ -14,9 +15,13 @@ pub enum DbNamespaceId {
Test(u64),
}
+#[cfg(target_arch = "wasm32")]
impl DbNamespaceId {
pub fn for_test() -> DbNamespaceId {
let mut rng = thread_rng();
DbNamespaceId::Test(rng.gen())
}
+
+ #[inline(always)]
+ pub fn for_test_with_id(id: u64) -> DbNamespaceId { DbNamespaceId::Test(id) }
}
diff --git a/mm2src/mm2_core/src/mm_ctx.rs b/mm2src/mm2_core/src/mm_ctx.rs
index ec7ceb036a..c61b4e1aba 100644
--- a/mm2src/mm2_core/src/mm_ctx.rs
+++ b/mm2src/mm2_core/src/mm_ctx.rs
@@ -290,7 +290,6 @@ impl MmCtx {
/// Returns the path to the MM databases root.
#[cfg(not(target_arch = "wasm32"))]
pub fn db_root(&self) -> PathBuf { path_to_db_root(self.conf["dbdir"].as_str()) }
-
#[cfg(not(target_arch = "wasm32"))]
pub fn wallet_file_path(&self, wallet_name: &str) -> PathBuf {
self.db_root().join(wallet_name.to_string() + ".dat")
@@ -503,7 +502,10 @@ lazy_static! {
impl MmArc {
pub fn new(ctx: MmCtx) -> MmArc { MmArc(SharedRc::new(ctx)) }
- pub fn stop(&self) -> Result<(), String> {
+ pub async fn stop(&self) -> Result<(), String> {
+ #[cfg(not(target_arch = "wasm32"))]
+ try_s!(self.close_async_connection().await);
+
try_s!(self.stop.pin(true));
// Notify shutdown listeners.
@@ -517,6 +519,16 @@ impl MmArc {
Ok(())
}
+ #[cfg(not(target_arch = "wasm32"))]
+ async fn close_async_connection(&self) -> Result<(), db_common::async_sql_conn::AsyncConnError> {
+ if let Some(async_conn) = self.async_sqlite_connection.as_option() {
+ let mut conn = async_conn.lock().await;
+ conn.close().await?;
+ }
+
+ Ok(())
+ }
+
#[cfg(feature = "track-ctx-pointer")]
fn track_ctx_pointer(&self) {
let ctx_weak = self.weak();
@@ -740,6 +752,12 @@ impl MmCtxBuilder {
self
}
+ #[cfg(target_arch = "wasm32")]
+ pub fn with_test_db_namespace_with_id(mut self, id: u64) -> Self {
+ self.db_namespace = DbNamespaceId::for_test_with_id(id);
+ self
+ }
+
pub fn into_mm_arc(self) -> MmArc {
// NB: We avoid recreating LogState
// in order not to interfere with the integration tests checking LogState drop on shutdown.
diff --git a/mm2src/mm2_err_handle/src/map_to_mm_fut.rs b/mm2src/mm2_err_handle/src/map_to_mm_fut.rs
index 01de1b7d7e..0cfeb9cf13 100644
--- a/mm2src/mm2_err_handle/src/map_to_mm_fut.rs
+++ b/mm2src/mm2_err_handle/src/map_to_mm_fut.rs
@@ -21,7 +21,7 @@ where
///
/// ```rust
/// let fut = futures01::future::err("An error".to_owned());
- /// let mapped_res: Result<(), MmError> = fut.map_to_mm_fut(|e| e.len()).wait();
+ /// let mapped_res: Result<(), MmError> = block_on_f01(fut.map_to_mm_fut(|e| e.len()));
/// ```
#[track_caller]
fn map_to_mm_fut(self, f: F) -> MapToMmFuture<'a, T, E1, E2>
diff --git a/mm2src/mm2_err_handle/src/mm_error.rs b/mm2src/mm2_err_handle/src/mm_error.rs
index 56e7f29f50..1ea7bf1555 100644
--- a/mm2src/mm2_err_handle/src/mm_error.rs
+++ b/mm2src/mm2_err_handle/src/mm_error.rs
@@ -332,6 +332,7 @@ impl FormattedTrace for Vec {
mod tests {
use super::*;
use crate::prelude::*;
+ use common::block_on_f01;
use futures01::Future;
use ser_error_derive::SerializeErrorType;
use serde_json::{self as json, json};
@@ -425,10 +426,8 @@ mod tests {
}
let into_mm_line = line!() + 2;
- let mm_err = generate_error("An error")
- .map_to_mm_fut(|error| error.len())
- .wait()
- .expect_err("Expected an error");
+ let mm_err =
+ block_on_f01(generate_error("An error").map_to_mm_fut(|error| error.len())).expect_err("Expected an error");
assert_eq!(mm_err.etype, 8);
assert_eq!(mm_err.trace, vec![TraceLocation::new("mm_error", into_mm_line)]);
}
diff --git a/mm2src/mm2_io/src/fs.rs b/mm2src/mm2_io/src/fs.rs
index 94a323c0b8..489b3bad8b 100644
--- a/mm2src/mm2_io/src/fs.rs
+++ b/mm2src/mm2_io/src/fs.rs
@@ -192,19 +192,52 @@ where
json::from_slice(&content).map_to_mm(FsJsonError::Deserializing)
}
-/// Read the `dir_path` entries trying to deserialize each as the `T` type.
+async fn filter_files_by_extension(dir_path: &Path, extension: &str) -> IoResult> {
+ let ext = Some(OsStr::new(extension).to_ascii_lowercase());
+ let entries = read_dir_async(dir_path)
+ .await?
+ .into_iter()
+ .filter(|path| path.extension().map(|ext| ext.to_ascii_lowercase()) == ext)
+ .collect();
+ Ok(entries)
+}
+
+/// Helper function to extract file names or stems based on the provided extraction function.
+fn extract_file_identifiers<'a, F>(entries: Vec, extractor: F) -> impl Iterator- + 'a
+where
+ F: Fn(&Path) -> Option<&OsStr> + 'a,
+{
+ entries
+ .into_iter()
+ .filter_map(move |path| extractor(&path).and_then(OsStr::to_str).map(ToOwned::to_owned))
+}
+
+/// Lists files by the specified extension from the given directory path.
+/// If include_extension is true, returns full file names; otherwise, returns file stems.
+pub async fn list_files_by_extension(
+ dir_path: &Path,
+ extension: &str,
+ include_extension: bool,
+) -> IoResult> {
+ let entries = filter_files_by_extension(dir_path, extension).await?;
+ let extractor = if include_extension {
+ Path::file_name
+ } else {
+ Path::file_stem
+ };
+ Ok(extract_file_identifiers(entries, extractor))
+}
+
+/// Read the `dir_path` entries trying to deserialize each as the `T` type,
+/// filtering by the specified extension.
/// Please note that files that couldn't be deserialized are skipped.
-pub async fn read_dir_json(dir_path: &Path) -> FsJsonResult>
+pub async fn read_files_with_extension(dir_path: &Path, extension: &str) -> FsJsonResult>
where
T: DeserializeOwned,
{
- let json_ext = Some(OsStr::new("json"));
- let entries: Vec<_> = read_dir_async(dir_path)
+ let entries = filter_files_by_extension(dir_path, extension)
.await
- .mm_err(FsJsonError::IoReading)?
- .into_iter()
- .filter(|path| path.extension() == json_ext)
- .collect();
+ .mm_err(FsJsonError::IoReading)?;
let type_name = std::any::type_name::();
let mut result = Vec::new();
@@ -233,6 +266,16 @@ where
Ok(result)
}
+/// Read the `dir_path` entries trying to deserialize each as the `T` type from JSON files.
+/// Please note that files that couldn't be deserialized are skipped.
+#[inline(always)]
+pub async fn read_dir_json(dir_path: &Path) -> FsJsonResult>
+where
+ T: DeserializeOwned,
+{
+ read_files_with_extension(dir_path, "json").await
+}
+
pub async fn write_json(t: &T, path: &Path, use_tmp_file: bool) -> FsJsonResult<()>
where
T: Serialize,
diff --git a/mm2src/mm2_main/Cargo.toml b/mm2src/mm2_main/Cargo.toml
index 60c3e9aa62..8f84ebb90a 100644
--- a/mm2src/mm2_main/Cargo.toml
+++ b/mm2src/mm2_main/Cargo.toml
@@ -77,9 +77,6 @@ primitives = { path = "../mm2_bitcoin/primitives" }
prost = "0.11"
rand = { version = "0.7", features = ["std", "small_rng"] }
rand6 = { version = "0.6", package = "rand" }
-# TODO: Reduce the size of regex by disabling the features we don't use.
-# cf. https://github.com/rust-lang/regex/issues/583
-regex = "1"
rmp-serde = "0.14.3"
rpc = { path = "../mm2_bitcoin/rpc" }
rpc_task = { path = "../rpc_task" }
@@ -116,7 +113,7 @@ hyper = { version = "0.14.26", features = ["client", "http2", "server", "tcp"] }
rcgen = "0.10"
rustls = { version = "0.21", default-features = false }
rustls-pemfile = "1.0.2"
-tokio = { version = "1.20", features = ["io-util", "rt-multi-thread", "net"] }
+tokio = { version = "1.20", features = ["io-util", "rt-multi-thread", "net", "signal"] }
[target.'cfg(windows)'.dependencies]
winapi = "0.3"
diff --git a/mm2src/mm2_main/src/lp_wallet.rs b/mm2src/mm2_main/src/lp_wallet.rs
index 19ac357cab..559821a26a 100644
--- a/mm2src/mm2_main/src/lp_wallet.rs
+++ b/mm2src/mm2_main/src/lp_wallet.rs
@@ -2,23 +2,24 @@ use common::HttpStatusCode;
use crypto::{decrypt_mnemonic, encrypt_mnemonic, generate_mnemonic, CryptoCtx, CryptoInitError, EncryptedData,
MnemonicError};
use http::StatusCode;
+use itertools::Itertools;
use mm2_core::mm_ctx::MmArc;
use mm2_err_handle::prelude::*;
use serde::de::DeserializeOwned;
-use serde_json::{self as json};
+use serde_json::{self as json, Value as Json};
cfg_wasm32! {
use crate::lp_wallet::mnemonics_wasm_db::{WalletsDb, WalletsDBError};
use mm2_core::mm_ctx::from_ctx;
use mm2_db::indexed_db::{ConstructibleDb, DbLocked, InitDbResult};
- use mnemonics_wasm_db::{read_encrypted_passphrase_if_available, save_encrypted_passphrase};
+ use mnemonics_wasm_db::{read_all_wallet_names, read_encrypted_passphrase_if_available, save_encrypted_passphrase};
use std::sync::Arc;
type WalletsDbLocked<'a> = DbLocked<'a, WalletsDb>;
}
cfg_native! {
- use mnemonics_storage::{read_encrypted_passphrase_if_available, save_encrypted_passphrase, WalletsStorageError};
+ use mnemonics_storage::{read_all_wallet_names, read_encrypted_passphrase_if_available, save_encrypted_passphrase, WalletsStorageError};
}
#[cfg(not(target_arch = "wasm32"))] mod mnemonics_storage;
@@ -499,3 +500,53 @@ pub async fn get_mnemonic_rpc(ctx: MmArc, req: GetMnemonicRequest) -> MmResult,
+ activated_wallet: Option,
+}
+
+#[derive(Debug, Display, Serialize, SerializeErrorType)]
+#[serde(tag = "error_type", content = "error_data")]
+pub enum GetWalletsError {
+ #[display(fmt = "Wallets storage error: {}", _0)]
+ WalletsStorageError(String),
+ #[display(fmt = "Internal error: {}", _0)]
+ Internal(String),
+}
+
+impl HttpStatusCode for GetWalletsError {
+ fn status_code(&self) -> StatusCode {
+ match self {
+ GetWalletsError::WalletsStorageError(_) | GetWalletsError::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,
+ }
+ }
+}
+
+#[cfg(not(target_arch = "wasm32"))]
+impl From for GetWalletsError {
+ fn from(e: WalletsStorageError) -> Self { GetWalletsError::WalletsStorageError(e.to_string()) }
+}
+
+#[cfg(target_arch = "wasm32")]
+impl From for GetWalletsError {
+ fn from(e: WalletsDBError) -> Self { GetWalletsError::WalletsStorageError(e.to_string()) }
+}
+
+/// Retrieves all created wallets and the currently activated wallet.
+pub async fn get_wallet_names_rpc(ctx: MmArc, _req: Json) -> MmResult {
+ // We want to return wallet names in the same order for both native and wasm32 targets.
+ let wallets = read_all_wallet_names(&ctx).await?.sorted().collect();
+ // Note: `ok_or` is used here on `Constructible