From 258feab6e671c9ae9b0a40f8420b1640e379f5ae Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 26 Jun 2025 04:01:27 +0100 Subject: [PATCH 01/75] chore(core): adapt `MmError` and usages for compatibility with new rustc versions (#2443) Recent Rust compiler updates have tightened coherence rules, causing the blanket From for MmError conversions to break. Instead of refactoring the core MmError type, this commit applies a minimal, mechanical change: it inserts calls to the new .map_mm_err() helper before each ? where the conversion would fail. No changes to business logic or public API 100% an internal compatibility update --- mm2src/coins/coin_balance.rs | 23 +- mm2src/coins/eth.rs | 335 +++++---- mm2src/coins/eth/eth_balance_events.rs | 4 +- mm2src/coins/eth/eth_hd_wallet.rs | 2 +- .../eth/eth_swap_v2/eth_maker_swap_v2.rs | 6 +- .../eth/eth_swap_v2/eth_taker_swap_v2.rs | 9 +- mm2src/coins/eth/eth_withdraw.rs | 66 +- .../eth/fee_estimation/eip1559/simple.rs | 3 +- mm2src/coins/eth/nft_swap_v2/mod.rs | 6 +- mm2src/coins/eth/v2_activation.rs | 36 +- mm2src/coins/eth/wallet_connect.rs | 26 +- mm2src/coins/hd_wallet/coin_ops.rs | 40 +- mm2src/coins/hd_wallet/confirm_address.rs | 24 +- mm2src/coins/hd_wallet/mod.rs | 18 +- mm2src/coins/hd_wallet/pubkey.rs | 15 +- mm2src/coins/hd_wallet/storage/mod.rs | 2 +- .../coins/hd_wallet/storage/wasm_storage.rs | 46 +- mm2src/coins/hd_wallet/withdraw_ops.rs | 2 +- mm2src/coins/lightning.rs | 4 +- mm2src/coins/lightning/ln_utils.rs | 3 +- mm2src/coins/lp_coins.rs | 84 ++- mm2src/coins/lp_price.rs | 6 +- mm2src/coins/my_tx_history_v2.rs | 13 +- mm2src/coins/nft.rs | 272 +++++--- mm2src/coins/nft/storage/mod.rs | 4 +- mm2src/coins/nft/storage/sql_storage.rs | 4 +- mm2src/coins/nft/storage/wasm/wasm_storage.rs | 440 +++++++----- mm2src/coins/qrc20.rs | 60 +- mm2src/coins/qrc20/swap.rs | 33 +- mm2src/coins/rpc_command/account_balance.rs | 10 +- mm2src/coins/rpc_command/get_current_mtp.rs | 14 +- mm2src/coins/rpc_command/get_new_address.rs | 39 +- .../coins/rpc_command/init_account_balance.rs | 12 +- .../coins/rpc_command/init_create_account.rs | 30 +- .../init_scan_for_new_addresses.rs | 14 +- mm2src/coins/rpc_command/init_withdraw.rs | 9 +- .../rpc_command/lightning/close_channel.rs | 2 +- .../rpc_command/lightning/connect_to_node.rs | 2 +- .../rpc_command/lightning/generate_invoice.rs | 2 +- .../lightning/get_channel_details.rs | 2 +- .../lightning/get_claimable_balances.rs | 2 +- .../lightning/get_payment_details.rs | 2 +- .../rpc_command/lightning/list_channels.rs | 4 +- .../lightning/list_payments_by_filter.rs | 2 +- .../rpc_command/lightning/open_channel.rs | 15 +- .../rpc_command/lightning/send_payment.rs | 9 +- .../rpc_command/lightning/trusted_nodes.rs | 6 +- .../rpc_command/lightning/update_channel.rs | 2 +- .../coins/rpc_command/tendermint/staking.rs | 18 +- mm2src/coins/siacoin.rs | 2 +- mm2src/coins/tendermint/tendermint_coin.rs | 85 ++- mm2src/coins/tendermint/tendermint_token.rs | 19 +- .../wasm/tx_history_storage_v1.rs | 22 +- .../wasm/tx_history_storage_v2.rs | 158 +++-- mm2src/coins/utxo.rs | 2 +- mm2src/coins/utxo/bch.rs | 17 +- mm2src/coins/utxo/bchd_grpc.rs | 6 +- mm2src/coins/utxo/qtum.rs | 9 +- mm2src/coins/utxo/qtum_delegation.rs | 39 +- mm2src/coins/utxo/rpc_clients.rs | 6 +- .../utxo/rpc_clients/electrum_rpc/client.rs | 11 +- mm2src/coins/utxo/slp.rs | 100 ++- .../utxo/utxo_builder/utxo_coin_builder.rs | 36 +- mm2src/coins/utxo/utxo_common.rs | 116 ++-- .../utxo_common/utxo_tx_history_v2_common.rs | 41 +- mm2src/coins/utxo/utxo_standard.rs | 5 +- mm2src/coins/utxo/utxo_withdraw.rs | 65 +- mm2src/coins/utxo_signer/src/lib.rs | 5 +- mm2src/coins/utxo_signer/src/with_trezor.rs | 18 +- mm2src/coins/z_coin.rs | 113 +-- .../storage/blockdb/blockdb_idb_storage.rs | 73 +- .../z_coin/storage/walletdb/wasm/storage.rs | 642 ++++++++++++------ .../z_coin/storage/z_locked_notes/wasm.rs | 32 +- .../z_coin/storage/z_params/indexeddb.rs | 29 +- mm2src/coins/z_coin/z_coin_errors.rs | 5 - mm2src/coins/z_coin/z_htlc.rs | 10 +- mm2src/coins/z_coin/z_rpc.rs | 31 +- mm2src/coins/z_coin/z_tx_history.rs | 81 ++- .../src/bch_with_tokens_activation.rs | 52 +- .../src/erc20_token_activation.rs | 17 +- .../src/eth_with_token_activation.rs | 21 +- .../src/init_erc20_token_activation.rs | 17 +- mm2src/coins_activation/src/init_token.rs | 30 +- mm2src/coins_activation/src/l2/init_l2.rs | 43 +- .../src/lightning_activation.rs | 38 +- .../src/platform_coin_with_tokens.rs | 84 ++- .../src/sia_coin_activation.rs | 13 +- .../src/slp_token_activation.rs | 2 +- .../standalone_coin/init_standalone_coin.rs | 43 +- .../src/tendermint_token_activation.rs | 5 +- mm2src/coins_activation/src/token.rs | 11 +- .../src/utxo_activation/common_impl.rs | 8 +- .../utxo_activation/init_bch_activation.rs | 3 +- .../utxo_activation/init_qtum_activation.rs | 2 +- .../init_utxo_standard_activation.rs | 4 +- .../src/utxo_activation/mod.rs | 3 +- .../coins_activation/src/z_coin_activation.rs | 14 +- mm2src/crypto/src/crypto_ctx.rs | 13 +- mm2src/crypto/src/global_hd_ctx.rs | 12 +- mm2src/crypto/src/hw_client.rs | 27 +- mm2src/crypto/src/hw_ctx.rs | 16 +- mm2src/crypto/src/hw_rpc_task.rs | 9 +- mm2src/crypto/src/mnemonic.rs | 9 +- mm2src/crypto/src/privkey.rs | 2 +- mm2src/crypto/src/slip21.rs | 4 +- mm2src/crypto/src/xpub.rs | 4 +- .../src/storage/indexed_db.rs | 30 +- mm2src/kdf_walletconnect/src/storage/mod.rs | 2 +- mm2src/mm2_err_handle/src/lib.rs | 4 +- mm2src/mm2_err_handle/src/map_mm_error.rs | 25 + mm2src/mm2_err_handle/src/map_to_mm.rs | 2 +- mm2src/mm2_err_handle/src/mm_error.rs | 24 +- .../src/account/storage/wasm_storage.rs | 73 +- mm2src/mm2_gui_storage/src/rpc_commands.rs | 126 +++- mm2src/mm2_main/src/lp_init/init_hw.rs | 12 +- mm2src/mm2_main/src/lp_init/init_metamask.rs | 8 +- mm2src/mm2_main/src/lp_native_dex.rs | 14 +- mm2src/mm2_main/src/lp_ordermatch.rs | 3 +- .../src/lp_ordermatch/my_orders_storage.rs | 186 ++--- .../src/lp_ordermatch/orderbook_rpc.rs | 4 +- .../src/lp_ordermatch/simple_market_maker.rs | 10 +- mm2src/mm2_main/src/lp_stats.rs | 4 +- mm2src/mm2_main/src/lp_swap.rs | 2 +- mm2src/mm2_main/src/lp_swap/check_balance.rs | 16 +- mm2src/mm2_main/src/lp_swap/maker_swap.rs | 16 +- mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs | 12 +- .../mm2_main/src/lp_swap/max_maker_vol_rpc.rs | 4 +- .../mm2_main/src/lp_swap/my_swaps_storage.rs | 98 +-- mm2src/mm2_main/src/lp_swap/saved_swap.rs | 90 +-- mm2src/mm2_main/src/lp_swap/swap_lock.rs | 32 +- mm2src/mm2_main/src/lp_swap/swap_v2_common.rs | 58 +- mm2src/mm2_main/src/lp_swap/swap_v2_rpcs.rs | 55 +- mm2src/mm2_main/src/lp_swap/taker_swap.rs | 7 +- mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs | 12 +- mm2src/mm2_main/src/lp_swap/trade_preimage.rs | 4 +- mm2src/mm2_main/src/lp_wallet.rs | 65 +- .../src/lp_wallet/mnemonics_wasm_db.rs | 37 +- .../src/rpc/lp_commands/one_inch/rpcs.rs | 4 +- .../src/rpc/lp_commands/one_inch/types.rs | 9 +- mm2src/mm2_main/src/rpc/lp_commands/pubkey.rs | 5 +- mm2src/mm2_main/src/rpc/lp_commands/tokens.rs | 9 +- mm2src/mm2_main/src/rpc/lp_commands/trezor.rs | 3 +- mm2src/mm2_net/src/grpc_web.rs | 12 +- mm2src/mm2_net/src/native_http.rs | 2 +- mm2src/mm2_net/src/transport.rs | 2 +- mm2src/mm2_net/src/wasm/tonic_client.rs | 5 +- mm2src/trezor/src/response.rs | 17 +- mm2src/trezor/src/response_processor.rs | 3 - mm2src/trezor/src/transport/usb.rs | 16 +- mm2src/trezor/src/transport/webusb.rs | 26 +- 150 files changed, 3205 insertions(+), 2009 deletions(-) diff --git a/mm2src/coins/coin_balance.rs b/mm2src/coins/coin_balance.rs index 3ec047ee80..d985b274ed 100644 --- a/mm2src/coins/coin_balance.rs +++ b/mm2src/coins/coin_balance.rs @@ -337,7 +337,8 @@ pub trait HDWalletBalanceOps: HDWalletCoinOps { // Derive HD addresses and split addresses and their derivation paths into two collections. let (addresses, der_paths): (Vec<_>, Vec<_>) = self .derive_addresses(hd_account, address_ids) - .await? + .await + .map_mm_err()? .into_iter() .map(|hd_address| (hd_address.address(), hd_address.derivation_path().clone())) .unzip(); @@ -428,11 +429,12 @@ pub mod common_impl { HDCoinAddress: fmt::Display, { let gap_limit = hd_wallet.gap_limit(); - let mut addresses = coin.all_known_addresses_balances(hd_account).await?; + let mut addresses = coin.all_known_addresses_balances(hd_account).await.map_mm_err()?; if scan_new_addresses { addresses.extend( coin.scan_for_new_addresses(hd_wallet, hd_account, address_scanner, gap_limit) - .await?, + .await + .map_mm_err()?, ); } @@ -474,7 +476,7 @@ pub mod common_impl { HDCoinHDAccount: HDAccountStorageOps, { let mut accounts = hd_wallet.get_accounts_mut().await; - let address_scanner = coin.produce_hd_address_scanner().await?; + let address_scanner = coin.produce_hd_address_scanner().await.map_mm_err()?; let mut result = HDWalletBalance { accounts: Vec::with_capacity(accounts.len() + 1), @@ -489,8 +491,9 @@ pub mod common_impl { ); // Create new HD account. - let mut new_account = - create_new_account(coin, hd_wallet, xpub_extractor, Some(path_to_address.account_id)).await?; + let mut new_account = create_new_account(coin, hd_wallet, xpub_extractor, Some(path_to_address.account_id)) + .await + .map_mm_err()?; let scan_new_addresses = matches!( params.scan_policy, EnableCoinScanPolicy::ScanIfNewWallet | EnableCoinScanPolicy::Scan @@ -576,7 +579,10 @@ pub mod common_impl { let mut new_addresses = Vec::with_capacity(to_generate); let mut addresses_to_request = Vec::with_capacity(to_generate); for _ in 0..to_generate { - let hd_address = coin.generate_new_address(hd_wallet, hd_account, chain).await?; + let hd_address = coin + .generate_new_address(hd_wallet, hd_account, chain) + .await + .map_mm_err()?; new_addresses.push(HDAddressBalance { address: hd_address.address().display_address(), @@ -589,7 +595,8 @@ pub mod common_impl { let to_extend = coin .known_addresses_balances(addresses_to_request) - .await? + .await + .map_mm_err()? .into_iter() // The balances are guaranteed to be in the same order as they were requests. .zip(new_addresses) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 91c3294c2d..8f0fc3d385 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -1120,12 +1120,14 @@ impl InitWithdrawCoin for EthCoin { /// `withdraw_erc1155` function returns details of `ERC-1155` transaction including tx hex, /// which should be sent to`send_raw_transaction` RPC to broadcast the transaction. pub async fn withdraw_erc1155(ctx: MmArc, withdraw_type: WithdrawErc1155) -> WithdrawNftResult { - let coin = lp_coinfind_or_err(&ctx, withdraw_type.chain.to_ticker()).await?; + let coin = lp_coinfind_or_err(&ctx, withdraw_type.chain.to_ticker()) + .await + .map_mm_err()?; let (to_addr, token_addr, eth_coin) = - get_valid_nft_addr_to_withdraw(coin, &withdraw_type.to, &withdraw_type.token_address)?; + get_valid_nft_addr_to_withdraw(coin, &withdraw_type.to, &withdraw_type.token_address).map_mm_err()?; let token_id_str = &withdraw_type.token_id.to_string(); - let wallet_erc1155_amount = eth_coin.erc1155_balance(token_addr, token_id_str).await?; + let wallet_erc1155_amount = eth_coin.erc1155_balance(token_addr, token_id_str).await.map_mm_err()?; let amount_uint = if withdraw_type.max { wallet_erc1155_amount.clone() @@ -1142,14 +1144,16 @@ pub async fn withdraw_erc1155(ctx: MmArc, withdraw_type: WithdrawErc1155) -> Wit }); } - let my_address = eth_coin.derivation_method.single_addr_or_err().await?; + let my_address = eth_coin.derivation_method.single_addr_or_err().await.map_mm_err()?; let (eth_value, data, call_addr, fee_coin) = match eth_coin.coin_type { EthCoinType::Eth => { let function = ERC1155_CONTRACT.function("safeTransferFrom")?; - let token_id_u256 = - U256::from_dec_str(token_id_str).map_to_mm(|e| NumConversError::new(format!("{:?}", e)))?; - let amount_u256 = - U256::from_dec_str(&amount_uint.to_string()).map_to_mm(|e| NumConversError::new(format!("{:?}", e)))?; + let token_id_u256 = U256::from_dec_str(token_id_str) + .map_to_mm(|e| NumConversError::new(format!("{:?}", e))) + .map_mm_err()?; + let amount_u256 = U256::from_dec_str(&amount_uint.to_string()) + .map_to_mm(|e| NumConversError::new(format!("{:?}", e))) + .map_mm_err()?; let data = function.encode_input(&[ Token::Address(my_address), Token::Address(to_addr), @@ -1175,7 +1179,8 @@ pub async fn withdraw_erc1155(ctx: MmArc, withdraw_type: WithdrawErc1155) -> Wit call_addr, false, ) - .await?; + .await + .map_mm_err()?; let address_lock = eth_coin.get_address_lock(my_address.to_string()).await; let _nonce_lock = address_lock.lock().await; let (nonce, _) = eth_coin @@ -1190,12 +1195,6 @@ pub async fn withdraw_erc1155(ctx: MmArc, withdraw_type: WithdrawErc1155) -> Wit if !eth_coin.is_tx_type_supported(&tx_type) { return MmError::err(WithdrawError::TxTypeNotSupported); } - let tx_builder = UnSignedEthTxBuilder::new(tx_type, nonce, gas, Action::Call(call_addr), eth_value, data); - let tx_builder = tx_builder_with_pay_for_gas_option(ð_coin, tx_builder, &pay_for_gas_option)?; - let tx = tx_builder - .build() - .map_to_mm(|e| WithdrawError::InternalError(e.to_string()))?; - let secret = eth_coin.priv_key_policy.activated_key_or_err()?.secret(); let chain_id = match eth_coin.chain_spec { ChainSpec::Evm { chain_id } => chain_id, // Todo: Add support for Tron NFTs @@ -1205,9 +1204,15 @@ pub async fn withdraw_erc1155(ctx: MmArc, withdraw_type: WithdrawErc1155) -> Wit )) }, }; + let tx_builder = UnSignedEthTxBuilder::new(tx_type, nonce, gas, Action::Call(call_addr), eth_value, data); + let tx_builder = tx_builder_with_pay_for_gas_option(ð_coin, tx_builder, &pay_for_gas_option)?; + let tx = tx_builder + .build() + .map_to_mm(|e| WithdrawError::InternalError(e.to_string()))?; + let secret = eth_coin.priv_key_policy.activated_key_or_err().map_mm_err()?.secret(); let signed = tx.sign(secret, Some(chain_id))?; let signed_bytes = rlp::encode(&signed); - let fee_details = EthTxFeeDetails::new(gas, pay_for_gas_option, fee_coin)?; + let fee_details = EthTxFeeDetails::new(gas, pay_for_gas_option, fee_coin).map_mm_err()?; Ok(TransactionNftDetails { tx_hex: BytesJson::from(signed_bytes.to_vec()), // TODO: should we return tx_hex 0x-prefixed (everywhere)? @@ -1230,13 +1235,15 @@ pub async fn withdraw_erc1155(ctx: MmArc, withdraw_type: WithdrawErc1155) -> Wit /// `withdraw_erc721` function returns details of `ERC-721` transaction including tx hex, /// which should be sent to`send_raw_transaction` RPC to broadcast the transaction. pub async fn withdraw_erc721(ctx: MmArc, withdraw_type: WithdrawErc721) -> WithdrawNftResult { - let coin = lp_coinfind_or_err(&ctx, withdraw_type.chain.to_ticker()).await?; + let coin = lp_coinfind_or_err(&ctx, withdraw_type.chain.to_ticker()) + .await + .map_mm_err()?; let (to_addr, token_addr, eth_coin) = - get_valid_nft_addr_to_withdraw(coin, &withdraw_type.to, &withdraw_type.token_address)?; + get_valid_nft_addr_to_withdraw(coin, &withdraw_type.to, &withdraw_type.token_address).map_mm_err()?; let token_id_str = &withdraw_type.token_id.to_string(); - let token_owner = eth_coin.erc721_owner(token_addr, token_id_str).await?; - let my_address = eth_coin.derivation_method.single_addr_or_err().await?; + let token_owner = eth_coin.erc721_owner(token_addr, token_id_str).await.map_mm_err()?; + let my_address = eth_coin.derivation_method.single_addr_or_err().await.map_mm_err()?; if token_owner != my_address { return MmError::err(WithdrawError::MyAddressNotNftOwner { my_address: my_address.display_address(), @@ -1244,12 +1251,13 @@ pub async fn withdraw_erc721(ctx: MmArc, withdraw_type: WithdrawErc721) -> Withd }); } - let my_address = eth_coin.derivation_method.single_addr_or_err().await?; + let my_address = eth_coin.derivation_method.single_addr_or_err().await.map_mm_err()?; let (eth_value, data, call_addr, fee_coin) = match eth_coin.coin_type { EthCoinType::Eth => { let function = ERC721_CONTRACT.function("safeTransferFrom")?; let token_id_u256 = U256::from_dec_str(&withdraw_type.token_id.to_string()) - .map_to_mm(|e| NumConversError::new(format!("{:?}", e)))?; + .map_to_mm(|e| NumConversError::new(format!("{:?}", e))) + .map_mm_err()?; let data = function.encode_input(&[ Token::Address(my_address), Token::Address(to_addr), @@ -1274,7 +1282,8 @@ pub async fn withdraw_erc721(ctx: MmArc, withdraw_type: WithdrawErc721) -> Withd call_addr, false, ) - .await?; + .await + .map_mm_err()?; let address_lock = eth_coin.get_address_lock(my_address.to_string()).await; let _nonce_lock = address_lock.lock().await; @@ -1295,7 +1304,7 @@ pub async fn withdraw_erc721(ctx: MmArc, withdraw_type: WithdrawErc721) -> Withd let tx = tx_builder .build() .map_to_mm(|e| WithdrawError::InternalError(e.to_string()))?; - let secret = eth_coin.priv_key_policy.activated_key_or_err()?.secret(); + let secret = eth_coin.priv_key_policy.activated_key_or_err().map_mm_err()?.secret(); let chain_id = match eth_coin.chain_spec { ChainSpec::Evm { chain_id } => chain_id, // Todo: Add support for Tron NFTs @@ -1307,7 +1316,7 @@ pub async fn withdraw_erc721(ctx: MmArc, withdraw_type: WithdrawErc721) -> Withd }; let signed = tx.sign(secret, Some(chain_id))?; let signed_bytes = rlp::encode(&signed); - let fee_details = EthTxFeeDetails::new(gas, pay_for_gas_option, fee_coin)?; + let fee_details = EthTxFeeDetails::new(gas, pay_for_gas_option, fee_coin).map_mm_err()?; Ok(TransactionNftDetails { tx_hex: BytesJson::from(signed_bytes.to_vec()), @@ -1731,23 +1740,25 @@ impl WatcherOps for EthCoin { .watcher_reward .clone() .ok_or_else(|| ValidatePaymentError::WatcherRewardError("Watcher reward not found".to_string()))); - let expected_reward_amount = try_f!(wei_from_big_decimal(&watcher_reward.amount, ETH_DECIMALS)); + let expected_reward_amount = try_f!(wei_from_big_decimal(&watcher_reward.amount, ETH_DECIMALS).map_mm_err()); let expected_swap_contract_address = try_f!(input .swap_contract_address .try_to_address() - .map_to_mm(ValidatePaymentError::InvalidParameter)); + .map_to_mm(ValidatePaymentError::InvalidParameter) + .map_mm_err()); let unsigned: UnverifiedTransactionWrapper = try_f!(rlp::decode(&input.payment_tx)); - let tx = - try_f!(SignedEthTx::new(unsigned) - .map_to_mm(|err| ValidatePaymentError::TxDeserializationError(err.to_string()))); + let tx = try_f!(SignedEthTx::new(unsigned) + .map_to_mm(|err| ValidatePaymentError::TxDeserializationError(err.to_string())) + .map_mm_err()); let selfi = self.clone(); let time_lock = try_f!(input .time_lock .try_into() - .map_to_mm(ValidatePaymentError::TimelockOverflow)); + .map_to_mm(ValidatePaymentError::TimelockOverflow) + .map_mm_err()); let swap_id = selfi.etomic_swap_id(time_lock, &input.secret_hash); let decimals = self.decimals; let secret_hash = if input.secret_hash.len() == 32 { @@ -1755,10 +1766,11 @@ impl WatcherOps for EthCoin { } else { input.secret_hash.to_vec() }; - let maker_addr = - try_f!(addr_from_raw_pubkey(&input.maker_pub).map_to_mm(ValidatePaymentError::InvalidParameter)); + let maker_addr = try_f!(addr_from_raw_pubkey(&input.maker_pub) + .map_to_mm(ValidatePaymentError::InvalidParameter) + .map_mm_err()); - let trade_amount = try_f!(wei_from_big_decimal(&(input.amount), decimals)); + let trade_amount = try_f!(wei_from_big_decimal(&(input.amount), decimals).map_mm_err()); let fut = async move { match tx.unsigned().action() { Call(contract_address) => { @@ -1780,7 +1792,8 @@ impl WatcherOps for EthCoin { .payment_status(expected_swap_contract_address, Token::FixedBytes(swap_id.clone())) .compat() .await - .map_to_mm(ValidatePaymentError::Transport)?; + .map_to_mm(ValidatePaymentError::Transport) + .map_mm_err()?; let expected_status = match input.spend_type { WatcherSpendType::MakerPaymentSpend => U256::from(PaymentState::Spent as u8), WatcherSpendType::TakerPaymentRefund => U256::from(PaymentState::Refunded as u8), @@ -1804,7 +1817,8 @@ impl WatcherOps for EthCoin { .map_to_mm(|err| ValidatePaymentError::TxDeserializationError(err.to_string()))?; let swap_id_input = get_function_input_data(&decoded, function, 0) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if swap_id_input != Token::FixedBytes(swap_id.clone()) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "Transaction invalid swap_id arg {:?}, expected {:?}", @@ -1816,7 +1830,8 @@ impl WatcherOps for EthCoin { let hash_input = match input.spend_type { WatcherSpendType::MakerPaymentSpend => { let secret_input = get_function_input_data(&decoded, function, 2) - .map_to_mm(ValidatePaymentError::TxDeserializationError)? + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()? .into_fixed_bytes() .ok_or_else(|| { ValidatePaymentError::WrongPaymentTx("Invalid type for secret hash argument".to_string()) @@ -1824,7 +1839,8 @@ impl WatcherOps for EthCoin { dhash160(&secret_input).to_vec() }, WatcherSpendType::TakerPaymentRefund => get_function_input_data(&decoded, function, 2) - .map_to_mm(ValidatePaymentError::TxDeserializationError)? + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()? .into_fixed_bytes() .ok_or_else(|| { ValidatePaymentError::WrongPaymentTx("Invalid type for secret argument".to_string()) @@ -1838,9 +1854,10 @@ impl WatcherOps for EthCoin { ))); } - let my_address = selfi.derivation_method.single_addr_or_err().await?; + let my_address = selfi.derivation_method.single_addr_or_err().await.map_mm_err()?; let sender_input = get_function_input_data(&decoded, function, 4) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; let expected_sender = match input.spend_type { WatcherSpendType::MakerPaymentSpend => maker_addr, WatcherSpendType::TakerPaymentRefund => my_address, @@ -1868,7 +1885,8 @@ impl WatcherOps for EthCoin { } let reward_target_input = get_function_input_data(&decoded, function, 6) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if reward_target_input != Token::Uint(U256::from(watcher_reward.reward_target as u8)) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "Transaction reward target arg {:?} is invalid, expected {:?}", @@ -1878,7 +1896,8 @@ impl WatcherOps for EthCoin { } let contract_reward_input = get_function_input_data(&decoded, function, 7) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if contract_reward_input != Token::Bool(watcher_reward.send_contract_reward_on_spend) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "Transaction sends contract reward on spend arg {:?} is invalid, expected {:?}", @@ -1888,7 +1907,8 @@ impl WatcherOps for EthCoin { } let reward_amount_input = get_function_input_data(&decoded, function, 8) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if reward_amount_input != Token::Uint(expected_reward_amount) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "Transaction watcher reward amount arg {:?} is invalid, expected {:?}", @@ -1907,7 +1927,8 @@ impl WatcherOps for EthCoin { match &selfi.coin_type { EthCoinType::Eth => { let amount_input = get_function_input_data(&decoded, function, 1) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; let total_amount = match input.spend_type { WatcherSpendType::MakerPaymentSpend => { if !matches!(watcher_reward.reward_target, RewardTarget::None) @@ -1929,7 +1950,8 @@ impl WatcherOps for EthCoin { } let token_address_input = get_function_input_data(&decoded, function, 3) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if token_address_input != Token::Address(Address::default()) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "Transaction token address arg {:?} is invalid, expected {:?}", @@ -1943,7 +1965,8 @@ impl WatcherOps for EthCoin { token_addr, } => { let amount_input = get_function_input_data(&decoded, function, 1) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if amount_input != Token::Uint(trade_amount) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "Transaction amount arg {:?} is invalid, expected {:?}", @@ -1953,7 +1976,8 @@ impl WatcherOps for EthCoin { } let token_address_input = get_function_input_data(&decoded, function, 3) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if token_address_input != Token::Address(*token_addr) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "Transaction token address arg {:?} is invalid, expected {:?}", @@ -1976,15 +2000,20 @@ impl WatcherOps for EthCoin { fn watcher_validate_taker_payment(&self, input: WatcherValidatePaymentInput) -> ValidatePaymentFut<()> { let unsigned: UnverifiedTransactionWrapper = try_f!(rlp::decode(&input.payment_tx)); - let tx = - try_f!(SignedEthTx::new(unsigned) - .map_to_mm(|err| ValidatePaymentError::TxDeserializationError(err.to_string()))); - let sender = try_f!(addr_from_raw_pubkey(&input.taker_pub).map_to_mm(ValidatePaymentError::InvalidParameter)); - let receiver = try_f!(addr_from_raw_pubkey(&input.maker_pub).map_to_mm(ValidatePaymentError::InvalidParameter)); + let tx = try_f!(SignedEthTx::new(unsigned) + .map_to_mm(|err| ValidatePaymentError::TxDeserializationError(err.to_string())) + .map_mm_err()); + let sender = try_f!(addr_from_raw_pubkey(&input.taker_pub) + .map_to_mm(ValidatePaymentError::InvalidParameter) + .map_mm_err()); + let receiver = try_f!(addr_from_raw_pubkey(&input.maker_pub) + .map_to_mm(ValidatePaymentError::InvalidParameter) + .map_mm_err()); let time_lock = try_f!(input .time_lock .try_into() - .map_to_mm(ValidatePaymentError::TimelockOverflow)); + .map_to_mm(ValidatePaymentError::TimelockOverflow) + .map_mm_err()); let selfi = self.clone(); let swap_id = selfi.etomic_swap_id(time_lock, &input.secret_hash); @@ -2027,7 +2056,8 @@ impl WatcherOps for EthCoin { .payment_status(swap_contract_address, Token::FixedBytes(swap_id.clone())) .compat() .await - .map_to_mm(ValidatePaymentError::Transport)?; + .map_to_mm(ValidatePaymentError::Transport) + .map_mm_err()?; if status != U256::from(PaymentState::Sent as u8) && status != U256::from(PaymentState::Spent as u8) { return MmError::err(ValidatePaymentError::UnexpectedPaymentState(format!( "{INVALID_PAYMENT_STATE_ERR_LOG}: Payment state is not PAYMENT_STATE_SENT or PAYMENT_STATE_SPENT, got {status}" @@ -2038,19 +2068,22 @@ impl WatcherOps for EthCoin { .get_taker_watcher_reward(&input.maker_coin, None, None, None, input.wait_until) .await .map_err(|err| ValidatePaymentError::WatcherRewardError(err.into_inner().to_string()))?; - let expected_reward_amount = wei_from_big_decimal(&watcher_reward.amount, ETH_DECIMALS)?; + let expected_reward_amount = wei_from_big_decimal(&watcher_reward.amount, ETH_DECIMALS).map_mm_err()?; match &selfi.coin_type { EthCoinType::Eth => { let function_name = get_function_name("ethPayment", true); let function = SWAP_CONTRACT .function(&function_name) - .map_to_mm(|err| ValidatePaymentError::InternalError(err.to_string()))?; + .map_to_mm(|err| ValidatePaymentError::InternalError(err.to_string())) + .map_mm_err()?; let decoded = decode_contract_call(function, &tx_from_rpc.input.0) - .map_to_mm(|err| ValidatePaymentError::TxDeserializationError(err.to_string()))?; + .map_to_mm(|err| ValidatePaymentError::TxDeserializationError(err.to_string())) + .map_mm_err()?; let swap_id_input = get_function_input_data(&decoded, function, 0) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if swap_id_input != Token::FixedBytes(swap_id.clone()) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "{INVALID_SWAP_ID_ERR_LOG}: Invalid 'swap_id' {decoded:?}, expected {swap_id:?}" @@ -2058,7 +2091,8 @@ impl WatcherOps for EthCoin { } let receiver_input = get_function_input_data(&decoded, function, 1) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if receiver_input != Token::Address(receiver) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "{INVALID_RECEIVER_ERR_LOG}: Payment tx receiver arg {receiver_input:?} is invalid, expected {:?}", Token::Address(receiver) @@ -2066,7 +2100,8 @@ impl WatcherOps for EthCoin { } let secret_hash_input = get_function_input_data(&decoded, function, 2) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if secret_hash_input != Token::FixedBytes(secret_hash.to_vec()) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "Payment tx secret_hash arg {:?} is invalid, expected {:?}", @@ -2076,7 +2111,8 @@ impl WatcherOps for EthCoin { } let time_lock_input = get_function_input_data(&decoded, function, 3) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if time_lock_input != Token::Uint(U256::from(input.time_lock)) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "Payment tx time_lock arg {:?} is invalid, expected {:?}", @@ -2086,7 +2122,8 @@ impl WatcherOps for EthCoin { } let reward_target_input = get_function_input_data(&decoded, function, 4) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; let expected_reward_target = watcher_reward.reward_target as u8; if reward_target_input != Token::Uint(U256::from(expected_reward_target)) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( @@ -2096,7 +2133,8 @@ impl WatcherOps for EthCoin { } let sends_contract_reward_input = get_function_input_data(&decoded, function, 5) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if sends_contract_reward_input != Token::Bool(watcher_reward.send_contract_reward_on_spend) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "Payment tx sends_contract_reward_on_spend arg {:?} is invalid, expected {:?}", @@ -2105,13 +2143,15 @@ impl WatcherOps for EthCoin { } let reward_amount_input = get_function_input_data(&decoded, function, 6) - .map_to_mm(ValidatePaymentError::TxDeserializationError)? + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()? .into_uint() .ok_or_else(|| { ValidatePaymentError::WrongPaymentTx("Invalid type for reward amount argument".to_string()) })?; - validate_watcher_reward(expected_reward_amount.as_u64(), reward_amount_input.as_u64(), false)?; + validate_watcher_reward(expected_reward_amount.as_u64(), reward_amount_input.as_u64(), false) + .map_mm_err()?; // TODO: Validate the value }, @@ -2122,12 +2162,15 @@ impl WatcherOps for EthCoin { let function_name = get_function_name("erc20Payment", true); let function = SWAP_CONTRACT .function(&function_name) - .map_to_mm(|err| ValidatePaymentError::InternalError(err.to_string()))?; + .map_to_mm(|err| ValidatePaymentError::InternalError(err.to_string())) + .map_mm_err()?; let decoded = decode_contract_call(function, &tx_from_rpc.input.0) - .map_to_mm(|err| ValidatePaymentError::TxDeserializationError(err.to_string()))?; + .map_to_mm(|err| ValidatePaymentError::TxDeserializationError(err.to_string())) + .map_mm_err()?; let swap_id_input = get_function_input_data(&decoded, function, 0) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if swap_id_input != Token::FixedBytes(swap_id.clone()) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "{INVALID_SWAP_ID_ERR_LOG}: Invalid 'swap_id' {decoded:?}, expected {swap_id:?}" @@ -2135,7 +2178,8 @@ impl WatcherOps for EthCoin { } let token_addr_input = get_function_input_data(&decoded, function, 2) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if token_addr_input != Token::Address(*token_addr) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "Payment tx token_addr arg {:?} is invalid, expected {:?}", @@ -2145,7 +2189,8 @@ impl WatcherOps for EthCoin { } let receiver_addr_input = get_function_input_data(&decoded, function, 3) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if receiver_addr_input != Token::Address(receiver) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "{INVALID_RECEIVER_ERR_LOG}: Payment tx receiver arg {receiver_addr_input:?} is invalid, expected {:?}", Token::Address(receiver), @@ -2153,7 +2198,8 @@ impl WatcherOps for EthCoin { } let secret_hash_input = get_function_input_data(&decoded, function, 4) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if secret_hash_input != Token::FixedBytes(secret_hash.to_vec()) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "Payment tx secret_hash arg {:?} is invalid, expected {:?}", @@ -2163,7 +2209,8 @@ impl WatcherOps for EthCoin { } let time_lock_input = get_function_input_data(&decoded, function, 5) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if time_lock_input != Token::Uint(U256::from(input.time_lock)) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "Payment tx time_lock arg {:?} is invalid, expected {:?}", @@ -2173,7 +2220,8 @@ impl WatcherOps for EthCoin { } let reward_target_input = get_function_input_data(&decoded, function, 6) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; let expected_reward_target = watcher_reward.reward_target as u8; if reward_target_input != Token::Uint(U256::from(expected_reward_target)) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( @@ -2183,7 +2231,8 @@ impl WatcherOps for EthCoin { } let sends_contract_reward_input = get_function_input_data(&decoded, function, 7) - .map_to_mm(ValidatePaymentError::TxDeserializationError)?; + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()?; if sends_contract_reward_input != Token::Bool(watcher_reward.send_contract_reward_on_spend) { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( "Payment tx sends_contract_reward_on_spend arg {:?} is invalid, expected {:?}", @@ -2192,13 +2241,15 @@ impl WatcherOps for EthCoin { } let reward_amount_input = get_function_input_data(&decoded, function, 8) - .map_to_mm(ValidatePaymentError::TxDeserializationError)? + .map_to_mm(ValidatePaymentError::TxDeserializationError) + .map_mm_err()? .into_uint() .ok_or_else(|| { ValidatePaymentError::WrongPaymentTx("Invalid type for reward amount argument".to_string()) })?; - validate_watcher_reward(expected_reward_amount.as_u64(), reward_amount_input.as_u64(), false)?; + validate_watcher_reward(expected_reward_amount.as_u64(), reward_amount_input.as_u64(), false) + .map_mm_err()?; if tx_from_rpc.value != reward_amount_input { return MmError::err(ValidatePaymentError::WrongPaymentTx(format!( @@ -2395,18 +2446,24 @@ impl MarketCoinOps for EthCoin { let message_hash = self.sign_message_hash(message).ok_or(SignatureError::PrefixNotFound)?; let secret = if let Some(address) = address { - let path_to_coin = self.priv_key_policy.path_to_coin_or_err()?; + let path_to_coin = self.priv_key_policy.path_to_coin_or_err().map_mm_err()?; let derivation_path = address .valid_derivation_path(path_to_coin) - .mm_err(|err| SignatureError::InvalidRequest(err.to_string()))?; + .mm_err(|err| SignatureError::InvalidRequest(err.to_string())) + .map_mm_err()?; let privkey = self .priv_key_policy - .hd_wallet_derived_priv_key_or_err(&derivation_path)?; + .hd_wallet_derived_priv_key_or_err(&derivation_path) + .map_mm_err()?; ethkey::Secret::from_slice(privkey.as_slice()).ok_or(MmError::new(SignatureError::InternalError( "failed to derive ethkey::Secret".to_string(), )))? } else { - self.priv_key_policy.activated_key_or_err()?.secret().clone() + self.priv_key_policy + .activated_key_or_err() + .map_mm_err()? + .secret() + .clone() }; let signature = sign(&secret, &H256::from(message_hash))?; @@ -2429,7 +2486,7 @@ impl MarketCoinOps for EthCoin { let decimals = self.decimals; let fut = self .get_balance() - .and_then(move |result| Ok(u256_to_big_decimal(result, decimals)?)) + .and_then(move |result| u256_to_big_decimal(result, decimals).map_mm_err()) .map(|spendable| CoinBalance { spendable, unspendable: BigDecimal::from(0), @@ -2440,7 +2497,7 @@ impl MarketCoinOps for EthCoin { fn base_coin_balance(&self) -> BalanceFut { Box::new( self.eth_balance() - .and_then(move |result| Ok(u256_to_big_decimal(result, ETH_DECIMALS)?)), + .and_then(move |result| u256_to_big_decimal(result, ETH_DECIMALS).map_mm_err()), ) } @@ -2826,7 +2883,8 @@ async fn sign_and_send_transaction_with_metamask( /// Sign eth transaction async fn sign_raw_eth_tx(coin: &EthCoin, args: &SignEthTransactionParams) -> RawTransactionResult { - let value = wei_from_big_decimal(args.value.as_ref().unwrap_or(&BigDecimal::from(0)), coin.decimals)?; + let value = + wei_from_big_decimal(args.value.as_ref().unwrap_or(&BigDecimal::from(0)), coin.decimals).map_mm_err()?; let action = if let Some(to) = &args.to { Call(Address::from_str(to).map_to_mm(|err| RawTransactionError::InvalidParam(err.to_string()))?) } else { @@ -2848,11 +2906,11 @@ async fn sign_raw_eth_tx(coin: &EthCoin, args: &SignEthTransactionParams) -> Raw let address_lock = coin.get_address_lock(my_address.to_string()).await; let _nonce_lock = address_lock.lock().await; let pay_for_gas_option = if let Some(ref pay_for_gas) = args.pay_for_gas { - pay_for_gas.clone().try_into()? + pay_for_gas.clone().try_into().map_mm_err()? } else { // use legacy gas_price() if not set info!(target: "sign-and-send", "get_gas_price…"); - let gas_price = coin.get_gas_price().await?; + let gas_price = coin.get_gas_price().await.map_mm_err()?; PayForGasOption::Legacy(LegacyGasPrice { gas_price }) }; sign_transaction_with_keypair( @@ -2892,11 +2950,11 @@ async fn sign_raw_eth_tx(coin: &EthCoin, args: &SignEthTransactionParams) -> Raw let address_lock = coin.get_address_lock(my_address.to_string()).await; let _nonce_lock = address_lock.lock().await; let pay_for_gas_option = if let Some(ref pay_for_gas) = args.pay_for_gas { - pay_for_gas.clone().try_into()? + pay_for_gas.clone().try_into().map_mm_err()? } else { // use legacy gas_price() if not set info!(target: "sign-and-send", "get_gas_price…"); - let gas_price = coin.get_gas_price().await?; + let gas_price = coin.get_gas_price().await.map_mm_err()?; PayForGasOption::Legacy(LegacyGasPrice { gas_price }) }; let (nonce, _) = coin @@ -4615,7 +4673,7 @@ impl EthCoin { fn get_balance(&self) -> BalanceFut { let coin = self.clone(); let fut = async move { - let my_address = coin.derivation_method.single_addr_or_err().await?; + let my_address = coin.derivation_method.single_addr_or_err().await.map_mm_err()?; coin.address_balance(my_address).compat().await }; Box::new(fut.boxed().compat()) @@ -4635,7 +4693,7 @@ impl EthCoin { let balance_as_u256 = coin() .get_token_balance_for_address(address, info.token_address) .await?; - let balance_as_big_decimal = u256_to_big_decimal(balance_as_u256, info.decimals)?; + let balance_as_big_decimal = u256_to_big_decimal(balance_as_u256, info.decimals).map_mm_err()?; let balance = CoinBalance::new(balance_as_big_decimal); Ok((token_ticker, balance)) }; @@ -4646,7 +4704,7 @@ impl EthCoin { } pub async fn get_tokens_balance_list(&self) -> Result> { - let my_address = self.derivation_method.single_addr_or_err().await?; + let my_address = self.derivation_method.single_addr_or_err().await.map_mm_err()?; self.get_tokens_balance_list_for_address(my_address).await } @@ -4672,7 +4730,7 @@ impl EthCoin { } async fn get_token_balance(&self, token_address: Address) -> Result> { - let my_address = self.derivation_method.single_addr_or_err().await?; + let my_address = self.derivation_method.single_addr_or_err().await.map_mm_err()?; self.get_token_balance_for_address(my_address, token_address).await } @@ -4680,9 +4738,10 @@ impl EthCoin { let wallet_amount_uint = match self.coin_type { EthCoinType::Eth | EthCoinType::Nft { .. } => { let function = ERC1155_CONTRACT.function("balanceOf")?; - let token_id_u256 = - U256::from_dec_str(token_id).map_to_mm(|e| NumConversError::new(format!("{:?}", e)))?; - let my_address = self.derivation_method.single_addr_or_err().await?; + let token_id_u256 = U256::from_dec_str(token_id) + .map_to_mm(|e| NumConversError::new(format!("{:?}", e))) + .map_mm_err()?; + let my_address = self.derivation_method.single_addr_or_err().await.map_mm_err()?; let data = function.encode_input(&[Token::Address(my_address), Token::Uint(token_id_u256)])?; let result = self .call_request(my_address, token_addr, None, Some(data.into()), BlockNumber::Latest) @@ -4711,10 +4770,11 @@ impl EthCoin { let owner_address = match self.coin_type { EthCoinType::Eth | EthCoinType::Nft { .. } => { let function = ERC721_CONTRACT.function("ownerOf")?; - let token_id_u256 = - U256::from_dec_str(token_id).map_to_mm(|e| NumConversError::new(format!("{:?}", e)))?; + let token_id_u256 = U256::from_dec_str(token_id) + .map_to_mm(|e| NumConversError::new(format!("{:?}", e))) + .map_mm_err()?; let data = function.encode_input(&[Token::Uint(token_id_u256)])?; - let my_address = self.derivation_method.single_addr_or_err().await?; + let my_address = self.derivation_method.single_addr_or_err().await.map_mm_err()?; let result = self .call_request(my_address, token_addr, None, Some(data.into()), BlockNumber::Latest) .await?; @@ -4757,7 +4817,7 @@ impl EthCoin { /// because [`CallRequest::from`] is set to [`EthCoinImpl::my_address`]. async fn estimate_gas_for_contract_call(&self, contract_addr: Address, call_data: Bytes) -> Web3RpcResult { let coin = self.clone(); - let my_address = coin.derivation_method.single_addr_or_err().await?; + let my_address = coin.derivation_method.single_addr_or_err().await.map_mm_err()?; let fee_policy_for_estimate = get_swap_fee_policy_for_estimate(self.get_swap_transaction_fee_policy()); let pay_for_gas_option = coin.get_swap_pay_for_gas_option(fee_policy_for_estimate).await?; let eth_value = U256::zero(); @@ -4780,7 +4840,7 @@ impl EthCoin { fn eth_balance(&self) -> BalanceFut { let coin = self.clone(); let fut = async move { - let my_address = coin.derivation_method.single_addr_or_err().await?; + let my_address = coin.derivation_method.single_addr_or_err().await.map_mm_err()?; coin.balance(my_address, Some(BlockNumber::Latest)) .await .map_to_mm(BalanceError::from) @@ -4818,7 +4878,7 @@ impl EthCoin { )), EthCoinType::Erc20 { ref token_addr, .. } => { let function = ERC20_CONTRACT.function("allowance")?; - let my_address = coin.derivation_method.single_addr_or_err().await?; + let my_address = coin.derivation_method.single_addr_or_err().await.map_mm_err()?; let data = function.encode_input(&[Token::Address(my_address), Token::Address(spender)])?; let res = coin @@ -4972,7 +5032,7 @@ impl EthCoin { } else { input.secret_hash.to_vec() }; - let trade_amount = try_f!(wei_from_big_decimal(&(input.amount), decimals)); + let trade_amount = try_f!(wei_from_big_decimal(&(input.amount), decimals).map_mm_err()); let fut = async move { let status = selfi .payment_status(expected_swap_contract_address, Token::FixedBytes(swap_id.clone())) @@ -4998,7 +5058,7 @@ impl EthCoin { ))); } - let my_address = selfi.derivation_method.single_addr_or_err().await?; + let my_address = selfi.derivation_method.single_addr_or_err().await.map_mm_err()?; match &selfi.coin_type { EthCoinType::Eth => { let mut expected_value = trade_amount; @@ -5064,7 +5124,8 @@ impl EthCoin { ))); } - let expected_reward_amount = wei_from_big_decimal(&watcher_reward.amount, decimals)?; + let expected_reward_amount = + wei_from_big_decimal(&watcher_reward.amount, decimals).map_mm_err()?; let actual_reward_amount = decoded[6].clone().into_uint().ok_or_else(|| { ValidatePaymentError::WrongPaymentTx("Invalid type for watcher reward argument".to_string()) })?; @@ -5170,15 +5231,15 @@ impl EthCoin { let expected_reward_amount = match watcher_reward.reward_target { RewardTarget::Contract | RewardTarget::PaymentSender => { - wei_from_big_decimal(&watcher_reward.amount, ETH_DECIMALS)? + wei_from_big_decimal(&watcher_reward.amount, ETH_DECIMALS).map_mm_err()? }, RewardTarget::PaymentSpender => { - wei_from_big_decimal(&watcher_reward.amount, selfi.decimals)? + wei_from_big_decimal(&watcher_reward.amount, selfi.decimals).map_mm_err()? }, _ => { // TODO tests passed without this change, need to research on how it worked if watcher_reward.send_contract_reward_on_spend { - wei_from_big_decimal(&watcher_reward.amount, ETH_DECIMALS)? + wei_from_big_decimal(&watcher_reward.amount, ETH_DECIMALS).map_mm_err()? } else { 0.into() } @@ -5867,7 +5928,8 @@ impl MmCoin for EthCoin { ) -> TradePreimageResult { let pay_for_gas_option = self .get_swap_pay_for_gas_option(self.get_swap_transaction_fee_policy()) - .await?; + .await + .map_mm_err()?; let pay_for_gas_option = increase_gas_price_by_stage(pay_for_gas_option, &stage); let gas_limit = match self.coin_type { EthCoinType::Eth => { @@ -5882,20 +5944,21 @@ impl MmCoin for EthCoin { let mut gas = U256::from(self.gas_limit.erc20_payment); let value = match value { TradePreimageValue::Exact(value) | TradePreimageValue::UpperBound(value) => { - wei_from_big_decimal(&value, self.decimals)? + wei_from_big_decimal(&value, self.decimals).map_mm_err()? }, }; - let allowed = self.allowance(self.swap_contract_address).compat().await?; + let allowed = self.allowance(self.swap_contract_address).compat().await.map_mm_err()?; if allowed < value { // estimate gas for the `approve` contract call // Pass a dummy spender. Let's use `my_address`. - let spender = self.derivation_method.single_addr_or_err().await?; + let spender = self.derivation_method.single_addr_or_err().await.map_mm_err()?; let approve_function = ERC20_CONTRACT.function("approve")?; let approve_data = approve_function.encode_input(&[Token::Address(spender), Token::Uint(value)])?; let approve_gas_limit = self .estimate_gas_for_contract_call(token_addr, Bytes::from(approve_data)) - .await?; + .await + .map_mm_err()?; // this gas_limit includes gas for `approve`, `erc20Payment` contract calls gas += approve_gas_limit; @@ -5909,8 +5972,8 @@ impl MmCoin for EthCoin { EthCoinType::Nft { .. } => return MmError::err(TradePreimageError::NftProtocolNotSupported), }; - let total_fee = calc_total_fee(gas_limit, &pay_for_gas_option)?; - let amount = u256_to_big_decimal(total_fee, ETH_DECIMALS)?; + let total_fee = calc_total_fee(gas_limit, &pay_for_gas_option).map_mm_err()?; + let amount = u256_to_big_decimal(total_fee, ETH_DECIMALS).map_mm_err()?; let fee_coin = match &self.coin_type { EthCoinType::Eth => &self.ticker, EthCoinType::Erc20 { platform, .. } => platform, @@ -5928,20 +5991,22 @@ impl MmCoin for EthCoin { let fut = async move { let pay_for_gas_option = coin .get_swap_pay_for_gas_option(coin.get_swap_transaction_fee_policy()) - .await?; + .await + .map_mm_err()?; let pay_for_gas_option = increase_gas_price_by_stage(pay_for_gas_option, &stage); let (fee_coin, total_fee) = match &coin.coin_type { EthCoinType::Eth => ( &coin.ticker, - calc_total_fee(U256::from(coin.gas_limit.eth_receiver_spend), &pay_for_gas_option)?, + calc_total_fee(U256::from(coin.gas_limit.eth_receiver_spend), &pay_for_gas_option).map_mm_err()?, ), EthCoinType::Erc20 { platform, .. } => ( platform, - calc_total_fee(U256::from(coin.gas_limit.erc20_receiver_spend), &pay_for_gas_option)?, + calc_total_fee(U256::from(coin.gas_limit.erc20_receiver_spend), &pay_for_gas_option) + .map_mm_err()?, ), EthCoinType::Nft { .. } => return MmError::err(TradePreimageError::NftProtocolNotSupported), }; - let amount = u256_to_big_decimal(total_fee, ETH_DECIMALS)?; + let amount = u256_to_big_decimal(total_fee, ETH_DECIMALS).map_mm_err()?; Ok(TradeFee { coin: fee_coin.into(), amount: amount.into(), @@ -5956,11 +6021,11 @@ impl MmCoin for EthCoin { dex_fee_amount: DexFee, stage: FeeApproxStage, ) -> TradePreimageResult { - let dex_fee_amount = wei_from_big_decimal(&dex_fee_amount.fee_amount().into(), self.decimals)?; + let dex_fee_amount = wei_from_big_decimal(&dex_fee_amount.fee_amount().into(), self.decimals).map_mm_err()?; // pass the dummy params let to_addr = addr_from_raw_pubkey(&DEX_FEE_ADDR_RAW_PUBKEY) .expect("addr_from_raw_pubkey should never fail with DEX_FEE_ADDR_RAW_PUBKEY"); - let my_address = self.derivation_method.single_addr_or_err().await?; + let my_address = self.derivation_method.single_addr_or_err().await.map_mm_err()?; let (eth_value, data, call_addr, fee_coin) = match &self.coin_type { EthCoinType::Eth => (dex_fee_amount, Vec::new(), &to_addr, &self.ticker), EthCoinType::Erc20 { platform, token_addr } => { @@ -5971,7 +6036,10 @@ impl MmCoin for EthCoin { EthCoinType::Nft { .. } => return MmError::err(TradePreimageError::NftProtocolNotSupported), }; let fee_policy_for_estimate = get_swap_fee_policy_for_estimate(self.get_swap_transaction_fee_policy()); - let pay_for_gas_option = self.get_swap_pay_for_gas_option(fee_policy_for_estimate).await?; + let pay_for_gas_option = self + .get_swap_pay_for_gas_option(fee_policy_for_estimate) + .await + .map_mm_err()?; let pay_for_gas_option = increase_gas_price_by_stage(pay_for_gas_option, &stage); let estimate_gas_req = CallRequest { value: Some(eth_value), @@ -5987,8 +6055,8 @@ impl MmCoin for EthCoin { // Please note if the wallet's balance is insufficient to withdraw, then `estimate_gas` may fail with the `Exception` error. // Ideally we should determine the case when we have the insufficient balance and return `TradePreimageError::NotSufficientBalance` error. let gas_limit = self.estimate_gas_wrapper(estimate_gas_req).compat().await?; - let total_fee = calc_total_fee(gas_limit, &pay_for_gas_option)?; - let amount = u256_to_big_decimal(total_fee, ETH_DECIMALS)?; + let total_fee = calc_total_fee(gas_limit, &pay_for_gas_option).map_mm_err()?; + let amount = u256_to_big_decimal(total_fee, ETH_DECIMALS).map_mm_err()?; Ok(TradeFee { coin: fee_coin.into(), amount: amount.into(), @@ -6084,7 +6152,7 @@ fn validate_fee_impl(coin: EthCoin, validate_fee_args: EthValidateFeeArgs<'_>) - let min_block_number = validate_fee_args.min_block_number; let fut = async move { - let expected_value = wei_from_big_decimal(&amount, coin.decimals)?; + let expected_value = wei_from_big_decimal(&amount, coin.decimals).map_mm_err()?; let tx_from_rpc = coin.transaction(TransactionId::Hash(fee_tx_hash)).await?; let tx_from_rpc = tx_from_rpc.as_ref().ok_or_else(|| { @@ -6790,17 +6858,19 @@ pub async fn get_eth_address( ticker: &str, path_to_address: &HDPathAccountToAddressId, ) -> MmResult { - let crypto_ctx = CryptoCtx::from_ctx(ctx)?; + let crypto_ctx = CryptoCtx::from_ctx(ctx).map_mm_err()?; let priv_key_policy = if crypto_ctx.hw_ctx().is_some() { PrivKeyBuildPolicy::Trezor } else { - PrivKeyBuildPolicy::detect_priv_key_policy(ctx)? + PrivKeyBuildPolicy::detect_priv_key_policy(ctx).map_mm_err()? } .into(); let (_, derivation_method) = - build_address_and_priv_key_policy(ctx, ticker, conf, priv_key_policy, path_to_address, None).await?; - let my_address = derivation_method.single_addr_or_err().await?; + build_address_and_priv_key_policy(ctx, ticker, conf, priv_key_policy, path_to_address, None) + .await + .map_mm_err()?; + let my_address = derivation_method.single_addr_or_err().await.map_mm_err()?; Ok(MyWalletAddress { coin: ticker.to_owned(), @@ -6880,7 +6950,7 @@ async fn get_eth_gas_details_from_withdraw_fee( ) -> MmResult { let pay_for_gas_option = match fee { Some(WithdrawFee::EthGas { gas_price, gas }) => { - let gas_price = wei_from_big_decimal(&gas_price, ETH_GWEI_DECIMALS)?; + let gas_price = wei_from_big_decimal(&gas_price, ETH_GWEI_DECIMALS).map_mm_err()?; return Ok((gas.into(), PayForGasOption::Legacy(LegacyGasPrice { gas_price }))); }, Some(WithdrawFee::EthGasEip1559 { @@ -6888,8 +6958,9 @@ async fn get_eth_gas_details_from_withdraw_fee( max_priority_fee_per_gas, gas_option: gas_limit, }) => { - let max_fee_per_gas = wei_from_big_decimal(&max_fee_per_gas, ETH_GWEI_DECIMALS)?; - let max_priority_fee_per_gas = wei_from_big_decimal(&max_priority_fee_per_gas, ETH_GWEI_DECIMALS)?; + let max_fee_per_gas = wei_from_big_decimal(&max_fee_per_gas, ETH_GWEI_DECIMALS).map_mm_err()?; + let max_priority_fee_per_gas = + wei_from_big_decimal(&max_priority_fee_per_gas, ETH_GWEI_DECIMALS).map_mm_err()?; match gas_limit { EthGasLimitOption::Set(gas) => { return Ok(( @@ -6916,7 +6987,7 @@ async fn get_eth_gas_details_from_withdraw_fee( }, None => { // If WithdrawFee not set use legacy gas price (?) - let gas_price = eth_coin.get_gas_price().await?; + let gas_price = eth_coin.get_gas_price().await.map_mm_err()?; // go to gas estimate code PayForGasOption::Legacy(LegacyGasPrice { gas_price }) }, @@ -6924,7 +6995,7 @@ async fn get_eth_gas_details_from_withdraw_fee( // covering edge case by deducting the standard transfer fee when we want to max withdraw ETH let eth_value_for_estimate = if fungible_max && eth_coin.coin_type == EthCoinType::Eth { - eth_value - calc_total_fee(U256::from(eth_coin.gas_limit.eth_send_coins), &pay_for_gas_option)? + eth_value - calc_total_fee(U256::from(eth_coin.gas_limit.eth_send_coins), &pay_for_gas_option).map_mm_err()? } else { eth_value }; diff --git a/mm2src/coins/eth/eth_balance_events.rs b/mm2src/coins/eth/eth_balance_events.rs index a991dab101..7ff25321b0 100644 --- a/mm2src/coins/eth/eth_balance_events.rs +++ b/mm2src/coins/eth/eth_balance_events.rs @@ -3,7 +3,7 @@ use crate::{eth::{u256_to_big_decimal, Erc20TokenDetails}, hd_wallet::AddrToString, BalanceError, CoinWithDerivationMethod}; use common::{executor::Timer, log, Future01CompatExt}; -use mm2_err_handle::prelude::MmError; +use mm2_err_handle::prelude::*; use mm2_event_stream::{Broadcaster, Event, EventStreamer, NoDataIn, StreamHandlerInput, StreamerId}; use mm2_number::BigDecimal; @@ -133,7 +133,7 @@ async fn fetch_balance( let balance_as_big_decimal = u256_to_big_decimal(balance_as_u256, decimals).map_err(|e| BalanceFetchError { ticker: token_ticker.clone(), address: address.addr_to_string(), - error: e.into(), + error: e.map(BalanceError::from), })?; Ok(BalanceData { diff --git a/mm2src/coins/eth/eth_hd_wallet.rs b/mm2src/coins/eth/eth_hd_wallet.rs index 1b1f2e1a6e..be5eb688b0 100644 --- a/mm2src/coins/eth/eth_hd_wallet.rs +++ b/mm2src/coins/eth/eth_hd_wallet.rs @@ -144,7 +144,7 @@ impl HDWalletBalanceOps for EthCoin { async fn known_address_balance(&self, address: &Address) -> BalanceResult { let balance = self .address_balance(*address) - .and_then(move |result| Ok(u256_to_big_decimal(result, self.decimals())?)) + .and_then(move |result| u256_to_big_decimal(result, self.decimals()).map_mm_err()) .compat() .await?; diff --git a/mm2src/coins/eth/eth_swap_v2/eth_maker_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2/eth_maker_swap_v2.rs index d576ee43f6..ec4f69b31a 100644 --- a/mm2src/coins/eth/eth_swap_v2/eth_maker_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2/eth_maker_swap_v2.rs @@ -10,7 +10,7 @@ use ethereum_types::{Address, Public, U256}; use ethkey::public_to_address; use futures::compat::Future01CompatExt; use mm2_err_handle::mm_error::MmError; -use mm2_err_handle::prelude::MapToMmResult; +use mm2_err_handle::prelude::{MapToMmResult, MmResultExt}; use std::convert::TryInto; use web3::types::TransactionId; @@ -137,10 +137,10 @@ impl EthCoin { )) })?; let maker_address = public_to_address(args.maker_pub); - validate_from_to_addresses(tx_from_rpc, maker_address, maker_swap_v2_contract)?; + validate_from_to_addresses(tx_from_rpc, maker_address, maker_swap_v2_contract).map_mm_err()?; let validation_args = { - let amount = wei_from_big_decimal(&args.amount, self.decimals)?; + let amount = wei_from_big_decimal(&args.amount, self.decimals).map_mm_err()?; MakerValidationArgs { swap_id, amount, diff --git a/mm2src/coins/eth/eth_swap_v2/eth_taker_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2/eth_taker_swap_v2.rs index ac0594cfa7..3792e12526 100644 --- a/mm2src/coins/eth/eth_swap_v2/eth_taker_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2/eth_taker_swap_v2.rs @@ -12,7 +12,7 @@ use ethcore_transaction::Action; use ethereum_types::{Address, Public, U256}; use ethkey::public_to_address; use futures::compat::Future01CompatExt; -use mm2_err_handle::prelude::{MapToMmResult, MmError, MmResult}; +use mm2_err_handle::prelude::{MapToMmResult, MmError, MmResult, MmResultExt}; use std::convert::TryInto; use web3::types::{BlockNumber, TransactionId}; @@ -166,11 +166,12 @@ impl EthCoin { )) })?; let taker_address = public_to_address(args.taker_pub); - validate_from_to_addresses(tx_from_rpc, taker_address, taker_swap_v2_contract)?; + validate_from_to_addresses(tx_from_rpc, taker_address, taker_swap_v2_contract).map_mm_err()?; let validation_args = { - let dex_fee = wei_from_big_decimal(&args.dex_fee.fee_amount().into(), self.decimals)?; - let payment_amount = wei_from_big_decimal(&(args.trading_amount + args.premium_amount), self.decimals)?; + let dex_fee = wei_from_big_decimal(&args.dex_fee.fee_amount().into(), self.decimals).map_mm_err()?; + let payment_amount = + wei_from_big_decimal(&(args.trading_amount + args.premium_amount), self.decimals).map_mm_err()?; TakerValidationArgs { swap_id, amount: payment_amount, diff --git a/mm2src/coins/eth/eth_withdraw.rs b/mm2src/coins/eth/eth_withdraw.rs index c9822619d6..534882f538 100644 --- a/mm2src/coins/eth/eth_withdraw.rs +++ b/mm2src/coins/eth/eth_withdraw.rs @@ -21,7 +21,7 @@ use kdf_walletconnect::{WalletConnectCtx, WalletConnectOps}; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::map_mm_error::MapMmError; use mm2_err_handle::mm_error::MmResult; -use mm2_err_handle::prelude::{MapToMmResult, MmError, OrMmError}; +use mm2_err_handle::prelude::{MapToMmResult, MmError, MmResultExt, OrMmError}; use std::ops::Deref; use std::sync::Arc; #[cfg(target_arch = "wasm32")] @@ -59,8 +59,8 @@ where async fn get_from_address(&self, req: &WithdrawRequest) -> Result> { let coin = self.coin(); match req.from { - Some(_) => Ok(coin.get_withdraw_sender_address(req).await?.address), - None => Ok(coin.derivation_method.single_addr_or_err().await?), + Some(_) => Ok(coin.get_withdraw_sender_address(req).await.map_mm_err()?.address), + None => Ok(coin.derivation_method.single_addr_or_err().await.map_mm_err()?), } } @@ -77,7 +77,8 @@ where let derivation_path = self.get_from_derivation_path(from)?; let raw_priv_key = coin .priv_key_policy - .hd_wallet_derived_priv_key_or_err(&derivation_path)?; + .hd_wallet_derived_priv_key_or_err(&derivation_path) + .map_mm_err()?; KeyPair::from_secret_slice(raw_priv_key.as_slice()) .map_to_mm(|e| WithdrawError::InternalError(e.to_string())) }, @@ -93,11 +94,17 @@ where #[allow(clippy::result_large_err)] fn get_from_derivation_path(&self, from: &HDAddressSelector) -> Result> { let coin = self.coin(); - let path_to_coin = &coin.deref().derivation_method.hd_wallet_or_err()?.derivation_path; + let path_to_coin = &coin + .deref() + .derivation_method + .hd_wallet_or_err() + .map_mm_err()? + .derivation_path; let path_to_address = from .to_address_path(path_to_coin.coin_type()) - .mm_err(|err| WithdrawError::UnexpectedFromAddress(err.to_string()))?; - let derivation_path = path_to_address.to_derivation_path(path_to_coin)?; + .mm_err(|err| WithdrawError::UnexpectedFromAddress(err.to_string())) + .map_mm_err()?; + let derivation_path = path_to_address.to_derivation_path(path_to_coin).map_mm_err()?; Ok(derivation_path) } @@ -113,7 +120,8 @@ where let default_hd_address = &coin .deref() .derivation_method - .hd_wallet_or_err()? + .hd_wallet_or_err() + .map_mm_err()? .get_enabled_address() .await .ok_or_else(|| WithdrawError::InternalError("no enabled address".to_owned()))?; @@ -187,7 +195,8 @@ where let signed_tx = coin .wait_for_tx_appears_on_rpc(tx_hash, wait_rpc_timeout, check_every) - .await?; + .await + .map_mm_err()?; let tx_hex = signed_tx .map(|signed_tx| BytesJson::from(rlp::encode(&signed_tx).to_vec())) // Return an empty `tx_hex` if the transaction is still not appeared on the RPC node. @@ -216,13 +225,13 @@ where self.on_generating_transaction()?; - let my_balance = coin.address_balance(my_address).compat().await?; - let my_balance_dec = u256_to_big_decimal(my_balance, coin.decimals)?; + let my_balance = coin.address_balance(my_address).compat().await.map_mm_err()?; + let my_balance_dec = u256_to_big_decimal(my_balance, coin.decimals).map_mm_err()?; let (mut wei_amount, dec_amount) = if req.max { (my_balance, my_balance_dec.clone()) } else { - let wei_amount = wei_from_big_decimal(&req.amount, coin.decimals)?; + let wei_amount = wei_from_big_decimal(&req.amount, coin.decimals).map_mm_err()?; (wei_amount, req.amount.clone()) }; if wei_amount > my_balance { @@ -241,7 +250,7 @@ where }, EthCoinType::Nft { .. } => return MmError::err(WithdrawError::NftProtocolNotSupported), }; - let eth_value_dec = u256_to_big_decimal(eth_value, coin.decimals)?; + let eth_value_dec = u256_to_big_decimal(eth_value, coin.decimals).map_mm_err()?; let (gas, pay_for_gas_option) = get_eth_gas_details_from_withdraw_fee( coin, @@ -252,9 +261,10 @@ where call_addr, false, ) - .await?; - let total_fee = calc_total_fee(gas, &pay_for_gas_option)?; - let total_fee_dec = u256_to_big_decimal(total_fee, coin.decimals)?; + .await + .map_mm_err()?; + let total_fee = calc_total_fee(gas, &pay_for_gas_option).map_mm_err()?; + let total_fee_dec = u256_to_big_decimal(total_fee, coin.decimals).map_mm_err()?; if req.max && coin.coin_type == EthCoinType::Eth { if eth_value < total_fee || wei_amount < total_fee { @@ -362,14 +372,14 @@ where let tx_hash_bytes = BytesJson::from(tx_hash.0.to_vec()); let tx_hash_str = format!("{:02x}", tx_hash_bytes); - let amount_decimal = u256_to_big_decimal(wei_amount, coin.decimals)?; + let amount_decimal = u256_to_big_decimal(wei_amount, coin.decimals).map_mm_err()?; let mut spent_by_me = amount_decimal.clone(); let received_by_me = if to_addr == my_address { amount_decimal.clone() } else { 0.into() }; - let fee_details = EthTxFeeDetails::new(gas, pay_for_gas_option, fee_coin)?; + let fee_details = EthTxFeeDetails::new(gas, pay_for_gas_option, fee_coin).map_mm_err()?; if coin.coin_type == EthCoinType::Eth { spent_by_me += &fee_details.total_fee; } @@ -408,15 +418,15 @@ impl EthWithdraw for InitEthWithdraw { fn request(&self) -> &WithdrawRequest { &self.req } fn on_generating_transaction(&self) -> Result<(), MmError> { - Ok(self - .task_handle - .update_in_progress_status(WithdrawInProgressStatus::GeneratingTransaction)?) + self.task_handle + .update_in_progress_status(WithdrawInProgressStatus::GeneratingTransaction) + .map_mm_err() } fn on_finishing(&self) -> Result<(), MmError> { - Ok(self - .task_handle - .update_in_progress_status(WithdrawInProgressStatus::Finishing)?) + self.task_handle + .update_in_progress_status(WithdrawInProgressStatus::Finishing) + .map_mm_err() } async fn sign_tx_with_trezor( @@ -425,7 +435,7 @@ impl EthWithdraw for InitEthWithdraw { unsigned_tx: &TransactionWrapper, ) -> Result> { let coin = self.coin(); - let crypto_ctx = CryptoCtx::from_ctx(&self.ctx)?; + let crypto_ctx = CryptoCtx::from_ctx(&self.ctx).map_mm_err()?; let hw_ctx = crypto_ctx .hw_ctx() .or_mm_err(|| WithdrawError::HwError(HwRpcError::NoTrezorDeviceAvailable))?; @@ -437,7 +447,7 @@ impl EthWithdraw for InitEthWithdraw { }; let sign_processor = TrezorRpcTaskProcessor::new(self.task_handle.clone(), trezor_statuses); let sign_processor = Arc::new(sign_processor); - let mut trezor_session = hw_ctx.trezor(sign_processor).await?; + let mut trezor_session = hw_ctx.trezor(sign_processor).await.map_mm_err()?; let chain_id = match coin.chain_spec { ChainSpec::Evm { chain_id } => chain_id, // Todo: Add support for Tron signing with Trezor @@ -449,7 +459,9 @@ impl EthWithdraw for InitEthWithdraw { }; let unverified_tx = trezor_session .sign_eth_tx(derivation_path, unsigned_tx, chain_id) - .await?; + .await + .map_mm_err()?; + Ok(SignedEthTx::new(unverified_tx).map_to_mm(|err| WithdrawError::InternalError(err.to_string()))?) } } diff --git a/mm2src/coins/eth/fee_estimation/eip1559/simple.rs b/mm2src/coins/eth/fee_estimation/eip1559/simple.rs index 995d27447c..fe42b03b8d 100644 --- a/mm2src/coins/eth/fee_estimation/eip1559/simple.rs +++ b/mm2src/coins/eth/fee_estimation/eip1559/simple.rs @@ -3,6 +3,7 @@ use crate::eth::web3_transport::FeeHistoryResult; use crate::eth::{wei_from_gwei_decimal, wei_to_gwei_decimal, EthCoin, Web3RpcError, Web3RpcResult}; use mm2_err_handle::mm_error::MmError; use mm2_err_handle::or_mm_error::OrMmError; +use mm2_err_handle::prelude::MmResultExt; use mm2_number::BigDecimal; use ethereum_types::U256; @@ -101,7 +102,7 @@ impl FeePerGasSimpleEstimator { Ok(FeePerGasLevel { max_priority_fee_per_gas, - max_fee_per_gas: wei_from_gwei_decimal(&max_fee_per_gas_dec)?, + max_fee_per_gas: wei_from_gwei_decimal(&max_fee_per_gas_dec).map_mm_err()?, // TODO: Consider adding default wait times if applicable (and mark them as uncertain). min_wait_time: None, max_wait_time: None, diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index ab81124792..d0e4ca8163 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -3,7 +3,7 @@ use ethcore_transaction::Action; use ethereum_types::U256; use ethkey::public_to_address; use futures::compat::Future01CompatExt; -use mm2_err_handle::prelude::{MapToMmResult, MmError, MmResult}; +use mm2_err_handle::prelude::{MapToMmResult, MmError, MmResult, MmResultExt}; use mm2_number::BigDecimal; use num_traits::Signed; use web3::types::TransactionId; @@ -89,7 +89,7 @@ impl EthCoin { args.maker_payment_tx.tx_hash() )) })?; - validate_from_to_addresses(tx_from_rpc, maker_address, *token_address)?; + validate_from_to_addresses(tx_from_rpc, maker_address, *token_address).map_mm_err()?; let (decoded, bytes_index) = get_decoded_tx_data_and_bytes_index(contract_type, &tx_from_rpc.input.0)?; @@ -116,7 +116,7 @@ impl EthCoin { maker_secret_hash: args.maker_secret_hash.to_vec(), time_lock: U256::from(args.time_lock), }; - decode_and_validate_htlc_params(decoded, bytes_index, htlc_params)?; + decode_and_validate_htlc_params(decoded, bytes_index, htlc_params).map_mm_err()?; }, EthCoinType::Eth | EthCoinType::Erc20 { .. } => { return MmError::err(ValidatePaymentError::InternalError( diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 9bcd2d6c57..6267feef92 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -460,9 +460,11 @@ impl EthCoin { }; let max_eth_tx_type = get_max_eth_tx_type_conf(&ctx, &token_conf, &coin_type).await?; let gas_limit: EthGasLimit = extract_gas_limit_from_conf(&token_conf) - .map_to_mm(|e| EthTokenActivationError::InternalError(format!("invalid gas_limit config {}", e)))?; + .map_to_mm(|e| EthTokenActivationError::InternalError(format!("invalid gas_limit config {}", e))) + .map_mm_err()?; let gas_limit_v2: EthGasLimitV2 = extract_gas_limit_from_conf(&token_conf) - .map_to_mm(|e| EthTokenActivationError::InternalError(format!("invalid gas_limit config {}", e)))?; + .map_to_mm(|e| EthTokenActivationError::InternalError(format!("invalid gas_limit config {}", e))) + .map_mm_err()?; let token = EthCoinImpl { priv_key_policy: self.priv_key_policy.clone(), @@ -532,7 +534,7 @@ impl EthCoin { let abortable_system = self.abortable_system.create_subsystem()?; // Todo: support HD wallet for NFTs, currently we get nfts for enabled address only and there might be some issues when activating NFTs while ETH is activated with HD wallet - let my_address = self.derivation_method.single_addr_or_err().await?; + let my_address = self.derivation_method.single_addr_or_err().await.map_mm_err()?; let proxy_sign = if komodo_proxy { let uri = Uri::from_str(original_url.as_ref()) @@ -544,7 +546,9 @@ impl EthCoin { None }; - let nft_infos = get_nfts_for_activation(&chain, &my_address, original_url, proxy_sign).await?; + let nft_infos = get_nfts_for_activation(&chain, &my_address, original_url, proxy_sign) + .await + .map_mm_err()?; let coin_type = EthCoinType::Nft { platform: self.ticker.clone(), }; @@ -763,7 +767,9 @@ pub(crate) async fn build_address_and_priv_key_policy( let hd_wallet_storage = HDWalletCoinStorage::init_with_rmd160(ctx, ticker.to_string(), hd_wallet_rmd160) .await .mm_err(EthActivationV2Error::from)?; - let accounts = load_hd_accounts_from_storage(&hd_wallet_storage, &path_to_coin).await?; + let accounts = load_hd_accounts_from_storage(&hd_wallet_storage, &path_to_coin) + .await + .map_mm_err()?; let gap_limit = gap_limit.unwrap_or(DEFAULT_GAP_LIMIT); let hd_wallet = EthHDWallet { hd_wallet_rmd160, @@ -791,7 +797,7 @@ pub(crate) async fn build_address_and_priv_key_policy( if trezor_coin.is_none() { return MmError::err(EthActivationV2Error::CoinDoesntSupportTrezor); } - let crypto_ctx = CryptoCtx::from_ctx(ctx)?; + let crypto_ctx = CryptoCtx::from_ctx(ctx).map_mm_err()?; let hw_ctx = crypto_ctx .hw_ctx() .or_mm_err(|| EthActivationV2Error::HwContextNotInitialized)?; @@ -799,7 +805,9 @@ pub(crate) async fn build_address_and_priv_key_policy( let hd_wallet_storage = HDWalletCoinStorage::init_with_rmd160(ctx, ticker.to_string(), hd_wallet_rmd160) .await .mm_err(EthActivationV2Error::from)?; - let accounts = load_hd_accounts_from_storage(&hd_wallet_storage, &path_to_coin).await?; + let accounts = load_hd_accounts_from_storage(&hd_wallet_storage, &path_to_coin) + .await + .map_mm_err()?; let gap_limit = gap_limit.unwrap_or(DEFAULT_GAP_LIMIT); let hd_wallet = EthHDWallet { hd_wallet_rmd160, @@ -814,7 +822,7 @@ pub(crate) async fn build_address_and_priv_key_policy( }, #[cfg(target_arch = "wasm32")] EthPrivKeyBuildPolicy::Metamask(metamask_ctx) => { - let address = *metamask_ctx.check_active_eth_account().await?; + let address = *metamask_ctx.check_active_eth_account().await.map_mm_err()?; let public_key_uncompressed = metamask_ctx.eth_account_pubkey_uncompressed(); let public_key = compress_public_key(public_key_uncompressed)?; Ok(( @@ -963,14 +971,13 @@ async fn build_metamask_transport( let event_handlers = rpc_event_handlers_for_eth_transport(ctx, coin_ticker.clone()); let eth_config = web3_transport::metamask_transport::MetamaskEthConfig { chain_id }; - let web3 = Web3::new(Web3Transport::new_metamask_with_event_handlers( - eth_config, - event_handlers, - )?); + let web3 = Web3::new(Web3Transport::new_metamask_with_event_handlers(eth_config, event_handlers).map_mm_err()?); // Check if MetaMask supports the given `chain_id`. // Please note that this request may take a long time. - check_metamask_supports_chain_id(coin_ticker, &web3, chain_id).await?; + check_metamask_supports_chain_id(coin_ticker, &web3, chain_id) + .await + .map_mm_err()?; // MetaMask doesn't use Parity nodes. So `MetamaskTransport` doesn't support `parity_nextNonce` RPC. // An example of the `web3_clientVersion` RPC - `MetaMask/v10.22.1`. @@ -1013,7 +1020,8 @@ async fn check_metamask_supports_chain_id( fn compress_public_key(uncompressed: H520) -> MmResult { let public_key = PublicKey::from_slice(uncompressed.as_bytes()) - .map_to_mm(|e| EthActivationV2Error::InternalError(e.to_string()))?; + .map_to_mm(|e| EthActivationV2Error::InternalError(e.to_string())) + .map_mm_err()?; let compressed = public_key.serialize(); Ok(H264::from(compressed)) diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 2bc241342e..1ab2590644 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -113,7 +113,9 @@ impl WalletConnectOps for EthCoin { }, }; let chain_id = WcChainId::new_eip155(chain_id.to_string()); - wc.validate_update_active_chain_id(session_topic, &chain_id).await?; + wc.validate_update_active_chain_id(session_topic, &chain_id) + .await + .map_mm_err()?; Ok(chain_id) } @@ -129,7 +131,8 @@ impl WalletConnectOps for EthCoin { let session_topic = self.session_topic()?; let tx_hex: String = wc .send_session_request_and_wait(session_topic, &chain_id, WcRequestMethods::EthSignTransaction, tx_json) - .await?; + .await + .map_mm_err()?; // if tx_hex.len() < 4 { // return MmError::err(EthWalletConnectError::TxDecodingFailed( // "invalid transaction hex returned from wallet".to_string(), @@ -157,7 +160,8 @@ impl WalletConnectOps for EthCoin { let tx_json = params.prepare_wc_tx_format()?; let session_topic = self.session_topic()?; wc.send_session_request_and_wait(session_topic, &chain_id, WcRequestMethods::EthSendTransaction, tx_json) - .await? + .await + .map_mm_err()? }; let tx_hash = tx_hash.strip_prefix("0x").unwrap_or(&tx_hash); @@ -192,9 +196,13 @@ pub async fn eth_request_wc_personal_sign( chain_id: u64, ) -> MmResult<(H520, Address), EthWalletConnectError> { let chain_id = WcChainId::new_eip155(chain_id.to_string()); - wc.validate_update_active_chain_id(session_topic, &chain_id).await?; + wc.validate_update_active_chain_id(session_topic, &chain_id) + .await + .map_mm_err()?; - let (account_str, _) = wc.get_account_and_properties_for_chain_id(session_topic, &chain_id)?; + let (account_str, _) = wc + .get_account_and_properties_for_chain_id(session_topic, &chain_id) + .map_mm_err()?; let message = "Authenticate with KDF"; let params = { let message_hex = format!("0x{}", hex::encode(message)); @@ -202,10 +210,12 @@ pub async fn eth_request_wc_personal_sign( }; let data = wc .send_session_request_and_wait::(session_topic, &chain_id, WcRequestMethods::PersonalSign, params) - .await?; + .await + .map_mm_err()?; - Ok(extract_pubkey_from_signature(&data, message, &account_str) - .mm_err(|err| WalletConnectError::SessionError(err.to_string()))?) + extract_pubkey_from_signature(&data, message, &account_str) + .mm_err(|err| WalletConnectError::SessionError(err.to_string())) + .map_mm_err() } fn extract_pubkey_from_signature( diff --git a/mm2src/coins/hd_wallet/coin_ops.rs b/mm2src/coins/hd_wallet/coin_ops.rs index 27b92d0aa6..bb6b2d9f64 100644 --- a/mm2src/coins/hd_wallet/coin_ops.rs +++ b/mm2src/coins/hd_wallet/coin_ops.rs @@ -6,7 +6,8 @@ use async_trait::async_trait; use bip32::{ChildNumber, DerivationPath}; use crypto::Bip44Chain; use itertools::Itertools; -use mm2_err_handle::mm_error::{MmError, MmResult}; +use mm2_err_handle::{mm_error::{MmError, MmResult}, + prelude::MmResultExt}; use std::collections::HashMap; type AddressDerivingResult = MmResult; @@ -137,7 +138,7 @@ pub trait HDWalletCoinOps { hd_account: &HDCoinHDAccount, chain: Bip44Chain, ) -> AddressDerivingResult>> { - let known_addresses_number = hd_account.known_addresses_number(chain)?; + let known_addresses_number = hd_account.known_addresses_number(chain).map_mm_err()?; let address_ids = (0..known_addresses_number).map(|address_id| HDAddressId { chain, address_id }); self.derive_addresses(hd_account, address_ids).await } @@ -155,7 +156,8 @@ pub trait HDWalletCoinOps { } = inner_impl::generate_new_address_immutable(self, hd_account, chain).await?; self.set_known_addresses_number(hd_wallet, hd_account, chain, new_known_addresses_number) - .await?; + .await + .map_mm_err()?; Ok(address) } @@ -178,22 +180,26 @@ pub trait HDWalletCoinOps { let inner_impl::NewAddress { hd_address, new_known_addresses_number, - } = inner_impl::generate_new_address_immutable(self, hd_account, chain).await?; + } = inner_impl::generate_new_address_immutable(self, hd_account, chain) + .await + .map_mm_err()?; - let trezor_coin = self.trezor_coin()?; + let trezor_coin = self.trezor_coin().map_mm_err()?; let derivation_path = hd_address.derivation_path().clone(); let expected_address = hd_address.address().display_address(); // Ask the user to confirm if the given `expected_address` is the same as on the HW display. confirm_address .confirm_address(trezor_coin, derivation_path, expected_address) - .await?; + .await + .map_mm_err()?; - let actual_known_addresses_number = hd_account.known_addresses_number(chain)?; + let actual_known_addresses_number = hd_account.known_addresses_number(chain).map_mm_err()?; // Check if the actual `known_addresses_number` hasn't been changed while we waited for the user confirmation. // If the actual value is greater than the new one, we don't need to update. if actual_known_addresses_number < new_known_addresses_number { self.set_known_addresses_number(hd_wallet, hd_account, chain, new_known_addresses_number) - .await?; + .await + .map_mm_err()?; } Ok(hd_address) @@ -213,16 +219,14 @@ pub trait HDWalletCoinOps { return MmError::err(AccountUpdatingError::AddressLimitReached { max_addresses_number }); } match chain { - Bip44Chain::External => { - hd_wallet - .update_external_addresses_number(hd_account.account_id(), new_known_addresses_number) - .await? - }, - Bip44Chain::Internal => { - hd_wallet - .update_internal_addresses_number(hd_account.account_id(), new_known_addresses_number) - .await? - }, + Bip44Chain::External => hd_wallet + .update_external_addresses_number(hd_account.account_id(), new_known_addresses_number) + .await + .map_mm_err()?, + Bip44Chain::Internal => hd_wallet + .update_internal_addresses_number(hd_account.account_id(), new_known_addresses_number) + .await + .map_mm_err()?, } hd_account.set_known_addresses_number(chain, new_known_addresses_number); diff --git a/mm2src/coins/hd_wallet/confirm_address.rs b/mm2src/coins/hd_wallet/confirm_address.rs index 39bb286322..0bbfcd7cde 100644 --- a/mm2src/coins/hd_wallet/confirm_address.rs +++ b/mm2src/coins/hd_wallet/confirm_address.rs @@ -125,7 +125,7 @@ where statuses: HwConnectStatuses, trezor_message_type: TrezorMessageType, ) -> MmResult, HDConfirmAddressError> { - let crypto_ctx = CryptoCtx::from_ctx(ctx)?; + let crypto_ctx = CryptoCtx::from_ctx(ctx).map_mm_err()?; let hw_ctx = crypto_ctx .hw_ctx() .or_mm_err(|| HDConfirmAddressError::HwContextNotInitialized)?; @@ -153,20 +153,22 @@ where let pubkey_processor = TrezorRpcTaskProcessor::new(task_handle, confirm_statuses); let pubkey_processor = Arc::new(pubkey_processor); - let mut trezor_session = hw_ctx.trezor(pubkey_processor.clone()).await?; + let mut trezor_session = hw_ctx.trezor(pubkey_processor.clone()).await.map_mm_err()?; let address = match trezor_message_type { - TrezorMessageType::Bitcoin => { - trezor_session - .get_utxo_address(derivation_path, trezor_coin, SHOW_ADDRESS_ON_DISPLAY) - .await? - .process(pubkey_processor.clone()) - .await? - }, + TrezorMessageType::Bitcoin => trezor_session + .get_utxo_address(derivation_path, trezor_coin, SHOW_ADDRESS_ON_DISPLAY) + .await + .map_mm_err()? + .process(pubkey_processor.clone()) + .await + .map_mm_err()?, TrezorMessageType::Ethereum => trezor_session .get_eth_address(derivation_path, SHOW_ADDRESS_ON_DISPLAY) - .await? + .await + .map_mm_err()? .process(pubkey_processor.clone()) - .await? + .await + .map_mm_err()? .or_mm_err(|| HDConfirmAddressError::NoAddressReceived)?, }; diff --git a/mm2src/coins/hd_wallet/mod.rs b/mm2src/coins/hd_wallet/mod.rs index 1fedf35fcd..17bae275a1 100644 --- a/mm2src/coins/hd_wallet/mod.rs +++ b/mm2src/coins/hd_wallet/mod.rs @@ -216,7 +216,8 @@ where let account_child = ChildNumber::new(account_info.account_id, ACCOUNT_CHILD_HARDENED)?; let account_derivation_path = wallet_der_path .derive(account_child) - .map_to_mm(StandardHDPathError::from)?; + .map_to_mm(StandardHDPathError::from) + .map_mm_err()?; let extended_pubkey = ExtendedPublicKey::from_str(&account_info.account_xpub) .map_err(|e| HDWalletStorageError::ErrorDeserializing(e.to_string()))?; let capacity = @@ -416,7 +417,8 @@ where let account_derivation_path: HDPathToAccount = hd_wallet.derivation_path().derive(account_child)?; let account_pubkey = coin .extract_extended_pubkey(xpub_extractor, account_derivation_path.to_derivation_path()) - .await?; + .await + .map_mm_err()?; let new_account = HDAccount::new(new_account_id, account_pubkey, account_derivation_path); @@ -429,7 +431,10 @@ where return MmError::err(NewAccountCreationError::Internal(error)); } - hd_wallet.upload_new_account(new_account.to_storage_item()).await?; + hd_wallet + .upload_new_account(new_account.to_storage_item()) + .await + .map_mm_err()?; Ok(AsyncMutexGuard::map(accounts, |accounts| { accounts @@ -564,14 +569,17 @@ pub(crate) mod inner_impl { where Coin: HDWalletCoinOps + ?Sized + Sync, { - let known_addresses_number = hd_account.known_addresses_number(chain)?; + let known_addresses_number = hd_account.known_addresses_number(chain).map_mm_err()?; // Address IDs start from 0, so the `known_addresses_number = last_known_address_id + 1`. let new_address_id = known_addresses_number; let max_addresses_number = hd_account.address_limit(); if new_address_id >= max_addresses_number { return MmError::err(NewAddressDerivingError::AddressLimitReached { max_addresses_number }); } - let address = coin.derive_address(hd_account, chain, new_address_id).await?; + let address = coin + .derive_address(hd_account, chain, new_address_id) + .await + .map_mm_err()?; Ok(NewAddress { hd_address: address, new_known_addresses_number: known_addresses_number + 1, diff --git a/mm2src/coins/hd_wallet/pubkey.rs b/mm2src/coins/hd_wallet/pubkey.rs index 64b24e2abd..c7489761bb 100644 --- a/mm2src/coins/hd_wallet/pubkey.rs +++ b/mm2src/coins/hd_wallet/pubkey.rs @@ -122,7 +122,7 @@ where statuses: HwConnectStatuses, coin_protocol: CoinProtocol, ) -> MmResult, HDExtractPubkeyError> { - let crypto_ctx = CryptoCtx::from_ctx(ctx)?; + let crypto_ctx = CryptoCtx::from_ctx(ctx).map_mm_err()?; let hw_ctx = crypto_ctx .hw_ctx() .or_mm_err(|| HDExtractPubkeyError::HwContextNotInitialized)?; @@ -150,7 +150,7 @@ where ) -> MmResult { let pubkey_processor = TrezorRpcTaskProcessor::new(task_handle, statuses.to_trezor_request_statuses()); let pubkey_processor = Arc::new(pubkey_processor); - let mut trezor_session = hw_ctx.trezor(pubkey_processor.clone()).await?; + let mut trezor_session = hw_ctx.trezor(pubkey_processor.clone()).await.map_mm_err()?; let xpub = trezor_session .get_public_key( derivation_path, @@ -159,9 +159,11 @@ where SHOW_PUBKEY_ON_DISPLAY, IGNORE_XPUB_MAGIC, ) - .await? + .await + .map_mm_err()? .process(pubkey_processor.clone()) - .await?; + .await + .map_mm_err()?; // Despite we pass `IGNORE_XPUB_MAGIC` to the [`TrezorSession::get_public_key`] method, // Trezor sometimes returns pubkeys with magic prefixes like `dgub` prefix for DOGE coin. // So we need to replace the magic prefix manually. @@ -176,10 +178,11 @@ where ) -> MmResult { let pubkey_processor = TrezorRpcTaskProcessor::new(task_handle, statuses.to_trezor_request_statuses()); let pubkey_processor = Arc::new(pubkey_processor); - let mut trezor_session = hw_ctx.trezor(pubkey_processor.clone()).await?; + let mut trezor_session = hw_ctx.trezor(pubkey_processor.clone()).await.map_mm_err()?; trezor_session .get_eth_public_key(&derivation_path, SHOW_PUBKEY_ON_DISPLAY) - .await? + .await + .map_mm_err()? .process(pubkey_processor) .await .mm_err(HDExtractPubkeyError::from) diff --git a/mm2src/coins/hd_wallet/storage/mod.rs b/mm2src/coins/hd_wallet/storage/mod.rs index cb8f11b01d..c01712bfc9 100644 --- a/mm2src/coins/hd_wallet/storage/mod.rs +++ b/mm2src/coins/hd_wallet/storage/mod.rs @@ -229,7 +229,7 @@ impl Default for HDWalletCoinStorage { impl HDWalletCoinStorage { pub async fn init(ctx: &MmArc, coin: String) -> HDWalletStorageResult { let inner = Box::new(HDWalletStorageInstance::init(ctx).await?); - let crypto_ctx = CryptoCtx::from_ctx(ctx)?; + let crypto_ctx = CryptoCtx::from_ctx(ctx).map_mm_err()?; let hd_wallet_rmd160 = crypto_ctx .hw_wallet_rmd160() .or_mm_err(|| HDWalletStorageError::HDWalletUnavailable)?; diff --git a/mm2src/coins/hd_wallet/storage/wasm_storage.rs b/mm2src/coins/hd_wallet/storage/wasm_storage.rs index 4654474236..5c7b57b77d 100644 --- a/mm2src/coins/hd_wallet/storage/wasm_storage.rs +++ b/mm2src/coins/hd_wallet/storage/wasm_storage.rs @@ -173,15 +173,18 @@ impl HDWalletStorageInternalOps for HDWalletIndexedDbStorage { let shared_db = self.get_shared_db()?; let locked_db = Self::lock_db_mutex(&shared_db).await?; - let transaction = locked_db.inner.transaction().await?; - let table = transaction.table::().await?; + let transaction = locked_db.inner.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(WALLET_ID_INDEX) - .with_value(wallet_id.coin)? - .with_value(wallet_id.hd_wallet_rmd160)?; + .with_value(wallet_id.coin) + .map_mm_err()? + .with_value(wallet_id.hd_wallet_rmd160) + .map_mm_err()?; Ok(table .get_items_by_multi_index(index_keys) - .await? + .await + .map_mm_err()? .into_iter() .map(|(_item_id, item)| HDAccountStorageItem::from(item)) .collect()) @@ -195,8 +198,8 @@ impl HDWalletStorageInternalOps for HDWalletIndexedDbStorage { let shared_db = self.get_shared_db()?; let locked_db = Self::lock_db_mutex(&shared_db).await?; - let transaction = locked_db.inner.transaction().await?; - let table = transaction.table::().await?; + let transaction = locked_db.inner.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; let maybe_account = Self::find_account(&table, wallet_id, account_id).await?; match maybe_account { @@ -237,8 +240,8 @@ impl HDWalletStorageInternalOps for HDWalletIndexedDbStorage { let shared_db = self.get_shared_db()?; let locked_db = Self::lock_db_mutex(&shared_db).await?; - let transaction = locked_db.inner.transaction().await?; - let table = transaction.table::().await?; + let transaction = locked_db.inner.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; let new_account = HDAccountTable::new(wallet_id, account); table @@ -252,13 +255,15 @@ impl HDWalletStorageInternalOps for HDWalletIndexedDbStorage { let shared_db = self.get_shared_db()?; let locked_db = Self::lock_db_mutex(&shared_db).await?; - let transaction = locked_db.inner.transaction().await?; - let table = transaction.table::().await?; + let transaction = locked_db.inner.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(WALLET_ID_INDEX) - .with_value(wallet_id.coin)? - .with_value(wallet_id.hd_wallet_rmd160)?; - table.delete_items_by_multi_index(index_keys).await?; + .with_value(wallet_id.coin) + .map_mm_err()? + .with_value(wallet_id.hd_wallet_rmd160) + .map_mm_err()?; + table.delete_items_by_multi_index(index_keys).await.map_mm_err()?; Ok(()) } } @@ -280,9 +285,12 @@ impl HDWalletIndexedDbStorage { account_id: u32, ) -> HDWalletStorageResult> { let index_keys = MultiIndex::new(WALLET_ACCOUNT_ID_INDEX) - .with_value(wallet_id.coin)? - .with_value(wallet_id.hd_wallet_rmd160)? - .with_value(account_id)?; + .with_value(wallet_id.coin) + .map_mm_err()? + .with_value(wallet_id.hd_wallet_rmd160) + .map_mm_err()? + .with_value(account_id) + .map_mm_err()?; table .get_item_by_unique_multi_index(index_keys) .await @@ -296,8 +304,8 @@ impl HDWalletIndexedDbStorage { let shared_db = self.get_shared_db()?; let locked_db = Self::lock_db_mutex(&shared_db).await?; - let transaction = locked_db.inner.transaction().await?; - let table = transaction.table::().await?; + let transaction = locked_db.inner.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; let (account_item_id, mut account) = Self::find_account(&table, wallet_id.clone(), account_id) .await? diff --git a/mm2src/coins/hd_wallet/withdraw_ops.rs b/mm2src/coins/hd_wallet/withdraw_ops.rs index 3b3d6ac7d9..6fc70e1630 100644 --- a/mm2src/coins/hd_wallet/withdraw_ops.rs +++ b/mm2src/coins/hd_wallet/withdraw_ops.rs @@ -42,7 +42,7 @@ pub trait HDCoinWithdrawOps: HDWalletCoinOps { // If [`HDWalletCoinOps::derive_address`] succeeds, [`HDAccountOps::is_address_activated`] shouldn't fails with an `InvalidBip44ChainError`. .mm_err(|e| HDWithdrawError::InternalError(e.to_string()))?; - let hd_address = self.derive_address(&hd_account, chain, address_id).await?; + let hd_address = self.derive_address(&hd_account, chain, address_id).await.map_mm_err()?; let address = hd_address.address(); if !is_address_activated { let error = format!("'{}' address is not activated", address.display_address()); diff --git a/mm2src/coins/lightning.rs b/mm2src/coins/lightning.rs index d9c48ecbf3..c5ae7501b3 100644 --- a/mm2src/coins/lightning.rs +++ b/mm2src/coins/lightning.rs @@ -487,7 +487,7 @@ impl LightningCoin { min_final_cltv_expiry: u64, ) -> Result, MmError> { // lightning decimals should be 11 in config since the smallest divisible unit in lightning coin is msat - let amt_msat = sat_from_big_decimal(&amount, self.decimals())?; + let amt_msat = sat_from_big_decimal(&amount, self.decimals()).map_mm_err()?; let payment_hash = payment_hash_from_slice(secret_hash).map_to_mm(|e| PaymentInstructionsErr::InternalError(e.to_string()))?; // note: No description is provided in the invoice to reduce the payload @@ -563,7 +563,7 @@ impl LightningCoin { .map_to_mm(|e| ValidatePaymentError::TxDeserializationError(e.to_string()))); let payment_hex = hex::encode(payment_hash.0); - let amt_msat = try_f!(sat_from_big_decimal(&input.amount, self.decimals())); + let amt_msat = try_f!(sat_from_big_decimal(&input.amount, self.decimals()).map_mm_err()); let coin = self.clone(); let fut = async move { diff --git a/mm2src/coins/lightning/ln_utils.rs b/mm2src/coins/lightning/ln_utils.rs index 68f3c7f7ab..93c86c8e5d 100644 --- a/mm2src/coins/lightning/ln_utils.rs +++ b/mm2src/coins/lightning/ln_utils.rs @@ -110,7 +110,8 @@ pub fn init_keys_manager(platform: &Platform) -> EnableLightningResult BalanceFut; @@ -4149,7 +4154,7 @@ impl CoinsContext { #[cfg(target_arch = "wasm32")] async fn tx_history_db(&self) -> TxHistoryResult> { - Ok(self.tx_history_db.get_or_initialize().await?) + self.tx_history_db.get_or_initialize().await.map_mm_err() } #[inline(always)] @@ -4333,7 +4338,7 @@ where { match xpub_extractor { Some(xpub_extractor) => { - let trezor_coin = coin.trezor_coin()?; + let trezor_coin = coin.trezor_coin().map_mm_err()?; let xpub = xpub_extractor.extract_xpub(trezor_coin, derivation_path).await?; Secp256k1ExtendedPublicKey::from_str(&xpub).map_to_mm(|e| HDExtractPubkeyError::InvalidXpub(e.to_string())) }, @@ -5140,12 +5145,12 @@ pub async fn validate_address(ctx: MmArc, req: Json) -> Result> } pub async fn withdraw(ctx: MmArc, req: WithdrawRequest) -> WithdrawResult { - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; coin.withdraw(req).compat().await } pub async fn get_raw_transaction(ctx: MmArc, req: RawTransactionRequest) -> RawTransactionResult { - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; coin.get_raw_transaction(req).compat().await } @@ -5155,14 +5160,14 @@ pub async fn sign_message(ctx: MmArc, req: SignatureRequest) -> SignatureResult< "You need to enable kdf with enable_hd to sign messages with a specific account/address".to_string(), )); }; - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; let signature = coin.sign_message(&req.message, req.address)?; Ok(SignatureResponse { signature }) } pub async fn verify_message(ctx: MmArc, req: VerificationRequest) -> VerificationResult { - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; let validate_address_result = coin.validate_address(&req.address); if !validate_address_result.is_valid { @@ -5177,12 +5182,12 @@ pub async fn verify_message(ctx: MmArc, req: VerificationRequest) -> Verificatio } pub async fn sign_raw_transaction(ctx: MmArc, req: SignRawTransactionRequest) -> RawTransactionResult { - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; coin.sign_raw_tx(&req).await } pub async fn remove_delegation(ctx: MmArc, req: RemoveDelegateRequest) -> DelegationResult { - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; match req.staking_details { Some(StakingDetails::Cosmos(req)) => { @@ -5217,7 +5222,7 @@ pub async fn remove_delegation(ctx: MmArc, req: RemoveDelegateRequest) -> Delega } pub async fn delegations_info(ctx: MmArc, req: DelegationsInfo) -> Result> { - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; match req.info_details { DelegationsInfoDetails::Qtum => { @@ -5231,7 +5236,7 @@ pub async fn delegations_info(ctx: MmArc, req: DelegationsInfo) -> Result match coin { - MmCoinEnum::Tendermint(t) => Ok(t.delegations_list(r.paging).await.map(|v| json!(v))?), + MmCoinEnum::Tendermint(t) => Ok(t.delegations_list(r.paging).await.map(|v| json!(v)).map_mm_err()?), MmCoinEnum::TendermintToken(_) => MmError::err(StakingInfoError::InvalidPayload { reason: "Tokens are not supported for delegation".into(), }), @@ -5243,11 +5248,15 @@ pub async fn delegations_info(ctx: MmArc, req: DelegationsInfo) -> Result Result> { - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; match req.info_details { UndelegationsInfoDetails::Cosmos(r) => match coin { - MmCoinEnum::Tendermint(t) => Ok(t.ongoing_undelegations_list(r.paging).await.map(|v| json!(v))?), + MmCoinEnum::Tendermint(t) => Ok(t + .ongoing_undelegations_list(r.paging) + .await + .map(|v| json!(v)) + .map_mm_err()?), MmCoinEnum::TendermintToken(_) => MmError::err(StakingInfoError::InvalidPayload { reason: "Tokens are not supported for delegation".into(), }), @@ -5259,7 +5268,7 @@ pub async fn ongoing_undelegations_info(ctx: MmArc, req: UndelegationsInfo) -> R } pub async fn validators_info(ctx: MmArc, req: ValidatorsInfo) -> Result> { - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; match req.info_details { ValidatorsInfoDetails::Cosmos(payload) => rpc_command::tendermint::staking::validators_rpc(coin, payload) @@ -5269,7 +5278,7 @@ pub async fn validators_info(ctx: MmArc, req: ValidatorsInfo) -> Result DelegationResult { - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; match req.staking_details { StakingDetails::Qtum(req) => { @@ -5296,7 +5305,7 @@ pub async fn add_delegation(ctx: MmArc, req: AddDelegateRequest) -> DelegationRe pub async fn claim_staking_rewards(ctx: MmArc, req: ClaimStakingRewardsRequest) -> DelegationResult { match req.claiming_details { ClaimingDetails::Cosmos(r) => { - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; let MmCoinEnum::Tendermint(tendermint) = coin else { return MmError::err(DelegationError::InvalidPayload { @@ -5611,7 +5620,7 @@ where { let ctx = ctx.clone(); let ticker = coin.ticker().to_owned(); - let my_address = try_f!(coin.my_address()); + let my_address = try_f!(coin.my_address().map_mm_err()); let fut = async move { let coins_ctx = CoinsContext::from_ctx(&ctx).unwrap(); @@ -5685,7 +5694,7 @@ where { let ctx = ctx.clone(); let ticker = coin.ticker().to_owned(); - let my_address = try_f!(coin.my_address()); + let my_address = try_f!(coin.my_address().map_mm_err()); history.sort_unstable_by(compare_transaction_details); @@ -5835,7 +5844,9 @@ pub async fn get_my_address(ctx: MmArc, req: MyAddressReq) -> MmResult get_eth_address(&ctx, &conf, ticker, &req.path_to_address).await?, + CoinProtocol::ETH { .. } => get_eth_address(&ctx, &conf, ticker, &req.path_to_address) + .await + .map_mm_err()?, _ => { return MmError::err(GetMyAddressError::CoinIsNotSupported(format!( "{} doesn't support get_my_address", @@ -5892,7 +5903,7 @@ pub trait Eip1559Ops { /// Get eip 1559 transaction fee per gas policy (low, medium, high) set for the coin pub async fn get_swap_transaction_fee_policy(ctx: MmArc, req: SwapTxFeePolicyRequest) -> SwapTxFeePolicyResult { - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; match coin { MmCoinEnum::EthCoin(eth_coin) => Ok(eth_coin.get_swap_transaction_fee_policy()), MmCoinEnum::Qrc20Coin(qrc20_coin) => Ok(qrc20_coin.get_swap_transaction_fee_policy()), @@ -5902,7 +5913,7 @@ pub async fn get_swap_transaction_fee_policy(ctx: MmArc, req: SwapTxFeePolicyReq /// Set eip 1559 transaction fee per gas policy (low, medium, high) pub async fn set_swap_transaction_fee_policy(ctx: MmArc, req: SwapTxFeePolicyRequest) -> SwapTxFeePolicyResult { - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; match coin { MmCoinEnum::EthCoin(eth_coin) => { eth_coin.set_swap_transaction_fee_policy(req.swap_tx_fee_policy); @@ -5940,7 +5951,10 @@ where let mut unused_addresses_counter = 0; let max_addresses_number = hd_account.address_limit(); while checking_address_id < max_addresses_number && unused_addresses_counter <= gap_limit { - let hd_address = coin.derive_address(hd_account, chain, checking_address_id).await?; + let hd_address = coin + .derive_address(hd_account, chain, checking_address_id) + .await + .map_mm_err()?; let checking_address = hd_address.address(); let checking_address_der_path = hd_address.derivation_path(); @@ -5953,16 +5967,17 @@ where // First, derive all empty addresses and put it into `balances` with default balance. let address_ids = (last_non_empty_address_id..checking_address_id) .map(|address_id| HDAddressId { chain, address_id }); - let empty_addresses = - coin.derive_addresses(hd_account, address_ids) - .await? - .into_iter() - .map(|empty_address| HDAddressBalance { - address: empty_address.address().display_address(), - derivation_path: RpcDerivationPath(empty_address.derivation_path().clone()), - chain, - balance: HDWalletBalanceObject::::new(), - }); + let empty_addresses = coin + .derive_addresses(hd_account, address_ids) + .await + .map_mm_err()? + .into_iter() + .map(|empty_address| HDAddressBalance { + address: empty_address.address().display_address(), + derivation_path: RpcDerivationPath(empty_address.derivation_path().clone()), + chain, + balance: HDWalletBalanceObject::::new(), + }); balances.extend(empty_addresses); // Then push this non-empty address. @@ -5987,7 +6002,8 @@ where chain, checking_address_id - unused_addresses_counter, ) - .await?; + .await + .map_mm_err()?; Ok(balances) } diff --git a/mm2src/coins/lp_price.rs b/mm2src/coins/lp_price.rs index 1a720d3e3d..f7cd971415 100644 --- a/mm2src/coins/lp_price.rs +++ b/mm2src/coins/lp_price.rs @@ -1,6 +1,6 @@ use common::log::{debug, error, info}; use common::StatusCode; -use mm2_err_handle::prelude::{MmError, OrMmError}; +use mm2_err_handle::prelude::*; use mm2_net::transport::SlurpError; #[cfg(not(feature = "run-docker-tests"))] use mm2_number::bigdecimal_custom::CheckedDivision; @@ -188,7 +188,7 @@ impl TickerInfosRegistry { #[cfg(not(target_arch = "wasm32"))] async fn process_price_request(price_url: &str) -> Result> { debug!("Fetching price from: {}", price_url); - let (status, headers, body) = mm2_net::native_http::slurp_url(price_url).await?; + let (status, headers, body) = mm2_net::native_http::slurp_url(price_url).await.map_mm_err()?; let (status_code, body, _) = (status, std::str::from_utf8(&body)?.trim().into(), headers); if status_code != StatusCode::OK { return MmError::err(PriceServiceRequestError::HttpProcessError(body)); @@ -200,7 +200,7 @@ async fn process_price_request(price_url: &str) -> Result Result> { debug!("Fetching price from: {}", price_url); - let (status, headers, body) = mm2_net::wasm::http::slurp_url(price_url).await?; + let (status, headers, body) = mm2_net::wasm::http::slurp_url(price_url).await.map_mm_err()?; let (status_code, body, _) = (status, std::str::from_utf8(&body)?.trim().into(), headers); if status_code != StatusCode::OK { return MmError::err(PriceServiceRequestError::HttpProcessError(body)); diff --git a/mm2src/coins/my_tx_history_v2.rs b/mm2src/coins/my_tx_history_v2.rs index 9bd5877ff5..02ed54d214 100644 --- a/mm2src/coins/my_tx_history_v2.rs +++ b/mm2src/coins/my_tx_history_v2.rs @@ -36,7 +36,7 @@ pub struct GetHistoryResult { pub total: usize, } -pub trait TxHistoryStorageError: std::fmt::Debug + NotMmError + NotEqual + Send {} +pub trait TxHistoryStorageError: std::fmt::Debug + NotMmError + Send {} #[async_trait] pub trait TxHistoryStorage: Send + Sync + 'static { @@ -365,7 +365,7 @@ pub async fn my_tx_history_v2_rpc( ctx: MmArc, request: MyTxHistoryRequestV2, ) -> Result, MmError> { - match lp_coinfind_or_err(&ctx, &request.coin).await? { + match lp_coinfind_or_err(&ctx, &request.coin).await.map_mm_err()? { MmCoinEnum::Bch(bch) => my_tx_history_v2_impl(ctx, &bch, request).await, MmCoinEnum::SlpToken(slp_token) => my_tx_history_v2_impl(ctx, &slp_token, request).await, MmCoinEnum::UtxoCoin(utxo) => my_tx_history_v2_impl(ctx, &utxo, request).await, @@ -384,10 +384,10 @@ pub(crate) async fn my_tx_history_v2_impl( where Coin: CoinWithTxHistoryV2 + MmCoin, { - let tx_history_storage = TxHistoryStorageBuilder::new(&ctx).build()?; + let tx_history_storage = TxHistoryStorageBuilder::new(&ctx).build().map_mm_err()?; let wallet_id = coin.history_wallet_id(); - let is_storage_init = tx_history_storage.is_initialized_for(&wallet_id).await?; + let is_storage_init = tx_history_storage.is_initialized_for(&wallet_id).await.map_mm_err()?; if !is_storage_init { let msg = format!("Storage is not initialized for {:?}", wallet_id); return MmError::err(MyTxHistoryErrorV2::StorageIsNotInitialized(msg)); @@ -401,7 +401,8 @@ where let filters = coin.get_tx_history_filters(request.target.clone()).await?; let history = tx_history_storage .get_history(&wallet_id, filters, request.paging_options.clone(), request.limit) - .await?; + .await + .map_mm_err()?; let coin_conf = coin_conf(&ctx, coin.ticker()); let protocol_type = coin_conf["protocol"]["type"].as_str().unwrap_or_default(); @@ -500,7 +501,7 @@ pub async fn z_coin_tx_history_rpc( ctx: MmArc, request: MyTxHistoryRequestV2, ) -> Result, MmError> { - match lp_coinfind_or_err(&ctx, &request.coin).await? { + match lp_coinfind_or_err(&ctx, &request.coin).await.map_mm_err()? { MmCoinEnum::ZCoin(z_coin) => z_coin.tx_history(request).await, other => MmError::err(MyTxHistoryErrorV2::NotSupportedFor(other.ticker().to_owned())), } diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index ebd4c83146..9c7ad4fa09 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -1,6 +1,6 @@ use http::Uri; use mm2_core::mm_ctx::MmArc; -use mm2_err_handle::prelude::{MmError, MmResult}; +use mm2_err_handle::prelude::{MmError, MmResult, MmResultExt}; use mm2_p2p::p2p_ctx::P2PContext; use proxy_signature::{ProxySign, RawMessage}; use url::Url; @@ -89,18 +89,19 @@ pub type WithdrawNftResult = Result MmResult { let nft_ctx = NftCtx::from_ctx(&ctx).map_to_mm(GetNftInfoError::Internal)?; - let storage = nft_ctx.lock_db().await?; + let storage = nft_ctx.lock_db().await.map_mm_err()?; for chain in req.chains.iter() { - if !NftListStorageOps::is_initialized(&storage, chain).await? { - NftListStorageOps::init(&storage, chain).await?; + if !NftListStorageOps::is_initialized(&storage, chain).await.map_mm_err()? { + NftListStorageOps::init(&storage, chain).await.map_mm_err()?; } } let mut nft_list = storage .get_nft_list(req.chains, req.max, req.limit, req.page_number, req.filters) - .await?; + .await + .map_mm_err()?; if req.protect_from_spam { for nft in &mut nft_list.nfts { - protect_from_nft_spam_links(nft, true)?; + protect_from_nft_spam_links(nft, true).map_mm_err()?; } } Ok(nft_list) @@ -114,19 +115,23 @@ pub async fn get_nft_list(ctx: MmArc, req: NftListReq) -> MmResult MmResult { let nft_ctx = NftCtx::from_ctx(&ctx).map_to_mm(GetNftInfoError::Internal)?; - let storage = nft_ctx.lock_db().await?; - if !NftListStorageOps::is_initialized(&storage, &req.chain).await? { - NftListStorageOps::init(&storage, &req.chain).await?; + let storage = nft_ctx.lock_db().await.map_mm_err()?; + if !NftListStorageOps::is_initialized(&storage, &req.chain) + .await + .map_mm_err()? + { + NftListStorageOps::init(&storage, &req.chain).await.map_mm_err()?; } let mut nft = storage .get_nft(&req.chain, format!("{:#02x}", req.token_address), req.token_id.clone()) - .await? + .await + .map_mm_err()? .ok_or_else(|| GetNftInfoError::TokenNotFoundInWallet { token_address: format!("{:#02x}", req.token_address), token_id: req.token_id.to_string(), })?; if req.protect_from_spam { - protect_from_nft_spam_links(&mut nft, true)?; + protect_from_nft_spam_links(&mut nft, true).map_mm_err()?; } Ok(nft) } @@ -154,24 +159,32 @@ pub async fn get_nft_metadata(ctx: MmArc, req: NftMetadataReq) -> MmResult MmResult { let nft_ctx = NftCtx::from_ctx(&ctx).map_to_mm(GetNftInfoError::Internal)?; - let storage = nft_ctx.lock_db().await?; + let storage = nft_ctx.lock_db().await.map_mm_err()?; for chain in req.chains.iter() { - if !NftTransferHistoryStorageOps::is_initialized(&storage, chain).await? { - NftTransferHistoryStorageOps::init(&storage, chain).await?; + if !NftTransferHistoryStorageOps::is_initialized(&storage, chain) + .await + .map_mm_err()? + { + NftTransferHistoryStorageOps::init(&storage, chain).await.map_mm_err()?; } else { #[cfg(not(target_arch = "wasm32"))] - NftMigrationOps::migrate_tx_history_if_needed(&storage, chain).await?; + NftMigrationOps::migrate_tx_history_if_needed(&storage, chain) + .await + .map_mm_err()?; } } let mut transfer_history_list = storage .get_transfer_history(req.chains.clone(), req.max, req.limit, req.page_number, req.filters) - .await?; + .await + .map_mm_err()?; if req.protect_from_spam { for transfer in &mut transfer_history_list.transfer_history { - protect_from_history_spam_links(transfer, true)?; + protect_from_history_spam_links(transfer, true).map_mm_err()?; } } - process_transfers_confirmations(&ctx, req.chains, &mut transfer_history_list).await?; + process_transfers_confirmations(&ctx, req.chains, &mut transfer_history_list) + .await + .map_mm_err()?; Ok(transfer_history_list) } @@ -189,7 +202,7 @@ async fn process_transfers_confirmations( let futures = chains.into_iter().map(|chain| async move { let ticker = chain.to_ticker(); - let coin_enum = lp_coinfind_or_err(ctx, ticker).await?; + let coin_enum = lp_coinfind_or_err(ctx, ticker).await.map_mm_err()?; match coin_enum { MmCoinEnum::EthCoin(eth_coin) => { let current_block = current_block_impl(eth_coin).await?; @@ -222,23 +235,31 @@ async fn process_transfers_confirmations( /// data fetched from the provided `url`. The function ensures the local cache is in /// sync with the latest data from the source, validates against spam contract addresses and phishing domains. pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNftError> { - let nft_ctx = NftCtx::from_ctx(&ctx).map_to_mm(GetNftInfoError::Internal)?; + let nft_ctx = NftCtx::from_ctx(&ctx) + .map_to_mm(GetNftInfoError::Internal) + .map_mm_err()?; let p2p_ctx = P2PContext::fetch_from_mm_arc(&ctx); - let storage = nft_ctx.lock_db().await?; + let storage = nft_ctx.lock_db().await.map_mm_err()?; for chain in req.chains.iter() { - let transfer_history_initialized = NftTransferHistoryStorageOps::is_initialized(&storage, chain).await?; + let transfer_history_initialized = NftTransferHistoryStorageOps::is_initialized(&storage, chain) + .await + .map_mm_err()?; let from_block = if transfer_history_initialized { #[cfg(not(target_arch = "wasm32"))] - NftMigrationOps::migrate_tx_history_if_needed(&storage, chain).await?; - let last_transfer_block = NftTransferHistoryStorageOps::get_last_block_number(&storage, chain).await?; + NftMigrationOps::migrate_tx_history_if_needed(&storage, chain) + .await + .map_mm_err()?; + let last_transfer_block = NftTransferHistoryStorageOps::get_last_block_number(&storage, chain) + .await + .map_mm_err()?; last_transfer_block.map(|b| b + 1) } else { - NftTransferHistoryStorageOps::init(&storage, chain).await?; + NftTransferHistoryStorageOps::init(&storage, chain).await.map_mm_err()?; None }; - let coin_enum = lp_coinfind_or_err(&ctx, chain.to_nft_ticker()).await?; + let coin_enum = lp_coinfind_or_err(&ctx, chain.to_nft_ticker()).await.map_mm_err()?; let global_nft = match coin_enum { MmCoinEnum::EthCoin(eth_coin) => eth_coin, _ => { @@ -247,7 +268,7 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft }) }, }; - let my_address = global_nft.derivation_method().single_addr_or_err().await?; + let my_address = global_nft.derivation_method().single_addr_or_err().await.map_mm_err()?; let my_address_str = my_address.addr_to_string(); let proxy_sign = if req.komodo_proxy { let uri = Uri::from_str(req.url.as_ref()).map_err(|e| UpdateNftError::Internal(e.to_string()))?; @@ -265,8 +286,13 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft proxy_sign, }; - let nft_transfers = get_moralis_nft_transfers(from_block, global_nft, &my_address_str, &wrapper).await?; - storage.add_transfers_to_history(*chain, nft_transfers).await?; + let nft_transfers = get_moralis_nft_transfers(from_block, global_nft, &my_address_str, &wrapper) + .await + .map_mm_err()?; + storage + .add_transfers_to_history(*chain, nft_transfers) + .await + .map_mm_err()?; let nft_block = match NftListStorageOps::get_last_block_number(&storage, chain).await { Ok(Some(block)) => block, @@ -275,28 +301,28 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft let nft_list = cache_nfts_from_moralis(&my_address_str, &storage, &wrapper).await?; update_meta_in_transfers(&storage, chain, nft_list).await?; update_transfers_with_empty_meta(&storage, &wrapper).await?; - update_spam(&storage, *chain, &req.url_antispam).await?; - update_phishing(&storage, chain, &req.url_antispam).await?; + update_spam(&storage, *chain, &req.url_antispam).await.map_mm_err()?; + update_phishing(&storage, chain, &req.url_antispam).await.map_mm_err()?; continue; }, Err(_) => { // if there is an error, then NFT LIST table doesn't exist, so we need to cache nft list from moralis. - NftListStorageOps::init(&storage, chain).await?; + NftListStorageOps::init(&storage, chain).await.map_mm_err()?; let nft_list = cache_nfts_from_moralis(&my_address_str, &storage, &wrapper).await?; update_meta_in_transfers(&storage, chain, nft_list).await?; update_transfers_with_empty_meta(&storage, &wrapper).await?; - update_spam(&storage, *chain, &req.url_antispam).await?; - update_phishing(&storage, chain, &req.url_antispam).await?; + update_spam(&storage, *chain, &req.url_antispam).await.map_mm_err()?; + update_phishing(&storage, chain, &req.url_antispam).await.map_mm_err()?; continue; }, }; - let scanned_block = - storage - .get_last_scanned_block(chain) - .await? - .ok_or_else(|| UpdateNftError::LastScannedBlockNotFound { - last_nft_block: nft_block.to_string(), - })?; + let scanned_block = storage + .get_last_scanned_block(chain) + .await + .map_mm_err()? + .ok_or_else(|| UpdateNftError::LastScannedBlockNotFound { + last_nft_block: nft_block.to_string(), + })?; // if both block numbers exist, last scanned block should be equal // or higher than last block number from NFT LIST table. if scanned_block < nft_block { @@ -308,8 +334,8 @@ pub async fn update_nft(ctx: MmArc, req: UpdateNftReq) -> MmResult<(), UpdateNft update_nft_list(&storage, scanned_block + 1, &my_address_str, &wrapper).await?; update_nft_global_in_coins_ctx(&ctx, &storage, *chain).await?; update_transfers_with_empty_meta(&storage, &wrapper).await?; - update_spam(&storage, *chain, &req.url_antispam).await?; - update_phishing(&storage, chain, &req.url_antispam).await?; + update_spam(&storage, *chain, &req.url_antispam).await.map_mm_err()?; + update_phishing(&storage, chain, &req.url_antispam).await.map_mm_err()?; } Ok(()) } @@ -331,7 +357,10 @@ where .. }) = coins.get_mut(ticker) { - let nft_list = storage.get_nft_list(vec![chain], true, 1, None, None).await?; + let nft_list = storage + .get_nft_list(vec![chain], true, 1, None, None) + .await + .map_mm_err()?; update_nft_infos(nft_global, nft_list.nfts).await; return Ok(()); } @@ -376,7 +405,7 @@ async fn update_spam(storage: &T, chain: Chain, url_antispam: &Url) -> MmResu where T: NftListStorageOps + NftTransferHistoryStorageOps, { - let token_addresses = storage.get_token_addresses(chain).await?; + let token_addresses = storage.get_token_addresses(chain).await.map_mm_err()?; if !token_addresses.is_empty() { let addresses = token_addresses .iter() @@ -389,10 +418,12 @@ where let address_hex = address.addr_to_string(); storage .update_nft_spam_by_token_address(&chain, address_hex.clone(), is_spam) - .await?; + .await + .map_mm_err()?; storage .update_transfer_spam_by_token_address(&chain, address_hex, is_spam) - .await?; + .await + .map_mm_err()?; } } } @@ -403,8 +434,8 @@ async fn update_phishing(storage: &T, chain: &Chain, url_antispam: &Url) -> M where T: NftListStorageOps + NftTransferHistoryStorageOps, { - let transfer_domains = storage.get_domains(chain).await?; - let nft_domains = storage.get_animation_external_domains(chain).await?; + let transfer_domains = storage.get_domains(chain).await.map_mm_err()?; + let nft_domains = storage.get_animation_external_domains(chain).await.map_mm_err()?; let domains: HashSet = transfer_domains.union(&nft_domains).cloned().collect(); if !domains.is_empty() { let domains = domains.into_iter().collect::>().join(","); @@ -413,10 +444,12 @@ where if is_phishing { storage .update_nft_phishing_by_domain(chain, domain.clone(), is_phishing) - .await?; + .await + .map_mm_err()?; storage .update_transfer_phishing_by_domain(chain, domain, is_phishing) - .await?; + .await + .map_mm_err()?; } } } @@ -435,7 +468,9 @@ async fn send_spam_request( addresses, }; let req_spam_json = serde_json::to_string(&req_spam)?; - let scan_contract_res = send_post_request_to_uri(scan_contract_uri.as_str(), req_spam_json).await?; + let scan_contract_res = send_post_request_to_uri(scan_contract_uri.as_str(), req_spam_json) + .await + .map_mm_err()?; let spam_res: SpamContractRes = serde_json::from_slice(&scan_contract_res)?; Ok(spam_res) } @@ -448,7 +483,9 @@ async fn send_phishing_request( let scan_contract_uri = prepare_uri_for_blocklist_endpoint(url_antispam, BLOCKLIST_DOMAIN, BLOCKLIST_SCAN)?; let req_phishing = PhishingDomainReq { domains }; let req_phishing_json = serde_json::to_string(&req_phishing)?; - let scan_domains_res = send_post_request_to_uri(scan_contract_uri.as_str(), req_phishing_json).await?; + let scan_domains_res = send_post_request_to_uri(scan_contract_uri.as_str(), req_phishing_json) + .await + .map_mm_err()?; let phishing_res: PhishingDomainRes = serde_json::from_slice(&scan_domains_res)?; Ok(phishing_res) } @@ -477,10 +514,12 @@ fn prepare_uri_for_blocklist_endpoint( /// is identified as spam or matches with any phishing domains, the NFT's `possible_spam` and/or /// `possible_phishing` flags are set to true. pub async fn refresh_nft_metadata(ctx: MmArc, req: RefreshMetadataReq) -> MmResult<(), UpdateNftError> { - let nft_ctx = NftCtx::from_ctx(&ctx).map_to_mm(GetNftInfoError::Internal)?; + let nft_ctx = NftCtx::from_ctx(&ctx) + .map_to_mm(GetNftInfoError::Internal) + .map_mm_err()?; let p2p_ctx = P2PContext::fetch_from_mm_arc(&ctx); - let storage = nft_ctx.lock_db().await?; + let storage = nft_ctx.lock_db().await.map_mm_err()?; let proxy_sign = if req.komodo_proxy { let uri = Uri::from_str(req.url.as_ref()).map_err(|e| UpdateNftError::Internal(e.to_string()))?; @@ -503,23 +542,26 @@ pub async fn refresh_nft_metadata(ctx: MmArc, req: RefreshMetadataReq) -> MmResu Err(_) => { storage .update_nft_spam_by_token_address(&req.chain, token_address_str.clone(), true) - .await?; + .await + .map_mm_err()?; storage .update_transfer_spam_by_token_address(&req.chain, token_address_str.clone(), true) - .await?; + .await + .map_mm_err()?; return Ok(()); }, }; let mut nft_db = storage .get_nft(&req.chain, token_address_str.clone(), req.token_id.clone()) - .await? + .await + .map_mm_err()? .ok_or_else(|| GetNftInfoError::TokenNotFoundInWallet { token_address: token_address_str, token_id: req.token_id.to_string(), })?; let token_uri = check_moralis_ipfs_bafy(moralis_meta.common.token_uri.as_deref()); let token_domain = get_domain_from_url(token_uri.as_deref()); - check_token_uri(&mut moralis_meta.common.possible_spam, token_uri.as_deref())?; + check_token_uri(&mut moralis_meta.common.possible_spam, token_uri.as_deref()).map_mm_err()?; drop_mutability!(moralis_meta); let uri_meta = get_uri_meta( token_uri.as_deref(), @@ -548,7 +590,8 @@ pub async fn refresh_nft_metadata(ctx: MmArc, req: RefreshMetadataReq) -> MmResu }; storage .refresh_nft_metadata(&moralis_meta.chain, nft_db.clone()) - .await?; + .await + .map_mm_err()?; update_transfer_meta_using_nft(&storage, &req.chain, &mut nft_db).await?; Ok(()) } @@ -562,7 +605,8 @@ where let transfer_meta = TransferMeta::from(nft.clone()); storage .update_transfers_meta_by_token_addr_id(chain, transfer_meta, nft.common.possible_spam) - .await?; + .await + .map_mm_err()?; Ok(()) } @@ -595,15 +639,19 @@ where T: NftListStorageOps + NftTransferHistoryStorageOps, { let address_hex = nft_db.common.token_address.addr_to_string(); - let spam_res = send_spam_request(chain, url_antispam, address_hex.clone()).await?; + let spam_res = send_spam_request(chain, url_antispam, address_hex.clone()) + .await + .map_mm_err()?; if let Some(true) = spam_res.result.get(&nft_db.common.token_address) { nft_db.common.possible_spam = true; storage .update_nft_spam_by_token_address(chain, address_hex.clone(), true) - .await?; + .await + .map_mm_err()?; storage .update_transfer_spam_by_token_address(chain, address_hex, true) - .await?; + .await + .map_mm_err()?; } Ok(()) } @@ -621,16 +669,18 @@ where { if !domains.is_empty() { let domain_list = domains.into_iter().collect::>().join(","); - let domain_res = send_phishing_request(url_antispam, domain_list).await?; + let domain_res = send_phishing_request(url_antispam, domain_list).await.map_mm_err()?; for (domain, is_phishing) in domain_res.result.into_iter() { if is_phishing { nft_db.possible_phishing = true; storage .update_transfer_phishing_by_domain(chain, domain.clone(), is_phishing) - .await?; + .await + .map_mm_err()?; storage .update_nft_phishing_by_domain(chain, domain, is_phishing) - .await?; + .await + .map_mm_err()?; } } } @@ -659,7 +709,7 @@ async fn get_moralis_nft_list( None => continue, }; let mut nft = build_nft_from_moralis(*chain, nft_moralis, contract_type, wrapper.url_antispam).await; - protect_from_nft_spam_links(&mut nft, false)?; + protect_from_nft_spam_links(&mut nft, false).map_mm_err()?; // collect NFTs from the page res_list.push(nft); } @@ -917,7 +967,7 @@ async fn get_moralis_metadata( None => return MmError::err(GetNftInfoError::ContractTypeIsNull), }; let mut nft_metadata = build_nft_from_moralis(*chain, nft_moralis, contract_type, wrapper.url_antispam).await; - protect_from_nft_spam_links(&mut nft_metadata, false)?; + protect_from_nft_spam_links(&mut nft_metadata, false).map_mm_err()?; Ok(nft_metadata) } @@ -988,7 +1038,7 @@ fn construct_camo_url_with_token(token_uri: &str, url_antispam: &Url) -> Option< } async fn fetch_meta_from_url(url: Url) -> MmResult { - let response_meta = send_request_to_uri(url.as_str(), None).await?; + let response_meta = send_request_to_uri(url.as_str(), None).await.map_mm_err()?; serde_json::from_value(response_meta).map_err(|e| e.into()) } @@ -1019,7 +1069,10 @@ async fn update_nft_list( wrapper: &UrlSignWrapper<'_>, ) -> MmResult<(), UpdateNftError> { let chain = wrapper.chain; - let transfers = storage.get_transfers_from_block(*chain, scan_from_block).await?; + let transfers = storage + .get_transfers_from_block(*chain, scan_from_block) + .await + .map_mm_err()?; for transfer in transfers.into_iter() { handle_nft_transfer(storage, wrapper, transfer, wallet_address).await?; } @@ -1056,7 +1109,8 @@ async fn handle_send_erc721 transfer.common.token_address.addr_to_string(), transfer.token_id.clone(), ) - .await? + .await + .map_mm_err()? .ok_or_else(|| UpdateNftError::TokenNotFoundInWallet { token_address: transfer.common.token_address.addr_to_string(), token_id: transfer.token_id.to_string(), @@ -1068,7 +1122,8 @@ async fn handle_send_erc721 transfer.token_id, transfer.block_number, ) - .await?; + .await + .map_mm_err()?; Ok(()) } @@ -1082,7 +1137,8 @@ async fn handle_receive_erc721 { // An error is raised if user tries to receive an identical ERC-721 token they already own @@ -1095,7 +1151,8 @@ async fn handle_receive_erc721 { @@ -1116,7 +1173,8 @@ async fn handle_receive_erc721 { storage .remove_nft_from_list(chain, token_address_str, transfer.token_id, transfer.block_number) - .await?; + .await + .map_mm_err()?; }, Ordering::Greater => { nft_db.common.amount -= transfer.common.amount; storage .update_nft_amount(chain, nft_db.clone(), transfer.block_number) - .await?; + .await + .map_mm_err()?; }, Ordering::Less => { return MmError::err(UpdateNftError::InsufficientAmountInCache { @@ -1168,7 +1229,8 @@ async fn handle_receive_erc1155 { // if owner address == from address, then owner sent tokens to themself, @@ -1180,7 +1242,8 @@ async fn handle_receive_erc1155 MmResult { let token_uri = check_moralis_ipfs_bafy(moralis_meta.common.token_uri.as_deref()); let token_domain = get_domain_from_url(token_uri.as_deref()); - check_token_uri(&mut moralis_meta.common.possible_spam, token_uri.as_deref())?; + check_token_uri(&mut moralis_meta.common.possible_spam, token_uri.as_deref()).map_mm_err()?; let uri_meta = get_uri_meta( token_uri.as_deref(), moralis_meta.common.metadata.as_deref(), @@ -1268,10 +1332,12 @@ async fn mark_as_spam_and_build_empty_meta MmResult { storage .update_nft_spam_by_token_address(chain, token_address_str.clone(), true) - .await?; + .await + .map_mm_err()?; storage .update_transfer_spam_by_token_address(chain, token_address_str, true) - .await?; + .await + .map_mm_err()?; Ok(build_nft_with_empty_meta(BuildNftFields { token_address: transfer.common.token_address, @@ -1290,13 +1356,15 @@ async fn cache_nfts_from_moralis, ) -> MmResult, UpdateNftError> { - let nft_list = get_moralis_nft_list(wallet_address, wrapper).await?; + let nft_list = get_moralis_nft_list(wallet_address, wrapper).await.map_mm_err()?; let last_scanned_block = NftTransferHistoryStorageOps::get_last_block_number(storage, wrapper.chain) - .await? + .await + .map_mm_err()? .unwrap_or(0); storage .add_nfts_to_list(*wrapper.chain, nft_list.clone(), last_scanned_block) - .await?; + .await + .map_mm_err()?; Ok(nft_list) } @@ -1317,7 +1385,7 @@ where T: NftListStorageOps + NftTransferHistoryStorageOps, { let chain = wrapper.chain; - let token_addr_id = storage.get_transfers_with_empty_meta(*chain).await?; + let token_addr_id = storage.get_transfers_with_empty_meta(*chain).await.map_mm_err()?; for addr_id_pair in token_addr_id.into_iter() { let mut nft_meta = match get_moralis_metadata(addr_id_pair.token_address.clone(), addr_id_pair.token_id, wrapper).await { @@ -1325,10 +1393,12 @@ where Err(_) => { storage .update_nft_spam_by_token_address(chain, addr_id_pair.token_address.clone(), true) - .await?; + .await + .map_mm_err()?; storage .update_transfer_spam_by_token_address(chain, addr_id_pair.token_address, true) - .await?; + .await + .map_mm_err()?; continue; }, }; @@ -1506,9 +1576,9 @@ pub(crate) fn get_domain_from_url(url: Option<&str>) -> Option { pub async fn clear_nft_db(ctx: MmArc, req: ClearNftDbReq) -> MmResult<(), ClearNftDbError> { if req.clear_all { let nft_ctx = NftCtx::from_ctx(&ctx).map_to_mm(ClearNftDbError::Internal)?; - let storage = nft_ctx.lock_db().await?; - storage.clear_all_nft_data().await?; - storage.clear_all_history_data().await?; + let storage = nft_ctx.lock_db().await.map_mm_err()?; + storage.clear_all_nft_data().await.map_mm_err()?; + storage.clear_all_history_data().await.map_mm_err()?; return Ok(()); } @@ -1519,7 +1589,7 @@ pub async fn clear_nft_db(ctx: MmArc, req: ClearNftDbReq) -> MmResult<(), ClearN } let nft_ctx = NftCtx::from_ctx(&ctx).map_to_mm(ClearNftDbError::Internal)?; - let storage = nft_ctx.lock_db().await?; + let storage = nft_ctx.lock_db().await.map_mm_err()?; let mut errors = Vec::new(); for chain in req.chains.iter() { if let Err(e) = clear_data_for_chain(&storage, chain).await { @@ -1538,14 +1608,16 @@ where T: NftListStorageOps + NftTransferHistoryStorageOps, { let (is_nft_list_init, is_history_init) = ( - NftListStorageOps::is_initialized(storage, chain).await?, - NftTransferHistoryStorageOps::is_initialized(storage, chain).await?, + NftListStorageOps::is_initialized(storage, chain).await.map_mm_err()?, + NftTransferHistoryStorageOps::is_initialized(storage, chain) + .await + .map_mm_err()?, ); if is_nft_list_init { - storage.clear_nft_data(chain).await?; + storage.clear_nft_data(chain).await.map_mm_err()?; } if is_history_init { - storage.clear_history_data(chain).await?; + storage.clear_history_data(chain).await.map_mm_err()?; } Ok(()) } @@ -1574,6 +1646,6 @@ struct UrlSignWrapper<'a> { async fn build_and_send_request(uri: &str, proxy_sign: &Option) -> MmResult { let payload = proxy_sign.as_ref().map(|msg| serde_json::to_string(&msg)).transpose()?; - let response = send_request_to_uri(uri, payload.as_deref()).await?; + let response = send_request_to_uri(uri, payload.as_deref()).await.map_mm_err()?; Ok(response) } diff --git a/mm2src/coins/nft/storage/mod.rs b/mm2src/coins/nft/storage/mod.rs index 3eed941b5d..de61d04a40 100644 --- a/mm2src/coins/nft/storage/mod.rs +++ b/mm2src/coins/nft/storage/mod.rs @@ -4,7 +4,7 @@ use crate::nft::nft_structs::{Chain, Nft, NftList, NftListFilters, NftTokenAddrI use async_trait::async_trait; use ethereum_types::Address; use mm2_err_handle::mm_error::MmResult; -use mm2_err_handle::mm_error::{NotEqual, NotMmError}; +use mm2_err_handle::mm_error::NotMmError; use mm2_number::{BigDecimal, BigUint}; use serde::{Deserialize, Serialize}; use std::collections::HashSet; @@ -25,7 +25,7 @@ pub enum RemoveNftResult { } /// Defines the standard errors that can occur in NFT storage operations -pub trait NftStorageError: std::fmt::Debug + NotMmError + NotEqual + Send {} +pub trait NftStorageError: std::fmt::Debug + NotMmError + Send {} /// Provides asynchronous operations for handling and querying NFT listings. #[async_trait] diff --git a/mm2src/coins/nft/storage/sql_storage.rs b/mm2src/coins/nft/storage/sql_storage.rs index c3e575b321..1829f8d500 100644 --- a/mm2src/coins/nft/storage/sql_storage.rs +++ b/mm2src/coins/nft/storage/sql_storage.rs @@ -605,7 +605,7 @@ impl NftListStorageOps for AsyncMutexGuard<'_, AsyncConnection> { type Error = AsyncConnError; async fn init(&self, chain: &Chain) -> MmResult<(), Self::Error> { - let sql_nft_list = create_nft_list_table_sql(chain)?; + let sql_nft_list = create_nft_list_table_sql(chain).map_mm_err()?; self.call(move |conn| { conn.execute(&sql_nft_list, []).map(|_| ())?; conn.execute(&create_scanned_nft_blocks_sql()?, []).map(|_| ())?; @@ -843,7 +843,7 @@ impl NftListStorageOps for AsyncMutexGuard<'_, AsyncConnection> { } async fn get_last_scanned_block(&self, chain: &Chain) -> MmResult, Self::Error> { - let sql = select_last_scanned_block_sql()?; + let sql = select_last_scanned_block_sql().map_mm_err()?; let params = [chain.to_ticker()]; self.call(move |conn| { let block_number = query_single_row(conn, &sql, params, block_number_from_row)?; diff --git a/mm2src/coins/nft/storage/wasm/wasm_storage.rs b/mm2src/coins/nft/storage/wasm/wasm_storage.rs index 5ad0190179..47e16870e0 100644 --- a/mm2src/coins/nft/storage/wasm/wasm_storage.rs +++ b/mm2src/coins/nft/storage/wasm/wasm_storage.rs @@ -8,8 +8,7 @@ use crate::nft::storage::{get_offset_limit, NftListStorageOps, NftTokenAddrId, N use async_trait::async_trait; use ethereum_types::Address; use mm2_db::indexed_db::{BeBigUint, DbTable, DbUpgrader, MultiIndex, OnUpgradeError, OnUpgradeResult, TableSignature}; -use mm2_err_handle::map_to_mm::MapToMmResult; -use mm2_err_handle::prelude::{MmError, MmResult}; +use mm2_err_handle::prelude::*; use mm2_number::BigUint; use num_traits::ToPrimitive; use serde_json::{self as json, Value as Json}; @@ -144,13 +143,14 @@ impl NftListStorageOps for NftCacheIDBLocked<'_> { page_number: Option, filters: Option, ) -> MmResult { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let mut nfts = Vec::new(); for chain in chains { let nft_tables = table .get_items("chain", chain.to_string()) - .await? + .await + .map_mm_err()? .into_iter() .map(|(_item_id, nft)| nft); let filtered = filter_nfts(nft_tables, filters)?; @@ -164,12 +164,12 @@ impl NftListStorageOps for NftCacheIDBLocked<'_> { I: IntoIterator + Send + 'static, I::IntoIter: Send, { - let db_transaction = self.get_inner().transaction().await?; - let nft_table = db_transaction.table::().await?; - let last_scanned_block_table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let nft_table = db_transaction.table::().await.map_mm_err()?; + let last_scanned_block_table = db_transaction.table::().await.map_mm_err()?; for nft in nfts { let nft_item = NftListTable::from_nft(&nft)?; - nft_table.add_item(&nft_item).await?; + nft_table.add_item(&nft_item).await.map_mm_err()?; } let last_scanned_block = LastScannedBlockTable { chain: chain.to_string(), @@ -177,7 +177,8 @@ impl NftListStorageOps for NftCacheIDBLocked<'_> { }; last_scanned_block_table .replace_item_by_unique_index("chain", chain.to_string(), &last_scanned_block) - .await?; + .await + .map_mm_err()?; Ok(()) } @@ -187,14 +188,17 @@ impl NftListStorageOps for NftCacheIDBLocked<'_> { token_address: String, token_id: BigUint, ) -> MmResult, Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(CHAIN_TOKEN_ADD_TOKEN_ID_INDEX) - .with_value(chain.to_string())? - .with_value(&token_address)? - .with_value(BeBigUint::from(token_id))?; - - if let Some((_item_id, item)) = table.get_item_by_unique_multi_index(index_keys).await? { + .with_value(chain.to_string()) + .map_mm_err()? + .with_value(&token_address) + .map_mm_err()? + .with_value(BeBigUint::from(token_id)) + .map_mm_err()?; + + if let Some((_item_id, item)) = table.get_item_by_unique_multi_index(index_keys).await.map_mm_err()? { Ok(Some(nft_details_from_item(item)?)) } else { Ok(None) @@ -208,24 +212,32 @@ impl NftListStorageOps for NftCacheIDBLocked<'_> { token_id: BigUint, scanned_block: u64, ) -> MmResult { - let db_transaction = self.get_inner().transaction().await?; - let nft_table = db_transaction.table::().await?; - let last_scanned_block_table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let nft_table = db_transaction.table::().await.map_mm_err()?; + let last_scanned_block_table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(CHAIN_TOKEN_ADD_TOKEN_ID_INDEX) - .with_value(chain.to_string())? - .with_value(&token_address)? - .with_value(BeBigUint::from(token_id))?; + .with_value(chain.to_string()) + .map_mm_err()? + .with_value(&token_address) + .map_mm_err()? + .with_value(BeBigUint::from(token_id)) + .map_mm_err()?; let last_scanned_block = LastScannedBlockTable { chain: chain.to_string(), last_scanned_block: BeBigUint::from(scanned_block), }; - let nft_removed = nft_table.delete_item_by_unique_multi_index(index_keys).await?.is_some(); + let nft_removed = nft_table + .delete_item_by_unique_multi_index(index_keys) + .await + .map_mm_err()? + .is_some(); last_scanned_block_table .replace_item_by_unique_index("chain", chain.to_string(), &last_scanned_block) - .await?; + .await + .map_mm_err()?; if nft_removed { Ok(RemoveNftResult::NftRemoved) } else { @@ -239,14 +251,17 @@ impl NftListStorageOps for NftCacheIDBLocked<'_> { token_address: String, token_id: BigUint, ) -> MmResult, Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(CHAIN_TOKEN_ADD_TOKEN_ID_INDEX) - .with_value(chain.to_string())? - .with_value(&token_address)? - .with_value(BeBigUint::from(token_id))?; - - if let Some((_item_id, item)) = table.get_item_by_unique_multi_index(index_keys).await? { + .with_value(chain.to_string()) + .map_mm_err()? + .with_value(&token_address) + .map_mm_err()? + .with_value(BeBigUint::from(token_id)) + .map_mm_err()?; + + if let Some((_item_id, item)) = table.get_item_by_unique_multi_index(index_keys).await.map_mm_err()? { Ok(Some(nft_details_from_item(item)?.common.amount.to_string())) } else { Ok(None) @@ -254,28 +269,38 @@ impl NftListStorageOps for NftCacheIDBLocked<'_> { } async fn refresh_nft_metadata(&self, chain: &Chain, nft: Nft) -> MmResult<(), Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(CHAIN_TOKEN_ADD_TOKEN_ID_INDEX) - .with_value(chain.to_string())? - .with_value(nft.common.token_address.addr_to_string())? - .with_value(BeBigUint::from(nft.token_id.clone()))?; + .with_value(chain.to_string()) + .map_mm_err()? + .with_value(nft.common.token_address.addr_to_string()) + .map_mm_err()? + .with_value(BeBigUint::from(nft.token_id.clone())) + .map_mm_err()?; let nft_item = NftListTable::from_nft(&nft)?; - table.replace_item_by_unique_multi_index(index_keys, &nft_item).await?; + table + .replace_item_by_unique_multi_index(index_keys, &nft_item) + .await + .map_mm_err()?; Ok(()) } async fn get_last_block_number(&self, chain: &Chain) -> MmResult, Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; get_last_block_from_table(chain, table, CHAIN_BLOCK_NUMBER_INDEX).await } async fn get_last_scanned_block(&self, chain: &Chain) -> MmResult, Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; - if let Some((_item_id, item)) = table.get_item_by_unique_index("chain", chain.to_string()).await? { + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; + if let Some((_item_id, item)) = table + .get_item_by_unique_index("chain", chain.to_string()) + .await + .map_mm_err()? + { let last_scanned_block = item .last_scanned_block .to_u64() @@ -287,64 +312,77 @@ impl NftListStorageOps for NftCacheIDBLocked<'_> { } async fn update_nft_amount(&self, chain: &Chain, nft: Nft, scanned_block: u64) -> MmResult<(), Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let nft_table = db_transaction.table::().await?; - let last_scanned_block_table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let nft_table = db_transaction.table::().await.map_mm_err()?; + let last_scanned_block_table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(CHAIN_TOKEN_ADD_TOKEN_ID_INDEX) - .with_value(chain.to_string())? - .with_value(nft.common.token_address.addr_to_string())? - .with_value(BeBigUint::from(nft.token_id.clone()))?; + .with_value(chain.to_string()) + .map_mm_err()? + .with_value(nft.common.token_address.addr_to_string()) + .map_mm_err()? + .with_value(BeBigUint::from(nft.token_id.clone())) + .map_mm_err()?; let nft_item = NftListTable::from_nft(&nft)?; nft_table .replace_item_by_unique_multi_index(index_keys, &nft_item) - .await?; + .await + .map_mm_err()?; let last_scanned_block = LastScannedBlockTable { chain: chain.to_string(), last_scanned_block: BeBigUint::from(scanned_block), }; last_scanned_block_table .replace_item_by_unique_index("chain", chain.to_string(), &last_scanned_block) - .await?; + .await + .map_mm_err()?; Ok(()) } async fn update_nft_amount_and_block_number(&self, chain: &Chain, nft: Nft) -> MmResult<(), Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let nft_table = db_transaction.table::().await?; - let last_scanned_block_table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let nft_table = db_transaction.table::().await.map_mm_err()?; + let last_scanned_block_table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(CHAIN_TOKEN_ADD_TOKEN_ID_INDEX) - .with_value(chain.to_string())? - .with_value(nft.common.token_address.addr_to_string())? - .with_value(BeBigUint::from(nft.token_id.clone()))?; + .with_value(chain.to_string()) + .map_mm_err()? + .with_value(nft.common.token_address.addr_to_string()) + .map_mm_err()? + .with_value(BeBigUint::from(nft.token_id.clone())) + .map_mm_err()?; let nft_item = NftListTable::from_nft(&nft)?; nft_table .replace_item_by_unique_multi_index(index_keys, &nft_item) - .await?; + .await + .map_mm_err()?; let last_scanned_block = LastScannedBlockTable { chain: chain.to_string(), last_scanned_block: BeBigUint::from(nft.block_number), }; last_scanned_block_table .replace_item_by_unique_index("chain", chain.to_string(), &last_scanned_block) - .await?; + .await + .map_mm_err()?; Ok(()) } async fn get_nfts_by_token_address(&self, chain: Chain, token_address: String) -> MmResult, Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(CHAIN_TOKEN_ADD_INDEX) - .with_value(chain.to_string())? - .with_value(&token_address)?; + .with_value(chain.to_string()) + .map_mm_err()? + .with_value(&token_address) + .map_mm_err()?; table .get_items_by_multi_index(index_keys) - .await? + .await + .map_mm_err()? .into_iter() .map(|(_item_id, item)| nft_details_from_item(item)) .collect() @@ -356,17 +394,20 @@ impl NftListStorageOps for NftCacheIDBLocked<'_> { token_address: String, possible_spam: bool, ) -> MmResult<(), Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let chain_str = chain.to_string(); let index_keys = MultiIndex::new(CHAIN_TOKEN_ADD_INDEX) - .with_value(&chain_str)? - .with_value(&token_address)?; + .with_value(&chain_str) + .map_mm_err()? + .with_value(&token_address) + .map_mm_err()?; let nfts: Result, _> = table .get_items_by_multi_index(index_keys) - .await? + .await + .map_mm_err()? .into_iter() .map(|(_item_id, item)| nft_details_from_item(item)) .collect(); @@ -377,22 +418,28 @@ impl NftListStorageOps for NftCacheIDBLocked<'_> { drop_mutability!(nft); let index_keys = MultiIndex::new(CHAIN_TOKEN_ADD_TOKEN_ID_INDEX) - .with_value(&chain_str)? - .with_value(nft.common.token_address.addr_to_string())? - .with_value(BeBigUint::from(nft.token_id.clone()))?; + .with_value(&chain_str) + .map_mm_err()? + .with_value(nft.common.token_address.addr_to_string()) + .map_mm_err()? + .with_value(BeBigUint::from(nft.token_id.clone())) + .map_mm_err()?; let item = NftListTable::from_nft(&nft)?; - table.replace_item_by_unique_multi_index(index_keys, &item).await?; + table + .replace_item_by_unique_multi_index(index_keys, &item) + .await + .map_mm_err()?; } Ok(()) } async fn get_animation_external_domains(&self, chain: &Chain) -> MmResult, Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let mut domains = HashSet::new(); - let nft_tables = table.get_items("chain", chain.to_string()).await?; + let nft_tables = table.get_items("chain", chain.to_string()).await.map_mm_err()?; for (_item_id, nft) in nft_tables.into_iter() { if let Some(domain) = nft.animation_domain { domains.insert(domain); @@ -410,8 +457,8 @@ impl NftListStorageOps for NftCacheIDBLocked<'_> { domain: String, possible_phishing: bool, ) -> MmResult<(), Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let chain_str = chain.to_string(); update_nft_phishing_for_index(&table, &chain_str, CHAIN_TOKEN_DOMAIN_INDEX, &domain, possible_phishing).await?; @@ -424,23 +471,27 @@ impl NftListStorageOps for NftCacheIDBLocked<'_> { } async fn clear_nft_data(&self, chain: &Chain) -> MmResult<(), Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let nft_table = db_transaction.table::().await?; - let last_scanned_block_table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let nft_table = db_transaction.table::().await.map_mm_err()?; + let last_scanned_block_table = db_transaction.table::().await.map_mm_err()?; - nft_table.delete_items_by_index("chain", chain.to_string()).await?; + nft_table + .delete_items_by_index("chain", chain.to_string()) + .await + .map_mm_err()?; last_scanned_block_table .delete_item_by_unique_index("chain", chain.to_string()) - .await?; + .await + .map_mm_err()?; Ok(()) } async fn clear_all_nft_data(&self) -> MmResult<(), Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let nft_table = db_transaction.table::().await?; - let last_scanned_block_table = db_transaction.table::().await?; - nft_table.clear().await?; - last_scanned_block_table.clear().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let nft_table = db_transaction.table::().await.map_mm_err()?; + let last_scanned_block_table = db_transaction.table::().await.map_mm_err()?; + nft_table.clear().await.map_mm_err()?; + last_scanned_block_table.clear().await.map_mm_err()?; Ok(()) } } @@ -461,13 +512,14 @@ impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { page_number: Option, filters: Option, ) -> MmResult { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let mut transfers = Vec::new(); for chain in chains { let transfer_tables = table .get_items("chain", chain.to_string()) - .await? + .await + .map_mm_err()? .into_iter() .map(|(_item_id, transfer)| transfer); let filtered = filter_transfers(transfer_tables, filters)?; @@ -481,18 +533,18 @@ impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { I: IntoIterator + Send + 'static, I::IntoIter: Send, { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; for transfer in transfers { let transfer_item = NftTransferHistoryTable::from_transfer_history(&transfer)?; - table.add_item(&transfer_item).await?; + table.add_item(&transfer_item).await.map_mm_err()?; } Ok(()) } async fn get_last_block_number(&self, chain: &Chain) -> MmResult, Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; get_last_block_from_table(chain, table, CHAIN_BLOCK_NUMBER_INDEX).await } @@ -501,8 +553,8 @@ impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { chain: Chain, from_block: u64, ) -> MmResult, Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let mut cursor_iter = table .cursor_builder() .only("chain", chain.to_string()) @@ -530,17 +582,21 @@ impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { token_address: String, token_id: BigUint, ) -> MmResult, Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(CHAIN_TOKEN_ADD_TOKEN_ID_INDEX) - .with_value(chain.to_string())? - .with_value(&token_address)? - .with_value(BeBigUint::from(token_id))?; + .with_value(chain.to_string()) + .map_mm_err()? + .with_value(&token_address) + .map_mm_err()? + .with_value(BeBigUint::from(token_id)) + .map_mm_err()?; table .get_items_by_multi_index(index_keys) - .await? + .await + .map_mm_err()? .into_iter() .map(|(_item_id, item)| transfer_details_from_item(item)) .collect() @@ -553,15 +609,19 @@ impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { log_index: u32, token_id: BigUint, ) -> MmResult, Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(NftTransferHistoryTable::CHAIN_TX_HASH_LOG_INDEX_TOKEN_ID_INDEX) - .with_value(chain.to_string())? - .with_value(&transaction_hash)? - .with_value(log_index)? - .with_value(BeBigUint::from(token_id))?; - - if let Some((_item_id, item)) = table.get_item_by_unique_multi_index(index_keys).await? { + .with_value(chain.to_string()) + .map_mm_err()? + .with_value(&transaction_hash) + .map_mm_err()? + .with_value(log_index) + .map_mm_err()? + .with_value(BeBigUint::from(token_id)) + .map_mm_err()?; + + if let Some((_item_id, item)) = table.get_item_by_unique_multi_index(index_keys).await.map_mm_err()? { Ok(Some(transfer_details_from_item(item)?)) } else { Ok(None) @@ -574,18 +634,22 @@ impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { transfer_meta: TransferMeta, set_spam: bool, ) -> MmResult<(), Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let chain_str = chain.to_string(); let index_keys = MultiIndex::new(CHAIN_TOKEN_ADD_TOKEN_ID_INDEX) - .with_value(&chain_str)? - .with_value(&transfer_meta.token_address)? - .with_value(BeBigUint::from(transfer_meta.token_id))?; + .with_value(&chain_str) + .map_mm_err()? + .with_value(&transfer_meta.token_address) + .map_mm_err()? + .with_value(BeBigUint::from(transfer_meta.token_id)) + .map_mm_err()?; let transfers: Result, _> = table .get_items_by_multi_index(index_keys) - .await? + .await + .map_mm_err()? .into_iter() .map(|(_item_id, item)| transfer_details_from_item(item)) .collect(); @@ -604,20 +668,27 @@ impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { drop_mutability!(transfer); let index_keys = MultiIndex::new(NftTransferHistoryTable::CHAIN_TX_HASH_LOG_INDEX_TOKEN_ID_INDEX) - .with_value(&chain_str)? - .with_value(&transfer.common.transaction_hash)? - .with_value(transfer.common.log_index)? - .with_value(BeBigUint::from(transfer.token_id.clone()))?; + .with_value(&chain_str) + .map_mm_err()? + .with_value(&transfer.common.transaction_hash) + .map_mm_err()? + .with_value(transfer.common.log_index) + .map_mm_err()? + .with_value(BeBigUint::from(transfer.token_id.clone())) + .map_mm_err()?; let item = NftTransferHistoryTable::from_transfer_history(&transfer)?; - table.replace_item_by_unique_multi_index(index_keys, &item).await?; + table + .replace_item_by_unique_multi_index(index_keys, &item) + .await + .map_mm_err()?; } Ok(()) } async fn get_transfers_with_empty_meta(&self, chain: Chain) -> MmResult, Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let mut cursor_iter = table .cursor_builder() .only("chain", chain.to_string()) @@ -652,16 +723,19 @@ impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { chain: Chain, token_address: String, ) -> MmResult, Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(CHAIN_TOKEN_ADD_INDEX) - .with_value(chain.to_string())? - .with_value(&token_address)?; + .with_value(chain.to_string()) + .map_mm_err()? + .with_value(&token_address) + .map_mm_err()?; table .get_items_by_multi_index(index_keys) - .await? + .await + .map_mm_err()? .into_iter() .map(|(_item_id, item)| transfer_details_from_item(item)) .collect() @@ -673,17 +747,20 @@ impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { token_address: String, possible_spam: bool, ) -> MmResult<(), Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let chain_str = chain.to_string(); let index_keys = MultiIndex::new(CHAIN_TOKEN_ADD_INDEX) - .with_value(&chain_str)? - .with_value(&token_address)?; + .with_value(&chain_str) + .map_mm_err()? + .with_value(&token_address) + .map_mm_err()?; let transfers: Result, _> = table .get_items_by_multi_index(index_keys) - .await? + .await + .map_mm_err()? .into_iter() .map(|(_item_id, item)| transfer_details_from_item(item)) .collect(); @@ -694,22 +771,29 @@ impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { drop_mutability!(transfer); let index_keys = MultiIndex::new(NftTransferHistoryTable::CHAIN_TX_HASH_LOG_INDEX_TOKEN_ID_INDEX) - .with_value(&chain_str)? - .with_value(&transfer.common.transaction_hash)? - .with_value(transfer.common.log_index)? - .with_value(BeBigUint::from(transfer.token_id.clone()))?; + .with_value(&chain_str) + .map_mm_err()? + .with_value(&transfer.common.transaction_hash) + .map_mm_err()? + .with_value(transfer.common.log_index) + .map_mm_err()? + .with_value(BeBigUint::from(transfer.token_id.clone())) + .map_mm_err()?; let item = NftTransferHistoryTable::from_transfer_history(&transfer)?; - table.replace_item_by_unique_multi_index(index_keys, &item).await?; + table + .replace_item_by_unique_multi_index(index_keys, &item) + .await + .map_mm_err()?; } Ok(()) } async fn get_token_addresses(&self, chain: Chain) -> MmResult, Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; - let items = table.get_items("chain", chain.to_string()).await?; + let items = table.get_items("chain", chain.to_string()).await.map_mm_err()?; let mut token_addresses = HashSet::with_capacity(items.len()); for (_item_id, item) in items.into_iter() { let transfer = transfer_details_from_item(item)?; @@ -719,11 +803,11 @@ impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { } async fn get_domains(&self, chain: &Chain) -> MmResult, Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let mut domains = HashSet::new(); - let transfer_tables = table.get_items("chain", chain.to_string()).await?; + let transfer_tables = table.get_items("chain", chain.to_string()).await.map_mm_err()?; for (_item_id, transfer) in transfer_tables.into_iter() { if let Some(domain) = transfer.token_domain { domains.insert(domain); @@ -741,8 +825,8 @@ impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { domain: String, possible_phishing: bool, ) -> MmResult<(), Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let chain_str = chain.to_string(); update_transfer_phishing_for_index(&table, &chain_str, CHAIN_TOKEN_DOMAIN_INDEX, &domain, possible_phishing) .await?; @@ -752,16 +836,19 @@ impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { } async fn clear_history_data(&self, chain: &Chain) -> MmResult<(), Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; - table.delete_items_by_index("chain", chain.to_string()).await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; + table + .delete_items_by_index("chain", chain.to_string()) + .await + .map_mm_err()?; Ok(()) } async fn clear_all_history_data(&self) -> MmResult<(), Self::Error> { - let db_transaction = self.get_inner().transaction().await?; - let table = db_transaction.table::().await?; - table.clear().await?; + let db_transaction = self.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; + table.clear().await.map_mm_err()?; Ok(()) } } @@ -773,21 +860,30 @@ async fn update_transfer_phishing_for_index( domain: &str, possible_phishing: bool, ) -> MmResult<(), WasmNftCacheError> { - let index_keys = MultiIndex::new(index).with_value(chain)?.with_value(domain)?; - let transfers_table = table.get_items_by_multi_index(index_keys).await?; + let index_keys = MultiIndex::new(index) + .with_value(chain) + .map_mm_err()? + .with_value(domain) + .map_mm_err()?; + let transfers_table = table.get_items_by_multi_index(index_keys).await.map_mm_err()?; for (_item_id, item) in transfers_table.into_iter() { let mut transfer = transfer_details_from_item(item)?; transfer.possible_phishing = possible_phishing; drop_mutability!(transfer); let transfer_item = NftTransferHistoryTable::from_transfer_history(&transfer)?; let index_keys = MultiIndex::new(NftTransferHistoryTable::CHAIN_TX_HASH_LOG_INDEX_TOKEN_ID_INDEX) - .with_value(chain)? - .with_value(&transfer.common.transaction_hash)? - .with_value(transfer.common.log_index)? - .with_value(BeBigUint::from(transfer.token_id))?; + .with_value(chain) + .map_mm_err()? + .with_value(&transfer.common.transaction_hash) + .map_mm_err()? + .with_value(transfer.common.log_index) + .map_mm_err()? + .with_value(BeBigUint::from(transfer.token_id)) + .map_mm_err()?; table .replace_item_by_unique_multi_index(index_keys, &transfer_item) - .await?; + .await + .map_mm_err()?; } Ok(()) } @@ -799,18 +895,28 @@ async fn update_nft_phishing_for_index( domain: &str, possible_phishing: bool, ) -> MmResult<(), WasmNftCacheError> { - let index_keys = MultiIndex::new(index).with_value(chain)?.with_value(domain)?; - let nfts_table = table.get_items_by_multi_index(index_keys).await?; + let index_keys = MultiIndex::new(index) + .with_value(chain) + .map_mm_err()? + .with_value(domain) + .map_mm_err()?; + let nfts_table = table.get_items_by_multi_index(index_keys).await.map_mm_err()?; for (_item_id, item) in nfts_table.into_iter() { let mut nft = nft_details_from_item(item)?; nft.possible_phishing = possible_phishing; drop_mutability!(nft); let nft_item = NftListTable::from_nft(&nft)?; let index_keys = MultiIndex::new(CHAIN_TOKEN_ADD_TOKEN_ID_INDEX) - .with_value(chain)? - .with_value(nft.common.token_address.addr_to_string())? - .with_value(BeBigUint::from(nft.token_id))?; - table.replace_item_by_unique_multi_index(index_keys, &nft_item).await?; + .with_value(chain) + .map_mm_err()? + .with_value(nft.common.token_address.addr_to_string()) + .map_mm_err()? + .with_value(BeBigUint::from(nft.token_id)) + .map_mm_err()?; + table + .replace_item_by_unique_multi_index(index_keys, &nft_item) + .await + .map_mm_err()?; } Ok(()) } diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index 3d6f8660b3..d070ccfed5 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -149,7 +149,7 @@ impl Qrc20ActivationParams { .map_to_mm(Qrc20FromLegacyReqErr::InvalidSwapContractAddr)?; let fallback_swap_contract = json::from_value(req["fallback_swap_contract"].clone()) .map_to_mm(Qrc20FromLegacyReqErr::InvalidFallbackSwapContract)?; - let utxo_params = UtxoActivationParams::from_legacy_req(req)?; + let utxo_params = UtxoActivationParams::from_legacy_req(req).map_mm_err()?; Ok(Qrc20ActivationParams { swap_contract_address, fallback_swap_contract, @@ -519,8 +519,8 @@ impl Qrc20Coin { &self, contract_outputs: Vec, ) -> Result> { - let my_address = self.utxo.derivation_method.single_addr_or_err().await?; - let (unspents, _) = self.get_unspent_ordered_list(&my_address).await?; + let my_address = self.utxo.derivation_method.single_addr_or_err().await.map_mm_err()?; + let (unspents, _) = self.get_unspent_ordered_list(&my_address).await.map_mm_err()?; let mut gas_fee = 0; let mut outputs = Vec::with_capacity(contract_outputs.len()); @@ -535,16 +535,18 @@ impl Qrc20Coin { .add_outputs(outputs) .with_gas_fee(gas_fee) .build() - .await?; + .await + .map_mm_err()?; - let key_pair = self.utxo.priv_key_policy.activated_key_or_err()?; + let key_pair = self.utxo.priv_key_policy.activated_key_or_err().map_mm_err()?; let signed = sign_tx( unsigned, key_pair, self.utxo.conf.signature_version, self.utxo.conf.fork_id, - )?; + ) + .map_mm_err()?; Ok(GenerateQrc20TxResult { signed, @@ -853,7 +855,8 @@ impl SwapOps for Qrc20Coin { let fee_addr = self .contract_address_from_raw_pubkey(self.dex_pubkey()) .map_to_mm(ValidatePaymentError::WrongPaymentTx)?; - let expected_value = wei_from_big_decimal(&validate_fee_args.dex_fee.fee_amount().into(), self.utxo.decimals)?; + let expected_value = + wei_from_big_decimal(&validate_fee_args.dex_fee.fee_amount().into(), self.utxo.decimals).map_mm_err()?; self.validate_fee_impl( fee_tx_hash, @@ -1065,9 +1068,10 @@ impl MarketCoinOps for Qrc20Coin { .rpc_client .rpc_contract_call(ViewContractCallType::BalanceOf, &contract_address, ¶ms) .compat() - .await?; + .await + .map_mm_err()?; let spendable = match tokens.first() { - Some(Token::Uint(bal)) => u256_to_big_decimal(*bal, decimals)?, + Some(Token::Uint(bal)) => u256_to_big_decimal(*bal, decimals).map_mm_err()?, _ => { let error = format!("Expected U256 as balanceOf result but got {:?}", tokens); return MmError::err(BalanceError::InvalidResponse(error)); @@ -1216,7 +1220,7 @@ impl MmCoin for Qrc20Coin { let my_balance = U256::max_value(); let value = match value { TradePreimageValue::Exact(value) | TradePreimageValue::UpperBound(value) => { - wei_from_big_decimal(&value, decimals)? + wei_from_big_decimal(&value, decimals).map_mm_err()? }, }; @@ -1231,15 +1235,17 @@ impl MmCoin for Qrc20Coin { receiver_addr, self.swap_contract_address, ) - .await?; + .await + .map_mm_err()?; self.preimage_trade_fee_required_to_send_outputs(erc20_payment_outputs, &stage) .await? }; // Optionally calculate refund fee. let sender_refund_fee = if include_refund_fee { - let sender_refund_output = - self.sender_refund_output(&self.swap_contract_address, swap_id, value, secret_hash, receiver_addr)?; + let sender_refund_output = self + .sender_refund_output(&self.swap_contract_address, swap_id, value, secret_hash, receiver_addr) + .map_mm_err()?; self.preimage_trade_fee_required_to_send_outputs(vec![sender_refund_output], &stage) .await? } else { @@ -1266,8 +1272,9 @@ impl MmCoin for Qrc20Coin { // get the max available value that we can pass into the contract call params // see `generate_contract_call_script_pubkey` let value = u64::MAX.into(); - let output = - selfi.receiver_spend_output(&selfi.swap_contract_address, swap_id, value, secret, sender_addr)?; + let output = selfi + .receiver_spend_output(&selfi.swap_contract_address, swap_id, value, secret, sender_addr) + .map_mm_err()?; let total_fee = selfi .preimage_trade_fee_required_to_send_outputs(vec![output], &stage) @@ -1286,12 +1293,13 @@ impl MmCoin for Qrc20Coin { dex_fee_amount: DexFee, stage: FeeApproxStage, ) -> TradePreimageResult { - let amount = wei_from_big_decimal(&dex_fee_amount.fee_amount().into(), self.utxo.decimals)?; + let amount = wei_from_big_decimal(&dex_fee_amount.fee_amount().into(), self.utxo.decimals).map_mm_err()?; // pass the dummy params let to_addr = H160::default(); - let transfer_output = - self.transfer_output(to_addr, amount, QRC20_GAS_LIMIT_DEFAULT, QRC20_GAS_PRICE_DEFAULT)?; + let transfer_output = self + .transfer_output(to_addr, amount, QRC20_GAS_LIMIT_DEFAULT, QRC20_GAS_PRICE_DEFAULT) + .map_mm_err()?; let total_fee = self .preimage_trade_fee_required_to_send_outputs(vec![transfer_output], &stage) @@ -1381,17 +1389,17 @@ async fn qrc20_withdraw(coin: Qrc20Coin, req: WithdrawRequest) -> WithdrawResult let _utxo_lock = UTXO_LOCK.lock().await; - let qrc20_balance = coin.my_spendable_balance().compat().await?; + let qrc20_balance = coin.my_spendable_balance().compat().await.map_mm_err()?; // the qrc20_amount_sat is used only within smart contract calls let (qrc20_amount_sat, qrc20_amount) = if req.max { - let amount = wei_from_big_decimal(&qrc20_balance, coin.utxo.decimals)?; + let amount = wei_from_big_decimal(&qrc20_balance, coin.utxo.decimals).map_mm_err()?; if amount.is_zero() { return MmError::err(WithdrawError::ZeroBalanceToWithdrawMax); } (amount, qrc20_balance.clone()) } else { - let amount_sat = wei_from_big_decimal(&req.amount, coin.utxo.decimals)?; + let amount_sat = wei_from_big_decimal(&req.amount, coin.utxo.decimals).map_mm_err()?; if req.amount > qrc20_balance { return MmError::err(WithdrawError::NotSufficientBalance { coin: coin.ticker().to_owned(), @@ -1412,8 +1420,10 @@ async fn qrc20_withdraw(coin: Qrc20Coin, req: WithdrawRequest) -> WithdrawResult }; // [`Qrc20Coin::transfer_output`] shouldn't fail if the arguments are correct - let contract_addr = qtum::contract_addr_from_utxo_addr(to_addr.clone())?; - let transfer_output = coin.transfer_output(contract_addr, qrc20_amount_sat, gas_limit, gas_price)?; + let contract_addr = qtum::contract_addr_from_utxo_addr(to_addr.clone()).map_mm_err()?; + let transfer_output = coin + .transfer_output(contract_addr, qrc20_amount_sat, gas_limit, gas_price) + .map_mm_err()?; let outputs = vec![transfer_output]; let GenerateQrc20TxResult { @@ -1425,7 +1435,7 @@ async fn qrc20_withdraw(coin: Qrc20Coin, req: WithdrawRequest) -> WithdrawResult .await .mm_err(|gen_tx_error| gen_tx_error.into_withdraw_error(coin.platform.clone(), coin.utxo.decimals))?; - let my_address = coin.utxo.derivation_method.single_addr_or_err().await?; + let my_address = coin.utxo.derivation_method.single_addr_or_err().await.map_mm_err()?; let received_by_me = if to_addr == my_address { qrc20_amount.clone() } else { @@ -1434,7 +1444,7 @@ async fn qrc20_withdraw(coin: Qrc20Coin, req: WithdrawRequest) -> WithdrawResult let my_balance_change = &received_by_me - &qrc20_amount; // [`MarketCoinOps::my_address`] and [`UtxoCommonOps::display_address`] shouldn't fail - let my_address_string = coin.my_address()?; + let my_address_string = coin.my_address().map_mm_err()?; let to_address = to_addr.display_address().map_to_mm(WithdrawError::InternalError)?; let fee_details = Qrc20FeeDetails { diff --git a/mm2src/coins/qrc20/swap.rs b/mm2src/coins/qrc20/swap.rs index 26dea25ab8..18e371bbdf 100644 --- a/mm2src/coins/qrc20/swap.rs +++ b/mm2src/coins/qrc20/swap.rs @@ -126,7 +126,8 @@ impl Qrc20Coin { let expected_swap_id = qrc20_swap_id(time_lock, &secret_hash); let status = self .payment_status(&expected_swap_contract_address, expected_swap_id.clone()) - .await?; + .await + .map_mm_err()?; if status != U256::from(PaymentState::Sent as u8) { return MmError::err(ValidatePaymentError::UnexpectedPaymentState(format!( "Payment state is not PAYMENT_STATE_SENT, got {}", @@ -135,8 +136,8 @@ impl Qrc20Coin { } let expected_call_bytes = { - let expected_value = wei_from_big_decimal(&amount, self.utxo.decimals)?; - let my_address = self.utxo.derivation_method.single_addr_or_err().await?; + let expected_value = wei_from_big_decimal(&amount, self.utxo.decimals).map_mm_err()?; + let my_address = self.utxo.derivation_method.single_addr_or_err().await.map_mm_err()?; let expected_receiver = qtum::contract_addr_from_utxo_addr(my_address) .mm_err(|err| ValidatePaymentError::InternalError(err.to_string()))?; self.erc20_payment_call_bytes( @@ -145,7 +146,8 @@ impl Qrc20Coin { time_lock, &secret_hash, expected_receiver, - )? + ) + .map_mm_err()? }; let erc20_payment = self .erc20_payment_details_from_tx(&payment_tx) @@ -454,21 +456,24 @@ impl Qrc20Coin { if allowance < value { if allowance > U256::zero() { // first reset the allowance to the 0 - outputs.push(self.approve_output(swap_contract_address, 0.into())?); + outputs.push(self.approve_output(swap_contract_address, 0.into()).map_mm_err()?); } // set the allowance from 0 to `my_balance` after the previous output is executed - outputs.push(self.approve_output(swap_contract_address, my_balance)?); + outputs.push(self.approve_output(swap_contract_address, my_balance).map_mm_err()?); } // when this output is executed, the allowance will be sufficient already - outputs.push(self.erc20_payment_output( - id, - value, - time_lock, - &secret_hash, - receiver_addr, - &swap_contract_address, - )?); + outputs.push( + self.erc20_payment_output( + id, + value, + time_lock, + &secret_hash, + receiver_addr, + &swap_contract_address, + ) + .map_mm_err()?, + ); Ok(outputs) } diff --git a/mm2src/coins/rpc_command/account_balance.rs b/mm2src/coins/rpc_command/account_balance.rs index 7e6587b788..f3f224ef73 100644 --- a/mm2src/coins/rpc_command/account_balance.rs +++ b/mm2src/coins/rpc_command/account_balance.rs @@ -62,7 +62,7 @@ pub async fn account_balance( ctx: MmArc, req: HDAccountBalanceRequest, ) -> MmResult { - match lp_coinfind_or_err(&ctx, &req.coin).await? { + match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::UtxoCoin(utxo) => Ok(HDAccountBalanceResponseEnum::Map( utxo.account_balance_rpc(req.params).await?, )), @@ -93,11 +93,12 @@ pub mod common_impl { let account_id = params.account_index; let hd_account = coin .derivation_method() - .hd_wallet_or_err()? + .hd_wallet_or_err() + .map_mm_err()? .get_account(account_id) .await .or_mm_err(|| HDAccountBalanceRpcError::UnknownAccount { account_id })?; - let total_addresses_number = hd_account.known_addresses_number(params.chain)?; + let total_addresses_number = hd_account.known_addresses_number(params.chain).map_mm_err()?; let from_address_id = match params.paging_options { PagingOptionsEnum::FromId(from_address_id) => from_address_id + 1, @@ -107,7 +108,8 @@ pub mod common_impl { let addresses = coin .known_addresses_balances_with_ids(&hd_account, params.chain, from_address_id..to_address_id) - .await?; + .await + .map_mm_err()?; let page_balance = addresses .iter() diff --git a/mm2src/coins/rpc_command/get_current_mtp.rs b/mm2src/coins/rpc_command/get_current_mtp.rs index 24b4f563b9..6db7b5b59a 100644 --- a/mm2src/coins/rpc_command/get_current_mtp.rs +++ b/mm2src/coins/rpc_command/get_current_mtp.rs @@ -1,7 +1,7 @@ use common::{HttpStatusCode, StatusCode}; use derive_more::Display; use mm2_core::mm_ctx::MmArc; -use mm2_err_handle::prelude::MmError; +use mm2_err_handle::prelude::*; use crate::{lp_coinfind_or_err, utxo::{rpc_clients::UtxoRpcError, UtxoCommonOps}, @@ -50,22 +50,22 @@ pub async fn get_current_mtp_rpc( ctx: MmArc, req: GetCurrentMtpRequest, ) -> GetCurrentMtpRpcResult { - match lp_coinfind_or_err(&ctx, &req.coin).await? { + match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::UtxoCoin(utxo) => Ok(GetCurrentMtpResponse { - mtp: utxo.get_current_mtp().await?, + mtp: utxo.get_current_mtp().await.map_mm_err()?, }), MmCoinEnum::QtumCoin(qtum) => Ok(GetCurrentMtpResponse { - mtp: qtum.get_current_mtp().await?, + mtp: qtum.get_current_mtp().await.map_mm_err()?, }), MmCoinEnum::Qrc20Coin(qrc) => Ok(GetCurrentMtpResponse { - mtp: qrc.get_current_mtp().await?, + mtp: qrc.get_current_mtp().await.map_mm_err()?, }), #[cfg(not(target_arch = "wasm32"))] MmCoinEnum::ZCoin(zcoin) => Ok(GetCurrentMtpResponse { - mtp: zcoin.get_current_mtp().await?, + mtp: zcoin.get_current_mtp().await.map_mm_err()?, }), MmCoinEnum::Bch(bch) => Ok(GetCurrentMtpResponse { - mtp: bch.get_current_mtp().await?, + mtp: bch.get_current_mtp().await.map_mm_err()?, }), _ => Err(MmError::new(GetCurrentMtpError::NotSupportedCoin(req.coin))), } diff --git a/mm2src/coins/rpc_command/get_new_address.rs b/mm2src/coins/rpc_command/get_new_address.rs index 1213905c74..a43225d864 100644 --- a/mm2src/coins/rpc_command/get_new_address.rs +++ b/mm2src/coins/rpc_command/get_new_address.rs @@ -315,7 +315,7 @@ impl RpcTask for InitGetNewAddressTask { on_ready: GetNewAddressInProgressStatus::RequestingAccountBalance, }; let confirm_address: RpcTaskConfirmAddress = - RpcTaskConfirmAddress::new(ctx, task_handle, hw_statuses, trezor_message_type)?; + RpcTaskConfirmAddress::new(ctx, task_handle, hw_statuses, trezor_message_type).map_mm_err()?; coin.get_new_address_rpc(params, &confirm_address).await } @@ -360,7 +360,7 @@ pub async fn get_new_address( ctx: MmArc, req: GetNewAddressRequest, ) -> MmResult { - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; match coin { MmCoinEnum::UtxoCoin(utxo) => Ok(GetNewAddressResponseEnum::Map( utxo.get_new_address_rpc_without_conf(req.params).await?, @@ -382,12 +382,13 @@ pub async fn init_get_new_address( req: RpcInitReq, ) -> MmResult { let (client_id, req) = (req.client_id, req.inner); - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; let coins_ctx = CoinsContext::from_ctx(&ctx).map_to_mm(GetNewAddressRpcError::Internal)?; let spawner = coin.spawner(); let task = InitGetNewAddressTask { ctx, coin, req }; let task_id = - GetNewAddressTaskManager::spawn_rpc_task(&coins_ctx.get_new_address_manager, &spawner, task, client_id)?; + GetNewAddressTaskManager::spawn_rpc_task(&coins_ctx.get_new_address_manager, &spawner, task, client_id) + .map_mm_err()?; Ok(InitRpcTaskResponse { task_id }) } @@ -414,7 +415,7 @@ pub async fn init_get_new_address_user_action( .get_new_address_manager .lock() .map_to_mm(|e| RpcTaskUserActionError::Internal(e.to_string()))?; - task_manager.on_user_action(req.task_id, req.user_action)?; + task_manager.on_user_action(req.task_id, req.user_action).map_mm_err()?; Ok(SuccessResponse::new()) } @@ -427,7 +428,7 @@ pub async fn cancel_get_new_address( .get_new_address_manager .lock() .map_to_mm(|e| CancelRpcTaskError::Internal(e.to_string()))?; - task_manager.cancel_task(req.task_id)?; + task_manager.cancel_task(req.task_id).map_mm_err()?; Ok(SuccessResponse::new()) } @@ -452,7 +453,7 @@ pub(crate) mod common_impl { Coin: HDWalletBalanceOps + CoinWithDerivationMethod + Sync + Send, HDCoinAddress: fmt::Display, { - let hd_wallet = coin.derivation_method().hd_wallet_or_err()?; + let hd_wallet = coin.derivation_method().hd_wallet_or_err().map_mm_err()?; let account_id = params.account_id; let mut hd_account = hd_wallet @@ -468,9 +469,10 @@ pub(crate) mod common_impl { let hd_address = coin .generate_new_address(hd_wallet, hd_account.deref_mut(), chain) - .await?; + .await + .map_mm_err()?; let address = hd_address.address(); - let balance = coin.known_address_balance(&address).await?; + let balance = coin.known_address_balance(&address).await.map_mm_err()?; Ok(GetNewAddressResponse { new_address: HDAddressBalance { @@ -492,7 +494,7 @@ pub(crate) mod common_impl { Coin: HDWalletBalanceOps + CoinWithDerivationMethod + Send + Sync, HDCoinAddress: Display + Eq + Hash, { - let hd_wallet = coin.derivation_method().hd_wallet_or_err()?; + let hd_wallet = coin.derivation_method().hd_wallet_or_err().map_mm_err()?; let account_id = params.account_id; let mut hd_account = hd_wallet @@ -508,9 +510,10 @@ pub(crate) mod common_impl { let hd_address = coin .generate_and_confirm_new_address(hd_wallet, &mut hd_account, chain, confirm_address) - .await?; + .await + .map_mm_err()?; let address = hd_address.address(); - let balance = coin.known_address_balance(&address).await?; + let balance = coin.known_address_balance(&address).await.map_mm_err()?; let formatted_address = address.display_address(); coin.prepare_addresses_for_balance_stream_if_enabled(HashSet::from([formatted_address.clone()])) @@ -537,7 +540,7 @@ pub(crate) mod common_impl { Coin: HDWalletBalanceOps + Sync, HDCoinAddress: fmt::Display, { - let known_addresses_number = hd_account.known_addresses_number(chain)?; + let known_addresses_number = hd_account.known_addresses_number(chain).map_mm_err()?; if known_addresses_number == 0 || gap_limit > known_addresses_number { return Ok(()); } @@ -547,15 +550,19 @@ pub(crate) mod common_impl { return MmError::err(GetNewAddressRpcError::AddressLimitReached { max_addresses_number }); } - let address_scanner = coin.produce_hd_address_scanner().await?; + let address_scanner = coin.produce_hd_address_scanner().await.map_mm_err()?; // Address IDs start from 0, so the `last_known_address_id = known_addresses_number - 1`. // At this point we are sure that `known_addresses_number > 0`. let last_address_id = known_addresses_number - 1; for address_id in (0..=last_address_id).rev() { - let address = coin.derive_address(hd_account, chain, address_id).await?.address(); - if address_scanner.is_address_used(&address).await? { + let address = coin + .derive_address(hd_account, chain, address_id) + .await + .map_mm_err()? + .address(); + if address_scanner.is_address_used(&address).await.map_mm_err()? { return Ok(()); } diff --git a/mm2src/coins/rpc_command/init_account_balance.rs b/mm2src/coins/rpc_command/init_account_balance.rs index b18e6bdbce..afec7e5761 100644 --- a/mm2src/coins/rpc_command/init_account_balance.rs +++ b/mm2src/coins/rpc_command/init_account_balance.rs @@ -93,12 +93,13 @@ pub async fn init_account_balance( req: RpcInitReq, ) -> MmResult { let (client_id, req) = (req.client_id, req.inner); - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; let spawner = coin.spawner(); let coins_ctx = CoinsContext::from_ctx(&ctx).map_to_mm(HDAccountBalanceRpcError::Internal)?; let task = InitAccountBalanceTask { coin, req }; let task_id = - AccountBalanceTaskManager::spawn_rpc_task(&coins_ctx.account_balance_task_manager, &spawner, task, client_id)?; + AccountBalanceTaskManager::spawn_rpc_task(&coins_ctx.account_balance_task_manager, &spawner, task, client_id) + .map_mm_err()?; Ok(InitRpcTaskResponse { task_id }) } @@ -125,7 +126,7 @@ pub async fn cancel_account_balance( .account_balance_task_manager .lock() .map_to_mm(|e| CancelRpcTaskError::Internal(e.to_string()))?; - task_manager.cancel_task(req.task_id)?; + task_manager.cancel_task(req.task_id).map_mm_err()?; Ok(SuccessResponse::new()) } @@ -148,12 +149,13 @@ pub mod common_impl { let account_id = params.account_index; let hd_account = coin .derivation_method() - .hd_wallet_or_err()? + .hd_wallet_or_err() + .map_mm_err()? .get_account(account_id) .await .or_mm_err(|| HDAccountBalanceRpcError::UnknownAccount { account_id })?; - let addresses = coin.all_known_addresses_balances(&hd_account).await?; + let addresses = coin.all_known_addresses_balances(&hd_account).await.map_mm_err()?; let total_balance = addresses .iter() diff --git a/mm2src/coins/rpc_command/init_create_account.rs b/mm2src/coins/rpc_command/init_create_account.rs index 774ab3bc77..4328e8f54a 100644 --- a/mm2src/coins/rpc_command/init_create_account.rs +++ b/mm2src/coins/rpc_command/init_create_account.rs @@ -273,12 +273,10 @@ impl RpcTask for InitCreateAccountTask { on_passphrase_request: CreateAccountAwaitingStatus::EnterTrezorPassphrase, on_ready: CreateAccountInProgressStatus::RequestingAccountBalance, }; - Some(CreateAccountXPubExtractor::new_trezor_extractor( - ctx, - task_handle, - hw_statuses, - coin_protocol, - )?) + Some( + CreateAccountXPubExtractor::new_trezor_extractor(ctx, task_handle, hw_statuses, coin_protocol) + .map_mm_err()?, + ) } else { None }; @@ -337,7 +335,7 @@ pub async fn init_create_new_account( req: RpcInitReq, ) -> MmResult { let (client_id, req) = (req.client_id, req.inner); - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; let coins_ctx = CoinsContext::from_ctx(&ctx).map_to_mm(CreateAccountRpcError::Internal)?; let spawner = coin.spawner(); let task = InitCreateAccountTask { @@ -347,7 +345,8 @@ pub async fn init_create_new_account( task_state: CreateAccountState::default(), }; let task_id = - CreateAccountTaskManager::spawn_rpc_task(&coins_ctx.create_account_manager, &spawner, task, client_id)?; + CreateAccountTaskManager::spawn_rpc_task(&coins_ctx.create_account_manager, &spawner, task, client_id) + .map_mm_err()?; Ok(InitRpcTaskResponse { task_id }) } @@ -374,7 +373,7 @@ pub async fn init_create_new_account_user_action( .create_account_manager .lock() .map_to_mm(|e| RpcTaskUserActionError::Internal(e.to_string()))?; - task_manager.on_user_action(req.task_id, req.user_action)?; + task_manager.on_user_action(req.task_id, req.user_action).map_mm_err()?; Ok(SuccessResponse::new()) } @@ -387,7 +386,7 @@ pub async fn cancel_create_new_account( .create_account_manager .lock() .map_to_mm(|e| CancelRpcTaskError::Internal(e.to_string()))?; - task_manager.cancel_task(req.task_id)?; + task_manager.cancel_task(req.task_id).map_mm_err()?; Ok(SuccessResponse::new()) } @@ -412,9 +411,11 @@ pub(crate) mod common_impl { XPubExtractor: HDXPubExtractor + Send, HDCoinHDAccount: HDAccountStorageOps, { - let hd_wallet = coin.derivation_method().hd_wallet_or_err()?; + let hd_wallet = coin.derivation_method().hd_wallet_or_err().map_mm_err()?; - let mut new_account = create_new_account(coin, hd_wallet, xpub_extractor, params.account_id).await?; + let mut new_account = create_new_account(coin, hd_wallet, xpub_extractor, params.account_id) + .await + .map_mm_err()?; let account_index = new_account.account_id(); let account_derivation_path = new_account.account_derivation_path(); @@ -423,9 +424,10 @@ pub(crate) mod common_impl { let addresses = if params.scan { let gap_limit = params.gap_limit.unwrap_or_else(|| hd_wallet.gap_limit()); - let address_scanner = coin.produce_hd_address_scanner().await?; + let address_scanner = coin.produce_hd_address_scanner().await.map_mm_err()?; coin.scan_for_new_addresses(hd_wallet, &mut new_account, &address_scanner, gap_limit) - .await? + .await + .map_mm_err()? } else { Vec::new() }; diff --git a/mm2src/coins/rpc_command/init_scan_for_new_addresses.rs b/mm2src/coins/rpc_command/init_scan_for_new_addresses.rs index d24c7229fe..7d1e7b1e09 100644 --- a/mm2src/coins/rpc_command/init_scan_for_new_addresses.rs +++ b/mm2src/coins/rpc_command/init_scan_for_new_addresses.rs @@ -112,12 +112,13 @@ pub async fn init_scan_for_new_addresses( req: RpcInitReq, ) -> MmResult { let (client_id, req) = (req.client_id, req.inner); - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; let spawner = coin.spawner(); let coins_ctx = CoinsContext::from_ctx(&ctx).map_to_mm(HDAccountBalanceRpcError::Internal)?; let task = InitScanAddressesTask { req, coin }; let task_id = - ScanAddressesTaskManager::spawn_rpc_task(&coins_ctx.scan_addresses_manager, &spawner, task, client_id)?; + ScanAddressesTaskManager::spawn_rpc_task(&coins_ctx.scan_addresses_manager, &spawner, task, client_id) + .map_mm_err()?; Ok(InitRpcTaskResponse { task_id }) } @@ -144,7 +145,7 @@ pub async fn cancel_scan_for_new_addresses( .scan_addresses_manager .lock() .map_to_mm(|e| CancelRpcTaskError::Internal(e.to_string()))?; - task_manager.cancel_task(req.task_id)?; + task_manager.cancel_task(req.task_id).map_mm_err()?; Ok(SuccessResponse::new()) } @@ -163,7 +164,7 @@ pub mod common_impl { where Coin: CoinWithDerivationMethod + HDWalletBalanceOps + Sync, { - let hd_wallet = coin.derivation_method().hd_wallet_or_err()?; + let hd_wallet = coin.derivation_method().hd_wallet_or_err().map_mm_err()?; let account_id = params.account_index; let mut hd_account = hd_wallet @@ -171,12 +172,13 @@ pub mod common_impl { .await .or_mm_err(|| HDAccountBalanceRpcError::CoinIsActivatedNotWithHDWallet)?; let account_derivation_path = hd_account.account_derivation_path(); - let address_scanner = coin.produce_hd_address_scanner().await?; + let address_scanner = coin.produce_hd_address_scanner().await.map_mm_err()?; let gap_limit = params.gap_limit.unwrap_or_else(|| hd_wallet.gap_limit()); let new_addresses = coin .scan_for_new_addresses(hd_wallet, hd_account.deref_mut(), &address_scanner, gap_limit) - .await?; + .await + .map_mm_err()?; let addresses: HashSet<_> = new_addresses .iter() diff --git a/mm2src/coins/rpc_command/init_withdraw.rs b/mm2src/coins/rpc_command/init_withdraw.rs index e82ccd4d63..1575f9b1ca 100644 --- a/mm2src/coins/rpc_command/init_withdraw.rs +++ b/mm2src/coins/rpc_command/init_withdraw.rs @@ -38,7 +38,7 @@ pub async fn init_withdraw( request: RpcInitReq, ) -> WithdrawInitResult { let (client_id, request) = (request.client_id, request.inner); - let coin = lp_coinfind_or_err(&ctx, &request.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &request.coin).await.map_mm_err()?; let spawner = coin.spawner(); let task = WithdrawTask { ctx: ctx.clone(), @@ -46,7 +46,8 @@ pub async fn init_withdraw( request, }; let coins_ctx = CoinsContext::from_ctx(&ctx).map_to_mm(WithdrawError::InternalError)?; - let task_id = WithdrawTaskManager::spawn_rpc_task(&coins_ctx.withdraw_task_manager, &spawner, task, client_id)?; + let task_id = WithdrawTaskManager::spawn_rpc_task(&coins_ctx.withdraw_task_manager, &spawner, task, client_id) + .map_mm_err()?; Ok(InitWithdrawResponse { task_id }) } @@ -86,7 +87,7 @@ pub async fn withdraw_user_action( .withdraw_task_manager .lock() .map_to_mm(|e| WithdrawUserActionError::Internal(e.to_string()))?; - task_manager.on_user_action(req.task_id, req.user_action)?; + task_manager.on_user_action(req.task_id, req.user_action).map_mm_err()?; Ok(SuccessResponse::new()) } @@ -96,7 +97,7 @@ pub async fn cancel_withdraw(ctx: MmArc, req: CancelRpcTaskRequest) -> MmResult< .withdraw_task_manager .lock() .map_to_mm(|e| CancelRpcTaskError::Internal(e.to_string()))?; - task_manager.cancel_task(req.task_id)?; + task_manager.cancel_task(req.task_id).map_mm_err()?; Ok(SuccessResponse::new()) } diff --git a/mm2src/coins/rpc_command/lightning/close_channel.rs b/mm2src/coins/rpc_command/lightning/close_channel.rs index 716b7db969..cbcb237582 100644 --- a/mm2src/coins/rpc_command/lightning/close_channel.rs +++ b/mm2src/coins/rpc_command/lightning/close_channel.rs @@ -47,7 +47,7 @@ pub struct CloseChannelReq { } pub async fn close_channel(ctx: MmArc, req: CloseChannelReq) -> CloseChannelResult { - let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await? { + let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::LightningCoin(c) => c, e => return MmError::err(CloseChannelError::UnsupportedCoin(e.ticker().to_string())), }; diff --git a/mm2src/coins/rpc_command/lightning/connect_to_node.rs b/mm2src/coins/rpc_command/lightning/connect_to_node.rs index 79ba0f1889..ab776cb49e 100644 --- a/mm2src/coins/rpc_command/lightning/connect_to_node.rs +++ b/mm2src/coins/rpc_command/lightning/connect_to_node.rs @@ -68,7 +68,7 @@ pub struct ConnectToNodeRequest { /// Connect to a certain node on the lightning network. pub async fn connect_to_node(ctx: MmArc, req: ConnectToNodeRequest) -> ConnectToNodeResult { - let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await? { + let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::LightningCoin(c) => c, e => return MmError::err(ConnectToNodeError::UnsupportedCoin(e.ticker().to_string())), }; diff --git a/mm2src/coins/rpc_command/lightning/generate_invoice.rs b/mm2src/coins/rpc_command/lightning/generate_invoice.rs index 83d0fc41f6..051402b44c 100644 --- a/mm2src/coins/rpc_command/lightning/generate_invoice.rs +++ b/mm2src/coins/rpc_command/lightning/generate_invoice.rs @@ -75,7 +75,7 @@ pub async fn generate_invoice( ctx: MmArc, req: GenerateInvoiceRequest, ) -> GenerateInvoiceResult { - let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await? { + let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::LightningCoin(c) => c, e => return MmError::err(GenerateInvoiceError::UnsupportedCoin(e.ticker().to_string())), }; diff --git a/mm2src/coins/rpc_command/lightning/get_channel_details.rs b/mm2src/coins/rpc_command/lightning/get_channel_details.rs index c96cf06e57..f806c0e916 100644 --- a/mm2src/coins/rpc_command/lightning/get_channel_details.rs +++ b/mm2src/coins/rpc_command/lightning/get_channel_details.rs @@ -62,7 +62,7 @@ pub async fn get_channel_details( ctx: MmArc, req: GetChannelDetailsRequest, ) -> GetChannelDetailsResult { - let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await? { + let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::LightningCoin(c) => c, e => return MmError::err(GetChannelDetailsError::UnsupportedCoin(e.ticker().to_string())), }; diff --git a/mm2src/coins/rpc_command/lightning/get_claimable_balances.rs b/mm2src/coins/rpc_command/lightning/get_claimable_balances.rs index 5d1b84dad1..511892a1cd 100644 --- a/mm2src/coins/rpc_command/lightning/get_claimable_balances.rs +++ b/mm2src/coins/rpc_command/lightning/get_claimable_balances.rs @@ -44,7 +44,7 @@ pub async fn get_claimable_balances( ctx: MmArc, req: ClaimableBalancesReq, ) -> ClaimableBalancesResult> { - let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await? { + let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::LightningCoin(c) => c, e => return MmError::err(ClaimableBalancesError::UnsupportedCoin(e.ticker().to_string())), }; diff --git a/mm2src/coins/rpc_command/lightning/get_payment_details.rs b/mm2src/coins/rpc_command/lightning/get_payment_details.rs index 0e7a4868c2..7823e04b5f 100644 --- a/mm2src/coins/rpc_command/lightning/get_payment_details.rs +++ b/mm2src/coins/rpc_command/lightning/get_payment_details.rs @@ -61,7 +61,7 @@ pub async fn get_payment_details( ctx: MmArc, req: GetPaymentDetailsRequest, ) -> GetPaymentDetailsResult { - let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await? { + let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::LightningCoin(c) => c, e => return MmError::err(GetPaymentDetailsError::UnsupportedCoin(e.ticker().to_string())), }; diff --git a/mm2src/coins/rpc_command/lightning/list_channels.rs b/mm2src/coins/rpc_command/lightning/list_channels.rs index d3eb582633..3c857f2e0f 100644 --- a/mm2src/coins/rpc_command/lightning/list_channels.rs +++ b/mm2src/coins/rpc_command/lightning/list_channels.rs @@ -68,7 +68,7 @@ pub async fn list_open_channels_by_filter( ctx: MmArc, req: ListOpenChannelsRequest, ) -> ListChannelsResult { - let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await? { + let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::LightningCoin(c) => c, e => return MmError::err(ListChannelsError::UnsupportedCoin(e.ticker().to_string())), }; @@ -111,7 +111,7 @@ pub async fn list_closed_channels_by_filter( ctx: MmArc, req: ListClosedChannelsRequest, ) -> ListChannelsResult { - let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await? { + let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::LightningCoin(c) => c, e => return MmError::err(ListChannelsError::UnsupportedCoin(e.ticker().to_string())), }; diff --git a/mm2src/coins/rpc_command/lightning/list_payments_by_filter.rs b/mm2src/coins/rpc_command/lightning/list_payments_by_filter.rs index 0a6d0d3308..05f3a6a4f0 100644 --- a/mm2src/coins/rpc_command/lightning/list_payments_by_filter.rs +++ b/mm2src/coins/rpc_command/lightning/list_payments_by_filter.rs @@ -64,7 +64,7 @@ pub struct ListPaymentsResponse { } pub async fn list_payments_by_filter(ctx: MmArc, req: ListPaymentsReq) -> ListPaymentsResult { - let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await? { + let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::LightningCoin(c) => c, e => return MmError::err(ListPaymentsError::UnsupportedCoin(e.ticker().to_string())), }; diff --git a/mm2src/coins/rpc_command/lightning/open_channel.rs b/mm2src/coins/rpc_command/lightning/open_channel.rs index 095ee1c4ee..81622b5962 100644 --- a/mm2src/coins/rpc_command/lightning/open_channel.rs +++ b/mm2src/coins/rpc_command/lightning/open_channel.rs @@ -134,7 +134,7 @@ pub struct OpenChannelResponse { /// Opens a channel on the lightning network. pub async fn open_channel(ctx: MmArc, req: OpenChannelRequest) -> OpenChannelResult { - let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await? { + let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::LightningCoin(c) => c, e => return MmError::err(OpenChannelError::UnsupportedCoin(e.ticker().to_string())), }; @@ -146,15 +146,20 @@ pub async fn open_channel(ctx: MmArc, req: OpenChannelRequest) -> OpenChannelRes let platform_coin = ln_coin.platform_coin().clone(); let decimals = platform_coin.as_ref().decimals; - let my_address = platform_coin.as_ref().derivation_method.single_addr_or_err().await?; - let (unspents, _) = platform_coin.get_unspent_ordered_list(&my_address).await?; + let my_address = platform_coin + .as_ref() + .derivation_method + .single_addr_or_err() + .await + .map_mm_err()?; + let (unspents, _) = platform_coin.get_unspent_ordered_list(&my_address).await.map_mm_err()?; let (value, fee_policy) = match req.amount.clone() { ChannelOpenAmount::Max => ( unspents.iter().fold(0, |sum, unspent| sum + unspent.value), FeePolicy::DeductFromOutput(0), ), ChannelOpenAmount::Exact(v) => { - let value = sat_from_big_decimal(&v, decimals)?; + let value = sat_from_big_decimal(&v, decimals).map_mm_err()?; (value, FeePolicy::SendExact) }, }; @@ -179,7 +184,7 @@ pub async fn open_channel(ctx: MmArc, req: OpenChannelRequest) -> OpenChannelRes .map_err(|e| OpenChannelError::RpcError(e.to_string()))?; tx_builder = tx_builder.with_fee(fee); - let (unsigned, _) = tx_builder.build().await?; + let (unsigned, _) = tx_builder.build().await.map_mm_err()?; let amount_in_sat = unsigned.outputs[0].value; let push_msat = req.push_msat; diff --git a/mm2src/coins/rpc_command/lightning/send_payment.rs b/mm2src/coins/rpc_command/lightning/send_payment.rs index 3efde180d4..43f1e30ae5 100644 --- a/mm2src/coins/rpc_command/lightning/send_payment.rs +++ b/mm2src/coins/rpc_command/lightning/send_payment.rs @@ -85,7 +85,7 @@ pub struct SendPaymentResponse { } pub async fn send_payment(ctx: MmArc, req: SendPaymentReq) -> SendPaymentResult { - let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await? { + let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::LightningCoin(c) => c, e => return MmError::err(SendPaymentError::UnsupportedCoin(e.ticker().to_string())), }; @@ -99,12 +99,15 @@ pub async fn send_payment(ctx: MmArc, req: SendPaymentReq) -> SendPaymentResult< )); } let payment_info = match req.payment { - Payment::Invoice { invoice } => ln_coin.pay_invoice(invoice, None).await?, + Payment::Invoice { invoice } => ln_coin.pay_invoice(invoice, None).await.map_mm_err()?, Payment::Keysend { destination, amount_in_msat, expiry, - } => ln_coin.keysend(destination.into(), amount_in_msat, expiry).await?, + } => ln_coin + .keysend(destination.into(), amount_in_msat, expiry) + .await + .map_mm_err()?, }; Ok(SendPaymentResponse { diff --git a/mm2src/coins/rpc_command/lightning/trusted_nodes.rs b/mm2src/coins/rpc_command/lightning/trusted_nodes.rs index 6f0f2fd36e..5527215def 100644 --- a/mm2src/coins/rpc_command/lightning/trusted_nodes.rs +++ b/mm2src/coins/rpc_command/lightning/trusted_nodes.rs @@ -53,7 +53,7 @@ pub struct AddTrustedNodeResponse { } pub async fn add_trusted_node(ctx: MmArc, req: AddTrustedNodeReq) -> TrustedNodeResult { - let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await? { + let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::LightningCoin(c) => c, e => return MmError::err(TrustedNodeError::UnsupportedCoin(e.ticker().to_string())), }; @@ -82,7 +82,7 @@ pub async fn remove_trusted_node( ctx: MmArc, req: RemoveTrustedNodeReq, ) -> TrustedNodeResult { - let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await? { + let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::LightningCoin(c) => c, e => return MmError::err(TrustedNodeError::UnsupportedCoin(e.ticker().to_string())), }; @@ -107,7 +107,7 @@ pub struct ListTrustedNodesResponse { } pub async fn list_trusted_nodes(ctx: MmArc, req: ListTrustedNodesReq) -> TrustedNodeResult { - let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await? { + let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::LightningCoin(c) => c, e => return MmError::err(TrustedNodeError::UnsupportedCoin(e.ticker().to_string())), }; diff --git a/mm2src/coins/rpc_command/lightning/update_channel.rs b/mm2src/coins/rpc_command/lightning/update_channel.rs index ad7768831f..57b772764c 100644 --- a/mm2src/coins/rpc_command/lightning/update_channel.rs +++ b/mm2src/coins/rpc_command/lightning/update_channel.rs @@ -53,7 +53,7 @@ pub struct UpdateChannelResponse { /// Updates configuration for an open channel. pub async fn update_channel(ctx: MmArc, req: UpdateChannelReq) -> UpdateChannelResult { - let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await? { + let ln_coin = match lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()? { MmCoinEnum::LightningCoin(c) => c, e => return MmError::err(UpdateChannelError::UnsupportedCoin(e.ticker().to_string())), }; diff --git a/mm2src/coins/rpc_command/tendermint/staking.rs b/mm2src/coins/rpc_command/tendermint/staking.rs index 519c18cc38..5ad332f5e3 100644 --- a/mm2src/coins/rpc_command/tendermint/staking.rs +++ b/mm2src/coins/rpc_command/tendermint/staking.rs @@ -1,6 +1,6 @@ use common::PagingOptions; use cosmrs::staking::{Commission, Description, Validator}; -use mm2_err_handle::prelude::MmError; +use mm2_err_handle::prelude::{MmError, MmResultExt}; use mm2_number::BigDecimal; use crate::{hd_wallet::HDAddressSelector, tendermint::TendermintCoinRpcError, MmCoinEnum, StakingInfoError, @@ -109,13 +109,15 @@ pub async fn validators_rpc( } let validators = match coin { - MmCoinEnum::Tendermint(coin) => coin.validators_list(req.filter_by_status, req.paging).await?, - MmCoinEnum::TendermintToken(token) => { - token - .platform_coin - .validators_list(req.filter_by_status, req.paging) - .await? - }, + MmCoinEnum::Tendermint(coin) => coin + .validators_list(req.filter_by_status, req.paging) + .await + .map_mm_err()?, + MmCoinEnum::TendermintToken(token) => token + .platform_coin + .validators_list(req.filter_by_status, req.paging) + .await + .map_mm_err()?, other => { return MmError::err(StakingInfoError::InvalidPayload { reason: format!("{} is not a Cosmos coin", other.ticker()), diff --git a/mm2src/coins/siacoin.rs b/mm2src/coins/siacoin.rs index c0b82f313b..628265b8c4 100644 --- a/mm2src/coins/siacoin.rs +++ b/mm2src/coins/siacoin.rs @@ -167,7 +167,7 @@ impl<'a> SiaCoinBuilder<'a> { fn ticker(&self) -> &str { self.ticker } async fn build(self) -> MmResult { - let conf = SiaConfBuilder::new(self.conf, self.ticker()).build()?; + let conf = SiaConfBuilder::new(self.conf, self.ticker()).build().map_mm_err()?; let sia_fields = SiaCoinFields { conf, http_client: SiaApiClient::new(self.params.http_conf.clone()) diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index b442f94ab2..1160d3b971 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -1990,7 +1990,7 @@ impl TendermintCoin { let sender = AccountId::new(&self.protocol_info.account_prefix, sender_pubkey_hash.as_slice()) .map_to_mm(|e| ValidatePaymentError::InvalidParameter(e.to_string()))?; - let amount = sat_from_big_decimal(&input.amount, decimals)?; + let amount = sat_from_big_decimal(&input.amount, decimals).map_mm_err()?; let amount = vec![Coin { denom, amount: amount.into(), @@ -2016,7 +2016,7 @@ impl TendermintCoin { } let hash = hex::encode_upper(sha256(&input.payment_tx).as_slice()); - let tx_from_rpc = self.request_tx(hash).await?; + let tx_from_rpc = self.request_tx(hash).await.map_mm_err()?; if input.payment_tx != tx_from_rpc.encode_to_vec() { return MmError::err(ValidatePaymentError::InvalidRpcResponse( "Tx from RPC doesn't match the input".into(), @@ -2025,7 +2025,7 @@ impl TendermintCoin { let htlc_id = self.calculate_htlc_id(&sender, &self.account_id, &amount, &input.secret_hash); - let htlc_response = self.query_htlc(htlc_id.clone()).await?; + let htlc_response = self.query_htlc(htlc_id.clone()).await.map_mm_err()?; let htlc_state = htlc_response .htlc_state() .or_mm_err(|| ValidatePaymentError::InvalidRpcResponse(format!("No HTLC data for {}", htlc_id)))?; @@ -2057,7 +2057,7 @@ impl TendermintCoin { let expected_dex_address = AccountId::new(&self.protocol_info.account_prefix, dex_pubkey_hash.as_slice()) .map_to_mm(|r| ValidatePaymentError::InvalidParameter(r.to_string()))?; - let fee_amount_as_u64 = dex_fee.fee_amount_as_u64(decimals)?; + let fee_amount_as_u64 = dex_fee.fee_amount_as_u64(decimals).map_mm_err()?; let expected_dex_amount = CoinProto { denom, amount: fee_amount_as_u64.to_string(), @@ -2113,12 +2113,12 @@ impl TendermintCoin { let expected_burn_address = AccountId::new(&self.protocol_info.account_prefix, burn_pubkey_hash.as_slice()) .map_to_mm(|r| ValidatePaymentError::InvalidParameter(r.to_string()))?; - let fee_amount_as_u64 = dex_fee.fee_amount_as_u64(decimals)?; + let fee_amount_as_u64 = dex_fee.fee_amount_as_u64(decimals).map_mm_err()?; let expected_dex_amount = CoinProto { denom: denom.clone(), amount: fee_amount_as_u64.to_string(), }; - let burn_amount_as_u64 = dex_fee.burn_amount_as_u64(decimals)?.unwrap_or_default(); + let burn_amount_as_u64 = dex_fee.burn_amount_as_u64(decimals).map_mm_err()?.unwrap_or_default(); let expected_burn_amount = CoinProto { denom, amount: burn_amount_as_u64.to_string(), @@ -2201,7 +2201,7 @@ impl TendermintCoin { let to_address = account_id_from_pubkey_hex(&self.protocol_info.account_prefix, DEX_FEE_ADDR_PUBKEY) .map_err(|e| MmError::new(TradePreimageError::InternalError(e.to_string())))?; - let amount = sat_from_big_decimal(&amount, decimals)?; + let amount = sat_from_big_decimal(&amount, decimals).map_mm_err()?; let create_htlc_tx = self .gen_create_htlc_tx(denom, &to_address, amount.into(), sha256(&sec).as_slice(), TIME_LOCK) @@ -2230,7 +2230,8 @@ impl TendermintCoin { TX_DEFAULT_MEMO, None, ) - .await?; + .await + .map_mm_err()?; let fee_amount = big_decimal_from_sat_unsigned(fee_uamount, self.protocol_info.decimals); @@ -2250,7 +2251,7 @@ impl TendermintCoin { ) -> TradePreimageResult { let to_address = account_id_from_pubkey_hex(&self.protocol_info.account_prefix, DEX_FEE_ADDR_PUBKEY) .map_err(|e| MmError::new(TradePreimageError::InternalError(e.to_string())))?; - let amount = sat_from_big_decimal(&dex_fee_amount.fee_amount().into(), decimals)?; + let amount = sat_from_big_decimal(&dex_fee_amount.fee_amount().into(), decimals).map_mm_err()?; let current_block = self.current_block().compat().await.map_err(|e| { MmError::new(TradePreimageError::InternalError(format!( @@ -2281,7 +2282,8 @@ impl TendermintCoin { TX_DEFAULT_MEMO, None, ) - .await?; + .await + .map_mm_err()?; let fee_amount = big_decimal_from_sat_unsigned(fee_uamount, decimals); Ok(TradeFee { @@ -2405,7 +2407,7 @@ impl TendermintCoin { let htlc = CreateHtlcMsg::try_from(htlc_proto)?; let htlc_id = self.calculate_htlc_id(htlc.sender(), htlc.to(), htlc.amount(), input.secret_hash); - let htlc_response = self.query_htlc(htlc_id.clone()).await?; + let htlc_response = self.query_htlc(htlc_id.clone()).await.map_mm_err()?; let htlc_state = match htlc_response.htlc_state() { Some(htlc_state) => htlc_state, @@ -2426,10 +2428,12 @@ impl TendermintCoin { let response = self .rpc_client() - .await? + .await + .map_mm_err()? .perform(request) .await - .map_to_mm(TendermintCoinRpcError::from)?; + .map_to_mm(TendermintCoinRpcError::from) + .map_mm_err()?; match response.txs.first() { Some(raw_tx) => { let tx = cosmrs::Tx::from_bytes(&raw_tx.tx)?; @@ -2593,7 +2597,8 @@ impl TendermintCoin { let (balance_u64, balance_dec) = self .get_balance_as_unsigned_and_decimal(&delegator_address, &self.protocol_info.denom, self.decimals()) - .await?; + .await + .map_mm_err()?; let amount_u64 = if req.max { balance_u64 @@ -2631,7 +2636,8 @@ impl TendermintCoin { &req.memo, req.fee, ) - .await?; + .await + .map_mm_err()?; let fee_amount_dec = big_decimal_from_sat_unsigned(fee_amount_u64, self.decimals()); @@ -2661,7 +2667,7 @@ impl TendermintCoin { ) .map_err(|e| DelegationError::InternalError(e.to_string()))?; - let account_info = self.account_info(&delegator_address).await?; + let account_info = self.account_info(&delegator_address).await.map_mm_err()?; let tx = self .any_to_transaction_data( @@ -2767,11 +2773,12 @@ impl TendermintCoin { &req.memo, req.fee, ) - .await?; + .await + .map_mm_err()?; let fee_amount_dec = big_decimal_from_sat_unsigned(fee_amount_u64, self.decimals()); - let my_balance = self.my_balance().compat().await?.spendable; + let my_balance = self.my_balance().compat().await.map_mm_err()?.spendable; if fee_amount_dec > my_balance { return MmError::err(DelegationError::NotSufficientBalance { @@ -2789,7 +2796,7 @@ impl TendermintCoin { gas_limit, ); - let account_info = self.account_info(&delegator_address).await?; + let account_info = self.account_info(&delegator_address).await.map_mm_err()?; let tx = self .any_to_transaction_data( @@ -2845,7 +2852,8 @@ impl TendermintCoin { let raw_response = self .rpc_client() - .await? + .await + .map_mm_err()? .abci_query( Some(ABCI_DELEGATION_PATH.to_owned()), request.encode_to_vec(), @@ -2892,7 +2900,8 @@ impl TendermintCoin { let raw_response = self .rpc_client() - .await? + .await + .map_mm_err()? .abci_query( Some(ABCI_DELEGATION_REWARDS_PATH.to_owned()), query_payload.encode_to_vec(), @@ -2964,11 +2973,12 @@ impl TendermintCoin { &req.memo, req.fee, ) - .await?; + .await + .map_mm_err()?; let fee_amount_dec = big_decimal_from_sat_unsigned(fee_amount_u64, self.decimals()); - let my_balance = self.my_balance().compat().await?.spendable; + let my_balance = self.my_balance().compat().await.map_mm_err()?.spendable; if fee_amount_dec > my_balance { return MmError::err(DelegationError::NotSufficientBalance { @@ -2993,7 +3003,7 @@ impl TendermintCoin { gas_limit, ); - let account_info = self.account_info(&delegator_address).await?; + let account_info = self.account_info(&delegator_address).await.map_mm_err()?; let tx = self .any_to_transaction_data(maybe_priv_key, msg, &account_info, fee, timeout_height, &req.memo) @@ -3237,7 +3247,8 @@ impl MmCoin for TendermintCoin { let (balance_denom, balance_dec) = coin .get_balance_as_unsigned_and_decimal(&account_id, &coin.protocol_info.denom, coin.decimals()) - .await?; + .await + .map_mm_err()?; let (amount_denom, amount_dec) = if req.max { let amount_denom = balance_denom; @@ -3246,7 +3257,10 @@ impl MmCoin for TendermintCoin { big_decimal_from_sat_unsigned(amount_denom, coin.decimals()), ) } else { - (sat_from_big_decimal(&req.amount, coin.decimals())?, req.amount.clone()) + ( + sat_from_big_decimal(&req.amount, coin.decimals()).map_mm_err()?, + req.amount.clone(), + ) }; if !coin.is_tx_amount_enough(coin.decimals(), &amount_dec) { @@ -3267,7 +3281,8 @@ impl MmCoin for TendermintCoin { Some(_) => req.ibc_source_channel, None => Some( coin.get_healthy_ibc_channel_for_address_prefix(to_address.prefix()) - .await?, + .await + .map_mm_err()?, ), } } else { @@ -3308,7 +3323,8 @@ impl MmCoin for TendermintCoin { &memo, req.fee, ) - .await?; + .await + .map_mm_err()?; let fee_amount_u64 = if coin.is_ledger_connection() { // When using `SIGN_MODE_LEGACY_AMINO_JSON`, Keplr ignores the fee we calculated @@ -3352,7 +3368,7 @@ impl MmCoin for TendermintCoin { }); } - (sat_from_big_decimal(&req.amount, coin.decimals())?, total) + (sat_from_big_decimal(&req.amount, coin.decimals()).map_mm_err()?, total) }; let msg_payload = create_withdraw_msg_as_any( @@ -3364,7 +3380,7 @@ impl MmCoin for TendermintCoin { ) .await?; - let account_info = coin.account_info(&account_id).await?; + let account_info = coin.account_info(&account_id).await.map_mm_err()?; let tx = coin .any_to_transaction_data(maybe_priv_key, msg_payload, &account_info, fee, timeout_height, &memo) @@ -3407,7 +3423,7 @@ impl MmCoin for TendermintCoin { let coin = self.clone(); let fut = async move { req.tx_hash.make_ascii_uppercase(); - let tx_from_rpc = coin.request_tx(req.tx_hash).await?; + let tx_from_rpc = coin.request_tx(req.tx_hash).await.map_mm_err()?; Ok(RawTransactionRes { tx_hex: tx_from_rpc.encode_to_vec().into(), }) @@ -3423,7 +3439,7 @@ impl MmCoin for TendermintCoin { RawTransactionError::InvalidHashError(format!("Invalid hash length: expected 32, got {}", len)) })?; let hash = hex::encode_upper(H256::from(hash)); - let tx_from_rpc = coin.request_tx(hash).await?; + let tx_from_rpc = coin.request_tx(hash).await.map_mm_err()?; Ok(RawTransactionRes { tx_hex: tx_from_rpc.encode_to_vec().into(), }) @@ -3672,7 +3688,7 @@ impl MarketCoinOps for TendermintCoin { } async fn get_public_key(&self) -> Result> { - let key = SigningKey::from_slice(self.activation_policy.activated_key_or_err()?.as_slice()) + let key = SigningKey::from_slice(self.activation_policy.activated_key_or_err().map_mm_err()?.as_slice()) .expect("privkey validity is checked on coin creation"); Ok(key.public_key().to_string()) } @@ -3697,7 +3713,8 @@ impl MarketCoinOps for TendermintCoin { let fut = async move { let balance_denom = coin .account_balance_for_denom(&coin.account_id, coin.protocol_info.denom.to_string()) - .await?; + .await + .map_mm_err()?; Ok(CoinBalance { spendable: big_decimal_from_sat_unsigned(balance_denom, coin.decimals()), unspendable: BigDecimal::default(), diff --git a/mm2src/coins/tendermint/tendermint_token.rs b/mm2src/coins/tendermint/tendermint_token.rs index 728541e9c3..c85fe08605 100644 --- a/mm2src/coins/tendermint/tendermint_token.rs +++ b/mm2src/coins/tendermint/tendermint_token.rs @@ -292,7 +292,8 @@ impl MarketCoinOps for TendermintToken { let balance_denom = coin .platform_coin .account_balance_for_denom(&coin.platform_coin.account_id, coin.denom.to_string()) - .await?; + .await + .map_mm_err()?; Ok(CoinBalance { spendable: big_decimal_from_sat_unsigned(balance_denom, coin.decimals), unspendable: BigDecimal::default(), @@ -383,11 +384,13 @@ impl MmCoin for TendermintToken { let (base_denom_balance, base_denom_balance_dec) = platform .get_balance_as_unsigned_and_decimal(&account_id, &platform.protocol_info.denom, token.decimals()) - .await?; + .await + .map_mm_err()?; let (balance_denom, balance_dec) = platform .get_balance_as_unsigned_and_decimal(&account_id, &token.denom, token.decimals()) - .await?; + .await + .map_mm_err()?; let (amount_denom, amount_dec, total_amount) = if req.max { ( @@ -405,7 +408,7 @@ impl MmCoin for TendermintToken { } ( - sat_from_big_decimal(&req.amount, token.decimals())?, + sat_from_big_decimal(&req.amount, token.decimals()).map_mm_err()?, req.amount.clone(), req.amount, ) @@ -430,7 +433,8 @@ impl MmCoin for TendermintToken { None => Some( platform .get_healthy_ibc_channel_for_address_prefix(to_address.prefix()) - .await?, + .await + .map_mm_err()?, ), } } else { @@ -470,7 +474,8 @@ impl MmCoin for TendermintToken { &memo, req.fee, ) - .await?; + .await + .map_mm_err()?; let fee_amount_dec = big_decimal_from_sat_unsigned(fee_amount_u64, platform.decimals()); @@ -489,7 +494,7 @@ impl MmCoin for TendermintToken { let fee = Fee::from_amount_and_gas(fee_amount, gas_limit); - let account_info = platform.account_info(&account_id).await?; + let account_info = platform.account_info(&account_id).await.map_mm_err()?; let tx = platform .any_to_transaction_data(maybe_priv_key, msg_payload, &account_info, fee, timeout_height, &memo) diff --git a/mm2src/coins/tx_history_storage/wasm/tx_history_storage_v1.rs b/mm2src/coins/tx_history_storage/wasm/tx_history_storage_v1.rs index c52fefd76d..77baedcb29 100644 --- a/mm2src/coins/tx_history_storage/wasm/tx_history_storage_v1.rs +++ b/mm2src/coins/tx_history_storage/wasm/tx_history_storage_v1.rs @@ -2,6 +2,7 @@ use crate::tx_history_storage::wasm::tx_history_db::TxHistoryDb; use crate::tx_history_storage::wasm::WasmTxHistoryResult; use crate::TransactionDetails; use mm2_db::indexed_db::{DbIdentifier, DbInstance, DbUpgrader, OnUpgradeResult, TableSignature}; +use mm2_err_handle::prelude::MmResultExt; pub async fn load_tx_history( db: &TxHistoryDb, @@ -10,12 +11,13 @@ pub async fn load_tx_history( ) -> WasmTxHistoryResult> { let history_id = HistoryId::new(ticker, wallet_address); - let transaction = db.get_inner().transaction().await?; - let table = transaction.table::().await?; + let transaction = db.get_inner().transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; let item_opt = table .get_item_by_unique_index("history_id", history_id.as_str()) - .await?; + .await + .map_mm_err()?; match item_opt { Some((_item_id, TxHistoryTableV1 { txs, .. })) => Ok(txs), None => Ok(Vec::new()), @@ -32,24 +34,26 @@ pub async fn save_tx_history( let history_id_value = history_id.to_string(); let tx_history_item = TxHistoryTableV1 { history_id, txs }; - let transaction = db.get_inner().transaction().await?; - let table = transaction.table::().await?; + let transaction = db.get_inner().transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; table .replace_item_by_unique_index("history_id", &history_id_value, &tx_history_item) - .await?; + .await + .map_mm_err()?; Ok(()) } pub async fn clear_tx_history(db: &TxHistoryDb, ticker: &str, wallet_address: &str) -> WasmTxHistoryResult<()> { let history_id = HistoryId::new(ticker, wallet_address); - let transaction = db.get_inner().transaction().await?; - let table = transaction.table::().await?; + let transaction = db.get_inner().transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; table .delete_item_by_unique_index("history_id", history_id.as_str()) - .await?; + .await + .map_mm_err()?; Ok(()) } diff --git a/mm2src/coins/tx_history_storage/wasm/tx_history_storage_v2.rs b/mm2src/coins/tx_history_storage/wasm/tx_history_storage_v2.rs index acc6d338e2..6b3f33ee2b 100644 --- a/mm2src/coins/tx_history_storage/wasm/tx_history_storage_v2.rs +++ b/mm2src/coins/tx_history_storage/wasm/tx_history_storage_v2.rs @@ -54,26 +54,29 @@ impl TxHistoryStorage for IndexedDbTxHistoryStorage { I::IntoIter: Send, { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let history_table = db_transaction.table::().await?; - let cache_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let history_table = db_transaction.table::().await.map_mm_err()?; + let cache_table = db_transaction.table::().await.map_mm_err()?; for tx in transactions { let Some(tx_hash) = tx.tx.tx_hash() else { continue }; let history_item = TxHistoryTableV2::from_tx_details(wallet_id.clone(), &tx)?; - history_table.add_item(&history_item).await?; + history_table.add_item(&history_item).await.map_mm_err()?; let cache_item = TxCacheTableV2::from_tx_details(wallet_id.clone(), &tx)?; let index_keys = MultiIndex::new(TxCacheTableV2::COIN_TX_HASH_INDEX) - .with_value(&wallet_id.ticker)? - .with_value(tx_hash)?; + .with_value(&wallet_id.ticker) + .map_mm_err()? + .with_value(tx_hash) + .map_mm_err()?; // `TxHistoryTableV2::tx_hash` is not a unique field, but `TxCacheTableV2::tx_hash` is unique. // So we use `DbTable::add_item_or_ignore_by_unique_multi_index` instead of `DbTable::add_item` // since `transactions` may contain txs with same `tx_hash` but different `internal_id`. cache_table .add_item_or_ignore_by_unique_multi_index(index_keys, &cache_item) - .await?; + .await + .map_mm_err()?; } Ok(()) } @@ -84,15 +87,23 @@ impl TxHistoryStorage for IndexedDbTxHistoryStorage { internal_id: &BytesJson, ) -> MmResult { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(TxHistoryTableV2::WALLET_ID_INTERNAL_ID_INDEX) - .with_value(&wallet_id.ticker)? - .with_value(wallet_id.hd_wallet_rmd160_or_exclude())? - .with_value(internal_id)?; - - if table.delete_item_by_unique_multi_index(index_keys).await?.is_some() { + .with_value(&wallet_id.ticker) + .map_mm_err()? + .with_value(wallet_id.hd_wallet_rmd160_or_exclude()) + .map_mm_err()? + .with_value(internal_id) + .map_mm_err()?; + + if table + .delete_item_by_unique_multi_index(index_keys) + .await + .map_mm_err()? + .is_some() + { Ok(RemoveTxResult::TxRemoved) } else { Ok(RemoveTxResult::TxDidNotExist) @@ -105,15 +116,18 @@ impl TxHistoryStorage for IndexedDbTxHistoryStorage { internal_id: &BytesJson, ) -> MmResult, Self::Error> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(TxHistoryTableV2::WALLET_ID_INTERNAL_ID_INDEX) - .with_value(&wallet_id.ticker)? - .with_value(wallet_id.hd_wallet_rmd160_or_exclude())? - .with_value(internal_id)?; - - let details_json = match table.get_item_by_unique_multi_index(index_keys).await? { + .with_value(&wallet_id.ticker) + .map_mm_err()? + .with_value(wallet_id.hd_wallet_rmd160_or_exclude()) + .map_mm_err()? + .with_value(internal_id) + .map_mm_err()?; + + let details_json = match table.get_item_by_unique_multi_index(index_keys).await.map_mm_err()? { Some((_item_id, item)) => item.details_json, None => return Ok(None), }; @@ -133,7 +147,10 @@ impl TxHistoryStorage for IndexedDbTxHistoryStorage { wallet_id: &WalletId, for_addresses: FilteringAddresses, ) -> Result> { - let txs = self.get_unconfirmed_txes_from_history(wallet_id, for_addresses).await?; + let txs = self + .get_unconfirmed_txes_from_history(wallet_id, for_addresses) + .await + .map_mm_err()?; Ok(!txs.is_empty()) } @@ -144,17 +161,21 @@ impl TxHistoryStorage for IndexedDbTxHistoryStorage { for_addresses: FilteringAddresses, ) -> MmResult, Self::Error> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(TxHistoryTableV2::WALLET_ID_CONFIRMATION_STATUS_INDEX) - .with_value(&wallet_id.ticker)? - .with_value(wallet_id.hd_wallet_rmd160_or_exclude())? - .with_value(ConfirmationStatus::Unconfirmed)?; + .with_value(&wallet_id.ticker) + .map_mm_err()? + .with_value(wallet_id.hd_wallet_rmd160_or_exclude()) + .map_mm_err()? + .with_value(ConfirmationStatus::Unconfirmed) + .map_mm_err()?; let transactions = table .get_items_by_multi_index(index_keys) - .await? + .await + .map_mm_err()? .into_iter() .map(|(_item_id, item)| item); @@ -164,28 +185,37 @@ impl TxHistoryStorage for IndexedDbTxHistoryStorage { /// Updates transaction in the selected coin's history async fn update_tx_in_history(&self, wallet_id: &WalletId, tx: &TransactionDetails) -> MmResult<(), Self::Error> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(TxHistoryTableV2::WALLET_ID_INTERNAL_ID_INDEX) - .with_value(&wallet_id.ticker)? - .with_value(wallet_id.hd_wallet_rmd160_or_exclude())? - .with_value(&tx.internal_id)?; + .with_value(&wallet_id.ticker) + .map_mm_err()? + .with_value(wallet_id.hd_wallet_rmd160_or_exclude()) + .map_mm_err()? + .with_value(&tx.internal_id) + .map_mm_err()?; let item = TxHistoryTableV2::from_tx_details(wallet_id.clone(), tx)?; - table.replace_item_by_unique_multi_index(index_keys, &item).await?; + table + .replace_item_by_unique_multi_index(index_keys, &item) + .await + .map_mm_err()?; Ok(()) } async fn history_has_tx_hash(&self, wallet_id: &WalletId, tx_hash: &str) -> Result> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(TxHistoryTableV2::WALLET_ID_TX_HASH_INDEX) - .with_value(&wallet_id.ticker)? - .with_value(wallet_id.hd_wallet_rmd160_or_exclude())? - .with_value(tx_hash)?; - let count_txs = table.count_by_multi_index(index_keys).await?; + .with_value(&wallet_id.ticker) + .map_mm_err()? + .with_value(wallet_id.hd_wallet_rmd160_or_exclude()) + .map_mm_err()? + .with_value(tx_hash) + .map_mm_err()?; + let count_txs = table.count_by_multi_index(index_keys).await.map_mm_err()?; Ok(count_txs > 0) } @@ -196,18 +226,21 @@ impl TxHistoryStorage for IndexedDbTxHistoryStorage { for_addresses: FilteringAddresses, ) -> Result> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(TxHistoryTableV2::WALLET_ID_INDEX) - .with_value(&wallet_id.ticker)? - .with_value(wallet_id.hd_wallet_rmd160_or_exclude())?; + .with_value(&wallet_id.ticker) + .map_mm_err()? + .with_value(wallet_id.hd_wallet_rmd160_or_exclude()) + .map_mm_err()?; // `IndexedDb` doesn't provide an elegant way to count records applying custom filters to index properties like `tx_hash`, // so currently fetch all records with `coin,hd_wallet_rmd160=wallet_id` and apply the `unique_by(|tx| tx.tx_hash)` to them. let transactions = table .get_items_by_multi_index(index_keys) - .await? + .await + .map_mm_err()? .into_iter() .map(|(_item_id, tx)| tx) .unique_by(|tx| tx.tx_hash.clone()); @@ -223,8 +256,8 @@ impl TxHistoryStorage for IndexedDbTxHistoryStorage { tx_hex: &BytesJson, ) -> Result<(), MmError> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; table .add_item(&TxCacheTableV2 { @@ -232,7 +265,8 @@ impl TxHistoryStorage for IndexedDbTxHistoryStorage { tx_hash: tx_hash.to_owned(), tx_hex: tx_hex.clone(), }) - .await?; + .await + .map_mm_err()?; Ok(()) } @@ -242,13 +276,15 @@ impl TxHistoryStorage for IndexedDbTxHistoryStorage { tx_hash: &str, ) -> MmResult, Self::Error> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(TxCacheTableV2::COIN_TX_HASH_INDEX) - .with_value(&wallet_id.ticker)? - .with_value(tx_hash)?; - match table.get_item_by_unique_multi_index(index_keys).await? { + .with_value(&wallet_id.ticker) + .map_mm_err()? + .with_value(tx_hash) + .map_mm_err()?; + match table.get_item_by_unique_multi_index(index_keys).await.map_mm_err()? { Some((_item_id, item)) => Ok(Some(item.tx_hex)), None => Ok(None), } @@ -283,17 +319,21 @@ impl TxHistoryStorage for IndexedDbTxHistoryStorage { } let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(TxHistoryTableV2::WALLET_ID_TOKEN_ID_INDEX) - .with_value(&wallet_id.ticker)? - .with_value(wallet_id.hd_wallet_rmd160_or_exclude())? - .with_value(filters.token_id_or_exclude())?; + .with_value(&wallet_id.ticker) + .map_mm_err()? + .with_value(wallet_id.hd_wallet_rmd160_or_exclude()) + .map_mm_err()? + .with_value(filters.token_id_or_exclude()) + .map_mm_err()?; let transactions = table .get_items_by_multi_index(index_keys) - .await? + .await + .map_mm_err()? .into_iter() .map(|(_item_id, tx)| tx); diff --git a/mm2src/coins/utxo.rs b/mm2src/coins/utxo.rs index 53e9bc7cdb..b03e27f6c1 100644 --- a/mm2src/coins/utxo.rs +++ b/mm2src/coins/utxo.rs @@ -242,7 +242,7 @@ impl From for TxProviderError { #[async_trait] impl TxProvider for UtxoRpcClientEnum { async fn get_rpc_transaction(&self, tx_hash: &H256Json) -> Result> { - Ok(self.get_verbose_transaction(tx_hash).compat().await?) + Ok(self.get_verbose_transaction(tx_hash).compat().await.map_mm_err()?) } } diff --git a/mm2src/coins/utxo/bch.rs b/mm2src/coins/utxo/bch.rs index 8694710907..8e5aab5c5b 100644 --- a/mm2src/coins/utxo/bch.rs +++ b/mm2src/coins/utxo/bch.rs @@ -64,7 +64,7 @@ impl BchActivationRequest { pub fn from_legacy_req(req: &Json) -> Result> { let bchd_urls = json::from_value(req["bchd_urls"].clone()).map_to_mm(BchFromLegacyReqErr::InvalidBchdUrls)?; let allow_slp_unsafe_conf = req["allow_slp_unsafe_conf"].as_bool().unwrap_or_default(); - let utxo_params = UtxoActivationParams::from_legacy_req(req)?; + let utxo_params = UtxoActivationParams::from_legacy_req(req).map_mm_err()?; Ok(BchActivationRequest { allow_slp_unsafe_conf, @@ -493,7 +493,7 @@ impl BchCoin { ) -> MmResult { let token_genesis_tx = self.tx_from_storage_or_rpc(&token_id.into(), storage).await?; let maybe_genesis_script: Script = token_genesis_tx.outputs[0].script_pubkey.clone().into(); - let slp_details = parse_slp_script(&maybe_genesis_script)?; + let slp_details = parse_slp_script(&maybe_genesis_script).map_mm_err()?; match slp_details.transaction { SlpTransaction::Genesis(params) => Ok(params), _ => { @@ -1160,8 +1160,13 @@ impl MarketCoinOps for BchCoin { fn my_balance(&self) -> BalanceFut { let coin = self.clone(); let fut = async move { - let my_address = coin.as_ref().derivation_method.single_addr_or_err().await?; - let bch_unspents = coin.bch_unspents_for_display(&my_address).await?; + let my_address = coin + .as_ref() + .derivation_method + .single_addr_or_err() + .await + .map_mm_err()?; + let bch_unspents = coin.bch_unspents_for_display(&my_address).await.map_mm_err()?; Ok(bch_unspents.platform_balance(coin.as_ref().decimals)) }; Box::new(fut.boxed().compat()) @@ -1474,7 +1479,7 @@ impl CoinWithTxHistoryV2 for BchCoin { return MmError::err(MyTxHistoryErrorV2::InvalidTarget(error)); }, } - let my_address = self.my_address()?; + let my_address = self.my_address().map_mm_err()?; Ok(GetTxHistoryFilters::for_address(my_address)) } } @@ -1482,7 +1487,7 @@ impl CoinWithTxHistoryV2 for BchCoin { #[async_trait] impl UtxoTxHistoryOps for BchCoin { async fn my_addresses(&self) -> MmResult, UtxoMyAddressesHistoryError> { - let addresses = self.all_addresses().await?; + let addresses = self.all_addresses().await.map_mm_err()?; Ok(addresses) } diff --git a/mm2src/coins/utxo/bchd_grpc.rs b/mm2src/coins/utxo/bchd_grpc.rs index c7c01d073b..56c4bc3849 100644 --- a/mm2src/coins/utxo/bchd_grpc.rs +++ b/mm2src/coins/utxo/bchd_grpc.rs @@ -130,7 +130,8 @@ pub async fn validate_slp_utxos( .iter() .map(|url| url.as_ref().to_owned() + "/pb.bchrpc/GetSlpTrustedValidation") .collect(); - let responses: Vec<(_, GetSlpTrustedValidationResponse)> = grpc_web_multi_url_request(&urls, &request).await?; + let responses: Vec<(_, GetSlpTrustedValidationResponse)> = + grpc_web_multi_url_request(&urls, &request).await.map_mm_err()?; for (url, response) in responses { for validation_result in response.results { let actual_token_id = { @@ -253,7 +254,8 @@ pub async fn check_slp_transaction( .map(|url| url.as_ref().to_owned() + "/pb.bchrpc/CheckSlpTransaction") .collect(); - let responses: Vec<(_, CheckSlpTransactionResponse)> = grpc_web_multi_url_request(&urls, &request).await?; + let responses: Vec<(_, CheckSlpTransactionResponse)> = + grpc_web_multi_url_request(&urls, &request).await.map_mm_err()?; for (url, response) in responses { if !response.is_valid { return MmError::err(CheckSlpTransactionErr { diff --git a/mm2src/coins/utxo/qtum.rs b/mm2src/coins/utxo/qtum.rs index a45b4a9491..472baedcfa 100644 --- a/mm2src/coins/utxo/qtum.rs +++ b/mm2src/coins/utxo/qtum.rs @@ -156,7 +156,12 @@ pub trait QtumBasedCoin: UtxoCommonOps + MarketCoinOps { } async fn my_addr_as_contract_addr(&self) -> MmResult { - let my_address = self.as_ref().derivation_method.single_addr_or_err().await?; + let my_address = self + .as_ref() + .derivation_method + .single_addr_or_err() + .await + .map_mm_err()?; contract_addr_from_utxo_addr(my_address).mm_err(Qrc20AddressError::from) } @@ -1200,7 +1205,7 @@ impl CoinWithTxHistoryV2 for QtumCoin { #[async_trait] impl UtxoTxHistoryOps for QtumCoin { async fn my_addresses(&self) -> MmResult, UtxoMyAddressesHistoryError> { - let addresses = self.all_addresses().await?; + let addresses = self.all_addresses().await.map_mm_err()?; Ok(addresses) } diff --git a/mm2src/coins/utxo/qtum_delegation.rs b/mm2src/coins/utxo/qtum_delegation.rs index 3723109720..a37eba4cdf 100644 --- a/mm2src/coins/utxo/qtum_delegation.rs +++ b/mm2src/coins/utxo/qtum_delegation.rs @@ -105,11 +105,12 @@ impl QtumDelegationOps for QtumCoin { let mut buffer = b"\x15Qtum Signed Message:\n\x28".to_vec(); buffer.append(&mut addr_hash.to_string().into_bytes()); let hashed = dhash256(&buffer); - let key_pair = self.as_ref().priv_key_policy.activated_key_or_err()?; + let key_pair = self.as_ref().priv_key_policy.activated_key_or_err().map_mm_err()?; let signature = key_pair .private() .sign_compact(&hashed) - .map_to_mm(|e| QtumStakingAbiError::PodSigningError(e.to_string()))?; + .map_to_mm(|e| QtumStakingAbiError::PodSigningError(e.to_string())) + .map_mm_err()?; Ok(signature) } } @@ -121,9 +122,11 @@ impl QtumCoin { reason: "Qtum doesn't support delegation for segwit".to_string(), }); } - let delegation_output = self.remove_delegation_output(QRC20_GAS_LIMIT_DEFAULT, QRC20_GAS_PRICE_DEFAULT)?; + let delegation_output = self + .remove_delegation_output(QRC20_GAS_LIMIT_DEFAULT, QRC20_GAS_PRICE_DEFAULT) + .map_mm_err()?; let outputs = vec![delegation_output]; - let my_address = self.my_address()?; + let my_address = self.my_address().map_mm_err()?; self.generate_delegation_transaction( outputs, my_address, @@ -142,7 +145,7 @@ impl QtumCoin { }, UtxoRpcClientEnum::Electrum(electrum) => electrum, }; - let address = self.my_addr_as_contract_addr().await?; + let address = self.my_addr_as_contract_addr().await.map_mm_err()?; let address_rpc = contract_addr_into_rpc_format(&address); let add_delegation_history = client .blockchain_contract_event_get_history(&address_rpc, &contract_address, QTUM_ADD_DELEGATION_TOPIC) @@ -198,10 +201,10 @@ impl QtumCoin { async fn get_delegation_infos_impl(&self) -> StakingInfosResult { let coin = self.as_ref(); - let my_address = coin.derivation_method.single_addr_or_err().await?; + let my_address = coin.derivation_method.single_addr_or_err().await.map_mm_err()?; let staker = self.am_i_currently_staking().await?; - let (unspents, _) = self.get_unspent_ordered_list(&my_address).await?; + let (unspents, _) = self.get_unspent_ordered_list(&my_address).await.map_mm_err()?; let lower_bound = QTUM_LOWER_BOUND_DELEGATION_AMOUNT .try_into() .expect("Conversion should succeed"); @@ -232,7 +235,7 @@ impl QtumCoin { reason: "Qtum doesn't support delegation for segwit".to_string(), }); } - if let Some(staking_addr) = self.am_i_currently_staking().await? { + if let Some(staking_addr) = self.am_i_currently_staking().await.map_mm_err()? { return MmError::err(DelegationError::AlreadyDelegating(staking_addr)); } let to_addr = @@ -240,7 +243,7 @@ impl QtumCoin { .map_to_mm(DelegationError::AddressError)?; let fee = request.fee.unwrap_or(QTUM_DELEGATION_STANDARD_FEE); let _utxo_lock = UTXO_LOCK.lock(); - let staker_address_hex = qtum::contract_addr_from_utxo_addr(to_addr.clone())?; + let staker_address_hex = qtum::contract_addr_from_utxo_addr(to_addr.clone()).map_mm_err()?; let delegation_output = self.add_delegation_output( staker_address_hex, to_addr.hash().clone(), @@ -250,7 +253,7 @@ impl QtumCoin { )?; let outputs = vec![delegation_output]; - let my_address = self.my_address()?; + let my_address = self.my_address().map_mm_err()?; self.generate_delegation_transaction( outputs, my_address, @@ -269,10 +272,10 @@ impl QtumCoin { ) -> DelegationResult { let utxo = self.as_ref(); - let key_pair = utxo.priv_key_policy.activated_key_or_err()?; - let my_address = utxo.derivation_method.single_addr_or_err().await?; + let key_pair = utxo.priv_key_policy.activated_key_or_err().map_mm_err()?; + let my_address = utxo.derivation_method.single_addr_or_err().await.map_mm_err()?; - let (unspents, _) = self.get_unspent_ordered_list(&my_address).await?; + let (unspents, _) = self.get_unspent_ordered_list(&my_address).await.map_mm_err()?; let mut gas_fee = 0; let mut outputs = Vec::with_capacity(contract_outputs.len()); for output in contract_outputs { @@ -292,7 +295,7 @@ impl QtumCoin { DelegationError::from_generate_tx_error(gen_tx_error, self.ticker().to_string(), utxo.decimals) })?; - let signed = sign_tx(unsigned, key_pair, utxo.conf.signature_version, utxo.conf.fork_id)?; + let signed = sign_tx(unsigned, key_pair, utxo.conf.signature_version, utxo.conf.fork_id).map_mm_err()?; let generated_tx = GenerateQrc20TxResult { signed, @@ -308,7 +311,7 @@ impl QtumCoin { gas_price: QRC20_GAS_PRICE_DEFAULT, total_gas_fee: utxo_common::big_decimal_from_sat(generated_tx.gas_fee as i64, utxo.decimals), }; - let my_address_string = self.my_address()?; + let my_address_string = self.my_address().map_mm_err()?; let spent_by_me = utxo_common::big_decimal_from_sat(data.spent_by_me as i64, utxo.decimals); let qtum_amount = spent_by_me.clone(); @@ -345,7 +348,8 @@ impl QtumCoin { gas_limit, gas_price, QTUM_DELEGATE_CONTRACT_ADDRESS.as_bytes(), - )? + ) + .map_mm_err()? .to_bytes(); Ok(ContractCallOutput { value: OUTPUT_QTUM_AMOUNT, @@ -377,7 +381,8 @@ impl QtumCoin { gas_limit, gas_price, QTUM_DELEGATE_CONTRACT_ADDRESS.as_bytes(), - )? + ) + .map_mm_err()? .to_bytes(); Ok(ContractCallOutput { value: OUTPUT_QTUM_AMOUNT, diff --git a/mm2src/coins/utxo/rpc_clients.rs b/mm2src/coins/utxo/rpc_clients.rs index fce6afa82a..f09d7ddf67 100644 --- a/mm2src/coins/utxo/rpc_clients.rs +++ b/mm2src/coins/utxo/rpc_clients.rs @@ -785,7 +785,7 @@ impl UtxoRpcClientOps for NativeClient { .and_then(move |unspents| { unspents .into_iter() - .map(|unspent| Ok(UnspentInfo::from_native(unspent, decimals, None)?)) + .map(|unspent| UnspentInfo::from_native(unspent, decimals, None).map_mm_err()) .collect::>() }); Box::new(fut) @@ -814,7 +814,7 @@ impl UtxoRpcClientOps for NativeClient { UtxoRpcError::InvalidResponse(format!("Unexpected address '{}'", unspent.address)) })? .clone(); - let unspent_info = UnspentInfo::from_native(unspent, decimals, None)?; + let unspent_info = UnspentInfo::from_native(unspent, decimals, None).map_mm_err()?; Ok((orig_address, unspent_info)) }) // Collect `(Address, UnspentInfo)` items into `HashMap>` grouped by the addresses. @@ -991,7 +991,7 @@ impl UtxoRpcClientOps for NativeClient { } async fn get_block_timestamp(&self, height: u64) -> Result> { - let block = self.get_block_by_height(height).await?; + let block = self.get_block_by_height(height).await.map_mm_err()?; Ok(block.time as u64) } } diff --git a/mm2src/coins/utxo/rpc_clients/electrum_rpc/client.rs b/mm2src/coins/utxo/rpc_clients/electrum_rpc/client.rs index 3cf3996f09..dec5920659 100644 --- a/mm2src/coins/utxo/rpc_clients/electrum_rpc/client.rs +++ b/mm2src/coins/utxo/rpc_clients/electrum_rpc/client.rs @@ -610,7 +610,12 @@ impl ElectrumClient { // This method should always be used if the block headers are saved to the DB async fn get_tx_height_from_storage(&self, tx: &UtxoTx) -> Result> { let tx_hash = tx.hash().reversed(); - let blockhash = self.get_verbose_transaction(&tx_hash.into()).compat().await?.blockhash; + let blockhash = self + .get_verbose_transaction(&tx_hash.into()) + .compat() + .await + .map_mm_err()? + .blockhash; Ok(self .block_headers_storage() .get_block_height_by_hash(blockhash.into()) @@ -688,7 +693,7 @@ impl ElectrumClient { &self, tx: &UtxoTx, ) -> Result<(TxMerkleBranch, BlockHeader, u64), MmError> { - let height = self.get_tx_height_from_storage(tx).await?; + let height = self.get_tx_height_from_storage(tx).await.map_mm_err()?; let merkle_branch = self .blockchain_transaction_get_merkle(tx.hash().reversed().into(), height) @@ -699,7 +704,7 @@ impl ElectrumClient { err: err.to_string(), })?; - let header = self.block_header_from_storage(height).await?; + let header = self.block_header_from_storage(height).await.map_mm_err()?; Ok((merkle_branch, header, height)) } diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index 5a537e42dc..13ac99cbe0 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -348,7 +348,7 @@ impl SlpToken { if slp_outputs.len() > 18 { return MmError::err(GenSlpSpendErr::TooManyOutputs); } - let (slp_unspents, bch_unspents, recently_spent) = self.slp_unspents_for_spend().await?; + let (slp_unspents, bch_unspents, recently_spent) = self.slp_unspents_for_spend().await.map_mm_err()?; let total_slp_output = slp_outputs.iter().fold(0, |cur, slp_out| cur + slp_out.amount); let mut total_slp_input = 0; @@ -385,7 +385,7 @@ impl SlpToken { })); if change > 0 { - let my_public_key = self.platform_coin.my_public_key()?; + let my_public_key = self.platform_coin.my_public_key().map_mm_err()?; let slp_change_out = TransactionOutput { value: self.platform_dust(), script_pubkey: ScriptBuilder::build_p2pkh(&my_public_key.address_hash().into()).to_bytes(), @@ -393,7 +393,9 @@ impl SlpToken { outputs.push(slp_change_out); } - validate_slp_utxos(self.platform_coin.bchd_urls(), &inputs, self.token_id()).await?; + validate_slp_utxos(self.platform_coin.bchd_urls(), &inputs, self.token_id()) + .await + .map_mm_err()?; let preimage = SlpTxPreimage { slp_inputs: inputs, available_bch_inputs: bch_unspents, @@ -447,7 +449,7 @@ impl SlpToken { )); } - let slp_satoshis = sat_from_big_decimal(&input.amount, self.decimals())?; + let slp_satoshis = sat_from_big_decimal(&input.amount, self.decimals()).map_mm_err()?; let slp_unspent = SlpUnspent { bch_unspent: UnspentInfo { @@ -461,9 +463,11 @@ impl SlpToken { }, slp_amount: slp_satoshis, }; - validate_slp_utxos(self.platform_coin.bchd_urls(), &[slp_unspent], self.token_id()).await?; + validate_slp_utxos(self.platform_coin.bchd_urls(), &[slp_unspent], self.token_id()) + .await + .map_mm_err()?; - let slp_tx: SlpTxDetails = parse_slp_script(tx.outputs[0].script_pubkey.as_slice())?; + let slp_tx: SlpTxDetails = parse_slp_script(tx.outputs[0].script_pubkey.as_slice()).map_mm_err()?; match slp_tx.transaction { SlpTransaction::Send { token_id, amounts } => { @@ -533,10 +537,10 @@ impl SlpToken { return MmError::err(SpendHtlcError::TxLackOfOutputs); } - let slp_tx: SlpTxDetails = parse_slp_script(tx.outputs[0].script_pubkey.as_slice())?; + let slp_tx: SlpTxDetails = parse_slp_script(tx.outputs[0].script_pubkey.as_slice()).map_mm_err()?; let other_pub = Public::from_slice(other_pub)?; - let my_public_key = self.platform_coin.my_public_key()?; + let my_public_key = self.platform_coin.my_public_key().map_mm_err()?; let redeem_script = payment_script(time_lock, secret_hash, my_public_key, &other_pub); let slp_amount = match slp_tx.transaction { @@ -561,7 +565,7 @@ impl SlpToken { slp_amount, }; - let tx_locktime = self.platform_coin.p2sh_tx_locktime(time_lock).await?; + let tx_locktime = self.platform_coin.p2sh_tx_locktime(time_lock).await.map_mm_err()?; let script_data = ScriptBuilder::default().push_opcode(Opcode::OP_1).into_script(); let tx = self .spend_p2sh( @@ -572,7 +576,8 @@ impl SlpToken { redeem_script, htlc_keypair, ) - .await?; + .await + .map_mm_err()?; Ok(tx) } @@ -613,14 +618,15 @@ impl SlpToken { slp_amount, }; - let tx_locktime = self.platform_coin.p2sh_tx_locktime(time_lock).await?; + let tx_locktime = self.platform_coin.p2sh_tx_locktime(time_lock).await.map_mm_err()?; let script_data = ScriptBuilder::default() .push_data(secret) .push_opcode(Opcode::OP_0) .into_script(); let tx = self .spend_p2sh(slp_utxo, tx_locktime, SEQUENCE_FINAL, script_data, redeem, keypair) - .await?; + .await + .map_mm_err()?; Ok(tx) } @@ -637,7 +643,7 @@ impl SlpToken { let mut outputs = Vec::with_capacity(3); outputs.push(op_return_out_mm); - let my_public_key = self.platform_coin.my_public_key()?; + let my_public_key = self.platform_coin.my_public_key().map_mm_err()?; let my_script_pubkey = ScriptBuilder::build_p2pkh(&my_public_key.address_hash().into()); let slp_output = TransactionOutput { value: self.platform_dust(), @@ -645,19 +651,25 @@ impl SlpToken { }; outputs.push(slp_output); - let (_, bch_inputs, _recently_spent) = self.slp_unspents_for_spend().await?; + let (_, bch_inputs, _recently_spent) = self.slp_unspents_for_spend().await.map_mm_err()?; let (mut unsigned, _) = UtxoTxBuilder::new(&self.platform_coin) .await .add_required_inputs(std::iter::once(p2sh_utxo.bch_unspent)) .add_available_inputs(bch_inputs) .add_outputs(outputs) .build() - .await?; + .await + .map_mm_err()?; unsigned.lock_time = tx_locktime; unsigned.inputs[0].sequence = input_sequence; - let my_key_pair = self.platform_coin.as_ref().priv_key_policy.activated_key_or_err()?; + let my_key_pair = self + .platform_coin + .as_ref() + .priv_key_policy + .activated_key_or_err() + .map_mm_err()?; let signed_p2sh_input = p2sh_spend( &unsigned, 0, @@ -666,7 +678,8 @@ impl SlpToken { redeem_script, self.platform_coin.as_ref().conf.signature_version, self.platform_coin.as_ref().conf.fork_id, - )?; + ) + .map_mm_err()?; let signed_inputs: Result, _> = unsigned .inputs @@ -684,7 +697,7 @@ impl SlpToken { }) .collect(); - let mut signed_inputs = signed_inputs?; + let mut signed_inputs = signed_inputs.map_mm_err()?; signed_inputs.insert(0, signed_p2sh_input); @@ -715,7 +728,8 @@ impl SlpToken { .rpc() .send_raw_transaction(serialize(&signed).into()) .compat() - .await?; + .await + .map_mm_err()?; Ok(signed) } @@ -730,7 +744,7 @@ impl SlpToken { return MmError::err(ValidateDexFeeError::TxLackOfOutputs); } - let slp_tx: SlpTxDetails = parse_slp_script(tx.outputs[0].script_pubkey.as_slice())?; + let slp_tx: SlpTxDetails = parse_slp_script(tx.outputs[0].script_pubkey.as_slice()).map_mm_err()?; match slp_tx.transaction { SlpTransaction::Send { token_id, amounts } => { @@ -742,7 +756,7 @@ impl SlpToken { return MmError::err(ValidateDexFeeError::InvalidSlpDetails); } - let expected = sat_from_big_decimal(&amount, self.decimals())?; + let expected = sat_from_big_decimal(&amount, self.decimals()).map_mm_err()?; if amounts[0] != expected { return MmError::err(ValidateDexFeeError::InvalidSlpDetails); @@ -1066,7 +1080,12 @@ impl UtxoTxBroadcastOps for SlpToken { .await .mm_err(|e| BroadcastTxErr::Other(e.to_string()))?; - let hash = self.rpc().send_raw_transaction(tx_bytes.into()).compat().await?; + let hash = self + .rpc() + .send_raw_transaction(tx_bytes.into()) + .compat() + .await + .map_mm_err()?; Ok(hash) } @@ -1140,7 +1159,7 @@ impl MarketCoinOps for SlpToken { fn my_balance(&self) -> BalanceFut { let coin = self.clone(); - let fut = async move { Ok(coin.my_coin_balance().await?) }; + let fut = async move { coin.my_coin_balance().await.map_mm_err() }; Box::new(fut.boxed().compat()) } @@ -1493,7 +1512,12 @@ impl MmCoin for SlpToken { )); } - let key_pair = coin.platform_coin.as_ref().priv_key_policy.activated_key_or_err()?; + let key_pair = coin + .platform_coin + .as_ref() + .priv_key_policy + .activated_key_or_err() + .map_mm_err()?; let address = CashAddress::decode(&req.to).map_to_mm(WithdrawError::InvalidAddress)?; if address.prefix != *coin.slp_prefix() { @@ -1504,9 +1528,9 @@ impl MmCoin for SlpToken { ))); }; let amount = if req.max { - coin.my_balance_sat().await? + coin.my_balance_sat().await.map_mm_err()? } else { - sat_from_big_decimal(&req.amount, coin.decimals())? + sat_from_big_decimal(&req.amount, coin.decimals()).map_mm_err()? }; let address_hash = address.hash.clone(); @@ -1530,7 +1554,7 @@ impl MmCoin for SlpToken { }, }; let slp_output = SlpOutput { amount, script_pubkey }; - let (slp_preimage, _) = coin.generate_slp_tx_preimage(vec![slp_output]).await?; + let (slp_preimage, _) = coin.generate_slp_tx_preimage(vec![slp_output]).await.map_mm_err()?; let mut tx_builder = UtxoTxBuilder::new(&coin.platform_coin) .await .add_required_inputs(slp_preimage.slp_inputs.into_iter().map(|slp| slp.bch_unspent)) @@ -1540,11 +1564,11 @@ impl MmCoin for SlpToken { let platform_decimals = coin.platform_decimals(); match req.fee { Some(WithdrawFee::UtxoFixed { amount }) => { - let fixed = sat_from_big_decimal(&amount, platform_decimals)?; + let fixed = sat_from_big_decimal(&amount, platform_decimals).map_mm_err()?; tx_builder = tx_builder.with_fee(ActualFeeRate::FixedPerKb(fixed)) }, Some(WithdrawFee::UtxoPerKbyte { amount }) => { - let dynamic = sat_from_big_decimal(&amount, platform_decimals)?; + let dynamic = sat_from_big_decimal(&amount, platform_decimals).map_mm_err()?; tx_builder = tx_builder.with_fee(ActualFeeRate::Dynamic(dynamic)); }, Some(fee_policy) => { @@ -1566,12 +1590,13 @@ impl MmCoin for SlpToken { key_pair, coin.platform_conf().signature_version, coin.platform_conf().fork_id, - )?; + ) + .map_mm_err()?; let fee_details = SlpFeeDetails { amount: big_decimal_from_sat_unsigned(tx_data.fee_amount, coin.platform_decimals()), coin: coin.platform_coin.ticker().into(), }; - let my_address_string = coin.my_address()?; + let my_address_string = coin.my_address().map_mm_err()?; let to_address = address.encode().map_to_mm(WithdrawError::InternalError)?; let total_amount = big_decimal_from_sat_unsigned(amount, coin.decimals()); @@ -1660,7 +1685,7 @@ impl MmCoin for SlpToken { ) -> TradePreimageResult { let slp_amount = match value { TradePreimageValue::Exact(decimal) | TradePreimageValue::UpperBound(decimal) => { - sat_from_big_decimal(&decimal, self.decimals())? + sat_from_big_decimal(&decimal, self.decimals()).map_mm_err()? }, }; // can use dummy P2SH script_pubkey here @@ -1669,7 +1694,7 @@ impl MmCoin for SlpToken { amount: slp_amount, script_pubkey, }; - let (preimage, _) = self.generate_slp_tx_preimage(vec![slp_out]).await?; + let (preimage, _) = self.generate_slp_tx_preimage(vec![slp_out]).await.map_mm_err()?; let fee = utxo_common::preimage_trade_fee_required_to_send_outputs( &self.platform_coin, self.platform_ticker(), @@ -1693,7 +1718,8 @@ impl MmCoin for SlpToken { let htlc_fee = coin .platform_coin .get_htlc_spend_fee(SLP_HTLC_SPEND_SIZE, &FeeApproxStage::WithoutApprox) - .await?; + .await + .map_mm_err()?; let amount = (big_decimal_from_sat_unsigned(htlc_fee, coin.platform_decimals()) + coin.platform_dust_dec()).into(); Ok(TradeFee { @@ -1711,14 +1737,14 @@ impl MmCoin for SlpToken { dex_fee_amount: DexFee, stage: FeeApproxStage, ) -> TradePreimageResult { - let slp_amount = sat_from_big_decimal(&dex_fee_amount.fee_amount().into(), self.decimals())?; + let slp_amount = sat_from_big_decimal(&dex_fee_amount.fee_amount().into(), self.decimals()).map_mm_err()?; // can use dummy P2PKH script_pubkey here let script_pubkey = ScriptBuilder::build_p2pkh(&H160::default().into()).into(); let slp_out = SlpOutput { amount: slp_amount, script_pubkey, }; - let (preimage, _) = self.generate_slp_tx_preimage(vec![slp_out]).await?; + let (preimage, _) = self.generate_slp_tx_preimage(vec![slp_out]).await.map_mm_err()?; let fee = utxo_common::preimage_trade_fee_required_to_send_outputs( &self.platform_coin, self.platform_ticker(), @@ -1787,7 +1813,7 @@ impl CoinWithTxHistoryV2 for SlpToken { MyTxHistoryTarget::Iguana => (), target => return MmError::err(MyTxHistoryErrorV2::with_expected_target(target, "Iguana")), } - let my_address = self.my_address()?; + let my_address = self.my_address().map_mm_err()?; Ok(GetTxHistoryFilters::for_address(my_address).with_token_id(self.token_id().to_string())) } } diff --git a/mm2src/coins/utxo/utxo_builder/utxo_coin_builder.rs b/mm2src/coins/utxo/utxo_builder/utxo_coin_builder.rs index 03ccd6fd8b..3c26f99c7d 100644 --- a/mm2src/coins/utxo/utxo_builder/utxo_coin_builder.rs +++ b/mm2src/coins/utxo/utxo_builder/utxo_coin_builder.rs @@ -141,7 +141,9 @@ pub trait UtxoFieldsWithIguanaSecretBuilder: UtxoCoinBuilderCommonOps { &self, priv_key: IguanaPrivKey, ) -> UtxoCoinBuildResult { - let conf = UtxoConfBuilder::new(self.conf(), self.activation_params(), self.ticker()).build()?; + let conf = UtxoConfBuilder::new(self.conf(), self.activation_params(), self.ticker()) + .build() + .map_mm_err()?; let private = Private { prefix: conf.wif_prefix, secret: priv_key, @@ -171,13 +173,16 @@ pub trait UtxoFieldsWithGlobalHDBuilder: UtxoCoinBuilderCommonOps { &self, global_hd_ctx: GlobalHDAccountArc, ) -> UtxoCoinBuildResult { - let conf = UtxoConfBuilder::new(self.conf(), self.activation_params(), self.ticker()).build()?; + let conf = UtxoConfBuilder::new(self.conf(), self.activation_params(), self.ticker()) + .build() + .map_mm_err()?; let path_to_address = self.activation_params().path_to_address; let path_to_coin = conf .derivation_path .as_ref() - .or_mm_err(|| UtxoConfError::DerivationPathIsNotSet)?; + .or_mm_err(|| UtxoConfError::DerivationPathIsNotSet) + .map_mm_err()?; let secret = global_hd_ctx .derive_secp256k1_secret( &path_to_address @@ -202,7 +207,9 @@ pub trait UtxoFieldsWithGlobalHDBuilder: UtxoCoinBuilderCommonOps { let address_format = self.address_format()?; let hd_wallet_rmd160 = *self.ctx().rmd160(); let hd_wallet_storage = - HDWalletCoinStorage::init_with_rmd160(self.ctx(), self.ticker().to_owned(), hd_wallet_rmd160).await?; + HDWalletCoinStorage::init_with_rmd160(self.ctx(), self.ticker().to_owned(), hd_wallet_rmd160) + .await + .map_mm_err()?; let accounts = load_hd_accounts_from_storage(&hd_wallet_storage, path_to_coin) .await .mm_err(UtxoCoinBuildError::from)?; @@ -234,7 +241,7 @@ async fn build_utxo_coin_fields_with_conf_and_policy( where Builder: UtxoCoinBuilderCommonOps + Sync + ?Sized, { - let key_pair = priv_key_policy.activated_key_or_err()?; + let key_pair = priv_key_policy.activated_key_or_err().map_mm_err()?; let addr_format = builder.address_format()?; let my_address = AddressBuilder::new( addr_format, @@ -290,7 +297,9 @@ where pub trait UtxoFieldsWithHardwareWalletBuilder: UtxoCoinBuilderCommonOps { async fn build_utxo_fields_with_trezor(&self) -> UtxoCoinBuildResult { let ticker = self.ticker().to_owned(); - let conf = UtxoConfBuilder::new(self.conf(), self.activation_params(), &ticker).build()?; + let conf = UtxoConfBuilder::new(self.conf(), self.activation_params(), &ticker) + .build() + .map_mm_err()?; if !self.supports_trezor(&conf) { return MmError::err(UtxoCoinBuildError::CoinDoesntSupportTrezor); @@ -301,9 +310,10 @@ pub trait UtxoFieldsWithHardwareWalletBuilder: UtxoCoinBuilderCommonOps { let path_to_coin = conf .derivation_path .clone() - .or_mm_err(|| UtxoConfError::DerivationPathIsNotSet)?; + .or_mm_err(|| UtxoConfError::DerivationPathIsNotSet) + .map_mm_err()?; - let hd_wallet_storage = HDWalletCoinStorage::init(self.ctx(), ticker).await?; + let hd_wallet_storage = HDWalletCoinStorage::init(self.ctx(), ticker).await.map_mm_err()?; let accounts = load_hd_accounts_from_storage(&hd_wallet_storage, &path_to_coin) .await @@ -370,7 +380,7 @@ pub trait UtxoFieldsWithHardwareWalletBuilder: UtxoCoinBuilderCommonOps { fn supports_trezor(&self, conf: &UtxoCoinConf) -> bool { conf.trezor_coin.is_some() } fn trezor_wallet_rmd160(&self) -> UtxoCoinBuildResult { - let crypto_ctx = CryptoCtx::from_ctx(self.ctx())?; + let crypto_ctx = CryptoCtx::from_ctx(self.ctx()).map_mm_err()?; let hw_ctx = crypto_ctx .hw_ctx() .or_mm_err(|| UtxoCoinBuildError::HwContextNotInitialized)?; @@ -380,7 +390,7 @@ pub trait UtxoFieldsWithHardwareWalletBuilder: UtxoCoinBuilderCommonOps { } fn check_if_trezor_is_initialized(&self) -> UtxoCoinBuildResult<()> { - let crypto_ctx = CryptoCtx::from_ctx(self.ctx())?; + let crypto_ctx = CryptoCtx::from_ctx(self.ctx()).map_mm_err()?; let hw_ctx = crypto_ctx .hw_ctx() .or_mm_err(|| UtxoCoinBuildError::HwContextNotInitialized)?; @@ -403,7 +413,8 @@ pub trait UtxoCoinBuilderCommonOps { fn address_format(&self) -> UtxoCoinBuildResult { let format_from_req = self.activation_params().address_format.clone(); let format_from_conf = json::from_value::>(self.conf()["address_format"].clone()) - .map_to_mm(|e| UtxoConfError::InvalidAddressFormat(e.to_string()))? + .map_to_mm(|e| UtxoConfError::InvalidAddressFormat(e.to_string())) + .map_mm_err()? .unwrap_or(UtxoAddressFormat::Standard); let mut address_format = match format_from_req { @@ -625,7 +636,8 @@ pub trait UtxoCoinBuilderCommonOps { None => { let name = conf["name"] .as_str() - .or_mm_err(|| UtxoConfError::CurrencyNameIsNotSet)?; + .or_mm_err(|| UtxoConfError::CurrencyNameIsNotSet) + .map_mm_err()?; (name, false) }, } diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 73f7043784..701cf58db0 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -142,7 +142,9 @@ pub async fn produce_hd_address_scanner(coin: &T) -> BalanceResult, { - Ok(UtxoAddressScanner::init(coin.as_ref().rpc_client.clone()).await?) + UtxoAddressScanner::init(coin.as_ref().rpc_client.clone()) + .await + .map_mm_err() } pub async fn scan_for_new_addresses( @@ -214,7 +216,7 @@ where T: UtxoCommonOps + GetUtxoListOps + MarketCoinOps, { if coin.as_ref().check_utxo_maturity { - let (unspents, _) = coin.get_mature_unspent_ordered_list(address).await?; + let (unspents, _) = coin.get_mature_unspent_ordered_list(address).await.map_mm_err()?; return Ok(unspents.to_coin_balance(coin.as_ref().decimals)); } @@ -238,7 +240,10 @@ where T: UtxoCommonOps + GetUtxoMapOps + MarketCoinOps, { if coin.as_ref().check_utxo_maturity { - let (unspents_map, _) = coin.get_mature_unspent_ordered_map(addresses.clone()).await?; + let (unspents_map, _) = coin + .get_mature_unspent_ordered_map(addresses.clone()) + .await + .map_mm_err()?; addresses .into_iter() .map(|address| { @@ -256,7 +261,8 @@ where .rpc_client .display_balances(addresses.clone(), coin.as_ref().decimals) .compat() - .await? + .await + .map_mm_err()? .into_iter() .map(|(address, spendable)| { let unspendable = BigDecimal::from(0); @@ -283,7 +289,8 @@ pub async fn get_htlc_spend_fee( }, ActualFeeRate::FixedPerKb(_) => fee_rate, }; - let min_relay_fee_rate = get_min_relay_rate(coin).await?; + + let min_relay_fee_rate = get_min_relay_rate(coin).await.map_mm_err()?; Ok(get_tx_fee_with_relay_fee(&fee_rate, tx_size, min_relay_fee_rate)) } @@ -376,7 +383,7 @@ pub fn my_public_key(coin: &UtxoCoinFields) -> Result<&Public, MmError(coin: &T, address: &str) -> MmResult { let addr = address_from_str_unchecked(coin.as_ref(), address)?; - check_withdraw_address_supported(coin, &addr)?; + check_withdraw_address_supported(coin, &addr).map_mm_err()?; Ok(addr) } @@ -699,7 +706,7 @@ impl<'a, T: AsRef + UtxoTxGenerationOps> UtxoTxBuilder<'a, T> { let actual_fee_rate = match self.fee { Some(fee) => fee, - None => coin.get_fee_rate().await?, + None => coin.get_fee_rate().await.map_mm_err()?, }; return_err_if!(self.outputs.is_empty(), GenerateTxError::EmptyOutputs); @@ -713,14 +720,14 @@ impl<'a, T: AsRef + UtxoTxGenerationOps> UtxoTxBuilder<'a, T> { } ); - self.min_relay_fee_rate = get_min_relay_rate(coin).await?; + self.min_relay_fee_rate = get_min_relay_rate(coin).await.map_mm_err()?; let mut one_time_fee_update = false; loop { let required_amount_0 = self.required_amount(); self.sum_inputs = self.add_tx_inputs(required_amount_0); self.sum_outputs = self.add_tx_outputs(); - self.interest = coin.calc_interest_if_required(&mut self.tx).await?; + self.interest = coin.calc_interest_if_required(&mut self.tx).await.map_mm_err()?; // try once tx_fee without the change output (if maybe txfee fits between total inputs and outputs) if !one_time_fee_update { @@ -842,7 +849,7 @@ pub fn is_kmd(coin: &T) -> bool { &coin.as_ref().conf.ticker = async fn get_min_relay_rate + UtxoTxGenerationOps>(coin: &T) -> UtxoRpcResult> { if coin.as_ref().conf.force_min_relay_fee { let fee_dec = coin.as_ref().rpc_client.get_relay_fee().compat().await?; - let min_relay_fee_rate = sat_from_big_decimal(&fee_dec, coin.as_ref().decimals)?; + let min_relay_fee_rate = sat_from_big_decimal(&fee_dec, coin.as_ref().decimals).map_mm_err()?; Ok(Some(min_relay_fee_rate)) } else { Ok(None) @@ -1016,10 +1023,10 @@ async fn gen_taker_funding_spend_preimage( .value; let fee = match fee { - FundingSpendFeeSetting::GetFromCoin => { - coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE, &FeeApproxStage::WithoutApprox) - .await? - }, + FundingSpendFeeSetting::GetFromCoin => coin + .get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE, &FeeApproxStage::WithoutApprox) + .await + .map_mm_err()?, FundingSpendFeeSetting::UseExact(f) => f, }; @@ -1075,7 +1082,8 @@ pub async fn gen_and_sign_taker_funding_spend_preimage( coin.as_ref().conf.signature_version, SIGHASH_ALL, coin.as_ref().conf.fork_id, - )?; + ) + .map_mm_err()?; Ok(TxPreimageWithSig { preimage: preimage.into(), signature: signature.take().into(), @@ -1110,7 +1118,8 @@ pub async fn validate_taker_funding_spend_preimage( let expected_fee = coin .get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE, &FeeApproxStage::WithoutApprox) - .await?; + .await + .map_mm_err()?; let actual_fee = funding_amount - payment_amount; @@ -1129,7 +1138,8 @@ pub async fn validate_taker_funding_spend_preimage( NTimeSetting::UseValue(preimage.preimage.n_time), FundingSpendFeeSetting::UseExact(actual_fee), ) - .await?; + .await + .map_mm_err()?; let funding_time_lock = gen_args .funding_time_lock @@ -1148,7 +1158,8 @@ pub async fn validate_taker_funding_spend_preimage( coin.as_ref().conf.signature_version, SIGHASH_ALL, coin.as_ref().conf.fork_id, - )?; + ) + .map_mm_err()?; if !gen_args .maker_pub @@ -1263,7 +1274,8 @@ async fn gen_taker_payment_spend_preimage( })?; let tx_fee = coin .get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE, &FeeApproxStage::WithoutApprox) - .await?; + .await + .map_mm_err()?; let dex_fee_value = if matches!(args.dex_fee, &DexFee::WithBurn { .. }) { outputs[0].value + outputs[1].value } else { @@ -1359,7 +1371,8 @@ pub async fn gen_and_sign_taker_payment_spend_preimage( // Here, we have to use the exact lock time from the preimage because maker // can get different values (e.g. if MTP advances during preimage exchange/fee rate changes) let expected_preimage = - gen_taker_payment_spend_preimage(coin, gen_args, NTimeSetting::UseValue(preimage.preimage.n_time)).await?; + gen_taker_payment_spend_preimage(coin, gen_args, NTimeSetting::UseValue(preimage.preimage.n_time)) + .await + .map_mm_err()?; let time_lock = gen_args .time_lock @@ -1401,7 +1416,8 @@ pub async fn validate_taker_payment_spend_preimage( coin.as_ref().conf.signature_version, sig_hash_type, coin.as_ref().conf.fork_id, - )?; + ) + .map_mm_err()?; if !gen_args .taker_pub @@ -2335,7 +2351,7 @@ fn validate_dex_output( dex_address: &Address, fee_amount: &MmNumber, ) -> MmResult<(), ValidatePaymentError> { - let fee_amount_u64 = sat_from_big_decimal(&fee_amount.to_decimal(), coin.as_ref().decimals)?; + let fee_amount_u64 = sat_from_big_decimal(&fee_amount.to_decimal(), coin.as_ref().decimals).map_mm_err()?; match tx.outputs.get(output_index) { Some(out) => { let expected_script_pubkey = Builder::build_p2pkh(dex_address.hash()).to_bytes(); @@ -2370,7 +2386,7 @@ fn validate_burn_output( burn_script_pubkey: &Script, burn_amount: &MmNumber, ) -> MmResult<(), ValidatePaymentError> { - let burn_amount_u64 = sat_from_big_decimal(&burn_amount.to_decimal(), coin.as_ref().decimals)?; + let burn_amount_u64 = sat_from_big_decimal(&burn_amount.to_decimal(), coin.as_ref().decimals).map_mm_err()?; match tx.outputs.get(output_index) { Some(out) => { if out.script_pubkey != burn_script_pubkey.to_bytes() { @@ -2426,7 +2442,8 @@ pub fn validate_fee( .rpc_client .get_verbose_transaction(&tx.hash().reversed().into()) .compat() - .await?; + .await + .map_mm_err()?; let tx_confirmed_before_block = is_tx_confirmed_before_block(&coin, &tx_from_rpc, min_block_number) .await @@ -2625,7 +2642,12 @@ pub fn validate_payment_spend_or_refund( let coin = coin.clone(); let fut = async move { - let my_address = coin.as_ref().derivation_method.single_addr_or_err().await?; + let my_address = coin + .as_ref() + .derivation_method + .single_addr_or_err() + .await + .map_mm_err()?; let expected_script_pubkey = output_script(&my_address).map(|script| script.to_bytes())?; let output = payment_spend_tx .outputs @@ -2896,13 +2918,15 @@ pub fn sign_message( let message_hash = sign_message_hash(coin, message).ok_or(SignatureError::PrefixNotFound)?; let private = if let Some(account) = account { - let path_to_coin = coin.priv_key_policy.path_to_coin_or_err()?; + let path_to_coin = coin.priv_key_policy.path_to_coin_or_err().map_mm_err()?; let derivation_path = account .valid_derivation_path(path_to_coin) - .mm_err(|err| SignatureError::InvalidRequest(err.to_string()))?; + .mm_err(|err| SignatureError::InvalidRequest(err.to_string())) + .map_mm_err()?; let privkey = coin .priv_key_policy - .hd_wallet_derived_priv_key_or_err(&derivation_path)?; + .hd_wallet_derived_priv_key_or_err(&derivation_path) + .map_mm_err()?; Private { prefix: coin.conf.wif_prefix, secret: privkey, @@ -2910,10 +2934,10 @@ pub fn sign_message( checksum_type: coin.conf.checksum_type, } } else { - *coin.priv_key_policy.activated_key_or_err()?.private() + *coin.priv_key_policy.activated_key_or_err().map_mm_err()?.private() }; - let signature = private.sign_compact(&H256::from(message_hash))?; + Ok(STANDARD.encode(&*signature)) } @@ -2927,7 +2951,7 @@ pub fn verify_message( let signature = CompactSignature::try_from(STANDARD.decode(signature_base64)?) .map_to_mm(|err| VerificationError::SignatureDecodingError(err.to_string()))?; let recovered_pubkey = Public::recover_compact(&H256::from(message_hash), &signature)?; - let received_address = checked_address_from_str(coin, address)?; + let received_address = checked_address_from_str(coin, address).map_mm_err()?; Ok(AddressHashEnum::from(recovered_pubkey.address_hash()) == *received_address.hash()) } @@ -4038,7 +4062,7 @@ where } // Todo: https://github.com/KomodoPlatform/komodo-defi-framework/issues/1625 - let my_address = &coin.my_address()?; + let my_address = &coin.my_address().map_mm_err()?; let claimed_by_me = tx_details.from.iter().all(|from| from == my_address) && tx_details.to.contains(my_address); tx_details.kmd_rewards = Some(KmdRewardsDetails { @@ -4126,10 +4150,15 @@ where T: UtxoCommonOps + GetUtxoListOps, { let decimals = coin.as_ref().decimals; - let fee_rate = coin.get_fee_rate().await?; + let fee_rate = coin.get_fee_rate().await.map_mm_err()?; // [`FeePolicy::DeductFromOutput`] is used if the value is [`TradePreimageValue::UpperBound`] only let is_amount_upper_bound = matches!(fee_policy, FeePolicy::DeductFromOutput(_)); - let my_address = coin.as_ref().derivation_method.single_addr_or_err().await?; + let my_address = coin + .as_ref() + .derivation_method + .single_addr_or_err() + .await + .map_mm_err()?; match fee_rate { // if it's a dynamic fee, we should generate a swap transaction to get an actual trade fee @@ -4138,7 +4167,7 @@ where let dynamic_fee_rate = coin.increase_dynamic_fee_by_stage(fee_rate, stage); let outputs_count = outputs.len(); - let (unspents, _recently_sent_txs) = coin.get_unspent_ordered_list(&my_address).await?; + let (unspents, _recently_sent_txs) = coin.get_unspent_ordered_list(&my_address).await.map_mm_err()?; let actual_fee_rate = ActualFeeRate::Dynamic(dynamic_fee_rate); let mut tx_builder = UtxoTxBuilder::new(coin) @@ -4167,7 +4196,7 @@ where }, ActualFeeRate::FixedPerKb(_fee) => { let outputs_count = outputs.len(); - let (unspents, _recently_sent_txs) = coin.get_unspent_ordered_list(&my_address).await?; + let (unspents, _recently_sent_txs) = coin.get_unspent_ordered_list(&my_address).await.map_mm_err()?; let mut tx_builder = UtxoTxBuilder::new(coin) .await .add_available_inputs(unspents) @@ -4246,7 +4275,9 @@ where /// The fee to spend (receive) other payment is deducted from the trading amount so we should display it pub fn get_receiver_trade_fee(coin: T) -> TradePreimageFut { let fut = async move { - let amount_sat = get_htlc_spend_fee(&coin, DEFAULT_SWAP_TX_SPEND_SIZE, &FeeApproxStage::WithoutApprox).await?; + let amount_sat = get_htlc_spend_fee(&coin, DEFAULT_SWAP_TX_SPEND_SIZE, &FeeApproxStage::WithoutApprox) + .await + .map_mm_err()?; let amount = big_decimal_from_sat_unsigned(amount_sat, coin.as_ref().decimals).into(); Ok(TradeFee { coin: coin.as_ref().conf.ticker.clone(), @@ -4560,7 +4591,7 @@ pub async fn validate_payment<'a, T: UtxoCommonOps>( try_spv_proof_until: u64, confirmations: u64, ) -> ValidatePaymentResult<()> { - let amount = sat_from_big_decimal(&amount, coin.as_ref().decimals)?; + let amount = sat_from_big_decimal(&amount, coin.as_ref().decimals).map_mm_err()?; let expected_redeem = tx_type_with_secret_hash.redeem_script(time_lock, first_pub0, second_pub0); let tx_hash = tx.tx_hash_as_bytes(); @@ -4606,7 +4637,7 @@ pub async fn validate_payment<'a, T: UtxoCommonOps>( } if let Some(watcher_reward) = watcher_reward { - let expected_reward = sat_from_big_decimal(&watcher_reward.amount, coin.as_ref().decimals)?; + let expected_reward = sat_from_big_decimal(&watcher_reward.amount, coin.as_ref().decimals).map_mm_err()?; let actual_reward = actual_output.value - amount; validate_watcher_reward(expected_reward, actual_reward, false)?; } else if actual_output.value != amount { @@ -5174,7 +5205,7 @@ where let total_expected_amount = &args.dex_fee.total_spend_amount().to_decimal() + &args.premium_amount + &args.trading_amount; - let expected_amount_sat = sat_from_big_decimal(&total_expected_amount, coin.as_ref().decimals)?; + let expected_amount_sat = sat_from_big_decimal(&total_expected_amount, coin.as_ref().decimals).map_mm_err()?; let time_lock = args .funding_time_lock @@ -5205,7 +5236,8 @@ where .rpc_client .get_transaction_bytes(&args.funding_tx.hash().reversed().into()) .compat() - .await?; + .await + .map_mm_err()?; let actual_tx_bytes = serialize(args.funding_tx).take(); if tx_bytes_from_rpc.0 != actual_tx_bytes { return MmError::err(ValidateSwapV2TxError::TxBytesMismatch { diff --git a/mm2src/coins/utxo/utxo_common/utxo_tx_history_v2_common.rs b/mm2src/coins/utxo/utxo_common/utxo_tx_history_v2_common.rs index 01f9750b03..c677e5f513 100644 --- a/mm2src/coins/utxo/utxo_common/utxo_tx_history_v2_common.rs +++ b/mm2src/coins/utxo/utxo_common/utxo_tx_history_v2_common.rs @@ -39,7 +39,7 @@ where { match (coin.derivation_method(), target) { (DerivationMethod::SingleAddress(_), MyTxHistoryTarget::Iguana) => { - let my_address = coin.my_address()?; + let my_address = coin.my_address().map_mm_err()?; Ok(GetTxHistoryFilters::for_address(my_address)) }, (DerivationMethod::SingleAddress(_), target) => { @@ -73,8 +73,14 @@ where .await .or_mm_err(|| MyTxHistoryErrorV2::InvalidTarget(format!("No such account_id={account_id}")))?; - let external_addresses = coin.derive_known_addresses(&hd_account, Bip44Chain::External).await?; - let internal_addresses = coin.derive_known_addresses(&hd_account, Bip44Chain::Internal).await?; + let external_addresses = coin + .derive_known_addresses(&hd_account, Bip44Chain::External) + .await + .map_mm_err()?; + let internal_addresses = coin + .derive_known_addresses(&hd_account, Bip44Chain::Internal) + .await + .map_mm_err()?; let addresses_iter = external_addresses .into_iter() @@ -98,7 +104,9 @@ where .await .or_mm_err(|| MyTxHistoryErrorV2::InvalidTarget(format!("No such account_id={}", hd_address_id.account_id)))?; - let is_address_activated = hd_account.is_address_activated(hd_address_id.chain, hd_address_id.address_id)?; + let is_address_activated = hd_account + .is_address_activated(hd_address_id.chain, hd_address_id.address_id) + .map_mm_err()?; if !is_address_activated { let error = format!( "'{:?}:{}' address is not activated", @@ -109,7 +117,8 @@ where let hd_address = coin .derive_address(&hd_account, hd_address_id.chain, hd_address_id.address_id) - .await?; + .await + .map_mm_err()?; Ok(GetTxHistoryFilters::for_address(hd_address.address().display_address())) } @@ -130,7 +139,8 @@ where .rpc_client .get_verbose_transaction(params.hash) .compat() - .await?; + .await + .map_mm_err()?; let tx: UtxoTx = deserialize(verbose_tx.hex.as_slice())?; let mut tx_builder = TxDetailsBuilder::new( @@ -227,11 +237,24 @@ where { let tx_hash_str = format!("{:02x}", tx_hash); let wallet_id = coin.history_wallet_id(); - let tx_bytes = match storage.tx_bytes_from_cache(&wallet_id, &tx_hash_str).await? { + let tx_bytes = match storage + .tx_bytes_from_cache(&wallet_id, &tx_hash_str) + .await + .map_mm_err()? + { Some(tx_bytes) => tx_bytes, None => { - let tx_bytes = coin.as_ref().rpc_client.get_transaction_bytes(tx_hash).compat().await?; - storage.add_tx_to_cache(&wallet_id, &tx_hash_str, &tx_bytes).await?; + let tx_bytes = coin + .as_ref() + .rpc_client + .get_transaction_bytes(tx_hash) + .compat() + .await + .map_mm_err()?; + storage + .add_tx_to_cache(&wallet_id, &tx_hash_str, &tx_bytes) + .await + .map_mm_err()?; tx_bytes }, }; diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index 49e4ea9d60..6297509289 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -813,7 +813,8 @@ impl TakerCoinSwapOpsV2 for UtxoStandardCoin { wait_until, 10., ) - .await?; + .await + .map_mm_err()?; Ok(res) } @@ -1287,7 +1288,7 @@ impl CoinWithTxHistoryV2 for UtxoStandardCoin { #[async_trait] impl UtxoTxHistoryOps for UtxoStandardCoin { async fn my_addresses(&self) -> MmResult, UtxoMyAddressesHistoryError> { - let addresses = self.all_addresses().await?; + let addresses = self.all_addresses().await.map_mm_err()?; Ok(addresses) } diff --git a/mm2src/coins/utxo/utxo_withdraw.rs b/mm2src/coins/utxo/utxo_withdraw.rs index 8dd491babe..9c8953cf3d 100644 --- a/mm2src/coins/utxo/utxo_withdraw.rs +++ b/mm2src/coins/utxo/utxo_withdraw.rs @@ -101,7 +101,8 @@ where let secret = coin .as_ref() .priv_key_policy - .hd_wallet_derived_priv_key_or_err(derivation_path)?; + .hd_wallet_derived_priv_key_or_err(derivation_path) + .map_mm_err()?; let private = Private { prefix: coin.as_ref().conf.wif_prefix, @@ -150,7 +151,7 @@ where let decimals = coin.as_ref().decimals; let req = self.request(); - let to = coin.address_from_str(&req.to)?; + let to = coin.address_from_str(&req.to).map_mm_err()?; // Generate unsigned transaction. self.on_generating_transaction()?; @@ -158,14 +159,17 @@ where let script_pubkey = output_script(&to).map(|script| script.to_bytes())?; let _utxo_lock = UTXO_LOCK.lock().await; - let (unspents, _) = coin.get_unspent_ordered_list(&self.sender_address()).await?; + let (unspents, _) = coin + .get_unspent_ordered_list(&self.sender_address()) + .await + .map_mm_err()?; let (value, fee_policy) = if req.max { ( unspents.iter().fold(0, |sum, unspent| sum + unspent.value), FeePolicy::DeductFromOutput(0), ) } else { - let value = sat_from_big_decimal(&req.amount, decimals)?; + let value = sat_from_big_decimal(&req.amount, decimals).map_mm_err()?; (value, FeePolicy::SendExact) }; let outputs = vec![TransactionOutput { value, script_pubkey }]; @@ -179,11 +183,11 @@ where match req.fee { Some(WithdrawFee::UtxoFixed { ref amount }) => { - let fixed = sat_from_big_decimal(amount, decimals)?; + let fixed = sat_from_big_decimal(amount, decimals).map_mm_err()?; tx_builder = tx_builder.with_fee(ActualFeeRate::FixedPerKb(fixed)); }, Some(WithdrawFee::UtxoPerKbyte { ref amount }) => { - let dynamic_fee_rate = sat_from_big_decimal(amount, decimals)?; + let dynamic_fee_rate = sat_from_big_decimal(amount, decimals).map_mm_err()?; tx_builder = tx_builder.with_fee(ActualFeeRate::Dynamic(dynamic_fee_rate)); }, Some(ref fee_policy) => { @@ -274,20 +278,21 @@ where amount_display, self.req.coin, self.from_address_string, self.req.to, ); - Ok(self - .task_handle - .update_in_progress_status(WithdrawInProgressStatus::GeneratingTransaction)?) + self.task_handle + .update_in_progress_status(WithdrawInProgressStatus::GeneratingTransaction) + .map_mm_err() } fn on_finishing(&self) -> Result<(), MmError> { - Ok(self - .task_handle - .update_in_progress_status(WithdrawInProgressStatus::Finishing)?) + self.task_handle + .update_in_progress_status(WithdrawInProgressStatus::Finishing) + .map_mm_err() } async fn sign_tx(&self, unsigned_tx: TransactionInputSigner) -> Result> { self.task_handle - .update_in_progress_status(WithdrawInProgressStatus::SigningTransaction)?; + .update_in_progress_status(WithdrawInProgressStatus::SigningTransaction) + .map_mm_err()?; let mut sign_params = UtxoSignTxParamsBuilder::new(); @@ -331,19 +336,20 @@ where sign_params .with_signature_version(self.signature_version()) .with_unsigned_tx(unsigned_tx); - let sign_params = sign_params.build()?; + let sign_params = sign_params.build().map_mm_err()?; let signed = match self.coin.as_ref().priv_key_policy { - PrivKeyPolicy::Iguana(ref key_pair) => { - self.coin - .sign_tx(sign_params, SignPolicy::WithKeyPair(key_pair)) - .await? - }, + PrivKeyPolicy::Iguana(ref key_pair) => self + .coin + .sign_tx(sign_params, SignPolicy::WithKeyPair(key_pair)) + .await + .map_mm_err()?, PrivKeyPolicy::HDWallet { .. } => { - let from_key_pair = derive_hd_key_pair(self.coin(), &self.from_derivation_path)?; + let from_key_pair = derive_hd_key_pair(self.coin(), &self.from_derivation_path).map_mm_err()?; self.coin() .sign_tx(sign_params, SignPolicy::WithKeyPair(&from_key_pair)) - .await? + .await + .map_mm_err()? }, PrivKeyPolicy::Trezor => { let trezor_statuses = TrezorRequestStatuses { @@ -354,16 +360,18 @@ where }; let sign_processor = TrezorRpcTaskProcessor::new(self.task_handle.clone(), trezor_statuses); let sign_processor = Arc::new(sign_processor); - let crypto_ctx = CryptoCtx::from_ctx(&self.ctx)?; + let crypto_ctx = CryptoCtx::from_ctx(&self.ctx).map_mm_err()?; let hw_ctx = crypto_ctx .hw_ctx() .or_mm_err(|| WithdrawError::HwError(HwRpcError::NoTrezorDeviceAvailable))?; - let trezor_session = hw_ctx.trezor(sign_processor).await?; + let trezor_session = hw_ctx.trezor(sign_processor).await.map_mm_err()?; self.task_handle - .update_in_progress_status(WithdrawInProgressStatus::WaitingForUserToConfirmSigning)?; + .update_in_progress_status(WithdrawInProgressStatus::WaitingForUserToConfirmSigning) + .map_mm_err()?; self.coin .sign_tx(sign_params, SignPolicy::WithTrezor(trezor_session)) - .await? + .await + .map_mm_err()? }, #[cfg(target_arch = "wasm32")] PrivKeyPolicy::Metamask(_) => { @@ -450,7 +458,8 @@ where &self.key_pair, self.signature_version(), self.coin.as_ref().conf.fork_id, - )?) + ) + .map_mm_err()?) } } @@ -467,13 +476,13 @@ where let from_address_string = from.address.display_address().map_to_mm(WithdrawError::InternalError)?; let key_pair = match from.derivation_path { - Some(der_path) => derive_hd_key_pair(&coin, &der_path)?, + Some(der_path) => derive_hd_key_pair(&coin, &der_path).map_mm_err()?, // [`WithdrawSenderAddress::derivation_path`] is not set, but the coin is initialized with an HD wallet derivation method. None if coin.has_hd_wallet_derivation_method() => { let error = "Cannot determine 'from' address derivation path".to_owned(); return MmError::err(WithdrawError::UnexpectedFromAddress(error)); }, - None => *coin.as_ref().priv_key_policy.activated_key_or_err()?, + None => *coin.as_ref().priv_key_policy.activated_key_or_err().map_mm_err()?, }; Ok(StandardUtxoWithdraw { diff --git a/mm2src/coins/utxo_signer/src/lib.rs b/mm2src/coins/utxo_signer/src/lib.rs index 8032e9acf7..3f9ee23095 100644 --- a/mm2src/coins/utxo_signer/src/lib.rs +++ b/mm2src/coins/utxo_signer/src/lib.rs @@ -138,7 +138,7 @@ pub trait UtxoSignerOps { let signer = with_trezor::TrezorTxSigner { trezor, tx_provider: self.tx_provider(), - trezor_coin: self.trezor_coin()?, + trezor_coin: self.trezor_coin().map_mm_err()?, params, fork_id: self.fork_id(), branch_id: self.branch_id(), @@ -147,7 +147,8 @@ pub trait UtxoSignerOps { }, SignPolicy::WithKeyPair(key_pair) => { let signed = - with_key_pair::sign_tx(params.unsigned_tx, key_pair, params.signature_version, self.fork_id())?; + with_key_pair::sign_tx(params.unsigned_tx, key_pair, params.signature_version, self.fork_id()) + .map_mm_err()?; Ok(signed) }, } diff --git a/mm2src/coins/utxo_signer/src/with_trezor.rs b/mm2src/coins/utxo_signer/src/with_trezor.rs index 8da3b972bb..75d882fa49 100644 --- a/mm2src/coins/utxo_signer/src/with_trezor.rs +++ b/mm2src/coins/utxo_signer/src/with_trezor.rs @@ -23,12 +23,12 @@ pub struct TrezorTxSigner<'a, TxP> { impl<'a, TxP: TxProvider + Send + Sync> TrezorTxSigner<'a, TxP> { pub async fn sign_tx(mut self) -> UtxoSignTxResult { - let trezor_unsigned_tx = self.get_trezor_unsigned_tx().await?; + let trezor_unsigned_tx = self.get_trezor_unsigned_tx().await.map_mm_err()?; let TxSignResult { signatures, serialized_tx, - } = self.trezor.sign_utxo_tx(trezor_unsigned_tx).await?; + } = self.trezor.sign_utxo_tx(trezor_unsigned_tx).await.map_mm_err()?; debug!("Transaction signed by Trezor: {}", hex::encode(serialized_tx)); if signatures.len() != self.params.inputs_count() { return MmError::err(UtxoSignTxError::InvalidSignaturesNumber { @@ -56,7 +56,10 @@ impl<'a, TxP: TxProvider + Send + Sync> TrezorTxSigner<'a, TxP> { async fn get_trezor_unsigned_tx(&self) -> UtxoSignTxResult { let mut inputs = Vec::with_capacity(self.params.unsigned_tx.inputs.len()); for (unsigned_input, input_info) in self.params.inputs() { - let unsigned_input = self.get_trezor_unsigned_input(unsigned_input, input_info).await?; + let unsigned_input = self + .get_trezor_unsigned_input(unsigned_input, input_info) + .await + .map_mm_err()?; inputs.push(unsigned_input); } @@ -99,7 +102,7 @@ impl<'a, TxP: TxProvider + Send + Sync> TrezorTxSigner<'a, TxP> { input_info: &SpendingInputInfo, ) -> UtxoSignTxResult { let prev_tx_hash_json = H256Json::from(unsigned_input.previous_output.hash.reversed()); - let prev_tx = self.get_trezor_prev_tx(&prev_tx_hash_json).await?; + let prev_tx = self.get_trezor_prev_tx(&prev_tx_hash_json).await.map_mm_err()?; let (address_derivation_path, input_script_type) = match input_info { SpendingInputInfo::P2PKH { @@ -130,9 +133,10 @@ impl<'a, TxP: TxProvider + Send + Sync> TrezorTxSigner<'a, TxP> { } async fn get_trezor_prev_tx(&self, prev_tx_hash: &H256Json) -> UtxoSignTxResult { - let prev_verbose = self.tx_provider.get_rpc_transaction(prev_tx_hash).await?; - let prev_utxo: UtxoTx = - deserialize(prev_verbose.hex.as_slice()).map_to_mm(|e| UtxoSignTxError::Transport(e.to_string()))?; + let prev_verbose = self.tx_provider.get_rpc_transaction(prev_tx_hash).await.map_mm_err()?; + let prev_utxo: UtxoTx = deserialize(prev_verbose.hex.as_slice()) + .map_to_mm(|e| UtxoSignTxError::Transport(e.to_string())) + .map_mm_err()?; let prev_tx_inputs = prev_utxo .inputs diff --git a/mm2src/coins/z_coin.rs b/mm2src/coins/z_coin.rs index 2d4d3bde42..4a0e92056e 100644 --- a/mm2src/coins/z_coin.rs +++ b/mm2src/coins/z_coin.rs @@ -380,9 +380,9 @@ impl ZCoin { ) -> Result, MmError> { // Wait for chain to sync before selecting spendable notes or waiting for locked_notes to become // available. - let sync_guard = self.wait_for_gen_tx_blockchain_sync().await?; + let sync_guard = self.wait_for_gen_tx_blockchain_sync().await.map_mm_err()?; drop(sync_guard); - let tx_fee = self.get_one_kbyte_tx_fee().await?; + let tx_fee = self.get_one_kbyte_tx_fee().await.map_mm_err()?; let t_output_sat: u64 = t_outputs.iter().fold(0, |cur, out| cur + u64::from(out.value)); let z_output_sat: u64 = z_outputs.iter().fold(0, |cur, out| cur + u64::from(out.amount)); let total_output_sat = t_output_sat + z_output_sat; @@ -391,7 +391,7 @@ impl ZCoin { let spendable_notes = wait_for_spendable_balance_spawner(self, &total_required).await?; // Recreate sync_guard - let sync_guard = self.wait_for_gen_tx_blockchain_sync().await?; + let sync_guard = self.wait_for_gen_tx_blockchain_sync().await.map_mm_err()?; let mut total_input_amount = BigDecimal::from(0); let mut change = BigDecimal::from(0); @@ -442,7 +442,7 @@ impl ZCoin { } // add change to tx output - let change_sat = sat_from_big_decimal(&change, self.utxo_arc.decimals)?; + let change_sat = sat_from_big_decimal(&change, self.utxo_arc.decimals).map_mm_err()?; if change > BigDecimal::from(0u8) { received_by_me += change_sat; let change_amount = Amount::from_u64(change_sat).map_to_mm(|_| { @@ -474,13 +474,15 @@ impl ZCoin { #[cfg(target_arch = "wasm32")] let (tx, _) = TxBuilderSpawner::request_tx_result(tx_builder, BranchId::Sapling, self.z_fields.z_tx_prover.clone()) - .await? - .tx_result?; + .await + .map_mm_err()? + .tx_result + .map_mm_err()?; let data = AdditionalTxData { received_by_me, - spent_by_me: sat_from_big_decimal(&total_input_amount, self.decimals())?, - fee_amount: sat_from_big_decimal(&tx_fee, self.decimals())?, + spent_by_me: sat_from_big_decimal(&total_input_amount, self.decimals()).map_mm_err()?, + fee_amount: sat_from_big_decimal(&tx_fee, self.decimals()).map_mm_err()?, kmd_rewards: None, }; @@ -502,14 +504,15 @@ impl ZCoin { data, rseeds, mut sync_guard, - } = self.gen_tx(t_outputs, z_outputs).await?; + } = self.gen_tx(t_outputs, z_outputs).await.map_mm_err()?; let mut tx_bytes = Vec::with_capacity(1024); tx.write(&mut tx_bytes).expect("Write should not fail"); self.utxo_rpc_client() .send_raw_transaction(tx_bytes.into()) .compat() - .await?; + .await + .map_mm_err()?; // TODO: Execute updates to `locked_notes_db` and `wallet_db` in a single transaction. // This will be possible with a newer librustzcash that supports both spent notes and unconfirmed change tracking. @@ -648,15 +651,20 @@ impl ZCoin { &self, request: MyTxHistoryRequestV2, ) -> Result, MmError> { - let current_block = self.utxo_rpc_client().get_block_count().compat().await?; - let req_result = fetch_tx_history_from_db(self, request.limit, request.paging_options.clone()).await?; + let current_block = self.utxo_rpc_client().get_block_count().compat().await.map_mm_err()?; + let req_result = fetch_tx_history_from_db(self, request.limit, request.paging_options.clone()) + .await + .map_mm_err()?; let hashes_for_verbose = req_result .transactions .iter() .map(|item| H256Json::from(item.tx_hash)) .collect(); - let transactions = self.z_transactions_from_cache_or_rpc(hashes_for_verbose).await?; + let transactions = self + .z_transactions_from_cache_or_rpc(hashes_for_verbose) + .await + .map_mm_err()?; let prev_tx_hashes: HashSet<_> = transactions .iter() @@ -668,13 +676,17 @@ impl ZCoin { }) }) .collect(); - let prev_transactions = self.z_transactions_from_cache_or_rpc(prev_tx_hashes).await?; + let prev_transactions = self + .z_transactions_from_cache_or_rpc(prev_tx_hashes) + .await + .map_mm_err()?; let transactions = req_result .transactions .into_iter() .map(|sql_item| self.tx_details_from_db_item(sql_item, &transactions, &prev_transactions, current_block)) - .collect::>()?; + .collect::>() + .map_mm_err()?; Ok(MyTxHistoryResponseV2 { coin: self.ticker().into(), @@ -930,7 +942,7 @@ impl<'a> UtxoCoinBuilder for ZCoinBuilder<'a> { fn priv_key_policy(&self) -> PrivKeyBuildPolicy { self.priv_key_policy.clone() } async fn build(self) -> MmResult { - let utxo = self.build_utxo_fields().await?; + let utxo = self.build_utxo_fields().await.map_mm_err()?; let utxo_arc = UtxoArc::new(utxo); let dex_fee_addr = decode_payment_address( @@ -948,30 +960,36 @@ impl<'a> UtxoCoinBuilder for ZCoinBuilder<'a> { .expect("DEX_BURN_Z_ADDR is a valid z-address"); let z_tx_prover = self.z_tx_prover().await?; - let blocks_db = self.init_blocks_db().await?; - let locked_notes_db = LockedNotesStorage::new(self.ctx, self.my_z_addr_encoded.clone()).await?; + let blocks_db = self.init_blocks_db().await.map_mm_err()?; + let locked_notes_db = LockedNotesStorage::new(self.ctx, self.my_z_addr_encoded.clone()) + .await + .map_mm_err()?; let (sync_state_connector, light_wallet_db) = match &self.z_coin_params.mode { #[cfg(not(target_arch = "wasm32"))] - ZcoinRpcMode::Native => { - init_native_client(&self, self.native_client()?, blocks_db, locked_notes_db.clone()).await? - }, + ZcoinRpcMode::Native => init_native_client( + &self, + self.native_client().map_mm_err()?, + blocks_db, + locked_notes_db.clone(), + ) + .await + .map_mm_err()?, ZcoinRpcMode::Light { light_wallet_d_servers, sync_params, skip_sync_params, .. - } => { - init_light_client( - &self, - light_wallet_d_servers.clone(), - blocks_db, - sync_params, - skip_sync_params.unwrap_or_default(), - locked_notes_db.clone(), - ) - .await? - }, + } => init_light_client( + &self, + light_wallet_d_servers.clone(), + blocks_db, + sync_params, + skip_sync_params.unwrap_or_default(), + locked_notes_db.clone(), + ) + .await + .map_mm_err()?, #[cfg(test)] ZcoinRpcMode::UnitTests => z_unit_tests::create_test_sync_connector(&self).await, }; @@ -1506,8 +1524,14 @@ impl SwapOps for ZCoin { ))) }, }; - let fee_amount_sat = validate_fee_args.dex_fee.fee_amount_as_u64(self.utxo_arc.decimals)?; - let burn_amount_sat = validate_fee_args.dex_fee.burn_amount_as_u64(self.utxo_arc.decimals)?; + let fee_amount_sat = validate_fee_args + .dex_fee + .fee_amount_as_u64(self.utxo_arc.decimals) + .map_mm_err()?; + let burn_amount_sat = validate_fee_args + .dex_fee + .burn_amount_as_u64(self.utxo_arc.decimals) + .map_mm_err()?; let expected_memo = MemoBytes::from_bytes(validate_fee_args.uuid).expect("Uuid length < 512"); let tx_hash = H256::from(z_tx.txid().0).reversed(); @@ -1750,7 +1774,7 @@ impl MmCoin for ZCoin { ) -> TradePreimageResult { Ok(TradeFee { coin: self.ticker().to_owned(), - amount: self.get_one_kbyte_tx_fee().await?.into(), + amount: self.get_one_kbyte_tx_fee().await.map_mm_err()?.into(), paid_from_trading_vol: false, }) } @@ -1766,7 +1790,7 @@ impl MmCoin for ZCoin { ) -> TradePreimageResult { Ok(TradeFee { coin: self.ticker().to_owned(), - amount: self.get_one_kbyte_tx_fee().await?.into(), + amount: self.get_one_kbyte_tx_fee().await.map_mm_err()?.into(), paid_from_trading_vol: false, }) } @@ -1985,27 +2009,30 @@ impl InitWithdrawCoin for ZCoin { .map_to_mm(|e| WithdrawError::InvalidAddress(format!("{}", e)))? .or_mm_err(|| WithdrawError::InvalidAddress(format!("Address {} decoded to None", req.to)))?; let amount = if req.max { - let fee = self.get_one_kbyte_tx_fee().await?; - let balance = self.my_balance().compat().await?; + let fee = self.get_one_kbyte_tx_fee().await.map_mm_err()?; + let balance = self.my_balance().compat().await.map_mm_err()?; balance.spendable - fee } else { req.amount }; - task_handle.update_in_progress_status(WithdrawInProgressStatus::GeneratingTransaction)?; - let satoshi = sat_from_big_decimal(&amount, self.decimals())?; + task_handle + .update_in_progress_status(WithdrawInProgressStatus::GeneratingTransaction) + .map_mm_err()?; + let satoshi = sat_from_big_decimal(&amount, self.decimals()).map_mm_err()?; let memo = req.memo.as_deref().map(interpret_memo_string).transpose()?; let z_output = ZOutput { to_addr, amount: Amount::from_u64(satoshi) - .map_to_mm(|_| NumConversError(format!("Failed to get ZCash amount from {}", amount)))?, + .map_to_mm(|_| NumConversError(format!("Failed to get ZCash amount from {}", amount))) + .map_mm_err()?, // TODO add optional viewing_key and memo fields to the WithdrawRequest viewing_key: Some(self.z_fields.evk.fvk.ovk), memo, }; - let GenTxData { tx, data, .. } = self.gen_tx(vec![], vec![z_output]).await?; + let GenTxData { tx, data, .. } = self.gen_tx(vec![], vec![z_output]).await.map_mm_err()?; let mut tx_bytes = Vec::with_capacity(1024); tx.write(&mut tx_bytes) .map_to_mm(|e| WithdrawError::InternalError(e.to_string()))?; @@ -2060,7 +2087,7 @@ async fn wait_for_spendable_balance_impl( .map_err(|e| GenTxError::SpendableNotesError(e.to_string()))?; let wallet_notes_len = wallet_notes.len(); - let locked_notes = selfi.z_fields.locked_notes_db.load_all_notes().await?; + let locked_notes = selfi.z_fields.locked_notes_db.load_all_notes().await.map_mm_err()?; let unlocked_notes: Vec = if locked_notes.is_empty() { wallet_notes diff --git a/mm2src/coins/z_coin/storage/blockdb/blockdb_idb_storage.rs b/mm2src/coins/z_coin/storage/blockdb/blockdb_idb_storage.rs index b95af8c4cd..4a74c621fe 100644 --- a/mm2src/coins/z_coin/storage/blockdb/blockdb_idb_storage.rs +++ b/mm2src/coins/z_coin/storage/blockdb/blockdb_idb_storage.rs @@ -85,18 +85,21 @@ impl BlockDbImpl { pub async fn get_latest_block(&self) -> ZcoinStorageRes { let ticker = self.ticker.clone(); let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let block_db = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let block_db = db_transaction.table::().await.map_mm_err()?; let maybe_height = block_db .cursor_builder() - .only("ticker", &ticker)? + .only("ticker", &ticker) + .map_mm_err()? .bound("height", 0u32, u32::MAX) .reverse() .where_first() .open_cursor(BlockDbTable::TICKER_HEIGHT_INDEX) - .await? + .await + .map_mm_err()? .next() - .await?; + .await + .map_mm_err()?; Ok(maybe_height.map(|(_, item)| item.height).unwrap_or_else(|| 0)) } @@ -105,12 +108,14 @@ impl BlockDbImpl { pub async fn insert_block(&self, height: u32, cb_bytes: Vec) -> ZcoinStorageRes { let ticker = self.ticker.clone(); let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let block_db = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let block_db = db_transaction.table::().await.map_mm_err()?; let indexes = MultiIndex::new(BlockDbTable::TICKER_HEIGHT_INDEX) - .with_value(&ticker)? - .with_value(BeBigUint::from(height))?; + .with_value(&ticker) + .map_mm_err()? + .with_value(BeBigUint::from(height)) + .map_mm_err()?; let block = BlockDbTable { height, data: cb_bytes, @@ -119,7 +124,8 @@ impl BlockDbImpl { Ok(block_db .add_item_or_ignore_by_unique_multi_index(indexes, &block) - .await? + .await + .map_mm_err()? .get_id() as usize) } @@ -127,28 +133,34 @@ impl BlockDbImpl { /// removing data beyond the specified height from the storage. pub async fn rewind_to_height(&self, height: BlockHeight) -> ZcoinStorageRes { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let block_db = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let block_db = db_transaction.table::().await.map_mm_err()?; let blocks = block_db .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("height", 0u32, u32::MAX) .reverse() .open_cursor(BlockDbTable::TICKER_HEIGHT_INDEX) - .await? + .await + .map_mm_err()? .collect() - .await?; + .await + .map_mm_err()?; for (_, block) in &blocks { if block.height > u32::from(height) { block_db .delete_item_by_unique_multi_index( MultiIndex::new(BlockDbTable::TICKER_HEIGHT_INDEX) - .with_value(&self.ticker)? - .with_value(block.height)?, + .with_value(&self.ticker) + .map_mm_err()? + .with_value(block.height) + .map_mm_err()?, ) - .await?; + .await + .map_mm_err()?; } } @@ -158,17 +170,20 @@ impl BlockDbImpl { #[allow(unused)] pub(crate) async fn get_earliest_block(&self) -> ZcoinStorageRes { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let block_db = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let block_db = db_transaction.table::().await.map_mm_err()?; let maybe_min_block = block_db .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("height", 0u32, u32::MAX) .where_first() .open_cursor(BlockDbTable::TICKER_HEIGHT_INDEX) - .await? + .await + .map_mm_err()? .next() - .await?; + .await + .map_mm_err()?; Ok(maybe_min_block.map(|(_, b)| b.height).unwrap_or(0)) } @@ -181,20 +196,22 @@ impl BlockDbImpl { limit: Option, ) -> ZcoinStorageRes> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let block_db = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let block_db = db_transaction.table::().await.map_mm_err()?; // Fetch CompactBlocks block_db are needed for scanning. let min = u32::from(from_height + 1); let mut maybe_blocks = block_db .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("height", min, u32::MAX) .open_cursor(BlockDbTable::TICKER_HEIGHT_INDEX) - .await?; + .await + .map_mm_err()?; let mut blocks_to_scan = vec![]; - while let Some((_, block)) = maybe_blocks.next().await? { + while let Some((_, block)) = maybe_blocks.next().await.map_mm_err()? { if let Some(limit) = limit { if blocks_to_scan.len() > limit as usize { break; diff --git a/mm2src/coins/z_coin/storage/walletdb/wasm/storage.rs b/mm2src/coins/z_coin/storage/walletdb/wasm/storage.rs index 78d8a6fbaa..f4e08c3ef2 100644 --- a/mm2src/coins/z_coin/storage/walletdb/wasm/storage.rs +++ b/mm2src/coins/z_coin/storage/walletdb/wasm/storage.rs @@ -154,13 +154,15 @@ impl<'a> WalletIndexedDb { pub async fn is_tx_imported(&self, tx_id: TxId) -> ZcoinStorageRes { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; - let tx_table = db_transaction.table::().await?; + let tx_table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(WalletDbTransactionsTable::TICKER_TXID_INDEX) - .with_value(&self.ticker)? - .with_value(tx_id.0.to_vec())?; - let maybe_tx = tx_table.get_items_by_multi_index(index_keys).await?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(tx_id.0.to_vec()) + .map_mm_err()?; + let maybe_tx = tx_table.get_items_by_multi_index(index_keys).await.map_mm_err()?; if !maybe_tx.is_empty() { Ok(true) @@ -175,19 +177,22 @@ impl<'a> WalletIndexedDb { pub(crate) async fn init_accounts_table(&self, extfvks: &[ExtendedFullViewingKey]) -> ZcoinStorageRes<()> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let walletdb_account_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let walletdb_account_table = db_transaction.table::().await.map_mm_err()?; // check if account exists let maybe_min_account = walletdb_account_table .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("height", 0u32, u32::MAX) .where_first() .open_cursor(WalletDbAccountsTable::TICKER_ACCOUNT_INDEX) - .await? + .await + .map_mm_err()? .next() - .await?; + .await + .map_mm_err()?; if maybe_min_account.is_some() { return MmError::err(ZcoinStorageError::TableNotEmpty( "Account table is not empty".to_string(), @@ -209,12 +214,15 @@ impl<'a> WalletIndexedDb { }; let index_keys = MultiIndex::new(WalletDbAccountsTable::TICKER_ACCOUNT_INDEX) - .with_value(&self.ticker)? - .with_value(account_int)?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(account_int) + .map_mm_err()?; walletdb_account_table .replace_item_by_unique_multi_index(index_keys, &account) - .await?; + .await + .map_mm_err()?; } Ok(()) @@ -228,19 +236,22 @@ impl<'a> WalletIndexedDb { sapling_tree: &[u8], ) -> ZcoinStorageRes<()> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let walletdb_account_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let walletdb_account_table = db_transaction.table::().await.map_mm_err()?; // check if account exists let maybe_min_account = walletdb_account_table .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("height", 0u32, u32::MAX) .where_first() .open_cursor(WalletDbBlocksTable::TICKER_HEIGHT_INDEX) - .await? + .await + .map_mm_err()? .next() - .await?; + .await + .map_mm_err()?; if maybe_min_account.is_some() { return MmError::err(ZcoinStorageError::TableNotEmpty( "Account table is not empty".to_string(), @@ -254,14 +265,18 @@ impl<'a> WalletIndexedDb { sapling_tree: sapling_tree.to_vec(), ticker: self.ticker.clone(), }; - let walletdb_blocks_table = db_transaction.table::().await?; + let walletdb_blocks_table = db_transaction.table::().await.map_mm_err()?; let height = u32::from(height); let index_keys = MultiIndex::new(WalletDbBlocksTable::TICKER_HEIGHT_INDEX) - .with_value(&self.ticker)? - .with_value(num_to_bigint!(height)?)?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(num_to_bigint!(height)?) + .map_mm_err()?; + walletdb_blocks_table .replace_item_by_unique_multi_index(index_keys, &block) - .await?; + .await + .map_mm_err()?; Ok(()) } @@ -276,8 +291,8 @@ impl WalletIndexedDb { commitment_tree: &CommitmentTree, ) -> ZcoinStorageRes<()> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let walletdb_blocks_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let walletdb_blocks_table = db_transaction.table::().await.map_mm_err()?; let mut encoded_tree = Vec::new(); commitment_tree.write(&mut encoded_tree).unwrap(); @@ -292,27 +307,35 @@ impl WalletIndexedDb { }; let index_keys = MultiIndex::new(WalletDbBlocksTable::TICKER_HEIGHT_INDEX) - .with_value(&self.ticker)? - .with_value(u32::from(block_height))?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(u32::from(block_height)) + .map_mm_err()?; - Ok(walletdb_blocks_table + walletdb_blocks_table .replace_item_by_unique_multi_index(index_keys, &block) .await - .map(|_| ())?) + .map(|_| ()) + .map_mm_err() } pub async fn get_balance(&self, account: AccountId) -> ZcoinStorageRes { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let rec_note_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let rec_note_table = db_transaction + .table::() + .await + .map_mm_err()?; let index_keys = MultiIndex::new(WalletDbReceivedNotesTable::TICKER_ACCOUNT_INDEX) - .with_value(&self.ticker)? - .with_value(account.0.to_bigint().unwrap())?; - let maybe_notes = rec_note_table.get_items_by_multi_index(index_keys).await?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(account.0.to_bigint().unwrap()) + .map_mm_err()?; + let maybe_notes = rec_note_table.get_items_by_multi_index(index_keys).await.map_mm_err()?; - let tx_table = db_transaction.table::().await?; - let txs = tx_table.get_items("ticker", &self.ticker).await?; + let tx_table = db_transaction.table::().await.map_mm_err()?; + let txs = tx_table.get_items("ticker", &self.ticker).await.map_mm_err()?; let balance: i64 = maybe_notes .iter() @@ -339,17 +362,19 @@ impl WalletIndexedDb { pub async fn put_tx_data(&self, tx: &Transaction, created_at: Option) -> ZcoinStorageRes { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let tx_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let tx_table = db_transaction.table::().await.map_mm_err()?; let mut raw_tx = vec![]; tx.write(&mut raw_tx).unwrap(); let txid = tx.txid().0.to_vec(); let index_keys = MultiIndex::new(WalletDbTransactionsTable::TICKER_TXID_INDEX) - .with_value(&self.ticker)? - .with_value(&txid)?; - let single_tx = tx_table.get_item_by_unique_multi_index(index_keys).await?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(&txid) + .map_mm_err()?; + let single_tx = tx_table.get_item_by_unique_multi_index(index_keys).await.map_mm_err()?; if let Some((id_tx, some_tx)) = single_tx { let updated_tx = WalletDbTransactionsTable { txid: txid.clone(), @@ -360,7 +385,7 @@ impl WalletIndexedDb { raw: Some(raw_tx), ticker: self.ticker.clone(), }; - tx_table.replace_item(id_tx, &updated_tx).await?; + tx_table.replace_item(id_tx, &updated_tx).await.map_mm_err()?; return Ok(id_tx as i64); }; @@ -375,25 +400,30 @@ impl WalletIndexedDb { ticker: self.ticker.clone(), }; let index_keys = MultiIndex::new(WalletDbTransactionsTable::TICKER_TXID_INDEX) - .with_value(&self.ticker)? - .with_value(txid)?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(txid) + .map_mm_err()?; Ok(tx_table .replace_item_by_unique_multi_index(index_keys, &new_tx) - .await? + .await + .map_mm_err()? .into()) } pub async fn put_tx_meta(&self, tx: &WalletTx, height: BlockHeight) -> ZcoinStorageRes { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let tx_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let tx_table = db_transaction.table::().await.map_mm_err()?; let txid = tx.txid.0.to_vec(); let index_keys = MultiIndex::new(WalletDbTransactionsTable::TICKER_TXID_INDEX) - .with_value(&self.ticker)? - .with_value(&txid)?; - let single_tx = tx_table.get_item_by_unique_multi_index(index_keys).await?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(&txid) + .map_mm_err()?; + let single_tx = tx_table.get_item_by_unique_multi_index(index_keys).await.map_mm_err()?; if let Some((id_tx, some_tx)) = single_tx { let updated_tx = WalletDbTransactionsTable { @@ -405,7 +435,7 @@ impl WalletIndexedDb { raw: some_tx.raw, ticker: self.ticker.clone(), }; - tx_table.replace_item(id_tx, &updated_tx).await?; + tx_table.replace_item(id_tx, &updated_tx).await.map_mm_err()?; return Ok(id_tx as i64); }; @@ -420,25 +450,36 @@ impl WalletIndexedDb { ticker: self.ticker.clone(), }; let index_keys = MultiIndex::new(WalletDbTransactionsTable::TICKER_TXID_INDEX) - .with_value(&self.ticker)? - .with_value(txid)?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(txid) + .map_mm_err()?; Ok(tx_table .replace_item_by_unique_multi_index(index_keys, &new_tx) - .await? + .await + .map_mm_err()? .into()) } pub async fn mark_spent(&self, tx_ref: i64, nf: &Nullifier) -> ZcoinStorageRes<()> { let ticker = self.ticker.clone(); let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let received_notes_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let received_notes_table = db_transaction + .table::() + .await + .map_mm_err()?; let index_keys = MultiIndex::new(WalletDbReceivedNotesTable::TICKER_NF_INDEX) - .with_value(&ticker)? - .with_value(nf.0.to_vec())?; - let maybe_note = received_notes_table.get_item_by_unique_multi_index(index_keys).await?; + .with_value(&ticker) + .map_mm_err()? + .with_value(nf.0.to_vec()) + .map_mm_err()?; + let maybe_note = received_notes_table + .get_item_by_unique_multi_index(index_keys) + .await + .map_mm_err()?; if let Some((id, note)) = maybe_note { let new_received_note = WalletDbReceivedNotesTable { @@ -454,7 +495,10 @@ impl WalletIndexedDb { spent: Some(num_to_bigint!(tx_ref)?), ticker, }; - received_notes_table.replace_item(id, &new_received_note).await?; + received_notes_table + .replace_item(id, &new_received_note) + .await + .map_mm_err()?; return Ok(()); } @@ -464,7 +508,7 @@ impl WalletIndexedDb { pub async fn put_received_note(&self, output: &T, tx_ref: i64) -> ZcoinStorageRes { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; let rcm = output.note().rcm().to_repr(); let account = BigInt::from(output.account().0); @@ -477,12 +521,21 @@ impl WalletIndexedDb { let output_index = output.index() as u32; let nf_bytes = output.nullifier().map(|nf| nf.0.to_vec()); - let received_note_table = db_transaction.table::().await?; + let received_note_table = db_transaction + .table::() + .await + .map_mm_err()?; let index_keys = MultiIndex::new(WalletDbReceivedNotesTable::TICKER_TX_OUTPUT_INDEX) - .with_value(&self.ticker)? - .with_value(tx)? - .with_value(output_index)?; - let current_note = received_note_table.get_item_by_unique_multi_index(index_keys).await?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(tx) + .map_mm_err()? + .with_value(output_index) + .map_mm_err()?; + let current_note = received_note_table + .get_item_by_unique_multi_index(index_keys) + .await + .map_mm_err()?; let id = if let Some((id, note)) = current_note { let temp_note = WalletDbReceivedNotesTable { @@ -498,7 +551,7 @@ impl WalletIndexedDb { spent: note.spent, ticker: self.ticker.clone(), }; - received_note_table.replace_item(id, &temp_note).await? + received_note_table.replace_item(id, &temp_note).await.map_mm_err()? } else { let new_note = WalletDbReceivedNotesTable { tx, @@ -515,12 +568,16 @@ impl WalletIndexedDb { }; let index_keys = MultiIndex::new(WalletDbReceivedNotesTable::TICKER_TX_OUTPUT_INDEX) - .with_value(&self.ticker)? - .with_value(tx)? - .with_value(num_to_bigint!(output_index)?)?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(tx) + .map_mm_err()? + .with_value(num_to_bigint!(output_index)?) + .map_mm_err()?; received_note_table .replace_item_by_unique_multi_index(index_keys, &new_note) - .await? + .await + .map_mm_err()? }; Ok(NoteId::ReceivedNoteId(id.into())) @@ -533,8 +590,11 @@ impl WalletIndexedDb { height: BlockHeight, ) -> ZcoinStorageRes<()> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let witness_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let witness_table = db_transaction + .table::() + .await + .map_mm_err()?; let mut encoded = Vec::new(); witness.write(&mut encoded).unwrap(); @@ -547,23 +607,28 @@ impl WalletIndexedDb { ticker: self.ticker.clone(), }; - Ok(witness_table.add_item(&witness).await.map(|_| ())?) + witness_table.add_item(&witness).await.map(|_| ()).map_mm_err() } pub async fn prune_witnesses(&self, below_height: BlockHeight) -> ZcoinStorageRes<()> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let witness_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let witness_table = db_transaction + .table::() + .await + .map_mm_err()?; let mut maybe_witness = witness_table .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("block", 0u32, (below_height - 1).into()) .open_cursor(WalletDbSaplingWitnessesTable::TICKER_BLOCK_INDEX) - .await?; + .await + .map_mm_err()?; - while let Some((id, _)) = maybe_witness.next().await? { - witness_table.delete_item(id).await?; + while let Some((id, _)) = maybe_witness.next().await.map_mm_err()? { + witness_table.delete_item(id).await.map_mm_err()?; } Ok(()) @@ -571,22 +636,30 @@ impl WalletIndexedDb { pub async fn update_expired_notes(&self, height: BlockHeight) -> ZcoinStorageRes<()> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; // fetch received_notes. - let received_notes_table = db_transaction.table::().await?; - let maybe_notes = received_notes_table.get_items("ticker", &self.ticker).await?; + let received_notes_table = db_transaction + .table::() + .await + .map_mm_err()?; + let maybe_notes = received_notes_table + .get_items("ticker", &self.ticker) + .await + .map_mm_err()?; // fetch transactions with block < height . - let txs_table = db_transaction.table::().await?; + let txs_table = db_transaction.table::().await.map_mm_err()?; let mut maybe_txs = txs_table .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("expiry_height", 0u32, u32::from(height - 1)) .reverse() .open_cursor(WalletDbTransactionsTable::TICKER_EXP_HEIGHT_INDEX) - .await?; + .await + .map_mm_err()?; - while let Some((id, note)) = maybe_txs.next().await? { + while let Some((id, note)) = maybe_txs.next().await.map_mm_err()? { if note.block.is_none() { if let Some(curr) = maybe_notes.iter().find(|(_, n)| n.spent == id.to_bigint()) { let temp_note = WalletDbReceivedNotesTable { @@ -603,7 +676,10 @@ impl WalletIndexedDb { ticker: self.ticker.clone(), }; - received_notes_table.replace_item(curr.0, &temp_note).await?; + received_notes_table + .replace_item(curr.0, &temp_note) + .await + .map_mm_err()?; } }; } @@ -613,7 +689,7 @@ impl WalletIndexedDb { pub async fn put_sent_note(&self, output: &DecryptedOutput, tx_ref: i64) -> ZcoinStorageRes<()> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; let tx_ref = num_to_bigint!(tx_ref)?; let output_index = output.index; @@ -624,12 +700,18 @@ impl WalletIndexedDb { let value = num_to_bigint!(value)?; let address = encode_payment_address(self.params.hrp_sapling_payment_address(), &output.to); - let sent_note_table = db_transaction.table::().await?; + let sent_note_table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(WalletDbSentNotesTable::TICKER_TX_OUTPUT_INDEX) - .with_value(&self.ticker)? - .with_value(&tx_ref)? - .with_value(&output_index)?; - let maybe_note = sent_note_table.get_item_by_unique_multi_index(index_keys).await?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(&tx_ref) + .map_mm_err()? + .with_value(&output_index) + .map_mm_err()?; + let maybe_note = sent_note_table + .get_item_by_unique_multi_index(index_keys) + .await + .map_mm_err()?; let update_note = WalletDbSentNotesTable { tx: tx_ref.clone(), @@ -641,15 +723,19 @@ impl WalletIndexedDb { ticker: self.ticker.clone(), }; if let Some((id, _)) = maybe_note { - sent_note_table.replace_item(id, &update_note).await?; + sent_note_table.replace_item(id, &update_note).await.map_mm_err()?; } else { let index_keys = MultiIndex::new(WalletDbReceivedNotesTable::TICKER_TX_OUTPUT_INDEX) - .with_value(&self.ticker)? - .with_value(tx_ref)? - .with_value(output_index)?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(tx_ref) + .map_mm_err()? + .with_value(output_index) + .map_mm_err()?; sent_note_table .replace_item_by_unique_multi_index(index_keys, &update_note) - .await?; + .await + .map_mm_err()?; } Ok(()) @@ -665,8 +751,8 @@ impl WalletIndexedDb { memo: Option<&MemoBytes>, ) -> ZcoinStorageRes<()> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let sent_note_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let sent_note_table = db_transaction.table::().await.map_mm_err()?; let tx_ref = num_to_bigint!(tx_ref)?; let output_index = num_to_bigint!(output_index)?; @@ -685,36 +771,43 @@ impl WalletIndexedDb { ticker: self.ticker.clone(), }; let index_keys = MultiIndex::new(WalletDbReceivedNotesTable::TICKER_TX_OUTPUT_INDEX) - .with_value(&self.ticker)? - .with_value(tx_ref)? - .with_value(output_index)?; - - Ok(sent_note_table + .with_value(&self.ticker) + .map_mm_err()? + .with_value(tx_ref) + .map_mm_err()? + .with_value(output_index) + .map_mm_err()?; + + sent_note_table .replace_item_by_unique_multi_index(index_keys, &new_note) .await - .map(|_| ())?) + .map(|_| ()) + .map_mm_err() } /// Asynchronously rewinds the storage to a specified block height, effectively /// removing data beyond the specified height from the storage. pub async fn rewind_to_height(&self, block_height: BlockHeight) -> ZcoinStorageRes<()> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; let block_height = u32::from(block_height); // Recall where we synced up to previously. - let blocks_table = db_transaction.table::().await?; + let blocks_table = db_transaction.table::().await.map_mm_err()?; let maybe_height = blocks_table .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("height", 0u32, u32::MAX) .reverse() .where_first() .open_cursor(WalletDbBlocksTable::TICKER_HEIGHT_INDEX) - .await? + .await + .map_mm_err()? .next() - .await? + .await + .map_mm_err()? .map(|(_, item)| { item.height .to_u32() @@ -732,31 +825,39 @@ impl WalletIndexedDb { }; // Decrement witnesses. - let db_transaction = locked_db.get_inner().transaction().await?; - let witnesses_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let witnesses_table = db_transaction + .table::() + .await + .map_mm_err()?; let maybe_witnesses_cursor = witnesses_table .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("block", block_height + 1, u32::MAX) .open_cursor(WalletDbSaplingWitnessesTable::TICKER_BLOCK_INDEX) - .await? + .await + .map_mm_err()? .collect() - .await?; + .await + .map_mm_err()?; for (id, _witness) in maybe_witnesses_cursor { - witnesses_table.delete_item(id).await?; + witnesses_table.delete_item(id).await.map_mm_err()?; } // Un-mine transactions. - let db_transaction = locked_db.get_inner().transaction().await?; - let transactions_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let transactions_table = db_transaction.table::().await.map_mm_err()?; let mut maybe_txs_cursor = transactions_table .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("block", block_height + 1, u32::MAX) .open_cursor(WalletDbTransactionsTable::TICKER_BLOCK_INDEX) - .await?; - while let Some((_, tx)) = maybe_txs_cursor.next().await? { + .await + .map_mm_err()?; + while let Some((_, tx)) = maybe_txs_cursor.next().await.map_mm_err()? { let modified_tx = WalletDbTransactionsTable { txid: tx.txid.clone(), created: tx.created.clone(), @@ -767,30 +868,41 @@ impl WalletIndexedDb { ticker: self.ticker.clone(), }; let index_keys = MultiIndex::new(WalletDbTransactionsTable::TICKER_TXID_INDEX) - .with_value(&self.ticker)? - .with_value(tx.txid)?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(tx.txid) + .map_mm_err()?; transactions_table .replace_item_by_unique_multi_index(index_keys, &modified_tx) - .await?; + .await + .map_mm_err()?; } // Now that they aren't depended on, delete scanned blocks. - let db_transaction = locked_db.get_inner().transaction().await?; - let blocks_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let blocks_table = db_transaction.table::().await.map_mm_err()?; let maybe_blocks = blocks_table .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("height", block_height + 1, u32::MAX) .open_cursor(WalletDbBlocksTable::TICKER_HEIGHT_INDEX) - .await? + .await + .map_mm_err()? .collect() - .await?; + .await + .map_mm_err()?; for (_, block) in maybe_blocks { let index_keys = MultiIndex::new(WalletDbBlocksTable::TICKER_HEIGHT_INDEX) - .with_value(&self.ticker)? - .with_value(block.height)?; - blocks_table.delete_item_by_unique_multi_index(index_keys).await?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(block.height) + .map_mm_err()?; + blocks_table + .delete_item_by_unique_multi_index(index_keys) + .await + .map_mm_err()?; } Ok(()) @@ -805,29 +917,35 @@ impl WalletRead for WalletIndexedDb { async fn block_height_extrema(&self) -> Result, Self::Error> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let block_headers_db = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let block_headers_db = db_transaction.table::().await.map_mm_err()?; let earliest_block = block_headers_db .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("height", 0u32, u32::MAX) .where_first() .open_cursor(WalletDbBlocksTable::TICKER_HEIGHT_INDEX) - .await? + .await + .map_mm_err()? .next() - .await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let block_headers_db = db_transaction.table::().await?; + .await + .map_mm_err()?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let block_headers_db = db_transaction.table::().await.map_mm_err()?; let latest_block = block_headers_db .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("height", 0u32, u32::MAX) .reverse() .where_first() .open_cursor(WalletDbBlocksTable::TICKER_HEIGHT_INDEX) - .await? + .await + .map_mm_err()? .next() - .await?; + .await + .map_mm_err()?; if let (Some(min), Some(max)) = (earliest_block, latest_block) { Ok(Some((BlockHeight::from(min.1.height), BlockHeight::from(max.1.height)))) @@ -838,44 +956,53 @@ impl WalletRead for WalletIndexedDb { async fn get_block_hash(&self, block_height: BlockHeight) -> Result, Self::Error> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let block_headers_db = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let block_headers_db = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(WalletDbBlocksTable::TICKER_HEIGHT_INDEX) - .with_value(&self.ticker)? - .with_value(u32::from(block_height))?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(u32::from(block_height)) + .map_mm_err()?; Ok(block_headers_db .get_item_by_unique_multi_index(index_keys) - .await? + .await + .map_mm_err()? .map(|(_, block)| BlockHash::from_slice(&block.hash[..]))) } async fn get_tx_height(&self, txid: TxId) -> Result, Self::Error> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let block_headers_db = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let block_headers_db = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(WalletDbTransactionsTable::TICKER_TXID_INDEX) - .with_value(&self.ticker)? - .with_value(txid.0.to_vec())?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(txid.0.to_vec()) + .map_mm_err()?; Ok(block_headers_db .get_item_by_unique_multi_index(index_keys) - .await? + .await + .map_mm_err()? .and_then(|(_, tx)| tx.block.map(BlockHeight::from))) } async fn get_address(&self, account: AccountId) -> Result, Self::Error> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let block_headers_db = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let block_headers_db = db_transaction.table::().await.map_mm_err()?; let account_num = account.0; let index_keys = MultiIndex::new(WalletDbAccountsTable::TICKER_ACCOUNT_INDEX) - .with_value(&self.ticker)? - .with_value(num_to_bigint!(account_num)?)?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(num_to_bigint!(account_num)?) + .map_mm_err()?; let address = block_headers_db .get_item_by_unique_multi_index(index_keys) - .await? + .await + .map_mm_err()? .map(|(_, account)| account.address) .ok_or_else(|| ZcoinStorageError::GetFromStorageError("Invalid account/not found".to_string()))?; @@ -889,9 +1016,9 @@ impl WalletRead for WalletIndexedDb { async fn get_extended_full_viewing_keys(&self) -> Result, Self::Error> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let accounts_table = db_transaction.table::().await?; - let maybe_accounts = accounts_table.get_items("ticker", &self.ticker).await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let accounts_table = db_transaction.table::().await.map_mm_err()?; + let maybe_accounts = accounts_table.get_items("ticker", &self.ticker).await.map_mm_err()?; let mut res_accounts: HashMap = HashMap::with_capacity(maybe_accounts.len()); for (_, account) in maybe_accounts { @@ -916,13 +1043,18 @@ impl WalletRead for WalletIndexedDb { extfvk: &ExtendedFullViewingKey, ) -> Result { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let accounts_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let accounts_table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(WalletDbAccountsTable::TICKER_ACCOUNT_INDEX) - .with_value(&self.ticker)? - .with_value(account.0.to_bigint())?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(account.0.to_bigint()) + .map_mm_err()?; - let account = accounts_table.get_item_by_unique_multi_index(index_keys).await?; + let account = accounts_table + .get_item_by_unique_multi_index(index_keys) + .await + .map_mm_err()?; if let Some((_, account)) = account { let expected = @@ -938,28 +1070,39 @@ impl WalletRead for WalletIndexedDb { async fn get_balance_at(&self, account: AccountId, anchor_height: BlockHeight) -> Result { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; - let tx_table = db_transaction.table::().await?; + let tx_table = db_transaction.table::().await.map_mm_err()?; // Retrieves a list of transaction IDs (txid) from the transactions table // that match the provided account ID. let txids = tx_table .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("block", 0u32, u32::from(anchor_height)) .open_cursor(WalletDbTransactionsTable::TICKER_BLOCK_INDEX) - .await? + .await + .map_mm_err()? .collect() - .await? + .await + .map_mm_err()? .into_iter() .map(|(id, _)| id) .collect::>(); - let received_notes_table = db_transaction.table::().await?; + let received_notes_table = db_transaction + .table::() + .await + .map_mm_err()?; let index_keys = MultiIndex::new(WalletDbReceivedNotesTable::TICKER_ACCOUNT_INDEX) - .with_value(&self.ticker)? - .with_value(account.0.to_bigint().unwrap())?; - let maybe_notes = received_notes_table.get_items_by_multi_index(index_keys).await?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(account.0.to_bigint().unwrap()) + .map_mm_err()?; + let maybe_notes = received_notes_table + .get_items_by_multi_index(index_keys) + .await + .map_mm_err()?; let mut value: i64 = 0; for (_, note) in maybe_notes { @@ -980,20 +1123,23 @@ impl WalletRead for WalletIndexedDb { async fn get_memo(&self, id_note: Self::NoteRef) -> Result { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; let memo = match id_note { NoteId::SentNoteId(id_note) => { - let sent_notes_table = db_transaction.table::().await?; - let notes = sent_notes_table.get_items("ticker", &self.ticker).await?; + let sent_notes_table = db_transaction.table::().await.map_mm_err()?; + let notes = sent_notes_table.get_items("ticker", &self.ticker).await.map_mm_err()?; notes .into_iter() .find(|(id, _)| *id as i64 == id_note) .map(|(_, n)| n.memo) }, NoteId::ReceivedNoteId(id_note) => { - let received_notes_table = db_transaction.table::().await?; - let notes = received_notes_table.get_items("ticker", &self.ticker).await?; + let received_notes_table = db_transaction.table::().await.map_mm_err()?; + let notes = received_notes_table + .get_items("ticker", &self.ticker) + .await + .map_mm_err()?; notes .into_iter() .find(|(id, _)| *id as i64 == id_note) @@ -1015,15 +1161,18 @@ impl WalletRead for WalletIndexedDb { block_height: BlockHeight, ) -> Result>, Self::Error> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let blocks_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let blocks_table = db_transaction.table::().await.map_mm_err()?; let index_keys = MultiIndex::new(WalletDbBlocksTable::TICKER_HEIGHT_INDEX) - .with_value(&self.ticker)? - .with_value(u32::from(block_height))?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(u32::from(block_height)) + .map_mm_err()?; let block = blocks_table .get_item_by_unique_multi_index(index_keys) - .await? + .await + .map_mm_err()? .map(|(_, account)| account); if let Some(block) = block { @@ -1041,14 +1190,22 @@ impl WalletRead for WalletIndexedDb { block_height: BlockHeight, ) -> Result)>, Self::Error> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; - let sapling_witness_table = db_transaction.table::().await?; + let sapling_witness_table = db_transaction + .table::() + .await + .map_mm_err()?; let index_keys = MultiIndex::new(WalletDbSaplingWitnessesTable::TICKER_BLOCK_INDEX) - .with_value(&self.ticker)? - .with_value(u32::from(block_height))?; - let maybe_witnesses = sapling_witness_table.get_items_by_multi_index(index_keys).await?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(u32::from(block_height)) + .map_mm_err()?; + let maybe_witnesses = sapling_witness_table + .get_items_by_multi_index(index_keys) + .await + .map_mm_err()?; // Retrieves a list of transaction IDs (id_tx) from the transactions table // that match the provided account ID and have not been spent (spent IS NULL). @@ -1067,15 +1224,21 @@ impl WalletRead for WalletIndexedDb { async fn get_nullifiers(&self) -> Result, Self::Error> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; // Received notes - let received_notes_table = db_transaction.table::().await?; - let maybe_notes = received_notes_table.get_items("ticker", &self.ticker).await?; + let received_notes_table = db_transaction + .table::() + .await + .map_mm_err()?; + let maybe_notes = received_notes_table + .get_items("ticker", &self.ticker) + .await + .map_mm_err()?; // Transactions - let txs_table = db_transaction.table::().await?; - let maybe_txs = txs_table.get_items("ticker", &self.ticker).await?; + let txs_table = db_transaction.table::().await.map_mm_err()?; + let maybe_txs = txs_table.get_items("ticker", &self.ticker).await.map_mm_err()?; let mut nullifiers = vec![]; for (_, note) in maybe_notes { @@ -1107,38 +1270,55 @@ impl WalletRead for WalletIndexedDb { anchor_height: BlockHeight, ) -> Result, Self::Error> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; // Received notes - let received_notes_table = db_transaction.table::().await?; + let received_notes_table = db_transaction + .table::() + .await + .map_mm_err()?; let index_keys = MultiIndex::new(WalletDbReceivedNotesTable::TICKER_ACCOUNT_INDEX) - .with_value(&self.ticker)? - .with_value(account.0.to_bigint())?; - let maybe_notes = received_notes_table.get_items_by_multi_index(index_keys).await?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(account.0.to_bigint()) + .map_mm_err()?; + let maybe_notes = received_notes_table + .get_items_by_multi_index(index_keys) + .await + .map_mm_err()?; // Transactions - let txs_table = db_transaction.table::().await?; + let txs_table = db_transaction.table::().await.map_mm_err()?; let txs = txs_table .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("block", 0u32, u32::from(anchor_height + 1)) .open_cursor(WalletDbTransactionsTable::TICKER_BLOCK_INDEX) - .await? + .await + .map_mm_err()? .collect() - .await? + .await + .map_mm_err()? .into_iter() .map(|(i, item)| (i, item)) .collect::>(); // Witnesses - let witnesses_table = db_transaction.table::().await?; + let witnesses_table = db_transaction + .table::() + .await + .map_mm_err()?; let witnesses = witnesses_table .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("block", 0u32, u32::from(anchor_height + 1)) .open_cursor(WalletDbSaplingWitnessesTable::TICKER_BLOCK_INDEX) - .await? + .await + .map_mm_err()? .collect() - .await? + .await + .map_mm_err()? .into_iter() .map(|(_, item)| item) .collect::>(); @@ -1190,34 +1370,50 @@ impl WalletRead for WalletIndexedDb { // // 4) Match the selected notes against the witnesses at the desired height. let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; // Received notes - let received_notes_table = db_transaction.table::().await?; + let received_notes_table = db_transaction + .table::() + .await + .map_mm_err()?; let index_keys = MultiIndex::new(WalletDbReceivedNotesTable::TICKER_ACCOUNT_INDEX) - .with_value(&self.ticker)? - .with_value(account.0.to_bigint().unwrap())?; - let maybe_notes = received_notes_table.get_items_by_multi_index(index_keys).await?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(account.0.to_bigint().unwrap()) + .map_mm_err()?; + let maybe_notes = received_notes_table + .get_items_by_multi_index(index_keys) + .await + .map_mm_err()?; // Transactions - let db_transaction = locked_db.get_inner().transaction().await?; - let txs_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let txs_table = db_transaction.table::().await.map_mm_err()?; let txs = txs_table .cursor_builder() - .only("ticker", &self.ticker)? + .only("ticker", &self.ticker) + .map_mm_err()? .bound("block", 0u32, u32::from(anchor_height)) .open_cursor(WalletDbTransactionsTable::TICKER_BLOCK_INDEX) - .await? + .await + .map_mm_err()? .collect() - .await?; + .await + .map_mm_err()?; // Sapling Witness - let db_transaction = locked_db.get_inner().transaction().await?; - let witness_table = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let witness_table = db_transaction + .table::() + .await + .map_mm_err()?; let index_keys = MultiIndex::new(WalletDbSaplingWitnessesTable::TICKER_BLOCK_INDEX) - .with_value(&self.ticker)? - .with_value(u32::from(anchor_height))?; - let witnesses = witness_table.get_items_by_multi_index(index_keys).await?; + .with_value(&self.ticker) + .map_mm_err()? + .with_value(u32::from(anchor_height)) + .map_mm_err()?; + let witnesses = witness_table.get_items_by_multi_index(index_keys).await.map_mm_err()?; let mut running_sum = 0; let mut notes = vec![]; diff --git a/mm2src/coins/z_coin/storage/z_locked_notes/wasm.rs b/mm2src/coins/z_coin/storage/z_locked_notes/wasm.rs index dc72ca9d4e..1713ca3ea9 100644 --- a/mm2src/coins/z_coin/storage/z_locked_notes/wasm.rs +++ b/mm2src/coins/z_coin/storage/z_locked_notes/wasm.rs @@ -70,12 +70,12 @@ impl LockedNoteDbInner { impl LockedNotesStorage { async fn lockdb(&self) -> MmResult { - Ok(self.db.get_or_initialize().await?) + self.db.get_or_initialize().await.map_mm_err() } } impl LockedNotesStorage { - pub(crate) async fn new(ctx: &MmArc, address: String) -> Result { + pub(crate) async fn new(ctx: &MmArc, address: String) -> MmResult { let db = ConstructibleDb::new(ctx).into_shared(); Ok(Self { address, db }) } @@ -87,8 +87,8 @@ impl LockedNotesStorage { ) -> MmResult<(), LockedNotesStorageError> { let db = self.lockdb().await?; let address = self.address.clone(); - let transaction = db.get_inner().transaction().await?; - let change_note_table = transaction.table::().await?; + let transaction = db.get_inner().transaction().await.map_mm_err()?; + let change_note_table = transaction.table::().await.map_mm_err()?; let change_note = LockedNoteTable { address, @@ -97,10 +97,10 @@ impl LockedNotesStorage { rseed: Some(rseed), value: None, }; - Ok(change_note_table + change_note_table .add_item(&change_note) .await - .map(|_| ())?) + .map(|_| ()).map_mm_err() } pub(crate) async fn insert_change_note( @@ -110,8 +110,8 @@ impl LockedNotesStorage { ) -> MmResult<(), LockedNotesStorageError> { let db = self.lockdb().await?; let address = self.address.clone(); - let transaction = db.get_inner().transaction().await?; - let change_note_table = transaction.table::().await?; + let transaction = db.get_inner().transaction().await.map_mm_err()?; + let change_note_table = transaction.table::().await.map_mm_err()?; let change_note = LockedNoteTable { address, @@ -120,26 +120,26 @@ impl LockedNotesStorage { rseed: None, value: Some(value), }; - Ok(change_note_table + change_note_table .add_item(&change_note) .await - .map(|_| ())?) + .map(|_| ()).map_mm_err() } pub(crate) async fn remove_notes_for_txid(&self, txid: String) -> MmResult<(), LockedNotesStorageError> { let db = self.lockdb().await?; - let transaction = db.get_inner().transaction().await?; - let change_note_table = transaction.table::().await?; - change_note_table.delete_items_by_index("txid", &txid).await?; + let transaction = db.get_inner().transaction().await.map_mm_err()?; + let change_note_table = transaction.table::().await.map_mm_err()?; + change_note_table.delete_items_by_index("txid", &txid).await.map_mm_err()?; Ok(()) } pub(crate) async fn load_all_notes(&self) -> MmResult, LockedNotesStorageError> { let db = self.lockdb().await?; - let transaction = db.get_inner().transaction().await?; - let change_note_table = transaction.table::().await?; - let records = change_note_table.get_items("address", &self.address).await?; + let transaction = db.get_inner().transaction().await.map_mm_err()?; + let change_note_table = transaction.table::().await.map_mm_err()?; + let records = change_note_table.get_items("address", &self.address).await.map_mm_err()?; Ok(records .into_iter() .filter_map(|(_, n)| { diff --git a/mm2src/coins/z_coin/storage/z_params/indexeddb.rs b/mm2src/coins/z_coin/storage/z_params/indexeddb.rs index 91a2ec51b4..6822c89c5b 100644 --- a/mm2src/coins/z_coin/storage/z_params/indexeddb.rs +++ b/mm2src/coins/z_coin/storage/z_params/indexeddb.rs @@ -88,8 +88,8 @@ impl ZcashParamsWasmImpl { sapling_output: &[u8], ) -> MmResult<(), ZcoinStorageError> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let params_db = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let params_db = db_transaction.table::().await.map_mm_err()?; let params = ZcashParamsWasmTable { sapling_spend_id, sapling_spend: sapling_spend.to_vec(), @@ -97,20 +97,21 @@ impl ZcashParamsWasmImpl { ticker: CHAIN.to_string(), }; - Ok(params_db + params_db .replace_item_by_unique_index("sapling_spend_id", sapling_spend_id as u32, ¶ms) .await - .map(|_| ())?) + .map(|_| ()) + .map_mm_err() } /// Check if z_params is previously stored. pub(crate) async fn check_params(&self) -> MmResult { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let params_db = db_transaction.table::().await?; - let count = params_db.count_all().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let params_db = db_transaction.table::().await.map_mm_err()?; + let count = params_db.count_all().await.map_mm_err()?; if count != TARGET_SPEND_CHUNKS { - params_db.delete_items_by_index("ticker", CHAIN).await?; + params_db.delete_items_by_index("ticker", CHAIN).await.map_mm_err()?; } Ok(count == TARGET_SPEND_CHUNKS) @@ -119,18 +120,20 @@ impl ZcashParamsWasmImpl { /// Get z_params from storage. pub(crate) async fn get_params(&self) -> MmResult<(Vec, Vec), ZcoinStorageError> { let locked_db = self.lock_db().await?; - let db_transaction = locked_db.get_inner().transaction().await?; - let params_db = db_transaction.table::().await?; + let db_transaction = locked_db.get_inner().transaction().await.map_mm_err()?; + let params_db = db_transaction.table::().await.map_mm_err()?; let mut maybe_params = params_db .cursor_builder() - .only("ticker", CHAIN)? + .only("ticker", CHAIN) + .map_mm_err()? .open_cursor("ticker") - .await?; + .await + .map_mm_err()?; let mut sapling_spend = vec![]; let mut sapling_output = vec![]; - while let Some((_, params)) = maybe_params.next().await? { + while let Some((_, params)) = maybe_params.next().await.map_mm_err()? { sapling_spend.extend_from_slice(¶ms.sapling_spend); if params.sapling_spend_id == 0 { sapling_output = params.sapling_output diff --git a/mm2src/coins/z_coin/z_coin_errors.rs b/mm2src/coins/z_coin/z_coin_errors.rs index 23b1664a5b..df293b89ff 100644 --- a/mm2src/coins/z_coin/z_coin_errors.rs +++ b/mm2src/coins/z_coin/z_coin_errors.rs @@ -256,11 +256,6 @@ pub enum ZCoinBuildError { FailedSpawningBalanceEvents(String), } -#[cfg(not(target_arch = "wasm32"))] -impl From for ZCoinBuildError { - fn from(err: SqliteError) -> ZCoinBuildError { ZCoinBuildError::ZcashDBError(err.to_string()) } -} - impl From for ZCoinBuildError { fn from(err: UtxoRpcError) -> ZCoinBuildError { ZCoinBuildError::Rpc(err) } } diff --git a/mm2src/coins/z_coin/z_htlc.rs b/mm2src/coins/z_coin/z_htlc.rs index ffda1aba42..0d68f7258e 100644 --- a/mm2src/coins/z_coin/z_htlc.rs +++ b/mm2src/coins/z_coin/z_htlc.rs @@ -56,7 +56,7 @@ pub async fn z_send_htlc( .build() .map_to_mm(SendOutputsErr::InternalError)?; - let amount_sat = sat_from_big_decimal(&amount, coin.utxo_arc.decimals)?; + let amount_sat = sat_from_big_decimal(&amount, coin.utxo_arc.decimals).map_mm_err()?; let address = htlc_address.to_string(); if let UtxoRpcClientEnum::Native(native) = coin.utxo_rpc_client() { native.import_address(&address, &address, false).compat().await.unwrap(); @@ -91,7 +91,8 @@ pub async fn z_send_dex_fee( if matches!(dex_fee, DexFee::NoFee) { return MmError::err(SendOutputsErr::InternalError("unexpected DexFee::NoFee".to_string())); } - let dex_fee_amount_sat = sat_from_big_decimal(&dex_fee.fee_amount().to_decimal(), coin.utxo_arc.decimals)?; + let dex_fee_amount_sat = + sat_from_big_decimal(&dex_fee.fee_amount().to_decimal(), coin.utxo_arc.decimals).map_mm_err()?; // add dex fee output let dex_fee_out = ZOutput { to_addr: coin.z_fields.dex_fee_addr.clone(), @@ -102,7 +103,8 @@ pub async fn z_send_dex_fee( }; let mut outputs = vec![dex_fee_out]; if let Some(dex_burn_amount) = dex_fee.burn_amount() { - let dex_burn_amount_sat = sat_from_big_decimal(&dex_burn_amount.to_decimal(), coin.utxo_arc.decimals)?; + let dex_burn_amount_sat = + sat_from_big_decimal(&dex_burn_amount.to_decimal(), coin.utxo_arc.decimals).map_mm_err()?; // add output to the dex burn address: let dex_burn_out = ZOutput { to_addr: coin.z_fields.dex_burn_addr.clone(), @@ -166,7 +168,7 @@ pub async fn z_p2sh_spend( script_data: Script, htlc_keypair: &KeyPair, ) -> Result> { - let current_block = coin.utxo_arc.rpc_client.get_block_count().compat().await? as u32; + let current_block = coin.utxo_arc.rpc_client.get_block_count().compat().await.map_mm_err()? as u32; let mut tx_builder = ZTxBuilder::new(coin.consensus_params(), current_block.into()); tx_builder.set_lock_time(tx_locktime); diff --git a/mm2src/coins/z_coin/z_rpc.rs b/mm2src/coins/z_coin/z_rpc.rs index 9b35081f7c..4971c6bc5a 100644 --- a/mm2src/coins/z_coin/z_rpc.rs +++ b/mm2src/coins/z_coin/z_rpc.rs @@ -380,7 +380,7 @@ impl ZRpcOps for LightRpcClient { #[async_trait] impl ZRpcOps for NativeClient { async fn get_block_height(&self) -> Result> { - Ok(self.get_block_count().compat().await?) + Ok(self.get_block_count().compat().await.map_mm_err()?) } async fn get_tree_state(&self, _height: u64) -> Result> { todo!() } @@ -393,13 +393,13 @@ impl ZRpcOps for NativeClient { handler: &mut SaplingSyncLoopHandle, ) -> Result<(), MmError> { for height in start_block..=last_block { - let block = self.get_block_by_height(height).await?; + let block = self.get_block_by_height(height).await.map_mm_err()?; debug!("Got block {:?}", block); let mut compact_txs = Vec::with_capacity(block.tx.len()); // By default, CompactBlocks only contain CompactTxs for transactions that contain Sapling spends or outputs. // Create and push compact_tx during iteration. for (tx_id, hash_tx) in block.tx.iter().enumerate() { - let tx_bytes = self.get_transaction_bytes(hash_tx).compat().await?; + let tx_bytes = self.get_transaction_bytes(hash_tx).compat().await.map_mm_err()?; let tx = ZTransaction::read(tx_bytes.as_slice()).unwrap(); let mut spends = Vec::new(); let mut outputs = Vec::new(); @@ -514,7 +514,7 @@ pub(super) async fn init_light_client<'a>( let light_rpc_clients = LightRpcClient::new(lightwalletd_urls).await?; - let min_height = blocks_db.get_earliest_block().await? as u64; + let min_height = blocks_db.get_earliest_block().await.map_mm_err()? as u64; let current_block_height = light_rpc_clients .get_block_height() .await @@ -534,19 +534,24 @@ pub(super) async fn init_light_client<'a>( }; let maybe_checkpoint_block = light_rpc_clients .checkpoint_block_from_height(sync_height.max(sapling_activation_height), &coin) - .await?; + .await + .map_mm_err()?; // check if no sync_params was provided and continue syncing from last height in db if it's > 0 or skip_sync_params is true. let continue_from_prev_sync = (min_height > 0 && sync_params.is_none()) || (skip_sync_params && min_height < sapling_activation_height); - let wallet_db = WalletDbShared::new(builder, maybe_checkpoint_block, continue_from_prev_sync).await?; + + let wallet_db = WalletDbShared::new(builder, maybe_checkpoint_block, continue_from_prev_sync) + .await + .map_mm_err()?; + // Check min_height in blocks_db and rewind blocks_db to 0 if sync_height != min_height if !continue_from_prev_sync && (sync_height != min_height) { // let user know we're clearing cache and re-syncing from new provided height. if min_height > 0 { info!("Older/Newer sync height detected!, rewinding blocks_db to new height: {sync_height:?}"); } - blocks_db.rewind_to_height(u32::MIN.into()).await?; + blocks_db.rewind_to_height(u32::MIN.into()).await.map_mm_err()?; }; let first_sync_block = FirstSyncBlock { @@ -771,9 +776,13 @@ impl SaplingSyncLoopHandle { async fn update_blocks_cache(&mut self, rpc: &dyn ZRpcOps) -> Result<(), MmError> { let current_block = rpc.get_block_height().await?; let block_db = self.blocks_db.clone(); - let current_block_in_db = &self.blocks_db.get_latest_block().await?; + let current_block_in_db = &self.blocks_db.get_latest_block().await.map_mm_err()?; let wallet_db = self.wallet_db.clone(); - let extrema = wallet_db.db.block_height_extrema().await?; + let extrema = wallet_db + .db + .block_height_extrema() + .await + .map_err(|err| MmError::new(UpdateBlocksCacheErr::ZcashDBError(err.to_string())))?; let mut from_block = self .consensus_params .sapling_activation_height @@ -784,7 +793,9 @@ impl SaplingSyncLoopHandle { } if current_block >= from_block { - rpc.scan_blocks(from_block, current_block, &block_db, self).await?; + rpc.scan_blocks(from_block, current_block, &block_db, self) + .await + .map_mm_err()?; } self.current_block = BlockHeight::from_u32(current_block as u32); diff --git a/mm2src/coins/z_coin/z_tx_history.rs b/mm2src/coins/z_coin/z_tx_history.rs index 7c442cc676..7061fbca6b 100644 --- a/mm2src/coins/z_coin/z_tx_history.rs +++ b/mm2src/coins/z_coin/z_tx_history.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use crate::z_coin::{ZCoin, ZTxHistoryError}; use common::PagingOptionsEnum; -use mm2_err_handle::prelude::MmError; +use mm2_err_handle::prelude::*; use primitives::hash::H256; use std::convert::TryInto; use zcash_primitives::transaction::TxId; @@ -12,7 +12,6 @@ cfg_wasm32!( use crate::MarketCoinOps; use mm2_number::BigInt; use mm2_db::indexed_db::cursor_prelude::CursorError; - use mm2_err_handle::prelude::MapToMmResult; use num_traits::ToPrimitive; ); @@ -53,9 +52,9 @@ pub(crate) async fn fetch_tx_history_from_db( ) -> Result> { let wallet_db = z.z_fields.light_wallet_db.clone(); let wallet_db = wallet_db.db.lock_db().await.unwrap(); - let db_transaction = wallet_db.get_inner().transaction().await?; - let tx_table = db_transaction.table::().await?; - let total_tx_count = tx_table.count_all().await? as u32; + let db_transaction = wallet_db.get_inner().transaction().await.map_mm_err()?; + let tx_table = db_transaction.table::().await.map_mm_err()?; + let total_tx_count = tx_table.count_all().await.map_mm_err()? as u32; let offset = match paging_options { PagingOptionsEnum::PageNumber(page_number) => ((page_number.get() - 1) * limit) as i64, PagingOptionsEnum::FromId(tx_id) => { @@ -69,34 +68,46 @@ pub(crate) async fn fetch_tx_history_from_db( // Fetch transactions let txs = tx_table .cursor_builder() - .only("ticker", z.ticker())? + .only("ticker", z.ticker()) + .map_mm_err()? .offset(offset as u32) .limit(limit) .reverse() .open_cursor("ticker") - .await? + .await + .map_mm_err()? .collect() - .await?; + .await + .map_mm_err()?; // Fetch received notes - let rn_table = db_transaction.table::().await?; + let rn_table = db_transaction + .table::() + .await + .map_mm_err()?; let received_notes = rn_table .cursor_builder() - .only("ticker", z.ticker())? + .only("ticker", z.ticker()) + .map_mm_err()? .open_cursor("ticker") - .await? + .await + .map_mm_err()? .collect() - .await?; + .await + .map_mm_err()?; // Fetch blocks - let blocks_table = db_transaction.table::().await?; + let blocks_table = db_transaction.table::().await.map_mm_err()?; let blocks = blocks_table .cursor_builder() - .only("ticker", z.ticker())? + .only("ticker", z.ticker()) + .map_mm_err()? .open_cursor("ticker") - .await? + .await + .map_mm_err()? .collect() - .await?; + .await + .map_mm_err()?; // Process transactions and construct tx_details let mut tx_details = Vec::new(); @@ -250,8 +261,8 @@ pub(crate) async fn fetch_txs_from_db( ) -> Result, MmError> { let wallet_db = z.z_fields.light_wallet_db.clone(); let wallet_db = wallet_db.db.lock_db().await.unwrap(); - let db_transaction = wallet_db.get_inner().transaction().await?; - let tx_table = db_transaction.table::().await?; + let db_transaction = wallet_db.get_inner().transaction().await.map_mm_err()?; + let tx_table = db_transaction.table::().await.map_mm_err()?; let limit = tx_hashes.len(); let condition = { @@ -267,36 +278,48 @@ pub(crate) async fn fetch_txs_from_db( // Fetch transactions let txs = tx_table .cursor_builder() - .only("ticker", z.ticker())? + .only("ticker", z.ticker()) + .map_mm_err()? // We need to explicitly set a limit since `where_` implicitly sets a limit of 1 if no limit is set. // TODO: Remove when `where_` doesn't exhibit this behavior. .limit(limit) .where_(condition) .reverse() .open_cursor("ticker") - .await? + .await + .map_mm_err()? .collect() - .await?; + .await + .map_mm_err()?; // Fetch received notes - let rn_table = db_transaction.table::().await?; + let rn_table = db_transaction + .table::() + .await + .map_mm_err()?; let received_notes = rn_table .cursor_builder() - .only("ticker", z.ticker())? + .only("ticker", z.ticker()) + .map_mm_err()? .open_cursor("ticker") - .await? + .await + .map_mm_err()? .collect() - .await?; + .await + .map_mm_err()?; // Fetch blocks - let blocks_table = db_transaction.table::().await?; + let blocks_table = db_transaction.table::().await.map_mm_err()?; let blocks = blocks_table .cursor_builder() - .only("ticker", z.ticker())? + .only("ticker", z.ticker()) + .map_mm_err()? .open_cursor("ticker") - .await? + .await + .map_mm_err()? .collect() - .await?; + .await + .map_mm_err()?; // Process transactions and construct tx_details let mut transactions = Vec::new(); diff --git a/mm2src/coins_activation/src/bch_with_tokens_activation.rs b/mm2src/coins_activation/src/bch_with_tokens_activation.rs index b38c1bee36..289c0785a6 100644 --- a/mm2src/coins_activation/src/bch_with_tokens_activation.rs +++ b/mm2src/coins_activation/src/bch_with_tokens_activation.rs @@ -226,7 +226,7 @@ impl PlatformCoinWithTokensActivationOps for BchCoin { activation_request: Self::ActivationRequest, protocol_conf: Self::PlatformProtocolInfo, ) -> Result> { - let priv_key_policy = PrivKeyBuildPolicy::detect_priv_key_policy(&ctx)?; + let priv_key_policy = PrivKeyBuildPolicy::detect_priv_key_policy(&ctx).map_mm_err::()?; let slp_prefix = CashAddrPrefix::from_str(&protocol_conf.slp_prefix).map_to_mm(|error| { BchWithTokensActivationError::InvalidSlpPrefix { @@ -245,7 +245,9 @@ impl PlatformCoinWithTokensActivationOps for BchCoin { priv_key_policy, ) .await - .map_to_mm(|error| BchWithTokensActivationError::PlatformCoinCreationError { ticker, error })?; + .map_to_mm(|error| BchWithTokensActivationError::PlatformCoinCreationError { ticker, error }) + .map_mm_err::()?; + Ok(platform_coin) } @@ -280,26 +282,53 @@ impl PlatformCoinWithTokensActivationOps for BchCoin { activation_request: &Self::ActivationRequest, _nft_global: &Option, ) -> Result> { - let current_block = self.as_ref().rpc_client.get_block_count().compat().await?; + let current_block = self + .as_ref() + .rpc_client + .get_block_count() + .compat() + .await + .map_mm_err::()?; - let my_address = self.as_ref().derivation_method.single_addr_or_err().await?; + let my_address = self + .as_ref() + .derivation_method + .single_addr_or_err() + .await + .map_mm_err::()?; let my_slp_address = self .get_my_slp_address() .await - .map_to_mm(BchWithTokensActivationError::Internal)? + .map_to_mm(BchWithTokensActivationError::Internal) + .map_mm_err::()? .encode() - .map_to_mm(BchWithTokensActivationError::Internal)?; - let pubkey = self.my_public_key()?.to_string(); + .map_to_mm(BchWithTokensActivationError::Internal) + .map_mm_err::()?; + + let pubkey = self + .my_public_key() + .map_mm_err::()? + .to_string(); let mut bch_address_info = CoinAddressInfo { - derivation_method: self.as_ref().derivation_method.to_response().await?, + derivation_method: self + .as_ref() + .derivation_method + .to_response() + .await + .map_mm_err::()?, pubkey: pubkey.clone(), balances: None, tickers: None, }; let mut slp_address_info = CoinAddressInfo { - derivation_method: self.as_ref().derivation_method.to_response().await?, + derivation_method: self + .as_ref() + .derivation_method + .to_response() + .await + .map_mm_err::()?, pubkey: pubkey.clone(), balances: None, tickers: None, @@ -318,7 +347,10 @@ impl PlatformCoinWithTokensActivationOps for BchCoin { }); } - let bch_unspents = self.bch_unspents_for_display(&my_address).await?; + let bch_unspents = self + .bch_unspents_for_display(&my_address) + .await + .map_mm_err::()?; bch_address_info.balances = Some(bch_unspents.platform_balance(self.decimals())); drop_mutability!(bch_address_info); diff --git a/mm2src/coins_activation/src/erc20_token_activation.rs b/mm2src/coins_activation/src/erc20_token_activation.rs index c73672d9e8..aa9d66ddeb 100644 --- a/mm2src/coins_activation/src/erc20_token_activation.rs +++ b/mm2src/coins_activation/src/erc20_token_activation.rs @@ -150,9 +150,15 @@ impl TokenActivationOps for EthCoin { erc20_protocol, is_custom, ) - .await?; + .await + .map_mm_err::()?; - let address = token.derivation_method().single_addr_or_err().await?.display_address(); + let address = token + .derivation_method() + .single_addr_or_err() + .await + .map_mm_err::()? + .display_address(); let token_contract_address = token.erc20_token_address().ok_or_else(|| { EthTokenActivationError::InternalError("Token contract address is missing".to_string()) })?; @@ -186,9 +192,10 @@ impl TokenActivationOps for EthCoin { )); } let nft_global = match &nft_init_params.provider { - NftProviderEnum::Moralis { url, komodo_proxy } => { - platform_coin.initialize_global_nft(url, *komodo_proxy).await? - }, + NftProviderEnum::Moralis { url, komodo_proxy } => platform_coin + .initialize_global_nft(url, *komodo_proxy) + .await + .map_mm_err::()?, }; let nfts = nft_global.nfts_infos.lock().await.clone(); let init_result = EthTokenInitResult::Nft(NftInitResult { diff --git a/mm2src/coins_activation/src/eth_with_token_activation.rs b/mm2src/coins_activation/src/eth_with_token_activation.rs index 95b74f71a4..b1fdf3a782 100644 --- a/mm2src/coins_activation/src/eth_with_token_activation.rs +++ b/mm2src/coins_activation/src/eth_with_token_activation.rs @@ -311,7 +311,10 @@ impl PlatformCoinWithTokensActivationOps for EthCoin { }, None => return Ok(None), }; - let nft_global = self.initialize_global_nft(url, proxy_auth).await?; + let nft_global = self + .initialize_global_nft(url, proxy_auth) + .await + .map_mm_err::()?; Ok(Some(MmCoinEnum::EthCoin(nft_global))) } @@ -353,15 +356,15 @@ impl PlatformCoinWithTokensActivationOps for EthCoin { match self.derivation_method() { DerivationMethod::SingleAddress(my_address) => { - let pubkey = self.get_public_key().await?; + let pubkey = self.get_public_key().await.map_mm_err()?; let mut eth_address_info = CoinAddressInfo { - derivation_method: self.derivation_method().to_response().await?, + derivation_method: self.derivation_method().to_response().await.map_mm_err()?, pubkey: pubkey.clone(), balances: None, tickers: None, }; let mut erc20_address_info = CoinAddressInfo { - derivation_method: self.derivation_method().to_response().await?, + derivation_method: self.derivation_method().to_response().await.map_mm_err()?, pubkey, balances: None, tickers: None, @@ -441,7 +444,8 @@ impl PlatformCoinWithTokensActivationOps for EthCoin { activation_request.platform_request.enable_params.clone(), &activation_request.platform_request.path_to_address, ) - .await?; + .await + .map_mm_err()?; Ok(EthWithTokensActivationResult::HD(HDEthWithTokensActivationResult { current_block, @@ -474,10 +478,13 @@ async fn eth_priv_key_build_policy( protocol: &ChainSpec, ) -> MmResult { match activation_policy { - EthPrivKeyActivationPolicy::ContextPrivKey => Ok(EthPrivKeyBuildPolicy::detect_priv_key_policy(ctx)?), + EthPrivKeyActivationPolicy::ContextPrivKey => { + Ok(EthPrivKeyBuildPolicy::detect_priv_key_policy(ctx).map_mm_err::()?) + }, #[cfg(target_arch = "wasm32")] EthPrivKeyActivationPolicy::Metamask => { - let metamask_ctx = crypto::CryptoCtx::from_ctx(ctx)? + let metamask_ctx = crypto::CryptoCtx::from_ctx(ctx) + .map_mm_err()? .metamask_ctx() .or_mm_err(|| EthActivationV2Error::MetamaskError(MetamaskRpcError::MetamaskCtxNotInitialized))?; Ok(EthPrivKeyBuildPolicy::Metamask(metamask_ctx)) diff --git a/mm2src/coins_activation/src/init_erc20_token_activation.rs b/mm2src/coins_activation/src/init_erc20_token_activation.rs index f162cb1754..491947e8bf 100644 --- a/mm2src/coins_activation/src/init_erc20_token_activation.rs +++ b/mm2src/coins_activation/src/init_erc20_token_activation.rs @@ -138,7 +138,8 @@ impl InitTokenActivationOps for EthCoin { protocol_conf, is_custom, ) - .await?; + .await + .map_mm_err()?; Ok(token) } @@ -156,7 +157,8 @@ impl InitTokenActivationOps for EthCoin { .current_block() .compat() .await - .map_to_mm(EthTokenActivationError::Transport)?; + .map_to_mm(EthTokenActivationError::Transport) + .map_mm_err()?; let xpub_extractor = if self.is_trezor() { Some( @@ -172,15 +174,20 @@ impl InitTokenActivationOps for EthCoin { None }; - task_handle.update_in_progress_status(InitTokenInProgressStatus::RequestingWalletBalance)?; + task_handle + .update_in_progress_status(InitTokenInProgressStatus::RequestingWalletBalance) + .map_mm_err()?; let wallet_balance = self .enable_coin_balance( xpub_extractor, activation_request.enable_params.clone(), &activation_request.path_to_address, ) - .await?; - task_handle.update_in_progress_status(InitTokenInProgressStatus::ActivatingCoin)?; + .await + .map_mm_err()?; + task_handle + .update_in_progress_status(InitTokenInProgressStatus::ActivatingCoin) + .map_mm_err()?; let token_contract_address = self .erc20_token_address() diff --git a/mm2src/coins_activation/src/init_token.rs b/mm2src/coins_activation/src/init_token.rs index 6b32f83622..2ed7b7b80d 100644 --- a/mm2src/coins_activation/src/init_token.rs +++ b/mm2src/coins_activation/src/init_token.rs @@ -12,7 +12,7 @@ use crypto::hw_rpc_task::{HwConnectStatuses, HwRpcTaskAwaitingStatus, HwRpcTaskU use crypto::HwRpcError; use derive_more::Display; use mm2_core::mm_ctx::MmArc; -use mm2_err_handle::mm_error::{MmError, MmResult, NotEqual, NotMmError}; +use mm2_err_handle::mm_error::{MmError, MmResult, NotMmError}; use mm2_err_handle::prelude::*; use rpc_task::rpc_common::{CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError, RpcTaskStatusRequest, RpcTaskUserActionError, RpcTaskUserActionRequest}; @@ -49,13 +49,7 @@ pub trait InitTokenActivationOps: Into + TokenOf + Clone + Send + Sy type ActivationRequest: Clone + Send + Sync; type ProtocolInfo: TokenProtocolParams + TryFromCoinProtocol + Clone + Send + Sync; type ActivationResult: CurrentBlock + serde::Serialize + Clone + Send + Sync; - type ActivationError: From - + Into - + NotEqual - + SerMmErrorType - + Clone - + Send - + Sync; + type ActivationError: From + Into + SerMmErrorType + Clone + Send + Sync; type InProgressStatus: InitTokenInitialStatus + serde::Serialize + Clone + Send + Sync; type AwaitingStatus: serde::Serialize + Clone + Send + Sync; type UserAction: NotMmError + Send + Sync; @@ -93,7 +87,6 @@ where Token: InitTokenActivationOps + Send + Sync + 'static, Token::InProgressStatus: InitTokenInitialStatus, InitTokenError: From, - (Token::ActivationError, InitTokenError): NotEqual, { let (client_id, request) = (request.client_id, request.inner); if let Ok(Some(_)) = lp_coinfind(&ctx, &request.ticker).await { @@ -101,7 +94,7 @@ where } let (token_conf, token_protocol): (_, Token::ProtocolInfo) = - coin_conf_with_protocol(&ctx, &request.ticker, request.protocol.clone())?; + coin_conf_with_protocol(&ctx, &request.ticker, request.protocol.clone()).map_mm_err::()?; let platform_coin = lp_coinfind_or_err(&ctx, token_protocol.platform_coin_ticker()) .await @@ -113,7 +106,9 @@ where token_ticker: request.ticker.clone(), })?; - let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx).map_to_mm(InitTokenError::Internal)?; + let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) + .map_to_mm(InitTokenError::Internal) + .map_mm_err::()?; let spawner = ctx.spawner(); let task = InitTokenTask:: { ctx, @@ -160,7 +155,9 @@ pub async fn init_token_user_action( let mut task_manager = Token::rpc_task_manager(&coins_act_ctx) .lock() .map_to_mm(|poison| InitTokenUserActionError::Internal(poison.to_string()))?; - task_manager.on_user_action(req.task_id, req.user_action)?; + task_manager + .on_user_action(req.task_id, req.user_action) + .map_mm_err::()?; Ok(SuccessResponse::new()) } @@ -173,7 +170,9 @@ pub async fn cancel_init_token( let mut task_manager = Standalone::rpc_task_manager(&coins_act_ctx) .lock() .map_to_mm(|poison| CancelInitTokenError::Internal(poison.to_string()))?; - task_manager.cancel_task(req.task_id)?; + task_manager + .cancel_task(req.task_id) + .map_mm_err::()?; Ok(SuccessResponse::new()) } @@ -237,7 +236,10 @@ where log::info!("{} current block {}", ticker, activation_result.current_block()); let coins_ctx = CoinsContext::from_ctx(&self.ctx).unwrap(); - coins_ctx.add_token(token.clone().into()).await?; + coins_ctx + .add_token(token.clone().into()) + .await + .map_mm_err::()?; self.platform_coin.register_token_info(&token); diff --git a/mm2src/coins_activation/src/l2/init_l2.rs b/mm2src/coins_activation/src/l2/init_l2.rs index 3dd3276ec6..5271cd36f2 100644 --- a/mm2src/coins_activation/src/l2/init_l2.rs +++ b/mm2src/coins_activation/src/l2/init_l2.rs @@ -39,7 +39,7 @@ pub trait InitL2ActivationOps: Into + Send + Sync + 'static { type ValidatedParams: Clone + Send + Sync; type CoinConf: Clone + Send + Sync; type ActivationResult: serde::Serialize + Clone + Send + Sync; - type ActivationError: From + NotEqual + SerMmErrorType + Clone + Send + Sync; + type ActivationError: From + SerMmErrorType + Clone + Send + Sync; type InProgressStatus: InitL2InitialStatus + serde::Serialize + Clone + Send + Sync; type AwaitingStatus: serde::Serialize + Clone + Send + Sync; type UserAction: NotMmError + Send + Sync; @@ -73,7 +73,6 @@ pub async fn init_l2( where L2: InitL2ActivationOps, InitL2Error: From, - (L2::ActivationError, InitL2Error): NotEqual, { let (client_id, req) = (req.client_id, req.inner); let ticker = req.ticker.clone(); @@ -81,8 +80,9 @@ where return MmError::err(InitL2Error::L2IsAlreadyActivated(ticker)); } - let (coin_conf_json, protocol_conf): (Json, L2::ProtocolInfo) = coin_conf_with_protocol(&ctx, &ticker, None)?; - let coin_conf = L2::coin_conf_from_json(coin_conf_json)?; + let (coin_conf_json, protocol_conf): (Json, L2::ProtocolInfo) = + coin_conf_with_protocol(&ctx, &ticker, None).map_mm_err::()?; + let coin_conf = L2::coin_conf_from_json(coin_conf_json).map_mm_err::()?; let platform_coin = lp_coinfind_or_err(&ctx, protocol_conf.platform_coin_ticker()) .await @@ -94,11 +94,13 @@ where l2_ticker: ticker.clone(), })?; - L2::validate_platform_configuration(&platform_coin)?; + L2::validate_platform_configuration(&platform_coin).map_mm_err::()?; - let validated_params = L2::validate_activation_params(req.activation_params.clone())?; + let validated_params = L2::validate_activation_params(req.activation_params.clone()).map_mm_err::()?; - let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx).map_to_mm(InitL2Error::Internal)?; + let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) + .map_to_mm(InitL2Error::Internal) + .map_mm_err::()?; let spawner = ctx.spawner(); let task = InitL2Task:: { ctx, @@ -126,7 +128,9 @@ pub async fn init_l2_status( where InitL2Error: From, { - let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx).map_to_mm(InitL2StatusError::Internal)?; + let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) + .map_to_mm(InitL2StatusError::Internal) + .map_mm_err::()?; let mut task_manager = L2::rpc_task_manager(&coins_act_ctx) .lock() .map_to_mm(|poison| InitL2StatusError::Internal(poison.to_string()))?; @@ -140,11 +144,15 @@ pub async fn init_l2_user_action( ctx: MmArc, req: InitL2UserActionRequest, ) -> MmResult { - let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx).map_to_mm(InitL2UserActionError::Internal)?; + let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) + .map_to_mm(InitL2UserActionError::Internal) + .map_mm_err::()?; let mut task_manager = L2::rpc_task_manager(&coins_act_ctx) .lock() .map_to_mm(|poison| InitL2UserActionError::Internal(poison.to_string()))?; - task_manager.on_user_action(req.task_id, req.user_action)?; + task_manager + .on_user_action(req.task_id, req.user_action) + .map_mm_err::()?; Ok(SuccessResponse::new()) } @@ -152,11 +160,14 @@ pub async fn cancel_init_l2( ctx: MmArc, req: CancelRpcTaskRequest, ) -> MmResult { - let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx).map_to_mm(CancelInitL2Error::Internal)?; + let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) + .map_to_mm(CancelInitL2Error::Internal) + .map_mm_err::()?; let mut task_manager = L2::rpc_task_manager(&coins_act_ctx) .lock() - .map_to_mm(|poison| CancelInitL2Error::Internal(poison.to_string()))?; - task_manager.cancel_task(req.task_id)?; + .map_to_mm(|poison| CancelInitL2Error::Internal(poison.to_string())) + .map_mm_err::()?; + task_manager.cancel_task(req.task_id).map_mm_err()?; Ok(SuccessResponse::new()) } @@ -205,8 +216,10 @@ where ) .await?; - let c_ctx = CoinsContext::from_ctx(&self.ctx).map_to_mm(RegisterCoinError::Internal)?; - c_ctx.add_l2(coin.into()).await?; + let c_ctx = CoinsContext::from_ctx(&self.ctx) + .map_to_mm(RegisterCoinError::Internal) + .map_mm_err()?; + c_ctx.add_l2(coin.into()).await.map_mm_err()?; Ok(result) } diff --git a/mm2src/coins_activation/src/lightning_activation.rs b/mm2src/coins_activation/src/lightning_activation.rs index 105fb2c422..e4a1a080ad 100644 --- a/mm2src/coins_activation/src/lightning_activation.rs +++ b/mm2src/coins_activation/src/lightning_activation.rs @@ -277,7 +277,8 @@ impl InitL2ActivationOps for LightningCoin { activation_params.color.unwrap_or_else(|| "000000".into()), &mut node_color as &mut [u8], ) - .map_to_mm(|_| LightningValidationErr::InvalidRequest("Invalid Hex Color".into()))?; + .map_to_mm(|_| LightningValidationErr::InvalidRequest("Invalid Hex Color".into())) + .map_mm_err()?; let listening_port = activation_params.listening_port.unwrap_or(DEFAULT_LISTENING_PORT); @@ -306,10 +307,11 @@ impl InitL2ActivationOps for LightningCoin { validated_params, task_handle, ) - .await?; + .await + .map_mm_err()?; Timer::sleep(10.).await; - let address = lightning_coin.my_address()?; + let address = lightning_coin.my_address().map_mm_err()?; let balance = lightning_coin .my_balance() .compat() @@ -345,8 +347,10 @@ async fn start_lightning( protocol_conf.network.clone(), protocol_conf.confirmation_targets, )?); - task_handle.update_in_progress_status(LightningInProgressStatus::GettingFeesFromRPC)?; - platform.set_latest_fees().await?; + task_handle + .update_in_progress_status(LightningInProgressStatus::GettingFeesFromRPC) + .map_mm_err()?; + platform.set_latest_fees().await.map_mm_err()?; // Initialize the Logger let logger = ctx.log.0.clone(); @@ -363,7 +367,9 @@ async fn start_lightning( let persister = init_persister(ctx, &node_id, conf.ticker.clone(), params.backup_path).await?; // Initialize the P2PGossipSync. This is used for providing routes to send payments over - task_handle.update_in_progress_status(LightningInProgressStatus::ReadingNetworkGraphFromFile)?; + task_handle + .update_in_progress_status(LightningInProgressStatus::ReadingNetworkGraphFromFile) + .map_mm_err()?; let network_graph = Arc::new( persister .get_network_graph(protocol_conf.network.into(), logger.clone()) @@ -380,7 +386,9 @@ async fn start_lightning( let db = init_db(ctx, &node_id, conf.ticker.clone()).await?; // Initialize the ChannelManager - task_handle.update_in_progress_status(LightningInProgressStatus::InitializingChannelManager)?; + task_handle + .update_in_progress_status(LightningInProgressStatus::InitializingChannelManager) + .map_mm_err()?; let (chain_monitor, channel_manager) = init_channel_manager( platform.clone(), logger.clone(), @@ -392,7 +400,9 @@ async fn start_lightning( .await?; // Initialize the PeerManager - task_handle.update_in_progress_status(LightningInProgressStatus::InitializingPeerManager)?; + task_handle + .update_in_progress_status(LightningInProgressStatus::InitializingPeerManager) + .map_mm_err()?; let peer_manager = init_peer_manager( ctx.clone(), &platform, @@ -418,7 +428,9 @@ async fn start_lightning( )); // Initialize routing Scorer - task_handle.update_in_progress_status(LightningInProgressStatus::ReadingScorerFromFile)?; + task_handle + .update_in_progress_status(LightningInProgressStatus::ReadingScorerFromFile) + .map_mm_err()?; // status_notifier // .try_send(LightningInProgressStatus::ReadingScorerFromFile) // .debug_log_with_msg("No one seems interested in LightningInProgressStatus"); @@ -451,7 +463,9 @@ async fn start_lightning( // InvoicePayer will act as our event handler as it handles some of the payments related events before // delegating it to LightningEventHandler. // note: background_processor stops automatically when dropped since BackgroundProcessor implements the Drop trait. - task_handle.update_in_progress_status(LightningInProgressStatus::InitializingBackgroundProcessor)?; + task_handle + .update_in_progress_status(LightningInProgressStatus::InitializingBackgroundProcessor) + .map_mm_err()?; let background_processor = Arc::new(BackgroundProcessor::start( persister.clone(), invoice_payer.clone(), @@ -464,7 +478,9 @@ async fn start_lightning( )); // If channel_nodes_data file exists, read channels nodes data from disk and reconnect to channel nodes/peers if possible. - task_handle.update_in_progress_status(LightningInProgressStatus::ReadingChannelsAddressesFromFile)?; + task_handle + .update_in_progress_status(LightningInProgressStatus::ReadingChannelsAddressesFromFile) + .map_mm_err()?; let open_channels_nodes = Arc::new(PaMutex::new( get_open_channels_nodes_addresses(persister.clone(), channel_manager.clone()).await?, )); diff --git a/mm2src/coins_activation/src/platform_coin_with_tokens.rs b/mm2src/coins_activation/src/platform_coin_with_tokens.rs index 24a1aca710..a53223f1ff 100644 --- a/mm2src/coins_activation/src/platform_coin_with_tokens.rs +++ b/mm2src/coins_activation/src/platform_coin_with_tokens.rs @@ -127,7 +127,6 @@ impl TokenAsMmCoinInitializer for T where T: TokenInitializer + Send + Sync, InitTokensAsMmCoinsError: From, - (T::InitTokensError, InitTokensAsMmCoinsError): NotEqual, { type PlatformCoin = ::PlatformCoin; type ActivationRequest = ::ActivationRequest; @@ -150,9 +149,13 @@ where is_custom: req.protocol.is_some(), }) }) - .collect::, _>>()?; + .collect::, _>>() + .map_mm_err::()?; - let tokens = self.enable_tokens(token_params).await?; + let tokens = self + .enable_tokens(token_params) + .await + .map_mm_err::()?; for token in tokens.iter() { self.platform_coin().register_token_info(token); } @@ -169,13 +172,7 @@ pub trait PlatformCoinWithTokensActivationOps: Into + Clone + Send + type ActivationRequest: Clone + Send + Sync + TxHistory + ActivationRequestInfo; type PlatformProtocolInfo: TryFromCoinProtocol + Send; type ActivationResult: GetPlatformBalance + CurrentBlock + serde::Serialize + Send + Clone + Sync + 'static; - type ActivationError: NotMmError - + std::fmt::Debug - + NotEqual - + Into - + Clone - + Send - + Sync; + type ActivationError: NotMmError + std::fmt::Debug + Into + Clone + Send + Sync; type InProgressStatus: InitPlatformCoinWithTokensInitialStatus + serde::Serialize + Clone + Send + Sync; type AwaitingStatus: serde::Serialize + Clone + Send + Sync; @@ -391,19 +388,25 @@ pub async fn re_enable_passive_platform_coin_with_tokens( where Platform: PlatformCoinWithTokensActivationOps + Clone, EnablePlatformCoinWithTokensError: From, - (Platform::ActivationError, EnablePlatformCoinWithTokensError): NotEqual, { let mut mm_tokens = Vec::new(); for initializer in platform_coin.token_initializers() { - let tokens = initializer.enable_tokens_as_mm_coins(&ctx, &req.request).await?; + let tokens = initializer + .enable_tokens_as_mm_coins(&ctx, &req.request) + .await + .map_mm_err()?; mm_tokens.extend(tokens); } - let nft_global = platform_coin.enable_global_nft(&req.request).await?; + let nft_global = platform_coin + .enable_global_nft(&req.request) + .await + .map_mm_err::()?; let activation_result = platform_coin .get_activation_result(task_handle, &req.request, &nft_global) - .await?; + .await + .map_mm_err::()?; log::info!("{} current block {}", req.ticker, activation_result.current_block()); let coins_ctx = CoinsContext::from_ctx(&ctx).unwrap(); @@ -422,7 +425,6 @@ pub async fn enable_platform_coin_with_tokens( where Platform: PlatformCoinWithTokensActivationOps, EnablePlatformCoinWithTokensError: From, - (Platform::ActivationError, EnablePlatformCoinWithTokensError): NotEqual, { if req.request.is_hw_policy() { return MmError::err(EnablePlatformCoinWithTokensError::UnexpectedDeviceActivationPolicy); @@ -438,7 +440,6 @@ pub async fn enable_platform_coin_with_tokens_impl( where Platform: PlatformCoinWithTokensActivationOps + Clone, EnablePlatformCoinWithTokensError: From, - (Platform::ActivationError, EnablePlatformCoinWithTokensError): NotEqual, { if let Ok(Some(coin)) = lp_coinfind_any(&ctx, &req.ticker).await { if !coin.is_available() { @@ -452,7 +453,8 @@ where )); } - let (platform_conf, platform_protocol) = coin_conf_with_protocol(&ctx, &req.ticker, None)?; + let (platform_conf, platform_protocol) = + coin_conf_with_protocol(&ctx, &req.ticker, None).map_mm_err::()?; let platform_coin = Platform::enable_platform_coin( ctx.clone(), @@ -461,25 +463,35 @@ where req.request.clone(), platform_protocol, ) - .await?; + .await + .map_mm_err::()?; let mut mm_tokens = Vec::new(); for initializer in platform_coin.token_initializers() { - let tokens = initializer.enable_tokens_as_mm_coins(&ctx, &req.request).await?; + let tokens = initializer + .enable_tokens_as_mm_coins(&ctx, &req.request) + .await + .map_mm_err()?; mm_tokens.extend(tokens); } - let nft_global = platform_coin.enable_global_nft(&req.request).await?; + let nft_global = platform_coin + .enable_global_nft(&req.request) + .await + .map_mm_err::()?; let activation_result = platform_coin .get_activation_result(task_handle, &req.request, &nft_global) - .await?; + .await + .map_mm_err::()?; log::info!("{} current block {}", req.ticker, activation_result.current_block()); if req.request.tx_history() { platform_coin.start_history_background_fetching( ctx.clone(), - TxHistoryStorageBuilder::new(&ctx).build()?, + TxHistoryStorageBuilder::new(&ctx) + .build() + .map_mm_err::()?, activation_result.get_platform_balance(), ); } @@ -562,7 +574,6 @@ where Platform: PlatformCoinWithTokensActivationOps + Send + Sync + 'static + Clone, Platform::InProgressStatus: InitPlatformCoinWithTokensInitialStatus, EnablePlatformCoinWithTokensError: From, - (Platform::ActivationError, EnablePlatformCoinWithTokensError): NotEqual, { let (client_id, request) = (request.client_id, request.inner); if let Ok(Some(_)) = lp_coinfind(&ctx, &request.ticker).await { @@ -618,12 +629,16 @@ pub async fn init_platform_coin_with_tokens_user_action, { - let coins_act_ctx = - CoinsActivationContext::from_ctx(&ctx).map_to_mm(InitPlatformCoinWithTokensUserActionError::Internal)?; + let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) + .map_to_mm(InitPlatformCoinWithTokensUserActionError::Internal) + .map_mm_err::()?; let mut task_manager = Platform::rpc_task_manager(&coins_act_ctx) .lock() - .map_to_mm(|poison| InitPlatformCoinWithTokensUserActionError::Internal(poison.to_string()))?; - task_manager.on_user_action(req.task_id, req.user_action)?; + .map_to_mm(|poison| InitPlatformCoinWithTokensUserActionError::Internal(poison.to_string())) + .map_mm_err::()?; + task_manager + .on_user_action(req.task_id, req.user_action) + .map_mm_err::()?; Ok(SuccessResponse::new()) } @@ -635,12 +650,16 @@ pub async fn cancel_init_platform_coin_with_tokens, { - let coins_act_ctx = - CoinsActivationContext::from_ctx(&ctx).map_to_mm(CancelInitPlatformCoinWithTokensError::Internal)?; + let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) + .map_to_mm(CancelInitPlatformCoinWithTokensError::Internal) + .map_mm_err::()?; let mut task_manager = Platform::rpc_task_manager(&coins_act_ctx) .lock() - .map_to_mm(|poison| CancelInitPlatformCoinWithTokensError::Internal(poison.to_string()))?; - task_manager.cancel_task(req.task_id)?; + .map_to_mm(|poison| CancelInitPlatformCoinWithTokensError::Internal(poison.to_string())) + .map_mm_err::()?; + task_manager + .cancel_task(req.task_id) + .map_mm_err::()?; Ok(SuccessResponse::new()) } @@ -665,7 +684,7 @@ pub mod for_tests { use super::{init_platform_coin_with_tokens, init_platform_coin_with_tokens_status, EnablePlatformCoinWithTokensError, EnablePlatformCoinWithTokensReq, - EnablePlatformCoinWithTokensStatusRequest, InitPlatformCoinWithTokensInitialStatus, NotEqual, + EnablePlatformCoinWithTokensStatusRequest, InitPlatformCoinWithTokensInitialStatus, PlatformCoinWithTokensActivationOps}; /// test helper to activate platform coin with waiting for the result @@ -677,7 +696,6 @@ pub mod for_tests { Platform: PlatformCoinWithTokensActivationOps + Clone + Send + Sync + 'static, Platform::InProgressStatus: InitPlatformCoinWithTokensInitialStatus, EnablePlatformCoinWithTokensError: From, - (Platform::ActivationError, EnablePlatformCoinWithTokensError): NotEqual, { let request = RpcInitReq { client_id: 0, diff --git a/mm2src/coins_activation/src/sia_coin_activation.rs b/mm2src/coins_activation/src/sia_coin_activation.rs index 110f8bbb7b..e2cd92ddbc 100644 --- a/mm2src/coins_activation/src/sia_coin_activation.rs +++ b/mm2src/coins_activation/src/sia_coin_activation.rs @@ -202,7 +202,7 @@ impl InitStandaloneCoinActivationOps for SiaCoin { _protocol_info: SiaCoinProtocolInfo, _task_handle: SiaCoinRpcTaskHandleShared, ) -> MmResult { - let priv_key_policy = PrivKeyBuildPolicy::detect_priv_key_policy(&ctx)?; + let priv_key_policy = PrivKeyBuildPolicy::detect_priv_key_policy(&ctx).map_mm_err()?; let coin = sia_coin_from_conf_and_params(&ctx, &ticker, &coin_conf, activation_request, priv_key_policy) .await @@ -217,15 +217,18 @@ impl InitStandaloneCoinActivationOps for SiaCoin { task_handle: SiaCoinRpcTaskHandleShared, _activation_request: &Self::ActivationRequest, ) -> MmResult { - task_handle.update_in_progress_status(SiaCoinInProgressStatus::RequestingWalletBalance)?; + task_handle + .update_in_progress_status(SiaCoinInProgressStatus::RequestingWalletBalance) + .map_mm_err()?; let current_block = self .current_block() .compat() .await - .map_to_mm(SiaCoinInitError::CouldNotGetBlockCount)?; + .map_to_mm(SiaCoinInitError::CouldNotGetBlockCount) + .map_mm_err()?; - let balance = self.my_balance().compat().await?; - let address = self.my_address()?; + let balance = self.my_balance().compat().await.map_mm_err()?; + let address = self.my_address().map_mm_err()?; Ok(SiaCoinActivationResult { ticker: self.ticker().into(), diff --git a/mm2src/coins_activation/src/slp_token_activation.rs b/mm2src/coins_activation/src/slp_token_activation.rs index 91dbf95ea7..66ea8d18a4 100644 --- a/mm2src/coins_activation/src/slp_token_activation.rs +++ b/mm2src/coins_activation/src/slp_token_activation.rs @@ -102,7 +102,7 @@ impl TokenActivationOps for SlpToken { required_confirmations, )?; let balance = token.my_coin_balance().await.mm_err(EnableSlpError::GetBalanceError)?; - let my_address = token.my_address()?; + let my_address = token.my_address().map_mm_err()?; let balances = HashMap::from([(my_address, balance)]); let init_result = SlpInitResult { balances, diff --git a/mm2src/coins_activation/src/standalone_coin/init_standalone_coin.rs b/mm2src/coins_activation/src/standalone_coin/init_standalone_coin.rs index 002d87c872..12a5af5d29 100644 --- a/mm2src/coins_activation/src/standalone_coin/init_standalone_coin.rs +++ b/mm2src/coins_activation/src/standalone_coin/init_standalone_coin.rs @@ -42,7 +42,6 @@ pub trait InitStandaloneCoinActivationOps: Into + Send + Sync + 'sta + From + Into + SerMmErrorType - + NotEqual + Clone + Send + Sync @@ -87,16 +86,19 @@ where Standalone: InitStandaloneCoinActivationOps + Send + Sync + 'static, Standalone::InProgressStatus: InitStandaloneCoinInitialStatus, InitStandaloneCoinError: From, - (Standalone::ActivationError, InitStandaloneCoinError): NotEqual, { let (client_id, request) = (request.client_id, request.inner); if let Ok(Some(_)) = lp_coinfind(&ctx, &request.ticker).await { return MmError::err(InitStandaloneCoinError::CoinIsAlreadyActivated { ticker: request.ticker }); } - let (coin_conf, protocol_info) = coin_conf_with_protocol(&ctx, &request.ticker, None)?; + let (coin_conf, protocol_info) = + coin_conf_with_protocol(&ctx, &request.ticker, None).map_mm_err::()?; + + let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) + .map_to_mm(InitStandaloneCoinError::Internal) + .map_mm_err::()?; - let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx).map_to_mm(InitStandaloneCoinError::Internal)?; let spawner = ctx.spawner(); let task = InitStandaloneCoinTask:: { ctx, @@ -141,12 +143,16 @@ pub async fn init_standalone_coin_user_action, ) -> MmResult { - let coins_act_ctx = - CoinsActivationContext::from_ctx(&ctx).map_to_mm(InitStandaloneCoinUserActionError::Internal)?; + let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) + .map_to_mm(InitStandaloneCoinUserActionError::Internal) + .map_mm_err::()?; let mut task_manager = Standalone::rpc_task_manager(&coins_act_ctx) .lock() - .map_to_mm(|poison| InitStandaloneCoinUserActionError::Internal(poison.to_string()))?; - task_manager.on_user_action(req.task_id, req.user_action)?; + .map_to_mm(|poison| InitStandaloneCoinUserActionError::Internal(poison.to_string())) + .map_mm_err::()?; + task_manager + .on_user_action(req.task_id, req.user_action) + .map_mm_err::()?; Ok(SuccessResponse::new()) } @@ -157,8 +163,11 @@ pub async fn cancel_init_standalone_coin()?; + task_manager + .cancel_task(req.task_id) + .map_mm_err::()?; Ok(SuccessResponse::new()) } @@ -206,11 +215,13 @@ where self.protocol_info.clone(), task_handle.clone(), ) - .await?; + .await + .map_mm_err::()?; let result = coin .get_activation_result(self.ctx.clone(), task_handle, &self.request.activation_params) - .await?; + .await + .map_mm_err::()?; log::info!("{} current block {}", ticker, result.current_block()); let tx_history = self.request.activation_params.tx_history(); @@ -218,13 +229,17 @@ where let current_balances = result.get_addresses_balances(); coin.start_history_background_fetching( self.ctx.metrics.clone(), - TxHistoryStorageBuilder::new(&self.ctx).build()?, + TxHistoryStorageBuilder::new(&self.ctx) + .build() + .map_mm_err::()?, self.ctx.event_stream_manager.clone(), current_balances, ); } - lp_register_coin(&self.ctx, coin.into(), RegisterCoinParams { ticker }).await?; + lp_register_coin(&self.ctx, coin.into(), RegisterCoinParams { ticker }) + .await + .map_mm_err::()?; Ok(result) } diff --git a/mm2src/coins_activation/src/tendermint_token_activation.rs b/mm2src/coins_activation/src/tendermint_token_activation.rs index 8f31ef75b2..e930b740b2 100644 --- a/mm2src/coins_activation/src/tendermint_token_activation.rs +++ b/mm2src/coins_activation/src/tendermint_token_activation.rs @@ -5,7 +5,8 @@ use coins::{tendermint::{TendermintCoin, TendermintToken, TendermintTokenActivat TendermintTokenProtocolInfo}, CoinBalance, MarketCoinOps, MmCoinEnum}; use common::Future01CompatExt; -use mm2_err_handle::prelude::{MapMmError, MmError}; +use mm2_err_handle::{map_mm_error::MmResultExt, + prelude::{MapMmError, MmError}}; use serde::Serialize; use serde_json::Value as Json; use std::collections::HashMap; @@ -66,7 +67,7 @@ impl TokenActivationOps for TendermintToken { .await .mm_err(|e| TendermintTokenInitError::CouldNotFetchBalance(e.to_string()))?; - let my_address = token.my_address()?; + let my_address = token.my_address().map_mm_err()?; let balances = HashMap::from([(my_address, balance)]); let init_result = TendermintTokenInitResult { diff --git a/mm2src/coins_activation/src/token.rs b/mm2src/coins_activation/src/token.rs index 5001a0f3de..46fb9b1a58 100644 --- a/mm2src/coins_activation/src/token.rs +++ b/mm2src/coins_activation/src/token.rs @@ -122,14 +122,13 @@ pub async fn enable_token( where Token: TokenActivationOps + Clone, EnableTokenError: From, - (Token::ActivationError, EnableTokenError): NotEqual, { if let Ok(Some(_)) = lp_coinfind(&ctx, &req.ticker).await { return MmError::err(EnableTokenError::TokenIsAlreadyActivated(req.ticker)); } let (token_conf, token_protocol): (_, Token::ProtocolInfo) = - coin_conf_with_protocol(&ctx, &req.ticker, req.protocol.clone())?; + coin_conf_with_protocol(&ctx, &req.ticker, req.protocol.clone()).map_mm_err::()?; let platform_coin = lp_coinfind_or_err(&ctx, token_protocol.platform_coin_ticker()) .await @@ -150,10 +149,14 @@ where token_protocol, req.protocol.is_some(), ) - .await?; + .await + .map_mm_err::()?; let coins_ctx = CoinsContext::from_ctx(&ctx).unwrap(); - coins_ctx.add_token(token.clone().into()).await?; + coins_ctx + .add_token(token.clone().into()) + .await + .map_mm_err::()?; platform_coin.register_token_info(&token); diff --git a/mm2src/coins_activation/src/utxo_activation/common_impl.rs b/mm2src/coins_activation/src/utxo_activation/common_impl.rs index eba196c370..589efa5b08 100644 --- a/mm2src/coins_activation/src/utxo_activation/common_impl.rs +++ b/mm2src/coins_activation/src/utxo_activation/common_impl.rs @@ -55,7 +55,9 @@ where } else { None }; - task_handle.update_in_progress_status(UtxoStandardInProgressStatus::RequestingWalletBalance)?; + task_handle + .update_in_progress_status(UtxoStandardInProgressStatus::RequestingWalletBalance) + .map_mm_err()?; let wallet_balance = coin .enable_coin_balance( xpub_extractor, @@ -64,7 +66,9 @@ where ) .await .mm_err(|enable_err| InitUtxoStandardError::from_enable_coin_balance_err(enable_err, ticker.clone()))?; - task_handle.update_in_progress_status(UtxoStandardInProgressStatus::ActivatingCoin)?; + task_handle + .update_in_progress_status(UtxoStandardInProgressStatus::ActivatingCoin) + .map_mm_err()?; let result = UtxoStandardActivationResult { ticker, diff --git a/mm2src/coins_activation/src/utxo_activation/init_bch_activation.rs b/mm2src/coins_activation/src/utxo_activation/init_bch_activation.rs index 8c27226959..35c1a32cc5 100644 --- a/mm2src/coins_activation/src/utxo_activation/init_bch_activation.rs +++ b/mm2src/coins_activation/src/utxo_activation/init_bch_activation.rs @@ -77,7 +77,8 @@ impl InitStandaloneCoinActivationOps for BchCoin { error: format!("Couldn't parse cash address prefix: {e:?}"), } })?; - let priv_key_policy = priv_key_build_policy(&ctx, activation_request.utxo_params.priv_key_policy)?; + let priv_key_policy = + priv_key_build_policy(&ctx, activation_request.utxo_params.priv_key_policy).map_mm_err()?; let bchd_urls = activation_request.bchd_urls.clone(); let constructor = { move |utxo_arc| BchCoin::new(utxo_arc, prefix.clone(), bchd_urls.clone()) }; diff --git a/mm2src/coins_activation/src/utxo_activation/init_qtum_activation.rs b/mm2src/coins_activation/src/utxo_activation/init_qtum_activation.rs index a6644f3275..3dd9010709 100644 --- a/mm2src/coins_activation/src/utxo_activation/init_qtum_activation.rs +++ b/mm2src/coins_activation/src/utxo_activation/init_qtum_activation.rs @@ -62,7 +62,7 @@ impl InitStandaloneCoinActivationOps for QtumCoin { _protocol_info: Self::StandaloneProtocol, _task_handle: QtumRpcTaskHandleShared, ) -> Result> { - let priv_key_policy = priv_key_build_policy(&ctx, activation_request.priv_key_policy)?; + let priv_key_policy = priv_key_build_policy(&ctx, activation_request.priv_key_policy).map_mm_err()?; let coin = QtumCoinBuilder::new(&ctx, &ticker, &coin_conf, activation_request, priv_key_policy) .build() diff --git a/mm2src/coins_activation/src/utxo_activation/init_utxo_standard_activation.rs b/mm2src/coins_activation/src/utxo_activation/init_utxo_standard_activation.rs index 10715e2f0e..f975d49fd7 100644 --- a/mm2src/coins_activation/src/utxo_activation/init_utxo_standard_activation.rs +++ b/mm2src/coins_activation/src/utxo_activation/init_utxo_standard_activation.rs @@ -63,7 +63,7 @@ impl InitStandaloneCoinActivationOps for UtxoStandardCoin { _protocol_info: Self::StandaloneProtocol, task_handle: UtxoStandardRpcTaskHandleShared, ) -> MmResult { - let priv_key_policy = priv_key_build_policy(&ctx, activation_request.priv_key_policy)?; + let priv_key_policy = priv_key_build_policy(&ctx, activation_request.priv_key_policy).map_mm_err()?; let coin = UtxoArcBuilder::new( &ctx, @@ -105,7 +105,7 @@ impl InitStandaloneCoinActivationOps for UtxoStandardCoin { }, UtxoSyncStatus::Finished { .. } => break, }; - task_handle.update_in_progress_status(in_progress_status)?; + task_handle.update_in_progress_status(in_progress_status).map_mm_err()?; } } diff --git a/mm2src/coins_activation/src/utxo_activation/mod.rs b/mm2src/coins_activation/src/utxo_activation/mod.rs index 42764e5c93..1dc64c620c 100644 --- a/mm2src/coins_activation/src/utxo_activation/mod.rs +++ b/mm2src/coins_activation/src/utxo_activation/mod.rs @@ -15,7 +15,7 @@ pub use init_utxo_standard_activation::UtxoStandardTaskManagerShared; pub mod for_tests { use common::{executor::Timer, now_ms, wait_until_ms}; use mm2_core::mm_ctx::MmArc; - use mm2_err_handle::prelude::{MmResult, NotEqual}; + use mm2_err_handle::prelude::MmResult; use rpc_task::{RpcInitReq, RpcTaskStatus}; use crate::{init_standalone_coin, init_standalone_coin_status, @@ -32,7 +32,6 @@ pub mod for_tests { Standalone: InitStandaloneCoinActivationOps + Send + Sync + 'static, Standalone::InProgressStatus: InitStandaloneCoinInitialStatus, InitStandaloneCoinError: From, - (Standalone::ActivationError, InitStandaloneCoinError): NotEqual, { let request = RpcInitReq { client_id: 0, diff --git a/mm2src/coins_activation/src/z_coin_activation.rs b/mm2src/coins_activation/src/z_coin_activation.rs index 2332710218..ff9df16119 100644 --- a/mm2src/coins_activation/src/z_coin_activation.rs +++ b/mm2src/coins_activation/src/z_coin_activation.rs @@ -234,7 +234,7 @@ impl InitStandaloneCoinActivationOps for ZCoin { ) -> MmResult { // When `ZCoin` supports Trezor, we'll need to check [`ZcoinActivationParams::priv_key_policy`] // instead of using [`PrivKeyBuildPolicy::detect_priv_key_policy`]. - let priv_key_policy = PrivKeyBuildPolicy::detect_priv_key_policy(&ctx)?; + let priv_key_policy = PrivKeyBuildPolicy::detect_priv_key_policy(&ctx).map_mm_err()?; let coin = z_coin_from_conf_and_params( &ctx, @@ -248,7 +248,7 @@ impl InitStandaloneCoinActivationOps for ZCoin { .mm_err(|e| ZcoinInitError::from_build_err(e, ticker))?; loop { - let in_progress_status = match coin.sync_status().await? { + let in_progress_status = match coin.sync_status().await.map_mm_err()? { SyncStatus::UpdatingBlocksCache { current_scanned_block, latest_block, @@ -266,7 +266,7 @@ impl InitStandaloneCoinActivationOps for ZCoin { SyncStatus::TemporaryError(e) => ZcoinInProgressStatus::TemporaryError(e), SyncStatus::Finished { .. } => break, }; - task_handle.update_in_progress_status(in_progress_status)?; + task_handle.update_in_progress_status(in_progress_status).map_mm_err()?; } Ok(coin) @@ -278,15 +278,17 @@ impl InitStandaloneCoinActivationOps for ZCoin { task_handle: ZcoinRpcTaskHandleShared, _activation_request: &Self::ActivationRequest, ) -> MmResult { - task_handle.update_in_progress_status(ZcoinInProgressStatus::RequestingWalletBalance)?; + task_handle + .update_in_progress_status(ZcoinInProgressStatus::RequestingWalletBalance) + .map_mm_err()?; let current_block = self .current_block() .compat() .await .map_to_mm(ZcoinInitError::CouldNotGetBlockCount)?; - let balance = self.my_balance().compat().await?; - let first_sync_block = self.first_sync_block().await?; + let balance = self.my_balance().compat().await.map_mm_err()?; + let first_sync_block = self.first_sync_block().await.map_mm_err()?; Ok(ZcoinActivationResult { ticker: self.ticker().into(), diff --git a/mm2src/crypto/src/crypto_ctx.rs b/mm2src/crypto/src/crypto_ctx.rs index ffc83603a6..e591ac37b4 100644 --- a/mm2src/crypto/src/crypto_ctx.rs +++ b/mm2src/crypto/src/crypto_ctx.rs @@ -76,9 +76,6 @@ impl From> for HwCtxInitError< } } -/// This is required for converting `MmError>` into `MmError>`. -impl NotEqual for HwCtxInitError {} - #[cfg(target_arch = "wasm32")] #[derive(Debug)] pub enum MetamaskCtxInitError { @@ -265,7 +262,7 @@ impl CryptoCtx { *state = InitializationState::Initializing; } - let metamask_ctx = MetamaskCtx::init(project_name).await?; + let metamask_ctx = MetamaskCtx::init(project_name).await.map_mm_err()?; let metamask_arc = MetamaskArc::new(metamask_ctx); *self.metamask_ctx.write() = InitializationState::Ready(metamask_arc.clone()); @@ -302,7 +299,7 @@ impl CryptoCtx { let (secp256k1_key_pair, key_pair_policy) = policy_builder.build(passphrase)?; let rmd160 = secp256k1_key_pair.public().address_hash(); - let shared_db_id = shared_db_id_from_seed(passphrase)?; + let shared_db_id = shared_db_id_from_seed(passphrase).map_mm_err()?; let crypto_ctx = CryptoCtx { secp256k1_key_pair, @@ -339,11 +336,11 @@ impl KeyPairPolicyBuilder { fn build(self, passphrase: &str) -> CryptoInitResult<(KeyPair, KeyPairPolicy)> { match self { KeyPairPolicyBuilder::Iguana => { - let secp256k1_key_pair = key_pair_from_seed(passphrase)?; + let secp256k1_key_pair = key_pair_from_seed(passphrase).map_mm_err()?; Ok((secp256k1_key_pair, KeyPairPolicy::Iguana)) }, KeyPairPolicyBuilder::GlobalHDAccount => { - let (mm2_internal_key_pair, global_hd_ctx) = GlobalHDAccountCtx::new(passphrase)?; + let (mm2_internal_key_pair, global_hd_ctx) = GlobalHDAccountCtx::new(passphrase).map_mm_err()?; let key_pair_policy = KeyPairPolicy::GlobalHDAccount(global_hd_ctx.into_arc()); Ok((mm2_internal_key_pair, key_pair_policy)) }, @@ -361,7 +358,7 @@ async fn init_check_hw_ctx_with_trezor( processor: Arc>, expected_pubkey: Option, ) -> MmResult<(HwDeviceInfo, HardwareWalletArc), HwCtxInitError> { - let (hw_device_info, hw_ctx) = HardwareWalletCtx::init_with_trezor(processor).await?; + let (hw_device_info, hw_ctx) = HardwareWalletCtx::init_with_trezor(processor).await.map_mm_err()?; let expected_pubkey = match expected_pubkey { Some(expected) => expected, None => return Ok((hw_device_info, hw_ctx)), diff --git a/mm2src/crypto/src/global_hd_ctx.rs b/mm2src/crypto/src/global_hd_ctx.rs index ad7c2bc63b..a2a3bb159a 100644 --- a/mm2src/crypto/src/global_hd_ctx.rs +++ b/mm2src/crypto/src/global_hd_ctx.rs @@ -29,9 +29,10 @@ pub struct GlobalHDAccountCtx { impl GlobalHDAccountCtx { pub fn new(passphrase: &str) -> CryptoInitResult<(Mm2InternalKeyPair, GlobalHDAccountCtx)> { - let bip39_seed = bip39_seed_from_passphrase(passphrase)?; - let bip39_secp_priv_key: ExtendedPrivateKey = - ExtendedPrivateKey::new(bip39_seed.0).map_to_mm(|e| PrivKeyError::InvalidPrivKey(e.to_string()))?; + let bip39_seed = bip39_seed_from_passphrase(passphrase).map_mm_err()?; + let bip39_secp_priv_key: ExtendedPrivateKey = ExtendedPrivateKey::new(bip39_seed.0) + .map_to_mm(|e| PrivKeyError::InvalidPrivKey(e.to_string())) + .map_mm_err()?; let derivation_path = mm2_internal_der_path(); @@ -39,10 +40,11 @@ impl GlobalHDAccountCtx { for child in derivation_path { internal_priv_key = internal_priv_key .derive_child(child) - .map_to_mm(|e| CryptoInitError::InvalidPassphrase(PrivKeyError::InvalidPrivKey(e.to_string())))?; + .map_to_mm(|e| CryptoInitError::InvalidPassphrase(PrivKeyError::InvalidPrivKey(e.to_string()))) + .map_mm_err()?; } - let mm2_internal_key_pair = key_pair_from_secret(internal_priv_key.private_key().as_ref())?; + let mm2_internal_key_pair = key_pair_from_secret(internal_priv_key.private_key().as_ref()).map_mm_err()?; let global_hd_ctx = GlobalHDAccountCtx { bip39_seed, diff --git a/mm2src/crypto/src/hw_client.rs b/mm2src/crypto/src/hw_client.rs index 4cb78b05b5..d9c6679e26 100644 --- a/mm2src/crypto/src/hw_client.rs +++ b/mm2src/crypto/src/hw_client.rs @@ -41,9 +41,6 @@ impl From> for HwProcessingError { } } -/// This is required for converting `MmError` into `MmError>`. -impl NotEqual for HwProcessingError {} - #[derive(Clone, Copy, Deserialize)] pub enum HwWalletType { Trezor, @@ -95,7 +92,7 @@ impl HwClient { pub(crate) async fn trezor( processor: Arc>, ) -> MmResult> { - let timeout = processor.on_connect().await?; + let timeout = processor.on_connect().await.map_mm_err()?; let fut = async move { // `find_devices` in a browser leads to a popup that asks the user which device he wants to connect. @@ -104,21 +101,23 @@ impl HwClient { .boxed() .timeout(timeout) .await - .map_to_mm(|_| HwError::ConnectionTimedOut { timeout })??; + .map_to_mm(|_| HwError::ConnectionTimedOut { timeout }) + .map_mm_err()? + .map_mm_err()?; if devices.available.is_empty() { return MmError::err(HwProcessingError::HwError(HwError::NoTrezorDeviceAvailable)); } let device = devices.available.remove(0); - Ok(device.connect().await?) + device.connect().await.map_mm_err() }; match fut.await { Ok(transport) => { - processor.on_connected().await?; + processor.on_connected().await.map_mm_err()?; Ok(TrezorClient::from_transport(transport)) }, Err(e) => { - processor.on_connection_failed().await?; + processor.on_connection_failed().await.map_mm_err()?; Err(e) }, } @@ -136,7 +135,7 @@ impl HwClient { where C: ConnectableDeviceWrapper + 'static, { - let mut devices = C::find_devices().await?; + let mut devices = C::find_devices().await.map_mm_err()?; if devices.is_empty() { return Ok(None); } @@ -144,7 +143,7 @@ impl HwClient { return MmError::err(HwError::CannotChooseDevice { count: devices.len() }); } let device = devices.remove(0); - let transport = device.connect().await?; + let transport = device.connect().await.map_mm_err()?; let trezor = TrezorClient::from_transport(transport); Ok(Some(trezor)) } @@ -165,19 +164,19 @@ impl HwClient { } }; - let timeout = processor.on_connect().await?; + let timeout = processor.on_connect().await.map_mm_err()?; let result: Result, TimeoutError> = fut.boxed().timeout(timeout).await; match result { Ok(Ok(trezor)) => { - processor.on_connected().await?; + processor.on_connected().await.map_mm_err()?; Ok(trezor) }, Ok(Err(hw_err)) => { - processor.on_connection_failed().await?; + processor.on_connection_failed().await.map_mm_err()?; Err(hw_err.map(HwProcessingError::from)) }, Err(_timed_out) => { - processor.on_connection_failed().await?; + processor.on_connection_failed().await.map_mm_err()?; MmError::err(HwProcessingError::HwError(HwError::ConnectionTimedOut { timeout })) }, } diff --git a/mm2src/crypto/src/hw_ctx.rs b/mm2src/crypto/src/hw_ctx.rs index 8d2c84a8f9..cda40a1159 100644 --- a/mm2src/crypto/src/hw_ctx.rs +++ b/mm2src/crypto/src/hw_ctx.rs @@ -55,8 +55,10 @@ impl HardwareWalletCtx { let (hw_device_info, hw_internal_pubkey) = { let processor = processor.as_base_shared(); - let (device_info, mut session) = trezor.init_new_session(processor).await?; - let hw_internal_pubkey = HardwareWalletCtx::trezor_mm_internal_pubkey(&mut session).await?; + let (device_info, mut session) = trezor.init_new_session(processor).await.map_mm_err()?; + let hw_internal_pubkey = HardwareWalletCtx::trezor_mm_internal_pubkey(&mut session) + .await + .map_mm_err()?; (HwDeviceInfo::Trezor(device_info), hw_internal_pubkey) }; @@ -131,10 +133,14 @@ impl HardwareWalletCtx { SHOW_PUBKEY_ON_DISPLAY, IGNORE_XPUB_MAGIC, ) - .await? + .await + .map_mm_err()? .process(processor) - .await?; - let extended_pubkey = Secp256k1ExtendedPublicKey::from_str(&mm2_internal_xpub).map_to_mm(HwError::from)?; + .await + .map_mm_err()?; + let extended_pubkey = Secp256k1ExtendedPublicKey::from_str(&mm2_internal_xpub) + .map_to_mm(HwError::from) + .map_mm_err()?; Ok(H264::from(extended_pubkey.public_key().serialize())) } diff --git a/mm2src/crypto/src/hw_rpc_task.rs b/mm2src/crypto/src/hw_rpc_task.rs index 96b0c73c03..140bcfba81 100644 --- a/mm2src/crypto/src/hw_rpc_task.rs +++ b/mm2src/crypto/src/hw_rpc_task.rs @@ -125,20 +125,23 @@ where { async fn on_connect(&self) -> MmResult> { self.request_processor - .update_in_progress_status(self.on_connect.clone())?; + .update_in_progress_status(self.on_connect.clone()) + .map_mm_err()?; Ok(self.connect_timeout) } async fn on_connected(&self) -> MmResult<(), HwProcessingError> { Ok(self .request_processor - .update_in_progress_status(self.on_connected.clone())?) + .update_in_progress_status(self.on_connected.clone()) + .map_mm_err()?) } async fn on_connection_failed(&self) -> MmResult<(), HwProcessingError> { Ok(self .request_processor - .update_in_progress_status(self.on_connection_failed.clone())?) + .update_in_progress_status(self.on_connection_failed.clone()) + .map_mm_err()?) } fn as_base_shared(&self) -> Arc> { diff --git a/mm2src/crypto/src/mnemonic.rs b/mm2src/crypto/src/mnemonic.rs index 9d89b25fce..793609bef0 100644 --- a/mm2src/crypto/src/mnemonic.rs +++ b/mm2src/crypto/src/mnemonic.rs @@ -80,7 +80,7 @@ pub fn encrypt_mnemonic(mnemonic: &str, password: &str) -> MmResult MmResult MmResult { // Re-create the keys from the password and salts - let (key_aes, key_hmac) = derive_keys_for_mnemonic(password, &encrypted_data.key_derivation_details)?; + let (key_aes, key_hmac) = + derive_keys_for_mnemonic(password, &encrypted_data.key_derivation_details).map_mm_err()?; // Decrypt the ciphertext let decrypted_data = decrypt_data(encrypted_data, &key_aes, &key_hmac).mm_err(|e| MnemonicError::DecryptionError(e.to_string()))?; // Convert decrypted data back to a string - let mnemonic_str = String::from_utf8(decrypted_data).map_to_mm(|e| MnemonicError::DecodeError(e.to_string()))?; + let mnemonic_str = String::from_utf8(decrypted_data) + .map_to_mm(|e| MnemonicError::DecodeError(e.to_string())) + .map_mm_err()?; Ok(mnemonic_str) } diff --git a/mm2src/crypto/src/privkey.rs b/mm2src/crypto/src/privkey.rs index 4d296d72a8..506d52b11a 100644 --- a/mm2src/crypto/src/privkey.rs +++ b/mm2src/crypto/src/privkey.rs @@ -94,7 +94,7 @@ pub fn secp_privkey_from_hash(mut hash: Secp256k1Secret) -> Secp256k1Secret { } pub fn key_pair_from_seed(seed: &str) -> PrivKeyResult { - let private = private_from_seed(seed)?; + let private = private_from_seed(seed).map_mm_err()?; if !private.compressed { return MmError::err(PrivKeyError::ExpectedCompressedKeys); } diff --git a/mm2src/crypto/src/slip21.rs b/mm2src/crypto/src/slip21.rs index bc2bb976d5..131202f4c9 100644 --- a/mm2src/crypto/src/slip21.rs +++ b/mm2src/crypto/src/slip21.rs @@ -40,7 +40,7 @@ pub fn encrypt_with_slip21( // Derive encryption and authentication keys using SLIP-0021 let (key_aes, key_hmac) = - derive_encryption_authentication_keys(master_secret, &encryption_path, &authentication_path)?; + derive_encryption_authentication_keys(master_secret, &encryption_path, &authentication_path).map_mm_err()?; let key_derivation_details = KeyDerivationDetails::SLIP0021 { encryption_path, @@ -71,7 +71,7 @@ pub fn decrypt_with_slip21(encrypted_data: &EncryptedData, master_secret: &[u8; // Derive encryption and authentication keys using SLIP-0021 let (key_aes, key_hmac) = - derive_encryption_authentication_keys(master_secret, encryption_path, authentication_path)?; + derive_encryption_authentication_keys(master_secret, encryption_path, authentication_path).map_mm_err()?; decrypt_data(encrypted_data, &key_aes, &key_hmac).mm_err(|e| SLIP21Error::DecryptionFailed(e.to_string())) } diff --git a/mm2src/crypto/src/xpub.rs b/mm2src/crypto/src/xpub.rs index 3d97168975..aba5adccf9 100644 --- a/mm2src/crypto/src/xpub.rs +++ b/mm2src/crypto/src/xpub.rs @@ -31,7 +31,7 @@ impl XPubConverter { /// The input string must start with the standard `xpub` prefix and contain a valid checksum. pub fn is_standard_xpub(xpub: &str) -> MmResult<(), XpubError> { let bytes = bs58::decode(&xpub).with_check(None).into_vec()?; - if has_xpub_prefix(&bytes)? { + if has_xpub_prefix(&bytes).map_mm_err()? { Ok(()) } else { MmError::err(XpubError::UnknownPrefix) @@ -43,7 +43,7 @@ impl XPubConverter { pub fn replace_magic_prefix(xpub: XPub) -> MmResult { let mut bytes = bs58::decode(&xpub).with_check(None).into_vec()?; - if has_xpub_prefix(&bytes)? { + if has_xpub_prefix(&bytes).map_mm_err()? { return Ok(xpub); } diff --git a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs index ac9205600f..978123ede4 100644 --- a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs +++ b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs @@ -77,11 +77,12 @@ impl WalletConnectStorageOps for IDBSessionStorage { async fn save_session(&self, session: &Session) -> MmResult<(), Self::Error> { debug!("[{}] Saving WalletConnect session to storage", session.topic); let lock_db = self.lock_db().await?; - let transaction = lock_db.get_inner().transaction().await?; - let session_table = transaction.table::().await?; + let transaction = lock_db.get_inner().transaction().await.map_mm_err()?; + let session_table = transaction.table::().await.map_mm_err()?; session_table .replace_item_by_unique_index("topic", session.topic.clone(), session) - .await?; + .await + .map_mm_err()?; Ok(()) } @@ -89,24 +90,26 @@ impl WalletConnectStorageOps for IDBSessionStorage { async fn get_session(&self, topic: &Topic) -> MmResult, Self::Error> { debug!("[{topic}] Retrieving WalletConnect session from storage"); let lock_db = self.lock_db().await?; - let transaction = lock_db.get_inner().transaction().await?; - let session_table = transaction.table::().await?; + let transaction = lock_db.get_inner().transaction().await.map_mm_err()?; + let session_table = transaction.table::().await.map_mm_err()?; Ok(session_table .get_item_by_unique_index("topic", topic) - .await? + .await + .map_mm_err()? .map(|s| s.1)) } async fn get_all_sessions(&self) -> MmResult, Self::Error> { debug!("Loading WalletConnect sessions from storage"); let lock_db = self.lock_db().await?; - let transaction = lock_db.get_inner().transaction().await?; - let session_table = transaction.table::().await?; + let transaction = lock_db.get_inner().transaction().await.map_mm_err()?; + let session_table = transaction.table::().await.map_mm_err()?; Ok(session_table .get_all_items() - .await? + .await + .map_mm_err()? .into_iter() .map(|s| s.1) .collect::>()) @@ -115,10 +118,13 @@ impl WalletConnectStorageOps for IDBSessionStorage { async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error> { debug!("[{topic}] Deleting WalletConnect session from storage"); let lock_db = self.lock_db().await?; - let transaction = lock_db.get_inner().transaction().await?; - let session_table = transaction.table::().await?; + let transaction = lock_db.get_inner().transaction().await.map_mm_err()?; + let session_table = transaction.table::().await.map_mm_err()?; - session_table.delete_item_by_unique_index("topic", topic).await?; + session_table + .delete_item_by_unique_index("topic", topic) + .await + .map_mm_err()?; Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/storage/mod.rs b/mm2src/kdf_walletconnect/src/storage/mod.rs index 088e052e2f..7fee54c535 100644 --- a/mm2src/kdf_walletconnect/src/storage/mod.rs +++ b/mm2src/kdf_walletconnect/src/storage/mod.rs @@ -13,7 +13,7 @@ use crate::{error::WalletConnectError, session::Session}; #[async_trait] pub(crate) trait WalletConnectStorageOps { - type Error: std::fmt::Debug + NotMmError + NotEqual + Send; + type Error: std::fmt::Debug + NotMmError + Send; async fn init(&self) -> MmResult<(), Self::Error>; async fn is_initialized(&self) -> MmResult; diff --git a/mm2src/mm2_err_handle/src/lib.rs b/mm2src/mm2_err_handle/src/lib.rs index 93b5030af3..b128b93b31 100644 --- a/mm2src/mm2_err_handle/src/lib.rs +++ b/mm2src/mm2_err_handle/src/lib.rs @@ -15,10 +15,10 @@ pub mod split_mm; pub mod prelude { pub use crate::common_errors::{WithInternal, WithTimeout}; pub use crate::discard_mm_trace::DiscardMmTrace; - pub use crate::map_mm_error::MapMmError; + pub use crate::map_mm_error::{MapMmError, MmResultExt}; pub use crate::map_to_mm::MapToMmResult; pub use crate::map_to_mm_fut::MapToMmFutureExt; - pub use crate::mm_error::{MmError, MmResult, NotEqual, NotMmError, SerMmErrorType}; + pub use crate::mm_error::{MmError, MmResult, NotMmError, SerMmErrorType}; pub use crate::mm_json_error::MmJsonError; pub use crate::or_mm_error::OrMmError; pub use crate::split_mm::SplitMmResult; diff --git a/mm2src/mm2_err_handle/src/map_mm_error.rs b/mm2src/mm2_err_handle/src/map_mm_error.rs index 3f1e3718ec..0f3c597ace 100644 --- a/mm2src/mm2_err_handle/src/map_mm_error.rs +++ b/mm2src/mm2_err_handle/src/map_mm_error.rs @@ -37,3 +37,28 @@ where } } } + +pub trait MmResultExt { + /// Convert `Result>` into `Result>` + /// by applying `E2::from` to the inner `E1`. + #[track_caller] + fn map_mm_err(self) -> Result> + where + E2: From + NotMmError; +} + +impl MmResultExt for Result> +where + E1: NotMmError, +{ + #[track_caller] + fn map_mm_err(self) -> Result> + where + E2: From + NotMmError, + { + match self { + Ok(v) => Ok(v), + Err(err_e1) => Err(err_e1.map(E2::from)), + } + } +} diff --git a/mm2src/mm2_err_handle/src/map_to_mm.rs b/mm2src/mm2_err_handle/src/map_to_mm.rs index 568df94ab1..9e88551631 100644 --- a/mm2src/mm2_err_handle/src/map_to_mm.rs +++ b/mm2src/mm2_err_handle/src/map_to_mm.rs @@ -35,7 +35,7 @@ where { match self { Ok(x) => Ok(x), - Err(e1) => MmError::err(f(e1)), + Err(e1) => Err(MmError::new(f(e1))), } } } diff --git a/mm2src/mm2_err_handle/src/mm_error.rs b/mm2src/mm2_err_handle/src/mm_error.rs index 1ea7bf1555..2264ca9ff8 100644 --- a/mm2src/mm2_err_handle/src/mm_error.rs +++ b/mm2src/mm2_err_handle/src/mm_error.rs @@ -17,7 +17,7 @@ //! //! fn is_static_library(path: &str) -> Result<(), MmError> { //! let filename = filename(path)?; -//! let extension = get_file_extension(filename)?; +//! let extension = get_file_extension(filename).map_mm_err()?; //! if extension == "a" || extension == "lib" { //! Ok(()) //! } else { @@ -42,7 +42,7 @@ //! fn get_file_extension(filename: &str) -> Result<&str, MmError> { MmError::err(E1::new()) } //! //! fn is_static_library(path: &str) -> Result<(), MmError> { -//! let filename = filename(path).map_to_mm(|e1| E2::from_e1(e1))?; +//! let filename = filename(path).map_to_mm(|e1| E2::from_e1(e1)).map_mm_err()??; //! let extension = get_file_extension(filename).mm_err(|e1| E2::from_e1(e1))?; //! if extension == "a" || extension == "lib" { //! Ok(()) @@ -115,11 +115,6 @@ pub trait SerMmErrorType: SerializeErrorType + fmt::Display + NotMmError {} impl SerMmErrorType for E where E: SerializeErrorType + fmt::Display + NotMmError {} -pub auto trait NotEqual {} -impl !NotEqual for (X, X) {} -impl NotEqual for Box {} -impl NotEqual for Arc {} - /// The unified error representation tracing an error path. #[derive(Clone, Eq, PartialEq)] pub struct MmError { @@ -145,17 +140,6 @@ where impl StdError for MmError {} -/// Track the location whenever `MmError::from(MmError)` is called. -impl From> for MmError -where - E1: NotMmError, - E2: From + NotMmError, - (E1, E2): NotEqual, -{ - #[track_caller] - fn from(orig: MmError) -> Self { orig.map(E2::from) } -} - /// Track the location whenever `MmError::from(E1)` is called. impl From for MmError where @@ -367,7 +351,7 @@ mod tests { const FORWARDED_LINE: u32 = line!() + 2; fn forward_error(actual: u64, required: u64) -> Result<(), MmError> { - generate_error(actual, required)?; + generate_error(actual, required).map_mm_err()?; unreachable!("'generate_error' must return an error") } @@ -462,7 +446,7 @@ mod tests { const FORWARDED_LINE: u32 = line!() + 2; fn forward_error_for_box(actual: u64, required: u64) -> Result<(), MmError> { - generate_error_for_box(actual, required)?; + generate_error_for_box(actual, required).map_mm_err()?; unreachable!("'generate_error' must return an error") } diff --git a/mm2src/mm2_gui_storage/src/account/storage/wasm_storage.rs b/mm2src/mm2_gui_storage/src/account/storage/wasm_storage.rs index 1f05370c29..bd051b3dc3 100644 --- a/mm2src/mm2_gui_storage/src/account/storage/wasm_storage.rs +++ b/mm2src/mm2_gui_storage/src/account/storage/wasm_storage.rs @@ -79,10 +79,11 @@ impl WasmAccountStorage { async fn load_accounts( db_transaction: &DbTransaction<'_>, ) -> AccountStorageResult> { - let table = db_transaction.table::().await?; + let table = db_transaction.table::().await.map_mm_err()?; table .get_all_items() - .await? + .await + .map_mm_err()? .into_iter() .map(|(_item_id, account)| { let account_info = AccountInfo::try_from(account)?; @@ -96,8 +97,8 @@ impl WasmAccountStorage { async fn load_enabled_account_id( db_transaction: &DbTransaction<'_>, ) -> AccountStorageResult> { - let enabled_table = db_transaction.table::().await?; - let enabled_accounts = enabled_table.get_all_items().await?; + let enabled_table = db_transaction.table::().await.map_mm_err()?; + let enabled_accounts = enabled_table.get_all_items().await.map_mm_err()?; if enabled_accounts.len() > 1 { let error = format!("Expected only one enabled account, found {}", enabled_accounts.len()); return MmError::err(AccountStorageError::Internal(error)); @@ -125,12 +126,13 @@ impl WasmAccountStorage { db_transaction: &DbTransaction<'_>, account_id: &AccountId, ) -> AccountStorageResult> { - let table = db_transaction.table::().await?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = AccountTable::account_id_to_index(account_id)?; table .get_item_by_unique_multi_index(index_keys) - .await? + .await + .map_mm_err()? .map(|(_item_id, account)| AccountWithCoins::try_from(account)) .transpose() } @@ -138,10 +140,10 @@ impl WasmAccountStorage { /// Checks whether an account with the given `account_id` exists. /// This method takes `db_transaction` to ensure data coherence. async fn account_exists(db_transaction: &DbTransaction<'_>, account_id: &AccountId) -> AccountStorageResult { - let table = db_transaction.table::().await?; + let table = db_transaction.table::().await.map_mm_err()?; let index_keys = AccountTable::account_id_to_index(account_id)?; - let count = table.count_by_multi_index(index_keys).await?; + let count = table.count_by_multi_index(index_keys).await.map_mm_err()?; Ok(count > 0) } @@ -157,9 +159,9 @@ impl WasmAccountStorage { _ => return Ok(()), } - let table = db_transaction.table::().await?; + let table = db_transaction.table::().await.map_mm_err()?; // Remove the account by clearing the table. - table.clear().await?; + table.clear().await.map_mm_err()?; Ok(()) } @@ -170,16 +172,17 @@ impl WasmAccountStorage { F: FnOnce(&mut AccountTable), { let locked_db = self.lock_db_mutex().await?; - let transaction = locked_db.inner.transaction().await?; - let table = transaction.table::().await?; + let transaction = locked_db.inner.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; let index_keys = AccountTable::account_id_to_index(&account_id)?; let (item_id, mut account) = table .get_item_by_unique_multi_index(index_keys) - .await? + .await + .map_mm_err()? .or_mm_err(|| AccountStorageError::NoSuchAccount(account_id))?; f(&mut account); - table.replace_item(item_id, &account).await?; + table.replace_item(item_id, &account).await.map_mm_err()?; Ok(()) } } @@ -191,7 +194,7 @@ impl AccountStorage for WasmAccountStorage { async fn load_account_coins(&self, account_id: AccountId) -> AccountStorageResult> { let locked_db = self.lock_db_mutex().await?; - let transaction = locked_db.inner.transaction().await?; + let transaction = locked_db.inner.transaction().await.map_mm_err()?; let account = Self::load_account_with_coins(&transaction, &account_id) .await? @@ -201,7 +204,7 @@ impl AccountStorage for WasmAccountStorage { async fn load_accounts(&self) -> AccountStorageResult> { let locked_db = self.lock_db_mutex().await?; - let transaction = locked_db.inner.transaction().await?; + let transaction = locked_db.inner.transaction().await.map_mm_err()?; Self::load_accounts(&transaction).await } @@ -210,7 +213,7 @@ impl AccountStorage for WasmAccountStorage { &self, ) -> AccountStorageResult> { let locked_db = self.lock_db_mutex().await?; - let transaction = locked_db.inner.transaction().await?; + let transaction = locked_db.inner.transaction().await.map_mm_err()?; let enabled_account_id = AccountId::from(Self::load_enabled_account_id_or_err(&transaction).await?); @@ -237,13 +240,13 @@ impl AccountStorage for WasmAccountStorage { async fn load_enabled_account_id(&self) -> AccountStorageResult { let locked_db = self.lock_db_mutex().await?; - let transaction = locked_db.inner.transaction().await?; + let transaction = locked_db.inner.transaction().await.map_mm_err()?; Self::load_enabled_account_id_or_err(&transaction).await } async fn load_enabled_account_with_coins(&self) -> AccountStorageResult { let locked_db = self.lock_db_mutex().await?; - let transaction = locked_db.inner.transaction().await?; + let transaction = locked_db.inner.transaction().await.map_mm_err()?; let account_id = AccountId::from(Self::load_enabled_account_id_or_err(&transaction).await?); @@ -254,7 +257,7 @@ impl AccountStorage for WasmAccountStorage { async fn enable_account(&self, enabled_account_id: EnabledAccountId) -> AccountStorageResult<()> { let locked_db = self.lock_db_mutex().await?; - let transaction = locked_db.inner.transaction().await?; + let transaction = locked_db.inner.transaction().await.map_mm_err()?; let account_id = AccountId::from(enabled_account_id); @@ -263,31 +266,34 @@ impl AccountStorage for WasmAccountStorage { return MmError::err(AccountStorageError::NoSuchAccount(account_id)); } - let table = transaction.table::().await?; + let table = transaction.table::().await.map_mm_err()?; // Remove the previous enabled account by clearing the table. - table.clear().await?; + table.clear().await.map_mm_err()?; - table.add_item(&EnabledAccountTable::from(enabled_account_id)).await?; + table + .add_item(&EnabledAccountTable::from(enabled_account_id)) + .await + .map_mm_err()?; Ok(()) } async fn upload_account(&self, account_info: AccountInfo) -> AccountStorageResult<()> { let locked_db = self.lock_db_mutex().await?; - let transaction = locked_db.inner.transaction().await?; + let transaction = locked_db.inner.transaction().await.map_mm_err()?; // First, check if the account doesn't exist. if Self::account_exists(&transaction, &account_info.account_id).await? { return MmError::err(AccountStorageError::AccountExistsAlready(account_info.account_id)); } - let table = transaction.table::().await?; - table.add_item(&AccountTable::from(account_info)).await?; + let table = transaction.table::().await.map_mm_err()?; + table.add_item(&AccountTable::from(account_info)).await.map_mm_err()?; Ok(()) } async fn delete_account(&self, account_id: AccountId) -> AccountStorageResult<()> { let locked_db = self.lock_db_mutex().await?; - let transaction = locked_db.inner.transaction().await?; + let transaction = locked_db.inner.transaction().await.map_mm_err()?; // First, check if the account exists already. if !Self::account_exists(&transaction, &account_id).await? { @@ -300,9 +306,9 @@ impl AccountStorage for WasmAccountStorage { } // Remove the account info. - let table = transaction.table::().await?; + let table = transaction.table::().await.map_mm_err()?; let index_keys = AccountTable::account_id_to_index(&account_id)?; - table.delete_item_by_unique_multi_index(index_keys).await?; + table.delete_item_by_unique_multi_index(index_keys).await.map_mm_err()?; Ok(()) } @@ -378,9 +384,12 @@ impl AccountTable { let (account_type, account_idx, device_pubkey) = account_id.to_tuple(); let multi_index = MultiIndex::new(AccountTable::ACCOUNT_ID_INDEX) - .with_value(account_type)? - .with_value(account_idx)? - .with_value(device_pubkey)?; + .with_value(account_type) + .map_mm_err()? + .with_value(account_idx) + .map_mm_err()? + .with_value(device_pubkey) + .map_mm_err()?; Ok(multi_index) } } diff --git a/mm2src/mm2_gui_storage/src/rpc_commands.rs b/mm2src/mm2_gui_storage/src/rpc_commands.rs index 2c3363443c..87f658a836 100644 --- a/mm2src/mm2_gui_storage/src/rpc_commands.rs +++ b/mm2src/mm2_gui_storage/src/rpc_commands.rs @@ -172,20 +172,30 @@ pub struct SetBalanceRequest { /// /// This RPC affects the storage **only**. It doesn't affect MarketMaker. pub async fn enable_account(ctx: MmArc, req: EnableAccountRequest) -> MmResult { - let account_ctx = AccountContext::from_ctx(&ctx).map_to_mm(AccountRpcError::Internal)?; + let account_ctx = AccountContext::from_ctx(&ctx) + .map_to_mm(AccountRpcError::Internal) + .map_mm_err()?; let account_id = match req.policy { EnableAccountPolicy::Existing(account_id) => account_id, EnableAccountPolicy::New(new_account) => { let account_id = new_account.account_id; account_ctx .storage() - .await? + .await + .map_mm_err()? .upload_account(AccountInfo::from(new_account)) - .await?; + .await + .map_mm_err()?; account_id }, }; - account_ctx.storage().await?.enable_account(account_id).await?; + account_ctx + .storage() + .await + .map_mm_err()? + .enable_account(account_id) + .await + .map_mm_err()?; Ok(SuccessResponse::new()) } @@ -197,12 +207,16 @@ pub async fn enable_account(ctx: MmArc, req: EnableAccountRequest) -> MmResult MmResult { validate_new_account(&req.account)?; - let account_ctx = AccountContext::from_ctx(&ctx).map_to_mm(AccountRpcError::Internal)?; + let account_ctx = AccountContext::from_ctx(&ctx) + .map_to_mm(AccountRpcError::Internal) + .map_mm_err()?; account_ctx .storage() - .await? + .await + .map_mm_err()? .upload_account(AccountInfo::from(req.account)) - .await?; + .await + .map_mm_err()?; Ok(SuccessResponse::new()) } @@ -214,7 +228,13 @@ pub async fn add_account(ctx: MmArc, req: AddAccountRequest) -> MmResult MmResult { let account_ctx = AccountContext::from_ctx(&ctx).map_to_mm(AccountRpcError::Internal)?; - account_ctx.storage().await?.delete_account(req.account_id).await?; + account_ctx + .storage() + .await + .map_mm_err()? + .delete_account(req.account_id) + .await + .map_mm_err()?; Ok(SuccessResponse::new()) } @@ -228,12 +248,16 @@ pub async fn get_accounts( ctx: MmArc, _req: GetAccountsRequest, ) -> MmResult, AccountRpcError> { - let account_ctx = AccountContext::from_ctx(&ctx).map_to_mm(AccountRpcError::Internal)?; + let account_ctx = AccountContext::from_ctx(&ctx) + .map_to_mm(AccountRpcError::Internal) + .map_mm_err()?; let accounts = account_ctx .storage() - .await? + .await + .map_mm_err()? .load_accounts_with_enabled_flag() - .await? + .await + .map_mm_err()? // The given `BTreeMap` accounts are sorted by `AccountId`. .into_values() .collect(); @@ -249,12 +273,16 @@ pub async fn get_account_coins( ctx: MmArc, req: GetAccountCoinsRequest, ) -> MmResult { - let account_ctx = AccountContext::from_ctx(&ctx).map_to_mm(AccountRpcError::Internal)?; + let account_ctx = AccountContext::from_ctx(&ctx) + .map_to_mm(AccountRpcError::Internal) + .map_mm_err()?; let coins = account_ctx .storage() - .await? + .await + .map_mm_err()? .load_account_coins(req.account_id.clone()) - .await?; + .await + .map_mm_err()?; Ok(GetAccountCoinsResponse { account_id: req.account_id, coins, @@ -271,16 +299,32 @@ pub async fn get_enabled_account( ctx: MmArc, _req: GetEnabledAccountRequest, ) -> MmResult { - let account_ctx = AccountContext::from_ctx(&ctx).map_to_mm(AccountRpcError::Internal)?; - let account = account_ctx.storage().await?.load_enabled_account_with_coins().await?; + let account_ctx = AccountContext::from_ctx(&ctx) + .map_to_mm(AccountRpcError::Internal) + .map_mm_err()?; + let account = account_ctx + .storage() + .await + .map_mm_err()? + .load_enabled_account_with_coins() + .await + .map_mm_err()?; Ok(account) } /// Sets the account name. pub async fn set_account_name(ctx: MmArc, req: SetAccountNameRequest) -> MmResult { - validate_account_name(&req.name)?; - let account_ctx = AccountContext::from_ctx(&ctx).map_to_mm(AccountRpcError::Internal)?; - account_ctx.storage().await?.set_name(req.account_id, req.name).await?; + validate_account_name(&req.name).map_mm_err()?; + let account_ctx = AccountContext::from_ctx(&ctx) + .map_to_mm(AccountRpcError::Internal) + .map_mm_err()?; + account_ctx + .storage() + .await + .map_mm_err()? + .set_name(req.account_id, req.name) + .await + .map_mm_err()?; Ok(SuccessResponse::new()) } @@ -290,12 +334,16 @@ pub async fn set_account_description( req: SetAccountDescriptionRequest, ) -> MmResult { validate_account_desc(&req.description)?; - let account_ctx = AccountContext::from_ctx(&ctx).map_to_mm(AccountRpcError::Internal)?; + let account_ctx = AccountContext::from_ctx(&ctx) + .map_to_mm(AccountRpcError::Internal) + .map_mm_err()?; account_ctx .storage() - .await? + .await + .map_mm_err()? .set_description(req.account_id, req.description) - .await?; + .await + .map_mm_err()?; Ok(SuccessResponse::new()) } @@ -305,12 +353,16 @@ pub async fn set_account_description( /// /// This RPC affects the storage **only**. It doesn't affect MarketMaker. pub async fn set_account_balance(ctx: MmArc, req: SetBalanceRequest) -> MmResult { - let account_ctx = AccountContext::from_ctx(&ctx).map_to_mm(AccountRpcError::Internal)?; + let account_ctx = AccountContext::from_ctx(&ctx) + .map_to_mm(AccountRpcError::Internal) + .map_mm_err()?; account_ctx .storage() - .await? + .await + .map_mm_err()? .set_balance(req.account_id, req.balance_usd) - .await?; + .await + .map_mm_err()?; Ok(SuccessResponse::new()) } @@ -321,12 +373,16 @@ pub async fn set_account_balance(ctx: MmArc, req: SetBalanceRequest) -> MmResult /// This RPC affects the storage **only**. It doesn't affect MarketMaker. pub async fn activate_coins(ctx: MmArc, req: CoinRequest) -> MmResult { validate_tickers(&req.tickers)?; - let account_ctx = AccountContext::from_ctx(&ctx).map_to_mm(AccountRpcError::Internal)?; + let account_ctx = AccountContext::from_ctx(&ctx) + .map_to_mm(AccountRpcError::Internal) + .map_mm_err()?; account_ctx .storage() - .await? + .await + .map_mm_err()? .activate_coins(req.account_id, req.tickers) - .await?; + .await + .map_mm_err()?; Ok(SuccessResponse::new()) } @@ -336,18 +392,22 @@ pub async fn activate_coins(ctx: MmArc, req: CoinRequest) -> MmResult MmResult { - let account_ctx = AccountContext::from_ctx(&ctx).map_to_mm(AccountRpcError::Internal)?; + let account_ctx = AccountContext::from_ctx(&ctx) + .map_to_mm(AccountRpcError::Internal) + .map_mm_err()?; account_ctx .storage() - .await? + .await + .map_mm_err()? .deactivate_coins(req.account_id, req.tickers) - .await?; + .await + .map_mm_err()?; Ok(SuccessResponse::new()) } fn validate_new_account(account: &NewAccount) -> MmResult<(), AccountRpcError> { - validate_account_name(&account.name)?; - validate_account_desc(&account.description) + validate_account_name(&account.name).map_mm_err()?; + validate_account_desc(&account.description).map_mm_err() } fn validate_account_name(name: &str) -> MmResult<(), AccountRpcError> { diff --git a/mm2src/mm2_main/src/lp_init/init_hw.rs b/mm2src/mm2_main/src/lp_init/init_hw.rs index 6148a44f53..77375928d9 100644 --- a/mm2src/mm2_main/src/lp_init/init_hw.rs +++ b/mm2src/mm2_main/src/lp_init/init_hw.rs @@ -136,7 +136,7 @@ impl RpcTask for InitHwTask { } async fn run(&mut self, task_handle: InitHwTaskHandleShared) -> Result> { - let crypto_ctx = CryptoCtx::from_ctx(&self.ctx)?; + let crypto_ctx = CryptoCtx::from_ctx(&self.ctx).map_mm_err()?; match self.hw_wallet_type { HwWalletType::Trezor => { @@ -154,7 +154,8 @@ impl RpcTask for InitHwTask { let trezor_connect_processor = Arc::new(trezor_connect_processor); let (device_info, hw_ctx) = crypto_ctx .init_hw_ctx_with_trezor(trezor_connect_processor, self.req.device_pubkey) - .await?; + .await + .map_mm_err()?; let device_pubkey = hw_ctx.hw_pubkey(); Ok(InitHwResponse { device_info, @@ -174,7 +175,8 @@ pub async fn init_trezor(ctx: MmArc, req: RpcInitReq) -> MmResult hw_wallet_type: HwWalletType::Trezor, req, }; - let task_id = RpcTaskManager::spawn_rpc_task(&init_ctx.init_hw_task_manager, &spawner, task, client_id)?; + let task_id = + RpcTaskManager::spawn_rpc_task(&init_ctx.init_hw_task_manager, &spawner, task, client_id).map_mm_err()?; Ok(InitRpcTaskResponse { task_id }) } @@ -198,7 +200,7 @@ pub async fn init_trezor_user_action( .init_hw_task_manager .lock() .map_to_mm(|e| RpcTaskUserActionError::Internal(e.to_string()))?; - task_manager.on_user_action(req.task_id, req.user_action)?; + task_manager.on_user_action(req.task_id, req.user_action).map_mm_err()?; Ok(SuccessResponse::new()) } @@ -211,6 +213,6 @@ pub async fn cancel_init_trezor( .init_hw_task_manager .lock() .map_to_mm(|e| CancelRpcTaskError::Internal(e.to_string()))?; - task_manager.cancel_task(req.task_id)?; + task_manager.cancel_task(req.task_id).map_mm_err()?; Ok(SuccessResponse::new()) } diff --git a/mm2src/mm2_main/src/lp_init/init_metamask.rs b/mm2src/mm2_main/src/lp_init/init_metamask.rs index 66b8524624..602c95bc58 100644 --- a/mm2src/mm2_main/src/lp_init/init_metamask.rs +++ b/mm2src/mm2_main/src/lp_init/init_metamask.rs @@ -122,9 +122,9 @@ impl RpcTask for InitMetamaskTask { } async fn run(&mut self, _task_handle: InitMetamaskTaskHandleShared) -> Result> { - let crypto_ctx = CryptoCtx::from_ctx(&self.ctx)?; + let crypto_ctx = CryptoCtx::from_ctx(&self.ctx).map_mm_err()?; - let metamask = crypto_ctx.init_metamask_ctx(self.req.project.clone()).await?; + let metamask = crypto_ctx.init_metamask_ctx(self.req.project.clone()).await.map_mm_err()?; Ok(InitMetamaskResponse { eth_address: metamask.eth_account_str().to_string(), }) @@ -139,7 +139,7 @@ pub async fn connect_metamask( let init_ctx = MmInitContext::from_ctx(&ctx).map_to_mm(InitMetamaskError::Internal)?; let spawner = ctx.spawner(); let task = InitMetamaskTask { ctx, req }; - let task_id = RpcTaskManager::spawn_rpc_task(&init_ctx.init_metamask_manager, &spawner, task, client_id)?; + let task_id = RpcTaskManager::spawn_rpc_task(&init_ctx.init_metamask_manager, &spawner, task, client_id).map_mm_err()?; Ok(InitRpcTaskResponse { task_id }) } @@ -166,6 +166,6 @@ pub async fn cancel_connect_metamask( .init_metamask_manager .lock() .map_to_mm(|e| CancelRpcTaskError::Internal(e.to_string()))?; - task_manager.cancel_task(req.task_id)?; + task_manager.cancel_task(req.task_id).map_mm_err()?; Ok(SuccessResponse::new()) } diff --git a/mm2src/mm2_main/src/lp_native_dex.rs b/mm2src/mm2_main/src/lp_native_dex.rs index 4877ef8de8..7ae20cad70 100644 --- a/mm2src/mm2_main/src/lp_native_dex.rs +++ b/mm2src/mm2_main/src/lp_native_dex.rs @@ -362,10 +362,10 @@ fn init_wasm_event_streaming(ctx: &MmArc) { } pub async fn lp_init_continue(ctx: MmArc) -> MmInitResult<()> { - init_ordermatch_context(&ctx)?; - init_p2p(ctx.clone()).await?; + init_ordermatch_context(&ctx).map_mm_err()?; + init_p2p(ctx.clone()).await.map_mm_err()?; - if !CryptoCtx::is_init(&ctx)? { + if !CryptoCtx::is_init(&ctx).map_mm_err()? { return Ok(()); } @@ -397,7 +397,7 @@ pub async fn lp_init_continue(ctx: MmArc) -> MmInitResult<()> { } } - init_message_service(&ctx).await?; + init_message_service(&ctx).await.map_mm_err()?; let balance_update_ordermatch_handler = BalanceUpdateOrdermatchHandler::new(ctx.clone()); register_balance_update_handler(ctx.clone(), Box::new(balance_update_ordermatch_handler)).await; @@ -437,7 +437,7 @@ pub async fn lp_init(ctx: MmArc, version: String, datetime: String) -> MmInitRes } // This either initializes the cryptographic context or sets up the context for "no login mode". - initialize_wallet_passphrase(&ctx).await?; + initialize_wallet_passphrase(&ctx).await.map_mm_err()?; lp_init_continue(ctx.clone()).await?; @@ -646,7 +646,7 @@ async fn relay_node_type(ctx: &MmArc) -> P2PResult { let ip = myipaddr(ctx.clone()) .await .map_to_mm(P2PInitError::ErrorGettingMyIpAddr)?; - let network_ports = lp_network_ports(netid)?; + let network_ports = lp_network_ports(netid).map_mm_err()?; let wss_certs = wss_certs(ctx)?; if wss_certs.is_none() { const WARN_MSG: &str = r#"Please note TLS private key and certificate are not specified. @@ -677,7 +677,7 @@ fn light_node_type(ctx: &MmArc) -> P2PResult { } let netid = ctx.netid(); - let network_ports = lp_network_ports(netid)?; + let network_ports = lp_network_ports(netid).map_mm_err()?; Ok(NodeType::Light { network_ports }) } diff --git a/mm2src/mm2_main/src/lp_ordermatch.rs b/mm2src/mm2_main/src/lp_ordermatch.rs index 9f57101d42..5fd6b8c8c7 100644 --- a/mm2src/mm2_main/src/lp_ordermatch.rs +++ b/mm2src/mm2_main/src/lp_ordermatch.rs @@ -321,7 +321,8 @@ async fn process_orders_keep_alive( P2PRequest::Ordermatch(req), propagated_from_peer.clone(), ) - .await? + .await + .map_mm_err()? .ok_or_else(|| { MmError::new(OrderbookP2PHandlerError::P2PRequestError(format!( "No response was received from peer {} for SyncPubkeyOrderbookState request!", diff --git a/mm2src/mm2_main/src/lp_ordermatch/my_orders_storage.rs b/mm2src/mm2_main/src/lp_ordermatch/my_orders_storage.rs index 9faa4f4722..11eccbb232 100644 --- a/mm2src/mm2_main/src/lp_ordermatch/my_orders_storage.rs +++ b/mm2src/mm2_main/src/lp_ordermatch/my_orders_storage.rs @@ -239,30 +239,31 @@ mod native_impl { impl MyActiveOrders for MyOrdersStorage { async fn load_active_maker_orders(&self) -> MyOrdersResult> { let dir_path = my_maker_orders_dir(&self.ctx); - Ok(read_dir_json(&dir_path).await?) + Ok(read_dir_json(&dir_path).await.map_mm_err()?) } async fn load_active_maker_order(&self, uuid: Uuid) -> MyOrdersResult { let path = my_maker_order_file_path(&self.ctx, &uuid); read_json(&path) - .await? + .await + .map_mm_err()? .or_mm_err(|| MyOrdersError::NoSuchOrder { uuid }) } async fn load_active_taker_orders(&self) -> MyOrdersResult> { let dir_path = my_taker_orders_dir(&self.ctx); - Ok(read_dir_json(&dir_path).await?) + Ok(read_dir_json(&dir_path).await.map_mm_err()?) } async fn save_new_active_maker_order(&self, order: &MakerOrder) -> MyOrdersResult<()> { let path = my_maker_order_file_path(&self.ctx, &order.uuid); - write_json(order, &path, USE_TMP_FILE).await?; + write_json(order, &path, USE_TMP_FILE).await.map_mm_err()?; Ok(()) } async fn save_new_active_taker_order(&self, order: &TakerOrder) -> MyOrdersResult<()> { let path = my_taker_order_file_path(&self.ctx, &order.request.uuid); - write_json(order, &path, USE_TMP_FILE).await?; + write_json(order, &path, USE_TMP_FILE).await.map_mm_err()?; Ok(()) } @@ -295,14 +296,15 @@ mod native_impl { impl MyOrdersHistory for MyOrdersStorage { async fn save_order_in_history(&self, order: &Order) -> MyOrdersResult<()> { let path = my_order_history_file_path(&self.ctx, &order.uuid()); - write_json(order, &path, USE_TMP_FILE).await?; + write_json(order, &path, USE_TMP_FILE).await.map_mm_err()?; Ok(()) } async fn load_order_from_history(&self, uuid: Uuid) -> MyOrdersResult { let path = my_order_history_file_path(&self.ctx, &uuid); read_json(&path) - .await? + .await + .map_mm_err()? .or_mm_err(|| MyOrdersError::NoSuchOrder { uuid }) } } @@ -402,10 +404,10 @@ mod wasm_impl { #[async_trait] impl MyActiveOrders for MyOrdersStorage { async fn load_active_maker_orders(&self) -> MyOrdersResult> { - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; - let maker_orders = table.get_all_items().await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; + let maker_orders = table.get_all_items().await.map_mm_err()?; Ok(maker_orders .into_iter() .map(|(_item_id, MyActiveMakerOrdersTable { order_payload, .. })| order_payload) @@ -413,22 +415,23 @@ mod wasm_impl { } async fn load_active_maker_order(&self, uuid: Uuid) -> MyOrdersResult { - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; table .get_item_by_unique_index("uuid", uuid) - .await? + .await + .map_mm_err()? .map(|(_item_id, MyActiveMakerOrdersTable { order_payload, .. })| order_payload) .or_mm_err(|| MyOrdersError::NoSuchOrder { uuid }) } async fn load_active_taker_orders(&self) -> MyOrdersResult> { - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; - let maker_orders = table.get_all_items().await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; + let maker_orders = table.get_all_items().await.map_mm_err()?; Ok(maker_orders .into_iter() .map(|(_item_id, MyActiveTakerOrdersTable { order_payload, .. })| order_payload) @@ -436,64 +439,67 @@ mod wasm_impl { } async fn save_new_active_maker_order(&self, order: &MakerOrder) -> MyOrdersResult<()> { - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; let item = MyActiveMakerOrdersTable { uuid: order.uuid, order_payload: order.clone(), }; - table.add_item(&item).await?; + table.add_item(&item).await.map_mm_err()?; Ok(()) } async fn save_new_active_taker_order(&self, order: &TakerOrder) -> MyOrdersResult<()> { - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; let item = MyActiveTakerOrdersTable { uuid: order.request.uuid, order_payload: order.clone(), }; - table.add_item(&item).await?; + table.add_item(&item).await.map_mm_err()?; Ok(()) } async fn delete_active_maker_order(&self, uuid: Uuid) -> MyOrdersResult<()> { - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; - table.delete_item_by_unique_index("uuid", uuid).await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; + table.delete_item_by_unique_index("uuid", uuid).await.map_mm_err()?; Ok(()) } async fn delete_active_taker_order(&self, uuid: Uuid) -> MyOrdersResult<()> { - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; - table.delete_item_by_unique_index("uuid", uuid).await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; + table.delete_item_by_unique_index("uuid", uuid).await.map_mm_err()?; Ok(()) } async fn update_active_maker_order(&self, order: &MakerOrder) -> MyOrdersResult<()> { - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; let item = MyActiveMakerOrdersTable { uuid: order.uuid, order_payload: order.clone(), }; - table.replace_item_by_unique_index("uuid", order.uuid, &item).await?; + table + .replace_item_by_unique_index("uuid", order.uuid, &item) + .await + .map_mm_err()?; Ok(()) } async fn update_active_taker_order(&self, order: &TakerOrder) -> MyOrdersResult<()> { - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; let item = MyActiveTakerOrdersTable { uuid: order.request.uuid, @@ -501,7 +507,8 @@ mod wasm_impl { }; table .replace_item_by_unique_index("uuid", order.request.uuid, &item) - .await?; + .await + .map_mm_err()?; Ok(()) } } @@ -509,26 +516,27 @@ mod wasm_impl { #[async_trait] impl MyOrdersHistory for MyOrdersStorage { async fn save_order_in_history(&self, order: &Order) -> MyOrdersResult<()> { - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; let item = MyHistoryOrdersTable { uuid: order.uuid(), order_payload: order.clone(), }; - table.add_item(&item).await?; + table.add_item(&item).await.map_mm_err()?; Ok(()) } async fn load_order_from_history(&self, uuid: Uuid) -> MyOrdersResult { - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; table .get_item_by_unique_index("uuid", uuid) - .await? + .await + .map_mm_err()? .map(|(_item_id, MyHistoryOrdersTable { order_payload, .. })| order_payload) .or_mm_err(|| MyOrdersError::NoSuchOrder { uuid }) } @@ -548,13 +556,17 @@ mod wasm_impl { } async fn select_order_status(&self, uuid: Uuid) -> MyOrdersResult { - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction + .table::() + .await + .map_mm_err()?; table .get_item_by_unique_index("uuid", uuid) - .await? + .await + .map_mm_err()? .map(|(_item_id, MyFilteringHistoryOrdersTable { status, .. })| status) .or_mm_err(|| MyOrdersError::NoSuchOrder { uuid }) } @@ -562,65 +574,83 @@ mod wasm_impl { async fn save_maker_order_in_filtering_history(&self, order: &MakerOrder) -> MyOrdersResult<()> { let item = maker_order_to_filtering_history_item(order, "Created".to_owned(), false)?; - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; - table.add_item(&item).await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction + .table::() + .await + .map_mm_err()?; + table.add_item(&item).await.map_mm_err()?; Ok(()) } async fn save_taker_order_in_filtering_history(&self, order: &TakerOrder) -> MyOrdersResult<()> { let item = taker_order_to_filtering_history_item(order, "Created".to_owned())?; - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; - table.add_item(&item).await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction + .table::() + .await + .map_mm_err()?; + table.add_item(&item).await.map_mm_err()?; Ok(()) } async fn update_maker_order_in_filtering_history(&self, order: &MakerOrder) -> MyOrdersResult<()> { - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction + .table::() + .await + .map_mm_err()?; // get the previous item to see if the order was taker let (item_id, prev_item) = table .get_item_by_unique_index("uuid", order.uuid) - .await? + .await + .map_mm_err()? .or_mm_err(|| MyOrdersError::NoSuchOrder { uuid: order.uuid })?; let item = maker_order_to_filtering_history_item(order, "Updated".to_owned(), prev_item.was_taker)?; - table.replace_item(item_id, &item).await?; + table.replace_item(item_id, &item).await.map_mm_err()?; Ok(()) } async fn update_order_status_in_filtering_history(&self, uuid: Uuid, status: String) -> MyOrdersResult<()> { - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction + .table::() + .await + .map_mm_err()?; let (item_id, mut item) = table .get_item_by_unique_index("uuid", uuid) - .await? + .await + .map_mm_err()? .or_mm_err(|| MyOrdersError::NoSuchOrder { uuid })?; item.status = status; - table.replace_item(item_id, &item).await?; + table.replace_item(item_id, &item).await.map_mm_err()?; Ok(()) } async fn update_was_taker_in_filtering_history(&self, uuid: Uuid) -> MyOrdersResult<()> { - let db = self.ctx.ordermatch_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = self.ctx.ordermatch_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction + .table::() + .await + .map_mm_err()?; let (item_id, mut item) = table .get_item_by_unique_index("uuid", uuid) - .await? + .await + .map_mm_err()? .or_mm_err(|| MyOrdersError::NoSuchOrder { uuid })?; item.was_taker = true; - table.replace_item(item_id, &item).await?; + table.replace_item(item_id, &item).await.map_mm_err()?; Ok(()) } } diff --git a/mm2src/mm2_main/src/lp_ordermatch/orderbook_rpc.rs b/mm2src/mm2_main/src/lp_ordermatch/orderbook_rpc.rs index d76af5dfba..66d24d1daf 100644 --- a/mm2src/mm2_main/src/lp_ordermatch/orderbook_rpc.rs +++ b/mm2src/mm2_main/src/lp_ordermatch/orderbook_rpc.rs @@ -239,9 +239,9 @@ pub async fn orderbook_rpc_v2( if req.base == req.rel { return MmError::err(OrderbookRpcError::BaseRelSame); } - let base_coin_conf = get_tradeable_coin_conf(&ctx, &req.base)?; + let base_coin_conf = get_tradeable_coin_conf(&ctx, &req.base).map_mm_err()?; - let rel_coin_conf = get_tradeable_coin_conf(&ctx, &req.rel)?; + let rel_coin_conf = get_tradeable_coin_conf(&ctx, &req.rel).map_mm_err()?; let ordermatch_ctx = OrdermatchContext::from_ctx(&ctx).expect("ctx is available"); let base_ticker = ordermatch_ctx.orderbook_ticker_bypass(&req.base); diff --git a/mm2src/mm2_main/src/lp_ordermatch/simple_market_maker.rs b/mm2src/mm2_main/src/lp_ordermatch/simple_market_maker.rs index 14551167d6..78aca5278d 100644 --- a/mm2src/mm2_main/src/lp_ordermatch/simple_market_maker.rs +++ b/mm2src/mm2_main/src/lp_ordermatch/simple_market_maker.rs @@ -356,8 +356,12 @@ async fn vwap_calculator( ctx: &MmArc, cfg: &SimpleCoinMarketMakerCfg, ) -> VwapProcessingResult { - let base_swaps = latest_swaps_for_pair(ctx.clone(), cfg.base.clone(), cfg.rel.clone(), LATEST_SWAPS_LIMIT).await?; - let rel_swaps = latest_swaps_for_pair(ctx.clone(), cfg.rel.clone(), cfg.base.clone(), LATEST_SWAPS_LIMIT).await?; + let base_swaps = latest_swaps_for_pair(ctx.clone(), cfg.base.clone(), cfg.rel.clone(), LATEST_SWAPS_LIMIT) + .await + .map_mm_err()?; + let rel_swaps = latest_swaps_for_pair(ctx.clone(), cfg.rel.clone(), cfg.base.clone(), LATEST_SWAPS_LIMIT) + .await + .map_mm_err()?; Ok(vwap(base_swaps, rel_swaps, calculated_price, cfg).await) } @@ -466,7 +470,7 @@ async fn prepare_order( let base_coin = lp_coinfind(ctx, cfg.base.as_str()) .await? .ok_or_else(|| MmError::new(OrderProcessingError::AssetNotEnabled))?; - let base_balance = base_coin.get_non_zero_balance().compat().await?; + let base_balance = base_coin.get_non_zero_balance().compat().await.map_mm_err()?; lp_coinfind(ctx, cfg.rel.as_str()) .await? .ok_or_else(|| MmError::new(OrderProcessingError::AssetNotEnabled))?; diff --git a/mm2src/mm2_main/src/lp_stats.rs b/mm2src/mm2_main/src/lp_stats.rs index b4d908e65a..0cef1b38aa 100644 --- a/mm2src/mm2_main/src/lp_stats.rs +++ b/mm2src/mm2_main/src/lp_stats.rs @@ -135,7 +135,7 @@ pub async fn add_node_to_version_stat(ctx: MmArc, req: Json) -> NodeVersionResul .parse::() .map_to_mm(|e| NodeVersionError::PeerIdParseError(node_info.peer_id.clone(), e.to_string()))?; - let ipv4_addr = mm2_net::ip_addr::addr_to_ipv4_string(&node_info.address)?; + let ipv4_addr = mm2_net::ip_addr::addr_to_ipv4_string(&node_info.address).map_mm_err()?; let node_info_with_ipv4_addr = NodeInfo { name: node_info.name, address: ipv4_addr, @@ -241,7 +241,7 @@ pub async fn start_version_stat_collection(ctx: MmArc, req: Json) -> NodeVersion let network_info = if ctx.p2p_in_memory() { NetworkInfo::InMemory } else { - let network_ports = lp_network_ports(netid)?; + let network_ports = lp_network_ports(netid).map_mm_err()?; NetworkInfo::Distributed { network_ports } }; diff --git a/mm2src/mm2_main/src/lp_swap.rs b/mm2src/mm2_main/src/lp_swap.rs index 7744b555d8..28dacbffe2 100644 --- a/mm2src/mm2_main/src/lp_swap.rs +++ b/mm2src/mm2_main/src/lp_swap.rs @@ -615,7 +615,7 @@ pub async fn get_locked_amount_rpc( ctx: MmArc, req: GetLockedAmountReq, ) -> Result> { - lp_coinfind_or_err(&ctx, &req.coin).await?; + lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; let locked_amount = get_locked_amount(&ctx, &req.coin); Ok(GetLockedAmountResp { diff --git a/mm2src/mm2_main/src/lp_swap/check_balance.rs b/mm2src/mm2_main/src/lp_swap/check_balance.rs index 178a3433fe..bae4a4d14a 100644 --- a/mm2src/mm2_main/src/lp_swap/check_balance.rs +++ b/mm2src/mm2_main/src/lp_swap/check_balance.rs @@ -24,7 +24,7 @@ pub async fn check_my_coin_balance_for_swap( ) -> CheckBalanceResult { let ticker = coin.ticker(); debug!("Check my_coin '{}' balance for swap", ticker); - let balance: MmNumber = coin.my_spendable_balance().compat().await?.into(); + let balance: MmNumber = coin.my_spendable_balance().compat().await.map_mm_err()?.into(); let locked = match swap_uuid { Some(u) => get_locked_amount_by_other_swaps(ctx, u, ticker), @@ -53,8 +53,10 @@ pub async fn check_my_coin_balance_for_swap( let total_trade_fee = if ticker == trade_fee.coin { trade_fee.amount } else { - let base_coin_balance: MmNumber = coin.base_coin_balance().compat().await?.into(); - check_base_coin_balance_for_swap(ctx, &base_coin_balance, trade_fee, swap_uuid).await?; + let base_coin_balance: MmNumber = coin.base_coin_balance().compat().await.map_mm_err()?.into(); + check_base_coin_balance_for_swap(ctx, &base_coin_balance, trade_fee, swap_uuid) + .await + .map_mm_err()?; MmNumber::from(0) }; @@ -94,7 +96,7 @@ pub async fn check_other_coin_balance_for_swap( } let ticker = coin.ticker(); debug!("Check other_coin '{}' balance for swap", ticker); - let balance: MmNumber = coin.my_spendable_balance().compat().await?.into(); + let balance: MmNumber = coin.my_spendable_balance().compat().await.map_mm_err()?.into(); let locked = match swap_uuid { Some(u) => get_locked_amount_by_other_swaps(ctx, u, ticker), @@ -120,8 +122,10 @@ pub async fn check_other_coin_balance_for_swap( }); } } else { - let base_coin_balance: MmNumber = coin.base_coin_balance().compat().await?.into(); - check_base_coin_balance_for_swap(ctx, &base_coin_balance, trade_fee, swap_uuid).await?; + let base_coin_balance: MmNumber = coin.base_coin_balance().compat().await.map_mm_err()?.into(); + check_base_coin_balance_for_swap(ctx, &base_coin_balance, trade_fee, swap_uuid) + .await + .map_mm_err()?; } Ok(()) diff --git a/mm2src/mm2_main/src/lp_swap/maker_swap.rs b/mm2src/mm2_main/src/lp_swap/maker_swap.rs index b74953f42b..af3b1bb767 100644 --- a/mm2src/mm2_main/src/lp_swap/maker_swap.rs +++ b/mm2src/mm2_main/src/lp_swap/maker_swap.rs @@ -2301,9 +2301,10 @@ pub async fn maker_swap_trade_preimage( let base_coin_ticker = base_coin.ticker(); let rel_coin_ticker = rel_coin.ticker(); let volume = if req.max { - let balance = base_coin.my_spendable_balance().compat().await?; + let balance = base_coin.my_spendable_balance().compat().await.map_mm_err()?; calc_max_maker_vol(ctx, &base_coin, &balance, FeeApproxStage::TradePreimage) - .await? + .await + .map_mm_err()? .volume } else { let threshold = base_coin.min_trading_vol().to_decimal(); @@ -2331,7 +2332,9 @@ pub async fn maker_swap_trade_preimage( if req.max { // Note the `calc_max_maker_vol` returns [`CheckBalanceError::NotSufficientBalance`] error if the balance of `base_coin` is not sufficient. // So we have to check the balance of the other coin only. - check_other_coin_balance_for_swap(ctx, rel_coin.deref(), None, rel_coin_fee.clone()).await? + check_other_coin_balance_for_swap(ctx, rel_coin.deref(), None, rel_coin_fee.clone()) + .await + .map_mm_err()? } else { let prepared_params = MakerSwapPreparedParams { maker_payment_trade_fee: base_coin_fee.clone(), @@ -2346,7 +2349,8 @@ pub async fn maker_swap_trade_preimage( Some(prepared_params), FeeApproxStage::TradePreimage, ) - .await?; + .await + .map_mm_err()?; } let conf_settings = OrderConfirmationsSettings { @@ -2382,7 +2386,7 @@ pub struct CoinVolumeInfo { /// Requests the `coin` balance and calculates max Maker volume. /// Returns [`CheckBalanceError::NotSufficientBalance`] if the balance is insufficient. pub async fn get_max_maker_vol(ctx: &MmArc, my_coin: &MmCoinEnum) -> CheckBalanceResult { - let my_balance = my_coin.my_spendable_balance().compat().await?; + let my_balance = my_coin.my_spendable_balance().compat().await.map_mm_err()?; calc_max_maker_vol(ctx, my_coin, &my_balance, FeeApproxStage::OrderIssue).await } @@ -2412,7 +2416,7 @@ pub async fn calc_max_maker_vol( volume = &volume - &trade_fee.amount; required_to_pay_fee = trade_fee.amount; } else { - let base_coin_balance = coin.base_coin_balance().compat().await?; + let base_coin_balance = coin.base_coin_balance().compat().await.map_mm_err()?; check_base_coin_balance_for_swap(ctx, &MmNumber::from(base_coin_balance), trade_fee.clone(), None).await?; } let min_tx_amount = MmNumber::from(coin.min_tx_amount()); diff --git a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs index 3783e43950..ac10601737 100644 --- a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs @@ -194,10 +194,10 @@ impl StateMachineStorage for MakerSwapStorage { #[cfg(target_arch = "wasm32")] async fn store_repr(&mut self, uuid: Self::MachineId, repr: Self::DbRepr) -> Result<(), Self::Error> { let swaps_ctx = SwapsContext::from_ctx(&self.ctx).expect("SwapsContext::from_ctx should not fail"); - let db = swaps_ctx.swap_db().await?; - let transaction = db.transaction().await?; + let db = swaps_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; - let filters_table = transaction.table::().await?; + let filters_table = transaction.table::().await.map_mm_err()?; let item = MySwapsFiltersTable { uuid, @@ -207,14 +207,14 @@ impl StateMachineStorage for MakerSwapStorage { is_finished: false.into(), swap_type: MAKER_SWAP_V2_TYPE, }; - filters_table.add_item(&item).await?; + filters_table.add_item(&item).await.map_mm_err()?; - let table = transaction.table::().await?; + let table = transaction.table::().await.map_mm_err()?; let item = SavedSwapTable { uuid, saved_swap: serde_json::to_value(repr)?, }; - table.add_item(&item).await?; + table.add_item(&item).await.map_mm_err()?; Ok(()) } diff --git a/mm2src/mm2_main/src/lp_swap/max_maker_vol_rpc.rs b/mm2src/mm2_main/src/lp_swap/max_maker_vol_rpc.rs index 625fad2947..18829252b5 100644 --- a/mm2src/mm2_main/src/lp_swap/max_maker_vol_rpc.rs +++ b/mm2src/mm2_main/src/lp_swap/max_maker_vol_rpc.rs @@ -134,12 +134,12 @@ pub struct MaxMakerVolResponse { } pub async fn max_maker_vol(ctx: MmArc, req: MaxMakerVolRequest) -> MmResult { - let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + let coin = lp_coinfind_or_err(&ctx, &req.coin).await.map_mm_err()?; let CoinVolumeInfo { volume, balance, locked_by_swaps, - } = get_max_maker_vol(&ctx, &coin).await?; + } = get_max_maker_vol(&ctx, &coin).await.map_mm_err()?; Ok(MaxMakerVolResponse { coin: req.coin, diff --git a/mm2src/mm2_main/src/lp_swap/my_swaps_storage.rs b/mm2src/mm2_main/src/lp_swap/my_swaps_storage.rs index f725dce5dc..150e8b9489 100644 --- a/mm2src/mm2_main/src/lp_swap/my_swaps_storage.rs +++ b/mm2src/mm2_main/src/lp_swap/my_swaps_storage.rs @@ -177,9 +177,9 @@ mod wasm_impl { swap_type: u8, ) -> MySwapsResult<()> { let swap_ctx = SwapsContext::from_ctx(&self.ctx).map_to_mm(MySwapsError::InternalError)?; - let db = swap_ctx.swap_db().await?; - let transaction = db.transaction().await?; - let my_swaps_table = transaction.table::().await?; + let db = swap_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let my_swaps_table = transaction.table::().await.map_mm_err()?; let item = MySwapsFiltersTable { uuid, @@ -189,7 +189,7 @@ mod wasm_impl { is_finished: false.into(), swap_type, }; - my_swaps_table.add_item(&item).await?; + my_swaps_table.add_item(&item).await.map_mm_err()?; Ok(()) } @@ -199,9 +199,9 @@ mod wasm_impl { paging_options: Option<&PagingOptions>, ) -> MySwapsResult { let swap_ctx = SwapsContext::from_ctx(&self.ctx).map_to_mm(MySwapsError::InternalError)?; - let db = swap_ctx.swap_db().await?; - let transaction = db.transaction().await?; - let my_swaps_table = transaction.table::().await?; + let db = swap_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let my_swaps_table = transaction.table::().await.map_mm_err()?; let from_timestamp = filter.from_timestamp.map(|t| t as u32).unwrap_or_default(); let to_timestamp = filter.to_timestamp.map(|t| t as u32).unwrap_or(u32::MAX); @@ -210,46 +210,50 @@ mod wasm_impl { } let items = match (&filter.my_coin, &filter.other_coin) { - (Some(my_coin), Some(other_coin)) => { - my_swaps_table - .cursor_builder() - .only("my_coin", my_coin)? - .only("other_coin", other_coin)? - .bound("started_at", from_timestamp, to_timestamp) - .open_cursor("with_my_other_coins") - .await? - .collect() - .await? - }, - (Some(my_coin), None) => { - my_swaps_table - .cursor_builder() - .only("my_coin", my_coin)? - .bound("started_at", from_timestamp, to_timestamp) - .open_cursor("with_my_coin") - .await? - .collect() - .await? - }, - (None, Some(other_coin)) => { - my_swaps_table - .cursor_builder() - .only("other_coin", other_coin)? - .bound("started_at", from_timestamp, to_timestamp) - .open_cursor("with_other_coin") - .await? - .collect() - .await? - }, - (None, None) => { - my_swaps_table - .cursor_builder() - .bound("started_at", from_timestamp, to_timestamp) - .open_cursor("started_at") - .await? - .collect() - .await? - }, + (Some(my_coin), Some(other_coin)) => my_swaps_table + .cursor_builder() + .only("my_coin", my_coin) + .map_mm_err()? + .only("other_coin", other_coin) + .map_mm_err()? + .bound("started_at", from_timestamp, to_timestamp) + .open_cursor("with_my_other_coins") + .await + .map_mm_err()? + .collect() + .await + .map_mm_err()?, + (Some(my_coin), None) => my_swaps_table + .cursor_builder() + .only("my_coin", my_coin) + .map_mm_err()? + .bound("started_at", from_timestamp, to_timestamp) + .open_cursor("with_my_coin") + .await + .map_mm_err()? + .collect() + .await + .map_mm_err()?, + (None, Some(other_coin)) => my_swaps_table + .cursor_builder() + .only("other_coin", other_coin) + .map_mm_err()? + .bound("started_at", from_timestamp, to_timestamp) + .open_cursor("with_other_coin") + .await + .map_mm_err()? + .collect() + .await + .map_mm_err()?, + (None, None) => my_swaps_table + .cursor_builder() + .bound("started_at", from_timestamp, to_timestamp) + .open_cursor("started_at") + .await + .map_mm_err()? + .collect() + .await + .map_mm_err()?, }; let uuids: BTreeSet = items diff --git a/mm2src/mm2_main/src/lp_swap/saved_swap.rs b/mm2src/mm2_main/src/lp_swap/saved_swap.rs index 158843dadb..93c6eabf29 100644 --- a/mm2src/mm2_main/src/lp_swap/saved_swap.rs +++ b/mm2src/mm2_main/src/lp_swap/saved_swap.rs @@ -231,7 +231,7 @@ mod native_impl { #[cfg(not(feature = "new-db-arch"))] let address_dir = address_dir.unwrap_or("no address directory for old DB architecture (has no effect)"); let path = my_swap_file_path(ctx, address_dir, &uuid); - Ok(read_json(&path).await?) + Ok(read_json(&path).await.map_mm_err()?) } #[cfg_attr(feature = "new-db-arch", allow(unreachable_code, unused_variables))] @@ -244,27 +244,27 @@ mod native_impl { todo!("Fix the dummy address directory in `my_swaps_dir` below or remove this method all together"); } let path = my_swaps_dir(ctx, "has no effect in not(feature = 'new-db-arch')"); - Ok(read_dir_json(&path).await?) + Ok(read_dir_json(&path).await.map_mm_err()?) } async fn load_from_maker_stats_db(ctx: &MmArc, uuid: Uuid) -> SavedSwapResult> { let path = stats_maker_swap_file_path(ctx, &uuid); - Ok(read_json(&path).await?) + Ok(read_json(&path).await.map_mm_err()?) } async fn load_all_from_maker_stats_db(ctx: &MmArc) -> SavedSwapResult> { let path = stats_maker_swap_dir(ctx); - Ok(read_dir_json(&path).await?) + Ok(read_dir_json(&path).await.map_mm_err()?) } async fn load_from_taker_stats_db(ctx: &MmArc, uuid: Uuid) -> SavedSwapResult> { let path = stats_taker_swap_file_path(ctx, &uuid); - Ok(read_json(&path).await?) + Ok(read_json(&path).await.map_mm_err()?) } async fn load_all_from_taker_stats_db(ctx: &MmArc) -> SavedSwapResult> { let path = stats_taker_swap_dir(ctx); - Ok(read_dir_json(&path).await?) + Ok(read_dir_json(&path).await.map_mm_err()?) } async fn save_to_db(&self, ctx: &MmArc) -> SavedSwapResult<()> { @@ -273,7 +273,7 @@ mod native_impl { #[cfg(not(feature = "new-db-arch"))] let address_dir = "no address directory for old DB architecture (has no effect)"; let path = my_swap_file_path(ctx, address_dir, self.uuid()); - write_json(self, &path, USE_TMP_FILE).await?; + write_json(self, &path, USE_TMP_FILE).await.map_mm_err()?; Ok(()) } @@ -282,11 +282,11 @@ mod native_impl { match self { SavedSwap::Maker(maker) => { let path = stats_maker_swap_file_path(ctx, &maker.uuid); - write_json(self, &path, USE_TMP_FILE).await?; + write_json(self, &path, USE_TMP_FILE).await.map_mm_err()?; }, SavedSwap::Taker(taker) => { let path = stats_taker_swap_file_path(ctx, &taker.uuid); - write_json(self, &path, USE_TMP_FILE).await?; + write_json(self, &path, USE_TMP_FILE).await.map_mm_err()?; }, } Ok(()) @@ -315,27 +315,29 @@ mod wasm_impl { .reverse() .where_first() .open_cursor("migration") - .await? + .await + .map_mm_err()? .next() - .await?; + .await + .map_mm_err()?; Ok(migrations.map(|(_, m)| m.migration).unwrap_or_default()) } pub async fn migrate_swaps_data(ctx: &MmArc) -> MmResult<(), SavedSwapError> { let swaps_ctx = SwapsContext::from_ctx(ctx).map_to_mm(SavedSwapError::InternalError)?; - let db = swaps_ctx.swap_db().await?; - let transaction = db.transaction().await?; - let migration_table = transaction.table::().await?; + let db = swaps_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let migration_table = transaction.table::().await.map_mm_err()?; let mut migration = get_current_migration(&migration_table).await?; info!("Current swaps data migration {}", migration); loop { match migration { 0 => { - let filters_table = transaction.table::().await?; - let swaps_table = transaction.table::().await?; - let swaps = swaps_table.get_all_items().await?; + let filters_table = transaction.table::().await.map_mm_err()?; + let swaps_table = transaction.table::().await.map_mm_err()?; + let swaps = swaps_table.get_all_items().await.map_mm_err()?; let swaps = swaps .into_iter() .map(|(_item_id, SavedSwapTable { saved_swap, .. })| saved_swap) @@ -345,17 +347,23 @@ mod wasm_impl { }) .collect::, _>>()?; for swap in swaps { - let (filter_id, mut filter_record) = - match filters_table.get_item_by_unique_index("uuid", swap.uuid()).await? { - Some(f) => f, - None => { - warn!("No MySwapsFiltersTable for {}", swap.uuid()); - continue; - }, - }; + let (filter_id, mut filter_record) = match filters_table + .get_item_by_unique_index("uuid", swap.uuid()) + .await + .map_mm_err()? + { + Some(f) => f, + None => { + warn!("No MySwapsFiltersTable for {}", swap.uuid()); + continue; + }, + }; filter_record.swap_type = LEGACY_SWAP_TYPE; filter_record.is_finished = swap.is_finished().into(); - filters_table.replace_item(filter_id, &filter_record).await?; + filters_table + .replace_item(filter_id, &filter_record) + .await + .map_mm_err()?; } }, 1 => break, @@ -367,7 +375,10 @@ mod wasm_impl { }, } migration += 1; - migration_table.add_item(&SwapsMigrationTable { migration }).await?; + migration_table + .add_item(&SwapsMigrationTable { migration }) + .await + .map_mm_err()?; } info!("Swaps data migration is completed, new version {}", migration); @@ -415,11 +426,11 @@ mod wasm_impl { uuid: Uuid, ) -> SavedSwapResult> { let swaps_ctx = SwapsContext::from_ctx(ctx).map_to_mm(SavedSwapError::InternalError)?; - let db = swaps_ctx.swap_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = swaps_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; - let saved_swap_json = match table.get_item_by_unique_index("uuid", uuid).await? { + let saved_swap_json = match table.get_item_by_unique_index("uuid", uuid).await.map_mm_err()? { Some((_item_id, SavedSwapTable { saved_swap, .. })) => saved_swap, None => return Ok(None), }; @@ -429,11 +440,11 @@ mod wasm_impl { async fn load_all_my_swaps_from_db(ctx: &MmArc) -> SavedSwapResult> { let swaps_ctx = SwapsContext::from_ctx(ctx).map_to_mm(SavedSwapError::InternalError)?; - let db = swaps_ctx.swap_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = swaps_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; - let swaps = table.get_all_items().await?; + let swaps = table.get_all_items().await.map_mm_err()?; swaps .into_iter() .map(|(_item_id, SavedSwapTable { saved_swap, .. })| saved_swap) @@ -450,13 +461,14 @@ mod wasm_impl { }; let swaps_ctx = SwapsContext::from_ctx(ctx).map_to_mm(SavedSwapError::InternalError)?; - let db = swaps_ctx.swap_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = swaps_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; table .replace_item_by_unique_index("uuid", *self.uuid(), &saved_swap_item) - .await?; + .await + .map_mm_err()?; Ok(()) } } diff --git a/mm2src/mm2_main/src/lp_swap/swap_lock.rs b/mm2src/mm2_main/src/lp_swap/swap_lock.rs index 38591deeff..5a09df019a 100644 --- a/mm2src/mm2_main/src/lp_swap/swap_lock.rs +++ b/mm2src/mm2_main/src/lp_swap/swap_lock.rs @@ -64,12 +64,12 @@ mod native_lock { .join("MY") .join(format!("{}.lock", swap_uuid)) }; - let file_lock = some_or_return_ok_none!(FileLock::lock(lock_path, ttl_sec)?); + let file_lock = some_or_return_ok_none!(FileLock::lock(lock_path, ttl_sec).map_mm_err()?); Ok(Some(SwapLock { file_lock })) } - async fn touch(&self) -> SwapLockResult<()> { Ok(self.file_lock.touch()?) } + async fn touch(&self) -> SwapLockResult<()> { Ok(self.file_lock.touch().map_mm_err()?) } } } @@ -134,26 +134,26 @@ mod wasm_lock { impl SwapLockOps for SwapLock { async fn lock(ctx: &MmArc, uuid: Uuid, ttl_sec: f64) -> SwapLockResult> { let swaps_ctx = SwapsContext::from_ctx(ctx).map_to_mm(SwapLockError::InternalError)?; - let db = swaps_ctx.swap_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = swaps_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; if let Some((item_id, SwapLockTable { timestamp, .. })) = - table.get_item_by_unique_index("uuid", uuid).await? + table.get_item_by_unique_index("uuid", uuid).await.map_mm_err()? { let time_passed = now_float() - timestamp as f64; if time_passed <= ttl_sec { return Ok(None); } // delete the timestamp from the table before the new timestamp is written - table.delete_item(item_id).await?; + table.delete_item(item_id).await.map_mm_err()?; } let item = SwapLockTable { uuid, timestamp: now_sec(), }; - let record_id = table.add_item(&item).await?; + let record_id = table.add_item(&item).await.map_mm_err()?; Ok(Some(SwapLock { ctx: ctx.clone(), @@ -164,17 +164,17 @@ mod wasm_lock { async fn touch(&self) -> SwapLockResult<()> { let swaps_ctx = SwapsContext::from_ctx(&self.ctx).map_to_mm(SwapLockError::InternalError)?; - let db = swaps_ctx.swap_db().await?; + let db = swaps_ctx.swap_db().await.map_mm_err()?; let item = SwapLockTable { uuid: self.swap_uuid, timestamp: now_sec(), }; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; - let replaced_record_id = table.replace_item(self.record_id, &item).await?; + let replaced_record_id = table.replace_item(self.record_id, &item).await.map_mm_err()?; if self.record_id != replaced_record_id { let error = format!("Expected {} record id, found {}", self.record_id, replaced_record_id); @@ -187,10 +187,10 @@ mod wasm_lock { impl SwapLock { async fn release(ctx: MmArc, record_id: ItemId) -> SwapLockResult<()> { let swaps_ctx = SwapsContext::from_ctx(&ctx).map_to_mm(SwapLockError::InternalError)?; - let db = swaps_ctx.swap_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; - table.delete_item(record_id).await?; + let db = swaps_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; + table.delete_item(record_id).await.map_mm_err()?; Ok(()) } } diff --git a/mm2src/mm2_main/src/lp_swap/swap_v2_common.rs b/mm2src/mm2_main/src/lp_swap/swap_v2_common.rs index 3624d42b8d..9ddd5f6b4c 100644 --- a/mm2src/mm2_main/src/lp_swap/swap_v2_common.rs +++ b/mm2src/mm2_main/src/lp_swap/swap_v2_common.rs @@ -107,10 +107,10 @@ pub(super) async fn has_db_record_for(ctx: MmArc, id: &Uuid) -> MmResult MmResult { let swaps_ctx = SwapsContext::from_ctx(&ctx).expect("SwapsContext::from_ctx should not fail"); - let db = swaps_ctx.swap_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; - let maybe_item = table.get_item_by_unique_index("uuid", id).await?; + let db = swaps_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; + let maybe_item = table.get_item_by_unique_index("uuid", id).await.map_mm_err()?; Ok(maybe_item.is_some()) } @@ -143,11 +143,11 @@ pub(super) async fn store_swap_event MmResult<(), SwapStateMachineError> { let swaps_ctx = SwapsContext::from_ctx(&ctx).expect("SwapsContext::from_ctx should not fail"); - let db = swaps_ctx.swap_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = swaps_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; - let saved_swap_json = match table.get_item_by_unique_index("uuid", id).await? { + let saved_swap_json = match table.get_item_by_unique_index("uuid", id).await.map_mm_err()? { Some((_item_id, SavedSwapTable { saved_swap, .. })) => saved_swap, None => return MmError::err(SwapStateMachineError::NoSwapWithUuid(id)), }; @@ -159,18 +159,21 @@ pub(super) async fn store_swap_event(ctx: &MmArc, id: Uuid) -> MmResult { let swaps_ctx = SwapsContext::from_ctx(ctx).expect("SwapsContext::from_ctx should not fail"); - let db = swaps_ctx.swap_db().await?; - let transaction = db.transaction().await?; + let db = swaps_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; - let table = transaction.table::().await?; - let saved_swap_json = match table.get_item_by_unique_index("uuid", id).await? { + let table = transaction.table::().await.map_mm_err()?; + let saved_swap_json = match table.get_item_by_unique_index("uuid", id).await.map_mm_err()? { Some((_item_id, SavedSwapTable { saved_swap, .. })) => saved_swap, None => return MmError::err(SwapStateMachineError::NoSwapWithUuid(id)), }; @@ -197,14 +200,16 @@ pub(super) async fn get_unfinished_swaps_uuids( swap_type: u8, ) -> MmResult, SwapStateMachineError> { let index = MultiIndex::new(IS_FINISHED_SWAP_TYPE_INDEX) - .with_value(BoolAsInt::new(false))? - .with_value(swap_type)?; + .with_value(BoolAsInt::new(false)) + .map_mm_err()? + .with_value(swap_type) + .map_mm_err()?; let swaps_ctx = SwapsContext::from_ctx(&ctx).expect("SwapsContext::from_ctx should not fail"); - let db = swaps_ctx.swap_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; - let table_items = table.get_items_by_multi_index(index).await?; + let db = swaps_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; + let table_items = table.get_items_by_multi_index(index).await.map_mm_err()?; Ok(table_items.into_iter().map(|(_item_id, item)| item.uuid).collect()) } @@ -217,15 +222,18 @@ pub(super) async fn mark_swap_as_finished(ctx: MmArc, id: Uuid) -> MmResult<(), #[cfg(target_arch = "wasm32")] pub(super) async fn mark_swap_as_finished(ctx: MmArc, id: Uuid) -> MmResult<(), SwapStateMachineError> { let swaps_ctx = SwapsContext::from_ctx(&ctx).expect("SwapsContext::from_ctx should not fail"); - let db = swaps_ctx.swap_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; - let mut item = match table.get_item_by_unique_index("uuid", id).await? { + let db = swaps_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; + let mut item = match table.get_item_by_unique_index("uuid", id).await.map_mm_err()? { Some((_item_id, item)) => item, None => return MmError::err(SwapStateMachineError::NoSwapWithUuid(id)), }; item.is_finished = true.into(); - table.replace_item_by_unique_index("uuid", id, &item).await?; + table + .replace_item_by_unique_index("uuid", id, &item) + .await + .map_mm_err()?; Ok(()) } @@ -259,7 +267,7 @@ pub(super) fn clean_up_context_impl(ctx: &MmArc, uuid: &Uuid, maker_coin: &str, pub(super) async fn acquire_reentrancy_lock_impl(ctx: &MmArc, uuid: Uuid) -> MmResult { let mut attempts = 0; loop { - match SwapLock::lock(ctx, uuid, 40.).await? { + match SwapLock::lock(ctx, uuid, 40.).await.map_mm_err()? { Some(l) => break Ok(l), None => { if attempts >= 1 { diff --git a/mm2src/mm2_main/src/lp_swap/swap_v2_rpcs.rs b/mm2src/mm2_main/src/lp_swap/swap_v2_rpcs.rs index 92a305f252..b6490338de 100644 --- a/mm2src/mm2_main/src/lp_swap/swap_v2_rpcs.rs +++ b/mm2src/mm2_main/src/lp_swap/swap_v2_rpcs.rs @@ -80,10 +80,10 @@ pub(super) async fn get_swap_type(ctx: &MmArc, uuid: &Uuid) -> MmResult().await?; - let item = match table.get_item_by_unique_index("uuid", uuid).await? { + let db = swaps_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; + let item = match table.get_item_by_unique_index("uuid", uuid).await.map_mm_err()? { Some((_item_id, item)) => item, None => return Ok(None), }; @@ -189,16 +189,20 @@ pub(super) async fn get_maker_swap_data_for_rpc( uuid: &Uuid, ) -> MmResult>, SwapV2DbError> { let swaps_ctx = SwapsContext::from_ctx(ctx).unwrap(); - let db = swaps_ctx.swap_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; - let item = match table.get_item_by_unique_index("uuid", uuid).await? { + let db = swaps_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; + let item = match table.get_item_by_unique_index("uuid", uuid).await.map_mm_err()? { Some((_item_id, item)) => item, None => return Ok(None), }; - let filters_table = transaction.table::().await?; - let filter_item = match filters_table.get_item_by_unique_index("uuid", uuid).await? { + let filters_table = transaction.table::().await.map_mm_err()?; + let filter_item = match filters_table + .get_item_by_unique_index("uuid", uuid) + .await + .map_mm_err()? + { Some((_item_id, item)) => item, None => return Ok(None), }; @@ -230,16 +234,20 @@ pub(super) async fn get_taker_swap_data_for_rpc( uuid: &Uuid, ) -> MmResult>, SwapV2DbError> { let swaps_ctx = SwapsContext::from_ctx(ctx).unwrap(); - let db = swaps_ctx.swap_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; - let item = match table.get_item_by_unique_index("uuid", uuid).await? { + let db = swaps_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; + let item = match table.get_item_by_unique_index("uuid", uuid).await.map_mm_err()? { Some((_item_id, item)) => item, None => return Ok(None), }; - let filters_table = transaction.table::().await?; - let filter_item = match filters_table.get_item_by_unique_index("uuid", uuid).await? { + let filters_table = transaction.table::().await.map_mm_err()?; + let filter_item = match filters_table + .get_item_by_unique_index("uuid", uuid) + .await + .map_mm_err()? + { Some((_item_id, item)) => item, None => return Ok(None), }; @@ -301,18 +309,18 @@ async fn get_swap_data_by_uuid_and_type( ) -> MmResult, GetSwapDataErr> { match swap_type { LEGACY_SWAP_TYPE => { - let saved_swap = SavedSwap::load_my_swap_from_db(ctx, None, uuid).await?; + let saved_swap = SavedSwap::load_my_swap_from_db(ctx, None, uuid).await.map_mm_err()?; Ok(saved_swap.map(|swap| match swap { SavedSwap::Maker(m) => SwapRpcData::MakerV1(m), SavedSwap::Taker(t) => SwapRpcData::TakerV1(t), })) }, MAKER_SWAP_V2_TYPE => { - let data = get_maker_swap_data_for_rpc(ctx, &uuid).await?; + let data = get_maker_swap_data_for_rpc(ctx, &uuid).await.map_mm_err()?; Ok(data.map(SwapRpcData::MakerV2)) }, TAKER_SWAP_V2_TYPE => { - let data = get_taker_swap_data_for_rpc(ctx, &uuid).await?; + let data = get_taker_swap_data_for_rpc(ctx, &uuid).await.map_mm_err()?; Ok(data.map(SwapRpcData::TakerV2)) }, unsupported => MmError::err(GetSwapDataErr::UnsupportedSwapType(unsupported)), @@ -367,10 +375,12 @@ pub(crate) async fn my_swap_status_rpc( req: MySwapStatusRequest, ) -> MmResult { let swap_type = get_swap_type(&ctx, &req.uuid) - .await? + .await + .map_mm_err()? .or_mm_err(|| MySwapStatusError::NoSwapWithUuid(req.uuid))?; get_swap_data_by_uuid_and_type(&ctx, req.uuid, swap_type) - .await? + .await + .map_mm_err()? .or_mm_err(|| MySwapStatusError::NoSwapWithUuid(req.uuid)) } @@ -429,7 +439,8 @@ pub(crate) async fn my_recent_swaps_rpc( ) -> MmResult { let db_result = MySwapsStorage::new(ctx.clone()) .my_recent_swaps_with_filters(&req.filter, Some(&req.paging_options)) - .await?; + .await + .map_mm_err()?; let mut swaps = Vec::with_capacity(db_result.uuids_and_types.len()); for (uuid, swap_type) in db_result.uuids_and_types.iter() { match get_swap_data_by_uuid_and_type(&ctx, *uuid, *swap_type).await { diff --git a/mm2src/mm2_main/src/lp_swap/taker_swap.rs b/mm2src/mm2_main/src/lp_swap/taker_swap.rs index 1fdb9e728f..d35391b182 100644 --- a/mm2src/mm2_main/src/lp_swap/taker_swap.rs +++ b/mm2src/mm2_main/src/lp_swap/taker_swap.rs @@ -2649,7 +2649,8 @@ pub async fn taker_swap_trade_preimage( Some(prepared_params), stage, ) - .await?; + .await + .map_mm_err()?; let conf_settings = OrderConfirmationsSettings { base_confs: base_coin.required_confirmations(), @@ -2657,7 +2658,7 @@ pub async fn taker_swap_trade_preimage( rel_confs: rel_coin.required_confirmations(), rel_nota: rel_coin.requires_notarization(), }; - let our_public_id = CryptoCtx::from_ctx(ctx)?.mm2_internal_public_id(); + let our_public_id = CryptoCtx::from_ctx(ctx).map_mm_err()?.mm2_internal_public_id(); let order_builder = TakerOrderBuilder::new(&base_coin, &rel_coin) .with_base_amount(base_amount) @@ -2746,7 +2747,7 @@ pub async fn calc_max_taker_vol( stage: FeeApproxStage, ) -> CheckBalanceResult { let my_coin = coin.ticker(); - let balance: MmNumber = coin.my_spendable_balance().compat().await?.into(); + let balance: MmNumber = coin.my_spendable_balance().compat().await.map_mm_err()?.into(); let locked = get_locked_amount(ctx, my_coin); let min_tx_amount = MmNumber::from(coin.min_tx_amount()); diff --git a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs index 7f8270f139..2926156325 100644 --- a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs @@ -225,10 +225,10 @@ impl StateMachineStorage for TakerSwapStorage { #[cfg(target_arch = "wasm32")] async fn store_repr(&mut self, uuid: Self::MachineId, repr: Self::DbRepr) -> Result<(), Self::Error> { let swaps_ctx = SwapsContext::from_ctx(&self.ctx).expect("SwapsContext::from_ctx should not fail"); - let db = swaps_ctx.swap_db().await?; - let transaction = db.transaction().await?; + let db = swaps_ctx.swap_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; - let filters_table = transaction.table::().await?; + let filters_table = transaction.table::().await.map_mm_err()?; let item = MySwapsFiltersTable { uuid, @@ -238,14 +238,14 @@ impl StateMachineStorage for TakerSwapStorage { is_finished: false.into(), swap_type: TAKER_SWAP_V2_TYPE, }; - filters_table.add_item(&item).await?; + filters_table.add_item(&item).await.map_mm_err()?; - let table = transaction.table::().await?; + let table = transaction.table::().await.map_mm_err()?; let item = SavedSwapTable { uuid, saved_swap: serde_json::to_value(repr)?, }; - table.add_item(&item).await?; + table.add_item(&item).await.map_mm_err()?; Ok(()) } diff --git a/mm2src/mm2_main/src/lp_swap/trade_preimage.rs b/mm2src/mm2_main/src/lp_swap/trade_preimage.rs index cb31ed63e9..ceccd64241 100644 --- a/mm2src/mm2_main/src/lp_swap/trade_preimage.rs +++ b/mm2src/mm2_main/src/lp_swap/trade_preimage.rs @@ -29,8 +29,8 @@ pub async fn trade_preimage_rpc( return MmError::err(TradePreimageRpcError::CoinIsWalletOnly { coin: req.rel }); } - let base_coin = lp_coinfind_or_err(&ctx, &req.base).await?; - let rel_coin = lp_coinfind_or_err(&ctx, &req.rel).await?; + let base_coin = lp_coinfind_or_err(&ctx, &req.base).await.map_mm_err()?; + let rel_coin = lp_coinfind_or_err(&ctx, &req.rel).await.map_mm_err()?; match req.swap_method { TradePreimageMethod::SetPrice => maker_swap_trade_preimage(&ctx, req, base_coin, rel_coin) diff --git a/mm2src/mm2_main/src/lp_wallet.rs b/mm2src/mm2_main/src/lp_wallet.rs index 7743b05039..36124e7a16 100644 --- a/mm2src/mm2_main/src/lp_wallet.rs +++ b/mm2src/mm2_main/src/lp_wallet.rs @@ -118,7 +118,7 @@ async fn encrypt_and_save_passphrase( passphrase: &str, wallet_password: &str, ) -> WalletInitResult<()> { - let encrypted_passphrase_data = encrypt_mnemonic(passphrase, wallet_password)?; + let encrypted_passphrase_data = encrypt_mnemonic(passphrase, wallet_password).map_mm_err()?; save_encrypted_passphrase(ctx, wallet_name, &encrypted_passphrase_data) .await .mm_err(|e| WalletInitError::WalletsStorageError(e.to_string())) @@ -188,7 +188,10 @@ async fn retrieve_or_create_passphrase( wallet_name: &str, wallet_password: &str, ) -> WalletInitResult> { - match try_load_active_wallet_passphrase(ctx, wallet_password).await? { + match try_load_active_wallet_passphrase(ctx, wallet_password) + .await + .map_mm_err()? + { Some(passphrase_from_file) => { // If an existing passphrase is found, return it Ok(Some(passphrase_from_file)) @@ -204,9 +207,11 @@ async fn retrieve_or_create_passphrase( password_policy(wallet_password)?; } // If no passphrase is found, generate a new one - let new_passphrase = generate_mnemonic(ctx)?.to_string(); + let new_passphrase = generate_mnemonic(ctx).map_mm_err()?.to_string(); // Encrypt and save the new passphrase - encrypt_and_save_passphrase(ctx, wallet_name, &new_passphrase, wallet_password).await?; + encrypt_and_save_passphrase(ctx, wallet_name, &new_passphrase, wallet_password) + .await + .map_mm_err()?; Ok(Some(new_passphrase)) }, } @@ -219,7 +224,10 @@ async fn confirm_or_encrypt_and_store_passphrase( passphrase: &str, wallet_password: &str, ) -> WalletInitResult> { - match try_load_active_wallet_passphrase(ctx, wallet_password).await? { + match try_load_active_wallet_passphrase(ctx, wallet_password) + .await + .map_mm_err()? + { Some(passphrase_from_file) if passphrase == passphrase_from_file => { // If an existing passphrase is found and it matches the provided passphrase, return it Ok(Some(passphrase_from_file)) @@ -235,7 +243,9 @@ async fn confirm_or_encrypt_and_store_passphrase( password_policy(wallet_password)?; } // If no passphrase is found in the file, encrypt and save the provided passphrase - encrypt_and_save_passphrase(ctx, wallet_name, passphrase, wallet_password).await?; + encrypt_and_save_passphrase(ctx, wallet_name, passphrase, wallet_password) + .await + .map_mm_err()?; Ok(Some(passphrase.to_string())) }, _ => { @@ -253,9 +263,12 @@ async fn decrypt_validate_or_save_passphrase( wallet_password: &str, ) -> WalletInitResult> { // Decrypt the provided encrypted passphrase - let decrypted_passphrase = decrypt_mnemonic(&encrypted_passphrase_data, wallet_password)?; + let decrypted_passphrase = decrypt_mnemonic(&encrypted_passphrase_data, wallet_password).map_mm_err()?; - match try_load_active_wallet_passphrase(ctx, wallet_password).await? { + match try_load_active_wallet_passphrase(ctx, wallet_password) + .await + .map_mm_err()? + { Some(passphrase_from_file) if decrypted_passphrase == passphrase_from_file => { // If an existing passphrase is found and it matches the decrypted passphrase, return it Ok(Some(decrypted_passphrase)) @@ -315,8 +328,8 @@ async fn process_passphrase_logic( fn initialize_crypto_context(ctx: &MmArc, passphrase: &str) -> WalletInitResult<()> { // This defaults to false to maintain backward compatibility. match ctx.enable_hd() { - true => CryptoCtx::init_with_global_hd_account(ctx.clone(), passphrase)?, - false => CryptoCtx::init_with_iguana_passphrase(ctx.clone(), passphrase)?, + true => CryptoCtx::init_with_global_hd_account(ctx.clone(), passphrase).map_mm_err()?, + false => CryptoCtx::init_with_iguana_passphrase(ctx.clone(), passphrase).map_mm_err()?, }; Ok(()) } @@ -345,11 +358,14 @@ pub(crate) async fn initialize_wallet_passphrase(ctx: &MmArc) -> WalletInitResul let (wallet_name, passphrase) = deserialize_wallet_config(ctx)?; ctx.wallet_name .set(wallet_name.clone()) - .map_to_mm(|_| WalletInitError::InternalError("Already Initialized".to_string()))?; + .map_to_mm(|_| WalletInitError::InternalError("Already Initialized".to_string())) + .map_mm_err()?; - let passphrase = process_passphrase_logic(ctx, wallet_name.as_deref(), passphrase).await?; + let passphrase = process_passphrase_logic(ctx, wallet_name.as_deref(), passphrase) + .await + .map_mm_err()?; if let Some(passphrase) = passphrase { - initialize_crypto_context(ctx, &passphrase)?; + initialize_crypto_context(ctx, &passphrase).map_mm_err()?; } Ok(()) @@ -549,7 +565,8 @@ pub async fn get_mnemonic_rpc(ctx: MmArc, req: GetMnemonicRequest) -> MmResult MmResult { let plaintext_mnemonic = try_load_active_wallet_passphrase(&ctx, &wallet_password) - .await? + .await + .map_mm_err()? .ok_or_else(|| MnemonicRpcError::InvalidRequest("Wallet mnemonic file not found".to_string()))?; Ok(GetMnemonicResponse { mnemonic: plaintext_mnemonic.into(), @@ -576,7 +594,7 @@ pub struct GetWalletNamesResponse { /// 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(); + let wallets = read_all_wallet_names(&ctx).await.map_mm_err()?.sorted().collect(); // Note: `ok_or` is used here on `Constructible>` to handle the case where the wallet name is not set. // `wallet_name` can be `None` in the case of no-login mode. let activated_wallet = ctx.wallet_name.get().ok_or(MnemonicRpcError::Internal( @@ -620,14 +638,17 @@ pub async fn change_mnemonic_password(ctx: MmArc, req: ChangeMnemonicPasswordReq .ok_or_else(|| MnemonicRpcError::Internal("`wallet_name` cannot be None!".to_string()))?; // read mnemonic for a wallet_name using current user's password. let mnemonic = try_load_active_wallet_passphrase(&ctx, &req.current_password) - .await? + .await + .map_mm_err()? .ok_or(MmError::new(MnemonicRpcError::Internal(format!( "{wallet_name}: wallet mnemonic file not found" ))))?; // encrypt mnemonic with new passphrase. - let encrypted_data = encrypt_mnemonic(&mnemonic, &req.new_password)?; + let encrypted_data = encrypt_mnemonic(&mnemonic, &req.new_password).map_mm_err()?; // save new encrypted mnemonic data with new password - save_encrypted_passphrase(&ctx, wallet_name, &encrypted_data).await?; + save_encrypted_passphrase(&ctx, wallet_name, &encrypted_data) + .await + .map_mm_err()?; Ok(()) } @@ -659,12 +680,14 @@ pub async fn delete_wallet_rpc(ctx: MmArc, req: DeleteWalletRequest) -> MmResult } // Verify the password by attempting to decrypt the mnemonic. - let maybe_mnemonic = try_load_wallet_passphrase(&ctx, &req.wallet_name, &req.password).await?; + let maybe_mnemonic = try_load_wallet_passphrase(&ctx, &req.wallet_name, &req.password) + .await + .map_mm_err()?; match maybe_mnemonic { Some(_) => { // Password is correct, proceed with deletion. - delete_wallet(&ctx, &req.wallet_name).await?; + delete_wallet(&ctx, &req.wallet_name).await.map_mm_err()?; Ok(()) }, None => { diff --git a/mm2src/mm2_main/src/lp_wallet/mnemonics_wasm_db.rs b/mm2src/mm2_main/src/lp_wallet/mnemonics_wasm_db.rs index 6eeaebc8d4..4c3dcd023b 100644 --- a/mm2src/mm2_main/src/lp_wallet/mnemonics_wasm_db.rs +++ b/mm2src/mm2_main/src/lp_wallet/mnemonics_wasm_db.rs @@ -99,9 +99,9 @@ pub(super) async fn save_encrypted_passphrase( ) -> WalletsDBResult<()> { let wallets_ctx = WalletsContext::from_ctx(ctx).map_to_mm(WalletsDBError::Internal)?; - let db = wallets_ctx.wallets_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = wallets_ctx.wallets_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; let mnemonics_table_item = MnemonicsTable { wallet_name: wallet_name.to_string(), @@ -114,7 +114,8 @@ pub(super) async fn save_encrypted_passphrase( }; table .replace_item_by_unique_index("wallet_name", wallet_name, &mnemonics_table_item) - .await?; + .await + .map_mm_err()?; Ok(()) } @@ -125,13 +126,14 @@ pub(super) async fn read_encrypted_passphrase( ) -> WalletsDBResult> { let wallets_ctx = WalletsContext::from_ctx(ctx).map_to_mm(WalletsDBError::Internal)?; - let db = wallets_ctx.wallets_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = wallets_ctx.wallets_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; table .get_item_by_unique_index("wallet_name", wallet_name) - .await? + .await + .map_mm_err()? .map(|(_item_id, wallet_table_item)| { serde_json::from_str(&wallet_table_item.encrypted_mnemonic).map_to_mm(|e| { WalletsDBError::DeserializationError { @@ -146,11 +148,11 @@ pub(super) async fn read_encrypted_passphrase( pub(super) async fn read_all_wallet_names(ctx: &MmArc) -> WalletsDBResult> { let wallets_ctx = WalletsContext::from_ctx(ctx).map_to_mm(WalletsDBError::Internal)?; - let db = wallets_ctx.wallets_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = wallets_ctx.wallets_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; - let all_items = table.get_all_items().await?; + let all_items = table.get_all_items().await.map_mm_err()?; let wallet_names = all_items.into_iter().map(|(_, item)| item.wallet_name); Ok(wallet_names) @@ -159,10 +161,13 @@ pub(super) async fn read_all_wallet_names(ctx: &MmArc) -> WalletsDBResult WalletsDBResult<()> { let wallets_ctx = WalletsContext::from_ctx(ctx).map_to_mm(WalletsDBError::Internal)?; - let db = wallets_ctx.wallets_db().await?; - let transaction = db.transaction().await?; - let table = transaction.table::().await?; + let db = wallets_ctx.wallets_db().await.map_mm_err()?; + let transaction = db.transaction().await.map_mm_err()?; + let table = transaction.table::().await.map_mm_err()?; - table.delete_item_by_unique_index("wallet_name", wallet_name).await?; + table + .delete_item_by_unique_index("wallet_name", wallet_name) + .await + .map_mm_err()?; Ok(()) } diff --git a/mm2src/mm2_main/src/rpc/lp_commands/one_inch/rpcs.rs b/mm2src/mm2_main/src/rpc/lp_commands/one_inch/rpcs.rs index 978a1d80b5..45fec7f680 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/one_inch/rpcs.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/one_inch/rpcs.rs @@ -69,7 +69,7 @@ pub async fn one_inch_v6_0_classic_swap_create_rpc( api_supports_pair(&base, &rel)?; let sell_amount = wei_from_big_decimal(&req.amount.to_decimal(), base.decimals()) .mm_err(|err| ApiIntegrationRpcError::InvalidParam(err.to_string()))?; - let single_address = base.derivation_method().single_addr_or_err().await?; + let single_address = base.derivation_method().single_addr_or_err().await.map_mm_err()?; let query_params = ClassicSwapCreateParams::new( base_contract, @@ -145,7 +145,7 @@ pub async fn one_inch_v6_0_classic_swap_tokens_rpc( } async fn get_coin_for_one_inch(ctx: &MmArc, ticker: &str) -> MmResult<(EthCoin, String), ApiIntegrationRpcError> { - let coin = match lp_coinfind_or_err(ctx, ticker).await? { + let coin = match lp_coinfind_or_err(ctx, ticker).await.map_mm_err()? { MmCoinEnum::EthCoin(coin) => coin, _ => return Err(MmError::new(ApiIntegrationRpcError::CoinTypeError)), }; diff --git a/mm2src/mm2_main/src/rpc/lp_commands/one_inch/types.rs b/mm2src/mm2_main/src/rpc/lp_commands/one_inch/types.rs index 202eb0dcf2..8324e801d4 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/one_inch/types.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/one_inch/types.rs @@ -152,7 +152,10 @@ impl ClassicSwapResponse { decimals: u8, ) -> MmResult { Ok(Self { - dst_amount: MmNumber::from(u256_to_big_decimal(U256::from_dec_str(&data.dst_amount)?, decimals)?).into(), + dst_amount: MmNumber::from( + u256_to_big_decimal(U256::from_dec_str(&data.dst_amount)?, decimals).map_mm_err()?, + ) + .into(), src_token: data.src_token, dst_token: data.dst_token, protocols: data.protocols, @@ -185,8 +188,8 @@ impl TxFields { from: tx_fields.from, to: tx_fields.to, data: BytesJson::from(hex::decode(str_strip_0x!(tx_fields.data.as_str()))?), - value: u256_to_big_decimal(U256::from_dec_str(&tx_fields.value)?, decimals)?, - gas_price: wei_to_gwei_decimal(U256::from_dec_str(&tx_fields.gas_price)?)?, + value: u256_to_big_decimal(U256::from_dec_str(&tx_fields.value)?, decimals).map_mm_err()?, + gas_price: wei_to_gwei_decimal(U256::from_dec_str(&tx_fields.gas_price)?).map_mm_err()?, gas: tx_fields.gas, }) } diff --git a/mm2src/mm2_main/src/rpc/lp_commands/pubkey.rs b/mm2src/mm2_main/src/rpc/lp_commands/pubkey.rs index f5a5a95063..6a84641f45 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/pubkey.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/pubkey.rs @@ -33,7 +33,10 @@ impl HttpStatusCode for GetPublicKeyError { } pub async fn get_public_key(ctx: MmArc, _req: Json) -> GetPublicKeyRpcResult { - let public_key = CryptoCtx::from_ctx(&ctx)?.mm2_internal_pubkey().to_string(); + let public_key = CryptoCtx::from_ctx(&ctx) + .map_mm_err()? + .mm2_internal_pubkey() + .to_string(); Ok(GetPublicKeyResponse { public_key }) } diff --git a/mm2src/mm2_main/src/rpc/lp_commands/tokens.rs b/mm2src/mm2_main/src/rpc/lp_commands/tokens.rs index 78697530c1..da54111581 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/tokens.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/tokens.rs @@ -11,6 +11,7 @@ use ethereum_types::Address as EthAddress; use futures::compat::Future01CompatExt; use http::StatusCode; use mm2_core::mm_ctx::MmArc; +use mm2_err_handle::map_mm_error::MmResultExt; use mm2_err_handle::{map_to_mm::MapToMmResult, mm_error::MmError, prelude::MmResult}; use mm2_number::BigDecimal; @@ -73,7 +74,7 @@ pub async fn get_token_info(ctx: MmArc, req: TokenInfoRequest) -> MmResult { let contract_address_str = @@ -141,8 +142,8 @@ pub struct Erc20AllowanceRequest { /// Returns BigDecimal allowance value. pub async fn get_token_allowance_rpc(ctx: MmArc, req: Erc20AllowanceRequest) -> MmResult { let eth_coin = find_erc20_eth_coin(&ctx, &req.coin).await?; - let wei = eth_coin.allowance(req.spender).compat().await?; - let amount = u256_to_big_decimal(wei, eth_coin.decimals())?; + let wei = eth_coin.allowance(req.spender).compat().await.map_mm_err()?; + let amount = u256_to_big_decimal(wei, eth_coin.decimals()).map_mm_err()?; Ok(amount) } @@ -157,7 +158,7 @@ pub struct Erc20ApproveRequest { /// Returns approval transaction hash. pub async fn approve_token_rpc(ctx: MmArc, req: Erc20ApproveRequest) -> MmResult { let eth_coin = find_erc20_eth_coin(&ctx, &req.coin).await?; - let amount = wei_from_big_decimal(&req.amount, eth_coin.decimals())?; + let amount = wei_from_big_decimal(&req.amount, eth_coin.decimals()).map_mm_err()?; let tx = eth_coin.approve(req.spender, amount).compat().await?; Ok(format!("0x{:02x}", tx.tx_hash_as_bytes())) } diff --git a/mm2src/mm2_main/src/rpc/lp_commands/trezor.rs b/mm2src/mm2_main/src/rpc/lp_commands/trezor.rs index 16698eb3cc..212c810331 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/trezor.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/trezor.rs @@ -2,6 +2,7 @@ use common::HttpStatusCode; use crypto::{CryptoCtx, CryptoCtxError, HwConnectionStatus, HwPubkey}; use http::StatusCode; use mm2_core::mm_ctx::MmArc; +use mm2_err_handle::map_mm_error::MmResultExt; use mm2_err_handle::mm_error::{MmError, MmResult}; use mm2_err_handle::or_mm_error::OrMmError; @@ -45,7 +46,7 @@ pub async fn trezor_connection_status( ctx: MmArc, req: TrezorConnectionStatusReq, ) -> MmResult { - let crypto_ctx = CryptoCtx::from_ctx(&ctx)?; + let crypto_ctx = CryptoCtx::from_ctx(&ctx).map_mm_err()?; let hw_ctx = crypto_ctx .hw_ctx() .or_mm_err(|| TrezorConnectionError::TrezorNotInitialized)?; diff --git a/mm2src/mm2_net/src/grpc_web.rs b/mm2src/mm2_net/src/grpc_web.rs index 55f796df82..2a62126c79 100644 --- a/mm2src/mm2_net/src/grpc_web.rs +++ b/mm2src/mm2_net/src/grpc_web.rs @@ -153,11 +153,11 @@ where .uri(url) .header(CONTENT_TYPE, APPLICATION_GRPC_WEB) .header(ACCEPT, APPLICATION_GRPC_WEB) - .body(encode_body(req)?)?; + .body(encode_body(req).map_mm_err()?)?; - let response = slurp_req(request).await?; + let response = slurp_req(request).await.map_mm_err()?; - let reply = decode_body(response.2.into())?; + let reply = decode_body(response.2.into()).map_mm_err()?; Ok(reply) } @@ -168,7 +168,7 @@ where Req: prost::Message + Send + 'static, Res: prost::Message + Default + Send + 'static, { - let body = encode_body(req)?; + let body = encode_body(req).map_mm_err()?; let request = FetchRequest::post(url) .body_bytes(body) .header(CONTENT_TYPE.as_str(), APPLICATION_GRPC_WEB_PROTO) @@ -176,9 +176,9 @@ where // https://github.com/grpc/grpc-web/issues/85#issue-217223001 .header(X_GRPC_WEB, "1"); - let response = request.request_array().await?; + let response = request.request_array().await.map_mm_err()?; - let reply = decode_body(response.1.into())?; + let reply = decode_body(response.1.into()).map_mm_err()?; Ok(reply) } diff --git a/mm2src/mm2_net/src/native_http.rs b/mm2src/mm2_net/src/native_http.rs index 6837c04655..b056c4ec03 100644 --- a/mm2src/mm2_net/src/native_http.rs +++ b/mm2src/mm2_net/src/native_http.rs @@ -245,7 +245,7 @@ pub async fn send_request_to_uri(uri: &str, auth_header: Option<&str>) -> MmResu } let request = request_builder.body(Body::empty())?; - let (status, _header, body) = slurp_req_body(request).await?; + let (status, _header, body) = slurp_req_body(request).await.map_mm_err()?; if !status.is_success() { return Err(MmError::new(GetInfoFromUriError::Transport(format!( "Status code not in 2xx range from {}: {}, {}", diff --git a/mm2src/mm2_net/src/transport.rs b/mm2src/mm2_net/src/transport.rs index 750d2561c2..cad2d553ed 100644 --- a/mm2src/mm2_net/src/transport.rs +++ b/mm2src/mm2_net/src/transport.rs @@ -113,7 +113,7 @@ impl From for GetInfoFromUriError { /// /// Returns an error if the HTTP status code of the response is not in the 2xx range. pub async fn send_post_request_to_uri(uri: &str, body: String) -> MmResult, GetInfoFromUriError> { - let (status, _header, body) = slurp_post_json(uri, body).await?; + let (status, _header, body) = slurp_post_json(uri, body).await.map_mm_err()?; if !status.is_success() { return Err(MmError::new(GetInfoFromUriError::Transport(format!( "Status code not in 2xx range from {}: {}", diff --git a/mm2src/mm2_net/src/wasm/tonic_client.rs b/mm2src/mm2_net/src/wasm/tonic_client.rs index 84df389e73..ccdb3ae4a4 100644 --- a/mm2src/mm2_net/src/wasm/tonic_client.rs +++ b/mm2src/mm2_net/src/wasm/tonic_client.rs @@ -6,7 +6,7 @@ use common::{APPLICATION_GRPC_WEB_PROTO, X_GRPC_WEB}; use futures_util::Future; use http::header::{ACCEPT, CONTENT_TYPE}; use http::{Request, Response}; -use mm2_err_handle::prelude::{MmError, MmResult}; +use mm2_err_handle::prelude::*; use std::pin::Pin; use std::task::{Context, Poll}; use tonic::body::BoxBody; @@ -48,6 +48,7 @@ async fn call(base_url: String, request: Request) -> MmResult return Ok(result), TrezorResponse::ButtonRequest(button_req) => { - processor_req.on_button_request().await?; - button_req.ack().await? + processor_req.on_button_request().await.map_mm_err()?; + button_req.ack().await.map_mm_err()? }, TrezorResponse::PinMatrixRequest(pin_req) => { - let pin_response = processor_req.on_pin_request().await?; - pin_req.ack_pin(pin_response.pin).await? + let pin_response = processor_req.on_pin_request().await.map_mm_err()?; + pin_req.ack_pin(pin_response.pin).await.map_mm_err()? }, TrezorResponse::PassphraseRequest(passphrase_req) => { - let passphrase_response = processor_req.on_passphrase_request().await?; - passphrase_req.ack_passphrase(passphrase_response.passphrase).await? + let passphrase_response = processor_req.on_passphrase_request().await.map_mm_err()?; + passphrase_req + .ack_passphrase(passphrase_response.passphrase) + .await + .map_mm_err()? }, }; } }; let res = fut.await; - processor.on_ready().await?; + processor.on_ready().await.map_mm_err()?; res } } diff --git a/mm2src/trezor/src/response_processor.rs b/mm2src/trezor/src/response_processor.rs index 33a3e0c46a..dba89a38c6 100644 --- a/mm2src/trezor/src/response_processor.rs +++ b/mm2src/trezor/src/response_processor.rs @@ -17,9 +17,6 @@ impl From for TrezorProcessingError { fn from(e: TrezorError) -> Self { TrezorProcessingError::TrezorError(e) } } -/// This is required for implementing `MmError>: From>`. -impl NotEqual for TrezorProcessingError {} - #[async_trait] pub trait TrezorRequestProcessor where diff --git a/mm2src/trezor/src/transport/usb.rs b/mm2src/trezor/src/transport/usb.rs index cfdba0d36c..bf69871154 100644 --- a/mm2src/trezor/src/transport/usb.rs +++ b/mm2src/trezor/src/transport/usb.rs @@ -6,6 +6,7 @@ use crate::TrezorResult; use async_trait::async_trait; use hw_common::transport::libusb::{GetDevicesFilters, UsbAvailableDevice as UsbAvailableDeviceImpl, UsbContext, UsbDevice}; +use mm2_err_handle::prelude::MmResultExt; use std::time::Duration; pub use hw_common::transport::libusb::UsbDeviceInfo; @@ -44,17 +45,21 @@ struct UsbLink { impl Link for UsbLink { async fn write_chunk(&mut self, chunk: Vec) -> TrezorResult<()> { // don't try to reconnect since libusb requires to enumerate all devices, ope and, claim interface again - Ok(self.device.write_chunk(chunk, WRITE_TIMEOUT).await?) + Ok(self.device.write_chunk(chunk, WRITE_TIMEOUT).await.map_mm_err()?) } async fn read_chunk(&mut self, chunk_len: u32) -> TrezorResult> { // don't try to reconnect since libusb requires to enumerate all devices, ope and, claim interface again - Ok(self.device.read_chunk(chunk_len as usize, READ_TIMEOUT).await?) + Ok(self + .device + .read_chunk(chunk_len as usize, READ_TIMEOUT) + .await + .map_mm_err()?) } } async fn find_devices() -> TrezorResult> { - let context = UsbContext::new()?; + let context = UsbContext::new().map_mm_err()?; let filters = GetDevicesFilters { config_id: CONFIG_ID, interface_id: INTERFACE, @@ -62,7 +67,8 @@ async fn find_devices() -> TrezorResult> { interface_class_code: LIBUSB_CLASS_VENDOR_SPEC, }; Ok(context - .get_devices(filters)? + .get_devices(filters) + .map_mm_err()? .into_iter() .filter(is_trezor) .map(UsbAvailableDevice) @@ -75,7 +81,7 @@ impl UsbAvailableDevice { /// Please note [`hw_common::transport::libusb::UsbAvailableDevice::connect`] spawns a thread. async fn connect(&self) -> TrezorResult { let link = UsbLink { - device: self.0.connect()?, + device: self.0.connect().map_mm_err()?, }; Ok(UsbTransport { protocol: ProtocolV1 { link }, diff --git a/mm2src/trezor/src/transport/webusb.rs b/mm2src/trezor/src/transport/webusb.rs index 6c438cea74..a1fc4cf1d9 100644 --- a/mm2src/trezor/src/transport/webusb.rs +++ b/mm2src/trezor/src/transport/webusb.rs @@ -44,17 +44,22 @@ struct WebUsbLink { #[async_trait] impl Link for WebUsbLink { async fn write_chunk(&mut self, chunk: Vec) -> TrezorResult<()> { - if !self.device.is_open().await? { + if !self.device.is_open().await.map_mm_err()? { return MmError::err(TrezorError::DeviceDisconnected); } - Ok(self.device.write_chunk(self.endpoint_number, chunk).await?) + + self.device.write_chunk(self.endpoint_number, chunk).await.map_mm_err() } async fn read_chunk(&mut self, chunk_len: u32) -> TrezorResult> { - if !self.device.is_open().await? { + if !self.device.is_open().await.map_mm_err()? { return MmError::err(TrezorError::DeviceDisconnected); } - Ok(self.device.read_chunk(self.endpoint_number, chunk_len).await?) + + self.device + .read_chunk(self.endpoint_number, chunk_len) + .await + .map_mm_err() } } @@ -66,15 +71,15 @@ impl WebUsbLink { /// Configure the WebUSB device. async fn establish_connection(&self, first: bool) -> TrezorResult<()> { - self.device.open().await?; + self.device.open().await.map_mm_err()?; if first { - self.device.select_configuration(CONFIGURATION_ID).await?; + self.device.select_configuration(CONFIGURATION_ID).await.map_mm_err()?; if let Err(e) = self.device.reset_device().await { // Reset fails on ChromeOS and Windows. warn!("{}", e); } } - self.device.claim_interface(self.interface_number).await?; + self.device.claim_interface(self.interface_number).await.map_mm_err()?; Ok(()) } } @@ -115,11 +120,12 @@ pub struct FoundDevices { /// /// This function **must** be called via a user gesture like a touch or mouse click. pub async fn find_devices() -> TrezorResult { - let wrapper = WebUsbWrapper::new()?; + let wrapper = WebUsbWrapper::new().map_mm_err()?; wrapper .request_device(TREZOR_DEVICES.iter().copied().map(DeviceFilter::from).collect()) - .await?; - let devices_iter = wrapper.get_devices().await?.into_iter().filter(is_trezor); + .await + .map_mm_err()?; + let devices_iter = wrapper.get_devices().await.map_mm_err()?.into_iter().filter(is_trezor); let mut available = Vec::new(); let mut not_supported = Vec::new(); for device in devices_iter { From 7f27264d4e5bdaed86e51cb9145468dc9052966c Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 26 Jun 2025 05:23:27 +0100 Subject: [PATCH 02/75] chore(core): replace hash_raw_entry with stable entry() API (#2473) --- mm2src/coins/lp_coins.rs | 20 +++++++++---------- mm2src/coins/utxo/tx_cache/fs_tx_cache.rs | 15 +++++--------- mm2src/common/common.rs | 1 - mm2src/mm2_main/src/lp_ordermatch.rs | 17 +++++----------- .../lp_ordermatch/order_requests_tracker.rs | 20 +++++++++---------- mm2src/mm2_main/src/mm2.rs | 1 - mm2src/mm2_main/tests/docker_tests_main.rs | 1 - .../mm2_main/tests/docker_tests_sia_unique.rs | 1 - 8 files changed, 29 insertions(+), 47 deletions(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 5f749b8389..81bd868324 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -29,7 +29,6 @@ #![allow(uncommon_codepoints)] // #![feature(integer_atomics)] #![feature(async_closure)] -#![feature(hash_raw_entry)] #![feature(stmt_expr_attributes)] #![feature(result_flattening)] #![feature(local_key_cell_methods)] // for tests @@ -77,7 +76,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::{self as json, Value as Json}; use std::array::TryFromSliceError; use std::cmp::Ordering; -use std::collections::hash_map::{HashMap, RawEntryMut}; +use std::collections::hash_map::{Entry, HashMap}; use std::collections::HashSet; use std::num::{NonZeroUsize, TryFromIntError}; use std::ops::{Add, AddAssign, Deref}; @@ -5005,20 +5004,21 @@ pub async fn lp_register_coin( // activated concurrently which results in long activation time: https://github.com/KomodoPlatform/atomicDEX/issues/24 // So I'm leaving the possibility of race condition intentionally in favor of faster concurrent activation. // Should consider refactoring: maybe extract the RPC client initialization part from coin init functions. - let mut coins = cctx.coins.lock().await; - match coins.raw_entry_mut().from_key(&ticker) { - RawEntryMut::Occupied(_oe) => { - return MmError::err(RegisterCoinError::CoinIsInitializedAlready { coin: ticker.clone() }) - }, - RawEntryMut::Vacant(ve) => ve.insert(ticker.clone(), MmCoinStruct::new(coin.clone())), + { + let mut coins = cctx.coins.lock().await; + match coins.entry(ticker.clone()) { + Entry::Occupied(_oe) => return MmError::err(RegisterCoinError::CoinIsInitializedAlready { coin: ticker }), + Entry::Vacant(ve) => ve.insert(MmCoinStruct::new(coin.clone())), + }; }; if coin.is_platform_coin() { - let mut platform_coin_tokens = cctx.platform_coin_tokens.lock(); - platform_coin_tokens + cctx.platform_coin_tokens + .lock() .entry(coin.ticker().to_string()) .or_insert_with(HashSet::new); } + Ok(()) } diff --git a/mm2src/coins/utxo/tx_cache/fs_tx_cache.rs b/mm2src/coins/utxo/tx_cache/fs_tx_cache.rs index 9327bd5163..84f1da7c52 100644 --- a/mm2src/coins/utxo/tx_cache/fs_tx_cache.rs +++ b/mm2src/coins/utxo/tx_cache/fs_tx_cache.rs @@ -7,7 +7,6 @@ use mm2_err_handle::prelude::*; use mm2_io::fs::{read_json, write_json, FsJsonError}; use parking_lot::Mutex as PaMutex; use rpc::v1::types::{Transaction as RpcTransaction, H256 as H256Json}; -use std::collections::hash_map::RawEntryMut; use std::collections::{HashMap, HashSet}; use std::path::PathBuf; use std::sync::Arc; @@ -37,15 +36,11 @@ struct TxCacheLock { impl TxCacheLock { /// Get the mutex corresponding to the specified `ticker`. pub fn mutex_by_ticker(&self, ticker: &str) -> Arc> { - let mut locks = self.mutexes.lock(); - - match locks.raw_entry_mut().from_key(ticker) { - RawEntryMut::Occupied(mutex) => mutex.get().clone(), - RawEntryMut::Vacant(vacant_mutex) => { - let (_key, mutex) = vacant_mutex.insert(ticker.to_owned(), Arc::new(AsyncMutex::new(()))); - mutex.clone() - }, - } + self.mutexes + .lock() + .entry(ticker.to_owned()) + .or_insert_with(|| Arc::new(AsyncMutex::new(()))) + .clone() } } diff --git a/mm2src/common/common.rs b/mm2src/common/common.rs index b2e00d5e57..7896df9d1d 100644 --- a/mm2src/common/common.rs +++ b/mm2src/common/common.rs @@ -13,7 +13,6 @@ #![allow(uncommon_codepoints)] #![feature(integer_atomics, panic_info_message)] #![feature(async_closure)] -#![feature(hash_raw_entry)] #![feature(drain_filter)] #[macro_use] extern crate arrayref; diff --git a/mm2src/mm2_main/src/lp_ordermatch.rs b/mm2src/mm2_main/src/lp_ordermatch.rs index 5fd6b8c8c7..0975675158 100644 --- a/mm2src/mm2_main/src/lp_ordermatch.rs +++ b/mm2src/mm2_main/src/lp_ordermatch.rs @@ -62,7 +62,7 @@ use rpc::v1::types::H256 as H256Json; use secp256k1::PublicKey as Secp256k1Pubkey; use serde_json::{self as json, Value as Json}; use sp_trie::{delta_trie_root, MemoryDB, Trie, TrieConfiguration, TrieDB, TrieDBMut, TrieHash, TrieMut}; -use std::collections::hash_map::{Entry, HashMap, RawEntryMut}; +use std::collections::hash_map::{Entry, HashMap}; use std::collections::{BTreeSet, HashSet}; use std::convert::TryInto; use std::fmt; @@ -2528,20 +2528,13 @@ fn pubkey_state_mut<'a>( state: &'a mut HashMap, from_pubkey: &str, ) -> &'a mut OrderbookPubkeyState { - match state.raw_entry_mut().from_key(from_pubkey) { - RawEntryMut::Occupied(e) => e.into_mut(), - RawEntryMut::Vacant(e) => { - let state = OrderbookPubkeyState::new(); - e.insert(from_pubkey.to_string(), state).1 - }, - } + state + .entry(from_pubkey.to_owned()) + .or_insert_with(OrderbookPubkeyState::new) } fn order_pair_root_mut<'a>(state: &'a mut HashMap, pair: &str) -> &'a mut H64 { - match state.raw_entry_mut().from_key(pair) { - RawEntryMut::Occupied(e) => e.into_mut(), - RawEntryMut::Vacant(e) => e.insert(pair.to_string(), Default::default()).1, - } + state.entry(pair.to_owned()).or_insert_with(Default::default) } /// `parity_util_mem::malloc_size` crushes for some reason on wasm32 diff --git a/mm2src/mm2_main/src/lp_ordermatch/order_requests_tracker.rs b/mm2src/mm2_main/src/lp_ordermatch/order_requests_tracker.rs index 66a0ba6fef..2c102968fe 100644 --- a/mm2src/mm2_main/src/lp_ordermatch/order_requests_tracker.rs +++ b/mm2src/mm2_main/src/lp_ordermatch/order_requests_tracker.rs @@ -1,8 +1,6 @@ #![allow(dead_code)] use compatible_time::Instant; -use std::{collections::hash_map::{HashMap, RawEntryMut}, - num::NonZeroUsize, - time::Duration}; +use std::{collections::hash_map::HashMap, num::NonZeroUsize, time::Duration}; const ONE_SECOND: Duration = Duration::from_secs(1); @@ -27,16 +25,16 @@ impl OrderRequestsTracker { pub fn peer_requested(&mut self, peer: &str) { let now = Instant::now(); - let peer_requested_at = match self.requested_at.raw_entry_mut().from_key(peer) { - RawEntryMut::Occupied(e) => e.into_mut(), - RawEntryMut::Vacant(e) => { - let tuple = e.insert(peer.to_string(), Vec::with_capacity(self.limit_per_sec.get())); - tuple.1 - }, - }; - if peer_requested_at.len() >= self.limit_per_sec.get() { + let limit_per_sec = self.limit_per_sec.get(); + let peer_requested_at = self + .requested_at + .entry(peer.to_owned()) + .or_insert_with(|| Vec::with_capacity(limit_per_sec)); + + if peer_requested_at.len() >= limit_per_sec { peer_requested_at.pop(); } + peer_requested_at.insert(0, now); } diff --git a/mm2src/mm2_main/src/mm2.rs b/mm2src/mm2_main/src/mm2.rs index 37ad202ed8..42cf7fbc3b 100644 --- a/mm2src/mm2_main/src/mm2.rs +++ b/mm2src/mm2_main/src/mm2.rs @@ -21,7 +21,6 @@ // Copyright © 2023 Pampex LTD and TillyHK LTD. All rights reserved. // -#![feature(hash_raw_entry)] // `mockable` implementation uses these #![allow( forgetting_references, diff --git a/mm2src/mm2_main/tests/docker_tests_main.rs b/mm2src/mm2_main/tests/docker_tests_main.rs index e5fdaafa8b..7465728008 100644 --- a/mm2src/mm2_main/tests/docker_tests_main.rs +++ b/mm2src/mm2_main/tests/docker_tests_main.rs @@ -4,7 +4,6 @@ #![feature(test)] #![test_runner(docker_tests_runner)] #![feature(drain_filter)] -#![feature(hash_raw_entry)] #![cfg(not(target_arch = "wasm32"))] #![feature(local_key_cell_methods)] // for setting global vars in tests diff --git a/mm2src/mm2_main/tests/docker_tests_sia_unique.rs b/mm2src/mm2_main/tests/docker_tests_sia_unique.rs index a176277c64..b8c2b74fea 100644 --- a/mm2src/mm2_main/tests/docker_tests_sia_unique.rs +++ b/mm2src/mm2_main/tests/docker_tests_sia_unique.rs @@ -5,7 +5,6 @@ #![feature(test)] #![test_runner(docker_tests_runner)] #![feature(drain_filter)] -#![feature(hash_raw_entry)] #![cfg(not(target_arch = "wasm32"))] #![feature(local_key_cell_methods)] From 8a2ccf664bc46d7dd2edb1ae4504f92b62413f9d Mon Sep 17 00:00:00 2001 From: shamardy <39480341+shamardy@users.noreply.github.com> Date: Tue, 1 Jul 2025 21:03:40 +0300 Subject: [PATCH 03/75] fix(kdf_walletconnect): apply explicit MmError mapping (#2514) * post merge fix: After merging staging into dev, there were compilation errors due to #2443, this fixes it * review fix: Improve error handling with `.into()` --- mm2src/kdf_walletconnect/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 8acf4895a2..50d2115f92 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -298,7 +298,7 @@ impl WalletConnectCtxImpl { .timeout_secs(PUBLISH_TIMEOUT_SECS) .await .map_to_mm(|_| WalletConnectError::TimeoutError)? - .map_to_mm(|e| e)?; + .map_to_mm(|e| e.into())?; info!("[{topic}] Subscribed to topic"); @@ -474,7 +474,7 @@ impl WalletConnectCtxImpl { .timeout_secs(PUBLISH_TIMEOUT_SECS) .await .map_to_mm(|_| WalletConnectError::TimeoutError)? - .map_to_mm(|e| e)?; + .map_to_mm(|e| e.into())?; info!("[{topic}] Message published successfully"); Ok(()) From 8c9326ea3e950020ec1b439f606384e54a47b8ec Mon Sep 17 00:00:00 2001 From: dimxy Date: Wed, 2 Jul 2025 15:12:51 +0500 Subject: [PATCH 04/75] feat(swap): rpc to find best swap with liquidity routing for ask (#2362) This introduces a new experimental RPC, `experimental::liquidity_routing::find_best_quote`, to find the most cost-effective swap path by aggregating atomic swaps with external liquidity routing via the 1inch API. The new endpoint allows users to execute token swaps even if they do not directly hold the tokens required by maker orders. It evaluates possible swap paths by combining external liquidity routing with atomic swaps to find the most price-effective route. Key changes include: - A new RPC endpoint `experimental::liquidity_routing::find_best_quote` for pathfinding. - Core logic in `mm2src/mm2_main/src/rpc/lp_commands/lr_swap/lr_impl.rs` to process orders and query the 1inch API. - Refactored the 1inch API client in `trading_api` to use a `UrlBuilder` for more robust URL construction and added support for the Portfolio API. - Extracted common Ethereum utility functions into a new `coins/eth/eth_utils.rs` module to improve code organization. - Updated `RpcOrderbookEntryV2` and `MmNumberMultiRepr` to be deserializable. Currently, this feature only supports filling `ask` orders with liquidity routing performed before the atomic swap. --- Cargo.lock | 2 + mm2src/coins/eth.rs | 82 +--- mm2src/coins/eth/erc20.rs | 35 +- mm2src/coins/eth/eth_utils.rs | 107 +++++ mm2src/coins/lp_coins.rs | 23 +- .../src/erc20_token_activation.rs | 1 + mm2src/mm2_main/Cargo.toml | 1 + mm2src/mm2_main/src/lp_ordermatch.rs | 26 +- mm2src/mm2_main/src/lp_swap/trade_preimage.rs | 1 + .../mm2_main/src/rpc/dispatcher/dispatcher.rs | 46 +- .../mm2_main/src/rpc/lp_commands/lr_swap.rs | 339 ++++++++++++++ .../src/rpc/lp_commands/lr_swap/lr_impl.rs | 414 ++++++++++++++++++ .../src/rpc/lp_commands/lr_swap/types.rs | 127 ++++++ mm2src/mm2_main/src/rpc/lp_commands/mod.rs | 1 + .../src/rpc/lp_commands/one_inch/errors.rs | 48 +- .../src/rpc/lp_commands/one_inch/rpcs.rs | 207 +++++---- .../src/rpc/lp_commands/one_inch/types.rs | 94 ++-- mm2src/mm2_main/src/rpc/lp_commands/tokens.rs | 2 +- mm2src/mm2_number/src/mm_number.rs | 4 +- mm2src/mm2_number/src/mm_number_multi_repr.rs | 4 +- mm2src/mm2_rpc/src/data/legacy/orders.rs | 2 +- mm2src/trading_api/Cargo.toml | 6 +- mm2src/trading_api/src/one_inch_api.rs | 3 +- .../{types.rs => classic_swap_types.rs} | 28 +- mm2src/trading_api/src/one_inch_api/client.rs | 171 +++++--- .../src/one_inch_api/portfolio_types.rs | 98 +++++ 26 files changed, 1564 insertions(+), 308 deletions(-) create mode 100644 mm2src/coins/eth/eth_utils.rs create mode 100644 mm2src/mm2_main/src/rpc/lp_commands/lr_swap.rs create mode 100644 mm2src/mm2_main/src/rpc/lp_commands/lr_swap/lr_impl.rs create mode 100644 mm2src/mm2_main/src/rpc/lp_commands/lr_swap/types.rs rename mm2src/trading_api/src/one_inch_api/{types.rs => classic_swap_types.rs} (93%) create mode 100644 mm2src/trading_api/src/one_inch_api/portfolio_types.rs diff --git a/Cargo.lock b/Cargo.lock index c6cd5560d8..639515ccdb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4078,6 +4078,7 @@ dependencies = [ "either", "enum-primitive-derive", "enum_derives", + "env_logger", "ethabi", "ethcore-transaction", "ethereum-types", @@ -7427,6 +7428,7 @@ dependencies = [ "derive_more", "enum_derives", "ethereum-types", + "futures 0.3.28", "lazy_static", "mm2_core", "mm2_err_handle", diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 8f0fc3d385..9483cf914e 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -128,6 +128,13 @@ use super::{coin_conf, lp_coinfind_or_err, AsyncMutex, BalanceError, BalanceFut, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest, WithdrawResult, EARLY_CONFIRMATION_ERR_LOG, INVALID_CONTRACT_ADDRESS_ERR_LOG, INVALID_PAYMENT_STATE_ERR_LOG, INVALID_RECEIVER_ERR_LOG, INVALID_SENDER_ERR_LOG, INVALID_SWAP_ID_ERR_LOG}; +#[cfg(test)] +pub(crate) use eth_utils::display_u256_with_decimal_point; +pub use eth_utils::{addr_from_pubkey_str, addr_from_raw_pubkey, mm_number_from_u256, mm_number_to_u256, + u256_to_big_decimal, wei_from_big_decimal, wei_from_coins_mm_number, wei_from_gwei_decimal, + wei_to_coins_mm_number, wei_to_eth_decimal, wei_to_gwei_decimal}; +use eth_utils::{get_function_input_data, get_function_name}; + pub use rlp; cfg_native! { use std::path::PathBuf; @@ -164,8 +171,12 @@ use erc20::get_token_decimals; pub(crate) mod eth_swap_v2; use eth_swap_v2::{extract_id_from_tx_data, EthPaymentType, PaymentMethod, SpendTxSearchParams}; +pub mod eth_utils; pub mod tron; +pub const ETH_PROTOCOL_TYPE: &str = "ETH"; +pub const ERC20_PROTOCOL_TYPE: &str = "ERC20"; + /// https://github.com/artemii235/etomic-swap/blob/master/contracts/EtomicSwap.sol /// Dev chain (195.201.137.5:8565) contract address: 0x83965C539899cC0F918552e5A26915de40ee8852 /// Ropsten: https://ropsten.etherscan.io/address/0x7bc1bbdd6a0a722fc9bffc49c921b685ecb84b94 @@ -6248,77 +6259,6 @@ fn validate_fee_impl(coin: EthCoin, validate_fee_args: EthValidateFeeArgs<'_>) - Box::new(fut.boxed().compat()) } -fn get_function_input_data(decoded: &[Token], func: &Function, index: usize) -> Result { - decoded.get(index).cloned().ok_or(format!( - "Missing input in function {}: No input found at index {}", - func.name.clone(), - index - )) -} - -fn get_function_name(name: &str, watcher_reward: bool) -> String { - if watcher_reward { - format!("{}{}", name, "Reward") - } else { - name.to_owned() - } -} - -pub fn addr_from_raw_pubkey(pubkey: &[u8]) -> Result { - let pubkey = try_s!(PublicKey::from_slice(pubkey).map_err(|e| ERRL!("{:?}", e))); - let eth_public = Public::from_slice(&pubkey.serialize_uncompressed()[1..65]); - Ok(public_to_address(ð_public)) -} - -pub fn addr_from_pubkey_str(pubkey: &str) -> Result { - let pubkey_bytes = try_s!(hex::decode(pubkey)); - let addr = try_s!(addr_from_raw_pubkey(&pubkey_bytes)); - Ok(format!("{:#02x}", addr)) -} - -fn display_u256_with_decimal_point(number: U256, decimals: u8) -> String { - let mut string = number.to_string(); - let decimals = decimals as usize; - if string.len() <= decimals { - string.insert_str(0, &"0".repeat(decimals - string.len() + 1)); - } - - string.insert(string.len() - decimals, '.'); - string.trim_end_matches('0').into() -} - -/// Converts 'number' to value with decimal point and shifts it left by 'decimals' places -pub fn u256_to_big_decimal(number: U256, decimals: u8) -> NumConversResult { - let string = display_u256_with_decimal_point(number, decimals); - Ok(string.parse::()?) -} - -/// Shifts 'number' with decimal point right by 'decimals' places and converts it to U256 value -pub fn wei_from_big_decimal(amount: &BigDecimal, decimals: u8) -> NumConversResult { - let mut amount = amount.to_string(); - let dot = amount.find(|c| c == '.'); - let decimals = decimals as usize; - if let Some(index) = dot { - let mut fractional = amount.split_off(index); - // remove the dot from fractional part - fractional.remove(0); - if fractional.len() < decimals { - fractional.insert_str(fractional.len(), &"0".repeat(decimals - fractional.len())); - } - fractional.truncate(decimals); - amount.push_str(&fractional); - } else { - amount.insert_str(amount.len(), &"0".repeat(decimals)); - } - U256::from_dec_str(&amount).map_to_mm(|e| NumConversError::new(format!("{:?}", e))) -} - -pub fn wei_from_gwei_decimal(bigdec: &BigDecimal) -> NumConversResult { - wei_from_big_decimal(bigdec, ETH_GWEI_DECIMALS) -} - -pub fn wei_to_gwei_decimal(wei: U256) -> NumConversResult { u256_to_big_decimal(wei, ETH_GWEI_DECIMALS) } - impl Transaction for SignedEthTx { fn tx_hex(&self) -> Vec { rlp::encode(self).to_vec() } diff --git a/mm2src/coins/eth/erc20.rs b/mm2src/coins/eth/erc20.rs index 3ab3d89a03..53c6b89cdf 100644 --- a/mm2src/coins/eth/erc20.rs +++ b/mm2src/coins/eth/erc20.rs @@ -1,11 +1,13 @@ +use super::{ERC20_PROTOCOL_TYPE, ETH_PROTOCOL_TYPE}; use crate::eth::web3_transport::Web3Transport; use crate::eth::{EthCoin, ERC20_CONTRACT}; -use crate::{CoinsContext, MarketCoinOps, MmCoinEnum}; +use crate::{CoinsContext, MarketCoinOps, MmCoinEnum, Ticker}; use ethabi::Token; use ethereum_types::Address; use futures_util::TryFutureExt; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::mm_error::MmResult; +use std::str::FromStr; use web3::types::{BlockId, BlockNumber, CallRequest}; use web3::{Transport, Web3}; @@ -70,19 +72,40 @@ pub async fn get_erc20_token_info(coin: &EthCoin, token_addr: Address) -> Result Ok(Erc20TokenInfo { symbol, decimals }) } +/// Finds eth platfrom coin in coins config by chain_id and returns its ticker. +pub fn get_platform_ticker(ctx: &MmArc, chain_id: u64) -> Option { + ctx.conf["coins"].as_array()?.iter().find_map(|coin| { + let protocol = coin.get("protocol")?; + let protocol_type = protocol.get("type")?.as_str()?; + if protocol_type != ETH_PROTOCOL_TYPE { + return None; + } + let coin_chain_id = protocol.get("protocol_data")?.get("chain_id")?.as_u64()?; + if coin_chain_id == chain_id { + coin.get("coin")?.as_str().map(|s| s.to_string()) + } else { + None + } + }) +} + /// Finds if an ERC20 token is in coins config by its contract address and returns its ticker. -pub fn get_erc20_ticker_by_contract_address(ctx: &MmArc, platform: &str, contract_address: &str) -> Option { +pub fn get_erc20_ticker_by_contract_address( + ctx: &MmArc, + platform_ticker: &str, + contract_address: &Address, +) -> Option { ctx.conf["coins"].as_array()?.iter().find_map(|coin| { let protocol = coin.get("protocol")?; let protocol_type = protocol.get("type")?.as_str()?; - if protocol_type != "ERC20" { + if protocol_type != ERC20_PROTOCOL_TYPE { return None; } let protocol_data = protocol.get("protocol_data")?; - let coin_platform = protocol_data.get("platform")?.as_str()?; - let coin_contract_address = protocol_data.get("contract_address")?.as_str()?; + let coin_platform_ticker = protocol_data.get("platform")?.as_str()?; + let coin_contract_address = Address::from_str(protocol_data.get("contract_address")?.as_str()?).ok()?; - if coin_platform == platform && coin_contract_address == contract_address { + if coin_platform_ticker == platform_ticker && &coin_contract_address == contract_address { coin.get("coin")?.as_str().map(|s| s.to_string()) } else { None diff --git a/mm2src/coins/eth/eth_utils.rs b/mm2src/coins/eth/eth_utils.rs new file mode 100644 index 0000000000..e6a191d534 --- /dev/null +++ b/mm2src/coins/eth/eth_utils.rs @@ -0,0 +1,107 @@ +use super::{ETH_DECIMALS, ETH_GWEI_DECIMALS}; +use crate::{NumConversError, NumConversResult}; +use ethabi::{Function, Token}; +use ethereum_types::{Address, FromDecStrErr, U256}; +use ethkey::{public_to_address, Public}; +use mm2_err_handle::prelude::MapToMmResult; +use mm2_number::{BigDecimal, MmNumber}; +use secp256k1::PublicKey; + +pub(crate) fn get_function_input_data(decoded: &[Token], func: &Function, index: usize) -> Result { + decoded.get(index).cloned().ok_or(format!( + "Missing input in function {}: No input found at index {}", + func.name.clone(), + index + )) +} + +pub(crate) fn get_function_name(name: &str, watcher_reward: bool) -> String { + if watcher_reward { + format!("{}{}", name, "Reward") + } else { + name.to_owned() + } +} + +pub fn addr_from_raw_pubkey(pubkey: &[u8]) -> Result { + let pubkey = try_s!(PublicKey::from_slice(pubkey).map_err(|e| ERRL!("{:?}", e))); + let eth_public = Public::from_slice(&pubkey.serialize_uncompressed()[1..65]); + Ok(public_to_address(ð_public)) +} + +pub fn addr_from_pubkey_str(pubkey: &str) -> Result { + let pubkey_bytes = try_s!(hex::decode(pubkey)); + let addr = try_s!(addr_from_raw_pubkey(&pubkey_bytes)); + Ok(format!("{:#02x}", addr)) +} + +pub(crate) fn display_u256_with_decimal_point(number: U256, decimals: u8) -> String { + let mut string = number.to_string(); + let decimals = decimals as usize; + if string.len() <= decimals { + string.insert_str(0, &"0".repeat(decimals - string.len() + 1)); + } + + string.insert(string.len() - decimals, '.'); + string.trim_end_matches('0').into() +} + +/// Converts 'number' to value with decimal point and shifts it left by 'decimals' places +pub fn u256_to_big_decimal(number: U256, decimals: u8) -> NumConversResult { + let string = display_u256_with_decimal_point(number, decimals); + Ok(string.parse::()?) +} + +/// Shifts 'number' with decimal point right by 'decimals' places and converts it to U256 value +pub fn wei_from_big_decimal(amount: &BigDecimal, decimals: u8) -> NumConversResult { + let mut amount = amount.to_string(); + let dot = amount.find(|c| c == '.'); + let decimals = decimals as usize; + if let Some(index) = dot { + let mut fractional = amount.split_off(index); + // remove the dot from fractional part + fractional.remove(0); + if fractional.len() < decimals { + fractional.insert_str(fractional.len(), &"0".repeat(decimals - fractional.len())); + } + fractional.truncate(decimals); + amount.push_str(&fractional); + } else { + amount.insert_str(amount.len(), &"0".repeat(decimals)); + } + U256::from_dec_str(&amount).map_to_mm(|e| NumConversError::new(format!("{:?}", e))) +} + +/// Converts BigDecimal gwei value to wei value as U256 +#[inline(always)] +pub fn wei_from_gwei_decimal(bigdec: &BigDecimal) -> NumConversResult { + wei_from_big_decimal(bigdec, ETH_GWEI_DECIMALS) +} + +/// Converts a U256 wei value to an gwei value as a BigDecimal +#[inline(always)] +pub fn wei_to_gwei_decimal(wei: U256) -> NumConversResult { u256_to_big_decimal(wei, ETH_GWEI_DECIMALS) } + +/// Converts a U256 wei value to an ETH value as a BigDecimal +/// TODO: use wei_to_eth_decimal instead of u256_to_big_decimal(gas_cost_wei, ETH_DECIMALS) +#[inline(always)] +pub fn wei_to_eth_decimal(wei: U256) -> NumConversResult { u256_to_big_decimal(wei, ETH_DECIMALS) } + +#[inline] +pub fn mm_number_to_u256(mm_number: &MmNumber) -> Result { + U256::from_dec_str(mm_number.to_ratio().to_integer().to_string().as_str()) +} + +#[inline] +pub fn mm_number_from_u256(u256: U256) -> MmNumber { MmNumber::from(u256.to_string().as_str()) } + +#[inline] +pub fn wei_from_coins_mm_number(mm_number: &MmNumber, decimals: u8) -> NumConversResult { + wei_from_big_decimal(&mm_number.to_decimal(), decimals) +} + +#[inline] +#[allow(unused)] +pub fn wei_to_coins_mm_number(u256: U256, decimals: u8) -> NumConversResult { + Ok(MmNumber::from(u256_to_big_decimal(u256, decimals)?)) +} diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 81bd868324..a3d9c8f856 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -52,7 +52,7 @@ use crypto::{derive_secp256k1_secret, Bip32Error, Bip44Chain, CryptoCtx, CryptoC Secp256k1ExtendedPublicKey, Secp256k1Secret, WithHwRpcError}; use derive_more::Display; use enum_derives::{EnumFromStringify, EnumFromTrait}; -use ethereum_types::{H256, H264, H520, U256}; +use ethereum_types::{Address as EthAddress, H256, H264, H520, U256}; use futures::compat::Future01CompatExt; use futures::lock::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard}; use futures::{FutureExt, TryFutureExt}; @@ -309,6 +309,7 @@ pub type ValidateTakerFundingSpendPreimageResult = MmResult<(), ValidateTakerFun pub type ValidateTakerPaymentSpendPreimageResult = MmResult<(), ValidateTakerPaymentSpendPreimageError>; pub type IguanaPrivKey = Secp256k1Secret; +pub type Ticker = String; // Constants for logs used in tests pub const INVALID_SENDER_ERR_LOG: &str = "Invalid sender"; @@ -4590,18 +4591,26 @@ pub enum CustomTokenError { fmt = "Token with the same ticker already exists in coins configs, ticker in config: {}", ticker_in_config )] - DuplicateTickerInConfig { ticker_in_config: String }, + DuplicateTickerInConfig { + ticker_in_config: String, + }, #[display( fmt = "Token with the same contract address already exists in coins configs, ticker in config: {}", ticker_in_config )] - DuplicateContractInConfig { ticker_in_config: String }, + DuplicateContractInConfig { + ticker_in_config: String, + }, #[display( fmt = "Token is already activated, ticker: {}, contract address: {}", ticker, contract_address )] - TokenWithSameContractAlreadyActivated { ticker: String, contract_address: String }, + TokenWithSameContractAlreadyActivated { + ticker: String, + contract_address: String, + }, + InvalidTokenAddress, } impl CoinProtocol { @@ -4667,7 +4676,11 @@ impl CoinProtocol { // if it is duplicated in config, we will have two orderbooks one using the ticker and one using the contract address. // Todo: We should use the contract address for orderbook topics instead of the ticker once we make custom tokens non-wallet only. // If a coin is added to the config later, users who added it as a custom token and did not update will not see the orderbook. - if let Some(existing_ticker) = get_erc20_ticker_by_contract_address(ctx, platform, contract_address) { + if let Some(existing_ticker) = get_erc20_ticker_by_contract_address( + ctx, + platform, + &EthAddress::from_str(contract_address).map_err(|_| MmError::new(CustomTokenError::InvalidTokenAddress))?, + ) { return Err(MmError::new(CustomTokenError::DuplicateContractInConfig { ticker_in_config: existing_ticker, })); diff --git a/mm2src/coins_activation/src/erc20_token_activation.rs b/mm2src/coins_activation/src/erc20_token_activation.rs index aa9d66ddeb..dad933ac16 100644 --- a/mm2src/coins_activation/src/erc20_token_activation.rs +++ b/mm2src/coins_activation/src/erc20_token_activation.rs @@ -72,6 +72,7 @@ impl TryFromCoinProtocol for Erc20Protocol { contract_address, } => { let token_addr = valid_addr_from_str(&contract_address).map_err(|_| CoinProtocol::ERC20 { + // TODO: maybe add error description to this err (we're losing 'Invalid address checksum' here) platform: platform.clone(), contract_address, })?; diff --git a/mm2src/mm2_main/Cargo.toml b/mm2src/mm2_main/Cargo.toml index b2fe520cfb..f3b526d6bd 100644 --- a/mm2src/mm2_main/Cargo.toml +++ b/mm2src/mm2_main/Cargo.toml @@ -135,6 +135,7 @@ coins_activation = { path = "../coins_activation", features = ["for-tests"] } common = { path = "../common", features = ["for-tests"] } mm2_test_helpers = { path = "../mm2_test_helpers" } trading_api = { path = "../trading_api", features = ["for-tests"] } +env_logger.workspace = true mocktopus.workspace = true testcontainers.workspace = true web3 = { workspace = true, default-features = false, features = ["http-rustls-tls"] } diff --git a/mm2src/mm2_main/src/lp_ordermatch.rs b/mm2src/mm2_main/src/lp_ordermatch.rs index 0975675158..601a9030fb 100644 --- a/mm2src/mm2_main/src/lp_ordermatch.rs +++ b/mm2src/mm2_main/src/lp_ordermatch.rs @@ -6028,19 +6028,19 @@ async fn subscribe_to_orderbook_topic( Ok(()) } -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct RpcOrderbookEntryV2 { - coin: String, - address: OrderbookAddress, - price: MmNumberMultiRepr, - pubkey: String, - uuid: Uuid, - is_mine: bool, - base_max_volume: MmNumberMultiRepr, - base_min_volume: MmNumberMultiRepr, - rel_max_volume: MmNumberMultiRepr, - rel_min_volume: MmNumberMultiRepr, - conf_settings: Option, + pub coin: String, + pub address: OrderbookAddress, + pub price: MmNumberMultiRepr, + pub pubkey: String, + pub uuid: Uuid, + pub is_mine: bool, + pub base_max_volume: MmNumberMultiRepr, + pub base_min_volume: MmNumberMultiRepr, + pub rel_max_volume: MmNumberMultiRepr, + pub rel_min_volume: MmNumberMultiRepr, + pub conf_settings: Option, } fn choose_maker_confs_and_notas( @@ -6153,7 +6153,7 @@ fn choose_taker_confs_and_notas( } } -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(tag = "address_type", content = "address_data")] pub enum OrderbookAddress { Transparent(String), diff --git a/mm2src/mm2_main/src/lp_swap/trade_preimage.rs b/mm2src/mm2_main/src/lp_swap/trade_preimage.rs index ceccd64241..e9a3cef9b6 100644 --- a/mm2src/mm2_main/src/lp_swap/trade_preimage.rs +++ b/mm2src/mm2_main/src/lp_swap/trade_preimage.rs @@ -18,6 +18,7 @@ construct_detailed!(DetailedRequiredBalance, required_balance); pub type TradePreimageRpcResult = Result>; +/// Calculate all fees for the swap and max volume (for maker) pub async fn trade_preimage_rpc( ctx: MmArc, req: TradePreimageRequest, diff --git a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs index 4b18118a7d..6e55fc0e65 100644 --- a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs +++ b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs @@ -13,6 +13,8 @@ use crate::lp_swap::swap_v2_rpcs::{active_swaps_rpc, my_recent_swaps_rpc, my_swa use crate::lp_swap::{get_locked_amount_rpc, max_maker_vol, recreate_swap_data, trade_preimage_rpc}; use crate::lp_wallet::{change_mnemonic_password, delete_wallet_rpc, get_mnemonic_rpc, get_wallet_names_rpc}; use crate::rpc::lp_commands::db_id::get_shared_db_id; +use crate::rpc::lp_commands::lr_swap::{lr_execute_routed_trade_rpc, lr_find_best_quote_rpc, + lr_get_quotes_for_tokens_rpc}; use crate::rpc::lp_commands::one_inch::rpcs::{one_inch_v6_0_classic_swap_contract_rpc, one_inch_v6_0_classic_swap_create_rpc, one_inch_v6_0_classic_swap_liquidity_sources_rpc, @@ -162,7 +164,12 @@ async fn experimental_rpcs_dispatcher( if let Some(staking_method) = experimental_method.strip_prefix("staking::") { return staking_dispatcher(request, ctx, staking_method).await; } - + if let Some(lr_method) = experimental_method.strip_prefix("liquidity_routing::") { + return liquidity_routing_dispatcher(request, ctx, lr_method).await; + } + if let Some(one_inch_method) = experimental_method.strip_prefix("1inch_v6_0::") { + return one_inch_dispatcher(request, ctx, one_inch_method).await; + } MmError::err(DispatcherError::NoSuchMethod) } @@ -254,13 +261,6 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, set_swap_transaction_fee_policy).await, "send_asked_data" => handle_mmrpc(ctx, request, send_asked_data_rpc).await, "z_coin_tx_history" => handle_mmrpc(ctx, request, coins::my_tx_history_v2::z_coin_tx_history_rpc).await, - "1inch_v6_0_classic_swap_contract" => handle_mmrpc(ctx, request, one_inch_v6_0_classic_swap_contract_rpc).await, - "1inch_v6_0_classic_swap_quote" => handle_mmrpc(ctx, request, one_inch_v6_0_classic_swap_quote_rpc).await, - "1inch_v6_0_classic_swap_create" => handle_mmrpc(ctx, request, one_inch_v6_0_classic_swap_create_rpc).await, - "1inch_v6_0_classic_swap_liquidity_sources" => { - handle_mmrpc(ctx, request, one_inch_v6_0_classic_swap_liquidity_sources_rpc).await - }, - "1inch_v6_0_classic_swap_tokens" => handle_mmrpc(ctx, request, one_inch_v6_0_classic_swap_tokens_rpc).await, "wc_new_connection" => handle_mmrpc(ctx, request, new_connection).await, "wc_get_session" => handle_mmrpc(ctx, request, get_session).await, "wc_get_sessions" => handle_mmrpc(ctx, request, get_all_sessions).await, @@ -493,3 +493,33 @@ async fn staking_dispatcher( _ => MmError::err(DispatcherError::NoSuchMethod), } } + +async fn one_inch_dispatcher( + request: MmRpcRequest, + ctx: MmArc, + lr_method: &str, +) -> DispatcherResult>> { + match lr_method { + "classic_swap_contract" => handle_mmrpc(ctx, request, one_inch_v6_0_classic_swap_contract_rpc).await, + "classic_swap_quote" => handle_mmrpc(ctx, request, one_inch_v6_0_classic_swap_quote_rpc).await, + "classic_swap_create" => handle_mmrpc(ctx, request, one_inch_v6_0_classic_swap_create_rpc).await, + "classic_swap_liquidity_sources" => { + handle_mmrpc(ctx, request, one_inch_v6_0_classic_swap_liquidity_sources_rpc).await + }, + "classic_swap_tokens" => handle_mmrpc(ctx, request, one_inch_v6_0_classic_swap_tokens_rpc).await, + _ => MmError::err(DispatcherError::NoSuchMethod), + } +} + +async fn liquidity_routing_dispatcher( + request: MmRpcRequest, + ctx: MmArc, + lr_method: &str, +) -> DispatcherResult>> { + match lr_method { + "find_best_quote" => handle_mmrpc(ctx, request, lr_find_best_quote_rpc).await, + "get_quotes_for_tokens" => handle_mmrpc(ctx, request, lr_get_quotes_for_tokens_rpc).await, + "execute_routed_trade" => handle_mmrpc(ctx, request, lr_execute_routed_trade_rpc).await, + _ => MmError::err(DispatcherError::NoSuchMethod), + } +} diff --git a/mm2src/mm2_main/src/rpc/lp_commands/lr_swap.rs b/mm2src/mm2_main/src/rpc/lp_commands/lr_swap.rs new file mode 100644 index 0000000000..289cd08f0d --- /dev/null +++ b/mm2src/mm2_main/src/rpc/lp_commands/lr_swap.rs @@ -0,0 +1,339 @@ +//! RPC implementations for swaps with liquidity routing (LR) of EVM tokens + +use super::one_inch::types::ClassicSwapDetails; +use crate::rpc::lp_commands::one_inch::errors::ApiIntegrationRpcError; +use crate::rpc::lp_commands::one_inch::rpcs::get_coin_for_one_inch; +use lr_impl::find_best_swap_path_with_lr; +use mm2_core::mm_ctx::MmArc; +use mm2_err_handle::{map_mm_error::MapMmError, mm_error::MmResult}; +use types::{LrExecuteRoutedTradeRequest, LrExecuteRoutedTradeResponse, LrFindBestQuoteRequest, + LrFindBestQuoteResponse, LrGetQuotesForTokensRequest}; + +mod lr_impl; +mod types; + +/// Finds the most cost-effective swap path using liquidity routing (LR) for EVM-compatible tokens (`Aggregated taker swap` path), +/// by selecting the best option from a list of orderbook entries (ask/bid orders). +/// This RPC returns the data needed for actual execution of the swap with LR . +/// +/// # Overview +/// This RPC helps users execute token swaps even if they do not directly hold the tokens required +/// by the maker orders. It uses external liquidity routing (e.g., via 1inch provider) to perform necessary conversions, currently for EVM networks +/// +/// A swap path may consist of: +/// - A liquidity routing (LR) step before or after the atomic swap. +/// - An atomic swap step to fill the selected maker order (ask or bid). +/// +/// Use Case +/// The user wants to buy a specific amount of a token `user_base`, but only holds a different token `user_rel`. +/// This RPC evaluates possible swap paths by combining: +/// - Converting `user_rel` (`user_base`) to the token required by a maker order via LR. +/// - Filling the order through an atomic swap. +/// - Converting the token required by a maker order to `user_base` (`user_rel`) via LR. +/// It then selects and returns the most price-effective path, taking into account: +/// - prices of orders (provided in the params) +/// - 1inch LR quotes +/// - (TODO) Total swap and routing fees +/// Sell requests are processed in a similar way. +/// +/// Example +/// A user wants to buy 1 BTC with their USDT, but the best available order sells 1 BTC for DAI. +/// This RPC calculates the total cost of liquidity routing the user's USDT into DAI and then using the +/// acquired DAI to take the BTC order. It compares this path against other potential candidates +/// (e.g., a order selling BTC for USDC and routing the user's USDT into USDC via LR) to find the cheapest option. +/// +/// Inputs +/// - A list of maker ask or bid orders (orderbook entries) +/// - Trade method (`buy` or `sell`) +/// - Target or source amount to buy/sell +/// - User’s tokens `user_rel` and `user_base` to be used for the swap +/// +/// Outputs +/// - The best swap path including any required LR steps +/// +/// Current Limitations +/// - Only supports filling ask orders with: +/// - `user_rel` (sell request) +/// - Liquidity routing before the atomic swap: `user_rel` -> maker `rel` +/// - Does not yet support: +/// - User's buy request +/// - Filling bid orders +/// - Liquidity routing after the atomic swap +/// +/// TODO: +/// - Return full trade fee breakdown (e.g., DEX fees, LR fees) +/// - Support the following additional aggregated swap configurations: +/// - Filling ask orders with LR after the atomic swap +/// - Filling bid orders with LR before and after the atomic swap +/// - Support user's buy request +/// +/// Notes: +/// - This function relies on external quote APIs (currently 1inch) and may incur latency. +/// - Use this RPC when a direct atomic swap is not available or optimal, and pre/post-routing is needed. +pub async fn lr_find_best_quote_rpc( + ctx: MmArc, + req: LrFindBestQuoteRequest, +) -> MmResult { + // TODO: add validation: + // order.base_min_volume << req.amount <= order.base_max_volume + // order.coin is supported in 1inch + // order.price not zero + // when best order is selected validate against req.rel_max_volume and req.rel_min_volume + // coins in orders should be unique + + let (user_rel_coin, _) = get_coin_for_one_inch(&ctx, &req.user_rel).await?; + let user_rel_chain = user_rel_coin + .chain_id() + .ok_or(ApiIntegrationRpcError::ChainNotSupported)?; + let (swap_data, best_order, total_price) = + find_best_swap_path_with_lr(&ctx, req.user_base, req.user_rel, req.asks, req.bids, &req.volume).await?; + let lr_swap_details = ClassicSwapDetails::from_api_classic_swap_data(&ctx, user_rel_chain, swap_data) + .await + .mm_err(|err| ApiIntegrationRpcError::ApiDataError(err.to_string()))?; + Ok(LrFindBestQuoteResponse { + lr_swap_details, + best_order, + total_price, + // TODO: implement later + // trade_fee: ... + }) +} + +/// Find possible swaps with liquidity routing of several user tokens to fill one order. +/// For the provided single order the RPC searches for the most price-effective swap path with LR for user tokens. +/// +/// More info: +/// User is interested in buying some coin. There is an order available the User would like to fill but the User does not have tokens from the order. +/// User calls this RPC with the order, desired coin name, amount to buy or sell and list of User tokens to convert to/from with LR. +/// The RPC calls several 1inch classic swap quotes (to find most efficient token conversions) +/// and return possible LR paths to fill the order, with total swap prices. +/// TODO: should also returns total fees. +/// +/// NOTE: this RPC does not select the best quote between User tokens because it finds routes for different tokens (with own value), +/// so returns all of them. +/// That is, it's up to the User to select the most cost effective swap, for e.g. comparing token fiat value. +/// In fact, this could be done even in this RPC as 1inch also can get value in fiat but maybe User evaludation is more prefferable. +/// Again, it's a TODO. +pub async fn lr_get_quotes_for_tokens_rpc( + _ctx: MmArc, + _req: LrGetQuotesForTokensRequest, +) -> MmResult { + // TODO: impl later + todo!() +} + +/// Run a swap with LR to fill a maker order +pub async fn lr_execute_routed_trade_rpc( + _ctx: MmArc, + _req: LrExecuteRoutedTradeRequest, +) -> MmResult { + todo!() +} + +#[cfg(all(test, feature = "test-ext-api", not(target_arch = "wasm32")))] +mod tests { + use super::types::{AsksForCoin, LrFindBestQuoteRequest}; + use crate::lp_ordermatch::{OrderbookAddress, RpcOrderbookEntryV2}; + use crate::rpc::lp_commands::legacy::electrum; + use coins::eth::EthCoin; + use coins_activation::platform_for_tests::init_platform_coin_with_tokens_loop; + use crypto::CryptoCtx; + use mm2_number::{MmNumber, MmNumberMultiRepr}; + use mm2_test_helpers::for_tests::{btc_with_spv_conf, mm_ctx_with_custom_db_with_conf}; + use std::str::FromStr; + use uuid::Uuid; + + /// Test to find best swap with LR. + /// checks how to find an order from an utxo/token ask order list, which is the most price efficient if route from my token into the token in the order. + /// With this test use --features test-ext-api and set ONE_INCH_API_TEST_AUTH env to the 1inch dev auth key + /// TODO: make it mockable to run within CI + #[tokio::test] + async fn test_find_best_lr_swap_for_order_list() { + // let _ = env_logger::try_init(); // enable to print log messages in the impl + let main_net_url: String = std::env::var("ETH_MAIN_NET_URL_FOR_TEST").unwrap_or_default(); + let platform_coin = "ETH".to_owned(); + let base_conf = btc_with_spv_conf(); + let platform_coin_conf = json!({ + "coin": platform_coin.clone(), + "name": "ethereum", + "derivation_path": "m/44'/1'", + "protocol": { + "type": "ETH", + "protocol_data": { + "chain_id": 1 + } + } + }); + + // WETH = 2696.90 USD + let weth_conf = json!({ + "coin": "WETH-ERC20", + "name": "WETH-ERC20", + "derivation_path": "m/44'/1'", + "decimals": 18, + "protocol": { + "type": "ERC20", + "protocol_data": { + "platform": "ETH", + "contract_address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" + } + } + }); + + // BNB = 612.36 USD + let bnb_conf = json!({ + "coin": "BNB-ERC20", + "name": "BNB token", + "derivation_path": "m/44'/1'", + "decimals": 18, + "protocol": { + "type": "ERC20", + "protocol_data": { + "platform": "ETH", + "contract_address": "0xB8c77482e45F1F44dE1745F52C74426C631bDD52" + } + } + }); + // AAVE 258.75 USD + let aave_conf = json!({ + "coin": "AAVE-ERC20", + "name": "AAVE token", + "derivation_path": "m/44'/1'", + "decimals": 18, + "protocol": { + "type": "ERC20", + "protocol_data": { + "platform": "ETH", + "contract_address": "0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9" + } + } + }); + // CNC 0.136968 USD USD + let cnc_conf = json!({ + "coin": "CNC-ERC20", + "name": "CNC token", + "derivation_path": "m/44'/1'", + "decimals": 18, + "protocol": { + "type": "ERC20", + "protocol_data": { + "platform": "ETH", + "contract_address": "0x9aE380F0272E2162340a5bB646c354271c0F5cFC" + } + } + }); + + let base_ticker = base_conf["coin"].as_str().unwrap().to_owned(); + let weth_ticker = weth_conf["coin"].as_str().unwrap().to_owned(); + let bnb_ticker = bnb_conf["coin"].as_str().unwrap().to_owned(); + let aave_ticker = aave_conf["coin"].as_str().unwrap().to_owned(); + let cnc_ticker = cnc_conf["coin"].as_str().unwrap().to_owned(); + + let conf = json!({ + "coins": [base_conf, platform_coin_conf, weth_conf, bnb_conf, aave_conf, cnc_conf], + "1inch_api": "https://api.1inch.dev" + }); + let ctx = mm_ctx_with_custom_db_with_conf(Some(conf)); + CryptoCtx::init_with_iguana_passphrase(ctx.clone(), "123").unwrap(); + + electrum( + ctx.clone(), + json!({ + "coin": base_ticker, + "mm2": 1, + "method": "electrum", + "servers": [ + {"url": "electrum1.cipig.net:10001"}, + {"url": "electrum2.cipig.net:10001"}, + {"url": "electrum3.cipig.net:10001"} + ], + "tx_history": false + }), + ) + .await + .unwrap(); + init_platform_coin_with_tokens_loop::( + ctx.clone(), + serde_json::from_value(json!({ + "ticker": platform_coin.clone(), + "rpc_mode": "Default", + "nodes": [ + {"url": main_net_url} + ], + "swap_contract_address": "0xeA6D65434A15377081495a9E7C5893543E7c32cB", + "erc20_tokens_requests": [ + {"ticker": weth_ticker.clone()}, + {"ticker": bnb_ticker.clone()}, + {"ticker": aave_ticker.clone()}, + {"ticker": cnc_ticker.clone()} + ], + "priv_key_policy": { "type": "ContextPrivKey" } + })) + .unwrap(), + ) + .await + .unwrap(); + + let asks = vec![AsksForCoin { + base: base_ticker.clone(), + orders: vec![ + RpcOrderbookEntryV2 { + coin: bnb_ticker, + address: OrderbookAddress::Transparent("RLL6n4ayAv1haokcEd1QUEYniyeoiYkn7W".into()), + price: MmNumberMultiRepr::from(MmNumber::from("145.69")), + pubkey: "02f3578fbc0fc76056eae34180a71e9190ee08ad05d40947aab7a286666e2ce798".to_owned(), + uuid: Uuid::from_str("7f26dc6a-39ab-4685-b5f1-55f12268ea50").unwrap(), + is_mine: false, + base_max_volume: MmNumberMultiRepr::from(MmNumber::from("1")), + base_min_volume: MmNumberMultiRepr::from(MmNumber::from("0.1")), + rel_max_volume: MmNumberMultiRepr::from(MmNumber::from("145.69")), + rel_min_volume: MmNumberMultiRepr::from(MmNumber::from("14.569")), + conf_settings: Default::default(), + }, + RpcOrderbookEntryV2 { + coin: aave_ticker, + address: OrderbookAddress::Transparent("RK1JDwZ1LvH47Tvqm6pQM7aSqC2Zo6JwRF".into()), + price: MmNumberMultiRepr::from(MmNumber::from("370.334")), + pubkey: "02470bfb8e7710be4a7c2b8e9ba4bcfc5362a71643e64fc2e33b0d64c844ee9123".to_owned(), + uuid: Uuid::from_str("2aadf450-6a8e-4e4e-8b89-19ca10f23cc3").unwrap(), + is_mine: false, + base_max_volume: MmNumberMultiRepr::from(MmNumber::from("1")), + base_min_volume: MmNumberMultiRepr::from(MmNumber::from("0.1")), + rel_max_volume: MmNumberMultiRepr::from(MmNumber::from("370.334")), + rel_min_volume: MmNumberMultiRepr::from(MmNumber::from("37.0334")), + conf_settings: Default::default(), + }, + RpcOrderbookEntryV2 { + coin: cnc_ticker, + address: OrderbookAddress::Transparent("RK1JDwZ1LvH47Tvqm6pQM7aSqC2Zo6JwRF".into()), + price: MmNumberMultiRepr::from(MmNumber::from("699300.69")), + pubkey: "03de96cb66dcfaceaa8b3d4993ce8914cd5fe84e3fd53cefdae45add8032792a12".to_owned(), + uuid: Uuid::from_str("89ab019f-b2fe-4d89-9764-96ac4a3fbf8e").unwrap(), + is_mine: false, + base_max_volume: MmNumberMultiRepr::from(MmNumber::from("1")), + base_min_volume: MmNumberMultiRepr::from(MmNumber::from("0.1")), + rel_max_volume: MmNumberMultiRepr::from(MmNumber::from("699300.69")), + rel_min_volume: MmNumberMultiRepr::from(MmNumber::from("69930.069")), + conf_settings: Default::default(), + }, + ], + }]; + let bids = vec![]; + + let req = LrFindBestQuoteRequest { + user_base: base_ticker, + volume: "0.123".into(), + asks, + method: "buy".to_string(), + bids, + user_rel: weth_ticker, + }; + + let response = super::lr_find_best_quote_rpc(ctx, req).await; + // log!("response={:?}", response); // enable to investigate the response + assert!(response.is_ok()); + + // BTC / WETH price around 35.0 + log!("response total_price={}", response.unwrap().total_price.to_decimal()); + } +} diff --git a/mm2src/mm2_main/src/rpc/lp_commands/lr_swap/lr_impl.rs b/mm2src/mm2_main/src/rpc/lp_commands/lr_swap/lr_impl.rs new file mode 100644 index 0000000000..18e43acfcd --- /dev/null +++ b/mm2src/mm2_main/src/rpc/lp_commands/lr_swap/lr_impl.rs @@ -0,0 +1,414 @@ +//! Finding best quote to do swaps with liquidity routing (LR) support +//! Swaps with LR run additional interim swaps in EVM chains to convert one token into another token suitable to do a normal atomic swap. + +use crate::lp_ordermatch::RpcOrderbookEntryV2; +use crate::rpc::lp_commands::lr_swap::types::{AskOrBidOrder, AsksForCoin, BidsForCoin}; +use crate::rpc::lp_commands::one_inch::errors::ApiIntegrationRpcError; +use crate::rpc::lp_commands::one_inch::rpcs::get_coin_for_one_inch; +use coins::eth::{mm_number_from_u256, mm_number_to_u256, wei_from_coins_mm_number}; +use coins::hd_wallet::DisplayAddress; +use coins::lp_coinfind_or_err; +use coins::MmCoin; +use coins::Ticker; +use common::log; +use ethereum_types::Address as EthAddress; +use ethereum_types::U256; +use futures::future::join_all; +use mm2_core::mm_ctx::MmArc; +use mm2_err_handle::prelude::*; +use mm2_number::MmNumber; +use num_traits::CheckedDiv; +use std::collections::HashMap; +use std::sync::{Arc, RwLock}; +use trading_api::one_inch_api::classic_swap_types::{ClassicSwapData, ClassicSwapQuoteParams}; +use trading_api::one_inch_api::client::{ApiClient, PortfolioApiMethods, PortfolioUrlBuilder, SwapApiMethods, + SwapUrlBuilder}; +use trading_api::one_inch_api::portfolio_types::{CrossPriceParams, CrossPricesSeries, DataGranularity}; + +/// To estimate src/dst price query price history for last 5 min +const CROSS_PRICES_GRANULARITY: DataGranularity = DataGranularity::FiveMin; +/// Use no more than 1 price history samples to estimate src/dst price +const CROSS_PRICES_LIMIT: u32 = 1; + +/// Internal struct to collect data for LR swap step +#[allow(dead_code)] // 'Clone' is detected as dead code in one combinator +#[derive(Clone)] +struct LrStepData { + /// Source coin or token ticker (to swap from) + _src_token: Ticker, + /// Source token contract address + src_contract: Option, + /// Source token amount in wei + src_amount: Option, + /// Source token decimals + src_decimals: Option, + /// Destination coin or token ticker (to swap into) + _dst_token: Ticker, + /// Destination token contract address + dst_contract: Option, + /// Destination token amount in wei + dst_amount: Option, + /// Destination token decimals + dst_decimals: Option, + /// Chain id where LR swap occurs (obtained from the destination token) + chain_id: Option, + /// Estimated src token / dst token price + lr_price: Option, + /// A quote from LR provider with destination amount for LR swap step + lr_swap_data: Option, +} + +impl LrStepData { + #[allow(clippy::result_large_err)] + fn get_chain_contract_info(&self) -> MmResult<(String, String, u64), ApiIntegrationRpcError> { + let src_contract = self + .src_contract + .as_ref() + .ok_or(ApiIntegrationRpcError::InternalError( + "Source LR contract not set".to_owned(), + ))? + .display_address(); + let dst_contract = self + .dst_contract + .as_ref() + .ok_or(ApiIntegrationRpcError::InternalError( + "Destination LR contract not set".to_owned(), + ))? + .display_address(); + let chain_id = self + .chain_id + .ok_or(ApiIntegrationRpcError::InternalError("LR chain id not set".to_owned()))?; + Ok((src_contract, dst_contract, chain_id)) + } +} + +struct LrSwapCandidateInfo { + /// Data for liquidity routing before atomic swap + lr_data_0: Option, + /// Atomic swap order to fill + atomic_swap_order: AskOrBidOrder, + /// Data for liquidity routing after atomic swap + _lr_data_1: Option, +} + +/// Array to store data (possible swap route candidated, with prices for each step) needed for estimation +/// of the aggregated swap with liquidity routing, with the best total price +struct LrSwapCandidates { + // The array of swaps with LR candidated is indexed by HashMaps with LR_0 and LR_1 base/rel pairs (to easily access and updated) + // TODO: maybe this is overcomplicated and just a vector of candidates would be sufficicent + inner0: HashMap<(Ticker, Ticker), Arc>>, + _inner1: HashMap<(Ticker, Ticker), Arc>>, +} + +impl LrSwapCandidates { + /// Init LR data map from the source token (mytoken) and tokens from orders + fn new_with_orders(src_token: Ticker, asks_coins: Vec, _bids_coins: Vec) -> Self { + let mut inner0 = HashMap::new(); + let inner1 = HashMap::new(); + for asks_for_coin in asks_coins { + for order in asks_for_coin.orders { + let candidate = LrSwapCandidateInfo { + lr_data_0: Some(LrStepData { + _src_token: src_token.clone(), + src_contract: None, + src_decimals: None, + src_amount: None, + _dst_token: order.coin.clone(), + dst_contract: None, + dst_amount: None, + dst_decimals: None, + chain_id: None, + lr_price: None, + lr_swap_data: None, + }), + atomic_swap_order: AskOrBidOrder::Ask { + base: asks_for_coin.base.clone(), + order: order.clone(), + }, + _lr_data_1: None, // TODO: add support for LR 1 + }; + let candidate = Arc::new(RwLock::new(candidate)); + inner0.insert((src_token.clone(), order.coin.clone()), candidate); + // TODO: add support for inner1 + } + } + Self { + inner0, + _inner1: inner1, + } + } + + /// Calculate amounts of destination tokens required to fill ask orders for the requested base_amount: + /// multiplies base_amount by the order price. Base_amount must be in coin units (with decimals) + async fn calc_destination_token_amounts( + &mut self, + ctx: &MmArc, + base_amount: &MmNumber, + ) -> MmResult<(), ApiIntegrationRpcError> { + for candidate in self.inner0.values_mut() { + let order_ticker = candidate.read().unwrap().atomic_swap_order.order().coin.clone(); + let coin = lp_coinfind_or_err(ctx, &order_ticker).await.map_mm_err()?; + let mut candidate_write = candidate.write().unwrap(); + let price: MmNumber = candidate_write.atomic_swap_order.order().price.rational.clone().into(); + let dst_amount = base_amount * &price; + let Some(ref mut lr_data_0) = candidate_write.lr_data_0 else { + continue; + }; + let dst_amount = wei_from_coins_mm_number(&dst_amount, coin.decimals()).map_mm_err()?; + lr_data_0.dst_amount = Some(dst_amount); + log::debug!( + "calc_destination_token_amounts atomic_swap_order.order.coin={} coin.decimals()={} lr_data_0.dst_amount={:?}", + order_ticker, + coin.decimals(), + dst_amount + ); + } + Ok(()) + } + + fn update_with_lr_prices(&mut self, mut lr_prices: HashMap<(Ticker, Ticker), Option>) { + for (key, val) in self.inner0.iter_mut() { + if let Some(ref mut lr_data_0) = val.write().unwrap().lr_data_0 { + lr_data_0.lr_price = lr_prices.remove(key).flatten(); + } + } + } + + fn update_with_lr_swap_data(&mut self, mut lr_swap_data: HashMap<(Ticker, Ticker), Option>) { + for (key, val) in self.inner0.iter_mut() { + if let Some(ref mut lr_data_0) = val.write().unwrap().lr_data_0 { + lr_data_0.lr_swap_data = lr_swap_data.remove(key).flatten(); + } + } + } + + async fn update_with_contracts(&mut self, ctx: &MmArc) -> MmResult<(), ApiIntegrationRpcError> { + for ((src_token, dst_token), candidate) in self.inner0.iter_mut() { + let (src_coin, src_contract) = get_coin_for_one_inch(ctx, src_token).await?; + let (dst_coin, dst_contract) = get_coin_for_one_inch(ctx, dst_token).await?; + let mut candidate_write = candidate.write().unwrap(); + let Some(ref mut lr_data_0) = candidate_write.lr_data_0 else { + continue; + }; + let src_decimals = src_coin.decimals(); + let dst_decimals = dst_coin.decimals(); + + #[cfg(feature = "for-tests")] + { + assert_ne!(src_decimals, 0); + assert_ne!(dst_decimals, 0); + } + + lr_data_0.src_contract = Some(src_contract); + lr_data_0.dst_contract = Some(dst_contract); + lr_data_0.src_decimals = Some(src_decimals); + lr_data_0.dst_decimals = Some(dst_decimals); + lr_data_0.chain_id = dst_coin.chain_id(); + } + Ok(()) + } + + /// Query 1inch token_0/token_1 price in series and calc average price + /// Assuming the outer RPC-level code ensures that relation src_tokens : dst_tokens will never be M:N (but only 1:M or M:1) + async fn query_destination_token_prices(&mut self, ctx: &MmArc) -> MmResult<(), ApiIntegrationRpcError> { + let mut prices_futs = vec![]; + let mut src_dst = vec![]; + for ((src_token, dst_token), candidate) in self.inner0.iter() { + let candidate_read = candidate.read().unwrap(); + let Some(ref lr_data_0) = candidate_read.lr_data_0 else { + continue; + }; + let (src_contract, dst_contract, chain_id) = lr_data_0.get_chain_contract_info()?; + // Run src / dst token price query: + let query_params = CrossPriceParams::new(chain_id, src_contract, dst_contract) + .with_granularity(Some(CROSS_PRICES_GRANULARITY)) + .with_limit(Some(CROSS_PRICES_LIMIT)) + .build_query_params() + .map_mm_err()?; + let url = PortfolioUrlBuilder::create_api_url_builder(ctx, PortfolioApiMethods::CrossPrices) + .map_mm_err()? + .with_query_params(query_params) + .build() + .map_mm_err()?; + let fut = ApiClient::call_api::(url); + prices_futs.push(fut); + src_dst.push((src_token.clone(), dst_token.clone())); + } + let prices_in_series = join_all(prices_futs).await.into_iter().map(|res| res.ok()); // set bad results to None to preserve prices_in_series length + + let quotes = src_dst + .into_iter() + .zip(prices_in_series) + .map(|((src, dst), series)| { + let dst_price = cross_prices_average(series); + ((src, dst), dst_price) + }) + .collect::>(); + + log_cross_prices("es); + self.update_with_lr_prices(quotes); + Ok(()) + } + + /// Estimate the needed source amount for LR swap, by dividing the known dst amount by the src/dst price + #[allow(clippy::result_large_err)] + fn estimate_source_token_amounts(&mut self) -> MmResult<(), ApiIntegrationRpcError> { + for candidate in self.inner0.values_mut() { + let order_ticker = candidate.read().unwrap().atomic_swap_order.order().coin.clone(); + let mut candidate_write = candidate.write().unwrap(); + let Some(ref mut lr_data_0) = candidate_write.lr_data_0 else { + continue; + }; + let Some(ref dst_price) = lr_data_0.lr_price else { + continue; + }; + let dst_amount = lr_data_0 + .dst_amount + .ok_or(ApiIntegrationRpcError::InternalError("no dst_amount".to_owned()))?; + let dst_amount = mm_number_from_u256(dst_amount); + if let Some(src_amount) = &dst_amount.checked_div(dst_price) { + lr_data_0.src_amount = Some(mm_number_to_u256(src_amount)?); + log::debug!( + "estimate_source_token_amounts lr_data.order.coin={} dst_price={} lr_data.src_amount={:?}", + order_ticker, + dst_price.to_decimal(), + src_amount + ); + } + } + Ok(()) + } + + /// Run 1inch requests to get LR quotes to convert source tokens to tokens in orders + async fn run_lr_quotes(&mut self, ctx: &MmArc) -> MmResult<(), ApiIntegrationRpcError> { + let mut src_dst = vec![]; + let mut quote_futs = vec![]; + for ((src_token, dst_token), candidate) in self.inner0.iter() { + let candidate_read = candidate.read().unwrap(); + let Some(ref lr_data_0) = candidate_read.lr_data_0 else { + continue; + }; + let Some(src_amount) = lr_data_0.src_amount else { + continue; + }; + let (src_contract, dst_contract, chain_id) = lr_data_0.get_chain_contract_info()?; + let query_params = ClassicSwapQuoteParams::new(src_contract, dst_contract, src_amount.to_string()) + .with_include_tokens_info(Some(true)) + .with_include_gas(Some(true)) + .build_query_params() + .map_mm_err()?; + let url = SwapUrlBuilder::create_api_url_builder(ctx, chain_id, SwapApiMethods::ClassicSwapQuote) + .map_mm_err()? + .with_query_params(query_params) + .build() + .map_mm_err()?; + let fut = ApiClient::call_api::(url); + quote_futs.push(fut); + src_dst.push((src_token.clone(), dst_token.clone())); + } + let swap_data = join_all(quote_futs).await.into_iter().map(|res| res.ok()); // if a bad result received (for e.g. low liguidity) set to None to preserve swap_data length + let swap_data_map = src_dst.into_iter().zip(swap_data).collect(); + self.update_with_lr_swap_data(swap_data_map); + Ok(()) + } + + /// Select the best swap path, by minimum of total swap price (including order and LR swap) + #[allow(clippy::result_large_err)] + fn select_best_swap(&self) -> MmResult<(ClassicSwapData, AskOrBidOrder, MmNumber), ApiIntegrationRpcError> { + // Calculate swap's total_price (filling the order plus LR swap) as src_amount / order_amount + // where src_amount is user tokens to pay for the swap with LR, 'order_amount' is amount which will fill the order + // Tx fee is not accounted here because it is in the platform coin, not token, so we can't compare LR swap tx fee directly here. + // Instead, GUI may calculate and show to the user the total spendings for LR swap, including fees, in USD or other fiat currency + let calc_total_price = |src_amount: U256, lr_swap: &ClassicSwapData, order: &RpcOrderbookEntryV2| { + let src_amount = mm_number_from_u256(src_amount); + let order_price = MmNumber::from(order.price.rational.clone()); + let dst_amount = MmNumber::from(lr_swap.dst_amount.as_str()); + let order_amount = dst_amount.checked_div(&order_price)?; + let total_price = src_amount.checked_div(&order_amount); + log::debug!("select_best_swap order.coin={} lr_swap.dst_amount(wei)={} order_amount(to fill order, wei)={} total_price(with LR)={}", + order.coin, lr_swap.dst_amount, order_amount.to_decimal(), total_price.clone().unwrap_or(MmNumber::from(0)).to_decimal()); + total_price + }; + + self.inner0 + .values() + .filter_map(|candidate| { + let candidate_read = candidate.read().unwrap(); + let atomic_swap_order = candidate_read.atomic_swap_order.clone(); + candidate_read + .lr_data_0 + .as_ref() + .map(|lr_data_0| (atomic_swap_order, lr_data_0.clone())) + }) + // filter out orders for which we did not get LR swap quotes and were not able to estimate needed source amount + .filter_map( + |(atomic_swap_order, lr_data_0)| match (lr_data_0.src_amount, lr_data_0.lr_swap_data) { + (Some(src_amount), Some(lr_swap_data)) => Some((src_amount, lr_swap_data, atomic_swap_order)), + (_, _) => None, + }, + ) + // calculate total price and filter out orders for which we could not calculate the total price + .filter_map(|(src_amount, lr_swap_data, order)| { + calc_total_price(src_amount, &lr_swap_data, order.order()) + .map(|total_price| (lr_swap_data, order, total_price)) + }) + .min_by(|(_, _, price_0), (_, _, price_1)| price_0.cmp(price_1)) + .map(|(lr_swap_data, order, price)| (lr_swap_data, order, price)) + .ok_or(MmError::new(ApiIntegrationRpcError::BestLrSwapNotFound)) + } +} + +/// Implementation code to find the optimal swap path (with the lowest total price) from the `user_base` coin to the `user_rel` coin +/// (`Aggregated taker swap` path). +/// This path includes: +/// - An atomic swap step: used to fill a specific ask (or, in future, bid) order provided in the parameters. +/// - A liquidity routing (LR) step before and/or after (todo) the atomic swap: converts `user_base` or `user_sell` into the coin in the order. +/// +/// This function currently supports only: +/// - Ask orders and User 'sell' requests. +/// - Liquidity routing before the atomic swap. +/// +/// TODO: +/// - Support bid orders and User 'buy' requests. +/// - Support liquidity routing after the atomic swap (e.g., to convert the output coin into `user_rel`). +pub async fn find_best_swap_path_with_lr( + ctx: &MmArc, + _user_base: Ticker, + user_rel: Ticker, + asks: Vec, + bids: Vec, + base_amount: &MmNumber, +) -> MmResult<(ClassicSwapData, AskOrBidOrder, MmNumber), ApiIntegrationRpcError> { + let mut candidates = LrSwapCandidates::new_with_orders(user_rel, asks, bids); + candidates.update_with_contracts(ctx).await?; + candidates.calc_destination_token_amounts(ctx, base_amount).await?; + candidates.query_destination_token_prices(ctx).await?; + candidates.estimate_source_token_amounts()?; + candidates.run_lr_quotes(ctx).await?; + + candidates.select_best_swap() +} + +/// Helper to process 1inch token cross prices data and return average price +fn cross_prices_average(series: Option) -> Option { + let Some(series) = series else { + return None; + }; + if series.is_empty() { + return None; + } + let total: MmNumber = series.iter().fold(MmNumber::from(0), |acc, price_data| { + acc + MmNumber::from(price_data.avg.clone()) + }); + Some(total / MmNumber::from(series.len() as u64)) +} + +fn log_cross_prices(prices: &HashMap<(Ticker, Ticker), Option>) { + for p in prices { + log::debug!( + "cross prices api src/dst price={:?} {:?}", + p, + p.1.clone().map(|v| v.to_decimal()) + ); + } +} diff --git a/mm2src/mm2_main/src/rpc/lp_commands/lr_swap/types.rs b/mm2src/mm2_main/src/rpc/lp_commands/lr_swap/types.rs new file mode 100644 index 0000000000..2e16f54310 --- /dev/null +++ b/mm2src/mm2_main/src/rpc/lp_commands/lr_swap/types.rs @@ -0,0 +1,127 @@ +//! Types for LR swaps rpc + +use crate::lp_ordermatch::RpcOrderbookEntryV2; +use crate::rpc::lp_commands::one_inch::types::ClassicSwapDetails; +use coins::Ticker; +use mm2_number::MmNumber; +use mm2_rpc::data::legacy::{SellBuyRequest, SellBuyResponse}; + +#[derive(Debug, Deserialize)] +pub struct AsksForCoin { + /// Base coin for ask orders + pub base: Ticker, + /// Best maker ask orders that could be filled with liquidity routing from the User source_token into ask's rel token + pub orders: Vec, +} + +#[derive(Debug, Deserialize)] +pub struct BidsForCoin { + /// Rel coin for bid orders + pub rel: Ticker, + /// Best maker ask orders that could be filled with liquidity routing from the User source_token into ask's rel token + pub orders: Vec, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(tag = "type")] +pub enum AskOrBidOrder { + Ask { base: Ticker, order: RpcOrderbookEntryV2 }, + Bid { rel: Ticker, order: RpcOrderbookEntryV2 }, +} + +impl AskOrBidOrder { + pub fn order(&self) -> &RpcOrderbookEntryV2 { + match self { + AskOrBidOrder::Ask { base: _, order } => order, + AskOrBidOrder::Bid { rel: _, order } => order, + } + } +} + +/// Request to find best swap path with LR to fill an order from list. +#[derive(Debug, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct LrFindBestQuoteRequest { + /// Base coin to fill an atomic swap maker order with possible liquidity routing from this coin over a coin/token in an ask/bid + pub user_base: Ticker, + /// List of maker atomic swap ask orders, to find best swap path with liquidity routing from user_base or user_rel coin + pub asks: Vec, + /// List of maker atomic swap bid orders, to find best swap path with liquidity routing from user_base or user_rel coin + pub bids: Vec, + /// Buy or sell volume (in coin units, i.e. with fraction) + pub volume: MmNumber, + /// Method buy or sell + /// TODO: use this field, now we support 'buy' only + pub method: String, + /// Rel coin to fill an atomic swap maker order with possible liquidity routing from this coin over a coin/token in an ask/bid + pub user_rel: Ticker, +} + +/// Response for find best swap path with LR +#[derive(Debug, Serialize)] +pub struct LrFindBestQuoteResponse { + /// Swap tx data (from 1inch quote) + pub lr_swap_details: ClassicSwapDetails, + /// found best order which can be filled with LR swap + pub best_order: AskOrBidOrder, + /// base/rel price including the price of the LR swap part + pub total_price: MmNumber, + // /// Fees to pay, including LR swap fee + // pub trade_fee: TradePreimageResponse, // TODO: implement when trade_preimage implemented for TPU +} + +/// Request to get quotes with possible swap paths to fill order with multiple tokens with LR +#[derive(Debug, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct LrGetQuotesForTokensRequest { + /// Order base coin ticker (from the orderbook). + pub base: Ticker, + /// Swap amount in base coins to sell (with fraction) + pub amount: MmNumber, + /// Maker order to find possible swap path with LR + pub orderbook_entry: RpcOrderbookEntryV2, + /// List of user tokens to trade with LR + pub my_tokens: Vec, +} + +/// Details with swap with LR +#[derive(Debug, Serialize)] +pub struct QuotesDetails { + /// interim token to route to/from + pub dest_token: Ticker, + /// Swap tx data (from 1inch quote) + pub lr_swap_details: ClassicSwapDetails, + /// total swap price with LR + pub total_price: MmNumber, + // /// Fees to pay, including LR swap fee + // pub trade_fee: TradePreimageResponse, // TODO: implement when trade_preimage implemented for TPU +} + +/// Response for quotes to fill order with LR +#[derive(Debug, Serialize)] +pub struct LrGetQuotesForTokensResponse { + pub quotes: Vec, +} + +/// Request to sell or buy order with LR +/// TODO: this struct will be changed in the next PR +#[derive(Debug, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct LrExecuteRoutedTradeRequest { + /// Original sell or buy request (but only MatchBy::Orders could be used to fill the maker swap found in ) + #[serde(flatten)] + pub fill_req: SellBuyRequest, + + /// Tx data to create one inch swap (from 1inch quote) + /// TODO: make this an enum to allow other LR providers + pub lr_swap_details: ClassicSwapDetails, +} + +/// Response to sell or buy order with LR +#[derive(Debug, Serialize)] +#[serde(deny_unknown_fields)] +pub struct LrExecuteRoutedTradeResponse { + /// Original sell or buy response + #[serde(flatten)] + pub fill_response: SellBuyResponse, +} diff --git a/mm2src/mm2_main/src/rpc/lp_commands/mod.rs b/mm2src/mm2_main/src/rpc/lp_commands/mod.rs index e61d5aead8..0826bbb648 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/mod.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/mod.rs @@ -1,5 +1,6 @@ pub(crate) mod db_id; pub mod legacy; +pub(crate) mod lr_swap; pub(crate) mod one_inch; pub(crate) mod pubkey; pub(crate) mod tokens; diff --git a/mm2src/mm2_main/src/rpc/lp_commands/one_inch/errors.rs b/mm2src/mm2_main/src/rpc/lp_commands/one_inch/errors.rs index 8ee65af984..7a4d995ecf 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/one_inch/errors.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/one_inch/errors.rs @@ -1,7 +1,7 @@ -use coins::{eth::u256_to_big_decimal, NumConversError}; +use coins::{CoinFindError, NumConversError}; use common::{HttpStatusCode, StatusCode}; use enum_derives::EnumFromStringify; -use mm2_number::BigDecimal; +use ethereum_types::U256; use ser_error_derive::SerializeErrorType; use serde::Serialize; use trading_api::one_inch_api::errors::ApiClientError; @@ -9,18 +9,21 @@ use trading_api::one_inch_api::errors::ApiClientError; #[derive(Debug, Display, Serialize, SerializeErrorType, EnumFromStringify)] #[serde(tag = "error_type", content = "error_data")] pub enum ApiIntegrationRpcError { - #[from_stringify("coins::CoinFindError")] - NoSuchCoin(String), + NoSuchCoin { + coin: String, + }, #[display(fmt = "EVM token needed")] CoinTypeError, #[display(fmt = "NFT not supported")] - NftNotSupported, + NftProtocolNotSupported, #[display(fmt = "Chain not supported")] ChainNotSupported, #[display(fmt = "Must be same chain")] DifferentChains, #[from_stringify("coins::UnexpectedDerivationMethod")] MyAddressError(String), + #[from_stringify("ethereum_types::FromDecStrErr", "coins::NumConversError")] + NumberError(String), InvalidParam(String), #[display(fmt = "Parameter {param} out of bounds, value: {value}, min: {min} max: {max}")] OutOfBounds { @@ -31,12 +34,15 @@ pub enum ApiIntegrationRpcError { }, #[display(fmt = "allowance not enough for 1inch contract, available: {allowance}, needed: {amount}")] OneInchAllowanceNotEnough { - allowance: BigDecimal, - amount: BigDecimal, + allowance: U256, + amount: U256, }, #[display(fmt = "1inch API error: {}", _0)] OneInchError(ApiClientError), ApiDataError(String), + InternalError(String), + #[display(fmt = "liquidity routing swap not found")] + BestLrSwapNotFound, } impl HttpStatusCode for ApiIntegrationRpcError { @@ -44,22 +50,25 @@ impl HttpStatusCode for ApiIntegrationRpcError { match self { ApiIntegrationRpcError::NoSuchCoin { .. } => StatusCode::NOT_FOUND, ApiIntegrationRpcError::CoinTypeError - | ApiIntegrationRpcError::NftNotSupported + | ApiIntegrationRpcError::NftProtocolNotSupported | ApiIntegrationRpcError::ChainNotSupported | ApiIntegrationRpcError::DifferentChains | ApiIntegrationRpcError::MyAddressError(_) | ApiIntegrationRpcError::InvalidParam(_) | ApiIntegrationRpcError::OutOfBounds { .. } - | ApiIntegrationRpcError::OneInchAllowanceNotEnough { .. } => StatusCode::BAD_REQUEST, + | ApiIntegrationRpcError::OneInchAllowanceNotEnough { .. } + | ApiIntegrationRpcError::NumberError(_) + | ApiIntegrationRpcError::BestLrSwapNotFound => StatusCode::BAD_REQUEST, ApiIntegrationRpcError::OneInchError(_) | ApiIntegrationRpcError::ApiDataError(_) => { StatusCode::BAD_GATEWAY }, + ApiIntegrationRpcError::InternalError { .. } => StatusCode::INTERNAL_SERVER_ERROR, } } } -impl ApiIntegrationRpcError { - pub(crate) fn from_api_error(error: ApiClientError, decimals: Option) -> Self { +impl From for ApiIntegrationRpcError { + fn from(error: ApiClientError) -> Self { match error { ApiClientError::InvalidParam(error) => ApiIntegrationRpcError::InvalidParam(error), ApiClientError::OutOfBounds { param, value, min, max } => { @@ -69,19 +78,28 @@ impl ApiIntegrationRpcError { | ApiClientError::ParseBodyError { .. } | ApiClientError::GeneralApiError { .. } => ApiIntegrationRpcError::OneInchError(error), ApiClientError::AllowanceNotEnough { allowance, amount, .. } => { - ApiIntegrationRpcError::OneInchAllowanceNotEnough { - allowance: u256_to_big_decimal(allowance, decimals.unwrap_or_default()).unwrap_or_default(), - amount: u256_to_big_decimal(amount, decimals.unwrap_or_default()).unwrap_or_default(), - } + ApiIntegrationRpcError::OneInchAllowanceNotEnough { allowance, amount } }, } } } +impl From for ApiIntegrationRpcError { + fn from(err: CoinFindError) -> Self { + match err { + CoinFindError::NoSuchCoin { coin } => ApiIntegrationRpcError::NoSuchCoin { coin }, + } + } +} + /// Error aggregator for errors of conversion of api returned values #[derive(Debug, Display, Serialize)] pub(crate) struct FromApiValueError(String); +impl FromApiValueError { + pub(crate) fn new(msg: String) -> Self { Self(msg) } +} + impl From for FromApiValueError { fn from(err: NumConversError) -> Self { Self(err.to_string()) } } diff --git a/mm2src/mm2_main/src/rpc/lp_commands/one_inch/rpcs.rs b/mm2src/mm2_main/src/rpc/lp_commands/one_inch/rpcs.rs index 45fec7f680..049c3de7c2 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/one_inch/rpcs.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/one_inch/rpcs.rs @@ -4,12 +4,14 @@ use super::types::{AggregationContractRequest, ClassicSwapCreateRequest, Classic ClassicSwapTokensRequest, ClassicSwapTokensResponse}; use coins::eth::{wei_from_big_decimal, EthCoin, EthCoinType}; use coins::hd_wallet::DisplayAddress; -use coins::{lp_coinfind_or_err, CoinWithDerivationMethod, MmCoin, MmCoinEnum}; +use coins::{lp_coinfind_or_err, CoinWithDerivationMethod, MmCoin, MmCoinEnum, Ticker}; +use ethereum_types::Address; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; -use trading_api::one_inch_api::client::ApiClient; -use trading_api::one_inch_api::types::{ClassicSwapCreateParams, ClassicSwapQuoteParams, ProtocolsResponse, - TokensResponse}; +use std::str::FromStr; +use trading_api::one_inch_api::classic_swap_types::{ClassicSwapCreateParams, ClassicSwapQuoteParams, + ProtocolsResponse, TokensResponse}; +use trading_api::one_inch_api::client::{ApiClient, SwapApiMethods, SwapUrlBuilder}; /// "1inch_v6_0_classic_swap_contract" rpc impl /// used to get contract address (for e.g. to approve funds) @@ -27,33 +29,37 @@ pub async fn one_inch_v6_0_classic_swap_quote_rpc( ) -> MmResult { let (base, base_contract) = get_coin_for_one_inch(&ctx, &req.base).await?; let (rel, rel_contract) = get_coin_for_one_inch(&ctx, &req.rel).await?; - api_supports_pair(&base, &rel)?; + let base_chain_id = base.chain_id().ok_or(ApiIntegrationRpcError::ChainNotSupported)?; + let rel_chain_id = rel.chain_id().ok_or(ApiIntegrationRpcError::ChainNotSupported)?; + api_supports_pair(base_chain_id, rel_chain_id)?; let sell_amount = wei_from_big_decimal(&req.amount.to_decimal(), base.decimals()) .mm_err(|err| ApiIntegrationRpcError::InvalidParam(err.to_string()))?; - let query_params = ClassicSwapQuoteParams::new(base_contract, rel_contract, sell_amount.to_string()) - .with_fee(req.fee) - .with_protocols(req.protocols) - .with_gas_price(req.gas_price) - .with_complexity_level(req.complexity_level) - .with_parts(req.parts) - .with_main_route_parts(req.main_route_parts) - .with_gas_limit(req.gas_limit) - .with_include_tokens_info(Some(req.include_tokens_info)) - .with_include_protocols(Some(req.include_protocols)) - .with_include_gas(Some(req.include_gas)) - .with_connector_tokens(req.connector_tokens) - .build_query_params() - .mm_err(|api_err| ApiIntegrationRpcError::from_api_error(api_err, Some(base.decimals())))?; - let quote = ApiClient::new(ctx) - .mm_err(|api_err| ApiIntegrationRpcError::from_api_error(api_err, Some(base.decimals())))? - .call_swap_api( - base.chain_id().ok_or(ApiIntegrationRpcError::ChainNotSupported)?, - ApiClient::get_quote_method().to_owned(), - Some(query_params), - ) + let query_params = ClassicSwapQuoteParams::new( + base_contract.display_address(), + rel_contract.display_address(), + sell_amount.to_string(), + ) + .with_fee(req.fee) + .with_protocols(req.protocols) + .with_gas_price(req.gas_price) + .with_complexity_level(req.complexity_level) + .with_parts(req.parts) + .with_main_route_parts(req.main_route_parts) + .with_gas_limit(req.gas_limit) + .with_include_tokens_info(Some(req.include_tokens_info)) + .with_include_protocols(Some(req.include_protocols)) + .with_include_gas(Some(req.include_gas)) + .with_connector_tokens(req.connector_tokens) + .build_query_params() + .map_mm_err()?; + let url = SwapUrlBuilder::create_api_url_builder(&ctx, base_chain_id, SwapApiMethods::ClassicSwapQuote) + .map_mm_err()? + .with_query_params(query_params) + .build() + .map_mm_err()?; + let quote = ApiClient::call_api(url).await.map_mm_err()?; + ClassicSwapResponse::from_api_classic_swap_data(&ctx, base_chain_id, quote) // use 'base' as amount in errors is in the src coin .await - .mm_err(|api_err| ApiIntegrationRpcError::from_api_error(api_err, Some(base.decimals())))?; // use 'base' as amount in errors is in the src coin - ClassicSwapResponse::from_api_classic_swap_data(quote, rel.decimals()) // use 'rel' as quote value is in the dst coin .mm_err(|err| ApiIntegrationRpcError::ApiDataError(err.to_string())) } @@ -66,14 +72,16 @@ pub async fn one_inch_v6_0_classic_swap_create_rpc( ) -> MmResult { let (base, base_contract) = get_coin_for_one_inch(&ctx, &req.base).await?; let (rel, rel_contract) = get_coin_for_one_inch(&ctx, &req.rel).await?; - api_supports_pair(&base, &rel)?; + let base_chain_id = base.chain_id().ok_or(ApiIntegrationRpcError::ChainNotSupported)?; + let rel_chain_id = rel.chain_id().ok_or(ApiIntegrationRpcError::ChainNotSupported)?; + api_supports_pair(base_chain_id, rel_chain_id)?; let sell_amount = wei_from_big_decimal(&req.amount.to_decimal(), base.decimals()) .mm_err(|err| ApiIntegrationRpcError::InvalidParam(err.to_string()))?; let single_address = base.derivation_method().single_addr_or_err().await.map_mm_err()?; let query_params = ClassicSwapCreateParams::new( - base_contract, - rel_contract, + base_contract.display_address(), + rel_contract.display_address(), sell_amount.to_string(), single_address.display_address(), req.slippage, @@ -98,17 +106,15 @@ pub async fn one_inch_v6_0_classic_swap_create_rpc( .with_allow_partial_fill(req.allow_partial_fill) .with_use_permit2(req.use_permit2) .build_query_params() - .mm_err(|api_err| ApiIntegrationRpcError::from_api_error(api_err, Some(base.decimals())))?; - let swap_with_tx = ApiClient::new(ctx) - .mm_err(|api_err| ApiIntegrationRpcError::from_api_error(api_err, Some(base.decimals())))? - .call_swap_api( - base.chain_id().ok_or(ApiIntegrationRpcError::ChainNotSupported)?, - ApiClient::get_swap_method().to_owned(), - Some(query_params), - ) + .map_mm_err()?; + let url = SwapUrlBuilder::create_api_url_builder(&ctx, base_chain_id, SwapApiMethods::ClassicSwapCreate) + .map_mm_err()? + .with_query_params(query_params) + .build() + .map_mm_err()?; + let swap_with_tx = ApiClient::call_api(url).await.map_mm_err()?; + ClassicSwapResponse::from_api_classic_swap_data(&ctx, base_chain_id, swap_with_tx) .await - .mm_err(|api_err| ApiIntegrationRpcError::from_api_error(api_err, Some(base.decimals())))?; // use 'base' as amount in errors is in the src coin - ClassicSwapResponse::from_api_classic_swap_data(swap_with_tx, base.decimals()) // use 'base' as we spend in the src coin .mm_err(|err| ApiIntegrationRpcError::ApiDataError(err.to_string())) } @@ -118,11 +124,11 @@ pub async fn one_inch_v6_0_classic_swap_liquidity_sources_rpc( ctx: MmArc, req: ClassicSwapLiquiditySourcesRequest, ) -> MmResult { - let response: ProtocolsResponse = ApiClient::new(ctx) - .mm_err(|api_err| ApiIntegrationRpcError::from_api_error(api_err, None))? - .call_swap_api(req.chain_id, ApiClient::get_liquidity_sources_method().to_owned(), None) - .await - .mm_err(|api_err| ApiIntegrationRpcError::from_api_error(api_err, None))?; + let url = SwapUrlBuilder::create_api_url_builder(&ctx, req.chain_id, SwapApiMethods::LiquiditySources) + .map_mm_err()? + .build() + .map_mm_err()?; + let response: ProtocolsResponse = ApiClient::call_api(url).await.map_mm_err()?; Ok(ClassicSwapLiquiditySourcesResponse { protocols: response.protocols, }) @@ -134,35 +140,39 @@ pub async fn one_inch_v6_0_classic_swap_tokens_rpc( ctx: MmArc, req: ClassicSwapTokensRequest, ) -> MmResult { - let response: TokensResponse = ApiClient::new(ctx) - .mm_err(|api_err| ApiIntegrationRpcError::from_api_error(api_err, None))? - .call_swap_api(req.chain_id, ApiClient::get_tokens_method().to_owned(), None) - .await - .mm_err(|api_err| ApiIntegrationRpcError::from_api_error(api_err, None))?; + let url = SwapUrlBuilder::create_api_url_builder(&ctx, req.chain_id, SwapApiMethods::Tokens) + .map_mm_err()? + .build() + .map_mm_err()?; + let response: TokensResponse = ApiClient::call_api(url).await.map_mm_err()?; Ok(ClassicSwapTokensResponse { tokens: response.tokens, }) } -async fn get_coin_for_one_inch(ctx: &MmArc, ticker: &str) -> MmResult<(EthCoin, String), ApiIntegrationRpcError> { +pub(crate) async fn get_coin_for_one_inch( + ctx: &MmArc, + ticker: &Ticker, +) -> MmResult<(EthCoin, Address), ApiIntegrationRpcError> { let coin = match lp_coinfind_or_err(ctx, ticker).await.map_mm_err()? { MmCoinEnum::EthCoin(coin) => coin, _ => return Err(MmError::new(ApiIntegrationRpcError::CoinTypeError)), }; let contract = match coin.coin_type { - EthCoinType::Eth => ApiClient::eth_special_contract().to_owned(), - EthCoinType::Erc20 { token_addr, .. } => token_addr.display_address(), - EthCoinType::Nft { .. } => return Err(MmError::new(ApiIntegrationRpcError::NftNotSupported)), + EthCoinType::Eth => Address::from_str(ApiClient::eth_special_contract()) + .map_to_mm(|_| ApiIntegrationRpcError::InternalError("invalid address".to_owned()))?, + EthCoinType::Erc20 { token_addr, .. } => token_addr, + EthCoinType::Nft { .. } => return Err(MmError::new(ApiIntegrationRpcError::NftProtocolNotSupported)), }; Ok((coin, contract)) } #[allow(clippy::result_large_err)] -fn api_supports_pair(base: &EthCoin, rel: &EthCoin) -> MmResult<(), ApiIntegrationRpcError> { - if !ApiClient::is_chain_supported(base.chain_id().ok_or(ApiIntegrationRpcError::ChainNotSupported)?) { +fn api_supports_pair(base_chain_id: u64, rel_chain_id: u64) -> MmResult<(), ApiIntegrationRpcError> { + if !ApiClient::is_chain_supported(base_chain_id) { return MmError::err(ApiIntegrationRpcError::ChainNotSupported); } - if base.chain_id() != rel.chain_id() { + if base_chain_id != rel_chain_id { return MmError::err(ApiIntegrationRpcError::DifferentChains); } Ok(()) @@ -181,7 +191,7 @@ mod tests { use mm2_number::{BigDecimal, MmNumber}; use mocktopus::mocking::{MockResult, Mockable}; use std::str::FromStr; - use trading_api::one_inch_api::{client::ApiClient, types::ClassicSwapData}; + use trading_api::one_inch_api::{classic_swap_types::ClassicSwapData, client::ApiClient}; #[test] fn test_classic_swap_response_conversion() { @@ -191,6 +201,8 @@ mod tests { "coin": ticker_coin, "name": "ethereum", "derivation_path": "m/44'/1'", + "chain_id": 1, + "decimals": 18, "protocol": { "type": "ETH", "protocol_data": { @@ -203,6 +215,7 @@ mod tests { "coin": ticker_token, "name": "jst", "chain_id": 1, + "decimals": 6, "protocol": { "type": "ERC20", "protocol_data": { @@ -296,42 +309,42 @@ mod tests { let response_create_raw = json!({ "dstAmount": "13", "tx": { - "from": "0x590559f6fb7720f24ff3e2fccf6015b466e9c92c", - "to": "0x111111125421ca6dc452d289314280a0f8842a65", - "data": "0x07ed23790000000000000000000000005f515f6c524b18ca30f7783fb58dd4be2e9904ec000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec70000000000000000000000005f515f6c524b18ca30f7783fb58dd4be2e9904ec000000000000000000000000590559f6fb7720f24ff3e2fccf6015b466e9c92c0000000000000000000000000000000000000000000000000000000000989680000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000648e8755f7ac30b5e4fa3f9c00e2cb6667501797b8bc01a7a367a4b2889ca6a05d9c31a31a781c12a4c3bdfc2ef1e02942e388b6565989ebe860bd67925bda74fbe0000000000000000000000000000000000000000000000000005ea0005bc00a007e5c0d200000000000000000000000000000000059800057e00018500009500001a4041c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2d0e30db00c20c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27b73644935b8e68019ac6356c40661e1bc3158606ae4071118002dc6c07b73644935b8e68019ac6356c40661e1bc3158600000000000000000000000000000000000000000000000000294932ccadc9c58c02aaa39b223fe8d0a0e5c4f27ead9083c756cc251204dff5675ecff96b565ba3804dd4a63799ccba406761d38e5ddf6ccf6cf7c55759d5210750b5d60f30044e331d039000000000000000000000000761d38e5ddf6ccf6cf7c55759d5210750b5d60f3000000000000000000000000111111111117dc0aa78b770fa6a738034120c302000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f8a744a79be00000000000000000000000042f527f50f16a103b6ccab48bccca214500c10210000000000000000000000005f515f6c524b18ca30f7783fb58dd4be2e9904ec00a0860a32ec00000000000000000000000000000000000000000000000000003005635d54300003d05120ead050515e10fdb3540ccd6f8236c46790508a76111111111117dc0aa78b770fa6a738034120c30200c4e525b10b000000000000000000000000000000000000000000000000000000000000002000000000000000000000000022b1a53ac4be63cdc1f47c99572290eff1edd8020000000000000000000000006a32cc044dd6359c27bb66e7b02dce6dd0fda2470000000000000000000000005f515f6c524b18ca30f7783fb58dd4be2e9904ec000000000000000000000000111111111117dc0aa78b770fa6a738034120c302000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003005635d5430000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000067138e8c00000000000000000000000000000000000000000000000000030fb9b1525d8185f8d63fbcbe42e5999263c349cb5d81000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000067297ee4eb097e072b4ab6f1620268061ae8046400000000000000000000000060cba82ddbf4b5ddcd4398cdd05354c6a790c309000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041d26038ef66344af785ff342b86db3da06c4cc6a62f0ca80ffd78affc0a95ccad44e814acebb1deda729bbfe3050bec14a47af487cc1cadc75f43db2d073016c31c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041a66cd52a747c5f60b9db637ffe30d0e413ec87858101832b4c5c1ae154bf247f3717c8ed4133e276ddf68d43a827f280863c91d6c42bc6ad1ec7083b2315b6fd1c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020d6bdbf78dac17f958d2ee523a2206206994597c13d831ec780a06c4eca27dac17f958d2ee523a2206206994597c13d831ec7111111125421ca6dc452d289314280a0f8842a65000000000000000000000000000000000000000000000000c095c0a2", - "value": "10000000", - "gas": 721429, - "gasPrice": "9525172167" + "from": "0x590559f6fb7720f24ff3e2fccf6015b466e9c92c", + "to": "0x111111125421ca6dc452d289314280a0f8842a65", + "data": "0x07ed23790000000000000000000000005f515f6c524b18ca30f7783fb58dd4be2e9904ec000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec70000000000000000000000005f515f6c524b18ca30f7783fb58dd4be2e9904ec000000000000000000000000590559f6fb7720f24ff3e2fccf6015b466e9c92c0000000000000000000000000000000000000000000000000000000000989680000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000648e8755f7ac30b5e4fa3f9c00e2cb6667501797b8bc01a7a367a4b2889ca6a05d9c31a31a781c12a4c3bdfc2ef1e02942e388b6565989ebe860bd67925bda74fbe0000000000000000000000000000000000000000000000000005ea0005bc00a007e5c0d200000000000000000000000000000000059800057e00018500009500001a4041c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2d0e30db00c20c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27b73644935b8e68019ac6356c40661e1bc3158606ae4071118002dc6c07b73644935b8e68019ac6356c40661e1bc3158600000000000000000000000000000000000000000000000000294932ccadc9c58c02aaa39b223fe8d0a0e5c4f27ead9083c756cc251204dff5675ecff96b565ba3804dd4a63799ccba406761d38e5ddf6ccf6cf7c55759d5210750b5d60f30044e331d039000000000000000000000000761d38e5ddf6ccf6cf7c55759d5210750b5d60f3000000000000000000000000111111111117dc0aa78b770fa6a738034120c302000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f8a744a79be00000000000000000000000042f527f50f16a103b6ccab48bccca214500c10210000000000000000000000005f515f6c524b18ca30f7783fb58dd4be2e9904ec00a0860a32ec00000000000000000000000000000000000000000000000000003005635d54300003d05120ead050515e10fdb3540ccd6f8236c46790508a76111111111117dc0aa78b770fa6a738034120c30200c4e525b10b000000000000000000000000000000000000000000000000000000000000002000000000000000000000000022b1a53ac4be63cdc1f47c99572290eff1edd8020000000000000000000000006a32cc044dd6359c27bb66e7b02dce6dd0fda2470000000000000000000000005f515f6c524b18ca30f7783fb58dd4be2e9904ec000000000000000000000000111111111117dc0aa78b770fa6a738034120c302000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003005635d5430000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000067138e8c00000000000000000000000000000000000000000000000000030fb9b1525d8185f8d63fbcbe42e5999263c349cb5d81000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026000000000000000000000000067297ee4eb097e072b4ab6f1620268061ae8046400000000000000000000000060cba82ddbf4b5ddcd4398cdd05354c6a790c309000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041d26038ef66344af785ff342b86db3da06c4cc6a62f0ca80ffd78affc0a95ccad44e814acebb1deda729bbfe3050bec14a47af487cc1cadc75f43db2d073016c31c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041a66cd52a747c5f60b9db637ffe30d0e413ec87858101832b4c5c1ae154bf247f3717c8ed4133e276ddf68d43a827f280863c91d6c42bc6ad1ec7083b2315b6fd1c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020d6bdbf78dac17f958d2ee523a2206206994597c13d831ec780a06c4eca27dac17f958d2ee523a2206206994597c13d831ec7111111125421ca6dc452d289314280a0f8842a65000000000000000000000000000000000000000000000000c095c0a2", + "value": "10000001", + "gas": 721429, + "gasPrice": "9525172167" }, "srcToken": { - "address": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", - "symbol": ticker_coin, - "name": "Ether", - "decimals": 18, - "eip2612": false, - "isFoT": false, - "logoURI": "https://tokens.1inch.io/0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.png", - "tags": [ - "crosschain", - "GROUP:ETH", - "native", - "PEG:ETH" - ] + "address": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "symbol": ticker_coin, + "name": "Ether", + "decimals": 18, + "eip2612": false, + "isFoT": false, + "logoURI": "https://tokens.1inch.io/0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.png", + "tags": [ + "crosschain", + "GROUP:ETH", + "native", + "PEG:ETH" + ] }, "dstToken": { - "address": "0x1234567890123456789012345678901234567890", - "symbol": ticker_token, - "name": "Just Token", - "decimals": 6, - "eip2612": false, - "isFoT": false, - "logoURI": "https://tokens.1inch.io/0x1234567890123456789012345678901234567890.png", - "tags": [ - "crosschain", - "GROUP:USDT", - "PEG:USD", - "tokens" - ] + "address": "0x1234567890123456789012345678901234567890", + "symbol": ticker_token, + "name": "Just Token", + "decimals": 6, + "eip2612": false, + "isFoT": false, + "logoURI": "https://tokens.1inch.io/0x1234567890123456789012345678901234567890.png", + "tags": [ + "crosschain", + "GROUP:USDT", + "PEG:USD", + "tokens" + ] }, "protocols": [ [ @@ -406,7 +419,7 @@ mod tests { use_permit2: None, }; - ApiClient::call_swap_api::.mock_safe(move |_, _, _, _| { + ApiClient::call_api::.mock_safe(move |_| { let response_quote_raw = response_quote_raw.clone(); MockResult::Return(Box::pin(async move { Ok(serde_json::from_value::(response_quote_raw).unwrap()) @@ -416,7 +429,7 @@ mod tests { let quote_response = block_on(one_inch_v6_0_classic_swap_quote_rpc(ctx.clone(), quote_req)).unwrap(); assert_eq!( quote_response.dst_amount.amount, - BigDecimal::from_str("0.000000000000000013").unwrap() + BigDecimal::from_str("0.000013").unwrap() ); assert_eq!(quote_response.src_token.as_ref().unwrap().symbol, ticker_coin); assert_eq!(quote_response.src_token.as_ref().unwrap().decimals, 18); @@ -424,7 +437,7 @@ mod tests { assert_eq!(quote_response.dst_token.as_ref().unwrap().decimals, 6); assert_eq!(quote_response.gas.unwrap(), 452704_u128); - ApiClient::call_swap_api::.mock_safe(move |_, _, _, _| { + ApiClient::call_api::.mock_safe(move |_| { let response_create_raw = response_create_raw.clone(); MockResult::Return(Box::pin(async move { Ok(serde_json::from_value::(response_create_raw).unwrap()) @@ -433,12 +446,16 @@ mod tests { let create_response = block_on(one_inch_v6_0_classic_swap_create_rpc(ctx, create_req)).unwrap(); assert_eq!( create_response.dst_amount.amount, - BigDecimal::from_str("0.000000000000000013").unwrap() + BigDecimal::from_str("0.000013").unwrap() ); assert_eq!(create_response.src_token.as_ref().unwrap().symbol, ticker_coin); assert_eq!(create_response.src_token.as_ref().unwrap().decimals, 18); assert_eq!(create_response.dst_token.as_ref().unwrap().symbol, ticker_token); assert_eq!(create_response.dst_token.as_ref().unwrap().decimals, 6); assert_eq!(create_response.tx.as_ref().unwrap().data.len(), 1960); + assert_eq!( + create_response.tx.as_ref().unwrap().value, + BigDecimal::from_str("0.000000000010000001").unwrap() + ); } } diff --git a/mm2src/mm2_main/src/rpc/lp_commands/one_inch/types.rs b/mm2src/mm2_main/src/rpc/lp_commands/one_inch/types.rs index 8324e801d4..b2f552c1ae 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/one_inch/types.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/one_inch/types.rs @@ -1,14 +1,20 @@ -use crate::rpc::lp_commands::one_inch::errors::FromApiValueError; -use coins::eth::{u256_to_big_decimal, wei_to_gwei_decimal}; +use super::errors::FromApiValueError; +use coins::eth::erc20::{get_erc20_ticker_by_contract_address, get_platform_ticker}; +use coins::eth::{u256_to_big_decimal, wei_to_eth_decimal, wei_to_gwei_decimal}; +use coins::Ticker; use common::true_f; use ethereum_types::{Address, U256}; +use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; use mm2_number::{construct_detailed, BigDecimal, MmNumber}; use rpc::v1::types::Bytes as BytesJson; use serde::{Deserialize, Serialize}; use std::collections::HashMap; +use std::convert::TryInto; +use std::str::FromStr; use trading_api::one_inch_api::{self, - types::{ProtocolImage, ProtocolInfo, TokenInfo}}; + classic_swap_types::{ProtocolImage, ProtocolInfo, TokenInfo as LrTokenInfo}, + client::ApiClient}; construct_detailed!(DetailedAmount, amount); @@ -21,9 +27,9 @@ pub struct AggregationContractRequest {} #[serde(deny_unknown_fields)] pub struct ClassicSwapQuoteRequest { /// Base coin ticker - pub base: String, + pub base: Ticker, /// Rel coin ticker - pub rel: String, + pub rel: Ticker, /// Swap amount in coins (with fraction) pub amount: MmNumber, /// Partner fee, percentage of src token amount will be sent to referrer address, min: 0; max: 3. @@ -66,9 +72,9 @@ pub struct ClassicSwapQuoteRequest { #[serde(deny_unknown_fields)] pub struct ClassicSwapCreateRequest { /// Base coin ticker - pub base: String, + pub base: Ticker, /// Rel coin ticker - pub rel: String, + pub rel: Ticker, /// Swap amount in coins (with fraction) pub amount: MmNumber, /// Allowed slippage, min: 0; max: 50 @@ -125,17 +131,24 @@ pub struct ClassicSwapCreateRequest { pub use_permit2: Option, } -/// Response for both classic swap quote or create swap calls -#[derive(Serialize, Debug)] -pub struct ClassicSwapResponse { +/// Details to create classic swap calls +#[derive(Serialize, Deserialize, Debug)] +pub struct ClassicSwapDetails { /// Destination token amount, in coins (with fraction) pub dst_amount: DetailedAmount, /// Source (base) token info #[serde(skip_serializing_if = "Option::is_none")] - pub src_token: Option, + pub src_token: Option, + /// Source (base) token name as it is defined in the coins file + pub src_token_kdf: Option, /// Destination (rel) token info #[serde(skip_serializing_if = "Option::is_none")] - pub dst_token: Option, + pub dst_token: Option, + /// Destination (rel) token name as it is defined in the coins file. + /// This is used to show route tokens in the GUI, like they are in the coin file. + /// However, route tokens can be missed in the coins file and therefore cannot be filled. + /// In this case GUI may use LrTokenInfo::Address or LrTokenInfo::Symbol + pub dst_token_kdf: Option, /// Used liquidity sources #[serde(skip_serializing_if = "Option::is_none")] pub protocols: Option>>>, @@ -146,29 +159,55 @@ pub struct ClassicSwapResponse { pub gas: Option, } -impl ClassicSwapResponse { - pub(crate) fn from_api_classic_swap_data( - data: one_inch_api::types::ClassicSwapData, - decimals: u8, +/// Response for both classic swap quote or create swap calls +pub type ClassicSwapResponse = ClassicSwapDetails; + +impl ClassicSwapDetails { + /// Get token name as it is defined in the coins file by contract address + async fn token_name_kdf(ctx: &MmArc, chain_id: u64, token_info: &LrTokenInfo) -> Option { + let special_contract = + Address::from_str(ApiClient::eth_special_contract()).expect("1inch special address must be valid"); // TODO: must call 1inch to get it, instead of burned consts + + let platform_ticker = get_platform_ticker(ctx, chain_id)?; + if token_info.address == special_contract { + Some(platform_ticker) + } else { + get_erc20_ticker_by_contract_address(ctx, &platform_ticker, &token_info.address) + } + } + + pub(crate) async fn from_api_classic_swap_data( + ctx: &MmArc, + chain_id: u64, + data: one_inch_api::classic_swap_types::ClassicSwapData, ) -> MmResult { + let src_token_info = data + .src_token + .ok_or(FromApiValueError::new("Missing source TokenInfo".to_owned()))?; + let dst_token_info = data + .dst_token + .ok_or(FromApiValueError::new("Missing destination TokenInfo".to_owned()))?; + let dst_decimals: u8 = dst_token_info + .decimals + .try_into() + .map_to_mm(|_| FromApiValueError::new("invalid decimals in destination TokenInfo".to_owned()))?; Ok(Self { dst_amount: MmNumber::from( - u256_to_big_decimal(U256::from_dec_str(&data.dst_amount)?, decimals).map_mm_err()?, + u256_to_big_decimal(U256::from_dec_str(&data.dst_amount)?, dst_decimals).map_mm_err()?, ) .into(), - src_token: data.src_token, - dst_token: data.dst_token, + src_token_kdf: Self::token_name_kdf(ctx, chain_id, &src_token_info).await, + src_token: Some(src_token_info), + dst_token_kdf: Self::token_name_kdf(ctx, chain_id, &dst_token_info).await, + dst_token: Some(dst_token_info), protocols: data.protocols, - tx: data - .tx - .map(|tx| TxFields::from_api_tx_fields(tx, decimals)) - .transpose()?, + tx: data.tx.map(TxFields::from_api_tx_fields).transpose()?, gas: data.gas, }) } } -#[derive(Serialize, Debug)] +#[derive(Deserialize, Serialize, Debug)] pub struct TxFields { pub from: Address, pub to: Address, @@ -181,14 +220,13 @@ pub struct TxFields { impl TxFields { pub(crate) fn from_api_tx_fields( - tx_fields: one_inch_api::types::TxFields, - decimals: u8, + tx_fields: one_inch_api::classic_swap_types::TxFields, ) -> MmResult { Ok(Self { from: tx_fields.from, to: tx_fields.to, data: BytesJson::from(hex::decode(str_strip_0x!(tx_fields.data.as_str()))?), - value: u256_to_big_decimal(U256::from_dec_str(&tx_fields.value)?, decimals).map_mm_err()?, + value: wei_to_eth_decimal(U256::from_dec_str(&tx_fields.value)?).map_mm_err()?, gas_price: wei_to_gwei_decimal(U256::from_dec_str(&tx_fields.gas_price)?).map_mm_err()?, gas: tx_fields.gas, }) @@ -212,5 +250,5 @@ pub struct ClassicSwapTokensRequest { #[derive(Serialize)] pub struct ClassicSwapTokensResponse { - pub tokens: HashMap, + pub tokens: HashMap, } diff --git a/mm2src/mm2_main/src/rpc/lp_commands/tokens.rs b/mm2src/mm2_main/src/rpc/lp_commands/tokens.rs index da54111581..9900b8d933 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/tokens.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/tokens.rs @@ -88,7 +88,7 @@ pub async fn get_token_info(ctx: MmArc, req: TokenInfoRequest) -> MmResult for MmNumber { } /// Useful for tests -impl From<&'static str> for MmNumber { - fn from(str: &'static str) -> MmNumber { +impl From<&str> for MmNumber { + fn from(str: &str) -> MmNumber { let num: BigDecimal = str.parse().expect("Input should be string representing decimal num"); num.into() } diff --git a/mm2src/mm2_number/src/mm_number_multi_repr.rs b/mm2src/mm2_number/src/mm_number_multi_repr.rs index 501a7626ba..973f1ffeb5 100644 --- a/mm2src/mm2_number/src/mm_number_multi_repr.rs +++ b/mm2src/mm2_number/src/mm_number_multi_repr.rs @@ -3,10 +3,10 @@ use crate::from_ratio_to_dec; use crate::mm_number::MmNumber; use bigdecimal::BigDecimal; use num_rational::BigRational; -use serde::Serialize; +use serde::{Deserialize, Serialize}; /// MmNumber representation in all available forms. -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct MmNumberMultiRepr { pub decimal: BigDecimal, pub rational: BigRational, diff --git a/mm2src/mm2_rpc/src/data/legacy/orders.rs b/mm2src/mm2_rpc/src/data/legacy/orders.rs index 9890b1d709..d88e73a8cd 100644 --- a/mm2src/mm2_rpc/src/data/legacy/orders.rs +++ b/mm2src/mm2_rpc/src/data/legacy/orders.rs @@ -36,7 +36,7 @@ pub struct SellBuyRequest { pub save_in_history: bool, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Debug, Deserialize)] pub struct SellBuyResponse { #[serde(flatten)] pub request: TakerRequestForRpc, diff --git a/mm2src/trading_api/Cargo.toml b/mm2src/trading_api/Cargo.toml index bc30874dfc..ffabd326ec 100644 --- a/mm2src/trading_api/Cargo.toml +++ b/mm2src/trading_api/Cargo.toml @@ -14,6 +14,7 @@ mm2_number = { path = "../mm2_number" } mocktopus = { workspace = true, optional = true } derive_more.workspace = true ethereum-types.workspace = true +futures = { workspace = true, features = ["async-await"], optional = true } lazy_static.workspace = true serde.workspace = true serde_derive.workspace = true @@ -21,7 +22,10 @@ serde_json = { workspace = true, features = ["preserve_order", "raw_value"] } url.workspace = true [features] -test-ext-api = [] # use test config to connect to an external api +# use this to connect to external trading api in tests +test-ext-api = [ + "futures" +] for-tests = ["dep:mocktopus"] [dev-dependencies] diff --git a/mm2src/trading_api/src/one_inch_api.rs b/mm2src/trading_api/src/one_inch_api.rs index 9b0af1625e..6c4c69ebab 100644 --- a/mm2src/trading_api/src/one_inch_api.rs +++ b/mm2src/trading_api/src/one_inch_api.rs @@ -1,5 +1,6 @@ //! Wrapper for 1inch API. +pub mod classic_swap_types; pub mod client; pub mod errors; -pub mod types; +pub mod portfolio_types; diff --git a/mm2src/trading_api/src/one_inch_api/types.rs b/mm2src/trading_api/src/one_inch_api/classic_swap_types.rs similarity index 93% rename from mm2src/trading_api/src/one_inch_api/types.rs rename to mm2src/trading_api/src/one_inch_api/classic_swap_types.rs index f13e943768..b7bb7902e8 100644 --- a/mm2src/trading_api/src/one_inch_api/types.rs +++ b/mm2src/trading_api/src/one_inch_api/classic_swap_types.rs @@ -1,4 +1,4 @@ -#![allow(clippy::result_large_err)] +//! Structs to call 1inch classic swap api use super::client::QueryParams; use super::errors::ApiClientError; @@ -63,7 +63,8 @@ impl ClassicSwapQuoteParams { def_with_opt_param!(include_gas, bool); def_with_opt_param!(connector_tokens, String); - pub fn build_query_params(&self) -> MmResult, ApiClientError> { + #[allow(clippy::result_large_err)] + pub fn build_query_params(&self) -> MmResult { self.validate_params()?; let mut params = vec![ @@ -87,6 +88,7 @@ impl ClassicSwapQuoteParams { } /// Validate params by 1inch rules (to avoid extra requests) + #[allow(clippy::result_large_err)] fn validate_params(&self) -> MmResult<(), ApiClientError> { validate_fee(&self.fee)?; validate_complexity_level(&self.complexity_level)?; @@ -159,7 +161,8 @@ impl ClassicSwapCreateParams { def_with_opt_param!(allow_partial_fill, bool); def_with_opt_param!(use_permit2, bool); - pub fn build_query_params(&self) -> MmResult, ApiClientError> { + #[allow(clippy::result_large_err)] + pub fn build_query_params(&self) -> MmResult { self.validate_params()?; let mut params = vec![ @@ -194,6 +197,7 @@ impl ClassicSwapCreateParams { } /// Validate params by 1inch rules (to avoid extra requests) + #[allow(clippy::result_large_err)] fn validate_params(&self) -> MmResult<(), ApiClientError> { validate_slippage(self.slippage)?; validate_fee(&self.fee)?; @@ -205,7 +209,7 @@ impl ClassicSwapCreateParams { } } -#[derive(Deserialize, Debug, Serialize)] +#[derive(Clone, Deserialize, Debug, Serialize)] pub struct TokenInfo { pub address: Address, pub symbol: String, @@ -219,7 +223,7 @@ pub struct TokenInfo { pub tags: Vec, } -#[derive(Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct ProtocolInfo { pub name: String, pub part: f64, @@ -229,7 +233,8 @@ pub struct ProtocolInfo { pub to_token_address: Address, } -#[derive(Deserialize, Debug)] +/// Returned data from an API call to get quote or create swap +#[derive(Clone, Deserialize, Debug)] pub struct ClassicSwapData { /// dst token amount to receive, in api is a decimal number as string #[serde(rename = "dstAmount")] @@ -239,11 +244,13 @@ pub struct ClassicSwapData { #[serde(rename = "dstToken")] pub dst_token: Option, pub protocols: Option>>>, + /// Returned from create swap call pub tx: Option, + /// Returned from quote call pub gas: Option, } -#[derive(Deserialize, Debug)] +#[derive(Clone, Deserialize, Debug)] pub struct TxFields { pub from: Address, pub to: Address, @@ -299,6 +306,7 @@ mod serde_one_inch_link { } } +#[allow(clippy::result_large_err)] fn validate_slippage(slippage: f32) -> MmResult<(), ApiClientError> { if !(0.0..=ONE_INCH_MAX_SLIPPAGE).contains(&slippage) { return Err(ApiClientError::OutOfBounds { @@ -312,6 +320,7 @@ fn validate_slippage(slippage: f32) -> MmResult<(), ApiClientError> { Ok(()) } +#[allow(clippy::result_large_err)] fn validate_fee(fee: &Option) -> MmResult<(), ApiClientError> { if let Some(fee) = fee { if !(0.0..=ONE_INCH_MAX_FEE_SHARE).contains(fee) { @@ -327,6 +336,7 @@ fn validate_fee(fee: &Option) -> MmResult<(), ApiClientError> { Ok(()) } +#[allow(clippy::result_large_err)] fn validate_gas_limit(gas_limit: &Option) -> MmResult<(), ApiClientError> { if let Some(gas_limit) = gas_limit { if gas_limit > &ONE_INCH_MAX_GAS { @@ -342,6 +352,7 @@ fn validate_gas_limit(gas_limit: &Option) -> MmResult<(), ApiClientError> Ok(()) } +#[allow(clippy::result_large_err)] fn validate_parts(parts: &Option) -> MmResult<(), ApiClientError> { if let Some(parts) = parts { if parts > &ONE_INCH_MAX_PARTS { @@ -357,6 +368,7 @@ fn validate_parts(parts: &Option) -> MmResult<(), ApiClientError> { Ok(()) } +#[allow(clippy::result_large_err)] fn validate_main_route_parts(main_route_parts: &Option) -> MmResult<(), ApiClientError> { if let Some(main_route_parts) = main_route_parts { if main_route_parts > &ONE_INCH_MAX_MAIN_ROUTE_PARTS { @@ -372,6 +384,7 @@ fn validate_main_route_parts(main_route_parts: &Option) -> MmResult<(), Api Ok(()) } +#[allow(clippy::result_large_err)] fn validate_complexity_level(complexity_level: &Option) -> MmResult<(), ApiClientError> { if let Some(complexity_level) = complexity_level { if complexity_level > &ONE_INCH_MAX_COMPLEXITY_LEVEL { @@ -388,6 +401,7 @@ fn validate_complexity_level(complexity_level: &Option) -> MmResult<(), Api } /// Check if url is valid and is a subdomain of 1inch domain (simple anti-phishing check) +#[allow(clippy::result_large_err)] fn validate_one_inch_link(s: &str) -> MmResult { let url = Url::parse(s).map_err(|_err| ApiClientError::ParseBodyError { error_msg: BAD_URL_IN_RESPONSE_ERROR.to_owned(), diff --git a/mm2src/trading_api/src/one_inch_api/client.rs b/mm2src/trading_api/src/one_inch_api/client.rs index 2825d930b5..c4856ae572 100644 --- a/mm2src/trading_api/src/one_inch_api/client.rs +++ b/mm2src/trading_api/src/one_inch_api/client.rs @@ -1,6 +1,6 @@ use super::errors::ApiClientError; use crate::one_inch_api::errors::NativeError; -use common::StatusCode; +use common::{log, StatusCode}; #[cfg(feature = "test-ext-api")] use lazy_static::lazy_static; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::{map_mm_error::MapMmError, @@ -10,15 +10,14 @@ use mm2_net::transport::slurp_url_with_headers; use serde::de::DeserializeOwned; use url::Url; +#[cfg(feature = "test-ext-api")] use common::executor::Timer; + +#[cfg(feature = "test-ext-api")] +use futures::lock::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard}; + #[cfg(any(test, feature = "for-tests"))] use mocktopus::macros::*; -const ONE_INCH_API_ENDPOINT_V6_0: &str = "swap/v6.0/"; -const SWAP_METHOD: &str = "swap"; -const QUOTE_METHOD: &str = "quote"; -const LIQUIDITY_SOURCES_METHOD: &str = "liquidity-sources"; -const TOKENS_METHOD: &str = "tokens"; - const ONE_INCH_AGGREGATION_ROUTER_CONTRACT_V6_0: &str = "0x111111125421ca6dc452d289314280a0f8842a65"; const ONE_INCH_ETH_SPECIAL_CONTRACT: &str = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; @@ -31,7 +30,7 @@ lazy_static! { static ref ONE_INCH_API_TEST_AUTH: String = std::env::var("ONE_INCH_API_TEST_AUTH").unwrap_or_default(); } -pub(crate) type QueryParams<'life> = Vec<(&'life str, String)>; +pub(crate) type QueryParams = Vec<(&'static str, String)>; /// 1inch v6.0 supported eth-based chains const ONE_INCH_V6_0_SUPPORTED_CHAINS: &[(&str, u64)] = &[ @@ -49,37 +48,42 @@ const ONE_INCH_V6_0_SUPPORTED_CHAINS: &[(&str, u64)] = &[ ("Aurora", 1313161554), ]; -pub(crate) struct UrlBuilder<'a> { +/// 1inch API basic url builder +pub struct UrlBuilder { base_url: Url, - endpoint: &'a str, - chain_id: u64, + endpoint: &'static str, + chain_id: Option, method_name: String, - query_params: QueryParams<'a>, + query_params: QueryParams, } -impl<'a> UrlBuilder<'a> { - pub(crate) fn new(api_client: &ApiClient, chain_id: u64, method_name: String) -> Self { +impl UrlBuilder { + /// Create new basic url builder to call 1inch API's. Normally used by specific API url builders. + /// Note: in the classic swap API chain_id is added into url path, in portfolio chain_id is a query param so it would be optional here. + fn new(base_url: Url, chain_id: Option, endpoint: &'static str, method_name: String) -> Self { Self { - base_url: api_client.base_url.clone(), - endpoint: ApiClient::get_swap_endpoint(), + base_url, + endpoint, chain_id, method_name, query_params: vec![], } } - pub(crate) fn with_query_params(&mut self, mut more_params: QueryParams<'a>) -> &mut Self { + pub fn with_query_params(mut self, mut more_params: QueryParams) -> Self { self.query_params.append(&mut more_params); self } #[allow(clippy::result_large_err)] - pub(crate) fn build(&self) -> MmResult { - let url = self - .base_url - .join(self.endpoint)? - .join(&format!("{}/", self.chain_id))? - .join(self.method_name.as_str())?; + pub fn build(&self) -> MmResult { + let url = self.base_url.join(self.endpoint)?; + let url = if let Some(chain_id) = self.chain_id { + url.join(&format!("{}/", chain_id))? + } else { + url + }; + let url = url.join(self.method_name.as_str())?; Ok(Url::parse_with_params( url.as_str(), self.query_params @@ -90,17 +94,88 @@ impl<'a> UrlBuilder<'a> { } } -/// 1-inch API caller -pub struct ApiClient { - base_url: Url, +/// 1inch swap api methods +pub enum SwapApiMethods { + ClassicSwapQuote, + ClassicSwapCreate, + LiquiditySources, + Tokens, } +impl SwapApiMethods { + const SWAP_METHOD: &str = "swap"; + const QUOTE_METHOD: &str = "quote"; + const LIQUIDITY_SOURCES_METHOD: &str = "liquidity-sources"; + const TOKENS_METHOD: &str = "tokens"; + + fn name(&self) -> &'static str { + match self { + Self::ClassicSwapQuote => Self::QUOTE_METHOD, + Self::ClassicSwapCreate => Self::SWAP_METHOD, + Self::LiquiditySources => Self::LIQUIDITY_SOURCES_METHOD, + Self::Tokens => Self::TOKENS_METHOD, + } + } +} + +/// 1inch swap api url builder +pub struct SwapUrlBuilder; + +impl SwapUrlBuilder { + const CLASSIC_SWAP_ENDPOINT_V6_0: &str = "swap/v6.0/"; + + #[allow(clippy::result_large_err)] + pub fn create_api_url_builder( + ctx: &MmArc, + chain_id: u64, + method: SwapApiMethods, + ) -> MmResult { + Ok(UrlBuilder::new( + ApiClient::base_url(ctx)?, + Some(chain_id), + Self::CLASSIC_SWAP_ENDPOINT_V6_0, + method.name().to_owned(), + )) + } +} + +pub enum PortfolioApiMethods { + CrossPrices, +} +impl PortfolioApiMethods { + const CROSS_PRICES_METHOD: &str = "time_range/cross_prices"; + + fn name(&self) -> &'static str { + match self { + Self::CrossPrices => Self::CROSS_PRICES_METHOD, + } + } +} + +pub struct PortfolioUrlBuilder; + +impl PortfolioUrlBuilder { + const PORTFOLIO_PRICES_ENDPOINT_V1_0: &str = "portfolio/integrations/prices/v1/"; + + #[allow(clippy::result_large_err)] + pub fn create_api_url_builder(ctx: &MmArc, method: PortfolioApiMethods) -> MmResult { + Ok(UrlBuilder::new( + ApiClient::base_url(ctx)?, + None, + Self::PORTFOLIO_PRICES_ENDPOINT_V1_0, + method.name().to_owned(), + )) + } +} + +/// 1-inch API caller +pub struct ApiClient; #[allow(clippy::swap_ptr_to_ref)] // need for moctopus #[cfg_attr(any(test, feature = "for-tests"), mockable)] impl ApiClient { #[allow(unused_variables)] #[allow(clippy::result_large_err)] - pub fn new(ctx: MmArc) -> MmResult { + fn base_url(ctx: &MmArc) -> MmResult { #[cfg(not(test))] let url_cfg = ctx.conf["1inch_api"] .as_str() @@ -109,9 +184,7 @@ impl ApiClient { #[cfg(test)] let url_cfg = ONE_INCH_API_TEST_URL; - Ok(Self { - base_url: Url::parse(url_cfg)?, - }) + Ok(Url::parse(url_cfg)?) } pub const fn eth_special_contract() -> &'static str { ONE_INCH_ETH_SPECIAL_CONTRACT } @@ -127,23 +200,20 @@ impl ApiClient { #[cfg(feature = "test-ext-api")] ("Authorization", ONE_INCH_API_TEST_AUTH.as_str()), ("accept", "application/json"), + ("content-type", "application/json"), ] } - fn get_swap_endpoint() -> &'static str { ONE_INCH_API_ENDPOINT_V6_0 } - - pub const fn get_swap_method() -> &'static str { SWAP_METHOD } - - pub const fn get_quote_method() -> &'static str { QUOTE_METHOD } + pub async fn call_api(api_url: Url) -> MmResult { + #[cfg(feature = "test-ext-api")] + let _guard = ApiClient::one_req_per_sec().await; - pub const fn get_liquidity_sources_method() -> &'static str { LIQUIDITY_SOURCES_METHOD } - - pub const fn get_tokens_method() -> &'static str { TOKENS_METHOD } - - pub(crate) async fn call_api(api_url: &Url) -> MmResult { + log::debug!("1inch call url={}", api_url.to_string()); let (status_code, _, body) = slurp_url_with_headers(api_url.as_str(), ApiClient::get_headers()) .await .mm_err(ApiClientError::TransportError)?; + log::debug!("1inch response body={}", String::from_utf8_lossy(&body)); + // TODO: handle text body errors like 'The limit of requests per second has been exceeded' let body = serde_json::from_slice(&body).map_to_mm(|err| ApiClientError::ParseBodyError { error_msg: err.to_string(), })?; @@ -159,18 +229,15 @@ impl ApiClient { }) } - pub async fn call_swap_api<'l, T: DeserializeOwned>( - &self, - chain_id: u64, - method: String, - params: Option>, - ) -> MmResult { - let mut builder = UrlBuilder::new(self, chain_id, method); - if let Some(params) = params { - builder.with_query_params(params); + /// Prevent concurrent calls + #[cfg(feature = "test-ext-api")] + async fn one_req_per_sec<'a>() -> AsyncMutexGuard<'a, ()> { + lazy_static! { + /// Lock to ensure requests to the API are not running concurrently in tests + static ref ONE_INCH_REQ_SYNC: AsyncMutex<()> = AsyncMutex::new(()); } - let api_url = builder.build()?; - - ApiClient::call_api(&api_url).await + let guard = ONE_INCH_REQ_SYNC.lock().await; + Timer::sleep(1.).await; // ensure 1 req per sec to prevent 1inch rate limiter error for dev account + guard } } diff --git a/mm2src/trading_api/src/one_inch_api/portfolio_types.rs b/mm2src/trading_api/src/one_inch_api/portfolio_types.rs new file mode 100644 index 0000000000..5100c7434c --- /dev/null +++ b/mm2src/trading_api/src/one_inch_api/portfolio_types.rs @@ -0,0 +1,98 @@ +//! Structs to call 1inch portfolio api + +use super::client::QueryParams; +use super::errors::ApiClientError; +use common::{def_with_opt_param, push_if_some}; +use mm2_err_handle::mm_error::MmResult; +use mm2_number::BigDecimal; +use serde::Deserialize; + +#[derive(Default)] +pub enum DataGranularity { + Month, + Week, + Day, + FourHour, + Hour, + FifteenMin, + #[default] + FiveMin, +} + +impl ToString for DataGranularity { + fn to_string(&self) -> String { + match self { + DataGranularity::Month => "month".to_owned(), + DataGranularity::Week => "week".to_owned(), + DataGranularity::Day => "day".to_owned(), + DataGranularity::FourHour => "4hour".to_owned(), + DataGranularity::Hour => "hour".to_owned(), + DataGranularity::FifteenMin => "15min".to_owned(), + DataGranularity::FiveMin => "5min".to_owned(), + } + } +} + +/// API params builder to get OHLC price history for token pair +/// See 1inch docs: https://portal.1inch.dev/documentation/apis/portfolio/swagger?method=get&path=%2Fintegrations%2Fprices%2Fv1%2Ftime_range%2Fcross_prices +#[derive(Default)] +pub struct CrossPriceParams { + chain_id: u64, + /// Base token address + token0_address: String, + /// Quote token address + token1_address: String, + /// Returned time series intervals + granularity: Option, + /// max number of time series + limit: Option, +} + +impl CrossPriceParams { + pub fn new(chain_id: u64, token0_address: String, token1_address: String) -> Self { + Self { + chain_id, + token0_address, + token1_address, + ..Default::default() + } + } + + def_with_opt_param!(granularity, DataGranularity); + def_with_opt_param!(limit, u32); + + #[allow(clippy::result_large_err)] + pub fn build_query_params(&self) -> MmResult { + let mut params = vec![ + ("chain_id", self.chain_id.to_string()), + ("token0_address", self.token0_address.clone()), + ("token1_address", self.token1_address.clone()), + ]; + + push_if_some!(params, "granularity", &self.granularity); + push_if_some!(params, "limit", &self.limit); + + Ok(params) + } +} + +/// Element of token_0/token_1 price series returned from the 1inch cross_prices call. +/// Contains OHLC (Open, High, Low, Close) prices for the granularity period. +/// TODO: check cross_prices v2 +#[derive(Clone, Deserialize, Debug)] +pub struct CrossPricesData { + /// Time of the granularity period + pub timestamp: u64, + /// Price at the period opening + pub open: BigDecimal, + /// Lowest price within the period + pub low: BigDecimal, + /// Average price within the period + pub avg: BigDecimal, + /// Highest price within the period + pub high: BigDecimal, + /// Price at the period closing + pub close: BigDecimal, +} + +pub type CrossPricesSeries = Vec; From 7d51c5a6ab4390e4db8c4510db7012abe6cec8ad Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 3 Jul 2025 10:00:38 +0100 Subject: [PATCH 05/75] chore(toolchain): upgrade toolchain to nightly 1.86.0 (#2444) --- .github/workflows/dev-build.yml | 36 ++--- .github/workflows/fmt-and-lint.yml | 8 +- .github/workflows/release-build.yml | 36 ++--- .github/workflows/test.yml | 32 ++--- Cargo.lock | 132 ++++++++++++------ Cargo.toml | 8 +- clippy.toml | 2 +- mm2src/coins/coin_balance.rs | 1 + mm2src/coins/coin_errors.rs | 1 + mm2src/coins/eth.rs | 12 +- mm2src/coins/eth/eth_balance_events.rs | 2 +- .../eth/eth_swap_v2/eth_taker_swap_v2.rs | 1 + mm2src/coins/eth/eth_swap_v2/mod.rs | 3 +- mm2src/coins/eth/eth_tests.rs | 3 +- mm2src/coins/eth/eth_utils.rs | 2 +- .../coins/eth/fee_estimation/eip1559/mod.rs | 12 +- mm2src/coins/eth/fee_estimation/rpc.rs | 1 + mm2src/coins/eth/nft_swap_v2/errors.rs | 1 + mm2src/coins/eth/wallet_connect.rs | 4 +- mm2src/coins/eth/web3_transport/mod.rs | 2 + mm2src/coins/hd_wallet/errors.rs | 1 + mm2src/coins/lightning.rs | 1 + mm2src/coins/lightning/ln_events.rs | 7 +- mm2src/coins/lightning/ln_serialization.rs | 4 +- mm2src/coins/lightning/ln_sql.rs | 23 ++- mm2src/coins/lightning/ln_utils.rs | 1 + mm2src/coins/lp_coins.rs | 34 +++-- mm2src/coins/nft/nft_structs.rs | 1 + mm2src/coins/nft/nft_tests.rs | 14 +- mm2src/coins/nft/storage/mod.rs | 6 + mm2src/coins/nft/storage/wasm/mod.rs | 1 + mm2src/coins/nft/storage/wasm/wasm_storage.rs | 4 +- mm2src/coins/qrc20.rs | 10 +- mm2src/coins/qrc20/history.rs | 2 +- mm2src/coins/qrc20/qrc20_tests.rs | 5 +- mm2src/coins/qrc20/rpc_clients.rs | 2 +- mm2src/coins/qrc20/swap.rs | 1 + mm2src/coins/rpc_command/get_enabled_coins.rs | 1 + mm2src/coins/rpc_command/get_new_address.rs | 2 +- .../coins/rpc_command/init_create_account.rs | 2 +- .../rpc_command/lightning/close_channel.rs | 1 + .../rpc_command/lightning/connect_to_node.rs | 1 + .../rpc_command/lightning/generate_invoice.rs | 1 + .../lightning/get_channel_details.rs | 1 + .../lightning/get_claimable_balances.rs | 1 + .../lightning/get_payment_details.rs | 1 + .../rpc_command/lightning/list_channels.rs | 1 + .../lightning/list_payments_by_filter.rs | 1 + .../rpc_command/lightning/open_channel.rs | 1 + .../rpc_command/lightning/send_payment.rs | 1 + .../rpc_command/lightning/trusted_nodes.rs | 1 + .../rpc_command/lightning/update_channel.rs | 1 + .../coins/rpc_command/tendermint/staking.rs | 10 +- mm2src/coins/siacoin.rs | 3 +- .../tendermint/rpc/tendermint_native_rpc.rs | 1 + .../tendermint/rpc/tendermint_wasm_rpc.rs | 1 - mm2src/coins/tendermint/tendermint_coin.rs | 4 +- .../tendermint/tendermint_tx_history_v2.rs | 1 + mm2src/coins/tx_history_storage/mod.rs | 2 +- mm2src/coins/utxo/bch.rs | 4 +- mm2src/coins/utxo/qtum.rs | 12 +- mm2src/coins/utxo/qtum_delegation.rs | 2 +- mm2src/coins/utxo/rpc_clients.rs | 16 +-- .../utxo/rpc_clients/electrum_rpc/client.rs | 10 +- .../rpc_clients/electrum_rpc/connection.rs | 10 +- .../connection_manager/manager.rs | 8 +- mm2src/coins/utxo/slp.rs | 1 + .../sql_block_header_storage.rs | 2 +- .../wasm/block_header_table.rs | 4 +- .../utxo/utxo_builder/utxo_arc_builder.rs | 17 ++- .../utxo/utxo_builder/utxo_coin_builder.rs | 3 +- .../utxo/utxo_builder/utxo_conf_builder.rs | 3 +- mm2src/coins/utxo/utxo_common.rs | 17 ++- mm2src/coins/utxo/utxo_tests.rs | 11 +- mm2src/coins/utxo/utxo_tx_history_v2.rs | 9 +- mm2src/coins/utxo_signer/src/with_trezor.rs | 2 +- mm2src/coins/z_coin.rs | 19 ++- .../storage/blockdb/blockdb_sql_storage.rs | 15 +- .../storage/walletdb/wallet_sql_storage.rs | 4 +- .../z_coin/storage/walletdb/wasm/storage.rs | 7 +- .../z_coin/storage/walletdb/wasm/tables.rs | 4 +- .../z_coin/storage/z_locked_notes/mod.rs | 1 + .../z_coin/storage/z_params/indexeddb.rs | 2 +- mm2src/coins/z_coin/z_coin_errors.rs | 4 +- mm2src/coins/z_coin/z_rpc.rs | 8 +- .../src/bch_with_tokens_activation.rs | 48 ++----- .../src/erc20_token_activation.rs | 6 +- .../src/eth_with_token_activation.rs | 13 +- mm2src/coins_activation/src/init_token.rs | 17 +-- mm2src/coins_activation/src/l2/init_l2.rs | 22 ++- mm2src/coins_activation/src/l2/mod.rs | 3 +- .../src/platform_coin_with_tokens.rs | 50 +++---- .../standalone_coin/init_standalone_coin.rs | 29 ++-- .../src/standalone_coin/mod.rs | 4 +- mm2src/coins_activation/src/token.rs | 9 +- mm2src/common/build.rs | 4 +- mm2src/common/common.rs | 15 +- mm2src/common/jsonrpc_client.rs | 1 + mm2src/common/log.rs | 13 +- mm2src/common/number_type_casting.rs | 2 +- mm2src/common/seri.rs | 2 +- .../common/shared_ref_counter/src/enable.rs | 6 +- mm2src/crypto/src/global_hd_ctx.rs | 2 + mm2src/db_common/src/sql_constraint.rs | 2 +- mm2src/db_common/src/sql_delete.rs | 2 +- mm2src/db_common/src/sql_query.rs | 2 +- mm2src/db_common/src/sql_update.rs | 2 +- mm2src/derives/enum_derives/src/lib.rs | 2 +- .../src/session/rpc/event.rs | 2 +- .../src/session/rpc/update.rs | 2 +- mm2src/kdf_walletconnect/src/storage/mod.rs | 2 + mm2src/mm2_bin_lib/src/mm2_native_lib.rs | 5 +- mm2src/mm2_bitcoin/chain/Cargo.toml | 1 + mm2src/mm2_bitcoin/chain/src/block_header.rs | 10 +- mm2src/mm2_bitcoin/chain/src/transaction.rs | 4 +- mm2src/mm2_bitcoin/crypto/Cargo.toml | 1 + mm2src/mm2_bitcoin/keys/Cargo.toml | 1 + mm2src/mm2_bitcoin/keys/src/address.rs | 4 +- .../mm2_bitcoin/keys/src/address_prefixes.rs | 2 +- mm2src/mm2_bitcoin/keys/src/cashaddress.rs | 8 +- mm2src/mm2_bitcoin/primitives/Cargo.toml | 1 + mm2src/mm2_bitcoin/primitives/src/bytes.rs | 2 +- mm2src/mm2_bitcoin/primitives/src/hash.rs | 8 +- mm2src/mm2_bitcoin/rpc/Cargo.toml | 1 + .../mm2_bitcoin/rpc/src/v1/types/address.rs | 2 +- mm2src/mm2_bitcoin/rpc/src/v1/types/bytes.rs | 2 +- mm2src/mm2_bitcoin/rpc/src/v1/types/hash.rs | 6 +- mm2src/mm2_bitcoin/rpc/src/v1/types/script.rs | 2 +- mm2src/mm2_bitcoin/script/Cargo.toml | 1 + mm2src/mm2_bitcoin/script/src/script.rs | 4 +- mm2src/mm2_bitcoin/script/src/sign.rs | 3 +- mm2src/mm2_bitcoin/serialization/Cargo.toml | 1 + mm2src/mm2_bitcoin/serialization/src/impls.rs | 2 +- .../mm2_bitcoin/serialization/src/reader.rs | 1 - .../serialization_derive/Cargo.toml | 1 + .../serialization_derive/src/de.rs | 2 +- .../serialization_derive/src/ser.rs | 2 +- .../spv_validation/src/helpers_validation.rs | 4 +- mm2src/mm2_core/Cargo.toml | 1 + mm2src/mm2_core/src/mm_ctx.rs | 4 +- .../mm2_db/src/indexed_db/drivers/builder.rs | 1 + .../drivers/cursor/multi_key_bound_cursor.rs | 4 +- .../mm2_db/src/indexed_db/indexed_cursor.rs | 7 +- mm2src/mm2_err_handle/src/map_to_mm_fut.rs | 2 +- mm2src/mm2_eth/src/eip712_encode.rs | 2 +- mm2src/mm2_event_stream/src/manager.rs | 2 +- mm2src/mm2_event_stream/src/streamer_ids.rs | 2 +- .../src/account/storage/mod.rs | 2 + mm2src/mm2_io/src/fs.rs | 2 +- mm2src/mm2_main/Cargo.toml | 4 + mm2src/mm2_main/src/database/my_orders.rs | 8 +- mm2src/mm2_main/src/database/my_swaps.rs | 6 +- mm2src/mm2_main/src/database/stats_nodes.rs | 6 +- mm2src/mm2_main/src/lp_native_dex.rs | 2 +- mm2src/mm2_main/src/lp_ordermatch.rs | 48 +++---- .../src/lp_ordermatch/my_orders_storage.rs | 2 + .../src/lp_ordermatch/simple_market_maker.rs | 2 +- mm2src/mm2_main/src/lp_swap.rs | 21 ++- mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs | 5 +- mm2src/mm2_main/src/lp_swap/swap_v2_common.rs | 1 + mm2src/mm2_main/src/lp_swap/swap_watcher.rs | 8 ++ mm2src/mm2_main/src/lp_swap/taker_swap.rs | 67 ++++++--- mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs | 5 +- mm2src/mm2_main/src/lp_wallet.rs | 1 + .../src/lp_wallet/mnemonics_storage.rs | 1 + .../src/lp_wallet/mnemonics_wasm_db.rs | 1 + .../src/rpc/dispatcher/dispatcher_legacy.rs | 9 +- .../mm2_main/src/rpc/lp_commands/lr_swap.rs | 18 +-- .../src/rpc/lp_commands/lr_swap/lr_impl.rs | 7 +- .../src/rpc/lp_commands/lr_swap/types.rs | 3 + .../src/rpc/lp_commands/one_inch/errors.rs | 1 + mm2src/mm2_main/src/rpc/lp_commands/trezor.rs | 1 + .../src/rpc/streaming_activations/balance.rs | 1 + .../src/rpc/streaming_activations/disable.rs | 1 + .../streaming_activations/fee_estimation.rs | 1 + .../rpc/streaming_activations/heartbeat.rs | 1 + .../src/rpc/streaming_activations/network.rs | 1 + .../rpc/streaming_activations/orderbook.rs | 1 + .../src/rpc/streaming_activations/orders.rs | 4 +- .../src/rpc/streaming_activations/swaps.rs | 7 +- .../rpc/streaming_activations/tx_history.rs | 1 + .../mm2_main/src/rpc/wc_commands/sessions.rs | 6 +- .../tests/docker_tests/docker_tests_common.rs | 14 +- .../tests/docker_tests/docker_tests_inner.rs | 2 +- .../tests/docker_tests/eth_docker_tests.rs | 6 +- mm2src/mm2_main/tests/docker_tests/mod.rs | 1 + .../tests/docker_tests/qrc20_tests.rs | 3 +- .../tests/docker_tests/swap_watcher_tests.rs | 6 +- .../tests/docker_tests/z_coin_docker_tests.rs | 2 +- mm2src/mm2_main/tests/docker_tests_main.rs | 6 +- .../mm2_main/tests/docker_tests_sia_unique.rs | 10 +- .../tests/mm2_tests/mm2_tests_inner.rs | 11 +- mm2src/mm2_main/tests/mm2_tests/mod.rs | 16 +-- mm2src/mm2_metamask/src/metamask.rs | 3 +- mm2src/mm2_metrics/src/mm_metrics.rs | 3 +- mm2src/mm2_net/src/wasm/wasm_ws.rs | 7 +- mm2src/mm2_number/src/big_int_str.rs | 2 +- mm2src/mm2_number/src/mm_number.rs | 8 +- mm2src/mm2_p2p/src/behaviours/mod.rs | 2 +- mm2src/mm2_p2p/src/lib.rs | 2 +- .../src/storable_state_machine.rs | 5 +- mm2src/trading_api/src/one_inch_api/client.rs | 5 +- .../src/one_inch_api/portfolio_types.rs | 19 +-- mm2src/trezor/src/error.rs | 2 +- mm2src/trezor/src/proto/messages_bitcoin.rs | 6 +- mm2src/trezor/src/response.rs | 8 +- mm2src/trezor/src/utxo/sign_utxo.rs | 32 ++--- rust-toolchain.toml | 2 +- 208 files changed, 772 insertions(+), 684 deletions(-) diff --git a/.github/workflows/dev-build.yml b/.github/workflows/dev-build.yml index 0849cca89a..5eccea1ea4 100644 --- a/.github/workflows/dev-build.yml +++ b/.github/workflows/dev-build.yml @@ -29,8 +29,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 - name: Install build deps uses: ./.github/actions/deps-install @@ -92,8 +92,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 rustup target add x86_64-apple-darwin - name: Install build deps @@ -144,8 +144,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 rustup target add aarch64-apple-darwin - name: Install build deps @@ -196,8 +196,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 - name: Install build deps uses: ./.github/actions/deps-install @@ -247,8 +247,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 rustup target add x86_64-apple-darwin - name: Install build deps @@ -314,8 +314,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 rustup target add wasm32-unknown-unknown - name: Install wasm-pack @@ -365,8 +365,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 rustup target add aarch64-apple-ios - name: Install build deps @@ -427,8 +427,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 rustup target add aarch64-linux-android - name: Install build deps @@ -494,8 +494,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 rustup target add armv7-linux-androideabi - name: Install build deps diff --git a/.github/workflows/fmt-and-lint.yml b/.github/workflows/fmt-and-lint.yml index 27e7f0cb85..8308def3fc 100644 --- a/.github/workflows/fmt-and-lint.yml +++ b/.github/workflows/fmt-and-lint.yml @@ -18,8 +18,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal --component rustfmt,clippy - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal --component rustfmt,clippy + rustup default nightly-2025-01-03 - name: Install build deps uses: ./.github/actions/deps-install @@ -45,8 +45,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal --component clippy - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal --component clippy + rustup default nightly-2025-01-03 rustup target add wasm32-unknown-unknown - name: Install build deps diff --git a/.github/workflows/release-build.yml b/.github/workflows/release-build.yml index 75e9262b55..04fc4ae26b 100644 --- a/.github/workflows/release-build.yml +++ b/.github/workflows/release-build.yml @@ -29,8 +29,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 - name: Install build deps uses: ./.github/actions/deps-install @@ -87,8 +87,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 - name: Install build deps uses: ./.github/actions/deps-install @@ -135,8 +135,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 rustup target add aarch64-apple-darwin - name: Install build deps @@ -184,8 +184,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 - name: Install build deps uses: ./.github/actions/deps-install @@ -232,8 +232,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 rustup target add x86_64-apple-darwin - name: Install build deps @@ -296,8 +296,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 rustup target add wasm32-unknown-unknown - name: Install wasm-pack @@ -344,8 +344,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 rustup target add aarch64-apple-ios - name: Install build deps @@ -403,8 +403,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 rustup target add aarch64-linux-android - name: Install build deps @@ -467,8 +467,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 rustup target add armv7-linux-androideabi - name: Install build deps diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bc242f6547..a01960da73 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,8 +25,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 - name: Install build deps uses: ./.github/actions/deps-install @@ -53,8 +53,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 - name: Install build deps uses: ./.github/actions/deps-install @@ -81,8 +81,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 - name: Install build deps uses: ./.github/actions/deps-install @@ -109,8 +109,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 - name: Install build deps uses: ./.github/actions/deps-install @@ -138,8 +138,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 - name: Install build deps uses: ./.github/actions/deps-install @@ -170,8 +170,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 - name: Install build deps uses: ./.github/actions/deps-install @@ -206,8 +206,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 - name: Install build deps uses: ./.github/actions/deps-install @@ -235,8 +235,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal - rustup default nightly-2023-06-01 + rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal + rustup default nightly-2025-01-03 rustup target add wasm32-unknown-unknown - name: Install build deps diff --git a/Cargo.lock b/Cargo.lock index 639515ccdb..ee1c7cb656 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "Inflector" @@ -70,9 +70,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom 0.2.9", "once_cell", @@ -81,13 +81,14 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if 1.0.0", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -242,9 +243,9 @@ checksum = "c17772156ef2829aadc587461c7753af20b7e8db1529bc66855add962a3b35d3" [[package]] name = "async-trait" -version = "0.1.76" +version = "0.1.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531b97fb4cd3dfdce92c35dedbfdc1f0b9d8091c8ca943d6dae340ef5012d514" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote 1.0.37", @@ -889,7 +890,7 @@ dependencies = [ "sia-rust", "spv_validation", "tendermint-rpc", - "time 0.3.20", + "time 0.3.41", "timed-map", "tokio", "tokio-rustls 0.24.1", @@ -1049,6 +1050,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + [[package]] name = "core-foundation" version = "0.9.3" @@ -1115,9 +1122,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if 1.0.0", ] @@ -1579,15 +1586,26 @@ dependencies = [ "zeroize", ] +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", +] + [[package]] name = "derive_more" -version = "0.99.11" +version = "0.99.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" dependencies = [ + "convert_case", "proc-macro2", "quote 1.0.37", - "syn 1.0.95", + "rustc_version 0.4.0", + "syn 2.0.77", ] [[package]] @@ -2364,9 +2382,9 @@ dependencies = [ [[package]] name = "gstuff" -version = "0.7.4" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e38a0ee5e8e3debd1336135939e6615d283b8375fab2f99d8b89dba718502212" +checksum = "2c495d42791143a3be6d33e5f442c35118ffc0819bd867bfe355b4cb6bfc20ee" dependencies = [ "lazy_static", "libc", @@ -2412,7 +2430,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.8", ] [[package]] @@ -2421,7 +2439,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.8", ] [[package]] @@ -2430,7 +2448,7 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.11", ] [[package]] @@ -3784,7 +3802,7 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa8ebbd1a9e57bbab77b9facae7f5136aea44c356943bf9a198f647da64285d6" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.11", "metrics-macros", "portable-atomic", ] @@ -4549,6 +4567,12 @@ dependencies = [ "serde", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-derive" version = "0.4.2" @@ -4941,6 +4965,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc59d1bcc64fc5d021d67521f818db868368028108d37f0e98d74e33f68297b5" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.8" @@ -5426,7 +5456,7 @@ checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ "pem", "ring 0.16.20", - "time 0.3.20", + "time 0.3.41", "yasna", ] @@ -5780,7 +5810,7 @@ dependencies = [ "hashlink", "libsqlite3-sys", "smallvec 1.6.1", - "time 0.3.20", + "time 0.3.41", ] [[package]] @@ -6230,9 +6260,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.125" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "indexmap 2.2.3", "itoa", @@ -6456,7 +6486,7 @@ dependencies = [ "num-bigint", "num-traits", "thiserror", - "time 0.3.20", + "time 0.3.41", ] [[package]] @@ -6950,7 +6980,7 @@ dependencies = [ "subtle", "subtle-encoding", "tendermint-proto", - "time 0.3.20", + "time 0.3.41", "zeroize", ] @@ -6983,7 +7013,7 @@ dependencies = [ "serde", "serde_bytes", "subtle-encoding", - "time 0.3.20", + "time 0.3.41", ] [[package]] @@ -7009,7 +7039,7 @@ dependencies = [ "tendermint-config", "tendermint-proto", "thiserror", - "time 0.3.20", + "time 0.3.41", "url", "uuid", "walkdir", @@ -7080,12 +7110,15 @@ dependencies = [ [[package]] name = "time" -version = "0.3.20" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ + "deranged", "itoa", "js-sys", + "num-conv", + "powerfmt", "serde", "time-core", "time-macros", @@ -7093,16 +7126,17 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.0" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.8" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ + "num-conv", "time-core", ] @@ -8446,7 +8480,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" dependencies = [ - "time 0.3.20", + "time 0.3.41", ] [[package]] @@ -8475,7 +8509,7 @@ dependencies = [ "protobuf-codegen-pure", "rand_core 0.5.1", "subtle", - "time 0.3.20", + "time 0.3.41", "zcash_note_encryption", "zcash_primitives", ] @@ -8495,7 +8529,7 @@ dependencies = [ "protobuf", "rand_core 0.5.1", "rusqlite", - "time 0.3.20", + "time 0.3.41", "tokio", "zcash_client_backend", "zcash_extras", @@ -8513,7 +8547,7 @@ dependencies = [ "jubjub", "protobuf", "rand_core 0.5.1", - "time 0.3.20", + "time 0.3.41", "zcash_client_backend", "zcash_primitives", ] @@ -8580,11 +8614,31 @@ dependencies = [ "zcash_primitives", ] +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] diff --git a/Cargo.toml b/Cargo.toml index dd317f0d87..019d0aacc0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,7 +82,7 @@ crossbeam = "0.8" crossbeam-channel = "0.5.1" compatible-time = { version = "1.1.0", package = "web-time" } crc32fast = { version = "1.3.2", features = ["std", "nightly"] } -derive_more = "0.99" +derive_more = "0.99.20" directories = "5.0" dirs = "1" ed25519-dalek = { version = "1.0.1", features = ["serde"] } @@ -176,7 +176,7 @@ secp256k1v24 = { version = "0.24", package = "secp256k1" } serde = { version = "1", default-features = false } serde_bytes = "0.11.5" serde_derive = { version = "1", default-features = false } -serde_json = { version = "1", features = ["preserve_order", "raw_value"] } +serde_json = { version = "1.0.140", features = ["preserve_order", "raw_value"] } serde_with = "1.14.0" serde_repr = "0.1.6" serde-wasm-bindgen = "0.4.3" @@ -197,7 +197,7 @@ tendermint-rpc = { version = "0.35", default-features = false } testcontainers = "0.15.0" tiny-bip39 = "0.8.0" thiserror = "1.0.40" -time = "0.3.20" +time = "0.3.36" timed-map = { version = "1.4", features = ["rustc-hash", "serde", "wasm"] } tokio = { version = "1.20", default-features = false } tokio-rustls = { version = "0.24", default-features = false } @@ -230,7 +230,7 @@ zcash_extras = { git = "https://github.com/komodoplatform/librustzcash.git", tag zcash_primitives = { git = "https://github.com/komodoplatform/librustzcash.git", tag = "k-1.4.2", features = ["transparent-inputs"] } zcash_proofs = { git = "https://github.com/KomodoPlatform/librustzcash.git", tag = "k-1.4.2", default-features = false } x25519-dalek = { version = "2.0", features = ["static_secrets"] } -zeroize = { version = "1.5", features = ["zeroize_derive"] } +zeroize = { version = "1.8.1", features = ["zeroize_derive"] } [profile.release] debug = 0 diff --git a/clippy.toml b/clippy.toml index 068d7e886b..7494d2e44a 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1,4 +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 +reason = "Use the default KDF async executor." diff --git a/mm2src/coins/coin_balance.rs b/mm2src/coins/coin_balance.rs index 86db6c9d7c..5c5476f58a 100644 --- a/mm2src/coins/coin_balance.rs +++ b/mm2src/coins/coin_balance.rs @@ -6,6 +6,7 @@ use crate::{BalanceError, BalanceResult, CoinBalance, CoinBalanceMap, CoinWithDe use async_trait::async_trait; use common::log::{debug, info}; use crypto::{Bip44Chain, RpcDerivationPath}; +use derive_more::Display; use mm2_err_handle::prelude::*; use mm2_number::BigDecimal; #[cfg(test)] use mocktopus::macros::*; diff --git a/mm2src/coins/coin_errors.rs b/mm2src/coins/coin_errors.rs index 86a2c0da00..c8601a7f6b 100644 --- a/mm2src/coins/coin_errors.rs +++ b/mm2src/coins/coin_errors.rs @@ -2,6 +2,7 @@ use crate::eth::eth_swap_v2::{PrepareTxDataError, ValidatePaymentV2Err}; use crate::eth::nft_swap_v2::errors::{Erc721FunctionError, HtlcParamsError}; use crate::eth::{EthAssocTypesError, EthNftAssocTypesError, Web3RpcError}; use crate::{utxo::rpc_clients::UtxoRpcError, NumConversError, UnexpectedDerivationMethod}; +use derive_more::Display; use enum_derives::EnumFromStringify; use futures01::Future; use mm2_err_handle::prelude::MmError; diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 9483cf914e..ba62d22b55 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -2766,8 +2766,8 @@ type EthTxFut = Box + Sen /// A `nonce_lock` is returned so that the caller doesn't release it until the transaction is sent and the /// address nonce is updated on RPC nodes. #[allow(clippy::too_many_arguments)] -async fn sign_transaction_with_keypair<'a>( - coin: &'a EthCoin, +async fn sign_transaction_with_keypair( + coin: &EthCoin, key_pair: &KeyPair, value: U256, action: Action, @@ -5742,7 +5742,7 @@ impl EthCoin { let nonces: Vec<_> = join_all(futures) .await .into_iter() - .zip(web3_instances.into_iter()) + .zip(web3_instances) .filter_map(|(nonce_res, instance)| match nonce_res { Ok(n) => Some((n, instance)), Err(e) => { @@ -6131,7 +6131,7 @@ impl TryToAddress for [u8] { fn try_to_address(&self) -> Result { (&self).try_to_address() } } -impl<'a> TryToAddress for &'a [u8] { +impl TryToAddress for &[u8] { fn try_to_address(&self) -> Result { if self.len() != Address::len_bytes() { return ERR!( @@ -6502,7 +6502,7 @@ pub async fn eth_coin_from_conf_and_request( } // Convert `PrivKeyBuildPolicy` to `EthPrivKeyBuildPolicy` if it's possible. - let priv_key_policy = try_s!(EthPrivKeyBuildPolicy::try_from(priv_key_policy)); + let priv_key_policy = From::from(priv_key_policy); let mut urls: Vec = try_s!(json::from_value(req["urls"].clone())); if urls.is_empty() { @@ -7223,7 +7223,7 @@ impl IguanaBalanceOps for EthCoin { let token_balances = self.get_tokens_balance_list().await?; let mut balances = CoinBalanceMap::new(); balances.insert(self.ticker().to_string(), platform_balance); - balances.extend(token_balances.into_iter()); + balances.extend(token_balances); Ok(balances) } } diff --git a/mm2src/coins/eth/eth_balance_events.rs b/mm2src/coins/eth/eth_balance_events.rs index 7ff25321b0..c47721be06 100644 --- a/mm2src/coins/eth/eth_balance_events.rs +++ b/mm2src/coins/eth/eth_balance_events.rs @@ -204,7 +204,7 @@ impl EventStreamer for EthBalanceEventStreamer { })); cache .entry(res.ticker.clone()) - .or_insert_with(HashMap::new) + .or_default() .insert(res.address, res.balance); }, Err(err) => { diff --git a/mm2src/coins/eth/eth_swap_v2/eth_taker_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2/eth_taker_swap_v2.rs index 3792e12526..a89ba16f57 100644 --- a/mm2src/coins/eth/eth_swap_v2/eth_taker_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2/eth_taker_swap_v2.rs @@ -6,6 +6,7 @@ use crate::eth::{decode_contract_call, get_function_input_data, wei_from_big_dec ValidateSwapV2TxResult, ValidateTakerFundingArgs, TAKER_SWAP_V2}; use crate::{FindPaymentSpendError, FundingTxSpend, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, SearchForFundingSpendErr}; +use derive_more::Display; use enum_derives::EnumFromStringify; use ethabi::{Contract, Function, Token}; use ethcore_transaction::Action; diff --git a/mm2src/coins/eth/eth_swap_v2/mod.rs b/mm2src/coins/eth/eth_swap_v2/mod.rs index eb23fd667d..4a132b091b 100644 --- a/mm2src/coins/eth/eth_swap_v2/mod.rs +++ b/mm2src/coins/eth/eth_swap_v2/mod.rs @@ -3,6 +3,7 @@ use crate::{FindPaymentSpendError, MarketCoinOps}; use common::executor::Timer; use common::log::{error, info}; use common::now_sec; +use derive_more::Display; use enum_derives::EnumFromStringify; use ethabi::{Contract, Token}; use ethcore_transaction::SignedTransaction as SignedEthTx; @@ -202,7 +203,7 @@ fn validate_amount(trading_amount: &BigDecimal) -> Result<(), String> { Ok(()) } -fn check_decoded_length(decoded: &Vec, expected_len: usize) -> Result<(), PrepareTxDataError> { +fn check_decoded_length(decoded: &[Token], expected_len: usize) -> Result<(), PrepareTxDataError> { if decoded.len() != expected_len { return Err(PrepareTxDataError::Internal(format!( "Invalid number of tokens in decoded. Expected {}, found {}", diff --git a/mm2src/coins/eth/eth_tests.rs b/mm2src/coins/eth/eth_tests.rs index 7cde52e740..b844b85863 100644 --- a/mm2src/coins/eth/eth_tests.rs +++ b/mm2src/coins/eth/eth_tests.rs @@ -9,7 +9,6 @@ cfg_native!( use common::{now_sec, block_on_f01}; use ethkey::{Generator, Random}; - use futures_util::future; use mm2_test_helpers::for_tests::{ETH_MAINNET_CHAIN_ID, ETH_MAINNET_NODES, ETH_SEPOLIA_CHAIN_ID, ETH_SEPOLIA_NODES, ETH_SEPOLIA_TOKEN_CONTRACT}; use mocktopus::mocking::*; @@ -165,6 +164,8 @@ fn test_wei_from_big_decimal() { #[cfg(not(target_arch = "wasm32"))] #[test] fn test_wait_for_payment_spend_timeout() { + use futures::future; + const TAKER_PAYMENT_SPEND_SEARCH_INTERVAL: f64 = 1.; EthCoin::events_from_block.mock_safe(|_, _, _, _, _, _| MockResult::Return(Box::pin(future::ok(vec![])))); diff --git a/mm2src/coins/eth/eth_utils.rs b/mm2src/coins/eth/eth_utils.rs index e6a191d534..87841070f6 100644 --- a/mm2src/coins/eth/eth_utils.rs +++ b/mm2src/coins/eth/eth_utils.rs @@ -55,7 +55,7 @@ pub fn u256_to_big_decimal(number: U256, decimals: u8) -> NumConversResult NumConversResult { let mut amount = amount.to_string(); - let dot = amount.find(|c| c == '.'); + let dot = amount.find('.'); let decimals = decimals as usize; if let Some(index) = dot { let mut fractional = amount.split_off(index); diff --git a/mm2src/coins/eth/fee_estimation/eip1559/mod.rs b/mm2src/coins/eth/fee_estimation/eip1559/mod.rs index b4c3ffbfbc..e9a63faf5b 100644 --- a/mm2src/coins/eth/fee_estimation/eip1559/mod.rs +++ b/mm2src/coins/eth/fee_estimation/eip1559/mod.rs @@ -19,13 +19,13 @@ pub enum EstimationSource { Blocknative, } -impl ToString for EstimationSource { - fn to_string(&self) -> String { +impl std::fmt::Display for EstimationSource { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - EstimationSource::Empty => "empty".into(), - EstimationSource::Simple => "simple".into(), - EstimationSource::Infura => "infura".into(), - EstimationSource::Blocknative => "blocknative".into(), + EstimationSource::Empty => write!(f, "empty"), + EstimationSource::Simple => write!(f, "simple"), + EstimationSource::Infura => write!(f, "infura"), + EstimationSource::Blocknative => write!(f, "blocknative"), } } } diff --git a/mm2src/coins/eth/fee_estimation/rpc.rs b/mm2src/coins/eth/fee_estimation/rpc.rs index 6fb3b84498..0d8deab749 100644 --- a/mm2src/coins/eth/fee_estimation/rpc.rs +++ b/mm2src/coins/eth/fee_estimation/rpc.rs @@ -2,6 +2,7 @@ use super::eth_fee_events::EstimatorType; use super::ser::FeePerGasEstimated; use crate::{lp_coinfind, MmCoinEnum}; use common::HttpStatusCode; +use derive_more::Display; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::mm_error::{MmError, MmResult}; diff --git a/mm2src/coins/eth/nft_swap_v2/errors.rs b/mm2src/coins/eth/nft_swap_v2/errors.rs index 02cb3c7626..7649906252 100644 --- a/mm2src/coins/eth/nft_swap_v2/errors.rs +++ b/mm2src/coins/eth/nft_swap_v2/errors.rs @@ -1,4 +1,5 @@ pub(crate) use crate::eth::eth_swap_v2::PrepareTxDataError; +use derive_more::Display; use enum_derives::EnumFromStringify; #[derive(Debug, Display)] diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 1ab2590644..30c5747269 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -252,9 +252,7 @@ fn extract_pubkey_from_signature( pub(crate) fn recover(signature: &Signature, message: &Message) -> Result { let recovery_id = { - let recovery_id = signature[64] - .checked_sub(27) - .ok_or_else(|| ethkey::Error::InvalidSignature)?; + let recovery_id = signature[64].checked_sub(27).ok_or(ethkey::Error::InvalidSignature)?; RecoveryId::from_i32(recovery_id as i32)? }; let sig = RecoverableSignature::from_compact(&signature[0..64], recovery_id)?; diff --git a/mm2src/coins/eth/web3_transport/mod.rs b/mm2src/coins/eth/web3_transport/mod.rs index e064e6025a..2d685b1bb5 100644 --- a/mm2src/coins/eth/web3_transport/mod.rs +++ b/mm2src/coins/eth/web3_transport/mod.rs @@ -111,10 +111,12 @@ impl From for Web3Transport { #[derive(Debug, Deserialize)] pub struct FeeHistoryResult { + #[expect(dead_code)] #[serde(rename = "oldestBlock")] pub oldest_block: U256, #[serde(rename = "baseFeePerGas")] pub base_fee_per_gas: Vec, + #[expect(dead_code)] #[serde(rename = "gasUsedRatio")] pub gas_used_ratio: Vec, #[serde(rename = "reward")] diff --git a/mm2src/coins/hd_wallet/errors.rs b/mm2src/coins/hd_wallet/errors.rs index 89ab2002de..e67ce0867e 100644 --- a/mm2src/coins/hd_wallet/errors.rs +++ b/mm2src/coins/hd_wallet/errors.rs @@ -2,6 +2,7 @@ use super::{HDConfirmAddressError, HDWalletStorageError}; use bip32::Error as Bip32Error; use crypto::trezor::{TrezorError, TrezorProcessingError}; use crypto::{Bip32DerPathError, Bip44Chain, CryptoCtxError, HwError, HwProcessingError, StandardHDPathError, XpubError}; +use derive_more::Display; use rpc_task::RpcTaskError; #[derive(Debug, Display, Serialize, SerializeErrorType)] diff --git a/mm2src/coins/lightning.rs b/mm2src/coins/lightning.rs index c5ae7501b3..08779f12be 100644 --- a/mm2src/coins/lightning.rs +++ b/mm2src/coins/lightning.rs @@ -38,6 +38,7 @@ use common::executor::{AbortableSystem, AbortedError, Timer}; use common::log::{error, info, LogOnError, LogState}; use common::{async_blocking, get_local_duration_since_epoch, log, now_sec, Future01CompatExt, PagingOptionsEnum}; use db_common::sqlite::rusqlite::Error as SqlError; +use derive_more::Display; use futures::{FutureExt, TryFutureExt}; use futures01::Future; use keys::{hash::H256, CompactSignature, KeyPair, Private, Public}; diff --git a/mm2src/coins/lightning/ln_events.rs b/mm2src/coins/lightning/ln_events.rs index d6c78f9ad9..33365a70dd 100644 --- a/mm2src/coins/lightning/ln_events.rs +++ b/mm2src/coins/lightning/ln_events.rs @@ -9,6 +9,7 @@ use common::executor::{AbortSettings, SpawnAbortable, SpawnFuture, Timer}; use common::log::{error, info}; use common::{new_uuid, now_sec_i64}; use core::time::Duration; +use derive_more::Display; use futures::compat::Future01CompatExt; use lightning::chain::chaininterface::{ConfirmationTarget, FeeEstimator}; use lightning::chain::keysinterface::SpendableOutputDescriptor; @@ -16,7 +17,7 @@ use lightning::util::events::{Event, EventHandler, PaymentPurpose}; use rand::Rng; use script::{Builder, SignatureVersion}; use secp256k1v24::Secp256k1; -use std::convert::{TryFrom, TryInto}; +use std::convert::TryInto; use std::sync::Arc; use utxo_signer::with_key_pair::sign_tx; @@ -181,8 +182,6 @@ pub async fn init_abortable_events(platform: Arc, db: SqliteLightningD pub enum SignFundingTransactionError { #[display(fmt = "Internal error: {}", _0)] Internal(String), - #[display(fmt = "Error converting transaction: {}", _0)] - ConvertTxErr(String), #[display(fmt = "Error signing transaction: {}", _0)] TxSignFailed(String), } @@ -222,7 +221,7 @@ async fn sign_funding_transaction( ) .map_err(|e| SignFundingTransactionError::TxSignFailed(e.to_string()))?; - Transaction::try_from(signed).map_err(|e| SignFundingTransactionError::ConvertTxErr(e.to_string())) + Ok(Transaction::from(signed)) } async fn save_channel_closing_details( diff --git a/mm2src/coins/lightning/ln_serialization.rs b/mm2src/coins/lightning/ln_serialization.rs index 37ece14bee..5e04f5cb41 100644 --- a/mm2src/coins/lightning/ln_serialization.rs +++ b/mm2src/coins/lightning/ln_serialization.rs @@ -27,7 +27,7 @@ impl<'de> de::Deserialize<'de> for NodeAddress { fn deserialize>(deserializer: D) -> Result { struct NodeAddressVisitor; - impl<'de> de::Visitor<'de> for NodeAddressVisitor { + impl de::Visitor<'_> for NodeAddressVisitor { type Value = NodeAddress; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "pubkey@host:port") } @@ -82,7 +82,7 @@ impl<'de> de::Deserialize<'de> for PublicKeyForRPC { fn deserialize>(deserializer: D) -> Result { struct PublicKeyForRPCVisitor; - impl<'de> de::Visitor<'de> for PublicKeyForRPCVisitor { + impl de::Visitor<'_> for PublicKeyForRPCVisitor { type Value = PublicKeyForRPC; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "a public key") } diff --git a/mm2src/coins/lightning/ln_sql.rs b/mm2src/coins/lightning/ln_sql.rs index 0062479ebf..59af04a698 100644 --- a/mm2src/coins/lightning/ln_sql.rs +++ b/mm2src/coins/lightning/ln_sql.rs @@ -1084,14 +1084,7 @@ mod tests { rng.fill_bytes(&mut bytes); Some(hex::encode(bytes)) }, - closure_reason: { - Some( - rng.sample_iter(&Alphanumeric) - .take(30) - .map(char::from) - .collect::(), - ) - }, + closure_reason: { Some(rng.sample_iter(&Alphanumeric).take(30).collect::()) }, claiming_tx: { rng.fill_bytes(&mut bytes); Some(hex::encode(bytes)) @@ -1132,7 +1125,7 @@ mod tests { } else { HTLCStatus::Failed }; - let description: String = rng.sample_iter(&Alphanumeric).take(30).map(char::from).collect(); + let description: String = rng.sample_iter(&Alphanumeric).take(30).collect(); let info = PaymentInfo { payment_hash: { rng.fill_bytes(&mut bytes); @@ -1442,8 +1435,8 @@ mod tests { let result = block_on(db.get_payments_by_filter(Some(filter.clone()), paging.clone(), limit)).unwrap(); let expected_payments_vec: Vec = payments .iter() + .filter(|&p| p.payment_type == PaymentType::InboundPayment) .cloned() - .filter(|p| p.payment_type == PaymentType::InboundPayment) .collect(); let expected_payments = if expected_payments_vec.len() > 10 { expected_payments_vec[..10].to_vec() @@ -1459,8 +1452,8 @@ mod tests { let result = block_on(db.get_payments_by_filter(Some(filter.clone()), paging.clone(), limit)).unwrap(); let expected_payments_vec: Vec = expected_payments_vec .iter() + .filter(|&p| p.status == HTLCStatus::Succeeded) .cloned() - .filter(|p| p.status == HTLCStatus::Succeeded) .collect(); let expected_payments = if expected_payments_vec.len() > 10 { expected_payments_vec[..10].to_vec() @@ -1480,8 +1473,8 @@ mod tests { let result = block_on(db.get_payments_by_filter(Some(filter), paging, limit)).unwrap(); let expected_payments_vec: Vec = payments .iter() + .filter(|&p| p.description.contains(substr)) .cloned() - .filter(|p| p.description.contains(substr)) .collect(); let expected_payments = if expected_payments_vec.len() > 10 { expected_payments_vec[..10].to_vec() @@ -1608,7 +1601,7 @@ mod tests { let result = block_on(db.get_closed_channels_by_filter(Some(filter.clone()), paging.clone(), limit)).unwrap(); let expected_channels_vec: Vec = - channels.iter().cloned().filter(|chan| chan.is_outbound).collect(); + channels.iter().filter(|&chan| chan.is_outbound).cloned().collect(); let expected_channels = if expected_channels_vec.len() > 10 { expected_channels_vec[..10].to_vec() } else { @@ -1623,8 +1616,8 @@ mod tests { let result = block_on(db.get_closed_channels_by_filter(Some(filter.clone()), paging.clone(), limit)).unwrap(); let expected_channels_vec: Vec = expected_channels_vec .iter() + .filter(|&chan| chan.is_public) .cloned() - .filter(|chan| chan.is_public) .collect(); let expected_channels = if expected_channels_vec.len() > 10 { expected_channels_vec[..10].to_vec() @@ -1642,8 +1635,8 @@ mod tests { let result = block_on(db.get_closed_channels_by_filter(Some(filter), paging, limit)).unwrap(); let expected_channels_vec: Vec = channels .iter() + .filter(|&chan| chan.channel_id == channel_id) .cloned() - .filter(|chan| chan.channel_id == channel_id) .collect(); let expected_channels = if expected_channels_vec.len() > 10 { expected_channels_vec[..10].to_vec() diff --git a/mm2src/coins/lightning/ln_utils.rs b/mm2src/coins/lightning/ln_utils.rs index 93c86c8e5d..59f6e0f6eb 100644 --- a/mm2src/coins/lightning/ln_utils.rs +++ b/mm2src/coins/lightning/ln_utils.rs @@ -8,6 +8,7 @@ use bitcoin::hash_types::BlockHash; use bitcoin_hashes::{sha256d, Hash}; use common::executor::SpawnFuture; use common::log::LogState; +use derive_more::Display; use lightning::chain::keysinterface::{InMemorySigner, KeysManager}; use lightning::chain::{chainmonitor, BestBlock, ChannelMonitorUpdateStatus, Watch}; use lightning::ln::channelmanager::{ChainParameters, ChannelManagerReadArgs, PaymentId, PaymentSendFailure, diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index a3d9c8f856..b35d8ae37d 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -24,14 +24,14 @@ forgetting_references, forgetting_copy_types, clippy::swap_ptr_to_ref, - clippy::forget_non_drop + clippy::forget_non_drop, + clippy::doc_lazy_continuation, + clippy::needless_lifetimes // mocktopus requires explicit lifetimes )] #![allow(uncommon_codepoints)] -// #![feature(integer_atomics)] -#![feature(async_closure)] +#![feature(hash_raw_entry)] #![feature(stmt_expr_attributes)] #![feature(result_flattening)] -#![feature(local_key_cell_methods)] // for tests #[macro_use] extern crate common; #[macro_use] extern crate gstuff; @@ -846,7 +846,7 @@ pub enum SwapTxTypeWithSecretHash<'a> { }, } -impl<'a> SwapTxTypeWithSecretHash<'a> { +impl SwapTxTypeWithSecretHash<'_> { pub fn redeem_script(&self, time_lock: u32, my_public: &Public, other_public: &Public) -> Script { match self { SwapTxTypeWithSecretHash::TakerOrMakerPayment { maker_secret_hash } => { @@ -2518,7 +2518,7 @@ impl TransactionDetails { pub fn should_update_block_height(&self) -> bool { // checking for std::u64::MAX because there was integer overflow // in case of electrum returned -1 so there could be records with MAX confirmations - self.block_height == 0 || self.block_height == std::u64::MAX + self.block_height == 0 || self.block_height == u64::MAX } /// Whether the transaction timestamp should be updated (when tx is confirmed) @@ -2562,7 +2562,7 @@ impl BalanceObjectOps for CoinBalanceMap { fn add(&mut self, other: Self) { for (ticker, balance) in other { - let total_balance = self.entry(ticker).or_insert_with(CoinBalance::default); + let total_balance = self.entry(ticker).or_default(); *total_balance += balance; } } @@ -3802,7 +3802,7 @@ pub enum DexFee { } impl DexFee { - const DEX_FEE_SHARE: &str = "0.75"; + const DEX_FEE_SHARE: &'static str = "0.75"; /// Recreates a `DexFee` from separate fields (usually stored in db). #[cfg(any(test, feature = "for-tests"))] @@ -4788,12 +4788,12 @@ pub enum RpcClientType { Ethereum, } -impl ToString for RpcClientType { - fn to_string(&self) -> String { +impl std::fmt::Display for RpcClientType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - RpcClientType::Native => "native".into(), - RpcClientType::Electrum => "electrum".into(), - RpcClientType::Ethereum => "ethereum".into(), + RpcClientType::Native => write!(f, "native"), + RpcClientType::Electrum => write!(f, "electrum"), + RpcClientType::Ethereum => write!(f, "ethereum"), } } } @@ -5225,11 +5225,9 @@ pub async fn remove_delegation(ctx: MmArc, req: RemoveDelegateRequest) -> Delega None => match coin { MmCoinEnum::QtumCoin(qtum) => qtum.remove_delegation().compat().await, - _ => { - return MmError::err(DelegationError::CoinDoesntSupportDelegation { - coin: coin.ticker().to_string(), - }) - }, + _ => MmError::err(DelegationError::CoinDoesntSupportDelegation { + coin: coin.ticker().to_string(), + }), }, } } diff --git a/mm2src/coins/nft/nft_structs.rs b/mm2src/coins/nft/nft_structs.rs index 34be85f2b5..cc2223da2b 100644 --- a/mm2src/coins/nft/nft_structs.rs +++ b/mm2src/coins/nft/nft_structs.rs @@ -1,4 +1,5 @@ use common::ten; +use derive_more::Display; use enum_derives::EnumVariantList; use ethereum_types::Address; use mm2_core::mm_ctx::{from_ctx, MmArc}; diff --git a/mm2src/coins/nft/nft_tests.rs b/mm2src/coins/nft/nft_tests.rs index b5659ae52e..c3574de55b 100644 --- a/mm2src/coins/nft/nft_tests.rs +++ b/mm2src/coins/nft/nft_tests.rs @@ -216,7 +216,7 @@ cross_test!(test_nft_list, { .await .unwrap(); assert_eq!(nft_list.nfts.len(), 1); - let nft = nft_list.nfts.get(0).unwrap(); + let nft = nft_list.nfts.first().unwrap(); assert_eq!(nft.block_number, 28056721); assert_eq!(nft_list.skipped, 2); assert_eq!(nft_list.total, 4); @@ -466,7 +466,7 @@ cross_test!(test_add_get_transfers, { .get_transfers_by_token_addr_id(chain, TOKEN_ADD.to_string(), token_id) .await .unwrap() - .get(0) + .first() .unwrap() .clone(); assert_eq!(transfer1.block_number, 28056721); @@ -513,7 +513,7 @@ cross_test!(test_transfer_history, { .await .unwrap(); assert_eq!(transfer_history.transfer_history.len(), 1); - let transfer = transfer_history.transfer_history.get(0).unwrap(); + let transfer = transfer_history.transfer_history.first().unwrap(); assert_eq!(transfer.block_number, 28056721); assert_eq!(transfer_history.skipped, 2); assert_eq!(transfer_history.total, 4); @@ -559,7 +559,7 @@ cross_test!(test_transfer_history_filters, { .await .unwrap(); assert_eq!(transfer_history.transfer_history.len(), 4); - let transfer = transfer_history.transfer_history.get(0).unwrap(); + let transfer = transfer_history.transfer_history.first().unwrap(); assert_eq!(transfer.block_number, 28056726); let transfer_history1 = storage @@ -567,7 +567,7 @@ cross_test!(test_transfer_history_filters, { .await .unwrap(); assert_eq!(transfer_history1.transfer_history.len(), 1); - let transfer1 = transfer_history1.transfer_history.get(0).unwrap(); + let transfer1 = transfer_history1.transfer_history.first().unwrap(); assert_eq!(transfer1.block_number, 25919780); let transfer_history2 = storage @@ -575,7 +575,7 @@ cross_test!(test_transfer_history_filters, { .await .unwrap(); assert_eq!(transfer_history2.transfer_history.len(), 2); - let transfer_0 = transfer_history2.transfer_history.get(0).unwrap(); + let transfer_0 = transfer_history2.transfer_history.first().unwrap(); assert_eq!(transfer_0.block_number, 28056721); let transfer_1 = transfer_history2.transfer_history.get(1).unwrap(); assert_eq!(transfer_1.block_number, 25919780); @@ -611,7 +611,7 @@ cross_test!(test_get_update_transfer_meta, { .get_transfers_by_token_addr_id(chain, token_add, Default::default()) .await .unwrap(); - let transfer_upd = transfer_upd.get(0).unwrap(); + let transfer_upd = transfer_upd.first().unwrap(); assert_eq!(transfer_upd.token_name, Some("Tiki box".to_string())); assert!(transfer_upd.common.possible_spam); }); diff --git a/mm2src/coins/nft/storage/mod.rs b/mm2src/coins/nft/storage/mod.rs index de61d04a40..b888cbdda9 100644 --- a/mm2src/coins/nft/storage/mod.rs +++ b/mm2src/coins/nft/storage/mod.rs @@ -67,6 +67,7 @@ pub trait NftListStorageOps { scanned_block: u64, ) -> MmResult; + #[allow(dead_code)] async fn get_nft_amount( &self, chain: &Chain, @@ -88,6 +89,7 @@ pub trait NftListStorageOps { async fn update_nft_amount_and_block_number(&self, chain: &Chain, nft: Nft) -> MmResult<(), Self::Error>; + #[allow(dead_code)] /// `get_nfts_by_token_address` function returns list of NFTs which have specified token address. async fn get_nfts_by_token_address(&self, chain: Chain, token_address: String) -> MmResult, Self::Error>; @@ -149,6 +151,7 @@ pub trait NftTransferHistoryStorageOps { from_block: u64, ) -> MmResult, Self::Error>; + #[allow(dead_code)] async fn get_transfers_by_token_addr_id( &self, chain: Chain, @@ -156,6 +159,7 @@ pub trait NftTransferHistoryStorageOps { token_id: BigUint, ) -> MmResult, Self::Error>; + #[allow(dead_code)] async fn get_transfer_by_tx_hash_log_index_token_id( &self, chain: &Chain, @@ -176,6 +180,7 @@ pub trait NftTransferHistoryStorageOps { async fn get_transfers_with_empty_meta(&self, chain: Chain) -> MmResult, Self::Error>; /// `get_transfers_by_token_address` function returns list of NFT transfers which have specified token address. + #[allow(dead_code)] async fn get_transfers_by_token_address( &self, chain: Chain, @@ -245,6 +250,7 @@ pub(crate) struct TransferDetailsJson { pub(crate) fee_details: Option, } +#[cfg_attr(target_arch = "wasm32", expect(dead_code))] #[async_trait] pub trait NftMigrationOps { type Error: NftStorageError; diff --git a/mm2src/coins/nft/storage/wasm/mod.rs b/mm2src/coins/nft/storage/wasm/mod.rs index 05c7bac5d9..e10f04a8c6 100644 --- a/mm2src/coins/nft/storage/wasm/mod.rs +++ b/mm2src/coins/nft/storage/wasm/mod.rs @@ -1,4 +1,5 @@ use crate::nft::storage::NftStorageError; +use derive_more::Display; use mm2_db::indexed_db::{DbTransactionError, InitDbError}; use mm2_err_handle::prelude::*; diff --git a/mm2src/coins/nft/storage/wasm/wasm_storage.rs b/mm2src/coins/nft/storage/wasm/wasm_storage.rs index 47e16870e0..7d5c595795 100644 --- a/mm2src/coins/nft/storage/wasm/wasm_storage.rs +++ b/mm2src/coins/nft/storage/wasm/wasm_storage.rs @@ -114,8 +114,8 @@ impl NftTransferHistoryFilters { } fn is_date_match(&self, transfer: &NftTransferHistory) -> bool { - self.from_date.map_or(true, |from| transfer.block_timestamp >= from) - && self.to_date.map_or(true, |to| transfer.block_timestamp <= to) + self.from_date.is_none_or(|from| transfer.block_timestamp >= from) + && self.to_date.is_none_or(|to| transfer.block_timestamp <= to) } fn passes_spam_filter(&self, transfer: &NftTransferHistory) -> bool { diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index d070ccfed5..02fec1b2fa 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -191,7 +191,7 @@ impl<'a> Qrc20CoinBuilder<'a> { } #[async_trait] -impl<'a> UtxoCoinBuilderCommonOps for Qrc20CoinBuilder<'a> { +impl UtxoCoinBuilderCommonOps for Qrc20CoinBuilder<'_> { fn ctx(&self) -> &MmArc { self.ctx } fn conf(&self) -> &Json { self.conf } @@ -265,16 +265,16 @@ impl<'a> UtxoCoinBuilderCommonOps for Qrc20CoinBuilder<'a> { } } -impl<'a> UtxoFieldsWithIguanaSecretBuilder for Qrc20CoinBuilder<'a> {} +impl UtxoFieldsWithIguanaSecretBuilder for Qrc20CoinBuilder<'_> {} -impl<'a> UtxoFieldsWithGlobalHDBuilder for Qrc20CoinBuilder<'a> {} +impl UtxoFieldsWithGlobalHDBuilder for Qrc20CoinBuilder<'_> {} /// Although, `Qrc20Coin` doesn't support [`PrivKeyBuildPolicy::Trezor`] yet, /// `UtxoCoinBuilder` trait requires `UtxoFieldsWithHardwareWalletBuilder` to be implemented. -impl<'a> UtxoFieldsWithHardwareWalletBuilder for Qrc20CoinBuilder<'a> {} +impl UtxoFieldsWithHardwareWalletBuilder for Qrc20CoinBuilder<'_> {} #[async_trait] -impl<'a> UtxoCoinBuilder for Qrc20CoinBuilder<'a> { +impl UtxoCoinBuilder for Qrc20CoinBuilder<'_> { type ResultCoin = Qrc20Coin; type Error = UtxoCoinBuildError; diff --git a/mm2src/coins/qrc20/history.rs b/mm2src/coins/qrc20/history.rs index e6c6eb7085..306876e687 100644 --- a/mm2src/coins/qrc20/history.rs +++ b/mm2src/coins/qrc20/history.rs @@ -558,7 +558,7 @@ impl Qrc20Coin { return Ok(HistoryMapByHash::default()); }, }; - let tx_hash_history = history_map.entry(id.tx_hash).or_insert_with(HashMap::default); + let tx_hash_history = history_map.entry(id.tx_hash).or_default(); if tx_hash_history.insert(id, tx).is_some() { ctx.log.log( "😟", diff --git a/mm2src/coins/qrc20/qrc20_tests.rs b/mm2src/coins/qrc20/qrc20_tests.rs index f4dd5a7121..79498af368 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, block_on_f01, wait_until_sec, DEX_FEE_ADDR_RAW_PUBKEY}; +use common::{block_on, block_on_f01, wait_until_sec}; use crypto::Secp256k1Secret; use itertools::Itertools; use keys::Address; @@ -315,9 +315,12 @@ fn test_wait_for_confirmations_excepted() { assert!(error.contains("Contract call failed with an error: Revert")); } +#[cfg(not(target_arch = "wasm32"))] #[test] fn test_validate_fee() { // priv_key of qXxsj5RtciAby9T7m98AgAATL4zTi4UwDG + + use common::DEX_FEE_ADDR_RAW_PUBKEY; let priv_key = [ 3, 98, 177, 3, 108, 39, 234, 144, 131, 178, 103, 103, 127, 80, 230, 166, 53, 68, 147, 215, 42, 216, 144, 72, 172, 110, 180, 13, 123, 179, 10, 49, diff --git a/mm2src/coins/qrc20/rpc_clients.rs b/mm2src/coins/qrc20/rpc_clients.rs index 4feb1848a1..4541a8cd71 100644 --- a/mm2src/coins/qrc20/rpc_clients.rs +++ b/mm2src/coins/qrc20/rpc_clients.rs @@ -421,7 +421,7 @@ impl Qrc20RpcOps for UtxoRpcClientEnum { Some(_) => return ERR!(r#"Expected Uint as "decimals" result but got {:?}"#, tokens), None => return ERR!(r#"Expected Uint as "decimals" result but got nothing"#), }; - if decimals <= (std::u8::MAX as u64) { + if decimals <= (u8::MAX as u64) { Ok(decimals as u8) } else { ERR!("decimals {} is not u8", decimals) diff --git a/mm2src/coins/qrc20/swap.rs b/mm2src/coins/qrc20/swap.rs index 18e371bbdf..58efe5b16b 100644 --- a/mm2src/coins/qrc20/swap.rs +++ b/mm2src/coins/qrc20/swap.rs @@ -22,6 +22,7 @@ pub struct Erc20PaymentDetails { } /// `receiverSpend` call details consist of values obtained from [`TransactionOutput::script_pubkey`]. +#[expect(dead_code)] #[derive(Debug)] pub struct ReceiverSpendDetails { pub swap_id: Vec, diff --git a/mm2src/coins/rpc_command/get_enabled_coins.rs b/mm2src/coins/rpc_command/get_enabled_coins.rs index d746d298df..e99ee2c19f 100644 --- a/mm2src/coins/rpc_command/get_enabled_coins.rs +++ b/mm2src/coins/rpc_command/get_enabled_coins.rs @@ -1,5 +1,6 @@ use crate::CoinsContext; use common::HttpStatusCode; +use derive_more::Display; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::MmResult; diff --git a/mm2src/coins/rpc_command/get_new_address.rs b/mm2src/coins/rpc_command/get_new_address.rs index a43225d864..71eb82304f 100644 --- a/mm2src/coins/rpc_command/get_new_address.rs +++ b/mm2src/coins/rpc_command/get_new_address.rs @@ -484,7 +484,7 @@ pub(crate) mod common_impl { }) } - pub async fn get_new_address_rpc<'a, Coin, ConfirmAddress>( + pub async fn get_new_address_rpc( coin: &Coin, params: GetNewAddressParams, confirm_address: &ConfirmAddress, diff --git a/mm2src/coins/rpc_command/init_create_account.rs b/mm2src/coins/rpc_command/init_create_account.rs index 4328e8f54a..d5a4a4e5bf 100644 --- a/mm2src/coins/rpc_command/init_create_account.rs +++ b/mm2src/coins/rpc_command/init_create_account.rs @@ -396,7 +396,7 @@ pub(crate) mod common_impl { use crate::hd_wallet::{create_new_account, ExtractExtendedPubkey, HDAccountOps, HDAccountStorageOps, HDCoinExtendedPubkey, HDCoinHDAccount, HDWalletOps}; - pub async fn init_create_new_account_rpc<'a, Coin, XPubExtractor>( + pub async fn init_create_new_account_rpc( coin: &Coin, params: CreateNewAccountParams, state: CreateAccountState, diff --git a/mm2src/coins/rpc_command/lightning/close_channel.rs b/mm2src/coins/rpc_command/lightning/close_channel.rs index cbcb237582..aabf15f9f3 100644 --- a/mm2src/coins/rpc_command/lightning/close_channel.rs +++ b/mm2src/coins/rpc_command/lightning/close_channel.rs @@ -1,5 +1,6 @@ use crate::{lp_coinfind_or_err, CoinFindError, MmCoinEnum}; use common::{async_blocking, HttpStatusCode}; +use derive_more::Display; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; diff --git a/mm2src/coins/rpc_command/lightning/connect_to_node.rs b/mm2src/coins/rpc_command/lightning/connect_to_node.rs index ab776cb49e..e365fd746a 100644 --- a/mm2src/coins/rpc_command/lightning/connect_to_node.rs +++ b/mm2src/coins/rpc_command/lightning/connect_to_node.rs @@ -4,6 +4,7 @@ use crate::lightning::ln_serialization::NodeAddress; use crate::lightning::ln_storage::LightningStorage; use crate::{lp_coinfind_or_err, CoinFindError, MmCoinEnum}; use common::HttpStatusCode; +use derive_more::Display; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; diff --git a/mm2src/coins/rpc_command/lightning/generate_invoice.rs b/mm2src/coins/rpc_command/lightning/generate_invoice.rs index 051402b44c..37ccbd4706 100644 --- a/mm2src/coins/rpc_command/lightning/generate_invoice.rs +++ b/mm2src/coins/rpc_command/lightning/generate_invoice.rs @@ -6,6 +6,7 @@ use bitcoin_hashes::Hash; use common::log::LogOnError; use common::{async_blocking, HttpStatusCode}; use db_common::sqlite::rusqlite::Error as SqlError; +use derive_more::Display; use http::StatusCode; use lightning::ln::PaymentHash; use lightning_invoice::utils::create_invoice_from_channelmanager; diff --git a/mm2src/coins/rpc_command/lightning/get_channel_details.rs b/mm2src/coins/rpc_command/lightning/get_channel_details.rs index f806c0e916..51965ae7c5 100644 --- a/mm2src/coins/rpc_command/lightning/get_channel_details.rs +++ b/mm2src/coins/rpc_command/lightning/get_channel_details.rs @@ -3,6 +3,7 @@ use crate::lightning::ln_serialization::ChannelDetailsForRPC; use crate::{lp_coinfind_or_err, CoinFindError, MmCoinEnum}; use common::HttpStatusCode; use db_common::sqlite::rusqlite::Error as SqlError; +use derive_more::Display; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; diff --git a/mm2src/coins/rpc_command/lightning/get_claimable_balances.rs b/mm2src/coins/rpc_command/lightning/get_claimable_balances.rs index 511892a1cd..a190ec4d56 100644 --- a/mm2src/coins/rpc_command/lightning/get_claimable_balances.rs +++ b/mm2src/coins/rpc_command/lightning/get_claimable_balances.rs @@ -1,6 +1,7 @@ use crate::lightning::ln_serialization::ClaimableBalance; use crate::{lp_coinfind_or_err, CoinFindError, MmCoinEnum}; use common::{async_blocking, HttpStatusCode}; +use derive_more::Display; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; diff --git a/mm2src/coins/rpc_command/lightning/get_payment_details.rs b/mm2src/coins/rpc_command/lightning/get_payment_details.rs index 7823e04b5f..be759874e3 100644 --- a/mm2src/coins/rpc_command/lightning/get_payment_details.rs +++ b/mm2src/coins/rpc_command/lightning/get_payment_details.rs @@ -3,6 +3,7 @@ use crate::lightning::ln_serialization::PaymentInfoForRPC; use crate::{lp_coinfind_or_err, CoinFindError, H256Json, MmCoinEnum}; use common::HttpStatusCode; use db_common::sqlite::rusqlite::Error as SqlError; +use derive_more::Display; use http::StatusCode; use lightning::ln::PaymentHash; use mm2_core::mm_ctx::MmArc; diff --git a/mm2src/coins/rpc_command/lightning/list_channels.rs b/mm2src/coins/rpc_command/lightning/list_channels.rs index 3c857f2e0f..3e36c2526d 100644 --- a/mm2src/coins/rpc_command/lightning/list_channels.rs +++ b/mm2src/coins/rpc_command/lightning/list_channels.rs @@ -4,6 +4,7 @@ use crate::lightning::OpenChannelsFilter; use crate::{lp_coinfind_or_err, CoinFindError, MmCoinEnum}; use common::{calc_total_pages, ten, HttpStatusCode, PagingOptionsEnum}; use db_common::sqlite::rusqlite::Error as SqlError; +use derive_more::Display; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; diff --git a/mm2src/coins/rpc_command/lightning/list_payments_by_filter.rs b/mm2src/coins/rpc_command/lightning/list_payments_by_filter.rs index 05f3a6a4f0..c025e0a30d 100644 --- a/mm2src/coins/rpc_command/lightning/list_payments_by_filter.rs +++ b/mm2src/coins/rpc_command/lightning/list_payments_by_filter.rs @@ -3,6 +3,7 @@ use crate::lightning::ln_serialization::{PaymentInfoForRPC, PaymentsFilterForRPC use crate::{lp_coinfind_or_err, CoinFindError, H256Json, MmCoinEnum}; use common::{calc_total_pages, ten, HttpStatusCode, PagingOptionsEnum}; use db_common::sqlite::rusqlite::Error as SqlError; +use derive_more::Display; use http::StatusCode; use lightning::ln::PaymentHash; use mm2_core::mm_ctx::MmArc; diff --git a/mm2src/coins/rpc_command/lightning/open_channel.rs b/mm2src/coins/rpc_command/lightning/open_channel.rs index 81622b5962..485fb93941 100644 --- a/mm2src/coins/rpc_command/lightning/open_channel.rs +++ b/mm2src/coins/rpc_command/lightning/open_channel.rs @@ -11,6 +11,7 @@ use chain::TransactionOutput; use common::log::error; use common::{async_blocking, new_uuid, HttpStatusCode}; use db_common::sqlite::rusqlite::Error as SqlError; +use derive_more::Display; use http::StatusCode; use keys::AddressHashEnum; use lightning::util::config::UserConfig; diff --git a/mm2src/coins/rpc_command/lightning/send_payment.rs b/mm2src/coins/rpc_command/lightning/send_payment.rs index 43f1e30ae5..e7318b6fdd 100644 --- a/mm2src/coins/rpc_command/lightning/send_payment.rs +++ b/mm2src/coins/rpc_command/lightning/send_payment.rs @@ -5,6 +5,7 @@ use crate::{lp_coinfind_or_err, CoinFindError, H256Json, MmCoinEnum}; use common::log::LogOnError; use common::HttpStatusCode; use db_common::sqlite::rusqlite::Error as SqlError; +use derive_more::Display; use http::StatusCode; use lightning_invoice::Invoice; use mm2_core::mm_ctx::MmArc; diff --git a/mm2src/coins/rpc_command/lightning/trusted_nodes.rs b/mm2src/coins/rpc_command/lightning/trusted_nodes.rs index 5527215def..d899169503 100644 --- a/mm2src/coins/rpc_command/lightning/trusted_nodes.rs +++ b/mm2src/coins/rpc_command/lightning/trusted_nodes.rs @@ -2,6 +2,7 @@ use crate::lightning::ln_serialization::PublicKeyForRPC; use crate::lightning::ln_storage::LightningStorage; use crate::{lp_coinfind_or_err, CoinFindError, MmCoinEnum}; use common::HttpStatusCode; +use derive_more::Display; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; diff --git a/mm2src/coins/rpc_command/lightning/update_channel.rs b/mm2src/coins/rpc_command/lightning/update_channel.rs index 57b772764c..24bbd7266e 100644 --- a/mm2src/coins/rpc_command/lightning/update_channel.rs +++ b/mm2src/coins/rpc_command/lightning/update_channel.rs @@ -1,6 +1,7 @@ use crate::lightning::ln_conf::ChannelOptions; use crate::{lp_coinfind_or_err, CoinFindError, MmCoinEnum}; use common::{async_blocking, HttpStatusCode}; +use derive_more::Display; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; diff --git a/mm2src/coins/rpc_command/tendermint/staking.rs b/mm2src/coins/rpc_command/tendermint/staking.rs index 5ad332f5e3..e04ebea081 100644 --- a/mm2src/coins/rpc_command/tendermint/staking.rs +++ b/mm2src/coins/rpc_command/tendermint/staking.rs @@ -19,13 +19,13 @@ pub(crate) enum ValidatorStatus { Unbonded, } -impl ToString for ValidatorStatus { - fn to_string(&self) -> String { +impl std::fmt::Display for ValidatorStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { // An empty string doesn't filter any validators and we get an unfiltered result. - ValidatorStatus::All => String::default(), - ValidatorStatus::Bonded => "BOND_STATUS_BONDED".into(), - ValidatorStatus::Unbonded => "BOND_STATUS_UNBONDED".into(), + ValidatorStatus::All => write!(f, ""), + ValidatorStatus::Bonded => write!(f, "BOND_STATUS_BONDED"), + ValidatorStatus::Unbonded => write!(f, "BOND_STATUS_UNBONDED"), } } } diff --git a/mm2src/coins/siacoin.rs b/mm2src/coins/siacoin.rs index 628265b8c4..71441d7c37 100644 --- a/mm2src/coins/siacoin.rs +++ b/mm2src/coins/siacoin.rs @@ -12,6 +12,7 @@ use crate::{coin_errors::MyAddressError, AddressFromPubkeyError, BalanceFut, Can use crate::{SignatureError, VerificationError}; use async_trait::async_trait; use common::executor::AbortedError; +use derive_more::Display; pub use ed25519_dalek::{Keypair, PublicKey, SecretKey, Signature}; use futures::{FutureExt, TryFutureExt}; use futures01::Future; @@ -157,7 +158,7 @@ pub enum SiaCoinBuildError { EllipticCurveError(ed25519_dalek::ed25519::Error), } -impl<'a> SiaCoinBuilder<'a> { +impl SiaCoinBuilder<'_> { #[allow(dead_code)] fn ctx(&self) -> &MmArc { self.ctx } diff --git a/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs b/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs index 5da40d622d..b0de493025 100644 --- a/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs +++ b/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs @@ -26,6 +26,7 @@ use tokio::time; /// /// [`SubscriptionClient`]: trait.SubscriptionClient.html #[async_trait] +#[allow(dead_code)] pub trait Client { /// `/abci_info`: get information about the ABCI application. async fn abci_info(&self) -> Result { self.perform(abci_info::Request).await } diff --git a/mm2src/coins/tendermint/rpc/tendermint_wasm_rpc.rs b/mm2src/coins/tendermint/rpc/tendermint_wasm_rpc.rs index 4a5d13c05f..559b097b7f 100644 --- a/mm2src/coins/tendermint/rpc/tendermint_wasm_rpc.rs +++ b/mm2src/coins/tendermint/rpc/tendermint_wasm_rpc.rs @@ -14,7 +14,6 @@ pub use tendermint_rpc::endpoint::{abci_query::{AbciQuery, Request as AbciReques health::Request as HealthRequest, tx_search::Request as TxSearchRequest}; use tendermint_rpc::error::Error as TendermintRpcError; -pub use tendermint_rpc::query::Query as TendermintQuery; use tendermint_rpc::request::SimpleRequest; pub use tendermint_rpc::Order; use tendermint_rpc::Response; diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index 1160d3b971..c249b02c75 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -2386,9 +2386,9 @@ impl TendermintCoin { amount >= &min_tx_amount } - async fn search_for_swap_tx_spend<'l>( + async fn search_for_swap_tx_spend<'a>( &self, - input: SearchForSwapTxSpendInput<'l>, + input: SearchForSwapTxSpendInput<'a>, ) -> MmResult, SearchForSwapTxSpendErr> { let tx = cosmrs::Tx::from_bytes(input.tx)?; let first_message = tx diff --git a/mm2src/coins/tendermint/tendermint_tx_history_v2.rs b/mm2src/coins/tendermint/tendermint_tx_history_v2.rs index 252b9ad4cd..1ab304a1a6 100644 --- a/mm2src/coins/tendermint/tendermint_tx_history_v2.rs +++ b/mm2src/coins/tendermint/tendermint_tx_history_v2.rs @@ -187,6 +187,7 @@ impl TendermintInit { #[derive(Debug)] enum StopReason { + #[expect(dead_code)] StorageError(String), RpcClient(String), } diff --git a/mm2src/coins/tx_history_storage/mod.rs b/mm2src/coins/tx_history_storage/mod.rs index d440c98098..6036554611 100644 --- a/mm2src/coins/tx_history_storage/mod.rs +++ b/mm2src/coins/tx_history_storage/mod.rs @@ -47,7 +47,7 @@ pub struct TxHistoryStorageBuilder<'a> { ctx: &'a MmArc, } -impl<'a> TxHistoryStorageBuilder<'a> { +impl TxHistoryStorageBuilder<'_> { #[inline] pub fn new(ctx: &MmArc) -> TxHistoryStorageBuilder<'_> { TxHistoryStorageBuilder { ctx } } diff --git a/mm2src/coins/utxo/bch.rs b/mm2src/coins/utxo/bch.rs index f480ca6592..cb63bb9059 100644 --- a/mm2src/coins/utxo/bch.rs +++ b/mm2src/coins/utxo/bch.rs @@ -114,7 +114,7 @@ impl BchUnspents { bch_unspent, slp_amount, }; - self.slp.entry(token_id).or_insert_with(Vec::new).push(slp_unspent); + self.slp.entry(token_id).or_default().push(slp_unspent); } fn add_slp_baton(&mut self, utxo: UnspentInfo) { self.slp_batons.push(utxo) } @@ -387,7 +387,7 @@ impl BchCoin { .await?; let maybe_op_return: Script = tx .outputs - .get(0) + .first() .ok_or(UtxoTxDetailsError::Internal(format!( "Transaction {} has no outputs", params.hash diff --git a/mm2src/coins/utxo/qtum.rs b/mm2src/coins/utxo/qtum.rs index 57dec786ff..21191f4e85 100644 --- a/mm2src/coins/utxo/qtum.rs +++ b/mm2src/coins/utxo/qtum.rs @@ -195,7 +195,7 @@ pub struct QtumCoinBuilder<'a> { } #[async_trait] -impl<'a> UtxoCoinBuilderCommonOps for QtumCoinBuilder<'a> { +impl UtxoCoinBuilderCommonOps for QtumCoinBuilder<'_> { fn ctx(&self) -> &MmArc { self.ctx } fn conf(&self) -> &Json { self.conf } @@ -207,14 +207,14 @@ impl<'a> UtxoCoinBuilderCommonOps for QtumCoinBuilder<'a> { fn check_utxo_maturity(&self) -> bool { self.activation_params().check_utxo_maturity.unwrap_or(true) } } -impl<'a> UtxoFieldsWithIguanaSecretBuilder for QtumCoinBuilder<'a> {} +impl UtxoFieldsWithIguanaSecretBuilder for QtumCoinBuilder<'_> {} -impl<'a> UtxoFieldsWithGlobalHDBuilder for QtumCoinBuilder<'a> {} +impl UtxoFieldsWithGlobalHDBuilder for QtumCoinBuilder<'_> {} -impl<'a> UtxoFieldsWithHardwareWalletBuilder for QtumCoinBuilder<'a> {} +impl UtxoFieldsWithHardwareWalletBuilder for QtumCoinBuilder<'_> {} #[async_trait] -impl<'a> UtxoCoinBuilder for QtumCoinBuilder<'a> { +impl UtxoCoinBuilder for QtumCoinBuilder<'_> { type ResultCoin = QtumCoin; type Error = UtxoCoinBuildError; @@ -229,7 +229,7 @@ impl<'a> UtxoCoinBuilder for QtumCoinBuilder<'a> { } } -impl<'a> MergeUtxoArcOps for QtumCoinBuilder<'a> {} +impl MergeUtxoArcOps for QtumCoinBuilder<'_> {} impl<'a> QtumCoinBuilder<'a> { pub fn new( diff --git a/mm2src/coins/utxo/qtum_delegation.rs b/mm2src/coins/utxo/qtum_delegation.rs index a37eba4cdf..6e51ab0586 100644 --- a/mm2src/coins/utxo/qtum_delegation.rs +++ b/mm2src/coins/utxo/qtum_delegation.rs @@ -185,7 +185,7 @@ impl QtumCoin { .and_then(|receipt| { receipt .log - .get(0) + .first() .and_then(|log_entry| log_entry.topics.get(1)) .map(|padded_staker_address_hex| padded_staker_address_hex.trim_start_matches('0')) }) { diff --git a/mm2src/coins/utxo/rpc_clients.rs b/mm2src/coins/utxo/rpc_clients.rs index f09d7ddf67..faa484c29e 100644 --- a/mm2src/coins/utxo/rpc_clients.rs +++ b/mm2src/coins/utxo/rpc_clients.rs @@ -67,11 +67,11 @@ pub enum UtxoRpcClientEnum { Electrum(ElectrumClient), } -impl ToString for UtxoRpcClientEnum { - fn to_string(&self) -> String { +impl std::fmt::Display for UtxoRpcClientEnum { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - UtxoRpcClientEnum::Native(_) => "native".to_owned(), - UtxoRpcClientEnum::Electrum(_) => "electrum".to_owned(), + UtxoRpcClientEnum::Native(_) => write!(f, "native"), + UtxoRpcClientEnum::Electrum(_) => write!(f, "electrum"), } } } @@ -780,7 +780,7 @@ impl JsonRpcBatchClient for NativeClientImpl {} impl UtxoRpcClientOps for NativeClient { fn list_unspent(&self, address: &Address, decimals: u8) -> UtxoRpcFut> { let fut = self - .list_unspent_impl(0, std::i32::MAX, vec![address.to_string()]) + .list_unspent_impl(0, i32::MAX, vec![address.to_string()]) .map_to_mm_fut(UtxoRpcError::from) .and_then(move |unspents| { unspents @@ -801,7 +801,7 @@ impl UtxoRpcClientOps for NativeClient { } let fut = self - .list_unspent_impl(0, std::i32::MAX, addresses_str) + .list_unspent_impl(0, i32::MAX, addresses_str) .map_to_mm_fut(UtxoRpcError::from) .and_then(move |unspents| { unspents @@ -865,7 +865,7 @@ impl UtxoRpcClientOps for NativeClient { fn display_balance(&self, address: Address, _decimals: u8) -> RpcRes { Box::new( - self.list_unspent_impl(0, std::i32::MAX, vec![address.to_string()]) + self.list_unspent_impl(0, i32::MAX, vec![address.to_string()]) .map(|unspents| { unspents .iter() @@ -1028,7 +1028,7 @@ impl NativeClient { return Ok(transaction_list); } - transaction_list.extend(transactions.into_iter()); + transaction_list.extend(transactions); from += step; } }; diff --git a/mm2src/coins/utxo/rpc_clients/electrum_rpc/client.rs b/mm2src/coins/utxo/rpc_clients/electrum_rpc/client.rs index dec5920659..bf37e54444 100644 --- a/mm2src/coins/utxo/rpc_clients/electrum_rpc/client.rs +++ b/mm2src/coins/utxo/rpc_clients/electrum_rpc/client.rs @@ -427,8 +427,10 @@ impl ElectrumClient { final_response = Some((address, response)); } client.connection_manager.not_needed(connection.address()); - if !send_to_all && final_response.is_some() { - return Ok(final_response.unwrap()); + if !send_to_all { + if let Some(response) = final_response { + return Ok(response); + } } }, Err(e) => { @@ -735,7 +737,7 @@ impl ElectrumClient { } let len = CompactInteger::from(headers.count); let mut serialized = serialize(&len).take(); - serialized.extend(headers.hex.0.into_iter()); + serialized.extend(headers.hex.0); drop_mutability!(serialized); let mut reader = Reader::new_with_coin_variant(serialized.as_slice(), coin_name.as_str().into()); @@ -1073,7 +1075,7 @@ impl UtxoRpcClientOps for ElectrumClient { } let len = CompactInteger::from(res.count); let mut serialized = serialize(&len).take(); - serialized.extend(res.hex.0.into_iter()); + serialized.extend(res.hex.0); let mut reader = Reader::new_with_coin_variant(serialized.as_slice(), coin_variant); let headers = reader.read_list::()?; let mut timestamps: Vec<_> = headers.into_iter().map(|block| block.time).collect(); diff --git a/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection.rs b/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection.rs index 3b234dc51f..be58dfb0fe 100644 --- a/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection.rs +++ b/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection.rs @@ -235,16 +235,18 @@ impl ElectrumConnection { /// ## Important: This should always return [`JsonRpcErrorType::Transport`] error. pub async fn electrum_request( &self, - mut req_json: String, + req_json: String, rpc_id: JsonRpcId, timeout: f64, ) -> Result { - #[cfg(not(target_arch = "wasm"))] - { + #[cfg(not(target_arch = "wasm32"))] + let req_json = { // Electrum request and responses must end with \n // https://electrumx.readthedocs.io/en/latest/protocol-basics.html#message-stream + let mut req_json = req_json; req_json.push('\n'); - } + req_json + }; // Create a oneshot channel to receive the response in. let (req_tx, res_rx) = async_oneshot::channel(); diff --git a/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection_manager/manager.rs b/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection_manager/manager.rs index a3b792e9f6..3410cc4275 100644 --- a/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection_manager/manager.rs +++ b/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection_manager/manager.rs @@ -12,6 +12,7 @@ use common::executor::{AbortableSystem, SpawnFuture, Timer}; use common::log::{debug, error, LogOnError}; use common::notifier::{Notifiee, Notifier}; use common::now_ms; +use derive_more::Display; use keys::Address; use futures::compat::Future01CompatExt; @@ -374,9 +375,8 @@ impl ConnectionManager { // The connections that we can consider (all connections - candidate connections). let all_candidate_connections: Vec<_> = all_connections .iter() - .filter_map(|(_, conn_ctx)| { - (!maintained_connections.contains_key(&conn_ctx.id)).then(|| (conn_ctx.connection.clone(), conn_ctx.id)) - }) + .filter(|&(_, conn_ctx)| (!maintained_connections.contains_key(&conn_ctx.id))) + .map(|(_, conn_ctx)| (conn_ctx.connection.clone(), conn_ctx.id)) .collect(); // The candidate connections from above, but further filtered by whether they are suspended or not. let non_suspended_candidate_connections: Vec<_> = all_candidate_connections @@ -384,7 +384,7 @@ impl ConnectionManager { .filter(|(connection, _)| { all_connections .get(connection.address()) - .map_or(false, |conn_ctx| now_ms() > conn_ctx.suspended_till()) + .is_some_and(|conn_ctx| now_ms() > conn_ctx.suspended_till()) }) .cloned() .collect(); diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index 13ac99cbe0..563dbb1cf8 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -298,6 +298,7 @@ pub struct SlpProtocolConf { } impl SlpToken { + #[allow(clippy::result_large_err)] pub fn new( decimals: u8, ticker: String, diff --git a/mm2src/coins/utxo/utxo_block_header_storage/sql_block_header_storage.rs b/mm2src/coins/utxo/utxo_block_header_storage/sql_block_header_storage.rs index 183c3abea1..bc32e41d05 100644 --- a/mm2src/coins/utxo/utxo_block_header_storage/sql_block_header_storage.rs +++ b/mm2src/coins/utxo/utxo_block_header_storage/sql_block_header_storage.rs @@ -314,7 +314,7 @@ impl BlockHeaderStorageOps for SqliteBlockHeadersStorage { ) -> Result<(), BlockHeaderStorageError> { let coin = self.ticker.clone(); let sql = remove_headers_from_to_height_sql(&coin)?; - let params = vec![from_height.to_string(), to_height.to_string()]; + let params = [from_height.to_string(), to_height.to_string()]; let selfi = self.clone(); async_blocking(move || { diff --git a/mm2src/coins/utxo/utxo_block_header_storage/wasm/block_header_table.rs b/mm2src/coins/utxo/utxo_block_header_storage/wasm/block_header_table.rs index 756e50614f..a7c35eab37 100644 --- a/mm2src/coins/utxo/utxo_block_header_storage/wasm/block_header_table.rs +++ b/mm2src/coins/utxo/utxo_block_header_storage/wasm/block_header_table.rs @@ -10,8 +10,8 @@ pub struct BlockHeaderStorageTable { } impl BlockHeaderStorageTable { - pub const TICKER_HEIGHT_INDEX: &str = "block_height_ticker_index"; - pub const HASH_TICKER_INDEX: &str = "block_hash_ticker_index"; + pub const TICKER_HEIGHT_INDEX: &'static str = "block_height_ticker_index"; + pub const HASH_TICKER_INDEX: &'static str = "block_hash_ticker_index"; } impl TableSignature for BlockHeaderStorageTable { diff --git a/mm2src/coins/utxo/utxo_builder/utxo_arc_builder.rs b/mm2src/coins/utxo/utxo_builder/utxo_arc_builder.rs index 65bd34103f..4199e3e39e 100644 --- a/mm2src/coins/utxo/utxo_builder/utxo_arc_builder.rs +++ b/mm2src/coins/utxo/utxo_builder/utxo_arc_builder.rs @@ -11,6 +11,7 @@ use async_trait::async_trait; use chain::{BlockHeader, TransactionOutput}; use common::executor::{AbortSettings, SpawnAbortable, Timer}; use common::log::{debug, error, info, warn}; +use derive_more::Display; use futures::compat::Future01CompatExt; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; @@ -65,7 +66,7 @@ where } #[async_trait] -impl<'a, F, T> UtxoCoinBuilderCommonOps for UtxoArcBuilder<'a, F, T> +impl UtxoCoinBuilderCommonOps for UtxoArcBuilder<'_, F, T> where F: Fn(UtxoArc) -> T + Send + Sync + 'static, { @@ -78,23 +79,20 @@ where fn ticker(&self) -> &str { self.ticker } } -impl<'a, F, T> UtxoFieldsWithIguanaSecretBuilder for UtxoArcBuilder<'a, F, T> where +impl UtxoFieldsWithIguanaSecretBuilder for UtxoArcBuilder<'_, F, T> where F: Fn(UtxoArc) -> T + Send + Sync + 'static { } -impl<'a, F, T> UtxoFieldsWithGlobalHDBuilder for UtxoArcBuilder<'a, F, T> where - F: Fn(UtxoArc) -> T + Send + Sync + 'static -{ -} +impl UtxoFieldsWithGlobalHDBuilder for UtxoArcBuilder<'_, F, T> where F: Fn(UtxoArc) -> T + Send + Sync + 'static {} -impl<'a, F, T> UtxoFieldsWithHardwareWalletBuilder for UtxoArcBuilder<'a, F, T> where +impl UtxoFieldsWithHardwareWalletBuilder for UtxoArcBuilder<'_, F, T> where F: Fn(UtxoArc) -> T + Send + Sync + 'static { } #[async_trait] -impl<'a, F, T> UtxoCoinBuilder for UtxoArcBuilder<'a, F, T> +impl UtxoCoinBuilder for UtxoArcBuilder<'_, F, T> where F: Fn(UtxoArc) -> T + Clone + Send + Sync + 'static, T: UtxoCommonOps + GetUtxoListOps, @@ -123,7 +121,7 @@ where } } -impl<'a, F, T> MergeUtxoArcOps for UtxoArcBuilder<'a, F, T> +impl MergeUtxoArcOps for UtxoArcBuilder<'_, F, T> where F: Fn(UtxoArc) -> T + Send + Sync + 'static, T: UtxoCommonOps + GetUtxoListOps, @@ -528,6 +526,7 @@ impl PossibleChainReorgError { } /// Retrieves block headers from the specified client within the given height range and revalidate against [`SPVError::ParentHashMismatch`] . +#[allow(clippy::unit_arg)] async fn resolve_possible_chain_reorg( client: &ElectrumClient, server_address: &str, diff --git a/mm2src/coins/utxo/utxo_builder/utxo_coin_builder.rs b/mm2src/coins/utxo/utxo_builder/utxo_coin_builder.rs index 81ccdeab79..76491bb172 100644 --- a/mm2src/coins/utxo/utxo_builder/utxo_coin_builder.rs +++ b/mm2src/coins/utxo/utxo_builder/utxo_coin_builder.rs @@ -19,8 +19,7 @@ use derive_more::Display; use futures::channel::mpsc::{channel, Receiver as AsyncReceiver}; use futures::compat::Future01CompatExt; use futures::lock::Mutex as AsyncMutex; -pub use keys::{Address, AddressBuilder, AddressFormat as UtxoAddressFormat, AddressHashEnum, AddressScriptType, - KeyPair, Private, Public, Secret}; +pub use keys::{Address, AddressBuilder, AddressFormat as UtxoAddressFormat, KeyPair, Private}; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; use primitives::hash::H160; diff --git a/mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs b/mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs index 5ae7fcb405..90077f1edd 100644 --- a/mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs +++ b/mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs @@ -5,9 +5,8 @@ use crate::UtxoActivationParams; use bitcrypto::ChecksumType; use crypto::{Bip32Error, HDPathToCoin}; use derive_more::Display; +pub use keys::AddressFormat as UtxoAddressFormat; use keys::NetworkAddressPrefixes; -pub use keys::{Address, AddressFormat as UtxoAddressFormat, AddressHashEnum, AddressScriptType, KeyPair, Private, - Public, Secret}; use mm2_err_handle::prelude::*; use script::SignatureVersion; use serde_json::{self as json, Value as Json}; diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 31b4a9c8fc..3641ce8d8a 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -2957,6 +2957,7 @@ pub fn sign_message( } else { *coin.priv_key_policy.activated_key_or_err().map_mm_err()?.private() }; + let signature = private.sign_compact(&H256::from(message_hash))?; Ok(STANDARD.encode(&*signature)) @@ -4013,8 +4014,8 @@ pub async fn tx_details_by_hash( }) } -pub async fn get_mut_verbose_transaction_from_map_or_rpc<'a, 'b, T>( - coin: &'a T, +pub async fn get_mut_verbose_transaction_from_map_or_rpc<'b, T>( + coin: &T, tx_hash: H256Json, utxo_tx_map: &'b mut HistoryUtxoTxMap, ) -> UtxoRpcResult<&'b mut HistoryUtxoTx> @@ -4408,6 +4409,7 @@ where fn can_tx_be_cached(tx: &RpcTransaction) -> bool { tx.height > Some(0) } /// Calculates actual confirmations number of the given `tx` transaction loaded from cache. + #[allow(clippy::result_large_err)] fn calc_actual_cached_tx_confirmations(tx: &RpcTransaction, block_count: u64) -> UtxoRpcResult { let tx_height = tx.height.or_mm_err(|| { UtxoRpcError::Internal(format!(r#"Warning, height of cached "{:?}" tx is unknown"#, tx.txid)) @@ -4599,7 +4601,7 @@ pub fn address_from_pubkey( #[allow(clippy::too_many_arguments)] #[cfg_attr(test, mockable)] -pub async fn validate_payment<'a, T: UtxoCommonOps>( +pub async fn validate_payment<'a, T>( coin: T, tx: &'a UtxoTx, output_index: usize, @@ -4611,7 +4613,10 @@ pub async fn validate_payment<'a, T: UtxoCommonOps>( time_lock: u32, try_spv_proof_until: u64, confirmations: u64, -) -> ValidatePaymentResult<()> { +) -> ValidatePaymentResult<()> +where + T: UtxoCommonOps, +{ let amount = sat_from_big_decimal(&amount, coin.as_ref().decimals).map_mm_err()?; let expected_redeem = tx_type_with_secret_hash.redeem_script(time_lock, first_pub0, second_pub0); @@ -5244,11 +5249,11 @@ where script_pubkey: Builder::build_p2sh(&AddressHashEnum::AddressHash(dhash160(&redeem_script))).into(), }; - if args.funding_tx.outputs.get(0) != Some(&expected_output) { + if args.funding_tx.outputs.first() != Some(&expected_output) { return MmError::err(ValidateSwapV2TxError::InvalidDestinationOrAmount(format!( "Expected {:?}, got {:?}", expected_output, - args.funding_tx.outputs.get(0) + args.funding_tx.outputs.first() ))); } diff --git a/mm2src/coins/utxo/utxo_tests.rs b/mm2src/coins/utxo/utxo_tests.rs index 7d8d760452..8a30c42c58 100644 --- a/mm2src/coins/utxo/utxo_tests.rs +++ b/mm2src/coins/utxo/utxo_tests.rs @@ -1,3 +1,4 @@ +#![allow(static_mut_refs)] use super::*; use crate::coin_balance::HDAddressBalance; use crate::coin_errors::ValidatePaymentError; @@ -12,7 +13,7 @@ use crate::rpc_command::init_scan_for_new_addresses::{InitScanAddressesRpcOps, S ScanAddressesResponse}; use crate::utxo::qtum::{qtum_coin_with_priv_key, QtumCoin, QtumDelegationOps, QtumDelegationRequest}; #[cfg(not(target_arch = "wasm32"))] -use crate::utxo::rpc_clients::{BlockHashOrHeight, ElectrumClientSettings, NativeUnspent}; +use crate::utxo::rpc_clients::{BlockHashOrHeight, NativeUnspent}; use crate::utxo::rpc_clients::{ElectrumBalance, ElectrumBlockHeader, ElectrumClient, ElectrumClientImpl, GetAddressInfoRes, ListSinceBlockRes, NativeClient, NativeClientImpl, NetworkInfo, UtxoRpcClientOps, ValidateAddressRes, VerboseBlock}; @@ -43,15 +44,12 @@ use futures::future::{join_all, Either, FutureExt, TryFutureExt}; use hex::FromHex; use keys::prefixes::*; use mm2_core::mm_ctx::MmCtxBuilder; -#[cfg(not(target_arch = "wasm32"))] -use mm2_event_stream::StreamingManager; use mm2_number::bigdecimal::{BigDecimal, Signed}; use mm2_number::MmNumber; use mm2_test_helpers::electrums::doc_electrums; use mm2_test_helpers::for_tests::{electrum_servers_rpc, mm_ctx_with_custom_db, DOC_ELECTRUM_ADDRS, MARTY_ELECTRUM_ADDRS, T_BCH_ELECTRUMS}; use mocktopus::mocking::*; -use rand::{rngs::ThreadRng, Rng}; use rpc::v1::types::H256 as H256Json; use serialization::{deserialize, CoinVariant, CompactInteger, Reader}; use spv_validation::conf::{BlockHeaderValidationParams, SPVBlockHeader}; @@ -457,6 +455,9 @@ fn test_wait_for_payment_spend_timeout_native() { #[cfg(not(target_arch = "wasm32"))] #[test] fn test_wait_for_payment_spend_timeout_electrum() { + use mm2_event_stream::StreamingManager; + use rpc_clients::ElectrumClientSettings; + static mut OUTPUT_SPEND_CALLED: bool = false; ElectrumClient::find_output_spend.mock_safe(|_, _, _, _, _, _| { @@ -1213,6 +1214,8 @@ fn test_generate_transaction_relay_fee_is_used_when_dynamic_fee_is_lower() { #[test] #[cfg(not(target_arch = "wasm32"))] fn test_generate_transaction_random_values() { + use rand::{rngs::ThreadRng, Rng}; + let client = NativeClientImpl::default(); let mut rng = rand::thread_rng(); diff --git a/mm2src/coins/utxo/utxo_tx_history_v2.rs b/mm2src/coins/utxo/utxo_tx_history_v2.rs index 0231bdc4c7..56b024efce 100644 --- a/mm2src/coins/utxo/utxo_tx_history_v2.rs +++ b/mm2src/coins/utxo/utxo_tx_history_v2.rs @@ -131,7 +131,6 @@ pub trait UtxoTxHistoryOps: -> RequestTxHistoryResult; /// Requests timestamp of the given block. - async fn get_block_timestamp(&self, height: u64) -> MmResult; /// Requests balances of all activated coin's addresses. @@ -643,6 +642,7 @@ where } } +#[expect(dead_code)] #[derive(Debug)] enum StopReason { HistoryTooLarge, @@ -733,14 +733,15 @@ pub async fn bch_and_slp_history_loop( }, None => { let ticker = coin.ticker().to_string(); - match retry_on_err!(async { coin.my_addresses_balances().await }) + let addr_bal = retry_on_err!(async { coin.my_addresses_balances().await }) .until_ready() .repeat_every_secs(30.) .inspect_err(move |e| { error!("Error {e:?} on balance fetching for the coin {}", ticker); }) - .await - { + .await; + + match addr_bal { Ok(addresses_balances) => addresses_balances, Err(e) => { error!("{}", e); diff --git a/mm2src/coins/utxo_signer/src/with_trezor.rs b/mm2src/coins/utxo_signer/src/with_trezor.rs index 75d882fa49..3909175a1b 100644 --- a/mm2src/coins/utxo_signer/src/with_trezor.rs +++ b/mm2src/coins/utxo_signer/src/with_trezor.rs @@ -21,7 +21,7 @@ pub struct TrezorTxSigner<'a, TxP> { pub branch_id: u32, } -impl<'a, TxP: TxProvider + Send + Sync> TrezorTxSigner<'a, TxP> { +impl TrezorTxSigner<'_, TxP> { pub async fn sign_tx(mut self) -> UtxoSignTxResult { let trezor_unsigned_tx = self.get_trezor_unsigned_tx().await.map_mm_err()?; diff --git a/mm2src/coins/z_coin.rs b/mm2src/coins/z_coin.rs index 4a0e92056e..ec2c0c6eb2 100644 --- a/mm2src/coins/z_coin.rs +++ b/mm2src/coins/z_coin.rs @@ -65,7 +65,7 @@ use script::{Builder as ScriptBuilder, Opcode, Script, TransactionInputSigner}; use serde_json::Value as Json; use serialization::CoinVariant; use std::collections::{HashMap, HashSet}; -use std::convert::{TryFrom, TryInto}; +use std::convert::TryInto; use std::iter; use std::num::NonZeroU32; use std::num::TryFromIntError; @@ -181,8 +181,6 @@ impl Parameters for ZcoinConsensusParams { NetworkUpgrade::Blossom => self.blossom_activation_height.map(BlockHeight::from), NetworkUpgrade::Heartwood => self.heartwood_activation_height.map(BlockHeight::from), NetworkUpgrade::Canopy => self.canopy_activation_height.map(BlockHeight::from), - #[cfg(feature = "zfuture")] - NetworkUpgrade::ZFuture => unimplemented!(), } } @@ -916,7 +914,7 @@ pub struct ZCoinBuilder<'a> { protocol_info: ZcoinProtocolInfo, } -impl<'a> UtxoCoinBuilderCommonOps for ZCoinBuilder<'a> { +impl UtxoCoinBuilderCommonOps for ZCoinBuilder<'_> { fn ctx(&self) -> &MmArc { self.ctx } fn conf(&self) -> &Json { self.conf } @@ -926,16 +924,16 @@ impl<'a> UtxoCoinBuilderCommonOps for ZCoinBuilder<'a> { fn ticker(&self) -> &str { self.ticker } } -impl<'a> UtxoFieldsWithIguanaSecretBuilder for ZCoinBuilder<'a> {} +impl UtxoFieldsWithIguanaSecretBuilder for ZCoinBuilder<'_> {} -impl<'a> UtxoFieldsWithGlobalHDBuilder for ZCoinBuilder<'a> {} +impl UtxoFieldsWithGlobalHDBuilder for ZCoinBuilder<'_> {} /// Although, `ZCoin` doesn't support [`PrivKeyBuildPolicy::Trezor`] yet, /// `UtxoCoinBuilder` trait requires `UtxoFieldsWithHardwareWalletBuilder` to be implemented. -impl<'a> UtxoFieldsWithHardwareWalletBuilder for ZCoinBuilder<'a> {} +impl UtxoFieldsWithHardwareWalletBuilder for ZCoinBuilder<'_> {} #[async_trait] -impl<'a> UtxoCoinBuilder for ZCoinBuilder<'a> { +impl UtxoCoinBuilder for ZCoinBuilder<'_> { type ResultCoin = ZCoin; type Error = ZCoinBuildError; @@ -1259,8 +1257,7 @@ impl MarketCoinOps for ZCoin { .filter(|n| !spent_rseeds.contains(&rseed_to_string(&n.rseed))) .fold(Amount::zero(), |acc, n| acc + n.note_value); - let spendable_sat = - u64::try_from(spendable_amount).map_to_mm(|err| BalanceError::Internal(err.to_string()))?; + let spendable_sat = u64::from(spendable_amount); let unspendable = big_decimal_from_sat_unsigned(unspendable_change_sat, coin.decimals()); let spendable = big_decimal_from_sat_unsigned(spendable_sat, coin.decimals()); Ok(CoinBalance { spendable, unspendable }) @@ -2111,7 +2108,7 @@ async fn wait_for_spendable_balance_impl( let unlocked_notes_len = unlocked_notes.len(); let sum_available = unlocked_notes.iter().map(|n| n.note_value).sum::(); - let sum_available = u64::try_from(sum_available).map_to_mm(|err| GenTxError::Internal(err.to_string()))?; + let sum_available = u64::from(sum_available); let sum_available = big_decimal_from_sat_unsigned(sum_available, selfi.decimals()); // Reteurn InsufficientBalance error when all notes are unlocked but amount is insufficient. diff --git a/mm2src/coins/z_coin/storage/blockdb/blockdb_sql_storage.rs b/mm2src/coins/z_coin/storage/blockdb/blockdb_sql_storage.rs index 6083751df6..b91478eacc 100644 --- a/mm2src/coins/z_coin/storage/blockdb/blockdb_sql_storage.rs +++ b/mm2src/coins/z_coin/storage/blockdb/blockdb_sql_storage.rs @@ -170,15 +170,12 @@ impl BlockDbImpl { .map_to_mm(|err| ZcoinStorageError::AddToStorageErr(err.to_string()))?; let rows = stmt_blocks - .query_map( - params![u32::from(from_height), limit.unwrap_or(u32::max_value()),], - |row| { - Ok(CompactBlockRow { - height: BlockHeight::from_u32(row.get(0)?), - data: row.get(1)?, - }) - }, - ) + .query_map(params![u32::from(from_height), limit.unwrap_or(u32::MAX),], |row| { + Ok(CompactBlockRow { + height: BlockHeight::from_u32(row.get(0)?), + data: row.get(1)?, + }) + }) .map_to_mm(|err| ZcoinStorageError::AddToStorageErr(err.to_string()))?; Ok(rows.collect_vec()) diff --git a/mm2src/coins/z_coin/storage/walletdb/wallet_sql_storage.rs b/mm2src/coins/z_coin/storage/walletdb/wallet_sql_storage.rs index 0408182ae0..b834629be0 100644 --- a/mm2src/coins/z_coin/storage/walletdb/wallet_sql_storage.rs +++ b/mm2src/coins/z_coin/storage/walletdb/wallet_sql_storage.rs @@ -80,9 +80,9 @@ pub async fn create_wallet_db( Ok(db) } -impl<'a> WalletDbShared { +impl WalletDbShared { pub async fn new( - builder: &ZCoinBuilder<'a>, + builder: &ZCoinBuilder<'_>, checkpoint_block: Option, continue_from_prev_sync: bool, ) -> ZcoinStorageRes { diff --git a/mm2src/coins/z_coin/storage/walletdb/wasm/storage.rs b/mm2src/coins/z_coin/storage/walletdb/wasm/storage.rs index f4e08c3ef2..6943590450 100644 --- a/mm2src/coins/z_coin/storage/walletdb/wasm/storage.rs +++ b/mm2src/coins/z_coin/storage/walletdb/wasm/storage.rs @@ -50,9 +50,9 @@ macro_rules! num_to_bigint { }; } -impl<'a> WalletDbShared { +impl WalletDbShared { pub async fn new( - builder: &ZCoinBuilder<'a>, + builder: &ZCoinBuilder<'_>, checkpoint_block: Option, continue_from_prev_sync: bool, ) -> ZcoinStorageRes { @@ -130,7 +130,7 @@ pub struct WalletIndexedDb { pub params: ZcoinConsensusParams, } -impl<'a> WalletIndexedDb { +impl WalletIndexedDb { pub async fn new( ctx: &MmArc, ticker: &str, @@ -1301,7 +1301,6 @@ impl WalletRead for WalletIndexedDb { .await .map_mm_err()? .into_iter() - .map(|(i, item)| (i, item)) .collect::>(); // Witnesses let witnesses_table = db_transaction diff --git a/mm2src/coins/z_coin/storage/walletdb/wasm/tables.rs b/mm2src/coins/z_coin/storage/walletdb/wasm/tables.rs index 92ce152837..4c1769714b 100644 --- a/mm2src/coins/z_coin/storage/walletdb/wasm/tables.rs +++ b/mm2src/coins/z_coin/storage/walletdb/wasm/tables.rs @@ -13,12 +13,12 @@ impl WalletDbAccountsTable { /// A **unique** index that consists of the following properties: /// * ticker /// * account - pub const TICKER_ACCOUNT_INDEX: &str = "ticker_account_index"; + pub const TICKER_ACCOUNT_INDEX: &'static str = "ticker_account_index"; /// A **unique** index that consists of the following properties: /// * ticker /// * account /// * extfvk - pub const TICKER_ACCOUNT_EXTFVK_INDEX: &str = "ticker_account_extfvk_index"; + pub const TICKER_ACCOUNT_EXTFVK_INDEX: &'static str = "ticker_account_extfvk_index"; } impl TableSignature for WalletDbAccountsTable { diff --git a/mm2src/coins/z_coin/storage/z_locked_notes/mod.rs b/mm2src/coins/z_coin/storage/z_locked_notes/mod.rs index fdbd9b8b76..bca87550c0 100644 --- a/mm2src/coins/z_coin/storage/z_locked_notes/mod.rs +++ b/mm2src/coins/z_coin/storage/z_locked_notes/mod.rs @@ -1,3 +1,4 @@ +use derive_more::Display; use enum_derives::EnumFromStringify; cfg_native!( diff --git a/mm2src/coins/z_coin/storage/z_params/indexeddb.rs b/mm2src/coins/z_coin/storage/z_params/indexeddb.rs index 6822c89c5b..97a115cca7 100644 --- a/mm2src/coins/z_coin/storage/z_params/indexeddb.rs +++ b/mm2src/coins/z_coin/storage/z_params/indexeddb.rs @@ -24,7 +24,7 @@ struct ZcashParamsWasmTable { } impl ZcashParamsWasmTable { - const SPEND_OUTPUT_INDEX: &str = "sapling_spend_sapling_output_index"; + const SPEND_OUTPUT_INDEX: &'static str = "sapling_spend_sapling_output_index"; } impl TableSignature for ZcashParamsWasmTable { diff --git a/mm2src/coins/z_coin/z_coin_errors.rs b/mm2src/coins/z_coin/z_coin_errors.rs index df293b89ff..1590fafa39 100644 --- a/mm2src/coins/z_coin/z_coin_errors.rs +++ b/mm2src/coins/z_coin/z_coin_errors.rs @@ -242,7 +242,7 @@ pub enum ZCoinBuildError { GetAddressError, #[from_stringify("LockedNotesStorageError")] ZcashDBError(String), - Rpc(UtxoRpcError), + Rpc(String), #[display(fmt = "Sapling cache DB does not exist at {}. Please download it.", path)] SaplingCacheDbDoesNotExist { path: String, @@ -257,7 +257,7 @@ pub enum ZCoinBuildError { } impl From for ZCoinBuildError { - fn from(err: UtxoRpcError) -> ZCoinBuildError { ZCoinBuildError::Rpc(err) } + fn from(err: UtxoRpcError) -> ZCoinBuildError { ZCoinBuildError::Rpc(err.to_string()) } } impl From for ZCoinBuildError { diff --git a/mm2src/coins/z_coin/z_rpc.rs b/mm2src/coins/z_coin/z_rpc.rs index 4971c6bc5a..c8b6e917c4 100644 --- a/mm2src/coins/z_coin/z_rpc.rs +++ b/mm2src/coins/z_coin/z_rpc.rs @@ -500,8 +500,8 @@ impl ZRpcOps for NativeClient { } } -pub(super) async fn init_light_client<'a>( - builder: &ZCoinBuilder<'a>, +pub(super) async fn init_light_client( + builder: &ZCoinBuilder<'_>, lightwalletd_urls: Vec, blocks_db: BlockDbImpl, sync_params: &Option, @@ -585,8 +585,8 @@ pub(super) async fn init_light_client<'a>( } #[cfg(not(target_arch = "wasm32"))] -pub(super) async fn init_native_client<'a>( - builder: &ZCoinBuilder<'a>, +pub(super) async fn init_native_client( + builder: &ZCoinBuilder<'_>, native_client: NativeClient, blocks_db: BlockDbImpl, locked_notes_db: LockedNotesStorage, diff --git a/mm2src/coins_activation/src/bch_with_tokens_activation.rs b/mm2src/coins_activation/src/bch_with_tokens_activation.rs index 289c0785a6..0513f5779e 100644 --- a/mm2src/coins_activation/src/bch_with_tokens_activation.rs +++ b/mm2src/coins_activation/src/bch_with_tokens_activation.rs @@ -163,8 +163,8 @@ impl GetPlatformBalance for BchWithTokensActivationResult { fn get_platform_balance(&self) -> Option { self.bch_addresses_infos .iter() - .fold(Some(BigDecimal::from(0)), |total, (_, addr_info)| { - total.and_then(|t| addr_info.balances.as_ref().map(|b| t + b.get_total())) + .try_fold(BigDecimal::from(0), |total, (_, addr_info)| { + addr_info.balances.as_ref().map(|b| total + b.get_total()) }) } } @@ -226,7 +226,7 @@ impl PlatformCoinWithTokensActivationOps for BchCoin { activation_request: Self::ActivationRequest, protocol_conf: Self::PlatformProtocolInfo, ) -> Result> { - let priv_key_policy = PrivKeyBuildPolicy::detect_priv_key_policy(&ctx).map_mm_err::()?; + let priv_key_policy = PrivKeyBuildPolicy::detect_priv_key_policy(&ctx).map_mm_err()?; let slp_prefix = CashAddrPrefix::from_str(&protocol_conf.slp_prefix).map_to_mm(|error| { BchWithTokensActivationError::InvalidSlpPrefix { @@ -246,7 +246,7 @@ impl PlatformCoinWithTokensActivationOps for BchCoin { ) .await .map_to_mm(|error| BchWithTokensActivationError::PlatformCoinCreationError { ticker, error }) - .map_mm_err::()?; + .map_mm_err()?; Ok(platform_coin) } @@ -282,53 +282,34 @@ impl PlatformCoinWithTokensActivationOps for BchCoin { activation_request: &Self::ActivationRequest, _nft_global: &Option, ) -> Result> { - let current_block = self - .as_ref() - .rpc_client - .get_block_count() - .compat() - .await - .map_mm_err::()?; + let current_block = self.as_ref().rpc_client.get_block_count().compat().await.map_mm_err()?; let my_address = self .as_ref() .derivation_method .single_addr_or_err() .await - .map_mm_err::()?; + .map_mm_err()?; let my_slp_address = self .get_my_slp_address() .await .map_to_mm(BchWithTokensActivationError::Internal) - .map_mm_err::()? + .map_mm_err()? .encode() .map_to_mm(BchWithTokensActivationError::Internal) - .map_mm_err::()?; + .map_mm_err()?; - let pubkey = self - .my_public_key() - .map_mm_err::()? - .to_string(); + let pubkey = self.my_public_key().map_mm_err()?.to_string(); let mut bch_address_info = CoinAddressInfo { - derivation_method: self - .as_ref() - .derivation_method - .to_response() - .await - .map_mm_err::()?, + derivation_method: self.as_ref().derivation_method.to_response().await.map_mm_err()?, pubkey: pubkey.clone(), balances: None, tickers: None, }; let mut slp_address_info = CoinAddressInfo { - derivation_method: self - .as_ref() - .derivation_method - .to_response() - .await - .map_mm_err::()?, + derivation_method: self.as_ref().derivation_method.to_response().await.map_mm_err()?, pubkey: pubkey.clone(), balances: None, tickers: None, @@ -347,10 +328,7 @@ impl PlatformCoinWithTokensActivationOps for BchCoin { }); } - let bch_unspents = self - .bch_unspents_for_display(&my_address) - .await - .map_mm_err::()?; + let bch_unspents = self.bch_unspents_for_display(&my_address).await.map_mm_err()?; bch_address_info.balances = Some(bch_unspents.platform_balance(self.decimals())); drop_mutability!(bch_address_info); @@ -375,7 +353,7 @@ impl PlatformCoinWithTokensActivationOps for BchCoin { fn start_history_background_fetching( &self, ctx: MmArc, - storage: impl TxHistoryStorage + Send + 'static, + storage: impl TxHistoryStorage + 'static, initial_balance: Option, ) { let fut = bch_and_slp_history_loop( diff --git a/mm2src/coins_activation/src/erc20_token_activation.rs b/mm2src/coins_activation/src/erc20_token_activation.rs index dad933ac16..e719ad6404 100644 --- a/mm2src/coins_activation/src/erc20_token_activation.rs +++ b/mm2src/coins_activation/src/erc20_token_activation.rs @@ -152,13 +152,13 @@ impl TokenActivationOps for EthCoin { is_custom, ) .await - .map_mm_err::()?; + .map_mm_err()?; let address = token .derivation_method() .single_addr_or_err() .await - .map_mm_err::()? + .map_mm_err()? .display_address(); let token_contract_address = token.erc20_token_address().ok_or_else(|| { EthTokenActivationError::InternalError("Token contract address is missing".to_string()) @@ -196,7 +196,7 @@ impl TokenActivationOps for EthCoin { NftProviderEnum::Moralis { url, komodo_proxy } => platform_coin .initialize_global_nft(url, *komodo_proxy) .await - .map_mm_err::()?, + .map_mm_err()?, }; let nfts = nft_global.nfts_infos.lock().await.clone(); let init_result = EthTokenInitResult::Nft(NftInitResult { diff --git a/mm2src/coins_activation/src/eth_with_token_activation.rs b/mm2src/coins_activation/src/eth_with_token_activation.rs index b1fdf3a782..d3ac19b0cb 100644 --- a/mm2src/coins_activation/src/eth_with_token_activation.rs +++ b/mm2src/coins_activation/src/eth_with_token_activation.rs @@ -240,8 +240,8 @@ impl GetPlatformBalance for EthWithTokensActivationResult { EthWithTokensActivationResult::Iguana(result) => result .eth_addresses_infos .iter() - .fold(Some(BigDecimal::from(0)), |total, (_, addr_info)| { - total.and_then(|t| addr_info.balances.as_ref().map(|b| t + b.get_total())) + .try_fold(BigDecimal::from(0), |total, (_, addr_info)| { + addr_info.balances.as_ref().map(|b| total + b.get_total()) }), EthWithTokensActivationResult::HD(result) => result .wallet_balance @@ -311,10 +311,7 @@ impl PlatformCoinWithTokensActivationOps for EthCoin { }, None => return Ok(None), }; - let nft_global = self - .initialize_global_nft(url, proxy_auth) - .await - .map_mm_err::()?; + let nft_global = self.initialize_global_nft(url, proxy_auth).await.map_mm_err()?; Ok(Some(MmCoinEnum::EthCoin(nft_global))) } @@ -460,7 +457,7 @@ impl PlatformCoinWithTokensActivationOps for EthCoin { fn start_history_background_fetching( &self, _ctx: MmArc, - _storage: impl TxHistoryStorage + Send + 'static, + _storage: impl TxHistoryStorage + 'static, _initial_balance: Option, ) { } @@ -479,7 +476,7 @@ async fn eth_priv_key_build_policy( ) -> MmResult { match activation_policy { EthPrivKeyActivationPolicy::ContextPrivKey => { - Ok(EthPrivKeyBuildPolicy::detect_priv_key_policy(ctx).map_mm_err::()?) + Ok(EthPrivKeyBuildPolicy::detect_priv_key_policy(ctx).map_mm_err()?) }, #[cfg(target_arch = "wasm32")] EthPrivKeyActivationPolicy::Metamask => { diff --git a/mm2src/coins_activation/src/init_token.rs b/mm2src/coins_activation/src/init_token.rs index 2ed7b7b80d..5a72ce3d4a 100644 --- a/mm2src/coins_activation/src/init_token.rs +++ b/mm2src/coins_activation/src/init_token.rs @@ -94,7 +94,7 @@ where } let (token_conf, token_protocol): (_, Token::ProtocolInfo) = - coin_conf_with_protocol(&ctx, &request.ticker, request.protocol.clone()).map_mm_err::()?; + coin_conf_with_protocol(&ctx, &request.ticker, request.protocol.clone()).map_mm_err()?; let platform_coin = lp_coinfind_or_err(&ctx, token_protocol.platform_coin_ticker()) .await @@ -108,7 +108,7 @@ where let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) .map_to_mm(InitTokenError::Internal) - .map_mm_err::()?; + .map_mm_err()?; let spawner = ctx.spawner(); let task = InitTokenTask:: { ctx, @@ -155,9 +155,7 @@ pub async fn init_token_user_action( let mut task_manager = Token::rpc_task_manager(&coins_act_ctx) .lock() .map_to_mm(|poison| InitTokenUserActionError::Internal(poison.to_string()))?; - task_manager - .on_user_action(req.task_id, req.user_action) - .map_mm_err::()?; + task_manager.on_user_action(req.task_id, req.user_action).map_mm_err()?; Ok(SuccessResponse::new()) } @@ -170,9 +168,7 @@ pub async fn cancel_init_token( let mut task_manager = Standalone::rpc_task_manager(&coins_act_ctx) .lock() .map_to_mm(|poison| CancelInitTokenError::Internal(poison.to_string()))?; - task_manager - .cancel_task(req.task_id) - .map_mm_err::()?; + task_manager.cancel_task(req.task_id).map_mm_err()?; Ok(SuccessResponse::new()) } @@ -236,10 +232,7 @@ where log::info!("{} current block {}", ticker, activation_result.current_block()); let coins_ctx = CoinsContext::from_ctx(&self.ctx).unwrap(); - coins_ctx - .add_token(token.clone().into()) - .await - .map_mm_err::()?; + coins_ctx.add_token(token.clone().into()).await.map_mm_err()?; self.platform_coin.register_token_info(&token); diff --git a/mm2src/coins_activation/src/l2/init_l2.rs b/mm2src/coins_activation/src/l2/init_l2.rs index 5271cd36f2..d08537fd1a 100644 --- a/mm2src/coins_activation/src/l2/init_l2.rs +++ b/mm2src/coins_activation/src/l2/init_l2.rs @@ -81,8 +81,8 @@ where } let (coin_conf_json, protocol_conf): (Json, L2::ProtocolInfo) = - coin_conf_with_protocol(&ctx, &ticker, None).map_mm_err::()?; - let coin_conf = L2::coin_conf_from_json(coin_conf_json).map_mm_err::()?; + coin_conf_with_protocol(&ctx, &ticker, None).map_mm_err()?; + let coin_conf = L2::coin_conf_from_json(coin_conf_json).map_mm_err()?; let platform_coin = lp_coinfind_or_err(&ctx, protocol_conf.platform_coin_ticker()) .await @@ -94,13 +94,13 @@ where l2_ticker: ticker.clone(), })?; - L2::validate_platform_configuration(&platform_coin).map_mm_err::()?; + L2::validate_platform_configuration(&platform_coin).map_mm_err()?; - let validated_params = L2::validate_activation_params(req.activation_params.clone()).map_mm_err::()?; + let validated_params = L2::validate_activation_params(req.activation_params.clone()).map_mm_err()?; let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) .map_to_mm(InitL2Error::Internal) - .map_mm_err::()?; + .map_mm_err()?; let spawner = ctx.spawner(); let task = InitL2Task:: { ctx, @@ -130,7 +130,7 @@ where { let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) .map_to_mm(InitL2StatusError::Internal) - .map_mm_err::()?; + .map_mm_err()?; let mut task_manager = L2::rpc_task_manager(&coins_act_ctx) .lock() .map_to_mm(|poison| InitL2StatusError::Internal(poison.to_string()))?; @@ -146,13 +146,11 @@ pub async fn init_l2_user_action( ) -> MmResult { let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) .map_to_mm(InitL2UserActionError::Internal) - .map_mm_err::()?; + .map_mm_err()?; let mut task_manager = L2::rpc_task_manager(&coins_act_ctx) .lock() .map_to_mm(|poison| InitL2UserActionError::Internal(poison.to_string()))?; - task_manager - .on_user_action(req.task_id, req.user_action) - .map_mm_err::()?; + task_manager.on_user_action(req.task_id, req.user_action).map_mm_err()?; Ok(SuccessResponse::new()) } @@ -162,11 +160,11 @@ pub async fn cancel_init_l2( ) -> MmResult { let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) .map_to_mm(CancelInitL2Error::Internal) - .map_mm_err::()?; + .map_mm_err()?; let mut task_manager = L2::rpc_task_manager(&coins_act_ctx) .lock() .map_to_mm(|poison| CancelInitL2Error::Internal(poison.to_string())) - .map_mm_err::()?; + .map_mm_err()?; task_manager.cancel_task(req.task_id).map_mm_err()?; Ok(SuccessResponse::new()) } diff --git a/mm2src/coins_activation/src/l2/mod.rs b/mm2src/coins_activation/src/l2/mod.rs index f1b0f93614..51539dbdb2 100644 --- a/mm2src/coins_activation/src/l2/mod.rs +++ b/mm2src/coins_activation/src/l2/mod.rs @@ -1,6 +1,5 @@ mod init_l2; mod init_l2_error; -pub use init_l2::{cancel_init_l2, init_l2, init_l2_status, init_l2_user_action, InitL2ActivationOps, - InitL2InitialStatus, InitL2Task, InitL2TaskHandleShared, InitL2TaskManagerShared, L2ProtocolParams}; +pub use init_l2::*; pub use init_l2_error::InitL2Error; diff --git a/mm2src/coins_activation/src/platform_coin_with_tokens.rs b/mm2src/coins_activation/src/platform_coin_with_tokens.rs index a53223f1ff..4179f9c85f 100644 --- a/mm2src/coins_activation/src/platform_coin_with_tokens.rs +++ b/mm2src/coins_activation/src/platform_coin_with_tokens.rs @@ -140,7 +140,8 @@ where let token_params = tokens_requests .into_iter() .map(|req| -> Result<_, MmError> { - let (token_conf, protocol) = coin_conf_with_protocol(ctx, &req.ticker, req.protocol.clone())?; + let (token_conf, protocol) = + coin_conf_with_protocol(ctx, &req.ticker, req.protocol.clone()).map_mm_err()?; Ok(TokenActivationParams { ticker: req.ticker, conf: token_conf, @@ -150,12 +151,9 @@ where }) }) .collect::, _>>() - .map_mm_err::()?; + .map_mm_err()?; - let tokens = self - .enable_tokens(token_params) - .await - .map_mm_err::()?; + let tokens = self.enable_tokens(token_params).await.map_mm_err()?; for token in tokens.iter() { self.platform_coin().register_token_info(token); } @@ -395,18 +393,16 @@ where .enable_tokens_as_mm_coins(&ctx, &req.request) .await .map_mm_err()?; + mm_tokens.extend(tokens); } - let nft_global = platform_coin - .enable_global_nft(&req.request) - .await - .map_mm_err::()?; + let nft_global = platform_coin.enable_global_nft(&req.request).await.map_mm_err()?; let activation_result = platform_coin .get_activation_result(task_handle, &req.request, &nft_global) .await - .map_mm_err::()?; + .map_mm_err()?; log::info!("{} current block {}", req.ticker, activation_result.current_block()); let coins_ctx = CoinsContext::from_ctx(&ctx).unwrap(); @@ -453,8 +449,7 @@ where )); } - let (platform_conf, platform_protocol) = - coin_conf_with_protocol(&ctx, &req.ticker, None).map_mm_err::()?; + let (platform_conf, platform_protocol) = coin_conf_with_protocol(&ctx, &req.ticker, None).map_mm_err()?; let platform_coin = Platform::enable_platform_coin( ctx.clone(), @@ -464,7 +459,7 @@ where platform_protocol, ) .await - .map_mm_err::()?; + .map_mm_err()?; let mut mm_tokens = Vec::new(); for initializer in platform_coin.token_initializers() { @@ -475,23 +470,18 @@ where mm_tokens.extend(tokens); } - let nft_global = platform_coin - .enable_global_nft(&req.request) - .await - .map_mm_err::()?; + let nft_global = platform_coin.enable_global_nft(&req.request).await.map_mm_err()?; let activation_result = platform_coin .get_activation_result(task_handle, &req.request, &nft_global) .await - .map_mm_err::()?; + .map_mm_err()?; log::info!("{} current block {}", req.ticker, activation_result.current_block()); if req.request.tx_history() { platform_coin.start_history_background_fetching( ctx.clone(), - TxHistoryStorageBuilder::new(&ctx) - .build() - .map_mm_err::()?, + TxHistoryStorageBuilder::new(&ctx).build().map_mm_err()?, activation_result.get_platform_balance(), ); } @@ -631,14 +621,12 @@ where { let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) .map_to_mm(InitPlatformCoinWithTokensUserActionError::Internal) - .map_mm_err::()?; + .map_mm_err()?; let mut task_manager = Platform::rpc_task_manager(&coins_act_ctx) .lock() .map_to_mm(|poison| InitPlatformCoinWithTokensUserActionError::Internal(poison.to_string())) - .map_mm_err::()?; - task_manager - .on_user_action(req.task_id, req.user_action) - .map_mm_err::()?; + .map_mm_err()?; + task_manager.on_user_action(req.task_id, req.user_action).map_mm_err()?; Ok(SuccessResponse::new()) } @@ -652,14 +640,12 @@ where { let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) .map_to_mm(CancelInitPlatformCoinWithTokensError::Internal) - .map_mm_err::()?; + .map_mm_err()?; let mut task_manager = Platform::rpc_task_manager(&coins_act_ctx) .lock() .map_to_mm(|poison| CancelInitPlatformCoinWithTokensError::Internal(poison.to_string())) - .map_mm_err::()?; - task_manager - .cancel_task(req.task_id) - .map_mm_err::()?; + .map_mm_err()?; + task_manager.cancel_task(req.task_id).map_mm_err()?; Ok(SuccessResponse::new()) } diff --git a/mm2src/coins_activation/src/standalone_coin/init_standalone_coin.rs b/mm2src/coins_activation/src/standalone_coin/init_standalone_coin.rs index 12a5af5d29..f97c46924a 100644 --- a/mm2src/coins_activation/src/standalone_coin/init_standalone_coin.rs +++ b/mm2src/coins_activation/src/standalone_coin/init_standalone_coin.rs @@ -92,12 +92,11 @@ where return MmError::err(InitStandaloneCoinError::CoinIsAlreadyActivated { ticker: request.ticker }); } - let (coin_conf, protocol_info) = - coin_conf_with_protocol(&ctx, &request.ticker, None).map_mm_err::()?; + let (coin_conf, protocol_info) = coin_conf_with_protocol(&ctx, &request.ticker, None).map_mm_err()?; let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) .map_to_mm(InitStandaloneCoinError::Internal) - .map_mm_err::()?; + .map_mm_err()?; let spawner = ctx.spawner(); let task = InitStandaloneCoinTask:: { @@ -145,14 +144,12 @@ pub async fn init_standalone_coin_user_action MmResult { let coins_act_ctx = CoinsActivationContext::from_ctx(&ctx) .map_to_mm(InitStandaloneCoinUserActionError::Internal) - .map_mm_err::()?; + .map_mm_err()?; let mut task_manager = Standalone::rpc_task_manager(&coins_act_ctx) .lock() .map_to_mm(|poison| InitStandaloneCoinUserActionError::Internal(poison.to_string())) - .map_mm_err::()?; - task_manager - .on_user_action(req.task_id, req.user_action) - .map_mm_err::()?; + .map_mm_err()?; + task_manager.on_user_action(req.task_id, req.user_action).map_mm_err()?; Ok(SuccessResponse::new()) } @@ -164,10 +161,8 @@ pub async fn cancel_init_standalone_coin()?; - task_manager - .cancel_task(req.task_id) - .map_mm_err::()?; + .map_mm_err()?; + task_manager.cancel_task(req.task_id).map_mm_err()?; Ok(SuccessResponse::new()) } @@ -216,12 +211,12 @@ where task_handle.clone(), ) .await - .map_mm_err::()?; + .map_mm_err()?; let result = coin .get_activation_result(self.ctx.clone(), task_handle, &self.request.activation_params) .await - .map_mm_err::()?; + .map_mm_err()?; log::info!("{} current block {}", ticker, result.current_block()); let tx_history = self.request.activation_params.tx_history(); @@ -229,9 +224,7 @@ where let current_balances = result.get_addresses_balances(); coin.start_history_background_fetching( self.ctx.metrics.clone(), - TxHistoryStorageBuilder::new(&self.ctx) - .build() - .map_mm_err::()?, + TxHistoryStorageBuilder::new(&self.ctx).build().map_mm_err()?, self.ctx.event_stream_manager.clone(), current_balances, ); @@ -239,7 +232,7 @@ where lp_register_coin(&self.ctx, coin.into(), RegisterCoinParams { ticker }) .await - .map_mm_err::()?; + .map_mm_err()?; Ok(result) } diff --git a/mm2src/coins_activation/src/standalone_coin/mod.rs b/mm2src/coins_activation/src/standalone_coin/mod.rs index 0ab208abc2..26afd8bc51 100644 --- a/mm2src/coins_activation/src/standalone_coin/mod.rs +++ b/mm2src/coins_activation/src/standalone_coin/mod.rs @@ -4,6 +4,6 @@ mod init_standalone_coin_error; pub use init_standalone_coin::{cancel_init_standalone_coin, init_standalone_coin, init_standalone_coin_status, init_standalone_coin_user_action, InitStandaloneCoinActivationOps, InitStandaloneCoinInitialStatus, InitStandaloneCoinReq, - InitStandaloneCoinStatusRequest, InitStandaloneCoinTask, - InitStandaloneCoinTaskHandleShared, InitStandaloneCoinTaskManagerShared}; + InitStandaloneCoinStatusRequest, InitStandaloneCoinTaskHandleShared, + InitStandaloneCoinTaskManagerShared}; pub use init_standalone_coin_error::InitStandaloneCoinError; diff --git a/mm2src/coins_activation/src/token.rs b/mm2src/coins_activation/src/token.rs index 46fb9b1a58..9b78102483 100644 --- a/mm2src/coins_activation/src/token.rs +++ b/mm2src/coins_activation/src/token.rs @@ -128,7 +128,7 @@ where } let (token_conf, token_protocol): (_, Token::ProtocolInfo) = - coin_conf_with_protocol(&ctx, &req.ticker, req.protocol.clone()).map_mm_err::()?; + coin_conf_with_protocol(&ctx, &req.ticker, req.protocol.clone()).map_mm_err()?; let platform_coin = lp_coinfind_or_err(&ctx, token_protocol.platform_coin_ticker()) .await @@ -150,13 +150,10 @@ where req.protocol.is_some(), ) .await - .map_mm_err::()?; + .map_mm_err()?; let coins_ctx = CoinsContext::from_ctx(&ctx).unwrap(); - coins_ctx - .add_token(token.clone().into()) - .await - .map_mm_err::()?; + coins_ctx.add_token(token.clone().into()).await.map_mm_err()?; platform_coin.register_token_info(&token); diff --git a/mm2src/common/build.rs b/mm2src/common/build.rs index 0230591b5b..c69d12de3a 100644 --- a/mm2src/common/build.rs +++ b/mm2src/common/build.rs @@ -48,7 +48,7 @@ fn _in_place(path: &dyn AsRef, update: &mut dyn FnMut(Vec) -> Vec) /// Please expand this enum if it is necessary. enum TargetArch { Wasm32, - Other(String), + Other, } impl TargetArch { @@ -67,7 +67,7 @@ impl From for TargetArch { fn from(arch: String) -> Self { match arch.as_str() { "wasm32" => TargetArch::Wasm32, - _ => TargetArch::Other(arch), + _ => TargetArch::Other, } } } diff --git a/mm2src/common/common.rs b/mm2src/common/common.rs index 7896df9d1d..1ab66c50e1 100644 --- a/mm2src/common/common.rs +++ b/mm2src/common/common.rs @@ -11,9 +11,7 @@ //! binary #![allow(uncommon_codepoints)] -#![feature(integer_atomics, panic_info_message)] -#![feature(async_closure)] -#![feature(drain_filter)] +#![feature(hash_raw_entry)] #[macro_use] extern crate arrayref; #[macro_use] extern crate gstuff; @@ -173,7 +171,7 @@ use std::mem::{forget, zeroed}; use std::num::{NonZeroUsize, TryFromIntError}; use std::ops::{Add, Deref, Div, RangeInclusive}; use std::os::raw::c_void; -use std::panic::{set_hook, PanicInfo}; +use std::panic::{set_hook, PanicHookInfo}; use std::path::{Path, PathBuf}; use std::ptr::read_volatile; use std::sync::atomic::Ordering; @@ -355,7 +353,7 @@ pub fn filename(path: &str) -> &str { // whereas the error trace might be coming from another operating system. // In particular, I see `file_name` failing with WASM. - let name = match path.rfind(|ch| ch == '/' || ch == '\\') { + let name = match path.rfind(['/', '\\']) { Some(ofs) => &path[ofs + 1..], None => path, }; @@ -493,7 +491,7 @@ fn output_pc_mem_addr(output: &mut dyn FnMut(&str)) { /// (The default Rust handler doesn't have the means to print the message). #[cfg(target_arch = "wasm32")] pub fn set_panic_hook() { - set_hook(Box::new(|info: &PanicInfo| { + set_hook(Box::new(|info: &PanicHookInfo| { let mut trace = String::new(); stack_trace(&mut stack_trace_frame, &mut |l| trace.push_str(l)); console_err!("{}", info); @@ -509,9 +507,9 @@ pub fn set_panic_hook() { pub fn set_panic_hook() { use std::sync::atomic::AtomicBool; - thread_local! {static ENTERED: AtomicBool = AtomicBool::new(false);} + thread_local! {static ENTERED: AtomicBool = const { AtomicBool::new(false) };} - set_hook(Box::new(|info: &PanicInfo| { + set_hook(Box::new(|info: &PanicHookInfo| { // Stack tracing and logging might panic (in `println!` for example). // Let us detect this and do nothing on second panic. // We'll likely still get a crash after the hook is finished @@ -773,6 +771,7 @@ static mut PROCESS_LOG_TAIL: [u8; 0x10000] = [0; 0x10000]; static TAIL_CUR: AtomicUsize = AtomicUsize::new(0); /// Keep a tail of the log in RAM for the integration tests. +#[allow(static_mut_refs)] // TODO: Refactor PROCESS_LOG_TAIL to use lazystatic #[cfg(target_arch = "wasm32")] pub fn append_log_tail(line: &str) { unsafe { diff --git a/mm2src/common/jsonrpc_client.rs b/mm2src/common/jsonrpc_client.rs index 3f9e4cf6f6..96669d160a 100644 --- a/mm2src/common/jsonrpc_client.rs +++ b/mm2src/common/jsonrpc_client.rs @@ -331,6 +331,7 @@ pub trait JsonRpcBatchClient: JsonRpcClient { } /// Validates the given batch requests if they all have unique IDs. + #[allow(clippy::result_large_err)] fn validate_batch_request(&self, request: &JsonRpcBatchRequest) -> Result<(), JsonRpcError> { if request.orig_sequence_ids().all_unique() { return Ok(()); diff --git a/mm2src/common/log.rs b/mm2src/common/log.rs index 41116073ca..14b0403b79 100644 --- a/mm2src/common/log.rs +++ b/mm2src/common/log.rs @@ -114,7 +114,7 @@ impl Gravity { thread_local! { /// If set, pulls the `chunk2log` (aka `log!`) invocations into the gravity of another thread. - static GRAVITY: RefCell>> = RefCell::new (None) + static GRAVITY: RefCell>> = const { RefCell::new (None) } } #[doc(hidden)] @@ -333,7 +333,7 @@ impl<'a> TagParam<'a> for &'a str { fn val(&self) -> Option { None } } -impl<'a> TagParam<'a> for String { +impl TagParam<'_> for String { fn key(&self) -> String { self.clone() } fn val(&self) -> Option { None } } @@ -353,7 +353,7 @@ impl<'a> TagParam<'a> for (&'a str, i32) { fn val(&self) -> Option { Some(self.1.to_string()) } } -impl<'a> TagParam<'a> for (String, String) { +impl TagParam<'_> for (String, String) { fn key(&self) -> String { self.0.clone() } fn val(&self) -> Option { Some(self.1.clone()) } } @@ -1046,11 +1046,8 @@ impl Drop for LogState { } } -#[derive(Debug)] -pub struct UnknownLogLevel(String); - impl FromStr for LogLevel { - type Err = UnknownLogLevel; + type Err = String; fn from_str(s: &str) -> Result { match s.to_lowercase().as_str() { @@ -1060,7 +1057,7 @@ impl FromStr for LogLevel { "info" => Ok(LogLevel::Info), "debug" => Ok(LogLevel::Debug), "trace" => Ok(LogLevel::Trace), - _ => Err(UnknownLogLevel(s.to_owned())), + _ => Err(s.to_owned()), } } } diff --git a/mm2src/common/number_type_casting.rs b/mm2src/common/number_type_casting.rs index 7d68029869..63dcd41521 100644 --- a/mm2src/common/number_type_casting.rs +++ b/mm2src/common/number_type_casting.rs @@ -21,7 +21,7 @@ macro_rules! impl_safe_number_type_cast { ($from: ident, $to: ident) => { impl SafeTypeCastingNumbers<$to> for $from { fn into_or(self, or: $to) -> $to { std::convert::TryFrom::try_from(self).unwrap_or(or) } - fn into_or_max(self) -> $to { std::convert::TryFrom::try_from(self).unwrap_or(std::$to::MAX) } + fn into_or_max(self) -> $to { std::convert::TryFrom::try_from(self).unwrap_or($to::MAX) } } }; } diff --git a/mm2src/common/seri.rs b/mm2src/common/seri.rs index a3a8ab3cc5..080dfa4dc0 100644 --- a/mm2src/common/seri.rs +++ b/mm2src/common/seri.rs @@ -6,7 +6,7 @@ use std::fmt; /// Use with `#[serde(default, deserialize_with = "de_none_if_empty")]`. pub fn de_none_if_empty<'de, D: Deserializer<'de>>(des: D) -> Result, D::Error> { struct Visitor; - impl<'de> de::Visitor<'de> for Visitor { + impl de::Visitor<'_> for Visitor { type Value = Option; fn expecting(&self, fm: &mut fmt::Formatter) -> fmt::Result { fm.write_str("Optional string") } diff --git a/mm2src/common/shared_ref_counter/src/enable.rs b/mm2src/common/shared_ref_counter/src/enable.rs index 581a5c1cc6..9654d894ce 100644 --- a/mm2src/common/shared_ref_counter/src/enable.rs +++ b/mm2src/common/shared_ref_counter/src/enable.rs @@ -136,11 +136,7 @@ impl WeakRc { /// This behavior is considered acceptable since the `enable` feature is expected to be used for **debug** purposes only. #[track_caller] pub fn upgrade(&self) -> Option> { - let inner = match self.inner.upgrade() { - Some(ctx) => ctx, - None => return None, - }; - + let inner = self.inner.upgrade()?; let next_index = self.next_index.upgrade().expect(UPGRADING_ERROR); let index = next_index.fetch_add(1, Ordering::Relaxed); diff --git a/mm2src/crypto/src/global_hd_ctx.rs b/mm2src/crypto/src/global_hd_ctx.rs index a2a3bb159a..6496065ab4 100644 --- a/mm2src/crypto/src/global_hd_ctx.rs +++ b/mm2src/crypto/src/global_hd_ctx.rs @@ -1,3 +1,5 @@ +#![allow(non_local_definitions)] + use crate::privkey::{bip39_seed_from_passphrase, key_pair_from_secret, PrivKeyError}; use crate::{mm2_internal_der_path, Bip32Error, CryptoInitError, CryptoInitResult}; use bip32::{DerivationPath, ExtendedPrivateKey}; diff --git a/mm2src/db_common/src/sql_constraint.rs b/mm2src/db_common/src/sql_constraint.rs index fa1592eba6..fe031c4fbb 100644 --- a/mm2src/db_common/src/sql_constraint.rs +++ b/mm2src/db_common/src/sql_constraint.rs @@ -237,7 +237,7 @@ pub mod foreign_key { action: &'a Action, } - impl<'a> fmt::Display for ActionOnEvent<'a> { + impl fmt::Display for ActionOnEvent<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{} {}", self.event, self.action) } } } diff --git a/mm2src/db_common/src/sql_delete.rs b/mm2src/db_common/src/sql_delete.rs index eac48b9e77..42e03ef359 100644 --- a/mm2src/db_common/src/sql_delete.rs +++ b/mm2src/db_common/src/sql_delete.rs @@ -60,7 +60,7 @@ impl<'a> SqlDelete<'a> { /// - [`SqlQuery::or_where_in`] /// - [`SqlQuery::or_where_in_quoted`] /// - [`SqlQuery::or_where_in_params`] -impl<'a> SqlCondition for SqlDelete<'a> { +impl SqlCondition for SqlDelete<'_> { fn sql_builder(&mut self) -> &mut SqlBuilder { &mut self.sql_builder } fn sql_params(&mut self) -> &mut SqlParamsBuilder { &mut self.params } diff --git a/mm2src/db_common/src/sql_query.rs b/mm2src/db_common/src/sql_query.rs index 170939c18a..a284faae60 100644 --- a/mm2src/db_common/src/sql_query.rs +++ b/mm2src/db_common/src/sql_query.rs @@ -348,7 +348,7 @@ impl<'a> SqlQuery<'a> { /// - [`SqlQuery::or_where_in`] /// - [`SqlQuery::or_where_in_quoted`] /// - [`SqlQuery::or_where_in_params`] -impl<'a> SqlCondition for SqlQuery<'a> { +impl SqlCondition for SqlQuery<'_> { fn sql_builder(&mut self) -> &mut SqlBuilder { &mut self.sql_builder } fn sql_params(&mut self) -> &mut SqlParamsBuilder { &mut self.params } diff --git a/mm2src/db_common/src/sql_update.rs b/mm2src/db_common/src/sql_update.rs index 2d4dbca6f6..5b955d979d 100644 --- a/mm2src/db_common/src/sql_update.rs +++ b/mm2src/db_common/src/sql_update.rs @@ -106,7 +106,7 @@ impl<'a> SqlUpdate<'a> { /// - [`SqlUpdate::or_where_in`] /// - [`SqlUpdate::or_where_in_quoted`] /// - [`SqlUpdate::or_where_in_params`] -impl<'a> SqlCondition for SqlUpdate<'a> { +impl SqlCondition for SqlUpdate<'_> { fn sql_builder(&mut self) -> &mut SqlBuilder { &mut self.sql_builder } fn sql_params(&mut self) -> &mut SqlParamsBuilder { &mut self.params } diff --git a/mm2src/derives/enum_derives/src/lib.rs b/mm2src/derives/enum_derives/src/lib.rs index 666e95a0e3..4f3cf5c67e 100644 --- a/mm2src/derives/enum_derives/src/lib.rs +++ b/mm2src/derives/enum_derives/src/lib.rs @@ -93,7 +93,7 @@ pub fn enum_from_trait(input: TokenStream) -> TokenStream { /// /// ### USAGE: /// -/// ```rust +/// ```ignore /// use enum_derives::EnumFromStringify; /// use std::fmt::{Display, Formatter}; /// use std::io::{Error, ErrorKind}; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/event.rs b/mm2src/kdf_walletconnect/src/session/rpc/event.rs index 62159e6b91..2c93dd22d3 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/event.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/event.rs @@ -32,7 +32,7 @@ pub async fn handle_session_event( ctx.validate_chain_id(&session, &chain_id)?; - if session.get_active_chain_id().as_ref().map_or(false, |c| c == &chain_id) { + if session.get_active_chain_id().as_ref() == Some(&chain_id) { return Ok(()); }; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/update.rs b/mm2src/kdf_walletconnect/src/session/rpc/update.rs index e15793fe76..e93c1a459f 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/update.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/update.rs @@ -24,7 +24,7 @@ pub(crate) async fn reply_session_update_request( .caip2_validate() .map_to_mm(|err| WalletConnectError::InternalError(err.to_string()))?; session.namespaces = update.namespaces.0; - let session = session; + info!("Updated extended, info: {:?}", session.topic); } diff --git a/mm2src/kdf_walletconnect/src/storage/mod.rs b/mm2src/kdf_walletconnect/src/storage/mod.rs index 7fee54c535..4f4077fb6f 100644 --- a/mm2src/kdf_walletconnect/src/storage/mod.rs +++ b/mm2src/kdf_walletconnect/src/storage/mod.rs @@ -16,8 +16,10 @@ pub(crate) trait WalletConnectStorageOps { type Error: std::fmt::Debug + NotMmError + Send; async fn init(&self) -> MmResult<(), Self::Error>; + #[expect(dead_code)] async fn is_initialized(&self) -> MmResult; async fn save_session(&self, session: &Session) -> MmResult<(), Self::Error>; + #[allow(dead_code)] async fn get_session(&self, topic: &Topic) -> MmResult, Self::Error>; async fn get_all_sessions(&self) -> MmResult, Self::Error>; async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error>; diff --git a/mm2src/mm2_bin_lib/src/mm2_native_lib.rs b/mm2src/mm2_bin_lib/src/mm2_native_lib.rs index 8ca51fd4f2..374fd9d630 100644 --- a/mm2src/mm2_bin_lib/src/mm2_native_lib.rs +++ b/mm2src/mm2_bin_lib/src/mm2_native_lib.rs @@ -108,7 +108,7 @@ pub unsafe extern "C" fn mm2_main(conf: *const c_char, log_cb: extern "C" fn(lin }; let rc = thread::Builder::new().name("lp_run".into()).spawn(move || { - match catch_unwind(move || { + let c = catch_unwind(move || { let ctx = match MmArc::from_ffi_handle(ctx_id) { Ok(ctx) => ctx, Err(err) => { @@ -116,7 +116,8 @@ pub unsafe extern "C" fn mm2_main(conf: *const c_char, log_cb: extern "C" fn(lin }, }; block_on(mm2_main::lp_run(ctx)); - }) { + }); + match c { Ok(_) => log!("MM2 thread completed normally"), Err(err) => { log!("MM2 thread panicked: {:?}", any_to_str(&*err)); diff --git a/mm2src/mm2_bitcoin/chain/Cargo.toml b/mm2src/mm2_bitcoin/chain/Cargo.toml index 3f85ae7db7..c13290a413 100644 --- a/mm2src/mm2_bitcoin/chain/Cargo.toml +++ b/mm2src/mm2_bitcoin/chain/Cargo.toml @@ -2,6 +2,7 @@ name = "chain" version = "0.1.0" authors = ["debris "] +edition = "2015" [lib] doctest = false diff --git a/mm2src/mm2_bitcoin/chain/src/block_header.rs b/mm2src/mm2_bitcoin/chain/src/block_header.rs index fcb5200dae..2d819fc280 100644 --- a/mm2src/mm2_bitcoin/chain/src/block_header.rs +++ b/mm2src/mm2_bitcoin/chain/src/block_header.rs @@ -157,11 +157,8 @@ impl Serializable for BlockHeader { if let Some(claim) = &self.claim_trie_root { s.append(claim); } - match &self.hash_final_sapling_root { - Some(h) => { - s.append(h); - }, - None => (), + if let Some(h) = &self.hash_final_sapling_root { + s.append(h); }; s.append(&self.time); s.append(&self.bits); @@ -379,7 +376,7 @@ impl From for ExtBlockHeader { #[cfg(test)] mod tests { - use super::ExtBlockHeader; + #[cfg(not(target_arch = "wasm32"))] use super::ExtBlockHeader; use block_header::{BlockHeader, BlockHeaderBits, BlockHeaderNonce, AUX_POW_VERSION_DOGE, AUX_POW_VERSION_NMC, AUX_POW_VERSION_SYS, BIP9_NO_SOFT_FORK_BLOCK_HEADER_VERSION, KAWPOW_VERSION, MTP_POW_VERSION, PROG_POW_SWITCH_TIME}; @@ -2510,6 +2507,7 @@ mod tests { assert_eq!(serialized.take(), header_bytes); } + #[cfg(not(target_arch = "wasm32"))] #[test] fn test_from_blockheader_to_ext_blockheader() { // https://live.blockcypher.com/btc/block/00000000000000000020cf2bdc6563fb25c424af588d5fb7223461e72715e4a9/ diff --git a/mm2src/mm2_bitcoin/chain/src/transaction.rs b/mm2src/mm2_bitcoin/chain/src/transaction.rs index 16ccc1a680..acc3218ba6 100644 --- a/mm2src/mm2_bitcoin/chain/src/transaction.rs +++ b/mm2src/mm2_bitcoin/chain/src/transaction.rs @@ -620,7 +620,8 @@ impl Deserializable for Transaction { #[cfg(test)] mod tests { - use super::{Bytes, ExtTransaction, OutPoint, Transaction, TransactionInput, TransactionOutput}; + #[cfg(not(target_arch = "wasm32"))] use super::ExtTransaction; + use super::{Bytes, OutPoint, Transaction, TransactionInput, TransactionOutput}; use hash::{H256, H512}; use hex::ToHex; use ser::{deserialize, serialize, serialize_with_flags, Serializable, SERIALIZE_TRANSACTION_WITNESS}; @@ -1103,6 +1104,7 @@ mod tests { assert_eq!(actual, expected); } + #[cfg(not(target_arch = "wasm32"))] #[test] fn test_from_tx_to_ext_tx() { // https://live.blockcypher.com/btc-testnet/tx/2be90e03abb4d5328bf7e9467ca9c571aef575837b55f1253119b87e85ccb94f/ diff --git a/mm2src/mm2_bitcoin/crypto/Cargo.toml b/mm2src/mm2_bitcoin/crypto/Cargo.toml index 1ca5ee8257..b418950be0 100644 --- a/mm2src/mm2_bitcoin/crypto/Cargo.toml +++ b/mm2src/mm2_bitcoin/crypto/Cargo.toml @@ -2,6 +2,7 @@ name = "bitcrypto" version = "0.1.0" authors = ["debris "] +edition = "2015" [lib] doctest = false diff --git a/mm2src/mm2_bitcoin/keys/Cargo.toml b/mm2src/mm2_bitcoin/keys/Cargo.toml index e840322fd1..9acf887d18 100644 --- a/mm2src/mm2_bitcoin/keys/Cargo.toml +++ b/mm2src/mm2_bitcoin/keys/Cargo.toml @@ -2,6 +2,7 @@ name = "keys" version = "0.1.0" authors = ["debris "] +edition = "2015" [lib] doctest = false diff --git a/mm2src/mm2_bitcoin/keys/src/address.rs b/mm2src/mm2_bitcoin/keys/src/address.rs index 224b886bb4..adf72131ff 100644 --- a/mm2src/mm2_bitcoin/keys/src/address.rs +++ b/mm2src/mm2_bitcoin/keys/src/address.rs @@ -518,12 +518,12 @@ mod tests { #[test] fn test_from_to_cashaddress() { - let cashaddresses = vec![ + let cashaddresses = [ "bitcoincash:qzxqqt9lh4feptf0mplnk58gnajfepzwcq9f2rxk55", "bitcoincash:qr6m7j9njldwwzlg9v7v53unlr4jkmx6eylep8ekg2", "bitcoincash:pq4ql3ph6738xuv2cycduvkpu4rdwqge5q2uxdfg6f", ]; - let expected = vec![ + let expected = [ "1DmFp16U73RrVZtYUbo2Ectt8mAnYScpqM", "1PQPheJQSauxRPTxzNMUco1XmoCyPoEJCp", "35XRC5HRZjih1sML23UXv1Ry1SzTDKSmfQ", diff --git a/mm2src/mm2_bitcoin/keys/src/address_prefixes.rs b/mm2src/mm2_bitcoin/keys/src/address_prefixes.rs index 1a20e4aa20..442cb05b3f 100644 --- a/mm2src/mm2_bitcoin/keys/src/address_prefixes.rs +++ b/mm2src/mm2_bitcoin/keys/src/address_prefixes.rs @@ -1,4 +1,4 @@ -use std::{convert::TryFrom, fmt, u8}; +use std::{convert::TryFrom, fmt}; /// Prefix for a legacy address (p2pkh or p2sh) #[derive(Debug, Clone, Eq, Hash, PartialEq, Default)] diff --git a/mm2src/mm2_bitcoin/keys/src/cashaddress.rs b/mm2src/mm2_bitcoin/keys/src/cashaddress.rs index ea7f43c2d6..d798d1501c 100644 --- a/mm2src/mm2_bitcoin/keys/src/cashaddress.rs +++ b/mm2src/mm2_bitcoin/keys/src/cashaddress.rs @@ -415,7 +415,7 @@ mod tests { #[test] fn test_base32() { // the raw arrays are 5-bit packed - the condition is required by base32 encode and decode functions - let raw = vec![ + let raw = [ vec![ 24, 14, 9, 25, 19, 30, 22, 1, 28, 0, 30, 28, 22, 7, 1, 11, 18, 7, 1, 7, 19, 23, 21, 30, 24, 25, 20, 27, 3, 27, 29, 10, @@ -429,7 +429,7 @@ mod tests { 15, 22, 11, 27, ], ]; - let encoded = vec![ + let encoded = [ "cwfen7kpuq7uk8ptj8p8nh47ce5mrma2", "gg0guaszp3e93yzg3405tcasx5tzkjk9", "vz4cqq9w8xkekl5fjv2xtu8wnf0a0ktm", @@ -447,14 +447,14 @@ mod tests { #[test] fn test_encode_decode() { - let encoded = vec![ + let encoded = [ "bitcoincash:pq4ql3ph6738xuv2cycduvkpu4rdwqge5q2uxdfg6f", "qrplwyx7kueqkrh6dmd3fclta6u32hafp5tnpkchx2", "BitCoinCash:QRPLWYX7KUEQKRH6DMD3FCLTA6U32HAFP5TNPKCHX2", "bchtest:qqjr7yu573z4faxw8ltgvjwpntwys08fysk07zmvce", "bchtest:pnq8zwpj8cq05n7pytfmskuk9r4gzzel8qtsvwz79zdskftrzxtar994cgutavfklvmgm6ynej", ]; - let expected_addresses = vec![ + let expected_addresses = [ CashAddress { prefix: "bitcoincash".into(), hash: vec![ diff --git a/mm2src/mm2_bitcoin/primitives/Cargo.toml b/mm2src/mm2_bitcoin/primitives/Cargo.toml index ac1000a9fb..4580cbb7d3 100644 --- a/mm2src/mm2_bitcoin/primitives/Cargo.toml +++ b/mm2src/mm2_bitcoin/primitives/Cargo.toml @@ -2,6 +2,7 @@ name = "primitives" version = "0.1.0" authors = ["debris "] +edition = "2015" [lib] doctest = false diff --git a/mm2src/mm2_bitcoin/primitives/src/bytes.rs b/mm2src/mm2_bitcoin/primitives/src/bytes.rs index 95f249e431..8b022bf46b 100644 --- a/mm2src/mm2_bitcoin/primitives/src/bytes.rs +++ b/mm2src/mm2_bitcoin/primitives/src/bytes.rs @@ -25,7 +25,7 @@ impl Bytes { pub fn split_off(&mut self, at: usize) -> Bytes { Bytes(self.0.split_off(at)) } } -impl<'a> From<&'a [u8]> for Bytes { +impl From<&[u8]> for Bytes { fn from(v: &[u8]) -> Self { Bytes(v.into()) } } diff --git a/mm2src/mm2_bitcoin/primitives/src/hash.rs b/mm2src/mm2_bitcoin/primitives/src/hash.rs index 7bf56f5700..80df5f8531 100644 --- a/mm2src/mm2_bitcoin/primitives/src/hash.rs +++ b/mm2src/mm2_bitcoin/primitives/src/hash.rs @@ -25,11 +25,7 @@ macro_rules! impl_hash { } impl Clone for $name { - fn clone(&self) -> Self { - let mut result = Self::default(); - result.copy_from_slice(&self.0); - result - } + fn clone(&self) -> Self { *self } } impl From<[u8; $size]> for $name { @@ -116,7 +112,7 @@ macro_rules! impl_hash { H: Hasher, { state.write(&self.0); - state.finish(); + let _ = state.finish(); } } diff --git a/mm2src/mm2_bitcoin/rpc/Cargo.toml b/mm2src/mm2_bitcoin/rpc/Cargo.toml index a9e0841695..ae2fec9dc2 100644 --- a/mm2src/mm2_bitcoin/rpc/Cargo.toml +++ b/mm2src/mm2_bitcoin/rpc/Cargo.toml @@ -2,6 +2,7 @@ name = "rpc" version = "0.1.0" authors = ["Ethcore "] +edition = "2015" [lib] doctest = false diff --git a/mm2src/mm2_bitcoin/rpc/src/v1/types/address.rs b/mm2src/mm2_bitcoin/rpc/src/v1/types/address.rs index bd8af944ac..5c9f06fd38 100644 --- a/mm2src/mm2_bitcoin/rpc/src/v1/types/address.rs +++ b/mm2src/mm2_bitcoin/rpc/src/v1/types/address.rs @@ -23,7 +23,7 @@ where #[derive(Default)] pub struct AddressVisitor; -impl<'b> Visitor<'b> for AddressVisitor { +impl Visitor<'_> for AddressVisitor { type Value = LegacyAddress; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("an address") } diff --git a/mm2src/mm2_bitcoin/rpc/src/v1/types/bytes.rs b/mm2src/mm2_bitcoin/rpc/src/v1/types/bytes.rs index 5368985a08..94d5b247ca 100644 --- a/mm2src/mm2_bitcoin/rpc/src/v1/types/bytes.rs +++ b/mm2src/mm2_bitcoin/rpc/src/v1/types/bytes.rs @@ -51,7 +51,7 @@ impl<'a> Deserialize<'a> for Bytes { struct BytesVisitor; -impl<'a> Visitor<'a> for BytesVisitor { +impl Visitor<'_> for BytesVisitor { type Value = Bytes; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a bytes") } diff --git a/mm2src/mm2_bitcoin/rpc/src/v1/types/hash.rs b/mm2src/mm2_bitcoin/rpc/src/v1/types/hash.rs index 08ae1d7afe..919a7049ab 100644 --- a/mm2src/mm2_bitcoin/rpc/src/v1/types/hash.rs +++ b/mm2src/mm2_bitcoin/rpc/src/v1/types/hash.rs @@ -131,11 +131,7 @@ macro_rules! impl_hash { } impl PartialOrd for $name { - fn partial_cmp(&self, other: &Self) -> Option { - let self_ref: &[u8] = &self.0; - let other_ref: &[u8] = &other.0; - self_ref.partial_cmp(other_ref) - } + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Hash for $name { diff --git a/mm2src/mm2_bitcoin/rpc/src/v1/types/script.rs b/mm2src/mm2_bitcoin/rpc/src/v1/types/script.rs index c2a44d2211..4e0eaf4d10 100644 --- a/mm2src/mm2_bitcoin/rpc/src/v1/types/script.rs +++ b/mm2src/mm2_bitcoin/rpc/src/v1/types/script.rs @@ -84,7 +84,7 @@ impl<'a> Deserialize<'a> for ScriptType { struct ScriptTypeVisitor; - impl<'b> Visitor<'b> for ScriptTypeVisitor { + impl Visitor<'_> for ScriptTypeVisitor { type Value = ScriptType; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("script type") } diff --git a/mm2src/mm2_bitcoin/script/Cargo.toml b/mm2src/mm2_bitcoin/script/Cargo.toml index 6a97b950b2..61cfd06e2b 100644 --- a/mm2src/mm2_bitcoin/script/Cargo.toml +++ b/mm2src/mm2_bitcoin/script/Cargo.toml @@ -2,6 +2,7 @@ name = "script" version = "0.1.0" authors = ["debris "] +edition = "2015" [lib] doctest = false diff --git a/mm2src/mm2_bitcoin/script/src/script.rs b/mm2src/mm2_bitcoin/script/src/script.rs index 8614961879..33300a7324 100644 --- a/mm2src/mm2_bitcoin/script/src/script.rs +++ b/mm2src/mm2_bitcoin/script/src/script.rs @@ -571,7 +571,7 @@ impl<'a> Iterator for Instructions<'a> { } } -impl<'a> Iterator for Opcodes<'a> { +impl Iterator for Opcodes<'_> { type Item = Result; fn next(&mut self) -> Option> { @@ -968,7 +968,7 @@ OP_ADD assert!(script.get_instruction(5).is_none()); assert!(script.get_instruction(10).is_none()); assert!(script.get_instruction(1245).is_none()); - assert!(script.get_instruction(99187829973).is_none()); + assert!(script.get_instruction(99187829).is_none()); } #[test] diff --git a/mm2src/mm2_bitcoin/script/src/sign.rs b/mm2src/mm2_bitcoin/script/src/sign.rs index 089c25a614..a0115172d1 100644 --- a/mm2src/mm2_bitcoin/script/src/sign.rs +++ b/mm2src/mm2_bitcoin/script/src/sign.rs @@ -42,7 +42,6 @@ impl From for u32 { fn from(s: SighashBase) -> Self { s as u32 } } -#[cfg_attr(feature = "cargo-clippy", allow(clippy::doc_markdown))] /// Signature hash type. [Documentation](https://en.bitcoin.it/wiki/OP_CHECKSIG#Procedure_for_Hashtype_SIGHASH_SINGLE) #[derive(Debug, PartialEq, Clone, Copy)] pub struct Sighash { @@ -82,7 +81,7 @@ impl Sighash { }; // Only exact All | None | Single values are passing this check - matches!(u, 1 | 2 | 3) + matches!(u, 1..=3) } /// Creates Sighash from any u, even if is_defined() == false diff --git a/mm2src/mm2_bitcoin/serialization/Cargo.toml b/mm2src/mm2_bitcoin/serialization/Cargo.toml index 6a843442a2..3a0298bb5d 100644 --- a/mm2src/mm2_bitcoin/serialization/Cargo.toml +++ b/mm2src/mm2_bitcoin/serialization/Cargo.toml @@ -2,6 +2,7 @@ name = "serialization" version = "0.1.0" authors = ["debris "] +edition = "2015" [lib] doctest = false diff --git a/mm2src/mm2_bitcoin/serialization/src/impls.rs b/mm2src/mm2_bitcoin/serialization/src/impls.rs index 80c037ce93..4b281c1e59 100644 --- a/mm2src/mm2_bitcoin/serialization/src/impls.rs +++ b/mm2src/mm2_bitcoin/serialization/src/impls.rs @@ -151,7 +151,7 @@ impl Serializable for String { } } -impl<'a> Serializable for &'a str { +impl Serializable for &str { fn serialize(&self, stream: &mut Stream) { let bytes: &[u8] = self.as_bytes(); stream.append(&CompactInteger::from(bytes.len())).append_slice(bytes); diff --git a/mm2src/mm2_bitcoin/serialization/src/reader.rs b/mm2src/mm2_bitcoin/serialization/src/reader.rs index 1b9677ac32..5274d94c75 100644 --- a/mm2src/mm2_bitcoin/serialization/src/reader.rs +++ b/mm2src/mm2_bitcoin/serialization/src/reader.rs @@ -212,7 +212,6 @@ where Ok(result) } - #[cfg_attr(feature = "cargo-clippy", allow(clippy::wrong_self_convention))] pub fn is_finished(&mut self) -> bool { if self.peeked.is_some() { return false; diff --git a/mm2src/mm2_bitcoin/serialization_derive/Cargo.toml b/mm2src/mm2_bitcoin/serialization_derive/Cargo.toml index a220338026..d731455211 100644 --- a/mm2src/mm2_bitcoin/serialization_derive/Cargo.toml +++ b/mm2src/mm2_bitcoin/serialization_derive/Cargo.toml @@ -2,6 +2,7 @@ name = "serialization_derive" version = "0.1.0" authors = ["debris "] +edition = "2015" [lib] name = "serialization_derive" diff --git a/mm2src/mm2_bitcoin/serialization_derive/src/de.rs b/mm2src/mm2_bitcoin/serialization_derive/src/de.rs index f916bb1caa..295afaf286 100644 --- a/mm2src/mm2_bitcoin/serialization_derive/src/de.rs +++ b/mm2src/mm2_bitcoin/serialization_derive/src/de.rs @@ -28,7 +28,7 @@ pub fn impl_deserializable(ast: &syn::DeriveInput) -> quote::Tokens { }; quote! { - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications, non_local_definitions)] const #dummy_const: () = { extern crate serialization; use std::io; diff --git a/mm2src/mm2_bitcoin/serialization_derive/src/ser.rs b/mm2src/mm2_bitcoin/serialization_derive/src/ser.rs index a2ea294264..1144718ae9 100644 --- a/mm2src/mm2_bitcoin/serialization_derive/src/ser.rs +++ b/mm2src/mm2_bitcoin/serialization_derive/src/ser.rs @@ -34,7 +34,7 @@ pub fn impl_serializable(ast: &syn::DeriveInput) -> quote::Tokens { }; quote! { - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications, non_local_definitions)] const #dummy_const: () = { extern crate serialization; #impl_block diff --git a/mm2src/mm2_bitcoin/spv_validation/src/helpers_validation.rs b/mm2src/mm2_bitcoin/spv_validation/src/helpers_validation.rs index fcdd5ce5ab..4ab1a7e9ca 100644 --- a/mm2src/mm2_bitcoin/spv_validation/src/helpers_validation.rs +++ b/mm2src/mm2_bitcoin/spv_validation/src/helpers_validation.rs @@ -324,9 +324,9 @@ fn validate_header_prev_hash(actual: &H256, to_compare_with: &H256) -> bool { ac /// /// * `headers` - Raw byte array of header chain /// * `difficulty_check`: Rather the difficulty need to check or not, usefull for chain like Qtum (Pos) -/// or KMD/SmartChain (Difficulty change NN) +/// or KMD/SmartChain (Difficulty change NN) /// * `constant_difficulty`: If we do not expect difficulty change (BTC difficulty change every 2016 blocks) -/// use this variable to false when you do not have a chance to use a checkpoint +/// use this variable to false when you do not have a chance to use a checkpoint /// /// # Errors /// diff --git a/mm2src/mm2_core/Cargo.toml b/mm2src/mm2_core/Cargo.toml index d0350c766a..aa8dcc0b9f 100644 --- a/mm2src/mm2_core/Cargo.toml +++ b/mm2src/mm2_core/Cargo.toml @@ -8,6 +8,7 @@ doctest = false [features] new-db-arch = [] +track-ctx-pointer = [] [dependencies] arrayref.workspace = true diff --git a/mm2src/mm2_core/src/mm_ctx.rs b/mm2src/mm2_core/src/mm_ctx.rs index 79da897fc4..e159298c49 100644 --- a/mm2src/mm2_core/src/mm_ctx.rs +++ b/mm2src/mm2_core/src/mm_ctx.rs @@ -447,7 +447,7 @@ impl MmCtx { } let default = !self.conf["disable_p2p"].as_bool().unwrap_or(false) - && self.conf["seednodes"].as_array().map_or(true, |t| t.is_empty()); + && self.conf["seednodes"].as_array().is_none_or(|t| t.is_empty()); default } @@ -697,6 +697,8 @@ impl MmArc { #[cfg(feature = "track-ctx-pointer")] fn track_ctx_pointer(&self) { + use common::executor::SpawnFuture; + let ctx_weak = self.weak(); let fut = async move { let level = log::log_crate::Level::Info; diff --git a/mm2src/mm2_db/src/indexed_db/drivers/builder.rs b/mm2src/mm2_db/src/indexed_db/drivers/builder.rs index 8fc411c8cb..80d237f96a 100644 --- a/mm2src/mm2_db/src/indexed_db/drivers/builder.rs +++ b/mm2src/mm2_db/src/indexed_db/drivers/builder.rs @@ -222,5 +222,6 @@ impl IdbDatabaseBuilder { enum DbOpenEvent { Failed(JsValue), UpgradeNeeded(JsValue), + #[expect(dead_code)] Success(JsValue), } diff --git a/mm2src/mm2_db/src/indexed_db/drivers/cursor/multi_key_bound_cursor.rs b/mm2src/mm2_db/src/indexed_db/drivers/cursor/multi_key_bound_cursor.rs index 18a5962498..6913442eec 100644 --- a/mm2src/mm2_db/src/indexed_db/drivers/cursor/multi_key_bound_cursor.rs +++ b/mm2src/mm2_db/src/indexed_db/drivers/cursor/multi_key_bound_cursor.rs @@ -28,8 +28,8 @@ impl IdbMultiKeyBoundCursor { } fn check_bounds( - only_values: &Vec<(String, Json)>, - bound_values: &Vec<(String, CursorBoundValue, CursorBoundValue)>, + only_values: &[(String, Json)], + bound_values: &[(String, CursorBoundValue, CursorBoundValue)], ) -> CursorResult<()> { if bound_values.is_empty() || (only_values.len() + bound_values.len() < 2) { let description = format!( diff --git a/mm2src/mm2_db/src/indexed_db/indexed_cursor.rs b/mm2src/mm2_db/src/indexed_db/indexed_cursor.rs index 3f0c1c7b8c..bd10cb1479 100644 --- a/mm2src/mm2_db/src/indexed_db/indexed_cursor.rs +++ b/mm2src/mm2_db/src/indexed_db/indexed_cursor.rs @@ -14,8 +14,7 @@ //! //! If you want to find all `RICK/MORTY` swaps where //! 1) `10 <= base_coin_value <= 13` -//! 2) `started_at <= 1000000030`, -//! you can use [`WithBound::bound`] along with [`WithOnly::only`]: +//! 2) `started_at <= 1000000030`, you can use [`WithBound::bound`] along with [`WithOnly::only`]: //! ```rust //! let table = open_table_somehow(); //! let all_rick_morty_swaps = table @@ -184,7 +183,7 @@ pub struct CursorIter<'transaction, Table> { phantom: PhantomData<&'transaction Table>, } -impl<'transaction, Table: TableSignature> CursorIter<'transaction, Table> { +impl CursorIter<'_, Table> { /// Advances the iterator and returns the next value. /// Please note that the items are sorted by the index keys. pub async fn next(&mut self) -> CursorResult> { @@ -425,8 +424,8 @@ mod tests { // Get `BeBigUint` numbers that should have been returned by the cursor above. let expected = numbers .iter() + .filter(|&num| num_x <= num && num <= num_y) .cloned() - .filter(|num| num_x <= num && num <= num_y) .sorted() .collect::>(); assert_eq!(actual_items, expected); 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 0cfeb9cf13..d617eb39e9 100644 --- a/mm2src/mm2_err_handle/src/map_to_mm_fut.rs +++ b/mm2src/mm2_err_handle/src/map_to_mm_fut.rs @@ -43,7 +43,7 @@ pub struct MapToMmFuture<'a, T, E1: NotMmError, E2: NotMmError> { closure: Option E2 + Send + 'a>>, } -impl<'a, T, E1: NotMmError, E2: NotMmError> Future for MapToMmFuture<'a, T, E1, E2> { +impl Future for MapToMmFuture<'_, T, E1, E2> { type Item = T; type Error = MmError; diff --git a/mm2src/mm2_eth/src/eip712_encode.rs b/mm2src/mm2_eth/src/eip712_encode.rs index dbda992b83..cc5605281f 100644 --- a/mm2src/mm2_eth/src/eip712_encode.rs +++ b/mm2src/mm2_eth/src/eip712_encode.rs @@ -144,7 +144,7 @@ fn encode_address(value: &Json, field_name: Option<&str>) -> Result> { .ok_or_else(|| expected_type_error("address", value, field_name))?; // "0x" - 2 chars, 40 chars are 20 hexed bytes. if string.len() != 42 { - return Err(decode_error("Expected 0x-prefixed address (20 bytes)", field_name))?; + return Err(decode_error("Expected 0x-prefixed address (20 bytes)", field_name)); } let address = Address::from_str(&string[2..]).map_err(|e| decode_error(e, field_name))?; Ok(encode(&[Token::Address(address)])) diff --git a/mm2src/mm2_event_stream/src/manager.rs b/mm2src/mm2_event_stream/src/manager.rs index 1bef846ef5..4c2d5c648b 100644 --- a/mm2src/mm2_event_stream/src/manager.rs +++ b/mm2src/mm2_event_stream/src/manager.rs @@ -545,7 +545,7 @@ mod tests { manager.remove_streamer_if_down(&streamer_id); // The streamer should be removed. - assert!(manager.read().streamers.get(&streamer_id).is_none()); + assert!(!manager.read().streamers.contains_key(&streamer_id)); // And the client is no more listening to it. assert!(!manager .0 diff --git a/mm2src/mm2_event_stream/src/streamer_ids.rs b/mm2src/mm2_event_stream/src/streamer_ids.rs index d019b9a9e0..064eb8f505 100644 --- a/mm2src/mm2_event_stream/src/streamer_ids.rs +++ b/mm2src/mm2_event_stream/src/streamer_ids.rs @@ -81,7 +81,7 @@ impl<'de> Deserialize<'de> for StreamerId { { struct StreamerIdVisitor; - impl<'de> Visitor<'de> for StreamerIdVisitor { + impl Visitor<'_> for StreamerIdVisitor { type Value = StreamerId; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { diff --git a/mm2src/mm2_gui_storage/src/account/storage/mod.rs b/mm2src/mm2_gui_storage/src/account/storage/mod.rs index a2a186d490..e7134121ca 100644 --- a/mm2src/mm2_gui_storage/src/account/storage/mod.rs +++ b/mm2src/mm2_gui_storage/src/account/storage/mod.rs @@ -149,6 +149,7 @@ pub(crate) trait AccountStorage: Send + Sync { async fn load_account_coins(&self, account_id: AccountId) -> AccountStorageResult>; /// Loads accounts from the storage. + #[allow(dead_code)] async fn load_accounts(&self) -> AccountStorageResult>; /// Loads accounts from the storage and marks **only** one account as enabled. @@ -157,6 +158,7 @@ pub(crate) trait AccountStorage: Send + Sync { ) -> AccountStorageResult>; /// Loads an enabled account ID, or returns an error if there is no enabled account yet. + #[allow(dead_code)] async fn load_enabled_account_id(&self) -> AccountStorageResult; /// Loads an enabled account with activated coins, or returns an error if there is no enabled account yet. diff --git a/mm2src/mm2_io/src/fs.rs b/mm2src/mm2_io/src/fs.rs index e24ee04284..ad69a69625 100644 --- a/mm2src/mm2_io/src/fs.rs +++ b/mm2src/mm2_io/src/fs.rs @@ -78,7 +78,7 @@ pub fn ensure_file_is_writable(file_path: &Path) -> Result<(), String> { } } else { // try to open file in write append mode - if let Err(e) = fs::OpenOptions::new().write(true).append(true).open(file_path) { + if let Err(e) = fs::OpenOptions::new().append(true).open(file_path) { return ERR!( "{} when trying to open the file {} in write mode", e, diff --git a/mm2src/mm2_main/Cargo.toml b/mm2src/mm2_main/Cargo.toml index f3b526d6bd..aa293a68b2 100644 --- a/mm2src/mm2_main/Cargo.toml +++ b/mm2src/mm2_main/Cargo.toml @@ -26,6 +26,10 @@ sepolia-maker-swap-v2-tests = [] sepolia-taker-swap-v2-tests = [] test-ext-api = ["trading_api/test-ext-api"] new-db-arch = ["mm2_core/new-db-arch"] # A temporary feature to integrate the new db architecture incrementally +# Temporary feature for implementing IBC wrap/unwrap mechanism and will be removed +# once we consider it as stable. +ibc-routing-for-swaps = [] +for-tests = [] [dependencies] async-std = { workspace = true, features = ["unstable"] } diff --git a/mm2src/mm2_main/src/database/my_orders.rs b/mm2src/mm2_main/src/database/my_orders.rs index 7e38c4bfa9..1495ccbd84 100644 --- a/mm2src/mm2_main/src/database/my_orders.rs +++ b/mm2src/mm2_main/src/database/my_orders.rs @@ -88,7 +88,7 @@ pub fn insert_taker_order(ctx: &MmArc, uuid: Uuid, order: &TakerOrder) -> SqlRes pub fn update_maker_order(ctx: &MmArc, uuid: Uuid, order: &MakerOrder) -> SqlResult<()> { debug!("Updating order {} in the SQLite database", uuid); - let params = vec![ + let params = [ uuid.to_string(), order.price.to_decimal().to_string(), order.max_base_vol.to_decimal().to_string(), @@ -102,7 +102,7 @@ pub fn update_maker_order(ctx: &MmArc, uuid: Uuid, order: &MakerOrder) -> SqlRes pub fn update_was_taker(ctx: &MmArc, uuid: Uuid) -> SqlResult<()> { debug!("Updating order {} in the SQLite database", uuid); - let params = vec![ + let params = [ uuid.to_string(), "Maker".to_string(), now_ms().to_string(), @@ -115,7 +115,7 @@ pub fn update_was_taker(ctx: &MmArc, uuid: Uuid) -> SqlResult<()> { pub fn update_order_status(ctx: &MmArc, uuid: Uuid, status: String) -> SqlResult<()> { debug!("Updating order {} in the SQLite database", uuid); - let params = vec![uuid.to_string(), now_ms().to_string(), status]; + let params = [uuid.to_string(), now_ms().to_string(), status]; let conn = ctx.sqlite_connection(); conn.execute(UPDATE_ORDER_STATUS, params_from_iter(params.iter())) .map(|_| ()) @@ -283,7 +283,7 @@ pub fn select_orders_by_filter( } pub fn select_status_by_uuid(conn: &Connection, uuid: &Uuid) -> Result { - let params = vec![uuid.to_string()]; + let params = [uuid.to_string()]; conn.query_row(SELECT_STATUS_BY_UUID, params_from_iter(params.iter()), |row| { row.get::<_, String>(0) }) diff --git a/mm2src/mm2_main/src/database/my_swaps.rs b/mm2src/mm2_main/src/database/my_swaps.rs index 91c2200bba..3f68b3b689 100644 --- a/mm2src/mm2_main/src/database/my_swaps.rs +++ b/mm2src/mm2_main/src/database/my_swaps.rs @@ -144,11 +144,7 @@ pub async fn fill_my_swaps_from_json_statements(ctx: &MmArc) -> Vec<(&'static st /// Use this only in migration code! fn insert_saved_swap_sql_migration_1(swap: SavedSwap) -> Option<(&'static str, Vec)> { - let swap_info = match swap.get_my_info() { - Some(s) => s, - // get_my_info returning None means that swap did not even start - so we can keep it away from indexing. - None => return None, - }; + let swap_info = swap.get_my_info()?; let params = vec![ swap_info.my_coin, swap_info.other_coin, diff --git a/mm2src/mm2_main/src/database/stats_nodes.rs b/mm2src/mm2_main/src/database/stats_nodes.rs index c62c84aa3e..b38199c187 100644 --- a/mm2src/mm2_main/src/database/stats_nodes.rs +++ b/mm2src/mm2_main/src/database/stats_nodes.rs @@ -32,7 +32,7 @@ const INSERT_STAT: &str = "INSERT INTO stats_nodes (name, version, timestamp, er pub fn insert_node_info(ctx: &MmArc, node_info: &NodeInfo) -> SqlResult<()> { debug!("Inserting info about node {} to the SQLite database", node_info.name); - let params = vec![ + let params = [ node_info.name.clone(), node_info.address.clone(), node_info.peer_id.clone(), @@ -46,7 +46,7 @@ pub fn insert_node_info(ctx: &MmArc, node_info: &NodeInfo) -> SqlResult<()> { pub fn delete_node_info(ctx: &MmArc, name: String) -> SqlResult<()> { debug!("Deleting info about node {} from the SQLite database", name); - let params = vec![name]; + let params = [name]; #[cfg(not(feature = "new-db-arch"))] let conn = ctx.sqlite_connection(); #[cfg(feature = "new-db-arch")] @@ -86,7 +86,7 @@ pub fn insert_node_version_stat(ctx: &MmArc, node_version_stat: NodeVersionStat) "Inserting new version stat for node {} to the SQLite database", node_version_stat.name ); - let params = vec![ + let params = [ node_version_stat.name, node_version_stat.version.unwrap_or_default(), node_version_stat.timestamp.to_string(), diff --git a/mm2src/mm2_main/src/lp_native_dex.rs b/mm2src/mm2_main/src/lp_native_dex.rs index 7ae20cad70..3600370ffc 100644 --- a/mm2src/mm2_main/src/lp_native_dex.rs +++ b/mm2src/mm2_main/src/lp_native_dex.rs @@ -46,11 +46,11 @@ use mm2_metrics::mm_gauge; use rpc_task::RpcTaskError; use serde_json as json; use std::convert::TryInto; +use std::fs; use std::io; use std::path::PathBuf; use std::str; use std::time::Duration; -use std::{fs, usize}; cfg_native! { use db_common::sqlite::rusqlite::Error as SqlError; diff --git a/mm2src/mm2_main/src/lp_ordermatch.rs b/mm2src/mm2_main/src/lp_ordermatch.rs index 601a9030fb..5369f98f50 100644 --- a/mm2src/mm2_main/src/lp_ordermatch.rs +++ b/mm2src/mm2_main/src/lp_ordermatch.rs @@ -539,7 +539,7 @@ fn remove_pubkey_pair_orders(orderbook: &mut Orderbook, pubkey: &str, alb_pair: None => return, }; - if pubkey_state.trie_roots.get(alb_pair).is_none() { + if !pubkey_state.trie_roots.contains_key(alb_pair) { return; } @@ -633,6 +633,7 @@ pub async fn process_msg(ctx: MmArc, from_peer: String, msg: &[u8], i_am_relay: } } +#[allow(dead_code)] #[derive(Debug)] struct TryFromBytesError(String); @@ -830,6 +831,7 @@ impl DeltaOrFullTrie { } } +#[expect(dead_code)] #[derive(Debug)] enum TrieDiffHistoryError { TrieDbError(Box>), @@ -1004,11 +1006,11 @@ fn test_alb_ordered_pair() { #[allow(dead_code)] pub fn parse_orderbook_pair_from_topic(topic: &str) -> Option<(&str, &str)> { - let mut split = topic.split(|maybe_sep| maybe_sep == TOPIC_SEPARATOR); + let mut split = topic.split(TOPIC_SEPARATOR); match split.next() { Some(ORDERBOOK_PREFIX) => match split.next() { Some(maybe_pair) => { - let colon = maybe_pair.find(|maybe_colon| maybe_colon == ':'); + let colon = maybe_pair.find(':'); match colon { Some(index) => { if index + 1 < maybe_pair.len() { @@ -1222,7 +1224,7 @@ impl TakerRequest { base_protocol_info: message.base_protocol_info, rel_protocol_info: message.rel_protocol_info, swap_version: message.swap_version, - /// TODO: Support the new protocol types. + // TODO: Support the new protocol types. #[cfg(feature = "ibc-routing-for-swaps")] order_metadata: OrderMetadata::default(), } @@ -2300,7 +2302,7 @@ impl MakerReserved { base_protocol_info: message.base_protocol_info, rel_protocol_info: message.rel_protocol_info, swap_version: message.swap_version, - /// TODO: Support the new protocol types. + // TODO: Support the new protocol types. #[cfg(feature = "ibc-routing-for-swaps")] order_metadata: OrderMetadata::default(), } @@ -2534,6 +2536,7 @@ fn pubkey_state_mut<'a>( } fn order_pair_root_mut<'a>(state: &'a mut HashMap, pair: &str) -> &'a mut H64 { + #[allow(clippy::unwrap_or_default)] state.entry(pair.to_owned()).or_insert_with(Default::default) } @@ -2699,7 +2702,7 @@ impl Orderbook { let base_rel = (order.base.clone(), order.rel.clone()); - let ordered = self.ordered.entry(base_rel.clone()).or_insert_with(BTreeSet::new); + let ordered = self.ordered.entry(base_rel.clone()).or_default(); // have to clone to drop immutable ordered borrow let existing = ordered @@ -2717,18 +2720,15 @@ impl Orderbook { self.pairs_existing_for_base .entry(order.base.clone()) - .or_insert_with(HashSet::new) + .or_default() .insert(order.rel.clone()); self.pairs_existing_for_rel .entry(order.rel.clone()) - .or_insert_with(HashSet::new) + .or_default() .insert(order.base.clone()); - self.unordered - .entry(base_rel) - .or_insert_with(HashSet::new) - .insert(order.uuid); + self.unordered.entry(base_rel).or_default().insert(order.uuid); self.streaming_manager .send_fn(&OrderbookStreamer::derive_streamer_id(&order.base, &order.rel), || { @@ -2739,10 +2739,7 @@ impl Orderbook { } fn remove_order_trie_update(&mut self, uuid: Uuid) -> Option { - let order = match self.order_set.remove(&uuid) { - Some(order) => order, - None => return None, - }; + let order = self.order_set.remove(&uuid)?; let base_rel = (order.base.clone(), order.rel.clone()); // create an `order_to_delete` that allows to find and remove an element from `self.ordered` by hash @@ -3051,6 +3048,7 @@ struct StateMachineParams<'a> { taker_amount: &'a MmNumber, } +#[allow(unreachable_code, unused_variables)] // TODO: remove with `ibc-routing-for-swaps` feature removal. #[cfg_attr(test, mockable)] fn lp_connect_start_bob(ctx: MmArc, maker_match: MakerMatch, maker_order: MakerOrder, taker_p2p_pubkey: PublicKey) { let spawner = ctx.spawner(); @@ -3293,6 +3291,7 @@ async fn start_maker_swap_state_machine< .error_log(); } +#[allow(unreachable_code, unused_variables)] // TODO: remove with `ibc-routing-for-swaps` feature removal. fn lp_connected_alice(ctx: MmArc, taker_order: TakerOrder, taker_match: TakerMatch, maker_p2p_pubkey: PublicKey) { let spawner = ctx.spawner(); let uuid = taker_match.reserved.taker_order_uuid; @@ -3343,6 +3342,7 @@ fn lp_connected_alice(ctx: MmArc, taker_order: TakerOrder, taker_match: TakerMat unreachable!(); } + #[allow(unreachable_code)] let maker_amount = taker_match.reserved.get_base_amount().clone(); let taker_amount = taker_match.reserved.get_rel_amount().clone(); @@ -4836,7 +4836,7 @@ pub struct TakerConnectForRpc<'a> { } impl<'a> From<&'a TakerConnect> for TakerConnectForRpc<'a> { - fn from(connect: &'a TakerConnect) -> TakerConnectForRpc { + fn from(connect: &'a TakerConnect) -> TakerConnectForRpc<'a> { TakerConnectForRpc { taker_order_uuid: &connect.taker_order_uuid, maker_order_uuid: &connect.maker_order_uuid, @@ -4857,7 +4857,7 @@ pub struct MakerConnectedForRpc<'a> { } impl<'a> From<&'a MakerConnected> for MakerConnectedForRpc<'a> { - fn from(connected: &'a MakerConnected) -> MakerConnectedForRpc { + fn from(connected: &'a MakerConnected) -> MakerConnectedForRpc<'a> { MakerConnectedForRpc { taker_order_uuid: &connected.taker_order_uuid, maker_order_uuid: &connected.maker_order_uuid, @@ -4869,7 +4869,7 @@ impl<'a> From<&'a MakerConnected> for MakerConnectedForRpc<'a> { } impl<'a> From<&'a MakerReserved> for MakerReservedForRpc<'a> { - fn from(reserved: &MakerReserved) -> MakerReservedForRpc { + fn from(reserved: &'a MakerReserved) -> MakerReservedForRpc<'a> { MakerReservedForRpc { base: &reserved.base, rel: &reserved.rel, @@ -4898,7 +4898,7 @@ struct MakerMatchForRpc<'a> { #[allow(clippy::needless_borrow)] impl<'a> From<&'a MakerMatch> for MakerMatchForRpc<'a> { - fn from(maker_match: &'a MakerMatch) -> MakerMatchForRpc { + fn from(maker_match: &'a MakerMatch) -> MakerMatchForRpc<'a> { MakerMatchForRpc { request: (&maker_match.request).into(), reserved: (&maker_match.reserved).into(), @@ -5385,7 +5385,7 @@ pub enum Order { } impl<'a> From<&'a Order> for OrderForRpc<'a> { - fn from(order: &'a Order) -> OrderForRpc { + fn from(order: &'a Order) -> OrderForRpc<'a> { match order { Order::Maker(o) => OrderForRpc::Maker(MakerOrderForRpc::from(o)), Order::Taker(o) => OrderForRpc::Taker(TakerOrderForRpc::from(o)), @@ -5635,7 +5635,7 @@ struct MakerOrderForMyOrdersRpc<'a> { } impl<'a> From<&'a MakerOrder> for MakerOrderForMyOrdersRpc<'a> { - fn from(order: &'a MakerOrder) -> MakerOrderForMyOrdersRpc { + fn from(order: &'a MakerOrder) -> MakerOrderForMyOrdersRpc<'a> { MakerOrderForMyOrdersRpc { order: order.into(), cancellable: order.is_cancellable(), @@ -5654,7 +5654,7 @@ struct TakerMatchForRpc<'a> { #[allow(clippy::needless_borrow)] impl<'a> From<&'a TakerMatch> for TakerMatchForRpc<'a> { - fn from(taker_match: &'a TakerMatch) -> TakerMatchForRpc { + fn from(taker_match: &'a TakerMatch) -> TakerMatchForRpc<'a> { TakerMatchForRpc { reserved: (&taker_match.reserved).into(), connect: (&taker_match.connect).into(), @@ -5677,7 +5677,7 @@ struct TakerOrderForRpc<'a> { #[allow(clippy::needless_borrow)] impl<'a> From<&'a TakerOrder> for TakerOrderForRpc<'a> { - fn from(order: &'a TakerOrder) -> TakerOrderForRpc { + fn from(order: &'a TakerOrder) -> TakerOrderForRpc<'a> { TakerOrderForRpc { created_at: order.created_at, request: (&order.request).into(), diff --git a/mm2src/mm2_main/src/lp_ordermatch/my_orders_storage.rs b/mm2src/mm2_main/src/lp_ordermatch/my_orders_storage.rs index 11eccbb232..88d9e314a9 100644 --- a/mm2src/mm2_main/src/lp_ordermatch/my_orders_storage.rs +++ b/mm2src/mm2_main/src/lp_ordermatch/my_orders_storage.rs @@ -147,6 +147,7 @@ pub trait MyActiveOrders { async fn load_active_taker_orders(&self) -> MyOrdersResult>; + #[expect(dead_code)] async fn save_new_active_order(&self, order: &Order) -> MyOrdersResult<()> { match order { Order::Maker(maker) => self.save_new_active_maker_order(maker).await, @@ -184,6 +185,7 @@ pub trait MyOrdersFilteringHistory { async fn select_order_status(&self, uuid: Uuid) -> MyOrdersResult; + #[expect(dead_code)] async fn save_order_in_filtering_history(&self, order: &Order) -> MyOrdersResult<()> { match order { Order::Maker(maker) => self.save_maker_order_in_filtering_history(maker).await, diff --git a/mm2src/mm2_main/src/lp_ordermatch/simple_market_maker.rs b/mm2src/mm2_main/src/lp_ordermatch/simple_market_maker.rs index 78aca5278d..9b80abc94b 100644 --- a/mm2src/mm2_main/src/lp_ordermatch/simple_market_maker.rs +++ b/mm2src/mm2_main/src/lp_ordermatch/simple_market_maker.rs @@ -693,7 +693,7 @@ async fn process_bot_logic(ctx: &MmArc) { let mut futures_order_creation = Vec::with_capacity(cfg.len()); // Now iterate over the registry and for every pairs that are not hit let's create an order for (trading_pair, cur_cfg) in cfg { - if memoization_pair_registry.get(&trading_pair).is_some() || !cur_cfg.enable { + if memoization_pair_registry.contains(&trading_pair) || !cur_cfg.enable { continue; } let rates_infos = rates_registry diff --git a/mm2src/mm2_main/src/lp_swap.rs b/mm2src/mm2_main/src/lp_swap.rs index 28dacbffe2..29b8b6fdf2 100644 --- a/mm2src/mm2_main/src/lp_swap.rs +++ b/mm2src/mm2_main/src/lp_swap.rs @@ -22,19 +22,18 @@ //! 1. AFee: OP_DUP OP_HASH160 FEE_RMD160 OP_EQUALVERIFY OP_CHECKSIG //! //! 2. BPayment: -//! OP_IF -//! OP_CLTV OP_DROP OP_CHECKSIG -//! OP_ELSE -//! OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG -//! OP_ENDIF +//! OP_IF +//! OP_CLTV OP_DROP OP_CHECKSIG +//! OP_ELSE +//! OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +//! OP_ENDIF //! //! 3. APayment: -//! OP_IF -//! OP_CLTV OP_DROP OP_CHECKSIG -//! OP_ELSE -//! OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG -//! OP_ENDIF -//! +//! OP_IF +//! OP_CLTV OP_DROP OP_CHECKSIG +//! OP_ELSE +//! OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +//! OP_ENDIF /****************************************************************************** * Copyright © 2023 Pampex LTD and TillyHK LTD * diff --git a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs index ac10601737..61584a5a60 100644 --- a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs @@ -20,6 +20,7 @@ use common::log::{debug, error, info, warn}; use common::{now_sec, Future01CompatExt}; use crypto::privkey::SerializableSecp256k1Keypair; use crypto::secret_hash_algo::SecretHashAlgo; +use derive_more::Display; use keys::KeyPair; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; @@ -769,7 +770,7 @@ impl { @@ -828,7 +829,7 @@ impl, } @@ -137,6 +143,7 @@ struct Stopped { stop_reason: StopReason, } +#[expect(dead_code)] #[derive(Debug)] enum StopReason { Finished(WatcherSuccess), @@ -151,6 +158,7 @@ enum WatcherSuccess { TakerPaymentRefundedByTaker, } +#[expect(dead_code)] #[derive(Debug)] enum WatcherError { InvalidTakerFee(String), diff --git a/mm2src/mm2_main/src/lp_swap/taker_swap.rs b/mm2src/mm2_main/src/lp_swap/taker_swap.rs index d35391b182..f923e27f9b 100644 --- a/mm2src/mm2_main/src/lp_swap/taker_swap.rs +++ b/mm2src/mm2_main/src/lp_swap/taker_swap.rs @@ -2659,7 +2659,6 @@ pub async fn taker_swap_trade_preimage( rel_nota: rel_coin.requires_notarization(), }; let our_public_id = CryptoCtx::from_ctx(ctx).map_mm_err()?.mm2_internal_public_id(); - let order_builder = TakerOrderBuilder::new(&base_coin, &rel_coin) .with_base_amount(base_amount) .with_rel_amount(rel_amount) @@ -2719,27 +2718,59 @@ pub async fn max_taker_vol(ctx: MmArc, req: Json) -> Result>, S } /// If we want to calculate the maximum taker volume, we should solve the following equation: -/// `max_vol = balance - locked_amount - trade_fee(max_vol) - fee_to_send_taker_fee(dex_fee(max_vol)) - dex_fee(max_vol)` /// -/// 1) If the `trade_fee` and `fee_to_send_taker_fee` should be paid in base coin, the equation can be simplified: -/// `max_vol = balance - locked_amount - dex_fee(max_vol)`, -/// where we can calculate the exact `max_vol` since the function inverse to `dex_fee(x)` can be obtained. +/// ```rust +/// max_vol = balance - locked_amount +/// - trade_fee(max_vol) +/// - fee_to_send_taker_fee(dex_fee(max_vol)) +/// - dex_fee(max_vol) +/// ``` +/// +/// 1. If the `trade_fee` and `fee_to_send_taker_fee` should be paid in base coin, the equation can be simplified: +/// +/// ```rust +/// max_vol = balance - locked_amount - dex_fee(max_vol) +/// ``` +/// +/// where we can calculate the exact `max_vol` since the inverse of `dex_fee(x)` is obtainable. +/// +/// 2. Otherwise we cannot express `max_vol` from the equation above, but we can find the smallest of the largest `max_vol`. That means if we find the largest `trade_fee` and `fee_to_send_taker_fee` values and plug them in: /// -/// 2) Otherwise we cannot express the `max_vol` from the equation above, but we can find smallest of the largest `max_vol`. -/// It means if we find the largest `trade_fee` and `fee_to_send_taker_fee` values and pass them into the equation, we will get: -/// `min_max_vol = balance - locked_amount - max_trade_fee - max_fee_to_send_taker_fee - dex_fee(max_vol)` -/// and then `min_max_vol` can be calculated as in the first case. +/// ```rust +/// min_max_vol = balance - locked_amount +/// - max_trade_fee +/// - max_fee_to_send_taker_fee +/// - dex_fee(max_vol) +/// ``` /// -/// Please note the following condition is satisfied for any `x` and `y`: -/// `if x < y then trade_fee(x) <= trade_fee(y) and fee_to_send_taker_fee(x) <= fee_to_send_taker_fee(y) and dex_fee(x) <= dex_fee(y)` -/// Let `real_max_vol` is a real desired volume. -/// Performing the following steps one by one, we will get an approximate maximum volume: -/// - `max_possible = balance - locked_amount` is a largest possible max volume. Hint, we've replaced unknown subtracted `trade_fee`, `fee_to_send_taker_fee`, `dex_fee` variables with zeros. -/// - `max_trade_fee = trade_fee(max_possible)` is a largest possible `trade_fee` value. -/// - `max_possible_2 = balance - locked_amount - max_trade_fee` is more accurate max volume than `max_possible`. Please note `real_max_vol <= max_possible_2 <= max_possible`. -/// - `max_dex_fee = dex_fee(max_possible_2)` is an intermediate value that will be passed into the `fee_to_send_taker_fee`. +/// then `min_max_vol` can be calculated as in the first case. +/// +/// Please note that for any `x` and `y`, if `x < y` then +/// `trade_fee(x) <= trade_fee(y)`, `fee_to_send_taker_fee(x) <= fee_to_send_taker_fee(y)`, +/// and `dex_fee(x) <= dex_fee(y)`. +/// +/// Let `real_max_vol` be the actual desired volume. Performing the following steps yields +/// an approximate maximum volume: +/// +/// - `max_possible = balance - locked_amount` +/// The largest possible max volume, replacing unknown fees with zero. +/// - `max_trade_fee = trade_fee(max_possible)` +/// The largest possible `trade_fee`. +/// - `max_possible_2 = balance - locked_amount - max_trade_fee` +/// A more accurate upper bound (`real_max_vol <= max_possible_2 <= max_possible`). +/// - `max_dex_fee = dex_fee(max_possible_2)` +/// Passed into `fee_to_send_taker_fee`. /// - `max_fee_to_send_taker_fee = fee_to_send_taker_fee(max_dex_fee)` -/// After that `min_max_vol = balance - locked_amount - max_trade_fee - max_fee_to_send_taker_fee - dex_fee(max_vol)` can be solved as in the first case. +/// +/// After that, +/// ```rust +/// min_max_vol = balance - locked_amount +/// - max_trade_fee +/// - max_fee_to_send_taker_fee +/// - dex_fee(max_vol) +/// ``` +/// can be solved as in the first case. +/// pub async fn calc_max_taker_vol( ctx: &MmArc, coin: &MmCoinEnum, diff --git a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs index 2926156325..32fe7f7dfc 100644 --- a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs @@ -20,6 +20,7 @@ use common::log::{debug, error, info, warn}; use common::Future01CompatExt; use crypto::privkey::SerializableSecp256k1Keypair; use crypto::secret_hash_algo::SecretHashAlgo; +use derive_more::Display; use keys::KeyPair; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; @@ -882,7 +883,7 @@ impl { @@ -935,7 +936,7 @@ impl Result<(), String> { @@ -54,7 +55,7 @@ fn hyres(handler: impl Future03>, String>> + Se pub fn dispatcher(req: Json, ctx: MmArc) -> DispatcherRes { let method = match req["method"].clone() { Json::String(method) => method, - _ => return DispatcherRes::NoMatch(req), + _ => return DispatcherRes::NoMatch, }; DispatcherRes::Match(match &method[..] { // Sorted alphanumerically (on the first latter) for readability. @@ -113,7 +114,7 @@ pub fn dispatcher(req: Json, ctx: MmArc) -> DispatcherRes { "validateaddress" => hyres(validate_address(ctx, req)), "version" => version(ctx), "withdraw" => hyres(into_legacy::withdraw(ctx, req)), - _ => return DispatcherRes::NoMatch(req), + _ => return DispatcherRes::NoMatch, }) } @@ -151,7 +152,7 @@ pub async fn process_single_request( let handler = match dispatcher(req, ctx.clone()) { DispatcherRes::Match(handler) => handler, - DispatcherRes::NoMatch(_) => { + DispatcherRes::NoMatch => { return Err(LegacyRequestProcessError::NoMatch); }, }; diff --git a/mm2src/mm2_main/src/rpc/lp_commands/lr_swap.rs b/mm2src/mm2_main/src/rpc/lp_commands/lr_swap.rs index 289cd08f0d..0d230d8324 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/lr_swap.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/lr_swap.rs @@ -21,19 +21,19 @@ mod types; /// by the maker orders. It uses external liquidity routing (e.g., via 1inch provider) to perform necessary conversions, currently for EVM networks /// /// A swap path may consist of: -/// - A liquidity routing (LR) step before or after the atomic swap. -/// - An atomic swap step to fill the selected maker order (ask or bid). +/// - A liquidity routing (LR) step before or after the atomic swap. +/// - An atomic swap step to fill the selected maker order (ask or bid). /// /// Use Case -/// The user wants to buy a specific amount of a token `user_base`, but only holds a different token `user_rel`. +/// The user wants to buy a specific amount of a token `user_base`, but only holds a different token `user_rel`. /// This RPC evaluates possible swap paths by combining: -/// - Converting `user_rel` (`user_base`) to the token required by a maker order via LR. -/// - Filling the order through an atomic swap. -/// - Converting the token required by a maker order to `user_base` (`user_rel`) via LR. +/// - Converting `user_rel` (`user_base`) to the token required by a maker order via LR. +/// - Filling the order through an atomic swap. +/// - Converting the token required by a maker order to `user_base` (`user_rel`) via LR. /// It then selects and returns the most price-effective path, taking into account: -/// - prices of orders (provided in the params) -/// - 1inch LR quotes -/// - (TODO) Total swap and routing fees +/// - prices of orders (provided in the params) +/// - 1inch LR quotes +/// - (TODO) Total swap and routing fees /// Sell requests are processed in a similar way. /// /// Example diff --git a/mm2src/mm2_main/src/rpc/lp_commands/lr_swap/lr_impl.rs b/mm2src/mm2_main/src/rpc/lp_commands/lr_swap/lr_impl.rs index 18e43acfcd..f1f709b27c 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/lr_swap/lr_impl.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/lr_swap/lr_impl.rs @@ -353,7 +353,6 @@ impl LrSwapCandidates { .map(|total_price| (lr_swap_data, order, total_price)) }) .min_by(|(_, _, price_0), (_, _, price_1)| price_0.cmp(price_1)) - .map(|(lr_swap_data, order, price)| (lr_swap_data, order, price)) .ok_or(MmError::new(ApiIntegrationRpcError::BestLrSwapNotFound)) } } @@ -391,12 +390,12 @@ pub async fn find_best_swap_path_with_lr( /// Helper to process 1inch token cross prices data and return average price fn cross_prices_average(series: Option) -> Option { - let Some(series) = series else { - return None; - }; + let series = series?; + if series.is_empty() { return None; } + let total: MmNumber = series.iter().fold(MmNumber::from(0), |acc, price_data| { acc + MmNumber::from(price_data.avg.clone()) }); diff --git a/mm2src/mm2_main/src/rpc/lp_commands/lr_swap/types.rs b/mm2src/mm2_main/src/rpc/lp_commands/lr_swap/types.rs index 2e16f54310..d407a6b63b 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/lr_swap/types.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/lr_swap/types.rs @@ -1,5 +1,8 @@ //! Types for LR swaps rpc +// Most of the code in this module fails on clippy. +#![allow(dead_code)] + use crate::lp_ordermatch::RpcOrderbookEntryV2; use crate::rpc::lp_commands::one_inch::types::ClassicSwapDetails; use coins::Ticker; diff --git a/mm2src/mm2_main/src/rpc/lp_commands/one_inch/errors.rs b/mm2src/mm2_main/src/rpc/lp_commands/one_inch/errors.rs index 7a4d995ecf..78545d02c5 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/one_inch/errors.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/one_inch/errors.rs @@ -1,5 +1,6 @@ use coins::{CoinFindError, NumConversError}; use common::{HttpStatusCode, StatusCode}; +use derive_more::Display; use enum_derives::EnumFromStringify; use ethereum_types::U256; use ser_error_derive::SerializeErrorType; diff --git a/mm2src/mm2_main/src/rpc/lp_commands/trezor.rs b/mm2src/mm2_main/src/rpc/lp_commands/trezor.rs index 212c810331..5d6a9044f1 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/trezor.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/trezor.rs @@ -1,5 +1,6 @@ use common::HttpStatusCode; use crypto::{CryptoCtx, CryptoCtxError, HwConnectionStatus, HwPubkey}; +use derive_more::Display; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::map_mm_error::MmResultExt; diff --git a/mm2src/mm2_main/src/rpc/streaming_activations/balance.rs b/mm2src/mm2_main/src/rpc/streaming_activations/balance.rs index 76f9d594e1..0a4a23f370 100644 --- a/mm2src/mm2_main/src/rpc/streaming_activations/balance.rs +++ b/mm2src/mm2_main/src/rpc/streaming_activations/balance.rs @@ -7,6 +7,7 @@ use coins::utxo::utxo_balance_events::UtxoBalanceEventStreamer; use coins::z_coin::z_balance_streaming::ZCoinBalanceEventStreamer; use coins::{lp_coinfind, MmCoin, MmCoinEnum}; use common::HttpStatusCode; +use derive_more::Display; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::{map_to_mm::MapToMmResult, mm_error::MmResult}; diff --git a/mm2src/mm2_main/src/rpc/streaming_activations/disable.rs b/mm2src/mm2_main/src/rpc/streaming_activations/disable.rs index 59490e173d..b98939b357 100644 --- a/mm2src/mm2_main/src/rpc/streaming_activations/disable.rs +++ b/mm2src/mm2_main/src/rpc/streaming_activations/disable.rs @@ -3,6 +3,7 @@ //! All event streamers are deactivated using the streamer ID only. use common::HttpStatusCode; +use derive_more::Display; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::{map_to_mm::MapToMmResult, mm_error::MmResult}; use mm2_event_stream::StreamerId; diff --git a/mm2src/mm2_main/src/rpc/streaming_activations/fee_estimation.rs b/mm2src/mm2_main/src/rpc/streaming_activations/fee_estimation.rs index ef36542716..9ff19d8020 100644 --- a/mm2src/mm2_main/src/rpc/streaming_activations/fee_estimation.rs +++ b/mm2src/mm2_main/src/rpc/streaming_activations/fee_estimation.rs @@ -4,6 +4,7 @@ use super::{EnableStreamingRequest, EnableStreamingResponse}; use coins::eth::fee_estimation::eth_fee_events::{EthFeeEventStreamer, EthFeeStreamingConfig}; use coins::{lp_coinfind, MmCoin, MmCoinEnum}; use common::HttpStatusCode; +use derive_more::Display; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::{map_to_mm::MapToMmResult, mm_error::MmResult}; diff --git a/mm2src/mm2_main/src/rpc/streaming_activations/heartbeat.rs b/mm2src/mm2_main/src/rpc/streaming_activations/heartbeat.rs index e3f4d06c5e..929b6059fd 100644 --- a/mm2src/mm2_main/src/rpc/streaming_activations/heartbeat.rs +++ b/mm2src/mm2_main/src/rpc/streaming_activations/heartbeat.rs @@ -3,6 +3,7 @@ use super::{EnableStreamingRequest, EnableStreamingResponse}; use crate::heartbeat_event::{HeartbeatEvent, HeartbeatEventConfig}; use common::HttpStatusCode; +use derive_more::Display; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::{map_to_mm::MapToMmResult, mm_error::MmResult}; diff --git a/mm2src/mm2_main/src/rpc/streaming_activations/network.rs b/mm2src/mm2_main/src/rpc/streaming_activations/network.rs index 11f9d0ed3b..ca413588b6 100644 --- a/mm2src/mm2_main/src/rpc/streaming_activations/network.rs +++ b/mm2src/mm2_main/src/rpc/streaming_activations/network.rs @@ -2,6 +2,7 @@ use super::{EnableStreamingRequest, EnableStreamingResponse}; use common::HttpStatusCode; +use derive_more::Display; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::{map_to_mm::MapToMmResult, mm_error::MmResult}; diff --git a/mm2src/mm2_main/src/rpc/streaming_activations/orderbook.rs b/mm2src/mm2_main/src/rpc/streaming_activations/orderbook.rs index 60805c4a54..f28794f575 100644 --- a/mm2src/mm2_main/src/rpc/streaming_activations/orderbook.rs +++ b/mm2src/mm2_main/src/rpc/streaming_activations/orderbook.rs @@ -1,6 +1,7 @@ //! RPC activation and deactivation of the orderbook streamer. use super::EnableStreamingResponse; use crate::lp_ordermatch::orderbook_events::OrderbookStreamer; +use derive_more::Display; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::{map_to_mm::MapToMmResult, mm_error::MmResult}; diff --git a/mm2src/mm2_main/src/rpc/streaming_activations/orders.rs b/mm2src/mm2_main/src/rpc/streaming_activations/orders.rs index 08fd0a959a..7c7aa0c082 100644 --- a/mm2src/mm2_main/src/rpc/streaming_activations/orders.rs +++ b/mm2src/mm2_main/src/rpc/streaming_activations/orders.rs @@ -1,6 +1,8 @@ //! RPC activation and deactivation of the order status streamer. -use super::{EnableStreamingRequest, EnableStreamingResponse}; use crate::lp_ordermatch::order_events::OrderStatusStreamer; + +use super::{EnableStreamingRequest, EnableStreamingResponse}; +use derive_more::Display; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::{map_to_mm::MapToMmResult, mm_error::MmResult}; diff --git a/mm2src/mm2_main/src/rpc/streaming_activations/swaps.rs b/mm2src/mm2_main/src/rpc/streaming_activations/swaps.rs index 3d4aa2b93e..f632b1758a 100644 --- a/mm2src/mm2_main/src/rpc/streaming_activations/swaps.rs +++ b/mm2src/mm2_main/src/rpc/streaming_activations/swaps.rs @@ -1,11 +1,12 @@ //! RPC activation and deactivation of the swap status streamer. -use super::{EnableStreamingRequest, EnableStreamingResponse}; use crate::lp_swap::swap_events::SwapStatusStreamer; -use mm2_core::mm_ctx::MmArc; -use mm2_err_handle::{map_to_mm::MapToMmResult, mm_error::MmResult}; +use super::{EnableStreamingRequest, EnableStreamingResponse}; use common::HttpStatusCode; +use derive_more::Display; use http::StatusCode; +use mm2_core::mm_ctx::MmArc; +use mm2_err_handle::{map_to_mm::MapToMmResult, mm_error::MmResult}; #[derive(Display, Serialize, SerializeErrorType)] #[serde(tag = "error_type", content = "error_data")] diff --git a/mm2src/mm2_main/src/rpc/streaming_activations/tx_history.rs b/mm2src/mm2_main/src/rpc/streaming_activations/tx_history.rs index ac37ca21b5..e79893ee8e 100644 --- a/mm2src/mm2_main/src/rpc/streaming_activations/tx_history.rs +++ b/mm2src/mm2_main/src/rpc/streaming_activations/tx_history.rs @@ -5,6 +5,7 @@ use coins::utxo::tx_history_events::TxHistoryEventStreamer; use coins::z_coin::tx_history_events::ZCoinTxHistoryEventStreamer; use coins::{lp_coinfind, MmCoin, MmCoinEnum}; use common::HttpStatusCode; +use derive_more::Display; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::{map_to_mm::MapToMmResult, mm_error::MmResult}; diff --git a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs index 3f8c457d63..86bf529d19 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs @@ -24,11 +24,7 @@ pub async fn get_all_sessions( ) -> MmResult { let wc_ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - let sessions = wc_ctx - .session_manager - .get_sessions() - .map(SessionRpcInfo::from) - .collect::>(); + let sessions = wc_ctx.session_manager.get_sessions().collect::>(); Ok(GetSessionsResponse { sessions }) } diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs index 6a483767af..97e8fde494 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_common.rs @@ -1,12 +1,10 @@ use coins::z_coin::ZCoin; -pub use common::{block_on, block_on_f01, now_ms, now_sec, wait_until_ms, wait_until_sec, DEX_FEE_ADDR_RAW_PUBKEY}; +pub use common::{block_on, block_on_f01, now_ms, now_sec, wait_until_ms, wait_until_sec}; pub use mm2_number::MmNumber; use mm2_rpc::data::legacy::BalanceResponse; pub use mm2_test_helpers::for_tests::{check_my_swap_status, check_recent_swaps, enable_eth_coin, enable_native, - enable_native_bch, erc20_dev_conf, eth_dev_conf, eth_sepolia_conf, - jst_sepolia_conf, mm_dump, wait_check_stats_swap_status, MarketMakerIt, - MAKER_ERROR_EVENTS, MAKER_SUCCESS_EVENTS, TAKER_ERROR_EVENTS, - TAKER_SUCCESS_EVENTS}; + enable_native_bch, erc20_dev_conf, eth_dev_conf, mm_dump, + wait_check_stats_swap_status, MarketMakerIt}; use super::eth_docker_tests::{erc20_contract_checksum, fill_eth, fill_eth_erc20_with_private_key, swap_contract}; use super::z_coin_docker_tests::z_coin_from_spending_key; @@ -122,7 +120,7 @@ pub static SEPOLIA_RPC_URL: &str = "https://ethereum-sepolia-rpc.publicnode.com" // use thread local to affect only the current running test thread_local! { /// Set test dex pubkey as Taker (to check DexFee::NoFee) - pub static SET_BURN_PUBKEY_TO_ALICE: Cell = Cell::new(false); + pub static SET_BURN_PUBKEY_TO_ALICE: Cell = const { Cell::new(false) }; } pub const UTXO_ASSET_DOCKER_IMAGE: &str = "docker.io/artempikulin/testblockchain"; @@ -830,7 +828,7 @@ where block_on_f01(coin.wait_for_confirmations(confirm_payment_input)).unwrap(); log!("{:02x}", tx_bytes); loop { - let unspents = block_on_f01(client.list_unspent_impl(0, std::i32::MAX, vec![address.to_string()])).unwrap(); + let unspents = block_on_f01(client.list_unspent_impl(0, i32::MAX, vec![address.to_string()])).unwrap(); if !unspents.is_empty() { break; } @@ -1261,7 +1259,7 @@ pub fn wait_until_relayer_container_is_ready(container_id: &str) { log!("Expected output {Q_RESULT}, received {output}."); if attempts > 10 { - panic!("{}", "Reached max attempts for <<{docker:?}>>."); + panic!("Reached max attempts for <<{:?}>>.", docker); } else { log!("Asking for relayer node status again.."); } diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs index c34a2afe55..b8a7164dd9 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs @@ -4125,7 +4125,7 @@ fn test_withdraw_and_send_hd_eth_erc20() { EnableCoinBalanceMap::HD(hd) => hd, _ => panic!("Expected EnableCoinBalance::HD"), }; - let account = balance.accounts.get(0).expect("Expected account at index 0"); + let account = balance.accounts.first().expect("Expected account at index 0"); assert_eq!( account.addresses[1].address, "0xDe841899aB4A22E23dB21634e54920aDec402397" diff --git a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs index 76b7f773c8..81fe6d4a10 100644 --- a/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/eth_docker_tests.rs @@ -2514,7 +2514,7 @@ fn test_eth_erc20_hd() { EnableCoinBalanceMap::HD(hd) => hd, _ => panic!("Expected EnableCoinBalance::HD"), }; - let account = balance.accounts.get(0).expect("Expected account at index 0"); + let account = balance.accounts.first().expect("Expected account at index 0"); assert_eq!( account.addresses[0].address, "0x1737F1FaB40c6Fd3dc729B51C0F97DB3297CCA93" @@ -2553,7 +2553,7 @@ fn test_eth_erc20_hd() { EnableCoinBalanceMap::HD(hd) => hd, _ => panic!("Expected EnableCoinBalance::HD"), }; - let account = balance.accounts.get(0).expect("Expected account at index 0"); + let account = balance.accounts.first().expect("Expected account at index 0"); assert_eq!( account.addresses[1].address, "0xDe841899aB4A22E23dB21634e54920aDec402397" @@ -2607,7 +2607,7 @@ fn test_eth_erc20_hd() { EnableCoinBalanceMap::HD(hd) => hd, _ => panic!("Expected EnableCoinBalance::HD"), }; - let account = balance.accounts.get(0).expect("Expected account at index 0"); + let account = balance.accounts.first().expect("Expected account at index 0"); assert_eq!( account.addresses[7].address, "0xa420a4DBd8C50e6240014Db4587d2ec8D0cE0e6B" diff --git a/mm2src/mm2_main/tests/docker_tests/mod.rs b/mm2src/mm2_main/tests/docker_tests/mod.rs index 8dce2cdfb8..7ea93458eb 100644 --- a/mm2src/mm2_main/tests/docker_tests/mod.rs +++ b/mm2src/mm2_main/tests/docker_tests/mod.rs @@ -1,3 +1,4 @@ +#![allow(static_mut_refs)] pub mod docker_tests_common; mod docker_ordermatch_tests; diff --git a/mm2src/mm2_main/tests/docker_tests/qrc20_tests.rs b/mm2src/mm2_main/tests/docker_tests/qrc20_tests.rs index dfc6f3fabf..5b076942bf 100644 --- a/mm2src/mm2_main/tests/docker_tests/qrc20_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/qrc20_tests.rs @@ -808,7 +808,8 @@ fn test_wait_for_tx_spend() { log!("error: {:?}", err); assert!(err.contains("Waited too long")); - // also spends the maker payment and try to check if the wait_for_htlc_tx_spend() returns the correct tx + /// Also spends the maker payment and try to check if the wait_for_htlc_tx_spend() returns the correct tx + #[allow(static_mut_refs)] static mut SPEND_TX: Option = None; let maker_pub_c = maker_pub.to_vec(); diff --git a/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs b/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs index fcb111dca3..cfd29cbecc 100644 --- a/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs @@ -1267,7 +1267,7 @@ fn test_watcher_validate_taker_fee_utxo() { let error = block_on_f01(taker_coin.watcher_validate_taker_fee(WatcherValidateTakerFeeInput { taker_fee_hash: taker_fee.tx_hash_as_bytes().into_vec(), sender_pubkey: taker_pubkey.to_vec(), - min_block_number: std::u64::MAX, + min_block_number: u64::MAX, lock_duration, })) .unwrap_err() @@ -1374,7 +1374,7 @@ fn test_watcher_validate_taker_fee_eth() { let error = block_on_f01(taker_coin.watcher_validate_taker_fee(WatcherValidateTakerFeeInput { taker_fee_hash: taker_fee.tx_hash_as_bytes().into_vec(), sender_pubkey: taker_pubkey.to_vec(), - min_block_number: std::u64::MAX, + min_block_number: u64::MAX, lock_duration, })) .unwrap_err() @@ -1465,7 +1465,7 @@ fn test_watcher_validate_taker_fee_erc20() { let error = block_on_f01(taker_coin.watcher_validate_taker_fee(WatcherValidateTakerFeeInput { taker_fee_hash: taker_fee.tx_hash_as_bytes().into_vec(), sender_pubkey: taker_pubkey.to_vec(), - min_block_number: std::u64::MAX, + min_block_number: u64::MAX, lock_duration, })) .unwrap_err() diff --git a/mm2src/mm2_main/tests/docker_tests/z_coin_docker_tests.rs b/mm2src/mm2_main/tests/docker_tests/z_coin_docker_tests.rs index 1fa139ab31..fe0f009dcd 100644 --- a/mm2src/mm2_main/tests/docker_tests/z_coin_docker_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/z_coin_docker_tests.rs @@ -23,7 +23,7 @@ lazy_static! { } /// Build asset `ZCoin` from ticker and spending_key. -pub async fn z_coin_from_spending_key<'a>(spending_key: &str, path: &'a str) -> (MmArc, ZCoin) { +pub async fn z_coin_from_spending_key(spending_key: &str, path: &str) -> (MmArc, ZCoin) { let tmp = TEMP_DIR.lock().await; let db_path = tmp.path().join(format!("ZOMBIE_DB_{path}")); std::fs::create_dir_all(&db_path).unwrap(); diff --git a/mm2src/mm2_main/tests/docker_tests_main.rs b/mm2src/mm2_main/tests/docker_tests_main.rs index 7465728008..fc5766cf79 100644 --- a/mm2src/mm2_main/tests/docker_tests_main.rs +++ b/mm2src/mm2_main/tests/docker_tests_main.rs @@ -1,11 +1,9 @@ #![cfg(feature = "run-docker-tests")] -#![feature(async_closure)] +#![cfg(not(target_arch = "wasm32"))] #![feature(custom_test_frameworks)] #![feature(test)] #![test_runner(docker_tests_runner)] -#![feature(drain_filter)] -#![cfg(not(target_arch = "wasm32"))] -#![feature(local_key_cell_methods)] // for setting global vars in tests +#![feature(hash_raw_entry)] #[cfg(test)] #[macro_use] diff --git a/mm2src/mm2_main/tests/docker_tests_sia_unique.rs b/mm2src/mm2_main/tests/docker_tests_sia_unique.rs index b8c2b74fea..67ba07aec6 100644 --- a/mm2src/mm2_main/tests/docker_tests_sia_unique.rs +++ b/mm2src/mm2_main/tests/docker_tests_sia_unique.rs @@ -1,12 +1,10 @@ -#![allow(unused_imports, dead_code)] -#![cfg(feature = "enable-sia")] -#![feature(async_closure)] #![feature(custom_test_frameworks)] #![feature(test)] -#![test_runner(docker_tests_runner)] -#![feature(drain_filter)] +#![feature(hash_raw_entry)] +#![cfg(feature = "enable-sia")] #![cfg(not(target_arch = "wasm32"))] -#![feature(local_key_cell_methods)] +#![allow(unused_imports, dead_code)] +#![test_runner(docker_tests_runner)] #[cfg(test)] #[macro_use] diff --git a/mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs b/mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs index 392a046838..439467c334 100644 --- a/mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs +++ b/mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs @@ -5067,8 +5067,8 @@ fn test_sign_verify_message_utxo_with_derivation_path() { EnableCoinBalanceMap::HD(hd) => hd, _ => panic!("Expected EnableCoinBalance::HD"), }; - let address0 = &balance.accounts.get(0).expect("Expected account at index 0").addresses[0].address; - let address1 = &balance.accounts.get(0).expect("Expected account at index 1").addresses[1].address; + let address0 = &balance.accounts.first().expect("Expected account at index 0").addresses[0].address; + let address1 = &balance.accounts.first().expect("Expected account at index 1").addresses[1].address; // Test address0 let expected_signature = "ICnkSvQkAurwLvK6RYtCItrWMOS4ESjCf4GKp1DvBM8Xc2+dxM4si6NcSb0JJaJajYhPkwg5yWHmgR/9AmGB0KE="; @@ -5239,7 +5239,7 @@ fn test_sign_verify_message_segwit_with_bip84_derivation_path() { _ => panic!("Expected EnableCoinBalance::HD"), }; - let account0 = balance.accounts.get(0).expect("Expected account at index 0"); + let account0 = balance.accounts.first().expect("Expected account at index 0"); let address0 = &account0.addresses[0].address; let address1 = &account0.addresses[1].address; @@ -6133,7 +6133,7 @@ fn test_enable_utxo_with_enable_hd() { EnableCoinBalanceMap::HD(hd) => hd, _ => panic!("Expected EnableCoinBalance::HD"), }; - let account = balance.accounts.get(0).expect("Expected account at index 0"); + let account = balance.accounts.first().expect("Expected account at index 0"); assert_eq!(account.addresses[0].address, "RXNtAyDSsY3DS3VxTpJegzoHU9bUX54j56"); assert_eq!(account.addresses[1].address, "RVyndZp3ZrhGKSwHryyM3Kcz9aq2EJrW1z"); let new_account = block_on(create_new_account(&mm_hd_0, "RICK", Some(77), 60)); @@ -6151,7 +6151,7 @@ fn test_enable_utxo_with_enable_hd() { EnableCoinBalanceMap::HD(hd) => hd, _ => panic!("Expected EnableCoinBalance::HD"), }; - let account = balance.accounts.get(0).expect("Expected account at index 0"); + let account = balance.accounts.first().expect("Expected account at index 0"); // This is the enabled address, so it should be derived and added to the account assert_eq!( account.addresses[0].address, @@ -6683,6 +6683,7 @@ mod trezor_tests { pub enum InitTrezorStatus { Ok(InitHwResponse), Error(Json), + #[expect(dead_code)] InProgress(Json), UserActionRequired(Json), } diff --git a/mm2src/mm2_main/tests/mm2_tests/mod.rs b/mm2src/mm2_main/tests/mm2_tests/mod.rs index 6bd10e28a2..62cd207cb3 100644 --- a/mm2src/mm2_main/tests/mm2_tests/mod.rs +++ b/mm2src/mm2_main/tests/mm2_tests/mod.rs @@ -7,21 +7,17 @@ mod mm2_tests_inner; mod orderbook_sync_tests; mod z_coin_tests; -mod zhtlc_native_reexport { - pub use common::executor::Timer; - pub use common::{now_ms, wait_until_ms}; - pub use mm2_test_helpers::for_tests::MarketMakerIt; - pub use mm2_test_helpers::for_tests::{init_z_coin_native, init_z_coin_status}; - pub use mm2_test_helpers::structs::{CoinActivationResult, InitTaskResult, InitZcoinStatus, RpcV2Response}; -} - #[cfg(all(feature = "zhtlc-native-tests", not(target_arch = "wasm32")))] -use mm2_test_helpers::structs::ZCoinActivationResult; +use mm2_test_helpers::for_tests::MarketMakerIt; #[cfg(all(feature = "zhtlc-native-tests", not(target_arch = "wasm32")))] -use zhtlc_native_reexport::*; +use mm2_test_helpers::structs::ZCoinActivationResult; #[cfg(all(feature = "zhtlc-native-tests", not(target_arch = "wasm32")))] async fn enable_z_coin(mm: &MarketMakerIt, coin: &str) -> ZCoinActivationResult { + use common::{executor::Timer, wait_until_ms}; + use mm2_test_helpers::{for_tests::{init_z_coin_native, init_z_coin_status}, + structs::{InitTaskResult, InitZcoinStatus, RpcV2Response}}; + let init = init_z_coin_native(mm, coin).await; let init: RpcV2Response = serde_json::from_value(init).unwrap(); let timeout = wait_until_ms(120000); diff --git a/mm2src/mm2_metamask/src/metamask.rs b/mm2src/mm2_metamask/src/metamask.rs index 9fd135eee5..b6036d93c2 100644 --- a/mm2src/mm2_metamask/src/metamask.rs +++ b/mm2src/mm2_metamask/src/metamask.rs @@ -56,8 +56,9 @@ impl<'a> MetamaskSession<'a> { CallFuture::new(self.transport.execute("wallet_switchEthereumChain", vec![req])).await } - /// * user_address - Must match user's active address. /// Returns a hash of the `Eip712` request and the signature. + /// + /// Note: `user_address` must match user's active address. pub async fn sign_typed_data_v4( &self, user_address: String, diff --git a/mm2src/mm2_metrics/src/mm_metrics.rs b/mm2src/mm2_metrics/src/mm_metrics.rs index 9c77bc73c8..cac7d8de4a 100644 --- a/mm2src/mm2_metrics/src/mm_metrics.rs +++ b/mm2src/mm2_metrics/src/mm_metrics.rs @@ -192,7 +192,7 @@ fn map_metrics_to_prepare_tag_metric_output( let (metric_name, labels) = key.into_parts(); output .entry(labels) - .or_insert_with(MetricNameValueMap::new) + .or_default() .insert(metric_name.as_str().to_string(), value); } @@ -537,6 +537,7 @@ mod test { block_on(async { Timer::sleep(6.).await }); } + #[cfg(not(target_arch = "wasm32"))] #[test] fn test_prometheus_format() { let mm_metrics = MetricsArc::new(); diff --git a/mm2src/mm2_net/src/wasm/wasm_ws.rs b/mm2src/mm2_net/src/wasm/wasm_ws.rs index 1d19d43a60..92634ea1a3 100644 --- a/mm2src/mm2_net/src/wasm/wasm_ws.rs +++ b/mm2src/mm2_net/src/wasm/wasm_ws.rs @@ -748,7 +748,12 @@ mod tests { let mut incoming_rx = incoming_rx.inner; match incoming_rx.next().timeout_secs(0.5).await.unwrap_w() { - Some((_conn_idx, WebSocketEvent::Closed { reason })) if reason == ClosureReason::NormalClosure => (), + Some(( + _conn_idx, + WebSocketEvent::Closed { + reason: ClosureReason::NormalClosure, + }, + )) => (), other => panic!("Expected 'Closed' event with 'ClientClosed' reason, found: {:?}", other), } } diff --git a/mm2src/mm2_number/src/big_int_str.rs b/mm2src/mm2_number/src/big_int_str.rs index d0855cfbbf..9f2d0b52a8 100644 --- a/mm2src/mm2_number/src/big_int_str.rs +++ b/mm2src/mm2_number/src/big_int_str.rs @@ -32,7 +32,7 @@ impl<'de> Deserialize<'de> for BigIntStr { fn deserialize>(deserializer: D) -> Result { struct BigIntStrVisitor; - impl<'de> de::Visitor<'de> for BigIntStrVisitor { + impl de::Visitor<'_> for BigIntStrVisitor { type Value = BigIntStr; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { diff --git a/mm2src/mm2_number/src/mm_number.rs b/mm2src/mm2_number/src/mm_number.rs index af45e7a040..326258e328 100644 --- a/mm2src/mm2_number/src/mm_number.rs +++ b/mm2src/mm2_number/src/mm_number.rs @@ -64,11 +64,13 @@ macro_rules! construct_detailed { pub struct MmNumber(pub(crate) BigRational); /// Handwritten deserialization method allows the MmNumber to be deserialized from: -/// 1. big rational representation, -/// 2. decimal string e.g. "0.1" -/// 3. fraction object e.g. { "numer":"2", "denom":"3" } +/// 1. big rational representation, +/// 2. decimal string e.g. "0.1" +/// 3. fraction object e.g. { "numer":"2", "denom":"3" } +/// /// IMPORTANT: the deserialization implementation works properly from JSON only! /// Consider using BigRational type directly for other serde implementations +/// impl<'de> Deserialize<'de> for MmNumber { fn deserialize(deserializer: D) -> Result>::Error> where diff --git a/mm2src/mm2_p2p/src/behaviours/mod.rs b/mm2src/mm2_p2p/src/behaviours/mod.rs index 8d8b4442b1..a778673a20 100644 --- a/mm2src/mm2_p2p/src/behaviours/mod.rs +++ b/mm2src/mm2_p2p/src/behaviours/mod.rs @@ -5,7 +5,7 @@ mod ping; pub(crate) mod peers_exchange; pub(crate) mod request_response; -#[cfg(test)] +#[cfg(all(test, not(target_arch = "wasm32")))] mod tests { use async_std::task::spawn; use common::executor::abortable_queue::AbortableQueue; diff --git a/mm2src/mm2_p2p/src/lib.rs b/mm2src/mm2_p2p/src/lib.rs index ff05a6d4f6..f856de98d1 100644 --- a/mm2src/mm2_p2p/src/lib.rs +++ b/mm2src/mm2_p2p/src/lib.rs @@ -76,7 +76,7 @@ impl<'de> Deserialize<'de> for PeerAddress { { struct PeerAddressVisitor; - impl<'de> serde::de::Visitor<'de> for PeerAddressVisitor { + impl serde::de::Visitor<'_> for PeerAddressVisitor { type Value = PeerAddress; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { diff --git a/mm2src/mm2_state_machine/src/storable_state_machine.rs b/mm2src/mm2_state_machine/src/storable_state_machine.rs index 49b57af532..87445fe033 100644 --- a/mm2src/mm2_state_machine/src/storable_state_machine.rs +++ b/mm2src/mm2_state_machine/src/storable_state_machine.rs @@ -430,10 +430,7 @@ mod tests { async fn has_record_for(&mut self, _id: &Self::MachineId) -> Result { Ok(false) } async fn store_event(&mut self, machine_id: usize, event: TestEvent) -> Result<(), Self::Error> { - self.events_unfinished - .entry(machine_id) - .or_insert_with(Vec::new) - .push(event); + self.events_unfinished.entry(machine_id).or_default().push(event); Ok(()) } diff --git a/mm2src/trading_api/src/one_inch_api/client.rs b/mm2src/trading_api/src/one_inch_api/client.rs index c4856ae572..0be898a84e 100644 --- a/mm2src/trading_api/src/one_inch_api/client.rs +++ b/mm2src/trading_api/src/one_inch_api/client.rs @@ -204,7 +204,10 @@ impl ApiClient { ] } - pub async fn call_api(api_url: Url) -> MmResult { + pub async fn call_api(api_url: Url) -> MmResult + where + T: DeserializeOwned, + { #[cfg(feature = "test-ext-api")] let _guard = ApiClient::one_req_per_sec().await; diff --git a/mm2src/trading_api/src/one_inch_api/portfolio_types.rs b/mm2src/trading_api/src/one_inch_api/portfolio_types.rs index 5100c7434c..a77a3d647c 100644 --- a/mm2src/trading_api/src/one_inch_api/portfolio_types.rs +++ b/mm2src/trading_api/src/one_inch_api/portfolio_types.rs @@ -6,6 +6,7 @@ use common::{def_with_opt_param, push_if_some}; use mm2_err_handle::mm_error::MmResult; use mm2_number::BigDecimal; use serde::Deserialize; +use std::fmt; #[derive(Default)] pub enum DataGranularity { @@ -19,16 +20,16 @@ pub enum DataGranularity { FiveMin, } -impl ToString for DataGranularity { - fn to_string(&self) -> String { +impl fmt::Display for DataGranularity { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - DataGranularity::Month => "month".to_owned(), - DataGranularity::Week => "week".to_owned(), - DataGranularity::Day => "day".to_owned(), - DataGranularity::FourHour => "4hour".to_owned(), - DataGranularity::Hour => "hour".to_owned(), - DataGranularity::FifteenMin => "15min".to_owned(), - DataGranularity::FiveMin => "5min".to_owned(), + DataGranularity::Month => write!(f, "month"), + DataGranularity::Week => write!(f, "week"), + DataGranularity::Day => write!(f, "day"), + DataGranularity::FourHour => write!(f, "4hour"), + DataGranularity::Hour => write!(f, "hour"), + DataGranularity::FifteenMin => write!(f, "15min"), + DataGranularity::FiveMin => write!(f, "5min"), } } } diff --git a/mm2src/trezor/src/error.rs b/mm2src/trezor/src/error.rs index 6a67c592f2..aa8954c1fd 100644 --- a/mm2src/trezor/src/error.rs +++ b/mm2src/trezor/src/error.rs @@ -35,7 +35,7 @@ pub enum TrezorError { UnexpectedInteractionRequest(TrezorUserInteraction), Internal(String), PongMessageMismatch, - #[display("no processor for trezor response")] + #[display(fmt = "no processor for trezor response")] InternalNoProcessor, } diff --git a/mm2src/trezor/src/proto/messages_bitcoin.rs b/mm2src/trezor/src/proto/messages_bitcoin.rs index 8826c9a997..ad0be5f85b 100644 --- a/mm2src/trezor/src/proto/messages_bitcoin.rs +++ b/mm2src/trezor/src/proto/messages_bitcoin.rs @@ -531,7 +531,7 @@ pub struct TxInput { pub decred_staking_spend: ::core::option::Option, } ///* Data type for transaction output to be signed. -/// @embed +/// @embed #[derive(Clone, PartialEq, ::prost::Message)] pub struct TxOutput { /// destination address in Base58 encoding; script_type must be PAYTOADDRESS @@ -560,7 +560,7 @@ pub struct TxOutput { pub orig_index: ::core::option::Option, } ///* Data type for metadata about previous transaction which contains the UTXO being spent. -/// @embed +/// @embed #[derive(Clone, PartialEq, ::prost::Message)] pub struct PrevTx { #[prost(uint32, required, tag = "1")] @@ -610,7 +610,7 @@ pub struct PrevInput { pub decred_tree: ::core::option::Option, } ///* Data type for outputs of previous transactions. -/// @embed +/// @embed #[derive(Clone, PartialEq, ::prost::Message)] pub struct PrevOutput { /// amount sent to this output diff --git a/mm2src/trezor/src/response.rs b/mm2src/trezor/src/response.rs index c0bebc2415..bec11e5f92 100644 --- a/mm2src/trezor/src/response.rs +++ b/mm2src/trezor/src/response.rs @@ -103,7 +103,7 @@ impl<'a, 'b, T: 'static> TrezorResponse<'a, 'b, T> { } #[async_trait] -impl<'a, 'b, T> ProcessTrezorResponse for TrezorResponse<'a, 'b, T> +impl ProcessTrezorResponse for TrezorResponse<'_, '_, T> where T: Send + Sync + 'static, { @@ -148,7 +148,7 @@ pub struct ButtonRequest<'a, 'b, T> { result_handler: ResultHandler, } -impl<'a, 'b, T> fmt::Debug for ButtonRequest<'a, 'b, T> { +impl fmt::Debug for ButtonRequest<'_, '_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self.message) } } @@ -175,7 +175,7 @@ pub struct PinMatrixRequest<'a, 'b, T> { result_handler: ResultHandler, } -impl<'a, 'b, T> fmt::Debug for PinMatrixRequest<'a, 'b, T> { +impl fmt::Debug for PinMatrixRequest<'_, '_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self.message) } } @@ -202,7 +202,7 @@ pub struct PassphraseRequest<'a, 'b, T> { result_handler: ResultHandler, } -impl<'a, 'b, T> fmt::Debug for PassphraseRequest<'a, 'b, T> { +impl fmt::Debug for PassphraseRequest<'_, '_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self.message) } } diff --git a/mm2src/trezor/src/utxo/sign_utxo.rs b/mm2src/trezor/src/utxo/sign_utxo.rs index 7f53182639..fca504bc44 100644 --- a/mm2src/trezor/src/utxo/sign_utxo.rs +++ b/mm2src/trezor/src/utxo/sign_utxo.rs @@ -35,7 +35,7 @@ impl<'a> TrezorSession<'a> { /// # Fail /// /// Currently, this method fails if a device requests a PIN. - pub async fn sign_utxo_tx<'b>(&'b mut self, unsigned: UnsignedUtxoTx) -> TrezorResult { + pub async fn sign_utxo_tx(&mut self, unsigned: UnsignedUtxoTx) -> TrezorResult { use proto_bitcoin::tx_request::RequestType as ProtoTxRequestType; let mut result = TxSignResult::new_with_inputs_count(unsigned.inputs.len()); @@ -107,8 +107,8 @@ impl<'a> TrezorSession<'a> { } } - async fn send_prev_tx_meta<'b>( - &'b mut self, + async fn send_prev_tx_meta( + &mut self, unsigned: &UnsignedUtxoTx, prev_tx_hash: &[u8], ) -> TrezorResult { @@ -128,8 +128,8 @@ impl<'a> TrezorSession<'a> { .mm_err(|e| TrezorError::Internal(e.to_string())) } - async fn send_prev_input<'b>( - &'b mut self, + async fn send_prev_input( + &mut self, unsigned: &UnsignedUtxoTx, request_details: &proto_bitcoin::tx_request::TxRequestDetailsType, prev_tx_hash: &[u8], @@ -155,8 +155,8 @@ impl<'a> TrezorSession<'a> { .mm_err(|e| TrezorError::Internal(e.to_string())) } - async fn send_prev_output<'b>( - &'b mut self, + async fn send_prev_output( + &mut self, unsigned: &UnsignedUtxoTx, request_details: &proto_bitcoin::tx_request::TxRequestDetailsType, prev_tx_hash: &[u8], @@ -182,8 +182,8 @@ impl<'a> TrezorSession<'a> { .mm_err(|e| TrezorError::Internal(e.to_string())) } - async fn send_input<'b>( - &'b mut self, + async fn send_input( + &mut self, unsigned: &UnsignedUtxoTx, request_details: &proto_bitcoin::tx_request::TxRequestDetailsType, ) -> TrezorResult { @@ -206,8 +206,8 @@ impl<'a> TrezorSession<'a> { .mm_err(|e| TrezorError::Internal(e.to_string())) } - async fn send_output<'b>( - &'b mut self, + async fn send_output( + &mut self, unsigned: &UnsignedUtxoTx, request_details: &proto_bitcoin::tx_request::TxRequestDetailsType, ) -> TrezorResult { @@ -230,8 +230,8 @@ impl<'a> TrezorSession<'a> { .mm_err(|e| TrezorError::Internal(e.to_string())) } - async fn send_extra_data<'b>( - &'b mut self, + async fn send_extra_data( + &mut self, unsigned: &UnsignedUtxoTx, request_details: &proto_bitcoin::tx_request::TxRequestDetailsType, prev_tx_hash: &[u8], @@ -260,10 +260,10 @@ impl<'a> TrezorSession<'a> { .mm_err(|e| TrezorError::Internal(e.to_string())) } - async fn sign_tx<'b>( - &'b mut self, + async fn sign_tx( + &mut self, req: proto_bitcoin::SignTx, - ) -> TrezorResult> { + ) -> TrezorResult> { let result_handler = ResultHandler::::new(Ok); self.call(req, result_handler).await } diff --git a/rust-toolchain.toml b/rust-toolchain.toml index f1739addd6..7334df45c5 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-06-01" +channel = "nightly-2025-01-03" components = ["rustfmt", "clippy", "rust-analyzer"] From 543598231c1e4c951c81c93c1d5fa2c99a857510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Mon, 7 Jul 2025 14:51:48 +0300 Subject: [PATCH 06/75] improvement(eth): drop parity support (#2527) Parity nodes have been deprecated for years, this removes support for them and also fixes the conflict between version checking and komodo-defi-proxy. --- mm2src/coins/eth.rs | 60 ++++++++++++------------------- mm2src/coins/eth/eth_rpc.rs | 6 ++-- mm2src/coins/eth/for_tests.rs | 2 +- mm2src/coins/eth/nonce.rs | 29 --------------- mm2src/coins/eth/v2_activation.rs | 14 ++------ 5 files changed, 28 insertions(+), 83 deletions(-) delete mode 100644 mm2src/coins/eth/nonce.rs diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index ba62d22b55..20346b6e9e 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -76,7 +76,7 @@ pub use ethcore_transaction::{SignedTransaction as SignedEthTx, TxType}; use ethereum_types::{Address, H160, H256, U256}; use ethkey::{public_to_address, sign, verify_address, KeyPair, Public, Signature}; use futures::compat::Future01CompatExt; -use futures::future::{join, join_all, select_ok, try_join_all, Either, FutureExt, TryFutureExt}; +use futures::future::{join, join_all, select_ok, try_join_all, FutureExt, TryFutureExt}; use futures01::Future; use http::Uri; use kdf_walletconnect::{WalletConnectCtx, WalletConnectOps}; @@ -159,9 +159,6 @@ use v2_activation::{build_address_and_priv_key_policy, EthActivationV2Error}; mod eth_withdraw; use eth_withdraw::{EthWithdraw, InitEthWithdraw, StandardEthWithdraw}; -mod nonce; -use nonce::ParityNonce; - pub mod fee_estimation; use fee_estimation::eip1559::{block_native::BlocknativeGasApiCaller, infura::InfuraGasApiCaller, simple::FeePerGasSimpleEstimator, FeePerGasEstimated, GasApiConfig, GasApiProvider}; @@ -908,9 +905,10 @@ pub struct EthCoinImpl { } #[derive(Clone, Debug)] -pub struct Web3Instance { - web3: Web3, - is_parity: bool, +pub struct Web3Instance(Web3); + +impl AsRef> for Web3Instance { + fn as_ref(&self) -> &Web3 { &self.0 } } /// Information about a token that follows the ERC20 protocol on an EVM-based network. @@ -2826,7 +2824,7 @@ async fn sign_and_send_transaction_with_keypair( let futures = web3_instances_with_latest_nonce .into_iter() - .map(|web3_instance| web3_instance.web3.eth().send_raw_transaction(bytes.clone())); + .map(|web3_instance| web3_instance.as_ref().eth().send_raw_transaction(bytes.clone())); try_tx_s!(select_ok(futures).await.map_err(|e| ERRL!("{}", e)), signed); info!(target: "sign-and-send", "wait_for_tx_appears_on_rpc…"); @@ -3017,18 +3015,18 @@ impl RpcCommonOps for EthCoin { // try to find first live client for (i, client) in clients.clone().into_iter().enumerate() { - if let Web3Transport::Websocket(socket_transport) = &client.web3.transport() { + if let Web3Transport::Websocket(socket_transport) = client.as_ref().transport() { socket_transport.maybe_spawn_connection_loop(self.clone()); }; - if !client.web3.transport().is_last_request_failed() { + if !client.as_ref().transport().is_last_request_failed() { // Bring the live client to the front of rpc_clients clients.rotate_left(i); return Ok(client); } match client - .web3 + .as_ref() .web3() .client_version() .timeout(ETH_RPC_REQUEST_TIMEOUT) @@ -3042,7 +3040,7 @@ impl RpcCommonOps for EthCoin { Ok(Err(rpc_error)) => { debug!("Could not get client version on: {:?}. Error: {}", &client, rpc_error); - if let Web3Transport::Websocket(socket_transport) = client.web3.transport() { + if let Web3Transport::Websocket(socket_transport) = client.as_ref().transport() { socket_transport.stop_connection_loop().await; }; }, @@ -3052,7 +3050,7 @@ impl RpcCommonOps for EthCoin { &client, timeout_error ); - if let Web3Transport::Websocket(socket_transport) = client.web3.transport() { + if let Web3Transport::Websocket(socket_transport) = client.as_ref().transport() { socket_transport.stop_connection_loop().await; }; }, @@ -3067,7 +3065,7 @@ impl RpcCommonOps for EthCoin { impl EthCoin { pub(crate) async fn web3(&self) -> Result, Web3RpcError> { - self.get_live_client().await.map(|t| t.web3) + self.get_live_client().await.map(|t| t.0) } /// Gets `SenderRefunded` events from etomic swap smart contract since `from_block` @@ -5720,22 +5718,19 @@ impl EthCoin { let (futures, web3_instances): (Vec<_>, Vec<_>) = web3_instances .iter() .map(|instance| { - if let Web3Transport::Websocket(socket_transport) = instance.web3.transport() { + if let Web3Transport::Websocket(socket_transport) = instance.as_ref().transport() { socket_transport.maybe_spawn_temporary_connection_loop( self.clone(), Instant::now() + TMP_SOCKET_DURATION, ); }; - if instance.is_parity { - let parity: ParityNonce<_> = instance.web3.api(); - (Either::Left(parity.parity_next_nonce(addr)), instance.clone()) - } else { - ( - Either::Right(instance.web3.eth().transaction_count(addr, Some(BlockNumber::Pending))), - instance.clone(), - ) - } + let nonce = instance + .as_ref() + .eth() + .transaction_count(addr, Some(BlockNumber::Pending)); + + (nonce, instance.clone()) }) .unzip(); @@ -6570,19 +6565,8 @@ pub async fn eth_coin_from_conf_and_request( }; let web3 = Web3::new(transport); - let version = match web3.web3().client_version().await { - Ok(v) => v, - Err(e) => { - error!("Couldn't get client version for url {}: {}", url, e); - continue; - }, - }; - - web3_instances.push(Web3Instance { - web3, - is_parity: version.contains("Parity") || version.contains("parity"), - }) + web3_instances.push(Web3Instance(web3)) } if web3_instances.is_empty() { @@ -6599,10 +6583,10 @@ pub async fn eth_coin_from_conf_and_request( let decimals = match conf["decimals"].as_u64() { None | Some(0) => try_s!( get_token_decimals( - &web3_instances + web3_instances .first() .expect("web3_instances can't be empty in ETH activation") - .web3, + .as_ref(), token_addr ) .await diff --git a/mm2src/coins/eth/eth_rpc.rs b/mm2src/coins/eth/eth_rpc.rs index f353f186ba..946e142439 100644 --- a/mm2src/coins/eth/eth_rpc.rs +++ b/mm2src/coins/eth/eth_rpc.rs @@ -20,7 +20,7 @@ impl EthCoin { let mut error = web3::Error::Unreachable; for (i, client) in clients.clone().into_iter().enumerate() { - let execute_fut = match client.web3.transport() { + let execute_fut = match client.as_ref().transport() { Web3Transport::Http(http) => http.execute(method, params.clone()), Web3Transport::Websocket(socket) => { socket.maybe_spawn_connection_loop(self.clone()); @@ -40,14 +40,14 @@ impl EthCoin { debug!("Request on '{method}' failed. Error: {err}"); error = err; - if let Web3Transport::Websocket(socket_transport) = client.web3.transport() { + if let Web3Transport::Websocket(socket_transport) = client.as_ref().transport() { socket_transport.stop_connection_loop().await; }; }, Err(timeout_error) => { debug!("Timeout exceed for '{method}' request. Error: {timeout_error}",); - if let Web3Transport::Websocket(socket_transport) = client.web3.transport() { + if let Web3Transport::Websocket(socket_transport) = client.as_ref().transport() { socket_transport.stop_connection_loop().await; }; }, diff --git a/mm2src/coins/eth/for_tests.rs b/mm2src/coins/eth/for_tests.rs index 9652ba0a80..2a830993f5 100644 --- a/mm2src/coins/eth/for_tests.rs +++ b/mm2src/coins/eth/for_tests.rs @@ -37,7 +37,7 @@ pub(crate) fn eth_coin_from_keypair( }; let transport = Web3Transport::new_http(node); let web3 = Web3::new(transport); - web3_instances.push(Web3Instance { web3, is_parity: false }); + web3_instances.push(Web3Instance(web3)); } drop_mutability!(web3_instances); diff --git a/mm2src/coins/eth/nonce.rs b/mm2src/coins/eth/nonce.rs deleted file mode 100644 index 48a3d04f02..0000000000 --- a/mm2src/coins/eth/nonce.rs +++ /dev/null @@ -1,29 +0,0 @@ -use web3::{api::Namespace, - helpers::{self, CallFuture}, - types::{Address, U256}, - Transport}; - -/// `ParityNonce` namespace. -#[derive(Debug, Clone)] -pub(crate) struct ParityNonce { - transport: T, -} - -impl Namespace for ParityNonce { - fn new(transport: T) -> Self - where - Self: Sized, - { - ParityNonce { transport } - } - - fn transport(&self) -> &T { &self.transport } -} - -impl ParityNonce { - /// Parity next nonce. - pub(crate) fn parity_next_nonce(&self, addr: Address) -> CallFuture { - let addr = helpers::serialize(&addr); - CallFuture::new(self.transport.execute("parity_nextNonce", vec![addr])) - } -} diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 6267feef92..6bb4683036 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -875,18 +875,8 @@ async fn build_web3_instances( let transport = create_transport(ctx, &uri, ð_node, &event_handlers)?; let web3 = Web3::new(transport); - let version = match web3.web3().client_version().await { - Ok(v) => v, - Err(e) => { - error!("Couldn't get client version for url {}: {}", eth_node.url, e); - continue; - }, - }; - web3_instances.push(Web3Instance { - web3, - is_parity: version.contains("Parity") || version.contains("parity"), - }); + web3_instances.push(Web3Instance(web3)); } if web3_instances.is_empty() { @@ -981,7 +971,7 @@ async fn build_metamask_transport( // MetaMask doesn't use Parity nodes. So `MetamaskTransport` doesn't support `parity_nextNonce` RPC. // An example of the `web3_clientVersion` RPC - `MetaMask/v10.22.1`. - let web3_instances = vec![Web3Instance { web3, is_parity: false }]; + let web3_instances = vec![Web3Instance(web3)]; Ok(web3_instances) } From 805aed3de79c34ea059623db5062390dc194c628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Tue, 8 Jul 2025 13:55:28 +0300 Subject: [PATCH 07/75] feat(orderbook): expirable maker orders (#2516) Implements expirable maker orders which can be easily used with timeout_in_minutes arg in setprice RPC. It's an optional field and doesn't cause a breaking-change. --- Cargo.lock | 4 +- Cargo.toml | 2 +- mm2src/mm2_main/src/lp_ordermatch.rs | 55 +++++++++++++++++-- .../src/lp_ordermatch/my_orders_storage.rs | 1 + .../src/lp_ordermatch/simple_market_maker.rs | 1 + mm2src/mm2_main/src/ordermatch_tests.rs | 16 ++++++ .../tests/docker_tests/docker_tests_inner.rs | 2 +- .../tests/docker_tests/tendermint_tests.rs | 4 +- .../tests/mm2_tests/orderbook_sync_tests.rs | 47 +++++++++++++++- mm2src/mm2_test_helpers/src/for_tests.rs | 2 + 10 files changed, 121 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ee1c7cb656..84a146dde8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7142,9 +7142,9 @@ dependencies = [ [[package]] name = "timed-map" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f664a6b916d03d3e32c312c3b6ce31c24697c0f7ea6d87e20eb6372053ddf29" +checksum = "47e29dadb55913b13f482a3d61e45762f71cb7b145a012d8a48b8f05561eaa11" dependencies = [ "rustc-hash", "serde", diff --git a/Cargo.toml b/Cargo.toml index 019d0aacc0..ec7af89702 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -198,7 +198,7 @@ testcontainers = "0.15.0" tiny-bip39 = "0.8.0" thiserror = "1.0.40" time = "0.3.36" -timed-map = { version = "1.4", features = ["rustc-hash", "serde", "wasm"] } +timed-map = { version = "1.5", features = ["rustc-hash", "serde", "wasm"] } tokio = { version = "1.20", default-features = false } tokio-rustls = { version = "0.24", default-features = false } tokio-tungstenite-wasm = { git = "https://github.com/KomodoPlatform/tokio-tungstenite-wasm", rev = "8fc7e2f", defautl-features = false, features = ["rustls-tls-native-roots"]} diff --git a/mm2src/mm2_main/src/lp_ordermatch.rs b/mm2src/mm2_main/src/lp_ordermatch.rs index 5369f98f50..5f3b00996b 100644 --- a/mm2src/mm2_main/src/lp_ordermatch.rs +++ b/mm2src/mm2_main/src/lp_ordermatch.rs @@ -1753,6 +1753,7 @@ pub struct MakerOrder { pub swap_version: SwapVersion, #[cfg(feature = "ibc-routing-for-swaps")] order_metadata: OrderMetadata, + timeout_in_minutes: Option, } pub struct MakerOrderBuilder<'a> { @@ -1768,6 +1769,7 @@ pub struct MakerOrderBuilder<'a> { swap_version: u8, #[cfg(feature = "ibc-routing-for-swaps")] order_metadata: OrderMetadata, + timeout_in_minutes: Option, } /// Contains extra and/or optional metadata (e.g., protocol-specific information) that can @@ -1930,6 +1932,7 @@ impl<'a> MakerOrderBuilder<'a> { swap_version: SWAP_VERSION_DEFAULT, #[cfg(feature = "ibc-routing-for-swaps")] order_metadata: OrderMetadata::default(), + timeout_in_minutes: None, } } @@ -1968,6 +1971,8 @@ impl<'a> MakerOrderBuilder<'a> { self } + pub fn set_timeout(&mut self, timeout_in_minutes: u16) { self.timeout_in_minutes = Some(timeout_in_minutes); } + /// When a new [MakerOrderBuilder::new] is created, it sets [SWAP_VERSION_DEFAULT]. /// However, if user has not specified in the config to use TPU V2, /// the MakerOrderBuilder's swap_version is changed to legacy. @@ -2033,6 +2038,7 @@ impl<'a> MakerOrderBuilder<'a> { swap_version: SwapVersion::from(self.swap_version), #[cfg(feature = "ibc-routing-for-swaps")] order_metadata: self.order_metadata, + timeout_in_minutes: self.timeout_in_minutes, }) } @@ -2060,6 +2066,7 @@ impl<'a> MakerOrderBuilder<'a> { swap_version: SwapVersion::from(self.swap_version), #[cfg(feature = "ibc-routing-for-swaps")] order_metadata: self.order_metadata, + timeout_in_minutes: self.timeout_in_minutes, } } } @@ -2194,6 +2201,7 @@ impl From for MakerOrder { // TODO: Add test coverage for this once we have an integration test for this feature. #[cfg(feature = "ibc-routing-for-swaps")] order_metadata: taker_order.request.order_metadata, + timeout_in_minutes: None, }, // The "buy" taker order is recreated with reversed pair as Maker order is always considered as "sell" TakerAction::Buy => { @@ -2220,6 +2228,7 @@ impl From for MakerOrder { // TODO: Add test coverage for this once we have an integration test for this feature. #[cfg(feature = "ibc-routing-for-swaps")] order_metadata: taker_order.request.order_metadata, + timeout_in_minutes: None, } }, } @@ -2962,7 +2971,7 @@ impl OrdermatchContext { } pub struct MakerOrdersContext { - orders: HashMap>>, + orders: TimedMap>>, order_tickers: HashMap, count_by_tickers: HashMap, /// The `check_balance_update_loop` future abort handles associated stored by corresponding tickers. @@ -2976,7 +2985,7 @@ impl MakerOrdersContext { let balance_loops = ctx.abortable_system.create_subsystem()?; Ok(MakerOrdersContext { - orders: HashMap::new(), + orders: TimedMap::new_with_map_kind(timed_map::MapKind::FxHashMap), order_tickers: HashMap::new(), count_by_tickers: HashMap::new(), balance_loops, @@ -2988,7 +2997,21 @@ impl MakerOrdersContext { self.order_tickers.insert(order.uuid, order.base.clone()); *self.count_by_tickers.entry(order.base.clone()).or_insert(0) += 1; - self.orders.insert(order.uuid, Arc::new(AsyncMutex::new(order))); + + if let Some(t) = order.timeout_in_minutes { + // Use unchecked write to skip automatic cleanup as we need to handle + // expired orders manually. + self.orders.insert_expirable_unchecked( + order.uuid, + Arc::new(AsyncMutex::new(order)), + Duration::from_secs(t as u64 * 60), + ); + } else { + // Use unchecked write to skip automatic cleanup as we need to handle + // expired orders manually. + self.orders + .insert_constant_unchecked(order.uuid, Arc::new(AsyncMutex::new(order))); + } } fn get_order(&self, uuid: &Uuid) -> Option<&Arc>> { self.orders.get(uuid) } @@ -3562,6 +3585,19 @@ pub async fn lp_ordermatch_loop(ctx: MmArc) { handle_timed_out_maker_matches(ctx.clone(), &ordermatch_ctx).await; check_balance_for_maker_orders(ctx.clone(), &ordermatch_ctx).await; + let expired_orders = ordermatch_ctx.maker_orders_ctx.lock().orders.drop_expired_entries(); + + for (uuid, order_mutex) in expired_orders { + log::info!("Order '{uuid}' is expired, cancelling"); + + let order = order_mutex.lock().await; + maker_order_cancelled_p2p_notify(&ctx, &order); + delete_my_maker_order(ctx.clone(), order.clone(), MakerOrderCancellationReason::Expired) + .compat() + .await + .ok(); + } + { // remove "timed out" pubkeys states with their orders from orderbook let mut orderbook = ordermatch_ctx.orderbook.lock(); @@ -3592,9 +3628,9 @@ pub async fn lp_ordermatch_loop(ctx: MmArc) { let mut to_cancel = Vec::new(); { let orderbook = ordermatch_ctx.orderbook.lock(); - for (uuid, _) in ordermatch_ctx.maker_orders_ctx.lock().orders.iter() { - if !orderbook.order_set.contains_key(uuid) { - missing_uuids.push(*uuid); + for uuid in ordermatch_ctx.maker_orders_ctx.lock().orders.keys() { + if !orderbook.order_set.contains_key(&uuid) { + missing_uuids.push(uuid); } } } @@ -4795,6 +4831,7 @@ pub struct SetPriceReq { rel_nota: Option, #[serde(default = "get_true")] save_in_history: bool, + timeout_in_minutes: Option, } #[derive(Deserialize)] @@ -5059,6 +5096,11 @@ pub async fn create_maker_order(ctx: &MmArc, req: SetPriceReq) -> Result mpsc::Receiver { swap_version: SwapVersion::default(), #[cfg(feature = "ibc-routing-for-swaps")] order_metadata: OrderMetadata::default(), + timeout_in_minutes: None, }, None, ); @@ -1128,6 +1138,7 @@ fn prepare_for_cancel_by(ctx: &MmArc) -> mpsc::Receiver { swap_version: SwapVersion::default(), #[cfg(feature = "ibc-routing-for-swaps")] order_metadata: OrderMetadata::default(), + timeout_in_minutes: None, }, None, ); @@ -1153,6 +1164,7 @@ fn prepare_for_cancel_by(ctx: &MmArc) -> mpsc::Receiver { swap_version: SwapVersion::default(), #[cfg(feature = "ibc-routing-for-swaps")] order_metadata: OrderMetadata::default(), + timeout_in_minutes: None, }, None, ); @@ -1353,6 +1365,7 @@ fn test_maker_order_was_updated() { swap_version: SwapVersion::default(), #[cfg(feature = "ibc-routing-for-swaps")] order_metadata: OrderMetadata::default(), + timeout_in_minutes: None, }; let mut update_msg = MakerOrderUpdated::new(maker_order.uuid); update_msg.with_new_price(BigRational::from_integer(2.into())); @@ -3365,6 +3378,7 @@ fn test_maker_order_balance_loops() { swap_version: SwapVersion::default(), #[cfg(feature = "ibc-routing-for-swaps")] order_metadata: OrderMetadata::default(), + timeout_in_minutes: None, }; let morty_order = MakerOrder { @@ -3387,6 +3401,7 @@ fn test_maker_order_balance_loops() { swap_version: SwapVersion::default(), #[cfg(feature = "ibc-routing-for-swaps")] order_metadata: OrderMetadata::default(), + timeout_in_minutes: None, }; assert!(!maker_orders_ctx.balance_loop_exists(rick_ticker)); @@ -3422,6 +3437,7 @@ fn test_maker_order_balance_loops() { swap_version: SwapVersion::default(), #[cfg(feature = "ibc-routing-for-swaps")] order_metadata: OrderMetadata::default(), + timeout_in_minutes: None, }; maker_orders_ctx.add_order(ctx.weak(), rick_order_2.clone(), None); diff --git a/mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs b/mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs index b8a7164dd9..aca3f247f6 100644 --- a/mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs +++ b/mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs @@ -2229,7 +2229,7 @@ fn test_get_max_maker_vol() { let actual = block_on(max_maker_vol(&mm, "MYCOIN1")).unwrap::(); assert_eq!(actual, expected); - let res = block_on(set_price(&mm, "MYCOIN1", "MYCOIN", "1", "0", true)); + let res = block_on(set_price(&mm, "MYCOIN1", "MYCOIN", "1", "0", true, None)); assert_eq!(res.result.max_base_vol, expected_volume.to_decimal()); } diff --git a/mm2src/mm2_main/tests/docker_tests/tendermint_tests.rs b/mm2src/mm2_main/tests/docker_tests/tendermint_tests.rs index 58ad67e645..4656613683 100644 --- a/mm2src/mm2_main/tests/docker_tests/tendermint_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/tendermint_tests.rs @@ -127,10 +127,10 @@ fn test_iris_ibc_nucleus_orderbook() { let expected_address = "nuc150evuj4j7k9kgu38e453jdv9m3u0ft2n4fgzfr"; assert_eq!(response.result.address, expected_address); - let set_price_res = block_on(set_price(&mm, token, platform_coin, "1", "0.1", false)); + let set_price_res = block_on(set_price(&mm, token, platform_coin, "1", "0.1", false, None)); log!("{:?}", set_price_res); - let set_price_res = block_on(set_price(&mm, platform_coin, token, "1", "0.1", false)); + let set_price_res = block_on(set_price(&mm, platform_coin, token, "1", "0.1", false, None)); log!("{:?}", set_price_res); let orderbook = block_on(orderbook(&mm, token, platform_coin)); diff --git a/mm2src/mm2_main/tests/mm2_tests/orderbook_sync_tests.rs b/mm2src/mm2_main/tests/mm2_tests/orderbook_sync_tests.rs index 832f23cfae..30a92cac4d 100644 --- a/mm2src/mm2_main/tests/mm2_tests/orderbook_sync_tests.rs +++ b/mm2src/mm2_main/tests/mm2_tests/orderbook_sync_tests.rs @@ -1334,7 +1334,7 @@ fn test_order_cancellation_received_before_creation() { ); // Bob places maker order before Alice connects to the network so that Alice receives the order creation through IHAVE/IWANT messages. - let set_price = block_on(set_price(&mm_bob, "RICK", "MORTY", "0.9", "0.9", false)); + let set_price = block_on(set_price(&mm_bob, "RICK", "MORTY", "0.9", "0.9", false, None)); let mm_alice_conf = Mm2TestConf::light_node("alice passphrase", &coins, &[&mm_bob.ip.to_string()]); let mut mm_alice = MarketMakerIt::start(mm_alice_conf.conf, mm_alice_conf.rpc_password, None).unwrap(); @@ -1542,3 +1542,48 @@ fn zhtlc_orders_sync_alice_connected_after_creation() { .find(|ask| ask.entry.uuid == bob_set_price_res.result.uuid) .unwrap(); } + +#[test] +fn test_expirable_order() { + let coins = json!([rick_conf(), morty_conf()]); + + let bob_passphrase = "bob passphrase"; + let mm_bob_conf = Mm2TestConf::seednode(bob_passphrase, &coins); + let mm_bob = MarketMakerIt::start(mm_bob_conf.conf, mm_bob_conf.rpc_password, None).unwrap(); + + block_on(enable_electrum(&mm_bob, "RICK", false, DOC_ELECTRUM_ADDRS)); + block_on(enable_electrum(&mm_bob, "MORTY", false, MARTY_ELECTRUM_ADDRS)); + + let expiration_min = 1; + let _ = block_on(set_price( + &mm_bob, + "RICK", + "MORTY", + "0.1", + "0.1", + false, + Some(expiration_min), + )); + + let mm_alice_conf = Mm2TestConf::light_node("alice passphrase", &coins, &[&mm_bob.ip.to_string()]); + let mut mm_alice = MarketMakerIt::start(mm_alice_conf.conf, mm_alice_conf.rpc_password, None).unwrap(); + + let orderbook = block_on(orderbook_v2(&mm_alice, "RICK", "MORTY")); + let asks = orderbook["result"]["asks"].as_array().unwrap(); + // Alice should see the order in the orderbook as she got it through `GetOrderbook` p2p request. + assert_eq!(asks.len(), 1, "Alice RICK/MORTY orderbook must have exactly 1 ask"); + + // Sleep until order expires + thread::sleep(Duration::from_secs(expiration_min as u64 * 60 + 1)); + + // Make sure Alice receives the order cancellation message. + block_on(mm_alice.wait_for_log(10., |log| { + log.contains("received ordermatch message MakerOrderCancelled") + })) + .unwrap(); + + let orderbook = block_on(orderbook_v2(&mm_alice, "RICK", "MORTY")); + let asks = orderbook["result"]["asks"].as_array().unwrap(); + // Alice shouldn't find the order in the orderbook as it was expired just recently. + assert_eq!(asks.len(), 0, "Alice RICK/MORTY orderbook must have exactly 0 ask"); +} diff --git a/mm2src/mm2_test_helpers/src/for_tests.rs b/mm2src/mm2_test_helpers/src/for_tests.rs index f98fe3041c..37a8b6bfb4 100644 --- a/mm2src/mm2_test_helpers/src/for_tests.rs +++ b/mm2src/mm2_test_helpers/src/for_tests.rs @@ -3618,6 +3618,7 @@ pub async fn set_price( price: &str, vol: &str, max: bool, + timeout_in_minutes: Option, ) -> SetPriceResponse { let request = mm .rpc(&json!({ @@ -3628,6 +3629,7 @@ pub async fn set_price( "price": price, "volume": vol, "max": max, + "timeout_in_minutes": timeout_in_minutes, })) .await .unwrap(); From eab808175674233b7317639e6b0936911e5041ea Mon Sep 17 00:00:00 2001 From: Ahmed Mohamed Ibrahim <63132227+BigFish2086@users.noreply.github.com> Date: Thu, 10 Jul 2025 06:38:55 +0300 Subject: [PATCH 08/75] feat(use-clap-for-cli): use clap to parse CLI-Args #2215 (#2510) * feat(use-clap-for-kdf): use clap to parse CLI-Args #2215 - had to set clap version to "=v4.2" in Cargo.toml, because cargo was trying to fetch clap version 4.5 and it requires a higher version of rust tool-chain (1.74) and the current one is (1.72) - clap provides both "-h" or "--help" for the help - override the behaviour of the help to be able to show the same message as before with the version of KDF_VERSION provided by the git-commit - modes & subcommands like `btc2kmd`, `events`, `vanity`, `update_config` weren't actually used or handled by the code, so I removed them * fix(use-clap-for-cli): remove '=' from Cargo.toml as the Cargo.lock file is already created. * fix(use-clap-for-cli): hard-code the version output prefix to keep it like before * fix(use-clap-for-cli): remove reference for the JSON parameters from help as they can quickly become obsolete and outdated. --- Cargo.lock | 121 ++++++++++++++++++++++++++++++++++ mm2src/mm2_main/Cargo.toml | 3 +- mm2src/mm2_main/src/mm2.rs | 131 +++++++++++-------------------------- 3 files changed, 160 insertions(+), 95 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 84a146dde8..43e9841436 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -118,6 +118,55 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + [[package]] name = "anyhow" version = "1.0.89" @@ -770,6 +819,48 @@ dependencies = [ "zeroize", ] +[[package]] +name = "clap" +version = "4.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" +dependencies = [ + "clap_builder", + "clap_derive", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" +dependencies = [ + "anstream", + "anstyle", + "bitflags 1.3.2", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +dependencies = [ + "heck 0.4.0", + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "clap_lex" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" + [[package]] name = "cloudabi" version = "0.0.3" @@ -952,6 +1043,12 @@ dependencies = [ "url", ] +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + [[package]] name = "common" version = "0.1.0" @@ -2517,6 +2614,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + [[package]] name = "hex" version = "0.4.3" @@ -2935,6 +3038,17 @@ version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" +[[package]] +name = "is-terminal" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" +dependencies = [ + "hermit-abi 0.5.2", + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "itertools" version = "0.10.3" @@ -4084,6 +4198,7 @@ dependencies = [ "cfg-if 1.0.0", "chain", "chrono", + "clap", "coins", "coins_activation", "common", @@ -7719,6 +7834,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "utxo_signer" version = "0.1.0" diff --git a/mm2src/mm2_main/Cargo.toml b/mm2src/mm2_main/Cargo.toml index aa293a68b2..79a457a75d 100644 --- a/mm2src/mm2_main/Cargo.toml +++ b/mm2src/mm2_main/Cargo.toml @@ -37,9 +37,10 @@ async-trait.workspace = true bitcrypto = { path = "../mm2_bitcoin/crypto" } blake2.workspace = true bytes.workspace = true +cfg-if.workspace = true chain = { path = "../mm2_bitcoin/chain" } chrono.workspace = true -cfg-if.workspace = true +clap.workspace = true coins = { path = "../coins" } coins_activation = { path = "../coins_activation" } common = { path = "../common" } diff --git a/mm2src/mm2_main/src/mm2.rs b/mm2src/mm2_main/src/mm2.rs index 42cf7fbc3b..1409419a63 100644 --- a/mm2src/mm2_main/src/mm2.rs +++ b/mm2src/mm2_main/src/mm2.rs @@ -57,10 +57,7 @@ use std::sync::atomic::Ordering; use gstuff::slurp; use serde_json::{self as json, Value as Json}; -use std::env; -use std::ffi::OsString; use std::process::exit; -use std::ptr::null; use std::str; pub use self::lp_native_dex::init_hw; @@ -83,11 +80,40 @@ pub mod rpc; mod swap_versioning; #[cfg(all(target_arch = "wasm32", test))] mod wasm_tests; +use clap::Parser; + pub const PASSWORD_MAXIMUM_CONSECUTIVE_CHARACTERS: usize = 3; #[cfg(any(feature = "custom-swap-locktime", test, feature = "run-docker-tests"))] const CUSTOM_PAYMENT_LOCKTIME_DEFAULT: u64 = 900; +const EXTRA_HELP_MESSAGE: &str = r#" +Environment variables: + + MM_CONF_PATH .. File path. MM2 will try to load the JSON configuration from this file. + File must contain valid json with structure mentioned above. + Defaults to `MM2.json` + MM_COINS_PATH .. File path. MM2 will try to load coins data from this file. + File must contain valid json. + Recommended: https://github.com/komodoplatform/coins/blob/master/coins. + Defaults to `coins`. + MM_LOG .. File path. Must end with '.log'. MM will log to this file. + +See also the online documentation at +https://komodoplatform.com/en/docs +"#; + +#[derive(Parser, Debug)] +#[command(about="Komodo DeFi Framework Daemon", long_about=None, after_help=EXTRA_HELP_MESSAGE)] +pub struct Cli { + /// JSON configuration string - will be used instead of the json config file + pub config: Option, + + /// Print version + #[clap(short, long)] + pub version: bool, +} + pub struct LpMainParams { conf: Json, filter: Option, @@ -200,115 +226,32 @@ fn spawn_ctrl_c_handler(ctx: MmArc) { }); } -fn help() { - const HELP_MSG: &str = r#"Command-line options. -The first command-line argument is special and designates the mode. - - help .. Display this message. - btc2kmd {WIF or BTC} .. Convert a BTC WIF into a KMD WIF. - events .. Listen to a feed coming from a separate MM daemon and print it to stdout. - vanity {substring} .. Tries to find an address with the given substring. - update_config {SRC} {DST} .. Update the configuration of coins from the SRC config and save it to DST file. - {JSON configuration} .. Run the MarketMaker daemon. - -Some (but not all) of the JSON configuration parameters (* - required): - - NB: The 'coins' command-line configuration must have the lowercased coin names in the 'name' field, - {"coins": [{"name": "dash", "coin": "DASH", ...}, ...], ...}. - coins .. Information about the currencies: their ticker symbols, names, ports, addresses, etc. - If the field isn't present on the command line then we try loading it from the 'coins' file. - dbdir .. MM database path. 'DB' by default. - gui .. The information about GUI app using KDF instance. Included in swap statuses shared with network. - .. It's recommended to put essential info to this field (application name, OS, version, etc). - .. e.g. AtomicDEX iOS 1.0.1000. - myipaddr .. IP address to bind to for P2P networking. - netid .. Subnetwork. Affects ports and keys. - passphrase * .. Wallet seed. - Compressed WIFs and hexadecimal ECDSA keys (prefixed with 0x) are also accepted. - rpccors .. Access-Control-Allow-Origin header value to be used in all the RPC responses. - Default is currently 'http://localhost:3000' - rpcip .. IP address to bind to for RPC server. Overrides the 127.0.0.1 default - rpc_password .. RPC password used to authorize non-public RPC calls - MM generates password from passphrase if this field is not set - rpc_local_only .. MM forbids some RPC requests from not loopback (localhost) IPs as additional security measure. - Defaults to `true`, set `false` to disable. `Use with caution`. - rpcport .. If > 1000 overrides the 7783 default. - i_am_seed .. Activate the seed node mode (acting as a relay for kdf clients). - Defaults to `false`. - seednodes .. Seednode IPs that node will use. - At least one seed IP must be present if the node is not a seed itself. - wif .. `1` to add WIFs to the information we provide about a coin. - -Environment variables: - - MM_CONF_PATH .. File path. MM2 will try to load the JSON configuration from this file. - File must contain valid json with structure mentioned above. - Defaults to `MM2.json` - MM_COINS_PATH .. File path. MM2 will try to load coins data from this file. - File must contain valid json. - Recommended: https://github.com/komodoplatform/coins/blob/master/coins. - Defaults to `coins`. - MM_LOG .. File path. Must end with '.log'. MM will log to this file. - -See also the online documentation at -https://komodoplatform.com/en/docs -"#; - - println!("{}", HELP_MSG); -} - #[cfg(not(target_arch = "wasm32"))] #[allow(dead_code)] // Not used by mm2_lib. pub fn mm2_main(version: String, datetime: String) { - use libc::c_char; - init_crash_reports(); - // Temporarily simulate `argv[]` for the C version of the main method. - let args: Vec = env::args() - .map(|mut arg| { - arg.push('\0'); - arg - }) - .collect(); - let mut args: Vec<*const c_char> = args.iter().map(|s| s.as_ptr() as *const c_char).collect(); - args.push(null()); - - let args_os: Vec = env::args_os().collect(); - - // NB: The first argument is special, being used as the mode switcher. - // The other arguments might be used to pass the data to the various MM modes, - // we're not checking them for the mode switches in order not to risk [untrusted] data being mistaken for a mode switch. - let first_arg = args_os.get(1).and_then(|arg| arg.to_str()); - - if first_arg == Some("--version") || first_arg == Some("-v") || first_arg == Some("version") { + let cli = Cli::parse(); + if cli.version { println!("Komodo DeFi Framework: {version}"); return; } - if first_arg == Some("--help") || first_arg == Some("-h") || first_arg == Some("help") { - help(); - return; - } - - if cfg!(windows) && first_arg == Some("/?") { - help(); - return; - } + let json_config = cli.config.as_deref(); log!("Komodo DeFi Framework {} DT {}", version, datetime); - if let Err(err) = run_lp_main(first_arg, &|_| (), version, datetime) { + if let Err(err) = run_lp_main(json_config, &|_| (), version, datetime) { log!("{}", err); exit(1); } } #[cfg(not(target_arch = "wasm32"))] -/// Parses and returns the `first_arg` as JSON. -/// Attempts to load the config from `MM2.json` file if `first_arg` is None -pub fn get_mm2config(first_arg: Option<&str>) -> Result { - let conf = match first_arg { +/// Parses and returns the `json_config` as JSON. +/// Attempts to load the config from `MM2.json` file if `json_config` is None +pub fn get_mm2config(json_config: Option<&str>) -> Result { + let conf = match json_config { Some(s) => s.to_owned(), None => { let conf_path = common::kdf_config_file().map_err(|e| e.to_string())?; From 5c8a4b111a51949da4e6d54e3f9daf526732c8cc Mon Sep 17 00:00:00 2001 From: shamardy <39480341+shamardy@users.noreply.github.com> Date: Fri, 11 Jul 2025 12:22:29 +0300 Subject: [PATCH 09/75] fix(eth): Correctly implement ETH max withdrawal logic (#2531) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EVM max withdrawals were broken due to the max flag always being set to false. This commit passes the correct `req.max` value and also addresses two low-balance edge cases: it avoids panic from arithmetic underflow when calculating max amount to transfer, and gracefully handles cryptic RPC errors by converting known “insufficient funds” messages into a clear `WithdrawError::AmountTooLow`. --- mm2src/coins/eth.rs | 34 ++++++++++++++++++++++++++++---- mm2src/coins/eth/eth_withdraw.rs | 2 +- mm2src/coins/lp_coins.rs | 1 + 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 20346b6e9e..c95d2a0a40 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -6837,6 +6837,12 @@ fn get_valid_nft_addr_to_withdraw( pub enum EthGasDetailsErr { #[display(fmt = "Invalid fee policy: {}", _0)] InvalidFeePolicy(String), + #[display( + fmt = "Amount {} is too low. Required minimum is {} to cover fees.", + amount, + threshold + )] + AmountTooLow { amount: BigDecimal, threshold: BigDecimal }, #[from_stringify("NumConversError")] #[display(fmt = "Internal error: {}", _0)] Internal(String), @@ -6919,7 +6925,11 @@ async fn get_eth_gas_details_from_withdraw_fee( // covering edge case by deducting the standard transfer fee when we want to max withdraw ETH let eth_value_for_estimate = if fungible_max && eth_coin.coin_type == EthCoinType::Eth { - eth_value - calc_total_fee(U256::from(eth_coin.gas_limit.eth_send_coins), &pay_for_gas_option).map_mm_err()? + let estimated_fee = + calc_total_fee(U256::from(eth_coin.gas_limit.eth_send_coins), &pay_for_gas_option).map_mm_err()?; + // Defaulting to zero is safe; if the balance is indeed too low, the `estimate_gas` call below + // will fail, and we will catch and handle that error gracefully. + eth_value.checked_sub(estimated_fee).unwrap_or_default() } else { eth_value }; @@ -6939,9 +6949,25 @@ async fn get_eth_gas_details_from_withdraw_fee( max_fee_per_gas, ..CallRequest::default() }; - // TODO Note if the wallet's balance is insufficient to withdraw, then `estimate_gas` may fail with the `Exception` error. - // TODO Ideally we should determine the case when we have the insufficient balance and return `WithdrawError::NotSufficientBalance`. - let gas_limit = eth_coin.estimate_gas_wrapper(estimate_gas_req).compat().await?; + let gas_limit = match eth_coin.estimate_gas_wrapper(estimate_gas_req).compat().await { + Ok(gas_limit) => gas_limit, + Err(e) => { + let error_str = e.to_string().to_lowercase(); + if error_str.contains("insufficient funds") || error_str.contains("exceeds allowance") { + let standard_tx_fee = + calc_total_fee(U256::from(eth_coin.gas_limit.eth_send_coins), &pay_for_gas_option).map_mm_err()?; + let threshold = u256_to_big_decimal(standard_tx_fee, eth_coin.decimals).map_mm_err()?; + let amount = u256_to_big_decimal(eth_value, eth_coin.decimals).map_mm_err()?; + + return MmError::err(EthGasDetailsErr::AmountTooLow { amount, threshold }); + } + // This can be a transport error or a non-standard insufficient funds error. + // In the latter case, + // we can add to the above error handling of insufficient funds on a case-by-case basis. + return MmError::err(EthGasDetailsErr::Transport(e.to_string())); + }, + }; + Ok((gas_limit, pay_for_gas_option)) } diff --git a/mm2src/coins/eth/eth_withdraw.rs b/mm2src/coins/eth/eth_withdraw.rs index 534882f538..2b260b4fed 100644 --- a/mm2src/coins/eth/eth_withdraw.rs +++ b/mm2src/coins/eth/eth_withdraw.rs @@ -259,7 +259,7 @@ where data.clone().into(), my_address, call_addr, - false, + req.max, ) .await .map_mm_err()?; diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index b35d8ae37d..09a638c0fd 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -3295,6 +3295,7 @@ impl From for WithdrawError { fn from(e: EthGasDetailsErr) -> Self { match e { EthGasDetailsErr::InvalidFeePolicy(e) => WithdrawError::InvalidFeePolicy(e), + EthGasDetailsErr::AmountTooLow { amount, threshold } => WithdrawError::AmountTooLow { amount, threshold }, EthGasDetailsErr::Internal(e) => WithdrawError::InternalError(e), EthGasDetailsErr::Transport(e) => WithdrawError::Transport(e), EthGasDetailsErr::NftProtocolNotSupported => WithdrawError::NftProtocolNotSupported, From 6aff6fc8ce00f71b45c921622bd59afa9486a30f Mon Sep 17 00:00:00 2001 From: shamardy <39480341+shamardy@users.noreply.github.com> Date: Mon, 14 Jul 2025 11:41:14 +0300 Subject: [PATCH 10/75] fix(eth): Propagate structured EIP-1559 fee errors (#2532) This commit improves the error handling for EVM withdrawals when the provided EIP-1559 max_fee_per_gas is too low. Previously, the API returned a generic string-based error, forcing the user to guess a new fee. Now, the withdraw endpoint can return a structured error object containing the required network base fee, allowing client applications to better handle the error. --- mm2src/coins/eth.rs | 39 +++++++++++++++++++++++++++++++++++++++ mm2src/coins/lp_coins.rs | 25 +++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index c95d2a0a40..47722ccab2 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -84,6 +84,7 @@ use mm2_core::mm_ctx::{MmArc, MmWeak}; use mm2_number::bigdecimal_custom::CheckedDivision; use mm2_number::{BigDecimal, BigUint, MmNumber}; use rand::seq::SliceRandom; +use regex::Regex; use rlp::{DecoderError, Encodable, RlpStream}; use rpc::v1::types::Bytes as BytesJson; use secp256k1::PublicKey; @@ -6843,6 +6844,17 @@ pub enum EthGasDetailsErr { threshold )] AmountTooLow { amount: BigDecimal, threshold: BigDecimal }, + #[display( + fmt = "Provided gas fee cap {} Gwei is too low, the required network base fee is {} Gwei.", + provided_fee_cap, + required_base_fee + )] + GasFeeCapTooLow { + provided_fee_cap: BigDecimal, + required_base_fee: BigDecimal, + }, + #[display(fmt = "The provided 'max_fee_per_gas' is below the current block's base fee.")] + GasFeeCapBelowBaseFee, #[from_stringify("NumConversError")] #[display(fmt = "Internal error: {}", _0)] Internal(String), @@ -6869,6 +6881,19 @@ impl From for EthGasDetailsErr { } } +fn parse_fee_cap_error(message: &str) -> Option<(U256, U256)> { + let re = Regex::new(r"gasfeecap: (\d+)\s+basefee: (\d+)").ok()?; + let caps = re.captures(message)?; + + let user_cap_str = caps.get(1)?.as_str(); + let required_base_str = caps.get(2)?.as_str(); + + let user_cap = U256::from_dec_str(user_cap_str).ok()?; + let required_base = U256::from_dec_str(required_base_str).ok()?; + + Some((user_cap, required_base)) +} + async fn get_eth_gas_details_from_withdraw_fee( eth_coin: &EthCoin, fee: Option, @@ -6960,6 +6985,20 @@ async fn get_eth_gas_details_from_withdraw_fee( let amount = u256_to_big_decimal(eth_value, eth_coin.decimals).map_mm_err()?; return MmError::err(EthGasDetailsErr::AmountTooLow { amount, threshold }); + } else if error_str.contains("fee cap less than block base fee") + || error_str.contains("max fee per gas less than block base fee") + { + if let Some((user_cap, required_base)) = parse_fee_cap_error(&error_str) { + // The RPC error gives fee values in wei. Convert to Gwei (9 decimals) for the user. + let provided_fee_cap = u256_to_big_decimal(user_cap, ETH_GWEI_DECIMALS).map_mm_err()?; + let required_base_fee = u256_to_big_decimal(required_base, ETH_GWEI_DECIMALS).map_mm_err()?; + return MmError::err(EthGasDetailsErr::GasFeeCapTooLow { + provided_fee_cap, + required_base_fee, + }); + } else { + return MmError::err(EthGasDetailsErr::GasFeeCapBelowBaseFee); + } } // This can be a transport error or a non-standard insufficient funds error. // In the latter case, diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 09a638c0fd..1626e9d8af 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -3108,6 +3108,12 @@ pub enum WithdrawError { InvalidAddress(String), #[display(fmt = "Invalid fee policy: {}", _0)] InvalidFeePolicy(String), + #[display(fmt = "Invalid fee parameters: {}", reason)] + InvalidFee { + reason: String, + #[serde(skip_serializing_if = "Option::is_none")] + details: Option, + }, #[display(fmt = "Invalid memo field: {}", _0)] InvalidMemo(String), #[display(fmt = "No such coin {}", coin)] @@ -3201,6 +3207,7 @@ impl HttpStatusCode for WithdrawError { | WithdrawError::AmountTooLow { .. } | WithdrawError::InvalidAddress(_) | WithdrawError::InvalidFeePolicy(_) + | WithdrawError::InvalidFee { .. } | WithdrawError::InvalidMemo(_) | WithdrawError::FromAddressNotFound | WithdrawError::UnexpectedFromAddress(_) @@ -3296,6 +3303,24 @@ impl From for WithdrawError { match e { EthGasDetailsErr::InvalidFeePolicy(e) => WithdrawError::InvalidFeePolicy(e), EthGasDetailsErr::AmountTooLow { amount, threshold } => WithdrawError::AmountTooLow { amount, threshold }, + EthGasDetailsErr::GasFeeCapTooLow { + provided_fee_cap, + required_base_fee, + } => { + let reason = "Provided gas fee cap is less than the required network base fee.".to_string(); + let details = json!({ + "provided_fee_cap_gwei": provided_fee_cap.to_string(), + "required_base_fee_gwei": required_base_fee.to_string() + }); + WithdrawError::InvalidFee { + reason, + details: Some(details), + } + }, + EthGasDetailsErr::GasFeeCapBelowBaseFee => { + let reason = "The provided 'max fee per gas' is too low for current network conditions.".to_string(); + WithdrawError::InvalidFee { reason, details: None } + }, EthGasDetailsErr::Internal(e) => WithdrawError::InternalError(e), EthGasDetailsErr::Transport(e) => WithdrawError::Transport(e), EthGasDetailsErr::NftProtocolNotSupported => WithdrawError::NftProtocolNotSupported, From aaef15434c090e9f3de308a4e8ac7d9f5ab3038c Mon Sep 17 00:00:00 2001 From: Ahmed Mohamed Ibrahim <63132227+BigFish2086@users.noreply.github.com> Date: Wed, 16 Jul 2025 14:19:41 +0300 Subject: [PATCH 11/75] improvement(event-streaming): impl DeriveStreamerId trait for all streamers (#2489) * refactor(event-streaming): impl DeriveStreamerId trait for all streamers #2441 - Added DeriveStreamerId trait with InitParam for new and DeriveParam for derive_streamer_id, including lifetime 'a for flexible references. - Refactored streamer structs to use &str for DeriveParam where applicable. * refactor(orderbook_events): introduce BaseAndRel type alias for DeriveParam #2441 Replaces the raw tuple (&str, &str) with a named type alias for clarity * docs(event-streaming): add documentation for DeriveStreamerId trait and its associated types #2441 --------- Co-authored-by: BigFish2086 --- .../tendermint/tendermint_tx_history_v2.rs | 2 +- .../utxo/rpc_clients/electrum_rpc/client.rs | 2 +- mm2src/coins/utxo/tx_history_events.rs | 12 ++++++---- mm2src/coins/utxo/utxo_balance_events.rs | 11 +++++---- mm2src/coins/utxo/utxo_tx_history_v2.rs | 2 +- .../storage/blockdb/blockdb_sql_storage.rs | 1 + mm2src/coins/z_coin/tx_history_events.rs | 12 ++++++---- .../coins/z_coin/tx_streaming_tests/native.rs | 1 + mm2src/coins/z_coin/z_balance_streaming.rs | 12 ++++++---- mm2src/mm2_event_stream/src/lib.rs | 2 +- mm2src/mm2_event_stream/src/streamer.rs | 19 +++++++++++++++ mm2src/mm2_main/src/lp_ordermatch.rs | 24 ++++++++++--------- .../src/lp_ordermatch/order_events.rs | 15 ++++++------ .../src/lp_ordermatch/orderbook_events.rs | 14 +++++++---- mm2src/mm2_main/src/lp_swap/maker_swap.rs | 9 ++++--- mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs | 9 ++++--- mm2src/mm2_main/src/lp_swap/swap_events.rs | 15 ++++++------ mm2src/mm2_main/src/lp_swap/taker_swap.rs | 9 ++++--- mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs | 9 ++++--- .../src/rpc/streaming_activations/balance.rs | 1 + .../rpc/streaming_activations/orderbook.rs | 3 ++- .../src/rpc/streaming_activations/orders.rs | 3 ++- .../src/rpc/streaming_activations/swaps.rs | 3 ++- .../rpc/streaming_activations/tx_history.rs | 1 + 24 files changed, 123 insertions(+), 68 deletions(-) diff --git a/mm2src/coins/tendermint/tendermint_tx_history_v2.rs b/mm2src/coins/tendermint/tendermint_tx_history_v2.rs index 1ab304a1a6..99133cb553 100644 --- a/mm2src/coins/tendermint/tendermint_tx_history_v2.rs +++ b/mm2src/coins/tendermint/tendermint_tx_history_v2.rs @@ -18,7 +18,7 @@ use cosmrs::tendermint::abci::{Code as TxCode, EventAttribute}; use cosmrs::tx::Fee; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::MmResult; -use mm2_event_stream::StreamingManager; +use mm2_event_stream::{DeriveStreamerId, StreamingManager}; use mm2_number::BigDecimal; use mm2_state_machine::prelude::*; use mm2_state_machine::state_machine::StateMachineTrait; diff --git a/mm2src/coins/utxo/rpc_clients/electrum_rpc/client.rs b/mm2src/coins/utxo/rpc_clients/electrum_rpc/client.rs index bf37e54444..dfb9c68baf 100644 --- a/mm2src/coins/utxo/rpc_clients/electrum_rpc/client.rs +++ b/mm2src/coins/utxo/rpc_clients/electrum_rpc/client.rs @@ -51,7 +51,7 @@ use futures::stream::FuturesUnordered; use futures::StreamExt; use futures01::Future; use itertools::Itertools; -use mm2_event_stream::{StreamingManager, StreamingManagerError}; +use mm2_event_stream::{DeriveStreamerId, StreamingManager, StreamingManagerError}; use serde_json::{self as json, Value as Json}; type ElectrumTxHistory = Vec; diff --git a/mm2src/coins/utxo/tx_history_events.rs b/mm2src/coins/utxo/tx_history_events.rs index e0404228a9..536482690b 100644 --- a/mm2src/coins/utxo/tx_history_events.rs +++ b/mm2src/coins/utxo/tx_history_events.rs @@ -1,5 +1,5 @@ use crate::TransactionDetails; -use mm2_event_stream::{Broadcaster, Event, EventStreamer, StreamHandlerInput, StreamerId}; +use mm2_event_stream::{Broadcaster, DeriveStreamerId, Event, EventStreamer, StreamHandlerInput, StreamerId}; use async_trait::async_trait; use futures::channel::oneshot; @@ -9,12 +9,14 @@ pub struct TxHistoryEventStreamer { coin: String, } -impl TxHistoryEventStreamer { - #[inline(always)] - pub fn new(coin: String) -> Self { Self { coin } } +impl<'a> DeriveStreamerId<'a> for TxHistoryEventStreamer { + type InitParam = String; + type DeriveParam = &'a str; + + fn new(coin: Self::InitParam) -> Self { Self { coin } } #[inline(always)] - pub fn derive_streamer_id(coin: &str) -> StreamerId { StreamerId::TxHistory { coin: coin.to_string() } } + fn derive_streamer_id(coin: Self::DeriveParam) -> StreamerId { StreamerId::TxHistory { coin: coin.to_string() } } } #[async_trait] diff --git a/mm2src/coins/utxo/utxo_balance_events.rs b/mm2src/coins/utxo/utxo_balance_events.rs index 9451675cdb..13ef83a4fd 100644 --- a/mm2src/coins/utxo/utxo_balance_events.rs +++ b/mm2src/coins/utxo/utxo_balance_events.rs @@ -12,7 +12,7 @@ use common::log; use futures::channel::oneshot; use futures::StreamExt; use keys::Address; -use mm2_event_stream::{Broadcaster, Event, EventStreamer, StreamHandlerInput, StreamerId}; +use mm2_event_stream::{Broadcaster, DeriveStreamerId, Event, EventStreamer, StreamHandlerInput, StreamerId}; use std::collections::{HashMap, HashSet}; macro_rules! try_or_continue { @@ -31,8 +31,11 @@ pub struct UtxoBalanceEventStreamer { coin: UtxoStandardCoin, } -impl UtxoBalanceEventStreamer { - pub fn new(utxo_arc: UtxoArc) -> Self { +impl<'a> DeriveStreamerId<'a> for UtxoBalanceEventStreamer { + type InitParam = UtxoArc; + type DeriveParam = &'a str; + + fn new(utxo_arc: Self::InitParam) -> Self { Self { // We wrap the UtxoArc in a UtxoStandardCoin for easier method accessibility. // The UtxoArc might belong to a different coin type though. @@ -40,7 +43,7 @@ impl UtxoBalanceEventStreamer { } } - pub fn derive_streamer_id(coin: &str) -> StreamerId { StreamerId::Balance { coin: coin.to_string() } } + fn derive_streamer_id(coin: Self::DeriveParam) -> StreamerId { StreamerId::Balance { coin: coin.to_string() } } } #[async_trait] diff --git a/mm2src/coins/utxo/utxo_tx_history_v2.rs b/mm2src/coins/utxo/utxo_tx_history_v2.rs index 56b024efce..333646a050 100644 --- a/mm2src/coins/utxo/utxo_tx_history_v2.rs +++ b/mm2src/coins/utxo/utxo_tx_history_v2.rs @@ -15,7 +15,7 @@ use common::log::{error, info}; use derive_more::Display; use keys::Address; use mm2_err_handle::prelude::*; -use mm2_event_stream::StreamingManager; +use mm2_event_stream::{DeriveStreamerId, StreamingManager}; use mm2_metrics::MetricsArc; use mm2_number::BigDecimal; use mm2_state_machine::prelude::*; diff --git a/mm2src/coins/z_coin/storage/blockdb/blockdb_sql_storage.rs b/mm2src/coins/z_coin/storage/blockdb/blockdb_sql_storage.rs index b91478eacc..631eac3aad 100644 --- a/mm2src/coins/z_coin/storage/blockdb/blockdb_sql_storage.rs +++ b/mm2src/coins/z_coin/storage/blockdb/blockdb_sql_storage.rs @@ -11,6 +11,7 @@ use db_common::sqlite::{query_single_row, run_optimization_pragmas, rusqlite}; use itertools::Itertools; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; +use mm2_event_stream::DeriveStreamerId; use protobuf::Message; use std::sync::{Arc, Mutex}; use zcash_client_backend::data_api::error::Error as ChainError; diff --git a/mm2src/coins/z_coin/tx_history_events.rs b/mm2src/coins/z_coin/tx_history_events.rs index c09da5d732..485c1e8053 100644 --- a/mm2src/coins/z_coin/tx_history_events.rs +++ b/mm2src/coins/z_coin/tx_history_events.rs @@ -4,7 +4,7 @@ use crate::utxo::rpc_clients::UtxoRpcError; use crate::MarketCoinOps; use common::log; use mm2_err_handle::prelude::MmError; -use mm2_event_stream::{Broadcaster, Event, EventStreamer, StreamHandlerInput, StreamerId}; +use mm2_event_stream::{Broadcaster, DeriveStreamerId, Event, EventStreamer, StreamHandlerInput, StreamerId}; use rpc::v1::types::H256 as H256Json; use async_trait::async_trait; @@ -18,12 +18,14 @@ pub struct ZCoinTxHistoryEventStreamer { coin: ZCoin, } -impl ZCoinTxHistoryEventStreamer { - #[inline(always)] - pub fn new(coin: ZCoin) -> Self { Self { coin } } +impl<'a> DeriveStreamerId<'a> for ZCoinTxHistoryEventStreamer { + type InitParam = ZCoin; + type DeriveParam = &'a str; + + fn new(coin: Self::InitParam) -> Self { Self { coin } } #[inline(always)] - pub fn derive_streamer_id(coin: &str) -> StreamerId { StreamerId::TxHistory { coin: coin.to_string() } } + fn derive_streamer_id(coin: Self::DeriveParam) -> StreamerId { StreamerId::TxHistory { coin: coin.to_string() } } } #[async_trait] diff --git a/mm2src/coins/z_coin/tx_streaming_tests/native.rs b/mm2src/coins/z_coin/tx_streaming_tests/native.rs index 6cb7f9a97c..0234b53656 100644 --- a/mm2src/coins/z_coin/tx_streaming_tests/native.rs +++ b/mm2src/coins/z_coin/tx_streaming_tests/native.rs @@ -7,6 +7,7 @@ use crate::{CoinProtocol, DexFee, MarketCoinOps, MmCoin, PrivKeyBuildPolicy}; use common::custom_futures::timeout::FutureTimerExt; use common::{block_on, Future01CompatExt}; use mm2_core::mm_ctx::MmCtxBuilder; +use mm2_event_stream::DeriveStreamerId; use mm2_test_helpers::for_tests::{pirate_conf, ARRR}; use std::time::Duration; diff --git a/mm2src/coins/z_coin/z_balance_streaming.rs b/mm2src/coins/z_coin/z_balance_streaming.rs index c5b012fb3b..45bdaa73d3 100644 --- a/mm2src/coins/z_coin/z_balance_streaming.rs +++ b/mm2src/coins/z_coin/z_balance_streaming.rs @@ -6,18 +6,20 @@ use async_trait::async_trait; use common::log::error; use futures::channel::oneshot; use futures_util::StreamExt; -use mm2_event_stream::{Broadcaster, Event, EventStreamer, StreamHandlerInput, StreamerId}; +use mm2_event_stream::{Broadcaster, DeriveStreamerId, Event, EventStreamer, StreamHandlerInput, StreamerId}; pub struct ZCoinBalanceEventStreamer { coin: ZCoin, } -impl ZCoinBalanceEventStreamer { - #[inline(always)] - pub fn new(coin: ZCoin) -> Self { Self { coin } } +impl<'a> DeriveStreamerId<'a> for ZCoinBalanceEventStreamer { + type InitParam = ZCoin; + type DeriveParam = &'a str; + + fn new(coin: Self::InitParam) -> Self { Self { coin } } #[inline(always)] - pub fn derive_streamer_id(coin: &str) -> StreamerId { StreamerId::Balance { coin: coin.to_string() } } + fn derive_streamer_id(coin: Self::DeriveParam) -> StreamerId { StreamerId::Balance { coin: coin.to_string() } } } #[async_trait] diff --git a/mm2src/mm2_event_stream/src/lib.rs b/mm2src/mm2_event_stream/src/lib.rs index 25a5758fff..55454798b2 100644 --- a/mm2src/mm2_event_stream/src/lib.rs +++ b/mm2src/mm2_event_stream/src/lib.rs @@ -8,5 +8,5 @@ pub mod streamer_ids; pub use configuration::EventStreamingConfiguration; pub use event::Event; pub use manager::{StreamingManager, StreamingManagerError}; -pub use streamer::{Broadcaster, EventStreamer, NoDataIn, StreamHandlerInput}; +pub use streamer::{Broadcaster, DeriveStreamerId, EventStreamer, NoDataIn, StreamHandlerInput}; pub use streamer_ids::StreamerId; diff --git a/mm2src/mm2_event_stream/src/streamer.rs b/mm2src/mm2_event_stream/src/streamer.rs index dee79af8d1..e6e5319a17 100644 --- a/mm2src/mm2_event_stream/src/streamer.rs +++ b/mm2src/mm2_event_stream/src/streamer.rs @@ -39,6 +39,25 @@ where ); } +/// Trait for types that can produce a unique [`StreamerId`] for event streaming. +/// +/// Used to standardize initialization and ID derivation for various streamers. +/// +/// - `'a`: Lifetime for borrowed derive parameters. +pub trait DeriveStreamerId<'a> { + /// Type used to create the instance. + type InitParam; + + /// Borrowed type used to derive the [`StreamerId`]. + type DeriveParam: 'a; + + /// Creates a new instance using the specified initialization parameter. + fn new(param: Self::InitParam) -> Self; + + /// Derives a unique [`StreamerId`] based on the provided parameter. + fn derive_streamer_id(param: Self::DeriveParam) -> StreamerId; +} + /// Spawns the [`EventStreamer::handle`] in a separate task using [`WeakSpawner`]. /// /// Returns a [`oneshot::Sender`] to shutdown the handler and an optional [`mpsc::UnboundedSender`] diff --git a/mm2src/mm2_main/src/lp_ordermatch.rs b/mm2src/mm2_main/src/lp_ordermatch.rs index 5f3b00996b..f874eac21b 100644 --- a/mm2src/mm2_main/src/lp_ordermatch.rs +++ b/mm2src/mm2_main/src/lp_ordermatch.rs @@ -40,7 +40,7 @@ use http::Response; use keys::{AddressFormat, KeyPair}; use mm2_core::mm_ctx::{from_ctx, MmArc, MmWeak}; use mm2_err_handle::prelude::*; -use mm2_event_stream::StreamingManager; +use mm2_event_stream::{DeriveStreamerId, StreamingManager}; use mm2_libp2p::application::request_response::ordermatch::OrdermatchRequest; use mm2_libp2p::application::request_response::P2PRequest; use mm2_libp2p::{decode_signed, encode_and_sign, encode_message, pub_sub_topic, PublicKey, TopicHash, TopicPrefix, @@ -2740,9 +2740,10 @@ impl Orderbook { self.unordered.entry(base_rel).or_default().insert(order.uuid); self.streaming_manager - .send_fn(&OrderbookStreamer::derive_streamer_id(&order.base, &order.rel), || { - OrderbookItemChangeEvent::NewOrUpdatedItem(Box::new(order.clone().into())) - }) + .send_fn( + &OrderbookStreamer::derive_streamer_id((&order.base, &order.rel)), + || OrderbookItemChangeEvent::NewOrUpdatedItem(Box::new(order.clone().into())), + ) .ok(); self.order_set.insert(order.uuid, order); } @@ -2806,9 +2807,10 @@ impl Orderbook { } self.streaming_manager - .send_fn(&OrderbookStreamer::derive_streamer_id(&order.base, &order.rel), || { - OrderbookItemChangeEvent::RemovedItem(order.uuid) - }) + .send_fn( + &OrderbookStreamer::derive_streamer_id((&order.base, &order.rel)), + || OrderbookItemChangeEvent::RemovedItem(order.uuid), + ) .ok(); Some(order) } @@ -3938,7 +3940,7 @@ async fn process_maker_reserved(ctx: MmArc, from_pubkey: H256Json, reserved_msg: }; ctx.event_stream_manager - .send_fn(&OrderStatusStreamer::derive_streamer_id(), || { + .send_fn(&OrderStatusStreamer::derive_streamer_id(()), || { OrderStatusEvent::TakerMatch(taker_match.clone()) }) .ok(); @@ -3993,7 +3995,7 @@ async fn process_maker_connected(ctx: MmArc, from_pubkey: PublicKey, connected: } ctx.event_stream_manager - .send_fn(&OrderStatusStreamer::derive_streamer_id(), || { + .send_fn(&OrderStatusStreamer::derive_streamer_id(()), || { OrderStatusEvent::TakerConnected(order_match.clone()) }) .ok(); @@ -4109,7 +4111,7 @@ async fn process_taker_request(ctx: MmArc, from_pubkey: H256Json, taker_request: }; ctx.event_stream_manager - .send_fn(&OrderStatusStreamer::derive_streamer_id(), || { + .send_fn(&OrderStatusStreamer::derive_streamer_id(()), || { OrderStatusEvent::MakerMatch(maker_match.clone()) }) .ok(); @@ -4180,7 +4182,7 @@ async fn process_taker_connect(ctx: MmArc, sender_pubkey: PublicKey, connect_msg let order_match = order_match.clone(); ctx.event_stream_manager - .send_fn(&OrderStatusStreamer::derive_streamer_id(), || { + .send_fn(&OrderStatusStreamer::derive_streamer_id(()), || { OrderStatusEvent::MakerConnected(order_match.clone()) }) .ok(); diff --git a/mm2src/mm2_main/src/lp_ordermatch/order_events.rs b/mm2src/mm2_main/src/lp_ordermatch/order_events.rs index 9e0fa97593..39d9a1deb0 100644 --- a/mm2src/mm2_main/src/lp_ordermatch/order_events.rs +++ b/mm2src/mm2_main/src/lp_ordermatch/order_events.rs @@ -1,5 +1,5 @@ use super::{MakerMatch, TakerMatch}; -use mm2_event_stream::{Broadcaster, Event, EventStreamer, StreamHandlerInput, StreamerId}; +use mm2_event_stream::{Broadcaster, DeriveStreamerId, Event, EventStreamer, StreamHandlerInput, StreamerId}; use async_trait::async_trait; use futures::channel::oneshot; @@ -7,12 +7,13 @@ use futures::StreamExt; pub struct OrderStatusStreamer; -impl OrderStatusStreamer { - #[inline(always)] - pub fn new() -> Self { Self } +impl DeriveStreamerId<'_> for OrderStatusStreamer { + type InitParam = (); + type DeriveParam = (); - #[inline(always)] - pub const fn derive_streamer_id() -> StreamerId { StreamerId::OrderStatus } + fn new(_: Self::InitParam) -> Self { Self } + + fn derive_streamer_id(_: Self::DeriveParam) -> StreamerId { StreamerId::OrderStatus } } #[derive(Serialize)] @@ -28,7 +29,7 @@ pub enum OrderStatusEvent { impl EventStreamer for OrderStatusStreamer { type DataInType = OrderStatusEvent; - fn streamer_id(&self) -> StreamerId { Self::derive_streamer_id() } + fn streamer_id(&self) -> StreamerId { Self::derive_streamer_id(()) } async fn handle( self, diff --git a/mm2src/mm2_main/src/lp_ordermatch/orderbook_events.rs b/mm2src/mm2_main/src/lp_ordermatch/orderbook_events.rs index 852da7fb1f..4e61496a96 100644 --- a/mm2src/mm2_main/src/lp_ordermatch/orderbook_events.rs +++ b/mm2src/mm2_main/src/lp_ordermatch/orderbook_events.rs @@ -1,7 +1,7 @@ use super::{orderbook_topic_from_base_rel, subscribe_to_orderbook_topic, OrderbookP2PItem}; use coins::{is_wallet_only_ticker, lp_coinfind}; use mm2_core::mm_ctx::MmArc; -use mm2_event_stream::{Broadcaster, Event, EventStreamer, StreamHandlerInput, StreamerId}; +use mm2_event_stream::{Broadcaster, DeriveStreamerId, Event, EventStreamer, StreamHandlerInput, StreamerId}; use async_trait::async_trait; use futures::channel::oneshot; @@ -14,10 +14,14 @@ pub struct OrderbookStreamer { rel: String, } -impl OrderbookStreamer { - pub fn new(ctx: MmArc, base: String, rel: String) -> Self { Self { ctx, base, rel } } +type BaseAndRel<'a> = (&'a str, &'a str); +impl<'a> DeriveStreamerId<'a> for OrderbookStreamer { + type InitParam = (MmArc, String, String); + type DeriveParam = BaseAndRel<'a>; - pub fn derive_streamer_id(base: &str, rel: &str) -> StreamerId { + fn new((ctx, base, rel): Self::InitParam) -> Self { Self { ctx, base, rel } } + + fn derive_streamer_id((base, rel): Self::DeriveParam) -> StreamerId { StreamerId::OrderbookUpdate { topic: orderbook_topic_from_base_rel(base, rel), } @@ -38,7 +42,7 @@ pub enum OrderbookItemChangeEvent { impl EventStreamer for OrderbookStreamer { type DataInType = OrderbookItemChangeEvent; - fn streamer_id(&self) -> StreamerId { Self::derive_streamer_id(&self.base, &self.rel) } + fn streamer_id(&self) -> StreamerId { Self::derive_streamer_id((&self.base, &self.rel)) } async fn handle( self, diff --git a/mm2src/mm2_main/src/lp_swap/maker_swap.rs b/mm2src/mm2_main/src/lp_swap/maker_swap.rs index af3b1bb767..69cba10ac4 100644 --- a/mm2src/mm2_main/src/lp_swap/maker_swap.rs +++ b/mm2src/mm2_main/src/lp_swap/maker_swap.rs @@ -31,6 +31,7 @@ use futures::{compat::Future01CompatExt, select, FutureExt}; use keys::KeyPair; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; +use mm2_event_stream::DeriveStreamerId; use mm2_number::{BigDecimal, MmNumber}; use mm2_rpc::data::legacy::OrderConfirmationsSettings; use parking_lot::Mutex as PaMutex; @@ -2190,9 +2191,11 @@ pub async fn run_maker_swap(swap: RunMakerSwapInput, ctx: MmArc) { drop(dispatcher); // Send a notification to the swap status streamer about a new event. ctx.event_stream_manager - .send_fn(&SwapStatusStreamer::derive_streamer_id(), || SwapStatusEvent::MakerV1 { - uuid: running_swap.uuid, - event: to_save.clone(), + .send_fn(&SwapStatusStreamer::derive_streamer_id(()), || { + SwapStatusEvent::MakerV1 { + uuid: running_swap.uuid, + event: to_save.clone(), + } }) .ok(); save_my_maker_swap_event(&ctx, &running_swap, to_save) diff --git a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs index 61584a5a60..53dbc1d6e7 100644 --- a/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs @@ -24,6 +24,7 @@ use derive_more::Display; use keys::KeyPair; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; +use mm2_event_stream::DeriveStreamerId; use mm2_libp2p::Secp256k1PubkeySerialize; use mm2_number::MmNumber; use mm2_state_machine::prelude::*; @@ -793,9 +794,11 @@ impl Self { Self } +impl DeriveStreamerId<'_> for SwapStatusStreamer { + type InitParam = (); + type DeriveParam = (); - #[inline(always)] - pub const fn derive_streamer_id() -> StreamerId { StreamerId::SwapStatus } + fn new(_: Self::InitParam) -> Self { Self } + + fn derive_streamer_id(_: Self::DeriveParam) -> StreamerId { StreamerId::SwapStatus } } #[derive(Serialize)] @@ -32,7 +33,7 @@ pub enum SwapStatusEvent { impl EventStreamer for SwapStatusStreamer { type DataInType = SwapStatusEvent; - fn streamer_id(&self) -> StreamerId { Self::derive_streamer_id() } + fn streamer_id(&self) -> StreamerId { Self::derive_streamer_id(()) } async fn handle( self, diff --git a/mm2src/mm2_main/src/lp_swap/taker_swap.rs b/mm2src/mm2_main/src/lp_swap/taker_swap.rs index f923e27f9b..ecc8490b28 100644 --- a/mm2src/mm2_main/src/lp_swap/taker_swap.rs +++ b/mm2src/mm2_main/src/lp_swap/taker_swap.rs @@ -31,6 +31,7 @@ use http::Response; use keys::KeyPair; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; +use mm2_event_stream::DeriveStreamerId; use mm2_number::{BigDecimal, MmNumber}; use mm2_rpc::data::legacy::{MatchBy, OrderConfirmationsSettings, TakerAction}; use parking_lot::Mutex as PaMutex; @@ -491,9 +492,11 @@ pub async fn run_taker_swap(swap: RunTakerSwapInput, ctx: MmArc) { // Send a notification to the swap status streamer about a new event. ctx.event_stream_manager - .send_fn(&SwapStatusStreamer::derive_streamer_id(), || SwapStatusEvent::TakerV1 { - uuid: running_swap.uuid, - event: to_save.clone(), + .send_fn(&SwapStatusStreamer::derive_streamer_id(()), || { + SwapStatusEvent::TakerV1 { + uuid: running_swap.uuid, + event: to_save.clone(), + } }) .ok(); save_my_taker_swap_event(&ctx, &running_swap, to_save) diff --git a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs index 32fe7f7dfc..b3ee43a6a1 100644 --- a/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs +++ b/mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs @@ -24,6 +24,7 @@ use derive_more::Display; use keys::KeyPair; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; +use mm2_event_stream::DeriveStreamerId; use mm2_libp2p::Secp256k1PubkeySerialize; use mm2_number::MmNumber; use mm2_state_machine::prelude::*; @@ -910,9 +911,11 @@ impl MmResult { - let order_status_streamer = OrderbookStreamer::new(ctx.clone(), req.base, req.rel); + let order_status_streamer = OrderbookStreamer::new((ctx.clone(), req.base, req.rel)); ctx.event_stream_manager .add(req.client_id, order_status_streamer, ctx.spawner()) .await diff --git a/mm2src/mm2_main/src/rpc/streaming_activations/orders.rs b/mm2src/mm2_main/src/rpc/streaming_activations/orders.rs index 7c7aa0c082..32fee3dfef 100644 --- a/mm2src/mm2_main/src/rpc/streaming_activations/orders.rs +++ b/mm2src/mm2_main/src/rpc/streaming_activations/orders.rs @@ -5,6 +5,7 @@ use super::{EnableStreamingRequest, EnableStreamingResponse}; use derive_more::Display; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::{map_to_mm::MapToMmResult, mm_error::MmResult}; +use mm2_event_stream::DeriveStreamerId; use common::HttpStatusCode; use http::StatusCode; @@ -23,7 +24,7 @@ pub async fn enable_order_status( ctx: MmArc, req: EnableStreamingRequest<()>, ) -> MmResult { - let order_status_streamer = OrderStatusStreamer::new(); + let order_status_streamer = OrderStatusStreamer::new(()); ctx.event_stream_manager .add(req.client_id, order_status_streamer, ctx.spawner()) .await diff --git a/mm2src/mm2_main/src/rpc/streaming_activations/swaps.rs b/mm2src/mm2_main/src/rpc/streaming_activations/swaps.rs index f632b1758a..497e7af86b 100644 --- a/mm2src/mm2_main/src/rpc/streaming_activations/swaps.rs +++ b/mm2src/mm2_main/src/rpc/streaming_activations/swaps.rs @@ -7,6 +7,7 @@ use derive_more::Display; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::{map_to_mm::MapToMmResult, mm_error::MmResult}; +use mm2_event_stream::DeriveStreamerId; #[derive(Display, Serialize, SerializeErrorType)] #[serde(tag = "error_type", content = "error_data")] @@ -27,7 +28,7 @@ pub async fn enable_swap_status( req: EnableStreamingRequest<()>, ) -> MmResult { ctx.event_stream_manager - .add(req.client_id, SwapStatusStreamer::new(), ctx.spawner()) + .add(req.client_id, SwapStatusStreamer::new(()), ctx.spawner()) .await .map(EnableStreamingResponse::new) .map_to_mm(|e| SwapStatusStreamingRequestError::EnableError(format!("{e:?}"))) diff --git a/mm2src/mm2_main/src/rpc/streaming_activations/tx_history.rs b/mm2src/mm2_main/src/rpc/streaming_activations/tx_history.rs index e79893ee8e..10bb9d1786 100644 --- a/mm2src/mm2_main/src/rpc/streaming_activations/tx_history.rs +++ b/mm2src/mm2_main/src/rpc/streaming_activations/tx_history.rs @@ -9,6 +9,7 @@ use derive_more::Display; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::{map_to_mm::MapToMmResult, mm_error::MmResult}; +use mm2_event_stream::DeriveStreamerId; #[derive(Deserialize)] pub struct EnableTxHistoryStreamingRequest { From 36cba1c6f21947d189cdae1f1d01f57cc98e5069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Wed, 16 Jul 2025 15:30:30 +0300 Subject: [PATCH 12/75] fix(WASM and Debian): fix build failures (#2534) In addition to fixing a small wasm build problem, this commit bumps Debian CI image to bullseye. --- .docker/Dockerfile.ci-container | 2 +- mm2src/coins/z_coin/storage/blockdb/blockdb_idb_storage.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.docker/Dockerfile.ci-container b/.docker/Dockerfile.ci-container index c56e686888..77f68f166b 100644 --- a/.docker/Dockerfile.ci-container +++ b/.docker/Dockerfile.ci-container @@ -1,4 +1,4 @@ -FROM docker.io/debian:buster-slim +FROM docker.io/debian:bullseye-slim MAINTAINER Onur Özkan diff --git a/mm2src/coins/z_coin/storage/blockdb/blockdb_idb_storage.rs b/mm2src/coins/z_coin/storage/blockdb/blockdb_idb_storage.rs index 4a74c621fe..b3863eb999 100644 --- a/mm2src/coins/z_coin/storage/blockdb/blockdb_idb_storage.rs +++ b/mm2src/coins/z_coin/storage/blockdb/blockdb_idb_storage.rs @@ -9,6 +9,7 @@ use mm2_core::mm_ctx::MmArc; use mm2_db::indexed_db::{BeBigUint, ConstructibleDb, DbIdentifier, DbInstance, DbLocked, DbUpgrader, IndexedDb, IndexedDbBuilder, InitDbResult, MultiIndex, OnUpgradeResult, TableSignature}; use mm2_err_handle::prelude::*; +use mm2_event_stream::DeriveStreamerId; use protobuf::Message; use zcash_client_backend::proto::compact_formats::CompactBlock; use zcash_extras::WalletRead; From b59860b32cebad69eeb7dc56fac2bd1fe0addd7c Mon Sep 17 00:00:00 2001 From: dragonhound <35845239+smk762@users.noreply.github.com> Date: Fri, 18 Jul 2025 15:41:54 +0800 Subject: [PATCH 13/75] fix(ci): adds nodejs 20 to ci-container (#2536) * adds nodejs 20 to ci container * remove comment * remove mm2 (in favor of kdf) from dockerfiles * move node install from ci container to build cache action --- .docker/Dockerfile.ci-container | 2 +- .docker/Dockerfile.dev-release | 1 - .docker/Dockerfile.release | 1 - .github/actions/build-cache/action.yml | 5 +++++ 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.docker/Dockerfile.ci-container b/.docker/Dockerfile.ci-container index 77f68f166b..39eee8f49c 100644 --- a/.docker/Dockerfile.ci-container +++ b/.docker/Dockerfile.ci-container @@ -1,6 +1,6 @@ FROM docker.io/debian:bullseye-slim -MAINTAINER Onur Özkan +LABEL maintainer="Onur Özkan " RUN apt-get update -y diff --git a/.docker/Dockerfile.dev-release b/.docker/Dockerfile.dev-release index 74abcb02e3..e61f129ead 100644 --- a/.docker/Dockerfile.dev-release +++ b/.docker/Dockerfile.dev-release @@ -1,6 +1,5 @@ FROM docker.io/debian:stable-slim WORKDIR /kdf COPY target/release/kdf /usr/local/bin/kdf -COPY target/release/mm2 /usr/local/bin/mm2 EXPOSE 7783 CMD ["kdf"] diff --git a/.docker/Dockerfile.release b/.docker/Dockerfile.release index d9d8d51325..4bc8398893 100644 --- a/.docker/Dockerfile.release +++ b/.docker/Dockerfile.release @@ -1,6 +1,5 @@ FROM docker.io/debian:stable-slim WORKDIR /kdf COPY target/release/kdf /usr/local/bin/kdf -COPY target/release/mm2 /usr/local/bin/mm2 EXPOSE 7783 CMD ["kdf"] \ No newline at end of file diff --git a/.github/actions/build-cache/action.yml b/.github/actions/build-cache/action.yml index c5af862e1b..26e3f51eb9 100644 --- a/.github/actions/build-cache/action.yml +++ b/.github/actions/build-cache/action.yml @@ -6,5 +6,10 @@ runs: - name: Checkout repository uses: actions/checkout@v3 + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + - name: Set up rust-cache uses: Swatinem/rust-cache@v2 From daf43ebeadf0b8e17f2b76019c6496236f4dd46c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Thu, 24 Jul 2025 20:49:53 +0300 Subject: [PATCH 14/75] refactor(toolchain): general stabilization for stable rust (#2528) This commit migrates to the stable compiler 1.85.1, some crates (like as mm2_state_machine, mm2_err_handle and certain test crates) still retain nightly features due to their practical benefits in those contexts. --- .cargo/config.toml | 19 +- .github/workflows/dev-build.yml | 36 +- .github/workflows/fmt-and-lint.yml | 8 +- .github/workflows/release-build.yml | 36 +- .github/workflows/test.yml | 32 +- Cargo.toml | 2 +- mm2src/coins/Cargo.toml | 18 +- mm2src/coins/coin_balance.rs | 34 +- mm2src/coins/coin_errors.rs | 4 +- mm2src/coins/eth.rs | 386 ++++++++----- mm2src/coins/eth/eth_balance_events.rs | 27 +- mm2src/coins/eth/eth_hd_wallet.rs | 13 +- mm2src/coins/eth/eth_rpc.rs | 7 +- .../eth/eth_swap_v2/eth_maker_swap_v2.rs | 16 +- .../eth/eth_swap_v2/eth_taker_swap_v2.rs | 21 +- mm2src/coins/eth/eth_tests.rs | 5 +- mm2src/coins/eth/eth_utils.rs | 12 +- mm2src/coins/eth/eth_wasm_tests.rs | 4 +- mm2src/coins/eth/eth_withdraw.rs | 44 +- .../coins/eth/fee_estimation/eip1559/mod.rs | 4 +- .../eth/fee_estimation/eip1559/simple.rs | 12 +- .../eth/fee_estimation/eth_fee_events.rs | 4 +- mm2src/coins/eth/for_tests.rs | 3 +- mm2src/coins/eth/nft_swap_v2/mod.rs | 15 +- mm2src/coins/eth/tron/address.rs | 24 +- mm2src/coins/eth/v2_activation.rs | 89 ++- mm2src/coins/eth/wallet_connect.rs | 4 +- .../eth/web3_transport/http_transport.rs | 8 +- .../eth/web3_transport/metamask_transport.rs | 4 +- mm2src/coins/eth/web3_transport/mod.rs | 18 +- .../eth/web3_transport/websocket_transport.rs | 6 +- mm2src/coins/hd_wallet/coin_ops.rs | 14 +- mm2src/coins/hd_wallet/confirm_address.rs | 4 +- mm2src/coins/hd_wallet/errors.rs | 60 +- mm2src/coins/hd_wallet/mod.rs | 95 ++- mm2src/coins/hd_wallet/pubkey.rs | 16 +- .../coins/hd_wallet/storage/mock_storage.rs | 7 +- mm2src/coins/hd_wallet/storage/mod.rs | 75 ++- .../coins/hd_wallet/storage/sqlite_storage.rs | 10 +- .../coins/hd_wallet/storage/wasm_storage.rs | 16 +- mm2src/coins/lightning.rs | 155 +++-- mm2src/coins/lightning/ln_db.rs | 4 +- mm2src/coins/lightning/ln_errors.rs | 32 +- .../lightning/ln_filesystem_persister.rs | 20 +- mm2src/coins/lightning/ln_platform.rs | 52 +- mm2src/coins/lightning/ln_serialization.rs | 12 +- mm2src/coins/lightning/ln_sql.rs | 23 +- mm2src/coins/lightning/ln_utils.rs | 13 +- mm2src/coins/lp_coins.rs | 435 ++++++++++---- mm2src/coins/lp_price.rs | 124 ++-- mm2src/coins/my_tx_history_v2.rs | 30 +- mm2src/coins/nft.rs | 36 +- mm2src/coins/nft/nft_errors.rs | 90 ++- mm2src/coins/nft/nft_structs.rs | 4 +- mm2src/coins/nft/nft_tests.rs | 13 +- mm2src/coins/nft/storage/db_test_helpers.rs | 5 +- mm2src/coins/nft/storage/mod.rs | 12 +- mm2src/coins/nft/storage/sql_storage.rs | 40 +- mm2src/coins/nft/storage/wasm/nft_idb.rs | 4 +- mm2src/coins/nft/storage/wasm/wasm_storage.rs | 44 +- mm2src/coins/qrc20.rs | 228 +++++--- mm2src/coins/qrc20/history.rs | 18 +- mm2src/coins/qrc20/rpc_clients.rs | 4 +- mm2src/coins/qrc20/swap.rs | 26 +- mm2src/coins/rpc_command/get_current_mtp.rs | 16 +- mm2src/coins/rpc_command/get_new_address.rs | 41 +- .../hd_account_balance_rpc_error.rs | 4 +- .../coins/rpc_command/init_account_balance.rs | 14 +- .../coins/rpc_command/init_create_account.rs | 59 +- .../init_scan_for_new_addresses.rs | 14 +- mm2src/coins/rpc_command/init_withdraw.rs | 15 +- .../rpc_command/lightning/connect_to_node.rs | 8 +- .../rpc_command/lightning/generate_invoice.rs | 8 +- .../lightning/get_channel_details.rs | 4 +- .../lightning/get_payment_details.rs | 4 +- .../rpc_command/lightning/list_channels.rs | 4 +- .../lightning/list_payments_by_filter.rs | 4 +- .../rpc_command/lightning/open_channel.rs | 38 +- .../rpc_command/lightning/send_payment.rs | 8 +- .../rpc_command/lightning/trusted_nodes.rs | 4 +- mm2src/coins/rpc_command/mod.rs | 3 +- mm2src/coins/rpc_command/tendermint/ibc.rs | 8 +- .../coins/rpc_command/tendermint/staking.rs | 5 +- mm2src/coins/siacoin.rs | 215 +++++-- mm2src/coins/tendermint/htlc/iris/htlc.rs | 8 +- mm2src/coins/tendermint/htlc/nucleus/htlc.rs | 8 +- mm2src/coins/tendermint/ibc/transfer_v1.rs | 8 +- mm2src/coins/tendermint/rpc/mod.rs | 6 +- .../tendermint/rpc/tendermint_native_rpc.rs | 41 +- .../tendermint/rpc/tendermint_wasm_rpc.rs | 28 +- .../tendermint/tendermint_balance_events.rs | 4 +- mm2src/coins/tendermint/tendermint_coin.rs | 231 +++++--- mm2src/coins/tendermint/tendermint_token.rs | 135 +++-- .../tendermint/tendermint_tx_history_v2.rs | 13 +- mm2src/coins/test_coin.rs | 319 ++++++++--- mm2src/coins/tx_history_storage/mod.rs | 35 +- .../sql_tx_history_storage_v2.rs | 30 +- .../tx_history_storage/tx_history_v2_tests.rs | 92 ++- .../tx_history_storage/wasm/tx_history_db.rs | 4 +- .../wasm/tx_history_storage_v1.rs | 12 +- .../wasm/tx_history_storage_v2.rs | 14 +- mm2src/coins/utxo.rs | 208 +++++-- mm2src/coins/utxo/bch.rs | 196 +++++-- mm2src/coins/utxo/bchd_grpc.rs | 23 +- mm2src/coins/utxo/qtum.rs | 246 +++++--- mm2src/coins/utxo/qtum_delegation.rs | 32 +- mm2src/coins/utxo/rpc_clients.rs | 77 ++- .../utxo/rpc_clients/electrum_rpc/client.rs | 89 ++- .../rpc_clients/electrum_rpc/connection.rs | 39 +- .../connection_manager/connection_context.rs | 12 +- .../connection_manager/manager.rs | 20 +- .../electrum_rpc/event_handlers.rs | 4 +- .../utxo/rpc_clients/electrum_rpc/mod.rs | 3 +- .../rpc_clients/electrum_rpc/rpc_responses.rs | 4 +- mm2src/coins/utxo/slp.rs | 246 +++++--- mm2src/coins/utxo/tx_cache/fs_tx_cache.rs | 8 +- mm2src/coins/utxo/tx_cache/mod.rs | 3 +- mm2src/coins/utxo/tx_history_events.rs | 12 +- mm2src/coins/utxo/utxo_balance_events.rs | 18 +- .../utxo/utxo_block_header_storage/mod.rs | 54 +- .../sql_block_header_storage.rs | 16 +- .../wasm/indexeddb_block_header_storage.rs | 18 +- mm2src/coins/utxo/utxo_builder/mod.rs | 7 +- .../utxo/utxo_builder/utxo_arc_builder.rs | 35 +- .../utxo/utxo_builder/utxo_coin_builder.rs | 76 ++- .../utxo/utxo_builder/utxo_conf_builder.rs | 58 +- mm2src/coins/utxo/utxo_common.rs | 144 +++-- .../utxo_common/utxo_tx_history_v2_common.rs | 17 +- mm2src/coins/utxo/utxo_common_tests.rs | 10 +- mm2src/coins/utxo/utxo_hd_wallet.rs | 55 +- mm2src/coins/utxo/utxo_standard.rs | 217 ++++--- mm2src/coins/utxo/utxo_tests.rs | 235 ++++++-- mm2src/coins/utxo/utxo_tx_history_v2.rs | 35 +- mm2src/coins/utxo/utxo_withdraw.rs | 64 ++- mm2src/coins/utxo_signer/src/lib.rs | 8 +- mm2src/coins/utxo_signer/src/sign_params.rs | 12 +- mm2src/coins/utxo_signer/src/with_key_pair.rs | 10 +- mm2src/coins/utxo_signer/src/with_trezor.rs | 13 +- mm2src/coins/watcher_common.rs | 8 +- mm2src/coins/z_coin.rs | 221 ++++--- mm2src/coins/z_coin/storage.rs | 19 +- .../storage/blockdb/blockdb_idb_storage.rs | 16 +- .../storage/blockdb/blockdb_sql_storage.rs | 10 +- mm2src/coins/z_coin/storage/blockdb/mod.rs | 32 +- mm2src/coins/z_coin/storage/walletdb/mod.rs | 3 +- .../coins/z_coin/storage/walletdb/wasm/mod.rs | 4 +- .../z_coin/storage/walletdb/wasm/storage.rs | 30 +- .../z_coin/storage/z_params/indexeddb.rs | 10 +- mm2src/coins/z_coin/tx_history_events.rs | 24 +- mm2src/coins/z_coin/tx_streaming_tests/mod.rs | 6 +- mm2src/coins/z_coin/z_balance_streaming.rs | 8 +- mm2src/coins/z_coin/z_coin_errors.rs | 131 +++-- mm2src/coins/z_coin/z_htlc.rs | 16 +- mm2src/coins/z_coin/z_rpc.rs | 4 +- mm2src/coins/z_coin/z_unit_tests.rs | 8 +- mm2src/coins_activation/Cargo.toml | 2 +- .../src/bch_with_tokens_activation.rs | 38 +- .../src/erc20_token_activation.rs | 20 +- .../src/eth_with_token_activation.rs | 50 +- .../src/init_erc20_token_activation.rs | 8 +- mm2src/coins_activation/src/init_token.rs | 32 +- mm2src/coins_activation/src/l2/init_l2.rs | 5 +- mm2src/coins_activation/src/lib.rs | 19 +- .../src/lightning_activation.rs | 32 +- .../src/platform_coin_with_tokens.rs | 35 +- mm2src/coins_activation/src/prelude.rs | 24 +- .../src/sia_coin_activation.rs | 28 +- .../src/slp_token_activation.rs | 4 +- .../standalone_coin/init_standalone_coin.rs | 12 +- .../src/standalone_coin/mod.rs | 10 +- .../src/tendermint_token_activation.rs | 26 +- .../src/tendermint_with_assets_activation.rs | 56 +- mm2src/coins_activation/src/token.rs | 6 +- .../src/utxo_activation/common_impl.rs | 5 +- .../utxo_activation/init_bch_activation.rs | 15 +- .../utxo_activation/init_qtum_activation.rs | 15 +- .../init_utxo_standard_activation.rs | 15 +- .../init_utxo_standard_activation_error.rs | 4 +- .../init_utxo_standard_statuses.rs | 4 +- .../src/utxo_activation/mod.rs | 9 +- .../utxo_standard_activation_result.rs | 4 +- .../coins_activation/src/z_coin_activation.rs | 37 +- mm2src/common/Cargo.toml | 4 +- mm2src/common/bool_as_int.rs | 12 +- mm2src/common/common.rs | 209 +++++-- mm2src/common/crash_reports.rs | 8 +- mm2src/common/custom_futures/repeatable.rs | 20 +- mm2src/common/executor/abort_on_drop.rs | 8 +- .../abortable_system/abortable_queue.rs | 12 +- .../abortable_system/graceful_shutdown.rs | 12 +- .../common/executor/abortable_system/mod.rs | 8 +- .../executor/abortable_system/simple_map.rs | 16 +- mm2src/common/executor/mod.rs | 6 +- mm2src/common/executor/native_executor.rs | 8 +- mm2src/common/executor/spawner.rs | 4 +- mm2src/common/executor/wasm_executor.rs | 12 +- mm2src/common/jsonrpc_client.rs | 64 ++- mm2src/common/log.rs | 88 ++- mm2src/common/log/native_log.rs | 4 +- mm2src/common/log/wasm_log.rs | 12 +- mm2src/common/notifier.rs | 4 +- mm2src/common/number_type_casting.rs | 8 +- mm2src/common/on_drop_callback.rs | 4 +- mm2src/common/seri.rs | 4 +- .../common/shared_ref_counter/src/disable.rs | 36 +- .../common/shared_ref_counter/src/enable.rs | 11 +- mm2src/common/shared_ref_counter/src/lib.rs | 9 +- mm2src/common/wio.rs | 8 +- mm2src/crypto/Cargo.toml | 2 +- mm2src/crypto/src/bip32_child.rs | 44 +- mm2src/crypto/src/crypto_ctx.rs | 44 +- mm2src/crypto/src/decrypt.rs | 4 +- mm2src/crypto/src/global_hd_ctx.rs | 20 +- mm2src/crypto/src/hw_client.rs | 12 +- mm2src/crypto/src/hw_ctx.rs | 36 +- mm2src/crypto/src/hw_error.rs | 4 +- mm2src/crypto/src/hw_rpc_task.rs | 5 +- mm2src/crypto/src/key_derivation.rs | 4 +- mm2src/crypto/src/lib.rs | 35 +- mm2src/crypto/src/metamask_ctx.rs | 28 +- mm2src/crypto/src/metamask_login.rs | 4 +- mm2src/crypto/src/mnemonic.rs | 8 +- mm2src/crypto/src/privkey.rs | 32 +- mm2src/crypto/src/slip21.rs | 4 +- mm2src/crypto/src/standard_hd_path.rs | 93 ++- mm2src/crypto/src/xpub.rs | 4 +- mm2src/db_common/src/async_conn_tests.rs | 12 +- mm2src/db_common/src/async_sql_conn.rs | 20 +- mm2src/db_common/src/lib.rs | 30 +- mm2src/db_common/src/sql_constraint.rs | 12 +- mm2src/db_common/src/sql_create.rs | 6 +- mm2src/db_common/src/sql_delete.rs | 16 +- mm2src/db_common/src/sql_insert.rs | 4 +- mm2src/db_common/src/sql_query.rs | 22 +- mm2src/db_common/src/sql_update.rs | 16 +- mm2src/db_common/src/sql_value.rs | 24 +- mm2src/db_common/src/sqlite.rs | 28 +- mm2src/derives/enum_derives/src/lib.rs | 17 +- mm2src/derives/ser_error/src/lib.rs | 8 +- mm2src/derives/ser_error_derive/src/lib.rs | 8 +- mm2src/hw_common/src/transport/libusb.rs | 12 +- mm2src/hw_common/src/transport/mod.rs | 3 +- .../hw_common/src/transport/webusb_driver.rs | 8 +- mm2src/kdf_walletconnect/Cargo.toml | 2 +- mm2src/kdf_walletconnect/src/error.rs | 8 +- .../kdf_walletconnect/src/inbound_message.rs | 24 +- mm2src/kdf_walletconnect/src/lib.rs | 16 +- mm2src/kdf_walletconnect/src/pairing.rs | 7 +- mm2src/kdf_walletconnect/src/session/key.rs | 16 +- mm2src/kdf_walletconnect/src/session/mod.rs | 37 +- .../src/session/rpc/delete.rs | 8 +- .../src/session/rpc/event.rs | 18 +- .../src/session/rpc/extend.rs | 6 +- .../kdf_walletconnect/src/session/rpc/ping.rs | 6 +- .../src/session/rpc/propose.rs | 20 +- .../src/storage/indexed_db.rs | 14 +- mm2src/kdf_walletconnect/src/storage/mod.rs | 18 +- .../kdf_walletconnect/src/storage/sqlite.rs | 10 +- mm2src/mm2_bin_lib/build.rs | 12 +- mm2src/mm2_bin_lib/src/lib.rs | 9 +- mm2src/mm2_bin_lib/src/mm2_bin.rs | 3 +- mm2src/mm2_bin_lib/src/mm2_native_lib.rs | 4 +- mm2src/mm2_bin_lib/src/mm2_wasm_lib.rs | 20 +- mm2src/mm2_bitcoin/chain/src/block.rs | 20 +- mm2src/mm2_bitcoin/chain/src/block_header.rs | 26 +- mm2src/mm2_bitcoin/chain/src/lib.rs | 8 +- mm2src/mm2_bitcoin/chain/src/raw_block.rs | 4 +- mm2src/mm2_bitcoin/chain/src/transaction.rs | 55 +- mm2src/mm2_bitcoin/crypto/src/lib.rs | 16 +- mm2src/mm2_bitcoin/keys/src/address.rs | 68 ++- .../mm2_bitcoin/keys/src/address_prefixes.rs | 16 +- mm2src/mm2_bitcoin/keys/src/cashaddress.rs | 12 +- mm2src/mm2_bitcoin/keys/src/keypair.rs | 20 +- mm2src/mm2_bitcoin/keys/src/legacyaddress.rs | 8 +- mm2src/mm2_bitcoin/keys/src/lib.rs | 23 +- mm2src/mm2_bitcoin/keys/src/private.rs | 8 +- mm2src/mm2_bitcoin/keys/src/public.rs | 22 +- mm2src/mm2_bitcoin/keys/src/segwitaddress.rs | 8 +- mm2src/mm2_bitcoin/keys/src/signature.rs | 48 +- mm2src/mm2_bitcoin/primitives/src/bytes.rs | 100 +++- mm2src/mm2_bitcoin/primitives/src/compact.rs | 20 +- mm2src/mm2_bitcoin/primitives/src/hash.rs | 72 ++- mm2src/mm2_bitcoin/rpc/src/lib.rs | 6 +- .../mm2_bitcoin/rpc/src/v1/types/address.rs | 8 +- mm2src/mm2_bitcoin/rpc/src/v1/types/bytes.rs | 24 +- mm2src/mm2_bitcoin/rpc/src/v1/types/hash.rs | 32 +- mm2src/mm2_bitcoin/rpc/src/v1/types/mod.rs | 17 +- mm2src/mm2_bitcoin/rpc/src/v1/types/script.rs | 4 +- .../rpc/src/v1/types/transaction.rs | 24 +- mm2src/mm2_bitcoin/rpc/src/v1/types/uint.rs | 12 +- mm2src/mm2_bitcoin/script/src/builder.rs | 12 +- mm2src/mm2_bitcoin/script/src/num.rs | 68 ++- mm2src/mm2_bitcoin/script/src/opcode.rs | 20 +- mm2src/mm2_bitcoin/script/src/script.rs | 40 +- mm2src/mm2_bitcoin/script/src/sign.rs | 20 +- mm2src/mm2_bitcoin/script/src/stack.rs | 32 +- mm2src/mm2_bitcoin/script/src/verify.rs | 18 +- .../serialization/src/compact_integer.rs | 40 +- mm2src/mm2_bitcoin/serialization/src/impls.rs | 82 ++- mm2src/mm2_bitcoin/serialization/src/lib.rs | 6 +- mm2src/mm2_bitcoin/serialization/src/list.rs | 12 +- .../mm2_bitcoin/serialization/src/reader.rs | 32 +- .../mm2_bitcoin/serialization/src/stream.rs | 16 +- .../serialization_derive/src/de.rs | 4 +- .../serialization_derive/src/lib.rs | 3 +- .../serialization_derive/src/ser.rs | 8 +- .../serialization_derive/tests/raw.rs | 3 +- .../spv_validation/src/helpers_validation.rs | 20 +- mm2src/mm2_bitcoin/spv_validation/src/work.rs | 28 +- mm2src/mm2_bitcoin/test_helpers/src/hex.rs | 8 +- mm2src/mm2_core/src/event_dispatcher.rs | 20 +- mm2src/mm2_core/src/lib.rs | 10 +- mm2src/mm2_core/src/mm_ctx.rs | 114 +++- mm2src/mm2_db/src/indexed_db/be_big_uint.rs | 36 +- mm2src/mm2_db/src/indexed_db/db_driver.rs | 22 +- mm2src/mm2_db/src/indexed_db/db_lock.rs | 4 +- .../mm2_db/src/indexed_db/drivers/builder.rs | 1 + .../src/indexed_db/drivers/cursor/cursor.rs | 24 +- .../indexed_db/drivers/cursor/empty_cursor.rs | 4 +- .../drivers/cursor/multi_key_bound_cursor.rs | 5 +- .../drivers/cursor/multi_key_cursor.rs | 4 +- .../src/indexed_db/drivers/object_store.rs | 7 +- .../src/indexed_db/drivers/transaction.rs | 9 +- .../mm2_db/src/indexed_db/drivers/upgrader.rs | 4 +- .../mm2_db/src/indexed_db/indexed_cursor.rs | 4 +- mm2src/mm2_db/src/indexed_db/indexed_db.rs | 33 +- mm2src/mm2_db/src/lib.rs | 2 - mm2src/mm2_err_handle/src/common_errors.rs | 4 +- mm2src/mm2_err_handle/src/discard_mm_trace.rs | 4 +- mm2src/mm2_err_handle/src/mm_error.rs | 48 +- mm2src/mm2_err_handle/src/mm_json_error.rs | 4 +- mm2src/mm2_err_handle/src/split_mm.rs | 4 +- mm2src/mm2_event_stream/src/event.rs | 8 +- mm2src/mm2_event_stream/src/manager.rs | 40 +- mm2src/mm2_event_stream/src/streamer.rs | 8 +- mm2src/mm2_git/src/github_client.rs | 20 +- .../account/storage/account_storage_tests.rs | 110 ++-- .../src/account/storage/mod.rs | 16 +- .../src/account/storage/sqlite_storage.rs | 65 ++- .../src/account/storage/wasm_storage.rs | 21 +- mm2src/mm2_gui_storage/src/rpc_commands.rs | 6 +- mm2src/mm2_io/src/file_lock.rs | 8 +- mm2src/mm2_io/src/fs.rs | 4 +- mm2src/mm2_io/src/lib.rs | 6 +- mm2src/mm2_main/Cargo.toml | 2 +- mm2src/mm2_main/src/database.rs | 19 +- mm2src/mm2_main/src/database/my_orders.rs | 12 +- mm2src/mm2_main/src/database/my_swaps.rs | 12 +- mm2src/mm2_main/src/database/stats_swaps.rs | 10 +- mm2src/mm2_main/src/heartbeat_event.rs | 8 +- mm2src/mm2_main/src/lp_dispatcher.rs | 18 +- mm2src/mm2_main/src/lp_healthcheck.rs | 16 +- mm2src/mm2_main/src/lp_init/init_hw.rs | 57 +- mm2src/mm2_main/src/lp_message_service.rs | 15 +- mm2src/mm2_main/src/lp_native_dex.rs | 33 +- mm2src/mm2_main/src/lp_network.rs | 18 +- mm2src/mm2_main/src/lp_ordermatch.rs | 268 ++++++--- .../mm2_main/src/lp_ordermatch/best_orders.rs | 34 +- mm2src/mm2_main/src/lp_ordermatch/lp_bot.rs | 70 ++- .../src/lp_ordermatch/my_orders_storage.rs | 45 +- .../src/lp_ordermatch/new_protocol.rs | 16 +- .../src/lp_ordermatch/order_events.rs | 12 +- .../lp_ordermatch/order_requests_tracker.rs | 4 +- .../src/lp_ordermatch/orderbook_events.rs | 8 +- .../src/lp_ordermatch/orderbook_rpc.rs | 6 +- .../src/lp_ordermatch/ordermatch_wasm_db.rs | 19 +- .../src/lp_ordermatch/simple_market_maker.rs | 70 ++- .../simple_market_maker_tests.rs | 8 +- mm2src/mm2_main/src/lp_stats.rs | 36 +- mm2src/mm2_main/src/lp_swap.rs | 98 +++- mm2src/mm2_main/src/lp_swap/maker_swap.rs | 541 +++++++++++------- mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs | 65 ++- .../mm2_main/src/lp_swap/my_swaps_storage.rs | 12 +- .../src/lp_swap/recreate_swap_data.rs | 20 +- mm2src/mm2_main/src/lp_swap/saved_swap.rs | 25 +- mm2src/mm2_main/src/lp_swap/swap_events.rs | 12 +- mm2src/mm2_main/src/lp_swap/swap_lock.rs | 14 +- mm2src/mm2_main/src/lp_swap/swap_v2_common.rs | 25 +- mm2src/mm2_main/src/lp_swap/swap_v2_rpcs.rs | 38 +- mm2src/mm2_main/src/lp_swap/swap_wasm_db.rs | 14 +- mm2src/mm2_main/src/lp_swap/swap_watcher.rs | 39 +- mm2src/mm2_main/src/lp_swap/taker_restart.rs | 4 +- mm2src/mm2_main/src/lp_swap/taker_swap.rs | 505 +++++++++------- mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs | 70 ++- mm2src/mm2_main/src/lp_swap/trade_preimage.rs | 4 +- mm2src/mm2_main/src/lp_wallet.rs | 35 +- .../src/lp_wallet/mnemonics_wasm_db.rs | 18 +- mm2src/mm2_main/src/mm2.rs | 33 +- .../src/notification/telegram/telegram.rs | 4 +- mm2src/mm2_main/src/ordermatch_tests.rs | 434 ++++++++------ mm2src/mm2_main/src/rpc.rs | 7 +- .../mm2_main/src/rpc/dispatcher/dispatcher.rs | 85 +-- .../src/rpc/dispatcher/dispatcher_legacy.rs | 22 +- mm2src/mm2_main/src/rpc/lp_commands/legacy.rs | 9 +- .../mm2_main/src/rpc/lp_commands/lr_swap.rs | 6 +- .../src/rpc/lp_commands/lr_swap/lr_impl.rs | 5 +- .../src/rpc/lp_commands/one_inch/errors.rs | 20 +- .../src/rpc/lp_commands/one_inch/rpcs.rs | 20 +- .../src/rpc/lp_commands/one_inch/types.rs | 8 +- mm2src/mm2_main/src/rpc/lp_commands/pubkey.rs | 4 +- mm2src/mm2_main/src/rpc/lp_commands/tokens.rs | 5 +- mm2src/mm2_main/src/rpc/lp_commands/trezor.rs | 4 +- .../src/rpc/streaming_activations/disable.rs | 8 +- .../rpc/streaming_activations/heartbeat.rs | 4 +- .../src/rpc/streaming_activations/mod.rs | 4 +- .../src/rpc/streaming_activations/network.rs | 4 +- .../rpc/streaming_activations/orderbook.rs | 4 +- .../src/rpc/streaming_activations/orders.rs | 4 +- mm2src/mm2_main/src/swap_versioning.rs | 12 +- mm2src/mm2_main/src/wasm_tests.rs | 20 +- .../docker_tests/docker_ordermatch_tests.rs | 30 +- .../tests/docker_tests/docker_tests_common.rs | 39 +- .../tests/docker_tests/docker_tests_inner.rs | 89 +-- .../tests/docker_tests/eth_docker_tests.rs | 139 +++-- mm2src/mm2_main/tests/docker_tests/mod.rs | 7 +- .../tests/docker_tests/qrc20_tests.rs | 34 +- .../tests/docker_tests/sia_docker_tests.rs | 4 +- .../mm2_main/tests/docker_tests/slp_tests.rs | 13 +- .../tests/docker_tests/swap_proto_v2_tests.rs | 51 +- .../tests/docker_tests/swap_watcher_tests.rs | 60 +- .../tests/docker_tests/tendermint_tests.rs | 49 +- .../tests/docker_tests/z_coin_docker_tests.rs | 11 +- mm2src/mm2_main/tests/docker_tests_main.rs | 10 +- .../mm2_main/tests/docker_tests_sia_unique.rs | 10 +- .../tests/integration_tests_common/mod.rs | 14 +- .../tests/mm2_tests/bch_and_slp_tests.rs | 17 +- .../tests/mm2_tests/best_orders_tests.rs | 7 +- mm2src/mm2_main/tests/mm2_tests/eth_tests.rs | 5 +- .../tests/mm2_tests/lightning_tests.rs | 16 +- .../tests/mm2_tests/mm2_tests_inner.rs | 152 +++-- mm2src/mm2_main/tests/mm2_tests/mod.rs | 10 +- .../tests/mm2_tests/orderbook_sync_tests.rs | 8 +- .../mm2_main/tests/mm2_tests/z_coin_tests.rs | 14 +- mm2src/mm2_metamask/Cargo.toml | 4 +- mm2src/mm2_metamask/src/eip_1193_provider.rs | 4 +- mm2src/mm2_metamask/src/lib.rs | 9 +- mm2src/mm2_metrics/src/lib.rs | 42 +- mm2src/mm2_metrics/src/mm_metrics.rs | 23 +- mm2src/mm2_metrics/src/recorder.rs | 8 +- mm2src/mm2_net/src/event_streaming/mod.rs | 6 +- mm2src/mm2_net/src/grpc_web.rs | 16 +- mm2src/mm2_net/src/ip_addr.rs | 20 + mm2src/mm2_net/src/lib.rs | 9 +- mm2src/mm2_net/src/native_http.rs | 28 +- mm2src/mm2_net/src/native_tls/acceptor.rs | 22 +- mm2src/mm2_net/src/native_tls/builder.rs | 8 +- mm2src/mm2_net/src/transport.rs | 16 +- mm2src/mm2_net/src/wasm/body_stream.rs | 27 +- mm2src/mm2_net/src/wasm/tonic_client.rs | 12 +- mm2src/mm2_net/src/wasm/wasm_ws.rs | 16 +- mm2src/mm2_number/src/big_int_str.rs | 16 +- mm2src/mm2_number/src/fraction.rs | 16 +- mm2src/mm2_number/src/mm_number.rs | 108 +++- mm2src/mm2_p2p/Cargo.toml | 4 +- .../mm2_p2p/src/application/network_event.rs | 8 +- mm2src/mm2_p2p/src/behaviours/atomicdex.rs | 61 +- mm2src/mm2_p2p/src/behaviours/mod.rs | 35 +- .../mm2_p2p/src/behaviours/peers_exchange.rs | 41 +- .../src/behaviours/request_response.rs | 16 +- mm2src/mm2_p2p/src/lib.rs | 56 +- mm2src/mm2_p2p/src/p2p_ctx.rs | 12 +- mm2src/mm2_p2p/src/relay_address.rs | 4 +- mm2src/mm2_p2p/src/swarm_runtime.rs | 4 +- mm2src/mm2_rpc/Cargo.toml | 2 +- mm2src/mm2_rpc/src/data/legacy.rs | 33 +- mm2src/mm2_rpc/src/data/legacy/activation.rs | 3 +- mm2src/mm2_rpc/src/lib.rs | 3 +- mm2src/mm2_rpc/src/mm_protocol.rs | 8 +- mm2src/mm2_state_machine/src/lib.rs | 6 +- mm2src/mm2_state_machine/src/state_machine.rs | 24 +- .../src/storable_state_machine.rs | 67 ++- mm2src/mm2_test_helpers/Cargo.toml | 4 +- mm2src/mm2_test_helpers/src/for_tests.rs | 3 +- mm2src/mm2_test_helpers/src/lib.rs | 2 - mm2src/proxy_signature/src/lib.rs | 4 +- mm2src/rpc_task/src/lib.rs | 18 +- mm2src/rpc_task/src/manager.rs | 57 +- mm2src/trading_api/src/one_inch_api/client.rs | 24 +- mm2src/trezor/src/client.rs | 4 +- mm2src/trezor/src/error.rs | 12 +- mm2src/trezor/src/eth/eth_command.rs | 11 +- mm2src/trezor/src/lib.rs | 3 +- mm2src/trezor/src/proto/mod.rs | 20 +- mm2src/trezor/src/response.rs | 24 +- mm2src/trezor/src/response_processor.rs | 4 +- mm2src/trezor/src/result_handler.rs | 8 +- mm2src/trezor/src/transport/mod.rs | 15 +- mm2src/trezor/src/transport/protocol.rs | 12 +- mm2src/trezor/src/transport/udp.rs | 26 +- mm2src/trezor/src/transport/usb.rs | 29 +- mm2src/trezor/src/transport/webusb.rs | 36 +- rust-toolchain.toml | 2 +- rustfmt.toml | 29 - 493 files changed, 10912 insertions(+), 4901 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index d59b360d40..b16c63ead9 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,8 +1,25 @@ [env] +# Enables unstable features for specific crates to take advantage of useful +# functionality not yet stabilized. Remove a crate from the list once all +# required features are stabilized. +# +# # Core crates (used in production) +# +# - mm2_state_machine: Depends on `negative_impls` and `auto_traits`. +# - mm2_err_handle: Depends on `negative_impls`, `auto_traits` and `allocator_api`. +# +# # Test crates (not leaked into the binary) +# +# - mocktopus: nightly only dependency. +# - mocktopus_macros: nightly only dependency. +# - docker_tests_main: Depends on `custom_test_frameworks` and `test`. +# - docker_tests_sia_unique: Depends on `custom_test_frameworks` and `test`. +RUSTC_BOOTSTRAP = "mm2_state_machine,mm2_err_handle,mocktopus,mocktopus_macros,docker_tests_main,docker_tests_sia_unique" + JEMALLOC_SYS_WITH_MALLOC_CONF = "background_thread:true,narenas:1,tcache:false,dirty_decay_ms:0,muzzy_decay_ms:0,metadata_thp:auto" [target.'cfg(all())'] -rustflags = [ "-Zshare-generics=y", '--cfg=curve25519_dalek_backend="fiat"' ] +rustflags = [ '--cfg=curve25519_dalek_backend="fiat"' ] # # Install lld using package manager # [target.x86_64-unknown-linux-gnu] diff --git a/.github/workflows/dev-build.yml b/.github/workflows/dev-build.yml index 5eccea1ea4..fc8627cbd7 100644 --- a/.github/workflows/dev-build.yml +++ b/.github/workflows/dev-build.yml @@ -29,8 +29,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 - name: Install build deps uses: ./.github/actions/deps-install @@ -92,8 +92,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 rustup target add x86_64-apple-darwin - name: Install build deps @@ -144,8 +144,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 rustup target add aarch64-apple-darwin - name: Install build deps @@ -196,8 +196,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 - name: Install build deps uses: ./.github/actions/deps-install @@ -247,8 +247,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 rustup target add x86_64-apple-darwin - name: Install build deps @@ -314,8 +314,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 rustup target add wasm32-unknown-unknown - name: Install wasm-pack @@ -365,8 +365,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 rustup target add aarch64-apple-ios - name: Install build deps @@ -427,8 +427,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 rustup target add aarch64-linux-android - name: Install build deps @@ -494,8 +494,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 rustup target add armv7-linux-androideabi - name: Install build deps diff --git a/.github/workflows/fmt-and-lint.yml b/.github/workflows/fmt-and-lint.yml index 8308def3fc..be81fc6889 100644 --- a/.github/workflows/fmt-and-lint.yml +++ b/.github/workflows/fmt-and-lint.yml @@ -18,8 +18,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal --component rustfmt,clippy - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal --component rustfmt,clippy + rustup default 1.85.1 - name: Install build deps uses: ./.github/actions/deps-install @@ -45,8 +45,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal --component clippy - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal --component clippy + rustup default 1.85.1 rustup target add wasm32-unknown-unknown - name: Install build deps diff --git a/.github/workflows/release-build.yml b/.github/workflows/release-build.yml index 04fc4ae26b..3a97f11f39 100644 --- a/.github/workflows/release-build.yml +++ b/.github/workflows/release-build.yml @@ -29,8 +29,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 - name: Install build deps uses: ./.github/actions/deps-install @@ -87,8 +87,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 - name: Install build deps uses: ./.github/actions/deps-install @@ -135,8 +135,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 rustup target add aarch64-apple-darwin - name: Install build deps @@ -184,8 +184,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 - name: Install build deps uses: ./.github/actions/deps-install @@ -232,8 +232,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 rustup target add x86_64-apple-darwin - name: Install build deps @@ -296,8 +296,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 rustup target add wasm32-unknown-unknown - name: Install wasm-pack @@ -344,8 +344,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 rustup target add aarch64-apple-ios - name: Install build deps @@ -403,8 +403,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 rustup target add aarch64-linux-android - name: Install build deps @@ -467,8 +467,8 @@ jobs: - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 rustup target add armv7-linux-androideabi - name: Install build deps diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a01960da73..f8658875ec 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,8 +25,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 - name: Install build deps uses: ./.github/actions/deps-install @@ -53,8 +53,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 - name: Install build deps uses: ./.github/actions/deps-install @@ -81,8 +81,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 - name: Install build deps uses: ./.github/actions/deps-install @@ -109,8 +109,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 - name: Install build deps uses: ./.github/actions/deps-install @@ -138,8 +138,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 - name: Install build deps uses: ./.github/actions/deps-install @@ -170,8 +170,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 - name: Install build deps uses: ./.github/actions/deps-install @@ -206,8 +206,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 - name: Install build deps uses: ./.github/actions/deps-install @@ -235,8 +235,8 @@ jobs: - uses: actions/checkout@v3 - name: Install toolchain run: | - rustup toolchain install nightly-2025-01-03 --no-self-update --profile=minimal - rustup default nightly-2025-01-03 + rustup toolchain install 1.85.1 --no-self-update --profile=minimal + rustup default 1.85.1 rustup target add wasm32-unknown-unknown - name: Install build deps diff --git a/Cargo.toml b/Cargo.toml index ec7af89702..ffa2f36e16 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,7 +106,7 @@ futures-timer = "3.0" futures-util = { version = "0.3", default-features = false, features = ["sink", "std"] } fnv = "1.0.6" group = "0.8.0" -gstuff = { version = "0.7", features = ["nightly"] } +gstuff = { version = "0.7" } hash256-std-hasher = "0.15.2" hash-db = "0.15.2" hex = "0.4.2" diff --git a/mm2src/coins/Cargo.toml b/mm2src/coins/Cargo.toml index 3e49769c7e..dc4b797973 100644 --- a/mm2src/coins/Cargo.toml +++ b/mm2src/coins/Cargo.toml @@ -25,7 +25,7 @@ doctest = false [dependencies] async-std = { workspace = true, features = ["unstable"] } -async-trait.workspace = true +async-trait.workspace = true base64.workspace = true bip32.workspace = true bitcoin_hashes.workspace = true @@ -56,7 +56,7 @@ futures-util.workspace = true futures-ticker.workspace = true futures = { workspace = true, features = ["compat", "async-await"] } group.workspace = true -gstuff.workspace = true +gstuff.workspace = true hex.workspace = true http.workspace = true itertools = { workspace = true, features = ["use_std"] } @@ -78,7 +78,7 @@ mm2_rpc = { path = "../mm2_rpc" } mm2_state_machine = { path = "../mm2_state_machine" } mocktopus = { workspace = true, optional = true } num-traits.workspace = true -parking_lot = { workspace = true, features = ["nightly"] } +parking_lot = { workspace = true } primitives = { path = "../mm2_bitcoin/primitives" } prost.workspace = true protobuf.workspace = true @@ -91,7 +91,7 @@ rmp-serde.workspace = true rpc = { path = "../mm2_bitcoin/rpc" } rpc_task = { path = "../rpc_task" } script = { path = "../mm2_bitcoin/script" } -secp256k1.workspace = true +secp256k1.workspace = true ser_error = { path = "../derives/ser_error" } ser_error_derive = { path = "../derives/ser_error_derive" } serde.workspace = true @@ -109,17 +109,17 @@ utxo_signer = { path = "utxo_signer" } tendermint-rpc.workspace = true tokio-tungstenite-wasm = { workspace = true, features = ["rustls-tls-native-roots"]} url.workspace = true -uuid.workspace = true +uuid.workspace = true # One of web3 dependencies is the old `tokio-uds 0.1.7` which fails cross-compiling to ARM. # We don't need the default web3 features at all since we added our own web3 transport using shared HYPER instance. web3 = { workspace = true, default-features = false } zbase32.workspace = true zcash_client_backend.workspace = true zcash_extras.workspace = true -zcash_primitives.workspace = true +zcash_primitives.workspace = true [target.'cfg(target_arch = "wasm32")'.dependencies] -blake2b_simd.workspace = true +blake2b_simd.workspace = true ff.workspace = true futures-util.workspace = true jubjub.workspace = true @@ -154,7 +154,7 @@ tokio.workspace = true tokio-rustls.workspace = true tonic = { workspace = true, features = ["codegen", "prost", "gzip", "tls", "tls-webpki-roots"] } webpki-roots.workspace = true -zcash_client_sqlite.workspace = true +zcash_client_sqlite.workspace = true zcash_proofs = { workspace = true, features = ["local-prover", "multicore"] } [target.'cfg(windows)'.dependencies] @@ -169,7 +169,7 @@ jubjub.workspace = true reqwest.workspace = true [target.'cfg(target_arch = "wasm32")'.dev-dependencies] -wagyu-zcash-parameters.workspace = true +wagyu-zcash-parameters.workspace = true [build-dependencies] prost-build.workspace = true diff --git a/mm2src/coins/coin_balance.rs b/mm2src/coins/coin_balance.rs index 5c5476f58a..cf389d7962 100644 --- a/mm2src/coins/coin_balance.rs +++ b/mm2src/coins/coin_balance.rs @@ -1,15 +1,19 @@ -use crate::hd_wallet::{DisplayAddress, HDAccountOps, HDAddressId, HDAddressOps, HDCoinAddress, HDCoinHDAccount, - HDPathAccountToAddressId, HDWalletCoinOps, HDWalletOps, HDXPubExtractor, - NewAccountCreationError, NewAddressDerivingError}; -use crate::{BalanceError, BalanceResult, CoinBalance, CoinBalanceMap, CoinWithDerivationMethod, DerivationMethod, - IguanaBalanceOps, MarketCoinOps}; +use crate::hd_wallet::{ + DisplayAddress, HDAccountOps, HDAddressId, HDAddressOps, HDCoinAddress, HDCoinHDAccount, HDPathAccountToAddressId, + HDWalletCoinOps, HDWalletOps, HDXPubExtractor, NewAccountCreationError, NewAddressDerivingError, +}; +use crate::{ + BalanceError, BalanceResult, CoinBalance, CoinBalanceMap, CoinWithDerivationMethod, DerivationMethod, + IguanaBalanceOps, MarketCoinOps, +}; use async_trait::async_trait; use common::log::{debug, info}; use crypto::{Bip44Chain, RpcDerivationPath}; use derive_more::Display; use mm2_err_handle::prelude::*; use mm2_number::BigDecimal; -#[cfg(test)] use mocktopus::macros::*; +#[cfg(test)] +use mocktopus::macros::*; use std::collections::{HashMap, HashSet}; use std::ops::Range; use std::{fmt, iter}; @@ -26,15 +30,21 @@ pub enum EnableCoinBalanceError { } impl From for EnableCoinBalanceError { - fn from(e: NewAddressDerivingError) -> Self { EnableCoinBalanceError::NewAddressDerivingError(e) } + fn from(e: NewAddressDerivingError) -> Self { + EnableCoinBalanceError::NewAddressDerivingError(e) + } } impl From for EnableCoinBalanceError { - fn from(e: NewAccountCreationError) -> Self { EnableCoinBalanceError::NewAccountCreationError(e) } + fn from(e: NewAccountCreationError) -> Self { + EnableCoinBalanceError::NewAccountCreationError(e) + } } impl From for EnableCoinBalanceError { - fn from(e: BalanceError) -> Self { EnableCoinBalanceError::BalanceError(e) } + fn from(e: BalanceError) -> Self { + EnableCoinBalanceError::BalanceError(e) + } } /// `BalanceObjectOps` should be implemented for a type that represents balance/s of a wallet. @@ -413,8 +423,10 @@ pub enum AddressBalanceStatus { pub mod common_impl { use super::*; - use crate::hd_wallet::{create_new_account, DisplayAddress, ExtractExtendedPubkey, HDAccountOps, - HDAccountStorageOps, HDAddressOps, HDCoinExtendedPubkey, HDWalletOps}; + use crate::hd_wallet::{ + create_new_account, DisplayAddress, ExtractExtendedPubkey, HDAccountOps, HDAccountStorageOps, HDAddressOps, + HDCoinExtendedPubkey, HDWalletOps, + }; pub(crate) async fn enable_hd_account( coin: &Coin, diff --git a/mm2src/coins/coin_errors.rs b/mm2src/coins/coin_errors.rs index c8601a7f6b..32879771d6 100644 --- a/mm2src/coins/coin_errors.rs +++ b/mm2src/coins/coin_errors.rs @@ -57,7 +57,9 @@ pub enum ValidatePaymentError { } impl From for ValidatePaymentError { - fn from(err: SPVError) -> Self { Self::SPVError(err) } + fn from(err: SPVError) -> Self { + Self::SPVError(err) + } } impl From for ValidatePaymentError { diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 47722ccab2..7741515439 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -24,39 +24,51 @@ use self::wallet_connect::{send_transaction_with_walletconnect, WcEthTxParams}; use super::eth::Action::{Call, Create}; use super::watcher_common::{validate_watcher_reward, REWARD_GAS_AMOUNT}; use super::*; -use crate::coin_balance::{EnableCoinBalanceError, EnabledCoinBalanceParams, HDAccountBalance, HDAddressBalance, - HDWalletBalance, HDWalletBalanceOps}; +use crate::coin_balance::{ + EnableCoinBalanceError, EnabledCoinBalanceParams, HDAccountBalance, HDAddressBalance, HDWalletBalance, + HDWalletBalanceOps, +}; use crate::eth::eth_rpc::ETH_RPC_REQUEST_TIMEOUT; use crate::eth::web3_transport::websocket_transport::{WebsocketTransport, WebsocketTransportNode}; -use crate::hd_wallet::{DisplayAddress, HDAccountOps, HDCoinAddress, HDCoinWithdrawOps, HDConfirmAddress, - HDPathAccountToAddressId, HDWalletCoinOps, HDXPubExtractor}; +use crate::hd_wallet::{ + DisplayAddress, HDAccountOps, HDCoinAddress, HDCoinWithdrawOps, HDConfirmAddress, HDPathAccountToAddressId, + HDWalletCoinOps, HDXPubExtractor, +}; use crate::lp_price::get_base_price_in_rel; use crate::nft::nft_errors::ParseContractTypeError; -use crate::nft::nft_structs::{ContractType, ConvertChain, NftInfo, TransactionNftDetails, WithdrawErc1155, - WithdrawErc721}; +use crate::nft::nft_structs::{ + ContractType, ConvertChain, NftInfo, TransactionNftDetails, WithdrawErc1155, WithdrawErc721, +}; use crate::nft::WithdrawNftResult; use crate::rpc_command::account_balance::{AccountBalanceParams, AccountBalanceRpcOps, HDAccountBalanceResponse}; -use crate::rpc_command::get_new_address::{GetNewAddressParams, GetNewAddressResponse, GetNewAddressRpcError, - GetNewAddressRpcOps}; +use crate::rpc_command::get_new_address::{ + GetNewAddressParams, GetNewAddressResponse, GetNewAddressRpcError, GetNewAddressRpcOps, +}; use crate::rpc_command::hd_account_balance_rpc_error::HDAccountBalanceRpcError; use crate::rpc_command::init_account_balance::{InitAccountBalanceParams, InitAccountBalanceRpcOps}; -use crate::rpc_command::init_create_account::{CreateAccountRpcError, CreateAccountState, CreateNewAccountParams, - InitCreateAccountRpcOps}; -use crate::rpc_command::init_scan_for_new_addresses::{InitScanAddressesRpcOps, ScanAddressesParams, - ScanAddressesResponse}; +use crate::rpc_command::init_create_account::{ + CreateAccountRpcError, CreateAccountState, CreateNewAccountParams, InitCreateAccountRpcOps, +}; +use crate::rpc_command::init_scan_for_new_addresses::{ + InitScanAddressesRpcOps, ScanAddressesParams, ScanAddressesResponse, +}; use crate::rpc_command::init_withdraw::{InitWithdrawCoin, WithdrawTaskHandleShared}; -use crate::rpc_command::{account_balance, get_new_address, init_account_balance, init_create_account, - init_scan_for_new_addresses}; -use crate::{coin_balance, scan_for_new_addresses_impl, BalanceResult, CoinWithDerivationMethod, DerivationMethod, - DexFee, Eip1559Ops, MakerNftSwapOpsV2, ParseCoinAssocTypes, ParseNftAssocTypes, PayForGasParams, - PrivKeyPolicy, RpcCommonOps, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs, ToBytes, - ValidateNftMakerPaymentArgs, ValidateWatcherSpendInput, WatcherSpendType}; +use crate::rpc_command::{ + account_balance, get_new_address, init_account_balance, init_create_account, init_scan_for_new_addresses, +}; +use crate::{ + coin_balance, scan_for_new_addresses_impl, BalanceResult, CoinWithDerivationMethod, DerivationMethod, DexFee, + Eip1559Ops, MakerNftSwapOpsV2, ParseCoinAssocTypes, ParseNftAssocTypes, PayForGasParams, PrivKeyPolicy, + RpcCommonOps, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs, ToBytes, ValidateNftMakerPaymentArgs, + ValidateWatcherSpendInput, WatcherSpendType, +}; use async_trait::async_trait; use bitcrypto::{dhash160, keccak256, ripemd160, sha256}; use common::custom_futures::repeatable::{Ready, Retry, RetryOnError}; use common::custom_futures::timeout::FutureTimerExt; -use common::executor::{abortable_queue::AbortableQueue, AbortSettings, AbortableSystem, AbortedError, SpawnAbortable, - Timer}; +use common::executor::{ + abortable_queue::AbortableQueue, AbortSettings, AbortableSystem, AbortedError, SpawnAbortable, Timer, +}; use common::log::{debug, error, info, warn}; use common::number_type_casting::SafeTypeCastingNumbers; use common::wait_until_sec; @@ -69,9 +81,10 @@ use enum_derives::EnumFromStringify; use compatible_time::Instant; use ethabi::{Contract, Function, Token}; use ethcore_transaction::tx_builders::TxBuilderError; -use ethcore_transaction::{Action, TransactionWrapper, TransactionWrapperBuilder as UnSignedEthTxBuilder, - UnverifiedEip1559Transaction, UnverifiedEip2930Transaction, UnverifiedLegacyTransaction, - UnverifiedTransactionWrapper}; +use ethcore_transaction::{ + Action, TransactionWrapper, TransactionWrapperBuilder as UnSignedEthTxBuilder, UnverifiedEip1559Transaction, + UnverifiedEip2930Transaction, UnverifiedLegacyTransaction, UnverifiedTransactionWrapper, +}; pub use ethcore_transaction::{SignedTransaction as SignedEthTx, TxType}; use ethereum_types::{Address, H160, H256, U256}; use ethkey::{public_to_address, sign, verify_address, KeyPair, Public, Signature}; @@ -99,8 +112,10 @@ use std::str::FromStr; use std::sync::atomic::{AtomicU64, Ordering as AtomicOrdering}; use std::sync::{Arc, Mutex}; use std::time::Duration; -use web3::types::{Action as TraceAction, BlockId, BlockNumber, Bytes, CallRequest, FilterBuilder, Log, Trace, - TraceFilterBuilder, Transaction as Web3Transaction, TransactionId, U64}; +use web3::types::{ + Action as TraceAction, BlockId, BlockNumber, Bytes, CallRequest, FilterBuilder, Log, Trace, TraceFilterBuilder, + Transaction as Web3Transaction, TransactionId, U64, +}; use web3::{self, Web3}; cfg_wasm32! { @@ -110,30 +125,32 @@ cfg_wasm32! { use web3::types::TransactionRequest; } -use super::{coin_conf, lp_coinfind_or_err, AsyncMutex, BalanceError, BalanceFut, CheckIfMyPaymentSentArgs, - CoinBalance, CoinProtocol, CoinTransportMetrics, CoinsContext, ConfirmPaymentInput, EthValidateFeeArgs, - FeeApproxStage, FoundSwapTxSpend, HistorySyncState, IguanaPrivKey, MarketCoinOps, MmCoin, MmCoinEnum, - MyAddressError, MyWalletAddress, NegotiateSwapContractAddrErr, NumConversError, NumConversResult, - PaymentInstructionArgs, PaymentInstructions, PaymentInstructionsErr, PrivKeyBuildPolicy, - PrivKeyPolicyNotAllowed, RawTransactionError, RawTransactionFut, RawTransactionRequest, RawTransactionRes, - RawTransactionResult, RefundPaymentArgs, RewardTarget, RpcClientType, RpcTransportEventHandler, - RpcTransportEventHandlerShared, SearchForSwapTxSpendInput, SendMakerPaymentSpendPreimageInput, - SendPaymentArgs, SignEthTransactionParams, SignRawTransactionEnum, SignRawTransactionRequest, - SignatureError, SignatureResult, SpendPaymentArgs, SwapOps, SwapTxFeePolicy, TradeFee, TradePreimageError, - TradePreimageFut, TradePreimageResult, TradePreimageValue, Transaction, TransactionDetails, - TransactionEnum, TransactionErr, TransactionFut, TransactionType, TxMarshalingErr, - UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, ValidateInstructionsErr, - ValidateOtherPubKeyErr, ValidatePaymentError, ValidatePaymentFut, ValidatePaymentInput, VerificationError, - VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, WatcherReward, WatcherRewardError, - WatcherSearchForSwapTxSpendInput, WatcherValidatePaymentInput, WatcherValidateTakerFeeInput, WeakSpawner, - WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest, WithdrawResult, EARLY_CONFIRMATION_ERR_LOG, - INVALID_CONTRACT_ADDRESS_ERR_LOG, INVALID_PAYMENT_STATE_ERR_LOG, INVALID_RECEIVER_ERR_LOG, - INVALID_SENDER_ERR_LOG, INVALID_SWAP_ID_ERR_LOG}; +use super::{ + coin_conf, lp_coinfind_or_err, AsyncMutex, BalanceError, BalanceFut, CheckIfMyPaymentSentArgs, CoinBalance, + CoinProtocol, CoinTransportMetrics, CoinsContext, ConfirmPaymentInput, EthValidateFeeArgs, FeeApproxStage, + FoundSwapTxSpend, HistorySyncState, IguanaPrivKey, MarketCoinOps, MmCoin, MmCoinEnum, MyAddressError, + MyWalletAddress, NegotiateSwapContractAddrErr, NumConversError, NumConversResult, PaymentInstructionArgs, + PaymentInstructions, PaymentInstructionsErr, PrivKeyBuildPolicy, PrivKeyPolicyNotAllowed, RawTransactionError, + RawTransactionFut, RawTransactionRequest, RawTransactionRes, RawTransactionResult, RefundPaymentArgs, RewardTarget, + RpcClientType, RpcTransportEventHandler, RpcTransportEventHandlerShared, SearchForSwapTxSpendInput, + SendMakerPaymentSpendPreimageInput, SendPaymentArgs, SignEthTransactionParams, SignRawTransactionEnum, + SignRawTransactionRequest, SignatureError, SignatureResult, SpendPaymentArgs, SwapOps, SwapTxFeePolicy, TradeFee, + TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, Transaction, TransactionDetails, + TransactionEnum, TransactionErr, TransactionFut, TransactionType, TxMarshalingErr, UnexpectedDerivationMethod, + ValidateAddressResult, ValidateFeeArgs, ValidateInstructionsErr, ValidateOtherPubKeyErr, ValidatePaymentError, + ValidatePaymentFut, ValidatePaymentInput, VerificationError, VerificationResult, WaitForHTLCTxSpendArgs, + WatcherOps, WatcherReward, WatcherRewardError, WatcherSearchForSwapTxSpendInput, WatcherValidatePaymentInput, + WatcherValidateTakerFeeInput, WeakSpawner, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest, + WithdrawResult, EARLY_CONFIRMATION_ERR_LOG, INVALID_CONTRACT_ADDRESS_ERR_LOG, INVALID_PAYMENT_STATE_ERR_LOG, + INVALID_RECEIVER_ERR_LOG, INVALID_SENDER_ERR_LOG, INVALID_SWAP_ID_ERR_LOG, +}; #[cfg(test)] pub(crate) use eth_utils::display_u256_with_decimal_point; -pub use eth_utils::{addr_from_pubkey_str, addr_from_raw_pubkey, mm_number_from_u256, mm_number_to_u256, - u256_to_big_decimal, wei_from_big_decimal, wei_from_coins_mm_number, wei_from_gwei_decimal, - wei_to_coins_mm_number, wei_to_eth_decimal, wei_to_gwei_decimal}; +pub use eth_utils::{ + addr_from_pubkey_str, addr_from_raw_pubkey, mm_number_from_u256, mm_number_to_u256, u256_to_big_decimal, + wei_from_big_decimal, wei_from_coins_mm_number, wei_from_gwei_decimal, wei_to_coins_mm_number, wei_to_eth_decimal, + wei_to_gwei_decimal, +}; use eth_utils::{get_function_input_data, get_function_name}; pub use rlp; @@ -143,9 +160,12 @@ cfg_native! { pub mod eth_balance_events; mod eth_rpc; -#[cfg(test)] mod eth_tests; -#[cfg(target_arch = "wasm32")] mod eth_wasm_tests; -#[cfg(any(test, target_arch = "wasm32"))] mod for_tests; +#[cfg(test)] +mod eth_tests; +#[cfg(target_arch = "wasm32")] +mod eth_wasm_tests; +#[cfg(any(test, target_arch = "wasm32"))] +mod for_tests; pub(crate) mod nft_swap_v2; pub mod wallet_connect; mod web3_transport; @@ -154,15 +174,18 @@ use web3_transport::{http_transport::HttpTransportNode, Web3Transport}; pub mod eth_hd_wallet; use eth_hd_wallet::EthHDWallet; -#[path = "eth/v2_activation.rs"] pub mod v2_activation; +#[path = "eth/v2_activation.rs"] +pub mod v2_activation; use v2_activation::{build_address_and_priv_key_policy, EthActivationV2Error}; mod eth_withdraw; use eth_withdraw::{EthWithdraw, InitEthWithdraw, StandardEthWithdraw}; pub mod fee_estimation; -use fee_estimation::eip1559::{block_native::BlocknativeGasApiCaller, infura::InfuraGasApiCaller, - simple::FeePerGasSimpleEstimator, FeePerGasEstimated, GasApiConfig, GasApiProvider}; +use fee_estimation::eip1559::{ + block_native::BlocknativeGasApiCaller, infura::InfuraGasApiCaller, simple::FeePerGasSimpleEstimator, + FeePerGasEstimated, GasApiConfig, GasApiProvider, +}; pub mod erc20; use erc20::get_token_decimals; @@ -509,11 +532,15 @@ trait ExtractGasLimit: Default + for<'de> Deserialize<'de> { } impl ExtractGasLimit for EthGasLimit { - fn key() -> &'static str { "gas_limit" } + fn key() -> &'static str { + "gas_limit" + } } impl ExtractGasLimit for EthGasLimitV2 { - fn key() -> &'static str { "gas_limit_v2" } + fn key() -> &'static str { + "gas_limit_v2" + } } /// Max transaction type according to EIP-2718 @@ -650,7 +677,9 @@ impl From for Web3RpcError { } impl From for Web3RpcError { - fn from(e: UnexpectedDerivationMethod) -> Self { Web3RpcError::Internal(e.to_string()) } + fn from(e: UnexpectedDerivationMethod) -> Self { + Web3RpcError::Internal(e.to_string()) + } } #[cfg(target_arch = "wasm32")] @@ -664,7 +693,9 @@ impl From for Web3RpcError { } impl From for Web3RpcError { - fn from(e: NumConversError) -> Self { Web3RpcError::NumConversError(e.to_string()) } + fn from(e: NumConversError) -> Self { + Web3RpcError::NumConversError(e.to_string()) + } } impl From for WithdrawError { @@ -676,7 +707,9 @@ impl From for WithdrawError { } impl From for WithdrawError { - fn from(e: web3::Error) -> Self { WithdrawError::Transport(e.to_string()) } + fn from(e: web3::Error) -> Self { + WithdrawError::Transport(e.to_string()) + } } impl From for WithdrawError { @@ -693,11 +726,15 @@ impl From for WithdrawError { } impl From for WithdrawError { - fn from(e: ethcore_transaction::Error) -> Self { WithdrawError::SigningError(e.to_string()) } + fn from(e: ethcore_transaction::Error) -> Self { + WithdrawError::SigningError(e.to_string()) + } } impl From for TradePreimageError { - fn from(e: web3::Error) -> Self { TradePreimageError::Transport(e.to_string()) } + fn from(e: web3::Error) -> Self { + TradePreimageError::Transport(e.to_string()) + } } impl From for TradePreimageError { @@ -730,7 +767,9 @@ impl From for BalanceError { } impl From for BalanceError { - fn from(e: web3::Error) -> Self { BalanceError::from(Web3RpcError::from(e)) } + fn from(e: web3::Error) -> Self { + BalanceError::from(Web3RpcError::from(e)) + } } impl From for BalanceError { @@ -749,11 +788,15 @@ impl From for BalanceError { } impl From for TransactionErr { - fn from(e: TxBuilderError) -> Self { TransactionErr::Plain(e.to_string()) } + fn from(e: TxBuilderError) -> Self { + TransactionErr::Plain(e.to_string()) + } } impl From for TransactionErr { - fn from(e: ethcore_transaction::Error) -> Self { TransactionErr::Plain(e.to_string()) } + fn from(e: ethcore_transaction::Error) -> Self { + TransactionErr::Plain(e.to_string()) + } } #[derive(Debug, Deserialize, Serialize)] @@ -909,7 +952,9 @@ pub struct EthCoinImpl { pub struct Web3Instance(Web3); impl AsRef> for Web3Instance { - fn as_ref(&self) -> &Web3 { &self.0 } + fn as_ref(&self) -> &Web3 { + &self.0 + } } /// Information about a token that follows the ERC20 protocol on an EVM-based network. @@ -1088,7 +1133,9 @@ impl EthCoinImpl { } #[inline(always)] - pub fn chain_id(&self) -> Option { self.chain_spec.chain_id() } + pub fn chain_id(&self) -> Option { + self.chain_spec.chain_id() + } } async fn get_raw_transaction_impl(coin: EthCoin, req: RawTransactionRequest) -> RawTransactionResult { @@ -1350,7 +1397,9 @@ pub async fn withdraw_erc721(ctx: MmArc, withdraw_type: WithdrawErc721) -> Withd pub struct EthCoin(Arc); impl Deref for EthCoin { type Target = EthCoinImpl; - fn deref(&self) -> &EthCoinImpl { &self.0 } + fn deref(&self) -> &EthCoinImpl { + &self.0 + } } #[async_trait] @@ -1420,13 +1469,16 @@ impl SwapOps for EthCoin { ))) }, }; - validate_fee_impl(self.clone(), EthValidateFeeArgs { - fee_tx_hash: &tx.tx_hash(), - expected_sender: validate_fee_args.expected_sender, - amount: &validate_fee_args.dex_fee.fee_amount().into(), - min_block_number: validate_fee_args.min_block_number, - uuid: validate_fee_args.uuid, - }) + validate_fee_impl( + self.clone(), + EthValidateFeeArgs { + fee_tx_hash: &tx.tx_hash(), + expected_sender: validate_fee_args.expected_sender, + amount: &validate_fee_args.dex_fee.fee_amount().into(), + min_block_number: validate_fee_args.min_block_number, + uuid: validate_fee_args.uuid, + }, + ) .compat() .await } @@ -1733,13 +1785,16 @@ impl WatcherOps for EthCoin { } fn watcher_validate_taker_fee(&self, validate_fee_args: WatcherValidateTakerFeeInput) -> ValidatePaymentFut<()> { - validate_fee_impl(self.clone(), EthValidateFeeArgs { - fee_tx_hash: &H256::from_slice(validate_fee_args.taker_fee_hash.as_slice()), - expected_sender: &validate_fee_args.sender_pubkey, - amount: &BigDecimal::from(0), - min_block_number: validate_fee_args.min_block_number, - uuid: &[], - }) + validate_fee_impl( + self.clone(), + EthValidateFeeArgs { + fee_tx_hash: &H256::from_slice(validate_fee_args.taker_fee_hash.as_slice()), + expected_sender: &validate_fee_args.sender_pubkey, + amount: &BigDecimal::from(0), + min_block_number: validate_fee_args.min_block_number, + uuid: &[], + }, + ) // TODO: Add validations specific for watchers // 1.Validate if taker fee is old @@ -2388,7 +2443,9 @@ impl WatcherOps for EthCoin { #[async_trait] #[cfg_attr(test, mockable)] impl MarketCoinOps for EthCoin { - fn ticker(&self) -> &str { &self.ticker[..] } + fn ticker(&self) -> &str { + &self.ticker[..] + } fn my_address(&self) -> MmResult { match self.derivation_method() { @@ -2728,7 +2785,9 @@ impl MarketCoinOps for EthCoin { } #[inline] - fn min_tx_amount(&self) -> BigDecimal { BigDecimal::from(0) } + fn min_tx_amount(&self) -> BigDecimal { + BigDecimal::from(0) + } #[inline] fn min_trading_vol(&self) -> MmNumber { @@ -2737,9 +2796,13 @@ impl MarketCoinOps for EthCoin { } #[inline] - fn should_burn_dex_fee(&self) -> bool { false } + fn should_burn_dex_fee(&self) -> bool { + false + } - fn is_trezor(&self) -> bool { self.priv_key_policy.is_trezor() } + fn is_trezor(&self) -> bool { + self.priv_key_policy.is_trezor() + } } pub fn signed_eth_tx_from_bytes(bytes: &[u8]) -> Result { @@ -2977,18 +3040,21 @@ async fn sign_raw_eth_tx(coin: &EthCoin, args: &SignEthTransactionParams) -> Raw info!(target: "sign-and-send", "WalletConnect signing and sending tx…"); let (signed_tx, _) = coin - .wc_sign_tx(&wc, WcEthTxParams { - my_address, - gas_price: pay_for_gas_option.get_gas_price(), - action, - value, - gas: args.gas_limit, - data: &data, - nonce, - chain_id, - max_fee_per_gas, - max_priority_fee_per_gas, - }) + .wc_sign_tx( + &wc, + WcEthTxParams { + my_address, + gas_price: pay_for_gas_option.get_gas_price(), + action, + value, + gas: args.gas_limit, + data: &data, + nonce, + chain_id, + max_fee_per_gas, + max_priority_fee_per_gas, + }, + ) .await .mm_err(|err| RawTransactionError::TransactionError(err.to_string()))?; @@ -5825,9 +5891,13 @@ impl EthTxFeeDetails { #[async_trait] impl MmCoin for EthCoin { - fn is_asset_chain(&self) -> bool { false } + fn is_asset_chain(&self) -> bool { + false + } - fn spawner(&self) -> WeakSpawner { self.abortable_system.weak_spawner() } + fn spawner(&self) -> WeakSpawner { + self.abortable_system.weak_spawner() + } fn get_raw_transaction(&self, req: RawTransactionRequest) -> RawTransactionFut { Box::new(get_raw_transaction_impl(self.clone(), req).boxed().compat()) @@ -5853,7 +5923,9 @@ impl MmCoin for EthCoin { Box::new(Box::pin(withdraw_impl(self.clone(), req)).compat()) } - fn decimals(&self) -> u8 { self.decimals } + fn decimals(&self) -> u8 { + self.decimals + } fn convert_to_address(&self, from: &str, to_address_format: Json) -> Result { let to_address_format: EthAddressFormat = @@ -5898,7 +5970,9 @@ impl MmCoin for EthCoin { } } - fn history_sync_status(&self) -> HistorySyncState { self.history_sync_state.lock().unwrap().clone() } + fn history_sync_status(&self) -> HistorySyncState { + self.history_sync_state.lock().unwrap().clone() + } fn get_trade_fee(&self) -> Box + Send> { let coin = self.clone(); @@ -6071,9 +6145,13 @@ impl MmCoin for EthCoin { }) } - fn required_confirmations(&self) -> u64 { self.required_confirmations.load(AtomicOrdering::Relaxed) } + fn required_confirmations(&self) -> u64 { + self.required_confirmations.load(AtomicOrdering::Relaxed) + } - fn requires_notarization(&self) -> bool { false } + fn requires_notarization(&self) -> bool { + false + } fn set_required_confirmations(&self, confirmations: u64) { self.required_confirmations @@ -6092,9 +6170,13 @@ impl MmCoin for EthCoin { self.fallback_swap_contract.map(|a| BytesJson::from(a.0.as_ref())) } - fn mature_confirmations(&self) -> Option { None } + fn mature_confirmations(&self) -> Option { + None + } - fn coin_protocol_info(&self, _amount_to_receive: Option) -> Vec { Vec::new() } + fn coin_protocol_info(&self, _amount_to_receive: Option) -> Vec { + Vec::new() + } fn is_coin_protocol_supported( &self, @@ -6106,7 +6188,9 @@ impl MmCoin for EthCoin { true } - fn on_disabled(&self) -> Result<(), AbortedError> { AbortableSystem::abort_all(&self.abortable_system) } + fn on_disabled(&self) -> Result<(), AbortedError> { + AbortableSystem::abort_all(&self.abortable_system) + } fn on_token_deactivated(&self, ticker: &str) { if let Ok(tokens) = self.erc20_tokens_infos.lock().as_deref_mut() { @@ -6120,11 +6204,15 @@ pub trait TryToAddress { } impl TryToAddress for BytesJson { - fn try_to_address(&self) -> Result { self.0.try_to_address() } + fn try_to_address(&self) -> Result { + self.0.try_to_address() + } } impl TryToAddress for [u8] { - fn try_to_address(&self) -> Result { (&self).try_to_address() } + fn try_to_address(&self) -> Result { + (&self).try_to_address() + } } impl TryToAddress for &[u8] { @@ -6256,9 +6344,13 @@ fn validate_fee_impl(coin: EthCoin, validate_fee_args: EthValidateFeeArgs<'_>) - } impl Transaction for SignedEthTx { - fn tx_hex(&self) -> Vec { rlp::encode(self).to_vec() } + fn tx_hex(&self) -> Vec { + rlp::encode(self).to_vec() + } - fn tx_hash_as_bytes(&self) -> BytesJson { self.tx_hash().as_bytes().into() } + fn tx_hash_as_bytes(&self) -> BytesJson { + self.tx_hash().as_bytes().into() + } } fn signed_tx_from_web3_tx(transaction: Web3Transaction) -> Result { @@ -6465,7 +6557,9 @@ async fn get_max_eth_tx_type_conf(ctx: &MmArc, conf: &Json, coin_type: &EthCoinT } #[inline] -fn new_nonce_lock() -> HashMap>> { HashMap::new() } +fn new_nonce_lock() -> HashMap>> { + HashMap::new() +} /// Activate eth coin or erc20 token from coin config and private key build policy pub async fn eth_coin_from_conf_and_request( @@ -6713,11 +6807,15 @@ pub fn checksum_address(addr: &str) -> String { /// `eth_addr_to_hex` converts Address to hex format. /// Note: the result will be in lowercase. -fn eth_addr_to_hex(address: &Address) -> String { format!("{:#x}", address) } +fn eth_addr_to_hex(address: &Address) -> String { + format!("{:#x}", address) +} /// Checks that input is valid mixed-case checksum form address /// The input must be 0x prefixed hex string -fn is_valid_checksum_addr(addr: &str) -> bool { addr == checksum_address(addr) } +fn is_valid_checksum_addr(addr: &str) -> bool { + addr == checksum_address(addr) +} fn increase_by_percent_one_gwei(num: U256, percent: u64) -> U256 { let one_gwei = U256::from(10u64.pow(9)); @@ -6763,15 +6861,21 @@ pub enum GetEthAddressError { } impl From for GetEthAddressError { - fn from(e: UnexpectedDerivationMethod) -> Self { GetEthAddressError::UnexpectedDerivationMethod(e) } + fn from(e: UnexpectedDerivationMethod) -> Self { + GetEthAddressError::UnexpectedDerivationMethod(e) + } } impl From for GetEthAddressError { - fn from(e: EthActivationV2Error) -> Self { GetEthAddressError::EthActivationV2Error(e) } + fn from(e: EthActivationV2Error) -> Self { + GetEthAddressError::EthActivationV2Error(e) + } } impl From for GetEthAddressError { - fn from(e: CryptoCtxError) -> Self { GetEthAddressError::Internal(e.to_string()) } + fn from(e: CryptoCtxError) -> Self { + GetEthAddressError::Internal(e.to_string()) + } } // Todo: `get_eth_address` should be removed since NFT is now part of the coins ctx. @@ -6865,7 +6969,9 @@ pub enum EthGasDetailsErr { } impl From for EthGasDetailsErr { - fn from(e: web3::Error) -> Self { EthGasDetailsErr::from(Web3RpcError::from(e)) } + fn from(e: web3::Error) -> Self { + EthGasDetailsErr::from(Web3RpcError::from(e)) + } } impl From for EthGasDetailsErr { @@ -7078,7 +7184,9 @@ fn call_request_with_pay_for_gas_option(call_request: CallRequest, pay_for_gas_o } impl ToBytes for Signature { - fn to_bytes(&self) -> Vec { self.to_vec() } + fn to_bytes(&self) -> Vec { + self.to_vec() + } } impl ToBytes for SignedEthTx { @@ -7112,7 +7220,9 @@ pub enum EthNftAssocTypesError { } impl From for EthNftAssocTypesError { - fn from(e: ParseContractTypeError) -> Self { EthNftAssocTypesError::ParseContractTypeError(e) } + fn from(e: ParseContractTypeError) -> Self { + EthNftAssocTypesError::ParseContractTypeError(e) + } } #[async_trait] @@ -7155,7 +7265,9 @@ impl ParseCoinAssocTypes for EthCoin { SignedEthTx::new(unverified).map_to_mm(|e| EthAssocTypesError::TxParseError(e.to_string())) } - fn parse_preimage(&self, tx: &[u8]) -> Result { self.parse_tx(tx) } + fn parse_preimage(&self, tx: &[u8]) -> Result { + self.parse_tx(tx) + } fn parse_signature(&self, sig: &[u8]) -> Result { if sig.len() != 65 { @@ -7171,23 +7283,33 @@ impl ParseCoinAssocTypes for EthCoin { } impl ToBytes for Address { - fn to_bytes(&self) -> Vec { self.0.to_vec() } + fn to_bytes(&self) -> Vec { + self.0.to_vec() + } } impl AddrToString for Address { - fn addr_to_string(&self) -> String { eth_addr_to_hex(self) } + fn addr_to_string(&self) -> String { + eth_addr_to_hex(self) + } } impl ToBytes for BigUint { - fn to_bytes(&self) -> Vec { self.to_bytes_be() } + fn to_bytes(&self) -> Vec { + self.to_bytes_be() + } } impl ToBytes for ContractType { - fn to_bytes(&self) -> Vec { self.to_string().into_bytes() } + fn to_bytes(&self) -> Vec { + self.to_string().into_bytes() + } } impl ToBytes for Public { - fn to_bytes(&self) -> Vec { self.0.to_vec() } + fn to_bytes(&self) -> Vec { + self.0.to_vec() + } } impl ParseNftAssocTypes for EthCoin { @@ -7256,11 +7378,15 @@ impl MakerNftSwapOpsV2 for EthCoin { impl CoinWithPrivKeyPolicy for EthCoin { type KeyPair = KeyPair; - fn priv_key_policy(&self) -> &PrivKeyPolicy { &self.priv_key_policy } + fn priv_key_policy(&self) -> &PrivKeyPolicy { + &self.priv_key_policy + } } impl CoinWithDerivationMethod for EthCoin { - fn derivation_method(&self) -> &DerivationMethod, Self::HDWallet> { &self.derivation_method } + fn derivation_method(&self) -> &DerivationMethod, Self::HDWallet> { + &self.derivation_method + } } #[async_trait] @@ -7374,7 +7500,9 @@ fn extract_gas_limit_from_conf(coin_conf: &Json) -> Result SwapTxFeePolicy { self.swap_txfee_policy.lock().unwrap().clone() } + fn get_swap_transaction_fee_policy(&self) -> SwapTxFeePolicy { + self.swap_txfee_policy.lock().unwrap().clone() + } fn set_swap_transaction_fee_policy(&self, swap_txfee_policy: SwapTxFeePolicy) { *self.swap_txfee_policy.lock().unwrap() = swap_txfee_policy @@ -7455,7 +7583,9 @@ impl TakerCoinSwapOpsV2 for EthCoin { self.refund_taker_payment_with_timelock_impl(args).await } - fn skip_taker_payment_spend_preimage(&self) -> bool { true } + fn skip_taker_payment_spend_preimage(&self) -> bool { + true + } /// Eth skips taker_payment_spend_preimage, as it doesnt need it async fn gen_taker_payment_spend_preimage( diff --git a/mm2src/coins/eth/eth_balance_events.rs b/mm2src/coins/eth/eth_balance_events.rs index c47721be06..816150fe83 100644 --- a/mm2src/coins/eth/eth_balance_events.rs +++ b/mm2src/coins/eth/eth_balance_events.rs @@ -1,7 +1,9 @@ use super::EthCoin; -use crate::{eth::{u256_to_big_decimal, Erc20TokenDetails}, - hd_wallet::AddrToString, - BalanceError, CoinWithDerivationMethod}; +use crate::{ + eth::{u256_to_big_decimal, Erc20TokenDetails}, + hd_wallet::AddrToString, + BalanceError, CoinWithDerivationMethod, +}; use common::{executor::Timer, log, Future01CompatExt}; use mm2_err_handle::prelude::*; use mm2_event_stream::{Broadcaster, Event, EventStreamer, NoDataIn, StreamHandlerInput, StreamerId}; @@ -73,14 +75,17 @@ async fn get_all_balance_results_concurrently(coin: &EthCoin, addresses: HashSet // type and mapping the platform coin and the entire token list (which can grow at any time), we map // the platform coin to Erc20TokenDetails so that we can use the token list right away without // additional mapping. - tokens.insert(coin.ticker.clone(), Erc20TokenDetails { - // This is a dummy value, since there is no token address for the platform coin. - // In the fetch_balance function, we check if the token_ticker is equal to this - // coin's ticker to avoid using token_address to fetch the balance - // and to use address_balance instead. - token_address: Address::default(), - decimals: coin.decimals, - }); + tokens.insert( + coin.ticker.clone(), + Erc20TokenDetails { + // This is a dummy value, since there is no token address for the platform coin. + // In the fetch_balance function, we check if the token_ticker is equal to this + // coin's ticker to avoid using token_address to fetch the balance + // and to use address_balance instead. + token_address: Address::default(), + decimals: coin.decimals, + }, + ); drop_mutability!(tokens); let mut all_jobs = FuturesUnordered::new(); diff --git a/mm2src/coins/eth/eth_hd_wallet.rs b/mm2src/coins/eth/eth_hd_wallet.rs index be5eb688b0..46bea6d52b 100644 --- a/mm2src/coins/eth/eth_hd_wallet.rs +++ b/mm2src/coins/eth/eth_hd_wallet.rs @@ -1,7 +1,8 @@ use super::*; use crate::coin_balance::HDAddressBalanceScanner; -use crate::hd_wallet::{ExtractExtendedPubkey, HDAccount, HDAddress, HDExtractPubkeyError, HDWallet, HDXPubExtractor, - TrezorCoinError}; +use crate::hd_wallet::{ + ExtractExtendedPubkey, HDAccount, HDAddress, HDExtractPubkeyError, HDWallet, HDXPubExtractor, TrezorCoinError, +}; use async_trait::async_trait; use bip32::DerivationPath; use crypto::Secp256k1ExtendedPublicKey; @@ -14,7 +15,9 @@ pub type EthHDWallet = HDWallet; impl DisplayAddress for Address { /// converts `Address` to mixed-case checksum form. #[inline] - fn display_address(&self) -> String { checksum_address(&self.addr_to_string()) } + fn display_address(&self) -> String { + checksum_address(&self.addr_to_string()) + } } #[async_trait] @@ -95,7 +98,9 @@ impl HDWalletBalanceOps for EthCoin { type HDAddressScanner = Self; type BalanceObject = CoinBalanceMap; - async fn produce_hd_address_scanner(&self) -> BalanceResult { Ok(self.clone()) } + async fn produce_hd_address_scanner(&self) -> BalanceResult { + Ok(self.clone()) + } async fn enable_hd_wallet( &self, diff --git a/mm2src/coins/eth/eth_rpc.rs b/mm2src/coins/eth/eth_rpc.rs index 946e142439..098f952a93 100644 --- a/mm2src/coins/eth/eth_rpc.rs +++ b/mm2src/coins/eth/eth_rpc.rs @@ -7,9 +7,10 @@ use super::{web3_transport::Web3Transport, EthCoin}; use common::{custom_futures::timeout::FutureTimerExt, log::debug}; use compatible_time::Duration; use serde_json::Value; -use web3::types::{Address, Block, BlockId, BlockNumber, Bytes, CallRequest, FeeHistory, Filter, Log, Proof, SyncState, - Trace, TraceFilter, Transaction, TransactionId, TransactionReceipt, TransactionRequest, Work, H256, - H520, H64, U256, U64}; +use web3::types::{ + Address, Block, BlockId, BlockNumber, Bytes, CallRequest, FeeHistory, Filter, Log, Proof, SyncState, Trace, + TraceFilter, Transaction, TransactionId, TransactionReceipt, TransactionRequest, Work, H256, H520, H64, U256, U64, +}; use web3::{helpers, Transport}; pub(crate) const ETH_RPC_REQUEST_TIMEOUT: Duration = Duration::from_secs(10); diff --git a/mm2src/coins/eth/eth_swap_v2/eth_maker_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2/eth_maker_swap_v2.rs index ec4f69b31a..d91d9a4bee 100644 --- a/mm2src/coins/eth/eth_swap_v2/eth_maker_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2/eth_maker_swap_v2.rs @@ -1,9 +1,15 @@ -use super::{validate_amount, validate_from_to_addresses, EthPaymentType, PaymentMethod, PrepareTxDataError, ZERO_VALUE}; +use super::{ + validate_amount, validate_from_to_addresses, EthPaymentType, PaymentMethod, PrepareTxDataError, ZERO_VALUE, +}; use crate::coin_errors::{ValidatePaymentError, ValidatePaymentResult}; -use crate::eth::{decode_contract_call, get_function_input_data, wei_from_big_decimal, EthCoin, EthCoinType, - SignedEthTx, MAKER_SWAP_V2}; -use crate::{ParseCoinAssocTypes, RefundMakerPaymentSecretArgs, RefundMakerPaymentTimelockArgs, SendMakerPaymentArgs, - SpendMakerPaymentArgs, SwapTxTypeWithSecretHash, TransactionErr, ValidateMakerPaymentArgs}; +use crate::eth::{ + decode_contract_call, get_function_input_data, wei_from_big_decimal, EthCoin, EthCoinType, SignedEthTx, + MAKER_SWAP_V2, +}; +use crate::{ + ParseCoinAssocTypes, RefundMakerPaymentSecretArgs, RefundMakerPaymentTimelockArgs, SendMakerPaymentArgs, + SpendMakerPaymentArgs, SwapTxTypeWithSecretHash, TransactionErr, ValidateMakerPaymentArgs, +}; use ethabi::{Function, Token}; use ethcore_transaction::Action; use ethereum_types::{Address, Public, U256}; diff --git a/mm2src/coins/eth/eth_swap_v2/eth_taker_swap_v2.rs b/mm2src/coins/eth/eth_swap_v2/eth_taker_swap_v2.rs index a89ba16f57..c32418286d 100644 --- a/mm2src/coins/eth/eth_swap_v2/eth_taker_swap_v2.rs +++ b/mm2src/coins/eth/eth_swap_v2/eth_taker_swap_v2.rs @@ -1,11 +1,16 @@ -use super::{check_decoded_length, extract_id_from_tx_data, validate_amount, validate_from_to_addresses, - EthPaymentType, PaymentMethod, PrepareTxDataError, SpendTxSearchParams, ZERO_VALUE}; -use crate::eth::{decode_contract_call, get_function_input_data, wei_from_big_decimal, EthCoin, EthCoinType, - ParseCoinAssocTypes, RefundFundingSecretArgs, RefundTakerPaymentArgs, SendTakerFundingArgs, - SignedEthTx, SwapTxTypeWithSecretHash, TakerPaymentStateV2, TransactionErr, ValidateSwapV2TxError, - ValidateSwapV2TxResult, ValidateTakerFundingArgs, TAKER_SWAP_V2}; -use crate::{FindPaymentSpendError, FundingTxSpend, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, - SearchForFundingSpendErr}; +use super::{ + check_decoded_length, extract_id_from_tx_data, validate_amount, validate_from_to_addresses, EthPaymentType, + PaymentMethod, PrepareTxDataError, SpendTxSearchParams, ZERO_VALUE, +}; +use crate::eth::{ + decode_contract_call, get_function_input_data, wei_from_big_decimal, EthCoin, EthCoinType, ParseCoinAssocTypes, + RefundFundingSecretArgs, RefundTakerPaymentArgs, SendTakerFundingArgs, SignedEthTx, SwapTxTypeWithSecretHash, + TakerPaymentStateV2, TransactionErr, ValidateSwapV2TxError, ValidateSwapV2TxResult, ValidateTakerFundingArgs, + TAKER_SWAP_V2, +}; +use crate::{ + FindPaymentSpendError, FundingTxSpend, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, SearchForFundingSpendErr, +}; use derive_more::Display; use enum_derives::EnumFromStringify; use ethabi::{Contract, Function, Token}; diff --git a/mm2src/coins/eth/eth_tests.rs b/mm2src/coins/eth/eth_tests.rs index b844b85863..6ff0a06bd6 100644 --- a/mm2src/coins/eth/eth_tests.rs +++ b/mm2src/coins/eth/eth_tests.rs @@ -9,8 +9,9 @@ cfg_native!( use common::{now_sec, block_on_f01}; use ethkey::{Generator, Random}; - use mm2_test_helpers::for_tests::{ETH_MAINNET_CHAIN_ID, ETH_MAINNET_NODES, ETH_SEPOLIA_CHAIN_ID, ETH_SEPOLIA_NODES, - ETH_SEPOLIA_TOKEN_CONTRACT}; + use mm2_test_helpers::for_tests::{ + ETH_MAINNET_CHAIN_ID, ETH_MAINNET_NODES, ETH_SEPOLIA_CHAIN_ID, ETH_SEPOLIA_NODES, ETH_SEPOLIA_TOKEN_CONTRACT, + }; use mocktopus::mocking::*; /// The gas price for the tests diff --git a/mm2src/coins/eth/eth_utils.rs b/mm2src/coins/eth/eth_utils.rs index 87841070f6..4b5abe0d2d 100644 --- a/mm2src/coins/eth/eth_utils.rs +++ b/mm2src/coins/eth/eth_utils.rs @@ -80,12 +80,16 @@ pub fn wei_from_gwei_decimal(bigdec: &BigDecimal) -> NumConversResult { /// Converts a U256 wei value to an gwei value as a BigDecimal #[inline(always)] -pub fn wei_to_gwei_decimal(wei: U256) -> NumConversResult { u256_to_big_decimal(wei, ETH_GWEI_DECIMALS) } +pub fn wei_to_gwei_decimal(wei: U256) -> NumConversResult { + u256_to_big_decimal(wei, ETH_GWEI_DECIMALS) +} /// Converts a U256 wei value to an ETH value as a BigDecimal /// TODO: use wei_to_eth_decimal instead of u256_to_big_decimal(gas_cost_wei, ETH_DECIMALS) #[inline(always)] -pub fn wei_to_eth_decimal(wei: U256) -> NumConversResult { u256_to_big_decimal(wei, ETH_DECIMALS) } +pub fn wei_to_eth_decimal(wei: U256) -> NumConversResult { + u256_to_big_decimal(wei, ETH_DECIMALS) +} #[inline] pub fn mm_number_to_u256(mm_number: &MmNumber) -> Result { @@ -93,7 +97,9 @@ pub fn mm_number_to_u256(mm_number: &MmNumber) -> Result { } #[inline] -pub fn mm_number_from_u256(u256: U256) -> MmNumber { MmNumber::from(u256.to_string().as_str()) } +pub fn mm_number_from_u256(u256: U256) -> MmNumber { + MmNumber::from(u256.to_string().as_str()) +} #[inline] pub fn wei_from_coins_mm_number(mm_number: &MmNumber, decimals: u8) -> NumConversResult { diff --git a/mm2src/coins/eth/eth_wasm_tests.rs b/mm2src/coins/eth/eth_wasm_tests.rs index 367e88321d..e50266cad6 100644 --- a/mm2src/coins/eth/eth_wasm_tests.rs +++ b/mm2src/coins/eth/eth_wasm_tests.rs @@ -47,7 +47,9 @@ async fn init_eth_coin_helper() -> Result<(MmArc, MmCoinEnum), String> { } #[wasm_bindgen_test] -async fn test_init_eth_coin() { let (_ctx, _coin) = init_eth_coin_helper().await.unwrap(); } +async fn test_init_eth_coin() { + let (_ctx, _coin) = init_eth_coin_helper().await.unwrap(); +} #[wasm_bindgen_test] async fn wasm_test_sign_eth_tx() { diff --git a/mm2src/coins/eth/eth_withdraw.rs b/mm2src/coins/eth/eth_withdraw.rs index 2b260b4fed..539b1d77a0 100644 --- a/mm2src/coins/eth/eth_withdraw.rs +++ b/mm2src/coins/eth/eth_withdraw.rs @@ -1,13 +1,19 @@ -use super::{checksum_address, u256_to_big_decimal, wei_from_big_decimal, ChainSpec, EthCoinType, EthDerivationMethod, - EthPrivKeyPolicy, Public, WithdrawError, WithdrawRequest, WithdrawResult, ERC20_CONTRACT, H160, H256}; +use super::{ + checksum_address, u256_to_big_decimal, wei_from_big_decimal, ChainSpec, EthCoinType, EthDerivationMethod, + EthPrivKeyPolicy, Public, WithdrawError, WithdrawRequest, WithdrawResult, ERC20_CONTRACT, H160, H256, +}; use crate::eth::wallet_connect::WcEthTxParams; -use crate::eth::{calc_total_fee, get_eth_gas_details_from_withdraw_fee, tx_builder_with_pay_for_gas_option, - tx_type_from_pay_for_gas_option, Action, Address, EthTxFeeDetails, KeyPair, PayForGasOption, - SignedEthTx, TransactionWrapper, UnSignedEthTxBuilder}; +use crate::eth::{ + calc_total_fee, get_eth_gas_details_from_withdraw_fee, tx_builder_with_pay_for_gas_option, + tx_type_from_pay_for_gas_option, Action, Address, EthTxFeeDetails, KeyPair, PayForGasOption, SignedEthTx, + TransactionWrapper, UnSignedEthTxBuilder, +}; use crate::hd_wallet::{HDAddressSelector, HDCoinWithdrawOps, HDWalletOps, WithdrawSenderAddress}; use crate::rpc_command::init_withdraw::{WithdrawInProgressStatus, WithdrawTaskHandleShared}; -use crate::{BytesJson, CoinWithDerivationMethod, EthCoin, GetWithdrawSenderAddress, PrivKeyPolicy, TransactionData, - TransactionDetails}; +use crate::{ + BytesJson, CoinWithDerivationMethod, EthCoin, GetWithdrawSenderAddress, PrivKeyPolicy, TransactionData, + TransactionDetails, +}; use async_trait::async_trait; use bip32::DerivationPath; use common::custom_futures::timeout::FutureTimerExt; @@ -413,9 +419,13 @@ pub struct InitEthWithdraw { #[async_trait] impl EthWithdraw for InitEthWithdraw { - fn coin(&self) -> &EthCoin { &self.coin } + fn coin(&self) -> &EthCoin { + &self.coin + } - fn request(&self) -> &WithdrawRequest { &self.req } + fn request(&self) -> &WithdrawRequest { + &self.req + } fn on_generating_transaction(&self) -> Result<(), MmError> { self.task_handle @@ -491,13 +501,21 @@ pub struct StandardEthWithdraw { #[async_trait] impl EthWithdraw for StandardEthWithdraw { - fn coin(&self) -> &EthCoin { &self.coin } + fn coin(&self) -> &EthCoin { + &self.coin + } - fn request(&self) -> &WithdrawRequest { &self.req } + fn request(&self) -> &WithdrawRequest { + &self.req + } - fn on_generating_transaction(&self) -> Result<(), MmError> { Ok(()) } + fn on_generating_transaction(&self) -> Result<(), MmError> { + Ok(()) + } - fn on_finishing(&self) -> Result<(), MmError> { Ok(()) } + fn on_finishing(&self) -> Result<(), MmError> { + Ok(()) + } async fn sign_tx_with_trezor( &self, diff --git a/mm2src/coins/eth/fee_estimation/eip1559/mod.rs b/mm2src/coins/eth/fee_estimation/eip1559/mod.rs index e9a63faf5b..4d2d7a6731 100644 --- a/mm2src/coins/eth/fee_estimation/eip1559/mod.rs +++ b/mm2src/coins/eth/fee_estimation/eip1559/mod.rs @@ -31,7 +31,9 @@ impl std::fmt::Display for EstimationSource { } impl Default for EstimationSource { - fn default() -> Self { Self::Empty } + fn default() -> Self { + Self::Empty + } } enum PriorityLevelId { diff --git a/mm2src/coins/eth/fee_estimation/eip1559/simple.rs b/mm2src/coins/eth/fee_estimation/eip1559/simple.rs index fe42b03b8d..2752ae691c 100644 --- a/mm2src/coins/eth/fee_estimation/eip1559/simple.rs +++ b/mm2src/coins/eth/fee_estimation/eip1559/simple.rs @@ -35,10 +35,14 @@ impl FeePerGasSimpleEstimator { const ADJUST_MAX_PRIORITY_FEE: [f64; FEE_PER_GAS_LEVELS] = [1.0, 1.0, 1.0]; /// block depth for eth_feeHistory - pub fn history_depth() -> u64 { Self::FEE_PRIORITY_DEPTH } + pub fn history_depth() -> u64 { + Self::FEE_PRIORITY_DEPTH + } /// percentiles for priority rewards obtained with eth_feeHistory - pub fn history_percentiles() -> &'static [f64] { &Self::HISTORY_PERCENTILES } + pub fn history_percentiles() -> &'static [f64] { + &Self::HISTORY_PERCENTILES + } /// percentile for vector fn percentile_of(v: &[U256], percent: f64) -> U256 { @@ -69,7 +73,9 @@ impl FeePerGasSimpleEstimator { } } - fn predict_base_fee(base_fees: &[U256]) -> U256 { Self::percentile_of(base_fees, Self::BASE_FEE_PERCENTILE) } + fn predict_base_fee(base_fees: &[U256]) -> U256 { + Self::percentile_of(base_fees, Self::BASE_FEE_PERCENTILE) + } fn priority_fee_for_level( level: PriorityLevelId, diff --git a/mm2src/coins/eth/fee_estimation/eth_fee_events.rs b/mm2src/coins/eth/fee_estimation/eth_fee_events.rs index 1c79e7da40..66f15dbcbd 100644 --- a/mm2src/coins/eth/fee_estimation/eth_fee_events.rs +++ b/mm2src/coins/eth/fee_estimation/eth_fee_events.rs @@ -45,7 +45,9 @@ pub struct EthFeeEventStreamer { impl EthFeeEventStreamer { #[inline(always)] - pub fn new(config: EthFeeStreamingConfig, coin: EthCoin) -> Self { Self { config, coin } } + pub fn new(config: EthFeeStreamingConfig, coin: EthCoin) -> Self { + Self { config, coin } + } } #[async_trait] diff --git a/mm2src/coins/eth/for_tests.rs b/mm2src/coins/eth/for_tests.rs index 2a830993f5..f9beef199e 100644 --- a/mm2src/coins/eth/for_tests.rs +++ b/mm2src/coins/eth/for_tests.rs @@ -1,4 +1,5 @@ -#[cfg(not(target_arch = "wasm32"))] use super::*; +#[cfg(not(target_arch = "wasm32"))] +use super::*; use mm2_core::mm_ctx::{MmArc, MmCtxBuilder}; #[cfg(not(target_arch = "wasm32"))] use mm2_test_helpers::for_tests::{eth_sepolia_conf, ETH_SEPOLIA_SWAP_CONTRACT}; diff --git a/mm2src/coins/eth/nft_swap_v2/mod.rs b/mm2src/coins/eth/nft_swap_v2/mod.rs index d0e4ca8163..92958eda12 100644 --- a/mm2src/coins/eth/nft_swap_v2/mod.rs +++ b/mm2src/coins/eth/nft_swap_v2/mod.rs @@ -11,10 +11,13 @@ use web3::types::TransactionId; use super::ContractType; use crate::coin_errors::{ValidatePaymentError, ValidatePaymentResult}; use crate::eth::eth_swap_v2::{validate_from_to_addresses, PaymentMethod, PrepareTxDataError, ZERO_VALUE}; -use crate::eth::{decode_contract_call, EthCoin, EthCoinType, SignedEthTx, ERC1155_CONTRACT, ERC721_CONTRACT, - NFT_MAKER_SWAP_V2}; -use crate::{ParseCoinAssocTypes, RefundNftMakerPaymentArgs, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs, - TransactionErr, ValidateNftMakerPaymentArgs}; +use crate::eth::{ + decode_contract_call, EthCoin, EthCoinType, SignedEthTx, ERC1155_CONTRACT, ERC721_CONTRACT, NFT_MAKER_SWAP_V2, +}; +use crate::{ + ParseCoinAssocTypes, RefundNftMakerPaymentArgs, SendNftMakerPaymentArgs, SpendNftMakerPaymentArgs, TransactionErr, + ValidateNftMakerPaymentArgs, +}; pub(crate) mod errors; use errors::{Erc721FunctionError, HtlcParamsError}; @@ -498,7 +501,9 @@ fn htlc_params() -> &'static [ethabi::ParamType] { /// function to check if BigDecimal is a positive integer #[inline(always)] -fn is_positive_integer(amount: &BigDecimal) -> bool { amount == &amount.with_scale(0) && amount.is_positive() } +fn is_positive_integer(amount: &BigDecimal) -> bool { + amount == &amount.with_scale(0) && amount.is_positive() +} fn validate_payment_args<'a>( taker_secret_hash: &'a [u8], diff --git a/mm2src/coins/eth/tron/address.rs b/mm2src/coins/eth/tron/address.rs index 0d4a45e07c..9f7732457a 100644 --- a/mm2src/coins/eth/tron/address.rs +++ b/mm2src/coins/eth/tron/address.rs @@ -73,27 +73,39 @@ impl Address { } /// Show as base58 string (canonical user format). - pub fn to_base58(&self) -> String { bs58::encode(self.inner).with_check().into_string() } + pub fn to_base58(&self) -> String { + bs58::encode(self.inner).with_check().into_string() + } /// Show as hex string, lowercase (canonical hex format). - pub fn to_hex(&self) -> String { hex::encode(self.inner) } + pub fn to_hex(&self) -> String { + hex::encode(self.inner) + } /// Return the 21 bytes (0x41 + 20). - pub fn as_bytes(&self) -> &[u8] { &self.inner } + pub fn as_bytes(&self) -> &[u8] { + &self.inner + } } impl TryFrom<[u8; ADDRESS_BYTES_LEN]> for Address { type Error = String; - fn try_from(bytes: [u8; ADDRESS_BYTES_LEN]) -> Result { Self::from_bytes(bytes) } + fn try_from(bytes: [u8; ADDRESS_BYTES_LEN]) -> Result { + Self::from_bytes(bytes) + } } impl AsRef<[u8]> for Address { - fn as_ref(&self) -> &[u8] { &self.inner } + fn as_ref(&self) -> &[u8] { + &self.inner + } } impl fmt::Display for Address { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.to_base58()) } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.to_base58()) + } } impl fmt::Debug for Address { diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 6bb4683036..70c2689a16 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -1,12 +1,15 @@ use super::*; use crate::eth::erc20::{get_enabled_erc20_by_platform_and_contract, get_token_decimals}; use crate::eth::web3_transport::http_transport::HttpTransport; -use crate::hd_wallet::{load_hd_accounts_from_storage, HDAccountsMutex, HDPathAccountToAddressId, HDWalletCoinStorage, - HDWalletStorageError, DEFAULT_GAP_LIMIT}; +use crate::hd_wallet::{ + load_hd_accounts_from_storage, HDAccountsMutex, HDPathAccountToAddressId, HDWalletCoinStorage, + HDWalletStorageError, DEFAULT_GAP_LIMIT, +}; use crate::nft::get_nfts_for_activation; use crate::nft::nft_errors::{GetNftInfoError, ParseChainTypeError}; use crate::nft::nft_structs::Chain; -#[cfg(target_arch = "wasm32")] use crate::EthMetamaskPolicy; +#[cfg(target_arch = "wasm32")] +use crate::EthMetamaskPolicy; use common::executor::AbortedError; use compatible_time::Instant; @@ -81,19 +84,27 @@ pub enum EthActivationV2Error { } impl From for EthActivationV2Error { - fn from(err: MyAddressError) -> Self { Self::InternalError(err.to_string()) } + fn from(err: MyAddressError) -> Self { + Self::InternalError(err.to_string()) + } } impl From for EthActivationV2Error { - fn from(e: AbortedError) -> Self { EthActivationV2Error::InternalError(e.to_string()) } + fn from(e: AbortedError) -> Self { + EthActivationV2Error::InternalError(e.to_string()) + } } impl From for EthActivationV2Error { - fn from(e: CryptoCtxError) -> Self { EthActivationV2Error::InternalError(e.to_string()) } + fn from(e: CryptoCtxError) -> Self { + EthActivationV2Error::InternalError(e.to_string()) + } } impl From for EthActivationV2Error { - fn from(e: UnexpectedDerivationMethod) -> Self { EthActivationV2Error::InternalError(e.to_string()) } + fn from(e: UnexpectedDerivationMethod) -> Self { + EthActivationV2Error::InternalError(e.to_string()) + } } impl From for EthActivationV2Error { @@ -115,19 +126,27 @@ impl From for EthActivationV2Error { } impl From for EthActivationV2Error { - fn from(e: HDWalletStorageError) -> Self { EthActivationV2Error::HDWalletStorageError(e.to_string()) } + fn from(e: HDWalletStorageError) -> Self { + EthActivationV2Error::HDWalletStorageError(e.to_string()) + } } impl From for EthActivationV2Error { - fn from(e: HwError) -> Self { EthActivationV2Error::InternalError(e.to_string()) } + fn from(e: HwError) -> Self { + EthActivationV2Error::InternalError(e.to_string()) + } } impl From for EthActivationV2Error { - fn from(e: Bip32Error) -> Self { EthActivationV2Error::InternalError(e.to_string()) } + fn from(e: Bip32Error) -> Self { + EthActivationV2Error::InternalError(e.to_string()) + } } impl From for EthActivationV2Error { - fn from(e: TrezorError) -> Self { EthActivationV2Error::InternalError(e.to_string()) } + fn from(e: TrezorError) -> Self { + EthActivationV2Error::InternalError(e.to_string()) + } } impl From for EthActivationV2Error { @@ -141,15 +160,21 @@ impl From for EthActivationV2Error { #[cfg(target_arch = "wasm32")] impl From for EthActivationV2Error { - fn from(e: MetamaskError) -> Self { from_metamask_error(e) } + fn from(e: MetamaskError) -> Self { + from_metamask_error(e) + } } impl From for EthActivationV2Error { - fn from(e: ParseChainTypeError) -> Self { EthActivationV2Error::InternalError(e.to_string()) } + fn from(e: ParseChainTypeError) -> Self { + EthActivationV2Error::InternalError(e.to_string()) + } } impl From for EthActivationV2Error { - fn from(e: String) -> Self { EthActivationV2Error::InternalError(e) } + fn from(e: String) -> Self { + EthActivationV2Error::InternalError(e) + } } impl From for EthActivationV2Error { @@ -181,7 +206,9 @@ pub enum EthPrivKeyActivationPolicy { } impl EthPrivKeyActivationPolicy { - pub fn is_hw_policy(&self) -> bool { matches!(self, EthPrivKeyActivationPolicy::Trezor) } + pub fn is_hw_policy(&self) -> bool { + matches!(self, EthPrivKeyActivationPolicy::Trezor) + } } #[derive(Clone, Debug, Deserialize, Serialize, Default)] @@ -236,15 +263,21 @@ pub enum EthTokenActivationError { } impl From for EthTokenActivationError { - fn from(e: AbortedError) -> Self { EthTokenActivationError::InternalError(e.to_string()) } + fn from(e: AbortedError) -> Self { + EthTokenActivationError::InternalError(e.to_string()) + } } impl From for EthTokenActivationError { - fn from(err: MyAddressError) -> Self { Self::InternalError(err.to_string()) } + fn from(err: MyAddressError) -> Self { + Self::InternalError(err.to_string()) + } } impl From for EthTokenActivationError { - fn from(e: UnexpectedDerivationMethod) -> Self { EthTokenActivationError::UnexpectedDerivationMethod(e) } + fn from(e: UnexpectedDerivationMethod) -> Self { + EthTokenActivationError::UnexpectedDerivationMethod(e) + } } impl From for EthTokenActivationError { @@ -276,15 +309,21 @@ impl From for EthTokenActivationError { } impl From for EthTokenActivationError { - fn from(e: ParseChainTypeError) -> Self { EthTokenActivationError::InternalError(e.to_string()) } + fn from(e: ParseChainTypeError) -> Self { + EthTokenActivationError::InternalError(e.to_string()) + } } impl From for EthTokenActivationError { - fn from(e: String) -> Self { EthTokenActivationError::InternalError(e) } + fn from(e: String) -> Self { + EthTokenActivationError::InternalError(e) + } } impl From for EthTokenActivationError { - fn from(e: PrivKeyPolicyNotAllowed) -> Self { EthTokenActivationError::PrivKeyPolicyNotAllowed(e) } + fn from(e: PrivKeyPolicyNotAllowed) -> Self { + EthTokenActivationError::PrivKeyPolicyNotAllowed(e) + } } impl From for EthTokenActivationError { @@ -306,11 +345,15 @@ pub enum GenerateSignedMessageError { } impl From for GenerateSignedMessageError { - fn from(e: PrivKeyPolicyNotAllowed) -> Self { GenerateSignedMessageError::PrivKeyPolicyNotAllowed(e) } + fn from(e: PrivKeyPolicyNotAllowed) -> Self { + GenerateSignedMessageError::PrivKeyPolicyNotAllowed(e) + } } impl From for GenerateSignedMessageError { - fn from(e: SignatureError) -> Self { GenerateSignedMessageError::InternalError(e.to_string()) } + fn from(e: SignatureError) -> Self { + GenerateSignedMessageError::InternalError(e.to_string()) + } } /// Represents the parameters required for activating either an ERC-20 token or an NFT on the Ethereum platform. diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 30c5747269..2ce06b1275 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -42,7 +42,9 @@ pub enum EthWalletConnectError { } impl From for EthWalletConnectError { - fn from(value: WalletConnectError) -> Self { Self::WalletConnectError(value) } + fn from(value: WalletConnectError) -> Self { + Self::WalletConnectError(value) + } } /// Eth Params required for constructing WalletConnect transaction. diff --git a/mm2src/coins/eth/web3_transport/http_transport.rs b/mm2src/coins/eth/web3_transport/http_transport.rs index 378e384df2..cf8b882e99 100644 --- a/mm2src/coins/eth/web3_transport/http_transport.rs +++ b/mm2src/coins/eth/web3_transport/http_transport.rs @@ -85,10 +85,14 @@ impl Transport for HttpTransport { } #[cfg(not(target_arch = "wasm32"))] - fn send(&self, _id: RequestId, request: Call) -> Self::Out { Box::pin(send_request(request, self.clone())) } + fn send(&self, _id: RequestId, request: Call) -> Self::Out { + Box::pin(send_request(request, self.clone())) + } #[cfg(target_arch = "wasm32")] - fn send(&self, _id: RequestId, request: Call) -> Self::Out { Box::pin(send_request(request, self.clone())) } + fn send(&self, _id: RequestId, request: Call) -> Self::Out { + Box::pin(send_request(request, self.clone())) + } } #[cfg(not(target_arch = "wasm32"))] diff --git a/mm2src/coins/eth/web3_transport/metamask_transport.rs b/mm2src/coins/eth/web3_transport/metamask_transport.rs index 45f8bca74d..b900f1a03e 100644 --- a/mm2src/coins/eth/web3_transport/metamask_transport.rs +++ b/mm2src/coins/eth/web3_transport/metamask_transport.rs @@ -61,7 +61,9 @@ impl Transport for MetamaskTransport { } impl fmt::Debug for MetamaskTransport { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "MetamaskTransport") } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "MetamaskTransport") + } } impl MetamaskTransport { diff --git a/mm2src/coins/eth/web3_transport/mod.rs b/mm2src/coins/eth/web3_transport/mod.rs index 2d685b1bb5..7f6dbce04d 100644 --- a/mm2src/coins/eth/web3_transport/mod.rs +++ b/mm2src/coins/eth/web3_transport/mod.rs @@ -1,7 +1,8 @@ use ethereum_types::U256; use futures::future::BoxFuture; use jsonrpc_core::Call; -#[cfg(target_arch = "wasm32")] use mm2_metamask::MetamaskResult; +#[cfg(target_arch = "wasm32")] +use mm2_metamask::MetamaskResult; use serde_json::Value as Json; use serde_json::Value; use std::sync::atomic::Ordering; @@ -10,7 +11,8 @@ use web3::{Error, RequestId, Transport}; use crate::RpcTransportEventHandlerShared; pub(crate) mod http_transport; -#[cfg(target_arch = "wasm32")] pub(crate) mod metamask_transport; +#[cfg(target_arch = "wasm32")] +pub(crate) mod metamask_transport; pub(crate) mod websocket_transport; pub(crate) type Web3SendOut = BoxFuture<'static, Result>; @@ -97,16 +99,22 @@ impl Transport for Web3Transport { } impl From for Web3Transport { - fn from(http: http_transport::HttpTransport) -> Self { Web3Transport::Http(http) } + fn from(http: http_transport::HttpTransport) -> Self { + Web3Transport::Http(http) + } } impl From for Web3Transport { - fn from(websocket: websocket_transport::WebsocketTransport) -> Self { Web3Transport::Websocket(websocket) } + fn from(websocket: websocket_transport::WebsocketTransport) -> Self { + Web3Transport::Websocket(websocket) + } } #[cfg(target_arch = "wasm32")] impl From for Web3Transport { - fn from(metamask: metamask_transport::MetamaskTransport) -> Self { Web3Transport::Metamask(metamask) } + fn from(metamask: metamask_transport::MetamaskTransport) -> Self { + Web3Transport::Metamask(metamask) + } } #[derive(Debug, Deserialize)] diff --git a/mm2src/coins/eth/web3_transport/websocket_transport.rs b/mm2src/coins/eth/web3_transport/websocket_transport.rs index 11f7d69a10..0dd270eaa0 100644 --- a/mm2src/coins/eth/web3_transport/websocket_transport.rs +++ b/mm2src/coins/eth/web3_transport/websocket_transport.rs @@ -22,8 +22,10 @@ use jsonrpc_core::Call; use mm2_p2p::Keypair; use proxy_signature::{ProxySign, RawMessage}; use std::sync::atomic::AtomicBool; -use std::sync::{atomic::{AtomicUsize, Ordering}, - Arc}; +use std::sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, +}; use timed_map::TimedMap; use tokio_tungstenite_wasm::WebSocketStream; use web3::error::{Error, TransportError}; diff --git a/mm2src/coins/hd_wallet/coin_ops.rs b/mm2src/coins/hd_wallet/coin_ops.rs index a28fea0672..af9b8e890c 100644 --- a/mm2src/coins/hd_wallet/coin_ops.rs +++ b/mm2src/coins/hd_wallet/coin_ops.rs @@ -1,13 +1,17 @@ -use super::{inner_impl, AccountUpdatingError, AddressDerivingError, DisplayAddress, ExtendedPublicKeyOps, - HDAccountOps, HDCoinExtendedPubkey, HDCoinHDAccount, HDCoinHDAddress, HDConfirmAddress, HDWalletOps, - NewAddressDeriveConfirmError, NewAddressDerivingError}; +use super::{ + inner_impl, AccountUpdatingError, AddressDerivingError, DisplayAddress, ExtendedPublicKeyOps, HDAccountOps, + HDCoinExtendedPubkey, HDCoinHDAccount, HDCoinHDAddress, HDConfirmAddress, HDWalletOps, + NewAddressDeriveConfirmError, NewAddressDerivingError, +}; use crate::hd_wallet::{errors::SettingEnabledAddressError, HDAddressOps, HDWalletStorageOps, TrezorCoinError}; use async_trait::async_trait; use bip32::{ChildNumber, DerivationPath}; use crypto::Bip44Chain; use itertools::Itertools; -use mm2_err_handle::{mm_error::{MmError, MmResult}, - prelude::MmResultExt}; +use mm2_err_handle::{ + mm_error::{MmError, MmResult}, + prelude::MmResultExt, +}; use std::collections::HashMap; type AddressDerivingResult = MmResult; diff --git a/mm2src/coins/hd_wallet/confirm_address.rs b/mm2src/coins/hd_wallet/confirm_address.rs index 0bbfcd7cde..664713f0a2 100644 --- a/mm2src/coins/hd_wallet/confirm_address.rs +++ b/mm2src/coins/hd_wallet/confirm_address.rs @@ -28,7 +28,9 @@ pub enum HDConfirmAddressError { } impl From for HDConfirmAddressError { - fn from(e: TrezorError) -> Self { HDConfirmAddressError::HardwareWalletError(HwError::from(e)) } + fn from(e: TrezorError) -> Self { + HDConfirmAddressError::HardwareWalletError(HwError::from(e)) + } } impl From> for HDConfirmAddressError { diff --git a/mm2src/coins/hd_wallet/errors.rs b/mm2src/coins/hd_wallet/errors.rs index e67ce0867e..814ab48b23 100644 --- a/mm2src/coins/hd_wallet/errors.rs +++ b/mm2src/coins/hd_wallet/errors.rs @@ -1,7 +1,9 @@ use super::{HDConfirmAddressError, HDWalletStorageError}; use bip32::Error as Bip32Error; use crypto::trezor::{TrezorError, TrezorProcessingError}; -use crypto::{Bip32DerPathError, Bip44Chain, CryptoCtxError, HwError, HwProcessingError, StandardHDPathError, XpubError}; +use crypto::{ + Bip32DerPathError, Bip44Chain, CryptoCtxError, HwError, HwProcessingError, StandardHDPathError, XpubError, +}; use derive_more::Display; use rpc_task::RpcTaskError; @@ -18,11 +20,15 @@ pub enum AddressDerivingError { } impl From for AddressDerivingError { - fn from(e: InvalidBip44ChainError) -> Self { AddressDerivingError::InvalidBip44Chain { chain: e.chain } } + fn from(e: InvalidBip44ChainError) -> Self { + AddressDerivingError::InvalidBip44Chain { chain: e.chain } + } } impl From for AddressDerivingError { - fn from(e: Bip32Error) -> Self { AddressDerivingError::Bip32Error(e.to_string()) } + fn from(e: Bip32Error) -> Self { + AddressDerivingError::Bip32Error(e.to_string()) + } } #[derive(Display)] @@ -40,7 +46,9 @@ pub enum NewAddressDerivingError { } impl From for NewAddressDerivingError { - fn from(e: Bip32Error) -> Self { NewAddressDerivingError::Bip32Error(e.to_string()) } + fn from(e: Bip32Error) -> Self { + NewAddressDerivingError::Bip32Error(e.to_string()) + } } impl From for NewAddressDerivingError { @@ -54,7 +62,9 @@ impl From for NewAddressDerivingError { } impl From for NewAddressDerivingError { - fn from(e: InvalidBip44ChainError) -> Self { NewAddressDerivingError::InvalidBip44Chain { chain: e.chain } } + fn from(e: InvalidBip44ChainError) -> Self { + NewAddressDerivingError::InvalidBip44Chain { chain: e.chain } + } } impl From for NewAddressDerivingError { @@ -75,11 +85,15 @@ pub enum NewAddressDeriveConfirmError { } impl From for NewAddressDeriveConfirmError { - fn from(e: HDConfirmAddressError) -> Self { NewAddressDeriveConfirmError::ConfirmError(e) } + fn from(e: HDConfirmAddressError) -> Self { + NewAddressDeriveConfirmError::ConfirmError(e) + } } impl From for NewAddressDeriveConfirmError { - fn from(e: NewAddressDerivingError) -> Self { NewAddressDeriveConfirmError::DeriveError(e) } + fn from(e: NewAddressDerivingError) -> Self { + NewAddressDeriveConfirmError::DeriveError(e) + } } impl From for NewAddressDeriveConfirmError { @@ -150,11 +164,15 @@ pub enum AccountUpdatingError { } impl From for AccountUpdatingError { - fn from(e: InvalidBip44ChainError) -> Self { AccountUpdatingError::InvalidBip44Chain(e) } + fn from(e: InvalidBip44ChainError) -> Self { + AccountUpdatingError::InvalidBip44Chain(e) + } } impl From for AccountUpdatingError { - fn from(e: HDWalletStorageError) -> Self { AccountUpdatingError::WalletStorageError(e) } + fn from(e: HDWalletStorageError) -> Self { + AccountUpdatingError::WalletStorageError(e) + } } #[derive(Display)] @@ -166,7 +184,9 @@ pub enum HDWithdrawError { } impl From for HDWithdrawError { - fn from(e: AddressDerivingError) -> Self { HDWithdrawError::AddressDerivingError(e) } + fn from(e: AddressDerivingError) -> Self { + HDWithdrawError::AddressDerivingError(e) + } } #[derive(Clone)] @@ -180,15 +200,21 @@ pub enum HDExtractPubkeyError { } impl From for HDExtractPubkeyError { - fn from(e: CryptoCtxError) -> Self { HDExtractPubkeyError::Internal(e.to_string()) } + fn from(e: CryptoCtxError) -> Self { + HDExtractPubkeyError::Internal(e.to_string()) + } } impl From for HDExtractPubkeyError { - fn from(e: TrezorError) -> Self { HDExtractPubkeyError::HardwareWalletError(HwError::from(e)) } + fn from(e: TrezorError) -> Self { + HDExtractPubkeyError::HardwareWalletError(HwError::from(e)) + } } impl From for HDExtractPubkeyError { - fn from(e: HwError) -> Self { HDExtractPubkeyError::HardwareWalletError(e) } + fn from(e: HwError) -> Self { + HDExtractPubkeyError::HardwareWalletError(e) + } } impl From> for HDExtractPubkeyError { @@ -211,7 +237,9 @@ impl From> for HDExtractPubkeyError { } impl From for HDExtractPubkeyError { - fn from(e: XpubError) -> Self { HDExtractPubkeyError::InvalidXpub(e.to_string()) } + fn from(e: XpubError) -> Self { + HDExtractPubkeyError::InvalidXpub(e.to_string()) + } } impl From for NewAccountCreationError { @@ -235,7 +263,9 @@ pub enum TrezorCoinError { } impl From for HDExtractPubkeyError { - fn from(e: TrezorCoinError) -> Self { HDExtractPubkeyError::Internal(e.to_string()) } + fn from(e: TrezorCoinError) -> Self { + HDExtractPubkeyError::Internal(e.to_string()) + } } impl From for NewAddressDeriveConfirmError { diff --git a/mm2src/coins/hd_wallet/mod.rs b/mm2src/coins/hd_wallet/mod.rs index 6ed0d0a9a5..3eb29e50d7 100644 --- a/mm2src/coins/hd_wallet/mod.rs +++ b/mm2src/coins/hd_wallet/mod.rs @@ -1,7 +1,9 @@ use async_trait::async_trait; use common::log::warn; -use crypto::{Bip32DerPathOps, Bip32Error, Bip44Chain, ChildNumber, DerivationPath, HDPathToAccount, HDPathToCoin, - Secp256k1ExtendedPublicKey, StandardHDPath, StandardHDPathError}; +use crypto::{ + Bip32DerPathOps, Bip32Error, Bip44Chain, ChildNumber, DerivationPath, HDPathToAccount, HDPathToCoin, + Secp256k1ExtendedPublicKey, StandardHDPath, StandardHDPathError, +}; use futures::lock::{MappedMutexGuard as AsyncMappedMutexGuard, Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard}; use mm2_err_handle::prelude::*; use primitives::hash::H160; @@ -28,9 +30,11 @@ pub(crate) use confirm_address::{ConfirmAddressStatus, RpcTaskConfirmAddress}; pub use confirm_address::{HDConfirmAddress, HDConfirmAddressError}; mod errors; -pub use errors::{AccountUpdatingError, AddressDerivingError, HDExtractPubkeyError, HDWithdrawError, - InvalidBip44ChainError, NewAccountCreationError, NewAddressDeriveConfirmError, - NewAddressDerivingError, SettingEnabledAddressError, TrezorCoinError}; +pub use errors::{ + AccountUpdatingError, AddressDerivingError, HDExtractPubkeyError, HDWithdrawError, InvalidBip44ChainError, + NewAccountCreationError, NewAddressDeriveConfirmError, NewAddressDerivingError, SettingEnabledAddressError, + TrezorCoinError, +}; mod pubkey; pub use pubkey::{ExtendedPublicKeyOps, ExtractExtendedPubkey, HDXPubExtractor, RpcTaskXPubExtractor}; @@ -38,9 +42,12 @@ pub use pubkey::{ExtendedPublicKeyOps, ExtractExtendedPubkey, HDXPubExtractor, R mod storage; #[cfg(target_arch = "wasm32")] pub(crate) use storage::HDWalletDb; -#[cfg(test)] pub(crate) use storage::HDWalletMockStorage; -pub use storage::{HDAccountStorageItem, HDAccountStorageOps, HDWalletCoinStorage, HDWalletId, HDWalletStorageError, - HDWalletStorageOps}; +#[cfg(test)] +pub(crate) use storage::HDWalletMockStorage; +pub use storage::{ + HDAccountStorageItem, HDAccountStorageOps, HDWalletCoinStorage, HDWalletId, HDWalletStorageError, + HDWalletStorageOps, +}; pub(crate) use storage::{HDWalletStorageInternalOps, HDWalletStorageResult}; mod wallet_ops; @@ -84,11 +91,17 @@ where type Address = Address; type Pubkey = Pubkey; - fn address(&self) -> Self::Address { self.address.clone() } + fn address(&self) -> Self::Address { + self.address.clone() + } - fn pubkey(&self) -> Self::Pubkey { self.pubkey.clone() } + fn pubkey(&self) -> Self::Pubkey { + self.pubkey.clone() + } - fn derivation_path(&self) -> &DerivationPath { &self.derivation_path } + fn derivation_path(&self) -> &DerivationPath { + &self.derivation_path + } } /// A generic HD address that can be used with any HD wallet. @@ -112,7 +125,9 @@ impl HDAddressesCache { } } - pub async fn lock(&self) -> AsyncMutexGuard<'_, HashMap> { self.cache.lock().await } + pub async fn lock(&self) -> AsyncMutexGuard<'_, HashMap> { + self.cache.lock().await + } } /// A generic HD account that can be used with any HD wallet. @@ -164,7 +179,9 @@ where } } - fn address_limit(&self) -> u32 { DEFAULT_ADDRESS_LIMIT } + fn address_limit(&self) -> u32 { + DEFAULT_ADDRESS_LIMIT + } fn known_addresses_number(&self, chain: Bip44Chain) -> MmResult { match chain { @@ -184,18 +201,26 @@ where } } - fn account_derivation_path(&self) -> DerivationPath { self.account_derivation_path.to_derivation_path() } + fn account_derivation_path(&self) -> DerivationPath { + self.account_derivation_path.to_derivation_path() + } - fn account_id(&self) -> u32 { self.account_id } + fn account_id(&self) -> u32 { + self.account_id + } fn is_address_activated(&self, chain: Bip44Chain, address_id: u32) -> MmResult { let is_activated = address_id < self.known_addresses_number(chain)?; Ok(is_activated) } - fn derived_addresses(&self) -> &HDAddressesCache { &self.derived_addresses } + fn derived_addresses(&self) -> &HDAddressesCache { + &self.derived_addresses + } - fn extended_pubkey(&self) -> &Self::ExtendedPublicKey { &self.extended_pubkey } + fn extended_pubkey(&self) -> &Self::ExtendedPublicKey { + &self.extended_pubkey + } } impl HDAccountStorageOps for HDAccount @@ -308,17 +333,29 @@ where { type HDAccount = HDAccount; - fn coin_type(&self) -> u32 { self.derivation_path.coin_type() } + fn coin_type(&self) -> u32 { + self.derivation_path.coin_type() + } - fn derivation_path(&self) -> &HDPathToCoin { &self.derivation_path } + fn derivation_path(&self) -> &HDPathToCoin { + &self.derivation_path + } - fn gap_limit(&self) -> u32 { self.gap_limit } + fn gap_limit(&self) -> u32 { + self.gap_limit + } - fn account_limit(&self) -> u32 { DEFAULT_ACCOUNT_LIMIT } + fn account_limit(&self) -> u32 { + DEFAULT_ACCOUNT_LIMIT + } - fn default_receiver_chain(&self) -> Bip44Chain { DEFAULT_RECEIVER_CHAIN } + fn default_receiver_chain(&self) -> Bip44Chain { + DEFAULT_RECEIVER_CHAIN + } - fn get_accounts_mutex(&self) -> &HDAccountsMutex { &self.accounts } + fn get_accounts_mutex(&self) -> &HDAccountsMutex { + &self.accounts + } async fn get_account(&self, account_id: u32) -> Option { let accounts = self.get_accounts_mutex().lock().await; @@ -338,9 +375,13 @@ where })) } - async fn get_accounts(&self) -> HDAccountsMap { self.get_accounts_mutex().lock().await.clone() } + async fn get_accounts(&self) -> HDAccountsMap { + self.get_accounts_mutex().lock().await.clone() + } - async fn get_accounts_mut(&self) -> HDAccountsMut<'_, Self::HDAccount> { self.get_accounts_mutex().lock().await } + async fn get_accounts_mut(&self) -> HDAccountsMut<'_, Self::HDAccount> { + self.get_accounts_mutex().lock().await + } async fn remove_account_if_last(&self, account_id: u32) -> Option { let mut x = self.get_accounts_mutex().lock().await; @@ -449,7 +490,9 @@ impl HDWalletStorageOps for HDWallet where HDAccount: HDAccountOps + HDAccountStorageOps + Clone + Send + Sync, { - fn hd_wallet_storage(&self) -> &HDWalletCoinStorage { &self.hd_wallet_storage } + fn hd_wallet_storage(&self) -> &HDWalletCoinStorage { + &self.hd_wallet_storage + } } /// Unique identifier for an HD wallet address within the whole wallet context. diff --git a/mm2src/coins/hd_wallet/pubkey.rs b/mm2src/coins/hd_wallet/pubkey.rs index c7489761bb..ca6590338a 100644 --- a/mm2src/coins/hd_wallet/pubkey.rs +++ b/mm2src/coins/hd_wallet/pubkey.rs @@ -27,16 +27,24 @@ pub trait ExtendedPublicKeyOps: FromStr + Sized { } impl ExtendedPublicKeyOps for Secp256k1ExtendedPublicKey { - fn derive_child(&self, child_number: ChildNumber) -> Result { self.derive_child(child_number) } + fn derive_child(&self, child_number: ChildNumber) -> Result { + self.derive_child(child_number) + } - fn to_string(&self, prefix: Prefix) -> String { self.to_string(prefix) } + fn to_string(&self, prefix: Prefix) -> String { + self.to_string(prefix) + } } #[cfg(feature = "enable-sia")] impl ExtendedPublicKeyOps for Ed25519ExtendedPublicKey { - fn derive_child(&self, child_number: ChildNumber) -> Result { self.derive_child(child_number) } + fn derive_child(&self, child_number: ChildNumber) -> Result { + self.derive_child(child_number) + } - fn to_string(&self, prefix: Prefix) -> String { self.to_string(prefix) } + fn to_string(&self, prefix: Prefix) -> String { + self.to_string(prefix) + } } /// This trait should be implemented for coins diff --git a/mm2src/coins/hd_wallet/storage/mock_storage.rs b/mm2src/coins/hd_wallet/storage/mock_storage.rs index 8086e58be8..3bc115b292 100644 --- a/mm2src/coins/hd_wallet/storage/mock_storage.rs +++ b/mm2src/coins/hd_wallet/storage/mock_storage.rs @@ -1,7 +1,8 @@ use crate::hd_wallet::{HDAccountStorageItem, HDWalletId, HDWalletStorageInternalOps, HDWalletStorageResult}; use async_trait::async_trait; use mm2_core::mm_ctx::MmArc; -#[cfg(test)] use mocktopus::macros::*; +#[cfg(test)] +use mocktopus::macros::*; pub(crate) struct HDWalletMockStorage; @@ -53,5 +54,7 @@ impl HDWalletStorageInternalOps for HDWalletMockStorage { unimplemented!() } - async fn clear_accounts(&self, _wallet_id: HDWalletId) -> HDWalletStorageResult<()> { unimplemented!() } + async fn clear_accounts(&self, _wallet_id: HDWalletId) -> HDWalletStorageResult<()> { + unimplemented!() + } } diff --git a/mm2src/coins/hd_wallet/storage/mod.rs b/mm2src/coins/hd_wallet/storage/mod.rs index c01712bfc9..681b8024f8 100644 --- a/mm2src/coins/hd_wallet/storage/mod.rs +++ b/mm2src/coins/hd_wallet/storage/mod.rs @@ -3,17 +3,21 @@ use crypto::{Bip32Error, CryptoCtx, CryptoCtxError, HDPathToCoin, StandardHDPath use derive_more::Display; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; -#[cfg(test)] use mocktopus::macros::*; +#[cfg(test)] +use mocktopus::macros::*; use primitives::hash::H160; use serde::{Deserialize, Serialize}; use std::fmt; use std::fmt::Formatter; use std::ops::Deref; -#[cfg(not(target_arch = "wasm32"))] mod sqlite_storage; -#[cfg(target_arch = "wasm32")] mod wasm_storage; +#[cfg(not(target_arch = "wasm32"))] +mod sqlite_storage; +#[cfg(target_arch = "wasm32")] +mod wasm_storage; -#[cfg(any(test, target_arch = "wasm32"))] mod mock_storage; +#[cfg(any(test, target_arch = "wasm32"))] +mod mock_storage; #[cfg(any(test, target_arch = "wasm32"))] pub(crate) use mock_storage::HDWalletMockStorage; @@ -48,19 +52,27 @@ pub enum HDWalletStorageError { } impl From for HDWalletStorageError { - fn from(e: Bip32Error) -> Self { HDWalletStorageError::ErrorDeserializing(e.to_string()) } + fn from(e: Bip32Error) -> Self { + HDWalletStorageError::ErrorDeserializing(e.to_string()) + } } impl From for HDWalletStorageError { - fn from(e: CryptoCtxError) -> Self { HDWalletStorageError::Internal(e.to_string()) } + fn from(e: CryptoCtxError) -> Self { + HDWalletStorageError::Internal(e.to_string()) + } } impl From for HDWalletStorageError { - fn from(e: StandardHDPathError) -> Self { HDWalletStorageError::ErrorDeserializing(e.to_string()) } + fn from(e: StandardHDPathError) -> Self { + HDWalletStorageError::ErrorDeserializing(e.to_string()) + } } impl HDWalletStorageError { - pub fn is_deserializing_err(&self) -> bool { matches!(self, HDWalletStorageError::ErrorDeserializing(_)) } + pub fn is_deserializing_err(&self) -> bool { + matches!(self, HDWalletStorageError::ErrorDeserializing(_)) + } } #[derive(Clone, Debug, Deserialize, Serialize)] @@ -253,7 +265,9 @@ impl HDWalletCoinStorage { }) } - pub fn wallet_id(&self) -> HDWalletId { HDWalletId::new(self.coin.clone(), &self.hd_wallet_rmd160) } + pub fn wallet_id(&self) -> HDWalletId { + HDWalletId::new(self.coin.clone(), &self.hd_wallet_rmd160) + } pub async fn load_all_accounts(&self) -> HDWalletStorageResult> { let wallet_id = self.wallet_id(); @@ -298,7 +312,9 @@ impl HDWalletCoinStorage { } } -fn display_rmd160(rmd160: &H160) -> String { hex::encode(rmd160.deref()) } +fn display_rmd160(rmd160: &H160) -> String { + hex::encode(rmd160.deref()) +} #[cfg(any(test, target_arch = "wasm32"))] mod tests { @@ -383,12 +399,15 @@ mod tests { .into_iter() .sorted_by(|x, y| x.external_addresses_number.cmp(&y.external_addresses_number)) .collect(); - assert_eq!(all_accounts, vec![ - rick_device0_account0.clone(), - rick_device0_account1.clone(), - rick_device1_account0.clone(), - morty_device0_account0.clone() - ]); + assert_eq!( + all_accounts, + vec![ + rick_device0_account0.clone(), + rick_device0_account1.clone(), + rick_device1_account0.clone(), + morty_device0_account0.clone() + ] + ); let mut actual = rick_device0_db .load_all_accounts() @@ -533,25 +552,37 @@ mod tests { #[cfg(target_arch = "wasm32")] #[wasm_bindgen_test] - async fn test_unique_wallets() { test_unique_wallets_impl().await } + async fn test_unique_wallets() { + test_unique_wallets_impl().await + } #[cfg(not(target_arch = "wasm32"))] #[test] - fn test_unique_wallets() { block_on(test_unique_wallets_impl()) } + fn test_unique_wallets() { + block_on(test_unique_wallets_impl()) + } #[cfg(target_arch = "wasm32")] #[wasm_bindgen_test] - async fn test_delete_accounts() { test_delete_accounts_impl().await } + async fn test_delete_accounts() { + test_delete_accounts_impl().await + } #[cfg(not(target_arch = "wasm32"))] #[test] - fn test_delete_accounts() { block_on(test_delete_accounts_impl()) } + fn test_delete_accounts() { + block_on(test_delete_accounts_impl()) + } #[cfg(target_arch = "wasm32")] #[wasm_bindgen_test] - async fn test_update_account() { test_update_account_impl().await } + async fn test_update_account() { + test_update_account_impl().await + } #[cfg(not(target_arch = "wasm32"))] #[test] - fn test_update_account() { block_on(test_update_account_impl()) } + fn test_update_account() { + block_on(test_update_account_impl()) + } } diff --git a/mm2src/coins/hd_wallet/storage/sqlite_storage.rs b/mm2src/coins/hd_wallet/storage/sqlite_storage.rs index f430eac042..fdf13d42a4 100644 --- a/mm2src/coins/hd_wallet/storage/sqlite_storage.rs +++ b/mm2src/coins/hd_wallet/storage/sqlite_storage.rs @@ -1,13 +1,15 @@ #![allow(deprecated)] // TODO: remove this once rusqlite is >= 0.29 -use crate::hd_wallet::{HDAccountStorageItem, HDWalletId, HDWalletStorageError, HDWalletStorageInternalOps, - HDWalletStorageResult}; +use crate::hd_wallet::{ + HDAccountStorageItem, HDWalletId, HDWalletStorageError, HDWalletStorageInternalOps, HDWalletStorageResult, +}; use async_trait::async_trait; use common::async_blocking; use db_common::owned_named_params; use db_common::sqlite::rusqlite::{Connection, Error as SqlError, Row}; -use db_common::sqlite::{query_single_row_with_named_params, AsSqlNamedParams, OwnedSqlNamedParams, SqliteConnShared, - SqliteConnWeak}; +use db_common::sqlite::{ + query_single_row_with_named_params, AsSqlNamedParams, OwnedSqlNamedParams, SqliteConnShared, SqliteConnWeak, +}; use derive_more::Display; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; diff --git a/mm2src/coins/hd_wallet/storage/wasm_storage.rs b/mm2src/coins/hd_wallet/storage/wasm_storage.rs index 5c7b57b77d..5acda0e8e7 100644 --- a/mm2src/coins/hd_wallet/storage/wasm_storage.rs +++ b/mm2src/coins/hd_wallet/storage/wasm_storage.rs @@ -1,13 +1,15 @@ -use crate::hd_wallet::{HDAccountStorageItem, HDWalletId, HDWalletStorageError, HDWalletStorageInternalOps, - HDWalletStorageResult}; +use crate::hd_wallet::{ + HDAccountStorageItem, HDWalletId, HDWalletStorageError, HDWalletStorageInternalOps, HDWalletStorageResult, +}; use crate::CoinsContext; use async_trait::async_trait; use crypto::XPub; use mm2_core::mm_ctx::MmArc; use mm2_db::indexed_db::cursor_prelude::*; -use mm2_db::indexed_db::{DbIdentifier, DbInstance, DbLocked, DbTable, DbTransactionError, DbUpgrader, IndexedDb, - IndexedDbBuilder, InitDbError, InitDbResult, ItemId, MultiIndex, OnUpgradeResult, SharedDb, - TableSignature, WeakDb}; +use mm2_db::indexed_db::{ + DbIdentifier, DbInstance, DbLocked, DbTable, DbTransactionError, DbUpgrader, IndexedDb, IndexedDbBuilder, + InitDbError, InitDbResult, ItemId, MultiIndex, OnUpgradeResult, SharedDb, TableSignature, WeakDb, +}; use mm2_err_handle::prelude::*; const DB_VERSION: u32 = 1; @@ -69,7 +71,9 @@ impl From for HDWalletStorageError { } impl From for HDWalletStorageError { - fn from(e: InitDbError) -> Self { HDWalletStorageError::Internal(e.to_string()) } + fn from(e: InitDbError) -> Self { + HDWalletStorageError::Internal(e.to_string()) + } } /// The table has the following individually non-unique indexes: `coin`, `hd_wallet_rmd160`, `account_id`, diff --git a/mm2src/coins/lightning.rs b/mm2src/coins/lightning.rs index 08779f12be..01f41362c2 100644 --- a/mm2src/coins/lightning.rs +++ b/mm2src/coins/lightning.rs @@ -16,17 +16,18 @@ use crate::lightning::ln_utils::{filter_channels, pay_invoice_with_max_total_clt use crate::utxo::rpc_clients::UtxoRpcClientEnum; use crate::utxo::utxo_common::{big_decimal_from_sat, big_decimal_from_sat_unsigned}; use crate::utxo::{sat_from_big_decimal, utxo_common, BlockchainNetwork}; -use crate::{BalanceFut, CheckIfMyPaymentSentArgs, CoinBalance, ConfirmPaymentInput, DexFee, FeeApproxStage, - FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, - PaymentInstructionArgs, PaymentInstructions, PaymentInstructionsErr, RawTransactionError, - RawTransactionFut, RawTransactionRequest, RawTransactionResult, RefundError, RefundPaymentArgs, - RefundResult, SearchForSwapTxSpendInput, SendPaymentArgs, SignRawTransactionRequest, SignatureError, - SignatureResult, SpendPaymentArgs, SwapOps, TradeFee, TradePreimageFut, TradePreimageResult, - TradePreimageValue, Transaction, TransactionEnum, TransactionErr, TransactionResult, TxMarshalingErr, - UnexpectedDerivationMethod, UtxoStandardCoin, ValidateAddressResult, ValidateFeeArgs, - ValidateInstructionsErr, ValidateOtherPubKeyErr, ValidatePaymentError, ValidatePaymentFut, - ValidatePaymentInput, VerificationError, VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, - WeakSpawner, WithdrawError, WithdrawFut, WithdrawRequest}; +use crate::{ + BalanceFut, CheckIfMyPaymentSentArgs, CoinBalance, ConfirmPaymentInput, DexFee, FeeApproxStage, FoundSwapTxSpend, + HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, PaymentInstructionArgs, PaymentInstructions, + PaymentInstructionsErr, RawTransactionError, RawTransactionFut, RawTransactionRequest, RawTransactionResult, + RefundError, RefundPaymentArgs, RefundResult, SearchForSwapTxSpendInput, SendPaymentArgs, + SignRawTransactionRequest, SignatureError, SignatureResult, SpendPaymentArgs, SwapOps, TradeFee, TradePreimageFut, + TradePreimageResult, TradePreimageValue, Transaction, TransactionEnum, TransactionErr, TransactionResult, + TxMarshalingErr, UnexpectedDerivationMethod, UtxoStandardCoin, ValidateAddressResult, ValidateFeeArgs, + ValidateInstructionsErr, ValidateOtherPubKeyErr, ValidatePaymentError, ValidatePaymentFut, ValidatePaymentInput, + VerificationError, VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, WeakSpawner, WithdrawError, WithdrawFut, + WithdrawRequest, +}; use async_trait::async_trait; use bitcoin::bech32::ToBase32; use bitcoin::hashes::Hash; @@ -121,7 +122,9 @@ pub struct LightningCoin { } impl fmt::Debug for LightningCoin { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "LightningCoin {{ conf: {:?} }}", self.conf) } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "LightningCoin {{ conf: {:?} }}", self.conf) + } } #[derive(Deserialize)] @@ -150,19 +153,29 @@ pub(crate) struct GetOpenChannelsResult { } impl Transaction for PaymentHash { - fn tx_hex(&self) -> Vec { self.0.to_vec() } + fn tx_hex(&self) -> Vec { + self.0.to_vec() + } - fn tx_hash_as_bytes(&self) -> BytesJson { self.0.to_vec().into() } + fn tx_hash_as_bytes(&self) -> BytesJson { + self.0.to_vec().into() + } } impl LightningCoin { - pub fn platform_coin(&self) -> &UtxoStandardCoin { &self.platform.coin } + pub fn platform_coin(&self) -> &UtxoStandardCoin { + &self.platform.coin + } #[inline] - fn avg_blocktime(&self) -> u64 { self.platform.avg_blocktime } + fn avg_blocktime(&self) -> u64 { + self.platform.avg_blocktime + } #[inline] - fn my_node_id(&self) -> String { self.channel_manager.get_our_node_id().to_string() } + fn my_node_id(&self) -> String { + self.channel_manager.get_our_node_id().to_string() + } pub(crate) async fn list_channels(&self) -> Vec { let channel_manager = self.channel_manager.clone(); @@ -478,7 +491,9 @@ impl LightningCoin { } } - fn estimate_blocks_from_duration(&self, duration: u64) -> u64 { duration / self.avg_blocktime() } + fn estimate_blocks_from_duration(&self, duration: u64) -> u64 { + duration / self.avg_blocktime() + } async fn swap_payment_instructions( &self, @@ -675,7 +690,9 @@ impl SwapOps for LightningCoin { } // Todo: This validates the dummy fee for now for the sake of swap P.O.C., this should be implemented probably after agreeing on how fees will work for lightning - async fn validate_fee(&self, _validate_fee_args: ValidateFeeArgs<'_>) -> ValidatePaymentResult<()> { Ok(()) } + async fn validate_fee(&self, _validate_fee_args: ValidateFeeArgs<'_>) -> ValidatePaymentResult<()> { + Ok(()) + } #[inline] async fn validate_maker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentResult<()> { @@ -801,7 +818,9 @@ impl SwapOps for LightningCoin { } } - fn is_auto_refundable(&self) -> bool { true } + fn is_auto_refundable(&self) -> bool { + true + } async fn wait_for_htlc_refund(&self, tx: &[u8], locktime: u64) -> RefundResult<()> { let payment_hash = payment_hash_from_slice(tx).map_err(|e| RefundError::DecodeErr(e.to_string()))?; @@ -904,9 +923,13 @@ impl SwapOps for LightningCoin { ) } - fn maker_locktime_multiplier(&self) -> f64 { 1.5 } + fn maker_locktime_multiplier(&self) -> f64 { + 1.5 + } - async fn on_taker_payment_refund_start(&self, _maker_payment: &[u8]) -> RefundResult<()> { Ok(()) } + async fn on_taker_payment_refund_start(&self, _maker_payment: &[u8]) -> RefundResult<()> { + Ok(()) + } async fn on_taker_payment_refund_success(&self, maker_payment: &[u8]) -> RefundResult<()> { self.on_swap_refund(maker_payment).await @@ -916,7 +939,9 @@ impl SwapOps for LightningCoin { self.on_swap_refund(taker_payment).await } - async fn on_maker_payment_refund_success(&self, _taker_payment: &[u8]) -> RefundResult<()> { Ok(()) } + async fn on_maker_payment_refund_success(&self, _taker_payment: &[u8]) -> RefundResult<()> { + Ok(()) + } } #[derive(Debug, Display)] @@ -940,9 +965,13 @@ impl WatcherOps for LightningCoin {} #[async_trait] impl MarketCoinOps for LightningCoin { - fn ticker(&self) -> &str { &self.conf.ticker } + fn ticker(&self) -> &str { + &self.conf.ticker + } - fn my_address(&self) -> MmResult { Ok(self.my_node_id()) } + fn my_address(&self) -> MmResult { + Ok(self.my_node_id()) + } fn address_from_pubkey(&self, pubkey: &H264Json) -> MmResult { PublicKey::from_slice(&pubkey.0) @@ -950,7 +979,9 @@ impl MarketCoinOps for LightningCoin { .map_to_mm(|e| AddressFromPubkeyError::InternalError(format!("Couldn't parse bytes into secp pubkey: {e}"))) } - async fn get_public_key(&self) -> Result> { Ok(self.my_node_id()) } + async fn get_public_key(&self) -> Result> { + Ok(self.my_node_id()) + } fn sign_message_hash(&self, message: &str) -> Option<[u8; 32]> { let mut _message_prefix = self.conf.sign_message_prefix.clone()?; @@ -1008,9 +1039,13 @@ impl MarketCoinOps for LightningCoin { Box::new(fut.boxed().compat()) } - fn base_coin_balance(&self) -> BalanceFut { Box::new(self.my_balance().map(|res| res.spendable)) } + fn base_coin_balance(&self) -> BalanceFut { + Box::new(self.my_balance().map(|res| res.spendable)) + } - fn platform_ticker(&self) -> &str { self.platform_coin().ticker() } + fn platform_ticker(&self) -> &str { + self.platform_coin().ticker() + } fn send_raw_tx(&self, _tx: &str) -> Box + Send> { Box::new(futures01::future::err( @@ -1146,7 +1181,9 @@ impl MarketCoinOps for LightningCoin { )) } - fn current_block(&self) -> Box + Send> { Box::new(futures01::future::ok(0)) } + fn current_block(&self) -> Box + Send> { + Box::new(futures01::future::ok(0)) + } fn display_priv_key(&self) -> Result { Ok(self @@ -1173,11 +1210,17 @@ impl MarketCoinOps for LightningCoin { // Todo: Equals to min_tx_amount for now (1 satoshi), should change this later // Todo: doesn't take routing fees into account too, There is no way to know the route to the other side of the swap when placing the order, need to find a workaround for this - fn min_trading_vol(&self) -> MmNumber { self.min_tx_amount().into() } + fn min_trading_vol(&self) -> MmNumber { + self.min_tx_amount().into() + } - fn should_burn_dex_fee(&self) -> bool { false } + fn should_burn_dex_fee(&self) -> bool { + false + } - fn is_trezor(&self) -> bool { self.platform.coin.is_trezor() } + fn is_trezor(&self) -> bool { + self.platform.coin.is_trezor() + } } #[derive(Deserialize, Serialize)] @@ -1188,9 +1231,13 @@ struct LightningProtocolInfo { #[async_trait] impl MmCoin for LightningCoin { - fn is_asset_chain(&self) -> bool { false } + fn is_asset_chain(&self) -> bool { + false + } - fn spawner(&self) -> WeakSpawner { self.platform.abortable_system.weak_spawner() } + fn spawner(&self) -> WeakSpawner { + self.platform.abortable_system.weak_spawner() + } fn get_raw_transaction(&self, _req: RawTransactionRequest) -> RawTransactionFut { let fut = async move { @@ -1219,7 +1266,9 @@ impl MmCoin for LightningCoin { Box::new(fut.boxed().compat()) } - fn decimals(&self) -> u8 { self.conf.decimals } + fn decimals(&self) -> u8 { + self.conf.decimals + } fn convert_to_address(&self, _from: &str, _to_address_format: Json) -> Result { Err(MmError::new("Address conversion is not available for LightningCoin".to_string()).to_string()) @@ -1239,13 +1288,19 @@ impl MmCoin for LightningCoin { } // Todo: Implement this when implementing payments history for lightning - fn process_history_loop(&self, _ctx: MmArc) -> Box + Send> { unimplemented!() } + fn process_history_loop(&self, _ctx: MmArc) -> Box + Send> { + unimplemented!() + } // Todo: Implement this when implementing payments history for lightning - fn history_sync_status(&self) -> HistorySyncState { unimplemented!() } + fn history_sync_status(&self) -> HistorySyncState { + unimplemented!() + } // Todo: Implement this when implementing swaps for lightning as it's is used only for swaps - fn get_trade_fee(&self) -> Box + Send> { unimplemented!() } + fn get_trade_fee(&self) -> Box + Send> { + unimplemented!() + } // Todo: This uses dummy data for now for the sake of swap P.O.C., this should be implemented probably after agreeing on how fees will work for lightning async fn get_sender_trade_fee( @@ -1285,19 +1340,29 @@ impl MmCoin for LightningCoin { // Lightning payments are either pending, successful or failed. Once a payment succeeds there is no need to for confirmations // unlike onchain transactions. - fn required_confirmations(&self) -> u64 { 0 } + fn required_confirmations(&self) -> u64 { + 0 + } - fn requires_notarization(&self) -> bool { false } + fn requires_notarization(&self) -> bool { + false + } fn set_required_confirmations(&self, _confirmations: u64) {} fn set_requires_notarization(&self, _requires_nota: bool) {} - fn swap_contract_address(&self) -> Option { None } + fn swap_contract_address(&self) -> Option { + None + } - fn fallback_swap_contract(&self) -> Option { None } + fn fallback_swap_contract(&self) -> Option { + None + } - fn mature_confirmations(&self) -> Option { None } + fn mature_confirmations(&self) -> Option { + None + } // Channels for users/non-routing nodes should be private, so routing hints are sent as part of the protocol info // alongside the receiver lightning node address/pubkey. @@ -1385,7 +1450,9 @@ impl MmCoin for LightningCoin { .is_ok() } - fn on_disabled(&self) -> Result<(), AbortedError> { AbortableSystem::abort_all(&self.platform.abortable_system) } + fn on_disabled(&self) -> Result<(), AbortedError> { + AbortableSystem::abort_all(&self.platform.abortable_system) + } fn on_token_deactivated(&self, _ticker: &str) {} } diff --git a/mm2src/coins/lightning/ln_db.rs b/mm2src/coins/lightning/ln_db.rs index 7dd3f81cc2..b20bf72b5f 100644 --- a/mm2src/coins/lightning/ln_db.rs +++ b/mm2src/coins/lightning/ln_db.rs @@ -173,7 +173,9 @@ impl PaymentInfo { self } - pub(crate) fn is_outbound(&self) -> bool { matches!(self.payment_type, PaymentType::OutboundPayment { .. }) } + pub(crate) fn is_outbound(&self) -> bool { + matches!(self.payment_type, PaymentType::OutboundPayment { .. }) + } } #[derive(Clone)] diff --git a/mm2src/coins/lightning/ln_errors.rs b/mm2src/coins/lightning/ln_errors.rs index 5d479e40b6..6f4d7b9ee7 100644 --- a/mm2src/coins/lightning/ln_errors.rs +++ b/mm2src/coins/lightning/ln_errors.rs @@ -64,27 +64,39 @@ impl HttpStatusCode for EnableLightningError { } impl From for EnableLightningError { - fn from(err: std::io::Error) -> EnableLightningError { EnableLightningError::IOError(err.to_string()) } + fn from(err: std::io::Error) -> EnableLightningError { + EnableLightningError::IOError(err.to_string()) + } } impl From for EnableLightningError { - fn from(err: SqlError) -> EnableLightningError { EnableLightningError::DbError(err.to_string()) } + fn from(err: SqlError) -> EnableLightningError { + EnableLightningError::DbError(err.to_string()) + } } impl From for EnableLightningError { - fn from(e: UtxoRpcError) -> Self { EnableLightningError::RpcError(e.to_string()) } + fn from(e: UtxoRpcError) -> Self { + EnableLightningError::RpcError(e.to_string()) + } } impl From for EnableLightningError { - fn from(e: PrivKeyPolicyNotAllowed) -> Self { EnableLightningError::PrivKeyPolicyNotAllowed(e) } + fn from(e: PrivKeyPolicyNotAllowed) -> Self { + EnableLightningError::PrivKeyPolicyNotAllowed(e) + } } impl From for EnableLightningError { - fn from(e: RpcTaskError) -> Self { EnableLightningError::RpcTaskError(e.to_string()) } + fn from(e: RpcTaskError) -> Self { + EnableLightningError::RpcTaskError(e.to_string()) + } } impl From for EnableLightningError { - fn from(e: AbortedError) -> Self { EnableLightningError::Internal(e.to_string()) } + fn from(e: AbortedError) -> Self { + EnableLightningError::Internal(e.to_string()) + } } #[derive(Display, PartialEq)] @@ -104,9 +116,13 @@ pub enum SaveChannelClosingError { } impl From for SaveChannelClosingError { - fn from(err: SqlError) -> SaveChannelClosingError { SaveChannelClosingError::DbError(err.to_string()) } + fn from(err: SqlError) -> SaveChannelClosingError { + SaveChannelClosingError::DbError(err.to_string()) + } } impl From for SaveChannelClosingError { - fn from(err: TryFromIntError) -> SaveChannelClosingError { SaveChannelClosingError::ConversionError(err) } + fn from(err: TryFromIntError) -> SaveChannelClosingError { + SaveChannelClosingError::ConversionError(err) + } } diff --git a/mm2src/coins/lightning/ln_filesystem_persister.rs b/mm2src/coins/lightning/ln_filesystem_persister.rs index d1444a62a6..ec7b4a0978 100644 --- a/mm2src/coins/lightning/ln_filesystem_persister.rs +++ b/mm2src/coins/lightning/ln_filesystem_persister.rs @@ -1,5 +1,6 @@ -use crate::lightning::ln_storage::{LightningStorage, NetworkGraph, NodesAddressesMap, NodesAddressesMapShared, Scorer, - TrustedNodesShared}; +use crate::lightning::ln_storage::{ + LightningStorage, NetworkGraph, NodesAddressesMap, NodesAddressesMapShared, Scorer, TrustedNodesShared, +}; use async_trait::async_trait; use bitcoin::blockdata::constants::genesis_block; use bitcoin::{BlockHash, Network, Txid}; @@ -22,7 +23,8 @@ use std::path::PathBuf; use std::str::FromStr; use std::sync::{Arc, Mutex}; -#[cfg(target_family = "unix")] use std::os::unix::io::AsRawFd; +#[cfg(target_family = "unix")] +use std::os::unix::io::AsRawFd; #[cfg(target_family = "windows")] use {std::ffi::OsStr, std::os::windows::ffi::OsStrExt}; @@ -38,15 +40,21 @@ impl LightningFilesystemPersister { /// Initialize a new LightningPersister and set the path to the individual channels' /// files. #[inline] - pub fn new(main_path: PathBuf, backup_path: Option) -> Self { Self { main_path, backup_path } } + pub fn new(main_path: PathBuf, backup_path: Option) -> Self { + Self { main_path, backup_path } + } /// Get the directory which was provided when this persister was initialized. #[inline] - pub fn main_path(&self) -> PathBuf { self.main_path.clone() } + pub fn main_path(&self) -> PathBuf { + self.main_path.clone() + } /// Get the backup directory which was provided when this persister was initialized. #[inline] - pub fn backup_path(&self) -> Option { self.backup_path.clone() } + pub fn backup_path(&self) -> Option { + self.backup_path.clone() + } pub fn nodes_addresses_path(&self) -> PathBuf { let mut path = self.main_path(); diff --git a/mm2src/coins/lightning/ln_platform.rs b/mm2src/coins/lightning/ln_platform.rs index 0d289aa8d0..634918bd0d 100644 --- a/mm2src/coins/lightning/ln_platform.rs +++ b/mm2src/coins/lightning/ln_platform.rs @@ -1,8 +1,10 @@ use super::*; use crate::lightning::ln_errors::{SaveChannelClosingError, SaveChannelClosingResult}; use crate::lightning::ln_utils::RpcBestBlock; -use crate::utxo::rpc_clients::{BlockHashOrHeight, ConfirmedTransactionInfo, ElectrumBlockHeader, ElectrumClient, - ElectrumNonce, EstimateFeeMethod, UtxoRpcClientEnum, UtxoRpcResult}; +use crate::utxo::rpc_clients::{ + BlockHashOrHeight, ConfirmedTransactionInfo, ElectrumBlockHeader, ElectrumClient, ElectrumNonce, EstimateFeeMethod, + UtxoRpcClientEnum, UtxoRpcResult, +}; use crate::utxo::spv::SimplePaymentVerification; use crate::utxo::utxo_standard::UtxoStandardCoin; use crate::utxo::GetConfirmedTxError; @@ -19,8 +21,10 @@ use common::{block_on_f01, wait_until_sec}; use futures::compat::Future01CompatExt; use futures::future::join_all; use keys::hash::H256; -use lightning::chain::{chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator}, - Confirm, Filter, WatchedOutput}; +use lightning::chain::{ + chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator}, + Confirm, Filter, WatchedOutput, +}; use rpc::v1::types::{Bytes as BytesJson, H256 as H256Json}; use spv_validation::spv_proof::TRY_SPV_PROOF_INTERVAL; use std::convert::TryInto; @@ -32,10 +36,14 @@ const TRY_LOOP_INTERVAL: f64 = 60.; const TAKER_PAYMENT_SPEND_SEARCH_INTERVAL: f64 = 10.; #[inline] -pub fn h256_json_from_txid(txid: Txid) -> H256Json { H256Json::from(txid.as_hash().into_inner()).reversed() } +pub fn h256_json_from_txid(txid: Txid) -> H256Json { + H256Json::from(txid.as_hash().into_inner()).reversed() +} #[inline] -pub fn h256_from_txid(txid: Txid) -> H256 { H256::from(txid.as_hash().into_inner()) } +pub fn h256_from_txid(txid: Txid) -> H256 { + H256::from(txid.as_hash().into_inner()) +} pub async fn get_best_header(best_header_listener: &ElectrumClient) -> EnableLightningResult { best_header_listener @@ -144,13 +152,19 @@ pub struct LatestFees { impl LatestFees { #[inline] - fn set_background_fees(&self, fee: u64) { self.background.store(fee, Ordering::Release); } + fn set_background_fees(&self, fee: u64) { + self.background.store(fee, Ordering::Release); + } #[inline] - fn set_normal_fees(&self, fee: u64) { self.normal.store(fee, Ordering::Release); } + fn set_normal_fees(&self, fee: u64) { + self.normal.store(fee, Ordering::Release); + } #[inline] - fn set_high_priority_fees(&self, fee: u64) { self.high_priority.store(fee, Ordering::Release); } + fn set_high_priority_fees(&self, fee: u64) { + self.high_priority.store(fee, Ordering::Release); + } } pub struct Platform { @@ -214,9 +228,13 @@ impl Platform { } #[inline] - fn rpc_client(&self) -> &UtxoRpcClientEnum { &self.coin.as_ref().rpc_client } + fn rpc_client(&self) -> &UtxoRpcClientEnum { + &self.coin.as_ref().rpc_client + } - pub fn spawner(&self) -> WeakSpawner { self.abortable_system.weak_spawner() } + pub fn spawner(&self) -> WeakSpawner { + self.abortable_system.weak_spawner() + } pub async fn set_latest_fees(&self) -> UtxoRpcResult<()> { let platform_coin = &self.coin; @@ -270,7 +288,9 @@ impl Platform { } #[inline] - pub fn best_block_height(&self) -> u64 { self.best_block_height.load(AtomicOrdering::Acquire) } + pub fn best_block_height(&self) -> u64 { + self.best_block_height.load(AtomicOrdering::Acquire) + } pub fn add_tx(&self, txid: Txid) { let mut registered_txs = self.registered_txs.lock(); @@ -642,8 +662,12 @@ impl BroadcasterInterface for Platform { impl Filter for Platform { // Watches for this transaction on-chain #[inline] - fn register_tx(&self, txid: &Txid, _script_pubkey: &Script) { self.add_tx(*txid); } + fn register_tx(&self, txid: &Txid, _script_pubkey: &Script) { + self.add_tx(*txid); + } // Watches for any transactions that spend this output on-chain - fn register_output(&self, output: WatchedOutput) { self.add_output(output); } + fn register_output(&self, output: WatchedOutput) { + self.add_output(output); + } } diff --git a/mm2src/coins/lightning/ln_serialization.rs b/mm2src/coins/lightning/ln_serialization.rs index 5e04f5cb41..0f765fcff0 100644 --- a/mm2src/coins/lightning/ln_serialization.rs +++ b/mm2src/coins/lightning/ln_serialization.rs @@ -30,7 +30,9 @@ impl<'de> de::Deserialize<'de> for NodeAddress { impl de::Visitor<'_> for NodeAddressVisitor { type Value = NodeAddress; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "pubkey@host:port") } + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "pubkey@host:port") + } fn visit_str(self, v: &str) -> Result { let mut pubkey_and_addr = v.split('@'); @@ -69,7 +71,9 @@ impl<'de> de::Deserialize<'de> for NodeAddress { pub struct PublicKeyForRPC(pub PublicKey); impl From for PublicKey { - fn from(p: PublicKeyForRPC) -> Self { p.0 } + fn from(p: PublicKeyForRPC) -> Self { + p.0 + } } impl Serialize for PublicKeyForRPC { @@ -85,7 +89,9 @@ impl<'de> de::Deserialize<'de> for PublicKeyForRPC { impl de::Visitor<'_> for PublicKeyForRPCVisitor { type Value = PublicKeyForRPC; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "a public key") } + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "a public key") + } fn visit_str(self, v: &str) -> Result { let pubkey = PublicKey::from_str(v).map_err(|e| { diff --git a/mm2src/coins/lightning/ln_sql.rs b/mm2src/coins/lightning/ln_sql.rs index 59af04a698..e827c28d5b 100644 --- a/mm2src/coins/lightning/ln_sql.rs +++ b/mm2src/coins/lightning/ln_sql.rs @@ -1,26 +1,33 @@ #![allow(deprecated)] // TODO: remove this once rusqlite is >= 0.29 -use crate::lightning::ln_db::{ChannelType, ChannelVisibility, ClosedChannelsFilter, DBChannelDetails, - DBPaymentsFilter, GetClosedChannelsResult, GetPaymentsResult, HTLCStatus, LightningDB, - PaymentInfo, PaymentType}; +use crate::lightning::ln_db::{ + ChannelType, ChannelVisibility, ClosedChannelsFilter, DBChannelDetails, DBPaymentsFilter, GetClosedChannelsResult, + GetPaymentsResult, HTLCStatus, LightningDB, PaymentInfo, PaymentType, +}; use async_trait::async_trait; use common::{async_blocking, now_sec_i64, PagingOptionsEnum}; use db_common::owned_named_params; use db_common::sqlite::rusqlite::types::Type; use db_common::sqlite::rusqlite::{params, Error as SqlError, Row, ToSql}; use db_common::sqlite::sql_builder::SqlBuilder; -use db_common::sqlite::{h256_option_slice_from_row, h256_slice_from_row, offset_by_id, query_single_row, - sql_text_conversion_err, string_from_row, validate_table_name, AsSqlNamedParams, - OwnedSqlNamedParams, SqlNamedParams, SqliteConnShared, CHECK_TABLE_EXISTS_SQL}; +use db_common::sqlite::{ + h256_option_slice_from_row, h256_slice_from_row, offset_by_id, query_single_row, sql_text_conversion_err, + string_from_row, validate_table_name, AsSqlNamedParams, OwnedSqlNamedParams, SqlNamedParams, SqliteConnShared, + CHECK_TABLE_EXISTS_SQL, +}; use lightning::ln::{PaymentHash, PaymentPreimage}; use secp256k1v24::PublicKey; use std::convert::TryInto; use std::str::FromStr; use uuid::Uuid; -fn channels_history_table(ticker: &str) -> String { ticker.to_owned() + "_channels_history" } +fn channels_history_table(ticker: &str) -> String { + ticker.to_owned() + "_channels_history" +} -fn payments_history_table(ticker: &str) -> String { ticker.to_owned() + "_payments_history" } +fn payments_history_table(ticker: &str) -> String { + ticker.to_owned() + "_payments_history" +} fn create_channels_history_table_sql(for_coin: &str) -> Result { let table_name = channels_history_table(for_coin); diff --git a/mm2src/coins/lightning/ln_utils.rs b/mm2src/coins/lightning/ln_utils.rs index 59f6e0f6eb..9e9c6fa395 100644 --- a/mm2src/coins/lightning/ln_utils.rs +++ b/mm2src/coins/lightning/ln_utils.rs @@ -11,8 +11,9 @@ use common::log::LogState; use derive_more::Display; use lightning::chain::keysinterface::{InMemorySigner, KeysManager}; use lightning::chain::{chainmonitor, BestBlock, ChannelMonitorUpdateStatus, Watch}; -use lightning::ln::channelmanager::{ChainParameters, ChannelManagerReadArgs, PaymentId, PaymentSendFailure, - SimpleArcChannelManager}; +use lightning::ln::channelmanager::{ + ChainParameters, ChannelManagerReadArgs, PaymentId, PaymentSendFailure, SimpleArcChannelManager, +}; use lightning::routing::gossip::RoutingFees; use lightning::routing::router::{PaymentParameters, RouteHint, RouteHintHop, RouteParameters, Router as RouterTrait}; use lightning::util::config::UserConfig; @@ -359,11 +360,15 @@ pub enum PaymentError { } impl From for PaymentError { - fn from(err: SqlError) -> PaymentError { PaymentError::DbError(err.to_string()) } + fn from(err: SqlError) -> PaymentError { + PaymentError::DbError(err.to_string()) + } } impl From for PaymentError { - fn from(err: InvoicePaymentError) -> PaymentError { PaymentError::Invoice(format!("{:?}", err)) } + fn from(err: InvoicePaymentError) -> PaymentError { + PaymentError::Invoice(format!("{:?}", err)) + } } // Todo: This is imported from rust-lightning and modified by me, will need to open a PR there with this modification and update the dependency to remove this code and the code it depends on. diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 1626e9d8af..029ad6e0fc 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -29,17 +29,21 @@ clippy::needless_lifetimes // mocktopus requires explicit lifetimes )] #![allow(uncommon_codepoints)] -#![feature(hash_raw_entry)] -#![feature(stmt_expr_attributes)] -#![feature(result_flattening)] - -#[macro_use] extern crate common; -#[macro_use] extern crate gstuff; -#[macro_use] extern crate lazy_static; -#[macro_use] extern crate mm2_metrics; -#[macro_use] extern crate serde_derive; -#[macro_use] extern crate serde_json; -#[macro_use] extern crate ser_error_derive; + +#[macro_use] +extern crate common; +#[macro_use] +extern crate gstuff; +#[macro_use] +extern crate lazy_static; +#[macro_use] +extern crate mm2_metrics; +#[macro_use] +extern crate serde_derive; +#[macro_use] +extern crate serde_json; +#[macro_use] +extern crate ser_error_derive; use async_trait::async_trait; use bip32::ExtendedPrivateKey; @@ -47,9 +51,11 @@ use common::custom_futures::timeout::TimeoutError; use common::executor::{abortable_queue::WeakSpawner, AbortedError, SpawnFuture}; use common::log::{warn, LogOnError}; use common::{calc_total_pages, now_sec, ten, HttpStatusCode, DEX_BURN_ADDR_RAW_PUBKEY, DEX_FEE_ADDR_RAW_PUBKEY}; -use crypto::{derive_secp256k1_secret, Bip32Error, Bip44Chain, CryptoCtx, CryptoCtxError, DerivationPath, - GlobalHDAccountArc, HDPathToCoin, HwRpcError, KeyPairPolicy, RpcDerivationPath, - Secp256k1ExtendedPublicKey, Secp256k1Secret, WithHwRpcError}; +use crypto::{ + derive_secp256k1_secret, Bip32Error, Bip44Chain, CryptoCtx, CryptoCtxError, DerivationPath, GlobalHDAccountArc, + HDPathToCoin, HwRpcError, KeyPairPolicy, RpcDerivationPath, Secp256k1ExtendedPublicKey, Secp256k1Secret, + WithHwRpcError, +}; use derive_more::Display; use enum_derives::{EnumFromStringify, EnumFromTrait}; use ethereum_types::{Address as EthAddress, H256, H264, H520, U256}; @@ -64,8 +70,10 @@ use mm2_core::mm_ctx::{from_ctx, MmArc}; use mm2_err_handle::prelude::*; use mm2_metrics::MetricsWeak; use mm2_number::BigRational; -use mm2_number::{bigdecimal::{BigDecimal, ParseBigDecimalError, Zero}, - BigUint, MmNumber, ParseBigIntError}; +use mm2_number::{ + bigdecimal::{BigDecimal, ParseBigDecimalError, Zero}, + BigUint, MmNumber, ParseBigIntError, +}; use mm2_rpc::data::legacy::{EnabledCoin, GetEnabledResponse, Mm2RpcResult}; #[cfg(any(test, feature = "for-tests"))] use mocktopus::macros::*; @@ -213,22 +221,28 @@ pub mod lp_price; pub mod watcher_common; pub mod coin_errors; -use coin_errors::{AddressFromPubkeyError, MyAddressError, ValidatePaymentError, ValidatePaymentFut, - ValidatePaymentResult}; +use coin_errors::{ + AddressFromPubkeyError, MyAddressError, ValidatePaymentError, ValidatePaymentFut, ValidatePaymentResult, +}; use crypto::secret_hash_algo::SecretHashAlgo; pub mod eth; use eth::erc20::get_erc20_ticker_by_contract_address; use eth::eth_swap_v2::{PrepareTxDataError, ValidatePaymentV2Err}; -use eth::{eth_coin_from_conf_and_request, get_eth_address, EthCoin, EthGasDetailsErr, EthTxFeeDetails, - GetEthAddressError, GetValidEthWithdrawAddError, SignedEthTx}; +use eth::{ + eth_coin_from_conf_and_request, get_eth_address, EthCoin, EthGasDetailsErr, EthTxFeeDetails, GetEthAddressError, + GetValidEthWithdrawAddError, SignedEthTx, +}; pub mod hd_wallet; -use hd_wallet::{AccountUpdatingError, AddressDerivingError, HDAccountOps, HDAddressId, HDAddressOps, - HDAddressSelector, HDCoinAddress, HDCoinHDAccount, HDExtractPubkeyError, HDPathAccountToAddressId, - HDWalletAddress, HDWalletCoinOps, HDWalletOps, HDWithdrawError, HDXPubExtractor, WithdrawSenderAddress}; +use hd_wallet::{ + AccountUpdatingError, AddressDerivingError, HDAccountOps, HDAddressId, HDAddressOps, HDAddressSelector, + HDCoinAddress, HDCoinHDAccount, HDExtractPubkeyError, HDPathAccountToAddressId, HDWalletAddress, HDWalletCoinOps, + HDWalletOps, HDWithdrawError, HDXPubExtractor, WithdrawSenderAddress, +}; -#[cfg(not(target_arch = "wasm32"))] pub mod lightning; +#[cfg(not(target_arch = "wasm32"))] +pub mod lightning; #[cfg_attr(target_arch = "wasm32", allow(dead_code, unused_imports))] pub mod my_tx_history_v2; @@ -236,16 +250,20 @@ pub mod qrc20; use qrc20::{qrc20_coin_with_policy, Qrc20ActivationParams, Qrc20Coin, Qrc20FeeDetails}; pub mod rpc_command; -use rpc_command::{get_new_address::{GetNewAddressTaskManager, GetNewAddressTaskManagerShared}, - init_account_balance::{AccountBalanceTaskManager, AccountBalanceTaskManagerShared}, - init_create_account::{CreateAccountTaskManager, CreateAccountTaskManagerShared}, - init_scan_for_new_addresses::{ScanAddressesTaskManager, ScanAddressesTaskManagerShared}, - init_withdraw::{WithdrawTaskManager, WithdrawTaskManagerShared}}; +use rpc_command::{ + get_new_address::{GetNewAddressTaskManager, GetNewAddressTaskManagerShared}, + init_account_balance::{AccountBalanceTaskManager, AccountBalanceTaskManagerShared}, + init_create_account::{CreateAccountTaskManager, CreateAccountTaskManagerShared}, + init_scan_for_new_addresses::{ScanAddressesTaskManager, ScanAddressesTaskManagerShared}, + init_withdraw::{WithdrawTaskManager, WithdrawTaskManagerShared}, +}; pub mod tendermint; use tendermint::htlc::CustomTendermintMsgType; -use tendermint::{CosmosTransaction, TendermintCoin, TendermintFeeDetails, TendermintProtocolInfo, TendermintToken, - TendermintTokenProtocolInfo}; +use tendermint::{ + CosmosTransaction, TendermintCoin, TendermintFeeDetails, TendermintProtocolInfo, TendermintToken, + TendermintTokenProtocolInfo, +}; #[doc(hidden)] #[allow(unused_variables)] @@ -256,13 +274,17 @@ pub use test_coin::TestCoin; pub mod tx_history_storage; -#[cfg(feature = "enable-sia")] pub mod siacoin; -#[cfg(feature = "enable-sia")] use siacoin::SiaCoin; +#[cfg(feature = "enable-sia")] +pub mod siacoin; +#[cfg(feature = "enable-sia")] +use siacoin::SiaCoin; pub mod utxo; use utxo::bch::{bch_coin_with_policy, BchActivationRequest, BchCoin}; -use utxo::qtum::{self, qtum_coin_with_policy, Qrc20AddressError, QtumCoin, QtumDelegationOps, QtumDelegationRequest, - QtumStakingInfosDetails, ScriptHashTypeNotSupported}; +use utxo::qtum::{ + self, qtum_coin_with_policy, Qrc20AddressError, QtumCoin, QtumDelegationOps, QtumDelegationRequest, + QtumStakingInfosDetails, ScriptHashTypeNotSupported, +}; use utxo::rpc_clients::UtxoRpcError; use utxo::slp::SlpToken; use utxo::slp::{slp_addr_from_pubkey_str, SlpFeeDetails}; @@ -394,7 +416,9 @@ pub enum GetMyAddressError { } impl From for GetMyAddressError { - fn from(e: GetEthAddressError) -> Self { GetMyAddressError::GetEthAddressError(e) } + fn from(e: GetEthAddressError) -> Self { + GetMyAddressError::GetEthAddressError(e) + } } impl HttpStatusCode for GetMyAddressError { @@ -601,10 +625,14 @@ ifrom!(TransactionEnum, LightningPayment); impl TransactionEnum { #[cfg(not(target_arch = "wasm32"))] - pub fn supports_tx_helper(&self) -> bool { !matches!(self, TransactionEnum::LightningPayment(_)) } + pub fn supports_tx_helper(&self) -> bool { + !matches!(self, TransactionEnum::LightningPayment(_)) + } #[cfg(target_arch = "wasm32")] - pub fn supports_tx_helper(&self) -> bool { true } + pub fn supports_tx_helper(&self) -> bool { + true + } } // NB: When stable and groked by IDEs, `enum_dispatch` can be used instead of `Deref` to speed things up. @@ -664,7 +692,9 @@ impl TransactionErr { } impl std::fmt::Display for TransactionErr { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", self.get_plain_text_format()) } + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.get_plain_text_format()) + } } #[derive(Debug, PartialEq)] @@ -1052,7 +1082,9 @@ pub enum ValidateInstructionsErr { #[cfg(not(target_arch = "wasm32"))] impl From for ValidateInstructionsErr { - fn from(e: ParseOrSemanticError) -> Self { ValidateInstructionsErr::ValidateLightningInvoiceErr(e.to_string()) } + fn from(e: ParseOrSemanticError) -> Self { + ValidateInstructionsErr::ValidateLightningInvoiceErr(e.to_string()) + } } #[derive(Display)] @@ -1136,7 +1168,9 @@ pub trait SwapOps { /// Whether the swap payment is refunded automatically or not when the locktime expires, or the other side fails the HTLC. /// lightning specific - fn is_auto_refundable(&self) -> bool { false } + fn is_auto_refundable(&self) -> bool { + false + } /// Waits for an htlc to be refunded automatically. - lightning specific async fn wait_for_htlc_refund(&self, _tx: &[u8], _locktime: u64) -> RefundResult<()> { @@ -1197,14 +1231,22 @@ pub trait SwapOps { )) } - fn is_supported_by_watchers(&self) -> bool { false } + fn is_supported_by_watchers(&self) -> bool { + false + } // Do we also need a method for the fallback contract? - fn contract_supports_watchers(&self) -> bool { true } + fn contract_supports_watchers(&self) -> bool { + true + } - fn maker_locktime_multiplier(&self) -> f64 { 2.0 } + fn maker_locktime_multiplier(&self) -> f64 { + 2.0 + } - fn dex_pubkey(&self) -> &[u8] { &DEX_FEE_ADDR_RAW_PUBKEY } + fn dex_pubkey(&self) -> &[u8] { + &DEX_FEE_ADDR_RAW_PUBKEY + } fn burn_pubkey(&self) -> &[u8] { #[cfg(feature = "for-tests")] @@ -1224,22 +1266,30 @@ pub trait SwapOps { /// Performs an action on Maker coin payment just before the Taker Swap payment refund begins /// Operation on maker coin from taker swap side /// Currently lightning specific - async fn on_taker_payment_refund_start(&self, _maker_payment: &[u8]) -> RefundResult<()> { Ok(()) } + async fn on_taker_payment_refund_start(&self, _maker_payment: &[u8]) -> RefundResult<()> { + Ok(()) + } /// Performs an action on Maker coin payment after the Taker Swap payment is refunded successfully /// Operation on maker coin from taker swap side /// Currently lightning specific - async fn on_taker_payment_refund_success(&self, _maker_payment: &[u8]) -> RefundResult<()> { Ok(()) } + async fn on_taker_payment_refund_success(&self, _maker_payment: &[u8]) -> RefundResult<()> { + Ok(()) + } /// Performs an action on Taker coin payment just before the Maker Swap payment refund begins /// Operation on taker coin from maker swap side /// Currently lightning specific - async fn on_maker_payment_refund_start(&self, _taker_payment: &[u8]) -> RefundResult<()> { Ok(()) } + async fn on_maker_payment_refund_start(&self, _taker_payment: &[u8]) -> RefundResult<()> { + Ok(()) + } /// Performs an action on Taker coin payment after the Maker Swap payment is refunded successfully /// Operation on taker coin from maker swap side /// Currently lightning specific - async fn on_maker_payment_refund_success(&self, _taker_payment: &[u8]) -> RefundResult<()> { Ok(()) } + async fn on_maker_payment_refund_success(&self, _taker_payment: &[u8]) -> RefundResult<()> { + Ok(()) + } } #[async_trait] @@ -1496,15 +1546,21 @@ pub enum TxGenError { } impl From for TxGenError { - fn from(err: UtxoRpcError) -> Self { TxGenError::Rpc(err.to_string()) } + fn from(err: UtxoRpcError) -> Self { + TxGenError::Rpc(err.to_string()) + } } impl From for TxGenError { - fn from(err: NumConversError) -> Self { TxGenError::NumConversion(err.to_string()) } + fn from(err: NumConversError) -> Self { + TxGenError::NumConversion(err.to_string()) + } } impl From for TxGenError { - fn from(err: UtxoSignWithKeyPairError) -> Self { TxGenError::Signing(err.to_string()) } + fn from(err: UtxoSignWithKeyPairError) -> Self { + TxGenError::Signing(err.to_string()) + } } /// Enum covering error cases that can happen during swap v2 transaction validation. @@ -1541,11 +1597,15 @@ pub enum ValidateSwapV2TxError { } impl From for ValidateSwapV2TxError { - fn from(err: NumConversError) -> Self { ValidateSwapV2TxError::NumConversion(err.to_string()) } + fn from(err: NumConversError) -> Self { + ValidateSwapV2TxError::NumConversion(err.to_string()) + } } impl From for ValidateSwapV2TxError { - fn from(err: UtxoRpcError) -> Self { ValidateSwapV2TxError::Rpc(err.to_string()) } + fn from(err: UtxoRpcError) -> Self { + ValidateSwapV2TxError::Rpc(err.to_string()) + } } impl From for ValidateSwapV2TxError { @@ -1589,7 +1649,9 @@ pub enum ValidateTakerFundingSpendPreimageError { } impl From for ValidateTakerFundingSpendPreimageError { - fn from(err: TxGenError) -> Self { ValidateTakerFundingSpendPreimageError::TxGenError(format!("{:?}", err)) } + fn from(err: TxGenError) -> Self { + ValidateTakerFundingSpendPreimageError::TxGenError(format!("{:?}", err)) + } } /// Enum covering error cases that can happen during taker payment spend preimage validation. @@ -1609,7 +1671,9 @@ pub enum ValidateTakerPaymentSpendPreimageError { } impl From for ValidateTakerPaymentSpendPreimageError { - fn from(err: TxGenError) -> Self { ValidateTakerPaymentSpendPreimageError::TxGenError(format!("{:?}", err)) } + fn from(err: TxGenError) -> Self { + ValidateTakerPaymentSpendPreimageError::TxGenError(format!("{:?}", err)) + } } /// Helper trait used for various types serialization to bytes @@ -2021,7 +2085,9 @@ pub trait TakerCoinSwapOpsV2: ParseCoinAssocTypes + CommonSwapOpsV2 + Send + Syn /// A bool flag that allows skipping the generation and P2P message broadcasting of `TakerPaymentSpendPreimage` on the Taker side, /// as well as its reception and validation on the Maker side. /// This is typically used for coins that rely on smart contracts. - fn skip_taker_payment_spend_preimage(&self) -> bool { false } + fn skip_taker_payment_spend_preimage(&self) -> bool { + false + } /// Generates and signs taker payment spend preimage. The preimage and signature should be /// shared with maker to proceed with protocol execution. @@ -2145,10 +2211,14 @@ pub trait MarketCoinOps { fn min_trading_vol(&self) -> MmNumber; /// Is privacy coin like zcash or pirate - fn is_privacy(&self) -> bool { false } + fn is_privacy(&self) -> bool { + false + } /// Returns `true` for coins (like KMD) that should use direct DEX fee burning via OP_RETURN. - fn should_burn_directly(&self) -> bool { false } + fn should_burn_directly(&self) -> bool { + false + } /// Should burn part of dex fee coin fn should_burn_dex_fee(&self) -> bool; @@ -2331,7 +2401,9 @@ pub enum StakingInfosDetails { } impl From for StakingInfosDetails { - fn from(qtum_staking_infos: QtumStakingInfosDetails) -> Self { StakingInfosDetails::Qtum(qtum_staking_infos) } + fn from(qtum_staking_infos: QtumStakingInfosDetails) -> Self { + StakingInfosDetails::Qtum(qtum_staking_infos) + } } #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] @@ -2386,19 +2458,27 @@ impl<'de> Deserialize<'de> for TxFeeDetails { } impl From for TxFeeDetails { - fn from(eth_details: EthTxFeeDetails) -> Self { TxFeeDetails::Eth(eth_details) } + fn from(eth_details: EthTxFeeDetails) -> Self { + TxFeeDetails::Eth(eth_details) + } } impl From for TxFeeDetails { - fn from(utxo_details: UtxoFeeDetails) -> Self { TxFeeDetails::Utxo(utxo_details) } + fn from(utxo_details: UtxoFeeDetails) -> Self { + TxFeeDetails::Utxo(utxo_details) + } } impl From for TxFeeDetails { - fn from(qrc20_details: Qrc20FeeDetails) -> Self { TxFeeDetails::Qrc20(qrc20_details) } + fn from(qrc20_details: Qrc20FeeDetails) -> Self { + TxFeeDetails::Qrc20(qrc20_details) + } } impl From for TxFeeDetails { - fn from(tendermint_details: TendermintFeeDetails) -> Self { TxFeeDetails::Tendermint(tendermint_details) } + fn from(tendermint_details: TendermintFeeDetails) -> Self { + TxFeeDetails::Tendermint(tendermint_details) + } } #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] @@ -2488,9 +2568,13 @@ pub enum TransactionData { } impl TransactionData { - pub fn new_signed(tx_hex: BytesJson, tx_hash: String) -> Self { Self::Signed { tx_hex, tx_hash } } + pub fn new_signed(tx_hex: BytesJson, tx_hash: String) -> Self { + Self::Signed { tx_hex, tx_hash } + } - pub fn new_unsigned(unsigned_tx_data: Json) -> Self { Self::Unsigned(unsigned_tx_data) } + pub fn new_unsigned(unsigned_tx_data: Json) -> Self { + Self::Unsigned(unsigned_tx_data) + } pub fn tx_hex(&self) -> Option<&BytesJson> { match self { @@ -2528,7 +2612,9 @@ impl TransactionDetails { self.timestamp == 0 } - pub fn should_update_kmd_rewards(&self) -> bool { self.coin == "KMD" && self.kmd_rewards.is_none() } + pub fn should_update_kmd_rewards(&self) -> bool { + self.coin == "KMD" && self.kmd_rewards.is_none() + } pub fn firo_negative_fee(&self) -> bool { match &self.fee_details { @@ -2558,7 +2644,9 @@ pub struct TradeFee { pub type CoinBalanceMap = HashMap; impl BalanceObjectOps for CoinBalanceMap { - fn new() -> Self { HashMap::new() } + fn new() -> Self { + HashMap::new() + } fn add(&mut self, other: Self) { for (ticker, balance) in other { @@ -2567,7 +2655,9 @@ impl BalanceObjectOps for CoinBalanceMap { } } - fn get_total_for_ticker(&self, ticker: &str) -> Option { self.get(ticker).map(|b| b.get_total()) } + fn get_total_for_ticker(&self, ticker: &str) -> Option { + self.get(ticker).map(|b| b.get_total()) + } } #[derive(Clone, Debug, Default, PartialEq, PartialOrd, Serialize)] @@ -2577,11 +2667,17 @@ pub struct CoinBalance { } impl BalanceObjectOps for CoinBalance { - fn new() -> Self { CoinBalance::default() } + fn new() -> Self { + CoinBalance::default() + } - fn add(&mut self, other: Self) { *self += other; } + fn add(&mut self, other: Self) { + *self += other; + } - fn get_total_for_ticker(&self, _ticker: &str) -> Option { Some(self.get_total()) } + fn get_total_for_ticker(&self, _ticker: &str) -> Option { + Some(self.get_total()) + } } impl CoinBalance { @@ -2592,9 +2688,13 @@ impl CoinBalance { } } - pub fn into_total(self) -> BigDecimal { self.spendable + self.unspendable } + pub fn into_total(self) -> BigDecimal { + self.spendable + self.unspendable + } - pub fn get_total(&self) -> BigDecimal { &self.spendable + &self.unspendable } + pub fn get_total(&self) -> BigDecimal { + &self.spendable + &self.unspendable + } } impl Add for CoinBalance { @@ -2768,13 +2868,19 @@ impl TradePreimageError { pub struct NumConversError(String); impl From for NumConversError { - fn from(e: ParseBigDecimalError) -> Self { NumConversError::new(e.to_string()) } + fn from(e: ParseBigDecimalError) -> Self { + NumConversError::new(e.to_string()) + } } impl NumConversError { - pub fn new(description: String) -> NumConversError { NumConversError(description) } + pub fn new(description: String) -> NumConversError { + NumConversError(description) + } - pub fn description(&self) -> &str { &self.0 } + pub fn description(&self) -> &str { + &self.0 + } } #[derive(Clone, Debug, Display, EnumFromStringify, PartialEq, Serialize, SerializeErrorType)] @@ -2801,7 +2907,9 @@ pub enum GetNonZeroBalance { } impl From for BalanceError { - fn from(e: AddressDerivingError) -> Self { BalanceError::Internal(e.to_string()) } + fn from(e: AddressDerivingError) -> Self { + BalanceError::Internal(e.to_string()) + } } impl From for BalanceError { @@ -2818,11 +2926,15 @@ impl From for BalanceError { } impl From for GetNonZeroBalance { - fn from(e: BalanceError) -> Self { GetNonZeroBalance::MyBalanceError(e) } + fn from(e: BalanceError) -> Self { + GetNonZeroBalance::MyBalanceError(e) + } } impl From for BalanceError { - fn from(e: UnexpectedDerivationMethod) -> Self { BalanceError::UnexpectedDerivationMethod(e) } + fn from(e: UnexpectedDerivationMethod) -> Self { + BalanceError::UnexpectedDerivationMethod(e) + } } #[derive(Debug, Deserialize, Display, EnumFromStringify, Serialize, SerializeErrorType)] @@ -3003,7 +3115,9 @@ impl From for DelegationError { } impl From for DelegationError { - fn from(e: PrivKeyPolicyNotAllowed) -> Self { DelegationError::DelegationOpsNotSupported { reason: e.to_string() } } + fn from(e: PrivKeyPolicyNotAllowed) -> Self { + DelegationError::DelegationOpsNotSupported { reason: e.to_string() } + } } impl From for DelegationError { @@ -3284,7 +3398,9 @@ impl From for WithdrawError { } impl From for WithdrawError { - fn from(e: TimeoutError) -> Self { WithdrawError::Timeout(e.duration) } + fn from(e: TimeoutError) -> Self { + WithdrawError::Timeout(e.duration) + } } impl From for WithdrawError { @@ -3528,7 +3644,9 @@ pub trait MmCoin: SwapOps + WatcherOps + MarketCoinOps + Send + Sync + 'static { } #[cfg(not(target_arch = "wasm32"))] - fn get_tx_history_migration(&self, ctx: &MmArc) -> TxHistoryFut { get_tx_history_migration_impl(self, ctx) } + fn get_tx_history_migration(&self, ctx: &MmArc) -> TxHistoryFut { + get_tx_history_migration_impl(self, ctx) + } #[cfg(not(target_arch = "wasm32"))] fn update_migration_file(&self, ctx: &MmArc, migration_number: u64) -> TxHistoryFut<()> { @@ -3646,54 +3764,78 @@ pub enum MmCoinEnum { } impl From for MmCoinEnum { - fn from(c: UtxoStandardCoin) -> MmCoinEnum { MmCoinEnum::UtxoCoin(c) } + fn from(c: UtxoStandardCoin) -> MmCoinEnum { + MmCoinEnum::UtxoCoin(c) + } } impl From for MmCoinEnum { - fn from(c: EthCoin) -> MmCoinEnum { MmCoinEnum::EthCoin(c) } + fn from(c: EthCoin) -> MmCoinEnum { + MmCoinEnum::EthCoin(c) + } } #[cfg(any(test, feature = "for-tests"))] impl From for MmCoinEnum { - fn from(c: TestCoin) -> MmCoinEnum { MmCoinEnum::Test(c) } + fn from(c: TestCoin) -> MmCoinEnum { + MmCoinEnum::Test(c) + } } impl From for MmCoinEnum { - fn from(coin: QtumCoin) -> Self { MmCoinEnum::QtumCoin(coin) } + fn from(coin: QtumCoin) -> Self { + MmCoinEnum::QtumCoin(coin) + } } impl From for MmCoinEnum { - fn from(c: Qrc20Coin) -> MmCoinEnum { MmCoinEnum::Qrc20Coin(c) } + fn from(c: Qrc20Coin) -> MmCoinEnum { + MmCoinEnum::Qrc20Coin(c) + } } impl From for MmCoinEnum { - fn from(c: BchCoin) -> MmCoinEnum { MmCoinEnum::Bch(c) } + fn from(c: BchCoin) -> MmCoinEnum { + MmCoinEnum::Bch(c) + } } impl From for MmCoinEnum { - fn from(c: SlpToken) -> MmCoinEnum { MmCoinEnum::SlpToken(c) } + fn from(c: SlpToken) -> MmCoinEnum { + MmCoinEnum::SlpToken(c) + } } impl From for MmCoinEnum { - fn from(c: TendermintCoin) -> Self { MmCoinEnum::Tendermint(c) } + fn from(c: TendermintCoin) -> Self { + MmCoinEnum::Tendermint(c) + } } impl From for MmCoinEnum { - fn from(c: TendermintToken) -> Self { MmCoinEnum::TendermintToken(c) } + fn from(c: TendermintToken) -> Self { + MmCoinEnum::TendermintToken(c) + } } #[cfg(not(target_arch = "wasm32"))] impl From for MmCoinEnum { - fn from(c: LightningCoin) -> MmCoinEnum { MmCoinEnum::LightningCoin(c) } + fn from(c: LightningCoin) -> MmCoinEnum { + MmCoinEnum::LightningCoin(c) + } } impl From for MmCoinEnum { - fn from(c: ZCoin) -> MmCoinEnum { MmCoinEnum::ZCoin(c) } + fn from(c: ZCoin) -> MmCoinEnum { + MmCoinEnum::ZCoin(c) + } } #[cfg(feature = "enable-sia")] impl From for MmCoinEnum { - fn from(c: SiaCoin) -> MmCoinEnum { MmCoinEnum::SiaCoin(c) } + fn from(c: SiaCoin) -> MmCoinEnum { + MmCoinEnum::SiaCoin(c) + } } // NB: When stable and groked by IDEs, `enum_dispatch` can be used instead of `Deref` to speed things up. @@ -3734,9 +3876,13 @@ impl MmCoinEnum { } } - pub fn is_eth(&self) -> bool { matches!(self, MmCoinEnum::EthCoin(_)) } + pub fn is_eth(&self) -> bool { + matches!(self, MmCoinEnum::EthCoin(_)) + } - fn is_platform_coin(&self) -> bool { self.ticker() == self.platform_ticker() } + fn is_platform_coin(&self) -> bool { + self.ticker() == self.platform_ticker() + } /// Determines the secret hash algorithm for a coin, prioritizing specific algorithms for certain protocols. /// # Attention @@ -4184,7 +4330,9 @@ impl CoinsContext { } #[inline(always)] - pub async fn lock_coins(&self) -> AsyncMutexGuard> { self.coins.lock().await } + pub async fn lock_coins(&self) -> AsyncMutexGuard> { + self.coins.lock().await + } } /// This enum is used in coin activation requests. @@ -4196,7 +4344,9 @@ pub enum PrivKeyActivationPolicy { } impl PrivKeyActivationPolicy { - pub fn is_hw_policy(&self) -> bool { matches!(self, PrivKeyActivationPolicy::Trezor) } + pub fn is_hw_policy(&self) -> bool { + matches!(self, PrivKeyActivationPolicy::Trezor) + } } /// Enum representing various private key management policies. @@ -4263,7 +4413,9 @@ pub struct EthMetamaskPolicy { } impl From for PrivKeyPolicy { - fn from(key_pair: T) -> Self { PrivKeyPolicy::Iguana(key_pair) } + fn from(key_pair: T) -> Self { + PrivKeyPolicy::Iguana(key_pair) + } } impl PrivKeyPolicy { @@ -4340,7 +4492,9 @@ impl PrivKeyPolicy { .mm_err(|e| PrivKeyPolicyNotAllowed::InternalError(e.to_string())) } - fn is_trezor(&self) -> bool { matches!(self, PrivKeyPolicy::Trezor) } + fn is_trezor(&self) -> bool { + matches!(self, PrivKeyPolicy::Trezor) + } } /// 'CoinWithPrivKeyPolicy' trait is used to get the private key policy of a coin. @@ -4474,7 +4628,9 @@ where /// # Panic /// /// Panic if the address mode is [`DerivationMethod::HDWallet`]. - pub async fn unwrap_single_addr(&self) -> Address { self.single_addr_or_err().await.unwrap() } + pub async fn unwrap_single_addr(&self) -> Address { + self.single_addr_or_err().await.unwrap() + } pub async fn to_response(&self) -> MmResult { match self { @@ -4736,31 +4892,53 @@ pub type SharableRpcTransportEventHandler = dyn RpcTransportEventHandler + Send pub type RpcTransportEventHandlerShared = Arc; impl fmt::Debug for SharableRpcTransportEventHandler { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.debug_info()) } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.debug_info()) + } } impl RpcTransportEventHandler for RpcTransportEventHandlerShared { - fn debug_info(&self) -> String { self.deref().debug_info() } + fn debug_info(&self) -> String { + self.deref().debug_info() + } - fn on_outgoing_request(&self, data: &[u8]) { self.as_ref().on_outgoing_request(data) } + fn on_outgoing_request(&self, data: &[u8]) { + self.as_ref().on_outgoing_request(data) + } - fn on_incoming_response(&self, data: &[u8]) { self.as_ref().on_incoming_response(data) } + fn on_incoming_response(&self, data: &[u8]) { + self.as_ref().on_incoming_response(data) + } - fn on_connected(&self, address: &str) -> Result<(), String> { self.as_ref().on_connected(address) } + fn on_connected(&self, address: &str) -> Result<(), String> { + self.as_ref().on_connected(address) + } - fn on_disconnected(&self, address: &str) -> Result<(), String> { self.as_ref().on_disconnected(address) } + fn on_disconnected(&self, address: &str) -> Result<(), String> { + self.as_ref().on_disconnected(address) + } } impl RpcTransportEventHandler for Box { - fn debug_info(&self) -> String { self.as_ref().debug_info() } + fn debug_info(&self) -> String { + self.as_ref().debug_info() + } - fn on_outgoing_request(&self, data: &[u8]) { self.as_ref().on_outgoing_request(data) } + fn on_outgoing_request(&self, data: &[u8]) { + self.as_ref().on_outgoing_request(data) + } - fn on_incoming_response(&self, data: &[u8]) { self.as_ref().on_incoming_response(data) } + fn on_incoming_response(&self, data: &[u8]) { + self.as_ref().on_incoming_response(data) + } - fn on_connected(&self, address: &str) -> Result<(), String> { self.as_ref().on_connected(address) } + fn on_connected(&self, address: &str) -> Result<(), String> { + self.as_ref().on_connected(address) + } - fn on_disconnected(&self, address: &str) -> Result<(), String> { self.as_ref().on_disconnected(address) } + fn on_disconnected(&self, address: &str) -> Result<(), String> { + self.as_ref().on_disconnected(address) + } } impl RpcTransportEventHandler for Vec { @@ -4843,11 +5021,15 @@ impl CoinTransportMetrics { } } - fn into_shared(self) -> RpcTransportEventHandlerShared { Arc::new(self) } + fn into_shared(self) -> RpcTransportEventHandlerShared { + Arc::new(self) + } } impl RpcTransportEventHandler for CoinTransportMetrics { - fn debug_info(&self) -> String { "CoinTransportMetrics".into() } + fn debug_info(&self) -> String { + "CoinTransportMetrics".into() + } fn on_outgoing_request(&self, data: &[u8]) { mm_counter!(self.metrics, "rpc_client.traffic.out", data.len() as u64, @@ -4863,9 +5045,13 @@ impl RpcTransportEventHandler for CoinTransportMetrics { "coin" => self.ticker.to_owned(), "client" => self.client.to_owned()); } - fn on_connected(&self, _address: &str) -> Result<(), String> { Ok(()) } + fn on_connected(&self, _address: &str) -> Result<(), String> { + Ok(()) + } - fn on_disconnected(&self, _address: &str) -> Result<(), String> { Ok(()) } + fn on_disconnected(&self, _address: &str) -> Result<(), String> { + Ok(()) + } } #[async_trait] @@ -5842,7 +6028,9 @@ pub(crate) struct TxIdHeight { } impl TxIdHeight { - pub(crate) fn new(block_height: u64, tx_id: Id) -> TxIdHeight { TxIdHeight { block_height, tx_id } } + pub(crate) fn new(block_height: u64, tx_id: Id) -> TxIdHeight { + TxIdHeight { block_height, tx_id } + } } pub(crate) fn compare_transactions(a: TxIdHeight, b: TxIdHeight) -> Ordering @@ -6281,10 +6469,13 @@ pub mod for_tests { if now_ms() > timeout { panic!("{} init_withdraw timed out", ticker); } - let status = withdraw_status(ctx.clone(), WithdrawStatusRequest { - task_id: init.task_id, - forget_if_finished: true, - }) + let status = withdraw_status( + ctx.clone(), + WithdrawStatusRequest { + task_id: init.task_id, + forget_if_finished: true, + }, + ) .await; if let Ok(status) = status { match status { diff --git a/mm2src/coins/lp_price.rs b/mm2src/coins/lp_price.rs index f7cd971415..1d5d0e5c85 100644 --- a/mm2src/coins/lp_price.rs +++ b/mm2src/coins/lp_price.rs @@ -7,7 +7,8 @@ use mm2_number::bigdecimal_custom::CheckedDivision; use mm2_number::{BigDecimal, MmNumber}; use num_traits::CheckedDiv; use std::collections::HashMap; -#[cfg(feature = "run-docker-tests")] use std::str::FromStr; +#[cfg(feature = "run-docker-tests")] +use std::str::FromStr; use std::str::Utf8Error; pub const PRICE_ENDPOINTS: [&str; 3] = [ @@ -24,15 +25,21 @@ pub enum PriceServiceRequestError { } impl From for PriceServiceRequestError { - fn from(error: serde_json::Error) -> Self { PriceServiceRequestError::ParsingAnswerError(error.to_string()) } + fn from(error: serde_json::Error) -> Self { + PriceServiceRequestError::ParsingAnswerError(error.to_string()) + } } impl From for PriceServiceRequestError { - fn from(error: String) -> Self { PriceServiceRequestError::HttpProcessError(error) } + fn from(error: String) -> Self { + PriceServiceRequestError::HttpProcessError(error) + } } impl From for PriceServiceRequestError { - fn from(error: Utf8Error) -> Self { PriceServiceRequestError::HttpProcessError(error.to_string()) } + fn from(error: Utf8Error) -> Self { + PriceServiceRequestError::HttpProcessError(error.to_string()) + } } impl From for PriceServiceRequestError { @@ -321,56 +328,65 @@ mod tests { assert_eq!(rates.base_provider, Provider::Unknown); assert_eq!(rates.rel_provider, Provider::Unknown); - registry.0.insert("KMD".to_string(), TickerInfos { - ticker: "KMD".to_string(), - last_price: MmNumber::from("10"), - last_updated: "".to_string(), - last_updated_timestamp: SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .unwrap() - .as_secs(), - volume24_h: MmNumber::from("25000"), - price_provider: Provider::Binance, - volume_provider: Provider::Coinpaprika, - sparkline_7_d: None, - sparkline_provider: Default::default(), - change_24_h: MmNumber::default(), - change_24_h_provider: Default::default(), - }); - - registry.0.insert("LTC".to_string(), TickerInfos { - ticker: "LTC".to_string(), - last_price: MmNumber::from("500.0"), - last_updated: "".to_string(), - last_updated_timestamp: SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .unwrap() - .as_secs(), - volume24_h: MmNumber::from("25000"), - price_provider: Provider::Coingecko, - volume_provider: Provider::Binance, - sparkline_7_d: None, - sparkline_provider: Default::default(), - change_24_h: MmNumber::default(), - change_24_h_provider: Default::default(), - }); - - registry.0.insert("USDT".to_string(), TickerInfos { - ticker: "USDT".to_string(), - last_price: MmNumber::from("1"), - last_updated: "".to_string(), - last_updated_timestamp: SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .unwrap() - .as_secs(), - volume24_h: MmNumber::from("25000"), - price_provider: Provider::Coingecko, - volume_provider: Provider::Binance, - sparkline_7_d: None, - sparkline_provider: Default::default(), - change_24_h: MmNumber::default(), - change_24_h_provider: Default::default(), - }); + registry.0.insert( + "KMD".to_string(), + TickerInfos { + ticker: "KMD".to_string(), + last_price: MmNumber::from("10"), + last_updated: "".to_string(), + last_updated_timestamp: SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_secs(), + volume24_h: MmNumber::from("25000"), + price_provider: Provider::Binance, + volume_provider: Provider::Coinpaprika, + sparkline_7_d: None, + sparkline_provider: Default::default(), + change_24_h: MmNumber::default(), + change_24_h_provider: Default::default(), + }, + ); + + registry.0.insert( + "LTC".to_string(), + TickerInfos { + ticker: "LTC".to_string(), + last_price: MmNumber::from("500.0"), + last_updated: "".to_string(), + last_updated_timestamp: SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_secs(), + volume24_h: MmNumber::from("25000"), + price_provider: Provider::Coingecko, + volume_provider: Provider::Binance, + sparkline_7_d: None, + sparkline_provider: Default::default(), + change_24_h: MmNumber::default(), + change_24_h_provider: Default::default(), + }, + ); + + registry.0.insert( + "USDT".to_string(), + TickerInfos { + ticker: "USDT".to_string(), + last_price: MmNumber::from("1"), + last_updated: "".to_string(), + last_updated_timestamp: SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_secs(), + volume24_h: MmNumber::from("25000"), + price_provider: Provider::Coingecko, + volume_provider: Provider::Binance, + sparkline_7_d: None, + sparkline_provider: Default::default(), + change_24_h: MmNumber::default(), + change_24_h_provider: Default::default(), + }, + ); let rates = registry.get_cex_rates("KMD", "LTC").unwrap_or_default(); assert_eq!(rates.base_provider, Provider::Binance); diff --git a/mm2src/coins/my_tx_history_v2.rs b/mm2src/coins/my_tx_history_v2.rs index 02ed54d214..78de7c9215 100644 --- a/mm2src/coins/my_tx_history_v2.rs +++ b/mm2src/coins/my_tx_history_v2.rs @@ -1,12 +1,16 @@ use crate::hd_wallet::{AddressDerivingError, DisplayAddress, InvalidBip44ChainError}; -use crate::tendermint::{BCH_COIN_PROTOCOL_TYPE, BCH_TOKEN_PROTOCOL_TYPE, TENDERMINT_ASSET_PROTOCOL_TYPE, - TENDERMINT_COIN_PROTOCOL_TYPE}; -use crate::tx_history_storage::{CreateTxHistoryStorageError, FilteringAddresses, GetTxHistoryFilters, - TxHistoryStorageBuilder, WalletId}; +use crate::tendermint::{ + BCH_COIN_PROTOCOL_TYPE, BCH_TOKEN_PROTOCOL_TYPE, TENDERMINT_ASSET_PROTOCOL_TYPE, TENDERMINT_COIN_PROTOCOL_TYPE, +}; +use crate::tx_history_storage::{ + CreateTxHistoryStorageError, FilteringAddresses, GetTxHistoryFilters, TxHistoryStorageBuilder, WalletId, +}; use crate::utxo::utxo_common::big_decimal_from_sat_unsigned; -use crate::{coin_conf, lp_coinfind_or_err, BlockHeightAndTime, CoinFindError, HDPathAccountToAddressId, - HistorySyncState, MmCoin, MmCoinEnum, MyAddressError, Transaction, TransactionData, TransactionDetails, - TransactionType, TxFeeDetails, UtxoRpcError}; +use crate::{ + coin_conf, lp_coinfind_or_err, BlockHeightAndTime, CoinFindError, HDPathAccountToAddressId, HistorySyncState, + MmCoin, MmCoinEnum, MyAddressError, Transaction, TransactionData, TransactionDetails, TransactionType, + TxFeeDetails, UtxoRpcError, +}; use async_trait::async_trait; use bitcrypto::sha256; use common::{calc_total_pages, ten, HttpStatusCode, PagingOptionsEnum, StatusCode}; @@ -27,7 +31,9 @@ pub enum RemoveTxResult { } impl RemoveTxResult { - pub fn tx_existed(&self) -> bool { matches!(self, RemoveTxResult::TxRemoved) } + pub fn tx_existed(&self) -> bool { + matches!(self, RemoveTxResult::TxRemoved) + } } pub struct GetHistoryResult { @@ -168,9 +174,13 @@ impl<'a, Addr: Clone + DisplayAddress + Eq + std::hash::Hash, Tx: Transaction> T } } - pub fn set_tx_fee(&mut self, tx_fee: Option) { self.tx_fee = tx_fee; } + pub fn set_tx_fee(&mut self, tx_fee: Option) { + self.tx_fee = tx_fee; + } - pub fn set_transaction_type(&mut self, tx_type: TransactionType) { self.transaction_type = tx_type; } + pub fn set_transaction_type(&mut self, tx_type: TransactionType) { + self.transaction_type = tx_type; + } pub fn transferred_to(&mut self, address: Addr, amount: &BigDecimal) { if self.my_addresses.contains(&address) { diff --git a/mm2src/coins/nft.rs b/mm2src/coins/nft.rs index 9c7ad4fa09..66236e62b5 100644 --- a/mm2src/coins/nft.rs +++ b/mm2src/coins/nft.rs @@ -9,23 +9,31 @@ pub(crate) mod nft_errors; pub mod nft_structs; pub(crate) mod storage; -#[cfg(any(test, target_arch = "wasm32"))] mod nft_tests; +#[cfg(any(test, target_arch = "wasm32"))] +mod nft_tests; use crate::hd_wallet::AddrToString; -use crate::{lp_coinfind_or_err, CoinWithDerivationMethod, CoinsContext, MarketCoinOps, MmCoinEnum, MmCoinStruct, - WithdrawError}; +use crate::{ + lp_coinfind_or_err, CoinWithDerivationMethod, CoinsContext, MarketCoinOps, MmCoinEnum, MmCoinStruct, WithdrawError, +}; use nft_errors::{GetNftInfoError, UpdateNftError}; -use nft_structs::{Chain, ContractType, ConvertChain, Nft, NftFromMoralis, NftList, NftListReq, NftMetadataReq, - NftTransferHistory, NftTransferHistoryFromMoralis, NftTransfersReq, NftsTransferHistoryList, - TransactionNftDetails, UpdateNftReq, WithdrawNftReq}; - -use crate::eth::{withdraw_erc1155, withdraw_erc721, EthCoin, EthCoinType, EthTxFeeDetails, LegacyGasPrice, - PayForGasOption}; -use crate::nft::nft_errors::{ClearNftDbError, MetaFromUrlError, ProtectFromSpamError, TransferConfirmationsError, - UpdateSpamPhishingError}; -use crate::nft::nft_structs::{build_nft_with_empty_meta, BuildNftFields, ClearNftDbReq, NftCommon, NftCtx, NftInfo, - NftTransferCommon, PhishingDomainReq, PhishingDomainRes, RefreshMetadataReq, - SpamContractReq, SpamContractRes, TransferMeta, TransferStatus, UriMeta}; +use nft_structs::{ + Chain, ContractType, ConvertChain, Nft, NftFromMoralis, NftList, NftListReq, NftMetadataReq, NftTransferHistory, + NftTransferHistoryFromMoralis, NftTransfersReq, NftsTransferHistoryList, TransactionNftDetails, UpdateNftReq, + WithdrawNftReq, +}; + +use crate::eth::{ + withdraw_erc1155, withdraw_erc721, EthCoin, EthCoinType, EthTxFeeDetails, LegacyGasPrice, PayForGasOption, +}; +use crate::nft::nft_errors::{ + ClearNftDbError, MetaFromUrlError, ProtectFromSpamError, TransferConfirmationsError, UpdateSpamPhishingError, +}; +use crate::nft::nft_structs::{ + build_nft_with_empty_meta, BuildNftFields, ClearNftDbReq, NftCommon, NftCtx, NftInfo, NftTransferCommon, + PhishingDomainReq, PhishingDomainRes, RefreshMetadataReq, SpamContractReq, SpamContractRes, TransferMeta, + TransferStatus, UriMeta, +}; #[cfg(not(target_arch = "wasm32"))] use crate::nft::storage::NftMigrationOps; use crate::nft::storage::{NftListStorageOps, NftTransferHistoryStorageOps}; diff --git a/mm2src/coins/nft/nft_errors.rs b/mm2src/coins/nft/nft_errors.rs index 74d5032cbe..2ba07951a5 100644 --- a/mm2src/coins/nft/nft_errors.rs +++ b/mm2src/coins/nft/nft_errors.rs @@ -3,8 +3,10 @@ use crate::eth::GetEthAddressError; #[cfg(target_arch = "wasm32")] use crate::nft::storage::wasm::WasmNftCacheError; use crate::nft::storage::NftStorageError; -use crate::{CoinFindError, GetMyAddressError, MyAddressError, NumConversError, PrivKeyPolicyNotAllowed, - UnexpectedDerivationMethod, WithdrawError}; +use crate::{ + CoinFindError, GetMyAddressError, MyAddressError, NumConversError, PrivKeyPolicyNotAllowed, + UnexpectedDerivationMethod, WithdrawError, +}; use common::{HttpStatusCode, ParseRfc3339Err}; #[cfg(not(target_arch = "wasm32"))] use db_common::sqlite::rusqlite::Error as SqlError; @@ -51,11 +53,15 @@ pub enum GetNftInfoError { } impl From for WithdrawError { - fn from(e: GetNftInfoError) -> Self { WithdrawError::GetNftInfoError(e) } + fn from(e: GetNftInfoError) -> Self { + WithdrawError::GetNftInfoError(e) + } } impl From for GetNftInfoError { - fn from(e: UnexpectedDerivationMethod) -> Self { GetNftInfoError::Internal(e.to_string()) } + fn from(e: UnexpectedDerivationMethod) -> Self { + GetNftInfoError::Internal(e.to_string()) + } } impl From for GetNftInfoError { @@ -84,11 +90,15 @@ impl From for GetNftInfoError { } impl From for GetNftInfoError { - fn from(e: GetEthAddressError) -> Self { GetNftInfoError::GetEthAddressError(e) } + fn from(e: GetEthAddressError) -> Self { + GetNftInfoError::GetEthAddressError(e) + } } impl From for GetNftInfoError { - fn from(err: T) -> Self { GetNftInfoError::DbError(format!("{:?}", err)) } + fn from(err: T) -> Self { + GetNftInfoError::DbError(format!("{:?}", err)) + } } impl From for GetNftInfoError { @@ -103,15 +113,21 @@ impl From for GetNftInfoError { } impl From for GetNftInfoError { - fn from(e: ParseRfc3339Err) -> Self { GetNftInfoError::ParseRfc3339Err(e) } + fn from(e: ParseRfc3339Err) -> Self { + GetNftInfoError::ParseRfc3339Err(e) + } } impl From for GetNftInfoError { - fn from(e: ProtectFromSpamError) -> Self { GetNftInfoError::ProtectFromSpamError(e) } + fn from(e: ProtectFromSpamError) -> Self { + GetNftInfoError::ProtectFromSpamError(e) + } } impl From for GetNftInfoError { - fn from(e: TransferConfirmationsError) -> Self { GetNftInfoError::TransferConfirmationsError(e) } + fn from(e: TransferConfirmationsError) -> Self { + GetNftInfoError::TransferConfirmationsError(e) + } } impl From for GetNftInfoError { @@ -221,27 +237,39 @@ pub enum UpdateNftError { } impl From for UpdateNftError { - fn from(e: GetNftInfoError) -> Self { UpdateNftError::GetNftInfoError(e) } + fn from(e: GetNftInfoError) -> Self { + UpdateNftError::GetNftInfoError(e) + } } impl From for UpdateNftError { - fn from(e: GetMyAddressError) -> Self { UpdateNftError::GetMyAddressError(e) } + fn from(e: GetMyAddressError) -> Self { + UpdateNftError::GetMyAddressError(e) + } } impl From for UpdateNftError { - fn from(err: T) -> Self { UpdateNftError::DbError(format!("{:?}", err)) } + fn from(err: T) -> Self { + UpdateNftError::DbError(format!("{:?}", err)) + } } impl From for UpdateNftError { - fn from(e: UpdateSpamPhishingError) -> Self { UpdateNftError::UpdateSpamPhishingError(e) } + fn from(e: UpdateSpamPhishingError) -> Self { + UpdateNftError::UpdateSpamPhishingError(e) + } } impl From for UpdateNftError { - fn from(e: GetInfoFromUriError) -> Self { UpdateNftError::GetInfoFromUriError(e) } + fn from(e: GetInfoFromUriError) -> Self { + UpdateNftError::GetInfoFromUriError(e) + } } impl From for UpdateNftError { - fn from(e: ProtectFromSpamError) -> Self { UpdateNftError::ProtectFromSpamError(e) } + fn from(e: ProtectFromSpamError) -> Self { + UpdateNftError::ProtectFromSpamError(e) + } } impl From for UpdateNftError { @@ -253,7 +281,9 @@ impl From for UpdateNftError { } impl From for UpdateNftError { - fn from(e: PrivKeyPolicyNotAllowed) -> Self { Self::PrivKeyPolicyNotAllowed(e) } + fn from(e: PrivKeyPolicyNotAllowed) -> Self { + Self::PrivKeyPolicyNotAllowed(e) + } } impl From for UpdateNftError { @@ -266,7 +296,9 @@ impl From for UpdateNftError { } impl From for UpdateNftError { - fn from(e: UnexpectedDerivationMethod) -> Self { Self::UnexpectedDerivationMethod(e) } + fn from(e: UnexpectedDerivationMethod) -> Self { + Self::UnexpectedDerivationMethod(e) + } } impl HttpStatusCode for UpdateNftError { @@ -328,7 +360,9 @@ pub enum UpdateSpamPhishingError { } impl From for UpdateSpamPhishingError { - fn from(e: GetMyAddressError) -> Self { UpdateSpamPhishingError::GetMyAddressError(e) } + fn from(e: GetMyAddressError) -> Self { + UpdateSpamPhishingError::GetMyAddressError(e) + } } impl From for UpdateSpamPhishingError { @@ -343,7 +377,9 @@ impl From for UpdateSpamPhishingError { } impl From for UpdateSpamPhishingError { - fn from(err: T) -> Self { UpdateSpamPhishingError::DbError(format!("{:?}", err)) } + fn from(err: T) -> Self { + UpdateSpamPhishingError::DbError(format!("{:?}", err)) + } } /// Errors encountered when parsing a `Chain` from a string. @@ -362,7 +398,9 @@ pub(crate) enum MetaFromUrlError { } impl From for MetaFromUrlError { - fn from(e: GetInfoFromUriError) -> Self { MetaFromUrlError::GetInfoFromUriError(e) } + fn from(e: GetInfoFromUriError) -> Self { + MetaFromUrlError::GetInfoFromUriError(e) + } } /// Represents errors that can occur while locking the NFT database. @@ -378,12 +416,16 @@ pub enum LockDBError { #[cfg(not(target_arch = "wasm32"))] impl From for LockDBError { - fn from(e: SqlError) -> Self { LockDBError::SqlError(e) } + fn from(e: SqlError) -> Self { + LockDBError::SqlError(e) + } } #[cfg(target_arch = "wasm32")] impl From for LockDBError { - fn from(e: WasmNftCacheError) -> Self { LockDBError::WasmNftCacheError(e) } + fn from(e: WasmNftCacheError) -> Self { + LockDBError::WasmNftCacheError(e) + } } /// Errors related to calculating transfer confirmations for NFTs. @@ -425,7 +467,9 @@ pub enum ClearNftDbError { } impl From for ClearNftDbError { - fn from(err: T) -> Self { ClearNftDbError::DbError(format!("{:?}", err)) } + fn from(err: T) -> Self { + ClearNftDbError::DbError(format!("{:?}", err)) + } } impl HttpStatusCode for ClearNftDbError { diff --git a/mm2src/coins/nft/nft_structs.rs b/mm2src/coins/nft/nft_structs.rs index cc2223da2b..7fe739772a 100644 --- a/mm2src/coins/nft/nft_structs.rs +++ b/mm2src/coins/nft/nft_structs.rs @@ -416,7 +416,9 @@ where impl std::ops::Deref for SerdeStringWrap { type Target = T; - fn deref(&self) -> &T { &self.0 } + fn deref(&self) -> &T { + &self.0 + } } /// Represents a detailed list of NFTs, including the total number of NFTs and the number of skipped NFTs. diff --git a/mm2src/coins/nft/nft_tests.rs b/mm2src/coins/nft/nft_tests.rs index c3574de55b..05e4ee78db 100644 --- a/mm2src/coins/nft/nft_tests.rs +++ b/mm2src/coins/nft/nft_tests.rs @@ -1,11 +1,14 @@ use crate::hd_wallet::AddrToString; -use crate::nft::nft_structs::{Chain, NftFromMoralis, NftListFilters, NftTransferHistoryFilters, - NftTransferHistoryFromMoralis, PhishingDomainReq, PhishingDomainRes, SpamContractReq, - SpamContractRes, TransferMeta}; +use crate::nft::nft_structs::{ + Chain, NftFromMoralis, NftListFilters, NftTransferHistoryFilters, NftTransferHistoryFromMoralis, PhishingDomainReq, + PhishingDomainRes, SpamContractReq, SpamContractRes, TransferMeta, +}; use crate::nft::storage::db_test_helpers::{get_nft_ctx, nft, nft_list, nft_transfer_history}; use crate::nft::storage::{NftListStorageOps, NftTransferHistoryStorageOps, RemoveNftResult}; -use crate::nft::{check_moralis_ipfs_bafy, get_domain_from_url, is_malicious, process_metadata_for_spam_link, - process_text_for_spam_link}; +use crate::nft::{ + check_moralis_ipfs_bafy, get_domain_from_url, is_malicious, process_metadata_for_spam_link, + process_text_for_spam_link, +}; use common::cross_test; use ethereum_types::Address; use mm2_net::transport::send_post_request_to_uri; diff --git a/mm2src/coins/nft/storage/db_test_helpers.rs b/mm2src/coins/nft/storage/db_test_helpers.rs index 2565be8f2e..a321b89d06 100644 --- a/mm2src/coins/nft/storage/db_test_helpers.rs +++ b/mm2src/coins/nft/storage/db_test_helpers.rs @@ -1,5 +1,6 @@ -use crate::nft::nft_structs::{Chain, ContractType, Nft, NftCommon, NftCtx, NftTransferCommon, NftTransferHistory, - TransferStatus, UriMeta}; +use crate::nft::nft_structs::{ + Chain, ContractType, Nft, NftCommon, NftCtx, NftTransferCommon, NftTransferHistory, TransferStatus, UriMeta, +}; use ethereum_types::Address; use mm2_number::{BigDecimal, BigUint}; #[cfg(not(target_arch = "wasm32"))] diff --git a/mm2src/coins/nft/storage/mod.rs b/mm2src/coins/nft/storage/mod.rs index b888cbdda9..7d87bacb26 100644 --- a/mm2src/coins/nft/storage/mod.rs +++ b/mm2src/coins/nft/storage/mod.rs @@ -1,6 +1,8 @@ use crate::eth::EthTxFeeDetails; -use crate::nft::nft_structs::{Chain, Nft, NftList, NftListFilters, NftTokenAddrId, NftTransferHistory, - NftTransferHistoryFilters, NftsTransferHistoryList, TransferMeta}; +use crate::nft::nft_structs::{ + Chain, Nft, NftList, NftListFilters, NftTokenAddrId, NftTransferHistory, NftTransferHistoryFilters, + NftsTransferHistoryList, TransferMeta, +}; use async_trait::async_trait; use ethereum_types::Address; use mm2_err_handle::mm_error::MmResult; @@ -12,8 +14,10 @@ use std::num::NonZeroUsize; #[cfg(any(test, target_arch = "wasm32"))] pub(crate) mod db_test_helpers; -#[cfg(not(target_arch = "wasm32"))] pub(crate) mod sql_storage; -#[cfg(target_arch = "wasm32")] pub(crate) mod wasm; +#[cfg(not(target_arch = "wasm32"))] +pub(crate) mod sql_storage; +#[cfg(target_arch = "wasm32")] +pub(crate) mod wasm; /// Represents the outcome of an attempt to remove an NFT. #[derive(Debug, PartialEq)] diff --git a/mm2src/coins/nft/storage/sql_storage.rs b/mm2src/coins/nft/storage/sql_storage.rs index 1829f8d500..e8d0e98d9f 100644 --- a/mm2src/coins/nft/storage/sql_storage.rs +++ b/mm2src/coins/nft/storage/sql_storage.rs @@ -1,9 +1,12 @@ use crate::hd_wallet::AddrToString; -use crate::nft::nft_structs::{Chain, ContractType, ConvertChain, Nft, NftCommon, NftList, NftListFilters, - NftTokenAddrId, NftTransferCommon, NftTransferHistory, NftTransferHistoryFilters, - NftsTransferHistoryList, TransferMeta, UriMeta}; -use crate::nft::storage::{get_offset_limit, NftDetailsJson, NftListStorageOps, NftMigrationOps, NftStorageError, - NftTransferHistoryStorageOps, RemoveNftResult, TransferDetailsJson}; +use crate::nft::nft_structs::{ + Chain, ContractType, ConvertChain, Nft, NftCommon, NftList, NftListFilters, NftTokenAddrId, NftTransferCommon, + NftTransferHistory, NftTransferHistoryFilters, NftsTransferHistoryList, TransferMeta, UriMeta, +}; +use crate::nft::storage::{ + get_offset_limit, NftDetailsJson, NftListStorageOps, NftMigrationOps, NftStorageError, + NftTransferHistoryStorageOps, RemoveNftResult, TransferDetailsJson, +}; use async_trait::async_trait; use db_common::async_sql_conn::{AsyncConnError, AsyncConnection, InternalError}; use db_common::sql_build::{SqlCondition, SqlQuery}; @@ -531,9 +534,13 @@ fn delete_nft_sql(safe_table_name: SafeTableName) -> Result { Ok(sql) } -fn block_number_from_row(row: &Row<'_>) -> Result { row.get::<_, i64>(0) } +fn block_number_from_row(row: &Row<'_>) -> Result { + row.get::<_, i64>(0) +} -fn nft_amount_from_row(row: &Row<'_>) -> Result { row.get(0) } +fn nft_amount_from_row(row: &Row<'_>) -> Result { + row.get(0) +} fn get_nfts_by_token_address_statement( conn: &Connection, @@ -1027,10 +1034,10 @@ impl NftTransferHistoryStorageOps for AsyncMutexGuard<'_, AsyncConnection> { self.call(move |conn| { conn.execute(&sql_transfer_history, []).map(|_| ())?; conn.execute(&create_schema_versions_sql()?, []).map(|_| ())?; - conn.execute(&insert_schema_version_sql()?, [ - table_name.inner(), - &CURRENT_SCHEMA_VERSION_TX_HISTORY.to_string(), - ]) + conn.execute( + &insert_schema_version_sql()?, + [table_name.inner(), &CURRENT_SCHEMA_VERSION_TX_HISTORY.to_string()], + ) .map(|_| ())?; Ok(()) }) @@ -1418,10 +1425,13 @@ fn migrate_tx_history_table_from_schema_0_to_2( ); sql_tx.execute(&rename_table_sql, [])?; - sql_tx.execute(&update_schema_version_sql(schema_table), [ - history_table.inner().to_string(), - CURRENT_SCHEMA_VERSION_TX_HISTORY.to_string(), - ])?; + sql_tx.execute( + &update_schema_version_sql(schema_table), + [ + history_table.inner().to_string(), + CURRENT_SCHEMA_VERSION_TX_HISTORY.to_string(), + ], + )?; sql_tx.commit()?; diff --git a/mm2src/coins/nft/storage/wasm/nft_idb.rs b/mm2src/coins/nft/storage/wasm/nft_idb.rs index 775a871589..79085c75fe 100644 --- a/mm2src/coins/nft/storage/wasm/nft_idb.rs +++ b/mm2src/coins/nft/storage/wasm/nft_idb.rs @@ -42,5 +42,7 @@ impl NftCacheIDB { /// Get a reference to the underlying `IndexedDb` instance. /// /// This method allows for direct interaction with the raw database, bypassing any abstractions. - pub(crate) fn get_inner(&self) -> &IndexedDb { &self.inner } + pub(crate) fn get_inner(&self) -> &IndexedDb { + &self.inner + } } diff --git a/mm2src/coins/nft/storage/wasm/wasm_storage.rs b/mm2src/coins/nft/storage/wasm/wasm_storage.rs index 7d5c595795..11c54344b8 100644 --- a/mm2src/coins/nft/storage/wasm/wasm_storage.rs +++ b/mm2src/coins/nft/storage/wasm/wasm_storage.rs @@ -1,10 +1,14 @@ use crate::hd_wallet::AddrToString; -use crate::nft::nft_structs::{Chain, ContractType, Nft, NftList, NftListFilters, NftTransferHistory, - NftsTransferHistoryList, TransferMeta, TransferStatus}; +use crate::nft::nft_structs::{ + Chain, ContractType, Nft, NftList, NftListFilters, NftTransferHistory, NftsTransferHistoryList, TransferMeta, + TransferStatus, +}; use crate::nft::storage::wasm::nft_idb::NftCacheIDBLocked; use crate::nft::storage::wasm::{WasmNftCacheError, WasmNftCacheResult}; -use crate::nft::storage::{get_offset_limit, NftListStorageOps, NftTokenAddrId, NftTransferHistoryFilters, - NftTransferHistoryStorageOps, RemoveNftResult}; +use crate::nft::storage::{ + get_offset_limit, NftListStorageOps, NftTokenAddrId, NftTransferHistoryFilters, NftTransferHistoryStorageOps, + RemoveNftResult, +}; use async_trait::async_trait; use ethereum_types::Address; use mm2_db::indexed_db::{BeBigUint, DbTable, DbUpgrader, MultiIndex, OnUpgradeError, OnUpgradeResult, TableSignature}; @@ -101,9 +105,13 @@ where } impl NftListFilters { - fn passes_spam_filter(&self, nft: &Nft) -> bool { !self.exclude_spam || !nft.common.possible_spam } + fn passes_spam_filter(&self, nft: &Nft) -> bool { + !self.exclude_spam || !nft.common.possible_spam + } - fn passes_phishing_filter(&self, nft: &Nft) -> bool { !self.exclude_phishing || !nft.possible_phishing } + fn passes_phishing_filter(&self, nft: &Nft) -> bool { + !self.exclude_phishing || !nft.possible_phishing + } } impl NftTransferHistoryFilters { @@ -131,9 +139,13 @@ impl NftTransferHistoryFilters { impl NftListStorageOps for NftCacheIDBLocked<'_> { type Error = WasmNftCacheError; - async fn init(&self, _chain: &Chain) -> MmResult<(), Self::Error> { Ok(()) } + async fn init(&self, _chain: &Chain) -> MmResult<(), Self::Error> { + Ok(()) + } - async fn is_initialized(&self, _chain: &Chain) -> MmResult { Ok(true) } + async fn is_initialized(&self, _chain: &Chain) -> MmResult { + Ok(true) + } async fn get_nft_list( &self, @@ -500,9 +512,13 @@ impl NftListStorageOps for NftCacheIDBLocked<'_> { impl NftTransferHistoryStorageOps for NftCacheIDBLocked<'_> { type Error = WasmNftCacheError; - async fn init(&self, _chain: &Chain) -> MmResult<(), Self::Error> { Ok(()) } + async fn init(&self, _chain: &Chain) -> MmResult<(), Self::Error> { + Ok(()) + } - async fn is_initialized(&self, _chain: &Chain) -> MmResult { Ok(true) } + async fn is_initialized(&self, _chain: &Chain) -> MmResult { + Ok(true) + } async fn get_transfer_history( &self, @@ -961,11 +977,15 @@ trait BlockNumberTable { } impl BlockNumberTable for NftListTable { - fn get_block_number(&self) -> &BeBigUint { &self.block_number } + fn get_block_number(&self) -> &BeBigUint { + &self.block_number + } } impl BlockNumberTable for NftTransferHistoryTable { - fn get_block_number(&self) -> &BeBigUint { &self.block_number } + fn get_block_number(&self) -> &BeBigUint { + &self.block_number + } } #[derive(Clone, Debug, Deserialize, Serialize)] diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index 02fec1b2fa..1d83e2aeed 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -1,31 +1,39 @@ use crate::coin_errors::{AddressFromPubkeyError, MyAddressError, ValidatePaymentError, ValidatePaymentResult}; use crate::eth::{self, u256_to_big_decimal, wei_from_big_decimal, TryToAddress}; use crate::hd_wallet::HDAddressSelector; -use crate::qrc20::rpc_clients::{LogEntry, Qrc20ElectrumOps, Qrc20NativeOps, Qrc20RpcOps, TopicFilter, TxReceipt, - ViewContractCallType}; +use crate::qrc20::rpc_clients::{ + LogEntry, Qrc20ElectrumOps, Qrc20NativeOps, Qrc20RpcOps, TopicFilter, TxReceipt, ViewContractCallType, +}; use crate::utxo::qtum::QtumBasedCoin; -use crate::utxo::rpc_clients::{ElectrumClient, NativeClient, UnspentInfo, UtxoRpcClientEnum, UtxoRpcClientOps, - UtxoRpcError, UtxoRpcFut, UtxoRpcResult}; +use crate::utxo::rpc_clients::{ + ElectrumClient, NativeClient, UnspentInfo, UtxoRpcClientEnum, UtxoRpcClientOps, UtxoRpcError, UtxoRpcFut, + UtxoRpcResult, +}; #[cfg(not(target_arch = "wasm32"))] use crate::utxo::tx_cache::{UtxoVerboseCacheOps, UtxoVerboseCacheShared}; -use crate::utxo::utxo_builder::{UtxoCoinBuildError, UtxoCoinBuildResult, UtxoCoinBuilder, UtxoCoinBuilderCommonOps, - UtxoFieldsWithGlobalHDBuilder, UtxoFieldsWithHardwareWalletBuilder, - UtxoFieldsWithIguanaSecretBuilder}; +use crate::utxo::utxo_builder::{ + UtxoCoinBuildError, UtxoCoinBuildResult, UtxoCoinBuilder, UtxoCoinBuilderCommonOps, UtxoFieldsWithGlobalHDBuilder, + UtxoFieldsWithHardwareWalletBuilder, UtxoFieldsWithIguanaSecretBuilder, +}; use crate::utxo::utxo_common::{self, big_decimal_from_sat, check_all_utxo_inputs_signed_by_pub, UtxoTxBuilder}; -use crate::utxo::{qtum, ActualFeeRate, AddrFromStrError, BroadcastTxErr, FeePolicy, GenerateTxError, GetUtxoListOps, - HistoryUtxoTx, HistoryUtxoTxMap, MatureUnspentList, RecentlySpentOutPointsGuard, UnsupportedAddr, - UtxoActivationParams, UtxoAddressFormat, UtxoCoinFields, UtxoCommonOps, UtxoFromLegacyReqErr, - UtxoTx, UtxoTxBroadcastOps, UtxoTxGenerationOps, VerboseTransactionFrom, UTXO_LOCK}; -use crate::{BalanceError, BalanceFut, CheckIfMyPaymentSentArgs, CoinBalance, ConfirmPaymentInput, DexFee, Eip1559Ops, - FeeApproxStage, FoundSwapTxSpend, HistorySyncState, IguanaPrivKey, MarketCoinOps, MmCoin, - NegotiateSwapContractAddrErr, PrivKeyBuildPolicy, PrivKeyPolicyNotAllowed, RawTransactionFut, - RawTransactionRequest, RawTransactionResult, RefundPaymentArgs, SearchForSwapTxSpendInput, - SendPaymentArgs, SignRawTransactionRequest, SignatureResult, SpendPaymentArgs, SwapOps, SwapTxFeePolicy, - TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionData, - TransactionDetails, TransactionEnum, TransactionErr, TransactionResult, TransactionType, TxMarshalingErr, - UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, ValidateOtherPubKeyErr, - ValidatePaymentInput, VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, WeakSpawner, WithdrawError, - WithdrawFee, WithdrawFut, WithdrawRequest, WithdrawResult}; +use crate::utxo::{ + qtum, ActualFeeRate, AddrFromStrError, BroadcastTxErr, FeePolicy, GenerateTxError, GetUtxoListOps, HistoryUtxoTx, + HistoryUtxoTxMap, MatureUnspentList, RecentlySpentOutPointsGuard, UnsupportedAddr, UtxoActivationParams, + UtxoAddressFormat, UtxoCoinFields, UtxoCommonOps, UtxoFromLegacyReqErr, UtxoTx, UtxoTxBroadcastOps, + UtxoTxGenerationOps, VerboseTransactionFrom, UTXO_LOCK, +}; +use crate::{ + BalanceError, BalanceFut, CheckIfMyPaymentSentArgs, CoinBalance, ConfirmPaymentInput, DexFee, Eip1559Ops, + FeeApproxStage, FoundSwapTxSpend, HistorySyncState, IguanaPrivKey, MarketCoinOps, MmCoin, + NegotiateSwapContractAddrErr, PrivKeyBuildPolicy, PrivKeyPolicyNotAllowed, RawTransactionFut, + RawTransactionRequest, RawTransactionResult, RefundPaymentArgs, SearchForSwapTxSpendInput, SendPaymentArgs, + SignRawTransactionRequest, SignatureResult, SpendPaymentArgs, SwapOps, SwapTxFeePolicy, TradeFee, + TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionData, TransactionDetails, + TransactionEnum, TransactionErr, TransactionResult, TransactionType, TxMarshalingErr, UnexpectedDerivationMethod, + ValidateAddressResult, ValidateFeeArgs, ValidateOtherPubKeyErr, ValidatePaymentInput, VerificationResult, + WaitForHTLCTxSpendArgs, WatcherOps, WeakSpawner, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest, + WithdrawResult, +}; use async_trait::async_trait; use bitcrypto::{dhash160, sha256}; use chain::TransactionOutput; @@ -44,9 +52,11 @@ use keys::{Address as UtxoAddress, KeyPair, Public}; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; use mm2_number::{BigDecimal, MmNumber}; -#[cfg(test)] use mocktopus::macros::*; -use rpc::v1::types::{Bytes as BytesJson, ToTxHash, Transaction as RpcTransaction, H160 as H160Json, H256 as H256Json, - H264 as H264Json}; +#[cfg(test)] +use mocktopus::macros::*; +use rpc::v1::types::{ + Bytes as BytesJson, ToTxHash, Transaction as RpcTransaction, H160 as H160Json, H256 as H256Json, H264 as H264Json, +}; use script::{Builder as ScriptBuilder, Opcode, Script, TransactionInputSigner}; use script_pubkey::generate_contract_call_script_pubkey; use serde_json::{self as json, Value as Json}; @@ -55,13 +65,15 @@ use std::collections::{HashMap, HashSet}; use std::convert::TryInto; use std::num::TryFromIntError; use std::ops::{Deref, Neg}; -#[cfg(not(target_arch = "wasm32"))] use std::path::PathBuf; +#[cfg(not(target_arch = "wasm32"))] +use std::path::PathBuf; use std::str::FromStr; use std::sync::Arc; use utxo_signer::with_key_pair::{sign_tx, UtxoSignWithKeyPairError}; mod history; -#[cfg(test)] mod qrc20_tests; +#[cfg(test)] +mod qrc20_tests; pub mod rpc_clients; pub mod script_pubkey; mod swap; @@ -91,23 +103,33 @@ pub enum Qrc20GenTxError { } impl From for Qrc20GenTxError { - fn from(e: GenerateTxError) -> Self { Qrc20GenTxError::ErrorGeneratingUtxoTx(e) } + fn from(e: GenerateTxError) -> Self { + Qrc20GenTxError::ErrorGeneratingUtxoTx(e) + } } impl From for Qrc20GenTxError { - fn from(e: UtxoSignWithKeyPairError) -> Self { Qrc20GenTxError::ErrorSigningTx(e) } + fn from(e: UtxoSignWithKeyPairError) -> Self { + Qrc20GenTxError::ErrorSigningTx(e) + } } impl From for Qrc20GenTxError { - fn from(e: PrivKeyPolicyNotAllowed) -> Self { Qrc20GenTxError::PrivKeyPolicyNotAllowed(e) } + fn from(e: PrivKeyPolicyNotAllowed) -> Self { + Qrc20GenTxError::PrivKeyPolicyNotAllowed(e) + } } impl From for Qrc20GenTxError { - fn from(e: UnexpectedDerivationMethod) -> Self { Qrc20GenTxError::UnexpectedDerivationMethod(e) } + fn from(e: UnexpectedDerivationMethod) -> Self { + Qrc20GenTxError::UnexpectedDerivationMethod(e) + } } impl From for Qrc20GenTxError { - fn from(e: UtxoRpcError) -> Self { Qrc20GenTxError::ErrorGeneratingUtxoTx(GenerateTxError::from(e)) } + fn from(e: UtxoRpcError) -> Self { + Qrc20GenTxError::ErrorGeneratingUtxoTx(GenerateTxError::from(e)) + } } impl Qrc20GenTxError { @@ -140,7 +162,9 @@ pub enum Qrc20FromLegacyReqErr { } impl From for Qrc20FromLegacyReqErr { - fn from(err: UtxoFromLegacyReqErr) -> Self { Qrc20FromLegacyReqErr::InvalidUtxoParams(err) } + fn from(err: UtxoFromLegacyReqErr) -> Self { + Qrc20FromLegacyReqErr::InvalidUtxoParams(err) + } } impl Qrc20ActivationParams { @@ -192,13 +216,21 @@ impl<'a> Qrc20CoinBuilder<'a> { #[async_trait] impl UtxoCoinBuilderCommonOps for Qrc20CoinBuilder<'_> { - fn ctx(&self) -> &MmArc { self.ctx } + fn ctx(&self) -> &MmArc { + self.ctx + } - fn conf(&self) -> &Json { self.conf } + fn conf(&self) -> &Json { + self.conf + } - fn activation_params(&self) -> &UtxoActivationParams { &self.activation_params.utxo_params } + fn activation_params(&self) -> &UtxoActivationParams { + &self.activation_params.utxo_params + } - fn ticker(&self) -> &str { self.ticker } + fn ticker(&self) -> &str { + self.ticker + } async fn decimals(&self, rpc_client: &UtxoRpcClientEnum) -> UtxoCoinBuildResult { if let Some(d) = self.conf()["decimals"].as_u64() { @@ -212,7 +244,9 @@ impl UtxoCoinBuilderCommonOps for Qrc20CoinBuilder<'_> { .map_to_mm(UtxoCoinBuildError::ErrorDetectingDecimals) } - fn dust_amount(&self) -> u64 { QRC20_DUST } + fn dust_amount(&self) -> u64 { + QRC20_DUST + } #[cfg(not(target_arch = "wasm32"))] fn confpath(&self) -> UtxoCoinBuildResult { @@ -278,7 +312,9 @@ impl UtxoCoinBuilder for Qrc20CoinBuilder<'_> { type ResultCoin = Qrc20Coin; type Error = UtxoCoinBuildError; - fn priv_key_policy(&self) -> PrivKeyBuildPolicy { self.priv_key_policy.clone() } + fn priv_key_policy(&self) -> PrivKeyBuildPolicy { + self.priv_key_policy.clone() + } async fn build(self) -> MmResult { let utxo = match self.priv_key_policy() { @@ -350,11 +386,15 @@ pub struct Qrc20Coin(Arc); impl Deref for Qrc20Coin { type Target = Qrc20CoinFields; - fn deref(&self) -> &Qrc20CoinFields { &self.0 } + fn deref(&self) -> &Qrc20CoinFields { + &self.0 + } } impl AsRef for Qrc20Coin { - fn as_ref(&self) -> &UtxoCoinFields { &self.utxo } + fn as_ref(&self) -> &UtxoCoinFields { + &self.utxo + } } impl qtum::QtumBasedCoin for Qrc20Coin {} @@ -436,7 +476,9 @@ impl MutContractCallType { } #[allow(dead_code)] - fn short_signature(&self) -> [u8; 4] { self.as_function().short_signature() } + fn short_signature(&self) -> [u8; 4] { + self.as_function().short_signature() + } } pub struct GenerateQrc20TxResult { @@ -454,15 +496,21 @@ pub enum Qrc20AbiError { } impl From for Qrc20AbiError { - fn from(e: ethabi::Error) -> Qrc20AbiError { Qrc20AbiError::ABIError(e.to_string()) } + fn from(e: ethabi::Error) -> Qrc20AbiError { + Qrc20AbiError::ABIError(e.to_string()) + } } impl From for ValidatePaymentError { - fn from(e: Qrc20AbiError) -> ValidatePaymentError { ValidatePaymentError::TxDeserializationError(e.to_string()) } + fn from(e: Qrc20AbiError) -> ValidatePaymentError { + ValidatePaymentError::TxDeserializationError(e.to_string()) + } } impl From for GenerateTxError { - fn from(e: Qrc20AbiError) -> Self { GenerateTxError::Internal(e.to_string()) } + fn from(e: Qrc20AbiError) -> Self { + GenerateTxError::Internal(e.to_string()) + } } impl From for TradePreimageError { @@ -611,13 +659,17 @@ impl UtxoTxBroadcastOps for Qrc20Coin { #[cfg_attr(test, mockable)] impl UtxoTxGenerationOps for Qrc20Coin { /// Get only QTUM transaction fee. - async fn get_fee_rate(&self) -> UtxoRpcResult { utxo_common::get_fee_rate(&self.utxo).await } + async fn get_fee_rate(&self) -> UtxoRpcResult { + utxo_common::get_fee_rate(&self.utxo).await + } async fn calc_interest_if_required(&self, unsigned: &mut TransactionInputSigner) -> UtxoRpcResult { utxo_common::calc_interest_if_required(self, unsigned).await } - fn supports_interest(&self) -> bool { utxo_common::is_kmd(self) } + fn supports_interest(&self) -> bool { + utxo_common::is_kmd(self) + } } #[async_trait] @@ -656,7 +708,9 @@ impl UtxoCommonOps for Qrc20Coin { utxo_common::addresses_from_script(self, script) } - fn denominate_satoshis(&self, satoshi: i64) -> f64 { utxo_common::denominate_satoshis(&self.utxo, satoshi) } + fn denominate_satoshis(&self, satoshi: i64) -> f64 { + utxo_common::denominate_satoshis(&self.utxo, satoshi) + } fn my_public_key(&self) -> Result<&Public, MmError> { utxo_common::my_public_key(self.as_ref()) @@ -674,7 +728,9 @@ impl UtxoCommonOps for Qrc20Coin { utxo_common::get_current_mtp(&self.utxo, CoinVariant::Qtum).await } - fn is_unspent_mature(&self, output: &RpcTransaction) -> bool { self.is_qtum_unspent_mature(output) } + fn is_unspent_mature(&self, output: &RpcTransaction) -> bool { + self.is_qtum_unspent_mature(output) + } async fn calc_interest_of_tx( &self, @@ -733,7 +789,9 @@ impl UtxoCommonOps for Qrc20Coin { utxo_common::p2sh_tx_locktime(self, &self.utxo.conf.ticker, htlc_locktime).await } - fn addr_format(&self) -> &UtxoAddressFormat { utxo_common::addr_format(self) } + fn addr_format(&self) -> &UtxoAddressFormat { + utxo_common::addr_format(self) + } fn addr_format_for_standard_scripts(&self) -> UtxoAddressFormat { utxo_common::addr_format_for_standard_scripts(self) @@ -1026,9 +1084,13 @@ impl WatcherOps for Qrc20Coin {} #[async_trait] impl MarketCoinOps for Qrc20Coin { - fn ticker(&self) -> &str { &self.utxo.conf.ticker } + fn ticker(&self) -> &str { + &self.utxo.conf.ticker + } - fn my_address(&self) -> MmResult { utxo_common::my_address(self) } + fn my_address(&self) -> MmResult { + utxo_common::my_address(self) + } fn address_from_pubkey(&self, pubkey: &H264Json) -> MmResult { let pubkey = Public::Compressed((*pubkey).into()); @@ -1089,7 +1151,9 @@ impl MarketCoinOps for Qrc20Coin { Box::new(utxo_common::my_balance(self.clone()).map(|CoinBalance { spendable, .. }| spendable)) } - fn platform_ticker(&self) -> &str { &self.0.platform } + fn platform_ticker(&self) -> &str { + &self.0.platform + } #[inline(always)] fn send_raw_tx(&self, tx: &str) -> Box + Send> { @@ -1138,10 +1202,14 @@ impl MarketCoinOps for Qrc20Coin { utxo_common::current_block(&self.utxo) } - fn display_priv_key(&self) -> Result { utxo_common::display_priv_key(&self.utxo) } + fn display_priv_key(&self) -> Result { + utxo_common::display_priv_key(&self.utxo) + } #[inline] - fn min_tx_amount(&self) -> BigDecimal { BigDecimal::from(0) } + fn min_tx_amount(&self) -> BigDecimal { + BigDecimal::from(0) + } #[inline] fn min_trading_vol(&self) -> MmNumber { @@ -1150,16 +1218,24 @@ impl MarketCoinOps for Qrc20Coin { } #[inline] - fn should_burn_dex_fee(&self) -> bool { false } + fn should_burn_dex_fee(&self) -> bool { + false + } - fn is_trezor(&self) -> bool { self.as_ref().priv_key_policy.is_trezor() } + fn is_trezor(&self) -> bool { + self.as_ref().priv_key_policy.is_trezor() + } } #[async_trait] impl MmCoin for Qrc20Coin { - fn is_asset_chain(&self) -> bool { utxo_common::is_asset_chain(&self.utxo) } + fn is_asset_chain(&self) -> bool { + utxo_common::is_asset_chain(&self.utxo) + } - fn spawner(&self) -> WeakSpawner { self.as_ref().abortable_system.weak_spawner() } + fn spawner(&self) -> WeakSpawner { + self.as_ref().abortable_system.weak_spawner() + } fn withdraw(&self, req: WithdrawRequest) -> WithdrawFut { Box::new(qrc20_withdraw(self.clone(), req).boxed().compat()) @@ -1173,19 +1249,25 @@ impl MmCoin for Qrc20Coin { Box::new(utxo_common::get_tx_hex_by_hash(&self.utxo, tx_hash).boxed().compat()) } - fn decimals(&self) -> u8 { utxo_common::decimals(&self.utxo) } + fn decimals(&self) -> u8 { + utxo_common::decimals(&self.utxo) + } fn convert_to_address(&self, from: &str, to_address_format: Json) -> Result { qtum::QtumBasedCoin::convert_to_address(self, from, to_address_format) } - fn validate_address(&self, address: &str) -> ValidateAddressResult { utxo_common::validate_address(self, address) } + fn validate_address(&self, address: &str) -> ValidateAddressResult { + utxo_common::validate_address(self, address) + } fn process_history_loop(&self, ctx: MmArc) -> Box + Send> { Box::new(self.clone().history_loop(ctx).map(|_| Ok(())).boxed().compat()) } - fn history_sync_status(&self) -> HistorySyncState { utxo_common::history_sync_status(&self.utxo) } + fn history_sync_status(&self) -> HistorySyncState { + utxo_common::history_sync_status(&self.utxo) + } /// This method is called to check our QTUM balance. fn get_trade_fee(&self) -> Box + Send> { @@ -1312,9 +1394,13 @@ impl MmCoin for Qrc20Coin { }) } - fn required_confirmations(&self) -> u64 { utxo_common::required_confirmations(&self.utxo) } + fn required_confirmations(&self) -> u64 { + utxo_common::required_confirmations(&self.utxo) + } - fn requires_notarization(&self) -> bool { utxo_common::requires_notarization(&self.utxo) } + fn requires_notarization(&self) -> bool { + utxo_common::requires_notarization(&self.utxo) + } fn set_required_confirmations(&self, confirmations: u64) { utxo_common::set_required_confirmations(&self.utxo, confirmations) @@ -1332,7 +1418,9 @@ impl MmCoin for Qrc20Coin { self.fallback_swap_contract.map(|a| BytesJson::from(a.0.as_ref())) } - fn mature_confirmations(&self) -> Option { Some(self.utxo.conf.mature_confirmations) } + fn mature_confirmations(&self) -> Option { + Some(self.utxo.conf.mature_confirmations) + } fn coin_protocol_info(&self, _amount_to_receive: Option) -> Vec { utxo_common::coin_protocol_info(self) @@ -1348,7 +1436,9 @@ impl MmCoin for Qrc20Coin { utxo_common::is_coin_protocol_supported(self, info) } - fn on_disabled(&self) -> Result<(), AbortedError> { AbortableSystem::abort_all(&self.as_ref().abortable_system) } + fn on_disabled(&self) -> Result<(), AbortedError> { + AbortableSystem::abort_all(&self.as_ref().abortable_system) + } fn on_token_deactivated(&self, _ticker: &str) {} } @@ -1362,7 +1452,9 @@ pub fn qrc20_swap_id(time_lock: u32, secret_hash: &[u8]) -> Vec { sha256(&input).to_vec() } -pub fn contract_addr_into_rpc_format(address: &H160) -> H160Json { H160Json::from(address.0) } +pub fn contract_addr_into_rpc_format(address: &H160) -> H160Json { + H160Json::from(address.0) +} #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct Qrc20FeeDetails { @@ -1534,7 +1626,9 @@ fn transfer_event_from_log(log: &LogEntry) -> Result SwapTxFeePolicy { SwapTxFeePolicy::Unsupported } + fn get_swap_transaction_fee_policy(&self) -> SwapTxFeePolicy { + SwapTxFeePolicy::Unsupported + } fn set_swap_transaction_fee_policy(&self, _swap_txfee_policy: SwapTxFeePolicy) {} } diff --git a/mm2src/coins/qrc20/history.rs b/mm2src/coins/qrc20/history.rs index 306876e687..cdf890c0c3 100644 --- a/mm2src/coins/qrc20/history.rs +++ b/mm2src/coins/qrc20/history.rs @@ -873,10 +873,11 @@ mod tests { assert_eq!(transfer_map, transfer_map_expected); let value: MetricsJson = json::from_value(ctx.metrics.collect_json().unwrap()).unwrap(); - let found = find_metrics_in_json(value, "tx.history.request.count", &[( - "method", - "transfer_details_by_hash", - )]); + let found = find_metrics_in_json( + value, + "tx.history.request.count", + &[("method", "transfer_details_by_hash")], + ); assert_eq!(found, None); } @@ -912,10 +913,11 @@ mod tests { assert_eq!(transfer_map_zero_timestamp, transfer_map_expected); let value: MetricsJson = json::from_value(ctx.metrics.collect_json().unwrap()).unwrap(); - let found = find_metrics_in_json(value, "tx.history.request.count", &[( - "method", - "get_verbose_transaction", - )]); + let found = find_metrics_in_json( + value, + "tx.history.request.count", + &[("method", "get_verbose_transaction")], + ); match found { Some(MetricType::Counter { key, value, .. }) if key == "tx.history.request.count" && value == 1 => (), found => panic!("Found metric type: {:?}", found), diff --git a/mm2src/coins/qrc20/rpc_clients.rs b/mm2src/coins/qrc20/rpc_clients.rs index 4541a8cd71..7740f3ec50 100644 --- a/mm2src/coins/qrc20/rpc_clients.rs +++ b/mm2src/coins/qrc20/rpc_clients.rs @@ -254,7 +254,9 @@ pub enum TopicFilter { } impl From<&str> for TopicFilter { - fn from(topic: &str) -> Self { TopicFilter::Match(topic.to_string()) } + fn from(topic: &str) -> Self { + TopicFilter::Match(topic.to_string()) + } } /// Qrc20 specific RPC ops diff --git a/mm2src/coins/qrc20/swap.rs b/mm2src/coins/qrc20/swap.rs index 58efe5b16b..0cba248d8e 100644 --- a/mm2src/coins/qrc20/swap.rs +++ b/mm2src/coins/qrc20/swap.rs @@ -488,13 +488,17 @@ impl Qrc20Coin { let tokens = self .utxo .rpc_client - .rpc_contract_call(ViewContractCallType::Allowance, &self.contract_address, &[ - Token::Address( - qtum::contract_addr_from_utxo_addr(my_address.clone()) - .mm_err(|e| UtxoRpcError::Internal(e.to_string()))?, - ), - Token::Address(spender), - ]) + .rpc_contract_call( + ViewContractCallType::Allowance, + &self.contract_address, + &[ + Token::Address( + qtum::contract_addr_from_utxo_addr(my_address.clone()) + .mm_err(|e| UtxoRpcError::Internal(e.to_string()))?, + ), + Token::Address(spender), + ], + ) .compat() .await?; @@ -517,9 +521,11 @@ impl Qrc20Coin { let decoded = self .utxo .rpc_client - .rpc_contract_call(ViewContractCallType::Payments, swap_contract_address, &[ - Token::FixedBytes(swap_id), - ]) + .rpc_contract_call( + ViewContractCallType::Payments, + swap_contract_address, + &[Token::FixedBytes(swap_id)], + ) .compat() .await?; if decoded.len() < 3 { diff --git a/mm2src/coins/rpc_command/get_current_mtp.rs b/mm2src/coins/rpc_command/get_current_mtp.rs index 6db7b5b59a..29956115d2 100644 --- a/mm2src/coins/rpc_command/get_current_mtp.rs +++ b/mm2src/coins/rpc_command/get_current_mtp.rs @@ -3,9 +3,11 @@ use derive_more::Display; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; -use crate::{lp_coinfind_or_err, - utxo::{rpc_clients::UtxoRpcError, UtxoCommonOps}, - CoinFindError, MmCoinEnum}; +use crate::{ + lp_coinfind_or_err, + utxo::{rpc_clients::UtxoRpcError, UtxoCommonOps}, + CoinFindError, MmCoinEnum, +}; pub type GetCurrentMtpRpcResult = Result>; @@ -39,11 +41,15 @@ impl HttpStatusCode for GetCurrentMtpError { } impl From for GetCurrentMtpError { - fn from(err: UtxoRpcError) -> Self { Self::RpcError(err.to_string()) } + fn from(err: UtxoRpcError) -> Self { + Self::RpcError(err.to_string()) + } } impl From for GetCurrentMtpError { - fn from(err: CoinFindError) -> Self { Self::NoSuchCoin(err.to_string()) } + fn from(err: CoinFindError) -> Self { + Self::NoSuchCoin(err.to_string()) + } } pub async fn get_current_mtp_rpc( diff --git a/mm2src/coins/rpc_command/get_new_address.rs b/mm2src/coins/rpc_command/get_new_address.rs index 71eb82304f..e279ec99d4 100644 --- a/mm2src/coins/rpc_command/get_new_address.rs +++ b/mm2src/coins/rpc_command/get_new_address.rs @@ -1,12 +1,17 @@ use crate::coin_balance::HDAddressBalance; -use crate::hd_wallet::{AddressDerivingError, ConfirmAddressStatus, HDConfirmAddress, HDConfirmAddressError, - InvalidBip44ChainError, NewAddressDeriveConfirmError, NewAddressDerivingError, - RpcTaskConfirmAddress}; -use crate::{lp_coinfind_or_err, BalanceError, CoinBalance, CoinBalanceMap, CoinFindError, CoinsContext, MmCoinEnum, - UnexpectedDerivationMethod}; +use crate::hd_wallet::{ + AddressDerivingError, ConfirmAddressStatus, HDConfirmAddress, HDConfirmAddressError, InvalidBip44ChainError, + NewAddressDeriveConfirmError, NewAddressDerivingError, RpcTaskConfirmAddress, +}; +use crate::{ + lp_coinfind_or_err, BalanceError, CoinBalance, CoinBalanceMap, CoinFindError, CoinsContext, MmCoinEnum, + UnexpectedDerivationMethod, +}; use async_trait::async_trait; use common::{HttpStatusCode, SuccessResponse}; -use crypto::hw_rpc_task::{HwConnectStatuses, HwRpcTaskAwaitingStatus, HwRpcTaskUserAction, HwRpcTaskUserActionRequest}; +use crypto::hw_rpc_task::{ + HwConnectStatuses, HwRpcTaskAwaitingStatus, HwRpcTaskUserAction, HwRpcTaskUserActionRequest, +}; use crypto::trezor::TrezorMessageType; use crypto::{from_hw_error, Bip44Chain, HwError, HwRpcError, WithHwRpcError}; use derive_more::Display; @@ -14,10 +19,14 @@ use enum_derives::EnumFromTrait; use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; -use rpc_task::rpc_common::{CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError, - RpcTaskStatusRequest, RpcTaskUserActionError}; -use rpc_task::{RpcInitReq, RpcTask, RpcTaskError, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, - RpcTaskStatus, RpcTaskTypes}; +use rpc_task::rpc_common::{ + CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError, RpcTaskStatusRequest, + RpcTaskUserActionError, +}; +use rpc_task::{ + RpcInitReq, RpcTask, RpcTaskError, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, + RpcTaskTypes, +}; use std::time::Duration; pub type GetNewAddressUserAction = HwRpcTaskUserAction; @@ -102,7 +111,9 @@ impl From for GetNewAddressRpcError { } impl From for GetNewAddressRpcError { - fn from(e: InvalidBip44ChainError) -> Self { GetNewAddressRpcError::InvalidBip44Chain { chain: e.chain } } + fn from(e: InvalidBip44ChainError) -> Self { + GetNewAddressRpcError::InvalidBip44Chain { chain: e.chain } + } } impl From for GetNewAddressRpcError { @@ -158,7 +169,9 @@ impl From for GetNewAddressRpcError { } impl From for GetNewAddressRpcError { - fn from(e: HwError) -> Self { from_hw_error(e) } + fn from(e: HwError) -> Self { + from_hw_error(e) + } } impl From for GetNewAddressRpcError { @@ -289,7 +302,9 @@ impl RpcTaskTypes for InitGetNewAddressTask { #[async_trait] impl RpcTask for InitGetNewAddressTask { - fn initial_status(&self) -> Self::InProgressStatus { GetNewAddressInProgressStatus::Preparing } + fn initial_status(&self) -> Self::InProgressStatus { + GetNewAddressInProgressStatus::Preparing + } // Do nothing if the task has been cancelled. async fn cancel(self) {} diff --git a/mm2src/coins/rpc_command/hd_account_balance_rpc_error.rs b/mm2src/coins/rpc_command/hd_account_balance_rpc_error.rs index 2e3592cc2c..01071f79bc 100644 --- a/mm2src/coins/rpc_command/hd_account_balance_rpc_error.rs +++ b/mm2src/coins/rpc_command/hd_account_balance_rpc_error.rs @@ -81,7 +81,9 @@ impl From for HDAccountBalanceRpcError { } impl From for HDAccountBalanceRpcError { - fn from(e: InvalidBip44ChainError) -> Self { HDAccountBalanceRpcError::InvalidBip44Chain { chain: e.chain } } + fn from(e: InvalidBip44ChainError) -> Self { + HDAccountBalanceRpcError::InvalidBip44Chain { chain: e.chain } + } } impl From for HDAccountBalanceRpcError { diff --git a/mm2src/coins/rpc_command/init_account_balance.rs b/mm2src/coins/rpc_command/init_account_balance.rs index afec7e5761..3f26ac74a8 100644 --- a/mm2src/coins/rpc_command/init_account_balance.rs +++ b/mm2src/coins/rpc_command/init_account_balance.rs @@ -5,10 +5,12 @@ use async_trait::async_trait; use common::{SerdeInfallible, SuccessResponse}; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; -use rpc_task::rpc_common::{CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError, - RpcTaskStatusRequest}; -use rpc_task::{RpcInitReq, RpcTask, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, - RpcTaskTypes}; +use rpc_task::rpc_common::{ + CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError, RpcTaskStatusRequest, +}; +use rpc_task::{ + RpcInitReq, RpcTask, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, RpcTaskTypes, +}; pub type AccountBalanceUserAction = SerdeInfallible; pub type AccountBalanceAwaitingStatus = SerdeInfallible; @@ -64,7 +66,9 @@ impl RpcTaskTypes for InitAccountBalanceTask { #[async_trait] impl RpcTask for InitAccountBalanceTask { - fn initial_status(&self) -> Self::InProgressStatus { AccountBalanceInProgressStatus::RequestingAccountBalance } + fn initial_status(&self) -> Self::InProgressStatus { + AccountBalanceInProgressStatus::RequestingAccountBalance + } // Do nothing if the task has been cancelled. async fn cancel(self) {} diff --git a/mm2src/coins/rpc_command/init_create_account.rs b/mm2src/coins/rpc_command/init_create_account.rs index d5a4a4e5bf..293aea246e 100644 --- a/mm2src/coins/rpc_command/init_create_account.rs +++ b/mm2src/coins/rpc_command/init_create_account.rs @@ -1,10 +1,14 @@ use crate::coin_balance::{BalanceObjectOps, HDAccountBalance, HDAccountBalanceEnum}; use crate::hd_wallet::{HDExtractPubkeyError, HDXPubExtractor, NewAccountCreationError, RpcTaskXPubExtractor}; -use crate::{lp_coinfind_or_err, BalanceError, CoinFindError, CoinProtocol, CoinWithDerivationMethod, CoinsContext, - MarketCoinOps, MmCoinEnum, UnexpectedDerivationMethod}; +use crate::{ + lp_coinfind_or_err, BalanceError, CoinFindError, CoinProtocol, CoinWithDerivationMethod, CoinsContext, + MarketCoinOps, MmCoinEnum, UnexpectedDerivationMethod, +}; use async_trait::async_trait; use common::{true_f, HttpStatusCode, SuccessResponse}; -use crypto::hw_rpc_task::{HwConnectStatuses, HwRpcTaskAwaitingStatus, HwRpcTaskUserAction, HwRpcTaskUserActionRequest}; +use crypto::hw_rpc_task::{ + HwConnectStatuses, HwRpcTaskAwaitingStatus, HwRpcTaskUserAction, HwRpcTaskUserActionRequest, +}; use crypto::{from_hw_error, Bip44Chain, HwError, HwRpcError, RpcDerivationPath, WithHwRpcError}; use derive_more::Display; use enum_derives::EnumFromTrait; @@ -12,10 +16,14 @@ use http::StatusCode; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; use parking_lot::Mutex as PaMutex; -use rpc_task::rpc_common::{CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError, - RpcTaskStatusRequest, RpcTaskUserActionError}; -use rpc_task::{RpcInitReq, RpcTask, RpcTaskError, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, - RpcTaskStatus, RpcTaskTypes}; +use rpc_task::rpc_common::{ + CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError, RpcTaskStatusRequest, + RpcTaskUserActionError, +}; +use rpc_task::{ + RpcInitReq, RpcTask, RpcTaskError, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, + RpcTaskTypes, +}; use std::sync::Arc; use std::time::Duration; @@ -118,7 +126,9 @@ impl From for CreateAccountRpcError { } impl From for CreateAccountRpcError { - fn from(e: HDExtractPubkeyError) -> Self { CreateAccountRpcError::from(NewAccountCreationError::from(e)) } + fn from(e: HDExtractPubkeyError) -> Self { + CreateAccountRpcError::from(NewAccountCreationError::from(e)) + } } impl From for CreateAccountRpcError { @@ -137,7 +147,9 @@ impl From for CreateAccountRpcError { } impl From for CreateAccountRpcError { - fn from(e: HwError) -> Self { from_hw_error(e) } + fn from(e: HwError) -> Self { + from_hw_error(e) + } } impl HttpStatusCode for CreateAccountRpcError { @@ -196,9 +208,13 @@ struct StateData { pub struct CreateAccountState(Arc>); impl CreateAccountState { - pub fn on_account_created(&self, account_id: u32) { self.0.lock().account_id = Some(account_id); } + pub fn on_account_created(&self, account_id: u32) { + self.0.lock().account_id = Some(account_id); + } - pub fn create_account_id(&self) -> Option { self.0.lock().account_id } + pub fn create_account_id(&self) -> Option { + self.0.lock().account_id + } } #[async_trait] @@ -236,7 +252,9 @@ impl RpcTaskTypes for InitCreateAccountTask { #[async_trait] impl RpcTask for InitCreateAccountTask { - fn initial_status(&self) -> Self::InProgressStatus { CreateAccountInProgressStatus::Preparing } + fn initial_status(&self) -> Self::InProgressStatus { + CreateAccountInProgressStatus::Preparing + } async fn cancel(self) { if let Some(account_id) = self.task_state.create_account_id() { @@ -393,8 +411,10 @@ pub async fn cancel_create_new_account( pub(crate) mod common_impl { use super::*; use crate::coin_balance::{HDWalletBalanceObject, HDWalletBalanceOps}; - use crate::hd_wallet::{create_new_account, ExtractExtendedPubkey, HDAccountOps, HDAccountStorageOps, - HDCoinExtendedPubkey, HDCoinHDAccount, HDWalletOps}; + use crate::hd_wallet::{ + create_new_account, ExtractExtendedPubkey, HDAccountOps, HDAccountStorageOps, HDCoinExtendedPubkey, + HDCoinHDAccount, HDWalletOps, + }; pub async fn init_create_new_account_rpc( coin: &Coin, @@ -488,10 +508,13 @@ pub mod for_tests { if now_ms() > timeout { panic!("{} init_withdraw timed out", ticker); } - let status = init_create_new_account_status(ctx.clone(), RpcTaskStatusRequest { - task_id: init.task_id, - forget_if_finished: true, - }) + let status = init_create_new_account_status( + ctx.clone(), + RpcTaskStatusRequest { + task_id: init.task_id, + forget_if_finished: true, + }, + ) .await; if let Ok(status) = status { match status { diff --git a/mm2src/coins/rpc_command/init_scan_for_new_addresses.rs b/mm2src/coins/rpc_command/init_scan_for_new_addresses.rs index 7d1e7b1e09..d3d8a3d06d 100644 --- a/mm2src/coins/rpc_command/init_scan_for_new_addresses.rs +++ b/mm2src/coins/rpc_command/init_scan_for_new_addresses.rs @@ -6,10 +6,12 @@ use common::{SerdeInfallible, SuccessResponse}; use crypto::RpcDerivationPath; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; -use rpc_task::rpc_common::{CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError, - RpcTaskStatusRequest}; -use rpc_task::{RpcInitReq, RpcTask, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, - RpcTaskTypes}; +use rpc_task::rpc_common::{ + CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError, RpcTaskStatusRequest, +}; +use rpc_task::{ + RpcInitReq, RpcTask, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, RpcTaskTypes, +}; pub type ScanAddressesUserAction = SerdeInfallible; pub type ScanAddressesAwaitingStatus = SerdeInfallible; @@ -86,7 +88,9 @@ impl RpcTaskTypes for InitScanAddressesTask { #[async_trait] impl RpcTask for InitScanAddressesTask { #[inline] - fn initial_status(&self) -> Self::InProgressStatus { ScanAddressesInProgressStatus::InProgress } + fn initial_status(&self) -> Self::InProgressStatus { + ScanAddressesInProgressStatus::InProgress + } // Do nothing if the task has been cancelled. async fn cancel(self) {} diff --git a/mm2src/coins/rpc_command/init_withdraw.rs b/mm2src/coins/rpc_command/init_withdraw.rs index 1575f9b1ca..976c916ecf 100644 --- a/mm2src/coins/rpc_command/init_withdraw.rs +++ b/mm2src/coins/rpc_command/init_withdraw.rs @@ -5,10 +5,13 @@ use common::SuccessResponse; use crypto::hw_rpc_task::{HwRpcTaskAwaitingStatus, HwRpcTaskUserAction, HwRpcTaskUserActionRequest}; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; -use rpc_task::rpc_common::{CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError, - RpcTaskStatusRequest, RpcTaskUserActionError}; -use rpc_task::{RpcInitReq, RpcTask, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatusAlias, - RpcTaskTypes}; +use rpc_task::rpc_common::{ + CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError, RpcTaskStatusRequest, + RpcTaskUserActionError, +}; +use rpc_task::{ + RpcInitReq, RpcTask, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatusAlias, RpcTaskTypes, +}; pub type WithdrawAwaitingStatus = HwRpcTaskAwaitingStatus; pub type WithdrawUserAction = HwRpcTaskUserAction; @@ -127,7 +130,9 @@ impl RpcTaskTypes for WithdrawTask { #[async_trait] impl RpcTask for WithdrawTask { - fn initial_status(&self) -> Self::InProgressStatus { WithdrawInProgressStatus::Preparing } + fn initial_status(&self) -> Self::InProgressStatus { + WithdrawInProgressStatus::Preparing + } // Do nothing if the task has been cancelled. async fn cancel(self) {} diff --git a/mm2src/coins/rpc_command/lightning/connect_to_node.rs b/mm2src/coins/rpc_command/lightning/connect_to_node.rs index e365fd746a..20d29306c0 100644 --- a/mm2src/coins/rpc_command/lightning/connect_to_node.rs +++ b/mm2src/coins/rpc_command/lightning/connect_to_node.rs @@ -54,11 +54,15 @@ impl From for ConnectToNodeError { } impl From for ConnectToNodeError { - fn from(err: std::io::Error) -> ConnectToNodeError { ConnectToNodeError::IOError(err.to_string()) } + fn from(err: std::io::Error) -> ConnectToNodeError { + ConnectToNodeError::IOError(err.to_string()) + } } impl From for ConnectToNodeError { - fn from(err: ConnectionError) -> ConnectToNodeError { ConnectToNodeError::ConnectionError(err.to_string()) } + fn from(err: ConnectionError) -> ConnectToNodeError { + ConnectToNodeError::ConnectionError(err.to_string()) + } } #[derive(Deserialize)] diff --git a/mm2src/coins/rpc_command/lightning/generate_invoice.rs b/mm2src/coins/rpc_command/lightning/generate_invoice.rs index 37ccbd4706..3affbdec4d 100644 --- a/mm2src/coins/rpc_command/lightning/generate_invoice.rs +++ b/mm2src/coins/rpc_command/lightning/generate_invoice.rs @@ -50,11 +50,15 @@ impl From for GenerateInvoiceError { } impl From for GenerateInvoiceError { - fn from(e: SignOrCreationError) -> Self { GenerateInvoiceError::SignOrCreationError(e.to_string()) } + fn from(e: SignOrCreationError) -> Self { + GenerateInvoiceError::SignOrCreationError(e.to_string()) + } } impl From for GenerateInvoiceError { - fn from(err: SqlError) -> GenerateInvoiceError { GenerateInvoiceError::DbError(err.to_string()) } + fn from(err: SqlError) -> GenerateInvoiceError { + GenerateInvoiceError::DbError(err.to_string()) + } } #[derive(Deserialize)] diff --git a/mm2src/coins/rpc_command/lightning/get_channel_details.rs b/mm2src/coins/rpc_command/lightning/get_channel_details.rs index 51965ae7c5..e0804c2eac 100644 --- a/mm2src/coins/rpc_command/lightning/get_channel_details.rs +++ b/mm2src/coins/rpc_command/lightning/get_channel_details.rs @@ -43,7 +43,9 @@ impl From for GetChannelDetailsError { } impl From for GetChannelDetailsError { - fn from(err: SqlError) -> GetChannelDetailsError { GetChannelDetailsError::DbError(err.to_string()) } + fn from(err: SqlError) -> GetChannelDetailsError { + GetChannelDetailsError::DbError(err.to_string()) + } } #[derive(Deserialize)] diff --git a/mm2src/coins/rpc_command/lightning/get_payment_details.rs b/mm2src/coins/rpc_command/lightning/get_payment_details.rs index be759874e3..8648500252 100644 --- a/mm2src/coins/rpc_command/lightning/get_payment_details.rs +++ b/mm2src/coins/rpc_command/lightning/get_payment_details.rs @@ -44,7 +44,9 @@ impl From for GetPaymentDetailsError { } impl From for GetPaymentDetailsError { - fn from(err: SqlError) -> GetPaymentDetailsError { GetPaymentDetailsError::DbError(err.to_string()) } + fn from(err: SqlError) -> GetPaymentDetailsError { + GetPaymentDetailsError::DbError(err.to_string()) + } } #[derive(Deserialize)] diff --git a/mm2src/coins/rpc_command/lightning/list_channels.rs b/mm2src/coins/rpc_command/lightning/list_channels.rs index 3e36c2526d..bc489092e7 100644 --- a/mm2src/coins/rpc_command/lightning/list_channels.rs +++ b/mm2src/coins/rpc_command/lightning/list_channels.rs @@ -42,7 +42,9 @@ impl From for ListChannelsError { } impl From for ListChannelsError { - fn from(err: SqlError) -> ListChannelsError { ListChannelsError::DbError(err.to_string()) } + fn from(err: SqlError) -> ListChannelsError { + ListChannelsError::DbError(err.to_string()) + } } #[derive(Deserialize)] diff --git a/mm2src/coins/rpc_command/lightning/list_payments_by_filter.rs b/mm2src/coins/rpc_command/lightning/list_payments_by_filter.rs index c025e0a30d..9a78882cd5 100644 --- a/mm2src/coins/rpc_command/lightning/list_payments_by_filter.rs +++ b/mm2src/coins/rpc_command/lightning/list_payments_by_filter.rs @@ -41,7 +41,9 @@ impl From for ListPaymentsError { } impl From for ListPaymentsError { - fn from(err: SqlError) -> ListPaymentsError { ListPaymentsError::DbError(err.to_string()) } + fn from(err: SqlError) -> ListPaymentsError { + ListPaymentsError::DbError(err.to_string()) + } } #[derive(Deserialize)] diff --git a/mm2src/coins/rpc_command/lightning/open_channel.rs b/mm2src/coins/rpc_command/lightning/open_channel.rs index 485fb93941..957d881e03 100644 --- a/mm2src/coins/rpc_command/lightning/open_channel.rs +++ b/mm2src/coins/rpc_command/lightning/open_channel.rs @@ -5,8 +5,10 @@ use crate::lightning::ln_serialization::NodeAddress; use crate::lightning::ln_storage::LightningStorage; use crate::utxo::utxo_common::UtxoTxBuilder; use crate::utxo::{sat_from_big_decimal, FeePolicy, GetUtxoListOps, UtxoTxGenerationOps}; -use crate::{lp_coinfind_or_err, BalanceError, CoinFindError, GenerateTxError, MmCoinEnum, NumConversError, - UnexpectedDerivationMethod, UtxoRpcError}; +use crate::{ + lp_coinfind_or_err, BalanceError, CoinFindError, GenerateTxError, MmCoinEnum, NumConversError, + UnexpectedDerivationMethod, UtxoRpcError, +}; use chain::TransactionOutput; use common::log::error; use common::{async_blocking, new_uuid, HttpStatusCode}; @@ -67,7 +69,9 @@ impl HttpStatusCode for OpenChannelError { } impl From for OpenChannelError { - fn from(err: ConnectionError) -> OpenChannelError { OpenChannelError::ConnectToNodeError(err.to_string()) } + fn from(err: ConnectionError) -> OpenChannelError { + OpenChannelError::ConnectToNodeError(err.to_string()) + } } impl From for OpenChannelError { @@ -79,31 +83,45 @@ impl From for OpenChannelError { } impl From for OpenChannelError { - fn from(e: BalanceError) -> Self { OpenChannelError::BalanceError(e.to_string()) } + fn from(e: BalanceError) -> Self { + OpenChannelError::BalanceError(e.to_string()) + } } impl From for OpenChannelError { - fn from(e: NumConversError) -> Self { OpenChannelError::InternalError(e.to_string()) } + fn from(e: NumConversError) -> Self { + OpenChannelError::InternalError(e.to_string()) + } } impl From for OpenChannelError { - fn from(e: GenerateTxError) -> Self { OpenChannelError::GenerateTxErr(e.to_string()) } + fn from(e: GenerateTxError) -> Self { + OpenChannelError::GenerateTxErr(e.to_string()) + } } impl From for OpenChannelError { - fn from(e: UtxoRpcError) -> Self { OpenChannelError::RpcError(e.to_string()) } + fn from(e: UtxoRpcError) -> Self { + OpenChannelError::RpcError(e.to_string()) + } } impl From for OpenChannelError { - fn from(e: UnexpectedDerivationMethod) -> Self { OpenChannelError::InternalError(e.to_string()) } + fn from(e: UnexpectedDerivationMethod) -> Self { + OpenChannelError::InternalError(e.to_string()) + } } impl From for OpenChannelError { - fn from(err: std::io::Error) -> OpenChannelError { OpenChannelError::IOError(err.to_string()) } + fn from(err: std::io::Error) -> OpenChannelError { + OpenChannelError::IOError(err.to_string()) + } } impl From for OpenChannelError { - fn from(err: SqlError) -> OpenChannelError { OpenChannelError::DbError(err.to_string()) } + fn from(err: SqlError) -> OpenChannelError { + OpenChannelError::DbError(err.to_string()) + } } #[derive(Clone, Debug, Deserialize, PartialEq)] diff --git a/mm2src/coins/rpc_command/lightning/send_payment.rs b/mm2src/coins/rpc_command/lightning/send_payment.rs index e7318b6fdd..23adfa4588 100644 --- a/mm2src/coins/rpc_command/lightning/send_payment.rs +++ b/mm2src/coins/rpc_command/lightning/send_payment.rs @@ -49,11 +49,15 @@ impl From for SendPaymentError { } impl From for SendPaymentError { - fn from(err: SqlError) -> SendPaymentError { SendPaymentError::DbError(err.to_string()) } + fn from(err: SqlError) -> SendPaymentError { + SendPaymentError::DbError(err.to_string()) + } } impl From for SendPaymentError { - fn from(err: PaymentError) -> SendPaymentError { SendPaymentError::PaymentError(err.to_string()) } + fn from(err: PaymentError) -> SendPaymentError { + SendPaymentError::PaymentError(err.to_string()) + } } #[derive(Clone, Debug, Deserialize, PartialEq)] diff --git a/mm2src/coins/rpc_command/lightning/trusted_nodes.rs b/mm2src/coins/rpc_command/lightning/trusted_nodes.rs index d899169503..2685e18b0d 100644 --- a/mm2src/coins/rpc_command/lightning/trusted_nodes.rs +++ b/mm2src/coins/rpc_command/lightning/trusted_nodes.rs @@ -39,7 +39,9 @@ impl From for TrustedNodeError { } impl From for TrustedNodeError { - fn from(err: std::io::Error) -> TrustedNodeError { TrustedNodeError::IOError(err.to_string()) } + fn from(err: std::io::Error) -> TrustedNodeError { + TrustedNodeError::IOError(err.to_string()) + } } #[derive(Deserialize)] diff --git a/mm2src/coins/rpc_command/mod.rs b/mm2src/coins/rpc_command/mod.rs index a47a9bf25a..05c1486c9b 100644 --- a/mm2src/coins/rpc_command/mod.rs +++ b/mm2src/coins/rpc_command/mod.rs @@ -9,4 +9,5 @@ pub mod init_scan_for_new_addresses; pub mod init_withdraw; pub mod tendermint; -#[cfg(not(target_arch = "wasm32"))] pub mod lightning; +#[cfg(not(target_arch = "wasm32"))] +pub mod lightning; diff --git a/mm2src/coins/rpc_command/tendermint/ibc.rs b/mm2src/coins/rpc_command/tendermint/ibc.rs index 48df82c44a..e3b8510b56 100644 --- a/mm2src/coins/rpc_command/tendermint/ibc.rs +++ b/mm2src/coins/rpc_command/tendermint/ibc.rs @@ -4,9 +4,13 @@ use std::fmt; pub struct ChannelId(u16); impl fmt::Display for ChannelId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "channel-{}", self.0) } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "channel-{}", self.0) + } } impl ChannelId { - pub fn new(id: u16) -> Self { Self(id) } + pub fn new(id: u16) -> Self { + Self(id) + } } diff --git a/mm2src/coins/rpc_command/tendermint/staking.rs b/mm2src/coins/rpc_command/tendermint/staking.rs index e04ebea081..02a005c4c0 100644 --- a/mm2src/coins/rpc_command/tendermint/staking.rs +++ b/mm2src/coins/rpc_command/tendermint/staking.rs @@ -3,8 +3,9 @@ use cosmrs::staking::{Commission, Description, Validator}; use mm2_err_handle::prelude::{MmError, MmResultExt}; use mm2_number::BigDecimal; -use crate::{hd_wallet::HDAddressSelector, tendermint::TendermintCoinRpcError, MmCoinEnum, StakingInfoError, - WithdrawFee}; +use crate::{ + hd_wallet::HDAddressSelector, tendermint::TendermintCoinRpcError, MmCoinEnum, StakingInfoError, WithdrawFee, +}; /// Represents current status of the validator. #[derive(Debug, Default, Deserialize)] diff --git a/mm2src/coins/siacoin.rs b/mm2src/coins/siacoin.rs index 71441d7c37..1fee959604 100644 --- a/mm2src/coins/siacoin.rs +++ b/mm2src/coins/siacoin.rs @@ -1,14 +1,17 @@ -use super::{BalanceError, CoinBalance, HistorySyncState, MarketCoinOps, MmCoin, RawTransactionFut, - RawTransactionRequest, SwapOps, TradeFee, TransactionEnum}; +use super::{ + BalanceError, CoinBalance, HistorySyncState, MarketCoinOps, MmCoin, RawTransactionFut, RawTransactionRequest, + SwapOps, TradeFee, TransactionEnum, +}; use crate::hd_wallet::HDAddressSelector; -use crate::{coin_errors::MyAddressError, AddressFromPubkeyError, BalanceFut, CanRefundHtlc, CheckIfMyPaymentSentArgs, - ConfirmPaymentInput, DexFee, FeeApproxStage, FoundSwapTxSpend, NegotiateSwapContractAddrErr, - PrivKeyBuildPolicy, PrivKeyPolicy, RawTransactionResult, RefundPaymentArgs, SearchForSwapTxSpendInput, - SendPaymentArgs, SignRawTransactionRequest, SignatureResult, SpendPaymentArgs, TradePreimageFut, - TradePreimageResult, TradePreimageValue, TransactionResult, TxMarshalingErr, UnexpectedDerivationMethod, - ValidateAddressResult, ValidateFeeArgs, ValidateOtherPubKeyErr, ValidatePaymentInput, - ValidatePaymentResult, VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, WeakSpawner, WithdrawFut, - WithdrawRequest}; +use crate::{ + coin_errors::MyAddressError, AddressFromPubkeyError, BalanceFut, CanRefundHtlc, CheckIfMyPaymentSentArgs, + ConfirmPaymentInput, DexFee, FeeApproxStage, FoundSwapTxSpend, NegotiateSwapContractAddrErr, PrivKeyBuildPolicy, + PrivKeyPolicy, RawTransactionResult, RefundPaymentArgs, SearchForSwapTxSpendInput, SendPaymentArgs, + SignRawTransactionRequest, SignatureResult, SpendPaymentArgs, TradePreimageFut, TradePreimageResult, + TradePreimageValue, TransactionResult, TxMarshalingErr, UnexpectedDerivationMethod, ValidateAddressResult, + ValidateFeeArgs, ValidateOtherPubKeyErr, ValidatePaymentInput, ValidatePaymentResult, VerificationResult, + WaitForHTLCTxSpendArgs, WatcherOps, WeakSpawner, WithdrawFut, WithdrawRequest, +}; use crate::{SignatureError, VerificationError}; use async_trait::async_trait; use common::executor::AbortedError; @@ -68,7 +71,9 @@ pub struct SiaConfBuilder<'a> { } impl<'a> SiaConfBuilder<'a> { - pub fn new(conf: &'a Json, ticker: &'a str) -> Self { SiaConfBuilder { conf, ticker } } + pub fn new(conf: &'a Json, ticker: &'a str) -> Self { + SiaConfBuilder { conf, ticker } + } pub fn build(&self) -> SiaConfResult { Ok(SiaCoinConf { @@ -147,7 +152,9 @@ fn siacoin_from_hastings(hastings: u128) -> BigDecimal { } impl From for SiaCoinBuildError { - fn from(e: SiaConfError) -> Self { SiaCoinBuildError::ConfError(e) } + fn from(e: SiaConfError) -> Self { + SiaCoinBuildError::ConfError(e) + } } #[derive(Debug, Display)] @@ -160,12 +167,18 @@ pub enum SiaCoinBuildError { impl SiaCoinBuilder<'_> { #[allow(dead_code)] - fn ctx(&self) -> &MmArc { self.ctx } + fn ctx(&self) -> &MmArc { + self.ctx + } #[allow(dead_code)] - fn conf(&self) -> &Json { self.conf } + fn conf(&self) -> &Json { + self.conf + } - fn ticker(&self) -> &str { self.ticker } + fn ticker(&self) -> &str { + self.ticker + } async fn build(self) -> MmResult { let conf = SiaConfBuilder::new(self.conf, self.ticker()).build().map_mm_err()?; @@ -184,25 +197,37 @@ impl SiaCoinBuilder<'_> { impl Deref for SiaArc { type Target = SiaCoinFields; - fn deref(&self) -> &SiaCoinFields { &self.0 } + fn deref(&self) -> &SiaCoinFields { + &self.0 + } } impl From for SiaArc { - fn from(coin: SiaCoinFields) -> SiaArc { SiaArc::new(coin) } + fn from(coin: SiaCoinFields) -> SiaArc { + SiaArc::new(coin) + } } impl From> for SiaArc { - fn from(arc: Arc) -> SiaArc { SiaArc(arc) } + fn from(arc: Arc) -> SiaArc { + SiaArc(arc) + } } impl From for SiaCoin { - fn from(coin: SiaArc) -> SiaCoin { SiaCoin(coin) } + fn from(coin: SiaArc) -> SiaCoin { + SiaCoin(coin) + } } impl SiaArc { - pub fn new(fields: SiaCoinFields) -> SiaArc { SiaArc(Arc::new(fields)) } + pub fn new(fields: SiaCoinFields) -> SiaArc { + SiaArc(Arc::new(fields)) + } - pub fn with_arc(inner: Arc) -> SiaArc { SiaArc(inner) } + pub fn with_arc(inner: Arc) -> SiaArc { + SiaArc(inner) + } } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -210,28 +235,50 @@ pub struct SiaCoinProtocolInfo; #[async_trait] impl MmCoin for SiaCoin { - fn is_asset_chain(&self) -> bool { false } + fn is_asset_chain(&self) -> bool { + false + } - fn spawner(&self) -> WeakSpawner { unimplemented!() } + fn spawner(&self) -> WeakSpawner { + unimplemented!() + } - fn get_raw_transaction(&self, _req: RawTransactionRequest) -> RawTransactionFut { unimplemented!() } + fn get_raw_transaction(&self, _req: RawTransactionRequest) -> RawTransactionFut { + unimplemented!() + } - fn get_tx_hex_by_hash(&self, _tx_hash: Vec) -> RawTransactionFut { unimplemented!() } + fn get_tx_hex_by_hash(&self, _tx_hash: Vec) -> RawTransactionFut { + unimplemented!() + } - fn withdraw(&self, _req: WithdrawRequest) -> WithdrawFut { unimplemented!() } + fn withdraw(&self, _req: WithdrawRequest) -> WithdrawFut { + unimplemented!() + } - fn decimals(&self) -> u8 { unimplemented!() } + fn decimals(&self) -> u8 { + unimplemented!() + } - fn convert_to_address(&self, _from: &str, _to_address_format: Json) -> Result { unimplemented!() } + fn convert_to_address(&self, _from: &str, _to_address_format: Json) -> Result { + unimplemented!() + } - fn validate_address(&self, _address: &str) -> ValidateAddressResult { unimplemented!() } + fn validate_address(&self, _address: &str) -> ValidateAddressResult { + unimplemented!() + } - fn process_history_loop(&self, _ctx: MmArc) -> Box + Send> { unimplemented!() } + fn process_history_loop(&self, _ctx: MmArc) -> Box + Send> { + unimplemented!() + } - fn history_sync_status(&self) -> HistorySyncState { unimplemented!() } + fn history_sync_status(&self) -> HistorySyncState { + unimplemented!() + } /// Get fee to be paid per 1 swap transaction - fn get_trade_fee(&self) -> Box + Send> { unimplemented!() } + fn get_trade_fee(&self) -> Box + Send> { + unimplemented!() + } async fn get_sender_trade_fee( &self, @@ -242,7 +289,9 @@ impl MmCoin for SiaCoin { unimplemented!() } - fn get_receiver_trade_fee(&self, _stage: FeeApproxStage) -> TradePreimageFut { unimplemented!() } + fn get_receiver_trade_fee(&self, _stage: FeeApproxStage) -> TradePreimageFut { + unimplemented!() + } async fn get_fee_to_send_taker_fee( &self, @@ -252,21 +301,37 @@ impl MmCoin for SiaCoin { unimplemented!() } - fn required_confirmations(&self) -> u64 { unimplemented!() } + fn required_confirmations(&self) -> u64 { + unimplemented!() + } - fn requires_notarization(&self) -> bool { false } + fn requires_notarization(&self) -> bool { + false + } - fn set_required_confirmations(&self, _confirmations: u64) { unimplemented!() } + fn set_required_confirmations(&self, _confirmations: u64) { + unimplemented!() + } - fn set_requires_notarization(&self, _requires_nota: bool) { unimplemented!() } + fn set_requires_notarization(&self, _requires_nota: bool) { + unimplemented!() + } - fn swap_contract_address(&self) -> Option { unimplemented!() } + fn swap_contract_address(&self) -> Option { + unimplemented!() + } - fn fallback_swap_contract(&self) -> Option { unimplemented!() } + fn fallback_swap_contract(&self) -> Option { + unimplemented!() + } - fn mature_confirmations(&self) -> Option { unimplemented!() } + fn mature_confirmations(&self) -> Option { + unimplemented!() + } - fn coin_protocol_info(&self, _amount_to_receive: Option) -> Vec { Vec::new() } + fn coin_protocol_info(&self, _amount_to_receive: Option) -> Vec { + Vec::new() + } fn is_coin_protocol_supported( &self, @@ -278,7 +343,9 @@ impl MmCoin for SiaCoin { true } - fn on_disabled(&self) -> Result<(), AbortedError> { Ok(()) } + fn on_disabled(&self) -> Result<(), AbortedError> { + Ok(()) + } fn on_token_deactivated(&self, _ticker: &str) {} } @@ -286,7 +353,9 @@ impl MmCoin for SiaCoin { // TODO Alright - Dummy values for these functions allow minimal functionality to produce signatures #[async_trait] impl MarketCoinOps for SiaCoin { - fn ticker(&self) -> &str { &self.0.conf.ticker } + fn ticker(&self) -> &str { + &self.0.conf.ticker + } // needs test coverage FIXME COME BACK fn my_address(&self) -> MmResult { @@ -334,7 +403,9 @@ impl MarketCoinOps for SiaCoin { MmError::err(UnexpectedDerivationMethod::InternalError("Not implemented".into())) } - fn sign_message_hash(&self, _message: &str) -> Option<[u8; 32]> { None } + fn sign_message_hash(&self, _message: &str) -> Option<[u8; 32]> { + None + } fn sign_message(&self, _message: &str, _address: Option) -> SignatureResult { MmError::err(SignatureError::InternalError("Not implemented".into())) @@ -369,25 +440,35 @@ impl MarketCoinOps for SiaCoin { Box::new(fut.boxed().compat()) } - fn base_coin_balance(&self) -> BalanceFut { unimplemented!() } + fn base_coin_balance(&self) -> BalanceFut { + unimplemented!() + } - fn platform_ticker(&self) -> &str { "FOO" } // TODO Alright + fn platform_ticker(&self) -> &str { + "FOO" + } // TODO Alright /// Receives raw transaction bytes in hexadecimal format as input and returns tx hash in hexadecimal format - fn send_raw_tx(&self, _tx: &str) -> Box + Send> { unimplemented!() } + fn send_raw_tx(&self, _tx: &str) -> Box + Send> { + unimplemented!() + } fn send_raw_tx_bytes(&self, _tx: &[u8]) -> Box + Send> { unimplemented!() } #[inline(always)] - async fn sign_raw_tx(&self, _args: &SignRawTransactionRequest) -> RawTransactionResult { unimplemented!() } + async fn sign_raw_tx(&self, _args: &SignRawTransactionRequest) -> RawTransactionResult { + unimplemented!() + } fn wait_for_confirmations(&self, _input: ConfirmPaymentInput) -> Box + Send> { unimplemented!() } - async fn wait_for_htlc_tx_spend(&self, _args: WaitForHTLCTxSpendArgs<'_>) -> TransactionResult { unimplemented!() } + async fn wait_for_htlc_tx_spend(&self, _args: WaitForHTLCTxSpendArgs<'_>) -> TransactionResult { + unimplemented!() + } fn tx_enum_from_bytes(&self, _bytes: &[u8]) -> Result> { MmError::err(TxMarshalingErr::NotSupported( @@ -405,15 +486,25 @@ impl MarketCoinOps for SiaCoin { Box::new(height_fut) } - fn display_priv_key(&self) -> Result { unimplemented!() } + fn display_priv_key(&self) -> Result { + unimplemented!() + } - fn min_tx_amount(&self) -> BigDecimal { unimplemented!() } + fn min_tx_amount(&self) -> BigDecimal { + unimplemented!() + } - fn min_trading_vol(&self) -> MmNumber { unimplemented!() } + fn min_trading_vol(&self) -> MmNumber { + unimplemented!() + } - fn should_burn_dex_fee(&self) -> bool { false } + fn should_burn_dex_fee(&self) -> bool { + false + } - fn is_trezor(&self) -> bool { self.0.priv_key_policy.is_trezor() } + fn is_trezor(&self) -> bool { + self.0.priv_key_policy.is_trezor() + } } #[async_trait] @@ -507,13 +598,21 @@ impl SwapOps for SiaCoin { Ok(None) } - fn derive_htlc_key_pair(&self, _swap_unique_data: &[u8]) -> KeyPair { unimplemented!() } + fn derive_htlc_key_pair(&self, _swap_unique_data: &[u8]) -> KeyPair { + unimplemented!() + } - fn derive_htlc_pubkey(&self, _swap_unique_data: &[u8]) -> [u8; 33] { unimplemented!() } + fn derive_htlc_pubkey(&self, _swap_unique_data: &[u8]) -> [u8; 33] { + unimplemented!() + } - async fn can_refund_htlc(&self, _locktime: u64) -> Result { unimplemented!() } + async fn can_refund_htlc(&self, _locktime: u64) -> Result { + unimplemented!() + } - fn validate_other_pubkey(&self, _raw_pubkey: &[u8]) -> MmResult<(), ValidateOtherPubKeyErr> { unimplemented!() } + fn validate_other_pubkey(&self, _raw_pubkey: &[u8]) -> MmResult<(), ValidateOtherPubKeyErr> { + unimplemented!() + } } #[async_trait] diff --git a/mm2src/coins/tendermint/htlc/iris/htlc.rs b/mm2src/coins/tendermint/htlc/iris/htlc.rs index 59cfb5cd73..3bc7a80330 100644 --- a/mm2src/coins/tendermint/htlc/iris/htlc.rs +++ b/mm2src/coins/tendermint/htlc/iris/htlc.rs @@ -65,7 +65,9 @@ impl TryFrom<&IrisCreateHtlcProto> for IrisCreateHtlcMsg { } impl From for IrisCreateHtlcProto { - fn from(t: IrisCreateHtlcMsg) -> IrisCreateHtlcProto { IrisCreateHtlcProto::from(&t) } + fn from(t: IrisCreateHtlcMsg) -> IrisCreateHtlcProto { + IrisCreateHtlcProto::from(&t) + } } impl From<&IrisCreateHtlcMsg> for IrisCreateHtlcProto { @@ -126,7 +128,9 @@ impl TryFrom<&IrisClaimHtlcProto> for IrisClaimHtlcMsg { } impl From for IrisClaimHtlcProto { - fn from(coin: IrisClaimHtlcMsg) -> IrisClaimHtlcProto { IrisClaimHtlcProto::from(&coin) } + fn from(coin: IrisClaimHtlcMsg) -> IrisClaimHtlcProto { + IrisClaimHtlcProto::from(&coin) + } } impl From<&IrisClaimHtlcMsg> for IrisClaimHtlcProto { diff --git a/mm2src/coins/tendermint/htlc/nucleus/htlc.rs b/mm2src/coins/tendermint/htlc/nucleus/htlc.rs index 2c423285bf..a1a2212a95 100644 --- a/mm2src/coins/tendermint/htlc/nucleus/htlc.rs +++ b/mm2src/coins/tendermint/htlc/nucleus/htlc.rs @@ -53,7 +53,9 @@ impl TryFrom<&NucleusCreateHtlcProto> for NucleusCreateHtlcMsg { } impl From for NucleusCreateHtlcProto { - fn from(coin: NucleusCreateHtlcMsg) -> NucleusCreateHtlcProto { NucleusCreateHtlcProto::from(&coin) } + fn from(coin: NucleusCreateHtlcMsg) -> NucleusCreateHtlcProto { + NucleusCreateHtlcProto::from(&coin) + } } impl From<&NucleusCreateHtlcMsg> for NucleusCreateHtlcProto { @@ -111,7 +113,9 @@ impl TryFrom<&NucleusClaimHtlcProto> for NucleusClaimHtlcMsg { } impl From for NucleusClaimHtlcProto { - fn from(coin: NucleusClaimHtlcMsg) -> NucleusClaimHtlcProto { NucleusClaimHtlcProto::from(&coin) } + fn from(coin: NucleusClaimHtlcMsg) -> NucleusClaimHtlcProto { + NucleusClaimHtlcProto::from(&coin) + } } impl From<&NucleusClaimHtlcMsg> for NucleusClaimHtlcProto { diff --git a/mm2src/coins/tendermint/ibc/transfer_v1.rs b/mm2src/coins/tendermint/ibc/transfer_v1.rs index 22bad1fefe..e6c6a28ea5 100644 --- a/mm2src/coins/tendermint/ibc/transfer_v1.rs +++ b/mm2src/coins/tendermint/ibc/transfer_v1.rs @@ -55,7 +55,9 @@ impl TryFrom for MsgTransfer { type Error = ErrorReport; #[inline(always)] - fn try_from(proto: IBCTransferV1Proto) -> Result { MsgTransfer::try_from(&proto) } + fn try_from(proto: IBCTransferV1Proto) -> Result { + MsgTransfer::try_from(&proto) + } } impl TryFrom<&IBCTransferV1Proto> for MsgTransfer { @@ -80,7 +82,9 @@ impl TryFrom<&IBCTransferV1Proto> for MsgTransfer { } impl From for IBCTransferV1Proto { - fn from(coin: MsgTransfer) -> IBCTransferV1Proto { IBCTransferV1Proto::from(&coin) } + fn from(coin: MsgTransfer) -> IBCTransferV1Proto { + IBCTransferV1Proto::from(&coin) + } } impl From<&MsgTransfer> for IBCTransferV1Proto { diff --git a/mm2src/coins/tendermint/rpc/mod.rs b/mm2src/coins/tendermint/rpc/mod.rs index 26ccdf6553..a41b013835 100644 --- a/mm2src/coins/tendermint/rpc/mod.rs +++ b/mm2src/coins/tendermint/rpc/mod.rs @@ -1,8 +1,10 @@ -#[cfg(not(target_arch = "wasm32"))] mod tendermint_native_rpc; +#[cfg(not(target_arch = "wasm32"))] +mod tendermint_native_rpc; #[cfg(not(target_arch = "wasm32"))] pub(crate) use tendermint_native_rpc::*; -#[cfg(target_arch = "wasm32")] mod tendermint_wasm_rpc; +#[cfg(target_arch = "wasm32")] +mod tendermint_wasm_rpc; #[cfg(target_arch = "wasm32")] pub(crate) use tendermint_wasm_rpc::*; diff --git a/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs b/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs index b0de493025..e56ea149f3 100644 --- a/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs +++ b/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs @@ -12,8 +12,9 @@ use std::fmt; use std::time::Duration; use tendermint_rpc::endpoint::validators::DEFAULT_VALIDATORS_PER_PAGE; use tendermint_rpc::endpoint::*; -pub use tendermint_rpc::endpoint::{abci_query::Request as AbciRequest, health::Request as HealthRequest, - tx_search::Request as TxSearchRequest}; +pub use tendermint_rpc::endpoint::{ + abci_query::Request as AbciRequest, health::Request as HealthRequest, tx_search::Request as TxSearchRequest, +}; use tendermint_rpc::Paging; pub use tendermint_rpc::{query::Query as TendermintQuery, Error, Order, Scheme, SimpleRequest, Url}; use tokio::time; @@ -29,7 +30,9 @@ use tokio::time; #[allow(dead_code)] pub trait Client { /// `/abci_info`: get information about the ABCI application. - async fn abci_info(&self) -> Result { self.perform(abci_info::Request).await } + async fn abci_info(&self) -> Result { + self.perform(abci_info::Request).await + } /// `/abci_query`: query the ABCI application async fn abci_query( @@ -57,7 +60,9 @@ pub trait Client { } /// `/block`: get the latest block. - async fn latest_block(&self) -> Result { self.perform(block::Request::default()).await } + async fn latest_block(&self) -> Result { + self.perform(block::Request::default()).await + } /// `/block_results`: get ABCI results for a block at a particular height. async fn block_results(&self, height: H) -> Result @@ -185,7 +190,9 @@ pub trait Client { } /// `/commit`: get the latest block commit - async fn latest_commit(&self) -> Result { self.perform(commit::Request::default()).await } + async fn latest_commit(&self) -> Result { + self.perform(commit::Request::default()).await + } /// `/health`: get node health. /// @@ -204,11 +211,15 @@ pub trait Client { } /// `/net_info`: obtain information about P2P and other network connections. - async fn net_info(&self) -> Result { self.perform(net_info::Request).await } + async fn net_info(&self) -> Result { + self.perform(net_info::Request).await + } /// `/status`: get Tendermint status including node info, pubkey, latest /// block hash, app hash, block height and time. - async fn status(&self) -> Result { self.perform(status::Request).await } + async fn status(&self) -> Result { + self.perform(status::Request).await + } /// `/broadcast_evidence`: broadcast an evidence. async fn broadcast_evidence(&self, e: Evidence) -> Result { @@ -310,10 +321,14 @@ impl HttpClient { } #[inline] - pub fn uri(&self) -> Uri { self.inner.uri() } + pub fn uri(&self) -> Uri { + self.inner.uri() + } #[inline] - pub fn proxy_sign_keypair(&self) -> &Option { self.inner.proxy_sign_keypair() } + pub fn proxy_sign_keypair(&self) -> &Option { + self.inner.proxy_sign_keypair() + } } #[async_trait] @@ -355,11 +370,15 @@ impl FromStr for HttpClientUrl { impl TryFrom<&str> for HttpClientUrl { type Error = Error; - fn try_from(value: &str) -> Result { value.parse() } + fn try_from(value: &str) -> Result { + value.parse() + } } impl From for Url { - fn from(url: HttpClientUrl) -> Self { url.0 } + fn from(url: HttpClientUrl) -> Self { + url.0 + } } impl TryFrom for hyper::Uri { diff --git a/mm2src/coins/tendermint/rpc/tendermint_wasm_rpc.rs b/mm2src/coins/tendermint/rpc/tendermint_wasm_rpc.rs index 559b097b7f..5a7eb55e82 100644 --- a/mm2src/coins/tendermint/rpc/tendermint_wasm_rpc.rs +++ b/mm2src/coins/tendermint/rpc/tendermint_wasm_rpc.rs @@ -10,9 +10,11 @@ use mm2_p2p::Keypair; use proxy_signature::RawMessage; use std::str::FromStr; use tendermint_rpc::endpoint::{abci_info, broadcast}; -pub use tendermint_rpc::endpoint::{abci_query::{AbciQuery, Request as AbciRequest}, - health::Request as HealthRequest, - tx_search::Request as TxSearchRequest}; +pub use tendermint_rpc::endpoint::{ + abci_query::{AbciQuery, Request as AbciRequest}, + health::Request as HealthRequest, + tx_search::Request as TxSearchRequest, +}; use tendermint_rpc::error::Error as TendermintRpcError; use tendermint_rpc::request::SimpleRequest; pub use tendermint_rpc::Order; @@ -30,7 +32,9 @@ pub(crate) enum HttpClientInitError { } impl From for HttpClientInitError { - fn from(err: InvalidUri) -> Self { HttpClientInitError::InvalidUri(err) } + fn from(err: InvalidUri) -> Self { + HttpClientInitError::InvalidUri(err) + } } #[derive(Debug, Display)] @@ -46,11 +50,15 @@ pub enum PerformError { } impl From for PerformError { - fn from(err: SlurpError) -> Self { PerformError::Slurp(err) } + fn from(err: SlurpError) -> Self { + PerformError::Slurp(err) + } } impl From for PerformError { - fn from(err: TendermintRpcError) -> Self { PerformError::TendermintRpc(err) } + fn from(err: TendermintRpcError) -> Self { + PerformError::TendermintRpc(err) + } } impl HttpClient { @@ -63,10 +71,14 @@ impl HttpClient { } #[inline] - pub fn uri(&self) -> http::Uri { Uri::from_str(&self.uri).expect("This should never happen.") } + pub fn uri(&self) -> http::Uri { + Uri::from_str(&self.uri).expect("This should never happen.") + } #[inline] - pub fn proxy_sign_keypair(&self) -> &Option { &self.proxy_sign_keypair } + pub fn proxy_sign_keypair(&self) -> &Option { + &self.proxy_sign_keypair + } pub(crate) async fn perform(&self, request: R) -> Result where diff --git a/mm2src/coins/tendermint/tendermint_balance_events.rs b/mm2src/coins/tendermint/tendermint_balance_events.rs index 3304e35e97..4e55b7c138 100644 --- a/mm2src/coins/tendermint/tendermint_balance_events.rs +++ b/mm2src/coins/tendermint/tendermint_balance_events.rs @@ -16,7 +16,9 @@ pub struct TendermintBalanceEventStreamer { } impl TendermintBalanceEventStreamer { - pub fn new(coin: TendermintCoin) -> Self { Self { coin } } + pub fn new(coin: TendermintCoin) -> Self { + Self { coin } + } } #[async_trait] diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index c249b02c75..4ec7a87b08 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -1,28 +1,33 @@ use super::ethermint_account::EthermintAccount; -use super::htlc::{ClaimHtlcMsg, ClaimHtlcProto, CreateHtlcMsg, CreateHtlcProto, HtlcType, QueryHtlcRequestProto, - QueryHtlcResponse, TendermintHtlc, HTLC_STATE_COMPLETED, HTLC_STATE_OPEN, HTLC_STATE_REFUNDED}; +use super::htlc::{ + ClaimHtlcMsg, ClaimHtlcProto, CreateHtlcMsg, CreateHtlcProto, HtlcType, QueryHtlcRequestProto, QueryHtlcResponse, + TendermintHtlc, HTLC_STATE_COMPLETED, HTLC_STATE_OPEN, HTLC_STATE_REFUNDED, +}; use super::ibc::transfer_v1::MsgTransfer; use super::ibc::IBC_GAS_LIMIT_DEFAULT; use super::rpc::*; use crate::coin_errors::{AddressFromPubkeyError, MyAddressError, ValidatePaymentError, ValidatePaymentResult}; use crate::hd_wallet::{HDAddressSelector, HDPathAccountToAddressId}; use crate::rpc_command::tendermint::ibc::ChannelId; -use crate::rpc_command::tendermint::staking::{ClaimRewardsPayload, Delegation, DelegationPayload, - DelegationsQueryResponse, Undelegation, UndelegationEntry, - UndelegationsQueryResponse, ValidatorStatus}; +use crate::rpc_command::tendermint::staking::{ + ClaimRewardsPayload, Delegation, DelegationPayload, DelegationsQueryResponse, Undelegation, UndelegationEntry, + UndelegationsQueryResponse, ValidatorStatus, +}; use crate::utxo::sat_from_big_decimal; use crate::utxo::utxo_common::big_decimal_from_sat; -use crate::{big_decimal_from_sat_unsigned, BalanceError, BalanceFut, BigDecimal, CheckIfMyPaymentSentArgs, - CoinBalance, ConfirmPaymentInput, DelegationError, DexFee, FeeApproxStage, FoundSwapTxSpend, - HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, PrivKeyBuildPolicy, PrivKeyPolicy, - PrivKeyPolicyNotAllowed, RawTransactionError, RawTransactionFut, RawTransactionRequest, RawTransactionRes, - RawTransactionResult, RefundPaymentArgs, RpcCommonOps, SearchForSwapTxSpendInput, SendPaymentArgs, - SignRawTransactionRequest, SignatureError, SignatureResult, SpendPaymentArgs, SwapOps, ToBytes, TradeFee, - TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionData, - TransactionDetails, TransactionEnum, TransactionErr, TransactionFut, TransactionResult, TransactionType, - TxFeeDetails, TxMarshalingErr, UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, - ValidateOtherPubKeyErr, ValidatePaymentFut, ValidatePaymentInput, VerificationError, VerificationResult, - WaitForHTLCTxSpendArgs, WatcherOps, WeakSpawner, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest}; +use crate::{ + big_decimal_from_sat_unsigned, BalanceError, BalanceFut, BigDecimal, CheckIfMyPaymentSentArgs, CoinBalance, + ConfirmPaymentInput, DelegationError, DexFee, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, + MmCoin, NegotiateSwapContractAddrErr, PrivKeyBuildPolicy, PrivKeyPolicy, PrivKeyPolicyNotAllowed, + RawTransactionError, RawTransactionFut, RawTransactionRequest, RawTransactionRes, RawTransactionResult, + RefundPaymentArgs, RpcCommonOps, SearchForSwapTxSpendInput, SendPaymentArgs, SignRawTransactionRequest, + SignatureError, SignatureResult, SpendPaymentArgs, SwapOps, ToBytes, TradeFee, TradePreimageError, + TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionData, TransactionDetails, TransactionEnum, + TransactionErr, TransactionFut, TransactionResult, TransactionType, TxFeeDetails, TxMarshalingErr, + UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, ValidateOtherPubKeyErr, ValidatePaymentFut, + ValidatePaymentInput, VerificationError, VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, WeakSpawner, + WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest, +}; use async_std::prelude::FutureExt as AsyncStdFutureExt; use async_trait::async_trait; use bip32::DerivationPath; @@ -36,20 +41,24 @@ use cosmrs::bank::{MsgMultiSend, MsgSend, MultiSendIo}; use cosmrs::crypto::secp256k1::SigningKey; use cosmrs::distribution::MsgWithdrawDelegatorReward; use cosmrs::proto::cosmos::auth::v1beta1::{BaseAccount, QueryAccountRequest, QueryAccountResponse}; -use cosmrs::proto::cosmos::bank::v1beta1::{MsgMultiSend as MsgMultiSendProto, MsgSend as MsgSendProto, - QueryBalanceRequest, QueryBalanceResponse}; +use cosmrs::proto::cosmos::bank::v1beta1::{ + MsgMultiSend as MsgMultiSendProto, MsgSend as MsgSendProto, QueryBalanceRequest, QueryBalanceResponse, +}; use cosmrs::proto::cosmos::base::query::v1beta1::PageRequest; -use cosmrs::proto::cosmos::base::tendermint::v1beta1::{GetBlockByHeightRequest, GetBlockByHeightResponse, - GetLatestBlockRequest, GetLatestBlockResponse}; +use cosmrs::proto::cosmos::base::tendermint::v1beta1::{ + GetBlockByHeightRequest, GetBlockByHeightResponse, GetLatestBlockRequest, GetLatestBlockResponse, +}; use cosmrs::proto::cosmos::base::v1beta1::{Coin as CoinProto, DecCoin}; use cosmrs::proto::cosmos::distribution::v1beta1::{QueryDelegationRewardsRequest, QueryDelegationRewardsResponse}; -use cosmrs::proto::cosmos::staking::v1beta1::{QueryDelegationRequest, QueryDelegationResponse, - QueryDelegatorDelegationsRequest, QueryDelegatorDelegationsResponse, - QueryDelegatorUnbondingDelegationsRequest, - QueryDelegatorUnbondingDelegationsResponse, QueryValidatorsRequest, - QueryValidatorsResponse as QueryValidatorsResponseProto}; -use cosmrs::proto::cosmos::tx::v1beta1::{GetTxRequest, GetTxResponse, SimulateRequest, SimulateResponse, Tx, TxBody, - TxRaw}; +use cosmrs::proto::cosmos::staking::v1beta1::{ + QueryDelegationRequest, QueryDelegationResponse, QueryDelegatorDelegationsRequest, + QueryDelegatorDelegationsResponse, QueryDelegatorUnbondingDelegationsRequest, + QueryDelegatorUnbondingDelegationsResponse, QueryValidatorsRequest, + QueryValidatorsResponse as QueryValidatorsResponseProto, +}; +use cosmrs::proto::cosmos::tx::v1beta1::{ + GetTxRequest, GetTxResponse, SimulateRequest, SimulateResponse, Tx, TxBody, TxRaw, +}; use cosmrs::proto::ibc; use cosmrs::proto::ibc::core::channel::v1::{QueryChannelRequest, QueryChannelResponse}; use cosmrs::proto::prost::{DecodeError, Message}; @@ -90,7 +99,8 @@ use std::str::FromStr; use std::sync::{Arc, Mutex}; use uuid::Uuid; -#[cfg(test)] use mocktopus::macros::*; +#[cfg(test)] +use mocktopus::macros::*; // ABCI Request Paths const ABCI_GET_LATEST_BLOCK_PATH: &str = "/cosmos.base.tendermint.v1beta1.Service/GetLatestBlock"; @@ -265,7 +275,9 @@ impl TendermintActivationPolicy { Self::PrivateKey(private_key_policy) } - pub fn with_public_key(account_public_key: PublicKey) -> Self { Self::PublicKey(account_public_key) } + pub fn with_public_key(account_public_key: PublicKey) -> Self { + Self::PublicKey(account_public_key) + } fn generate_account_id(&self, account_prefix: &str) -> Result { match self { @@ -395,7 +407,9 @@ pub enum TendermintWalletConnectionType { } impl Default for TendermintWalletConnectionType { - fn default() -> Self { Self::Native } + fn default() -> Self { + Self::Native + } } pub struct TendermintCoinImpl { @@ -422,7 +436,9 @@ pub struct TendermintCoin(Arc); impl Deref for TendermintCoin { type Target = TendermintCoinImpl; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { + &self.0 + } } #[derive(Debug, Clone)] @@ -502,23 +518,33 @@ pub enum IBCError { } impl From for WithdrawError { - fn from(err: IBCError) -> Self { WithdrawError::IBCError(err) } + fn from(err: IBCError) -> Self { + WithdrawError::IBCError(err) + } } impl From for TendermintCoinRpcError { - fn from(err: DecodeError) -> Self { TendermintCoinRpcError::Prost(err.to_string()) } + fn from(err: DecodeError) -> Self { + TendermintCoinRpcError::Prost(err.to_string()) + } } impl From for TendermintCoinRpcError { - fn from(err: PrivKeyPolicyNotAllowed) -> Self { TendermintCoinRpcError::InternalError(err.to_string()) } + fn from(err: PrivKeyPolicyNotAllowed) -> Self { + TendermintCoinRpcError::InternalError(err.to_string()) + } } impl From for WithdrawError { - fn from(err: TendermintCoinRpcError) -> Self { WithdrawError::Transport(err.to_string()) } + fn from(err: TendermintCoinRpcError) -> Self { + WithdrawError::Transport(err.to_string()) + } } impl From for DelegationError { - fn from(err: TendermintCoinRpcError) -> Self { DelegationError::Transport(err.to_string()) } + fn from(err: TendermintCoinRpcError) -> Self { + DelegationError::Transport(err.to_string()) + } } impl From for BalanceError { @@ -554,21 +580,29 @@ impl From for ValidatePaymentError { } impl From for TradePreimageError { - fn from(err: TendermintCoinRpcError) -> Self { TradePreimageError::Transport(err.to_string()) } + fn from(err: TendermintCoinRpcError) -> Self { + TradePreimageError::Transport(err.to_string()) + } } #[cfg(not(target_arch = "wasm32"))] impl From for TendermintCoinRpcError { - fn from(err: tendermint_rpc::Error) -> Self { TendermintCoinRpcError::PerformError(err.to_string()) } + fn from(err: tendermint_rpc::Error) -> Self { + TendermintCoinRpcError::PerformError(err.to_string()) + } } #[cfg(target_arch = "wasm32")] impl From for TendermintCoinRpcError { - fn from(err: PerformError) -> Self { TendermintCoinRpcError::PerformError(err.to_string()) } + fn from(err: PerformError) -> Self { + TendermintCoinRpcError::PerformError(err.to_string()) + } } impl From for RawTransactionError { - fn from(err: TendermintCoinRpcError) -> Self { RawTransactionError::Transport(err.to_string()) } + fn from(err: TendermintCoinRpcError) -> Self { + RawTransactionError::Transport(err.to_string()) + } } #[derive(Clone, Debug, PartialEq)] @@ -577,7 +611,9 @@ pub struct CosmosTransaction { } impl crate::Transaction for CosmosTransaction { - fn tx_hex(&self) -> Vec { self.data.encode_to_vec() } + fn tx_hex(&self) -> Vec { + self.data.encode_to_vec() + } fn tx_hash_as_bytes(&self) -> BytesJson { let bytes = self.data.encode_to_vec(); @@ -603,11 +639,15 @@ pub enum AccountIdFromPubkeyHexErr { } impl From for AccountIdFromPubkeyHexErr { - fn from(err: FromHexError) -> Self { AccountIdFromPubkeyHexErr::InvalidHexString(err) } + fn from(err: FromHexError) -> Self { + AccountIdFromPubkeyHexErr::InvalidHexString(err) + } } impl From for AccountIdFromPubkeyHexErr { - fn from(err: ErrorReport) -> Self { AccountIdFromPubkeyHexErr::CouldNotCreateAccountId(err) } + fn from(err: ErrorReport) -> Self { + AccountIdFromPubkeyHexErr::CouldNotCreateAccountId(err) + } } pub fn account_id_from_pubkey_hex(prefix: &str, pubkey: &str) -> Result { @@ -641,20 +681,28 @@ enum SearchForSwapTxSpendErr { } impl From for SearchForSwapTxSpendErr { - fn from(e: ErrorReport) -> Self { SearchForSwapTxSpendErr::Cosmrs(e) } + fn from(e: ErrorReport) -> Self { + SearchForSwapTxSpendErr::Cosmrs(e) + } } impl From for SearchForSwapTxSpendErr { - fn from(e: TendermintCoinRpcError) -> Self { SearchForSwapTxSpendErr::Rpc(e) } + fn from(e: TendermintCoinRpcError) -> Self { + SearchForSwapTxSpendErr::Rpc(e) + } } impl From for SearchForSwapTxSpendErr { - fn from(e: DecodeError) -> Self { SearchForSwapTxSpendErr::Proto(e) } + fn from(e: DecodeError) -> Self { + SearchForSwapTxSpendErr::Proto(e) + } } #[async_trait] impl TendermintCommons for TendermintCoin { - fn platform_denom(&self) -> &Denom { &self.protocol_info.denom } + fn platform_denom(&self) -> &Denom { + &self.protocol_info.denom + } fn set_history_sync_state(&self, new_state: HistorySyncState) { *self.history_sync_state.lock().unwrap() = new_state; @@ -861,7 +909,9 @@ impl TendermintCoin { } #[inline(always)] - fn gas_price(&self) -> f64 { self.protocol_info.gas_price.unwrap_or(DEFAULT_GAS_PRICE) } + fn gas_price(&self) -> f64 { + self.protocol_info.gas_price.unwrap_or(DEFAULT_GAS_PRICE) + } #[allow(unused)] async fn get_latest_block(&self) -> MmResult { @@ -3190,7 +3240,9 @@ fn clients_from_urls(ctx: &MmArc, nodes: Vec) -> MmResult bool { false } + fn is_asset_chain(&self) -> bool { + false + } #[cfg(feature = "ibc-routing-for-swaps")] fn wallet_only(&self, ctx: &MmArc) -> bool { @@ -3230,7 +3282,9 @@ impl MmCoin for TendermintCoin { wallet_only_conf || self.is_ledger_connection() } - fn spawner(&self) -> WeakSpawner { self.abortable_system.weak_spawner() } + fn spawner(&self) -> WeakSpawner { + self.abortable_system.weak_spawner() + } fn withdraw(&self, req: WithdrawRequest) -> WithdrawFut { let coin = self.clone(); @@ -3447,7 +3501,9 @@ impl MmCoin for TendermintCoin { Box::new(fut.boxed().compat()) } - fn decimals(&self) -> u8 { self.protocol_info.decimals } + fn decimals(&self) -> u8 { + self.protocol_info.decimals + } fn convert_to_address(&self, from: &str, to_address_format: Json) -> Result { // TODO @@ -3472,7 +3528,9 @@ impl MmCoin for TendermintCoin { Box::new(futures01::future::err(())) } - fn history_sync_status(&self) -> HistorySyncState { self.history_sync_state.lock().unwrap().clone() } + fn history_sync_status(&self) -> HistorySyncState { + self.history_sync_state.lock().unwrap().clone() + } fn get_trade_fee(&self) -> Box + Send> { Box::new(futures01::future::err("Not implemented".into())) @@ -3642,23 +3700,37 @@ impl MmCoin for TendermintCoin { .await } - fn required_confirmations(&self) -> u64 { 0 } + fn required_confirmations(&self) -> u64 { + 0 + } - fn requires_notarization(&self) -> bool { false } + fn requires_notarization(&self) -> bool { + false + } fn set_required_confirmations(&self, confirmations: u64) { warn!("set_required_confirmations is not supported for tendermint") } - fn set_requires_notarization(&self, requires_nota: bool) { warn!("TendermintCoin doesn't support notarization") } + fn set_requires_notarization(&self, requires_nota: bool) { + warn!("TendermintCoin doesn't support notarization") + } - fn swap_contract_address(&self) -> Option { None } + fn swap_contract_address(&self) -> Option { + None + } - fn fallback_swap_contract(&self) -> Option { None } + fn fallback_swap_contract(&self) -> Option { + None + } - fn mature_confirmations(&self) -> Option { None } + fn mature_confirmations(&self) -> Option { + None + } - fn coin_protocol_info(&self, _amount_to_receive: Option) -> Vec { Vec::new() } + fn coin_protocol_info(&self, _amount_to_receive: Option) -> Vec { + Vec::new() + } fn is_coin_protocol_supported( &self, @@ -3670,16 +3742,22 @@ impl MmCoin for TendermintCoin { true } - fn on_disabled(&self) -> Result<(), AbortedError> { AbortableSystem::abort_all(&self.abortable_system) } + fn on_disabled(&self) -> Result<(), AbortedError> { + AbortableSystem::abort_all(&self.abortable_system) + } fn on_token_deactivated(&self, _ticker: &str) {} } #[async_trait] impl MarketCoinOps for TendermintCoin { - fn ticker(&self) -> &str { &self.ticker } + fn ticker(&self) -> &str { + &self.ticker + } - fn my_address(&self) -> MmResult { Ok(self.account_id.to_string()) } + fn my_address(&self) -> MmResult { + Ok(self.account_id.to_string()) + } fn address_from_pubkey(&self, pubkey: &H264Json) -> MmResult { let address = account_id_from_raw_pubkey(&self.protocol_info.account_prefix, &pubkey.0) @@ -3727,7 +3805,9 @@ impl MarketCoinOps for TendermintCoin { Box::new(self.my_balance().map(|coin_balance| coin_balance.spendable)) } - fn platform_ticker(&self) -> &str { &self.ticker } + fn platform_ticker(&self) -> &str { + &self.ticker + } fn send_raw_tx(&self, tx: &str) -> Box + Send> { let tx_bytes = try_fus!(hex::decode(tx)); @@ -3874,13 +3954,19 @@ impl MarketCoinOps for TendermintCoin { } #[inline] - fn min_tx_amount(&self) -> BigDecimal { big_decimal_from_sat(MIN_TX_SATOSHIS, self.protocol_info.decimals) } + fn min_tx_amount(&self) -> BigDecimal { + big_decimal_from_sat(MIN_TX_SATOSHIS, self.protocol_info.decimals) + } #[inline] - fn min_trading_vol(&self) -> MmNumber { self.min_tx_amount().into() } + fn min_trading_vol(&self) -> MmNumber { + self.min_tx_amount().into() + } #[inline] - fn should_burn_dex_fee(&self) -> bool { false } // TODO: fix back to true when negotiation version added + fn should_burn_dex_fee(&self) -> bool { + false + } // TODO: fix back to true when negotiation version added fn is_trezor(&self) -> bool { match &self.activation_policy { @@ -4237,10 +4323,15 @@ pub(crate) async fn create_withdraw_msg_as_any( ibc_source_channel: Option, ) -> Result> { if let Some(channel_id) = ibc_source_channel { - MsgTransfer::new_with_default_timeout(channel_id.to_string(), sender, receiver, Coin { - denom: denom.clone(), - amount: amount.into(), - }) + MsgTransfer::new_with_default_timeout( + channel_id.to_string(), + sender, + receiver, + Coin { + denom: denom.clone(), + amount: amount.into(), + }, + ) .to_any() } else { MsgSend { diff --git a/mm2src/coins/tendermint/tendermint_token.rs b/mm2src/coins/tendermint/tendermint_token.rs index c85fe08605..220ddedf48 100644 --- a/mm2src/coins/tendermint/tendermint_token.rs +++ b/mm2src/coins/tendermint/tendermint_token.rs @@ -1,21 +1,24 @@ //! Module containing implementation for Tendermint Tokens. They include native assets + IBC use super::ibc::IBC_GAS_LIMIT_DEFAULT; -use super::{create_withdraw_msg_as_any, TendermintCoin, TendermintFeeDetails, GAS_LIMIT_DEFAULT, MIN_TX_SATOSHIS, - TIMEOUT_HEIGHT_DELTA, TX_DEFAULT_MEMO}; +use super::{ + create_withdraw_msg_as_any, TendermintCoin, TendermintFeeDetails, GAS_LIMIT_DEFAULT, MIN_TX_SATOSHIS, + TIMEOUT_HEIGHT_DELTA, TX_DEFAULT_MEMO, +}; use crate::coin_errors::{AddressFromPubkeyError, ValidatePaymentResult}; use crate::hd_wallet::HDAddressSelector; use crate::utxo::utxo_common::big_decimal_from_sat; -use crate::{big_decimal_from_sat_unsigned, utxo::sat_from_big_decimal, BalanceFut, BigDecimal, - CheckIfMyPaymentSentArgs, CoinBalance, ConfirmPaymentInput, DexFee, FeeApproxStage, FoundSwapTxSpend, - HistorySyncState, MarketCoinOps, MmCoin, MyAddressError, NegotiateSwapContractAddrErr, - RawTransactionError, RawTransactionFut, RawTransactionRequest, RawTransactionResult, RefundPaymentArgs, - SearchForSwapTxSpendInput, SendPaymentArgs, SignRawTransactionRequest, SignatureResult, SpendPaymentArgs, - SwapOps, TradeFee, TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionDetails, - TransactionEnum, TransactionErr, TransactionResult, TransactionType, TxFeeDetails, TxMarshalingErr, - UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, ValidateOtherPubKeyErr, - ValidatePaymentInput, VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, WeakSpawner, WithdrawError, - WithdrawFut, WithdrawRequest}; +use crate::{ + big_decimal_from_sat_unsigned, utxo::sat_from_big_decimal, BalanceFut, BigDecimal, CheckIfMyPaymentSentArgs, + CoinBalance, ConfirmPaymentInput, DexFee, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, + MmCoin, MyAddressError, NegotiateSwapContractAddrErr, RawTransactionError, RawTransactionFut, + RawTransactionRequest, RawTransactionResult, RefundPaymentArgs, SearchForSwapTxSpendInput, SendPaymentArgs, + SignRawTransactionRequest, SignatureResult, SpendPaymentArgs, SwapOps, TradeFee, TradePreimageFut, + TradePreimageResult, TradePreimageValue, TransactionDetails, TransactionEnum, TransactionErr, TransactionResult, + TransactionType, TxFeeDetails, TxMarshalingErr, UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, + ValidateOtherPubKeyErr, ValidatePaymentInput, VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, WeakSpawner, + WithdrawError, WithdrawFut, WithdrawRequest, +}; use async_trait::async_trait; use bitcrypto::sha256; use common::executor::abortable_queue::AbortableQueue; @@ -52,7 +55,9 @@ pub struct TendermintToken(Arc); impl Deref for TendermintToken { type Target = TendermintTokenImpl; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { + &self.0 + } } #[derive(Clone, Debug, Deserialize, Serialize)] @@ -72,11 +77,15 @@ pub enum TendermintTokenInitError { } impl From for TendermintTokenInitError { - fn from(err: MyAddressError) -> Self { TendermintTokenInitError::MyAddressError(err.to_string()) } + fn from(err: MyAddressError) -> Self { + TendermintTokenInitError::MyAddressError(err.to_string()) + } } impl From for TendermintTokenInitError { - fn from(e: AbortedError) -> Self { TendermintTokenInitError::Internal(e.to_string()) } + fn from(e: AbortedError) -> Self { + TendermintTokenInitError::Internal(e.to_string()) + } } impl TendermintToken { @@ -264,9 +273,13 @@ impl WatcherOps for TendermintToken {} #[async_trait] impl MarketCoinOps for TendermintToken { - fn ticker(&self) -> &str { &self.ticker } + fn ticker(&self) -> &str { + &self.ticker + } - fn my_address(&self) -> MmResult { self.platform_coin.my_address() } + fn my_address(&self) -> MmResult { + self.platform_coin.my_address() + } fn address_from_pubkey(&self, pubkey: &H264Json) -> MmResult { self.platform_coin.address_from_pubkey(pubkey) @@ -276,7 +289,9 @@ impl MarketCoinOps for TendermintToken { self.platform_coin.get_public_key().await } - fn sign_message_hash(&self, message: &str) -> Option<[u8; 32]> { self.platform_coin.sign_message_hash(message) } + fn sign_message_hash(&self, message: &str) -> Option<[u8; 32]> { + self.platform_coin.sign_message_hash(message) + } fn sign_message(&self, message: &str, address: Option) -> SignatureResult { self.platform_coin.sign_message(message, address) @@ -302,9 +317,13 @@ impl MarketCoinOps for TendermintToken { Box::new(fut.boxed().compat()) } - fn base_coin_balance(&self) -> BalanceFut { self.platform_coin.my_spendable_balance() } + fn base_coin_balance(&self) -> BalanceFut { + self.platform_coin.my_spendable_balance() + } - fn platform_ticker(&self) -> &str { self.platform_coin.ticker() } + fn platform_ticker(&self) -> &str { + self.platform_coin.ticker() + } fn send_raw_tx(&self, tx: &str) -> Box + Send> { self.platform_coin.send_raw_tx(tx) @@ -343,30 +362,48 @@ impl MarketCoinOps for TendermintToken { self.platform_coin.tx_enum_from_bytes(bytes) } - fn current_block(&self) -> Box + Send> { self.platform_coin.current_block() } + fn current_block(&self) -> Box + Send> { + self.platform_coin.current_block() + } - fn display_priv_key(&self) -> Result { self.platform_coin.display_priv_key() } + fn display_priv_key(&self) -> Result { + self.platform_coin.display_priv_key() + } #[inline] - fn min_tx_amount(&self) -> BigDecimal { big_decimal_from_sat(MIN_TX_SATOSHIS, self.decimals) } + fn min_tx_amount(&self) -> BigDecimal { + big_decimal_from_sat(MIN_TX_SATOSHIS, self.decimals) + } #[inline] - fn min_trading_vol(&self) -> MmNumber { self.min_tx_amount().into() } + fn min_trading_vol(&self) -> MmNumber { + self.min_tx_amount().into() + } #[inline] - fn should_burn_dex_fee(&self) -> bool { false } // TODO: fix back to true when negotiation version added + fn should_burn_dex_fee(&self) -> bool { + false + } // TODO: fix back to true when negotiation version added - fn is_trezor(&self) -> bool { self.platform_coin.is_trezor() } + fn is_trezor(&self) -> bool { + self.platform_coin.is_trezor() + } } #[async_trait] #[allow(unused_variables)] impl MmCoin for TendermintToken { - fn is_asset_chain(&self) -> bool { false } + fn is_asset_chain(&self) -> bool { + false + } - fn wallet_only(&self, ctx: &MmArc) -> bool { self.platform_coin.wallet_only(ctx) } + fn wallet_only(&self, ctx: &MmArc) -> bool { + self.platform_coin.wallet_only(ctx) + } - fn spawner(&self) -> WeakSpawner { self.abortable_system.weak_spawner() } + fn spawner(&self) -> WeakSpawner { + self.abortable_system.weak_spawner() + } fn withdraw(&self, req: WithdrawRequest) -> WithdrawFut { let platform = self.platform_coin.clone(); @@ -540,22 +577,30 @@ impl MmCoin for TendermintToken { self.platform_coin.get_raw_transaction(req) } - fn get_tx_hex_by_hash(&self, tx_hash: Vec) -> RawTransactionFut { unimplemented!() } + fn get_tx_hex_by_hash(&self, tx_hash: Vec) -> RawTransactionFut { + unimplemented!() + } - fn decimals(&self) -> u8 { self.decimals } + fn decimals(&self) -> u8 { + self.decimals + } fn convert_to_address(&self, from: &str, to_address_format: Json) -> Result { self.platform_coin.convert_to_address(from, to_address_format) } - fn validate_address(&self, address: &str) -> ValidateAddressResult { self.platform_coin.validate_address(address) } + fn validate_address(&self, address: &str) -> ValidateAddressResult { + self.platform_coin.validate_address(address) + } fn process_history_loop(&self, ctx: MmArc) -> Box + Send> { warn!("process_history_loop is deprecated, tendermint uses tx_history_v2"); Box::new(futures01::future::err(())) } - fn history_sync_status(&self) -> HistorySyncState { self.platform_coin.history_sync_status() } + fn history_sync_status(&self) -> HistorySyncState { + self.platform_coin.history_sync_status() + } fn get_trade_fee(&self) -> Box + Send> { Box::new(futures01::future::err("Not implemented".into())) @@ -594,9 +639,13 @@ impl MmCoin for TendermintToken { .await } - fn required_confirmations(&self) -> u64 { self.platform_coin.required_confirmations() } + fn required_confirmations(&self) -> u64 { + self.platform_coin.required_confirmations() + } - fn requires_notarization(&self) -> bool { self.platform_coin.requires_notarization() } + fn requires_notarization(&self) -> bool { + self.platform_coin.requires_notarization() + } fn set_required_confirmations(&self, confirmations: u64) { warn!("set_required_confirmations is not supported for tendermint") @@ -606,11 +655,17 @@ impl MmCoin for TendermintToken { self.platform_coin.set_requires_notarization(requires_nota) } - fn swap_contract_address(&self) -> Option { self.platform_coin.swap_contract_address() } + fn swap_contract_address(&self) -> Option { + self.platform_coin.swap_contract_address() + } - fn fallback_swap_contract(&self) -> Option { self.platform_coin.fallback_swap_contract() } + fn fallback_swap_contract(&self) -> Option { + self.platform_coin.fallback_swap_contract() + } - fn mature_confirmations(&self) -> Option { None } + fn mature_confirmations(&self) -> Option { + None + } fn coin_protocol_info(&self, amount_to_receive: Option) -> Vec { self.platform_coin.coin_protocol_info(amount_to_receive) @@ -627,7 +682,9 @@ impl MmCoin for TendermintToken { .is_coin_protocol_supported(info, amount_to_send, locktime, is_maker) } - fn on_disabled(&self) -> Result<(), AbortedError> { self.abortable_system.abort_all() } + fn on_disabled(&self) -> Result<(), AbortedError> { + self.abortable_system.abort_all() + } fn on_token_deactivated(&self, _ticker: &str) {} } diff --git a/mm2src/coins/tendermint/tendermint_tx_history_v2.rs b/mm2src/coins/tendermint/tendermint_tx_history_v2.rs index 99133cb553..9490fb4fc6 100644 --- a/mm2src/coins/tendermint/tendermint_tx_history_v2.rs +++ b/mm2src/coins/tendermint/tendermint_tx_history_v2.rs @@ -6,8 +6,9 @@ use crate::tendermint::TendermintFeeDetails; use crate::tx_history_storage::{GetTxHistoryFilters, WalletId}; use crate::utxo::tx_history_events::TxHistoryEventStreamer; use crate::utxo::utxo_common::big_decimal_from_sat_unsigned; -use crate::{HistorySyncState, MarketCoinOps, MmCoin, TransactionData, TransactionDetails, TransactionType, - TxFeeDetails}; +use crate::{ + HistorySyncState, MarketCoinOps, MmCoin, TransactionData, TransactionDetails, TransactionType, TxFeeDetails, +}; use async_trait::async_trait; use base64::Engine; use bitcrypto::sha256; @@ -127,7 +128,9 @@ impl CoinCapabilities for TendermintCoin {} #[async_trait] impl CoinWithTxHistoryV2 for TendermintCoin { - fn history_wallet_id(&self) -> WalletId { WalletId::new(self.ticker().into()) } + fn history_wallet_id(&self) -> WalletId { + WalletId::new(self.ticker().into()) + } async fn get_tx_history_filters( &self, @@ -139,7 +142,9 @@ impl CoinWithTxHistoryV2 for TendermintCoin { #[async_trait] impl CoinWithTxHistoryV2 for TendermintToken { - fn history_wallet_id(&self) -> WalletId { WalletId::new(self.platform_ticker().to_owned()) } + fn history_wallet_id(&self) -> WalletId { + WalletId::new(self.platform_ticker().to_owned()) + } async fn get_tx_history_filters( &self, diff --git a/mm2src/coins/test_coin.rs b/mm2src/coins/test_coin.rs index 13c8beb7a5..1dc64d30db 100644 --- a/mm2src/coins/test_coin.rs +++ b/mm2src/coins/test_coin.rs @@ -1,23 +1,26 @@ #![allow(clippy::all)] -use super::{CoinBalance, CommonSwapOpsV2, FindPaymentSpendError, FundingTxSpend, HistorySyncState, MarketCoinOps, - MmCoin, RawTransactionFut, RawTransactionRequest, RefundTakerPaymentArgs, SearchForFundingSpendErr, - SwapOps, TradeFee, TransactionEnum, TransactionFut}; +use super::{ + CoinBalance, CommonSwapOpsV2, FindPaymentSpendError, FundingTxSpend, HistorySyncState, MarketCoinOps, MmCoin, + RawTransactionFut, RawTransactionRequest, RefundTakerPaymentArgs, SearchForFundingSpendErr, SwapOps, TradeFee, + TransactionEnum, TransactionFut, +}; use crate::coin_errors::{AddressFromPubkeyError, ValidatePaymentResult}; use crate::hd_wallet::{AddrToString, HDAddressSelector}; -use crate::{coin_errors::MyAddressError, BalanceFut, CanRefundHtlc, CheckIfMyPaymentSentArgs, ConfirmPaymentInput, - FeeApproxStage, FoundSwapTxSpend, GenPreimageResult, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, - MmCoinEnum, NegotiateSwapContractAddrErr, ParseCoinAssocTypes, PaymentInstructionArgs, - PaymentInstructions, PaymentInstructionsErr, RawTransactionResult, RefundFundingSecretArgs, - RefundPaymentArgs, RefundResult, SearchForSwapTxSpendInput, SendMakerPaymentSpendPreimageInput, - SendPaymentArgs, SendTakerFundingArgs, SignRawTransactionRequest, SignatureResult, SpendPaymentArgs, - TakerCoinSwapOpsV2, TradePreimageFut, TradePreimageResult, TradePreimageValue, Transaction, - TransactionErr, TransactionResult, TxMarshalingErr, TxPreimageWithSig, UnexpectedDerivationMethod, - ValidateAddressResult, ValidateFeeArgs, ValidateInstructionsErr, ValidateOtherPubKeyErr, - ValidatePaymentFut, ValidatePaymentInput, ValidateSwapV2TxResult, ValidateTakerFundingArgs, - ValidateTakerFundingSpendPreimageResult, ValidateTakerPaymentSpendPreimageResult, VerificationResult, - WaitForHTLCTxSpendArgs, WatcherOps, WatcherReward, WatcherRewardError, WatcherSearchForSwapTxSpendInput, - WatcherValidatePaymentInput, WatcherValidateTakerFeeInput, WeakSpawner, WithdrawFut, WithdrawRequest}; +use crate::{ + coin_errors::MyAddressError, BalanceFut, CanRefundHtlc, CheckIfMyPaymentSentArgs, ConfirmPaymentInput, + FeeApproxStage, FoundSwapTxSpend, GenPreimageResult, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, + MmCoinEnum, NegotiateSwapContractAddrErr, ParseCoinAssocTypes, PaymentInstructionArgs, PaymentInstructions, + PaymentInstructionsErr, RawTransactionResult, RefundFundingSecretArgs, RefundPaymentArgs, RefundResult, + SearchForSwapTxSpendInput, SendMakerPaymentSpendPreimageInput, SendPaymentArgs, SendTakerFundingArgs, + SignRawTransactionRequest, SignatureResult, SpendPaymentArgs, TakerCoinSwapOpsV2, TradePreimageFut, + TradePreimageResult, TradePreimageValue, Transaction, TransactionErr, TransactionResult, TxMarshalingErr, + TxPreimageWithSig, UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, ValidateInstructionsErr, + ValidateOtherPubKeyErr, ValidatePaymentFut, ValidatePaymentInput, ValidateSwapV2TxResult, ValidateTakerFundingArgs, + ValidateTakerFundingSpendPreimageResult, ValidateTakerPaymentSpendPreimageResult, VerificationResult, + WaitForHTLCTxSpendArgs, WatcherOps, WatcherReward, WatcherRewardError, WatcherSearchForSwapTxSpendInput, + WatcherValidatePaymentInput, WatcherValidateTakerFeeInput, WeakSpawner, WithdrawFut, WithdrawRequest, +}; use crate::{DexFee, ToBytes, ValidateWatcherSpendInput}; use async_trait::async_trait; use common::executor::AbortedError; @@ -42,7 +45,9 @@ pub struct TestCoin(Arc); impl Deref for TestCoin { type Target = TestCoinImpl; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { + &self.0 + } } #[derive(Debug)] @@ -51,25 +56,39 @@ pub struct TestCoinImpl { } impl Default for TestCoin { - fn default() -> Self { TestCoin(Arc::new(TestCoinImpl { ticker: "test".into() })) } + fn default() -> Self { + TestCoin(Arc::new(TestCoinImpl { ticker: "test".into() })) + } } impl TestCoin { - pub fn new(ticker: &str) -> TestCoin { TestCoin(Arc::new(TestCoinImpl { ticker: ticker.into() })) } + pub fn new(ticker: &str) -> TestCoin { + TestCoin(Arc::new(TestCoinImpl { ticker: ticker.into() })) + } } #[async_trait] #[cfg_attr(any(test, feature = "for-tests"), mockable)] impl MarketCoinOps for TestCoin { - fn ticker(&self) -> &str { &self.ticker } + fn ticker(&self) -> &str { + &self.ticker + } - fn my_address(&self) -> MmResult { unimplemented!() } + fn my_address(&self) -> MmResult { + unimplemented!() + } - fn address_from_pubkey(&self, _pubkey: &H264Json) -> MmResult { unimplemented!() } + fn address_from_pubkey(&self, _pubkey: &H264Json) -> MmResult { + unimplemented!() + } - async fn get_public_key(&self) -> Result> { unimplemented!() } + async fn get_public_key(&self) -> Result> { + unimplemented!() + } - fn sign_message_hash(&self, _message: &str) -> Option<[u8; 32]> { unimplemented!() } + fn sign_message_hash(&self, _message: &str) -> Option<[u8; 32]> { + unimplemented!() + } fn sign_message(&self, _message: &str, _address: Option) -> SignatureResult { unimplemented!() @@ -79,25 +98,39 @@ impl MarketCoinOps for TestCoin { unimplemented!() } - fn my_balance(&self) -> BalanceFut { unimplemented!() } + fn my_balance(&self) -> BalanceFut { + unimplemented!() + } - fn base_coin_balance(&self) -> BalanceFut { unimplemented!() } + fn base_coin_balance(&self) -> BalanceFut { + unimplemented!() + } - fn platform_ticker(&self) -> &str { &self.ticker } + fn platform_ticker(&self) -> &str { + &self.ticker + } /// Receives raw transaction bytes in hexadecimal format as input and returns tx hash in hexadecimal format - fn send_raw_tx(&self, tx: &str) -> Box + Send> { unimplemented!() } + fn send_raw_tx(&self, tx: &str) -> Box + Send> { + unimplemented!() + } - fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { unimplemented!() } + fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { + unimplemented!() + } #[inline(always)] - async fn sign_raw_tx(&self, _args: &SignRawTransactionRequest) -> RawTransactionResult { unimplemented!() } + async fn sign_raw_tx(&self, _args: &SignRawTransactionRequest) -> RawTransactionResult { + unimplemented!() + } fn wait_for_confirmations(&self, _input: ConfirmPaymentInput) -> Box + Send> { unimplemented!() } - async fn wait_for_htlc_tx_spend(&self, args: WaitForHTLCTxSpendArgs<'_>) -> TransactionResult { unimplemented!() } + async fn wait_for_htlc_tx_spend(&self, args: WaitForHTLCTxSpendArgs<'_>) -> TransactionResult { + unimplemented!() + } fn tx_enum_from_bytes(&self, _bytes: &[u8]) -> Result> { MmError::err(TxMarshalingErr::NotSupported( @@ -105,19 +138,33 @@ impl MarketCoinOps for TestCoin { )) } - fn current_block(&self) -> Box + Send> { unimplemented!() } + fn current_block(&self) -> Box + Send> { + unimplemented!() + } - fn display_priv_key(&self) -> Result { unimplemented!() } + fn display_priv_key(&self) -> Result { + unimplemented!() + } - fn min_tx_amount(&self) -> BigDecimal { Default::default() } + fn min_tx_amount(&self) -> BigDecimal { + Default::default() + } - fn min_trading_vol(&self) -> MmNumber { MmNumber::from("0.00777") } + fn min_trading_vol(&self) -> MmNumber { + MmNumber::from("0.00777") + } - fn should_burn_directly(&self) -> bool { &self.ticker == "KMD" } + fn should_burn_directly(&self) -> bool { + &self.ticker == "KMD" + } - fn should_burn_dex_fee(&self) -> bool { false } + fn should_burn_dex_fee(&self) -> bool { + false + } - fn is_trezor(&self) -> bool { unimplemented!() } + fn is_trezor(&self) -> bool { + unimplemented!() + } } #[async_trait] @@ -205,9 +252,13 @@ impl SwapOps for TestCoin { unimplemented!() } - fn is_auto_refundable(&self) -> bool { false } + fn is_auto_refundable(&self) -> bool { + false + } - async fn wait_for_htlc_refund(&self, _tx: &[u8], _locktime: u64) -> RefundResult<()> { unimplemented!() } + async fn wait_for_htlc_refund(&self, _tx: &[u8], _locktime: u64) -> RefundResult<()> { + unimplemented!() + } fn negotiate_swap_contract_addr( &self, @@ -216,13 +267,21 @@ impl SwapOps for TestCoin { unimplemented!() } - fn derive_htlc_key_pair(&self, _swap_unique_data: &[u8]) -> KeyPair { unimplemented!() } + fn derive_htlc_key_pair(&self, _swap_unique_data: &[u8]) -> KeyPair { + unimplemented!() + } - fn derive_htlc_pubkey(&self, _swap_unique_data: &[u8]) -> [u8; 33] { unimplemented!() } + fn derive_htlc_pubkey(&self, _swap_unique_data: &[u8]) -> [u8; 33] { + unimplemented!() + } - async fn can_refund_htlc(&self, locktime: u64) -> Result { unimplemented!() } + async fn can_refund_htlc(&self, locktime: u64) -> Result { + unimplemented!() + } - fn validate_other_pubkey(&self, raw_pubkey: &[u8]) -> MmResult<(), ValidateOtherPubKeyErr> { unimplemented!() } + fn validate_other_pubkey(&self, raw_pubkey: &[u8]) -> MmResult<(), ValidateOtherPubKeyErr> { + unimplemented!() + } async fn maker_payment_instructions( &self, @@ -254,13 +313,21 @@ impl SwapOps for TestCoin { unimplemented!() } - async fn on_taker_payment_refund_start(&self, _maker_payment: &[u8]) -> RefundResult<()> { unimplemented!() } + async fn on_taker_payment_refund_start(&self, _maker_payment: &[u8]) -> RefundResult<()> { + unimplemented!() + } - async fn on_taker_payment_refund_success(&self, _maker_payment: &[u8]) -> RefundResult<()> { unimplemented!() } + async fn on_taker_payment_refund_success(&self, _maker_payment: &[u8]) -> RefundResult<()> { + unimplemented!() + } - async fn on_maker_payment_refund_start(&self, _taker_payment: &[u8]) -> RefundResult<()> { unimplemented!() } + async fn on_maker_payment_refund_start(&self, _taker_payment: &[u8]) -> RefundResult<()> { + unimplemented!() + } - async fn on_maker_payment_refund_success(&self, _taker_payment: &[u8]) -> RefundResult<()> { unimplemented!() } + async fn on_maker_payment_refund_success(&self, _taker_payment: &[u8]) -> RefundResult<()> { + unimplemented!() + } } #[async_trait] @@ -340,28 +407,50 @@ impl WatcherOps for TestCoin { #[async_trait] #[cfg_attr(any(test, feature = "for-tests"), mockable)] impl MmCoin for TestCoin { - fn is_asset_chain(&self) -> bool { unimplemented!() } + fn is_asset_chain(&self) -> bool { + unimplemented!() + } - fn spawner(&self) -> WeakSpawner { unimplemented!() } + fn spawner(&self) -> WeakSpawner { + unimplemented!() + } - fn get_raw_transaction(&self, _req: RawTransactionRequest) -> RawTransactionFut { unimplemented!() } + fn get_raw_transaction(&self, _req: RawTransactionRequest) -> RawTransactionFut { + unimplemented!() + } - fn get_tx_hex_by_hash(&self, tx_hash: Vec) -> RawTransactionFut { unimplemented!() } + fn get_tx_hex_by_hash(&self, tx_hash: Vec) -> RawTransactionFut { + unimplemented!() + } - fn withdraw(&self, req: WithdrawRequest) -> WithdrawFut { unimplemented!() } + fn withdraw(&self, req: WithdrawRequest) -> WithdrawFut { + unimplemented!() + } - fn decimals(&self) -> u8 { unimplemented!() } + fn decimals(&self) -> u8 { + unimplemented!() + } - fn convert_to_address(&self, from: &str, to_address_format: Json) -> Result { unimplemented!() } + fn convert_to_address(&self, from: &str, to_address_format: Json) -> Result { + unimplemented!() + } - fn validate_address(&self, address: &str) -> ValidateAddressResult { unimplemented!() } + fn validate_address(&self, address: &str) -> ValidateAddressResult { + unimplemented!() + } - fn process_history_loop(&self, ctx: MmArc) -> Box + Send> { unimplemented!() } + fn process_history_loop(&self, ctx: MmArc) -> Box + Send> { + unimplemented!() + } - fn history_sync_status(&self) -> HistorySyncState { unimplemented!() } + fn history_sync_status(&self) -> HistorySyncState { + unimplemented!() + } /// Get fee to be paid per 1 swap transaction - fn get_trade_fee(&self) -> Box + Send> { unimplemented!() } + fn get_trade_fee(&self) -> Box + Send> { + unimplemented!() + } async fn get_sender_trade_fee( &self, @@ -372,7 +461,9 @@ impl MmCoin for TestCoin { unimplemented!() } - fn get_receiver_trade_fee(&self, _stage: FeeApproxStage) -> TradePreimageFut { unimplemented!() } + fn get_receiver_trade_fee(&self, _stage: FeeApproxStage) -> TradePreimageFut { + unimplemented!() + } async fn get_fee_to_send_taker_fee( &self, @@ -382,21 +473,37 @@ impl MmCoin for TestCoin { unimplemented!() } - fn required_confirmations(&self) -> u64 { 1 } + fn required_confirmations(&self) -> u64 { + 1 + } - fn requires_notarization(&self) -> bool { false } + fn requires_notarization(&self) -> bool { + false + } - fn set_required_confirmations(&self, _confirmations: u64) { unimplemented!() } + fn set_required_confirmations(&self, _confirmations: u64) { + unimplemented!() + } - fn set_requires_notarization(&self, _requires_nota: bool) { unimplemented!() } + fn set_requires_notarization(&self, _requires_nota: bool) { + unimplemented!() + } - fn swap_contract_address(&self) -> Option { unimplemented!() } + fn swap_contract_address(&self) -> Option { + unimplemented!() + } - fn fallback_swap_contract(&self) -> Option { unimplemented!() } + fn fallback_swap_contract(&self) -> Option { + unimplemented!() + } - fn mature_confirmations(&self) -> Option { unimplemented!() } + fn mature_confirmations(&self) -> Option { + unimplemented!() + } - fn coin_protocol_info(&self, _amount_to_receive: Option) -> Vec { Vec::new() } + fn coin_protocol_info(&self, _amount_to_receive: Option) -> Vec { + Vec::new() + } fn is_coin_protocol_supported( &self, @@ -408,46 +515,64 @@ impl MmCoin for TestCoin { true } - fn on_disabled(&self) -> Result<(), AbortedError> { Ok(()) } + fn on_disabled(&self) -> Result<(), AbortedError> { + Ok(()) + } - fn on_token_deactivated(&self, _ticker: &str) { () } + fn on_token_deactivated(&self, _ticker: &str) { + () + } } pub struct TestPubkey {} impl ToBytes for TestPubkey { - fn to_bytes(&self) -> Vec { vec![] } + fn to_bytes(&self) -> Vec { + vec![] + } } #[derive(Debug)] pub struct TestTx {} impl Transaction for TestTx { - fn tx_hex(&self) -> Vec { todo!() } + fn tx_hex(&self) -> Vec { + todo!() + } - fn tx_hash_as_bytes(&self) -> BytesJson { todo!() } + fn tx_hash_as_bytes(&self) -> BytesJson { + todo!() + } } pub struct TestPreimage {} impl ToBytes for TestPreimage { - fn to_bytes(&self) -> Vec { vec![] } + fn to_bytes(&self) -> Vec { + vec![] + } } pub struct TestSig {} impl ToBytes for TestSig { - fn to_bytes(&self) -> Vec { vec![] } + fn to_bytes(&self) -> Vec { + vec![] + } } pub struct TestAddress {} impl AddrToString for TestAddress { - fn addr_to_string(&self) -> String { unimplemented!() } + fn addr_to_string(&self) -> String { + unimplemented!() + } } impl Display for TestAddress { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { unimplemented!() } + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + unimplemented!() + } } #[async_trait] @@ -463,23 +588,37 @@ impl ParseCoinAssocTypes for TestCoin { type Sig = TestSig; type SigParseError = String; - async fn my_addr(&self) -> Self::Address { todo!() } + async fn my_addr(&self) -> Self::Address { + todo!() + } - fn parse_address(&self, address: &str) -> Result { todo!() } + fn parse_address(&self, address: &str) -> Result { + todo!() + } - fn parse_pubkey(&self, pubkey: &[u8]) -> Result { unimplemented!() } + fn parse_pubkey(&self, pubkey: &[u8]) -> Result { + unimplemented!() + } - fn parse_tx(&self, tx: &[u8]) -> Result { unimplemented!() } + fn parse_tx(&self, tx: &[u8]) -> Result { + unimplemented!() + } - fn parse_preimage(&self, preimage: &[u8]) -> Result { todo!() } + fn parse_preimage(&self, preimage: &[u8]) -> Result { + todo!() + } - fn parse_signature(&self, sig: &[u8]) -> Result { todo!() } + fn parse_signature(&self, sig: &[u8]) -> Result { + todo!() + } } #[async_trait] #[cfg_attr(any(test, feature = "for-tests"), mockable)] impl TakerCoinSwapOpsV2 for TestCoin { - async fn send_taker_funding(&self, args: SendTakerFundingArgs<'_>) -> Result { todo!() } + async fn send_taker_funding(&self, args: SendTakerFundingArgs<'_>) -> Result { + todo!() + } async fn validate_taker_funding(&self, args: ValidateTakerFundingArgs<'_, Self>) -> ValidateSwapV2TxResult { unimplemented!() @@ -581,10 +720,16 @@ impl TakerCoinSwapOpsV2 for TestCoin { } impl CommonSwapOpsV2 for TestCoin { - fn derive_htlc_pubkey_v2(&self, _swap_unique_data: &[u8]) -> Self::Pubkey { todo!() } + fn derive_htlc_pubkey_v2(&self, _swap_unique_data: &[u8]) -> Self::Pubkey { + todo!() + } - fn derive_htlc_pubkey_v2_bytes(&self, _swap_unique_data: &[u8]) -> Vec { todo!() } + fn derive_htlc_pubkey_v2_bytes(&self, _swap_unique_data: &[u8]) -> Vec { + todo!() + } #[inline(always)] - fn taker_pubkey_bytes(&self) -> Option> { todo!() } + fn taker_pubkey_bytes(&self) -> Option> { + todo!() + } } diff --git a/mm2src/coins/tx_history_storage/mod.rs b/mm2src/coins/tx_history_storage/mod.rs index 6036554611..f70a566804 100644 --- a/mm2src/coins/tx_history_storage/mod.rs +++ b/mm2src/coins/tx_history_storage/mod.rs @@ -10,7 +10,8 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::collections::HashSet; use std::iter::FromIterator; -#[cfg(target_arch = "wasm32")] pub mod wasm; +#[cfg(target_arch = "wasm32")] +pub mod wasm; #[cfg(not(target_arch = "wasm32"))] pub mod sql_tx_history_storage_v2; @@ -49,7 +50,9 @@ pub struct TxHistoryStorageBuilder<'a> { impl TxHistoryStorageBuilder<'_> { #[inline] - pub fn new(ctx: &MmArc) -> TxHistoryStorageBuilder<'_> { TxHistoryStorageBuilder { ctx } } + pub fn new(ctx: &MmArc) -> TxHistoryStorageBuilder<'_> { + TxHistoryStorageBuilder { ctx } + } #[inline] pub fn build(self) -> MmResult { @@ -121,7 +124,9 @@ impl WalletId { } #[inline] - pub fn set_hd_wallet_rmd160(&mut self, hd_wallet_rmd160: H160) { self.hd_wallet_rmd160 = Some(hd_wallet_rmd160); } + pub fn set_hd_wallet_rmd160(&mut self, hd_wallet_rmd160: H160) { + self.hd_wallet_rmd160 = Some(hd_wallet_rmd160); + } #[inline] pub fn with_hd_wallet_rmd160(mut self, hd_wallet_rmd160: H160) -> WalletId { @@ -160,11 +165,15 @@ impl GetTxHistoryFilters { } #[inline] - pub fn set_token_id(&mut self, token_id: String) { self.token_id = Some(token_id); } + pub fn set_token_id(&mut self, token_id: String) { + self.token_id = Some(token_id); + } /// If [`GetTxHistoryFilters::token_id`] is not specified, /// we should exclude token's transactions by applying an empty `token_id` filter. - fn token_id_or_exclude(&self) -> String { self.token_id.clone().unwrap_or_default() } + fn token_id_or_exclude(&self) -> String { + self.token_id.clone().unwrap_or_default() + } } #[derive(Clone, Debug, Deserialize, Serialize)] @@ -172,10 +181,14 @@ pub struct FilteringAddresses(HashSet); impl FilteringAddresses { #[inline] - pub fn is_empty(&self) -> bool { self.0.is_empty() } + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } #[inline] - pub fn len(&self) -> usize { self.0.len() } + pub fn len(&self) -> usize { + self.0.len() + } /// Whether the containers have the same addresses. #[inline] @@ -188,9 +201,13 @@ impl IntoIterator for FilteringAddresses { type Item = String; type IntoIter = std::collections::hash_set::IntoIter; - fn into_iter(self) -> Self::IntoIter { self.0.into_iter() } + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } } impl FromIterator for FilteringAddresses { - fn from_iter>(iter: T) -> Self { FilteringAddresses(iter.into_iter().collect()) } + fn from_iter>(iter: T) -> Self { + FilteringAddresses(iter.into_iter().collect()) + } } diff --git a/mm2src/coins/tx_history_storage/sql_tx_history_storage_v2.rs b/mm2src/coins/tx_history_storage/sql_tx_history_storage_v2.rs index f5b1312a65..7d1fbf0fbd 100644 --- a/mm2src/coins/tx_history_storage/sql_tx_history_storage_v2.rs +++ b/mm2src/coins/tx_history_storage/sql_tx_history_storage_v2.rs @@ -1,6 +1,8 @@ use crate::my_tx_history_v2::{GetHistoryResult, RemoveTxResult, TxHistoryStorage, TxHistoryStorageError}; -use crate::tx_history_storage::{token_id_from_tx_type, ConfirmationStatus, CreateTxHistoryStorageError, - FilteringAddresses, GetTxHistoryFilters, WalletId}; +use crate::tx_history_storage::{ + token_id_from_tx_type, ConfirmationStatus, CreateTxHistoryStorageError, FilteringAddresses, GetTxHistoryFilters, + WalletId, +}; use crate::TransactionDetails; use async_trait::async_trait; use common::{async_blocking, PagingOptionsEnum}; @@ -15,12 +17,18 @@ use serde_json::{self as json}; use std::convert::TryInto; use std::sync::{Arc, Mutex}; -fn tx_history_table(wallet_id: &WalletId) -> String { wallet_id.to_sql_table_name() + "_tx_history" } +fn tx_history_table(wallet_id: &WalletId) -> String { + wallet_id.to_sql_table_name() + "_tx_history" +} -fn tx_address_table(wallet_id: &WalletId) -> String { wallet_id.to_sql_table_name() + "_tx_address" } +fn tx_address_table(wallet_id: &WalletId) -> String { + wallet_id.to_sql_table_name() + "_tx_address" +} /// Please note TX cache table name doesn't depend on [`WalletId::hd_wallet_rmd160`]. -fn tx_cache_table(wallet_id: &WalletId) -> String { format!("{}_tx_cache", wallet_id.ticker) } +fn tx_cache_table(wallet_id: &WalletId) -> String { + format!("{}_tx_cache", wallet_id.ticker) +} fn create_tx_history_table_sql(wallet_id: &WalletId) -> Result> { let table_name = tx_history_table(wallet_id); @@ -352,14 +360,20 @@ fn tx_details_from_row(row: &Row<'_>) -> Result { json::from_str(&json_string).map_err(|e| SqlError::FromSqlConversionFailure(0, Type::Text, Box::new(e))) } -fn block_height_from_row(row: &Row<'_>) -> Result { row.get(0) } +fn block_height_from_row(row: &Row<'_>) -> Result { + row.get(0) +} impl TxHistoryStorageError for SqlError {} impl ConfirmationStatus { - fn to_sql_param_str(self) -> String { (self as u8).to_string() } + fn to_sql_param_str(self) -> String { + (self as u8).to_string() + } - fn to_sql_param(self) -> i64 { self as i64 } + fn to_sql_param(self) -> i64 { + self as i64 + } } impl WalletId { diff --git a/mm2src/coins/tx_history_storage/tx_history_v2_tests.rs b/mm2src/coins/tx_history_storage/tx_history_v2_tests.rs index 2ffcc9760d..5cd8eed6ec 100644 --- a/mm2src/coins/tx_history_storage/tx_history_v2_tests.rs +++ b/mm2src/coins/tx_history_storage/tx_history_v2_tests.rs @@ -18,7 +18,9 @@ lazy_static! { static ref BCH_TX_HISTORY_MAP: HashMap = parse_tx_history_map(); } -fn parse_tx_history() -> Vec { json::from_str(BCH_TX_HISTORY_STR).unwrap() } +fn parse_tx_history() -> Vec { + json::from_str(BCH_TX_HISTORY_STR).unwrap() +} fn parse_tx_history_map() -> HashMap { parse_tx_history() @@ -27,9 +29,13 @@ fn parse_tx_history_map() -> HashMap { .collect() } -fn get_bch_tx_details(internal_id: &str) -> TransactionDetails { BCH_TX_HISTORY_MAP.get(internal_id).unwrap().clone() } +fn get_bch_tx_details(internal_id: &str) -> TransactionDetails { + BCH_TX_HISTORY_MAP.get(internal_id).unwrap().clone() +} -fn wallet_id_for_test(test_name: &str) -> WalletId { WalletId::new(test_name.to_owned()) } +fn wallet_id_for_test(test_name: &str) -> WalletId { + WalletId::new(test_name.to_owned()) +} #[track_caller] fn assert_get_history_result(actual: GetHistoryResult, expected_ids: Vec, skipped: usize, total: usize) { @@ -605,16 +611,24 @@ mod native_tests { } #[test] - fn test_add_transactions() { block_on(super::test_add_transactions_impl()); } + fn test_add_transactions() { + block_on(super::test_add_transactions_impl()); + } #[test] - fn test_remove_transaction() { block_on(super::test_remove_transaction_impl()); } + fn test_remove_transaction() { + block_on(super::test_remove_transaction_impl()); + } #[test] - fn test_get_transaction() { block_on(super::test_get_transaction_impl()); } + fn test_get_transaction() { + block_on(super::test_get_transaction_impl()); + } #[test] - fn test_update_transaction() { block_on(super::test_update_transaction_impl()); } + fn test_update_transaction() { + block_on(super::test_update_transaction_impl()); + } #[test] fn test_contains_and_get_unconfirmed_transaction() { @@ -622,13 +636,19 @@ mod native_tests { } #[test] - fn test_has_transactions_with_hash() { block_on(super::test_has_transactions_with_hash_impl()); } + fn test_has_transactions_with_hash() { + block_on(super::test_has_transactions_with_hash_impl()); + } #[test] - fn test_unique_tx_hashes_num() { block_on(super::test_unique_tx_hashes_num_impl()); } + fn test_unique_tx_hashes_num() { + block_on(super::test_unique_tx_hashes_num_impl()); + } #[test] - fn test_add_and_get_tx_from_cache() { block_on(super::test_add_and_get_tx_from_cache_impl()); } + fn test_add_and_get_tx_from_cache() { + block_on(super::test_add_and_get_tx_from_cache_impl()); + } #[test] fn test_get_raw_tx_bytes_on_add_transactions() { @@ -636,13 +656,19 @@ mod native_tests { } #[test] - fn test_get_history_page_number() { block_on(super::test_get_history_page_number_impl()); } + fn test_get_history_page_number() { + block_on(super::test_get_history_page_number_impl()); + } #[test] - fn test_get_history_from_id() { block_on(super::test_get_history_from_id_impl()); } + fn test_get_history_from_id() { + block_on(super::test_get_history_from_id_impl()); + } #[test] - fn test_get_history_for_addresses() { block_on(super::test_get_history_for_addresses_impl()); } + fn test_get_history_for_addresses() { + block_on(super::test_get_history_for_addresses_impl()); + } } #[cfg(target_arch = "wasm32")] @@ -675,16 +701,24 @@ mod wasm_tests { } #[wasm_bindgen_test] - async fn test_add_transactions() { super::test_add_transactions_impl().await; } + async fn test_add_transactions() { + super::test_add_transactions_impl().await; + } #[wasm_bindgen_test] - async fn test_remove_transaction() { super::test_remove_transaction_impl().await; } + async fn test_remove_transaction() { + super::test_remove_transaction_impl().await; + } #[wasm_bindgen_test] - async fn test_get_transaction() { super::test_get_transaction_impl().await; } + async fn test_get_transaction() { + super::test_get_transaction_impl().await; + } #[wasm_bindgen_test] - async fn test_update_transaction() { super::test_update_transaction_impl().await; } + async fn test_update_transaction() { + super::test_update_transaction_impl().await; + } #[wasm_bindgen_test] async fn test_contains_and_get_unconfirmed_transaction() { @@ -692,13 +726,19 @@ mod wasm_tests { } #[wasm_bindgen_test] - async fn test_has_transactions_with_hash() { super::test_has_transactions_with_hash_impl().await; } + async fn test_has_transactions_with_hash() { + super::test_has_transactions_with_hash_impl().await; + } #[wasm_bindgen_test] - async fn test_unique_tx_hashes_num() { super::test_unique_tx_hashes_num_impl().await; } + async fn test_unique_tx_hashes_num() { + super::test_unique_tx_hashes_num_impl().await; + } #[wasm_bindgen_test] - async fn test_add_and_get_tx_from_cache() { super::test_add_and_get_tx_from_cache_impl().await; } + async fn test_add_and_get_tx_from_cache() { + super::test_add_and_get_tx_from_cache_impl().await; + } #[wasm_bindgen_test] async fn test_get_raw_tx_bytes_on_add_transactions() { @@ -706,11 +746,17 @@ mod wasm_tests { } #[wasm_bindgen_test] - async fn test_get_history_page_number() { super::test_get_history_page_number_impl().await; } + async fn test_get_history_page_number() { + super::test_get_history_page_number_impl().await; + } #[wasm_bindgen_test] - async fn test_get_history_from_id() { super::test_get_history_from_id_impl().await; } + async fn test_get_history_from_id() { + super::test_get_history_from_id_impl().await; + } #[wasm_bindgen_test] - async fn test_get_history_for_addresses() { super::test_get_history_for_addresses_impl().await; } + async fn test_get_history_for_addresses() { + super::test_get_history_for_addresses_impl().await; + } } diff --git a/mm2src/coins/tx_history_storage/wasm/tx_history_db.rs b/mm2src/coins/tx_history_storage/wasm/tx_history_db.rs index b646e7cefc..a301af364a 100644 --- a/mm2src/coins/tx_history_storage/wasm/tx_history_db.rs +++ b/mm2src/coins/tx_history_storage/wasm/tx_history_db.rs @@ -28,5 +28,7 @@ impl DbInstance for TxHistoryDb { } impl TxHistoryDb { - pub fn get_inner(&self) -> &IndexedDb { &self.inner } + pub fn get_inner(&self) -> &IndexedDb { + &self.inner + } } diff --git a/mm2src/coins/tx_history_storage/wasm/tx_history_storage_v1.rs b/mm2src/coins/tx_history_storage/wasm/tx_history_storage_v1.rs index 77baedcb29..623cb82bca 100644 --- a/mm2src/coins/tx_history_storage/wasm/tx_history_storage_v1.rs +++ b/mm2src/coins/tx_history_storage/wasm/tx_history_storage_v1.rs @@ -61,13 +61,19 @@ pub async fn clear_tx_history(db: &TxHistoryDb, ticker: &str, wallet_address: &s struct HistoryId(String); impl HistoryId { - fn new(ticker: &str, wallet_address: &str) -> HistoryId { HistoryId(format!("{}_{}", ticker, wallet_address)) } + fn new(ticker: &str, wallet_address: &str) -> HistoryId { + HistoryId(format!("{}_{}", ticker, wallet_address)) + } - fn as_str(&self) -> &str { &self.0 } + fn as_str(&self) -> &str { + &self.0 + } } impl std::fmt::Display for HistoryId { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", &self.0) } + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", &self.0) + } } #[derive(Debug, Deserialize, Serialize)] diff --git a/mm2src/coins/tx_history_storage/wasm/tx_history_storage_v2.rs b/mm2src/coins/tx_history_storage/wasm/tx_history_storage_v2.rs index 6b3f33ee2b..5384b7fee9 100644 --- a/mm2src/coins/tx_history_storage/wasm/tx_history_storage_v2.rs +++ b/mm2src/coins/tx_history_storage/wasm/tx_history_storage_v2.rs @@ -1,8 +1,10 @@ use crate::my_tx_history_v2::{GetHistoryResult, RemoveTxResult, TxHistoryStorage}; use crate::tx_history_storage::wasm::tx_history_db::{TxHistoryDb, TxHistoryDbLocked}; use crate::tx_history_storage::wasm::{WasmTxHistoryError, WasmTxHistoryResult}; -use crate::tx_history_storage::{token_id_from_tx_type, ConfirmationStatus, CreateTxHistoryStorageError, - FilteringAddresses, GetTxHistoryFilters, WalletId}; +use crate::tx_history_storage::{ + token_id_from_tx_type, ConfirmationStatus, CreateTxHistoryStorageError, FilteringAddresses, GetTxHistoryFilters, + WalletId, +}; use crate::{compare_transaction_details, CoinsContext, TransactionDetails}; use async_trait::async_trait; use common::PagingOptionsEnum; @@ -42,9 +44,13 @@ impl IndexedDbTxHistoryStorage { impl TxHistoryStorage for IndexedDbTxHistoryStorage { type Error = WasmTxHistoryError; - async fn init(&self, _wallet_id: &WalletId) -> MmResult<(), Self::Error> { Ok(()) } + async fn init(&self, _wallet_id: &WalletId) -> MmResult<(), Self::Error> { + Ok(()) + } - async fn is_initialized_for(&self, _wallet_id: &WalletId) -> MmResult { Ok(true) } + async fn is_initialized_for(&self, _wallet_id: &WalletId) -> MmResult { + Ok(true) + } /// Adds multiple transactions to the selected coin's history /// Also consider adding tx_hex to the cache during this operation diff --git a/mm2src/coins/utxo.rs b/mm2src/coins/utxo.rs index b03e27f6c1..97cdee814c 100644 --- a/mm2src/coins/utxo.rs +++ b/mm2src/coins/utxo.rs @@ -56,7 +56,8 @@ use common::log::LogOnError; use common::{now_sec, now_sec_u32}; use crypto::{DerivationPath, HDPathToCoin, Secp256k1ExtendedPublicKey}; use derive_more::Display; -#[cfg(not(target_arch = "wasm32"))] use dirs::home_dir; +#[cfg(not(target_arch = "wasm32"))] +use dirs::home_dir; use futures::channel::mpsc::{Receiver as AsyncReceiver, Sender as AsyncSender}; use futures::compat::Future01CompatExt; use futures::lock::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard}; @@ -64,8 +65,10 @@ use futures01::Future; use keys::bytes::Bytes; use keys::NetworkAddressPrefixes; use keys::Signature; -pub use keys::{Address, AddressBuilder, AddressFormat as UtxoAddressFormat, AddressHashEnum, AddressPrefix, - AddressScriptType, KeyPair, LegacyAddress, Private, Public, Secret}; +pub use keys::{ + Address, AddressBuilder, AddressFormat as UtxoAddressFormat, AddressHashEnum, AddressPrefix, AddressScriptType, + KeyPair, LegacyAddress, Private, Public, Secret, +}; #[cfg(not(target_arch = "wasm32"))] use lightning_invoice::Currency as LightningCurrency; use mm2_core::mm_ctx::{MmArc, MmWeak}; @@ -73,7 +76,8 @@ use mm2_err_handle::prelude::*; use mm2_metrics::MetricsArc; use mm2_number::BigDecimal; use mm2_rpc::data::legacy::UtxoMergeParams; -#[cfg(test)] use mocktopus::macros::*; +#[cfg(test)] +use mocktopus::macros::*; use num_traits::ToPrimitive; use primitives::hash::{H160, H256, H264}; use rpc::v1::types::{Bytes as BytesJson, Transaction as RpcTransaction, H256 as H256Json}; @@ -100,18 +104,22 @@ use utxo_hd_wallet::UtxoHDWallet; use utxo_signer::with_key_pair::sign_tx; use utxo_signer::{TxProvider, TxProviderError, UtxoSignTxError, UtxoSignTxResult}; -use self::rpc_clients::{electrum_script_hash, ElectrumClient, ElectrumConnectionSettings, EstimateFeeMethod, - EstimateFeeMode, NativeClient, UnspentInfo, UnspentMap, UtxoRpcClientEnum, UtxoRpcError, - UtxoRpcFut, UtxoRpcResult}; -use super::{big_decimal_from_sat_unsigned, BalanceError, BalanceFut, BalanceResult, CoinBalance, CoinsContext, - DerivationMethod, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, KmdRewardsDetails, MarketCoinOps, - MmCoin, NumConversError, NumConversResult, PrivKeyActivationPolicy, PrivKeyPolicy, - PrivKeyPolicyNotAllowed, RawTransactionFut, TradeFee, TradePreimageError, TradePreimageFut, - TradePreimageResult, Transaction, TransactionDetails, TransactionEnum, TransactionErr, - UnexpectedDerivationMethod, VerificationError, WeakSpawner, WithdrawError, WithdrawRequest}; +use self::rpc_clients::{ + electrum_script_hash, ElectrumClient, ElectrumConnectionSettings, EstimateFeeMethod, EstimateFeeMode, NativeClient, + UnspentInfo, UnspentMap, UtxoRpcClientEnum, UtxoRpcError, UtxoRpcFut, UtxoRpcResult, +}; +use super::{ + big_decimal_from_sat_unsigned, BalanceError, BalanceFut, BalanceResult, CoinBalance, CoinsContext, + DerivationMethod, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, KmdRewardsDetails, MarketCoinOps, MmCoin, + NumConversError, NumConversResult, PrivKeyActivationPolicy, PrivKeyPolicy, PrivKeyPolicyNotAllowed, + RawTransactionFut, TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, Transaction, + TransactionDetails, TransactionEnum, TransactionErr, UnexpectedDerivationMethod, VerificationError, WeakSpawner, + WithdrawError, WithdrawRequest, +}; use crate::coin_balance::{EnableCoinScanPolicy, EnabledCoinBalanceParams, HDAddressBalanceScanner}; -use crate::hd_wallet::{AddrToString, HDAccountOps, HDAddressOps, HDPathAccountToAddressId, HDWalletCoinOps, - HDWalletOps}; +use crate::hd_wallet::{ + AddrToString, HDAccountOps, HDAddressOps, HDPathAccountToAddressId, HDWalletCoinOps, HDWalletOps, +}; use crate::utxo::tx_cache::UtxoVerboseCacheShared; use crate::{ParseCoinAssocTypes, ToBytes}; @@ -119,8 +127,10 @@ pub mod tx_cache; #[cfg(any(test, target_arch = "wasm32"))] pub mod utxo_common_tests; -#[cfg(test)] pub mod utxo_tests; -#[cfg(target_arch = "wasm32")] pub mod utxo_wasm_tests; +#[cfg(test)] +pub mod utxo_tests; +#[cfg(target_arch = "wasm32")] +pub mod utxo_wasm_tests; const KILO_BYTE: u64 = 1000; /// https://bitcoin.stackexchange.com/a/77192 @@ -168,7 +178,9 @@ fn get_special_folder_path() -> PathBuf { #[cfg(not(windows))] #[cfg(not(target_arch = "wasm32"))] -fn get_special_folder_path() -> PathBuf { panic!("!windows") } +fn get_special_folder_path() -> PathBuf { + panic!("!windows") +} impl Transaction for UtxoTx { fn tx_hex(&self) -> Vec { @@ -179,11 +191,15 @@ impl Transaction for UtxoTx { } } - fn tx_hash_as_bytes(&self) -> BytesJson { self.hash().reversed().to_vec().into() } + fn tx_hash_as_bytes(&self) -> BytesJson { + self.hash().reversed().to_vec().into() + } } impl From for BalanceError { - fn from(e: JsonRpcError) -> Self { BalanceError::Transport(e.to_string()) } + fn from(e: JsonRpcError) -> Self { + BalanceError::Transport(e.to_string()) + } } impl From for BalanceError { @@ -196,7 +212,9 @@ impl From for BalanceError { } impl From for BalanceError { - fn from(e: keys::Error) -> Self { BalanceError::Internal(e.to_string()) } + fn from(e: keys::Error) -> Self { + BalanceError::Internal(e.to_string()) + } } impl From for WithdrawError { @@ -212,7 +230,9 @@ impl From for WithdrawError { } impl From for TradePreimageError { - fn from(e: JsonRpcError) -> Self { TradePreimageError::Transport(e.to_string()) } + fn from(e: JsonRpcError) -> Self { + TradePreimageError::Transport(e.to_string()) + } } impl From for TradePreimageError { @@ -669,11 +689,15 @@ pub enum UnsupportedAddr { } impl From for WithdrawError { - fn from(e: UnsupportedAddr) -> Self { WithdrawError::InvalidAddress(e.to_string()) } + fn from(e: UnsupportedAddr) -> Self { + WithdrawError::InvalidAddress(e.to_string()) + } } impl From for UnsupportedAddr { - fn from(e: keys::Error) -> Self { UnsupportedAddr::InternalError(e.to_string()) } + fn from(e: keys::Error) -> Self { + UnsupportedAddr::InternalError(e.to_string()) + } } #[derive(Debug)] @@ -684,11 +708,15 @@ pub enum GetTxError { } impl From for GetTxError { - fn from(err: UtxoRpcError) -> GetTxError { GetTxError::Rpc(err) } + fn from(err: UtxoRpcError) -> GetTxError { + GetTxError::Rpc(err) + } } impl From for GetTxError { - fn from(err: SerError) -> GetTxError { GetTxError::TxDeserialization(err) } + fn from(err: SerError) -> GetTxError { + GetTxError::TxDeserialization(err) + } } #[derive(Debug, Display)] @@ -709,15 +737,21 @@ impl From for SPVError { } impl From for GetTxHeightError { - fn from(e: UtxoRpcError) -> Self { GetTxHeightError::HeightNotFound(e.to_string()) } + fn from(e: UtxoRpcError) -> Self { + GetTxHeightError::HeightNotFound(e.to_string()) + } } impl From for GetTxHeightError { - fn from(e: BlockHeaderStorageError) -> Self { GetTxHeightError::StorageError(e) } + fn from(e: BlockHeaderStorageError) -> Self { + GetTxHeightError::StorageError(e) + } } impl From for GetTxHeightError { - fn from(err: TryFromIntError) -> GetTxHeightError { GetTxHeightError::ConversionError(err) } + fn from(err: TryFromIntError) -> GetTxHeightError { + GetTxHeightError::ConversionError(err) + } } #[derive(Debug, Display)] @@ -737,7 +771,9 @@ pub enum GetBlockHeaderError { } impl From for GetBlockHeaderError { - fn from(err: JsonRpcError) -> Self { GetBlockHeaderError::RpcError(err) } + fn from(err: JsonRpcError) -> Self { + GetBlockHeaderError::RpcError(err) + } } impl From for GetBlockHeaderError { @@ -751,15 +787,21 @@ impl From for GetBlockHeaderError { } impl From for GetBlockHeaderError { - fn from(err: serialization::Error) -> Self { GetBlockHeaderError::SerializationError(err) } + fn from(err: serialization::Error) -> Self { + GetBlockHeaderError::SerializationError(err) + } } impl From for GetBlockHeaderError { - fn from(err: BlockHeaderStorageError) -> Self { GetBlockHeaderError::StorageError(err) } + fn from(err: BlockHeaderStorageError) -> Self { + GetBlockHeaderError::StorageError(err) + } } impl From for SPVError { - fn from(e: GetBlockHeaderError) -> Self { SPVError::UnableToGetHeader(e.to_string()) } + fn from(e: GetBlockHeaderError) -> Self { + SPVError::UnableToGetHeader(e.to_string()) + } } #[derive(Debug, Display)] @@ -772,19 +814,27 @@ pub enum GetConfirmedTxError { } impl From for GetConfirmedTxError { - fn from(err: GetTxHeightError) -> Self { GetConfirmedTxError::HeightNotFound(err) } + fn from(err: GetTxHeightError) -> Self { + GetConfirmedTxError::HeightNotFound(err) + } } impl From for GetConfirmedTxError { - fn from(err: GetBlockHeaderError) -> Self { GetConfirmedTxError::UnableToGetHeader(err) } + fn from(err: GetBlockHeaderError) -> Self { + GetConfirmedTxError::UnableToGetHeader(err) + } } impl From for GetConfirmedTxError { - fn from(err: JsonRpcError) -> Self { GetConfirmedTxError::RpcError(err) } + fn from(err: JsonRpcError) -> Self { + GetConfirmedTxError::RpcError(err) + } } impl From for GetConfirmedTxError { - fn from(err: serialization::Error) -> Self { GetConfirmedTxError::SerializationError(err) } + fn from(err: serialization::Error) -> Self { + GetConfirmedTxError::SerializationError(err) + } } #[derive(Debug, Display)] @@ -796,15 +846,21 @@ pub enum AddrFromStrError { } impl From for AddrFromStrError { - fn from(e: UnsupportedAddr) -> Self { AddrFromStrError::Unsupported(e) } + fn from(e: UnsupportedAddr) -> Self { + AddrFromStrError::Unsupported(e) + } } impl From for VerificationError { - fn from(e: AddrFromStrError) -> Self { VerificationError::AddressDecodingError(e.to_string()) } + fn from(e: AddrFromStrError) -> Self { + VerificationError::AddressDecodingError(e.to_string()) + } } impl From for WithdrawError { - fn from(e: AddrFromStrError) -> Self { WithdrawError::InvalidAddress(e.to_string()) } + fn from(e: AddrFromStrError) -> Self { + WithdrawError::InvalidAddress(e.to_string()) + } } impl UtxoCoinFields { @@ -860,7 +916,9 @@ pub enum BroadcastTxErr { } impl From for BroadcastTxErr { - fn from(err: UtxoRpcError) -> Self { BroadcastTxErr::Rpc(err) } + fn from(err: UtxoRpcError) -> Self { + BroadcastTxErr::Rpc(err) + } } #[async_trait] @@ -963,7 +1021,9 @@ impl MatureUnspentList { } #[inline] - pub fn only_mature(self) -> Vec { self.mature } + pub fn only_mature(self) -> Vec { + self.mature + } #[inline] pub fn to_coin_balance(&self, decimals: u8) -> CoinBalance { @@ -1050,15 +1110,21 @@ pub trait UtxoCommonOps: } impl ToBytes for UtxoTx { - fn to_bytes(&self) -> Vec { self.tx_hex() } + fn to_bytes(&self) -> Vec { + self.tx_hex() + } } impl ToBytes for Signature { - fn to_bytes(&self) -> Vec { self.to_vec() } + fn to_bytes(&self) -> Vec { + self.to_vec() + } } impl AddrToString for Address { - fn addr_to_string(&self) -> String { self.to_string() } + fn addr_to_string(&self) -> String { + self.to_string() + } } #[async_trait] @@ -1103,7 +1169,9 @@ impl ParseCoinAssocTypes for T { } #[inline] - fn parse_preimage(&self, tx: &[u8]) -> Result { self.parse_tx(tx) } + fn parse_preimage(&self, tx: &[u8]) -> Result { + self.parse_tx(tx) + } fn parse_signature(&self, sig: &[u8]) -> Result { SecpSignature::from_der(sig)?; @@ -1211,21 +1279,31 @@ pub trait UtxoStandardOps { pub struct UtxoArc(Arc); impl Deref for UtxoArc { type Target = UtxoCoinFields; - fn deref(&self) -> &UtxoCoinFields { &self.0 } + fn deref(&self) -> &UtxoCoinFields { + &self.0 + } } impl From for UtxoArc { - fn from(coin: UtxoCoinFields) -> UtxoArc { UtxoArc::new(coin) } + fn from(coin: UtxoCoinFields) -> UtxoArc { + UtxoArc::new(coin) + } } impl From> for UtxoArc { - fn from(arc: Arc) -> UtxoArc { UtxoArc(arc) } + fn from(arc: Arc) -> UtxoArc { + UtxoArc(arc) + } } impl UtxoArc { - pub fn new(fields: UtxoCoinFields) -> UtxoArc { UtxoArc(Arc::new(fields)) } + pub fn new(fields: UtxoCoinFields) -> UtxoArc { + UtxoArc(Arc::new(fields)) + } - pub fn with_arc(inner: Arc) -> UtxoArc { UtxoArc(inner) } + pub fn with_arc(inner: Arc) -> UtxoArc { + UtxoArc(inner) + } /// Returns weak reference to the inner UtxoCoinFields pub fn downgrade(&self) -> UtxoWeak { @@ -1238,11 +1316,15 @@ impl UtxoArc { pub struct UtxoWeak(Weak); impl From> for UtxoWeak { - fn from(weak: Weak) -> Self { UtxoWeak(weak) } + fn from(weak: Weak) -> Self { + UtxoWeak(weak) + } } impl UtxoWeak { - pub fn upgrade(&self) -> Option { self.0.upgrade().map(UtxoArc::from) } + pub fn upgrade(&self) -> Option { + self.0.upgrade().map(UtxoArc::from) + } } // We can use a shared UTXO lock for all UTXO coins at 1 time. @@ -1286,7 +1368,9 @@ pub enum GenerateTxError { } impl From for GenerateTxError { - fn from(rpc_err: JsonRpcError) -> Self { GenerateTxError::Transport(rpc_err.to_string()) } + fn from(rpc_err: JsonRpcError) -> Self { + GenerateTxError::Transport(rpc_err.to_string()) + } } impl From for GenerateTxError { @@ -1302,11 +1386,15 @@ impl From for GenerateTxError { } impl From for GenerateTxError { - fn from(e: NumConversError) -> Self { GenerateTxError::Internal(e.to_string()) } + fn from(e: NumConversError) -> Self { + GenerateTxError::Internal(e.to_string()) + } } impl From for GenerateTxError { - fn from(e: keys::Error) -> Self { GenerateTxError::Internal(e.to_string()) } + fn from(e: keys::Error) -> Self { + GenerateTxError::Internal(e.to_string()) + } } pub enum RequestTxHistoryResult { @@ -1539,7 +1627,9 @@ pub enum UtxoRpcMode { impl UtxoRpcMode { #[inline] - pub fn is_native(&self) -> bool { matches!(*self, UtxoRpcMode::Native) } + pub fn is_native(&self) -> bool { + matches!(*self, UtxoRpcMode::Native) + } } #[derive(Debug)] @@ -1828,7 +1918,9 @@ pub fn output_script(address: &Address) -> Result { } /// Builds transaction output script for a legacy P2PK address -pub fn output_script_p2pk(pubkey: &Public) -> Script { Builder::build_p2pk(pubkey) } +pub fn output_script_p2pk(pubkey: &Public) -> Script { + Builder::build_p2pk(pubkey) +} pub fn address_by_conf_and_pubkey_str( coin: &str, diff --git a/mm2src/coins/utxo/bch.rs b/mm2src/coins/utxo/bch.rs index cb63bb9059..ddffd9c1cd 100644 --- a/mm2src/coins/utxo/bch.rs +++ b/mm2src/coins/utxo/bch.rs @@ -1,30 +1,34 @@ use super::*; use crate::coin_balance::{EnableCoinBalanceError, HDAddressBalance, HDWalletBalance, HDWalletBalanceOps}; use crate::coin_errors::{AddressFromPubkeyError, MyAddressError, ValidatePaymentResult}; -use crate::hd_wallet::{ExtractExtendedPubkey, HDAddressSelector, HDCoinAddress, HDCoinWithdrawOps, - HDExtractPubkeyError, HDXPubExtractor, SettingEnabledAddressError, TrezorCoinError, - WithdrawSenderAddress}; -use crate::my_tx_history_v2::{CoinWithTxHistoryV2, MyTxHistoryErrorV2, MyTxHistoryTarget, TxDetailsBuilder, - TxHistoryStorage}; +use crate::hd_wallet::{ + ExtractExtendedPubkey, HDAddressSelector, HDCoinAddress, HDCoinWithdrawOps, HDExtractPubkeyError, HDXPubExtractor, + SettingEnabledAddressError, TrezorCoinError, WithdrawSenderAddress, +}; +use crate::my_tx_history_v2::{ + CoinWithTxHistoryV2, MyTxHistoryErrorV2, MyTxHistoryTarget, TxDetailsBuilder, TxHistoryStorage, +}; use crate::tx_history_storage::{GetTxHistoryFilters, WalletId}; use crate::utxo::rpc_clients::UtxoRpcFut; use crate::utxo::slp::{parse_slp_script, SlpGenesisParams, SlpTokenInfo, SlpTransaction, SlpUnspent}; use crate::utxo::utxo_builder::{UtxoArcBuilder, UtxoCoinBuilder}; use crate::utxo::utxo_common::{big_decimal_from_sat_unsigned, utxo_prepare_addresses_for_balance_stream_if_enabled}; use crate::utxo::utxo_hd_wallet::{UtxoHDAccount, UtxoHDAddress}; -use crate::utxo::utxo_tx_history_v2::{UtxoMyAddressesHistoryError, UtxoTxDetailsError, UtxoTxDetailsParams, - UtxoTxHistoryOps}; -use crate::{coin_balance, BlockHeightAndTime, CanRefundHtlc, CheckIfMyPaymentSentArgs, CoinBalance, CoinBalanceMap, - CoinProtocol, CoinWithDerivationMethod, CoinWithPrivKeyPolicy, ConfirmPaymentInput, DexFee, - GetWithdrawSenderAddress, IguanaBalanceOps, IguanaPrivKey, MmCoinEnum, NegotiateSwapContractAddrErr, - PrivKeyBuildPolicy, RawTransactionFut, RawTransactionRequest, RawTransactionResult, RefundPaymentArgs, - SearchForSwapTxSpendInput, SendMakerPaymentSpendPreimageInput, SendPaymentArgs, SignRawTransactionRequest, - SignatureResult, SpendPaymentArgs, SwapOps, TradePreimageValue, TransactionFut, TransactionResult, - TransactionType, TxFeeDetails, TxMarshalingErr, UnexpectedDerivationMethod, ValidateAddressResult, - ValidateFeeArgs, ValidateOtherPubKeyErr, ValidatePaymentError, ValidatePaymentFut, ValidatePaymentInput, - ValidateWatcherSpendInput, VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, WatcherReward, - WatcherRewardError, WatcherSearchForSwapTxSpendInput, WatcherValidatePaymentInput, - WatcherValidateTakerFeeInput, WithdrawFut}; +use crate::utxo::utxo_tx_history_v2::{ + UtxoMyAddressesHistoryError, UtxoTxDetailsError, UtxoTxDetailsParams, UtxoTxHistoryOps, +}; +use crate::{ + coin_balance, BlockHeightAndTime, CanRefundHtlc, CheckIfMyPaymentSentArgs, CoinBalance, CoinBalanceMap, + CoinProtocol, CoinWithDerivationMethod, CoinWithPrivKeyPolicy, ConfirmPaymentInput, DexFee, + GetWithdrawSenderAddress, IguanaBalanceOps, IguanaPrivKey, MmCoinEnum, NegotiateSwapContractAddrErr, + PrivKeyBuildPolicy, RawTransactionFut, RawTransactionRequest, RawTransactionResult, RefundPaymentArgs, + SearchForSwapTxSpendInput, SendMakerPaymentSpendPreimageInput, SendPaymentArgs, SignRawTransactionRequest, + SignatureResult, SpendPaymentArgs, SwapOps, TradePreimageValue, TransactionFut, TransactionResult, TransactionType, + TxFeeDetails, TxMarshalingErr, UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, + ValidateOtherPubKeyErr, ValidatePaymentError, ValidatePaymentFut, ValidatePaymentInput, ValidateWatcherSpendInput, + VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, WatcherReward, WatcherRewardError, + WatcherSearchForSwapTxSpendInput, WatcherValidatePaymentInput, WatcherValidateTakerFeeInput, WithdrawFut, +}; use common::executor::{AbortableSystem, AbortedError}; use common::log::warn; use derive_more::Display; @@ -58,7 +62,9 @@ pub enum BchFromLegacyReqErr { } impl From for BchFromLegacyReqErr { - fn from(err: UtxoFromLegacyReqErr) -> Self { BchFromLegacyReqErr::InvalidUtxoParams(err) } + fn from(err: UtxoFromLegacyReqErr) -> Self { + BchFromLegacyReqErr::InvalidUtxoParams(err) + } } impl BchActivationRequest { @@ -84,7 +90,9 @@ pub struct BchCoin { } impl From for UtxoArc { - fn from(coin: BchCoin) -> Self { coin.utxo_arc } + fn from(coin: BchCoin) -> Self { + coin.utxo_arc + } } #[allow(clippy::large_enum_variant)] @@ -107,7 +115,9 @@ pub struct BchUnspents { } impl BchUnspents { - fn add_standard(&mut self, utxo: UnspentInfo) { self.standard.push(utxo) } + fn add_standard(&mut self, utxo: UnspentInfo) { + self.standard.push(utxo) + } fn add_slp(&mut self, token_id: H256, bch_unspent: UnspentInfo, slp_amount: u64) { let slp_unspent = SlpUnspent { @@ -117,9 +127,13 @@ impl BchUnspents { self.slp.entry(token_id).or_default().push(slp_unspent); } - fn add_slp_baton(&mut self, utxo: UnspentInfo) { self.slp_batons.push(utxo) } + fn add_slp_baton(&mut self, utxo: UnspentInfo) { + self.slp_batons.push(utxo) + } - fn add_undetermined(&mut self, utxo: UnspentInfo) { self.undetermined.push(utxo) } + fn add_undetermined(&mut self, utxo: UnspentInfo) { + self.undetermined.push(utxo) + } pub fn platform_balance(&self, decimals: u8) -> CoinBalance { let spendable_sat = total_unspent_value(&self.standard); @@ -154,11 +168,15 @@ impl BchUnspents { } impl From for IsSlpUtxoError { - fn from(err: UtxoRpcError) -> IsSlpUtxoError { IsSlpUtxoError::Rpc(err) } + fn from(err: UtxoRpcError) -> IsSlpUtxoError { + IsSlpUtxoError::Rpc(err) + } } impl From for IsSlpUtxoError { - fn from(err: serialization::Error) -> IsSlpUtxoError { IsSlpUtxoError::TxDeserialization(err) } + fn from(err: serialization::Error) -> IsSlpUtxoError { + IsSlpUtxoError::TxDeserialization(err) + } } impl BchCoin { @@ -171,14 +189,18 @@ impl BchCoin { } } - pub fn slp_prefix(&self) -> &CashAddrPrefix { &self.slp_addr_prefix } + pub fn slp_prefix(&self) -> &CashAddrPrefix { + &self.slp_addr_prefix + } pub fn slp_address(&self, address: &Address) -> Result { let conf = &self.as_ref().conf; address.to_cashaddress(&self.slp_prefix().to_string(), &conf.address_prefixes) } - pub fn bchd_urls(&self) -> &[String] { &self.bchd_urls } + pub fn bchd_urls(&self) -> &[String] { + &self.bchd_urls + } async fn utxos_into_bch_unspents(&self, utxos: Vec) -> UtxoRpcResult { let mut result = BchUnspents::default(); @@ -624,7 +646,9 @@ impl BchCoin { } impl AsRef for BchCoin { - fn as_ref(&self) -> &UtxoCoinFields { &self.utxo_arc } + fn as_ref(&self) -> &UtxoCoinFields { + &self.utxo_arc + } } pub async fn bch_coin_with_policy( @@ -686,7 +710,9 @@ pub enum BchActivationError { } impl From for BchActivationError { - fn from(e: UtxoRpcError) -> Self { BchActivationError::RpcError(e) } + fn from(e: UtxoRpcError) -> Self { + BchActivationError::RpcError(e) + } } // if mockable is placed before async_trait there is `munmap_chunk(): invalid pointer` error on async fn mocking attempt @@ -702,13 +728,17 @@ impl UtxoTxBroadcastOps for BchCoin { #[async_trait] #[cfg_attr(test, mockable)] impl UtxoTxGenerationOps for BchCoin { - async fn get_fee_rate(&self) -> UtxoRpcResult { utxo_common::get_fee_rate(&self.utxo_arc).await } + async fn get_fee_rate(&self) -> UtxoRpcResult { + utxo_common::get_fee_rate(&self.utxo_arc).await + } async fn calc_interest_if_required(&self, unsigned: &mut TransactionInputSigner) -> UtxoRpcResult { utxo_common::calc_interest_if_required(self, unsigned).await } - fn supports_interest(&self) -> bool { utxo_common::is_kmd(self) } + fn supports_interest(&self) -> bool { + utxo_common::is_kmd(self) + } } #[async_trait] @@ -775,7 +805,9 @@ impl UtxoCommonOps for BchCoin { utxo_common::addresses_from_script(self, script) } - fn denominate_satoshis(&self, satoshi: i64) -> f64 { utxo_common::denominate_satoshis(&self.utxo_arc, satoshi) } + fn denominate_satoshis(&self, satoshi: i64) -> f64 { + utxo_common::denominate_satoshis(&self.utxo_arc, satoshi) + } fn my_public_key(&self) -> Result<&Public, MmError> { utxo_common::my_public_key(self.as_ref()) @@ -849,7 +881,9 @@ impl UtxoCommonOps for BchCoin { utxo_common::p2sh_tx_locktime(self, &self.utxo_arc.conf.ticker, htlc_locktime).await } - fn addr_format(&self) -> &UtxoAddressFormat { utxo_common::addr_format(self) } + fn addr_format(&self) -> &UtxoAddressFormat { + utxo_common::addr_format(self) + } fn addr_format_for_standard_scripts(&self) -> UtxoAddressFormat { utxo_common::addr_format_for_standard_scripts(self) @@ -1021,7 +1055,9 @@ impl SwapOps for BchCoin { utxo_common::validate_other_pubkey(raw_pubkey) } - fn is_supported_by_watchers(&self) -> bool { true } + fn is_supported_by_watchers(&self) -> bool { + true + } } fn total_unspent_value<'a>(unspents: impl IntoIterator) -> u64 { @@ -1132,9 +1168,13 @@ impl WatcherOps for BchCoin { #[async_trait] impl MarketCoinOps for BchCoin { - fn ticker(&self) -> &str { &self.utxo_arc.conf.ticker } + fn ticker(&self) -> &str { + &self.utxo_arc.conf.ticker + } - fn my_address(&self) -> MmResult { utxo_common::my_address(self) } + fn my_address(&self) -> MmResult { + utxo_common::my_address(self) + } fn address_from_pubkey(&self, pubkey: &H264Json) -> MmResult { let pubkey = Public::Compressed((*pubkey).into()); @@ -1173,9 +1213,13 @@ impl MarketCoinOps for BchCoin { Box::new(fut.boxed().compat()) } - fn base_coin_balance(&self) -> BalanceFut { utxo_common::base_coin_balance(self) } + fn base_coin_balance(&self) -> BalanceFut { + utxo_common::base_coin_balance(self) + } - fn platform_ticker(&self) -> &str { self.ticker() } + fn platform_ticker(&self) -> &str { + self.ticker() + } #[inline(always)] fn send_raw_tx(&self, tx: &str) -> Box + Send> { @@ -1216,22 +1260,36 @@ impl MarketCoinOps for BchCoin { utxo_common::current_block(&self.utxo_arc) } - fn display_priv_key(&self) -> Result { utxo_common::display_priv_key(&self.utxo_arc) } + fn display_priv_key(&self) -> Result { + utxo_common::display_priv_key(&self.utxo_arc) + } - fn min_tx_amount(&self) -> BigDecimal { utxo_common::min_tx_amount(self.as_ref()) } + fn min_tx_amount(&self) -> BigDecimal { + utxo_common::min_tx_amount(self.as_ref()) + } - fn min_trading_vol(&self) -> MmNumber { utxo_common::min_trading_vol(self.as_ref()) } + fn min_trading_vol(&self) -> MmNumber { + utxo_common::min_trading_vol(self.as_ref()) + } - fn should_burn_dex_fee(&self) -> bool { utxo_common::should_burn_dex_fee() } + fn should_burn_dex_fee(&self) -> bool { + utxo_common::should_burn_dex_fee() + } - fn is_trezor(&self) -> bool { self.as_ref().priv_key_policy.is_trezor() } + fn is_trezor(&self) -> bool { + self.as_ref().priv_key_policy.is_trezor() + } } #[async_trait] impl MmCoin for BchCoin { - fn is_asset_chain(&self) -> bool { utxo_common::is_asset_chain(&self.utxo_arc) } + fn is_asset_chain(&self) -> bool { + utxo_common::is_asset_chain(&self.utxo_arc) + } - fn spawner(&self) -> WeakSpawner { self.as_ref().abortable_system.weak_spawner() } + fn spawner(&self) -> WeakSpawner { + self.as_ref().abortable_system.weak_spawner() + } fn get_raw_transaction(&self, req: RawTransactionRequest) -> RawTransactionFut { Box::new(utxo_common::get_raw_transaction(&self.utxo_arc, req).boxed().compat()) @@ -1249,20 +1307,26 @@ impl MmCoin for BchCoin { Box::new(utxo_common::withdraw(self.clone(), req).boxed().compat()) } - fn decimals(&self) -> u8 { utxo_common::decimals(&self.utxo_arc) } + fn decimals(&self) -> u8 { + utxo_common::decimals(&self.utxo_arc) + } fn convert_to_address(&self, from: &str, to_address_format: Json) -> Result { utxo_common::convert_to_address(self, from, to_address_format) } - fn validate_address(&self, address: &str) -> ValidateAddressResult { utxo_common::validate_address(self, address) } + fn validate_address(&self, address: &str) -> ValidateAddressResult { + utxo_common::validate_address(self, address) + } fn process_history_loop(&self, _ctx: MmArc) -> Box + Send> { warn!("'process_history_loop' is not implemented for BchCoin! Consider using 'my_tx_history_v2'"); Box::new(futures01::future::err(())) } - fn history_sync_status(&self) -> HistorySyncState { utxo_common::history_sync_status(&self.utxo_arc) } + fn history_sync_status(&self) -> HistorySyncState { + utxo_common::history_sync_status(&self.utxo_arc) + } fn get_trade_fee(&self) -> Box + Send> { utxo_common::get_trade_fee(self.clone()) @@ -1289,9 +1353,13 @@ impl MmCoin for BchCoin { utxo_common::get_fee_to_send_taker_fee(self, dex_fee_amount, stage).await } - fn required_confirmations(&self) -> u64 { utxo_common::required_confirmations(&self.utxo_arc) } + fn required_confirmations(&self) -> u64 { + utxo_common::required_confirmations(&self.utxo_arc) + } - fn requires_notarization(&self) -> bool { utxo_common::requires_notarization(&self.utxo_arc) } + fn requires_notarization(&self) -> bool { + utxo_common::requires_notarization(&self.utxo_arc) + } fn set_required_confirmations(&self, confirmations: u64) { utxo_common::set_required_confirmations(&self.utxo_arc, confirmations) @@ -1301,11 +1369,17 @@ impl MmCoin for BchCoin { utxo_common::set_requires_notarization(&self.utxo_arc, requires_nota) } - fn swap_contract_address(&self) -> Option { utxo_common::swap_contract_address() } + fn swap_contract_address(&self) -> Option { + utxo_common::swap_contract_address() + } - fn fallback_swap_contract(&self) -> Option { utxo_common::fallback_swap_contract() } + fn fallback_swap_contract(&self) -> Option { + utxo_common::fallback_swap_contract() + } - fn mature_confirmations(&self) -> Option { Some(self.utxo_arc.conf.mature_confirmations) } + fn mature_confirmations(&self) -> Option { + Some(self.utxo_arc.conf.mature_confirmations) + } fn coin_protocol_info(&self, _amount_to_receive: Option) -> Vec { utxo_common::coin_protocol_info(self) @@ -1321,7 +1395,9 @@ impl MmCoin for BchCoin { utxo_common::is_coin_protocol_supported(self, info) } - fn on_disabled(&self) -> Result<(), AbortedError> { AbortableSystem::abort_all(&self.as_ref().abortable_system) } + fn on_disabled(&self) -> Result<(), AbortedError> { + AbortableSystem::abort_all(&self.as_ref().abortable_system) + } fn on_token_deactivated(&self, ticker: &str) { if let Ok(tokens) = self.slp_tokens_infos.lock().as_deref_mut() { @@ -1346,7 +1422,9 @@ impl GetWithdrawSenderAddress for BchCoin { impl CoinWithPrivKeyPolicy for BchCoin { type KeyPair = KeyPair; - fn priv_key_policy(&self) -> &PrivKeyPolicy { &self.utxo_arc.priv_key_policy } + fn priv_key_policy(&self) -> &PrivKeyPolicy { + &self.utxo_arc.priv_key_policy + } } impl CoinWithDerivationMethod for BchCoin { @@ -1393,7 +1471,9 @@ impl HDWalletCoinOps for BchCoin { utxo_common::address_from_extended_pubkey(self, extended_pubkey, derivation_path) } - fn trezor_coin(&self) -> MmResult { utxo_common::trezor_coin(self) } + fn trezor_coin(&self) -> MmResult { + utxo_common::trezor_coin(self) + } async fn received_enabled_address_from_hw_wallet( &self, @@ -1474,7 +1554,9 @@ impl HDWalletBalanceOps for BchCoin { #[async_trait] impl CoinWithTxHistoryV2 for BchCoin { - fn history_wallet_id(&self) -> WalletId { WalletId::new(self.ticker().to_owned()) } + fn history_wallet_id(&self) -> WalletId { + WalletId::new(self.ticker().to_owned()) + } /// TODO consider using `utxo_common::utxo_tx_history_common::get_tx_history_filters` /// when `BchCoin` implements `CoinWithDerivationMethod`. diff --git a/mm2src/coins/utxo/bchd_grpc.rs b/mm2src/coins/utxo/bchd_grpc.rs index 56c4bc3849..ccb1e6c09a 100644 --- a/mm2src/coins/utxo/bchd_grpc.rs +++ b/mm2src/coins/utxo/bchd_grpc.rs @@ -382,18 +382,21 @@ mod bchd_grpc_tests { slp_amount: 999, }; - let slp_utxos = [invalid_utxo.clone(), SlpUnspent { - bch_unspent: UnspentInfo { - outpoint: OutPoint { - hash: tx_hash, - index: 2, + let slp_utxos = [ + invalid_utxo.clone(), + SlpUnspent { + bch_unspent: UnspentInfo { + outpoint: OutPoint { + hash: tx_hash, + index: 2, + }, + value: 0, + height: None, + script: Vec::new().into(), }, - value: 0, - height: None, - script: Vec::new().into(), + slp_amount: 8999, }, - slp_amount: 8999, - }]; + ]; let token_id = H256::from("bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"); let err = block_on(validate_slp_utxos(BCHD_TESTNET_URLS, &slp_utxos, &token_id)).unwrap_err(); diff --git a/mm2src/coins/utxo/qtum.rs b/mm2src/coins/utxo/qtum.rs index 21191f4e85..67c5a810d5 100644 --- a/mm2src/coins/utxo/qtum.rs +++ b/mm2src/coins/utxo/qtum.rs @@ -1,40 +1,49 @@ use super::utxo_common::utxo_prepare_addresses_for_balance_stream_if_enabled; use super::*; -use crate::coin_balance::{self, EnableCoinBalanceError, EnabledCoinBalanceParams, HDAccountBalance, HDAddressBalance, - HDWalletBalance, HDWalletBalanceOps}; +use crate::coin_balance::{ + self, EnableCoinBalanceError, EnabledCoinBalanceParams, HDAccountBalance, HDAddressBalance, HDWalletBalance, + HDWalletBalanceOps, +}; use crate::coin_errors::{AddressFromPubkeyError, MyAddressError, ValidatePaymentResult}; -use crate::hd_wallet::{ExtractExtendedPubkey, HDAddressSelector, HDCoinAddress, HDCoinWithdrawOps, HDConfirmAddress, - HDExtractPubkeyError, HDXPubExtractor, SettingEnabledAddressError, TrezorCoinError, - WithdrawSenderAddress}; +use crate::hd_wallet::{ + ExtractExtendedPubkey, HDAddressSelector, HDCoinAddress, HDCoinWithdrawOps, HDConfirmAddress, HDExtractPubkeyError, + HDXPubExtractor, SettingEnabledAddressError, TrezorCoinError, WithdrawSenderAddress, +}; use crate::my_tx_history_v2::{CoinWithTxHistoryV2, MyTxHistoryErrorV2, MyTxHistoryTarget, TxHistoryStorage}; use crate::rpc_command::account_balance::{self, AccountBalanceParams, AccountBalanceRpcOps, HDAccountBalanceResponse}; -use crate::rpc_command::get_new_address::{self, GetNewAddressParams, GetNewAddressResponse, GetNewAddressRpcError, - GetNewAddressRpcOps}; +use crate::rpc_command::get_new_address::{ + self, GetNewAddressParams, GetNewAddressResponse, GetNewAddressRpcError, GetNewAddressRpcOps, +}; use crate::rpc_command::hd_account_balance_rpc_error::HDAccountBalanceRpcError; use crate::rpc_command::init_account_balance::{self, InitAccountBalanceParams, InitAccountBalanceRpcOps}; -use crate::rpc_command::init_create_account::{self, CreateAccountRpcError, CreateAccountState, CreateNewAccountParams, - InitCreateAccountRpcOps}; -use crate::rpc_command::init_scan_for_new_addresses::{self, InitScanAddressesRpcOps, ScanAddressesParams, - ScanAddressesResponse}; +use crate::rpc_command::init_create_account::{ + self, CreateAccountRpcError, CreateAccountState, CreateNewAccountParams, InitCreateAccountRpcOps, +}; +use crate::rpc_command::init_scan_for_new_addresses::{ + self, InitScanAddressesRpcOps, ScanAddressesParams, ScanAddressesResponse, +}; use crate::rpc_command::init_withdraw::{InitWithdrawCoin, WithdrawTaskHandleShared}; use crate::tx_history_storage::{GetTxHistoryFilters, WalletId}; -use crate::utxo::utxo_builder::{MergeUtxoArcOps, UtxoCoinBuildError, UtxoCoinBuilder, UtxoCoinBuilderCommonOps, - UtxoFieldsWithGlobalHDBuilder, UtxoFieldsWithHardwareWalletBuilder, - UtxoFieldsWithIguanaSecretBuilder}; +use crate::utxo::utxo_builder::{ + MergeUtxoArcOps, UtxoCoinBuildError, UtxoCoinBuilder, UtxoCoinBuilderCommonOps, UtxoFieldsWithGlobalHDBuilder, + UtxoFieldsWithHardwareWalletBuilder, UtxoFieldsWithIguanaSecretBuilder, +}; use crate::utxo::utxo_hd_wallet::{UtxoHDAccount, UtxoHDAddress}; -use crate::utxo::utxo_tx_history_v2::{UtxoMyAddressesHistoryError, UtxoTxDetailsError, UtxoTxDetailsParams, - UtxoTxHistoryOps}; -use crate::{eth, CanRefundHtlc, CheckIfMyPaymentSentArgs, CoinBalance, CoinBalanceMap, CoinWithDerivationMethod, - CoinWithPrivKeyPolicy, ConfirmPaymentInput, DelegationError, DelegationFut, DexFee, - GetWithdrawSenderAddress, IguanaBalanceOps, IguanaPrivKey, MmCoinEnum, NegotiateSwapContractAddrErr, - PrivKeyBuildPolicy, RawTransactionRequest, RawTransactionResult, RefundPaymentArgs, - SearchForSwapTxSpendInput, SendMakerPaymentSpendPreimageInput, SendPaymentArgs, SignRawTransactionRequest, - SignatureResult, SpendPaymentArgs, StakingInfosFut, SwapOps, TradePreimageValue, TransactionFut, - TransactionResult, TxMarshalingErr, UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, - ValidateOtherPubKeyErr, ValidatePaymentError, ValidatePaymentFut, ValidatePaymentInput, - ValidateWatcherSpendInput, VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, WatcherReward, - WatcherRewardError, WatcherSearchForSwapTxSpendInput, WatcherValidatePaymentInput, - WatcherValidateTakerFeeInput, WithdrawFut}; +use crate::utxo::utxo_tx_history_v2::{ + UtxoMyAddressesHistoryError, UtxoTxDetailsError, UtxoTxDetailsParams, UtxoTxHistoryOps, +}; +use crate::{ + eth, CanRefundHtlc, CheckIfMyPaymentSentArgs, CoinBalance, CoinBalanceMap, CoinWithDerivationMethod, + CoinWithPrivKeyPolicy, ConfirmPaymentInput, DelegationError, DelegationFut, DexFee, GetWithdrawSenderAddress, + IguanaBalanceOps, IguanaPrivKey, MmCoinEnum, NegotiateSwapContractAddrErr, PrivKeyBuildPolicy, + RawTransactionRequest, RawTransactionResult, RefundPaymentArgs, SearchForSwapTxSpendInput, + SendMakerPaymentSpendPreimageInput, SendPaymentArgs, SignRawTransactionRequest, SignatureResult, SpendPaymentArgs, + StakingInfosFut, SwapOps, TradePreimageValue, TransactionFut, TransactionResult, TxMarshalingErr, + UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, ValidateOtherPubKeyErr, ValidatePaymentError, + ValidatePaymentFut, ValidatePaymentInput, ValidateWatcherSpendInput, VerificationResult, WaitForHTLCTxSpendArgs, + WatcherOps, WatcherReward, WatcherRewardError, WatcherSearchForSwapTxSpendInput, WatcherValidatePaymentInput, + WatcherValidateTakerFeeInput, WithdrawFut, +}; use common::executor::{AbortableSystem, AbortedError}; use ethereum_types::H160; use futures::{FutureExt, TryFutureExt}; @@ -53,7 +62,9 @@ pub enum Qrc20AddressError { } impl From for Qrc20AddressError { - fn from(e: UnexpectedDerivationMethod) -> Self { Qrc20AddressError::UnexpectedDerivationMethod(e.to_string()) } + fn from(e: UnexpectedDerivationMethod) -> Self { + Qrc20AddressError::UnexpectedDerivationMethod(e.to_string()) + } } impl From for Qrc20AddressError { @@ -70,10 +81,13 @@ pub struct ScriptHashTypeNotSupported { } impl From for WithdrawError { - fn from(e: ScriptHashTypeNotSupported) -> Self { WithdrawError::InvalidAddress(e.to_string()) } + fn from(e: ScriptHashTypeNotSupported) -> Self { + WithdrawError::InvalidAddress(e.to_string()) + } } -#[path = "qtum_delegation.rs"] mod qtum_delegation; +#[path = "qtum_delegation.rs"] +mod qtum_delegation; #[derive(Debug, Serialize, Deserialize)] #[serde(tag = "format")] pub enum QtumAddressFormat { @@ -196,15 +210,25 @@ pub struct QtumCoinBuilder<'a> { #[async_trait] impl UtxoCoinBuilderCommonOps for QtumCoinBuilder<'_> { - fn ctx(&self) -> &MmArc { self.ctx } + fn ctx(&self) -> &MmArc { + self.ctx + } - fn conf(&self) -> &Json { self.conf } + fn conf(&self) -> &Json { + self.conf + } - fn activation_params(&self) -> &UtxoActivationParams { self.activation_params } + fn activation_params(&self) -> &UtxoActivationParams { + self.activation_params + } - fn ticker(&self) -> &str { self.ticker } + fn ticker(&self) -> &str { + self.ticker + } - fn check_utxo_maturity(&self) -> bool { self.activation_params().check_utxo_maturity.unwrap_or(true) } + fn check_utxo_maturity(&self) -> bool { + self.activation_params().check_utxo_maturity.unwrap_or(true) + } } impl UtxoFieldsWithIguanaSecretBuilder for QtumCoinBuilder<'_> {} @@ -218,7 +242,9 @@ impl UtxoCoinBuilder for QtumCoinBuilder<'_> { type ResultCoin = QtumCoin; type Error = UtxoCoinBuildError; - fn priv_key_policy(&self) -> PrivKeyBuildPolicy { self.priv_key_policy.clone() } + fn priv_key_policy(&self) -> PrivKeyBuildPolicy { + self.priv_key_policy.clone() + } async fn build(self) -> MmResult { let utxo = self.build_utxo_fields().await?; @@ -255,15 +281,21 @@ pub struct QtumCoin { } impl AsRef for QtumCoin { - fn as_ref(&self) -> &UtxoCoinFields { &self.utxo_arc } + fn as_ref(&self) -> &UtxoCoinFields { + &self.utxo_arc + } } impl From for QtumCoin { - fn from(coin: UtxoArc) -> QtumCoin { QtumCoin { utxo_arc: coin } } + fn from(coin: UtxoArc) -> QtumCoin { + QtumCoin { utxo_arc: coin } + } } impl From for UtxoArc { - fn from(coin: QtumCoin) -> Self { coin.utxo_arc } + fn from(coin: QtumCoin) -> Self { + coin.utxo_arc + } } pub async fn qtum_coin_with_policy( @@ -320,13 +352,17 @@ impl UtxoTxBroadcastOps for QtumCoin { #[async_trait] #[cfg_attr(test, mockable)] impl UtxoTxGenerationOps for QtumCoin { - async fn get_fee_rate(&self) -> UtxoRpcResult { utxo_common::get_fee_rate(&self.utxo_arc).await } + async fn get_fee_rate(&self) -> UtxoRpcResult { + utxo_common::get_fee_rate(&self.utxo_arc).await + } async fn calc_interest_if_required(&self, unsigned: &mut TransactionInputSigner) -> UtxoRpcResult { utxo_common::calc_interest_if_required(self, unsigned).await } - fn supports_interest(&self) -> bool { utxo_common::is_kmd(self) } + fn supports_interest(&self) -> bool { + utxo_common::is_kmd(self) + } } #[async_trait] @@ -390,7 +426,9 @@ impl UtxoCommonOps for QtumCoin { utxo_common::addresses_from_script(self, script) } - fn denominate_satoshis(&self, satoshi: i64) -> f64 { utxo_common::denominate_satoshis(&self.utxo_arc, satoshi) } + fn denominate_satoshis(&self, satoshi: i64) -> f64 { + utxo_common::denominate_satoshis(&self.utxo_arc, satoshi) + } fn my_public_key(&self) -> Result<&Public, MmError> { utxo_common::my_public_key(self.as_ref()) @@ -408,7 +446,9 @@ impl UtxoCommonOps for QtumCoin { utxo_common::get_current_mtp(&self.utxo_arc, CoinVariant::Qtum).await } - fn is_unspent_mature(&self, output: &RpcTransaction) -> bool { self.is_qtum_unspent_mature(output) } + fn is_unspent_mature(&self, output: &RpcTransaction) -> bool { + self.is_qtum_unspent_mature(output) + } async fn calc_interest_of_tx( &self, @@ -467,7 +507,9 @@ impl UtxoCommonOps for QtumCoin { utxo_common::p2sh_tx_locktime(self, &self.utxo_arc.conf.ticker, htlc_locktime).await } - fn addr_format(&self) -> &UtxoAddressFormat { utxo_common::addr_format(self) } + fn addr_format(&self) -> &UtxoAddressFormat { + utxo_common::addr_format(self) + } fn addr_format_for_standard_scripts(&self) -> UtxoAddressFormat { utxo_common::addr_format_for_standard_scripts(self) @@ -661,7 +703,9 @@ impl SwapOps for QtumCoin { utxo_common::validate_other_pubkey(raw_pubkey) } - fn is_supported_by_watchers(&self) -> bool { true } + fn is_supported_by_watchers(&self) -> bool { + true + } } #[async_trait] @@ -760,9 +804,13 @@ impl WatcherOps for QtumCoin { #[async_trait] impl MarketCoinOps for QtumCoin { - fn ticker(&self) -> &str { &self.utxo_arc.conf.ticker } + fn ticker(&self) -> &str { + &self.utxo_arc.conf.ticker + } - fn my_address(&self) -> MmResult { utxo_common::my_address(self) } + fn my_address(&self) -> MmResult { + utxo_common::my_address(self) + } fn address_from_pubkey(&self, pubkey: &H264Json) -> MmResult { let pubkey = Public::Compressed((*pubkey).into()); @@ -786,11 +834,17 @@ impl MarketCoinOps for QtumCoin { utxo_common::verify_message(self, signature_base64, message, address) } - fn my_balance(&self) -> BalanceFut { utxo_common::my_balance(self.clone()) } + fn my_balance(&self) -> BalanceFut { + utxo_common::my_balance(self.clone()) + } - fn base_coin_balance(&self) -> BalanceFut { utxo_common::base_coin_balance(self) } + fn base_coin_balance(&self) -> BalanceFut { + utxo_common::base_coin_balance(self) + } - fn platform_ticker(&self) -> &str { self.ticker() } + fn platform_ticker(&self) -> &str { + self.ticker() + } #[inline(always)] fn send_raw_tx(&self, tx: &str) -> Box + Send> { @@ -831,22 +885,36 @@ impl MarketCoinOps for QtumCoin { utxo_common::current_block(&self.utxo_arc) } - fn display_priv_key(&self) -> Result { utxo_common::display_priv_key(&self.utxo_arc) } + fn display_priv_key(&self) -> Result { + utxo_common::display_priv_key(&self.utxo_arc) + } - fn min_tx_amount(&self) -> BigDecimal { utxo_common::min_tx_amount(self.as_ref()) } + fn min_tx_amount(&self) -> BigDecimal { + utxo_common::min_tx_amount(self.as_ref()) + } - fn min_trading_vol(&self) -> MmNumber { utxo_common::min_trading_vol(self.as_ref()) } + fn min_trading_vol(&self) -> MmNumber { + utxo_common::min_trading_vol(self.as_ref()) + } - fn is_trezor(&self) -> bool { self.as_ref().priv_key_policy.is_trezor() } + fn is_trezor(&self) -> bool { + self.as_ref().priv_key_policy.is_trezor() + } - fn should_burn_dex_fee(&self) -> bool { utxo_common::should_burn_dex_fee() } + fn should_burn_dex_fee(&self) -> bool { + utxo_common::should_burn_dex_fee() + } } #[async_trait] impl MmCoin for QtumCoin { - fn is_asset_chain(&self) -> bool { utxo_common::is_asset_chain(&self.utxo_arc) } + fn is_asset_chain(&self) -> bool { + utxo_common::is_asset_chain(&self.utxo_arc) + } - fn spawner(&self) -> WeakSpawner { self.as_ref().abortable_system.weak_spawner() } + fn spawner(&self) -> WeakSpawner { + self.as_ref().abortable_system.weak_spawner() + } fn get_raw_transaction(&self, req: RawTransactionRequest) -> RawTransactionFut { Box::new(utxo_common::get_raw_transaction(&self.utxo_arc, req).boxed().compat()) @@ -864,14 +932,18 @@ impl MmCoin for QtumCoin { Box::new(utxo_common::withdraw(self.clone(), req).boxed().compat()) } - fn decimals(&self) -> u8 { utxo_common::decimals(&self.utxo_arc) } + fn decimals(&self) -> u8 { + utxo_common::decimals(&self.utxo_arc) + } /// Check if the `to_address_format` is standard and if the `from` address is standard UTXO address. fn convert_to_address(&self, from: &str, to_address_format: Json) -> Result { QtumBasedCoin::convert_to_address(self, from, to_address_format) } - fn validate_address(&self, address: &str) -> ValidateAddressResult { utxo_common::validate_address(self, address) } + fn validate_address(&self, address: &str) -> ValidateAddressResult { + utxo_common::validate_address(self, address) + } fn process_history_loop(&self, ctx: MmArc) -> Box + Send> { Box::new( @@ -882,7 +954,9 @@ impl MmCoin for QtumCoin { ) } - fn history_sync_status(&self) -> HistorySyncState { utxo_common::history_sync_status(&self.utxo_arc) } + fn history_sync_status(&self) -> HistorySyncState { + utxo_common::history_sync_status(&self.utxo_arc) + } fn get_trade_fee(&self) -> Box + Send> { utxo_common::get_trade_fee(self.clone()) @@ -909,9 +983,13 @@ impl MmCoin for QtumCoin { utxo_common::get_fee_to_send_taker_fee(self, dex_fee_amount, stage).await } - fn required_confirmations(&self) -> u64 { utxo_common::required_confirmations(&self.utxo_arc) } + fn required_confirmations(&self) -> u64 { + utxo_common::required_confirmations(&self.utxo_arc) + } - fn requires_notarization(&self) -> bool { utxo_common::requires_notarization(&self.utxo_arc) } + fn requires_notarization(&self) -> bool { + utxo_common::requires_notarization(&self.utxo_arc) + } fn set_required_confirmations(&self, confirmations: u64) { utxo_common::set_required_confirmations(&self.utxo_arc, confirmations) @@ -921,11 +999,17 @@ impl MmCoin for QtumCoin { utxo_common::set_requires_notarization(&self.utxo_arc, requires_nota) } - fn swap_contract_address(&self) -> Option { utxo_common::swap_contract_address() } + fn swap_contract_address(&self) -> Option { + utxo_common::swap_contract_address() + } - fn fallback_swap_contract(&self) -> Option { utxo_common::fallback_swap_contract() } + fn fallback_swap_contract(&self) -> Option { + utxo_common::fallback_swap_contract() + } - fn mature_confirmations(&self) -> Option { Some(self.utxo_arc.conf.mature_confirmations) } + fn mature_confirmations(&self) -> Option { + Some(self.utxo_arc.conf.mature_confirmations) + } fn coin_protocol_info(&self, _amount_to_receive: Option) -> Vec { utxo_common::coin_protocol_info(self) @@ -941,7 +1025,9 @@ impl MmCoin for QtumCoin { utxo_common::is_coin_protocol_supported(self, info) } - fn on_disabled(&self) -> Result<(), AbortedError> { AbortableSystem::abort_all(&self.as_ref().abortable_system) } + fn on_disabled(&self) -> Result<(), AbortedError> { + AbortableSystem::abort_all(&self.as_ref().abortable_system) + } fn on_token_deactivated(&self, _ticker: &str) {} } @@ -984,17 +1070,25 @@ impl UtxoSignerOps for QtumCoin { }) } - fn fork_id(&self) -> u32 { self.utxo_arc.conf.fork_id } + fn fork_id(&self) -> u32 { + self.utxo_arc.conf.fork_id + } - fn branch_id(&self) -> u32 { self.utxo_arc.conf.consensus_branch_id } + fn branch_id(&self) -> u32 { + self.utxo_arc.conf.consensus_branch_id + } - fn tx_provider(&self) -> Self::TxGetter { self.utxo_arc.rpc_client.clone() } + fn tx_provider(&self) -> Self::TxGetter { + self.utxo_arc.rpc_client.clone() + } } impl CoinWithPrivKeyPolicy for QtumCoin { type KeyPair = KeyPair; - fn priv_key_policy(&self) -> &PrivKeyPolicy { &self.utxo_arc.priv_key_policy } + fn priv_key_policy(&self) -> &PrivKeyPolicy { + &self.utxo_arc.priv_key_policy + } } impl CoinWithDerivationMethod for QtumCoin { @@ -1041,7 +1135,9 @@ impl HDWalletCoinOps for QtumCoin { utxo_common::address_from_extended_pubkey(self, extended_pubkey, derivation_path) } - fn trezor_coin(&self) -> MmResult { utxo_common::trezor_coin(self) } + fn trezor_coin(&self) -> MmResult { + utxo_common::trezor_coin(self) + } async fn received_enabled_address_from_hw_wallet( &self, @@ -1202,7 +1298,9 @@ impl InitCreateAccountRpcOps for QtumCoin { #[async_trait] impl CoinWithTxHistoryV2 for QtumCoin { - fn history_wallet_id(&self) -> WalletId { utxo_common::utxo_tx_history_v2_common::history_wallet_id(self.as_ref()) } + fn history_wallet_id(&self) -> WalletId { + utxo_common::utxo_tx_history_v2_common::history_wallet_id(self.as_ref()) + } async fn get_tx_history_filters( &self, @@ -1264,7 +1362,9 @@ impl UtxoTxHistoryOps for QtumCoin { /// Parse contract address (H160) from string. /// Qtum Contract addresses have another checksum verification algorithm, because of this do not use [`eth::valid_addr_from_str`]. -pub fn contract_addr_from_str(addr: &str) -> Result { eth::addr_from_str(addr) } +pub fn contract_addr_from_str(addr: &str) -> Result { + eth::addr_from_str(addr) +} pub fn contract_addr_from_utxo_addr(address: Address) -> MmResult { match address.hash() { diff --git a/mm2src/coins/utxo/qtum_delegation.rs b/mm2src/coins/utxo/qtum_delegation.rs index 6e51ab0586..fdf153ef93 100644 --- a/mm2src/coins/utxo/qtum_delegation.rs +++ b/mm2src/coins/utxo/qtum_delegation.rs @@ -1,14 +1,18 @@ use crate::qrc20::rpc_clients::Qrc20ElectrumOps; use crate::qrc20::script_pubkey::generate_contract_call_script_pubkey; -use crate::qrc20::{contract_addr_into_rpc_format, ContractCallOutput, GenerateQrc20TxResult, Qrc20AbiError, - Qrc20FeeDetails, OUTPUT_QTUM_AMOUNT, QRC20_DUST, QRC20_GAS_LIMIT_DEFAULT, QRC20_GAS_PRICE_DEFAULT}; +use crate::qrc20::{ + contract_addr_into_rpc_format, ContractCallOutput, GenerateQrc20TxResult, Qrc20AbiError, Qrc20FeeDetails, + OUTPUT_QTUM_AMOUNT, QRC20_DUST, QRC20_GAS_LIMIT_DEFAULT, QRC20_GAS_PRICE_DEFAULT, +}; use crate::utxo::qtum::{QtumBasedCoin, QtumCoin, QtumDelegationOps, QtumDelegationRequest, QtumStakingInfosDetails}; use crate::utxo::rpc_clients::UtxoRpcClientEnum; use crate::utxo::utxo_common::{big_decimal_from_sat_unsigned, UtxoTxBuilder}; use crate::utxo::{qtum, utxo_common, Address, GetUtxoListOps, UtxoCommonOps}; use crate::utxo::{PrivKeyPolicyNotAllowed, UTXO_LOCK}; -use crate::{DelegationError, DelegationFut, DelegationResult, MarketCoinOps, StakingInfoError, StakingInfos, - StakingInfosFut, TransactionData, TransactionDetails, TransactionType}; +use crate::{ + DelegationError, DelegationFut, DelegationResult, MarketCoinOps, StakingInfoError, StakingInfos, StakingInfosFut, + TransactionData, TransactionDetails, TransactionType, +}; use bitcrypto::dhash256; use common::now_sec; use derive_more::Display; @@ -63,23 +67,33 @@ impl From for QtumStakingAbiError { } impl From for DelegationError { - fn from(e: QtumStakingAbiError) -> Self { DelegationError::CannotInteractWithSmartContract(e.to_string()) } + fn from(e: QtumStakingAbiError) -> Self { + DelegationError::CannotInteractWithSmartContract(e.to_string()) + } } impl From for QtumStakingAbiError { - fn from(e: ethabi::Error) -> QtumStakingAbiError { QtumStakingAbiError::ABIError(e.to_string()) } + fn from(e: ethabi::Error) -> QtumStakingAbiError { + QtumStakingAbiError::ABIError(e.to_string()) + } } impl From for DelegationError { - fn from(e: ethabi::Error) -> Self { DelegationError::from(QtumStakingAbiError::from(e)) } + fn from(e: ethabi::Error) -> Self { + DelegationError::from(QtumStakingAbiError::from(e)) + } } impl From for DelegationError { - fn from(e: Qrc20AbiError) -> Self { DelegationError::from(QtumStakingAbiError::from(e)) } + fn from(e: Qrc20AbiError) -> Self { + DelegationError::from(QtumStakingAbiError::from(e)) + } } impl From for QtumStakingAbiError { - fn from(e: PrivKeyPolicyNotAllowed) -> Self { QtumStakingAbiError::Internal(e.to_string()) } + fn from(e: PrivKeyPolicyNotAllowed) -> Self { + QtumStakingAbiError::Internal(e.to_string()) + } } impl QtumDelegationOps for QtumCoin { diff --git a/mm2src/coins/utxo/rpc_clients.rs b/mm2src/coins/utxo/rpc_clients.rs index faa484c29e..706af16189 100644 --- a/mm2src/coins/utxo/rpc_clients.rs +++ b/mm2src/coins/utxo/rpc_clients.rs @@ -9,8 +9,10 @@ use crate::{big_decimal_from_sat_unsigned, MyAddressError, RpcTransportEventHand use chain::{OutPoint, Transaction as UtxoTx, TransactionInput, TxHashAlgo}; use common::custom_iter::TryIntoGroupMap; use common::executor::Timer; -use common::jsonrpc_client::{JsonRpcBatchClient, JsonRpcClient, JsonRpcError, JsonRpcErrorType, JsonRpcRequest, - JsonRpcRequestEnum, JsonRpcResponseFut, RpcRes}; +use common::jsonrpc_client::{ + JsonRpcBatchClient, JsonRpcClient, JsonRpcError, JsonRpcErrorType, JsonRpcRequest, JsonRpcRequestEnum, + JsonRpcResponseFut, RpcRes, +}; use common::log::{error, info, warn}; use common::{median, now_sec}; use enum_derives::EnumFromStringify; @@ -37,7 +39,8 @@ use futures::compat::Future01CompatExt; use futures::future::{FutureExt, TryFutureExt}; use futures::lock::Mutex as AsyncMutex; use futures01::Future; -#[cfg(test)] use mocktopus::macros::*; +#[cfg(test)] +use mocktopus::macros::*; use serde_json::{self as json, Value as Json}; cfg_native! { @@ -77,11 +80,15 @@ impl std::fmt::Display for UtxoRpcClientEnum { } impl From for UtxoRpcClientEnum { - fn from(client: ElectrumClient) -> UtxoRpcClientEnum { UtxoRpcClientEnum::Electrum(client) } + fn from(client: ElectrumClient) -> UtxoRpcClientEnum { + UtxoRpcClientEnum::Electrum(client) + } } impl From for UtxoRpcClientEnum { - fn from(client: NativeClient) -> UtxoRpcClientEnum { UtxoRpcClientEnum::Native(client) } + fn from(client: NativeClient) -> UtxoRpcClientEnum { + UtxoRpcClientEnum::Native(client) + } } impl Deref for UtxoRpcClientEnum { @@ -279,15 +286,21 @@ impl From for UtxoRpcError { } impl From for UtxoRpcError { - fn from(e: serialization::Error) -> Self { UtxoRpcError::InvalidResponse(format!("{:?}", e)) } + fn from(e: serialization::Error) -> Self { + UtxoRpcError::InvalidResponse(format!("{:?}", e)) + } } impl From for UtxoRpcError { - fn from(e: NumConversError) -> Self { UtxoRpcError::Internal(e.to_string()) } + fn from(e: NumConversError) -> Self { + UtxoRpcError::Internal(e.to_string()) + } } impl From for UtxoRpcError { - fn from(e: keys::Error) -> Self { UtxoRpcError::Internal(e.to_string()) } + fn from(e: keys::Error) -> Self { + UtxoRpcError::Internal(e.to_string()) + } } impl UtxoRpcError { @@ -311,7 +324,9 @@ impl UtxoRpcError { false } - pub fn is_network_error(&self) -> bool { matches!(self, UtxoRpcError::Transport(_)) } + pub fn is_network_error(&self) -> bool { + matches!(self, UtxoRpcError::Transport(_)) + } } /// Common operations that both types of UTXO clients have but implement them differently @@ -462,7 +477,9 @@ pub struct ListTransactionsItem { impl ListTransactionsItem { /// Checks if the transaction is conflicting. /// It means the transaction has conflicts or has negative confirmations. - pub fn is_conflicting(&self) -> bool { self.confirmations < 0 || !self.walletconflicts.is_empty() } + pub fn is_conflicting(&self) -> bool { + self.confirmations < 0 || !self.walletconflicts.is_empty() + } } #[derive(Clone, Debug, Deserialize)] @@ -634,7 +651,9 @@ impl Default for ConcurrentRequestMap { } impl ConcurrentRequestMap { - pub fn new() -> ConcurrentRequestMap { ConcurrentRequestMap::default() } + pub fn new() -> ConcurrentRequestMap { + ConcurrentRequestMap::default() + } async fn wrap_request(&self, request_arg: K, request_fut: RpcRes) -> Result { let mut map = self.inner.lock().await; @@ -701,7 +720,9 @@ impl Default for NativeClientImpl { pub struct NativeClient(pub Arc); impl Deref for NativeClient { type Target = NativeClientImpl; - fn deref(&self) -> &NativeClientImpl { &self.0 } + fn deref(&self) -> &NativeClientImpl { + &self.0 + } } /// The trait provides methods to generate the JsonRpcClient instance info such as name of coin. @@ -710,19 +731,29 @@ pub trait UtxoJsonRpcClientInfo: JsonRpcClient { fn coin_name(&self) -> &str; /// Generate client info from coin name - fn client_info(&self) -> String { format!("coin: {}", self.coin_name()) } + fn client_info(&self) -> String { + format!("coin: {}", self.coin_name()) + } } impl UtxoJsonRpcClientInfo for NativeClientImpl { - fn coin_name(&self) -> &str { self.coin_ticker.as_str() } + fn coin_name(&self) -> &str { + self.coin_ticker.as_str() + } } impl JsonRpcClient for NativeClientImpl { - fn version(&self) -> &'static str { "1.0" } + fn version(&self) -> &'static str { + "1.0" + } - fn next_id(&self) -> u64 { self.request_id.fetch_add(1, AtomicOrdering::Relaxed) } + fn next_id(&self) -> u64 { + self.request_id.fetch_add(1, AtomicOrdering::Relaxed) + } - fn client_info(&self) -> String { UtxoJsonRpcClientInfo::client_info(self) } + fn client_info(&self) -> String { + UtxoJsonRpcClientInfo::client_info(self) + } #[cfg(target_arch = "wasm32")] fn transport(&self, _request: JsonRpcRequestEnum) -> JsonRpcResponseFut { @@ -915,7 +946,9 @@ impl UtxoRpcClientOps for NativeClient { } } - fn get_relay_fee(&self) -> RpcRes { Box::new(self.get_network_info().map(|info| info.relay_fee)) } + fn get_relay_fee(&self) -> RpcRes { + Box::new(self.get_network_info().map(|info| info.relay_fee)) + } fn find_output_spend( &self, @@ -1084,7 +1117,9 @@ impl NativeClientImpl { } /// https://developer.bitcoin.org/reference/rpc/getblockcount.html - pub fn get_block_count(&self) -> RpcRes { rpc_func!(self, "getblockcount") } + pub fn get_block_count(&self) -> RpcRes { + rpc_func!(self, "getblockcount") + } /// https://developer.bitcoin.org/reference/rpc/getrawtransaction.html /// Always returns verbose transaction @@ -1204,7 +1239,9 @@ impl NativeClientImpl { } /// https://developer.bitcoin.org/reference/rpc/getnetworkinfo.html - pub fn get_network_info(&self) -> RpcRes { rpc_func!(self, "getnetworkinfo") } + pub fn get_network_info(&self) -> RpcRes { + rpc_func!(self, "getnetworkinfo") + } /// https://developer.bitcoin.org/reference/rpc/getaddressinfo.html pub fn get_address_info(&self, address: &str) -> RpcRes { diff --git a/mm2src/coins/utxo/rpc_clients/electrum_rpc/client.rs b/mm2src/coins/utxo/rpc_clients/electrum_rpc/client.rs index dfb9c68baf..4f1061984d 100644 --- a/mm2src/coins/utxo/rpc_clients/electrum_rpc/client.rs +++ b/mm2src/coins/utxo/rpc_clients/electrum_rpc/client.rs @@ -1,34 +1,43 @@ -use super::super::{BlockHashOrHeight, EstimateFeeMethod, EstimateFeeMode, SpentOutputInfo, UnspentInfo, UnspentMap, - UtxoJsonRpcClientInfo, UtxoRpcClientOps, UtxoRpcError, UtxoRpcFut}; +use super::super::{ + BlockHashOrHeight, EstimateFeeMethod, EstimateFeeMode, SpentOutputInfo, UnspentInfo, UnspentMap, + UtxoJsonRpcClientInfo, UtxoRpcClientOps, UtxoRpcError, UtxoRpcFut, +}; use super::connection::{ElectrumConnection, ElectrumConnectionErr, ElectrumConnectionSettings}; use super::connection_manager::ConnectionManager; -use super::constants::{BLOCKCHAIN_HEADERS_SUB_ID, BLOCKCHAIN_SCRIPTHASH_SUB_ID, ELECTRUM_REQUEST_TIMEOUT, - NO_FORCE_CONNECT_METHODS, SEND_TO_ALL_METHODS}; +use super::constants::{ + BLOCKCHAIN_HEADERS_SUB_ID, BLOCKCHAIN_SCRIPTHASH_SUB_ID, ELECTRUM_REQUEST_TIMEOUT, NO_FORCE_CONNECT_METHODS, + SEND_TO_ALL_METHODS, +}; use super::electrum_script_hash; use super::event_handlers::ElectrumConnectionManagerNotifier; use super::rpc_responses::*; use crate::utxo::rpc_clients::ConcurrentRequestMap; use crate::utxo::utxo_block_header_storage::BlockHeaderStorage; -use crate::utxo::{output_script, output_script_p2pk, GetBlockHeaderError, GetConfirmedTxError, GetTxHeightError, - ScripthashNotification}; +use crate::utxo::{ + output_script, output_script_p2pk, GetBlockHeaderError, GetConfirmedTxError, GetTxHeightError, + ScripthashNotification, +}; use crate::RpcTransportEventHandler; use crate::SharableRpcTransportEventHandler; use chain::{BlockHeader, Transaction as UtxoTx, TxHashAlgo}; use common::executor::abortable_queue::{AbortableQueue, WeakSpawner}; -use common::jsonrpc_client::{JsonRpcBatchClient, JsonRpcClient, JsonRpcError, JsonRpcErrorType, JsonRpcId, - JsonRpcMultiClient, JsonRpcRemoteAddr, JsonRpcRequest, JsonRpcRequestEnum, - JsonRpcResponseEnum, JsonRpcResponseFut, RpcRes}; +use common::jsonrpc_client::{ + JsonRpcBatchClient, JsonRpcClient, JsonRpcError, JsonRpcErrorType, JsonRpcId, JsonRpcMultiClient, + JsonRpcRemoteAddr, JsonRpcRequest, JsonRpcRequestEnum, JsonRpcResponseEnum, JsonRpcResponseFut, RpcRes, +}; use common::log::warn; use common::{median, OrdRange}; use keys::hash::H256; use keys::Address; use mm2_err_handle::prelude::*; use mm2_number::BigDecimal; -#[cfg(test)] use mocktopus::macros::*; +#[cfg(test)] +use mocktopus::macros::*; use rpc::v1::types::{Bytes as BytesJson, Transaction as RpcTransaction, H256 as H256Json}; -use serialization::{deserialize, serialize, serialize_with_flags, CoinVariant, CompactInteger, Reader, - SERIALIZE_TRANSACTION_WITNESS}; +use serialization::{ + deserialize, serialize, serialize_with_flags, CoinVariant, CompactInteger, Reader, SERIALIZE_TRANSACTION_WITNESS, +}; use spv_validation::helpers_validation::SPVError; use spv_validation::storage::BlockHeaderStorageOps; @@ -164,18 +173,28 @@ impl ElectrumClientImpl { } /// Check if all connections have been removed. - pub fn is_connections_pool_empty(&self) -> bool { self.connection_manager.is_connections_pool_empty() } + pub fn is_connections_pool_empty(&self) -> bool { + self.connection_manager.is_connections_pool_empty() + } /// Get available protocol versions. - pub fn protocol_version(&self) -> &OrdRange { &self.protocol_version } + pub fn protocol_version(&self) -> &OrdRange { + &self.protocol_version + } - pub fn coin_ticker(&self) -> &str { &self.coin_ticker } + pub fn coin_ticker(&self) -> &str { + &self.coin_ticker + } /// Whether to negotiate the protocol version. - pub fn negotiate_version(&self) -> bool { self.negotiate_version } + pub fn negotiate_version(&self) -> bool { + self.negotiate_version + } /// Get the event handlers. - pub fn event_handlers(&self) -> Arc>> { self.event_handlers.clone() } + pub fn event_handlers(&self) -> Arc>> { + self.event_handlers.clone() + } /// Sends a list of addresses through the scripthash notification sender to subscribe to their scripthash notifications. pub fn subscribe_addresses(&self, addresses: HashSet
) -> Result<(), String> { @@ -204,9 +223,13 @@ impl ElectrumClientImpl { } /// Get block headers storage. - pub fn block_headers_storage(&self) -> &BlockHeaderStorage { &self.block_headers_storage } + pub fn block_headers_storage(&self) -> &BlockHeaderStorage { + &self.block_headers_storage + } - pub fn weak_spawner(&self) -> WeakSpawner { self.abortable_system.weak_spawner() } + pub fn weak_spawner(&self) -> WeakSpawner { + self.abortable_system.weak_spawner() + } #[cfg(test)] pub fn with_protocol_version( @@ -242,19 +265,29 @@ pub struct ElectrumClient(pub Arc); impl Deref for ElectrumClient { type Target = ElectrumClientImpl; - fn deref(&self) -> &ElectrumClientImpl { &self.0 } + fn deref(&self) -> &ElectrumClientImpl { + &self.0 + } } impl UtxoJsonRpcClientInfo for ElectrumClient { - fn coin_name(&self) -> &str { self.coin_ticker.as_str() } + fn coin_name(&self) -> &str { + self.coin_ticker.as_str() + } } impl JsonRpcClient for ElectrumClient { - fn version(&self) -> &'static str { "2.0" } + fn version(&self) -> &'static str { + "2.0" + } - fn next_id(&self) -> u64 { self.next_id.fetch_add(1, AtomicOrdering::Relaxed) } + fn next_id(&self) -> u64 { + self.next_id.fetch_add(1, AtomicOrdering::Relaxed) + } - fn client_info(&self) -> String { UtxoJsonRpcClientInfo::client_info(self) } + fn client_info(&self) -> String { + UtxoJsonRpcClientInfo::client_info(self) + } fn transport(&self, request: JsonRpcRequestEnum) -> JsonRpcResponseFut { Box::new(self.clone().electrum_request_multi(request).boxed().compat()) @@ -451,7 +484,9 @@ impl ElectrumClient { } /// https://electrumx.readthedocs.io/en/latest/protocol-methods.html#server-ping - pub fn server_ping(&self) -> RpcRes<()> { rpc_func!(self, "server.ping") } + pub fn server_ping(&self) -> RpcRes<()> { + rpc_func!(self, "server.ping") + } /// https://electrumx.readthedocs.io/en/latest/protocol-methods.html#server-version pub fn server_version(&self, server_address: &str, version: &OrdRange) -> RpcRes { @@ -1012,7 +1047,9 @@ impl UtxoRpcClientOps for ElectrumClient { })) } - fn get_relay_fee(&self) -> RpcRes { rpc_func!(self, "blockchain.relayfee") } + fn get_relay_fee(&self) -> RpcRes { + rpc_func!(self, "blockchain.relayfee") + } fn find_output_spend( &self, diff --git a/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection.rs b/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection.rs index be58dfb0fe..6dda9d88c8 100644 --- a/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection.rs +++ b/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection.rs @@ -1,13 +1,16 @@ use super::client::ElectrumClient; -use super::constants::{BLOCKCHAIN_HEADERS_SUB_ID, BLOCKCHAIN_SCRIPTHASH_SUB_ID, CUTOFF_TIMEOUT, - DEFAULT_CONNECTION_ESTABLISHMENT_TIMEOUT}; +use super::constants::{ + BLOCKCHAIN_HEADERS_SUB_ID, BLOCKCHAIN_SCRIPTHASH_SUB_ID, CUTOFF_TIMEOUT, DEFAULT_CONNECTION_ESTABLISHMENT_TIMEOUT, +}; use crate::{RpcTransportEventHandler, SharableRpcTransportEventHandler}; use common::custom_futures::timeout::FutureTimerExt; -use common::executor::{abortable_queue::AbortableQueue, abortable_queue::WeakSpawner, AbortableSystem, SpawnFuture, - Timer}; -use common::jsonrpc_client::{JsonRpcBatchResponse, JsonRpcErrorType, JsonRpcId, JsonRpcRequest, JsonRpcResponse, - JsonRpcResponseEnum}; +use common::executor::{ + abortable_queue::AbortableQueue, abortable_queue::WeakSpawner, AbortableSystem, SpawnFuture, Timer, +}; +use common::jsonrpc_client::{ + JsonRpcBatchResponse, JsonRpcErrorType, JsonRpcId, JsonRpcRequest, JsonRpcResponse, JsonRpcResponseEnum, +}; use common::log::{error, info}; use common::{now_float, now_ms}; use mm2_rpc::data::legacy::ElectrumProtocol; @@ -184,11 +187,17 @@ impl ElectrumConnection { } } - pub fn address(&self) -> &str { &self.settings.url } + pub fn address(&self) -> &str { + &self.settings.url + } - fn weak_spawner(&self) -> WeakSpawner { self.abortable_system.weak_spawner() } + fn weak_spawner(&self) -> WeakSpawner { + self.abortable_system.weak_spawner() + } - fn is_connected(&self) -> bool { self.tx.lock().unwrap().is_some() } + fn is_connected(&self) -> bool { + self.tx.lock().unwrap().is_some() + } fn set_protocol_version(&self, version: f32) { let mut protocol_version = self.protocol_version.lock().unwrap(); @@ -197,7 +206,9 @@ impl ElectrumConnection { } } - fn clear_protocol_version(&self) { self.protocol_version.lock().unwrap().take(); } + fn clear_protocol_version(&self) { + self.protocol_version.lock().unwrap().take(); + } fn set_last_error(&self, reason: ElectrumConnectionErr) { let mut last_error = self.last_error.lock().unwrap(); @@ -206,9 +217,13 @@ impl ElectrumConnection { } } - fn clear_last_error(&self) { self.last_error.lock().unwrap().take(); } + fn clear_last_error(&self) { + self.last_error.lock().unwrap().take(); + } - fn last_error(&self) -> Option { self.last_error.lock().unwrap().clone() } + fn last_error(&self) -> Option { + self.last_error.lock().unwrap().clone() + } /// Connects to the electrum server by setting the `tx` sender channel. /// diff --git a/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection_manager/connection_context.rs b/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection_manager/connection_context.rs index 17f3495b85..07082c874b 100644 --- a/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection_manager/connection_context.rs +++ b/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection_manager/connection_context.rs @@ -73,7 +73,9 @@ impl ConnectionContext { } /// Resets the suspend time. - pub(super) fn connected(&self) { self.suspend_timer.reset(); } + pub(super) fn connected(&self) { + self.suspend_timer.reset(); + } /// Inform the connection context that the connection has been disconnected. /// @@ -84,8 +86,12 @@ impl ConnectionContext { } /// Returns the time the server should be suspended until (when to take it up) in milliseconds. - pub(super) fn suspended_till(&self) -> u64 { self.suspend_timer.get_suspend_until() } + pub(super) fn suspended_till(&self) -> u64 { + self.suspend_timer.get_suspend_until() + } /// Adds a subscription to the connection context. - pub(super) fn add_sub(&self, address: Address) { self.subs.lock().unwrap().insert(address); } + pub(super) fn add_sub(&self, address: Address) { + self.subs.lock().unwrap().insert(address); + } } diff --git a/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection_manager/manager.rs b/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection_manager/manager.rs index 3410cc4275..ee33b162d5 100644 --- a/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection_manager/manager.rs +++ b/mm2src/coins/utxo/rpc_clients/electrum_rpc/connection_manager/manager.rs @@ -177,7 +177,9 @@ impl ConnectionManager { } /// Returns all the server addresses. - pub fn get_all_server_addresses(&self) -> Vec { self.read_connections().keys().cloned().collect() } + pub fn get_all_server_addresses(&self) -> Vec { + self.read_connections().keys().cloned().collect() + } /// Returns all the connections. pub fn get_all_connections(&self) -> Vec> { @@ -219,7 +221,9 @@ impl ConnectionManager { } /// Returns a boolean `true` if the connection pool is empty, `false` otherwise. - pub fn is_connections_pool_empty(&self) -> bool { self.read_connections().is_empty() } + pub fn is_connections_pool_empty(&self) -> bool { + self.read_connections().is_empty() + } /// Subscribe the list of addresses to our active connections. /// @@ -456,7 +460,9 @@ impl ConnectionManager { // Abstractions over the accesses of the inner fields of the connection manager. impl ConnectionManager { #[inline] - pub fn config(&self) -> &ManagerConfig { &self.0.config } + pub fn config(&self) -> &ManagerConfig { + &self.0.config + } #[inline] fn read_connections(&self) -> RwLockReadGuard> { @@ -507,7 +513,9 @@ impl ConnectionManager { } #[inline] - fn notify_below_min_connected(&self) { self.0.below_min_connected_notifier.notify().ok(); } + fn notify_below_min_connected(&self) { + self.0.below_min_connected_notifier.notify().ok(); + } #[inline] fn extract_below_min_connected_notifiee(&self) -> Option { @@ -515,7 +523,9 @@ impl ConnectionManager { } #[inline] - fn weak_client(&self) -> &RwLock>> { &self.0.electrum_client } + fn weak_client(&self) -> &RwLock>> { + &self.0.electrum_client + } #[inline] fn get_client(&self) -> Option { diff --git a/mm2src/coins/utxo/rpc_clients/electrum_rpc/event_handlers.rs b/mm2src/coins/utxo/rpc_clients/electrum_rpc/event_handlers.rs index 9db2ab93ec..56905f5076 100644 --- a/mm2src/coins/utxo/rpc_clients/electrum_rpc/event_handlers.rs +++ b/mm2src/coins/utxo/rpc_clients/electrum_rpc/event_handlers.rs @@ -11,7 +11,9 @@ pub struct ElectrumConnectionManagerNotifier { } impl RpcTransportEventHandler for ElectrumConnectionManagerNotifier { - fn debug_info(&self) -> String { "ElectrumConnectionManagerNotifier".into() } + fn debug_info(&self) -> String { + "ElectrumConnectionManagerNotifier".into() + } fn on_connected(&self, address: &str) -> Result<(), String> { self.connection_manager.on_connected(address); diff --git a/mm2src/coins/utxo/rpc_clients/electrum_rpc/mod.rs b/mm2src/coins/utxo/rpc_clients/electrum_rpc/mod.rs index bf78308be2..c0b189d579 100644 --- a/mm2src/coins/utxo/rpc_clients/electrum_rpc/mod.rs +++ b/mm2src/coins/utxo/rpc_clients/electrum_rpc/mod.rs @@ -6,7 +6,8 @@ mod connection_manager; mod constants; mod event_handlers; mod rpc_responses; -#[cfg(not(target_arch = "wasm32"))] mod tcp_stream; +#[cfg(not(target_arch = "wasm32"))] +mod tcp_stream; pub use client::{ElectrumClient, ElectrumClientImpl, ElectrumClientSettings}; pub use connection::ElectrumConnectionSettings; diff --git a/mm2src/coins/utxo/rpc_clients/electrum_rpc/rpc_responses.rs b/mm2src/coins/utxo/rpc_clients/electrum_rpc/rpc_responses.rs index c045de98a4..379aa5d021 100644 --- a/mm2src/coins/utxo/rpc_clients/electrum_rpc/rpc_responses.rs +++ b/mm2src/coins/utxo/rpc_clients/electrum_rpc/rpc_responses.rs @@ -104,7 +104,9 @@ pub struct ElectrumBlockHeaderV14 { } impl ElectrumBlockHeaderV14 { - pub fn hash(&self) -> H256Json { dhash256(&self.hex.clone().into_vec()).into() } + pub fn hash(&self) -> H256Json { + dhash256(&self.hex.clone().into_vec()).into() + } } #[derive(Clone, Debug, Deserialize)] diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index 563dbb1cf8..896e61ce2b 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -11,19 +11,22 @@ use crate::utxo::bch::BchCoin; use crate::utxo::bchd_grpc::{check_slp_transaction, validate_slp_utxos, ValidateSlpUtxosErr}; use crate::utxo::rpc_clients::{UnspentInfo, UtxoRpcClientEnum, UtxoRpcError, UtxoRpcResult}; use crate::utxo::utxo_common::{self, big_decimal_from_sat_unsigned, payment_script, UtxoTxBuilder}; -use crate::utxo::{generate_and_send_tx, sat_from_big_decimal, ActualFeeRate, BroadcastTxErr, FeePolicy, - GenerateTxError, RecentlySpentOutPointsGuard, UtxoCoinConf, UtxoCoinFields, UtxoCommonOps, UtxoTx, - UtxoTxBroadcastOps, UtxoTxGenerationOps}; -use crate::{BalanceFut, CheckIfMyPaymentSentArgs, CoinBalance, ConfirmPaymentInput, DerivationMethod, DexFee, - FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, - NumConversError, PrivKeyPolicyNotAllowed, RawTransactionFut, RawTransactionRequest, RawTransactionResult, - RefundPaymentArgs, SearchForSwapTxSpendInput, SendPaymentArgs, SignRawTransactionRequest, SignatureResult, - SpendPaymentArgs, SwapOps, SwapTxTypeWithSecretHash, TradeFee, TradePreimageError, TradePreimageFut, - TradePreimageResult, TradePreimageValue, TransactionData, TransactionDetails, TransactionEnum, - TransactionErr, TransactionResult, TxFeeDetails, TxMarshalingErr, UnexpectedDerivationMethod, - ValidateAddressResult, ValidateFeeArgs, ValidateOtherPubKeyErr, ValidatePaymentInput, VerificationError, - VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, WeakSpawner, WithdrawError, WithdrawFee, - WithdrawFut, WithdrawRequest}; +use crate::utxo::{ + generate_and_send_tx, sat_from_big_decimal, ActualFeeRate, BroadcastTxErr, FeePolicy, GenerateTxError, + RecentlySpentOutPointsGuard, UtxoCoinConf, UtxoCoinFields, UtxoCommonOps, UtxoTx, UtxoTxBroadcastOps, + UtxoTxGenerationOps, +}; +use crate::{ + BalanceFut, CheckIfMyPaymentSentArgs, CoinBalance, ConfirmPaymentInput, DerivationMethod, DexFee, FeeApproxStage, + FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, NumConversError, + PrivKeyPolicyNotAllowed, RawTransactionFut, RawTransactionRequest, RawTransactionResult, RefundPaymentArgs, + SearchForSwapTxSpendInput, SendPaymentArgs, SignRawTransactionRequest, SignatureResult, SpendPaymentArgs, SwapOps, + SwapTxTypeWithSecretHash, TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, + TransactionData, TransactionDetails, TransactionEnum, TransactionErr, TransactionResult, TxFeeDetails, + TxMarshalingErr, UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, ValidateOtherPubKeyErr, + ValidatePaymentInput, VerificationError, VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, WeakSpawner, + WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest, +}; use async_trait::async_trait; use base64::engine::general_purpose::STANDARD; use base64::Engine; @@ -39,8 +42,9 @@ use futures::{FutureExt, TryFutureExt}; use futures01::Future; use hex::FromHexError; use keys::hash::H160; -use keys::{AddressHashEnum, CashAddrType, CashAddress, CompactSignature, KeyPair, NetworkPrefix as CashAddrPrefix, - Public}; +use keys::{ + AddressHashEnum, CashAddrType, CashAddress, CompactSignature, KeyPair, NetworkPrefix as CashAddrPrefix, Public, +}; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; use mm2_number::{BigDecimal, MmNumber}; @@ -84,7 +88,9 @@ impl From for EnableSlpError { } impl From for EnableSlpError { - fn from(e: AbortedError) -> Self { EnableSlpError::Internal(e.to_string()) } + fn from(e: AbortedError) -> Self { + EnableSlpError::Internal(e.to_string()) + } } pub struct SlpTokenFields { @@ -141,11 +147,15 @@ enum ValidateDexFeeError { } impl From for ValidateDexFeeError { - fn from(err: NumConversError) -> ValidateDexFeeError { ValidateDexFeeError::NumConversionErr(err) } + fn from(err: NumConversError) -> ValidateDexFeeError { + ValidateDexFeeError::NumConversionErr(err) + } } impl From for ValidateDexFeeError { - fn from(err: ParseSlpScriptError) -> Self { ValidateDexFeeError::OpReturnParseError(err) } + fn from(err: ParseSlpScriptError) -> Self { + ValidateDexFeeError::OpReturnParseError(err) + } } #[allow(clippy::upper_case_acronyms, clippy::large_enum_variant)] @@ -160,27 +170,39 @@ pub enum SpendP2SHError { } impl From for SpendP2SHError { - fn from(err: GenerateTxError) -> SpendP2SHError { SpendP2SHError::GenerateTxErr(err) } + fn from(err: GenerateTxError) -> SpendP2SHError { + SpendP2SHError::GenerateTxErr(err) + } } impl From for SpendP2SHError { - fn from(err: UtxoRpcError) -> SpendP2SHError { SpendP2SHError::Rpc(err) } + fn from(err: UtxoRpcError) -> SpendP2SHError { + SpendP2SHError::Rpc(err) + } } impl From for SpendP2SHError { - fn from(sign: UtxoSignWithKeyPairError) -> SpendP2SHError { SpendP2SHError::SignTxErr(sign) } + fn from(sign: UtxoSignWithKeyPairError) -> SpendP2SHError { + SpendP2SHError::SignTxErr(sign) + } } impl From for SpendP2SHError { - fn from(e: PrivKeyPolicyNotAllowed) -> Self { SpendP2SHError::PrivKeyPolicyNotAllowed(e) } + fn from(e: PrivKeyPolicyNotAllowed) -> Self { + SpendP2SHError::PrivKeyPolicyNotAllowed(e) + } } impl From for SpendP2SHError { - fn from(e: UnexpectedDerivationMethod) -> Self { SpendP2SHError::UnexpectedDerivationMethod(e) } + fn from(e: UnexpectedDerivationMethod) -> Self { + SpendP2SHError::UnexpectedDerivationMethod(e) + } } impl From for SpendP2SHError { - fn from(err: String) -> SpendP2SHError { SpendP2SHError::String(err) } + fn from(err: String) -> SpendP2SHError { + SpendP2SHError::String(err) + } } #[derive(Debug, Display)] @@ -200,31 +222,45 @@ pub enum SpendHtlcError { } impl From for SpendHtlcError { - fn from(e: UnexpectedDerivationMethod) -> Self { SpendHtlcError::UnexpectedDerivationMethod(e) } + fn from(e: UnexpectedDerivationMethod) -> Self { + SpendHtlcError::UnexpectedDerivationMethod(e) + } } impl From for SpendHtlcError { - fn from(err: NumConversError) -> SpendHtlcError { SpendHtlcError::NumConversionErr(err) } + fn from(err: NumConversError) -> SpendHtlcError { + SpendHtlcError::NumConversionErr(err) + } } impl From for SpendHtlcError { - fn from(err: SerError) -> SpendHtlcError { SpendHtlcError::DeserializationErr(err) } + fn from(err: SerError) -> SpendHtlcError { + SpendHtlcError::DeserializationErr(err) + } } impl From for SpendHtlcError { - fn from(err: keys::Error) -> SpendHtlcError { SpendHtlcError::PubkeyParseErr(err) } + fn from(err: keys::Error) -> SpendHtlcError { + SpendHtlcError::PubkeyParseErr(err) + } } impl From for SpendHtlcError { - fn from(err: SpendP2SHError) -> SpendHtlcError { SpendHtlcError::SpendP2SHErr(err) } + fn from(err: SpendP2SHError) -> SpendHtlcError { + SpendHtlcError::SpendP2SHErr(err) + } } impl From for SpendHtlcError { - fn from(err: UtxoRpcError) -> SpendHtlcError { SpendHtlcError::RpcErr(err) } + fn from(err: UtxoRpcError) -> SpendHtlcError { + SpendHtlcError::RpcErr(err) + } } impl From for SpendHtlcError { - fn from(err: ParseSlpScriptError) -> Self { SpendHtlcError::OpReturnParseError(err) } + fn from(err: ParseSlpScriptError) -> Self { + SpendHtlcError::OpReturnParseError(err) + } } fn slp_send_output(token_id: &H256, amounts: &[u64]) -> TransactionOutput { @@ -325,7 +361,9 @@ impl SlpToken { slp_send_output(&self.conf.token_id, amounts) } - fn rpc(&self) -> &UtxoRpcClientEnum { &self.platform_coin.as_ref().rpc_client } + fn rpc(&self) -> &UtxoRpcClientEnum { + &self.platform_coin.as_ref().rpc_client + } /// Returns unspents of the SLP token plus plain BCH UTXOs plus RecentlySpentOutPoints mutex guard async fn slp_unspents_for_spend( @@ -783,19 +821,29 @@ impl SlpToken { Ok(()) } - pub fn platform_dust(&self) -> u64 { self.platform_coin.as_ref().dust_amount } + pub fn platform_dust(&self) -> u64 { + self.platform_coin.as_ref().dust_amount + } - pub fn platform_decimals(&self) -> u8 { self.platform_coin.as_ref().decimals } + pub fn platform_decimals(&self) -> u8 { + self.platform_coin.as_ref().decimals + } pub fn platform_dust_dec(&self) -> BigDecimal { big_decimal_from_sat_unsigned(self.platform_dust(), self.platform_decimals()) } - pub fn decimals(&self) -> u8 { self.conf.decimals } + pub fn decimals(&self) -> u8 { + self.conf.decimals + } - pub fn token_id(&self) -> &H256 { &self.conf.token_id } + pub fn token_id(&self) -> &H256 { + &self.conf.token_id + } - fn platform_conf(&self) -> &UtxoCoinConf { &self.platform_coin.as_ref().conf } + fn platform_conf(&self) -> &UtxoCoinConf { + &self.platform_coin.as_ref().conf + } async fn my_balance_sat(&self) -> UtxoRpcResult { let (slp_unspents, _) = self.slp_unspents_for_display().await?; @@ -812,7 +860,9 @@ impl SlpToken { }) } - fn slp_prefix(&self) -> &CashAddrPrefix { self.platform_coin.slp_prefix() } + fn slp_prefix(&self) -> &CashAddrPrefix { + self.platform_coin.slp_prefix() + } pub fn get_info(&self) -> SlpTokenInfo { SlpTokenInfo { @@ -993,11 +1043,15 @@ pub enum ParseSlpScriptError { } impl From for ParseSlpScriptError { - fn from(err: SerError) -> ParseSlpScriptError { ParseSlpScriptError::DeserializeFailed(err) } + fn from(err: SerError) -> ParseSlpScriptError { + ParseSlpScriptError::DeserializeFailed(err) + } } impl From for ValidatePaymentError { - fn from(err: ParseSlpScriptError) -> Self { Self::TxDeserializationError(err.to_string()) } + fn from(err: ParseSlpScriptError) -> Self { + Self::TxDeserializationError(err.to_string()) + } } pub fn parse_slp_script(script: &[u8]) -> Result> { @@ -1037,15 +1091,21 @@ enum GenSlpSpendErr { } impl From for GenSlpSpendErr { - fn from(err: UtxoRpcError) -> GenSlpSpendErr { GenSlpSpendErr::RpcError(err) } + fn from(err: UtxoRpcError) -> GenSlpSpendErr { + GenSlpSpendErr::RpcError(err) + } } impl From for GenSlpSpendErr { - fn from(err: ValidateSlpUtxosErr) -> GenSlpSpendErr { GenSlpSpendErr::InvalidSlpUtxos(err) } + fn from(err: ValidateSlpUtxosErr) -> GenSlpSpendErr { + GenSlpSpendErr::InvalidSlpUtxos(err) + } } impl From for GenSlpSpendErr { - fn from(e: UnexpectedDerivationMethod) -> Self { GenSlpSpendErr::Internal(e.to_string()) } + fn from(e: UnexpectedDerivationMethod) -> Self { + GenSlpSpendErr::Internal(e.to_string()) + } } impl From for WithdrawError { @@ -1070,7 +1130,9 @@ impl From for WithdrawError { } impl AsRef for SlpToken { - fn as_ref(&self) -> &UtxoCoinFields { self.platform_coin.as_ref() } + fn as_ref(&self) -> &UtxoCoinFields { + self.platform_coin.as_ref() + } } #[async_trait] @@ -1094,18 +1156,24 @@ impl UtxoTxBroadcastOps for SlpToken { #[async_trait] impl UtxoTxGenerationOps for SlpToken { - async fn get_fee_rate(&self) -> UtxoRpcResult { self.platform_coin.get_fee_rate().await } + async fn get_fee_rate(&self) -> UtxoRpcResult { + self.platform_coin.get_fee_rate().await + } async fn calc_interest_if_required(&self, unsigned: &mut TransactionInputSigner) -> UtxoRpcResult { self.platform_coin.calc_interest_if_required(unsigned).await } - fn supports_interest(&self) -> bool { self.platform_coin.supports_interest() } + fn supports_interest(&self) -> bool { + self.platform_coin.supports_interest() + } } #[async_trait] impl MarketCoinOps for SlpToken { - fn ticker(&self) -> &str { &self.conf.ticker } + fn ticker(&self) -> &str { + &self.conf.ticker + } fn my_address(&self) -> MmResult { let my_address = match self.platform_coin.as_ref().derivation_method { @@ -1168,7 +1236,9 @@ impl MarketCoinOps for SlpToken { Box::new(self.platform_coin.my_balance().map(|res| res.spendable)) } - fn platform_ticker(&self) -> &str { self.platform_coin.ticker() } + fn platform_ticker(&self) -> &str { + self.platform_coin.ticker() + } /// Receives raw transaction bytes in hexadecimal format as input and returns tx hash in hexadecimal format fn send_raw_tx(&self, tx: &str) -> Box + Send> { @@ -1221,17 +1291,29 @@ impl MarketCoinOps for SlpToken { self.platform_coin.tx_enum_from_bytes(bytes) } - fn current_block(&self) -> Box + Send> { self.platform_coin.current_block() } + fn current_block(&self) -> Box + Send> { + self.platform_coin.current_block() + } - fn display_priv_key(&self) -> Result { self.platform_coin.display_priv_key() } + fn display_priv_key(&self) -> Result { + self.platform_coin.display_priv_key() + } - fn min_tx_amount(&self) -> BigDecimal { big_decimal_from_sat_unsigned(1, self.decimals()) } + fn min_tx_amount(&self) -> BigDecimal { + big_decimal_from_sat_unsigned(1, self.decimals()) + } - fn min_trading_vol(&self) -> MmNumber { big_decimal_from_sat_unsigned(1, self.decimals()).into() } + fn min_trading_vol(&self) -> MmNumber { + big_decimal_from_sat_unsigned(1, self.decimals()).into() + } - fn should_burn_dex_fee(&self) -> bool { false } + fn should_burn_dex_fee(&self) -> bool { + false + } - fn is_trezor(&self) -> bool { self.as_ref().priv_key_policy.is_trezor() } + fn is_trezor(&self) -> bool { + self.as_ref().priv_key_policy.is_trezor() + } } #[async_trait] @@ -1479,14 +1561,20 @@ pub struct SlpFeeDetails { } impl From for TxFeeDetails { - fn from(slp: SlpFeeDetails) -> TxFeeDetails { TxFeeDetails::Slp(slp) } + fn from(slp: SlpFeeDetails) -> TxFeeDetails { + TxFeeDetails::Slp(slp) + } } #[async_trait] impl MmCoin for SlpToken { - fn is_asset_chain(&self) -> bool { false } + fn is_asset_chain(&self) -> bool { + false + } - fn spawner(&self) -> WeakSpawner { self.conf.abortable_system.weak_spawner() } + fn spawner(&self) -> WeakSpawner { + self.conf.abortable_system.weak_spawner() + } fn get_raw_transaction(&self, req: RawTransactionRequest) -> RawTransactionFut { Box::new( @@ -1631,7 +1719,9 @@ impl MmCoin for SlpToken { Box::new(fut.boxed().compat()) } - fn decimals(&self) -> u8 { self.decimals() } + fn decimals(&self) -> u8 { + self.decimals() + } fn convert_to_address(&self, from: &str, to_address_format: Json) -> Result { utxo_common::convert_to_address(&self.platform_coin, from, to_address_format) @@ -1671,7 +1761,9 @@ impl MmCoin for SlpToken { Box::new(futures01::future::err(())) } - fn history_sync_status(&self) -> HistorySyncState { self.platform_coin.history_sync_status() } + fn history_sync_status(&self) -> HistorySyncState { + self.platform_coin.history_sync_status() + } /// Get fee to be paid per 1 swap transaction fn get_trade_fee(&self) -> Box + Send> { @@ -1763,9 +1855,13 @@ impl MmCoin for SlpToken { }) } - fn required_confirmations(&self) -> u64 { self.conf.required_confirmations.load(AtomicOrdering::Relaxed) } + fn required_confirmations(&self) -> u64 { + self.conf.required_confirmations.load(AtomicOrdering::Relaxed) + } - fn requires_notarization(&self) -> bool { false } + fn requires_notarization(&self) -> bool { + false + } fn set_required_confirmations(&self, confirmations: u64) { self.conf @@ -1777,13 +1873,21 @@ impl MmCoin for SlpToken { warn!("set_requires_notarization has no effect on SLPTOKEN!") } - fn swap_contract_address(&self) -> Option { utxo_common::fallback_swap_contract() } + fn swap_contract_address(&self) -> Option { + utxo_common::fallback_swap_contract() + } - fn fallback_swap_contract(&self) -> Option { utxo_common::fallback_swap_contract() } + fn fallback_swap_contract(&self) -> Option { + utxo_common::fallback_swap_contract() + } - fn mature_confirmations(&self) -> Option { self.platform_coin.mature_confirmations() } + fn mature_confirmations(&self) -> Option { + self.platform_coin.mature_confirmations() + } - fn coin_protocol_info(&self, _amount_to_receive: Option) -> Vec { Vec::new() } + fn coin_protocol_info(&self, _amount_to_receive: Option) -> Vec { + Vec::new() + } fn is_coin_protocol_supported( &self, @@ -1795,14 +1899,18 @@ impl MmCoin for SlpToken { true } - fn on_disabled(&self) -> Result<(), AbortedError> { self.conf.abortable_system.abort_all() } + fn on_disabled(&self) -> Result<(), AbortedError> { + self.conf.abortable_system.abort_all() + } fn on_token_deactivated(&self, _ticker: &str) {} } #[async_trait] impl CoinWithTxHistoryV2 for SlpToken { - fn history_wallet_id(&self) -> WalletId { WalletId::new(self.platform_ticker().to_owned()) } + fn history_wallet_id(&self) -> WalletId { + WalletId::new(self.platform_ticker().to_owned()) + } /// TODO consider using `utxo_common::utxo_tx_history_common::get_tx_history_filters` /// when `SlpToken` implements `CoinWithDerivationMethod`. @@ -1827,7 +1935,9 @@ pub enum SlpAddrFromPubkeyErr { } impl From for SlpAddrFromPubkeyErr { - fn from(err: FromHexError) -> SlpAddrFromPubkeyErr { SlpAddrFromPubkeyErr::InvalidHex(err) } + fn from(err: FromHexError) -> SlpAddrFromPubkeyErr { + SlpAddrFromPubkeyErr::InvalidHex(err) + } } pub fn slp_addr_from_pubkey_str(pubkey: &str, prefix: &str) -> Result> { diff --git a/mm2src/coins/utxo/tx_cache/fs_tx_cache.rs b/mm2src/coins/utxo/tx_cache/fs_tx_cache.rs index 84f1da7c52..d17e0cb01c 100644 --- a/mm2src/coins/utxo/tx_cache/fs_tx_cache.rs +++ b/mm2src/coins/utxo/tx_cache/fs_tx_cache.rs @@ -84,7 +84,9 @@ impl UtxoVerboseCacheOps for FsVerboseCache { impl FsVerboseCache { #[inline] - pub fn new(ticker: String, tx_cache_path: PathBuf) -> FsVerboseCache { FsVerboseCache { ticker, tx_cache_path } } + pub fn new(ticker: String, tx_cache_path: PathBuf) -> FsVerboseCache { + FsVerboseCache { ticker, tx_cache_path } + } /// Tries to load transaction from cache. /// Note: `tx.confirmations` can be out-of-date. @@ -102,5 +104,7 @@ impl FsVerboseCache { } #[inline] - fn cached_transaction_path(&self, txid: &H256Json) -> PathBuf { self.tx_cache_path.join(format!("{:?}", txid)) } + fn cached_transaction_path(&self, txid: &H256Json) -> PathBuf { + self.tx_cache_path.join(format!("{:?}", txid)) + } } diff --git a/mm2src/coins/utxo/tx_cache/mod.rs b/mm2src/coins/utxo/tx_cache/mod.rs index 32d6e67ee7..a64b2653c1 100644 --- a/mm2src/coins/utxo/tx_cache/mod.rs +++ b/mm2src/coins/utxo/tx_cache/mod.rs @@ -7,7 +7,8 @@ use std::fmt; use std::sync::Arc; pub mod dummy_tx_cache; -#[cfg(not(target_arch = "wasm32"))] pub mod fs_tx_cache; +#[cfg(not(target_arch = "wasm32"))] +pub mod fs_tx_cache; #[cfg(target_arch = "wasm32")] pub mod wasm_tx_cache { diff --git a/mm2src/coins/utxo/tx_history_events.rs b/mm2src/coins/utxo/tx_history_events.rs index 536482690b..10a184d923 100644 --- a/mm2src/coins/utxo/tx_history_events.rs +++ b/mm2src/coins/utxo/tx_history_events.rs @@ -13,17 +13,23 @@ impl<'a> DeriveStreamerId<'a> for TxHistoryEventStreamer { type InitParam = String; type DeriveParam = &'a str; - fn new(coin: Self::InitParam) -> Self { Self { coin } } + fn new(coin: Self::InitParam) -> Self { + Self { coin } + } #[inline(always)] - fn derive_streamer_id(coin: Self::DeriveParam) -> StreamerId { StreamerId::TxHistory { coin: coin.to_string() } } + fn derive_streamer_id(coin: Self::DeriveParam) -> StreamerId { + StreamerId::TxHistory { coin: coin.to_string() } + } } #[async_trait] impl EventStreamer for TxHistoryEventStreamer { type DataInType = Vec; - fn streamer_id(&self) -> StreamerId { Self::derive_streamer_id(&self.coin) } + fn streamer_id(&self) -> StreamerId { + Self::derive_streamer_id(&self.coin) + } async fn handle( self, diff --git a/mm2src/coins/utxo/utxo_balance_events.rs b/mm2src/coins/utxo/utxo_balance_events.rs index 13ef83a4fd..942dac5948 100644 --- a/mm2src/coins/utxo/utxo_balance_events.rs +++ b/mm2src/coins/utxo/utxo_balance_events.rs @@ -1,11 +1,15 @@ use super::{utxo_standard::UtxoStandardCoin, UtxoArc}; use crate::utxo::rpc_clients::UtxoRpcClientEnum; -use crate::{utxo::{output_script, - rpc_clients::electrum_script_hash, - utxo_common::{address_balance, address_to_scripthash}, - ScripthashNotification, UtxoCoinFields}, - CoinWithDerivationMethod, MarketCoinOps}; +use crate::{ + utxo::{ + output_script, + rpc_clients::electrum_script_hash, + utxo_common::{address_balance, address_to_scripthash}, + ScripthashNotification, UtxoCoinFields, + }, + CoinWithDerivationMethod, MarketCoinOps, +}; use async_trait::async_trait; use common::log; @@ -43,7 +47,9 @@ impl<'a> DeriveStreamerId<'a> for UtxoBalanceEventStreamer { } } - fn derive_streamer_id(coin: Self::DeriveParam) -> StreamerId { StreamerId::Balance { coin: coin.to_string() } } + fn derive_streamer_id(coin: Self::DeriveParam) -> StreamerId { + StreamerId::Balance { coin: coin.to_string() } + } } #[async_trait] diff --git a/mm2src/coins/utxo/utxo_block_header_storage/mod.rs b/mm2src/coins/utxo/utxo_block_header_storage/mod.rs index 7ebc87d70a..908a850bd2 100644 --- a/mm2src/coins/utxo/utxo_block_header_storage/mod.rs +++ b/mm2src/coins/utxo/utxo_block_header_storage/mod.rs @@ -1,8 +1,10 @@ -#[cfg(not(target_arch = "wasm32"))] mod sql_block_header_storage; +#[cfg(not(target_arch = "wasm32"))] +mod sql_block_header_storage; #[cfg(not(target_arch = "wasm32"))] pub use sql_block_header_storage::SqliteBlockHeadersStorage; -#[cfg(target_arch = "wasm32")] mod wasm; +#[cfg(target_arch = "wasm32")] +mod wasm; #[cfg(target_arch = "wasm32")] pub use wasm::IDBBlockHeadersStorage; @@ -21,7 +23,9 @@ pub struct BlockHeaderStorage { } impl Debug for BlockHeaderStorage { - fn fmt(&self, _f: &mut Formatter<'_>) -> std::fmt::Result { Ok(()) } + fn fmt(&self, _f: &mut Formatter<'_>) -> std::fmt::Result { + Ok(()) + } } impl BlockHeaderStorage { @@ -66,13 +70,17 @@ impl BlockHeaderStorage { } #[allow(dead_code)] - pub(crate) fn into_inner(self) -> Box { self.inner } + pub(crate) fn into_inner(self) -> Box { + self.inner + } } #[async_trait] #[cfg_attr(all(test, not(target_arch = "wasm32")), mockable)] impl BlockHeaderStorageOps for BlockHeaderStorage { - async fn init(&self) -> Result<(), BlockHeaderStorageError> { self.inner.init().await } + async fn init(&self) -> Result<(), BlockHeaderStorageError> { + self.inner.init().await + } async fn is_initialized_for(&self) -> Result { self.inner.is_initialized_for().await @@ -116,7 +124,9 @@ impl BlockHeaderStorageOps for BlockHeaderStorage { self.inner.remove_headers_from_storage(from_height, to_height).await } - async fn is_table_empty(&self) -> Result<(), BlockHeaderStorageError> { self.inner.is_table_empty().await } + async fn is_table_empty(&self) -> Result<(), BlockHeaderStorageError> { + self.inner.is_table_empty().await + } } #[cfg(any(test, target_arch = "wasm32"))] @@ -313,10 +323,14 @@ mod native_tests { const FOR_COIN_GET: &str = "get"; const FOR_COIN_INSERT: &str = "insert"; #[test] - fn test_add_block_headers() { block_on(test_add_block_headers_impl(FOR_COIN_INSERT)) } + fn test_add_block_headers() { + block_on(test_add_block_headers_impl(FOR_COIN_INSERT)) + } #[test] - fn test_test_get_block_header() { block_on(test_get_block_header_impl(FOR_COIN_GET)) } + fn test_test_get_block_header() { + block_on(test_get_block_header_impl(FOR_COIN_GET)) + } #[test] fn test_get_last_block_header_with_non_max_bits() { @@ -324,10 +338,14 @@ mod native_tests { } #[test] - fn test_get_last_block_height() { block_on(test_get_last_block_height_impl(FOR_COIN_GET)) } + fn test_get_last_block_height() { + block_on(test_get_last_block_height_impl(FOR_COIN_GET)) + } #[test] - fn test_remove_headers_from_storage() { block_on(test_remove_headers_from_storage_impl(FOR_COIN_GET)) } + fn test_remove_headers_from_storage() { + block_on(test_remove_headers_from_storage_impl(FOR_COIN_GET)) + } } #[cfg(target_arch = "wasm32")] @@ -360,10 +378,14 @@ mod wasm_test { } #[wasm_bindgen_test] - async fn test_add_block_headers() { test_add_block_headers_impl(FOR_COIN).await } + async fn test_add_block_headers() { + test_add_block_headers_impl(FOR_COIN).await + } #[wasm_bindgen_test] - async fn test_test_get_block_header() { test_get_block_header_impl(FOR_COIN).await } + async fn test_test_get_block_header() { + test_get_block_header_impl(FOR_COIN).await + } #[wasm_bindgen_test] async fn test_get_last_block_header_with_non_max_bits() { @@ -371,8 +393,12 @@ mod wasm_test { } #[wasm_bindgen_test] - async fn test_get_last_block_height() { test_get_last_block_height_impl(FOR_COIN).await } + async fn test_get_last_block_height() { + test_get_last_block_height_impl(FOR_COIN).await + } #[wasm_bindgen_test] - async fn test_remove_headers_from_storage() { test_remove_headers_from_storage_impl(FOR_COIN).await } + async fn test_remove_headers_from_storage() { + test_remove_headers_from_storage_impl(FOR_COIN).await + } } diff --git a/mm2src/coins/utxo/utxo_block_header_storage/sql_block_header_storage.rs b/mm2src/coins/utxo/utxo_block_header_storage/sql_block_header_storage.rs index bc32e41d05..ba2322de16 100644 --- a/mm2src/coins/utxo/utxo_block_header_storage/sql_block_header_storage.rs +++ b/mm2src/coins/utxo/utxo_block_header_storage/sql_block_header_storage.rs @@ -1,11 +1,13 @@ use async_trait::async_trait; use chain::BlockHeader; use common::async_blocking; -use db_common::{sqlite::rusqlite::Error as SqlError, - sqlite::rusqlite::{params_from_iter, Connection, Row, ToSql}, - sqlite::string_from_row, - sqlite::validate_table_name, - sqlite::CHECK_TABLE_EXISTS_SQL}; +use db_common::{ + sqlite::rusqlite::Error as SqlError, + sqlite::rusqlite::{params_from_iter, Connection, Row, ToSql}, + sqlite::string_from_row, + sqlite::validate_table_name, + sqlite::CHECK_TABLE_EXISTS_SQL, +}; use primitives::hash::H256; use serialization::Reader; use spv_validation::storage::{BlockHeaderStorageError, BlockHeaderStorageOps}; @@ -14,7 +16,9 @@ use std::convert::TryInto; use std::num::TryFromIntError; use std::sync::{Arc, Mutex}; -pub(crate) fn block_headers_cache_table(ticker: &str) -> String { ticker.to_owned() + "_block_headers_cache" } +pub(crate) fn block_headers_cache_table(ticker: &str) -> String { + ticker.to_owned() + "_block_headers_cache" +} fn get_table_name_and_validate(for_coin: &str) -> Result { let table_name = block_headers_cache_table(for_coin); diff --git a/mm2src/coins/utxo/utxo_block_header_storage/wasm/indexeddb_block_header_storage.rs b/mm2src/coins/utxo/utxo_block_header_storage/wasm/indexeddb_block_header_storage.rs index 08e1a962c8..292f3ac2b8 100644 --- a/mm2src/coins/utxo/utxo_block_header_storage/wasm/indexeddb_block_header_storage.rs +++ b/mm2src/coins/utxo/utxo_block_header_storage/wasm/indexeddb_block_header_storage.rs @@ -4,8 +4,10 @@ use async_trait::async_trait; use chain::BlockHeader; use mm2_core::mm_ctx::MmArc; use mm2_db::indexed_db::cursor_prelude::CursorError; -use mm2_db::indexed_db::{BeBigUint, ConstructibleDb, DbIdentifier, DbInstance, DbLocked, IndexedDb, IndexedDbBuilder, - InitDbResult, MultiIndex, SharedDb}; +use mm2_db::indexed_db::{ + BeBigUint, ConstructibleDb, DbIdentifier, DbInstance, DbLocked, IndexedDb, IndexedDbBuilder, InitDbResult, + MultiIndex, SharedDb, +}; use mm2_err_handle::prelude::*; use num_traits::ToPrimitive; use primitives::hash::H256; @@ -38,7 +40,9 @@ impl DbInstance for IDBBlockHeadersInner { } impl IDBBlockHeadersInner { - pub fn get_inner(&self) -> &IndexedDb { &self.inner } + pub fn get_inner(&self) -> &IndexedDb { + &self.inner + } } pub struct IDBBlockHeadersStorage { @@ -64,9 +68,13 @@ impl IDBBlockHeadersStorage { #[async_trait] impl BlockHeaderStorageOps for IDBBlockHeadersStorage { - async fn init(&self) -> Result<(), BlockHeaderStorageError> { Ok(()) } + async fn init(&self) -> Result<(), BlockHeaderStorageError> { + Ok(()) + } - async fn is_initialized_for(&self) -> Result { Ok(true) } + async fn is_initialized_for(&self) -> Result { + Ok(true) + } async fn add_block_headers_to_storage( &self, diff --git a/mm2src/coins/utxo/utxo_builder/mod.rs b/mm2src/coins/utxo/utxo_builder/mod.rs index 205c36ee71..1b66bd0621 100644 --- a/mm2src/coins/utxo/utxo_builder/mod.rs +++ b/mm2src/coins/utxo/utxo_builder/mod.rs @@ -3,9 +3,10 @@ mod utxo_coin_builder; mod utxo_conf_builder; pub use utxo_arc_builder::{MergeUtxoArcOps, UtxoArcBuilder}; -pub use utxo_coin_builder::{UtxoCoinBuildError, UtxoCoinBuildResult, UtxoCoinBuilder, UtxoCoinBuilderCommonOps, - UtxoFieldsWithGlobalHDBuilder, UtxoFieldsWithHardwareWalletBuilder, - UtxoFieldsWithIguanaSecretBuilder, DAY_IN_SECONDS}; +pub use utxo_coin_builder::{ + UtxoCoinBuildError, UtxoCoinBuildResult, UtxoCoinBuilder, UtxoCoinBuilderCommonOps, UtxoFieldsWithGlobalHDBuilder, + UtxoFieldsWithHardwareWalletBuilder, UtxoFieldsWithIguanaSecretBuilder, DAY_IN_SECONDS, +}; pub use utxo_conf_builder::{UtxoConfBuilder, UtxoConfError, UtxoConfResult}; #[cfg(test)] diff --git a/mm2src/coins/utxo/utxo_builder/utxo_arc_builder.rs b/mm2src/coins/utxo/utxo_builder/utxo_arc_builder.rs index 4199e3e39e..6ea7a66147 100644 --- a/mm2src/coins/utxo/utxo_builder/utxo_arc_builder.rs +++ b/mm2src/coins/utxo/utxo_builder/utxo_arc_builder.rs @@ -1,11 +1,13 @@ use crate::utxo::rpc_clients::{ElectrumClient, ElectrumClientImpl, UtxoJsonRpcClientInfo, UtxoRpcClientEnum}; use crate::utxo::utxo_block_header_storage::BlockHeaderStorage; -use crate::utxo::utxo_builder::{UtxoCoinBuildError, UtxoCoinBuilder, UtxoCoinBuilderCommonOps, - UtxoFieldsWithGlobalHDBuilder, UtxoFieldsWithHardwareWalletBuilder, - UtxoFieldsWithIguanaSecretBuilder}; -use crate::utxo::{generate_and_send_tx, FeePolicy, GetUtxoListOps, UtxoArc, UtxoCommonOps, UtxoSyncStatusLoopHandle, - UtxoWeak}; +use crate::utxo::utxo_builder::{ + UtxoCoinBuildError, UtxoCoinBuilder, UtxoCoinBuilderCommonOps, UtxoFieldsWithGlobalHDBuilder, + UtxoFieldsWithHardwareWalletBuilder, UtxoFieldsWithIguanaSecretBuilder, +}; +use crate::utxo::{ + generate_and_send_tx, FeePolicy, GetUtxoListOps, UtxoArc, UtxoCommonOps, UtxoSyncStatusLoopHandle, UtxoWeak, +}; use crate::{DerivationMethod, PrivKeyBuildPolicy, UtxoActivationParams}; use async_trait::async_trait; use chain::{BlockHeader, TransactionOutput}; @@ -15,7 +17,8 @@ use derive_more::Display; use futures::compat::Future01CompatExt; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; -#[cfg(test)] use mocktopus::macros::*; +#[cfg(test)] +use mocktopus::macros::*; use rand::Rng; use script::Builder; use serde_json::Value as Json; @@ -70,13 +73,21 @@ impl UtxoCoinBuilderCommonOps for UtxoArcBuilder<'_, F, T> where F: Fn(UtxoArc) -> T + Send + Sync + 'static, { - fn ctx(&self) -> &MmArc { self.ctx } + fn ctx(&self) -> &MmArc { + self.ctx + } - fn conf(&self) -> &Json { self.conf } + fn conf(&self) -> &Json { + self.conf + } - fn activation_params(&self) -> &UtxoActivationParams { self.activation_params } + fn activation_params(&self) -> &UtxoActivationParams { + self.activation_params + } - fn ticker(&self) -> &str { self.ticker } + fn ticker(&self) -> &str { + self.ticker + } } impl UtxoFieldsWithIguanaSecretBuilder for UtxoArcBuilder<'_, F, T> where @@ -100,7 +111,9 @@ where type ResultCoin = T; type Error = UtxoCoinBuildError; - fn priv_key_policy(&self) -> PrivKeyBuildPolicy { self.priv_key_policy.clone() } + fn priv_key_policy(&self) -> PrivKeyBuildPolicy { + self.priv_key_policy.clone() + } async fn build(self) -> MmResult { let utxo = self.build_utxo_fields().await?; diff --git a/mm2src/coins/utxo/utxo_builder/utxo_coin_builder.rs b/mm2src/coins/utxo/utxo_builder/utxo_coin_builder.rs index 76491bb172..3ba7352e42 100644 --- a/mm2src/coins/utxo/utxo_builder/utxo_coin_builder.rs +++ b/mm2src/coins/utxo/utxo_builder/utxo_coin_builder.rs @@ -1,15 +1,21 @@ -use crate::hd_wallet::{load_hd_accounts_from_storage, HDAccountsMutex, HDWallet, HDWalletCoinStorage, - HDWalletStorageError, DEFAULT_GAP_LIMIT}; -use crate::utxo::rpc_clients::{ElectrumClient, ElectrumClientSettings, ElectrumConnectionSettings, EstimateFeeMethod, - UtxoRpcClientEnum}; +use crate::hd_wallet::{ + load_hd_accounts_from_storage, HDAccountsMutex, HDWallet, HDWalletCoinStorage, HDWalletStorageError, + DEFAULT_GAP_LIMIT, +}; +use crate::utxo::rpc_clients::{ + ElectrumClient, ElectrumClientSettings, ElectrumConnectionSettings, EstimateFeeMethod, UtxoRpcClientEnum, +}; use crate::utxo::tx_cache::{UtxoVerboseCacheOps, UtxoVerboseCacheShared}; use crate::utxo::utxo_block_header_storage::BlockHeaderStorage; use crate::utxo::utxo_builder::utxo_conf_builder::{UtxoConfBuilder, UtxoConfError}; -use crate::utxo::{output_script, ElectrumBuilderArgs, FeeRate, RecentlySpentOutPoints, UtxoCoinConf, UtxoCoinFields, - UtxoHDWallet, UtxoRpcMode, UtxoSyncStatus, UtxoSyncStatusLoopHandle, UTXO_DUST_AMOUNT}; -use crate::{BlockchainNetwork, CoinTransportMetrics, DerivationMethod, HistorySyncState, IguanaPrivKey, - PrivKeyBuildPolicy, PrivKeyPolicy, PrivKeyPolicyNotAllowed, RpcClientType, - SharableRpcTransportEventHandler, UtxoActivationParams}; +use crate::utxo::{ + output_script, ElectrumBuilderArgs, FeeRate, RecentlySpentOutPoints, UtxoCoinConf, UtxoCoinFields, UtxoHDWallet, + UtxoRpcMode, UtxoSyncStatus, UtxoSyncStatusLoopHandle, UTXO_DUST_AMOUNT, +}; +use crate::{ + BlockchainNetwork, CoinTransportMetrics, DerivationMethod, HistorySyncState, IguanaPrivKey, PrivKeyBuildPolicy, + PrivKeyPolicy, PrivKeyPolicyNotAllowed, RpcClientType, SharableRpcTransportEventHandler, UtxoActivationParams, +}; use async_trait::async_trait; use chain::TxHashAlgo; use common::executor::{abortable_queue::AbortableQueue, AbortableSystem, AbortedError}; @@ -80,36 +86,52 @@ pub enum UtxoCoinBuildError { } impl From for UtxoCoinBuildError { - fn from(e: UtxoConfError) -> Self { UtxoCoinBuildError::ConfError(e) } + fn from(e: UtxoConfError) -> Self { + UtxoCoinBuildError::ConfError(e) + } } impl From for UtxoCoinBuildError { /// `CryptoCtx` is expected to be initialized already. - fn from(crypto_err: CryptoCtxError) -> Self { UtxoCoinBuildError::Internal(crypto_err.to_string()) } + fn from(crypto_err: CryptoCtxError) -> Self { + UtxoCoinBuildError::Internal(crypto_err.to_string()) + } } impl From for UtxoCoinBuildError { - fn from(e: Bip32DerPathError) -> Self { UtxoCoinBuildError::Internal(StandardHDPathError::from(e).to_string()) } + fn from(e: Bip32DerPathError) -> Self { + UtxoCoinBuildError::Internal(StandardHDPathError::from(e).to_string()) + } } impl From for UtxoCoinBuildError { - fn from(e: HDWalletStorageError) -> Self { UtxoCoinBuildError::HDWalletStorageError(e) } + fn from(e: HDWalletStorageError) -> Self { + UtxoCoinBuildError::HDWalletStorageError(e) + } } impl From for UtxoCoinBuildError { - fn from(e: BlockHeaderStorageError) -> Self { UtxoCoinBuildError::BlockHeaderStorageError(e) } + fn from(e: BlockHeaderStorageError) -> Self { + UtxoCoinBuildError::BlockHeaderStorageError(e) + } } impl From for UtxoCoinBuildError { - fn from(e: AbortedError) -> Self { UtxoCoinBuildError::Internal(e.to_string()) } + fn from(e: AbortedError) -> Self { + UtxoCoinBuildError::Internal(e.to_string()) + } } impl From for UtxoCoinBuildError { - fn from(e: PrivKeyPolicyNotAllowed) -> Self { UtxoCoinBuildError::PrivKeyPolicyNotAllowed(e) } + fn from(e: PrivKeyPolicyNotAllowed) -> Self { + UtxoCoinBuildError::PrivKeyPolicyNotAllowed(e) + } } impl From for UtxoCoinBuildError { - fn from(e: keys::Error) -> Self { UtxoCoinBuildError::Internal(e.to_string()) } + fn from(e: keys::Error) -> Self { + UtxoCoinBuildError::Internal(e.to_string()) + } } #[async_trait] @@ -228,7 +250,9 @@ pub trait UtxoFieldsWithGlobalHDBuilder: UtxoCoinBuilderCommonOps { build_utxo_coin_fields_with_conf_and_policy(self, conf, priv_key_policy, derivation_method).await } - fn gap_limit(&self) -> u32 { self.activation_params().gap_limit.unwrap_or(DEFAULT_GAP_LIMIT) } + fn gap_limit(&self) -> u32 { + self.activation_params().gap_limit.unwrap_or(DEFAULT_GAP_LIMIT) + } } async fn build_utxo_coin_fields_with_conf_and_policy( @@ -370,9 +394,13 @@ pub trait UtxoFieldsWithHardwareWalletBuilder: UtxoCoinBuilderCommonOps { Ok(coin) } - fn gap_limit(&self) -> u32 { self.activation_params().gap_limit.unwrap_or(DEFAULT_GAP_LIMIT) } + fn gap_limit(&self) -> u32 { + self.activation_params().gap_limit.unwrap_or(DEFAULT_GAP_LIMIT) + } - fn supports_trezor(&self, conf: &UtxoCoinConf) -> bool { conf.trezor_coin.is_some() } + fn supports_trezor(&self, conf: &UtxoCoinConf) -> bool { + conf.trezor_coin.is_some() + } fn trezor_wallet_rmd160(&self) -> UtxoCoinBuildResult { let crypto_ctx = CryptoCtx::from_ctx(self.ctx()).map_mm_err()?; @@ -459,7 +487,9 @@ pub trait UtxoCoinBuilderCommonOps { .unwrap_or(if self.ticker() == "BTC" { 5 } else { 85 }) as u8 } - fn dust_amount(&self) -> u64 { json::from_value(self.conf()["dust"].clone()).unwrap_or(UTXO_DUST_AMOUNT) } + fn dust_amount(&self) -> u64 { + json::from_value(self.conf()["dust"].clone()).unwrap_or(UTXO_DUST_AMOUNT) + } fn network(&self) -> UtxoCoinBuildResult { let conf = self.conf(); @@ -689,7 +719,9 @@ pub trait UtxoCoinBuilderCommonOps { } #[cfg(not(target_arch = "wasm32"))] - fn tx_cache_path(&self) -> PathBuf { self.ctx().global_dir().join("TX_CACHE") } + fn tx_cache_path(&self) -> PathBuf { + self.ctx().global_dir().join("TX_CACHE") + } fn block_header_status_channel( &self, diff --git a/mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs b/mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs index 90077f1edd..d6cf68d7a9 100644 --- a/mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs +++ b/mm2src/coins/utxo/utxo_builder/utxo_conf_builder.rs @@ -1,6 +1,8 @@ use crate::utxo::rpc_clients::EstimateFeeMode; -use crate::utxo::{parse_hex_encoded_u32, UtxoCoinConf, DEFAULT_DYNAMIC_FEE_VOLATILITY_PERCENT, KMD_MTP_BLOCK_COUNT, - MATURE_CONFIRMATIONS_DEFAULT}; +use crate::utxo::{ + parse_hex_encoded_u32, UtxoCoinConf, DEFAULT_DYNAMIC_FEE_VOLATILITY_PERCENT, KMD_MTP_BLOCK_COUNT, + MATURE_CONFIRMATIONS_DEFAULT, +}; use crate::UtxoActivationParams; use bitcrypto::ChecksumType; use crypto::{Bip32Error, HDPathToCoin}; @@ -36,7 +38,9 @@ pub enum UtxoConfError { } impl From for UtxoConfError { - fn from(e: Bip32Error) -> Self { UtxoConfError::ErrorDeserializingDerivationPath(e.to_string()) } + fn from(e: Bip32Error) -> Self { + UtxoConfError::ErrorDeserializingDerivationPath(e.to_string()) + } } pub struct UtxoConfBuilder<'a> { @@ -168,9 +172,13 @@ impl<'a> UtxoConfBuilder<'a> { .unwrap_or(if self.ticker == "BTC" { 5 } else { 85 }) as u8 } - fn pub_t_address_prefix(&self) -> u8 { self.conf["taddr"].as_u64().unwrap_or(0) as u8 } + fn pub_t_address_prefix(&self) -> u8 { + self.conf["taddr"].as_u64().unwrap_or(0) as u8 + } - fn p2sh_t_address_prefix(&self) -> u8 { self.conf["taddr"].as_u64().unwrap_or(0) as u8 } + fn p2sh_t_address_prefix(&self) -> u8 { + self.conf["taddr"].as_u64().unwrap_or(0) as u8 + } fn sign_message_prefix(&self) -> Option { json::from_value(self.conf["sign_message_prefix"].clone()).unwrap_or(None) @@ -183,7 +191,9 @@ impl<'a> UtxoConfBuilder<'a> { wiftype as u8 } - fn bech32_hrp(&self) -> Option { json::from_value(self.conf["bech32_hrp"].clone()).unwrap_or(None) } + fn bech32_hrp(&self) -> Option { + json::from_value(self.conf["bech32_hrp"].clone()).unwrap_or(None) + } fn default_address_format(&self) -> UtxoAddressFormat { let mut address_format: UtxoAddressFormat = @@ -202,11 +212,17 @@ impl<'a> UtxoConfBuilder<'a> { address_format } - fn asset_chain(&self) -> bool { self.conf["asset"].as_str().is_some() } + fn asset_chain(&self) -> bool { + self.conf["asset"].as_str().is_some() + } - fn tx_version(&self) -> i32 { self.conf["txversion"].as_i64().unwrap_or(1) as i32 } + fn tx_version(&self) -> i32 { + self.conf["txversion"].as_i64().unwrap_or(1) as i32 + } - fn overwintered(&self) -> bool { self.conf["overwintered"].as_u64().unwrap_or(0) == 1 } + fn overwintered(&self) -> bool { + self.conf["overwintered"].as_u64().unwrap_or(0) == 1 + } fn tx_fee_volatility_percent(&self) -> f64 { self.conf["txfee_volatility_percent"] @@ -282,11 +298,17 @@ impl<'a> UtxoConfBuilder<'a> { .unwrap_or(MATURE_CONFIRMATIONS_DEFAULT) } - fn is_pos(&self) -> bool { self.conf["isPoS"].as_u64() == Some(1) } + fn is_pos(&self) -> bool { + self.conf["isPoS"].as_u64() == Some(1) + } - fn is_posv(&self) -> bool { self.conf["isPoSV"].as_u64() == Some(1) } + fn is_posv(&self) -> bool { + self.conf["isPoSV"].as_u64() == Some(1) + } - fn segwit(&self) -> bool { self.conf["segwit"].as_bool().unwrap_or(false) } + fn segwit(&self) -> bool { + self.conf["segwit"].as_bool().unwrap_or(false) + } fn mtp_block_count(&self) -> NonZeroU64 { json::from_value(self.conf["mtp_block_count"].clone()).unwrap_or(KMD_MTP_BLOCK_COUNT) @@ -296,9 +318,13 @@ impl<'a> UtxoConfBuilder<'a> { json::from_value(self.conf["estimate_fee_mode"].clone()).unwrap_or(None) } - fn estimate_fee_blocks(&self) -> u32 { json::from_value(self.conf["estimate_fee_blocks"].clone()).unwrap_or(1) } + fn estimate_fee_blocks(&self) -> u32 { + json::from_value(self.conf["estimate_fee_blocks"].clone()).unwrap_or(1) + } - fn trezor_coin(&self) -> Option { self.conf["trezor_coin"].as_str().map(|coin| coin.to_string()) } + fn trezor_coin(&self) -> Option { + self.conf["trezor_coin"].as_str().map(|coin| coin.to_string()) + } fn spv_conf(&self) -> UtxoConfResult> { json::from_value(self.conf["spv_conf"].clone()) @@ -310,5 +336,7 @@ impl<'a> UtxoConfBuilder<'a> { .map_to_mm(|e| UtxoConfError::ErrorDeserializingDerivationPath(e.to_string())) } - fn avg_blocktime(&self) -> Option { self.conf["avg_blocktime"].as_u64() } + fn avg_blocktime(&self) -> Option { + self.conf["avg_blocktime"].as_u64() + } } diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 3641ce8d8a..fc944c29f5 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -5,29 +5,32 @@ use crate::eth::EthCoinType; use crate::hd_wallet::{HDAddressSelector, HDCoinAddress, HDCoinHDAccount, HDCoinWithdrawOps, TrezorCoinError}; use crate::lp_price::get_base_price_in_rel; use crate::rpc_command::init_withdraw::WithdrawTaskHandleShared; -use crate::utxo::rpc_clients::{electrum_script_hash, BlockHashOrHeight, UnspentInfo, UnspentMap, UtxoRpcClientEnum, - UtxoRpcClientOps, UtxoRpcResult}; +use crate::utxo::rpc_clients::{ + electrum_script_hash, BlockHashOrHeight, UnspentInfo, UnspentMap, UtxoRpcClientEnum, UtxoRpcClientOps, + UtxoRpcResult, +}; use crate::utxo::spv::SimplePaymentVerification; use crate::utxo::tx_cache::TxCacheResult; use crate::utxo::utxo_hd_wallet::UtxoHDAddress; use crate::utxo::utxo_withdraw::{InitUtxoWithdraw, StandardUtxoWithdraw, UtxoWithdraw}; use crate::watcher_common::validate_watcher_reward; -use crate::{scan_for_new_addresses_impl, CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, ConfirmPaymentInput, - DexFee, DexFeeBurnDestination, GenPreimageResult, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, - GetWithdrawSenderAddress, RawTransactionError, RawTransactionRequest, RawTransactionRes, - RawTransactionResult, RefundFundingSecretArgs, RefundMakerPaymentSecretArgs, RefundPaymentArgs, - RewardTarget, SearchForSwapTxSpendInput, SendMakerPaymentArgs, SendMakerPaymentSpendPreimageInput, - SendPaymentArgs, SendTakerFundingArgs, SignRawTransactionEnum, SignRawTransactionRequest, - SignUtxoTransactionParams, SignatureError, SignatureResult, SpendMakerPaymentArgs, SpendPaymentArgs, - SwapOps, SwapTxTypeWithSecretHash, TradePreimageValue, TransactionData, TransactionFut, TransactionResult, - TxFeeDetails, TxGenError, TxMarshalingErr, TxPreimageWithSig, ValidateAddressResult, - ValidateOtherPubKeyErr, ValidatePaymentFut, ValidatePaymentInput, ValidateSwapV2TxError, - ValidateSwapV2TxResult, ValidateTakerFundingArgs, ValidateTakerFundingSpendPreimageError, - ValidateTakerFundingSpendPreimageResult, ValidateTakerPaymentSpendPreimageError, - ValidateTakerPaymentSpendPreimageResult, ValidateWatcherSpendInput, VerificationError, VerificationResult, - WatcherSearchForSwapTxSpendInput, WatcherValidatePaymentInput, WatcherValidateTakerFeeInput, - WithdrawResult, WithdrawSenderAddress, EARLY_CONFIRMATION_ERR_LOG, INVALID_RECEIVER_ERR_LOG, - INVALID_REFUND_TX_ERR_LOG, INVALID_SCRIPT_ERR_LOG, INVALID_SENDER_ERR_LOG, OLD_TRANSACTION_ERR_LOG}; +use crate::{ + scan_for_new_addresses_impl, CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, ConfirmPaymentInput, DexFee, + DexFeeBurnDestination, GenPreimageResult, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, + GetWithdrawSenderAddress, RawTransactionError, RawTransactionRequest, RawTransactionRes, RawTransactionResult, + RefundFundingSecretArgs, RefundMakerPaymentSecretArgs, RefundPaymentArgs, RewardTarget, SearchForSwapTxSpendInput, + SendMakerPaymentArgs, SendMakerPaymentSpendPreimageInput, SendPaymentArgs, SendTakerFundingArgs, + SignRawTransactionEnum, SignRawTransactionRequest, SignUtxoTransactionParams, SignatureError, SignatureResult, + SpendMakerPaymentArgs, SpendPaymentArgs, SwapOps, SwapTxTypeWithSecretHash, TradePreimageValue, TransactionData, + TransactionFut, TransactionResult, TxFeeDetails, TxGenError, TxMarshalingErr, TxPreimageWithSig, + ValidateAddressResult, ValidateOtherPubKeyErr, ValidatePaymentFut, ValidatePaymentInput, ValidateSwapV2TxError, + ValidateSwapV2TxResult, ValidateTakerFundingArgs, ValidateTakerFundingSpendPreimageError, + ValidateTakerFundingSpendPreimageResult, ValidateTakerPaymentSpendPreimageError, + ValidateTakerPaymentSpendPreimageResult, ValidateWatcherSpendInput, VerificationError, VerificationResult, + WatcherSearchForSwapTxSpendInput, WatcherValidatePaymentInput, WatcherValidateTakerFeeInput, WithdrawResult, + WithdrawSenderAddress, EARLY_CONFIRMATION_ERR_LOG, INVALID_RECEIVER_ERR_LOG, INVALID_REFUND_TX_ERR_LOG, + INVALID_SCRIPT_ERR_LOG, INVALID_SENDER_ERR_LOG, OLD_TRANSACTION_ERR_LOG, +}; use crate::{MmCoinEnum, WatcherReward, WatcherRewardError}; use base64::engine::general_purpose::STANDARD; use base64::Engine; @@ -44,21 +47,27 @@ use futures::future::{FutureExt, TryFutureExt}; use futures01::future::Either; use itertools::Itertools; use keys::bytes::Bytes; -#[cfg(test)] use keys::prefixes::{KMD_PREFIXES, T_QTUM_PREFIXES}; -use keys::{Address, AddressBuilder, AddressBuilderOption, AddressFormat as UtxoAddressFormat, AddressFormat, - AddressHashEnum, AddressScriptType, CompactSignature, Public, SegwitAddress}; +#[cfg(test)] +use keys::prefixes::{KMD_PREFIXES, T_QTUM_PREFIXES}; +use keys::{ + Address, AddressBuilder, AddressBuilderOption, AddressFormat as UtxoAddressFormat, AddressFormat, AddressHashEnum, + AddressScriptType, CompactSignature, Public, SegwitAddress, +}; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; use mm2_number::bigdecimal_custom::CheckedDivision; use mm2_number::{BigDecimal, MmNumber}; use primitives::hash::H512; use rpc::v1::types::{Bytes as BytesJson, ToTxHash, TransactionInputEnum, H256 as H256Json}; -#[cfg(test)] use rpc_clients::NativeClientImpl; +#[cfg(test)] +use rpc_clients::NativeClientImpl; use script::{Builder, Opcode, Script, ScriptAddress, TransactionInputSigner, UnsignedTransactionInput}; use secp256k1::{PublicKey, Signature as SecpSignature}; use serde_json::{self as json}; -use serialization::{deserialize, serialize, serialize_with_flags, CoinVariant, CompactInteger, Serializable, Stream, - SERIALIZE_TRANSACTION_WITNESS}; +use serialization::{ + deserialize, serialize, serialize_with_flags, CoinVariant, CompactInteger, Serializable, Stream, + SERIALIZE_TRANSACTION_WITNESS, +}; use std::cmp::Ordering; use std::collections::hash_map::{Entry, HashMap}; use std::convert::TryFrom; @@ -66,8 +75,9 @@ use std::str::FromStr; use std::sync::atomic::Ordering as AtomicOrdering; #[cfg(test)] use utxo_common_tests::{utxo_coin_fields_for_test, utxo_coin_from_fields}; -use utxo_signer::with_key_pair::{calc_and_sign_sighash, p2sh_spend, signature_hash_to_sign, SIGHASH_ALL, - SIGHASH_SINGLE}; +use utxo_signer::with_key_pair::{ + calc_and_sign_sighash, p2sh_spend, signature_hash_to_sign, SIGHASH_ALL, SIGHASH_SINGLE, +}; use utxo_signer::UtxoSignerOps; pub mod utxo_tx_history_v2_common; @@ -294,7 +304,9 @@ where } } -pub fn derivation_method(coin: &UtxoCoinFields) -> &DerivationMethod { &coin.derivation_method } +pub fn derivation_method(coin: &UtxoCoinFields) -> &DerivationMethod { + &coin.derivation_method +} /// returns the tx fee required to be paid for HTLC spend transaction pub async fn get_htlc_spend_fee( @@ -663,11 +675,14 @@ impl<'a, T: AsRef + UtxoTxGenerationOps> UtxoTxBuilder<'a, T> { let tx_fee = self.total_tx_fee_needed(); let min_output = tx_fee + self.dust(); let val = self.tx.outputs[i].value; - return_err_if!(val < min_output, GenerateTxError::DeductFeeFromOutputFailed { - output_idx: i, - output_value: val, - required: min_output, - }); + return_err_if!( + val < min_output, + GenerateTxError::DeductFeeFromOutputFailed { + output_idx: i, + output_value: val, + required: min_output, + } + ); self.tx.outputs[i].value -= tx_fee; Ok(tx_fee) }, @@ -678,10 +693,13 @@ impl<'a, T: AsRef + UtxoTxGenerationOps> UtxoTxBuilder<'a, T> { for output in self.outputs.iter() { let script: Script = output.script_pubkey.clone().into(); if script.opcodes().next() != Some(Ok(Opcode::OP_RETURN)) { - return_err_if!(output.value < self.dust(), GenerateTxError::OutputValueLessThanDust { - value: output.value, - dust: self.dust() - }); + return_err_if!( + output.value < self.dust(), + GenerateTxError::OutputValueLessThanDust { + value: output.value, + dust: self.dust() + } + ); } } Ok(()) @@ -704,7 +722,9 @@ impl<'a, T: AsRef + UtxoTxGenerationOps> UtxoTxBuilder<'a, T> { } } - fn total_tx_fee_needed(&self) -> u64 { self.tx_fee_needed + self.gas_fee.unwrap_or(0u64) } + fn total_tx_fee_needed(&self) -> u64 { + self.tx_fee_needed + self.gas_fee.unwrap_or(0u64) + } fn tx_fee_fact(&self) -> MmResult { (self.sum_inputs + self.interest) @@ -755,10 +775,13 @@ impl<'a, T: AsRef + UtxoTxGenerationOps> UtxoTxBuilder<'a, T> { self.update_tx_fee(from.addr_format(), &actual_fee_rate); one_time_fee_update = true; } - return_err_if!(self.sum_inputs < required_amount_0, GenerateTxError::NotEnoughUtxos { - sum_utxos: self.sum_inputs, - required: self.required_amount(), // send updated required amount, with txfee - }); + return_err_if!( + self.sum_inputs < required_amount_0, + GenerateTxError::NotEnoughUtxos { + sum_utxos: self.sum_inputs, + required: self.required_amount(), // send updated required amount, with txfee + } + ); self.sum_outputs = self .sum_outputs @@ -864,7 +887,9 @@ pub async fn calc_interest_if_required( Ok(interest) } -pub fn is_kmd(coin: &T) -> bool { &coin.as_ref().conf.ticker == "KMD" } +pub fn is_kmd(coin: &T) -> bool { + &coin.as_ref().conf.ticker == "KMD" +} /// Helper to get min relay fee rate and convert to sat async fn get_min_relay_rate + UtxoTxGenerationOps>(coin: &T) -> UtxoRpcResult> { @@ -3301,9 +3326,13 @@ pub fn min_trading_vol(coin: &UtxoCoinFields) -> MmNumber { dust_multiplier * min_tx_amount(coin).into() } -pub fn is_asset_chain(coin: &UtxoCoinFields) -> bool { coin.conf.asset_chain } +pub fn is_asset_chain(coin: &UtxoCoinFields) -> bool { + coin.conf.asset_chain +} -pub const fn should_burn_dex_fee() -> bool { false } // TODO: fix back to true when negotiation version added +pub const fn should_burn_dex_fee() -> bool { + false +} // TODO: fix back to true when negotiation version added pub async fn get_raw_transaction(coin: &UtxoCoinFields, req: RawTransactionRequest) -> RawTransactionResult { let hash = H256Json::from_str(&req.tx_hash).map_to_mm(|e| RawTransactionError::InvalidHashError(e.to_string()))?; @@ -3396,7 +3425,9 @@ pub fn get_withdraw_iguana_sender( }) } -pub fn decimals(coin: &UtxoCoinFields) -> u8 { coin.decimals } +pub fn decimals(coin: &UtxoCoinFields) -> u8 { + coin.decimals +} pub fn convert_to_address(coin: &T, from: &str, to_address_format: Json) -> Result { let to_address_format: UtxoAddressFormat = @@ -3881,10 +3912,13 @@ pub async fn tx_details_by_hash( tx.tx_hash_algo = coin.as_ref().tx_hash_algo; let my_address = try_s!(coin.as_ref().derivation_method.single_addr_or_err().await); - input_transactions.insert(*hash, HistoryUtxoTx { - tx: tx.clone(), - height: verbose_tx.height, - }); + input_transactions.insert( + *hash, + HistoryUtxoTx { + tx: tx.clone(), + height: verbose_tx.height, + }, + ); let mut input_amount = 0; let mut output_amount = 0; @@ -4406,7 +4440,9 @@ where T: UtxoCommonOps, { /// Returns `true` if the given transaction has a known non-zero height. - fn can_tx_be_cached(tx: &RpcTransaction) -> bool { tx.height > Some(0) } + fn can_tx_be_cached(tx: &RpcTransaction) -> bool { + tx.height > Some(0) + } /// Calculates actual confirmations number of the given `tx` transaction loaded from cache. #[allow(clippy::result_large_err)] @@ -4557,11 +4593,15 @@ pub async fn get_verbose_transactions_from_cache_or_rpc( /// Swap contract address is not used by standard UTXO coins. #[inline] -pub fn swap_contract_address() -> Option { None } +pub fn swap_contract_address() -> Option { + None +} /// Fallback swap contract address is not used by standard UTXO coins. #[inline] -pub fn fallback_swap_contract() -> Option { None } +pub fn fallback_swap_contract() -> Option { + None +} /// Convert satoshis to BigDecimal amount of coin units #[inline] diff --git a/mm2src/coins/utxo/utxo_common/utxo_tx_history_v2_common.rs b/mm2src/coins/utxo/utxo_common/utxo_tx_history_v2_common.rs index c677e5f513..7a9836b54d 100644 --- a/mm2src/coins/utxo/utxo_common/utxo_tx_history_v2_common.rs +++ b/mm2src/coins/utxo/utxo_common/utxo_tx_history_v2_common.rs @@ -1,15 +1,18 @@ use crate::coin_balance::CoinBalanceReportOps; use crate::hd_wallet::{DisplayAddress, HDAccountOps, HDAddressOps, HDCoinAddress, HDWalletCoinOps, HDWalletOps}; -use crate::my_tx_history_v2::{CoinWithTxHistoryV2, MyTxHistoryErrorV2, MyTxHistoryTarget, TxDetailsBuilder, - TxHistoryStorage}; +use crate::my_tx_history_v2::{ + CoinWithTxHistoryV2, MyTxHistoryErrorV2, MyTxHistoryTarget, TxDetailsBuilder, TxHistoryStorage, +}; use crate::tx_history_storage::{GetTxHistoryFilters, WalletId}; use crate::utxo::rpc_clients::{electrum_script_hash, ElectrumClient, NativeClient, UtxoRpcClientEnum}; use crate::utxo::utxo_common::{big_decimal_from_sat, HISTORY_TOO_LARGE_ERROR}; use crate::utxo::utxo_tx_history_v2::{UtxoTxDetailsError, UtxoTxDetailsParams, UtxoTxHistoryOps}; use crate::utxo::{output_script, RequestTxHistoryResult, UtxoCoinFields, UtxoCommonOps}; -use crate::{big_decimal_from_sat_unsigned, compare_transactions, BalanceResult, CoinWithDerivationMethod, - DerivationMethod, HDPathAccountToAddressId, MarketCoinOps, NumConversError, TransactionDetails, - TxFeeDetails, TxIdHeight, UtxoFeeDetails, UtxoTx}; +use crate::{ + big_decimal_from_sat_unsigned, compare_transactions, BalanceResult, CoinWithDerivationMethod, DerivationMethod, + HDPathAccountToAddressId, MarketCoinOps, NumConversError, TransactionDetails, TxFeeDetails, TxIdHeight, + UtxoFeeDetails, UtxoTx, +}; use common::jsonrpc_client::JsonRpcErrorType; use crypto::Bip44Chain; use futures::compat::Future01CompatExt; @@ -25,7 +28,9 @@ use std::convert::{TryFrom, TryInto}; use std::num::TryFromIntError; /// [`CoinWithTxHistoryV2::history_wallet_id`] implementation. -pub fn history_wallet_id(coin: &UtxoCoinFields) -> WalletId { WalletId::new(coin.conf.ticker.clone()) } +pub fn history_wallet_id(coin: &UtxoCoinFields) -> WalletId { + WalletId::new(coin.conf.ticker.clone()) +} /// [`CoinWithTxHistoryV2::get_tx_history_filters`] implementation. /// Returns `GetTxHistoryFilters` according to the derivation method. diff --git a/mm2src/coins/utxo/utxo_common_tests.rs b/mm2src/coins/utxo/utxo_common_tests.rs index 4203f4d8ba..0eeed36194 100644 --- a/mm2src/coins/utxo/utxo_common_tests.rs +++ b/mm2src/coins/utxo/utxo_common_tests.rs @@ -1,7 +1,9 @@ use super::*; use crate::hd_wallet::{HDAccountsMap, HDAccountsMutex, HDAddressesCache, HDWallet, HDWalletCoinStorage}; -use crate::my_tx_history_v2::{my_tx_history_v2_impl, CoinWithTxHistoryV2, MyTxHistoryDetails, MyTxHistoryRequestV2, - MyTxHistoryResponseV2, MyTxHistoryTarget}; +use crate::my_tx_history_v2::{ + my_tx_history_v2_impl, CoinWithTxHistoryV2, MyTxHistoryDetails, MyTxHistoryRequestV2, MyTxHistoryResponseV2, + MyTxHistoryTarget, +}; use crate::tx_history_storage::TxHistoryStorageBuilder; use crate::utxo::rpc_clients::{ElectrumClient, UtxoRpcClientOps}; use crate::utxo::tx_cache::dummy_tx_cache::DummyVerboseCache; @@ -35,7 +37,9 @@ lazy_static! { static ref DOC_HD_TX_HISTORY_MAP: HashMap = parse_tx_history_map(DOC_HD_TX_HISTORY_STR); } -fn parse_tx_history(history_str: &'static str) -> Vec { json::from_str(history_str).unwrap() } +fn parse_tx_history(history_str: &'static str) -> Vec { + json::from_str(history_str).unwrap() +} fn parse_tx_history_map(history_str: &'static str) -> HashMap { parse_tx_history(history_str) diff --git a/mm2src/coins/utxo/utxo_hd_wallet.rs b/mm2src/coins/utxo/utxo_hd_wallet.rs index 93a9cad110..ec5f57a070 100644 --- a/mm2src/coins/utxo/utxo_hd_wallet.rs +++ b/mm2src/coins/utxo/utxo_hd_wallet.rs @@ -1,6 +1,7 @@ -use crate::hd_wallet::{DisplayAddress, HDAccount, HDAccountMut, HDAccountOps, HDAccountsMap, HDAccountsMut, - HDAccountsMutex, HDAddress, HDWallet, HDWalletCoinStorage, HDWalletOps, HDWalletStorageOps, - WithdrawSenderAddress}; +use crate::hd_wallet::{ + DisplayAddress, HDAccount, HDAccountMut, HDAccountOps, HDAccountsMap, HDAccountsMut, HDAccountsMutex, HDAddress, + HDWallet, HDWalletCoinStorage, HDWalletOps, HDWalletStorageOps, WithdrawSenderAddress, +}; use async_trait::async_trait; use crypto::{Bip44Chain, HDPathToCoin, Secp256k1ExtendedPublicKey}; use keys::{Address, AddressFormat as UtxoAddressFormat, CashAddress, Public}; @@ -19,34 +20,54 @@ pub struct UtxoHDWallet { #[async_trait] impl HDWalletStorageOps for UtxoHDWallet { - fn hd_wallet_storage(&self) -> &HDWalletCoinStorage { self.inner.hd_wallet_storage() } + fn hd_wallet_storage(&self) -> &HDWalletCoinStorage { + self.inner.hd_wallet_storage() + } } #[async_trait] impl HDWalletOps for UtxoHDWallet { type HDAccount = UtxoHDAccount; - fn coin_type(&self) -> u32 { self.inner.coin_type() } + fn coin_type(&self) -> u32 { + self.inner.coin_type() + } - fn derivation_path(&self) -> &HDPathToCoin { self.inner.derivation_path() } + fn derivation_path(&self) -> &HDPathToCoin { + self.inner.derivation_path() + } - fn gap_limit(&self) -> u32 { self.inner.gap_limit() } + fn gap_limit(&self) -> u32 { + self.inner.gap_limit() + } - fn account_limit(&self) -> u32 { self.inner.account_limit() } + fn account_limit(&self) -> u32 { + self.inner.account_limit() + } - fn default_receiver_chain(&self) -> Bip44Chain { self.inner.default_receiver_chain() } + fn default_receiver_chain(&self) -> Bip44Chain { + self.inner.default_receiver_chain() + } - fn get_accounts_mutex(&self) -> &HDAccountsMutex { self.inner.get_accounts_mutex() } + fn get_accounts_mutex(&self) -> &HDAccountsMutex { + self.inner.get_accounts_mutex() + } - async fn get_account(&self, account_id: u32) -> Option { self.inner.get_account(account_id).await } + async fn get_account(&self, account_id: u32) -> Option { + self.inner.get_account(account_id).await + } async fn get_account_mut(&self, account_id: u32) -> Option> { self.inner.get_account_mut(account_id).await } - async fn get_accounts(&self) -> HDAccountsMap { self.inner.get_accounts().await } + async fn get_accounts(&self) -> HDAccountsMap { + self.inner.get_accounts().await + } - async fn get_accounts_mut(&self) -> HDAccountsMut<'_, Self::HDAccount> { self.inner.get_accounts_mut().await } + async fn get_accounts_mut(&self) -> HDAccountsMut<'_, Self::HDAccount> { + self.inner.get_accounts_mut().await + } async fn remove_account_if_last(&self, account_id: u32) -> Option { self.inner.remove_account_if_last(account_id).await @@ -58,9 +79,13 @@ impl HDWalletOps for UtxoHDWallet { } impl DisplayAddress for Address { - fn display_address(&self) -> String { self.to_string() } + fn display_address(&self) -> String { + self.to_string() + } } impl DisplayAddress for CashAddress { - fn display_address(&self) -> String { self.encode().expect("A valid cash address") } + fn display_address(&self) -> String { + self.encode().expect("A valid cash address") + } } diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index 073b1b75f2..3086a129d3 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -1,49 +1,58 @@ use super::utxo_common::utxo_prepare_addresses_for_balance_stream_if_enabled; use super::*; -use crate::coin_balance::{self, EnableCoinBalanceError, EnabledCoinBalanceParams, HDAccountBalance, HDAddressBalance, - HDWalletBalance, HDWalletBalanceOps}; +use crate::coin_balance::{ + self, EnableCoinBalanceError, EnabledCoinBalanceParams, HDAccountBalance, HDAddressBalance, HDWalletBalance, + HDWalletBalanceOps, +}; use crate::coin_errors::{AddressFromPubkeyError, MyAddressError, ValidatePaymentResult}; -use crate::hd_wallet::{ExtractExtendedPubkey, HDAddressSelector, HDCoinAddress, HDCoinWithdrawOps, HDConfirmAddress, - HDExtractPubkeyError, HDXPubExtractor, SettingEnabledAddressError, TrezorCoinError, - WithdrawSenderAddress}; +use crate::hd_wallet::{ + ExtractExtendedPubkey, HDAddressSelector, HDCoinAddress, HDCoinWithdrawOps, HDConfirmAddress, HDExtractPubkeyError, + HDXPubExtractor, SettingEnabledAddressError, TrezorCoinError, WithdrawSenderAddress, +}; use crate::my_tx_history_v2::{CoinWithTxHistoryV2, MyTxHistoryErrorV2, MyTxHistoryTarget, TxHistoryStorage}; use crate::rpc_command::account_balance::{self, AccountBalanceParams, AccountBalanceRpcOps, HDAccountBalanceResponse}; -use crate::rpc_command::get_new_address::{self, GetNewAddressParams, GetNewAddressResponse, GetNewAddressRpcError, - GetNewAddressRpcOps}; +use crate::rpc_command::get_new_address::{ + self, GetNewAddressParams, GetNewAddressResponse, GetNewAddressRpcError, GetNewAddressRpcOps, +}; use crate::rpc_command::hd_account_balance_rpc_error::HDAccountBalanceRpcError; use crate::rpc_command::init_account_balance::{self, InitAccountBalanceParams, InitAccountBalanceRpcOps}; -use crate::rpc_command::init_create_account::{self, CreateAccountRpcError, CreateAccountState, CreateNewAccountParams, - InitCreateAccountRpcOps}; -use crate::rpc_command::init_scan_for_new_addresses::{self, InitScanAddressesRpcOps, ScanAddressesParams, - ScanAddressesResponse}; +use crate::rpc_command::init_create_account::{ + self, CreateAccountRpcError, CreateAccountState, CreateNewAccountParams, InitCreateAccountRpcOps, +}; +use crate::rpc_command::init_scan_for_new_addresses::{ + self, InitScanAddressesRpcOps, ScanAddressesParams, ScanAddressesResponse, +}; use crate::rpc_command::init_withdraw::{InitWithdrawCoin, WithdrawTaskHandleShared}; use crate::tx_history_storage::{GetTxHistoryFilters, WalletId}; use crate::utxo::rpc_clients::BlockHashOrHeight; use crate::utxo::utxo_builder::{UtxoArcBuilder, UtxoCoinBuilder}; use crate::utxo::utxo_hd_wallet::{UtxoHDAccount, UtxoHDAddress}; -use crate::utxo::utxo_tx_history_v2::{UtxoMyAddressesHistoryError, UtxoTxDetailsError, UtxoTxDetailsParams, - UtxoTxHistoryOps}; -use crate::{CanRefundHtlc, CheckIfMyPaymentSentArgs, CoinBalance, CoinBalanceMap, CoinWithDerivationMethod, - CoinWithPrivKeyPolicy, CommonSwapOpsV2, ConfirmPaymentInput, DexFee, FindPaymentSpendError, - FundingTxSpend, GenPreimageResult, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, - GetWithdrawSenderAddress, IguanaBalanceOps, IguanaPrivKey, MakerCoinSwapOpsV2, MmCoinEnum, - NegotiateSwapContractAddrErr, PrivKeyBuildPolicy, RawTransactionRequest, RawTransactionResult, - RefundFundingSecretArgs, RefundMakerPaymentSecretArgs, RefundMakerPaymentTimelockArgs, RefundPaymentArgs, - RefundTakerPaymentArgs, SearchForFundingSpendErr, SearchForSwapTxSpendInput, SendMakerPaymentArgs, - SendMakerPaymentSpendPreimageInput, SendPaymentArgs, SendTakerFundingArgs, SignRawTransactionRequest, - SignatureResult, SpendMakerPaymentArgs, SpendPaymentArgs, SwapOps, SwapTxTypeWithSecretHash, - TakerCoinSwapOpsV2, ToBytes, TradePreimageValue, TransactionFut, TransactionResult, TxMarshalingErr, - TxPreimageWithSig, ValidateAddressResult, ValidateFeeArgs, ValidateMakerPaymentArgs, - ValidateOtherPubKeyErr, ValidatePaymentError, ValidatePaymentFut, ValidatePaymentInput, - ValidateSwapV2TxResult, ValidateTakerFundingArgs, ValidateTakerFundingSpendPreimageResult, - ValidateTakerPaymentSpendPreimageResult, ValidateWatcherSpendInput, VerificationResult, - WaitForHTLCTxSpendArgs, WatcherOps, WatcherReward, WatcherRewardError, WatcherSearchForSwapTxSpendInput, - WatcherValidatePaymentInput, WatcherValidateTakerFeeInput, WithdrawFut}; +use crate::utxo::utxo_tx_history_v2::{ + UtxoMyAddressesHistoryError, UtxoTxDetailsError, UtxoTxDetailsParams, UtxoTxHistoryOps, +}; +use crate::{ + CanRefundHtlc, CheckIfMyPaymentSentArgs, CoinBalance, CoinBalanceMap, CoinWithDerivationMethod, + CoinWithPrivKeyPolicy, CommonSwapOpsV2, ConfirmPaymentInput, DexFee, FindPaymentSpendError, FundingTxSpend, + GenPreimageResult, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, GetWithdrawSenderAddress, IguanaBalanceOps, + IguanaPrivKey, MakerCoinSwapOpsV2, MmCoinEnum, NegotiateSwapContractAddrErr, PrivKeyBuildPolicy, + RawTransactionRequest, RawTransactionResult, RefundFundingSecretArgs, RefundMakerPaymentSecretArgs, + RefundMakerPaymentTimelockArgs, RefundPaymentArgs, RefundTakerPaymentArgs, SearchForFundingSpendErr, + SearchForSwapTxSpendInput, SendMakerPaymentArgs, SendMakerPaymentSpendPreimageInput, SendPaymentArgs, + SendTakerFundingArgs, SignRawTransactionRequest, SignatureResult, SpendMakerPaymentArgs, SpendPaymentArgs, SwapOps, + SwapTxTypeWithSecretHash, TakerCoinSwapOpsV2, ToBytes, TradePreimageValue, TransactionFut, TransactionResult, + TxMarshalingErr, TxPreimageWithSig, ValidateAddressResult, ValidateFeeArgs, ValidateMakerPaymentArgs, + ValidateOtherPubKeyErr, ValidatePaymentError, ValidatePaymentFut, ValidatePaymentInput, ValidateSwapV2TxResult, + ValidateTakerFundingArgs, ValidateTakerFundingSpendPreimageResult, ValidateTakerPaymentSpendPreimageResult, + ValidateWatcherSpendInput, VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, WatcherReward, + WatcherRewardError, WatcherSearchForSwapTxSpendInput, WatcherValidatePaymentInput, WatcherValidateTakerFeeInput, + WithdrawFut, +}; use common::executor::{AbortableSystem, AbortedError}; use futures::{FutureExt, TryFutureExt}; use mm2_metrics::MetricsArc; use mm2_number::MmNumber; -#[cfg(test)] use mocktopus::macros::*; +#[cfg(test)] +use mocktopus::macros::*; use rpc::v1::types::H264 as H264Json; use script::Opcode; use utxo_signer::UtxoSignerOps; @@ -54,15 +63,21 @@ pub struct UtxoStandardCoin { } impl AsRef for UtxoStandardCoin { - fn as_ref(&self) -> &UtxoCoinFields { &self.utxo_arc } + fn as_ref(&self) -> &UtxoCoinFields { + &self.utxo_arc + } } impl From for UtxoStandardCoin { - fn from(coin: UtxoArc) -> UtxoStandardCoin { UtxoStandardCoin { utxo_arc: coin } } + fn from(coin: UtxoArc) -> UtxoStandardCoin { + UtxoStandardCoin { utxo_arc: coin } + } } impl From for UtxoArc { - fn from(coin: UtxoStandardCoin) -> Self { coin.utxo_arc } + fn from(coin: UtxoStandardCoin) -> Self { + coin.utxo_arc + } } pub async fn utxo_standard_coin_with_policy( @@ -112,13 +127,17 @@ impl UtxoTxBroadcastOps for UtxoStandardCoin { #[async_trait] #[cfg_attr(test, mockable)] impl UtxoTxGenerationOps for UtxoStandardCoin { - async fn get_fee_rate(&self) -> UtxoRpcResult { utxo_common::get_fee_rate(&self.utxo_arc).await } + async fn get_fee_rate(&self) -> UtxoRpcResult { + utxo_common::get_fee_rate(&self.utxo_arc).await + } async fn calc_interest_if_required(&self, unsigned: &mut TransactionInputSigner) -> UtxoRpcResult { utxo_common::calc_interest_if_required(self, unsigned).await } - fn supports_interest(&self) -> bool { utxo_common::is_kmd(self) } + fn supports_interest(&self) -> bool { + utxo_common::is_kmd(self) + } } #[async_trait] @@ -183,7 +202,9 @@ impl UtxoCommonOps for UtxoStandardCoin { utxo_common::addresses_from_script(self, script) } - fn denominate_satoshis(&self, satoshi: i64) -> f64 { utxo_common::denominate_satoshis(&self.utxo_arc, satoshi) } + fn denominate_satoshis(&self, satoshi: i64) -> f64 { + utxo_common::denominate_satoshis(&self.utxo_arc, satoshi) + } fn my_public_key(&self) -> Result<&Public, MmError> { utxo_common::my_public_key(self.as_ref()) @@ -256,7 +277,9 @@ impl UtxoCommonOps for UtxoStandardCoin { utxo_common::p2sh_tx_locktime(self, &self.utxo_arc.conf.ticker, htlc_locktime).await } - fn addr_format(&self) -> &UtxoAddressFormat { utxo_common::addr_format(self) } + fn addr_format(&self) -> &UtxoAddressFormat { + utxo_common::addr_format(self) + } fn addr_format_for_standard_scripts(&self) -> UtxoAddressFormat { utxo_common::addr_format_for_standard_scripts(self) @@ -451,7 +474,9 @@ impl SwapOps for UtxoStandardCoin { utxo_common::validate_other_pubkey(raw_pubkey) } - fn is_supported_by_watchers(&self) -> bool { true } + fn is_supported_by_watchers(&self) -> bool { + true + } } #[async_trait] @@ -558,7 +583,9 @@ impl WatcherOps for UtxoStandardCoin { } impl ToBytes for Public { - fn to_bytes(&self) -> Vec { self.to_vec() } + fn to_bytes(&self) -> Vec { + self.to_vec() + } } #[async_trait] @@ -842,14 +869,18 @@ impl CommonSwapOpsV2 for UtxoStandardCoin { #[async_trait] impl MarketCoinOps for UtxoStandardCoin { - fn ticker(&self) -> &str { &self.utxo_arc.conf.ticker } + fn ticker(&self) -> &str { + &self.utxo_arc.conf.ticker + } async fn get_public_key(&self) -> Result> { let pubkey = utxo_common::my_public_key(&self.utxo_arc)?; Ok(pubkey.to_string()) } - fn my_address(&self) -> MmResult { utxo_common::my_address(self) } + fn my_address(&self) -> MmResult { + utxo_common::my_address(self) + } fn address_from_pubkey(&self, pubkey: &H264Json) -> MmResult { let pubkey = Public::Compressed((*pubkey).into()); @@ -868,11 +899,17 @@ impl MarketCoinOps for UtxoStandardCoin { utxo_common::verify_message(self, signature_base64, message, address) } - fn my_balance(&self) -> BalanceFut { utxo_common::my_balance(self.clone()) } + fn my_balance(&self) -> BalanceFut { + utxo_common::my_balance(self.clone()) + } - fn base_coin_balance(&self) -> BalanceFut { utxo_common::base_coin_balance(self) } + fn base_coin_balance(&self) -> BalanceFut { + utxo_common::base_coin_balance(self) + } - fn platform_ticker(&self) -> &str { self.ticker() } + fn platform_ticker(&self) -> &str { + self.ticker() + } #[inline(always)] fn send_raw_tx(&self, tx: &str) -> Box + Send> { @@ -913,24 +950,40 @@ impl MarketCoinOps for UtxoStandardCoin { utxo_common::current_block(&self.utxo_arc) } - fn display_priv_key(&self) -> Result { utxo_common::display_priv_key(&self.utxo_arc) } + fn display_priv_key(&self) -> Result { + utxo_common::display_priv_key(&self.utxo_arc) + } - fn min_tx_amount(&self) -> BigDecimal { utxo_common::min_tx_amount(self.as_ref()) } + fn min_tx_amount(&self) -> BigDecimal { + utxo_common::min_tx_amount(self.as_ref()) + } - fn min_trading_vol(&self) -> MmNumber { utxo_common::min_trading_vol(self.as_ref()) } + fn min_trading_vol(&self) -> MmNumber { + utxo_common::min_trading_vol(self.as_ref()) + } - fn should_burn_directly(&self) -> bool { &self.utxo_arc.conf.ticker == "KMD" } + fn should_burn_directly(&self) -> bool { + &self.utxo_arc.conf.ticker == "KMD" + } - fn should_burn_dex_fee(&self) -> bool { utxo_common::should_burn_dex_fee() } + fn should_burn_dex_fee(&self) -> bool { + utxo_common::should_burn_dex_fee() + } - fn is_trezor(&self) -> bool { self.as_ref().priv_key_policy.is_trezor() } + fn is_trezor(&self) -> bool { + self.as_ref().priv_key_policy.is_trezor() + } } #[async_trait] impl MmCoin for UtxoStandardCoin { - fn is_asset_chain(&self) -> bool { utxo_common::is_asset_chain(&self.utxo_arc) } + fn is_asset_chain(&self) -> bool { + utxo_common::is_asset_chain(&self.utxo_arc) + } - fn spawner(&self) -> WeakSpawner { self.as_ref().abortable_system.weak_spawner() } + fn spawner(&self) -> WeakSpawner { + self.as_ref().abortable_system.weak_spawner() + } fn get_raw_transaction(&self, req: RawTransactionRequest) -> RawTransactionFut { Box::new(utxo_common::get_raw_transaction(&self.utxo_arc, req).boxed().compat()) @@ -948,13 +1001,17 @@ impl MmCoin for UtxoStandardCoin { Box::new(utxo_common::withdraw(self.clone(), req).boxed().compat()) } - fn decimals(&self) -> u8 { utxo_common::decimals(&self.utxo_arc) } + fn decimals(&self) -> u8 { + utxo_common::decimals(&self.utxo_arc) + } fn convert_to_address(&self, from: &str, to_address_format: Json) -> Result { utxo_common::convert_to_address(self, from, to_address_format) } - fn validate_address(&self, address: &str) -> ValidateAddressResult { utxo_common::validate_address(self, address) } + fn validate_address(&self, address: &str) -> ValidateAddressResult { + utxo_common::validate_address(self, address) + } fn process_history_loop(&self, ctx: MmArc) -> Box + Send> { Box::new( @@ -965,7 +1022,9 @@ impl MmCoin for UtxoStandardCoin { ) } - fn history_sync_status(&self) -> HistorySyncState { utxo_common::history_sync_status(&self.utxo_arc) } + fn history_sync_status(&self) -> HistorySyncState { + utxo_common::history_sync_status(&self.utxo_arc) + } fn get_trade_fee(&self) -> Box + Send> { utxo_common::get_trade_fee(self.clone()) @@ -992,9 +1051,13 @@ impl MmCoin for UtxoStandardCoin { utxo_common::get_fee_to_send_taker_fee(self, dex_fee_amount, stage).await } - fn required_confirmations(&self) -> u64 { utxo_common::required_confirmations(&self.utxo_arc) } + fn required_confirmations(&self) -> u64 { + utxo_common::required_confirmations(&self.utxo_arc) + } - fn requires_notarization(&self) -> bool { utxo_common::requires_notarization(&self.utxo_arc) } + fn requires_notarization(&self) -> bool { + utxo_common::requires_notarization(&self.utxo_arc) + } fn set_required_confirmations(&self, confirmations: u64) { utxo_common::set_required_confirmations(&self.utxo_arc, confirmations) @@ -1004,11 +1067,17 @@ impl MmCoin for UtxoStandardCoin { utxo_common::set_requires_notarization(&self.utxo_arc, requires_nota) } - fn swap_contract_address(&self) -> Option { utxo_common::swap_contract_address() } + fn swap_contract_address(&self) -> Option { + utxo_common::swap_contract_address() + } - fn fallback_swap_contract(&self) -> Option { utxo_common::fallback_swap_contract() } + fn fallback_swap_contract(&self) -> Option { + utxo_common::fallback_swap_contract() + } - fn mature_confirmations(&self) -> Option { Some(self.utxo_arc.conf.mature_confirmations) } + fn mature_confirmations(&self) -> Option { + Some(self.utxo_arc.conf.mature_confirmations) + } fn coin_protocol_info(&self, _amount_to_receive: Option) -> Vec { utxo_common::coin_protocol_info(self) @@ -1024,7 +1093,9 @@ impl MmCoin for UtxoStandardCoin { utxo_common::is_coin_protocol_supported(self, info) } - fn on_disabled(&self) -> Result<(), AbortedError> { AbortableSystem::abort_all(&self.as_ref().abortable_system) } + fn on_disabled(&self) -> Result<(), AbortedError> { + AbortableSystem::abort_all(&self.as_ref().abortable_system) + } fn on_token_deactivated(&self, _ticker: &str) {} } @@ -1067,17 +1138,25 @@ impl UtxoSignerOps for UtxoStandardCoin { }) } - fn fork_id(&self) -> u32 { self.utxo_arc.conf.fork_id } + fn fork_id(&self) -> u32 { + self.utxo_arc.conf.fork_id + } - fn branch_id(&self) -> u32 { self.utxo_arc.conf.consensus_branch_id } + fn branch_id(&self) -> u32 { + self.utxo_arc.conf.consensus_branch_id + } - fn tx_provider(&self) -> Self::TxGetter { self.utxo_arc.rpc_client.clone() } + fn tx_provider(&self) -> Self::TxGetter { + self.utxo_arc.rpc_client.clone() + } } impl CoinWithPrivKeyPolicy for UtxoStandardCoin { type KeyPair = KeyPair; - fn priv_key_policy(&self) -> &PrivKeyPolicy { &self.utxo_arc.priv_key_policy } + fn priv_key_policy(&self) -> &PrivKeyPolicy { + &self.utxo_arc.priv_key_policy + } } impl CoinWithDerivationMethod for UtxoStandardCoin { @@ -1124,7 +1203,9 @@ impl HDWalletCoinOps for UtxoStandardCoin { utxo_common::address_from_extended_pubkey(self, extended_pubkey, derivation_path) } - fn trezor_coin(&self) -> MmResult { utxo_common::trezor_coin(self) } + fn trezor_coin(&self) -> MmResult { + utxo_common::trezor_coin(self) + } async fn received_enabled_address_from_hw_wallet( &self, @@ -1285,7 +1366,9 @@ impl InitCreateAccountRpcOps for UtxoStandardCoin { #[async_trait] impl CoinWithTxHistoryV2 for UtxoStandardCoin { - fn history_wallet_id(&self) -> WalletId { utxo_common::utxo_tx_history_v2_common::history_wallet_id(self.as_ref()) } + fn history_wallet_id(&self) -> WalletId { + utxo_common::utxo_tx_history_v2_common::history_wallet_id(self.as_ref()) + } async fn get_tx_history_filters( &self, diff --git a/mm2src/coins/utxo/utxo_tests.rs b/mm2src/coins/utxo/utxo_tests.rs index 8a30c42c58..9064fe54b3 100644 --- a/mm2src/coins/utxo/utxo_tests.rs +++ b/mm2src/coins/utxo/utxo_tests.rs @@ -2,21 +2,24 @@ use super::*; use crate::coin_balance::HDAddressBalance; use crate::coin_errors::ValidatePaymentError; -use crate::hd_wallet::{HDAccountsMap, HDAccountsMutex, HDAddressesCache, HDConfirmAddress, HDConfirmAddressError, - HDWallet, HDWalletCoinStorage, HDWalletMockStorage, HDWalletStorageInternalOps, - MockableConfirmAddress}; +use crate::hd_wallet::{ + HDAccountsMap, HDAccountsMutex, HDAddressesCache, HDConfirmAddress, HDConfirmAddressError, HDWallet, + HDWalletCoinStorage, HDWalletMockStorage, HDWalletStorageInternalOps, MockableConfirmAddress, +}; use crate::my_tx_history_v2::for_tests::init_storage_for; use crate::my_tx_history_v2::CoinWithTxHistoryV2; use crate::rpc_command::account_balance::{AccountBalanceParams, AccountBalanceRpcOps, HDAccountBalanceResponse}; use crate::rpc_command::get_new_address::{GetNewAddressParams, GetNewAddressRpcError, GetNewAddressRpcOps}; -use crate::rpc_command::init_scan_for_new_addresses::{InitScanAddressesRpcOps, ScanAddressesParams, - ScanAddressesResponse}; +use crate::rpc_command::init_scan_for_new_addresses::{ + InitScanAddressesRpcOps, ScanAddressesParams, ScanAddressesResponse, +}; use crate::utxo::qtum::{qtum_coin_with_priv_key, QtumCoin, QtumDelegationOps, QtumDelegationRequest}; #[cfg(not(target_arch = "wasm32"))] use crate::utxo::rpc_clients::{BlockHashOrHeight, NativeUnspent}; -use crate::utxo::rpc_clients::{ElectrumBalance, ElectrumBlockHeader, ElectrumClient, ElectrumClientImpl, - GetAddressInfoRes, ListSinceBlockRes, NativeClient, NativeClientImpl, NetworkInfo, - UtxoRpcClientOps, ValidateAddressRes, VerboseBlock}; +use crate::utxo::rpc_clients::{ + ElectrumBalance, ElectrumBlockHeader, ElectrumClient, ElectrumClientImpl, GetAddressInfoRes, ListSinceBlockRes, + NativeClient, NativeClientImpl, NetworkInfo, UtxoRpcClientOps, ValidateAddressRes, VerboseBlock, +}; use crate::utxo::spv::SimplePaymentVerification; #[cfg(not(target_arch = "wasm32"))] use crate::utxo::utxo_block_header_storage::{BlockHeaderStorage, SqliteBlockHeadersStorage}; @@ -28,9 +31,11 @@ use crate::utxo::utxo_common_tests::{self, utxo_coin_fields_for_test, utxo_coin_ use crate::utxo::utxo_hd_wallet::UtxoHDAccount; use crate::utxo::utxo_standard::{utxo_standard_coin_with_priv_key, UtxoStandardCoin}; use crate::utxo::utxo_tx_history_v2::{UtxoTxDetailsParams, UtxoTxHistoryOps}; -use crate::{BlockHeightAndTime, CoinBalance, CoinBalanceMap, ConfirmPaymentInput, DexFee, IguanaPrivKey, - PrivKeyBuildPolicy, SearchForSwapTxSpendInput, SpendPaymentArgs, StakingInfosDetails, SwapOps, - TradePreimageValue, TxFeeDetails, TxMarshalingErr, ValidateFeeArgs, INVALID_SENDER_ERR_LOG}; +use crate::{ + BlockHeightAndTime, CoinBalance, CoinBalanceMap, ConfirmPaymentInput, DexFee, IguanaPrivKey, PrivKeyBuildPolicy, + SearchForSwapTxSpendInput, SpendPaymentArgs, StakingInfosDetails, SwapOps, TradePreimageValue, TxFeeDetails, + TxMarshalingErr, ValidateFeeArgs, INVALID_SENDER_ERR_LOG, +}; #[cfg(not(target_arch = "wasm32"))] use crate::{WaitForHTLCTxSpendArgs, WithdrawFee}; use chain::{BlockHeader, BlockHeaderBits, OutPoint}; @@ -47,15 +52,17 @@ use mm2_core::mm_ctx::MmCtxBuilder; use mm2_number::bigdecimal::{BigDecimal, Signed}; use mm2_number::MmNumber; use mm2_test_helpers::electrums::doc_electrums; -use mm2_test_helpers::for_tests::{electrum_servers_rpc, mm_ctx_with_custom_db, DOC_ELECTRUM_ADDRS, - MARTY_ELECTRUM_ADDRS, T_BCH_ELECTRUMS}; +use mm2_test_helpers::for_tests::{ + electrum_servers_rpc, mm_ctx_with_custom_db, DOC_ELECTRUM_ADDRS, MARTY_ELECTRUM_ADDRS, T_BCH_ELECTRUMS, +}; use mocktopus::mocking::*; use rpc::v1::types::H256 as H256Json; use serialization::{deserialize, CoinVariant, CompactInteger, Reader}; use spv_validation::conf::{BlockHeaderValidationParams, SPVBlockHeader}; use spv_validation::storage::BlockHeaderStorageOps; use spv_validation::work::DifficultyAlgorithm; -#[cfg(not(target_arch = "wasm32"))] use std::convert::TryFrom; +#[cfg(not(target_arch = "wasm32"))] +use std::convert::TryFrom; use std::iter; use std::num::NonZeroUsize; use std::str::FromStr; @@ -93,7 +100,9 @@ pub fn electrum_client_for_test(servers: &[&str]) -> ElectrumClient { /// Returned client won't work by default, requires some mocks to be usable #[cfg(not(target_arch = "wasm32"))] -fn native_client_for_test() -> NativeClient { NativeClient(Arc::new(NativeClientImpl::default())) } +fn native_client_for_test() -> NativeClient { + NativeClient(Arc::new(NativeClientImpl::default())) +} fn utxo_coin_for_test( rpc_client: UtxoRpcClientEnum, @@ -1300,10 +1309,13 @@ fn test_generate_transaction_random_values() { if let Err(ref err) = result { let tx_size_max = est_tx_size(input_vals.len(), output_vals.len() + 1); let tx_fee_max = fee_rate * tx_size_max / 1000; - if matches!(err.get_inner(), GenerateTxError::NotEnoughUtxos { - sum_utxos: _, - required: _ - }) { + if matches!( + err.get_inner(), + GenerateTxError::NotEnoughUtxos { + sum_utxos: _, + required: _ + } + ) { assert!(total_inputs < total_outputs + tx_fee_max); continue; } @@ -4233,15 +4245,18 @@ fn test_account_balance_rpc() { macro_rules! known_address { ($der_path:literal, $address:literal, $chain:expr, balance = $balance:literal) => { addresses_map.insert($address.to_string(), $balance); - balances_by_der_path.insert($der_path.to_string(), HDAddressBalance { - address: $address.to_string(), - derivation_path: RpcDerivationPath(DerivationPath::from_str($der_path).unwrap()), - chain: $chain, - balance: HashMap::from([( - TEST_COIN_NAME.to_string(), - CoinBalance::new(BigDecimal::from($balance)), - )]), - }) + balances_by_der_path.insert( + $der_path.to_string(), + HDAddressBalance { + address: $address.to_string(), + derivation_path: RpcDerivationPath(DerivationPath::from_str($der_path).unwrap()), + chain: $chain, + balance: HashMap::from([( + TEST_COIN_NAME.to_string(), + CoinBalance::new(BigDecimal::from($balance)), + )]), + }, + ) }; } @@ -4251,24 +4266,78 @@ fn test_account_balance_rpc() { }; } - #[rustfmt::skip] { // Account#0, external addresses. - known_address!("m/44'/141'/0'/0/0", "RRqF4cYniMwYs66S4QDUUZ4GJQFQF69rBE", Bip44Chain::External, balance = 0); - known_address!("m/44'/141'/0'/0/1", "RSVLsjXc9LJ8fm9Jq7gXjeubfja3bbgSDf", Bip44Chain::External, balance = 0); - known_address!("m/44'/141'/0'/0/2", "RSSZjtgfnLzvqF4cZQJJEpN5gvK3pWmd3h", Bip44Chain::External, balance = 0); - known_address!("m/44'/141'/0'/0/3", "RU1gRFXWXNx7uPRAEJ7wdZAW1RZ4TE6Vv1", Bip44Chain::External, balance = 98); - known_address!("m/44'/141'/0'/0/4", "RUkEvRzb7mtwfVeKiSFEbYupLkcvU5KJBw", Bip44Chain::External, balance = 1); - known_address!("m/44'/141'/0'/0/5", "RP8deqVfjBbkvxbGbsQ2EGdamMaP1wxizR", Bip44Chain::External, balance = 0); - known_address!("m/44'/141'/0'/0/6", "RSvKMMegKGP5e2EanH7fnD4yNsxdJvLAmL", Bip44Chain::External, balance = 32); + known_address!( + "m/44'/141'/0'/0/0", + "RRqF4cYniMwYs66S4QDUUZ4GJQFQF69rBE", + Bip44Chain::External, + balance = 0 + ); + known_address!( + "m/44'/141'/0'/0/1", + "RSVLsjXc9LJ8fm9Jq7gXjeubfja3bbgSDf", + Bip44Chain::External, + balance = 0 + ); + known_address!( + "m/44'/141'/0'/0/2", + "RSSZjtgfnLzvqF4cZQJJEpN5gvK3pWmd3h", + Bip44Chain::External, + balance = 0 + ); + known_address!( + "m/44'/141'/0'/0/3", + "RU1gRFXWXNx7uPRAEJ7wdZAW1RZ4TE6Vv1", + Bip44Chain::External, + balance = 98 + ); + known_address!( + "m/44'/141'/0'/0/4", + "RUkEvRzb7mtwfVeKiSFEbYupLkcvU5KJBw", + Bip44Chain::External, + balance = 1 + ); + known_address!( + "m/44'/141'/0'/0/5", + "RP8deqVfjBbkvxbGbsQ2EGdamMaP1wxizR", + Bip44Chain::External, + balance = 0 + ); + known_address!( + "m/44'/141'/0'/0/6", + "RSvKMMegKGP5e2EanH7fnD4yNsxdJvLAmL", + Bip44Chain::External, + balance = 32 + ); // Account#0, internal addresses. - known_address!("m/44'/141'/0'/1/0", "RLZxcZSYtKe74JZd1hBAmmD9PNHZqb72oL", Bip44Chain::Internal, balance = 13); - known_address!("m/44'/141'/0'/1/1", "RPj9JXUVnewWwVpxZDeqGB25qVqz5qJzwP", Bip44Chain::Internal, balance = 44); - known_address!("m/44'/141'/0'/1/2", "RSYdSLRYWuzBson2GDbWBa632q2PmFnCaH", Bip44Chain::Internal, balance = 10); + known_address!( + "m/44'/141'/0'/1/0", + "RLZxcZSYtKe74JZd1hBAmmD9PNHZqb72oL", + Bip44Chain::Internal, + balance = 13 + ); + known_address!( + "m/44'/141'/0'/1/1", + "RPj9JXUVnewWwVpxZDeqGB25qVqz5qJzwP", + Bip44Chain::Internal, + balance = 44 + ); + known_address!( + "m/44'/141'/0'/1/2", + "RSYdSLRYWuzBson2GDbWBa632q2PmFnCaH", + Bip44Chain::Internal, + balance = 10 + ); // Account#1, internal addresses. - known_address!("m/44'/141'/1'/1/0", "RGo7sYzivPtzv8aRQ4A6vRJDxoqkRRBRhZ", Bip44Chain::Internal, balance = 0); + known_address!( + "m/44'/141'/1'/1/0", + "RGo7sYzivPtzv8aRQ4A6vRJDxoqkRRBRhZ", + Bip44Chain::Internal, + balance = 0 + ); } NativeClient::display_balances.mock_safe(move |_, addresses: Vec
, _| { @@ -4535,14 +4604,17 @@ fn test_scan_for_new_addresses() { non_empty_addresses.insert($address.to_string()); } expected_checked_addresses.push($address.to_string()); - balances_by_der_path.insert($der_path.to_string(), HDAddressBalance { - address: $address.to_string(), - derivation_path: RpcDerivationPath(DerivationPath::from_str($der_path).unwrap()), - chain: $chain, - balance: $balance.map_or_else(HashMap::default, |balance| { - HashMap::from([(TEST_COIN_NAME.to_string(), CoinBalance::new(BigDecimal::from(balance)))]) - }), - }); + balances_by_der_path.insert( + $der_path.to_string(), + HDAddressBalance { + address: $address.to_string(), + derivation_path: RpcDerivationPath(DerivationPath::from_str($der_path).unwrap()), + chain: $chain, + balance: $balance.map_or_else(HashMap::default, |balance| { + HashMap::from([(TEST_COIN_NAME.to_string(), CoinBalance::new(BigDecimal::from(balance)))]) + }), + }, + ); }}; } @@ -4560,30 +4632,74 @@ fn test_scan_for_new_addresses() { } // Please note that the order of the `known` and `new` addresses is important. - #[rustfmt::skip] { // Account#0, external addresses. - new_address!("m/44'/141'/0'/0/3", "RU1gRFXWXNx7uPRAEJ7wdZAW1RZ4TE6Vv1", Bip44Chain::External, balance = Some(98)); + new_address!( + "m/44'/141'/0'/0/3", + "RU1gRFXWXNx7uPRAEJ7wdZAW1RZ4TE6Vv1", + Bip44Chain::External, + balance = Some(98) + ); unused_address!("m/44'/141'/0'/0/4", "RUkEvRzb7mtwfVeKiSFEbYupLkcvU5KJBw"); unused_address!("m/44'/141'/0'/0/5", "RP8deqVfjBbkvxbGbsQ2EGdamMaP1wxizR"); unused_address!("m/44'/141'/0'/0/6", "RSvKMMegKGP5e2EanH7fnD4yNsxdJvLAmL"); unused_address!("m/44'/141'/0'/0/7", "RX76e9G7H4Xy6cYrtr1qGghxytAmWpv375"); // Stop searching for a non-empty address (gap_limit = 3). // Account#0, internal addresses. - new_address!("m/44'/141'/0'/1/1", "RPj9JXUVnewWwVpxZDeqGB25qVqz5qJzwP", Bip44Chain::Internal, balance = Some(98)); - new_address!("m/44'/141'/0'/1/2", "RSYdSLRYWuzBson2GDbWBa632q2PmFnCaH", Bip44Chain::Internal, balance = None::); - new_address!("m/44'/141'/0'/1/3", "RQstQeTUEZLh6c3YWJDkeVTTQoZUsfvNCr", Bip44Chain::Internal, balance = Some(14)); + new_address!( + "m/44'/141'/0'/1/1", + "RPj9JXUVnewWwVpxZDeqGB25qVqz5qJzwP", + Bip44Chain::Internal, + balance = Some(98) + ); + new_address!( + "m/44'/141'/0'/1/2", + "RSYdSLRYWuzBson2GDbWBa632q2PmFnCaH", + Bip44Chain::Internal, + balance = None:: + ); + new_address!( + "m/44'/141'/0'/1/3", + "RQstQeTUEZLh6c3YWJDkeVTTQoZUsfvNCr", + Bip44Chain::Internal, + balance = Some(14) + ); unused_address!("m/44'/141'/0'/1/4", "RT54m6pfj9scqwSLmYdfbmPcrpxnWGAe9J"); unused_address!("m/44'/141'/0'/1/5", "RYWfEFxqA6zya9c891Dj7vxiDojCmuWR9T"); unused_address!("m/44'/141'/0'/1/6", "RSkY6twW8knTcn6wGACUAG9crJHcuQ2kEH"); unused_address!("m/44'/141'/0'/1/7", "RGRybU5awT9Chn9FeKZd8CEBREq5vNFDKJ"); // Stop searching for a non-empty address (gap_limit = 3). // Account#1, external addresses. - new_address!("m/44'/141'/1'/0/0", "RBQFLwJ88gVcnfkYvJETeTAB6AAYLow12K", Bip44Chain::External, balance = Some(9)); - new_address!("m/44'/141'/1'/0/1", "RCyy77sRWFa2oiFPpyimeTQfenM1aRoiZs", Bip44Chain::External, balance = Some(7)); - new_address!("m/44'/141'/1'/0/2", "RDnNa3pQmisfi42KiTZrfYfuxkLC91PoTJ", Bip44Chain::External, balance = None::); - new_address!("m/44'/141'/1'/0/3", "RQRGgXcGJz93CoAfQJoLgBz2r9HtJYMX3Z", Bip44Chain::External, balance = None::); - new_address!("m/44'/141'/1'/0/4", "RM6cqSFCFZ4J1LngLzqKkwo2ouipbDZUbm", Bip44Chain::External, balance = Some(11)); + new_address!( + "m/44'/141'/1'/0/0", + "RBQFLwJ88gVcnfkYvJETeTAB6AAYLow12K", + Bip44Chain::External, + balance = Some(9) + ); + new_address!( + "m/44'/141'/1'/0/1", + "RCyy77sRWFa2oiFPpyimeTQfenM1aRoiZs", + Bip44Chain::External, + balance = Some(7) + ); + new_address!( + "m/44'/141'/1'/0/2", + "RDnNa3pQmisfi42KiTZrfYfuxkLC91PoTJ", + Bip44Chain::External, + balance = None:: + ); + new_address!( + "m/44'/141'/1'/0/3", + "RQRGgXcGJz93CoAfQJoLgBz2r9HtJYMX3Z", + Bip44Chain::External, + balance = None:: + ); + new_address!( + "m/44'/141'/1'/0/4", + "RM6cqSFCFZ4J1LngLzqKkwo2ouipbDZUbm", + Bip44Chain::External, + balance = Some(11) + ); unused_address!("m/44'/141'/1'/0/5", "RX2fGBZjNZMNdNcnc5QBRXvmsXTvadvTPN"); unused_address!("m/44'/141'/1'/0/6", "RJJ7muUETyp59vxVXna9KAZ9uQ1QSqmcjE"); unused_address!("m/44'/141'/1'/0/7", "RYJ6vbhxFre5yChCMiJJFNTTBhAQbKM9AY"); @@ -4593,7 +4709,8 @@ fn test_scan_for_new_addresses() { unused_address!("m/44'/141'/1'/0/2", "RCjRDibDAXKYpVYSUeJXrbTzZ1UEKYAwJa"); unused_address!("m/44'/141'/1'/0/3", "REs1NRzg8XjwN3v8Jp1wQUAyQb3TzeT8EB"); unused_address!("m/44'/141'/1'/0/4", "RS4UZtkwZ8eYaTL1xodXgFNryJoTbPJYE5"); - unused_address!("m/44'/141'/1'/0/5", "RDzcAqivNqUCJA4auetoVE4hcmH2p4L1fB"); // Stop searching for a non-empty address (gap_limit = 3). + unused_address!("m/44'/141'/1'/0/5", "RDzcAqivNqUCJA4auetoVE4hcmH2p4L1fB"); + // Stop searching for a non-empty address (gap_limit = 3). } NativeClient::display_balance.mock_safe(move |_, address: Address, _| { diff --git a/mm2src/coins/utxo/utxo_tx_history_v2.rs b/mm2src/coins/utxo/utxo_tx_history_v2.rs index 333646a050..c69b6f29b8 100644 --- a/mm2src/coins/utxo/utxo_tx_history_v2.rs +++ b/mm2src/coins/utxo/utxo_tx_history_v2.rs @@ -6,9 +6,10 @@ use crate::utxo::bch::BchCoin; use crate::utxo::slp::ParseSlpScriptError; use crate::utxo::tx_history_events::TxHistoryEventStreamer; use crate::utxo::{utxo_common, AddrFromStrError, GetBlockHeaderError}; -use crate::{BalanceError, BalanceResult, BlockHeightAndTime, CoinWithDerivationMethod, HistorySyncState, - MarketCoinOps, MmCoin, NumConversError, ParseBigDecimalError, TransactionDetails, - UnexpectedDerivationMethod, UtxoRpcError, UtxoTx}; +use crate::{ + BalanceError, BalanceResult, BlockHeightAndTime, CoinWithDerivationMethod, HistorySyncState, MarketCoinOps, MmCoin, + NumConversError, ParseBigDecimalError, TransactionDetails, UnexpectedDerivationMethod, UtxoRpcError, UtxoTx, +}; use async_trait::async_trait; use common::executor::Timer; use common::log::{error, info}; @@ -42,11 +43,15 @@ pub enum UtxoMyAddressesHistoryError { } impl From for UtxoMyAddressesHistoryError { - fn from(e: AddressDerivingError) -> Self { UtxoMyAddressesHistoryError::AddressDerivingError(e) } + fn from(e: AddressDerivingError) -> Self { + UtxoMyAddressesHistoryError::AddressDerivingError(e) + } } impl From for UtxoMyAddressesHistoryError { - fn from(e: UnexpectedDerivationMethod) -> Self { UtxoMyAddressesHistoryError::UnexpectedDerivationMethod(e) } + fn from(e: UnexpectedDerivationMethod) -> Self { + UtxoMyAddressesHistoryError::UnexpectedDerivationMethod(e) + } } #[allow(clippy::large_enum_variant)] @@ -69,19 +74,27 @@ pub enum UtxoTxDetailsError { } impl From for UtxoTxDetailsError { - fn from(e: serialization::Error) -> Self { UtxoTxDetailsError::TxDeserializationError(e) } + fn from(e: serialization::Error) -> Self { + UtxoTxDetailsError::TxDeserializationError(e) + } } impl From for UtxoTxDetailsError { - fn from(e: UtxoRpcError) -> Self { UtxoTxDetailsError::RpcError(e) } + fn from(e: UtxoRpcError) -> Self { + UtxoTxDetailsError::RpcError(e) + } } impl From for UtxoTxDetailsError { - fn from(e: NumConversError) -> Self { UtxoTxDetailsError::NumConversionErr(e) } + fn from(e: NumConversError) -> Self { + UtxoTxDetailsError::NumConversionErr(e) + } } impl From for UtxoTxDetailsError { - fn from(e: ParseBigDecimalError) -> Self { UtxoTxDetailsError::from(NumConversError::from(e)) } + fn from(e: ParseBigDecimalError) -> Self { + UtxoTxDetailsError::from(NumConversError::from(e)) + } } impl From for UtxoTxDetailsError { @@ -94,7 +107,9 @@ impl From for UtxoTxDetailsError where StorageErr: TxHistoryStorageError, { - fn from(e: StorageErr) -> Self { UtxoTxDetailsError::StorageError(format!("{:?}", e)) } + fn from(e: StorageErr) -> Self { + UtxoTxDetailsError::StorageError(format!("{:?}", e)) + } } pub struct UtxoTxDetailsParams<'a, Storage> { diff --git a/mm2src/coins/utxo/utxo_withdraw.rs b/mm2src/coins/utxo/utxo_withdraw.rs index 9c8953cf3d..d8ca0460d9 100644 --- a/mm2src/coins/utxo/utxo_withdraw.rs +++ b/mm2src/coins/utxo/utxo_withdraw.rs @@ -1,9 +1,13 @@ use crate::rpc_command::init_withdraw::{WithdrawInProgressStatus, WithdrawTaskHandleShared}; use crate::utxo::utxo_common::{big_decimal_from_sat, UtxoTxBuilder}; -use crate::utxo::{output_script, sat_from_big_decimal, ActualFeeRate, Address, FeePolicy, GetUtxoListOps, - PrivKeyPolicy, UtxoAddressFormat, UtxoCoinFields, UtxoCommonOps, UtxoFeeDetails, UtxoTx, UTXO_LOCK}; -use crate::{CoinWithDerivationMethod, GetWithdrawSenderAddress, MarketCoinOps, TransactionData, TransactionDetails, - UnexpectedDerivationMethod, WithdrawError, WithdrawFee, WithdrawRequest, WithdrawResult}; +use crate::utxo::{ + output_script, sat_from_big_decimal, ActualFeeRate, Address, FeePolicy, GetUtxoListOps, PrivKeyPolicy, + UtxoAddressFormat, UtxoCoinFields, UtxoCommonOps, UtxoFeeDetails, UtxoTx, UTXO_LOCK, +}; +use crate::{ + CoinWithDerivationMethod, GetWithdrawSenderAddress, MarketCoinOps, TransactionData, TransactionDetails, + UnexpectedDerivationMethod, WithdrawError, WithdrawFee, WithdrawRequest, WithdrawResult, +}; use async_trait::async_trait; use chain::TransactionOutput; use common::log::info; @@ -56,7 +60,9 @@ impl From> for WithdrawError { } impl From for WithdrawError { - fn from(e: HwError) -> Self { from_hw_error(e) } + fn from(e: HwError) -> Self { + from_hw_error(e) + } } impl From for WithdrawError { @@ -69,7 +75,9 @@ impl From for WithdrawError { } impl From for WithdrawError { - fn from(e: CryptoCtxError) -> Self { WithdrawError::InternalError(e.to_string()) } + fn from(e: CryptoCtxError) -> Self { + WithdrawError::InternalError(e.to_string()) + } } impl From for WithdrawError { @@ -88,7 +96,9 @@ impl From for WithdrawError { } impl From for WithdrawError { - fn from(e: keys::Error) -> Self { WithdrawError::InternalError(e.to_string()) } + fn from(e: keys::Error) -> Self { + WithdrawError::InternalError(e.to_string()) + } } fn derive_hd_key_pair( @@ -257,13 +267,21 @@ impl UtxoWithdraw for InitUtxoWithdraw where Coin: UtxoCommonOps + GetUtxoListOps + UtxoSignerOps, { - fn coin(&self) -> &Coin { &self.coin } + fn coin(&self) -> &Coin { + &self.coin + } - fn sender_address(&self) -> Address { self.from_address.clone() } + fn sender_address(&self) -> Address { + self.from_address.clone() + } - fn sender_address_string(&self) -> String { self.from_address_string.clone() } + fn sender_address_string(&self) -> String { + self.from_address_string.clone() + } - fn request(&self) -> &WithdrawRequest { &self.req } + fn request(&self) -> &WithdrawRequest { + &self.req + } fn on_generating_transaction(&self) -> Result<(), MmError> { let amount_display = if self.req.max { @@ -440,17 +458,29 @@ impl UtxoWithdraw for StandardUtxoWithdraw where Coin: UtxoCommonOps + GetUtxoListOps, { - fn coin(&self) -> &Coin { &self.coin } + fn coin(&self) -> &Coin { + &self.coin + } - fn sender_address(&self) -> Address { self.from_address.clone() } + fn sender_address(&self) -> Address { + self.from_address.clone() + } - fn sender_address_string(&self) -> String { self.from_address_string.clone() } + fn sender_address_string(&self) -> String { + self.from_address_string.clone() + } - fn request(&self) -> &WithdrawRequest { &self.req } + fn request(&self) -> &WithdrawRequest { + &self.req + } - fn on_generating_transaction(&self) -> Result<(), MmError> { Ok(()) } + fn on_generating_transaction(&self) -> Result<(), MmError> { + Ok(()) + } - fn on_finishing(&self) -> Result<(), MmError> { Ok(()) } + fn on_finishing(&self) -> Result<(), MmError> { + Ok(()) + } async fn sign_tx(&self, unsigned_tx: TransactionInputSigner) -> Result> { Ok(with_key_pair::sign_tx( diff --git a/mm2src/coins/utxo_signer/src/lib.rs b/mm2src/coins/utxo_signer/src/lib.rs index 3f9ee23095..ba9dc1ea6d 100644 --- a/mm2src/coins/utxo_signer/src/lib.rs +++ b/mm2src/coins/utxo_signer/src/lib.rs @@ -67,7 +67,9 @@ pub enum UtxoSignTxError { } impl From for UtxoSignTxError { - fn from(e: TrezorError) -> Self { UtxoSignTxError::TrezorError(e) } + fn from(e: TrezorError) -> Self { + UtxoSignTxError::TrezorError(e) + } } impl From for UtxoSignTxError { @@ -94,7 +96,9 @@ impl From for UtxoSignTxError { } impl From for UtxoSignTxError { - fn from(e: keys::Error) -> Self { UtxoSignTxError::ErrorSigning(e) } + fn from(e: keys::Error) -> Self { + UtxoSignTxError::ErrorSigning(e) + } } impl From for UtxoSignTxError { diff --git a/mm2src/coins/utxo_signer/src/sign_params.rs b/mm2src/coins/utxo_signer/src/sign_params.rs index c43ed040ef..e1aa4b391c 100644 --- a/mm2src/coins/utxo_signer/src/sign_params.rs +++ b/mm2src/coins/utxo_signer/src/sign_params.rs @@ -41,7 +41,9 @@ pub enum OutputDestination { } impl OutputDestination { - pub fn plain(address: String) -> OutputDestination { OutputDestination::Plain { address } } + pub fn plain(address: String) -> OutputDestination { + OutputDestination::Plain { address } + } #[inline] pub fn change(derivation_path: DerivationPath, addr_format: AddressFormat) -> OutputDestination { @@ -80,7 +82,9 @@ pub struct UtxoSignTxParamsBuilder { } impl Default for UtxoSignTxParamsBuilder { - fn default() -> Self { UtxoSignTxParamsBuilder::new() } + fn default() -> Self { + UtxoSignTxParamsBuilder::new() + } } impl UtxoSignTxParamsBuilder { @@ -166,7 +170,9 @@ pub struct UtxoSignTxParams { } impl UtxoSignTxParams { - pub fn inputs_count(&self) -> usize { self.unsigned_tx.inputs.len() } + pub fn inputs_count(&self) -> usize { + self.unsigned_tx.inputs.len() + } /// We are sure that the number of `unsigned_tx.inputs.len()` is the same as `inputs_infos.len()`. /// Please see [`UtxoSignTxParamsBuilder::build`]. diff --git a/mm2src/coins/utxo_signer/src/with_key_pair.rs b/mm2src/coins/utxo_signer/src/with_key_pair.rs index b62fa695f2..1180b244b8 100644 --- a/mm2src/coins/utxo_signer/src/with_key_pair.rs +++ b/mm2src/coins/utxo_signer/src/with_key_pair.rs @@ -1,5 +1,7 @@ -use crate::sign_common::{complete_tx, p2pk_spend_with_signature, p2pkh_spend_with_signature, - p2sh_spend_with_signature, p2wpkh_spend_with_signature}; +use crate::sign_common::{ + complete_tx, p2pk_spend_with_signature, p2pkh_spend_with_signature, p2sh_spend_with_signature, + p2wpkh_spend_with_signature, +}; use crate::Signature; use chain::{Transaction as UtxoTx, TransactionInput}; use derive_more::Display; @@ -40,7 +42,9 @@ pub enum UtxoSignWithKeyPairError { } impl From for UtxoSignWithKeyPairError { - fn from(sign: keys::Error) -> Self { UtxoSignWithKeyPairError::ErrorSigning(sign) } + fn from(sign: keys::Error) -> Self { + UtxoSignWithKeyPairError::ErrorSigning(sign) + } } pub fn sign_tx( diff --git a/mm2src/coins/utxo_signer/src/with_trezor.rs b/mm2src/coins/utxo_signer/src/with_trezor.rs index 3909175a1b..0b747260e2 100644 --- a/mm2src/coins/utxo_signer/src/with_trezor.rs +++ b/mm2src/coins/utxo_signer/src/with_trezor.rs @@ -3,8 +3,9 @@ use crate::sign_params::{OutputDestination, SendingOutputInfo, SpendingInputInfo use crate::{TxProvider, UtxoSignTxError, UtxoSignTxResult}; use chain::{Transaction as UtxoTx, TransactionOutput}; use common::log::debug; -use crypto::trezor::utxo::{PrevTx, PrevTxInput, PrevTxOutput, TrezorInputScriptType, TxOutput, TxSignResult, - UnsignedTxInput, UnsignedUtxoTx}; +use crypto::trezor::utxo::{ + PrevTx, PrevTxInput, PrevTxOutput, TrezorInputScriptType, TxOutput, TxSignResult, UnsignedTxInput, UnsignedUtxoTx, +}; use crypto::trezor::TrezorSession; use keys::bytes::Bytes; use mm2_err_handle::prelude::*; @@ -207,8 +208,12 @@ impl TrezorTxSigner<'_, TxP> { } /// https://github.com/trezor/trezor-utxo-lib/blob/trezor/src/transaction.js#L405 - fn is_overwinter_compatible(&self) -> bool { self.is_zcash_type() && self.params.unsigned_tx.version > 3 } + fn is_overwinter_compatible(&self) -> bool { + self.is_zcash_type() && self.params.unsigned_tx.version > 3 + } /// https://github.com/trezor/trezor-utxo-lib/blob/trezor/src/coins.js#L55 - fn is_zcash_type(&self) -> bool { matches!(self.trezor_coin.as_str(), "Komodo" | "Zcash" | "Zcash Testnet") } + fn is_zcash_type(&self) -> bool { + matches!(self.trezor_coin.as_str(), "Komodo" | "Zcash" | "Zcash Testnet") + } } diff --git a/mm2src/coins/watcher_common.rs b/mm2src/coins/watcher_common.rs index 893a598974..98614d25ca 100644 --- a/mm2src/coins/watcher_common.rs +++ b/mm2src/coins/watcher_common.rs @@ -29,6 +29,10 @@ pub fn validate_watcher_reward( Ok(()) } -fn get_reward_lower_boundary(reward: u64) -> u64 { (reward as f64 * (1. - REWARD_MARGIN)) as u64 } +fn get_reward_lower_boundary(reward: u64) -> u64 { + (reward as f64 * (1. - REWARD_MARGIN)) as u64 +} -fn get_reward_upper_boundary(reward: u64) -> u64 { (reward as f64 * (1. + REWARD_MARGIN)) as u64 } +fn get_reward_upper_boundary(reward: u64) -> u64 { + (reward as f64 * (1. + REWARD_MARGIN)) as u64 +} diff --git a/mm2src/coins/z_coin.rs b/mm2src/coins/z_coin.rs index ec2c0c6eb2..34fb82f836 100644 --- a/mm2src/coins/z_coin.rs +++ b/mm2src/coins/z_coin.rs @@ -7,36 +7,42 @@ mod z_coin_errors; mod z_htlc; mod z_rpc; mod z_tx_history; -#[cfg(all(test, not(target_arch = "wasm32")))] mod z_unit_tests; +#[cfg(all(test, not(target_arch = "wasm32")))] +mod z_unit_tests; use crate::coin_errors::{AddressFromPubkeyError, MyAddressError, ValidatePaymentResult}; use crate::hd_wallet::{HDAddressSelector, HDPathAccountToAddressId}; use crate::my_tx_history_v2::{MyTxHistoryErrorV2, MyTxHistoryRequestV2, MyTxHistoryResponseV2}; use crate::rpc_command::init_withdraw::{InitWithdrawCoin, WithdrawInProgressStatus, WithdrawTaskHandleShared}; -use crate::utxo::rpc_clients::{ElectrumConnectionSettings, UnspentInfo, UtxoRpcClientEnum, UtxoRpcError, UtxoRpcFut, - UtxoRpcResult}; -use crate::utxo::utxo_builder::{UtxoCoinBuildError, UtxoCoinBuilder, UtxoCoinBuilderCommonOps, - UtxoFieldsWithGlobalHDBuilder, UtxoFieldsWithHardwareWalletBuilder, - UtxoFieldsWithIguanaSecretBuilder}; -use crate::utxo::utxo_common::{addresses_from_script, big_decimal_from_sat, big_decimal_from_sat_unsigned, - payment_script}; -use crate::utxo::{sat_from_big_decimal, utxo_common, ActualFeeRate, AdditionalTxData, AddrFromStrError, Address, - BroadcastTxErr, FeePolicy, GetUtxoListOps, HistoryUtxoTx, HistoryUtxoTxMap, MatureUnspentList, - RecentlySpentOutPointsGuard, UnsupportedAddr, UtxoActivationParams, UtxoAddressFormat, UtxoArc, - UtxoCoinFields, UtxoCommonOps, UtxoFeeDetails, UtxoRpcMode, UtxoTxBroadcastOps, UtxoTxGenerationOps, - VerboseTransactionFrom}; +use crate::utxo::rpc_clients::{ + ElectrumConnectionSettings, UnspentInfo, UtxoRpcClientEnum, UtxoRpcError, UtxoRpcFut, UtxoRpcResult, +}; +use crate::utxo::utxo_builder::{ + UtxoCoinBuildError, UtxoCoinBuilder, UtxoCoinBuilderCommonOps, UtxoFieldsWithGlobalHDBuilder, + UtxoFieldsWithHardwareWalletBuilder, UtxoFieldsWithIguanaSecretBuilder, +}; +use crate::utxo::utxo_common::{ + addresses_from_script, big_decimal_from_sat, big_decimal_from_sat_unsigned, payment_script, +}; +use crate::utxo::{ + sat_from_big_decimal, utxo_common, ActualFeeRate, AdditionalTxData, AddrFromStrError, Address, BroadcastTxErr, + FeePolicy, GetUtxoListOps, HistoryUtxoTx, HistoryUtxoTxMap, MatureUnspentList, RecentlySpentOutPointsGuard, + UnsupportedAddr, UtxoActivationParams, UtxoAddressFormat, UtxoArc, UtxoCoinFields, UtxoCommonOps, UtxoFeeDetails, + UtxoRpcMode, UtxoTxBroadcastOps, UtxoTxGenerationOps, VerboseTransactionFrom, +}; use crate::z_coin::storage::{BlockDbImpl, LockedNotesStorage, WalletDbShared}; use crate::z_coin::z_tx_history::{fetch_tx_history_from_db, ZCoinTxHistoryItem}; -use crate::{BalanceError, BalanceFut, CheckIfMyPaymentSentArgs, CoinBalance, ConfirmPaymentInput, DexFee, - FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, - NumConversError, PrivKeyActivationPolicy, PrivKeyBuildPolicy, PrivKeyPolicyNotAllowed, RawTransactionFut, - RawTransactionRequest, RawTransactionResult, RefundPaymentArgs, SearchForSwapTxSpendInput, - SendPaymentArgs, SignRawTransactionRequest, SignatureError, SignatureResult, SpendPaymentArgs, SwapOps, - TradeFee, TradePreimageFut, TradePreimageResult, TradePreimageValue, Transaction, TransactionData, - TransactionDetails, TransactionEnum, TransactionResult, TxFeeDetails, TxMarshalingErr, - UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, ValidateOtherPubKeyErr, - ValidatePaymentError, ValidatePaymentInput, VerificationError, VerificationResult, WaitForHTLCTxSpendArgs, - WatcherOps, WeakSpawner, WithdrawError, WithdrawFut, WithdrawRequest}; +use crate::{ + BalanceError, BalanceFut, CheckIfMyPaymentSentArgs, CoinBalance, ConfirmPaymentInput, DexFee, FeeApproxStage, + FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, NumConversError, + PrivKeyActivationPolicy, PrivKeyBuildPolicy, PrivKeyPolicyNotAllowed, RawTransactionFut, RawTransactionRequest, + RawTransactionResult, RefundPaymentArgs, SearchForSwapTxSpendInput, SendPaymentArgs, SignRawTransactionRequest, + SignatureError, SignatureResult, SpendPaymentArgs, SwapOps, TradeFee, TradePreimageFut, TradePreimageResult, + TradePreimageValue, Transaction, TransactionData, TransactionDetails, TransactionEnum, TransactionResult, + TxFeeDetails, TxMarshalingErr, UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, + ValidateOtherPubKeyErr, ValidatePaymentError, ValidatePaymentInput, VerificationError, VerificationResult, + WaitForHTLCTxSpendArgs, WatcherOps, WeakSpawner, WithdrawError, WithdrawFut, WithdrawRequest, +}; use crate::z_coin::storage::z_locked_notes::LockedNote; use async_trait::async_trait; @@ -59,7 +65,8 @@ use keys::{KeyPair, Message, Public}; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; use mm2_number::{BigDecimal, MmNumber}; -#[cfg(test)] use mocktopus::macros::*; +#[cfg(test)] +use mocktopus::macros::*; use rpc::v1::types::{Bytes as BytesJson, Transaction as RpcTransaction, H256 as H256Json, H264 as H264Json}; use script::{Builder as ScriptBuilder, Opcode, Script, TransactionInputSigner}; use serde_json::Value as Json; @@ -89,8 +96,10 @@ use zcash_primitives::transaction::builder::Builder as ZTxBuilder; use zcash_primitives::transaction::components::{Amount, OutputDescription, TxOut}; use zcash_primitives::transaction::Transaction as ZTransaction; use zcash_primitives::zip32::ChildIndex as Zip32Child; -use zcash_primitives::{constants::mainnet as z_mainnet_constants, sapling::PaymentAddress, - zip32::ExtendedFullViewingKey, zip32::ExtendedSpendingKey}; +use zcash_primitives::{ + constants::mainnet as z_mainnet_constants, sapling::PaymentAddress, zip32::ExtendedFullViewingKey, + zip32::ExtendedSpendingKey, +}; use zcash_proofs::prover::LocalTxProver; cfg_native!( @@ -184,17 +193,29 @@ impl Parameters for ZcoinConsensusParams { } } - fn coin_type(&self) -> u32 { self.coin_type } + fn coin_type(&self) -> u32 { + self.coin_type + } - fn hrp_sapling_extended_spending_key(&self) -> &str { &self.hrp_sapling_extended_spending_key } + fn hrp_sapling_extended_spending_key(&self) -> &str { + &self.hrp_sapling_extended_spending_key + } - fn hrp_sapling_extended_full_viewing_key(&self) -> &str { &self.hrp_sapling_extended_full_viewing_key } + fn hrp_sapling_extended_full_viewing_key(&self) -> &str { + &self.hrp_sapling_extended_full_viewing_key + } - fn hrp_sapling_payment_address(&self) -> &str { &self.hrp_sapling_payment_address } + fn hrp_sapling_payment_address(&self) -> &str { + &self.hrp_sapling_payment_address + } - fn b58_pubkey_address_prefix(&self) -> [u8; 2] { self.b58_pubkey_address_prefix } + fn b58_pubkey_address_prefix(&self) -> [u8; 2] { + self.b58_pubkey_address_prefix + } - fn b58_script_address_prefix(&self) -> [u8; 2] { self.b58_script_address_prefix } + fn b58_script_address_prefix(&self) -> [u8; 2] { + self.b58_script_address_prefix + } } #[allow(unused)] @@ -274,16 +295,24 @@ struct GenTxData<'a> { impl ZCoin { #[inline] - pub fn utxo_rpc_client(&self) -> &UtxoRpcClientEnum { &self.utxo_arc.rpc_client } + pub fn utxo_rpc_client(&self) -> &UtxoRpcClientEnum { + &self.utxo_arc.rpc_client + } #[inline] - pub fn my_z_address_encoded(&self) -> String { self.z_fields.my_z_addr_encoded.clone() } + pub fn my_z_address_encoded(&self) -> String { + self.z_fields.my_z_addr_encoded.clone() + } #[inline] - pub fn consensus_params(&self) -> ZcoinConsensusParams { self.z_fields.consensus_params.clone() } + pub fn consensus_params(&self) -> ZcoinConsensusParams { + self.z_fields.consensus_params.clone() + } #[inline] - pub fn consensus_params_ref(&self) -> &ZcoinConsensusParams { &self.z_fields.consensus_params } + pub fn consensus_params_ref(&self) -> &ZcoinConsensusParams { + &self.z_fields.consensus_params + } /// Asynchronously checks the synchronization status and returns `true` if /// the Sapling state has finished synchronizing, meaning that the block number is available. @@ -731,7 +760,9 @@ impl ZCoin { } impl AsRef for ZCoin { - fn as_ref(&self) -> &UtxoCoinFields { &self.utxo_arc } + fn as_ref(&self) -> &UtxoCoinFields { + &self.utxo_arc + } } #[cfg(target_arch = "wasm32")] @@ -915,13 +946,21 @@ pub struct ZCoinBuilder<'a> { } impl UtxoCoinBuilderCommonOps for ZCoinBuilder<'_> { - fn ctx(&self) -> &MmArc { self.ctx } + fn ctx(&self) -> &MmArc { + self.ctx + } - fn conf(&self) -> &Json { self.conf } + fn conf(&self) -> &Json { + self.conf + } - fn activation_params(&self) -> &UtxoActivationParams { &self.utxo_params } + fn activation_params(&self) -> &UtxoActivationParams { + &self.utxo_params + } - fn ticker(&self) -> &str { self.ticker } + fn ticker(&self) -> &str { + self.ticker + } } impl UtxoFieldsWithIguanaSecretBuilder for ZCoinBuilder<'_> {} @@ -937,7 +976,9 @@ impl UtxoCoinBuilder for ZCoinBuilder<'_> { type ResultCoin = ZCoin; type Error = ZCoinBuildError; - fn priv_key_policy(&self) -> PrivKeyBuildPolicy { self.priv_key_policy.clone() } + fn priv_key_policy(&self) -> PrivKeyBuildPolicy { + self.priv_key_policy.clone() + } async fn build(self) -> MmResult { let utxo = self.build_utxo_fields().await.map_mm_err()?; @@ -1180,9 +1221,13 @@ pub async fn z_coin_from_conf_and_params_with_docker( #[async_trait] impl MarketCoinOps for ZCoin { - fn ticker(&self) -> &str { &self.utxo_arc.conf.ticker } + fn ticker(&self) -> &str { + &self.utxo_arc.conf.ticker + } - fn my_address(&self) -> MmResult { Ok(self.z_fields.my_z_addr_encoded.clone()) } + fn my_address(&self) -> MmResult { + Ok(self.z_fields.my_z_addr_encoded.clone()) + } fn address_from_pubkey(&self, _pubkey: &H264Json) -> MmResult { // NOTE: We can't derive a z-address from pubkey, so we will just return our own z_address. @@ -1194,7 +1239,9 @@ impl MarketCoinOps for ZCoin { Ok(pubkey.to_string()) } - fn sign_message_hash(&self, _message: &str) -> Option<[u8; 32]> { None } + fn sign_message_hash(&self, _message: &str) -> Option<[u8; 32]> { + None + } fn sign_message(&self, _message: &str, _address: Option) -> SignatureResult { MmError::err(SignatureError::InvalidRequest( @@ -1266,9 +1313,13 @@ impl MarketCoinOps for ZCoin { Box::new(fut.boxed().compat()) } - fn base_coin_balance(&self) -> BalanceFut { utxo_common::base_coin_balance(self) } + fn base_coin_balance(&self) -> BalanceFut { + utxo_common::base_coin_balance(self) + } - fn platform_ticker(&self) -> &str { self.ticker() } + fn platform_ticker(&self) -> &str { + self.ticker() + } fn send_raw_tx(&self, tx: &str) -> Box + Send> { let tx_bytes = try_fus!(hex::decode(tx)); @@ -1339,15 +1390,25 @@ impl MarketCoinOps for ZCoin { )) } - fn min_tx_amount(&self) -> BigDecimal { utxo_common::min_tx_amount(self.as_ref()) } + fn min_tx_amount(&self) -> BigDecimal { + utxo_common::min_tx_amount(self.as_ref()) + } - fn min_trading_vol(&self) -> MmNumber { utxo_common::min_trading_vol(self.as_ref()) } + fn min_trading_vol(&self) -> MmNumber { + utxo_common::min_trading_vol(self.as_ref()) + } - fn is_privacy(&self) -> bool { true } + fn is_privacy(&self) -> bool { + true + } - fn should_burn_dex_fee(&self) -> bool { false } // TODO: enable when burn z_address fixed + fn should_burn_dex_fee(&self) -> bool { + false + } // TODO: enable when burn z_address fixed - fn is_trezor(&self) -> bool { self.as_ref().priv_key_policy.is_trezor() } + fn is_trezor(&self) -> bool { + self.as_ref().priv_key_policy.is_trezor() + } } #[async_trait] @@ -1707,9 +1768,13 @@ impl WatcherOps for ZCoin {} #[async_trait] impl MmCoin for ZCoin { - fn is_asset_chain(&self) -> bool { self.utxo_arc.conf.asset_chain } + fn is_asset_chain(&self) -> bool { + self.utxo_arc.conf.asset_chain + } - fn spawner(&self) -> WeakSpawner { self.as_ref().abortable_system.weak_spawner() } + fn spawner(&self) -> WeakSpawner { + self.as_ref().abortable_system.weak_spawner() + } fn withdraw(&self, _req: WithdrawRequest) -> WithdrawFut { Box::new(futures01::future::err(MmError::new(WithdrawError::InternalError( @@ -1729,7 +1794,9 @@ impl MmCoin for ZCoin { ) } - fn decimals(&self) -> u8 { self.utxo_arc.decimals } + fn decimals(&self) -> u8 { + self.utxo_arc.decimals + } fn convert_to_address(&self, _from: &str, _to_address_format: Json) -> Result { Err(MmError::new("Address conversion is not available for ZCoin".to_string()).to_string()) @@ -1757,7 +1824,9 @@ impl MmCoin for ZCoin { Box::new(futures01::future::err(())) } - fn history_sync_status(&self) -> HistorySyncState { HistorySyncState::NotEnabled } + fn history_sync_status(&self) -> HistorySyncState { + HistorySyncState::NotEnabled + } fn get_trade_fee(&self) -> Box + Send> { utxo_common::get_trade_fee(self.clone()) @@ -1792,9 +1861,13 @@ impl MmCoin for ZCoin { }) } - fn required_confirmations(&self) -> u64 { utxo_common::required_confirmations(&self.utxo_arc) } + fn required_confirmations(&self) -> u64 { + utxo_common::required_confirmations(&self.utxo_arc) + } - fn requires_notarization(&self) -> bool { utxo_common::requires_notarization(&self.utxo_arc) } + fn requires_notarization(&self) -> bool { + utxo_common::requires_notarization(&self.utxo_arc) + } fn set_required_confirmations(&self, confirmations: u64) { utxo_common::set_required_confirmations(&self.utxo_arc, confirmations) @@ -1804,11 +1877,17 @@ impl MmCoin for ZCoin { utxo_common::set_requires_notarization(&self.utxo_arc, requires_nota) } - fn swap_contract_address(&self) -> Option { utxo_common::swap_contract_address() } + fn swap_contract_address(&self) -> Option { + utxo_common::swap_contract_address() + } - fn fallback_swap_contract(&self) -> Option { utxo_common::fallback_swap_contract() } + fn fallback_swap_contract(&self) -> Option { + utxo_common::fallback_swap_contract() + } - fn mature_confirmations(&self) -> Option { Some(self.utxo_arc.conf.mature_confirmations) } + fn mature_confirmations(&self) -> Option { + Some(self.utxo_arc.conf.mature_confirmations) + } fn coin_protocol_info(&self, _amount_to_receive: Option) -> Vec { utxo_common::coin_protocol_info(self) @@ -1824,20 +1903,26 @@ impl MmCoin for ZCoin { utxo_common::is_coin_protocol_supported(self, info) } - fn on_disabled(&self) -> Result<(), AbortedError> { AbortableSystem::abort_all(&self.as_ref().abortable_system) } + fn on_disabled(&self) -> Result<(), AbortedError> { + AbortableSystem::abort_all(&self.as_ref().abortable_system) + } fn on_token_deactivated(&self, _ticker: &str) {} } #[async_trait] impl UtxoTxGenerationOps for ZCoin { - async fn get_fee_rate(&self) -> UtxoRpcResult { utxo_common::get_fee_rate(&self.utxo_arc).await } + async fn get_fee_rate(&self) -> UtxoRpcResult { + utxo_common::get_fee_rate(&self.utxo_arc).await + } async fn calc_interest_if_required(&self, unsigned: &mut TransactionInputSigner) -> UtxoRpcResult { utxo_common::calc_interest_if_required(self, unsigned).await } - fn supports_interest(&self) -> bool { utxo_common::is_kmd(self) } + fn supports_interest(&self) -> bool { + utxo_common::is_kmd(self) + } } #[async_trait] @@ -1885,7 +1970,9 @@ impl UtxoCommonOps for ZCoin { utxo_common::addresses_from_script(self, script) } - fn denominate_satoshis(&self, satoshi: i64) -> f64 { utxo_common::denominate_satoshis(&self.utxo_arc, satoshi) } + fn denominate_satoshis(&self, satoshi: i64) -> f64 { + utxo_common::denominate_satoshis(&self.utxo_arc, satoshi) + } fn my_public_key(&self) -> Result<&Public, MmError> { utxo_common::my_public_key(self.as_ref()) @@ -1964,7 +2051,9 @@ impl UtxoCommonOps for ZCoin { utxo_common::p2sh_tx_locktime(self, self.ticker(), htlc_locktime).await } - fn addr_format(&self) -> &UtxoAddressFormat { utxo_common::addr_format(self) } + fn addr_format(&self) -> &UtxoAddressFormat { + utxo_common::addr_format(self) + } fn addr_format_for_standard_scripts(&self) -> UtxoAddressFormat { utxo_common::addr_format_for_standard_scripts(self) diff --git a/mm2src/coins/z_coin/storage.rs b/mm2src/coins/z_coin/storage.rs index e8b1b6e971..6b146ec8cb 100644 --- a/mm2src/coins/z_coin/storage.rs +++ b/mm2src/coins/z_coin/storage.rs @@ -10,7 +10,8 @@ pub(crate) use walletdb::*; pub(crate) mod z_locked_notes; pub(crate) use z_locked_notes::{LockedNotesStorage, LockedNotesStorageError}; -#[cfg(target_arch = "wasm32")] mod z_params; +#[cfg(target_arch = "wasm32")] +mod z_params; #[cfg(target_arch = "wasm32")] pub(crate) use z_params::ZcashParamsWasmImpl; @@ -44,15 +45,23 @@ pub struct DataConnStmtCacheWrapper { impl DataConnStmtCacheWrapper { #[cfg(not(target_arch = "wasm32"))] - pub fn new(cache: DataConnStmtCacheAsync) -> Self { Self { cache } } + pub fn new(cache: DataConnStmtCacheAsync) -> Self { + Self { cache } + } #[cfg(target_arch = "wasm32")] - pub fn new(cache: DataConnStmtCacheWasm) -> Self { Self { cache } } + pub fn new(cache: DataConnStmtCacheWasm) -> Self { + Self { cache } + } #[cfg(not(target_arch = "wasm32"))] #[inline] - pub fn inner(&self) -> &DataConnStmtCacheAsync { &self.cache } + pub fn inner(&self) -> &DataConnStmtCacheAsync { + &self.cache + } #[cfg(target_arch = "wasm32")] #[inline] - pub fn inner(&self) -> &DataConnStmtCacheWasm { &self.cache } + pub fn inner(&self) -> &DataConnStmtCacheWasm { + &self.cache + } } pub struct CompactBlockRow { diff --git a/mm2src/coins/z_coin/storage/blockdb/blockdb_idb_storage.rs b/mm2src/coins/z_coin/storage/blockdb/blockdb_idb_storage.rs index b3863eb999..75c216f974 100644 --- a/mm2src/coins/z_coin/storage/blockdb/blockdb_idb_storage.rs +++ b/mm2src/coins/z_coin/storage/blockdb/blockdb_idb_storage.rs @@ -1,13 +1,17 @@ -use crate::z_coin::storage::{scan_cached_block, validate_chain, BlockDbImpl, BlockProcessingMode, CompactBlockRow, - LockedNotesStorage, ZcoinConsensusParams, ZcoinStorageRes}; +use crate::z_coin::storage::{ + scan_cached_block, validate_chain, BlockDbImpl, BlockProcessingMode, CompactBlockRow, LockedNotesStorage, + ZcoinConsensusParams, ZcoinStorageRes, +}; use crate::z_coin::tx_history_events::ZCoinTxHistoryEventStreamer; use crate::z_coin::z_balance_streaming::ZCoinBalanceEventStreamer; use crate::z_coin::z_coin_errors::ZcoinStorageError; use async_trait::async_trait; use mm2_core::mm_ctx::MmArc; -use mm2_db::indexed_db::{BeBigUint, ConstructibleDb, DbIdentifier, DbInstance, DbLocked, DbUpgrader, IndexedDb, - IndexedDbBuilder, InitDbResult, MultiIndex, OnUpgradeResult, TableSignature}; +use mm2_db::indexed_db::{ + BeBigUint, ConstructibleDb, DbIdentifier, DbInstance, DbLocked, DbUpgrader, IndexedDb, IndexedDbBuilder, + InitDbResult, MultiIndex, OnUpgradeResult, TableSignature, +}; use mm2_err_handle::prelude::*; use mm2_event_stream::DeriveStreamerId; use protobuf::Message; @@ -64,7 +68,9 @@ impl DbInstance for BlockDbInner { } impl BlockDbInner { - pub fn get_inner(&self) -> &IndexedDb { &self.0 } + pub fn get_inner(&self) -> &IndexedDb { + &self.0 + } } impl BlockDbImpl { diff --git a/mm2src/coins/z_coin/storage/blockdb/blockdb_sql_storage.rs b/mm2src/coins/z_coin/storage/blockdb/blockdb_sql_storage.rs index 631eac3aad..04015fe73a 100644 --- a/mm2src/coins/z_coin/storage/blockdb/blockdb_sql_storage.rs +++ b/mm2src/coins/z_coin/storage/blockdb/blockdb_sql_storage.rs @@ -1,5 +1,7 @@ -use crate::z_coin::storage::{scan_cached_block, validate_chain, BlockDbImpl, BlockProcessingMode, CompactBlockRow, - LockedNotesStorage, ZcoinStorageRes}; +use crate::z_coin::storage::{ + scan_cached_block, validate_chain, BlockDbImpl, BlockProcessingMode, CompactBlockRow, LockedNotesStorage, + ZcoinStorageRes, +}; use crate::z_coin::tx_history_events::ZCoinTxHistoryEventStreamer; use crate::z_coin::z_balance_streaming::ZCoinBalanceEventStreamer; use crate::z_coin::z_coin_errors::ZcoinStorageError; @@ -41,7 +43,9 @@ impl From for ZcoinStorageError { } impl From> for ZcoinStorageError { - fn from(value: ChainError) -> Self { Self::SqliteError(ZcashClientError::from(value)) } + fn from(value: ChainError) -> Self { + Self::SqliteError(ZcashClientError::from(value)) + } } impl BlockDbImpl { diff --git a/mm2src/coins/z_coin/storage/blockdb/mod.rs b/mm2src/coins/z_coin/storage/blockdb/mod.rs index e1b9c13d5b..ee1dd0c5ea 100644 --- a/mm2src/coins/z_coin/storage/blockdb/mod.rs +++ b/mm2src/coins/z_coin/storage/blockdb/mod.rs @@ -3,13 +3,15 @@ pub(crate) mod blockdb_sql_storage; #[cfg(not(target_arch = "wasm32"))] use db_common::sqlite::rusqlite::Connection; -#[cfg(not(target_arch = "wasm32"))] use std::sync::{Arc, Mutex}; +#[cfg(not(target_arch = "wasm32"))] +use std::sync::{Arc, Mutex}; #[cfg(target_arch = "wasm32")] pub(crate) mod blockdb_idb_storage; #[cfg(target_arch = "wasm32")] use blockdb_idb_storage::BlockDbInner; -#[cfg(target_arch = "wasm32")] use mm2_db::indexed_db::SharedDb; +#[cfg(target_arch = "wasm32")] +use mm2_db::indexed_db::SharedDb; /// A wrapper for the db connection to the block cache database in native and browser. #[derive(Clone)] @@ -87,21 +89,27 @@ mod block_db_storage_tests { #[cfg(all(test, not(target_arch = "wasm32")))] mod native_tests { - use crate::z_coin::storage::blockdb::block_db_storage_tests::{test_insert_block_and_get_latest_block_impl, - test_rewind_to_height_impl}; + use crate::z_coin::storage::blockdb::block_db_storage_tests::{ + test_insert_block_and_get_latest_block_impl, test_rewind_to_height_impl, + }; use common::block_on; #[test] - fn test_insert_block_and_get_latest_block() { block_on(test_insert_block_and_get_latest_block_impl()) } + fn test_insert_block_and_get_latest_block() { + block_on(test_insert_block_and_get_latest_block_impl()) + } #[test] - fn test_rewind_to_height() { block_on(test_rewind_to_height_impl()) } + fn test_rewind_to_height() { + block_on(test_rewind_to_height_impl()) + } } #[cfg(target_arch = "wasm32")] mod wasm_tests { - use crate::z_coin::storage::blockdb::block_db_storage_tests::{test_insert_block_and_get_latest_block_impl, - test_rewind_to_height_impl}; + use crate::z_coin::storage::blockdb::block_db_storage_tests::{ + test_insert_block_and_get_latest_block_impl, test_rewind_to_height_impl, + }; // use crate::z_coin::z_rpc::{LightRpcClient, ZRpcOps}; // use common::log::info; // use common::log::wasm_log::register_wasm_log; @@ -111,10 +119,14 @@ mod wasm_tests { wasm_bindgen_test_configure!(run_in_browser); #[wasm_bindgen_test] - async fn test_insert_block_and_get_latest_block() { test_insert_block_and_get_latest_block_impl().await } + async fn test_insert_block_and_get_latest_block() { + test_insert_block_and_get_latest_block_impl().await + } #[wasm_bindgen_test] - async fn test_rewind_to_height() { test_rewind_to_height_impl().await } + async fn test_rewind_to_height() { + test_rewind_to_height_impl().await + } #[wasm_bindgen_test] async fn test_transport() { diff --git a/mm2src/coins/z_coin/storage/walletdb/mod.rs b/mm2src/coins/z_coin/storage/walletdb/mod.rs index 244d72f1a6..b0304cba92 100644 --- a/mm2src/coins/z_coin/storage/walletdb/mod.rs +++ b/mm2src/coins/z_coin/storage/walletdb/mod.rs @@ -6,7 +6,8 @@ cfg_native!( use zcash_client_sqlite::for_async::WalletDbAsync; ); -#[cfg(target_arch = "wasm32")] pub mod wasm; +#[cfg(target_arch = "wasm32")] +pub mod wasm; #[cfg(target_arch = "wasm32")] use wasm::storage::WalletIndexedDb; diff --git a/mm2src/coins/z_coin/storage/walletdb/wasm/mod.rs b/mm2src/coins/z_coin/storage/walletdb/wasm/mod.rs index 5fb428db4f..1371c9736b 100644 --- a/mm2src/coins/z_coin/storage/walletdb/wasm/mod.rs +++ b/mm2src/coins/z_coin/storage/walletdb/wasm/mod.rs @@ -847,7 +847,9 @@ mod wasm_test { assert_eq!(walletdb.get_balance(AccountId(0)).await.unwrap(), value - value2); } - fn network() -> Network { Network::TestNetwork } + fn network() -> Network { + Network::TestNetwork + } // Todo: Uncomment after improving tx creation time // https://github.com/KomodoPlatform/komodo-defi-framework/issues/2000 diff --git a/mm2src/coins/z_coin/storage/walletdb/wasm/storage.rs b/mm2src/coins/z_coin/storage/walletdb/wasm/storage.rs index 6943590450..096ab11770 100644 --- a/mm2src/coins/z_coin/storage/walletdb/wasm/storage.rs +++ b/mm2src/coins/z_coin/storage/walletdb/wasm/storage.rs @@ -1,6 +1,7 @@ -use crate::z_coin::storage::walletdb::wasm::tables::{WalletDbAccountsTable, WalletDbBlocksTable, - WalletDbReceivedNotesTable, WalletDbSaplingWitnessesTable, - WalletDbSentNotesTable, WalletDbTransactionsTable}; +use crate::z_coin::storage::walletdb::wasm::tables::{ + WalletDbAccountsTable, WalletDbBlocksTable, WalletDbReceivedNotesTable, WalletDbSaplingWitnessesTable, + WalletDbSentNotesTable, WalletDbTransactionsTable, +}; use crate::z_coin::storage::wasm::{to_spendable_note, SpendableNoteConstructor}; use crate::z_coin::storage::ZcoinStorageRes; use crate::z_coin::z_coin_errors::ZcoinStorageError; @@ -10,8 +11,10 @@ use async_trait::async_trait; use common::log::info; use ff::PrimeField; use mm2_core::mm_ctx::MmArc; -use mm2_db::indexed_db::{ConstructibleDb, DbIdentifier, DbInstance, DbLocked, IndexedDb, IndexedDbBuilder, - InitDbResult, MultiIndex, SharedDb}; +use mm2_db::indexed_db::{ + ConstructibleDb, DbIdentifier, DbInstance, DbLocked, IndexedDb, IndexedDbBuilder, InitDbResult, MultiIndex, + SharedDb, +}; use mm2_err_handle::prelude::*; use mm2_number::num_bigint::ToBigInt; use mm2_number::BigInt; @@ -21,8 +24,9 @@ use std::convert::TryFrom; use std::ops::Deref; use zcash_client_backend::address::RecipientAddress; use zcash_client_backend::data_api::{PrunedBlock, ReceivedTransaction, SentTransaction}; -use zcash_client_backend::encoding::{decode_extended_full_viewing_key, decode_payment_address, - encode_extended_full_viewing_key, encode_payment_address}; +use zcash_client_backend::encoding::{ + decode_extended_full_viewing_key, decode_payment_address, encode_extended_full_viewing_key, encode_payment_address, +}; use zcash_client_backend::wallet::{AccountId, SpendableNote, WalletTx}; use zcash_client_backend::DecryptedOutput; use zcash_extras::{NoteId, ShieldedOutput, WalletRead, WalletWrite}; @@ -100,7 +104,9 @@ impl WalletDbShared { pub struct WalletDbInner(pub IndexedDb); impl WalletDbInner { - pub fn get_inner(&self) -> &IndexedDb { &self.0 } + pub fn get_inner(&self) -> &IndexedDb { + &self.0 + } } #[async_trait] @@ -1604,7 +1610,9 @@ impl WalletRead for DataConnStmtCacheWasm { self.0.get_balance_at(account, anchor_height).await } - async fn get_memo(&self, id_note: Self::NoteRef) -> Result { self.0.get_memo(id_note).await } + async fn get_memo(&self, id_note: Self::NoteRef) -> Result { + self.0.get_memo(id_note).await + } async fn get_commitment_tree( &self, @@ -1620,7 +1628,9 @@ impl WalletRead for DataConnStmtCacheWasm { self.0.get_witnesses(block_height).await } - async fn get_nullifiers(&self) -> Result, Self::Error> { self.0.get_nullifiers().await } + async fn get_nullifiers(&self) -> Result, Self::Error> { + self.0.get_nullifiers().await + } async fn get_spendable_notes( &self, diff --git a/mm2src/coins/z_coin/storage/z_params/indexeddb.rs b/mm2src/coins/z_coin/storage/z_params/indexeddb.rs index 97a115cca7..e08d9ee5e2 100644 --- a/mm2src/coins/z_coin/storage/z_params/indexeddb.rs +++ b/mm2src/coins/z_coin/storage/z_params/indexeddb.rs @@ -1,8 +1,10 @@ use crate::z_coin::z_coin_errors::ZcoinStorageError; use mm2_core::mm_ctx::MmArc; -use mm2_db::indexed_db::{ConstructibleDb, DbIdentifier, DbInstance, DbLocked, DbUpgrader, IndexedDb, IndexedDbBuilder, - InitDbResult, OnUpgradeResult, SharedDb, TableSignature}; +use mm2_db::indexed_db::{ + ConstructibleDb, DbIdentifier, DbInstance, DbLocked, DbUpgrader, IndexedDb, IndexedDbBuilder, InitDbResult, + OnUpgradeResult, SharedDb, TableSignature, +}; use mm2_err_handle::prelude::*; const CHAIN: &str = "z_coin"; @@ -62,7 +64,9 @@ impl DbInstance for ZcashParamsWasmInner { } impl ZcashParamsWasmInner { - pub(crate) fn get_inner(&self) -> &IndexedDb { &self.0 } + pub(crate) fn get_inner(&self) -> &IndexedDb { + &self.0 + } } #[derive(Clone)] diff --git a/mm2src/coins/z_coin/tx_history_events.rs b/mm2src/coins/z_coin/tx_history_events.rs index 485c1e8053..3be936234b 100644 --- a/mm2src/coins/z_coin/tx_history_events.rs +++ b/mm2src/coins/z_coin/tx_history_events.rs @@ -22,17 +22,23 @@ impl<'a> DeriveStreamerId<'a> for ZCoinTxHistoryEventStreamer { type InitParam = ZCoin; type DeriveParam = &'a str; - fn new(coin: Self::InitParam) -> Self { Self { coin } } + fn new(coin: Self::InitParam) -> Self { + Self { coin } + } #[inline(always)] - fn derive_streamer_id(coin: Self::DeriveParam) -> StreamerId { StreamerId::TxHistory { coin: coin.to_string() } } + fn derive_streamer_id(coin: Self::DeriveParam) -> StreamerId { + StreamerId::TxHistory { coin: coin.to_string() } + } } #[async_trait] impl EventStreamer for ZCoinTxHistoryEventStreamer { type DataInType = Vec>; - fn streamer_id(&self) -> StreamerId { Self::derive_streamer_id(self.coin.ticker()) } + fn streamer_id(&self) -> StreamerId { + Self::derive_streamer_id(self.coin.ticker()) + } async fn handle( self, @@ -75,15 +81,21 @@ enum GetTxDetailsError { } impl From> for GetTxDetailsError { - fn from(e: MmError) -> Self { GetTxDetailsError::UtxoRpcError(e.into_inner()) } + fn from(e: MmError) -> Self { + GetTxDetailsError::UtxoRpcError(e.into_inner()) + } } impl From> for GetTxDetailsError { - fn from(e: MmError) -> Self { GetTxDetailsError::DbError(e.to_string()) } + fn from(e: MmError) -> Self { + GetTxDetailsError::DbError(e.to_string()) + } } impl From> for GetTxDetailsError { - fn from(e: MmError) -> Self { GetTxDetailsError::Internal(e.into_inner()) } + fn from(e: MmError) -> Self { + GetTxDetailsError::Internal(e.into_inner()) + } } async fn get_tx_details(coin: &ZCoin, txs: Vec>) -> Result, GetTxDetailsError> { diff --git a/mm2src/coins/z_coin/tx_streaming_tests/mod.rs b/mm2src/coins/z_coin/tx_streaming_tests/mod.rs index 852bbbb768..d3122e5bc3 100644 --- a/mm2src/coins/z_coin/tx_streaming_tests/mod.rs +++ b/mm2src/coins/z_coin/tx_streaming_tests/mod.rs @@ -1,5 +1,7 @@ -#[cfg(not(target_arch = "wasm32"))] mod native; -#[cfg(target_arch = "wasm32")] mod wasm; +#[cfg(not(target_arch = "wasm32"))] +mod native; +#[cfg(target_arch = "wasm32")] +mod wasm; use common::now_sec; use mm2_test_helpers::for_tests::{PIRATE_ELECTRUMS, PIRATE_LIGHTWALLETD_URLS}; diff --git a/mm2src/coins/z_coin/z_balance_streaming.rs b/mm2src/coins/z_coin/z_balance_streaming.rs index 45bdaa73d3..dce8671ea7 100644 --- a/mm2src/coins/z_coin/z_balance_streaming.rs +++ b/mm2src/coins/z_coin/z_balance_streaming.rs @@ -16,10 +16,14 @@ impl<'a> DeriveStreamerId<'a> for ZCoinBalanceEventStreamer { type InitParam = ZCoin; type DeriveParam = &'a str; - fn new(coin: Self::InitParam) -> Self { Self { coin } } + fn new(coin: Self::InitParam) -> Self { + Self { coin } + } #[inline(always)] - fn derive_streamer_id(coin: Self::DeriveParam) -> StreamerId { StreamerId::Balance { coin: coin.to_string() } } + fn derive_streamer_id(coin: Self::DeriveParam) -> StreamerId { + StreamerId::Balance { coin: coin.to_string() } + } } #[async_trait] diff --git a/mm2src/coins/z_coin/z_coin_errors.rs b/mm2src/coins/z_coin/z_coin_errors.rs index 1590fafa39..200678ba90 100644 --- a/mm2src/coins/z_coin/z_coin_errors.rs +++ b/mm2src/coins/z_coin/z_coin_errors.rs @@ -22,7 +22,8 @@ use rpc::v1::types::{Bytes as BytesJson, H256 as H256Json}; use zcash_client_backend::data_api::error::ChainInvalid; #[cfg(not(target_arch = "wasm32"))] use zcash_client_sqlite::error::SqliteClientError; -#[cfg(target_arch = "wasm32")] use zcash_extras::NoteId; +#[cfg(target_arch = "wasm32")] +use zcash_extras::NoteId; use zcash_primitives::consensus::BlockHeight; use zcash_primitives::transaction::builder::Error as ZTxBuilderError; @@ -40,29 +41,41 @@ pub enum UpdateBlocksCacheErr { } impl From for UpdateBlocksCacheErr { - fn from(err: ZcoinStorageError) -> Self { UpdateBlocksCacheErr::ZcashDBError(err.to_string()) } + fn from(err: ZcoinStorageError) -> Self { + UpdateBlocksCacheErr::ZcashDBError(err.to_string()) + } } impl From for UpdateBlocksCacheErr { - fn from(err: tonic::Status) -> Self { UpdateBlocksCacheErr::GrpcError(err) } + fn from(err: tonic::Status) -> Self { + UpdateBlocksCacheErr::GrpcError(err) + } } #[cfg(not(target_arch = "wasm32"))] impl From for UpdateBlocksCacheErr { - fn from(err: SqliteError) -> Self { UpdateBlocksCacheErr::ZcashDBError(err.to_string()) } + fn from(err: SqliteError) -> Self { + UpdateBlocksCacheErr::ZcashDBError(err.to_string()) + } } #[cfg(not(target_arch = "wasm32"))] impl From for UpdateBlocksCacheErr { - fn from(err: SqliteClientError) -> Self { UpdateBlocksCacheErr::ZcashDBError(err.to_string()) } + fn from(err: SqliteClientError) -> Self { + UpdateBlocksCacheErr::ZcashDBError(err.to_string()) + } } impl From for UpdateBlocksCacheErr { - fn from(err: UtxoRpcError) -> Self { UpdateBlocksCacheErr::UtxoRpcError(err) } + fn from(err: UtxoRpcError) -> Self { + UpdateBlocksCacheErr::UtxoRpcError(err) + } } impl From for UpdateBlocksCacheErr { - fn from(err: JsonRpcError) -> Self { UpdateBlocksCacheErr::JsonRpcError(err) } + fn from(err: JsonRpcError) -> Self { + UpdateBlocksCacheErr::JsonRpcError(err) + } } /// This enum encompasses various error scenarios that may arise @@ -81,16 +94,22 @@ pub enum ZcoinClientInitError { } impl From for ZcoinClientInitError { - fn from(err: ZcoinStorageError) -> Self { ZcoinClientInitError::ZcoinStorageError(err.to_string()) } + fn from(err: ZcoinStorageError) -> Self { + ZcoinClientInitError::ZcoinStorageError(err.to_string()) + } } impl From for ZcoinClientInitError { - fn from(err: UpdateBlocksCacheErr) -> Self { ZcoinClientInitError::UpdateBlocksCacheErr(err) } + fn from(err: UpdateBlocksCacheErr) -> Self { + ZcoinClientInitError::UpdateBlocksCacheErr(err) + } } #[cfg(not(target_arch = "wasm32"))] impl From for ZcoinClientInitError { - fn from(err: SqliteClientError) -> Self { ZcoinClientInitError::ZcoinStorageError(err.to_string()) } + fn from(err: SqliteClientError) -> Self { + ZcoinClientInitError::ZcoinStorageError(err.to_string()) + } } #[derive(Debug, Display)] @@ -137,24 +156,34 @@ pub enum GenTxError { } impl From for GenTxError { - fn from(err: GetUnspentWitnessErr) -> GenTxError { GenTxError::GetWitnessErr(err) } + fn from(err: GetUnspentWitnessErr) -> GenTxError { + GenTxError::GetWitnessErr(err) + } } impl From for GenTxError { - fn from(err: NumConversError) -> GenTxError { GenTxError::NumConversion(err) } + fn from(err: NumConversError) -> GenTxError { + GenTxError::NumConversion(err) + } } impl From for GenTxError { - fn from(err: UtxoRpcError) -> GenTxError { GenTxError::Rpc(err) } + fn from(err: UtxoRpcError) -> GenTxError { + GenTxError::Rpc(err) + } } impl From for GenTxError { - fn from(err: ZTxBuilderError) -> GenTxError { GenTxError::TxBuilderError(err) } + fn from(err: ZTxBuilderError) -> GenTxError { + GenTxError::TxBuilderError(err) + } } #[cfg(not(target_arch = "wasm32"))] impl From for GenTxError { - fn from(err: SqliteClientError) -> Self { GenTxError::LightClientErr(err.to_string()) } + fn from(err: SqliteClientError) -> Self { + GenTxError::LightClientErr(err.to_string()) + } } impl From for WithdrawError { @@ -193,7 +222,9 @@ pub struct BlockchainScanStopped {} impl From for GenTxError { #[inline] - fn from(_: BlockchainScanStopped) -> Self { GenTxError::BlockchainScanStopped } + fn from(_: BlockchainScanStopped) -> Self { + GenTxError::BlockchainScanStopped + } } #[derive(Debug, Display)] @@ -208,19 +239,27 @@ pub enum SendOutputsErr { } impl From for SendOutputsErr { - fn from(err: PrivKeyPolicyNotAllowed) -> Self { SendOutputsErr::PrivKeyPolicyNotAllowed(err) } + fn from(err: PrivKeyPolicyNotAllowed) -> Self { + SendOutputsErr::PrivKeyPolicyNotAllowed(err) + } } impl From for SendOutputsErr { - fn from(err: GenTxError) -> SendOutputsErr { SendOutputsErr::GenTxError(err) } + fn from(err: GenTxError) -> SendOutputsErr { + SendOutputsErr::GenTxError(err) + } } impl From for SendOutputsErr { - fn from(err: NumConversError) -> SendOutputsErr { SendOutputsErr::NumConversion(err) } + fn from(err: NumConversError) -> SendOutputsErr { + SendOutputsErr::NumConversion(err) + } } impl From for SendOutputsErr { - fn from(err: UtxoRpcError) -> SendOutputsErr { SendOutputsErr::Rpc(err) } + fn from(err: UtxoRpcError) -> SendOutputsErr { + SendOutputsErr::Rpc(err) + } } #[derive(Debug, Display)] @@ -233,7 +272,9 @@ pub enum GetUnspentWitnessErr { #[cfg(not(target_arch = "wasm32"))] impl From for GetUnspentWitnessErr { - fn from(err: SqliteError) -> GetUnspentWitnessErr { GetUnspentWitnessErr::ZcashDBError(err.to_string()) } + fn from(err: SqliteError) -> GetUnspentWitnessErr { + GetUnspentWitnessErr::ZcashDBError(err.to_string()) + } } #[derive(Debug, Display, EnumFromStringify)] @@ -257,19 +298,27 @@ pub enum ZCoinBuildError { } impl From for ZCoinBuildError { - fn from(err: UtxoRpcError) -> ZCoinBuildError { ZCoinBuildError::Rpc(err.to_string()) } + fn from(err: UtxoRpcError) -> ZCoinBuildError { + ZCoinBuildError::Rpc(err.to_string()) + } } impl From for ZCoinBuildError { - fn from(err: std::io::Error) -> ZCoinBuildError { ZCoinBuildError::Io(err) } + fn from(err: std::io::Error) -> ZCoinBuildError { + ZCoinBuildError::Io(err) + } } impl From for ZCoinBuildError { - fn from(err: UtxoCoinBuildError) -> Self { ZCoinBuildError::UtxoBuilderError(err) } + fn from(err: UtxoCoinBuildError) -> Self { + ZCoinBuildError::UtxoBuilderError(err) + } } impl From for ZCoinBuildError { - fn from(err: ZcoinClientInitError) -> Self { ZCoinBuildError::RpcClientInitErr(err) } + fn from(err: ZcoinClientInitError) -> Self { + ZCoinBuildError::RpcClientInitErr(err) + } } #[derive(Debug, Display)] @@ -282,22 +331,30 @@ pub(crate) enum ZTxHistoryError { } impl From for MyTxHistoryErrorV2 { - fn from(err: ZTxHistoryError) -> Self { MyTxHistoryErrorV2::StorageError(err.to_string()) } + fn from(err: ZTxHistoryError) -> Self { + MyTxHistoryErrorV2::StorageError(err.to_string()) + } } #[cfg(not(target_arch = "wasm32"))] impl From for ZTxHistoryError { - fn from(err: SqliteError) -> Self { ZTxHistoryError::Sql(err) } + fn from(err: SqliteError) -> Self { + ZTxHistoryError::Sql(err) + } } #[cfg(target_arch = "wasm32")] impl From for ZTxHistoryError { - fn from(err: DbTransactionError) -> Self { ZTxHistoryError::IndexedDbError(err.to_string()) } + fn from(err: DbTransactionError) -> Self { + ZTxHistoryError::IndexedDbError(err.to_string()) + } } #[cfg(target_arch = "wasm32")] impl From for ZTxHistoryError { - fn from(err: CursorError) -> Self { ZTxHistoryError::IndexedDbError(err.to_string()) } + fn from(err: CursorError) -> Self { + ZTxHistoryError::IndexedDbError(err.to_string()) + } } #[derive(Debug)] @@ -320,7 +377,9 @@ pub enum ZCoinBalanceError { } impl From for ZCoinBalanceError { - fn from(value: ZcoinStorageError) -> Self { ZCoinBalanceError::BalanceError(value.to_string()) } + fn from(value: ZcoinStorageError) -> Self { + ZCoinBalanceError::BalanceError(value.to_string()) + } } /// The `ValidateBlocksError` enum encapsulates different types of errors that may occur @@ -347,11 +406,15 @@ pub enum ValidateBlocksError { } impl From for ZcoinStorageError { - fn from(value: ValidateBlocksError) -> Self { Self::ValidateBlocksError(value) } + fn from(value: ValidateBlocksError) -> Self { + Self::ValidateBlocksError(value) + } } impl From> for ValidateBlocksError { - fn from(value: MmError) -> Self { Self::ZcoinStorageError(value.to_string()) } + fn from(value: MmError) -> Self { + Self::ZcoinStorageError(value.to_string()) + } } impl ValidateBlocksError { @@ -438,7 +501,9 @@ pub enum ZcoinStorageError { } impl From for ZcoinStorageError { - fn from(err: UpdateBlocksCacheErr) -> Self { ZcoinStorageError::DbError(err.to_string()) } + fn from(err: UpdateBlocksCacheErr) -> Self { + ZcoinStorageError::DbError(err.to_string()) + } } #[cfg(target_arch = "wasm32")] diff --git a/mm2src/coins/z_coin/z_htlc.rs b/mm2src/coins/z_coin/z_htlc.rs index 0d68f7258e..2f8b2c1852 100644 --- a/mm2src/coins/z_coin/z_htlc.rs +++ b/mm2src/coins/z_coin/z_htlc.rs @@ -133,19 +133,27 @@ pub enum ZP2SHSpendError { } impl From for ZP2SHSpendError { - fn from(tx_builder: ZTxBuilderError) -> ZP2SHSpendError { ZP2SHSpendError::ZTxBuilderError(tx_builder) } + fn from(tx_builder: ZTxBuilderError) -> ZP2SHSpendError { + ZP2SHSpendError::ZTxBuilderError(tx_builder) + } } impl From for ZP2SHSpendError { - fn from(err: PrivKeyPolicyNotAllowed) -> Self { ZP2SHSpendError::PrivKeyPolicyNotAllowed(err) } + fn from(err: PrivKeyPolicyNotAllowed) -> Self { + ZP2SHSpendError::PrivKeyPolicyNotAllowed(err) + } } impl From for ZP2SHSpendError { - fn from(rpc: UtxoRpcError) -> ZP2SHSpendError { ZP2SHSpendError::Rpc(rpc) } + fn from(rpc: UtxoRpcError) -> ZP2SHSpendError { + ZP2SHSpendError::Rpc(rpc) + } } impl From for ZP2SHSpendError { - fn from(e: std::io::Error) -> Self { ZP2SHSpendError::Io(e) } + fn from(e: std::io::Error) -> Self { + ZP2SHSpendError::Io(e) + } } impl ZP2SHSpendError { diff --git a/mm2src/coins/z_coin/z_rpc.rs b/mm2src/coins/z_coin/z_rpc.rs index c8b6e917c4..4d3ae4ecbb 100644 --- a/mm2src/coins/z_coin/z_rpc.rs +++ b/mm2src/coins/z_coin/z_rpc.rs @@ -383,7 +383,9 @@ impl ZRpcOps for NativeClient { Ok(self.get_block_count().compat().await.map_mm_err()?) } - async fn get_tree_state(&self, _height: u64) -> Result> { todo!() } + async fn get_tree_state(&self, _height: u64) -> Result> { + todo!() + } async fn scan_blocks( &self, diff --git a/mm2src/coins/z_coin/z_unit_tests.rs b/mm2src/coins/z_coin/z_unit_tests.rs index 25ce04ff3b..c4f8dcbb5d 100644 --- a/mm2src/coins/z_coin/z_unit_tests.rs +++ b/mm2src/coins/z_coin/z_unit_tests.rs @@ -30,10 +30,10 @@ const GITHUB_CLIENT_USER_AGENT: &str = "mm2"; async fn fetch_and_save_params(param: &str, fname: &Path) -> Result<(), String> { let url = Url::parse(&format!("{}/", DOWNLOAD_URL)).unwrap().join(param).unwrap(); println!("downloading zcash params {}...", url); - let data = slurp_url_with_headers(url.as_str(), vec![( - http::header::USER_AGENT.as_str(), - GITHUB_CLIENT_USER_AGENT, - )]) + let data = slurp_url_with_headers( + url.as_str(), + vec![(http::header::USER_AGENT.as_str(), GITHUB_CLIENT_USER_AGENT)], + ) .await .map_err(|err| format!("could not download zcash params: {}", err))? .2; diff --git a/mm2src/coins_activation/Cargo.toml b/mm2src/coins_activation/Cargo.toml index 69f020c809..dc9b2641f9 100644 --- a/mm2src/coins_activation/Cargo.toml +++ b/mm2src/coins_activation/Cargo.toml @@ -26,7 +26,7 @@ mm2_err_handle = { path = "../mm2_err_handle" } mm2_event_stream = { path = "../mm2_event_stream" } mm2_metrics = { path = "../mm2_metrics" } mm2_number = { path = "../mm2_number" } -parking_lot = { workspace = true, features = ["nightly"] } +parking_lot = { workspace = true } rpc = { path = "../mm2_bitcoin/rpc" } rpc_task = { path = "../rpc_task" } secp256k1 = { version = "0.24" } diff --git a/mm2src/coins_activation/src/bch_with_tokens_activation.rs b/mm2src/coins_activation/src/bch_with_tokens_activation.rs index 0513f5779e..bd3f54a471 100644 --- a/mm2src/coins_activation/src/bch_with_tokens_activation.rs +++ b/mm2src/coins_activation/src/bch_with_tokens_activation.rs @@ -11,8 +11,10 @@ use coins::utxo::slp::{EnableSlpError, SlpProtocolConf, SlpToken}; use coins::utxo::utxo_tx_history_v2::bch_and_slp_history_loop; use coins::utxo::UtxoCommonOps; use coins::MmCoinEnum; -use coins::{CoinBalance, CoinProtocol, MarketCoinOps, MmCoin, PrivKeyBuildPolicy, PrivKeyPolicyNotAllowed, - UnexpectedDerivationMethod}; +use coins::{ + CoinBalance, CoinProtocol, MarketCoinOps, MmCoin, PrivKeyBuildPolicy, PrivKeyPolicyNotAllowed, + UnexpectedDerivationMethod, +}; use common::executor::{AbortSettings, SpawnAbortable}; use common::Future01CompatExt; use common::{drop_mutability, true_f}; @@ -88,11 +90,15 @@ impl TokenInitializer for SlpTokenInitializer { Ok(tokens) } - fn platform_coin(&self) -> &BchCoin { &self.platform_coin } + fn platform_coin(&self) -> &BchCoin { + &self.platform_coin + } } impl RegisterTokenInfo for BchCoin { - fn register_token_info(&self, token: &SlpToken) { self.add_slp_token_info(token.ticker().into(), token.get_info()) } + fn register_token_info(&self, token: &SlpToken) { + self.add_slp_token_info(token.ticker().into(), token.get_info()) + } } impl From for EnablePlatformCoinWithTokensError { @@ -129,11 +135,15 @@ pub struct BchWithTokensActivationRequest { } impl TxHistory for BchWithTokensActivationRequest { - fn tx_history(&self) -> bool { self.platform_request.utxo_params.tx_history } + fn tx_history(&self) -> bool { + self.platform_request.utxo_params.tx_history + } } impl ActivationRequestInfo for BchWithTokensActivationRequest { - fn is_hw_policy(&self) -> bool { self.platform_request.utxo_params.is_hw_policy() } + fn is_hw_policy(&self) -> bool { + self.platform_request.utxo_params.is_hw_policy() + } } pub struct BchProtocolInfo { @@ -170,7 +180,9 @@ impl GetPlatformBalance for BchWithTokensActivationResult { } impl CurrentBlock for BchWithTokensActivationResult { - fn current_block(&self) -> u64 { self.current_block } + fn current_block(&self) -> u64 { + self.current_block + } } #[derive(Debug, Clone)] @@ -191,7 +203,9 @@ pub enum BchWithTokensActivationError { } impl From for BchWithTokensActivationError { - fn from(err: UtxoRpcError) -> Self { BchWithTokensActivationError::Transport(err.to_string()) } + fn from(err: UtxoRpcError) -> Self { + BchWithTokensActivationError::Transport(err.to_string()) + } } impl From for BchWithTokensActivationError { @@ -201,11 +215,15 @@ impl From for BchWithTokensActivationError { } impl From for BchWithTokensActivationError { - fn from(e: PrivKeyPolicyNotAllowed) -> Self { BchWithTokensActivationError::PrivKeyPolicyNotAllowed(e) } + fn from(e: PrivKeyPolicyNotAllowed) -> Self { + BchWithTokensActivationError::PrivKeyPolicyNotAllowed(e) + } } impl From for BchWithTokensActivationError { - fn from(e: CryptoCtxError) -> Self { BchWithTokensActivationError::Internal(e.to_string()) } + fn from(e: CryptoCtxError) -> Self { + BchWithTokensActivationError::Internal(e.to_string()) + } } #[async_trait] diff --git a/mm2src/coins_activation/src/erc20_token_activation.rs b/mm2src/coins_activation/src/erc20_token_activation.rs index e719ad6404..93f4ff4b25 100644 --- a/mm2src/coins_activation/src/erc20_token_activation.rs +++ b/mm2src/coins_activation/src/erc20_token_activation.rs @@ -1,12 +1,18 @@ -use crate::{prelude::{TryFromCoinProtocol, TryPlatformCoinFromMmCoinEnum}, - token::{EnableTokenError, TokenActivationOps, TokenProtocolParams}}; +use crate::{ + prelude::{TryFromCoinProtocol, TryPlatformCoinFromMmCoinEnum}, + token::{EnableTokenError, TokenActivationOps, TokenProtocolParams}, +}; use async_trait::async_trait; use coins::eth::v2_activation::{EthTokenActivationParams, EthTokenProtocol, NftProtocol, NftProviderEnum}; use coins::hd_wallet::DisplayAddress; use coins::nft::nft_structs::NftInfo; -use coins::{eth::{v2_activation::{Erc20Protocol, EthTokenActivationError}, - valid_addr_from_str, EthCoin}, - CoinBalance, CoinProtocol, CoinWithDerivationMethod, MarketCoinOps, MmCoin, MmCoinEnum}; +use coins::{ + eth::{ + v2_activation::{Erc20Protocol, EthTokenActivationError}, + valid_addr_from_str, EthCoin, + }, + CoinBalance, CoinProtocol, CoinWithDerivationMethod, MarketCoinOps, MmCoin, MmCoinEnum, +}; use common::Future01CompatExt; use mm2_err_handle::prelude::*; use serde::Serialize; @@ -113,7 +119,9 @@ impl TryFromCoinProtocol for EthTokenProtocol { } impl TokenProtocolParams for Erc20Protocol { - fn platform_coin_ticker(&self) -> &str { &self.platform } + fn platform_coin_ticker(&self) -> &str { + &self.platform + } } impl TokenProtocolParams for EthTokenProtocol { diff --git a/mm2src/coins_activation/src/eth_with_token_activation.rs b/mm2src/coins_activation/src/eth_with_token_activation.rs index d3ac19b0cb..d3fd52d474 100644 --- a/mm2src/coins_activation/src/eth_with_token_activation.rs +++ b/mm2src/coins_activation/src/eth_with_token_activation.rs @@ -1,24 +1,27 @@ use crate::context::CoinsActivationContext; -use crate::platform_coin_with_tokens::{platform_coin_xpub_extractor_rpc_statuses, EnablePlatformCoinWithTokensError, - GetPlatformBalance, InitPlatformCoinWithTokensAwaitingStatus, - InitPlatformCoinWithTokensInProgressStatus, - InitPlatformCoinWithTokensTaskManagerShared, - InitPlatformCoinWithTokensUserAction, InitTokensAsMmCoinsError, - PlatformCoinWithTokensActivationOps, RegisterTokenInfo, TokenActivationParams, - TokenActivationRequest, TokenAsMmCoinInitializer, TokenInitializer, TokenOf}; +use crate::platform_coin_with_tokens::{ + platform_coin_xpub_extractor_rpc_statuses, EnablePlatformCoinWithTokensError, GetPlatformBalance, + InitPlatformCoinWithTokensAwaitingStatus, InitPlatformCoinWithTokensInProgressStatus, + InitPlatformCoinWithTokensTaskManagerShared, InitPlatformCoinWithTokensUserAction, InitTokensAsMmCoinsError, + PlatformCoinWithTokensActivationOps, RegisterTokenInfo, TokenActivationParams, TokenActivationRequest, + TokenAsMmCoinInitializer, TokenInitializer, TokenOf, +}; use crate::prelude::*; use async_trait::async_trait; use coins::coin_balance::{CoinBalanceReport, EnableCoinBalanceOps}; -use coins::eth::v2_activation::{eth_coin_from_conf_and_request_v2, Erc20Protocol, Erc20TokenActivationRequest, - EthActivationV2Error, EthActivationV2Request, EthPrivKeyActivationPolicy, - EthTokenActivationError, NftActivationRequest, NftProviderEnum}; +use coins::eth::v2_activation::{ + eth_coin_from_conf_and_request_v2, Erc20Protocol, Erc20TokenActivationRequest, EthActivationV2Error, + EthActivationV2Request, EthPrivKeyActivationPolicy, EthTokenActivationError, NftActivationRequest, NftProviderEnum, +}; use coins::eth::wallet_connect::eth_request_wc_personal_sign; use coins::eth::{ChainSpec, Erc20TokenDetails, EthCoin, EthCoinType, EthPrivKeyBuildPolicy}; use coins::hd_wallet::{DisplayAddress, RpcTaskXPubExtractor}; use coins::my_tx_history_v2::TxHistoryStorage; use coins::nft::nft_structs::NftInfo; -use coins::{CoinBalance, CoinBalanceMap, CoinProtocol, CoinWithDerivationMethod, DerivationMethod, MarketCoinOps, - MmCoin, MmCoinEnum}; +use coins::{ + CoinBalance, CoinBalanceMap, CoinProtocol, CoinWithDerivationMethod, DerivationMethod, MarketCoinOps, MmCoin, + MmCoinEnum, +}; use kdf_walletconnect::WalletConnectCtx; use crate::platform_coin_with_tokens::InitPlatformCoinWithTokensTask; @@ -165,7 +168,9 @@ impl TokenInitializer for Erc20Initializer { Ok(tokens) } - fn platform_coin(&self) -> &EthCoin { &self.platform_coin } + fn platform_coin(&self) -> &EthCoin { + &self.platform_coin + } } #[derive(Clone, Deserialize)] @@ -179,11 +184,15 @@ pub struct EthWithTokensActivationRequest { } impl TxHistory for EthWithTokensActivationRequest { - fn tx_history(&self) -> bool { false } + fn tx_history(&self) -> bool { + false + } } impl ActivationRequestInfo for EthWithTokensActivationRequest { - fn is_hw_policy(&self) -> bool { self.platform_request.priv_key_policy.is_hw_policy() } + fn is_hw_policy(&self) -> bool { + self.platform_request.priv_key_policy.is_hw_policy() + } } impl TokenOf for EthCoin { @@ -197,10 +206,13 @@ impl RegisterTokenInfo for EthCoin { return; } - self.add_erc_token_info(token.ticker().to_string(), Erc20TokenDetails { - token_address: token.erc20_token_address().unwrap(), - decimals: token.decimals(), - }); + self.add_erc_token_info( + token.ticker().to_string(), + Erc20TokenDetails { + token_address: token.erc20_token_address().unwrap(), + decimals: token.decimals(), + }, + ); } } diff --git a/mm2src/coins_activation/src/init_erc20_token_activation.rs b/mm2src/coins_activation/src/init_erc20_token_activation.rs index 491947e8bf..73fb29fc82 100644 --- a/mm2src/coins_activation/src/init_erc20_token_activation.rs +++ b/mm2src/coins_activation/src/init_erc20_token_activation.rs @@ -1,7 +1,9 @@ use crate::context::CoinsActivationContext; -use crate::init_token::{token_xpub_extractor_rpc_statuses, InitTokenActivationOps, InitTokenActivationResult, - InitTokenAwaitingStatus, InitTokenError, InitTokenInProgressStatus, InitTokenTaskHandleShared, - InitTokenTaskManagerShared, InitTokenUserAction}; +use crate::init_token::{ + token_xpub_extractor_rpc_statuses, InitTokenActivationOps, InitTokenActivationResult, InitTokenAwaitingStatus, + InitTokenError, InitTokenInProgressStatus, InitTokenTaskHandleShared, InitTokenTaskManagerShared, + InitTokenUserAction, +}; use async_trait::async_trait; use coins::coin_balance::{EnableCoinBalanceError, EnableCoinBalanceOps}; use coins::eth::v2_activation::{Erc20Protocol, EthTokenActivationError, InitErc20TokenActivationRequest}; diff --git a/mm2src/coins_activation/src/init_token.rs b/mm2src/coins_activation/src/init_token.rs index 5a72ce3d4a..54a11e886a 100644 --- a/mm2src/coins_activation/src/init_token.rs +++ b/mm2src/coins_activation/src/init_token.rs @@ -1,12 +1,16 @@ use crate::context::CoinsActivationContext; use crate::platform_coin_with_tokens::{RegisterTokenInfo, TokenOf}; -use crate::prelude::{coin_conf_with_protocol, CoinConfWithProtocolError, CurrentBlock, TryFromCoinProtocol, - TryPlatformCoinFromMmCoinEnum}; +use crate::prelude::{ + coin_conf_with_protocol, CoinConfWithProtocolError, CurrentBlock, TryFromCoinProtocol, + TryPlatformCoinFromMmCoinEnum, +}; use crate::token::TokenProtocolParams; use async_trait::async_trait; use coins::coin_balance::CoinBalanceReport; -use coins::{lp_coinfind, lp_coinfind_or_err, CoinBalanceMap, CoinProtocol, CoinsContext, CustomTokenError, MmCoinEnum, - RegisterCoinError}; +use coins::{ + lp_coinfind, lp_coinfind_or_err, CoinBalanceMap, CoinProtocol, CoinsContext, CustomTokenError, MmCoinEnum, + RegisterCoinError, +}; use common::{log, HttpStatusCode, StatusCode, SuccessResponse}; use crypto::hw_rpc_task::{HwConnectStatuses, HwRpcTaskAwaitingStatus, HwRpcTaskUserAction}; use crypto::HwRpcError; @@ -14,10 +18,14 @@ use derive_more::Display; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::mm_error::{MmError, MmResult, NotMmError}; use mm2_err_handle::prelude::*; -use rpc_task::rpc_common::{CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError, - RpcTaskStatusRequest, RpcTaskUserActionError, RpcTaskUserActionRequest}; -use rpc_task::{RpcInitReq, RpcTask, RpcTaskError, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, - RpcTaskStatus, RpcTaskTypes, TaskId}; +use rpc_task::rpc_common::{ + CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError, RpcTaskStatusRequest, + RpcTaskUserActionError, RpcTaskUserActionRequest, +}; +use rpc_task::{ + RpcInitReq, RpcTask, RpcTaskError, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, + RpcTaskTypes, TaskId, +}; use ser_error_derive::SerializeErrorType; use serde_derive::{Deserialize, Serialize}; use serde_json::Value as Json; @@ -252,7 +260,9 @@ pub struct InitTokenActivationResult { } impl CurrentBlock for InitTokenActivationResult { - fn current_block(&self) -> u64 { self.current_block } + fn current_block(&self) -> u64 { + self.current_block + } } /// Trait for the initial status of the token initialization task. @@ -274,7 +284,9 @@ pub enum InitTokenInProgressStatus { } impl InitTokenInitialStatus for InitTokenInProgressStatus { - fn initial_status() -> Self { InitTokenInProgressStatus::ActivatingCoin } + fn initial_status() -> Self { + InitTokenInProgressStatus::ActivatingCoin + } } pub(crate) fn token_xpub_extractor_rpc_statuses( diff --git a/mm2src/coins_activation/src/l2/init_l2.rs b/mm2src/coins_activation/src/l2/init_l2.rs index d08537fd1a..6e49fb570d 100644 --- a/mm2src/coins_activation/src/l2/init_l2.rs +++ b/mm2src/coins_activation/src/l2/init_l2.rs @@ -10,8 +10,9 @@ use common::SuccessResponse; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; use rpc_task::rpc_common::{CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusRequest, RpcTaskUserActionRequest}; -use rpc_task::{RpcInitReq, RpcTask, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, - RpcTaskTypes}; +use rpc_task::{ + RpcInitReq, RpcTask, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, RpcTaskTypes, +}; use serde_derive::Deserialize; use serde_json::Value as Json; diff --git a/mm2src/coins_activation/src/lib.rs b/mm2src/coins_activation/src/lib.rs index 8020f91f27..318305fa17 100644 --- a/mm2src/coins_activation/src/lib.rs +++ b/mm2src/coins_activation/src/lib.rs @@ -5,10 +5,12 @@ mod eth_with_token_activation; mod init_erc20_token_activation; mod init_token; mod l2; -#[cfg(not(target_arch = "wasm32"))] mod lightning_activation; +#[cfg(not(target_arch = "wasm32"))] +mod lightning_activation; mod platform_coin_with_tokens; mod prelude; -#[cfg(feature = "enable-sia")] mod sia_coin_activation; +#[cfg(feature = "enable-sia")] +mod sia_coin_activation; mod slp_token_activation; mod standalone_coin; mod tendermint_token_activation; @@ -22,9 +24,12 @@ mod z_coin_activation; pub use init_token::{cancel_init_token, init_token, init_token_status, init_token_user_action}; pub use l2::{cancel_init_l2, init_l2, init_l2_status, init_l2_user_action}; pub use platform_coin_with_tokens::for_tests as platform_for_tests; -pub use platform_coin_with_tokens::{cancel_init_platform_coin_with_tokens, enable_platform_coin_with_tokens, - init_platform_coin_with_tokens, init_platform_coin_with_tokens_status, - init_platform_coin_with_tokens_user_action}; -pub use standalone_coin::{cancel_init_standalone_coin, init_standalone_coin, init_standalone_coin_status, - init_standalone_coin_user_action, InitStandaloneCoinReq, InitStandaloneCoinStatusRequest}; +pub use platform_coin_with_tokens::{ + cancel_init_platform_coin_with_tokens, enable_platform_coin_with_tokens, init_platform_coin_with_tokens, + init_platform_coin_with_tokens_status, init_platform_coin_with_tokens_user_action, +}; +pub use standalone_coin::{ + cancel_init_standalone_coin, init_standalone_coin, init_standalone_coin_status, init_standalone_coin_user_action, + InitStandaloneCoinReq, InitStandaloneCoinStatusRequest, +}; pub use token::enable_token; diff --git a/mm2src/coins_activation/src/lightning_activation.rs b/mm2src/coins_activation/src/lightning_activation.rs index e4a1a080ad..0c21c18d3c 100644 --- a/mm2src/coins_activation/src/lightning_activation.rs +++ b/mm2src/coins_activation/src/lightning_activation.rs @@ -1,6 +1,8 @@ use crate::context::CoinsActivationContext; -use crate::l2::{InitL2ActivationOps, InitL2Error, InitL2InitialStatus, InitL2TaskHandleShared, - InitL2TaskManagerShared, L2ProtocolParams}; +use crate::l2::{ + InitL2ActivationOps, InitL2Error, InitL2InitialStatus, InitL2TaskHandleShared, InitL2TaskManagerShared, + L2ProtocolParams, +}; use crate::prelude::*; use async_trait::async_trait; use coins::coin_errors::MyAddressError; @@ -10,8 +12,10 @@ use coins::lightning::ln_events::{init_abortable_events, LightningEventHandler}; use coins::lightning::ln_p2p::{connect_to_ln_nodes_loop, init_peer_manager, ln_node_announcement_loop}; use coins::lightning::ln_platform::Platform; use coins::lightning::ln_storage::LightningStorage; -use coins::lightning::ln_utils::{get_open_channels_nodes_addresses, init_channel_manager, init_db, init_keys_manager, - init_persister, PAYMENT_RETRY_ATTEMPTS}; +use coins::lightning::ln_utils::{ + get_open_channels_nodes_addresses, init_channel_manager, init_db, init_keys_manager, init_persister, + PAYMENT_RETRY_ATTEMPTS, +}; use coins::lightning::{InvoicePayer, LightningCoin}; use coins::utxo::utxo_standard::UtxoStandardCoin; use coins::utxo::UtxoCommonOps; @@ -60,7 +64,9 @@ pub enum LightningInProgressStatus { } impl InitL2InitialStatus for LightningInProgressStatus { - fn initial_status() -> Self { LightningInProgressStatus::ActivatingCoin } + fn initial_status() -> Self { + LightningInProgressStatus::ActivatingCoin + } } impl TryPlatformCoinFromMmCoinEnum for UtxoStandardCoin { @@ -96,7 +102,9 @@ impl TryFromCoinProtocol for LightningProtocolConf { } impl L2ProtocolParams for LightningProtocolConf { - fn platform_coin_ticker(&self) -> &str { &self.platform_coin_ticker } + fn platform_coin_ticker(&self) -> &str { + &self.platform_coin_ticker + } } #[derive(Clone, Debug, Deserialize)] @@ -169,7 +177,9 @@ pub enum LightningInitError { } impl From for LightningInitError { - fn from(err: MyAddressError) -> Self { Self::MyAddressError(err.to_string()) } + fn from(err: MyAddressError) -> Self { + Self::MyAddressError(err.to_string()) + } } impl From for InitL2Error { @@ -200,11 +210,15 @@ impl From for InitL2Error { } impl From for LightningInitError { - fn from(err: EnableLightningError) -> Self { LightningInitError::EnableLightningError(err) } + fn from(err: EnableLightningError) -> Self { + LightningInitError::EnableLightningError(err) + } } impl From for LightningInitError { - fn from(err: LightningValidationErr) -> Self { LightningInitError::LightningValidationErr(err) } + fn from(err: LightningValidationErr) -> Self { + LightningInitError::LightningValidationErr(err) + } } impl From for LightningInitError { diff --git a/mm2src/coins_activation/src/platform_coin_with_tokens.rs b/mm2src/coins_activation/src/platform_coin_with_tokens.rs index 4179f9c85f..fc06eb8a15 100644 --- a/mm2src/coins_activation/src/platform_coin_with_tokens.rs +++ b/mm2src/coins_activation/src/platform_coin_with_tokens.rs @@ -5,8 +5,10 @@ use crate::prelude::*; use async_trait::async_trait; use coins::my_tx_history_v2::TxHistoryStorage; use coins::tx_history_storage::{CreateTxHistoryStorageError, TxHistoryStorageBuilder}; -use coins::{lp_coinfind, lp_coinfind_any, CoinProtocol, CoinsContext, CustomTokenError, MmCoinEnum, - PrivKeyPolicyNotAllowed, UnexpectedDerivationMethod}; +use coins::{ + lp_coinfind, lp_coinfind_any, CoinProtocol, CoinsContext, CustomTokenError, MmCoinEnum, PrivKeyPolicyNotAllowed, + UnexpectedDerivationMethod, +}; use common::{log, HttpStatusCode, StatusCode, SuccessResponse}; use crypto::hw_rpc_task::{HwConnectStatuses, HwRpcTaskAwaitingStatus, HwRpcTaskUserAction}; use crypto::CryptoCtxError; @@ -14,10 +16,14 @@ use derive_more::Display; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; use mm2_number::BigDecimal; -use rpc_task::rpc_common::{CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError, - RpcTaskStatusRequest, RpcTaskUserActionError, RpcTaskUserActionRequest}; -use rpc_task::{RpcInitReq, RpcTask, RpcTaskError, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, - RpcTaskStatus, RpcTaskTypes, TaskId}; +use rpc_task::rpc_common::{ + CancelRpcTaskError, CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusError, RpcTaskStatusRequest, + RpcTaskUserActionError, RpcTaskUserActionRequest, +}; +use rpc_task::{ + RpcInitReq, RpcTask, RpcTaskError, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, + RpcTaskTypes, TaskId, +}; use ser_error_derive::SerializeErrorType; use serde_derive::{Deserialize, Serialize}; use serde_json::Value as Json; @@ -337,7 +343,9 @@ impl From for EnablePlatformCoinWithTokensError { } impl From for EnablePlatformCoinWithTokensError { - fn from(e: CryptoCtxError) -> Self { EnablePlatformCoinWithTokensError::Internal(e.to_string()) } + fn from(e: CryptoCtxError) -> Self { + EnablePlatformCoinWithTokensError::Internal(e.to_string()) + } } impl From for EnablePlatformCoinWithTokensError { @@ -552,7 +560,9 @@ pub enum InitPlatformCoinWithTokensInProgressStatus { } impl InitPlatformCoinWithTokensInitialStatus for InitPlatformCoinWithTokensInProgressStatus { - fn initial_status() -> Self { InitPlatformCoinWithTokensInProgressStatus::ActivatingCoin } + fn initial_status() -> Self { + InitPlatformCoinWithTokensInProgressStatus::ActivatingCoin + } } /// Implementation of the init platform coin with tokens RPC command. @@ -668,10 +678,11 @@ pub mod for_tests { use mm2_err_handle::prelude::MmResult; use rpc_task::{RpcInitReq, RpcTaskStatus}; - use super::{init_platform_coin_with_tokens, init_platform_coin_with_tokens_status, - EnablePlatformCoinWithTokensError, EnablePlatformCoinWithTokensReq, - EnablePlatformCoinWithTokensStatusRequest, InitPlatformCoinWithTokensInitialStatus, - PlatformCoinWithTokensActivationOps}; + use super::{ + init_platform_coin_with_tokens, init_platform_coin_with_tokens_status, EnablePlatformCoinWithTokensError, + EnablePlatformCoinWithTokensReq, EnablePlatformCoinWithTokensStatusRequest, + InitPlatformCoinWithTokensInitialStatus, PlatformCoinWithTokensActivationOps, + }; /// test helper to activate platform coin with waiting for the result pub async fn init_platform_coin_with_tokens_loop( diff --git a/mm2src/coins_activation/src/prelude.rs b/mm2src/coins_activation/src/prelude.rs index 0816ecd7fe..91e9cef58c 100644 --- a/mm2src/coins_activation/src/prelude.rs +++ b/mm2src/coins_activation/src/prelude.rs @@ -20,20 +20,28 @@ pub trait TxHistory { } impl TxHistory for UtxoActivationParams { - fn tx_history(&self) -> bool { self.tx_history } + fn tx_history(&self) -> bool { + self.tx_history + } } impl TxHistory for BchActivationRequest { - fn tx_history(&self) -> bool { self.utxo_params.tx_history } + fn tx_history(&self) -> bool { + self.utxo_params.tx_history + } } #[cfg(feature = "enable-sia")] impl TxHistory for SiaCoinActivationParams { - fn tx_history(&self) -> bool { self.tx_history } + fn tx_history(&self) -> bool { + self.tx_history + } } impl TxHistory for ZcoinActivationParams { - fn tx_history(&self) -> bool { false } + fn tx_history(&self) -> bool { + false + } } pub trait GetAddressesBalances { @@ -151,10 +159,14 @@ pub trait ActivationRequestInfo { } impl ActivationRequestInfo for UtxoActivationParams { - fn is_hw_policy(&self) -> bool { self.priv_key_policy.is_hw_policy() } + fn is_hw_policy(&self) -> bool { + self.priv_key_policy.is_hw_policy() + } } #[cfg(not(target_arch = "wasm32"))] impl ActivationRequestInfo for ZcoinActivationParams { - fn is_hw_policy(&self) -> bool { false } // TODO: fix when device policy is added + fn is_hw_policy(&self) -> bool { + false + } // TODO: fix when device policy is added } diff --git a/mm2src/coins_activation/src/sia_coin_activation.rs b/mm2src/coins_activation/src/sia_coin_activation.rs index e2cd92ddbc..2dac4068d5 100644 --- a/mm2src/coins_activation/src/sia_coin_activation.rs +++ b/mm2src/coins_activation/src/sia_coin_activation.rs @@ -1,14 +1,16 @@ use crate::context::CoinsActivationContext; use crate::prelude::*; -use crate::standalone_coin::{InitStandaloneCoinActivationOps, InitStandaloneCoinError, - InitStandaloneCoinInitialStatus, InitStandaloneCoinTaskHandleShared, - InitStandaloneCoinTaskManagerShared}; +use crate::standalone_coin::{ + InitStandaloneCoinActivationOps, InitStandaloneCoinError, InitStandaloneCoinInitialStatus, + InitStandaloneCoinTaskHandleShared, InitStandaloneCoinTaskManagerShared, +}; use async_trait::async_trait; use coins::coin_balance::{CoinBalanceReport, IguanaWalletBalance}; use coins::coin_errors::MyAddressError; use coins::my_tx_history_v2::TxHistoryStorage; -use coins::siacoin::{sia_coin_from_conf_and_params, SiaCoin, SiaCoinActivationParams, SiaCoinBuildError, - SiaCoinProtocolInfo}; +use coins::siacoin::{ + sia_coin_from_conf_and_params, SiaCoin, SiaCoinActivationParams, SiaCoinBuildError, SiaCoinProtocolInfo, +}; use coins::tx_history_storage::CreateTxHistoryStorageError; use coins::{BalanceError, CoinBalance, CoinProtocol, MarketCoinOps, PrivKeyBuildPolicy, RegisterCoinError}; use crypto::hw_rpc_task::{HwRpcTaskAwaitingStatus, HwRpcTaskUserAction}; @@ -42,7 +44,9 @@ pub struct SiaCoinActivationResult { } impl CurrentBlock for SiaCoinActivationResult { - fn current_block(&self) -> u64 { self.current_block } + fn current_block(&self) -> u64 { + self.current_block + } } impl GetAddressesBalances for SiaCoinActivationResult { @@ -68,7 +72,9 @@ pub enum SiaCoinInProgressStatus { } impl InitStandaloneCoinInitialStatus for SiaCoinInProgressStatus { - fn initial_status() -> Self { SiaCoinInProgressStatus::ActivatingCoin } + fn initial_status() -> Self { + SiaCoinInProgressStatus::ActivatingCoin + } } #[derive(Clone, Display, Serialize, SerializeErrorType)] @@ -103,7 +109,9 @@ impl SiaCoinInitError { } impl From for SiaCoinInitError { - fn from(err: BalanceError) -> Self { SiaCoinInitError::CouldNotGetBalance(err.to_string()) } + fn from(err: BalanceError) -> Self { + SiaCoinInitError::CouldNotGetBalance(err.to_string()) + } } impl From for SiaCoinInitError { @@ -127,7 +135,9 @@ impl From for SiaCoinInitError { } impl From for SiaCoinInitError { - fn from(err: CryptoCtxError) -> Self { SiaCoinInitError::Internal(err.to_string()) } + fn from(err: CryptoCtxError) -> Self { + SiaCoinInitError::Internal(err.to_string()) + } } impl From for InitStandaloneCoinError { diff --git a/mm2src/coins_activation/src/slp_token_activation.rs b/mm2src/coins_activation/src/slp_token_activation.rs index 66ea8d18a4..17114bbc81 100644 --- a/mm2src/coins_activation/src/slp_token_activation.rs +++ b/mm2src/coins_activation/src/slp_token_activation.rs @@ -50,7 +50,9 @@ impl TryFromCoinProtocol for SlpProtocolConf { } impl TokenProtocolParams for SlpProtocolConf { - fn platform_coin_ticker(&self) -> &str { &self.platform_coin_ticker } + fn platform_coin_ticker(&self) -> &str { + &self.platform_coin_ticker + } } impl From for EnableTokenError { diff --git a/mm2src/coins_activation/src/standalone_coin/init_standalone_coin.rs b/mm2src/coins_activation/src/standalone_coin/init_standalone_coin.rs index f97c46924a..bd63162857 100644 --- a/mm2src/coins_activation/src/standalone_coin/init_standalone_coin.rs +++ b/mm2src/coins_activation/src/standalone_coin/init_standalone_coin.rs @@ -1,8 +1,9 @@ use crate::context::CoinsActivationContext; use crate::prelude::*; -use crate::standalone_coin::init_standalone_coin_error::{CancelInitStandaloneCoinError, InitStandaloneCoinError, - InitStandaloneCoinStatusError, - InitStandaloneCoinUserActionError}; +use crate::standalone_coin::init_standalone_coin_error::{ + CancelInitStandaloneCoinError, InitStandaloneCoinError, InitStandaloneCoinStatusError, + InitStandaloneCoinUserActionError, +}; use async_trait::async_trait; use coins::my_tx_history_v2::TxHistoryStorage; use coins::tx_history_storage::{CreateTxHistoryStorageError, TxHistoryStorageBuilder}; @@ -14,8 +15,9 @@ use mm2_event_stream::StreamingManager; use mm2_metrics::MetricsArc; use mm2_number::BigDecimal; use rpc_task::rpc_common::{CancelRpcTaskRequest, InitRpcTaskResponse, RpcTaskStatusRequest, RpcTaskUserActionRequest}; -use rpc_task::{RpcInitReq, RpcTask, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, - RpcTaskTypes}; +use rpc_task::{ + RpcInitReq, RpcTask, RpcTaskHandleShared, RpcTaskManager, RpcTaskManagerShared, RpcTaskStatus, RpcTaskTypes, +}; use serde_derive::Deserialize; use serde_json::Value as Json; use std::collections::HashMap; diff --git a/mm2src/coins_activation/src/standalone_coin/mod.rs b/mm2src/coins_activation/src/standalone_coin/mod.rs index 26afd8bc51..af15b4f01c 100644 --- a/mm2src/coins_activation/src/standalone_coin/mod.rs +++ b/mm2src/coins_activation/src/standalone_coin/mod.rs @@ -1,9 +1,9 @@ mod init_standalone_coin; mod init_standalone_coin_error; -pub use init_standalone_coin::{cancel_init_standalone_coin, init_standalone_coin, init_standalone_coin_status, - init_standalone_coin_user_action, InitStandaloneCoinActivationOps, - InitStandaloneCoinInitialStatus, InitStandaloneCoinReq, - InitStandaloneCoinStatusRequest, InitStandaloneCoinTaskHandleShared, - InitStandaloneCoinTaskManagerShared}; +pub use init_standalone_coin::{ + cancel_init_standalone_coin, init_standalone_coin, init_standalone_coin_status, init_standalone_coin_user_action, + InitStandaloneCoinActivationOps, InitStandaloneCoinInitialStatus, InitStandaloneCoinReq, + InitStandaloneCoinStatusRequest, InitStandaloneCoinTaskHandleShared, InitStandaloneCoinTaskManagerShared, +}; pub use init_standalone_coin_error::InitStandaloneCoinError; diff --git a/mm2src/coins_activation/src/tendermint_token_activation.rs b/mm2src/coins_activation/src/tendermint_token_activation.rs index e930b740b2..d067160851 100644 --- a/mm2src/coins_activation/src/tendermint_token_activation.rs +++ b/mm2src/coins_activation/src/tendermint_token_activation.rs @@ -1,12 +1,20 @@ -use crate::{prelude::TryPlatformCoinFromMmCoinEnum, - token::{EnableTokenError, TokenActivationOps, TokenProtocolParams}}; +use crate::{ + prelude::TryPlatformCoinFromMmCoinEnum, + token::{EnableTokenError, TokenActivationOps, TokenProtocolParams}, +}; use async_trait::async_trait; -use coins::{tendermint::{TendermintCoin, TendermintToken, TendermintTokenActivationParams, TendermintTokenInitError, - TendermintTokenProtocolInfo}, - CoinBalance, MarketCoinOps, MmCoinEnum}; +use coins::{ + tendermint::{ + TendermintCoin, TendermintToken, TendermintTokenActivationParams, TendermintTokenInitError, + TendermintTokenProtocolInfo, + }, + CoinBalance, MarketCoinOps, MmCoinEnum, +}; use common::Future01CompatExt; -use mm2_err_handle::{map_mm_error::MmResultExt, - prelude::{MapMmError, MmError}}; +use mm2_err_handle::{ + map_mm_error::MmResultExt, + prelude::{MapMmError, MmError}, +}; use serde::Serialize; use serde_json::Value as Json; use std::collections::HashMap; @@ -41,7 +49,9 @@ impl TryPlatformCoinFromMmCoinEnum for TendermintCoin { } impl TokenProtocolParams for TendermintTokenProtocolInfo { - fn platform_coin_ticker(&self) -> &str { &self.platform } + fn platform_coin_ticker(&self) -> &str { + &self.platform + } } #[async_trait] diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index 349fce564a..3bdf267acc 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -1,21 +1,22 @@ use crate::context::CoinsActivationContext; -use crate::platform_coin_with_tokens::{EnablePlatformCoinWithTokensError, GetPlatformBalance, - InitPlatformCoinWithTokensAwaitingStatus, - InitPlatformCoinWithTokensInProgressStatus, InitPlatformCoinWithTokensTask, - InitPlatformCoinWithTokensTaskManagerShared, - InitPlatformCoinWithTokensUserAction, InitTokensAsMmCoinsError, - PlatformCoinWithTokensActivationOps, RegisterTokenInfo, TokenActivationParams, - TokenActivationRequest, TokenAsMmCoinInitializer, TokenInitializer, TokenOf}; +use crate::platform_coin_with_tokens::{ + EnablePlatformCoinWithTokensError, GetPlatformBalance, InitPlatformCoinWithTokensAwaitingStatus, + InitPlatformCoinWithTokensInProgressStatus, InitPlatformCoinWithTokensTask, + InitPlatformCoinWithTokensTaskManagerShared, InitPlatformCoinWithTokensUserAction, InitTokensAsMmCoinsError, + PlatformCoinWithTokensActivationOps, RegisterTokenInfo, TokenActivationParams, TokenActivationRequest, + TokenAsMmCoinInitializer, TokenInitializer, TokenOf, +}; use crate::prelude::*; use async_trait::async_trait; use coins::hd_wallet::HDPathAccountToAddressId; use coins::my_tx_history_v2::TxHistoryStorage; use coins::tendermint::tendermint_tx_history_v2::tendermint_history_loop; -use coins::tendermint::{cosmos_get_accounts_impl, tendermint_priv_key_policy, CosmosAccountAlgo, RpcNode, - TendermintActivationPolicy, TendermintCoin, TendermintCommons, TendermintConf, - TendermintInitError, TendermintInitErrorKind, TendermintProtocolInfo, TendermintPublicKey, - TendermintToken, TendermintTokenActivationParams, TendermintTokenInitError, - TendermintTokenProtocolInfo, TendermintWalletConnectionType}; +use coins::tendermint::{ + cosmos_get_accounts_impl, tendermint_priv_key_policy, CosmosAccountAlgo, RpcNode, TendermintActivationPolicy, + TendermintCoin, TendermintCommons, TendermintConf, TendermintInitError, TendermintInitErrorKind, + TendermintProtocolInfo, TendermintPublicKey, TendermintToken, TendermintTokenActivationParams, + TendermintTokenInitError, TendermintTokenProtocolInfo, TendermintWalletConnectionType, +}; use coins::{CoinBalance, CoinProtocol, MarketCoinOps, MmCoin, MmCoinEnum, PrivKeyBuildPolicy}; use common::executor::{AbortSettings, SpawnAbortable}; use common::{true_f, Future01CompatExt}; @@ -113,11 +114,15 @@ where } impl TxHistory for TendermintActivationParams { - fn tx_history(&self) -> bool { self.tx_history } + fn tx_history(&self) -> bool { + self.tx_history + } } impl ActivationRequestInfo for TendermintActivationParams { - fn is_hw_policy(&self) -> bool { false } // TODO: fix when device policy is added + fn is_hw_policy(&self) -> bool { + false + } // TODO: fix when device policy is added } struct TendermintTokenInitializer { @@ -157,7 +162,9 @@ impl TokenInitializer for TendermintTokenInitializer { .collect() } - fn platform_coin(&self) -> &::PlatformCoin { &self.platform_coin } + fn platform_coin(&self) -> &::PlatformCoin { + &self.platform_coin + } } impl TryFromCoinProtocol for TendermintProtocolInfo { @@ -205,11 +212,15 @@ pub struct TendermintActivationResult { } impl CurrentBlock for TendermintActivationResult { - fn current_block(&self) -> u64 { self.current_block } + fn current_block(&self) -> u64 { + self.current_block + } } impl GetPlatformBalance for TendermintActivationResult { - fn get_platform_balance(&self) -> Option { self.balance.as_ref().map(|b| b.spendable.clone()) } + fn get_platform_balance(&self) -> Option { + self.balance.as_ref().map(|b| b.spendable.clone()) + } } impl From for EnablePlatformCoinWithTokensError { @@ -403,10 +414,13 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { .tokens_balances .into_iter() .map(|(ticker, balance)| { - (ticker, CoinBalance { - spendable: balance, - unspendable: BigDecimal::default(), - }) + ( + ticker, + CoinBalance { + spendable: balance, + unspendable: BigDecimal::default(), + }, + ) }) .collect(), ), diff --git a/mm2src/coins_activation/src/token.rs b/mm2src/coins_activation/src/token.rs index 9b78102483..3ddc4b7390 100644 --- a/mm2src/coins_activation/src/token.rs +++ b/mm2src/coins_activation/src/token.rs @@ -4,8 +4,10 @@ use crate::platform_coin_with_tokens::{self, RegisterTokenInfo}; use crate::prelude::*; use async_trait::async_trait; use coins::utxo::rpc_clients::UtxoRpcError; -use coins::{lp_coinfind, lp_coinfind_or_err, BalanceError, CoinProtocol, CoinsContext, CustomTokenError, MmCoinEnum, - PrivKeyPolicyNotAllowed, RegisterCoinError, UnexpectedDerivationMethod}; +use coins::{ + lp_coinfind, lp_coinfind_or_err, BalanceError, CoinProtocol, CoinsContext, CustomTokenError, MmCoinEnum, + PrivKeyPolicyNotAllowed, RegisterCoinError, UnexpectedDerivationMethod, +}; use common::{HttpStatusCode, StatusCode}; use derive_more::Display; use mm2_core::mm_ctx::MmArc; diff --git a/mm2src/coins_activation/src/utxo_activation/common_impl.rs b/mm2src/coins_activation/src/utxo_activation/common_impl.rs index 589efa5b08..d4e670d38f 100644 --- a/mm2src/coins_activation/src/utxo_activation/common_impl.rs +++ b/mm2src/coins_activation/src/utxo_activation/common_impl.rs @@ -1,7 +1,8 @@ use crate::standalone_coin::{InitStandaloneCoinActivationOps, InitStandaloneCoinTaskHandleShared}; use crate::utxo_activation::init_utxo_standard_activation_error::InitUtxoStandardError; -use crate::utxo_activation::init_utxo_standard_statuses::{UtxoStandardAwaitingStatus, UtxoStandardInProgressStatus, - UtxoStandardUserAction}; +use crate::utxo_activation::init_utxo_standard_statuses::{ + UtxoStandardAwaitingStatus, UtxoStandardInProgressStatus, UtxoStandardUserAction, +}; use crate::utxo_activation::utxo_standard_activation_result::UtxoStandardActivationResult; use coins::coin_balance::EnableCoinBalanceOps; use coins::hd_wallet::RpcTaskXPubExtractor; diff --git a/mm2src/coins_activation/src/utxo_activation/init_bch_activation.rs b/mm2src/coins_activation/src/utxo_activation/init_bch_activation.rs index 35c1a32cc5..a545ccb9aa 100644 --- a/mm2src/coins_activation/src/utxo_activation/init_bch_activation.rs +++ b/mm2src/coins_activation/src/utxo_activation/init_bch_activation.rs @@ -1,12 +1,15 @@ use crate::context::CoinsActivationContext; use crate::prelude::TryFromCoinProtocol; -use crate::standalone_coin::{InitStandaloneCoinActivationOps, InitStandaloneCoinTaskHandleShared, - InitStandaloneCoinTaskManagerShared}; -use crate::utxo_activation::common_impl::{get_activation_result, priv_key_build_policy, - start_history_background_fetching}; +use crate::standalone_coin::{ + InitStandaloneCoinActivationOps, InitStandaloneCoinTaskHandleShared, InitStandaloneCoinTaskManagerShared, +}; +use crate::utxo_activation::common_impl::{ + get_activation_result, priv_key_build_policy, start_history_background_fetching, +}; use crate::utxo_activation::init_utxo_standard_activation_error::InitUtxoStandardError; -use crate::utxo_activation::init_utxo_standard_statuses::{UtxoStandardAwaitingStatus, UtxoStandardInProgressStatus, - UtxoStandardUserAction}; +use crate::utxo_activation::init_utxo_standard_statuses::{ + UtxoStandardAwaitingStatus, UtxoStandardInProgressStatus, UtxoStandardUserAction, +}; use crate::utxo_activation::utxo_standard_activation_result::UtxoStandardActivationResult; use async_trait::async_trait; use coins::my_tx_history_v2::TxHistoryStorage; diff --git a/mm2src/coins_activation/src/utxo_activation/init_qtum_activation.rs b/mm2src/coins_activation/src/utxo_activation/init_qtum_activation.rs index 3dd9010709..49bbf20208 100644 --- a/mm2src/coins_activation/src/utxo_activation/init_qtum_activation.rs +++ b/mm2src/coins_activation/src/utxo_activation/init_qtum_activation.rs @@ -1,12 +1,15 @@ use crate::context::CoinsActivationContext; use crate::prelude::TryFromCoinProtocol; -use crate::standalone_coin::{InitStandaloneCoinActivationOps, InitStandaloneCoinTaskHandleShared, - InitStandaloneCoinTaskManagerShared}; -use crate::utxo_activation::common_impl::{get_activation_result, priv_key_build_policy, - start_history_background_fetching}; +use crate::standalone_coin::{ + InitStandaloneCoinActivationOps, InitStandaloneCoinTaskHandleShared, InitStandaloneCoinTaskManagerShared, +}; +use crate::utxo_activation::common_impl::{ + get_activation_result, priv_key_build_policy, start_history_background_fetching, +}; use crate::utxo_activation::init_utxo_standard_activation_error::InitUtxoStandardError; -use crate::utxo_activation::init_utxo_standard_statuses::{UtxoStandardAwaitingStatus, UtxoStandardInProgressStatus, - UtxoStandardUserAction}; +use crate::utxo_activation::init_utxo_standard_statuses::{ + UtxoStandardAwaitingStatus, UtxoStandardInProgressStatus, UtxoStandardUserAction, +}; use crate::utxo_activation::utxo_standard_activation_result::UtxoStandardActivationResult; use async_trait::async_trait; use coins::my_tx_history_v2::TxHistoryStorage; diff --git a/mm2src/coins_activation/src/utxo_activation/init_utxo_standard_activation.rs b/mm2src/coins_activation/src/utxo_activation/init_utxo_standard_activation.rs index f975d49fd7..13935dd924 100644 --- a/mm2src/coins_activation/src/utxo_activation/init_utxo_standard_activation.rs +++ b/mm2src/coins_activation/src/utxo_activation/init_utxo_standard_activation.rs @@ -1,12 +1,15 @@ use crate::context::CoinsActivationContext; use crate::prelude::TryFromCoinProtocol; -use crate::standalone_coin::{InitStandaloneCoinActivationOps, InitStandaloneCoinTaskHandleShared, - InitStandaloneCoinTaskManagerShared}; -use crate::utxo_activation::common_impl::{get_activation_result, priv_key_build_policy, - start_history_background_fetching}; +use crate::standalone_coin::{ + InitStandaloneCoinActivationOps, InitStandaloneCoinTaskHandleShared, InitStandaloneCoinTaskManagerShared, +}; +use crate::utxo_activation::common_impl::{ + get_activation_result, priv_key_build_policy, start_history_background_fetching, +}; use crate::utxo_activation::init_utxo_standard_activation_error::InitUtxoStandardError; -use crate::utxo_activation::init_utxo_standard_statuses::{UtxoStandardAwaitingStatus, UtxoStandardInProgressStatus, - UtxoStandardUserAction}; +use crate::utxo_activation::init_utxo_standard_statuses::{ + UtxoStandardAwaitingStatus, UtxoStandardInProgressStatus, UtxoStandardUserAction, +}; use crate::utxo_activation::utxo_standard_activation_result::UtxoStandardActivationResult; use async_trait::async_trait; use coins::my_tx_history_v2::TxHistoryStorage; diff --git a/mm2src/coins_activation/src/utxo_activation/init_utxo_standard_activation_error.rs b/mm2src/coins_activation/src/utxo_activation/init_utxo_standard_activation_error.rs index 4cc7c7a5fd..8260bb025e 100644 --- a/mm2src/coins_activation/src/utxo_activation/init_utxo_standard_activation_error.rs +++ b/mm2src/coins_activation/src/utxo_activation/init_utxo_standard_activation_error.rs @@ -39,7 +39,9 @@ impl From for InitUtxoStandardError { impl From for InitUtxoStandardError { /// `CryptoCtx` is expected to be initialized already. - fn from(crypto_err: CryptoCtxError) -> Self { InitUtxoStandardError::Internal(crypto_err.to_string()) } + fn from(crypto_err: CryptoCtxError) -> Self { + InitUtxoStandardError::Internal(crypto_err.to_string()) + } } impl From for InitUtxoStandardError { diff --git a/mm2src/coins_activation/src/utxo_activation/init_utxo_standard_statuses.rs b/mm2src/coins_activation/src/utxo_activation/init_utxo_standard_statuses.rs index 5bf863815c..d34c960ac2 100644 --- a/mm2src/coins_activation/src/utxo_activation/init_utxo_standard_statuses.rs +++ b/mm2src/coins_activation/src/utxo_activation/init_utxo_standard_statuses.rs @@ -22,5 +22,7 @@ pub enum UtxoStandardInProgressStatus { } impl InitStandaloneCoinInitialStatus for UtxoStandardInProgressStatus { - fn initial_status() -> Self { UtxoStandardInProgressStatus::ActivatingCoin } + fn initial_status() -> Self { + UtxoStandardInProgressStatus::ActivatingCoin + } } diff --git a/mm2src/coins_activation/src/utxo_activation/mod.rs b/mm2src/coins_activation/src/utxo_activation/mod.rs index 1dc64c620c..54a62ed4f6 100644 --- a/mm2src/coins_activation/src/utxo_activation/mod.rs +++ b/mm2src/coins_activation/src/utxo_activation/mod.rs @@ -18,10 +18,11 @@ pub mod for_tests { use mm2_err_handle::prelude::MmResult; use rpc_task::{RpcInitReq, RpcTaskStatus}; - use crate::{init_standalone_coin, init_standalone_coin_status, - standalone_coin::{InitStandaloneCoinActivationOps, InitStandaloneCoinError, - InitStandaloneCoinInitialStatus}, - InitStandaloneCoinReq, InitStandaloneCoinStatusRequest}; + use crate::{ + init_standalone_coin, init_standalone_coin_status, + standalone_coin::{InitStandaloneCoinActivationOps, InitStandaloneCoinError, InitStandaloneCoinInitialStatus}, + InitStandaloneCoinReq, InitStandaloneCoinStatusRequest, + }; /// test helper to activate standalone coin with waiting for the result pub async fn init_standalone_coin_loop( diff --git a/mm2src/coins_activation/src/utxo_activation/utxo_standard_activation_result.rs b/mm2src/coins_activation/src/utxo_activation/utxo_standard_activation_result.rs index 2fd75e5ab8..95aa93519b 100644 --- a/mm2src/coins_activation/src/utxo_activation/utxo_standard_activation_result.rs +++ b/mm2src/coins_activation/src/utxo_activation/utxo_standard_activation_result.rs @@ -13,7 +13,9 @@ pub struct UtxoStandardActivationResult { } impl CurrentBlock for UtxoStandardActivationResult { - fn current_block(&self) -> u64 { self.current_block } + fn current_block(&self) -> u64 { + self.current_block + } } impl GetAddressesBalances for UtxoStandardActivationResult { diff --git a/mm2src/coins_activation/src/z_coin_activation.rs b/mm2src/coins_activation/src/z_coin_activation.rs index ff9df16119..8b4bd874ed 100644 --- a/mm2src/coins_activation/src/z_coin_activation.rs +++ b/mm2src/coins_activation/src/z_coin_activation.rs @@ -1,14 +1,17 @@ use crate::context::CoinsActivationContext; use crate::prelude::*; -use crate::standalone_coin::{InitStandaloneCoinActivationOps, InitStandaloneCoinError, - InitStandaloneCoinInitialStatus, InitStandaloneCoinTaskHandleShared, - InitStandaloneCoinTaskManagerShared}; +use crate::standalone_coin::{ + InitStandaloneCoinActivationOps, InitStandaloneCoinError, InitStandaloneCoinInitialStatus, + InitStandaloneCoinTaskHandleShared, InitStandaloneCoinTaskManagerShared, +}; use async_trait::async_trait; use coins::coin_balance::{CoinBalanceReport, IguanaWalletBalance}; use coins::my_tx_history_v2::TxHistoryStorage; use coins::tx_history_storage::CreateTxHistoryStorageError; -use coins::z_coin::{z_coin_from_conf_and_params, BlockchainScanStopped, FirstSyncBlock, SyncStatus, ZCoin, - ZCoinBuildError, ZcoinActivationParams, ZcoinProtocolInfo}; +use coins::z_coin::{ + z_coin_from_conf_and_params, BlockchainScanStopped, FirstSyncBlock, SyncStatus, ZCoin, ZCoinBuildError, + ZcoinActivationParams, ZcoinProtocolInfo, +}; use coins::{BalanceError, CoinBalance, CoinProtocol, MarketCoinOps, PrivKeyBuildPolicy, RegisterCoinError}; use crypto::hw_rpc_task::{HwRpcTaskAwaitingStatus, HwRpcTaskUserAction}; use crypto::CryptoCtxError; @@ -49,7 +52,9 @@ pub struct ZcoinActivationResult { } impl CurrentBlock for ZcoinActivationResult { - fn current_block(&self) -> u64 { self.current_block } + fn current_block(&self) -> u64 { + self.current_block + } } impl GetAddressesBalances for ZcoinActivationResult { @@ -99,7 +104,9 @@ pub enum ZcoinInProgressStatus { } impl InitStandaloneCoinInitialStatus for ZcoinInProgressStatus { - fn initial_status() -> Self { ZcoinInProgressStatus::ActivatingCoin } + fn initial_status() -> Self { + ZcoinInProgressStatus::ActivatingCoin + } } #[derive(Clone, Display, Serialize, SerializeErrorType)] @@ -134,7 +141,9 @@ impl ZcoinInitError { } impl From for ZcoinInitError { - fn from(err: BalanceError) -> Self { ZcoinInitError::CouldNotGetBalance(err.to_string()) } + fn from(err: BalanceError) -> Self { + ZcoinInitError::CouldNotGetBalance(err.to_string()) + } } impl From for ZcoinInitError { @@ -158,11 +167,15 @@ impl From for ZcoinInitError { } impl From for ZcoinInitError { - fn from(err: CryptoCtxError) -> Self { ZcoinInitError::Internal(err.to_string()) } + fn from(err: CryptoCtxError) -> Self { + ZcoinInitError::Internal(err.to_string()) + } } impl From for ZcoinInitError { - fn from(e: BlockchainScanStopped) -> Self { ZcoinInitError::Internal(e.to_string()) } + fn from(e: BlockchainScanStopped) -> Self { + ZcoinInitError::Internal(e.to_string()) + } } impl From for ZcoinInitError { @@ -195,7 +208,9 @@ impl From for InitStandaloneCoinError { } impl From for InitStandaloneCoinError { - fn from(e: CryptoCtxError) -> Self { InitStandaloneCoinError::Internal(e.to_string()) } + fn from(e: CryptoCtxError) -> Self { + InitStandaloneCoinError::Internal(e.to_string()) + } } impl TryFromCoinProtocol for ZcoinProtocolInfo { diff --git a/mm2src/common/Cargo.toml b/mm2src/common/Cargo.toml index 39590862d8..640de61fc3 100644 --- a/mm2src/common/Cargo.toml +++ b/mm2src/common/Cargo.toml @@ -34,8 +34,8 @@ http-body.workspace = true itertools.workspace = true lazy_static.workspace = true log.workspace = true -parking_lot = { workspace = true, features = ["nightly"] } -parking_lot_core.workspace = true +parking_lot = { workspace = true } +parking_lot_core.workspace = true paste.workspace = true primitive-types.workspace = true rand = { workspace = true, features = ["std", "small_rng"] } diff --git a/mm2src/common/bool_as_int.rs b/mm2src/common/bool_as_int.rs index 0acfe3fb27..1908dfd560 100644 --- a/mm2src/common/bool_as_int.rs +++ b/mm2src/common/bool_as_int.rs @@ -6,14 +6,20 @@ pub struct BoolAsInt(bool); impl BoolAsInt { /// Creates a new `BoolAsInt` instance from a boolean value. - pub fn new(value: bool) -> Self { BoolAsInt(value) } + pub fn new(value: bool) -> Self { + BoolAsInt(value) + } /// Retrieves the inner boolean value. - pub fn as_bool(&self) -> bool { self.0 } + pub fn as_bool(&self) -> bool { + self.0 + } } impl From for BoolAsInt { - fn from(value: bool) -> Self { BoolAsInt(value) } + fn from(value: bool) -> Self { + BoolAsInt(value) + } } impl Serialize for BoolAsInt { diff --git a/mm2src/common/common.rs b/mm2src/common/common.rs index 1ab66c50e1..3efded9270 100644 --- a/mm2src/common/common.rs +++ b/mm2src/common/common.rs @@ -11,14 +11,19 @@ //! binary #![allow(uncommon_codepoints)] -#![feature(hash_raw_entry)] -#[macro_use] extern crate arrayref; -#[macro_use] extern crate gstuff; -#[macro_use] extern crate lazy_static; -#[macro_use] pub extern crate serde_derive; -#[macro_use] pub extern crate serde_json; -#[macro_use] extern crate ser_error_derive; +#[macro_use] +extern crate arrayref; +#[macro_use] +extern crate gstuff; +#[macro_use] +extern crate lazy_static; +#[macro_use] +pub extern crate serde_derive; +#[macro_use] +pub extern crate serde_json; +#[macro_use] +extern crate ser_error_derive; /// Implements a `From` for `enum` with a variant name matching the name of the type stored. /// @@ -31,7 +36,9 @@ macro_rules! ifrom { ($enum: ident, $id: ident) => { impl From<$id> for $enum { - fn from(t: $id) -> $enum { $enum::$id(t) } + fn from(t: $id) -> $enum { + $enum::$id(t) + } } }; } @@ -130,7 +137,8 @@ pub mod bool_as_int; pub mod crash_reports; pub mod custom_futures; pub mod custom_iter; -#[path = "executor/mod.rs"] pub mod executor; +#[path = "executor/mod.rs"] +pub mod executor; pub mod notifier; pub mod number_type_casting; pub mod on_drop_callback; @@ -141,9 +149,11 @@ pub mod seri; #[path = "wio.rs"] pub mod wio; -#[cfg(target_arch = "wasm32")] pub mod wasm; +#[cfg(target_arch = "wasm32")] +pub mod wasm; -#[cfg(target_arch = "wasm32")] pub use wasm::*; +#[cfg(target_arch = "wasm32")] +pub use wasm::*; use backtrace::SymbolName; use chrono::format::ParseError; @@ -175,6 +185,7 @@ use std::panic::{set_hook, PanicHookInfo}; use std::path::{Path, PathBuf}; use std::ptr::read_volatile; use std::sync::atomic::Ordering; +use std::sync::OnceLock; use std::time::{Duration, SystemTime, SystemTimeError}; use uuid::Uuid; @@ -228,7 +239,21 @@ lazy_static! { } /// Converts u64 satoshis to f64 -pub fn sat_to_f(sat: u64) -> f64 { sat as f64 / SATOSHIS as f64 } +pub fn sat_to_f(sat: u64) -> f64 { + sat as f64 / SATOSHIS as f64 +} + +/// Marker type to indicate that a type is `!Send` in a stable way. +/// +/// Raw pointers are not `Send` by default, so this makes `NotSend` +/// not `Send` either. +pub struct NotSend(std::marker::PhantomData<*const ()>); + +impl Default for NotSend { + fn default() -> NotSend { + NotSend(std::marker::PhantomData) + } +} #[allow(non_camel_case_types)] #[derive(Clone, Copy, Eq, Hash, PartialEq)] @@ -279,7 +304,9 @@ impl<'de> de::Deserialize<'de> for bits256 { struct Bits256Visitor; impl<'de> de::Visitor<'de> for Bits256Visitor { type Value = bits256; - fn expecting(&self, fm: &mut std::fmt::Formatter) -> std::fmt::Result { fm.write_str("a byte array") } + fn expecting(&self, fm: &mut std::fmt::Formatter) -> std::fmt::Result { + fm.write_str("a byte array") + } fn visit_seq(self, mut seq: S) -> Result where S: de::SeqAccess<'de>, @@ -312,11 +339,15 @@ impl<'de> de::Deserialize<'de> for bits256 { } impl std::fmt::Debug for bits256 { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { (self as &dyn std::fmt::Display).fmt(f) } + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + (self as &dyn std::fmt::Display).fmt(f) + } } impl From<[u8; 32]> for bits256 { - fn from(bytes: [u8; 32]) -> Self { bits256 { bytes } } + fn from(bytes: [u8; 32]) -> Self { + bits256 { bytes } + } } /// Use the value, preventing the compiler and linker from optimizing it away. @@ -331,13 +362,13 @@ pub fn black_box(v: T) -> T { /// Using a static buffer in order to minimize the chance of heap and stack allocations in the signal handler. fn trace_buf() -> PaMutexGuard<'static, [u8; 256]> { - static TRACE_BUF: PaMutex<[u8; 256]> = PaMutex::new([0; 256]); - TRACE_BUF.lock() + static TRACE_BUF: OnceLock> = OnceLock::new(); + TRACE_BUF.get_or_init(|| PaMutex::new([0; 256])).lock() } fn trace_name_buf() -> PaMutexGuard<'static, [u8; 128]> { - static TRACE_NAME_BUF: PaMutex<[u8; 128]> = PaMutex::new([0; 128]); - TRACE_NAME_BUF.lock() + static TRACE_NAME_BUF: OnceLock> = OnceLock::new(); + TRACE_NAME_BUF.get_or_init(|| PaMutex::new([0; 128])).lock() } /// Shortcut to path->filename conversion. @@ -529,7 +560,7 @@ pub fn set_panic_hook() { })) } -/// RPC response, returned by the RPC handlers. +/// 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. pub type HyRes = Box>, Error = String> + Send>; @@ -582,18 +613,24 @@ impl std::fmt::Display for SerializationError { } impl SerializationError { - pub fn from_error(e: E) -> SerializationError { SerializationError::InternalError(e.to_string()) } + pub fn from_error(e: E) -> SerializationError { + SerializationError::InternalError(e.to_string()) + } } #[derive(Clone, Serialize)] pub struct SuccessResponse(&'static str); impl SuccessResponse { - pub fn new() -> SuccessResponse { SuccessResponse("success") } + pub fn new() -> SuccessResponse { + SuccessResponse("success") + } } impl Default for SuccessResponse { - fn default() -> Self { SuccessResponse::new() } + fn default() -> Self { + SuccessResponse::new() + } } #[derive(Serialize)] @@ -607,7 +644,9 @@ pub fn err_to_rpc_json_string(err: &str) -> String { json::to_string(&err).unwrap() } -pub fn err_tp_rpc_json(error: String) -> Json { json::to_value(ErrResponse { error }).unwrap() } +pub fn err_tp_rpc_json(error: String) -> Json { + json::to_value(ErrResponse { error }).unwrap() +} /// Returns the `{error: $msg}` JSON response with the given HTTP `status`. /// Also logs the error (if possible). @@ -637,11 +676,15 @@ pub fn env_var_as_bool(name: &str) -> bool { } #[cfg(target_arch = "wasm32")] -pub fn env_var_as_bool(_name: &str) -> bool { false } +pub fn env_var_as_bool(_name: &str) -> bool { + false +} /// TODO make it wasm32 only #[cfg(target_arch = "wasm32")] -pub fn var(_name: &str) -> Result { ERR!("Environment variable not supported in WASM") } +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. /// @@ -690,7 +733,9 @@ where } #[cfg(target_arch = "wasm32")] -pub fn now_ms() -> u64 { js_sys::Date::now() as u64 } +pub fn now_ms() -> u64 { + js_sys::Date::now() as u64 +} #[cfg(target_arch = "wasm32")] pub fn now_float() -> f64 { @@ -698,11 +743,17 @@ pub fn now_float() -> f64 { duration_to_float(Duration::from_millis(now_ms())) } -pub fn wait_until_sec(seconds: u64) -> u64 { (now_ms() / 1000) + seconds } +pub fn wait_until_sec(seconds: u64) -> u64 { + (now_ms() / 1000) + seconds +} -pub fn wait_until_ms(milliseconds: u64) -> u64 { now_ms() + milliseconds } +pub fn wait_until_ms(milliseconds: u64) -> u64 { + now_ms() + milliseconds +} -pub fn now_sec() -> u64 { now_ms() / 1000 } +pub fn now_sec() -> u64 { + now_ms() / 1000 +} pub fn now_sec_u32() -> u32 { (now_ms() / 1000) @@ -717,10 +768,12 @@ pub fn now_sec_i64() -> i64 { } #[cfg(not(target_arch = "wasm32"))] -pub fn temp_dir() -> PathBuf { env::temp_dir() } +pub fn temp_dir() -> PathBuf { + env::temp_dir() +} -/// If the `MM_LOG` variable is present then tries to open that file. -/// Prints a warning to `stdout` if there's a problem opening the file. +/// If the `MM_LOG` variable is present then tries to open that file. +/// Prints a warning to `stdout` if there's a problem opening the file. /// Returns `None` if `MM_LOG` variable is not present or if the specified path can't be opened. #[cfg(not(target_arch = "wasm32"))] pub(crate) fn open_log_file() -> Option { @@ -878,10 +931,14 @@ fn find_kdf_dependency_file(value_from_env: Option, path_leaf: &str) -> } } -pub fn small_rng() -> SmallRng { SmallRng::seed_from_u64(now_ms()) } +pub fn small_rng() -> SmallRng { + SmallRng::seed_from_u64(now_ms()) +} #[inline(always)] -pub fn os_rng(dest: &mut [u8]) -> Result<(), rand::Error> { rand::rngs::OsRng.try_fill_bytes(dest) } +pub fn os_rng(dest: &mut [u8]) -> Result<(), rand::Error> { + rand::rngs::OsRng.try_fill_bytes(dest) +} #[derive(Debug, Clone)] /// Ordered from low to height inclusive range. @@ -890,7 +947,9 @@ pub struct OrdRange(RangeInclusive); impl Deref for OrdRange { type Target = RangeInclusive; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { + &self.0 + } } impl OrdRange { @@ -906,28 +965,50 @@ impl OrdRange { impl OrdRange { /// Flatten a start-end pair into the vector. - pub fn flatten(&self) -> Vec { vec![*self.start(), *self.end()] } + pub fn flatten(&self) -> Vec { + vec![*self.start(), *self.end()] + } } -pub const fn true_f() -> bool { true } +pub const fn true_f() -> bool { + true +} -pub const fn ten() -> usize { 10 } +pub const fn ten() -> usize { + 10 +} -pub const fn ten_f64() -> f64 { 10. } +pub const fn ten_f64() -> f64 { + 10. +} -pub const fn one_hundred() -> usize { 100 } +pub const fn one_hundred() -> usize { + 100 +} -pub const fn one_thousand_u32() -> u32 { 1000 } +pub const fn one_thousand_u32() -> u32 { + 1000 +} -pub const fn one_and_half_f64() -> f64 { 1.5 } +pub const fn one_and_half_f64() -> f64 { + 1.5 +} -pub const fn three_hundred_f64() -> f64 { 300. } +pub const fn three_hundred_f64() -> f64 { + 300. +} -pub const fn one_f64() -> f64 { 1. } +pub const fn one_f64() -> f64 { + 1. +} -pub const fn sixty_f64() -> f64 { 60. } +pub const fn sixty_f64() -> f64 { + 60. +} -pub fn one() -> NonZeroUsize { NonZeroUsize::new(1).unwrap() } +pub fn one() -> NonZeroUsize { + NonZeroUsize::new(1).unwrap() +} #[derive(Debug, Deserialize)] pub struct PagingOptions { @@ -939,7 +1020,9 @@ pub struct PagingOptions { } #[inline] -pub fn new_uuid() -> Uuid { Uuid::new_v4() } +pub fn new_uuid() -> Uuid { + Uuid::new_v4() +} pub fn first_char_to_upper(input: &str) -> String { let mut v: Vec = input.chars().collect(); @@ -1023,7 +1106,9 @@ impl SequentialCount where I: Iterator, { - fn new(iter: I) -> Self { SequentialCount { iter: iter.peekable() } } + fn new(iter: I) -> Self { + SequentialCount { iter: iter.peekable() } + } } /// https://stackoverflow.com/questions/32702386/iterator-adapter-that-counts-repeated-characters @@ -1097,7 +1182,9 @@ impl PagingOptionsEnum { } impl Default for PagingOptionsEnum { - fn default() -> Self { PagingOptionsEnum::PageNumber(NonZeroUsize::new(1).expect("1 > 0")) } + fn default() -> Self { + PagingOptionsEnum::PageNumber(NonZeroUsize::new(1).expect("1 > 0")) + } } #[inline(always)] @@ -1114,7 +1201,9 @@ pub fn get_utc_timestamp() -> i64 { } #[inline(always)] -pub fn get_utc_timestamp_nanos() -> i64 { Utc::now().timestamp_nanos() } +pub fn get_utc_timestamp_nanos() -> i64 { + Utc::now().timestamp_nanos() +} #[inline(always)] pub fn get_local_duration_since_epoch() -> Result { @@ -1153,11 +1242,15 @@ pub enum ParseRfc3339Err { } impl From for ParseRfc3339Err { - fn from(e: ParseError) -> Self { ParseRfc3339Err::ParseTimestampError(e.to_string()) } + fn from(e: ParseError) -> Self { + ParseRfc3339Err::ParseTimestampError(e.to_string()) + } } impl From for ParseRfc3339Err { - fn from(e: TryFromIntError) -> Self { ParseRfc3339Err::TryFromIntError(e.to_string()) } + fn from(e: TryFromIntError) -> Self { + ParseRfc3339Err::TryFromIntError(e.to_string()) + } } pub fn parse_rfc3339_to_timestamp(date_str: &str) -> Result { @@ -1168,7 +1261,9 @@ pub fn parse_rfc3339_to_timestamp(date_str: &str) -> Result bool { old_version == 0 && new_version == 1 } +pub fn is_initial_upgrade(old_version: u32, new_version: u32) -> bool { + old_version == 0 && new_version == 1 +} /// Takes `http:Uri` and converts it into `String` of websocket address /// @@ -1188,9 +1283,11 @@ pub fn http_uri_to_ws_address(uri: http::Uri) -> String { /// Converts a U256 value to a lowercase hexadecimal string with "0x" prefix #[inline] -pub fn u256_to_hex(value: U256) -> String { format!("0x{:x}", value) } +pub fn u256_to_hex(value: U256) -> String { + format!("0x{:x}", value) +} -/// If 0x prefix exists in an str strip it or return the str as-is +/// If 0x prefix exists in an str strip it or return the str as-is #[macro_export] macro_rules! str_strip_0x { ($s: expr) => { diff --git a/mm2src/common/crash_reports.rs b/mm2src/common/crash_reports.rs index 7d9c7ad8cc..ddfa601458 100644 --- a/mm2src/common/crash_reports.rs +++ b/mm2src/common/crash_reports.rs @@ -49,7 +49,9 @@ fn access_violation() { #[cfg(test)] #[inline(never)] #[allow(dead_code)] -extern "C" fn call_access_violation() { access_violation() } +extern "C" fn call_access_violation() { + access_violation() +} #[cfg(unix)] extern "C" fn signal_handler(sig: c_int) { @@ -129,7 +131,9 @@ pub fn init_crash_reports() { } #[cfg(target_arch = "wasm32")] -pub fn init_crash_reports() { unimplemented!() } +pub fn init_crash_reports() { + unimplemented!() +} // Make sure Rust panics still work in the presence of the VEH handler. #[test] diff --git a/mm2src/common/custom_futures/repeatable.rs b/mm2src/common/custom_futures/repeatable.rs index 842c2f0a2b..d12f8c5320 100644 --- a/mm2src/common/custom_futures/repeatable.rs +++ b/mm2src/common/custom_futures/repeatable.rs @@ -134,9 +134,13 @@ impl RepeatError { } } - fn timeout(until_ms: u64, error: E) -> Self { RepeatError::TimeoutExpired { until_ms, error } } + fn timeout(until_ms: u64, error: E) -> Self { + RepeatError::TimeoutExpired { until_ms, error } + } - fn attempts(attempts: usize, error: E) -> Self { RepeatError::AttemptsExceed { attempts, error } } + fn attempts(attempts: usize, error: E) -> Self { + RepeatError::AttemptsExceed { attempts, error } + } } impl fmt::Display for RepeatError { @@ -229,7 +233,9 @@ where } #[inline] - pub fn repeat_every_ms(self, repeat_every: u64) -> Self { self.repeat_every(Duration::from_millis(repeat_every)) } + pub fn repeat_every_ms(self, repeat_every: u64) -> Self { + self.repeat_every(Duration::from_millis(repeat_every)) + } #[inline] pub fn repeat_every_secs(self, repeat_every: f64) -> Self { @@ -283,7 +289,9 @@ where /// Specifies a timeout in milliseconds before that we may try to repeat the future. /// Note this method name should differ from [`FutureTimerExt::timeout_ms`]. #[inline] - pub fn with_timeout_ms(self, timeout_ms: u64) -> Self { self.until_ms(wait_until_ms(timeout_ms)) } + pub fn with_timeout_ms(self, timeout_ms: u64) -> Self { + self.until_ms(wait_until_ms(timeout_ms)) + } /// Specifies a timeout in seconds before that we may try to repeat the future. /// Note this method name should differ from [`FutureTimerExt::timeout_secs`]. @@ -373,7 +381,9 @@ enum RepeatUntil { } impl Default for RepeatUntil { - fn default() -> Self { RepeatUntil::AttemptsExceed(AttemptsState::new(1)) } + fn default() -> Self { + RepeatUntil::AttemptsExceed(AttemptsState::new(1)) + } } /// Returns `Poll::Ready(())` if there is no need to wait for the timeout. diff --git a/mm2src/common/executor/abort_on_drop.rs b/mm2src/common/executor/abort_on_drop.rs index e975f0ba70..b4142d93c5 100644 --- a/mm2src/common/executor/abort_on_drop.rs +++ b/mm2src/common/executor/abort_on_drop.rs @@ -4,10 +4,14 @@ use futures::future::AbortHandle; pub struct AbortOnDropHandle(AbortHandle); impl From for AbortOnDropHandle { - fn from(handle: AbortHandle) -> Self { AbortOnDropHandle(handle) } + fn from(handle: AbortHandle) -> Self { + AbortOnDropHandle(handle) + } } impl Drop for AbortOnDropHandle { #[inline(always)] - fn drop(&mut self) { self.0.abort(); } + fn drop(&mut self) { + self.0.abort(); + } } diff --git a/mm2src/common/executor/abortable_system/abortable_queue.rs b/mm2src/common/executor/abortable_system/abortable_queue.rs index 89781bcfa4..2948bde2e4 100644 --- a/mm2src/common/executor/abortable_system/abortable_queue.rs +++ b/mm2src/common/executor/abortable_system/abortable_queue.rs @@ -34,13 +34,17 @@ impl AbortableQueue { } impl From> for AbortableQueue { - fn from(inner: InnerShared) -> Self { AbortableQueue { inner } } + fn from(inner: InnerShared) -> Self { + AbortableQueue { inner } + } } impl AbortableSystem for AbortableQueue { type Inner = QueueInnerState; - fn __inner(&self) -> InnerShared { self.inner.clone() } + fn __inner(&self) -> InnerShared { + self.inner.clone() + } fn __push_subsystem_abort_tx(&self, subsystem_abort_tx: oneshot::Sender<()>) -> Result<(), AbortedError> { self.inner.lock().insert_handle(subsystem_abort_tx).map(|_| ()) @@ -246,7 +250,9 @@ impl SystemInner for QueueInnerState { Ok(()) } - fn is_aborted(&self) -> bool { matches!(self, QueueInnerState::Aborted) } + fn is_aborted(&self) -> bool { + matches!(self, QueueInnerState::Aborted) + } } #[cfg(test)] diff --git a/mm2src/common/executor/abortable_system/graceful_shutdown.rs b/mm2src/common/executor/abortable_system/graceful_shutdown.rs index 6a902faab7..db11a479f6 100644 --- a/mm2src/common/executor/abortable_system/graceful_shutdown.rs +++ b/mm2src/common/executor/abortable_system/graceful_shutdown.rs @@ -26,13 +26,17 @@ impl GracefulShutdownRegistry { } impl From> for GracefulShutdownRegistry { - fn from(inner: InnerShared) -> Self { GracefulShutdownRegistry { inner } } + fn from(inner: InnerShared) -> Self { + GracefulShutdownRegistry { inner } + } } impl AbortableSystem for GracefulShutdownRegistry { type Inner = ShutdownInnerState; - fn __inner(&self) -> InnerShared { self.inner.clone() } + fn __inner(&self) -> InnerShared { + self.inner.clone() + } fn __push_subsystem_abort_tx(&self, subsystem_abort_tx: oneshot::Sender<()>) -> Result<(), AbortedError> { self.inner.lock().insert_handle(subsystem_abort_tx) @@ -74,5 +78,7 @@ impl SystemInner for ShutdownInnerState { Ok(()) } - fn is_aborted(&self) -> bool { matches!(self, ShutdownInnerState::Aborted) } + fn is_aborted(&self) -> bool { + matches!(self, ShutdownInnerState::Aborted) + } } diff --git a/mm2src/common/executor/abortable_system/mod.rs b/mm2src/common/executor/abortable_system/mod.rs index 82ef564278..66bae0445c 100644 --- a/mm2src/common/executor/abortable_system/mod.rs +++ b/mm2src/common/executor/abortable_system/mod.rs @@ -16,7 +16,9 @@ pub type InnerWeak = Weak>; pub struct AbortedError; impl fmt::Display for AbortedError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Abortable system has been aborted already") } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Abortable system has been aborted already") + } } pub trait AbortableSystem: From> { @@ -24,7 +26,9 @@ pub trait AbortableSystem: From> { /// Aborts all spawned futures and subsystems if they present. /// The abortable system is considered not to be - fn abort_all(&self) -> Result<(), AbortedError> { self.__inner().lock().abort_all() } + fn abort_all(&self) -> Result<(), AbortedError> { + self.__inner().lock().abort_all() + } /// Aborts all the spawned futures & subsystems if present, and resets the system /// to the initial state for further use. diff --git a/mm2src/common/executor/abortable_system/simple_map.rs b/mm2src/common/executor/abortable_system/simple_map.rs index d759d53a04..50af2d2624 100644 --- a/mm2src/common/executor/abortable_system/simple_map.rs +++ b/mm2src/common/executor/abortable_system/simple_map.rs @@ -29,13 +29,17 @@ pub struct AbortableSimpleMap { impl AbortableSimpleMap { /// Locks the inner `SimpleMapInner` that can be used to spawn/abort/check if contains future /// by its `FutureId` identifier. - pub fn lock(&self) -> PaMutexGuard<'_, SimpleMapInnerState> { self.inner.lock() } + pub fn lock(&self) -> PaMutexGuard<'_, SimpleMapInnerState> { + self.inner.lock() + } } impl AbortableSystem for AbortableSimpleMap { type Inner = SimpleMapInnerState; - fn __inner(&self) -> InnerShared { self.inner.clone() } + fn __inner(&self) -> InnerShared { + self.inner.clone() + } fn __push_subsystem_abort_tx(&self, subsystem_abort_tx: oneshot::Sender<()>) -> Result<(), AbortedError> { self.inner.lock().insert_subsystem(subsystem_abort_tx) @@ -43,7 +47,9 @@ impl AbortableSystem for AbortableSimpleMap { } impl From>> for AbortableSimpleMap { - fn from(inner: InnerShared>) -> Self { AbortableSimpleMap { inner } } + fn from(inner: InnerShared>) -> Self { + AbortableSimpleMap { inner } + } } pub enum SimpleMapInnerState { @@ -82,7 +88,9 @@ impl SystemInner for SimpleMapInnerState { Ok(()) } - fn is_aborted(&self) -> bool { matches!(self, SimpleMapInnerState::Aborted) } + fn is_aborted(&self) -> bool { + matches!(self, SimpleMapInnerState::Aborted) + } } impl SimpleMapInnerState { diff --git a/mm2src/common/executor/mod.rs b/mm2src/common/executor/mod.rs index c11460a22e..0dbeb9c36e 100644 --- a/mm2src/common/executor/mod.rs +++ b/mm2src/common/executor/mod.rs @@ -1,7 +1,8 @@ use futures::future::abortable; use futures::{Future as Future03, FutureExt}; -#[cfg(not(target_arch = "wasm32"))] mod native_executor; +#[cfg(not(target_arch = "wasm32"))] +mod native_executor; #[cfg(not(target_arch = "wasm32"))] pub use native_executor::{spawn, Timer}; @@ -14,7 +15,8 @@ pub use spawner::{BoxFutureSpawner, SpawnAbortable, SpawnFuture}; mod abort_on_drop; pub use abort_on_drop::AbortOnDropHandle; -#[cfg(target_arch = "wasm32")] mod wasm_executor; +#[cfg(target_arch = "wasm32")] +mod wasm_executor; #[cfg(target_arch = "wasm32")] pub use wasm_executor::{spawn, spawn_local, spawn_local_abortable, Timer}; diff --git a/mm2src/common/executor/native_executor.rs b/mm2src/common/executor/native_executor.rs index 6876355b88..2e95f2fc50 100644 --- a/mm2src/common/executor/native_executor.rs +++ b/mm2src/common/executor/native_executor.rs @@ -9,7 +9,9 @@ use std::time::Duration; /// /// The `spawn` function must be used carefully to avoid hanging pointers. /// Please consider using `AbortableQueue`, `AbortableSimpleMap` or `spawn_abortable` instead. -pub fn spawn(future: impl Future03 + Send + 'static) { crate::wio::CORE.0.spawn(future); } +pub fn spawn(future: impl Future03 + Send + 'static) { + crate::wio::CORE.0.spawn(future); +} /// A future that completes at a given time. #[must_use] @@ -34,7 +36,9 @@ impl Timer { impl Future03 for Timer { type Output = (); - fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll03 { Pin::new(&mut self.delay).poll(cx) } + fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll03 { + Pin::new(&mut self.delay).poll(cx) + } } #[cfg(test)] diff --git a/mm2src/common/executor/spawner.rs b/mm2src/common/executor/spawner.rs index 169c97ce14..6ec1558d02 100644 --- a/mm2src/common/executor/spawner.rs +++ b/mm2src/common/executor/spawner.rs @@ -6,7 +6,9 @@ pub trait BoxFutureSpawner { } impl BoxFutureSpawner for S { - fn spawn_boxed(&self, f: Box + Send + Unpin + 'static>) { self.spawn(f) } + fn spawn_boxed(&self, f: Box + Send + Unpin + 'static>) { + self.spawn(f) + } } pub trait SpawnFuture { diff --git a/mm2src/common/executor/wasm_executor.rs b/mm2src/common/executor/wasm_executor.rs index 422f564623..e3533a3e17 100644 --- a/mm2src/common/executor/wasm_executor.rs +++ b/mm2src/common/executor/wasm_executor.rs @@ -23,13 +23,17 @@ extern "C" { /// /// The `spawn` function must be used carefully to avoid hanging pointers. /// Please consider using `AbortableQueue`, `AbortableSimpleMap` or `spawn_abortable` instead. -pub fn spawn(future: impl Future + Send + 'static) { spawn_local(future) } +pub fn spawn(future: impl Future + Send + 'static) { + spawn_local(future) +} /// # Important /// /// The `spawn` function must be used carefully to avoid hanging pointers. /// Please consider using `AbortableQueue`, `AbortableSimpleMap` or `spawn_abortable` instead. -pub fn spawn_local(future: impl Future + 'static) { wasm_bindgen_futures::spawn_local(future) } +pub fn spawn_local(future: impl Future + 'static) { + wasm_bindgen_futures::spawn_local(future) +} pub fn spawn_local_abortable(future: impl Future + 'static) -> AbortOnDropHandle { let (abortable, handle) = abortable(future); @@ -96,7 +100,9 @@ impl Timer { /// When the `Timer` is destroyed, cancel its `setTimeout` timer. impl Drop for Timer { - fn drop(&mut self) { clearTimeout(self.timeout_id) } + fn drop(&mut self) { + clearTimeout(self.timeout_id) + } } impl Future for Timer { diff --git a/mm2src/common/jsonrpc_client.rs b/mm2src/common/jsonrpc_client.rs index 96669d160a..4e790a122d 100644 --- a/mm2src/common/jsonrpc_client.rs +++ b/mm2src/common/jsonrpc_client.rs @@ -56,15 +56,21 @@ pub type RpcRes = Box + Send + 'st pub struct JsonRpcRemoteAddr(pub String); impl fmt::Debug for JsonRpcRemoteAddr { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0) } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } } impl From for String { - fn from(addr: JsonRpcRemoteAddr) -> Self { addr.0 } + fn from(addr: JsonRpcRemoteAddr) -> Self { + addr.0 + } } impl From for JsonRpcRemoteAddr { - fn from(addr: String) -> Self { JsonRpcRemoteAddr(addr) } + fn from(addr: String) -> Self { + JsonRpcRemoteAddr(addr) + } } /// The identifier is designed to uniquely match outgoing requests and incoming responses. @@ -122,11 +128,15 @@ pub struct JsonRpcRequest { impl JsonRpcRequest { /// Returns a `JsonRpcId` identifier of the request. #[inline] - pub fn rpc_id(&self) -> JsonRpcId { JsonRpcId::Single(self.id) } + pub fn rpc_id(&self) -> JsonRpcId { + JsonRpcId::Single(self.id) + } } impl From for JsonRpcRequestEnum { - fn from(single: JsonRpcRequest) -> Self { JsonRpcRequestEnum::Single(single) } + fn from(single: JsonRpcRequest) -> Self { + JsonRpcRequestEnum::Single(single) + } } /// Serializable RPC batch request. @@ -145,20 +155,28 @@ impl JsonRpcBatchRequest { /// Returns the number of the requests in the batch. #[inline] - pub fn len(&self) -> usize { self.0.len() } + pub fn len(&self) -> usize { + self.0.len() + } /// Whether the batch is empty. #[inline] - pub fn is_empty(&self) -> bool { self.0.is_empty() } + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } /// Returns original sequence of identifiers. /// The method is used to process batch responses in the same order in which the requests were sent. #[inline] - fn orig_sequence_ids(&self) -> impl Iterator + '_ { self.0.iter().map(|req| req.id) } + fn orig_sequence_ids(&self) -> impl Iterator + '_ { + self.0.iter().map(|req| req.id) + } } impl From for JsonRpcRequestEnum { - fn from(batch: JsonRpcBatchRequest) -> Self { JsonRpcRequestEnum::Batch(batch) } + fn from(batch: JsonRpcBatchRequest) -> Self { + JsonRpcRequestEnum::Batch(batch) + } } /// Deserializable RPC response that is either single or batch. @@ -196,7 +214,9 @@ pub struct JsonRpcResponse { impl JsonRpcResponse { /// Returns a `JsonRpcId` identifier of the response. #[inline] - pub fn rpc_id(&self) -> JsonRpcId { JsonRpcId::Single(self.id) } + pub fn rpc_id(&self) -> JsonRpcId { + JsonRpcId::Single(self.id) + } } /// Deserializable RPC batch response. @@ -214,18 +234,24 @@ impl JsonRpcBatchResponse { /// Returns the number of the requests in the batch. #[inline] - pub fn len(&self) -> usize { self.0.len() } + pub fn len(&self) -> usize { + self.0.len() + } /// Whether the batch is empty. #[inline] - pub fn is_empty(&self) -> bool { self.0.is_empty() } + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } } impl IntoIterator for JsonRpcBatchResponse { type Item = JsonRpcResponse; type IntoIter = std::vec::IntoIter; - fn into_iter(self) -> Self::IntoIter { self.0.into_iter() } + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } } #[derive(Clone, Debug)] @@ -240,7 +266,9 @@ pub struct JsonRpcError { } impl fmt::Display for JsonRpcError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self) } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self) + } } impl JsonRpcError { @@ -267,11 +295,15 @@ pub enum JsonRpcErrorType { } impl JsonRpcErrorType { - pub fn parse_error(remote_addr: &str, err: String) -> Self { Self::Parse(remote_addr.to_string().into(), err) } + pub fn parse_error(remote_addr: &str, err: String) -> Self { + Self::Parse(remote_addr.to_string().into(), err) + } /// Whether the error type is [`JsonRpcErrorType::Transport`]. #[inline] - pub fn is_transport(&self) -> bool { matches!(self, JsonRpcErrorType::Transport(_)) } + pub fn is_transport(&self) -> bool { + matches!(self, JsonRpcErrorType::Transport(_)) + } } pub trait JsonRpcClient { diff --git a/mm2src/common/log.rs b/mm2src/common/log.rs index 14b0403b79..31c9a1a492 100644 --- a/mm2src/common/log.rs +++ b/mm2src/common/log.rs @@ -90,7 +90,9 @@ impl Gravity { } } #[cfg(target_arch = "wasm32")] - fn chunk2log(&self, chunk: String) { self.landing.push(chunk); } + fn chunk2log(&self, chunk: String) { + self.landing.push(chunk); + } /// Prints the collected log chunks. /// `println!` is used for compatibility with unit test stdout capturing. @@ -329,33 +331,57 @@ pub trait TagParam<'a> { } impl<'a> TagParam<'a> for &'a str { - fn key(&self) -> String { String::from(&self[..]) } - fn val(&self) -> Option { None } + fn key(&self) -> String { + String::from(&self[..]) + } + fn val(&self) -> Option { + None + } } impl TagParam<'_> for String { - fn key(&self) -> String { self.clone() } - fn val(&self) -> Option { None } + fn key(&self) -> String { + self.clone() + } + fn val(&self) -> Option { + None + } } impl<'a> TagParam<'a> for (&'a str, &'a str) { - fn key(&self) -> String { String::from(self.0) } - fn val(&self) -> Option { Some(String::from(self.1)) } + fn key(&self) -> String { + String::from(self.0) + } + fn val(&self) -> Option { + Some(String::from(self.1)) + } } impl<'a> TagParam<'a> for (String, &'a str) { - fn key(&self) -> String { self.0.clone() } - fn val(&self) -> Option { Some(String::from(self.1)) } + fn key(&self) -> String { + self.0.clone() + } + fn val(&self) -> Option { + Some(String::from(self.1)) + } } impl<'a> TagParam<'a> for (&'a str, i32) { - fn key(&self) -> String { String::from(self.0) } - fn val(&self) -> Option { Some(self.1.to_string()) } + fn key(&self) -> String { + String::from(self.0) + } + fn val(&self) -> Option { + Some(self.1.to_string()) + } } impl TagParam<'_> for (String, String) { - fn key(&self) -> String { self.0.clone() } - fn val(&self) -> Option { Some(self.1.clone()) } + fn key(&self) -> String { + self.0.clone() + } + fn val(&self) -> Option { + Some(self.1.clone()) + } } #[derive(Clone, Eq, Hash, PartialEq)] @@ -628,18 +654,26 @@ pub struct LogArc(pub Arc); impl Deref for LogArc { type Target = LogState; - fn deref(&self) -> &LogState { &self.0 } + fn deref(&self) -> &LogState { + &self.0 + } } impl LogArc { /// Create LogArc from real `LogState`. - pub fn new(state: LogState) -> LogArc { LogArc(Arc::new(state)) } + pub fn new(state: LogState) -> LogArc { + LogArc(Arc::new(state)) + } /// Try to obtain the `LogState` from the weak pointer. - pub fn from_weak(weak: &LogWeak) -> Option { weak.0.upgrade().map(LogArc) } + pub fn from_weak(weak: &LogWeak) -> Option { + weak.0.upgrade().map(LogArc) + } /// Create a weak pointer to `LogState`. - pub fn weak(&self) -> LogWeak { LogWeak(Arc::downgrade(&self.0)) } + pub fn weak(&self) -> LogWeak { + LogWeak(Arc::downgrade(&self.0)) + } } #[derive(Default)] @@ -647,9 +681,13 @@ pub struct LogWeak(pub Weak); impl LogWeak { /// Create a default MmWeak without allocating any memory. - pub fn new() -> LogWeak { Default::default() } + pub fn new() -> LogWeak { + Default::default() + } - pub fn dropped(&self) -> bool { self.0.strong_count() == 0 } + pub fn dropped(&self) -> bool { + self.0.strong_count() == 0 + } } /// The state used to periodically log the dashboard. @@ -768,7 +806,9 @@ impl LogState { } } - pub fn set_level(&mut self, level: LogLevel) { self.level = level; } + pub fn set_level(&mut self, level: LogLevel) { + self.level = level; + } /// The operation is considered "in progress" while the `StatusHandle` exists. /// @@ -977,7 +1017,9 @@ impl LogState { } } #[cfg(target_arch = "wasm32")] - pub fn thread_gravity_on(&self) -> Result<(), String> { Ok(()) } + pub fn thread_gravity_on(&self) -> Result<(), String> { + Ok(()) + } /// Start intercepting the `log!` invocations happening on the current thread. #[cfg(not(target_arch = "wasm32"))] @@ -994,7 +1036,9 @@ impl LogState { Ok(()) } #[cfg(target_arch = "wasm32")] - pub fn register_my_thread(&self) -> Result<(), String> { Ok(()) } + pub fn register_my_thread(&self) -> Result<(), String> { + Ok(()) + } } #[cfg(not(target_arch = "wasm32"))] diff --git a/mm2src/common/log/native_log.rs b/mm2src/common/log/native_log.rs index 739b7d017e..48d118d527 100644 --- a/mm2src/common/log/native_log.rs +++ b/mm2src/common/log/native_log.rs @@ -52,7 +52,9 @@ pub struct UnifiedLoggerBuilder { } impl UnifiedLoggerBuilder { - pub fn new() -> UnifiedLoggerBuilder { UnifiedLoggerBuilder::default() } + pub fn new() -> UnifiedLoggerBuilder { + UnifiedLoggerBuilder::default() + } pub fn silent_console(mut self, silent_console: bool) -> UnifiedLoggerBuilder { self.silent_console = silent_console; diff --git a/mm2src/common/log/wasm_log.rs b/mm2src/common/log/wasm_log.rs index 3d7f83a16b..ba82d81be4 100644 --- a/mm2src/common/log/wasm_log.rs +++ b/mm2src/common/log/wasm_log.rs @@ -67,11 +67,15 @@ pub enum LogLevel { } impl Default for LogLevel { - fn default() -> Self { DEFAULT_LEVEL_FILTER } + fn default() -> Self { + DEFAULT_LEVEL_FILTER + } } impl From for JsValue { - fn from(lvl: LogLevel) -> Self { JsValue::from(lvl as u32) } + fn from(lvl: LogLevel) -> Self { + JsValue::from(lvl as u32) + } } pub struct WasmCallback { @@ -160,7 +164,9 @@ struct WasmLogger { } impl Log for WasmLogger { - fn enabled(&self, metadata: &Metadata) -> bool { LogLevel::from(metadata.level()) <= self.filter } + fn enabled(&self, metadata: &Metadata) -> bool { + LogLevel::from(metadata.level()) <= self.filter + } fn log(&self, record: &Record) { if let Some(ref mut log_cb) = *LOG_CALLBACK.lock() { diff --git a/mm2src/common/notifier.rs b/mm2src/common/notifier.rs index a82253b537..ab47e90d80 100644 --- a/mm2src/common/notifier.rs +++ b/mm2src/common/notifier.rs @@ -49,5 +49,7 @@ impl Notifiee { } /// Clears the pending notifications if there are any. - fn clear(&mut self) { while let Ok(Some(_)) = self.0.try_next() {} } + fn clear(&mut self) { + while let Ok(Some(_)) = self.0.try_next() {} + } } diff --git a/mm2src/common/number_type_casting.rs b/mm2src/common/number_type_casting.rs index 63dcd41521..5ea39cf8fa 100644 --- a/mm2src/common/number_type_casting.rs +++ b/mm2src/common/number_type_casting.rs @@ -20,8 +20,12 @@ pub trait SafeTypeCastingNumbers: Sized { macro_rules! impl_safe_number_type_cast { ($from: ident, $to: ident) => { impl SafeTypeCastingNumbers<$to> for $from { - fn into_or(self, or: $to) -> $to { std::convert::TryFrom::try_from(self).unwrap_or(or) } - fn into_or_max(self) -> $to { std::convert::TryFrom::try_from(self).unwrap_or($to::MAX) } + fn into_or(self, or: $to) -> $to { + std::convert::TryFrom::try_from(self).unwrap_or(or) + } + fn into_or_max(self) -> $to { + std::convert::TryFrom::try_from(self).unwrap_or($to::MAX) + } } }; } diff --git a/mm2src/common/on_drop_callback.rs b/mm2src/common/on_drop_callback.rs index a454cc9554..3f128635b5 100644 --- a/mm2src/common/on_drop_callback.rs +++ b/mm2src/common/on_drop_callback.rs @@ -7,7 +7,9 @@ pub struct OnDropCallback(Option>); impl OnDropCallback { - pub fn new(f: impl FnOnce() + Send + 'static) -> Self { Self(Some(Box::new(f))) } + pub fn new(f: impl FnOnce() + Send + 'static) -> Self { + Self(Some(Box::new(f))) + } } impl Drop for OnDropCallback { diff --git a/mm2src/common/seri.rs b/mm2src/common/seri.rs index 080dfa4dc0..59f90b2c5e 100644 --- a/mm2src/common/seri.rs +++ b/mm2src/common/seri.rs @@ -8,7 +8,9 @@ pub fn de_none_if_empty<'de, D: Deserializer<'de>>(des: D) -> Result for Visitor { type Value = Option; - fn expecting(&self, fm: &mut fmt::Formatter) -> fmt::Result { fm.write_str("Optional string") } + fn expecting(&self, fm: &mut fmt::Formatter) -> fmt::Result { + fm.write_str("Optional string") + } fn visit_none(self) -> Result, E> where diff --git a/mm2src/common/shared_ref_counter/src/disable.rs b/mm2src/common/shared_ref_counter/src/disable.rs index 3c93985b9d..eb11ea267e 100644 --- a/mm2src/common/shared_ref_counter/src/disable.rs +++ b/mm2src/common/shared_ref_counter/src/disable.rs @@ -10,20 +10,30 @@ unsafe impl Sync for SharedRc {} impl Deref for SharedRc { type Target = T; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { + &self.0 + } } impl Clone for SharedRc { - fn clone(&self) -> Self { SharedRc(self.0.clone()) } + fn clone(&self) -> Self { + SharedRc(self.0.clone()) + } } impl SharedRc { - pub fn new(inner: T) -> Self { SharedRc(Arc::new(inner)) } + pub fn new(inner: T) -> Self { + SharedRc(Arc::new(inner)) + } - pub fn existing_pointers(&self) -> Vec<&'static Location<'static>> { Vec::new() } + pub fn existing_pointers(&self) -> Vec<&'static Location<'static>> { + Vec::new() + } /// Generates a weak pointer, to track the allocated data without prolonging its life. - pub fn downgrade(&self) -> WeakRc { WeakRc(Arc::downgrade(&self.0)) } + pub fn downgrade(&self) -> WeakRc { + WeakRc(Arc::downgrade(&self.0)) + } } pub struct WeakRc(Weak); @@ -32,15 +42,23 @@ unsafe impl Send for WeakRc where Weak: Send {} unsafe impl Sync for WeakRc {} impl Clone for WeakRc { - fn clone(&self) -> Self { WeakRc(self.0.clone()) } + fn clone(&self) -> Self { + WeakRc(self.0.clone()) + } } impl Default for WeakRc { - fn default() -> Self { WeakRc(Weak::default()) } + fn default() -> Self { + WeakRc(Weak::default()) + } } impl WeakRc { - pub fn upgrade(&self) -> Option> { self.0.upgrade().map(SharedRc) } + pub fn upgrade(&self) -> Option> { + self.0.upgrade().map(SharedRc) + } - pub fn strong_count(&self) -> usize { self.0.strong_count() } + pub fn strong_count(&self) -> usize { + self.0.strong_count() + } } diff --git a/mm2src/common/shared_ref_counter/src/enable.rs b/mm2src/common/shared_ref_counter/src/enable.rs index 9654d894ce..39f11b2f20 100644 --- a/mm2src/common/shared_ref_counter/src/enable.rs +++ b/mm2src/common/shared_ref_counter/src/enable.rs @@ -1,4 +1,5 @@ -#[cfg(feature = "log")] use log::{log, Level}; +#[cfg(feature = "log")] +use log::{log, Level}; use std::collections::HashMap; use std::ops::Deref; use std::panic::Location; @@ -21,7 +22,9 @@ unsafe impl Sync for SharedRc {} impl Deref for SharedRc { type Target = T; - fn deref(&self) -> &Self::Target { &self.inner } + fn deref(&self) -> &Self::Target { + &self.inner + } } impl Drop for SharedRc { @@ -153,7 +156,9 @@ impl WeakRc { }) } - pub fn strong_count(&self) -> usize { self.inner.strong_count() } + pub fn strong_count(&self) -> usize { + self.inner.strong_count() + } } #[cfg(feature = "log")] diff --git a/mm2src/common/shared_ref_counter/src/lib.rs b/mm2src/common/shared_ref_counter/src/lib.rs index 864553dc75..802380ac65 100644 --- a/mm2src/common/shared_ref_counter/src/lib.rs +++ b/mm2src/common/shared_ref_counter/src/lib.rs @@ -22,9 +22,12 @@ //! Some operations over `SharedRc` may lead to a panic if the `enable` features is activated. //! This behavior is considered acceptable since the `enable` feature is expected to be used for **debug** purposes only. -#[cfg(not(feature = "enable"))] mod disable; -#[cfg(feature = "enable")] mod enable; +#[cfg(not(feature = "enable"))] +mod disable; +#[cfg(feature = "enable")] +mod enable; #[cfg(not(feature = "enable"))] pub use disable::{SharedRc, WeakRc}; -#[cfg(feature = "enable")] pub use enable::{SharedRc, WeakRc}; +#[cfg(feature = "enable")] +pub use enable::{SharedRc, WeakRc}; diff --git a/mm2src/common/wio.rs b/mm2src/common/wio.rs index 7f436f8f2b..cf708b11f8 100644 --- a/mm2src/common/wio.rs +++ b/mm2src/common/wio.rs @@ -11,7 +11,9 @@ use std::fmt; use std::sync::Mutex; use tokio::runtime::Runtime; -fn start_core_thread() -> Mm2Runtime { Mm2Runtime(Runtime::new().unwrap()) } +fn start_core_thread() -> Mm2Runtime { + Mm2Runtime(Runtime::new().unwrap()) +} pub struct Mm2Runtime(pub Runtime); @@ -26,7 +28,9 @@ lazy_static! { } impl + Send + 'static> hyper::rt::Executor for &Mm2Runtime { - fn execute(&self, fut: Fut) { self.0.spawn(fut); } + fn execute(&self, fut: Fut) { + self.0.spawn(fut); + } } /// With a shared reactor drives the future `f` to completion. diff --git a/mm2src/crypto/Cargo.toml b/mm2src/crypto/Cargo.toml index 52c36a6cdb..2999e3053b 100644 --- a/mm2src/crypto/Cargo.toml +++ b/mm2src/crypto/Cargo.toml @@ -32,7 +32,7 @@ lazy_static.workspace = true mm2_core = { path = "../mm2_core" } mm2_err_handle = { path = "../mm2_err_handle" } num-traits.workspace = true -parking_lot = { workspace = true, features = ["nightly"] } +parking_lot = { workspace = true } primitives = { path = "../mm2_bitcoin/primitives" } rpc = { path = "../mm2_bitcoin/rpc" } rpc_task = { path = "../rpc_task" } diff --git a/mm2src/crypto/src/bip32_child.rs b/mm2src/crypto/src/bip32_child.rs index a187398563..f7b2d978a8 100644 --- a/mm2src/crypto/src/bip32_child.rs +++ b/mm2src/crypto/src/bip32_child.rs @@ -29,11 +29,15 @@ pub enum Bip32DerPathError { } impl From for Bip32DerPathError { - fn from(e: Bip32Error) -> Self { Bip32DerPathError::Bip32Error(e) } + fn from(e: Bip32Error) -> Self { + Bip32DerPathError::Bip32Error(e) + } } pub trait Bip32DerPathOps: Sized { - fn to_derivation_path(&self) -> DerivationPath { DerivationPath::default() } + fn to_derivation_path(&self) -> DerivationPath { + DerivationPath::default() + } fn derive(&self, bip32_number: ChildNumber) -> Result where @@ -47,7 +51,9 @@ pub trait Bip32DerPathOps: Sized { pub trait Bip32InternalOps: Sized { /// This method is used to get the number of expected children. - fn depth() -> usize { 0 } + fn depth() -> usize { + 0 + } fn from_iter(iter: I, current_depth: usize) -> Result where @@ -55,7 +61,9 @@ pub trait Bip32InternalOps: Sized { fn fill_derivation_path(&self, _derivation_path: &mut DerivationPath) {} - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { Ok(()) } + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + Ok(()) + } } pub trait Bip32ChildValue: Sized { @@ -82,11 +90,17 @@ pub struct AnyValue { impl Bip32ChildValue for AnyValue { type Value = u32; - fn hardened() -> bool { HARDENED } + fn hardened() -> bool { + HARDENED + } - fn number(&self) -> u32 { self.number } + fn number(&self) -> u32 { + self.number + } - fn value(&self) -> Self::Value { self.number } + fn value(&self) -> Self::Value { + self.number + } fn from_bip32_number(child_number: ChildNumber, child_at: usize) -> Result { if child_number.is_hardened() == HARDENED { @@ -109,7 +123,9 @@ pub struct Bip32Child { } impl fmt::Debug for Bip32Child { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self) } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self) + } } impl fmt::Display for Bip32Child { @@ -190,7 +206,9 @@ where Child: Bip32InternalOps, Value: Bip32ChildValue, { - fn depth() -> usize { Child::depth() + 1 } + fn depth() -> usize { + Child::depth() + 1 + } fn from_iter(mut iter: I, current_depth: usize) -> Result where @@ -221,9 +239,13 @@ where } impl Bip32Child { - pub fn value(&self) -> Value::Value { self.value.value() } + pub fn value(&self) -> Value::Value { + self.value.value() + } - pub fn child(&self) -> &Child { &self.child } + pub fn child(&self) -> &Child { + &self.child + } } #[derive(Clone, PartialEq)] diff --git a/mm2src/crypto/src/crypto_ctx.rs b/mm2src/crypto/src/crypto_ctx.rs index e591ac37b4..a858c0a856 100644 --- a/mm2src/crypto/src/crypto_ctx.rs +++ b/mm2src/crypto/src/crypto_ctx.rs @@ -34,7 +34,9 @@ pub enum CryptoInitError { } impl From for CryptoInitError { - fn from(e: PrivKeyError) -> Self { CryptoInitError::InvalidPassphrase(e) } + fn from(e: PrivKeyError) -> Self { + CryptoInitError::InvalidPassphrase(e) + } } impl From for CryptoInitError { @@ -85,7 +87,9 @@ pub enum MetamaskCtxInitError { #[cfg(target_arch = "wasm32")] impl From for MetamaskCtxInitError { - fn from(value: MetamaskError) -> Self { MetamaskCtxInitError::MetamaskError(value) } + fn from(value: MetamaskError) -> Self { + MetamaskCtxInitError::MetamaskError(value) + } } pub struct CryptoCtx { @@ -126,7 +130,9 @@ impl CryptoCtx { } #[inline] - pub fn key_pair_policy(&self) -> &KeyPairPolicy { &self.key_pair_policy } + pub fn key_pair_policy(&self) -> &KeyPairPolicy { + &self.key_pair_policy + } /// This is our public ID, allowing us to be different from other peers. /// This should also be our public key which we'd use for P2P message verification. @@ -150,7 +156,9 @@ impl CryptoCtx { /// If [`CryptoCtx::key_pair_ctx`] is `Iguana`, then the returning key-pair is used to activate coins. /// Please use this method carefully. #[inline] - pub fn mm2_internal_key_pair(&self) -> &KeyPair { &self.secp256k1_key_pair } + pub fn mm2_internal_key_pair(&self) -> &KeyPair { + &self.secp256k1_key_pair + } /// Returns `secp256k1` public key. /// It can be used for mm2 internal purposes such as P2P peer ID. @@ -163,7 +171,9 @@ impl CryptoCtx { /// at the activated coins. /// Please use this method carefully. #[inline] - pub fn mm2_internal_pubkey(&self) -> PublicKey { *self.secp256k1_key_pair.public() } + pub fn mm2_internal_pubkey(&self) -> PublicKey { + *self.secp256k1_key_pair.public() + } /// Returns `secp256k1` public key hex. /// It can be used for mm2 internal purposes such as P2P peer ID. @@ -176,7 +186,9 @@ impl CryptoCtx { /// at the activated coins. /// Please use this method carefully. #[inline] - pub fn mm2_internal_pubkey_hex(&self) -> String { hex::encode(&*self.mm2_internal_pubkey()) } + pub fn mm2_internal_pubkey_hex(&self) -> String { + hex::encode(&*self.mm2_internal_pubkey()) + } /// Returns `secp256k1` private key as `H256` bytes. /// It can be used for mm2 internal purposes such as signing P2P messages. @@ -188,7 +200,9 @@ impl CryptoCtx { /// If [`CryptoCtx::key_pair_ctx`] is `Iguana`, then the returning private is used to activate coins. /// Please use this method carefully. #[inline] - pub fn mm2_internal_privkey_secret(&self) -> Secp256k1Secret { self.secp256k1_key_pair.private().secret } + pub fn mm2_internal_privkey_secret(&self) -> Secp256k1Secret { + self.secp256k1_key_pair.private().secret + } /// Returns `secp256k1` private key as `[u8]` slice. /// It can be used for mm2 internal purposes such as signing P2P messages. @@ -202,17 +216,25 @@ impl CryptoCtx { /// If [`CryptoCtx::key_pair_ctx`] is `Iguana`, then the returning private is used to activate coins. /// Please use this method carefully. #[inline] - pub fn mm2_internal_privkey_slice(&self) -> &[u8] { self.secp256k1_key_pair.private().secret.as_slice() } + pub fn mm2_internal_privkey_slice(&self) -> &[u8] { + self.secp256k1_key_pair.private().secret.as_slice() + } #[inline] - pub fn hw_ctx(&self) -> Option { self.hw_ctx.read().to_option().cloned() } + pub fn hw_ctx(&self) -> Option { + self.hw_ctx.read().to_option().cloned() + } #[cfg(target_arch = "wasm32")] - pub fn metamask_ctx(&self) -> Option { self.metamask_ctx.read().to_option().cloned() } + pub fn metamask_ctx(&self) -> Option { + self.metamask_ctx.read().to_option().cloned() + } /// Returns an `RIPEMD160(SHA256(x))` where x is secp256k1 pubkey that identifies a Hardware Wallet device or an HD master private key. #[inline] - pub fn hw_wallet_rmd160(&self) -> Option { self.hw_ctx.read().to_option().map(|hw_ctx| hw_ctx.rmd160()) } + pub fn hw_wallet_rmd160(&self) -> Option { + self.hw_ctx.read().to_option().map(|hw_ctx| hw_ctx.rmd160()) + } pub fn init_with_iguana_passphrase(ctx: MmArc, passphrase: &str) -> CryptoInitResult> { Self::init_crypto_ctx_with_policy_builder(ctx, passphrase, KeyPairPolicyBuilder::Iguana) diff --git a/mm2src/crypto/src/decrypt.rs b/mm2src/crypto/src/decrypt.rs index a0c750f58c..ce519c3c3a 100644 --- a/mm2src/crypto/src/decrypt.rs +++ b/mm2src/crypto/src/decrypt.rs @@ -22,7 +22,9 @@ pub enum DecryptionError { } impl From for DecryptionError { - fn from(e: base64::DecodeError) -> Self { DecryptionError::DecodeError(e.to_string()) } + fn from(e: base64::DecodeError) -> Self { + DecryptionError::DecodeError(e.to_string()) + } } /// Decrypts the provided encrypted data using AES-256-CBC decryption and HMAC for integrity check. diff --git a/mm2src/crypto/src/global_hd_ctx.rs b/mm2src/crypto/src/global_hd_ctx.rs index 6496065ab4..913ad97a3b 100644 --- a/mm2src/crypto/src/global_hd_ctx.rs +++ b/mm2src/crypto/src/global_hd_ctx.rs @@ -18,7 +18,9 @@ pub struct GlobalHDAccountArc(Arc); impl Deref for GlobalHDAccountArc { type Target = GlobalHDAccountCtx; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { + &self.0 + } } #[derive(Zeroize, ZeroizeOnDrop)] @@ -56,16 +58,24 @@ impl GlobalHDAccountCtx { } #[inline] - pub fn into_arc(self) -> GlobalHDAccountArc { GlobalHDAccountArc(Arc::new(self)) } + pub fn into_arc(self) -> GlobalHDAccountArc { + GlobalHDAccountArc(Arc::new(self)) + } /// Returns the root BIP39 seed. - pub fn root_seed(&self) -> &Bip39Seed { &self.bip39_seed } + pub fn root_seed(&self) -> &Bip39Seed { + &self.bip39_seed + } /// Returns the root BIP39 seed as bytes. - pub fn root_seed_bytes(&self) -> &[u8] { &self.bip39_seed.0 } + pub fn root_seed_bytes(&self) -> &[u8] { + &self.bip39_seed.0 + } /// Returns the root BIP39 private key. - pub fn root_priv_key(&self) -> &ExtendedPrivateKey { &self.bip39_secp_priv_key } + pub fn root_priv_key(&self) -> &ExtendedPrivateKey { + &self.bip39_secp_priv_key + } /// Derives a `secp256k1::SecretKey` from [`HDAccountCtx::bip39_secp_priv_key`] /// at the given `m/purpose'/coin_type'/account_id'/chain/address_id` derivation path, diff --git a/mm2src/crypto/src/hw_client.rs b/mm2src/crypto/src/hw_client.rs index d9c6679e26..04af2279ba 100644 --- a/mm2src/crypto/src/hw_client.rs +++ b/mm2src/crypto/src/hw_client.rs @@ -25,11 +25,15 @@ pub enum HwProcessingError { } impl From for HwProcessingError { - fn from(e: HwError) -> Self { HwProcessingError::HwError(e) } + fn from(e: HwError) -> Self { + HwProcessingError::HwError(e) + } } impl From for HwProcessingError { - fn from(e: TrezorError) -> Self { HwProcessingError::HwError(HwError::from(e)) } + fn from(e: TrezorError) -> Self { + HwProcessingError::HwError(HwError::from(e)) + } } impl From> for HwProcessingError { @@ -78,7 +82,9 @@ pub enum HwClient { } impl From for HwClient { - fn from(trezor: TrezorClient) -> Self { HwClient::Trezor(trezor) } + fn from(trezor: TrezorClient) -> Self { + HwClient::Trezor(trezor) + } } impl HwClient { diff --git a/mm2src/crypto/src/hw_ctx.rs b/mm2src/crypto/src/hw_ctx.rs index cda40a1159..4ba3e8c1d6 100644 --- a/mm2src/crypto/src/hw_ctx.rs +++ b/mm2src/crypto/src/hw_ctx.rs @@ -1,4 +1,6 @@ -use crate::hw_client::{HwClient, HwConnectionStatus, HwDeviceInfo, HwProcessingError, HwPubkey, TrezorConnectProcessor}; +use crate::hw_client::{ + HwClient, HwConnectionStatus, HwDeviceInfo, HwProcessingError, HwPubkey, TrezorConnectProcessor, +}; use crate::hw_error::HwError; use crate::trezor::TrezorSession; use crate::{mm2_internal_der_path, HwWalletType}; @@ -27,11 +29,15 @@ pub struct HardwareWalletArc(Arc); impl Deref for HardwareWalletArc { type Target = HardwareWalletCtx; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { + &self.0 + } } impl HardwareWalletArc { - pub fn new(ctx: HardwareWalletCtx) -> HardwareWalletArc { HardwareWalletArc(Arc::new(ctx)) } + pub fn new(ctx: HardwareWalletCtx) -> HardwareWalletArc { + HardwareWalletArc(Arc::new(ctx)) + } } pub struct HardwareWalletCtx { @@ -72,7 +78,9 @@ impl HardwareWalletCtx { Ok((hw_device_info, hw_ctx)) } - pub fn hw_wallet_type(&self) -> HwWalletType { self.hw_wallet_type } + pub fn hw_wallet_type(&self) -> HwWalletType { + self.hw_wallet_type + } /// Returns a Trezor session. pub async fn trezor( @@ -108,13 +116,19 @@ impl HardwareWalletCtx { } } - pub fn secp256k1_pubkey(&self) -> PublicKey { PublicKey::Compressed(self.hw_internal_pubkey) } + pub fn secp256k1_pubkey(&self) -> PublicKey { + PublicKey::Compressed(self.hw_internal_pubkey) + } /// Returns `RIPEMD160(SHA256(x))` where x is a pubkey extracted from the Hardware wallet. - pub fn rmd160(&self) -> H160 { h160_from_h264(&self.hw_internal_pubkey) } + pub fn rmd160(&self) -> H160 { + h160_from_h264(&self.hw_internal_pubkey) + } /// Returns serializable/deserializable Hardware wallet pubkey. - pub fn hw_pubkey(&self) -> HwPubkey { hw_pubkey_from_h264(&self.hw_internal_pubkey) } + pub fn hw_pubkey(&self) -> HwPubkey { + hw_pubkey_from_h264(&self.hw_internal_pubkey) + } pub(crate) async fn trezor_mm_internal_pubkey( trezor_session: &mut TrezorSession<'_>, @@ -188,7 +202,11 @@ impl HardwareWalletCtx { } /// Applies `RIPEMD160(SHA256(h264))` to the given `h264`. -fn h160_from_h264(h264: &H264) -> H160 { dhash160(h264.as_slice()) } +fn h160_from_h264(h264: &H264) -> H160 { + dhash160(h264.as_slice()) +} /// Converts `H264` into a serializable/deserializable Hardware wallet pubkey. -fn hw_pubkey_from_h264(h264: &H264) -> HwPubkey { HwPubkey::from(h160_from_h264(h264).take()) } +fn hw_pubkey_from_h264(h264: &H264) -> HwPubkey { + HwPubkey::from(h160_from_h264(h264).take()) +} diff --git a/mm2src/crypto/src/hw_error.rs b/mm2src/crypto/src/hw_error.rs index 6631de5204..b82c926f94 100644 --- a/mm2src/crypto/src/hw_error.rs +++ b/mm2src/crypto/src/hw_error.rs @@ -83,7 +83,9 @@ impl From for HwError { } impl From for HwError { - fn from(e: Bip32Error) -> Self { HwError::InvalidXpub(e.to_string()) } + fn from(e: Bip32Error) -> Self { + HwError::InvalidXpub(e.to_string()) + } } /// This error enumeration is involved to be used as a part of another RPC error. diff --git a/mm2src/crypto/src/hw_rpc_task.rs b/mm2src/crypto/src/hw_rpc_task.rs index 140bcfba81..aefaed9c24 100644 --- a/mm2src/crypto/src/hw_rpc_task.rs +++ b/mm2src/crypto/src/hw_rpc_task.rs @@ -7,8 +7,9 @@ use serde::Serialize; use std::convert::TryFrom; use std::sync::Arc; use std::time::Duration; -use trezor::trezor_rpc_task::{RpcTask, RpcTaskError, RpcTaskHandleShared, TrezorRequestStatuses, - TrezorRpcTaskProcessor, TryIntoUserAction}; +use trezor::trezor_rpc_task::{ + RpcTask, RpcTaskError, RpcTaskHandleShared, TrezorRequestStatuses, TrezorRpcTaskProcessor, TryIntoUserAction, +}; use trezor::user_interaction::TrezorPassphraseResponse; use trezor::{TrezorProcessingError, TrezorRequestProcessor}; diff --git a/mm2src/crypto/src/key_derivation.rs b/mm2src/crypto/src/key_derivation.rs index 69cd1a4d66..9efbb9cdbe 100644 --- a/mm2src/crypto/src/key_derivation.rs +++ b/mm2src/crypto/src/key_derivation.rs @@ -31,7 +31,9 @@ pub enum KeyDerivationError { } impl From for KeyDerivationError { - fn from(e: argon2::password_hash::Error) -> Self { KeyDerivationError::PasswordHashingFailed(e.to_string()) } + fn from(e: argon2::password_hash::Error) -> Self { + KeyDerivationError::PasswordHashingFailed(e.to_string()) + } } /// Parameters for the Argon2 key derivation function. diff --git a/mm2src/crypto/src/lib.rs b/mm2src/crypto/src/lib.rs index f735203232..5efba0ce29 100644 --- a/mm2src/crypto/src/lib.rs +++ b/mm2src/crypto/src/lib.rs @@ -1,4 +1,5 @@ -#[macro_use] extern crate serde_derive; +#[macro_use] +extern crate serde_derive; mod bip32_child; mod crypto_ctx; @@ -18,24 +19,29 @@ mod slip21; mod standard_hd_path; mod xpub; -#[cfg(target_arch = "wasm32")] mod metamask_ctx; +#[cfg(target_arch = "wasm32")] +mod metamask_ctx; // Uncomment this to finish MetaMask login. -#[cfg(target_arch = "wasm32")] mod metamask_login; +#[cfg(target_arch = "wasm32")] +mod metamask_login; pub use bip32_child::{Bip32Child, Bip32DerPathError, Bip32DerPathOps, Bip44Tail}; pub use crypto_ctx::{CryptoCtx, CryptoCtxError, CryptoInitError, CryptoInitResult, HwCtxInitError, KeyPairPolicy}; pub use encrypt::EncryptedData; pub use global_hd_ctx::{derive_secp256k1_secret, GlobalHDAccountArc}; -pub use hw_client::{HwClient, HwConnectionStatus, HwDeviceInfo, HwProcessingError, HwPubkey, HwWalletType, - TrezorConnectProcessor}; -pub use hw_common::primitives::{Bip32Error, ChildNumber, DerivationPath, EcdsaCurve, ExtendedPublicKey, - Secp256k1ExtendedPublicKey, XPub}; +pub use hw_client::{ + HwClient, HwConnectionStatus, HwDeviceInfo, HwProcessingError, HwPubkey, HwWalletType, TrezorConnectProcessor, +}; +pub use hw_common::primitives::{ + Bip32Error, ChildNumber, DerivationPath, EcdsaCurve, ExtendedPublicKey, Secp256k1ExtendedPublicKey, XPub, +}; pub use hw_ctx::{HardwareWalletArc, HardwareWalletCtx}; pub use hw_error::{from_hw_error, HwError, HwResult, HwRpcError, WithHwRpcError}; pub use keys::Secret as Secp256k1Secret; pub use mnemonic::{decrypt_mnemonic, encrypt_mnemonic, generate_mnemonic, MnemonicError}; -pub use standard_hd_path::{Bip44Chain, HDPathToAccount, HDPathToCoin, StandardHDPath, StandardHDPathError, - UnknownChainError}; +pub use standard_hd_path::{ + Bip44Chain, HDPathToAccount, HDPathToCoin, StandardHDPath, StandardHDPathError, UnknownChainError, +}; pub use trezor; pub use xpub::{XPubConverter, XpubError}; @@ -43,7 +49,8 @@ pub use xpub::{XPubConverter, XpubError}; pub use crypto_ctx::MetamaskCtxInitError; #[cfg(target_arch = "wasm32")] pub use metamask_ctx::{MetamaskArc, MetamaskError, MetamaskResult, MetamaskWeak}; -#[cfg(target_arch = "wasm32")] pub use mm2_metamask as metamask; +#[cfg(target_arch = "wasm32")] +pub use mm2_metamask as metamask; use serde::de::Error; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -65,11 +72,15 @@ pub(crate) fn mm2_internal_der_path() -> DerivationPath { pub struct RpcDerivationPath(pub DerivationPath); impl From for RpcDerivationPath { - fn from(der: DerivationPath) -> Self { RpcDerivationPath(der) } + fn from(der: DerivationPath) -> Self { + RpcDerivationPath(der) + } } impl From for DerivationPath { - fn from(der: RpcDerivationPath) -> Self { der.0 } + fn from(der: RpcDerivationPath) -> Self { + der.0 + } } impl Serialize for RpcDerivationPath { diff --git a/mm2src/crypto/src/metamask_ctx.rs b/mm2src/crypto/src/metamask_ctx.rs index a36b957e79..096484c3ce 100644 --- a/mm2src/crypto/src/metamask_ctx.rs +++ b/mm2src/crypto/src/metamask_ctx.rs @@ -15,22 +15,30 @@ pub use mm2_metamask::{MetamaskError, MetamaskResult}; pub struct MetamaskArc(Arc); impl MetamaskArc { - pub fn new(metamask_ctx: MetamaskCtx) -> MetamaskArc { MetamaskArc(Arc::new(metamask_ctx)) } + pub fn new(metamask_ctx: MetamaskCtx) -> MetamaskArc { + MetamaskArc(Arc::new(metamask_ctx)) + } - pub fn downgrade(&self) -> MetamaskWeak { MetamaskWeak(Arc::downgrade(&self.0)) } + pub fn downgrade(&self) -> MetamaskWeak { + MetamaskWeak(Arc::downgrade(&self.0)) + } } impl Deref for MetamaskArc { type Target = MetamaskCtx; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { + &self.0 + } } #[derive(Clone)] pub struct MetamaskWeak(Weak); impl MetamaskWeak { - pub fn upgrade(&self) -> Option { self.0.upgrade().map(MetamaskArc) } + pub fn upgrade(&self) -> Option { + self.0.upgrade().map(MetamaskArc) + } } pub struct MetamaskCtx { @@ -85,13 +93,19 @@ impl MetamaskCtx { } #[inline] - pub fn eth_account(&self) -> Address { self.eth_account } + pub fn eth_account(&self) -> Address { + self.eth_account + } #[inline] - pub fn eth_account_str(&self) -> &str { &self.eth_account_str } + pub fn eth_account_str(&self) -> &str { + &self.eth_account_str + } #[inline] - pub fn eth_account_pubkey_uncompressed(&self) -> H520 { self.eth_account_pubkey } + pub fn eth_account_pubkey_uncompressed(&self) -> H520 { + self.eth_account_pubkey + } /// Checks if the `MetamaskCtx::eth_account` is still active. /// This is required to check before sending transactions. diff --git a/mm2src/crypto/src/metamask_login.rs b/mm2src/crypto/src/metamask_login.rs index aa156af294..dcda1660f4 100644 --- a/mm2src/crypto/src/metamask_login.rs +++ b/mm2src/crypto/src/metamask_login.rs @@ -29,7 +29,9 @@ pub(crate) struct AtomicDEXDomain { } impl AtomicDEXDomain { - pub fn new(name: String) -> AtomicDEXDomain { AtomicDEXDomain { name } } + pub fn new(name: String) -> AtomicDEXDomain { + AtomicDEXDomain { name } + } } #[derive(Debug, Serialize)] diff --git a/mm2src/crypto/src/mnemonic.rs b/mm2src/crypto/src/mnemonic.rs index 793609bef0..4cb4058458 100644 --- a/mm2src/crypto/src/mnemonic.rs +++ b/mm2src/crypto/src/mnemonic.rs @@ -26,11 +26,15 @@ pub enum MnemonicError { } impl From for MnemonicError { - fn from(e: bip39::Error) -> Self { MnemonicError::BIP39Error(e.to_string()) } + fn from(e: bip39::Error) -> Self { + MnemonicError::BIP39Error(e.to_string()) + } } impl From for MnemonicError { - fn from(e: KeyDerivationError) -> Self { MnemonicError::KeyDerivationError(e.to_string()) } + fn from(e: KeyDerivationError) -> Self { + MnemonicError::KeyDerivationError(e.to_string()) + } } /// Generates a new mnemonic passphrase. diff --git a/mm2src/crypto/src/privkey.rs b/mm2src/crypto/src/privkey.rs index 506d52b11a..951c51b807 100644 --- a/mm2src/crypto/src/privkey.rs +++ b/mm2src/crypto/src/privkey.rs @@ -42,11 +42,15 @@ pub enum PrivKeyError { } impl From for PrivKeyError { - fn from(e: FromHexError) -> Self { PrivKeyError::ErrorParsingPassphrase(e.to_string()) } + fn from(e: FromHexError) -> Self { + PrivKeyError::ErrorParsingPassphrase(e.to_string()) + } } impl From for PrivKeyError { - fn from(e: KeysError) -> Self { PrivKeyError::InvalidPrivKey(e.to_string()) } + fn from(e: KeysError) -> Self { + PrivKeyError::InvalidPrivKey(e.to_string()) + } } impl std::error::Error for PrivKeyError {} @@ -127,7 +131,9 @@ pub struct SerializableSecp256k1Keypair { } impl PartialEq for SerializableSecp256k1Keypair { - fn eq(&self, other: &Self) -> bool { self.inner.public() == other.inner.public() } + fn eq(&self, other: &Self) -> bool { + self.inner.public() == other.inner.public() + } } impl Eq for SerializableSecp256k1Keypair {} @@ -139,11 +145,17 @@ impl SerializableSecp256k1Keypair { }) } - pub fn key_pair(&self) -> &KeyPair { &self.inner } + pub fn key_pair(&self) -> &KeyPair { + &self.inner + } - pub fn public_slice(&self) -> &[u8] { self.inner.public_slice() } + pub fn public_slice(&self) -> &[u8] { + self.inner.public_slice() + } - pub fn priv_key(&self) -> [u8; 32] { self.inner.private().secret.take() } + pub fn priv_key(&self) -> [u8; 32] { + self.inner.private().secret.take() + } pub fn random() -> Self { SerializableSecp256k1Keypair { @@ -151,11 +163,15 @@ impl SerializableSecp256k1Keypair { } } - pub fn into_inner(self) -> KeyPair { self.inner } + pub fn into_inner(self) -> KeyPair { + self.inner + } } impl From for SerializableSecp256k1Keypair { - fn from(inner: KeyPair) -> Self { SerializableSecp256k1Keypair { inner } } + fn from(inner: KeyPair) -> Self { + SerializableSecp256k1Keypair { inner } + } } impl Serialize for SerializableSecp256k1Keypair { diff --git a/mm2src/crypto/src/slip21.rs b/mm2src/crypto/src/slip21.rs index 131202f4c9..ca529b361e 100644 --- a/mm2src/crypto/src/slip21.rs +++ b/mm2src/crypto/src/slip21.rs @@ -22,7 +22,9 @@ pub enum SLIP21Error { } impl From for SLIP21Error { - fn from(e: KeyDerivationError) -> Self { SLIP21Error::KeyDerivationError(e.to_string()) } + fn from(e: KeyDerivationError) -> Self { + SLIP21Error::KeyDerivationError(e.to_string()) + } } /// Encrypts data using SLIP-0021 derived keys. diff --git a/mm2src/crypto/src/standard_hd_path.rs b/mm2src/crypto/src/standard_hd_path.rs index a0fbbd6f66..0c930334a7 100644 --- a/mm2src/crypto/src/standard_hd_path.rs +++ b/mm2src/crypto/src/standard_hd_path.rs @@ -32,15 +32,25 @@ pub type HDPathToAccount = Bip44Tail>>>; impl StandardHDPath { - pub fn purpose(&self) -> Bip43Purpose { self.value() } + pub fn purpose(&self) -> Bip43Purpose { + self.value() + } - pub fn coin_type(&self) -> u32 { self.child().value() } + pub fn coin_type(&self) -> u32 { + self.child().value() + } - pub fn account_id(&self) -> u32 { self.child().child().value() } + pub fn account_id(&self) -> u32 { + self.child().child().value() + } - pub fn chain(&self) -> Bip44Chain { self.child().child().child().value() } + pub fn chain(&self) -> Bip44Chain { + self.child().child().child().value() + } - pub fn address_id(&self) -> u32 { self.child().child().child().child().value() } + pub fn address_id(&self) -> u32 { + self.child().child().child().child().value() + } /// Derive `HDPathToCoin` from `StandardHDPath` pub fn path_to_coin(&self) -> HDPathToCoin { @@ -61,17 +71,27 @@ impl StandardHDPath { } impl HDPathToCoin { - pub fn purpose(&self) -> Bip43Purpose { self.value() } + pub fn purpose(&self) -> Bip43Purpose { + self.value() + } - pub fn coin_type(&self) -> u32 { self.child().value() } + pub fn coin_type(&self) -> u32 { + self.child().value() + } } impl HDPathToAccount { - pub fn purpose(&self) -> Bip43Purpose { self.value() } + pub fn purpose(&self) -> Bip43Purpose { + self.value() + } - pub fn coin_type(&self) -> u32 { self.child().value() } + pub fn coin_type(&self) -> u32 { + self.child().value() + } - pub fn account_id(&self) -> u32 { self.child().child().value() } + pub fn account_id(&self) -> u32 { + self.child().child().value() + } } #[derive(Debug)] @@ -172,7 +192,9 @@ impl TryFrom for Bip44Chain { } impl Bip44Chain { - pub fn to_child_number(&self) -> ChildNumber { ChildNumber::from(*self as u32) } + pub fn to_child_number(&self) -> ChildNumber { + ChildNumber::from(*self as u32) + } } #[derive(Clone, PartialEq)] @@ -184,11 +206,17 @@ impl Bip32ChildValue for Bip44ChainValue { type Value = Bip44Chain; /// `chain` is a non-hardened child as it's described in the BIP44 standard. - fn hardened() -> bool { false } + fn hardened() -> bool { + false + } - fn number(&self) -> u32 { self.chain as u32 } + fn number(&self) -> u32 { + self.chain as u32 + } - fn value(&self) -> Self::Value { self.chain } + fn value(&self) -> Self::Value { + self.chain + } fn from_bip32_number(child_number: ChildNumber, child_at: usize) -> Result { if child_number.is_hardened() { @@ -218,11 +246,17 @@ impl Bip32ChildValue for Bip32PurposeValue { type Value = Bip43Purpose; /// `purpose` is always a hardened child as it's described in the BIP44/BIP49/BIP84 standards. - fn hardened() -> bool { true } + fn hardened() -> bool { + true + } - fn number(&self) -> u32 { self.purpose as u32 } + fn number(&self) -> u32 { + self.purpose as u32 + } - fn value(&self) -> Bip43Purpose { self.purpose } + fn value(&self) -> Bip43Purpose { + self.purpose + } fn from_bip32_number(child_number: ChildNumber, child_at: usize) -> Result { if !child_number.is_hardened() { @@ -284,17 +318,17 @@ mod tests { #[test] fn test_from_invalid_length() { let error = StandardHDPath::from_str("m/44'/141'/0'").expect_err("derivation path is too short"); - assert_eq!(error, Bip32DerPathError::InvalidDerivationPathLength { - expected: 5, - found: 3 - }); + assert_eq!( + error, + Bip32DerPathError::InvalidDerivationPathLength { expected: 5, found: 3 } + ); let error = StandardHDPath::from_str("m/44'/141'/0'/1/2/3").expect_err("max number of children is 5, but 6 passes"); - assert_eq!(error, Bip32DerPathError::InvalidDerivationPathLength { - expected: 5, - found: 6 - }); + assert_eq!( + error, + Bip32DerPathError::InvalidDerivationPathLength { expected: 5, found: 6 } + ); } #[test] @@ -302,9 +336,12 @@ mod tests { let error = HDPathToAccount::from_str("m/44'/141'/0").expect_err("'account_id' is not hardened"); assert_eq!(error, Bip32DerPathError::ChildIsNotHardened { child_at: 2 }); let error = StandardHDPathError::from(error); - assert_eq!(error, StandardHDPathError::ChildIsNotHardened { - child: "AccountId".to_owned() - }); + assert_eq!( + error, + StandardHDPathError::ChildIsNotHardened { + child: "AccountId".to_owned() + } + ); } #[test] diff --git a/mm2src/crypto/src/xpub.rs b/mm2src/crypto/src/xpub.rs index aba5adccf9..fd0a1c09b5 100644 --- a/mm2src/crypto/src/xpub.rs +++ b/mm2src/crypto/src/xpub.rs @@ -20,7 +20,9 @@ pub enum XpubError { } impl From for XpubError { - fn from(e: Base58Error) -> Self { XpubError::Base58Error(e) } + fn from(e: Base58Error) -> Self { + XpubError::Base58Error(e) + } } #[derive(Clone, Debug, PartialEq)] diff --git a/mm2src/db_common/src/async_conn_tests.rs b/mm2src/db_common/src/async_conn_tests.rs index 4002b4ac3c..6d810fc5a8 100644 --- a/mm2src/db_common/src/async_conn_tests.rs +++ b/mm2src/db_common/src/async_conn_tests.rs @@ -218,7 +218,9 @@ async fn test_error_source() -> AsyncConnResult<()> { Ok(()) } -fn failable_func(_: &rusqlite::Connection) -> std::result::Result<(), MyError> { Err(MyError::MySpecificError) } +fn failable_func(_: &rusqlite::Connection) -> std::result::Result<(), MyError> { + Err(MyError::MySpecificError) +} #[tokio::test] async fn test_ergonomic_errors() -> AsyncConnResult<()> { @@ -245,9 +247,13 @@ enum MyError { } impl Display for MyError { - fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Ok(()) } + fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Ok(()) + } } impl std::error::Error for MyError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + None + } } diff --git a/mm2src/db_common/src/async_sql_conn.rs b/mm2src/db_common/src/async_sql_conn.rs index f9e8747fd7..d3a4ef921a 100644 --- a/mm2src/db_common/src/async_sql_conn.rs +++ b/mm2src/db_common/src/async_sql_conn.rs @@ -44,20 +44,26 @@ impl std::error::Error for AsyncConnError { } impl From for AsyncConnError { - fn from(err: String) -> Self { Self::Internal(InternalError(err)) } + fn from(err: String) -> Self { + Self::Internal(InternalError(err)) + } } #[derive(Debug)] pub struct InternalError(pub String); impl fmt::Display for InternalError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0) } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } } impl std::error::Error for InternalError {} impl From for AsyncConnError { - fn from(value: SqlError) -> Self { AsyncConnError::Rusqlite(value) } + fn from(value: SqlError) -> Self { + AsyncConnError::Rusqlite(value) + } } /// The result returned on method calls in this crate. @@ -97,7 +103,9 @@ impl AsyncConnection { /// # Failure /// /// Will return `Err` if the underlying SQLite open call fails. - pub async fn open_in_memory() -> Result { start(rusqlite::Connection::open_in_memory).await } + pub async fn open_in_memory() -> Result { + start(rusqlite::Connection::open_in_memory).await + } /// Open a new AsyncConnection to a SQLite database. /// @@ -239,7 +247,9 @@ impl AsyncConnection { } impl Debug for AsyncConnection { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("AsyncConnection").finish() } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("AsyncConnection").finish() + } } async fn start(open: F) -> Result diff --git a/mm2src/db_common/src/lib.rs b/mm2src/db_common/src/lib.rs index c1806e3b97..d1ac0dce2e 100644 --- a/mm2src/db_common/src/lib.rs +++ b/mm2src/db_common/src/lib.rs @@ -1,15 +1,25 @@ #[cfg(all(test, not(target_arch = "wasm32")))] mod async_conn_tests; -#[cfg(not(target_arch = "wasm32"))] pub mod async_sql_conn; -#[cfg(not(target_arch = "wasm32"))] mod sql_condition; -#[cfg(not(target_arch = "wasm32"))] mod sql_constraint; -#[cfg(not(target_arch = "wasm32"))] mod sql_create; -#[cfg(not(target_arch = "wasm32"))] mod sql_delete; -#[cfg(not(target_arch = "wasm32"))] mod sql_insert; -#[cfg(not(target_arch = "wasm32"))] mod sql_query; -#[cfg(not(target_arch = "wasm32"))] mod sql_update; -#[cfg(not(target_arch = "wasm32"))] mod sql_value; -#[cfg(not(target_arch = "wasm32"))] pub mod sqlite; +#[cfg(not(target_arch = "wasm32"))] +pub mod async_sql_conn; +#[cfg(not(target_arch = "wasm32"))] +mod sql_condition; +#[cfg(not(target_arch = "wasm32"))] +mod sql_constraint; +#[cfg(not(target_arch = "wasm32"))] +mod sql_create; +#[cfg(not(target_arch = "wasm32"))] +mod sql_delete; +#[cfg(not(target_arch = "wasm32"))] +mod sql_insert; +#[cfg(not(target_arch = "wasm32"))] +mod sql_query; +#[cfg(not(target_arch = "wasm32"))] +mod sql_update; +#[cfg(not(target_arch = "wasm32"))] +mod sql_value; +#[cfg(not(target_arch = "wasm32"))] +pub mod sqlite; #[cfg(not(target_arch = "wasm32"))] pub mod sql_build { diff --git a/mm2src/db_common/src/sql_constraint.rs b/mm2src/db_common/src/sql_constraint.rs index fe031c4fbb..4fa0e335bc 100644 --- a/mm2src/db_common/src/sql_constraint.rs +++ b/mm2src/db_common/src/sql_constraint.rs @@ -33,7 +33,9 @@ macro_rules! named_constraint { } impl From<$constraint_ident> for SqlConstraint { - fn from(constraint: $constraint_ident) -> Self { SqlConstraint::$constraint_ident(constraint) } + fn from(constraint: $constraint_ident) -> Self { + SqlConstraint::$constraint_ident(constraint) + } } impl fmt::Display for $constraint_ident { @@ -191,7 +193,9 @@ pub mod foreign_key { } impl From for SqlConstraint { - fn from(foreign: ForeignKey) -> Self { SqlConstraint::ForeignKey(foreign) } + fn from(foreign: ForeignKey) -> Self { + SqlConstraint::ForeignKey(foreign) + } } impl fmt::Display for ForeignKey { @@ -238,7 +242,9 @@ pub mod foreign_key { } impl fmt::Display for ActionOnEvent<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{} {}", self.event, self.action) } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{} {}", self.event, self.action) + } } } diff --git a/mm2src/db_common/src/sql_create.rs b/mm2src/db_common/src/sql_create.rs index 771232dfd8..478eff93ac 100644 --- a/mm2src/db_common/src/sql_create.rs +++ b/mm2src/db_common/src/sql_create.rs @@ -1,8 +1,10 @@ use crate::sql_constraint::SqlConstraint; use crate::sql_value::{FromQuoted, SqlValue}; use crate::sqlite::StringError; -use common::{write_safe, - write_safe::fmt::{WriteSafe, WriteSafeJoin}}; +use common::{ + write_safe, + write_safe::fmt::{WriteSafe, WriteSafeJoin}, +}; use rusqlite::{Connection, Error as SqlError, Result as SqlResult}; use std::fmt; diff --git a/mm2src/db_common/src/sql_delete.rs b/mm2src/db_common/src/sql_delete.rs index 42e03ef359..b55c769748 100644 --- a/mm2src/db_common/src/sql_delete.rs +++ b/mm2src/db_common/src/sql_delete.rs @@ -26,7 +26,9 @@ impl<'a> SqlDelete<'a> { /// Returns a reference to the SQL params of the request. #[inline] - pub fn params(&self) -> &OwnedSqlParams { self.params.params() } + pub fn params(&self) -> &OwnedSqlParams { + self.params.params() + } /// Convenience method to execute the `DELETE` request. /// Returns a number of deleted records. @@ -61,9 +63,13 @@ impl<'a> SqlDelete<'a> { /// - [`SqlQuery::or_where_in_quoted`] /// - [`SqlQuery::or_where_in_params`] impl SqlCondition for SqlDelete<'_> { - fn sql_builder(&mut self) -> &mut SqlBuilder { &mut self.sql_builder } + fn sql_builder(&mut self) -> &mut SqlBuilder { + &mut self.sql_builder + } - fn sql_params(&mut self) -> &mut SqlParamsBuilder { &mut self.params } + fn sql_params(&mut self) -> &mut SqlParamsBuilder { + &mut self.params + } } #[cfg(test)] @@ -77,7 +83,9 @@ mod tests { description TEXT );"; - fn init_table_for_test(conn: &Connection) { conn.execute(CREATE_TX_HISTORY_TABLE, []).unwrap(); } + fn init_table_for_test(conn: &Connection) { + conn.execute(CREATE_TX_HISTORY_TABLE, []).unwrap(); + } #[test] fn test_delete_all_sql() { diff --git a/mm2src/db_common/src/sql_insert.rs b/mm2src/db_common/src/sql_insert.rs index bf6d77a5ca..044d564992 100644 --- a/mm2src/db_common/src/sql_insert.rs +++ b/mm2src/db_common/src/sql_insert.rs @@ -117,7 +117,9 @@ impl<'a> SqlInsert<'a> { /// Returns the reference to the specified SQL parameters. #[inline] - pub fn params(&self) -> &OwnedSqlParams { self.params.params() } + pub fn params(&self) -> &OwnedSqlParams { + self.params.params() + } /// Generates a string SQL request. pub fn sql(&self) -> SqlResult { diff --git a/mm2src/db_common/src/sql_query.rs b/mm2src/db_common/src/sql_query.rs index a284faae60..1adad5b4f1 100644 --- a/mm2src/db_common/src/sql_query.rs +++ b/mm2src/db_common/src/sql_query.rs @@ -1,7 +1,9 @@ use crate::sql_condition::SqlCondition; use crate::sql_value::{SqlValue, SqlValueToString}; -use crate::sqlite::{query_single_row, validate_ident, validate_table_name, OwnedSqlParam, OwnedSqlParams, - SqlParamsBuilder, StringError, ToValidSqlIdent, ToValidSqlTable}; +use crate::sqlite::{ + query_single_row, validate_ident, validate_table_name, OwnedSqlParam, OwnedSqlParams, SqlParamsBuilder, + StringError, ToValidSqlIdent, ToValidSqlTable, +}; use log::debug; use rusqlite::{params_from_iter, Connection, Error as SqlError, Result as SqlResult, Row}; use sql_builder::SqlBuilder; @@ -196,11 +198,15 @@ impl<'a> SqlQuery<'a> { /// Returns an SQL subquery that can be used in [`SqlQuery::select_from_subquery`]. #[inline] - pub fn subquery(self) -> SqlSubquery<'a> { SqlSubquery(self) } + pub fn subquery(self) -> SqlSubquery<'a> { + SqlSubquery(self) + } /// Returns the reference to the specified SQL parameters. #[inline] - pub fn params(&self) -> &OwnedSqlParams { self.params.params() } + pub fn params(&self) -> &OwnedSqlParams { + self.params.params() + } /// # Usage /// @@ -349,9 +355,13 @@ impl<'a> SqlQuery<'a> { /// - [`SqlQuery::or_where_in_quoted`] /// - [`SqlQuery::or_where_in_params`] impl SqlCondition for SqlQuery<'_> { - fn sql_builder(&mut self) -> &mut SqlBuilder { &mut self.sql_builder } + fn sql_builder(&mut self) -> &mut SqlBuilder { + &mut self.sql_builder + } - fn sql_params(&mut self) -> &mut SqlParamsBuilder { &mut self.params } + fn sql_params(&mut self) -> &mut SqlParamsBuilder { + &mut self.params + } } /// An instance of this structure is returned by [`SqlQuery::subquery`]. diff --git a/mm2src/db_common/src/sql_update.rs b/mm2src/db_common/src/sql_update.rs index 5b955d979d..b4e3fc9e63 100644 --- a/mm2src/db_common/src/sql_update.rs +++ b/mm2src/db_common/src/sql_update.rs @@ -81,7 +81,9 @@ impl<'a> SqlUpdate<'a> { /// Returns the reference to the specified SQL parameters. #[inline] - pub fn params(&self) -> &OwnedSqlParams { self.params.params() } + pub fn params(&self) -> &OwnedSqlParams { + self.params.params() + } /// Convenience method to execute the `UPDATE` request. /// Returns a number of updated records. @@ -107,9 +109,13 @@ impl<'a> SqlUpdate<'a> { /// - [`SqlUpdate::or_where_in_quoted`] /// - [`SqlUpdate::or_where_in_params`] impl SqlCondition for SqlUpdate<'_> { - fn sql_builder(&mut self) -> &mut SqlBuilder { &mut self.sql_builder } + fn sql_builder(&mut self) -> &mut SqlBuilder { + &mut self.sql_builder + } - fn sql_params(&mut self) -> &mut SqlParamsBuilder { &mut self.params } + fn sql_params(&mut self) -> &mut SqlParamsBuilder { + &mut self.params + } } #[cfg(test)] @@ -123,7 +129,9 @@ mod tests { kmd_rewards REAL );"; - fn init_table_for_test(conn: &Connection) { conn.execute(CREATE_TX_HISTORY_TABLE, []).unwrap(); } + fn init_table_for_test(conn: &Connection) { + conn.execute(CREATE_TX_HISTORY_TABLE, []).unwrap(); + } #[test] fn test_update_all_records() { diff --git a/mm2src/db_common/src/sql_value.rs b/mm2src/db_common/src/sql_value.rs index 30d424972d..b4c7b4e58b 100644 --- a/mm2src/db_common/src/sql_value.rs +++ b/mm2src/db_common/src/sql_value.rs @@ -27,19 +27,27 @@ impl fmt::Display for SqlValue { } impl From<&'static str> for SqlValue { - fn from(string: &'static str) -> Self { SqlValue::String(string) } + fn from(string: &'static str) -> Self { + SqlValue::String(string) + } } impl FromQuoted<&'static str> for SqlValue { - fn from_quoted(string: &'static str) -> Self { SqlValue::StringQuoted(string) } + fn from_quoted(string: &'static str) -> Self { + SqlValue::StringQuoted(string) + } } impl From for SqlValue { - fn from(decimal: i64) -> Self { SqlValue::Integer(decimal) } + fn from(decimal: i64) -> Self { + SqlValue::Integer(decimal) + } } impl From for SqlValue { - fn from(real: f64) -> Self { SqlValue::Real(real) } + fn from(real: f64) -> Self { + SqlValue::Real(real) + } } /// A valid SQL optional value that can be passed as an argument to the `SqlQuery`, `SqlCreate`, `SqlInsert` safely. @@ -64,7 +72,9 @@ impl From for SqlValueOptional where SqlValue: From, { - fn from(value: T) -> Self { SqlValueOptional::Some(SqlValue::from(value)) } + fn from(value: T) -> Self { + SqlValueOptional::Some(SqlValue::from(value)) + } } impl From> for SqlValueOptional @@ -83,7 +93,9 @@ impl FromQuoted for SqlValueOptional where SqlValue: FromQuoted, { - fn from_quoted(value: T) -> Self { SqlValueOptional::Some(SqlValue::from_quoted(value)) } + fn from_quoted(value: T) -> Self { + SqlValueOptional::Some(SqlValue::from_quoted(value)) + } } impl FromQuoted> for SqlValueOptional diff --git a/mm2src/db_common/src/sqlite.rs b/mm2src/db_common/src/sqlite.rs index f92707d2d5..f0a388055b 100644 --- a/mm2src/db_common/src/sqlite.rs +++ b/mm2src/db_common/src/sqlite.rs @@ -48,7 +48,9 @@ impl AsSqlNamedParams for OwnedSqlNamedParams { } } -pub fn string_from_row(row: &Row<'_>) -> Result { row.get(0) } +pub fn string_from_row(row: &Row<'_>) -> Result { + row.get(0) +} pub fn query_single_row(conn: &Connection, query: &str, params: P, map_fn: F) -> Result, SqlError> where @@ -188,7 +190,9 @@ impl SafeTableName { /// Retrieves the table name. #[inline(always)] - pub fn inner(&self) -> &str { &self.0 } + pub fn inner(&self) -> &str { + &self.0 + } } /// Calculates the offset to skip records by uuid. @@ -391,7 +395,9 @@ impl SqlParamsBuilder { params.into_iter().map(|param| self.push_param(param)).collect() } - pub(crate) fn params(&self) -> &OwnedSqlParams { &self.params } + pub(crate) fn params(&self) -> &OwnedSqlParams { + &self.params + } } /// TODO move it to `mm2_err_handle::common_errors` when it's merged. @@ -399,21 +405,29 @@ impl SqlParamsBuilder { pub struct StringError(String); impl fmt::Display for StringError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0) } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } } impl StdError for StringError {} impl From<&'static str> for StringError { - fn from(s: &str) -> Self { StringError(s.to_owned()) } + fn from(s: &str) -> Self { + StringError(s.to_owned()) + } } impl From for StringError { - fn from(s: String) -> Self { StringError(s) } + fn from(s: String) -> Self { + StringError(s) + } } impl StringError { - pub fn into_boxed(self) -> Box { Box::new(self) } + pub fn into_boxed(self) -> Box { + Box::new(self) + } } /// Internal function to validate identifiers such as table names. diff --git a/mm2src/derives/enum_derives/src/lib.rs b/mm2src/derives/enum_derives/src/lib.rs index 4f3cf5c67e..acb5f8b495 100644 --- a/mm2src/derives/enum_derives/src/lib.rs +++ b/mm2src/derives/enum_derives/src/lib.rs @@ -3,8 +3,9 @@ use proc_macro2::{Ident, Span, TokenStream as TokenStream2}; use quote::quote; use std::fmt; use syn::Meta::List; -use syn::{parse_macro_input, Data, DataEnum, DeriveInput, Error, Field, Fields, ImplGenerics, Type, TypeGenerics, - WhereClause}; +use syn::{ + parse_macro_input, Data, DataEnum, DeriveInput, Error, Field, Fields, ImplGenerics, Type, TypeGenerics, WhereClause, +}; use syn::{Attribute, NestedMeta, Variant}; mod from_inner; @@ -232,11 +233,15 @@ impl CompileError { } impl From for TokenStream { - fn from(e: CompileError) -> Self { TokenStream2::from(e).into() } + fn from(e: CompileError) -> Self { + TokenStream2::from(e).into() + } } impl From for TokenStream2 { - fn from(e: CompileError) -> Self { Error::new(Span::call_site(), e.0).to_compile_error() } + fn from(e: CompileError) -> Self { + Error::new(Span::call_site(), e.0).to_compile_error() + } } /// An information about the derive ident. @@ -277,7 +282,9 @@ impl<'a> UnnamedInnerField<'a> { } /// Get a type of the field. - fn ty(&self) -> &Type { &self.field.ty } + fn ty(&self) -> &Type { + &self.field.ty + } } /// An implementation of `EnumFromInner` and `EnumFromTrait` macros. diff --git a/mm2src/derives/ser_error/src/lib.rs b/mm2src/derives/ser_error/src/lib.rs index 5262e250f9..7132347e35 100644 --- a/mm2src/derives/ser_error/src/lib.rs +++ b/mm2src/derives/ser_error/src/lib.rs @@ -6,9 +6,13 @@ pub const CONTENT: &str = "error_data"; /// [`SerializeErrorType`] trait ensures that the each type implementing this trait serializes into /// `error_type: String` and `error_data: Option` fields only. pub trait SerializeErrorType: Serialize + __private::SerializeErrorTypeImpl { - fn tag() -> &'static str { TAG } + fn tag() -> &'static str { + TAG + } - fn content() -> &'static str { CONTENT } + fn content() -> &'static str { + CONTENT + } } /// Every type that implements [`__private::SerializeErrorTypeImpl`] also implements [`SerializeErrorType`]. diff --git a/mm2src/derives/ser_error_derive/src/lib.rs b/mm2src/derives/ser_error_derive/src/lib.rs index 79608cc630..ec0abff97b 100644 --- a/mm2src/derives/ser_error_derive/src/lib.rs +++ b/mm2src/derives/ser_error_derive/src/lib.rs @@ -22,11 +22,15 @@ macro_rules! compile_err { struct CompileError(String); impl From for TokenStream { - fn from(e: CompileError) -> Self { TokenStream2::from(e).into() } + fn from(e: CompileError) -> Self { + TokenStream2::from(e).into() + } } impl From for TokenStream2 { - fn from(e: CompileError) -> Self { Error::new(Span::call_site(), e.0).to_compile_error() } + fn from(e: CompileError) -> Self { + Error::new(Span::call_site(), e.0).to_compile_error() + } } /// Use the same `serde` attributes as in the `serde-derive` crate to check if the container satisfies the following statements: diff --git a/mm2src/hw_common/src/transport/libusb.rs b/mm2src/hw_common/src/transport/libusb.rs index da303f4919..42dcc6178d 100644 --- a/mm2src/hw_common/src/transport/libusb.rs +++ b/mm2src/hw_common/src/transport/libusb.rs @@ -34,7 +34,9 @@ pub enum UsbError { } impl InternalError for UsbError { - fn internal(e: String) -> Self { UsbError::Internal(e) } + fn internal(e: String) -> Self { + UsbError::Internal(e) + } } #[derive(Clone)] @@ -146,7 +148,9 @@ impl UsbAvailableDevice { }) } - pub fn device_info(&self) -> &UsbDeviceInfo { &self.device_info } + pub fn device_info(&self) -> &UsbDeviceInfo { + &self.device_info + } fn event_loop(mut event_rx: DeviceEventReceiver, device_handle: rusb::DeviceHandle) { while let Some(event) = block_on(event_rx.next()) { @@ -274,7 +278,9 @@ impl UsbDevice { send_event_recv_response(&self.event_tx, event, result_rx).await } - fn endpoint_number(&self) -> u8 { self.device_info.interface_info.endpoint_number } + fn endpoint_number(&self) -> u8 { + self.device_info.interface_info.endpoint_number + } } #[derive(Clone, Copy, Debug)] diff --git a/mm2src/hw_common/src/transport/mod.rs b/mm2src/hw_common/src/transport/mod.rs index 5eb1c198b4..ce430d8fd1 100644 --- a/mm2src/hw_common/src/transport/mod.rs +++ b/mm2src/hw_common/src/transport/mod.rs @@ -1,7 +1,8 @@ use futures::channel::{mpsc, oneshot}; use mm2_err_handle::prelude::*; -#[cfg(target_arch = "wasm32")] pub mod webusb_driver; +#[cfg(target_arch = "wasm32")] +pub mod webusb_driver; #[cfg(target_arch = "wasm32")] pub use webusb_driver::WebUsbError; diff --git a/mm2src/hw_common/src/transport/webusb_driver.rs b/mm2src/hw_common/src/transport/webusb_driver.rs index 14e6ad6cd8..77b2792b8d 100644 --- a/mm2src/hw_common/src/transport/webusb_driver.rs +++ b/mm2src/hw_common/src/transport/webusb_driver.rs @@ -53,7 +53,9 @@ pub enum WebUsbError { } impl InternalError for WebUsbError { - fn internal(e: String) -> Self { WebUsbError::Internal(e) } + fn internal(e: String) -> Self { + WebUsbError::Internal(e) + } } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -339,7 +341,9 @@ impl WebUsbDevice { Ok(()) } - fn on_is_open(device: &UsbDevice) -> WebUsbResult { Ok(device.opened()) } + fn on_is_open(device: &UsbDevice) -> WebUsbResult { + Ok(device.opened()) + } async fn on_reset_device(device: &UsbDevice) -> WebUsbResult<()> { JsFuture::from(device.reset()) diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index 88978fd0d5..70974fc5c5 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -19,7 +19,7 @@ hkdf.workspace = true mm2_db = { path = "../mm2_db" } mm2_core = { path = "../mm2_core" } mm2_err_handle = { path = "../mm2_err_handle" } -parking_lot = { workspace = true, features = ["nightly"] } +parking_lot = { workspace = true } pairing_api.workspace = true rand = "0.8" relay_client.workspace = true diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index 1d8b6bcf93..f3cfb6ba6a 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -95,11 +95,15 @@ pub enum WalletConnectError { } impl From> for WalletConnectError { - fn from(error: Error) -> Self { WalletConnectError::PublishError(format!("{error:?}")) } + fn from(error: Error) -> Self { + WalletConnectError::PublishError(format!("{error:?}")) + } } impl From> for WalletConnectError { - fn from(error: Error) -> Self { WalletConnectError::SubscriptionError(format!("{error:?}")) } + fn from(error: Error) -> Self { + WalletConnectError::SubscriptionError(format!("{error:?}")) + } } /// Session key and topic derivation errors. diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index f2ac60036a..ad6945bf8f 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -1,13 +1,17 @@ -use crate::{error::WalletConnectError, - pairing::{reply_pairing_delete_response, reply_pairing_extend_response, reply_pairing_ping_response}, - session::rpc::{delete::reply_session_delete_request, - event::handle_session_event, - extend::reply_session_extend_request, - ping::reply_session_ping_request, - propose::{process_session_propose_response, reply_session_proposal_request}, - settle::reply_session_settle_request, - update::reply_session_update_request}, - WalletConnectCtxImpl}; +use crate::{ + error::WalletConnectError, + pairing::{reply_pairing_delete_response, reply_pairing_extend_response, reply_pairing_ping_response}, + session::rpc::{ + delete::reply_session_delete_request, + event::handle_session_event, + extend::reply_session_extend_request, + ping::reply_session_ping_request, + propose::{process_session_propose_response, reply_session_proposal_request}, + settle::reply_session_settle_request, + update::reply_session_update_request, + }, + WalletConnectCtxImpl, +}; use common::log::{info, LogOnError}; use mm2_err_handle::prelude::*; diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 50d2115f92..0e5cfacc17 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -1,9 +1,11 @@ pub mod chain; mod connection_handler; -#[allow(unused)] pub mod error; +#[allow(unused)] +pub mod error; pub mod inbound_message; mod metadata; -#[allow(unused)] mod pairing; +#[allow(unused)] +mod pairing; pub mod session; mod storage; @@ -28,8 +30,10 @@ use relay_rpc::auth::{ed25519_dalek::SigningKey, AuthToken}; use relay_rpc::domain::{MessageId, Topic}; use relay_rpc::rpc::params::session::{Namespace, ProposeNamespaces}; use relay_rpc::rpc::params::session_request::SessionRequestRequest; -use relay_rpc::rpc::params::{session_request::Request as SessionRequest, IrnMetadata, Metadata, Relay, - RelayProtocolMetadata, RequestParams, ResponseParamsError, ResponseParamsSuccess}; +use relay_rpc::rpc::params::{ + session_request::Request as SessionRequest, IrnMetadata, Metadata, Relay, RelayProtocolMetadata, RequestParams, + ResponseParamsError, ResponseParamsSuccess, +}; use relay_rpc::rpc::{ErrorResponse, Payload, Request, Response, SuccessfulResponse}; use serde::de::DeserializeOwned; use session::rpc::delete::send_session_delete_request; @@ -106,7 +110,9 @@ pub struct WalletConnectCtxImpl { pub struct WalletConnectCtx(pub Arc); impl Deref for WalletConnectCtx { type Target = WalletConnectCtxImpl; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { + &self.0 + } } impl WalletConnectCtx { diff --git a/mm2src/kdf_walletconnect/src/pairing.rs b/mm2src/kdf_walletconnect/src/pairing.rs index 4990dd197a..b04f2bc914 100644 --- a/mm2src/kdf_walletconnect/src/pairing.rs +++ b/mm2src/kdf_walletconnect/src/pairing.rs @@ -6,9 +6,10 @@ use mm2_err_handle::prelude::MmResult; use relay_rpc::domain::MessageId; use relay_rpc::rpc::params::pairing_ping::PairingPingRequest; use relay_rpc::rpc::params::{RelayProtocolMetadata, RequestParams}; -use relay_rpc::{domain::Topic, - rpc::params::{pairing_delete::PairingDeleteRequest, pairing_extend::PairingExtendRequest, - ResponseParamsSuccess}}; +use relay_rpc::{ + domain::Topic, + rpc::params::{pairing_delete::PairingDeleteRequest, pairing_extend::PairingExtendRequest, ResponseParamsSuccess}, +}; pub(crate) async fn reply_pairing_ping_response( ctx: &WalletConnectCtxImpl, diff --git a/mm2src/kdf_walletconnect/src/session/key.rs b/mm2src/kdf_walletconnect/src/session/key.rs index 7ac299cae6..9bfef3c835 100644 --- a/mm2src/kdf_walletconnect/src/session/key.rs +++ b/mm2src/kdf_walletconnect/src/session/key.rs @@ -3,9 +3,11 @@ use crate::error::SessionError; use serde::{Deserialize, Serialize}; use wc_common::SymKey; use x25519_dalek::{PublicKey, SharedSecret, StaticSecret}; -use {hkdf::Hkdf, - rand::{rngs::OsRng, CryptoRng, RngCore}, - sha2::{Digest, Sha256}}; +use { + hkdf::Hkdf, + rand::{rngs::OsRng, CryptoRng, RngCore}, + sha2::{Digest, Sha256}, +}; pub(crate) struct SymKeyPair { pub(crate) secret: StaticSecret, @@ -88,10 +90,14 @@ impl SessionKey { } /// Gets symmetic key reference. - pub fn symmetric_key(&self) -> SymKey { self.sym_key } + pub fn symmetric_key(&self) -> SymKey { + self.sym_key + } /// Gets "our" public key used in symmetric key derivation. - pub fn diffie_public_key(&self) -> SymKey { self.public_key } + pub fn diffie_public_key(&self) -> SymKey { + self.public_key + } /// Generates new session topic. pub fn generate_topic(&self) -> String { diff --git a/mm2src/kdf_walletconnect/src/session/mod.rs b/mm2src/kdf_walletconnect/src/session/mod.rs index de43ea967b..d905ff6575 100644 --- a/mm2src/kdf_walletconnect/src/session/mod.rs +++ b/mm2src/kdf_walletconnect/src/session/mod.rs @@ -16,8 +16,10 @@ use relay_rpc::domain::Topic; use relay_rpc::rpc::params::session::Namespace; use relay_rpc::rpc::params::session_propose::Proposer; use relay_rpc::rpc::params::IrnMetadata; -use relay_rpc::{domain::SubscriptionId, - rpc::params::{session::ProposeNamespaces, session_settle::Controller, Metadata, Relay}}; +use relay_rpc::{ + domain::SubscriptionId, + rpc::params::{session::ProposeNamespaces, session_settle::Controller, Metadata, Relay}, +}; use serde::{Deserialize, Deserializer, Serialize}; use serde_json::Value; use std::collections::{BTreeMap, HashMap}; @@ -170,10 +172,13 @@ impl Session { }, Controller::default(), ), - SessionType::Controller => (Proposer::default(), Controller { - public_key: hex::encode(session_key.diffie_public_key()), - metadata, - }), + SessionType::Controller => ( + Proposer::default(), + Controller { + public_key: hex::encode(session_key.diffie_public_key()), + metadata, + }, + ), }; Self { @@ -194,13 +199,19 @@ impl Session { } } - pub(crate) fn extend(&mut self, till: u64) { self.expiry = till; } + pub(crate) fn extend(&mut self, till: u64) { + self.expiry = till; + } /// Get the active chain ID for the current session. - pub fn get_active_chain_id(&self) -> &Option { &self.active_chain_id } + pub fn get_active_chain_id(&self) -> &Option { + &self.active_chain_id + } /// Sets the active chain ID for the current session. - pub fn set_active_chain_id(&mut self, chain_id: WcChainId) { self.active_chain_id = Some(chain_id); } + pub fn set_active_chain_id(&mut self, chain_id: WcChainId) { + self.active_chain_id = Some(chain_id); + } } /// Internal implementation of session management. @@ -244,7 +255,9 @@ impl SessionManager { self.0.sessions.write().expect("read shouldn't fail") } - pub(crate) fn storage(&self) -> &SessionStorageDb { &self.0.storage } + pub(crate) fn storage(&self) -> &SessionStorageDb { + &self.0.storage + } /// Inserts `Session` into the session store, associated with the specified topic. /// If a session with the same topic already exists, it will be overwritten. @@ -262,7 +275,9 @@ impl SessionManager { } /// Retrieves a cloned session associated with a given topic. - pub fn get_session(&self, topic: &Topic) -> Option { self.read().get(topic).cloned() } + pub fn get_session(&self, topic: &Topic) -> Option { + self.read().get(topic).cloned() + } /// Retrieves a cloned session associated with a given sessionn or pairing topic. pub fn get_session_with_any_topic(&self, topic: &Topic, with_pairing_topic: bool) -> Option { diff --git a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs index c88922575a..249b1a926a 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs @@ -1,6 +1,8 @@ -use crate::{error::{WalletConnectError, USER_REQUESTED}, - storage::WalletConnectStorageOps, - WalletConnectCtxImpl}; +use crate::{ + error::{WalletConnectError, USER_REQUESTED}, + storage::WalletConnectStorageOps, + WalletConnectCtxImpl, +}; use common::log::debug; use mm2_err_handle::prelude::{MapMmError, MmResult}; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/event.rs b/mm2src/kdf_walletconnect/src/session/rpc/event.rs index 2c93dd22d3..58b76690b5 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/event.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/event.rs @@ -1,12 +1,18 @@ -use crate::{chain::{WcChain, WcChainId}, - error::{WalletConnectError, UNSUPPORTED_CHAINS}, - WalletConnectCtxImpl}; +use crate::{ + chain::{WcChain, WcChainId}, + error::{WalletConnectError, UNSUPPORTED_CHAINS}, + WalletConnectCtxImpl, +}; use common::log::{error, info}; use mm2_err_handle::prelude::*; -use relay_rpc::{domain::{MessageId, Topic}, - rpc::{params::{session_event::SessionEventRequest, ResponseParamsError}, - ErrorData}}; +use relay_rpc::{ + domain::{MessageId, Topic}, + rpc::{ + params::{session_event::SessionEventRequest, ResponseParamsError}, + ErrorData, + }, +}; pub async fn handle_session_event( ctx: &WalletConnectCtxImpl, diff --git a/mm2src/kdf_walletconnect/src/session/rpc/extend.rs b/mm2src/kdf_walletconnect/src/session/rpc/extend.rs index 0574277af1..59fccf2b44 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/extend.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/extend.rs @@ -1,8 +1,10 @@ use crate::{error::WalletConnectError, WalletConnectCtxImpl}; use mm2_err_handle::prelude::MmResult; -use relay_rpc::{domain::{MessageId, Topic}, - rpc::params::{session_extend::SessionExtendRequest, ResponseParamsSuccess}}; +use relay_rpc::{ + domain::{MessageId, Topic}, + rpc::params::{session_extend::SessionExtendRequest, ResponseParamsSuccess}, +}; /// Process session extend request. pub(crate) async fn reply_session_extend_request( diff --git a/mm2src/kdf_walletconnect/src/session/rpc/ping.rs b/mm2src/kdf_walletconnect/src/session/rpc/ping.rs index ad4423c7d5..dfaf0f519e 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/ping.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/ping.rs @@ -2,8 +2,10 @@ use crate::{error::WalletConnectError, WalletConnectCtxImpl}; use common::custom_futures::timeout::FutureTimerExt; use mm2_err_handle::prelude::*; -use relay_rpc::{domain::{MessageId, Topic}, - rpc::params::{RequestParams, ResponseParamsSuccess}}; +use relay_rpc::{ + domain::{MessageId, Topic}, + rpc::params::{RequestParams, ResponseParamsSuccess}, +}; pub(crate) async fn reply_session_ping_request( ctx: &WalletConnectCtxImpl, diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index d3626430ce..9b61328f9d 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -1,17 +1,23 @@ use super::settle::send_session_settle_request; use crate::storage::WalletConnectStorageOps; -use crate::{error::WalletConnectError, - metadata::generate_metadata, - session::{Session, SessionKey, SessionType, THIRTY_DAYS}, - WalletConnectCtxImpl}; +use crate::{ + error::WalletConnectError, + metadata::generate_metadata, + session::{Session, SessionKey, SessionType, THIRTY_DAYS}, + WalletConnectCtxImpl, +}; use chrono::Utc; use mm2_err_handle::map_to_mm::MapToMmResult; use mm2_err_handle::prelude::*; use relay_rpc::rpc::params::session::ProposeNamespaces; -use relay_rpc::{domain::{MessageId, Topic}, - rpc::params::{session_propose::{Proposer, SessionProposeRequest, SessionProposeResponse}, - RequestParams, ResponseParamsSuccess}}; +use relay_rpc::{ + domain::{MessageId, Topic}, + rpc::params::{ + session_propose::{Proposer, SessionProposeRequest, SessionProposeResponse}, + RequestParams, ResponseParamsSuccess, + }, +}; /// Creates a new session proposal from topic and metadata. pub(crate) async fn send_proposal_request( diff --git a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs index 978123ede4..138519426b 100644 --- a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs +++ b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs @@ -4,8 +4,10 @@ use crate::session::Session; use async_trait::async_trait; use common::log::debug; use mm2_core::mm_ctx::MmArc; -use mm2_db::indexed_db::{ConstructibleDb, DbIdentifier, DbInstance, DbLocked, DbUpgrader, IndexedDb, IndexedDbBuilder, - InitDbResult, OnUpgradeResult, SharedDb, TableSignature}; +use mm2_db::indexed_db::{ + ConstructibleDb, DbIdentifier, DbInstance, DbLocked, DbUpgrader, IndexedDb, IndexedDbBuilder, InitDbResult, + OnUpgradeResult, SharedDb, TableSignature, +}; use mm2_err_handle::prelude::MmResult; use mm2_err_handle::prelude::*; use relay_rpc::domain::Topic; @@ -44,7 +46,9 @@ impl DbInstance for IDBSessionStorageInner { } impl IDBSessionStorageInner { - pub(crate) fn get_inner(&self) -> &IndexedDb { &self.0 } + pub(crate) fn get_inner(&self) -> &IndexedDb { + &self.0 + } } #[derive(Clone)] @@ -72,7 +76,9 @@ impl WalletConnectStorageOps for IDBSessionStorage { Ok(()) } - async fn is_initialized(&self) -> MmResult { Ok(true) } + async fn is_initialized(&self) -> MmResult { + Ok(true) + } async fn save_session(&self, session: &Session) -> MmResult<(), Self::Error> { debug!("[{}] Saving WalletConnect session to storage", session.topic); diff --git a/mm2src/kdf_walletconnect/src/storage/mod.rs b/mm2src/kdf_walletconnect/src/storage/mod.rs index 4f4077fb6f..8dc414550b 100644 --- a/mm2src/kdf_walletconnect/src/storage/mod.rs +++ b/mm2src/kdf_walletconnect/src/storage/mod.rs @@ -8,8 +8,10 @@ use relay_rpc::domain::Topic; use crate::{error::WalletConnectError, session::Session}; -#[cfg(target_arch = "wasm32")] pub(crate) mod indexed_db; -#[cfg(not(target_arch = "wasm32"))] pub(crate) mod sqlite; +#[cfg(target_arch = "wasm32")] +pub(crate) mod indexed_db; +#[cfg(not(target_arch = "wasm32"))] +pub(crate) mod sqlite; #[async_trait] pub(crate) trait WalletConnectStorageOps { @@ -35,7 +37,9 @@ pub(crate) struct SessionStorageDb(DB); impl Deref for SessionStorageDb { type Target = DB; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { + &self.0 + } } impl SessionStorageDb { @@ -56,9 +60,11 @@ pub(crate) mod session_storage_tests { use mm2_test_helpers::for_tests::mm_ctx_with_custom_async_db; use relay_rpc::{domain::SubscriptionId, rpc::params::Metadata}; - use crate::{session::key::SessionKey, - session::{Session, SessionType}, - WalletConnectCtx}; + use crate::{ + session::key::SessionKey, + session::{Session, SessionType}, + WalletConnectCtx, + }; use super::WalletConnectStorageOps; diff --git a/mm2src/kdf_walletconnect/src/storage/sqlite.rs b/mm2src/kdf_walletconnect/src/storage/sqlite.rs index 40bfcf9431..d95606d641 100644 --- a/mm2src/kdf_walletconnect/src/storage/sqlite.rs +++ b/mm2src/kdf_walletconnect/src/storage/sqlite.rs @@ -3,8 +3,10 @@ use common::log::debug; use db_common::async_sql_conn::InternalError; use db_common::sqlite::rusqlite::Result as SqlResult; use db_common::sqlite::{query_single_row, string_from_row, CHECK_TABLE_EXISTS_SQL}; -use db_common::{async_sql_conn::{AsyncConnError, AsyncConnection}, - sqlite::validate_table_name}; +use db_common::{ + async_sql_conn::{AsyncConnError, AsyncConnection}, + sqlite::validate_table_name, +}; use futures::lock::{Mutex, MutexGuard}; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; @@ -45,7 +47,9 @@ impl SqliteSessionStorage { Ok(Self { conn: conn.clone() }) } - pub(crate) async fn lock_db(&self) -> MutexGuard<'_, AsyncConnection> { self.conn.lock().await } + pub(crate) async fn lock_db(&self) -> MutexGuard<'_, AsyncConnection> { + self.conn.lock().await + } } #[async_trait] diff --git a/mm2src/mm2_bin_lib/build.rs b/mm2src/mm2_bin_lib/build.rs index 76cc3a9d4d..ce4ca83710 100644 --- a/mm2src/mm2_bin_lib/build.rs +++ b/mm2src/mm2_bin_lib/build.rs @@ -2,7 +2,9 @@ use chrono::Utc; use regex::Regex; use std::{env, process::Command}; -fn crate_version() -> &'static str { env!("CARGO_PKG_VERSION") } +fn crate_version() -> &'static str { + env!("CARGO_PKG_VERSION") +} fn version_tag() -> Result { if let Ok(tag) = env::var("KDF_BUILD_TAG") { @@ -29,9 +31,13 @@ fn version_tag() -> Result { Ok(commit_hash) } -fn version() -> Result { version_tag().map(|tag| format!("{}_{}", crate_version(), tag)) } +fn version() -> Result { + version_tag().map(|tag| format!("{}_{}", crate_version(), tag)) +} -fn build_datetime() -> String { Utc::now().to_rfc3339() } +fn build_datetime() -> String { + Utc::now().to_rfc3339() +} fn set_build_variables() -> Result<(), String> { println!("cargo:rustc-env=KDF_VERSION={}", version()?); diff --git a/mm2src/mm2_bin_lib/src/lib.rs b/mm2src/mm2_bin_lib/src/lib.rs index 453f1b55f5..8c01098e0d 100644 --- a/mm2src/mm2_bin_lib/src/lib.rs +++ b/mm2src/mm2_bin_lib/src/lib.rs @@ -2,10 +2,13 @@ use enum_primitive_derive::Primitive; use mm2_core::mm_ctx::MmArc; use mm2_main::lp_dispatcher::{dispatch_lp_event, StopCtxEvent}; use std::sync::atomic::{AtomicBool, AtomicU32, Ordering}; -#[cfg(target_arch = "wasm32")] use wasm_bindgen::prelude::*; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; -#[cfg(not(target_arch = "wasm32"))] mod mm2_native_lib; -#[cfg(target_arch = "wasm32")] mod mm2_wasm_lib; +#[cfg(not(target_arch = "wasm32"))] +mod mm2_native_lib; +#[cfg(target_arch = "wasm32")] +mod mm2_wasm_lib; const KDF_VERSION: &str = env!("KDF_VERSION"); const KDF_DATETIME: &str = env!("KDF_DATETIME"); diff --git a/mm2src/mm2_bin_lib/src/mm2_bin.rs b/mm2src/mm2_bin_lib/src/mm2_bin.rs index a944edaa8d..7b8aa687a4 100644 --- a/mm2src/mm2_bin_lib/src/mm2_bin.rs +++ b/mm2src/mm2_bin_lib/src/mm2_bin.rs @@ -1,4 +1,5 @@ -#[cfg(not(target_arch = "wasm32"))] use mm2_main::mm2_main; +#[cfg(not(target_arch = "wasm32"))] +use mm2_main::mm2_main; #[cfg(not(target_arch = "wasm32"))] const KDF_VERSION: &str = env!("KDF_VERSION"); diff --git a/mm2src/mm2_bin_lib/src/mm2_native_lib.rs b/mm2src/mm2_bin_lib/src/mm2_native_lib.rs index 374fd9d630..68cc0ca892 100644 --- a/mm2src/mm2_bin_lib/src/mm2_native_lib.rs +++ b/mm2src/mm2_bin_lib/src/mm2_native_lib.rs @@ -144,7 +144,9 @@ pub unsafe extern "C" fn mm2_main(conf: *const c_char, log_cb: extern "C" fn(lin /// 2 .. context, but no RPC yet. /// 3 .. RPC is up. #[no_mangle] -pub extern "C" fn mm2_main_status() -> i8 { mm2_status() as i8 } +pub extern "C" fn mm2_main_status() -> i8 { + mm2_status() as i8 +} /// Run a few hand-picked tests. /// diff --git a/mm2src/mm2_bin_lib/src/mm2_wasm_lib.rs b/mm2src/mm2_bin_lib/src/mm2_wasm_lib.rs index 9fcf795012..5fe4cff123 100644 --- a/mm2src/mm2_bin_lib/src/mm2_wasm_lib.rs +++ b/mm2src/mm2_bin_lib/src/mm2_wasm_lib.rs @@ -35,10 +35,14 @@ impl StartupError { } #[wasm_bindgen(getter)] - pub fn code(&self) -> i8 { self.code as i8 } + pub fn code(&self) -> i8 { + self.code as i8 + } #[wasm_bindgen(getter)] - pub fn message(&self) -> String { self.message.clone() } + pub fn message(&self) -> String { + self.message.clone() + } } #[derive(Deserialize)] @@ -48,7 +52,9 @@ struct MainParams { } impl From for LpMainParams { - fn from(orig: MainParams) -> Self { LpMainParams::with_conf(orig.conf).log_filter(Some(orig.log_level)) } + fn from(orig: MainParams) -> Self { + LpMainParams::with_conf(orig.conf).log_filter(Some(orig.log_level)) + } } /// Runs a MarketMaker2 instance. @@ -154,7 +160,9 @@ pub async fn mm2_main(params: JsValue, log_cb: js_sys::Function) -> Result MainStatus { mm2_status() } +pub fn mm2_main_status() -> MainStatus { + mm2_status() +} #[derive(Debug, Serialize)] #[serde(untagged)] @@ -182,7 +190,9 @@ pub enum Mm2RpcErr { } impl From for JsValue { - fn from(e: Mm2RpcErr) -> Self { JsValue::from(e as i32) } + fn from(e: Mm2RpcErr) -> Self { + JsValue::from(e as i32) + } } /// Invokes an RPC request. diff --git a/mm2src/mm2_bitcoin/chain/src/block.rs b/mm2src/mm2_bitcoin/chain/src/block.rs index 747da3ac88..92235993ec 100644 --- a/mm2src/mm2_bitcoin/chain/src/block.rs +++ b/mm2src/mm2_bitcoin/chain/src/block.rs @@ -12,11 +12,15 @@ pub struct Block { } impl From<&'static str> for Block { - fn from(s: &'static str) -> Self { deserialize(&s.from_hex::>().unwrap() as &[u8]).unwrap() } + fn from(s: &'static str) -> Self { + deserialize(&s.from_hex::>().unwrap() as &[u8]).unwrap() + } } impl RepresentH256 for Block { - fn h256(&self) -> H256 { self.hash() } + fn h256(&self) -> H256 { + self.hash() + } } impl Block { @@ -46,11 +50,17 @@ impl Block { merkle_root(&hashes) } - pub fn transactions(&self) -> &[Transaction] { &self.transactions } + pub fn transactions(&self) -> &[Transaction] { + &self.transactions + } - pub fn header(&self) -> &BlockHeader { &self.block_header } + pub fn header(&self) -> &BlockHeader { + &self.block_header + } - pub fn hash(&self) -> H256 { self.block_header.hash() } + pub fn hash(&self) -> H256 { + self.block_header.hash() + } } #[cfg(test)] diff --git a/mm2src/mm2_bitcoin/chain/src/block_header.rs b/mm2src/mm2_bitcoin/chain/src/block_header.rs index 2d819fc280..e4fce6103f 100644 --- a/mm2src/mm2_bitcoin/chain/src/block_header.rs +++ b/mm2src/mm2_bitcoin/chain/src/block_header.rs @@ -337,10 +337,16 @@ impl BlockHeader { reader.read::() } - pub fn hash(&self) -> H256 { dhash256(&serialize(self)) } + pub fn hash(&self) -> H256 { + dhash256(&serialize(self)) + } - pub fn is_prog_pow(&self) -> bool { self.version == MTP_POW_VERSION && self.time >= PROG_POW_SWITCH_TIME } - pub fn raw(&self) -> Bytes { serialize(self) } + pub fn is_prog_pow(&self) -> bool { + self.version == MTP_POW_VERSION && self.time >= PROG_POW_SWITCH_TIME + } + pub fn raw(&self) -> Bytes { + serialize(self) + } pub fn target(&self) -> Result { match self.bits { BlockHeaderBits::Compact(compact) => compact.to_u256(), @@ -350,7 +356,9 @@ impl BlockHeader { } impl From<&'static str> for BlockHeader { - fn from(s: &'static str) -> Self { deserialize(&s.from_hex::>().unwrap() as &[u8]).unwrap() } + fn from(s: &'static str) -> Self { + deserialize(&s.from_hex::>().unwrap() as &[u8]).unwrap() + } } #[cfg(not(target_arch = "wasm32"))] @@ -376,10 +384,12 @@ impl From for ExtBlockHeader { #[cfg(test)] mod tests { - #[cfg(not(target_arch = "wasm32"))] use super::ExtBlockHeader; - use block_header::{BlockHeader, BlockHeaderBits, BlockHeaderNonce, AUX_POW_VERSION_DOGE, AUX_POW_VERSION_NMC, - AUX_POW_VERSION_SYS, BIP9_NO_SOFT_FORK_BLOCK_HEADER_VERSION, KAWPOW_VERSION, MTP_POW_VERSION, - PROG_POW_SWITCH_TIME}; + #[cfg(not(target_arch = "wasm32"))] + use super::ExtBlockHeader; + use block_header::{ + BlockHeader, BlockHeaderBits, BlockHeaderNonce, AUX_POW_VERSION_DOGE, AUX_POW_VERSION_NMC, AUX_POW_VERSION_SYS, + BIP9_NO_SOFT_FORK_BLOCK_HEADER_VERSION, KAWPOW_VERSION, MTP_POW_VERSION, PROG_POW_SWITCH_TIME, + }; use hex::FromHex; use primitives::bytes::Bytes; use ser::{deserialize, serialize, serialize_list, CoinVariant, Error as ReaderError, Reader, Stream}; diff --git a/mm2src/mm2_bitcoin/chain/src/lib.rs b/mm2src/mm2_bitcoin/chain/src/lib.rs index 58133355bf..db7e2dd4b9 100644 --- a/mm2src/mm2_bitcoin/chain/src/lib.rs +++ b/mm2src/mm2_bitcoin/chain/src/lib.rs @@ -4,7 +4,8 @@ extern crate bitcrypto as crypto; extern crate primitives; extern crate rustc_hex as hex; extern crate serialization as ser; -#[macro_use] extern crate serialization_derive; +#[macro_use] +extern crate serialization_derive; pub mod constants; @@ -27,8 +28,9 @@ pub use primitives::{bytes, compact, hash, U256}; pub use block::Block; pub use block_header::{BlockHeader, BlockHeaderBits, BlockHeaderNonce}; pub use merkle_root::{merkle_node_hash, merkle_root}; -pub use transaction::{JoinSplit, OutPoint, ShieldedOutput, ShieldedSpend, Transaction, TransactionInput, - TransactionOutput, TxHashAlgo}; +pub use transaction::{ + JoinSplit, OutPoint, ShieldedOutput, ShieldedSpend, Transaction, TransactionInput, TransactionOutput, TxHashAlgo, +}; pub use read_and_hash::{HashedData, ReadAndHash}; diff --git a/mm2src/mm2_bitcoin/chain/src/raw_block.rs b/mm2src/mm2_bitcoin/chain/src/raw_block.rs index c50e4c1e31..bfa0f2dfbe 100644 --- a/mm2src/mm2_bitcoin/chain/src/raw_block.rs +++ b/mm2src/mm2_bitcoin/chain/src/raw_block.rs @@ -27,7 +27,9 @@ impl RawBlockHeader { } /// Calculate the LE header digest - pub fn digest(&self) -> H256 { dhash256(self.0.as_slice()) } + pub fn digest(&self) -> H256 { + dhash256(self.0.as_slice()) + } /// Extract the LE tx merkle root from the header pub fn extract_merkle_root(&self) -> H256 { diff --git a/mm2src/mm2_bitcoin/chain/src/transaction.rs b/mm2src/mm2_bitcoin/chain/src/transaction.rs index acc3218ba6..f623b75ab8 100644 --- a/mm2src/mm2_bitcoin/chain/src/transaction.rs +++ b/mm2src/mm2_bitcoin/chain/src/transaction.rs @@ -39,7 +39,9 @@ impl OutPoint { } } - pub fn is_null(&self) -> bool { self.hash.is_zero() && self.index == u32::MAX } + pub fn is_null(&self) -> bool { + self.hash.is_zero() && self.index == u32::MAX + } } #[cfg(not(target_arch = "wasm32"))] @@ -70,9 +72,13 @@ impl TransactionInput { } } - pub fn is_final(&self) -> bool { self.sequence == SEQUENCE_FINAL } + pub fn is_final(&self) -> bool { + self.sequence == SEQUENCE_FINAL + } - pub fn has_witness(&self) -> bool { !self.script_witness.is_empty() } + pub fn has_witness(&self) -> bool { + !self.script_witness.is_empty() + } } #[cfg(not(target_arch = "wasm32"))] @@ -234,7 +240,9 @@ pub struct Transaction { } impl From<&'static str> for Transaction { - fn from(s: &'static str) -> Self { deserialize(&s.from_hex::>().unwrap() as &[u8]).unwrap() } + fn from(s: &'static str) -> Self { + deserialize(&s.from_hex::>().unwrap() as &[u8]).unwrap() + } } #[cfg(not(target_arch = "wasm32"))] @@ -262,7 +270,9 @@ pub enum TxHashAlgo { pub struct TxHasNoOutputs {} impl std::fmt::Display for TxHasNoOutputs { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str("Tx has no outputs") } + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.write_str("Tx has no outputs") + } } impl Transaction { @@ -274,17 +284,29 @@ impl Transaction { } } - pub fn witness_hash(&self) -> H256 { dhash256(&serialize_with_flags(self, SERIALIZE_TRANSACTION_WITNESS)) } + pub fn witness_hash(&self) -> H256 { + dhash256(&serialize_with_flags(self, SERIALIZE_TRANSACTION_WITNESS)) + } - pub fn inputs(&self) -> &[TransactionInput] { &self.inputs } + pub fn inputs(&self) -> &[TransactionInput] { + &self.inputs + } - pub fn outputs(&self) -> &[TransactionOutput] { &self.outputs } + pub fn outputs(&self) -> &[TransactionOutput] { + &self.outputs + } - pub fn is_empty(&self) -> bool { self.inputs.is_empty() || self.outputs.is_empty() } + pub fn is_empty(&self) -> bool { + self.inputs.is_empty() || self.outputs.is_empty() + } - pub fn is_null(&self) -> bool { self.inputs.iter().any(|input| input.previous_output.is_null()) } + pub fn is_null(&self) -> bool { + self.inputs.iter().any(|input| input.previous_output.is_null()) + } - pub fn is_coinbase(&self) -> bool { self.inputs.len() == 1 && self.inputs[0].previous_output.is_null() } + pub fn is_coinbase(&self) -> bool { + self.inputs.len() == 1 && self.inputs[0].previous_output.is_null() + } pub fn is_final(&self) -> bool { // if lock_time is 0, transaction is final @@ -314,7 +336,9 @@ impl Transaction { self.inputs.iter().all(TransactionInput::is_final) } - pub fn has_witness(&self) -> bool { self.inputs.iter().any(TransactionInput::has_witness) } + pub fn has_witness(&self) -> bool { + self.inputs.iter().any(TransactionInput::has_witness) + } pub fn total_spends(&self) -> u64 { let mut result = 0u64; @@ -452,7 +476,9 @@ pub enum TxType { } impl TxType { - fn uses_witness(&self) -> bool { matches!(self, TxType::StandardWithWitness | TxType::PosvWithNTime) } + fn uses_witness(&self) -> bool { + matches!(self, TxType::StandardWithWitness | TxType::PosvWithNTime) + } } pub fn deserialize_tx(reader: &mut Reader, tx_type: TxType) -> Result @@ -620,7 +646,8 @@ impl Deserializable for Transaction { #[cfg(test)] mod tests { - #[cfg(not(target_arch = "wasm32"))] use super::ExtTransaction; + #[cfg(not(target_arch = "wasm32"))] + use super::ExtTransaction; use super::{Bytes, OutPoint, Transaction, TransactionInput, TransactionOutput}; use hash::{H256, H512}; use hex::ToHex; diff --git a/mm2src/mm2_bitcoin/crypto/src/lib.rs b/mm2src/mm2_bitcoin/crypto/src/lib.rs index fc034858f2..fdc7e24fc8 100644 --- a/mm2src/mm2_bitcoin/crypto/src/lib.rs +++ b/mm2src/mm2_bitcoin/crypto/src/lib.rs @@ -76,15 +76,21 @@ pub fn keccak256(input: &[u8]) -> H256 { /// Double Keccak-256 #[inline] -pub fn dkeccak256(input: &[u8]) -> H256 { keccak256(&*keccak256(input)) } +pub fn dkeccak256(input: &[u8]) -> H256 { + keccak256(&*keccak256(input)) +} /// SHA-256 and RIPEMD160 #[inline] -pub fn dhash160(input: &[u8]) -> H160 { ripemd160(&*sha256(input)) } +pub fn dhash160(input: &[u8]) -> H160 { + ripemd160(&*sha256(input)) +} /// Double SHA-256 #[inline] -pub fn dhash256(input: &[u8]) -> H256 { sha256(&*sha256(input)) } +pub fn dhash256(input: &[u8]) -> H256 { + sha256(&*sha256(input)) +} /// SipHash-2-4 #[inline] @@ -96,7 +102,9 @@ pub fn siphash24(key0: u64, key1: u64, input: &[u8]) -> u64 { /// Double Groestl-512 #[inline] -pub fn dgroestl512(input: &[u8]) -> H512 { groestl512(&*groestl512(input)) } +pub fn dgroestl512(input: &[u8]) -> H512 { + groestl512(&*groestl512(input)) +} /// Data checksum #[inline] diff --git a/mm2src/mm2_bitcoin/keys/src/address.rs b/mm2src/mm2_bitcoin/keys/src/address.rs index adf72131ff..ee4e4fef5b 100644 --- a/mm2src/mm2_bitcoin/keys/src/address.rs +++ b/mm2src/mm2_bitcoin/keys/src/address.rs @@ -12,8 +12,10 @@ use serde::{Deserialize, Serialize}; use std::str::FromStr; use std::{fmt, hash::Hash}; -use {AddressHashEnum, AddressPrefix, CashAddrType, CashAddress, Error, LegacyAddress, NetworkAddressPrefixes, - SegwitAddress}; +use { + AddressHashEnum, AddressPrefix, CashAddrType, CashAddress, Error, LegacyAddress, NetworkAddressPrefixes, + SegwitAddress, +}; mod address_builder; pub use self::address_builder::{AddressBuilder, AddressBuilderOption}; @@ -70,11 +72,17 @@ pub enum AddressFormat { } impl AddressFormat { - pub fn is_segwit(&self) -> bool { matches!(*self, AddressFormat::Segwit) } + pub fn is_segwit(&self) -> bool { + matches!(*self, AddressFormat::Segwit) + } - pub fn is_cashaddress(&self) -> bool { matches!(*self, AddressFormat::CashAddress { .. }) } + pub fn is_cashaddress(&self) -> bool { + matches!(*self, AddressFormat::CashAddress { .. }) + } - pub fn is_legacy(&self) -> bool { matches!(*self, AddressFormat::Standard) } + pub fn is_legacy(&self) -> bool { + matches!(*self, AddressFormat::Standard) + } } // Todo: add segwit checksum detection @@ -141,13 +149,27 @@ impl Hash for Address { } impl Address { - pub fn prefix(&self) -> &AddressPrefix { &self.prefix } - pub fn hrp(&self) -> &Option { &self.hrp } - pub fn pubkey(&self) -> &Option { &self.pubkey } - pub fn hash(&self) -> &AddressHashEnum { &self.hash } - pub fn checksum_type(&self) -> &ChecksumType { &self.checksum_type } - pub fn addr_format(&self) -> &AddressFormat { &self.addr_format } - pub fn script_type(&self) -> &AddressScriptType { &self.script_type } + pub fn prefix(&self) -> &AddressPrefix { + &self.prefix + } + pub fn hrp(&self) -> &Option { + &self.hrp + } + pub fn pubkey(&self) -> &Option { + &self.pubkey + } + pub fn hash(&self) -> &AddressHashEnum { + &self.hash + } + pub fn checksum_type(&self) -> &ChecksumType { + &self.checksum_type + } + pub fn addr_format(&self) -> &AddressFormat { + &self.addr_format + } + pub fn script_type(&self) -> &AddressScriptType { + &self.script_type + } /// Returns true if output script type is pubkey hash (p2pkh or p2wpkh) pub fn is_pubkey_hash(&self) -> bool { @@ -172,10 +194,13 @@ impl Address { pub_addr_prefix, p2sh_addr_prefix, } => self - .to_cashaddress(network, &NetworkAddressPrefixes { - p2pkh: [*pub_addr_prefix].into(), - p2sh: [*p2sh_addr_prefix].into(), - }) + .to_cashaddress( + network, + &NetworkAddressPrefixes { + p2pkh: [*pub_addr_prefix].into(), + p2sh: [*p2sh_addr_prefix].into(), + }, + ) .and_then(|cashaddress| cashaddress.encode()), } } @@ -304,10 +329,13 @@ impl fmt::Display for Address { p2sh_addr_prefix, } => { let cash_address = self - .to_cashaddress(network, &NetworkAddressPrefixes { - p2pkh: [*pub_addr_prefix].into(), - p2sh: [*p2sh_addr_prefix].into(), - }) + .to_cashaddress( + network, + &NetworkAddressPrefixes { + p2pkh: [*pub_addr_prefix].into(), + p2sh: [*p2sh_addr_prefix].into(), + }, + ) .expect("A valid address"); cash_address.encode().expect("A valid address").fmt(f) }, diff --git a/mm2src/mm2_bitcoin/keys/src/address_prefixes.rs b/mm2src/mm2_bitcoin/keys/src/address_prefixes.rs index 442cb05b3f..56f72920c7 100644 --- a/mm2src/mm2_bitcoin/keys/src/address_prefixes.rs +++ b/mm2src/mm2_bitcoin/keys/src/address_prefixes.rs @@ -19,11 +19,15 @@ impl TryFrom<&[u8]> for AddressPrefix { } impl From<[u8; 1]> for AddressPrefix { - fn from(prefix: [u8; 1]) -> Self { Self { data: prefix.to_vec() } } + fn from(prefix: [u8; 1]) -> Self { + Self { data: prefix.to_vec() } + } } impl From<[u8; 2]> for AddressPrefix { - fn from(prefix: [u8; 2]) -> Self { Self { data: prefix.to_vec() } } + fn from(prefix: [u8; 2]) -> Self { + Self { data: prefix.to_vec() } + } } impl fmt::Display for AddressPrefix { @@ -42,7 +46,9 @@ impl fmt::Display for AddressPrefix { impl AddressPrefix { /// Get as vec of u8 - pub fn to_vec(&self) -> Vec { self.data.to_vec() } + pub fn to_vec(&self) -> Vec { + self.data.to_vec() + } /// Get if prefix size is 1, for use in cash_address pub fn get_size_1_prefix(&self) -> u8 { @@ -53,7 +59,9 @@ impl AddressPrefix { } } - pub fn is_empty(&self) -> bool { self.data.is_empty() } + pub fn is_empty(&self) -> bool { + self.data.is_empty() + } } /// All prefixes for legacy address types supported for a coin, from coin config diff --git a/mm2src/mm2_bitcoin/keys/src/cashaddress.rs b/mm2src/mm2_bitcoin/keys/src/cashaddress.rs index d798d1501c..322b70b23d 100644 --- a/mm2src/mm2_bitcoin/keys/src/cashaddress.rs +++ b/mm2src/mm2_bitcoin/keys/src/cashaddress.rs @@ -58,7 +58,9 @@ impl FromStr for NetworkPrefix { } impl From<&'static str> for NetworkPrefix { - fn from(s: &str) -> Self { s.parse().unwrap() } + fn from(s: &str) -> Self { + s.parse().unwrap() + } } impl NetworkPrefix { @@ -203,11 +205,15 @@ impl CashAddress { impl FromStr for CashAddress { type Err = String; - fn from_str(s: &str) -> Result { CashAddress::decode(s) } + fn from_str(s: &str) -> Result { + CashAddress::decode(s) + } } impl From<&'static str> for CashAddress { - fn from(s: &'static str) -> Self { s.parse().unwrap() } + fn from(s: &'static str) -> Self { + s.parse().unwrap() + } } fn split_address(addr: &str) -> Result<(NetworkPrefix, &str), String> { diff --git a/mm2src/mm2_bitcoin/keys/src/keypair.rs b/mm2src/mm2_bitcoin/keys/src/keypair.rs index 4c3abdb8f4..44aa433818 100644 --- a/mm2src/mm2_bitcoin/keys/src/keypair.rs +++ b/mm2src/mm2_bitcoin/keys/src/keypair.rs @@ -28,15 +28,25 @@ impl fmt::Display for KeyPair { } impl KeyPair { - pub fn private(&self) -> &Private { &self.private } + pub fn private(&self) -> &Private { + &self.private + } - pub fn private_bytes(&self) -> [u8; 32] { self.private.secret.take() } + pub fn private_bytes(&self) -> [u8; 32] { + self.private.secret.take() + } - pub fn private_ref(&self) -> &[u8; 32] { &self.private.secret } + pub fn private_ref(&self) -> &[u8; 32] { + &self.private.secret + } - pub fn public(&self) -> &Public { &self.public } + pub fn public(&self) -> &Public { + &self.public + } - pub fn public_slice(&self) -> &[u8] { &self.public } + pub fn public_slice(&self) -> &[u8] { + &self.public + } pub fn from_private(private: Private) -> Result { let s: SecretKey = SecretKey::from_slice(&*private.secret)?; diff --git a/mm2src/mm2_bitcoin/keys/src/legacyaddress.rs b/mm2src/mm2_bitcoin/keys/src/legacyaddress.rs index e6a4bf4cd9..d4da2243d2 100644 --- a/mm2src/mm2_bitcoin/keys/src/legacyaddress.rs +++ b/mm2src/mm2_bitcoin/keys/src/legacyaddress.rs @@ -24,7 +24,9 @@ pub struct LegacyAddressDisplayLayout(Vec); impl Deref for LegacyAddressDisplayLayout { type Target = [u8]; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { + &self.0 + } } impl DisplayLayout for LegacyAddress { @@ -87,7 +89,9 @@ impl FromStr for LegacyAddress { } impl From<&'static str> for LegacyAddress { - fn from(s: &'static str) -> Self { s.parse().unwrap_or_default() } + fn from(s: &'static str) -> Self { + s.parse().unwrap_or_default() + } } impl fmt::Display for LegacyAddress { diff --git a/mm2src/mm2_bitcoin/keys/src/lib.rs b/mm2src/mm2_bitcoin/keys/src/lib.rs index 88eea9408f..3ce18fcb4e 100644 --- a/mm2src/mm2_bitcoin/keys/src/lib.rs +++ b/mm2src/mm2_bitcoin/keys/src/lib.rs @@ -9,7 +9,8 @@ extern crate primitives; extern crate rustc_hex as hex; extern crate secp256k1; extern crate serde; -#[macro_use] extern crate serde_derive; +#[macro_use] +extern crate serde_derive; mod address; mod address_prefixes; @@ -59,9 +60,13 @@ pub enum AddressHashEnum { } impl AddressHashEnum { - pub fn default_address_hash() -> Self { AddressHashEnum::AddressHash(H160::default()) } + pub fn default_address_hash() -> Self { + AddressHashEnum::AddressHash(H160::default()) + } - pub fn default_witness_script_hash() -> Self { AddressHashEnum::WitnessScriptHash(H256::default()) } + pub fn default_witness_script_hash() -> Self { + AddressHashEnum::WitnessScriptHash(H256::default()) + } pub fn copy_from_slice(&mut self, src: &[u8]) { match self { @@ -77,9 +82,13 @@ impl AddressHashEnum { } } - pub fn is_address_hash(&self) -> bool { matches!(*self, AddressHashEnum::AddressHash(_)) } + pub fn is_address_hash(&self) -> bool { + matches!(*self, AddressHashEnum::AddressHash(_)) + } - pub fn is_witness_script_hash(&self) -> bool { matches!(*self, AddressHashEnum::WitnessScriptHash(_)) } + pub fn is_witness_script_hash(&self) -> bool { + matches!(*self, AddressHashEnum::WitnessScriptHash(_)) + } } impl fmt::Display for AddressHashEnum { @@ -92,7 +101,9 @@ impl fmt::Display for AddressHashEnum { } impl From for AddressHashEnum { - fn from(hash: H160) -> Self { AddressHashEnum::AddressHash(hash) } + fn from(hash: H160) -> Self { + AddressHashEnum::AddressHash(hash) + } } lazy_static! { diff --git a/mm2src/mm2_bitcoin/keys/src/private.rs b/mm2src/mm2_bitcoin/keys/src/private.rs index 435a3b7a46..36cf5379fe 100644 --- a/mm2src/mm2_bitcoin/keys/src/private.rs +++ b/mm2src/mm2_bitcoin/keys/src/private.rs @@ -109,7 +109,9 @@ impl fmt::Debug for Private { } impl fmt::Display for Private { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { bs58::encode(self.layout()).into_string().fmt(f) } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + bs58::encode(self.layout()).into_string().fmt(f) + } } impl FromStr for Private { @@ -125,7 +127,9 @@ impl FromStr for Private { } impl From<&'static str> for Private { - fn from(s: &'static str) -> Self { s.parse().unwrap() } + fn from(s: &'static str) -> Self { + s.parse().unwrap() + } } #[cfg(test)] diff --git a/mm2src/mm2_bitcoin/keys/src/public.rs b/mm2src/mm2_bitcoin/keys/src/public.rs index c21eda0259..0d2c80b715 100644 --- a/mm2src/mm2_bitcoin/keys/src/public.rs +++ b/mm2src/mm2_bitcoin/keys/src/public.rs @@ -2,8 +2,10 @@ use crate::SECP_VERIFY; use crypto::dhash160; use hash::{H160, H264, H520}; use hex::ToHex; -use secp256k1::{recovery::{RecoverableSignature, RecoveryId}, - Error as SecpError, Message as SecpMessage, PublicKey, Signature as SecpSignature}; +use secp256k1::{ + recovery::{RecoverableSignature, RecoveryId}, + Error as SecpError, Message as SecpMessage, PublicKey, Signature as SecpSignature, +}; use std::{fmt, ops::Deref}; use {CompactSignature, Error, Message, Signature}; @@ -17,7 +19,9 @@ pub enum Public { } impl Default for Public { - fn default() -> Public { Public::Compressed(H264::default()) } + fn default() -> Public { + Public::Compressed(H264::default()) + } } impl Public { @@ -37,7 +41,9 @@ impl Public { } } - pub fn address_hash(&self) -> H160 { dhash160(self) } + pub fn address_hash(&self) -> H160 { + dhash160(self) + } pub fn verify(&self, message: &Message, signature: &Signature) -> Result { let public = match self { @@ -82,7 +88,9 @@ impl Public { } #[inline(always)] - pub fn to_secp256k1_pubkey(&self) -> Result { PublicKey::from_slice(self.deref()) } + pub fn to_secp256k1_pubkey(&self) -> Result { + PublicKey::from_slice(self.deref()) + } } impl Deref for Public { @@ -114,5 +122,7 @@ impl fmt::Debug for Public { } impl fmt::Display for Public { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.to_hex::().fmt(f) } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.to_hex::().fmt(f) + } } diff --git a/mm2src/mm2_bitcoin/keys/src/segwitaddress.rs b/mm2src/mm2_bitcoin/keys/src/segwitaddress.rs index 1b3d63b04e..d8841b6b1e 100644 --- a/mm2src/mm2_bitcoin/keys/src/segwitaddress.rs +++ b/mm2src/mm2_bitcoin/keys/src/segwitaddress.rs @@ -53,7 +53,9 @@ impl fmt::Display for Error { #[doc(hidden)] impl From for Error { - fn from(e: bech32::Error) -> Error { Error::Bech32(e) } + fn from(e: bech32::Error) -> Error { + Error::Bech32(e) + } } /// The different types of segwit addresses. @@ -103,7 +105,9 @@ impl SegwitAddress { /// /// Segwit addresses with unassigned witness versions or non-standard /// program sizes are considered non-standard. - pub fn is_standard(&self) -> bool { self.address_type().is_some() } + pub fn is_standard(&self) -> bool { + self.address_type().is_some() + } } struct UpperWriter(W); diff --git a/mm2src/mm2_bitcoin/keys/src/signature.rs b/mm2src/mm2_bitcoin/keys/src/signature.rs index 90122ed630..be65722d55 100644 --- a/mm2src/mm2_bitcoin/keys/src/signature.rs +++ b/mm2src/mm2_bitcoin/keys/src/signature.rs @@ -12,17 +12,23 @@ use Error; pub struct Signature(Vec); impl fmt::Debug for Signature { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.to_hex::().fmt(f) } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.to_hex::().fmt(f) + } } impl fmt::Display for Signature { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.to_hex::().fmt(f) } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.to_hex::().fmt(f) + } } impl ops::Deref for Signature { type Target = [u8]; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { + &self.0 + } } impl str::FromStr for Signature { @@ -35,15 +41,21 @@ impl str::FromStr for Signature { } impl From<&'static str> for Signature { - fn from(s: &'static str) -> Self { s.parse().unwrap() } + fn from(s: &'static str) -> Self { + s.parse().unwrap() + } } impl From> for Signature { - fn from(v: Vec) -> Self { Signature(v) } + fn from(v: Vec) -> Self { + Signature(v) + } } impl From for Vec { - fn from(s: Signature) -> Self { s.0 } + fn from(s: Signature) -> Self { + s.0 + } } impl Signature { @@ -53,24 +65,32 @@ impl Signature { } impl<'a> From<&'a [u8]> for Signature { - fn from(v: &'a [u8]) -> Self { Signature(v.to_vec()) } + fn from(v: &'a [u8]) -> Self { + Signature(v.to_vec()) + } } #[derive(PartialEq)] pub struct CompactSignature(H520); impl fmt::Debug for CompactSignature { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(&self.0.to_hex::()) } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(&self.0.to_hex::()) + } } impl fmt::Display for CompactSignature { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(&self.0.to_hex::()) } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(&self.0.to_hex::()) + } } impl ops::Deref for CompactSignature { type Target = [u8]; - fn deref(&self) -> &Self::Target { &*self.0 } + fn deref(&self) -> &Self::Target { + &*self.0 + } } impl str::FromStr for CompactSignature { @@ -85,11 +105,15 @@ impl str::FromStr for CompactSignature { } impl From<&'static str> for CompactSignature { - fn from(s: &'static str) -> Self { s.parse().unwrap() } + fn from(s: &'static str) -> Self { + s.parse().unwrap() + } } impl From for CompactSignature { - fn from(h: H520) -> Self { CompactSignature(h) } + fn from(h: H520) -> Self { + CompactSignature(h) + } } impl TryFrom> for CompactSignature { diff --git a/mm2src/mm2_bitcoin/primitives/src/bytes.rs b/mm2src/mm2_bitcoin/primitives/src/bytes.rs index 8b022bf46b..b5a94f85e8 100644 --- a/mm2src/mm2_bitcoin/primitives/src/bytes.rs +++ b/mm2src/mm2_bitcoin/primitives/src/bytes.rs @@ -8,71 +8,111 @@ use std::{fmt, io, marker, ops, str}; pub struct Bytes(Vec); impl Bytes { - pub fn new() -> Self { Bytes::default() } + pub fn new() -> Self { + Bytes::default() + } - pub fn new_with_len(len: usize) -> Self { Bytes(vec![0; len]) } + pub fn new_with_len(len: usize) -> Self { + Bytes(vec![0; len]) + } - pub fn take(self) -> Vec { self.0 } + pub fn take(self) -> Vec { + self.0 + } - pub fn as_slice(&self) -> &[u8] { &self.0 } + pub fn as_slice(&self) -> &[u8] { + &self.0 + } - pub fn len(&self) -> usize { self.0.len() } + pub fn len(&self) -> usize { + self.0.len() + } - pub fn is_empty(&self) -> bool { self.0.is_empty() } + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } - pub fn append(&mut self, other: &mut Bytes) { self.0.append(&mut other.0); } + pub fn append(&mut self, other: &mut Bytes) { + self.0.append(&mut other.0); + } - pub fn split_off(&mut self, at: usize) -> Bytes { Bytes(self.0.split_off(at)) } + pub fn split_off(&mut self, at: usize) -> Bytes { + Bytes(self.0.split_off(at)) + } } impl From<&[u8]> for Bytes { - fn from(v: &[u8]) -> Self { Bytes(v.into()) } + fn from(v: &[u8]) -> Self { + Bytes(v.into()) + } } impl From> for Bytes { - fn from(v: Vec) -> Self { Bytes(v) } + fn from(v: Vec) -> Self { + Bytes(v) + } } impl From for Vec { - fn from(bytes: Bytes) -> Self { bytes.0 } + fn from(bytes: Bytes) -> Self { + bytes.0 + } } impl From<&'static str> for Bytes { - fn from(s: &'static str) -> Self { s.parse().unwrap() } + fn from(s: &'static str) -> Self { + s.parse().unwrap() + } } impl str::FromStr for Bytes { type Err = FromHexError; - fn from_str(s: &str) -> Result { s.from_hex().map(Bytes) } + fn from_str(s: &str) -> Result { + s.from_hex().map(Bytes) + } } impl io::Write for Bytes { - fn write(&mut self, buf: &[u8]) -> Result { self.0.write(buf) } + fn write(&mut self, buf: &[u8]) -> Result { + self.0.write(buf) + } - fn flush(&mut self) -> Result<(), io::Error> { self.0.flush() } + fn flush(&mut self) -> Result<(), io::Error> { + self.0.flush() + } } impl fmt::Debug for Bytes { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(&self.0.to_hex::()) } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(&self.0.to_hex::()) + } } impl ops::Deref for Bytes { type Target = Vec; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { + &self.0 + } } impl ops::DerefMut for Bytes { - fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } } impl AsRef<[u8]> for Bytes { - fn as_ref(&self) -> &[u8] { &self.0 } + fn as_ref(&self) -> &[u8] { + &self.0 + } } impl AsMut<[u8]> for Bytes { - fn as_mut(&mut self) -> &mut [u8] { &mut self.0 } + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0 + } } /// Wrapper around `Vec` which represent associated type @@ -90,25 +130,35 @@ impl TaggedBytes { } } - pub fn into_raw(self) -> Bytes { self.bytes } + pub fn into_raw(self) -> Bytes { + self.bytes + } } impl ops::Deref for TaggedBytes { type Target = Vec; - fn deref(&self) -> &Self::Target { &self.bytes.0 } + fn deref(&self) -> &Self::Target { + &self.bytes.0 + } } impl ops::DerefMut for TaggedBytes { - fn deref_mut(&mut self) -> &mut Self::Target { &mut self.bytes.0 } + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.bytes.0 + } } impl AsRef<[u8]> for TaggedBytes { - fn as_ref(&self) -> &[u8] { &self.bytes.0 } + fn as_ref(&self) -> &[u8] { + &self.bytes.0 + } } impl AsMut<[u8]> for TaggedBytes { - fn as_mut(&mut self) -> &mut [u8] { &mut self.bytes.0 } + fn as_mut(&mut self) -> &mut [u8] { + &mut self.bytes.0 + } } #[cfg(test)] diff --git a/mm2src/mm2_bitcoin/primitives/src/compact.rs b/mm2src/mm2_bitcoin/primitives/src/compact.rs index dba99c3121..a9ba7e429b 100644 --- a/mm2src/mm2_bitcoin/primitives/src/compact.rs +++ b/mm2src/mm2_bitcoin/primitives/src/compact.rs @@ -7,15 +7,21 @@ use crate::U256; pub struct Compact(u32); impl From for Compact { - fn from(u: u32) -> Self { Compact(u) } + fn from(u: u32) -> Self { + Compact(u) + } } impl From for u32 { - fn from(c: Compact) -> Self { c.0 } + fn from(c: Compact) -> Self { + c.0 + } } impl From for Compact { - fn from(u: U256) -> Self { Compact::from_u256(u) } + fn from(u: U256) -> Self { + Compact::from_u256(u) + } } impl From for U256 { @@ -26,9 +32,13 @@ impl From for U256 { } impl Compact { - pub fn new(u: u32) -> Self { Compact(u) } + pub fn new(u: u32) -> Self { + Compact(u) + } - pub fn max_value() -> Self { U256::max_value().into() } + pub fn max_value() -> Self { + U256::max_value().into() + } #[allow(clippy::wrong_self_convention)] /// Computes the target [0, T] that a blockhash must land in to be valid diff --git a/mm2src/mm2_bitcoin/primitives/src/hash.rs b/mm2src/mm2_bitcoin/primitives/src/hash.rs index 80df5f8531..8c967b89ad 100644 --- a/mm2src/mm2_bitcoin/primitives/src/hash.rs +++ b/mm2src/mm2_bitcoin/primitives/src/hash.rs @@ -13,27 +13,39 @@ macro_rules! impl_hash { pub struct $name([u8; $size]); impl Default for $name { - fn default() -> Self { $name([0u8; $size]) } + fn default() -> Self { + $name([0u8; $size]) + } } impl AsRef<$name> for $name { - fn as_ref(&self) -> &$name { self } + fn as_ref(&self) -> &$name { + self + } } impl AsRef<[u8]> for $name { - fn as_ref(&self) -> &[u8] { &self.0 } + fn as_ref(&self) -> &[u8] { + &self.0 + } } impl Clone for $name { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } impl From<[u8; $size]> for $name { - fn from(h: [u8; $size]) -> Self { $name(h) } + fn from(h: [u8; $size]) -> Self { + $name(h) + } } impl From<$name> for [u8; $size] { - fn from(h: $name) -> Self { h.0 } + fn from(h: $name) -> Self { + h.0 + } } impl<'a> From<&'a [u8; $size]> for $name { @@ -45,7 +57,9 @@ macro_rules! impl_hash { } impl From<&'static str> for $name { - fn from(s: &'static str) -> Self { s.parse().unwrap() } + fn from(s: &'static str) -> Self { + s.parse().unwrap() + } } impl From for $name { @@ -65,21 +79,29 @@ macro_rules! impl_hash { } impl fmt::Debug for $name { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(&self.0.to_hex::()) } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(&self.0.to_hex::()) + } } impl fmt::Display for $name { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(&self.0.to_hex::()) } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(&self.0.to_hex::()) + } } impl ops::Deref for $name { type Target = [u8; $size]; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { + &self.0 + } } impl ops::DerefMut for $name { - fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } } impl cmp::PartialEq for $name { @@ -119,9 +141,13 @@ macro_rules! impl_hash { impl Eq for $name {} impl $name { - pub fn take(self) -> [u8; $size] { self.0 } + pub fn take(self) -> [u8; $size] { + self.0 + } - pub fn as_slice(&self) -> &[u8] { &self.0 } + pub fn as_slice(&self) -> &[u8] { + &self.0 + } pub fn reversed(&self) -> Self { let mut result = self.clone(); @@ -129,9 +155,13 @@ macro_rules! impl_hash { result } - pub fn size() -> usize { $size } + pub fn size() -> usize { + $size + } - pub fn is_zero(&self) -> bool { self.0.iter().all(|b| *b == 0) } + pub fn is_zero(&self) -> bool { + self.0.iter().all(|b| *b == 0) + } /// Preferred method for constructing from a slice - checks length and returns Result pub fn from_slice(slc: &[u8]) -> Result { @@ -163,11 +193,17 @@ impl_hash!(EquihashSolution, 1344); impl H256 { #[inline] - pub fn from_reversed_str(s: &'static str) -> Self { H256::from(s).reversed() } + pub fn from_reversed_str(s: &'static str) -> Self { + H256::from(s).reversed() + } #[inline] - pub fn to_reversed_str(self) -> String { self.reversed().to_string() } + pub fn to_reversed_str(self) -> String { + self.reversed().to_string() + } #[inline] - pub fn to_sha256d(self) -> sha256d::Hash { sha256d::Hash::from_inner(self.take()) } + pub fn to_sha256d(self) -> sha256d::Hash { + sha256d::Hash::from_inner(self.take()) + } } diff --git a/mm2src/mm2_bitcoin/rpc/src/lib.rs b/mm2src/mm2_bitcoin/rpc/src/lib.rs index 70efe15dc7..efe94ce9c7 100644 --- a/mm2src/mm2_bitcoin/rpc/src/lib.rs +++ b/mm2src/mm2_bitcoin/rpc/src/lib.rs @@ -1,9 +1,11 @@ -#[cfg(test)] extern crate lazy_static; +#[cfg(test)] +extern crate lazy_static; extern crate log; extern crate rustc_hex as hex; extern crate serde; extern crate serde_json; -#[macro_use] extern crate serde_derive; +#[macro_use] +extern crate serde_derive; extern crate chain; extern crate keys; extern crate primitives; diff --git a/mm2src/mm2_bitcoin/rpc/src/v1/types/address.rs b/mm2src/mm2_bitcoin/rpc/src/v1/types/address.rs index 5c9f06fd38..076a1994cc 100644 --- a/mm2src/mm2_bitcoin/rpc/src/v1/types/address.rs +++ b/mm2src/mm2_bitcoin/rpc/src/v1/types/address.rs @@ -26,7 +26,9 @@ pub struct AddressVisitor; impl Visitor<'_> for AddressVisitor { type Value = LegacyAddress; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("an address") } + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("an address") + } fn visit_str(self, value: &str) -> Result where @@ -85,7 +87,9 @@ mod tests { } impl TestStruct { - fn new(address: LegacyAddress) -> Self { TestStruct { address } } + fn new(address: LegacyAddress) -> Self { + TestStruct { address } + } } #[test] diff --git a/mm2src/mm2_bitcoin/rpc/src/v1/types/bytes.rs b/mm2src/mm2_bitcoin/rpc/src/v1/types/bytes.rs index 94d5b247ca..65182f4a04 100644 --- a/mm2src/mm2_bitcoin/rpc/src/v1/types/bytes.rs +++ b/mm2src/mm2_bitcoin/rpc/src/v1/types/bytes.rs @@ -12,21 +12,29 @@ pub struct Bytes(pub Vec); impl Bytes { /// Simple constructor. - pub fn new(bytes: Vec) -> Bytes { Bytes(bytes) } + pub fn new(bytes: Vec) -> Bytes { + Bytes(bytes) + } /// Convert back to vector - pub fn into_vec(self) -> Vec { self.0 } + pub fn into_vec(self) -> Vec { + self.0 + } } impl From for Bytes where GlobalBytes: From, { - fn from(other: T) -> Self { Bytes(GlobalBytes::from(other).take()) } + fn from(other: T) -> Self { + Bytes(GlobalBytes::from(other).take()) + } } impl From for Vec { - fn from(bytes: Bytes) -> Self { bytes.0 } + fn from(bytes: Bytes) -> Self { + bytes.0 + } } impl Serialize for Bytes { @@ -54,7 +62,9 @@ struct BytesVisitor; impl Visitor<'_> for BytesVisitor { type Value = Bytes; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a bytes") } + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a bytes") + } fn visit_str(self, value: &str) -> Result where @@ -82,7 +92,9 @@ impl Visitor<'_> for BytesVisitor { impl ops::Deref for Bytes { type Target = Vec; - fn deref(&self) -> &Self::Target { &self.0 } + fn deref(&self) -> &Self::Target { + &self.0 + } } impl ::std::fmt::LowerHex for Bytes { diff --git a/mm2src/mm2_bitcoin/rpc/src/v1/types/hash.rs b/mm2src/mm2_bitcoin/rpc/src/v1/types/hash.rs index 919a7049ab..75bf10cd3f 100644 --- a/mm2src/mm2_bitcoin/rpc/src/v1/types/hash.rs +++ b/mm2src/mm2_bitcoin/rpc/src/v1/types/hash.rs @@ -17,7 +17,9 @@ macro_rules! impl_hash { pub struct $name(pub [u8; $size]); impl $name { - pub const fn const_default() -> $name { $name([0; $size]) } + pub const fn const_default() -> $name { + $name([0; $size]) + } pub fn serialize_to_byte_seq(value: &Self, serializer: S) -> Result where @@ -75,22 +77,30 @@ macro_rules! impl_hash { } impl Default for $name { - fn default() -> Self { $name::const_default() } + fn default() -> Self { + $name::const_default() + } } impl fmt::Display for $name { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, "{:02x}", self) } + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!(f, "{:02x}", self) + } } impl fmt::Debug for $name { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, "{:02x}", self) } + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!(f, "{:02x}", self) + } } impl From for $name where $other: From, { - fn from(o: T) -> Self { $name($other::from(o).take()) } + fn from(o: T) -> Self { + $name($other::from(o).take()) + } } impl FromStr for $name { @@ -104,12 +114,16 @@ macro_rules! impl_hash { #[allow(clippy::from_over_into)] impl Into<$other> for $name { - fn into(self) -> $other { $other::from(self.0) } + fn into(self) -> $other { + $other::from(self.0) + } } #[allow(clippy::from_over_into)] impl Into> for $name { - fn into(self) -> Vec { self.0.to_vec() } + fn into(self) -> Vec { + self.0.to_vec() + } } impl Eq for $name {} @@ -131,7 +145,9 @@ macro_rules! impl_hash { } impl PartialOrd for $name { - fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } } impl Hash for $name { diff --git a/mm2src/mm2_bitcoin/rpc/src/v1/types/mod.rs b/mm2src/mm2_bitcoin/rpc/src/v1/types/mod.rs index c7b16c672c..eb1118bcf3 100644 --- a/mm2src/mm2_bitcoin/rpc/src/v1/types/mod.rs +++ b/mm2src/mm2_bitcoin/rpc/src/v1/types/mod.rs @@ -18,10 +18,11 @@ pub use self::get_tx_out_response::GetTxOutResponse; pub use self::get_tx_out_set_info_response::GetTxOutSetInfoResponse; pub use self::hash::{H160, H256, H264}; pub use self::script::ScriptType; -pub use self::transaction::{GetRawTransactionResponse, RawTransaction, SignedTransactionInput, - SignedTransactionOutput, Transaction, TransactionInput, TransactionInputEnum, - TransactionInputScript, TransactionOutputScript, TransactionOutputWithAddress, - TransactionOutputWithScriptData}; +pub use self::transaction::{ + GetRawTransactionResponse, RawTransaction, SignedTransactionInput, SignedTransactionOutput, Transaction, + TransactionInput, TransactionInputEnum, TransactionInputScript, TransactionOutputScript, + TransactionOutputWithAddress, TransactionOutputWithScriptData, +}; pub use self::uint::U256; pub trait ToTxHash { @@ -29,9 +30,13 @@ pub trait ToTxHash { } impl ToTxHash for Bytes { - fn to_tx_hash(&self) -> String { format!("{:02x}", self) } + fn to_tx_hash(&self) -> String { + format!("{:02x}", self) + } } impl ToTxHash for Vec { - fn to_tx_hash(&self) -> String { Bytes::new(self.clone()).to_tx_hash() } + fn to_tx_hash(&self) -> String { + Bytes::new(self.clone()).to_tx_hash() + } } diff --git a/mm2src/mm2_bitcoin/rpc/src/v1/types/script.rs b/mm2src/mm2_bitcoin/rpc/src/v1/types/script.rs index 4e0eaf4d10..773bd14d15 100644 --- a/mm2src/mm2_bitcoin/rpc/src/v1/types/script.rs +++ b/mm2src/mm2_bitcoin/rpc/src/v1/types/script.rs @@ -87,7 +87,9 @@ impl<'a> Deserialize<'a> for ScriptType { impl Visitor<'_> for ScriptTypeVisitor { type Value = ScriptType; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("script type") } + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("script type") + } fn visit_str(self, value: &str) -> Result where diff --git a/mm2src/mm2_bitcoin/rpc/src/v1/types/transaction.rs b/mm2src/mm2_bitcoin/rpc/src/v1/types/transaction.rs index 0a43c4cbe4..9a9b3d48a5 100644 --- a/mm2src/mm2_bitcoin/rpc/src/v1/types/transaction.rs +++ b/mm2src/mm2_bitcoin/rpc/src/v1/types/transaction.rs @@ -63,7 +63,9 @@ pub struct TransactionOutputScript { } impl TransactionOutputScript { - pub fn is_empty(&self) -> bool { self.asm.is_empty() && self.hex.is_empty() } + pub fn is_empty(&self) -> bool { + self.asm.is_empty() && self.hex.is_empty() + } } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] @@ -113,7 +115,9 @@ pub struct SparkInput { } impl TransactionInputEnum { - pub fn is_coinbase(&self) -> bool { matches!(self, TransactionInputEnum::Coinbase(_)) } + pub fn is_coinbase(&self) -> bool { + matches!(self, TransactionInputEnum::Coinbase(_)) + } } /// Signed transaction input @@ -154,7 +158,9 @@ pub struct SignedTransactionOutput { } impl SignedTransactionOutput { - pub fn is_empty(&self) -> bool { self.value == Some(0.0) && self.script.is_empty() } + pub fn is_empty(&self) -> bool { + self.value == Some(0.0) && self.script.is_empty() + } } fn deserialize_null_default<'de, D, T>(deserializer: D) -> Result @@ -213,7 +219,9 @@ pub struct Transaction { } impl Transaction { - pub fn is_coinbase(&self) -> bool { self.vin.iter().any(|input| input.is_coinbase()) } + pub fn is_coinbase(&self) -> bool { + self.vin.iter().any(|input| input.is_coinbase()) + } } /// Return value of `getrawtransaction` method @@ -253,9 +261,13 @@ mod tests { static ref TRANSACTIONS_MAP: HashMap = parse_transactions(); } - fn parse_transactions() -> HashMap { serde_json::from_str(TRANSACTIONS_STR).unwrap() } + fn parse_transactions() -> HashMap { + serde_json::from_str(TRANSACTIONS_STR).unwrap() + } - fn get_transaction_json(key: &str) -> serde_json::Value { TRANSACTIONS_MAP.get(key).cloned().unwrap() } + fn get_transaction_json(key: &str) -> serde_json::Value { + TRANSACTIONS_MAP.get(key).cloned().unwrap() + } #[test] fn transaction_input_serialize() { diff --git a/mm2src/mm2_bitcoin/rpc/src/v1/types/uint.rs b/mm2src/mm2_bitcoin/rpc/src/v1/types/uint.rs index 5fd7abf4c8..97c12266b9 100644 --- a/mm2src/mm2_bitcoin/rpc/src/v1/types/uint.rs +++ b/mm2src/mm2_bitcoin/rpc/src/v1/types/uint.rs @@ -16,18 +16,24 @@ macro_rules! impl_uint { where $other: From, { - fn from(o: T) -> Self { $name($other::from(o)) } + fn from(o: T) -> Self { + $name($other::from(o)) + } } impl FromStr for $name { type Err = <$other as FromStr>::Err; - fn from_str(s: &str) -> Result { $other::from_str(s).map($name) } + fn from_str(s: &str) -> Result { + $other::from_str(s).map($name) + } } #[allow(clippy::from_over_into)] impl Into<$other> for $name { - fn into(self) -> $other { self.0 } + fn into(self) -> $other { + self.0 + } } impl serde::Serialize for $name { diff --git a/mm2src/mm2_bitcoin/script/src/builder.rs b/mm2src/mm2_bitcoin/script/src/builder.rs index 45153b5f48..537344f036 100644 --- a/mm2src/mm2_bitcoin/script/src/builder.rs +++ b/mm2src/mm2_bitcoin/script/src/builder.rs @@ -86,7 +86,9 @@ impl Builder { } /// Appends num push operation to the end of script - pub fn push_num(self, num: Num) -> Self { self.push_data(&num.to_bytes()) } + pub fn push_num(self, num: Num) -> Self { + self.push_data(&num.to_bytes()) + } /// Appends data push operation to the end of script pub fn push_data(mut self, data: &[u8]) -> Self { @@ -137,8 +139,12 @@ impl Builder { } /// Builds final script - pub fn into_script(self) -> Script { Script::new(self.data) } + pub fn into_script(self) -> Script { + Script::new(self.data) + } /// Builds final script bytes - pub fn into_bytes(self) -> Bytes { self.data } + pub fn into_bytes(self) -> Bytes { + self.data + } } diff --git a/mm2src/mm2_bitcoin/script/src/num.rs b/mm2src/mm2_bitcoin/script/src/num.rs index 5d98826a93..47fbf69b46 100644 --- a/mm2src/mm2_bitcoin/script/src/num.rs +++ b/mm2src/mm2_bitcoin/script/src/num.rs @@ -18,39 +18,57 @@ pub struct Num { } impl From for Num { - fn from(i: bool) -> Self { Num { value: i.into() } } + fn from(i: bool) -> Self { + Num { value: i.into() } + } } impl From for Num { - fn from(i: u8) -> Self { Num { value: i as i64 } } + fn from(i: u8) -> Self { + Num { value: i as i64 } + } } impl From for Num { - fn from(i: u32) -> Self { Num { value: i as i64 } } + fn from(i: u32) -> Self { + Num { value: i as i64 } + } } impl From for Num { - fn from(i: usize) -> Self { Num { value: i as i64 } } + fn from(i: usize) -> Self { + Num { value: i as i64 } + } } impl From for Num { - fn from(i: i32) -> Self { Num { value: i as i64 } } + fn from(i: i32) -> Self { + Num { value: i as i64 } + } } impl From for Num { - fn from(i: i64) -> Self { Num { value: i } } + fn from(i: i64) -> Self { + Num { value: i } + } } impl From for i64 { - fn from(n: Num) -> Self { n.value } + fn from(n: Num) -> Self { + n.value + } } impl From for u32 { - fn from(n: Num) -> Self { n.value as u32 } + fn from(n: Num) -> Self { + n.value as u32 + } } impl From for usize { - fn from(n: Num) -> Self { n.value as usize } + fn from(n: Num) -> Self { + n.value as usize + } } impl Num { @@ -177,9 +195,13 @@ impl Num { result.into() } - pub fn is_negative(&self) -> bool { self.value < 0 } + pub fn is_negative(&self) -> bool { + self.value < 0 + } - pub fn is_zero(&self) -> bool { self.value == 0 } + pub fn is_zero(&self) -> bool { + self.value == 0 + } pub fn abs(&self) -> Num { if self.value < 0 { @@ -193,35 +215,47 @@ impl Num { impl ops::BitAnd for Num { type Output = Self; - fn bitand(self, rhs: Self) -> Self::Output { (self.value & rhs.value).into() } + fn bitand(self, rhs: Self) -> Self::Output { + (self.value & rhs.value).into() + } } impl ops::Add for Num { type Output = Self; - fn add(self, rhs: Self) -> Self::Output { (self.value + rhs.value).into() } + fn add(self, rhs: Self) -> Self::Output { + (self.value + rhs.value).into() + } } impl ops::Sub for Num { type Output = Self; - fn sub(self, rhs: Self) -> Self::Output { (self.value - rhs.value).into() } + fn sub(self, rhs: Self) -> Self::Output { + (self.value - rhs.value).into() + } } impl ops::Neg for Num { type Output = Self; - fn neg(self) -> Self::Output { (-self.value).into() } + fn neg(self) -> Self::Output { + (-self.value).into() + } } impl ops::Div for Num { type Output = Self; - fn div(self, rhs: Self) -> Self::Output { (self.value / rhs.value).into() } + fn div(self, rhs: Self) -> Self::Output { + (self.value / rhs.value).into() + } } impl ops::Rem for Num { type Output = Self; - fn rem(self, rhs: Self) -> Self::Output { (self.value % rhs.value).into() } + fn rem(self, rhs: Self) -> Self::Output { + (self.value % rhs.value).into() + } } diff --git a/mm2src/mm2_bitcoin/script/src/opcode.rs b/mm2src/mm2_bitcoin/script/src/opcode.rs index 7633899668..cda77b33ad 100644 --- a/mm2src/mm2_bitcoin/script/src/opcode.rs +++ b/mm2src/mm2_bitcoin/script/src/opcode.rs @@ -223,7 +223,9 @@ pub enum Opcode { } impl fmt::Display for Opcode { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(self, f) } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(self, f) + } } impl Opcode { @@ -463,13 +465,21 @@ impl Opcode { } /// Returns true if opcode is countable - pub fn is_countable(&self) -> bool { *self > Opcode::OP_16 } + pub fn is_countable(&self) -> bool { + *self > Opcode::OP_16 + } - pub fn is_simple_push(&self) -> bool { *self < Opcode::OP_PUSHDATA1 } + pub fn is_simple_push(&self) -> bool { + *self < Opcode::OP_PUSHDATA1 + } - pub fn is_push_value(&self) -> bool { *self >= Opcode::OP_1NEGATE && *self <= Opcode::OP_16 } + pub fn is_push_value(&self) -> bool { + *self >= Opcode::OP_1NEGATE && *self <= Opcode::OP_16 + } - pub fn is_within_op_n(&self) -> bool { *self >= Opcode::OP_1 && *self <= Opcode::OP_16 } + pub fn is_within_op_n(&self) -> bool { + *self >= Opcode::OP_1 && *self <= Opcode::OP_16 + } pub fn decode_op_n(&self) -> u8 { assert!(self.is_within_op_n()); diff --git a/mm2src/mm2_bitcoin/script/src/script.rs b/mm2src/mm2_bitcoin/script/src/script.rs index 33300a7324..99fb22b80c 100644 --- a/mm2src/mm2_bitcoin/script/src/script.rs +++ b/mm2src/mm2_bitcoin/script/src/script.rs @@ -81,31 +81,47 @@ pub struct Script { } impl From<&'static str> for Script { - fn from(s: &'static str) -> Self { Script::new(s.into()) } + fn from(s: &'static str) -> Self { + Script::new(s.into()) + } } impl From for Script { - fn from(s: Bytes) -> Self { Script::new(s) } + fn from(s: Bytes) -> Self { + Script::new(s) + } } impl From> for Script { - fn from(v: Vec) -> Self { Script::new(v.into()) } + fn from(v: Vec) -> Self { + Script::new(v.into()) + } } impl From