Skip to content

Commit

Permalink
fix overriding eth gas config params with token config (needed for te…
Browse files Browse the repository at this point in the history
…sts)
  • Loading branch information
dimxy committed Oct 10, 2024
1 parent 7055acc commit 3a56430
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 58 deletions.
91 changes: 43 additions & 48 deletions mm2src/coins/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -634,7 +634,7 @@ pub struct EthCoinImpl {
history_sync_state: Mutex<HistorySyncState>,
required_confirmations: AtomicU64,
swap_txfee_policy: Mutex<SwapTxFeePolicy>,
max_eth_tx_type: Option<u64>,
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,
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -6101,36 +6101,17 @@ fn rpc_event_handlers_for_eth_transport(ctx: &MmArc, ticker: String) -> Vec<RpcT
vec![CoinTransportMetrics::new(metrics, ticker, RpcClientType::Ethereum).into_shared()]
}

async fn get_max_eth_tx_type_conf(ctx: &MmArc, conf: &Json, coin_type: &EthCoinType) -> Result<Option<u64>, String> {
fn check_max_eth_tx_type_conf(conf: &Json) -> Result<Option<u64>, 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<Option<u64>, 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)
}
}

Expand Down Expand Up @@ -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(),
),
}
},
};

Expand Down Expand Up @@ -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<EthGasLimit, String> {
fn extract_gas_limit_from_conf(coin_conf: &Json) -> Result<Option<EthGasLimit>, 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<GasFeeEstimator, String> {
fn extract_gas_fee_estimator_from_value(value: &Json) -> Result<Option<GasFeeEstimator>, 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)
}
}

Expand Down
6 changes: 4 additions & 2 deletions mm2src/coins/eth/for_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down
22 changes: 14 additions & 8 deletions mm2src/coins/eth/v2_activation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 3a56430

Please sign in to comment.