From 3a56430b21e992bbf9b3184336fa79e956f634cd Mon Sep 17 00:00:00 2001 From: dimxy Date: Thu, 10 Oct 2024 23:25:00 +0500 Subject: [PATCH] fix overriding eth gas config params with token config (needed for tests) --- mm2src/coins/eth.rs | 91 +++++++++++++++---------------- mm2src/coins/eth/for_tests.rs | 6 +- mm2src/coins/eth/v2_activation.rs | 22 +++++--- 3 files changed, 61 insertions(+), 58 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 996901ffba..f8f96368a8 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -250,7 +250,7 @@ pub mod gas_limit { } /// Coin conf param to override default gas limits -#[derive(Clone, Deserialize)] +#[derive(Clone, Deserialize, PartialEq)] #[serde(default)] pub struct EthGasLimit { /// Gas limit for sending coins @@ -634,7 +634,7 @@ pub struct EthCoinImpl { history_sync_state: Mutex, required_confirmations: AtomicU64, swap_txfee_policy: Mutex, - max_eth_tx_type: Option, + max_eth_tx_type: u64, /// Coin needs access to the context in order to reuse the logging and shutdown facilities. /// Using a weak reference by default in order to avoid circular references and leaks. pub ctx: MmWeak, @@ -3564,7 +3564,7 @@ impl EthCoin { TxType::Type2 => 2_u64, TxType::Invalid => return false, }; - let max_tx_type = self.max_eth_tx_type.unwrap_or(0_u64); + let max_tx_type = self.max_eth_tx_type; tx_type_as_num <= max_tx_type } @@ -6101,36 +6101,17 @@ fn rpc_event_handlers_for_eth_transport(ctx: &MmArc, ticker: String) -> Vec Result, String> { - fn check_max_eth_tx_type_conf(conf: &Json) -> Result, String> { - if !conf["max_eth_tx_type"].is_null() { - let max_eth_tx_type = conf["max_eth_tx_type"] - .as_u64() - .ok_or_else(|| "max_eth_tx_type in coins is invalid".to_string())?; - if max_eth_tx_type > ETH_MAX_TX_TYPE { - return Err("max_eth_tx_type in coins is too big".to_string()); - } - Ok(Some(max_eth_tx_type)) - } else { - Ok(None) +async fn get_max_eth_tx_type_conf(conf: &Json) -> Result, String> { + if !conf["max_eth_tx_type"].is_null() { + let max_eth_tx_type = conf["max_eth_tx_type"] + .as_u64() + .ok_or_else(|| "max_eth_tx_type in coins is invalid".to_string())?; + if max_eth_tx_type > ETH_MAX_TX_TYPE { + return Err("max_eth_tx_type in coins is too big".to_string()); } - } - - match &coin_type { - EthCoinType::Eth => check_max_eth_tx_type_conf(conf), - EthCoinType::Erc20 { platform, .. } | EthCoinType::Nft { platform } => { - let coin_max_eth_tx_type = check_max_eth_tx_type_conf(conf)?; - // Normally we suppose max_eth_tx_type is in platform coin but also try to get it from tokens for tests to work: - if let Some(coin_max_eth_tx_type) = coin_max_eth_tx_type { - Ok(Some(coin_max_eth_tx_type)) - } else { - let platform_coin = lp_coinfind_or_err(ctx, platform).await; - match platform_coin { - Ok(MmCoinEnum::EthCoin(eth_coin)) => Ok(eth_coin.max_eth_tx_type), - _ => Ok(None), - } - } - }, + Ok(Some(max_eth_tx_type)) + } else { + Ok(None) } } @@ -6308,17 +6289,27 @@ pub async fn eth_coin_from_conf_and_request( // This is a deprecated method to activate tokens this way. We should eth_coin_from_conf_and_request_v2 instead let (max_eth_tx_type, gas_limit, gas_fee_estimator) = match &coin_type { EthCoinType::Eth => ( - get_max_eth_tx_type_conf(ctx, conf, &coin_type).await?, - extract_gas_limit_from_conf(conf)?, - extract_gas_fee_estimator_from_value(req)?, + get_max_eth_tx_type_conf(conf).await?.unwrap_or_default(), + extract_gas_limit_from_conf(conf)?.unwrap_or_default(), + extract_gas_fee_estimator_from_value(req)?.unwrap_or_default(), ), - EthCoinType::Erc20 { platform, .. } | EthCoinType::Nft { platform } => match lp_coinfind(ctx, platform).await { - Ok(Some(MmCoinEnum::EthCoin(platform_coin))) => ( - platform_coin.max_eth_tx_type, - platform_coin.gas_limit.clone(), - platform_coin.gas_fee_estimator.clone(), - ), - _ => (Default::default(), Default::default(), Default::default()), + EthCoinType::Erc20 { platform, .. } | EthCoinType::Nft { platform } => { + let max_eth_tx_type = get_max_eth_tx_type_conf(conf).await?; + let gas_limit = extract_gas_limit_from_conf(conf)?; + let gas_fee_estimator = extract_gas_fee_estimator_from_value(req)?; + match lp_coinfind(ctx, platform).await { + Ok(Some(MmCoinEnum::EthCoin(platform_coin))) => ( + // use platform coins settings if token does not have explicit settings + max_eth_tx_type.unwrap_or(platform_coin.max_eth_tx_type), + gas_limit.unwrap_or(platform_coin.gas_limit.clone()), + gas_fee_estimator.unwrap_or(platform_coin.gas_fee_estimator.clone()), + ), + _ => ( + max_eth_tx_type.unwrap_or_default(), + gas_limit.unwrap_or_default(), + gas_fee_estimator.unwrap_or_default(), + ), + } }, }; @@ -6969,19 +6960,23 @@ pub fn pubkey_from_extended(extended_pubkey: &Secp256k1ExtendedPublicKey) -> Pub pubkey_uncompressed } -fn extract_gas_limit_from_conf(coin_conf: &Json) -> Result { +fn extract_gas_limit_from_conf(coin_conf: &Json) -> Result, String> { if coin_conf["gas_limit"].is_null() { - Ok(Default::default()) + Ok(None) } else { - json::from_value(coin_conf["gas_limit"].clone()).map_err(|e| e.to_string()) + json::from_value(coin_conf["gas_limit"].clone()) + .map_err(|e| e.to_string()) + .map(Some) } } -fn extract_gas_fee_estimator_from_value(value: &Json) -> Result { +fn extract_gas_fee_estimator_from_value(value: &Json) -> Result, String> { if value["gas_fee_estimator"].is_null() { - Ok(Default::default()) + Ok(None) } else { - json::from_value(value["gas_fee_estimator"].clone()).map_err(|e| e.to_string()) + json::from_value(value["gas_fee_estimator"].clone()) + .map_err(|e| e.to_string()) + .map(Some) } } diff --git a/mm2src/coins/eth/for_tests.rs b/mm2src/coins/eth/for_tests.rs index ec30bd510a..4cce7c1f29 100644 --- a/mm2src/coins/eth/for_tests.rs +++ b/mm2src/coins/eth/for_tests.rs @@ -50,7 +50,9 @@ pub(crate) fn eth_coin_from_keypair( }; let my_address = key_pair.address(); let coin_conf = coin_conf(&ctx, &ticker); - let gas_limit = extract_gas_limit_from_conf(&coin_conf).expect("expected valid gas_limit config"); + let gas_limit = extract_gas_limit_from_conf(&coin_conf) + .expect("expected valid gas_limit config") + .unwrap_or_default(); let eth_coin = EthCoin(Arc::new(EthCoinImpl { coin_type, @@ -73,7 +75,7 @@ pub(crate) fn eth_coin_from_keypair( trezor_coin: None, logs_block_range: DEFAULT_LOGS_BLOCK_RANGE, address_nonce_locks: Arc::new(AsyncMutex::new(new_nonce_lock())), - max_eth_tx_type: None, + max_eth_tx_type: 0, erc20_tokens_infos: Default::default(), nfts_infos: Arc::new(Default::default()), gas_limit, diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 4b138d369d..a4f778a131 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -417,9 +417,12 @@ impl EthCoin { platform: protocol.platform, token_addr: protocol.token_addr, }; - let max_eth_tx_type = get_max_eth_tx_type_conf(&ctx, &conf, &coin_type).await?; + + // allow token params to override platform coin setting + let max_eth_tx_type = get_max_eth_tx_type_conf(&conf).await?.unwrap_or(self.max_eth_tx_type); let gas_limit = extract_gas_limit_from_conf(&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)))? + .unwrap_or(self.gas_limit.clone()); let token = EthCoinImpl { priv_key_policy: self.priv_key_policy.clone(), @@ -505,9 +508,12 @@ impl EthCoin { let coin_type = EthCoinType::Nft { platform: self.ticker.clone(), }; - let max_eth_tx_type = get_max_eth_tx_type_conf(&ctx, &conf, &coin_type).await?; + + // allow token params to override platform coin setting + let max_eth_tx_type = get_max_eth_tx_type_conf(&conf).await?.unwrap_or(self.max_eth_tx_type); let gas_limit = extract_gas_limit_from_conf(&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)))? + .unwrap_or(self.gas_limit.clone()); let global_nft = EthCoinImpl { ticker, @@ -636,15 +642,15 @@ pub async fn eth_coin_from_conf_and_request_v2( // Create an abortable system linked to the `MmCtx` so if the app is stopped on `MmArc::stop`, // all spawned futures related to `ETH` coin will be aborted as well. let abortable_system = ctx.abortable_system.create_subsystem()?; - let coin_type = EthCoinType::Eth; - let max_eth_tx_type = get_max_eth_tx_type_conf(ctx, conf, &coin_type).await?; + let max_eth_tx_type = get_max_eth_tx_type_conf(conf).await?.unwrap_or_default(); let gas_limit = extract_gas_limit_from_conf(conf) - .map_to_mm(|e| EthActivationV2Error::InternalError(format!("invalid gas_limit config {}", e)))?; + .map_to_mm(|e| EthActivationV2Error::InternalError(format!("invalid gas_limit config {}", e)))? + .unwrap_or_default(); let coin = EthCoinImpl { priv_key_policy, derivation_method: Arc::new(derivation_method), - coin_type, + coin_type: EthCoinType::Eth, sign_message_prefix, swap_contract_address: req.swap_contract_address, swap_v2_contracts: req.swap_v2_contracts,