Skip to content

Commit cacf073

Browse files
committed
merge with dev
2 parents 66bbb1d + 9ea63ec commit cacf073

31 files changed

+590
-270
lines changed

.github/workflows/fmt-and-lint.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818

1919
- name: Install toolchain
2020
run: |
21-
rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal --component rustfmt clippy
21+
rustup toolchain install nightly-2023-06-01 --no-self-update --profile=minimal --component rustfmt,clippy
2222
rustup default nightly-2023-06-01
2323
2424
- name: Install build deps

mm2src/coins/coin_balance.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::hd_wallet::{HDAccountOps, HDAddressId, HDAddressOps, HDCoinAddress, HDCoinHDAccount,
1+
use crate::hd_wallet::{DisplayAddress, HDAccountOps, HDAddressId, HDAddressOps, HDCoinAddress, HDCoinHDAccount,
22
HDPathAccountToAddressId, HDWalletCoinOps, HDWalletOps, HDXPubExtractor,
33
NewAccountCreationError, NewAddressDerivingError};
44
use crate::{BalanceError, BalanceResult, CoinBalance, CoinBalanceMap, CoinWithDerivationMethod, DerivationMethod,
@@ -238,7 +238,7 @@ where
238238
.await
239239
.map(|balance| {
240240
CoinBalanceReport::Iguana(IguanaWalletBalance {
241-
address: self.address_formatter()(my_address),
241+
address: my_address.display_address(),
242242
balance,
243243
})
244244
})
@@ -351,7 +351,7 @@ pub trait HDWalletBalanceOps: HDWalletCoinOps {
351351
// So we can zip the derivation paths with the pairs `(Address, CoinBalance)`.
352352
.zip(der_paths)
353353
.map(|((address, balance), derivation_path)| HDAddressBalance {
354-
address: self.address_formatter()(&address),
354+
address: address.display_address(),
355355
derivation_path: RpcDerivationPath(derivation_path),
356356
chain,
357357
balance,
@@ -411,8 +411,8 @@ pub enum AddressBalanceStatus<Balance> {
411411

412412
pub mod common_impl {
413413
use super::*;
414-
use crate::hd_wallet::{create_new_account, ExtractExtendedPubkey, HDAccountOps, HDAccountStorageOps, HDAddressOps,
415-
HDCoinExtendedPubkey, HDWalletOps};
414+
use crate::hd_wallet::{create_new_account, DisplayAddress, ExtractExtendedPubkey, HDAccountOps,
415+
HDAccountStorageOps, HDAddressOps, HDCoinExtendedPubkey, HDWalletOps};
416416

417417
pub(crate) async fn enable_hd_account<Coin>(
418418
coin: &Coin,
@@ -579,7 +579,7 @@ pub mod common_impl {
579579
let hd_address = coin.generate_new_address(hd_wallet, hd_account, chain).await?;
580580

581581
new_addresses.push(HDAddressBalance {
582-
address: coin.address_formatter()(&hd_address.address()),
582+
address: hd_address.address().display_address(),
583583
derivation_path: RpcDerivationPath(hd_address.derivation_path().clone()),
584584
chain,
585585
balance: HDWalletBalanceObject::<Coin>::new(),

mm2src/coins/eth.rs

+24-25
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ use crate::coin_balance::{EnableCoinBalanceError, EnabledCoinBalanceParams, HDAc
2828
HDWalletBalance, HDWalletBalanceOps};
2929
use crate::eth::eth_rpc::ETH_RPC_REQUEST_TIMEOUT;
3030
use crate::eth::web3_transport::websocket_transport::{WebsocketTransport, WebsocketTransportNode};
31-
use crate::hd_wallet::{HDAccountOps, HDCoinAddress, HDCoinWithdrawOps, HDConfirmAddress, HDPathAccountToAddressId,
32-
HDWalletCoinOps, HDXPubExtractor};
31+
use crate::hd_wallet::{DisplayAddress, HDAccountOps, HDCoinAddress, HDCoinWithdrawOps, HDConfirmAddress,
32+
HDPathAccountToAddressId, HDWalletCoinOps, HDXPubExtractor};
3333
use crate::lp_price::get_base_price_in_rel;
3434
use crate::nft::nft_errors::ParseContractTypeError;
3535
use crate::nft::nft_structs::{ContractType, ConvertChain, NftInfo, TransactionNftDetails, WithdrawErc1155,
@@ -1204,8 +1204,8 @@ pub async fn withdraw_erc721(ctx: MmArc, withdraw_type: WithdrawErc721) -> Withd
12041204
let my_address = eth_coin.derivation_method.single_addr_or_err().await?;
12051205
if token_owner != my_address {
12061206
return MmError::err(WithdrawError::MyAddressNotNftOwner {
1207-
my_address: eth_addr_to_hex(&my_address),
1208-
token_owner: eth_addr_to_hex(&token_owner),
1207+
my_address: my_address.display_address(),
1208+
token_owner: token_owner.display_address(),
12091209
});
12101210
}
12111211

@@ -2296,7 +2296,7 @@ impl MarketCoinOps for EthCoin {
22962296

22972297
fn my_address(&self) -> MmResult<String, MyAddressError> {
22982298
match self.derivation_method() {
2299-
DerivationMethod::SingleAddress(my_address) => Ok(display_eth_address(my_address)),
2299+
DerivationMethod::SingleAddress(my_address) => Ok(my_address.display_address()),
23002300
DerivationMethod::HDWallet(_) => MmError::err(MyAddressError::UnexpectedDerivationMethod(
23012301
"'my_address' is deprecated for HD wallets".to_string(),
23022302
)),
@@ -3331,8 +3331,8 @@ impl EthCoin {
33313331
spent_by_me,
33323332
received_by_me,
33333333
total_amount,
3334-
to: vec![display_eth_address(&call_data.to)],
3335-
from: vec![display_eth_address(&call_data.from)],
3334+
to: vec![call_data.to.display_address()],
3335+
from: vec![call_data.from.display_address()],
33363336
coin: self.ticker.clone(),
33373337
fee_details: fee_details.map(|d| d.into()),
33383338
block_height: trace.block_number,
@@ -3711,8 +3711,8 @@ impl EthCoin {
37113711
spent_by_me,
37123712
received_by_me,
37133713
total_amount,
3714-
to: vec![display_eth_address(&to_addr)],
3715-
from: vec![display_eth_address(&from_addr)],
3714+
to: vec![to_addr.display_address()],
3715+
from: vec![from_addr.display_address()],
37163716
coin: self.ticker.clone(),
37173717
fee_details: fee_details.map(|d| d.into()),
37183718
block_height: block_number.as_u64(),
@@ -6625,16 +6625,12 @@ pub fn checksum_address(addr: &str) -> String {
66256625

66266626
/// `eth_addr_to_hex` converts Address to hex format.
66276627
/// Note: the result will be in lowercase.
6628-
pub fn eth_addr_to_hex(address: &Address) -> String { format!("{:#02x}", address) }
6628+
fn eth_addr_to_hex(address: &Address) -> String { format!("{:#x}", address) }
66296629

66306630
/// Checks that input is valid mixed-case checksum form address
66316631
/// The input must be 0x prefixed hex string
66326632
fn is_valid_checksum_addr(addr: &str) -> bool { addr == checksum_address(addr) }
66336633

6634-
/// `display_eth_address` converts Address to mixed-case checksum form.
6635-
#[inline]
6636-
pub fn display_eth_address(addr: &Address) -> String { checksum_address(&eth_addr_to_hex(addr)) }
6637-
66386634
fn increase_by_percent_one_gwei(num: U256, percent: u64) -> U256 {
66396635
let one_gwei = U256::from(10u64.pow(9));
66406636
let percent = (num / U256::from(100)) * U256::from(percent);
@@ -6720,7 +6716,7 @@ pub async fn get_eth_address(
67206716

67216717
Ok(MyWalletAddress {
67226718
coin: ticker.to_owned(),
6723-
wallet_address: display_eth_address(&my_address),
6719+
wallet_address: my_address.display_address(),
67246720
})
67256721
}
67266722

@@ -7304,31 +7300,34 @@ impl TakerCoinSwapOpsV2 for EthCoin {
73047300
self.refund_taker_payment_with_timelock_impl(args).await
73057301
}
73067302

7307-
/// Eth doesnt have preimages
7303+
fn skip_taker_payment_spend_preimage(&self) -> bool { true }
7304+
7305+
/// Eth skips taker_payment_spend_preimage, as it doesnt need it
73087306
async fn gen_taker_payment_spend_preimage(
73097307
&self,
7310-
args: &GenTakerPaymentSpendArgs<'_, Self>,
7308+
_args: &GenTakerPaymentSpendArgs<'_, Self>,
73117309
_swap_unique_data: &[u8],
73127310
) -> GenPreimageResult<Self> {
7313-
Ok(TxPreimageWithSig {
7314-
preimage: args.taker_tx.clone(),
7315-
signature: args.taker_tx.signature(),
7316-
})
7311+
MmError::err(TxGenError::Other(
7312+
"EVM-based coin doesn't have taker_payment_spend_preimage. Report the Bug!".to_string(),
7313+
))
73177314
}
73187315

7319-
/// Eth doesnt have preimages
7316+
/// Eth skips taker_payment_spend_preimage, as it doesnt need it
73207317
async fn validate_taker_payment_spend_preimage(
73217318
&self,
73227319
_gen_args: &GenTakerPaymentSpendArgs<'_, Self>,
73237320
_preimage: &TxPreimageWithSig<Self>,
73247321
) -> ValidateTakerPaymentSpendPreimageResult {
7325-
Ok(())
7322+
MmError::err(ValidateTakerPaymentSpendPreimageError::InvalidPreimage(
7323+
"EVM-based coin skips taker_payment_spend_preimage validation. Report the Bug!".to_string(),
7324+
))
73267325
}
73277326

7328-
/// Wrapper for [EthCoin::sign_and_broadcast_taker_payment_spend_impl]
7327+
/// Eth doesnt have preimages
73297328
async fn sign_and_broadcast_taker_payment_spend(
73307329
&self,
7331-
_preimage: &TxPreimageWithSig<Self>,
7330+
_preimage: Option<&TxPreimageWithSig<Self>>,
73327331
gen_args: &GenTakerPaymentSpendArgs<'_, Self>,
73337332
secret: &[u8],
73347333
_swap_unique_data: &[u8],

mm2src/coins/eth/eth_hd_wallet.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ pub type EthHDAddress = HDAddress<Address, Public>;
1111
pub type EthHDAccount = HDAccount<EthHDAddress, Secp256k1ExtendedPublicKey>;
1212
pub type EthHDWallet = HDWallet<EthHDAccount>;
1313

14+
impl DisplayAddress for Address {
15+
/// converts `Address` to mixed-case checksum form.
16+
#[inline]
17+
fn display_address(&self) -> String { checksum_address(&self.addr_to_string()) }
18+
}
19+
1420
#[async_trait]
1521
impl ExtractExtendedPubkey for EthCoin {
1622
type ExtendedPublicKey = Secp256k1ExtendedPublicKey;
@@ -31,8 +37,6 @@ impl ExtractExtendedPubkey for EthCoin {
3137
impl HDWalletCoinOps for EthCoin {
3238
type HDWallet = EthHDWallet;
3339

34-
fn address_formatter(&self) -> fn(&Address) -> String { display_eth_address }
35-
3640
fn address_from_extended_pubkey(
3741
&self,
3842
extended_pubkey: &Secp256k1ExtendedPublicKey,

mm2src/coins/eth/v2_activation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ impl EthCoin {
413413
return MmError::err(EthTokenActivationError::CustomTokenError(
414414
CustomTokenError::TokenWithSameContractAlreadyActivated {
415415
ticker: token.ticker().to_string(),
416-
contract_address: display_eth_address(&protocol.token_addr),
416+
contract_address: protocol.token_addr.display_address(),
417417
},
418418
));
419419
},

mm2src/coins/hd_wallet/address_ops.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,29 @@
11
use bip32::DerivationPath;
2-
use std::fmt::Display;
32
use std::hash::Hash;
43

4+
/// A trait for converting an address into a string suitable for display in logs, errors, or messages.
5+
pub trait DisplayAddress {
6+
fn display_address(&self) -> String;
7+
}
8+
9+
/// Should convert coin `Self::Address` type into a properly formatted string representation.
10+
///
11+
/// Don't use `to_string` directly on `Self::Address` types in generic TPU code!
12+
/// It may produce abbreviated or non-standard formats (e.g. `ethereum_types::Address` will be like this `0x7cc9…3874`),
13+
/// which are not guaranteed to be parsable back into the original `Address` type.
14+
/// This function should ensure the resulting string is consistently formatted and fully reversible.
15+
pub trait AddrToString {
16+
fn addr_to_string(&self) -> String;
17+
}
18+
519
/// `HDAddressOps` Trait
620
///
721
/// Defines operations associated with an HD (Hierarchical Deterministic) address.
822
/// In the context of BIP-44 derivation paths, an HD address corresponds to the fifth level (`address_index`)
923
/// in the structure `m / purpose' / coin_type' / account' / chain (or change) / address_index`.
1024
/// This allows for managing individual addresses within a specific account and chain.
1125
pub trait HDAddressOps {
12-
type Address: Clone + Display + Eq + Hash + Send + Sync;
26+
type Address: Clone + DisplayAddress + Eq + Hash + Send + Sync;
1327
type Pubkey: Clone;
1428

1529
fn address(&self) -> Self::Address;

mm2src/coins/hd_wallet/coin_ops.rs

+3-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use super::{inner_impl, AccountUpdatingError, AddressDerivingError, ExtendedPublicKeyOps, HDAccountOps, HDCoinAddress,
2-
HDCoinExtendedPubkey, HDCoinHDAccount, HDCoinHDAddress, HDConfirmAddress, HDWalletOps,
1+
use super::{inner_impl, AccountUpdatingError, AddressDerivingError, DisplayAddress, ExtendedPublicKeyOps,
2+
HDAccountOps, HDCoinExtendedPubkey, HDCoinHDAccount, HDCoinHDAddress, HDConfirmAddress, HDWalletOps,
33
NewAddressDeriveConfirmError, NewAddressDerivingError};
44
use crate::hd_wallet::{HDAddressOps, HDWalletStorageOps, TrezorCoinError};
55
use async_trait::async_trait;
@@ -25,13 +25,6 @@ pub trait HDWalletCoinOps {
2525
/// Any type that represents a Hierarchical Deterministic (HD) wallet.
2626
type HDWallet: HDWalletOps + HDWalletStorageOps + Send + Sync;
2727

28-
/// Returns a formatter function for address representation.
29-
/// Useful when an address has multiple display formats.
30-
/// For example, Ethereum addresses can be fully displayed or truncated.
31-
/// By default, the formatter uses the Display trait of the address type, which truncates Ethereum addresses.
32-
/// Implement this function if a different display format is required.
33-
fn address_formatter(&self) -> fn(&HDCoinAddress<Self>) -> String { |address| address.to_string() }
34-
3528
/// Derives an address for the coin that implements this trait from an extended public key and a derivation path.
3629
fn address_from_extended_pubkey(
3730
&self,
@@ -189,7 +182,7 @@ pub trait HDWalletCoinOps {
189182

190183
let trezor_coin = self.trezor_coin()?;
191184
let derivation_path = hd_address.derivation_path().clone();
192-
let expected_address = hd_address.address().to_string();
185+
let expected_address = hd_address.address().display_address();
193186
// Ask the user to confirm if the given `expected_address` is the same as on the HW display.
194187
confirm_address
195188
.confirm_address(trezor_coin, derivation_path, expected_address)

mm2src/coins/hd_wallet/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ mod account_ops;
1616
pub use account_ops::HDAccountOps;
1717

1818
mod address_ops;
19-
pub use address_ops::HDAddressOps;
19+
pub use address_ops::{AddrToString, DisplayAddress, HDAddressOps};
2020

2121
mod coin_ops;
2222
pub use coin_ops::{HDAddressId, HDWalletCoinOps};
@@ -78,7 +78,7 @@ pub struct HDAddress<Address, Pubkey> {
7878

7979
impl<Address, Pubkey> HDAddressOps for HDAddress<Address, Pubkey>
8080
where
81-
Address: Clone + Display + Eq + Hash + Send + Sync,
81+
Address: Clone + DisplayAddress + Eq + Hash + Send + Sync,
8282
Pubkey: Clone,
8383
{
8484
type Address = Address;

mm2src/coins/hd_wallet/withdraw_ops.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{HDPathAccountToAddressId, HDWalletOps, HDWithdrawError};
1+
use super::{DisplayAddress, HDPathAccountToAddressId, HDWalletOps, HDWithdrawError};
22
use crate::hd_wallet::{HDAccountOps, HDAddressOps, HDCoinAddress, HDWalletCoinOps};
33
use async_trait::async_trait;
44
use bip32::DerivationPath;
@@ -82,7 +82,7 @@ pub trait HDCoinWithdrawOps: HDWalletCoinOps {
8282
let hd_address = self.derive_address(&hd_account, chain, address_id).await?;
8383
let address = hd_address.address();
8484
if !is_address_activated {
85-
let error = format!("'{}' address is not activated", address);
85+
let error = format!("'{}' address is not activated", address.display_address());
8686
return MmError::err(HDWithdrawError::UnexpectedFromAddress(error));
8787
}
8888

mm2src/coins/lp_coins.rs

+11-15
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ use script::Script;
273273

274274
pub mod z_coin;
275275
use crate::coin_balance::{BalanceObjectOps, HDWalletBalanceObject};
276+
use crate::hd_wallet::{AddrToString, DisplayAddress};
276277
use z_coin::{ZCoin, ZcoinProtocolInfo};
277278

278279
pub type TransactionFut = Box<dyn Future<Item = TransactionEnum, Error = TransactionErr> + Send>;
@@ -1599,16 +1600,6 @@ pub trait ToBytes {
15991600
fn to_bytes(&self) -> Vec<u8>;
16001601
}
16011602

1602-
/// Should convert coin `Self::Address` type into a properly formatted string representation.
1603-
///
1604-
/// Don't use `to_string` directly on `Self::Address` types in generic TPU code!
1605-
/// It may produce abbreviated or non-standard formats (e.g. `ethereum_types::Address` will be like this `0x7cc9…3874`),
1606-
/// which are not guaranteed to be parsable back into the original `Address` type.
1607-
/// This function should ensure the resulting string is consistently formatted and fully reversible.
1608-
pub trait AddrToString {
1609-
fn addr_to_string(&self) -> String;
1610-
}
1611-
16121603
/// Defines associated types specific to each coin (Pubkey, Address, etc.)
16131604
#[async_trait]
16141605
pub trait ParseCoinAssocTypes {
@@ -2010,6 +2001,11 @@ pub trait TakerCoinSwapOpsV2: ParseCoinAssocTypes + CommonSwapOpsV2 + Send + Syn
20102001
async fn refund_combined_taker_payment(&self, args: RefundTakerPaymentArgs<'_>)
20112002
-> Result<Self::Tx, TransactionErr>;
20122003

2004+
/// A bool flag that allows skipping the generation and P2P message broadcasting of `TakerPaymentSpendPreimage` on the Taker side,
2005+
/// as well as its reception and validation on the Maker side.
2006+
/// This is typically used for coins that rely on smart contracts.
2007+
fn skip_taker_payment_spend_preimage(&self) -> bool { false }
2008+
20132009
/// Generates and signs taker payment spend preimage. The preimage and signature should be
20142010
/// shared with maker to proceed with protocol execution.
20152011
async fn gen_taker_payment_spend_preimage(
@@ -2028,7 +2024,7 @@ pub trait TakerCoinSwapOpsV2: ParseCoinAssocTypes + CommonSwapOpsV2 + Send + Syn
20282024
/// Sign and broadcast taker payment spend on maker's side.
20292025
async fn sign_and_broadcast_taker_payment_spend(
20302026
&self,
2031-
preimage: &TxPreimageWithSig<Self>,
2027+
preimage: Option<&TxPreimageWithSig<Self>>,
20322028
gen_args: &GenTakerPaymentSpendArgs<'_, Self>,
20332029
secret: &[u8],
20342030
swap_unique_data: &[u8],
@@ -5003,7 +4999,7 @@ pub async fn delegations_info(ctx: MmArc, req: DelegationsInfo) -> Result<Json,
50034999
DelegationsInfoDetails::Qtum => {
50045000
let MmCoinEnum::QtumCoin(qtum) = coin else {
50055001
return MmError::err(StakingInfoError::InvalidPayload {
5006-
reason: format!("{} is not a Qtum coin", req.coin)
5002+
reason: format!("{} is not a Qtum coin", req.coin),
50075003
});
50085004
};
50095005

@@ -5054,7 +5050,7 @@ pub async fn claim_staking_rewards(ctx: MmArc, req: ClaimStakingRewardsRequest)
50545050

50555051
let MmCoinEnum::Tendermint(tendermint) = coin else {
50565052
return MmError::err(DelegationError::InvalidPayload {
5057-
reason: format!("{} is not a Cosmos coin", req.coin)
5053+
reason: format!("{} is not a Cosmos coin", req.coin),
50585054
});
50595055
};
50605056

@@ -5749,7 +5745,7 @@ where
57495745
.await?
57505746
.into_iter()
57515747
.map(|empty_address| HDAddressBalance {
5752-
address: coin.address_formatter()(&empty_address.address()),
5748+
address: empty_address.address().display_address(),
57535749
derivation_path: RpcDerivationPath(empty_address.derivation_path().clone()),
57545750
chain,
57555751
balance: HDWalletBalanceObject::<T>::new(),
@@ -5758,7 +5754,7 @@ where
57585754

57595755
// Then push this non-empty address.
57605756
balances.push(HDAddressBalance {
5761-
address: coin.address_formatter()(&checking_address),
5757+
address: checking_address.display_address(),
57625758
derivation_path: RpcDerivationPath(checking_address_der_path.clone()),
57635759
chain,
57645760
balance: non_empty_balance,

0 commit comments

Comments
 (0)