From 67f20b6c7cf3521a2aad01fea94b324d71f556a7 Mon Sep 17 00:00:00 2001 From: nhpd Date: Mon, 28 Oct 2024 21:08:02 +0400 Subject: [PATCH] refactor query min ibc fee helper. improve comments --- contracts/ibc_transfer/src/contract.rs | 49 +---------------- .../neutron_interchain_txs/src/contract.rs | 54 ++----------------- .../v045/register_queries.rs | 13 +++++ .../neutron-sdk/src/interchain_txs/helpers.rs | 52 ++++++++++++++++-- 4 files changed, 68 insertions(+), 100 deletions(-) diff --git a/contracts/ibc_transfer/src/contract.rs b/contracts/ibc_transfer/src/contract.rs index a8858cbf..f690a089 100644 --- a/contracts/ibc_transfer/src/contract.rs +++ b/contracts/ibc_transfer/src/contract.rs @@ -10,10 +10,9 @@ use cosmwasm_std::{ StdResult, SubMsg, }; use cw2::set_contract_version; -use neutron_sdk::interchain_txs::helpers::decode_message_response; +use neutron_sdk::interchain_txs::helpers::{decode_message_response, query_denom_min_ibc_fee}; use neutron_sdk::sudo::msg::{RequestPacket, TransferSudoMsg}; use neutron_std::types::cosmos::base::v1beta1::Coin as SDKCoin; -use neutron_std::types::neutron::feerefunder::{Fee, FeerefunderQuerier}; use neutron_std::types::neutron::transfer::{MsgTransfer, MsgTransferResponse}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -141,7 +140,7 @@ fn execute_send( ) -> StdResult { // contract must pay for relaying of acknowledgements // See more info here: https://docs.neutron.org/neutron/feerefunder/overview - let fee = min_ntrn_ibc_fee(query_min_fee(deps.as_ref())?); + let fee = query_denom_min_ibc_fee(deps.as_ref(), FEE_DENOM)?; let msg1 = MsgTransfer { source_port: "transfer".to_string(), source_channel: channel.clone(), @@ -270,47 +269,3 @@ pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult StdResult { - let querier = FeerefunderQuerier::new(&deps.querier); - let params = querier.params()?; - let params_inner = params - .params - .ok_or_else(|| StdError::generic_err("no params found for feerefunder"))?; - let min_fee = params_inner - .min_fee - .ok_or_else(|| StdError::generic_err("no minimum fee param for feerefunder"))?; - - Ok(min_fee) -} - -fn min_ntrn_ibc_fee(fee: Fee) -> Fee { - Fee { - recv_fee: fee - .recv_fee - .iter() - .map(|r| SDKCoin { - denom: r.denom.to_string(), - amount: r.amount.clone(), - }) - .collect(), - ack_fee: fee - .ack_fee - .iter() - .map(|r| SDKCoin { - denom: r.denom.to_string(), - amount: r.amount.clone(), - }) - .filter(|a| a.denom == FEE_DENOM) - .collect(), - timeout_fee: fee - .timeout_fee - .iter() - .map(|r| SDKCoin { - denom: r.denom.to_string(), - amount: r.amount.clone(), - }) - .filter(|a| a.denom == FEE_DENOM) - .collect(), - } -} diff --git a/contracts/neutron_interchain_txs/src/contract.rs b/contracts/neutron_interchain_txs/src/contract.rs index 9a55abe7..27d9fa07 100644 --- a/contracts/neutron_interchain_txs/src/contract.rs +++ b/contracts/neutron_interchain_txs/src/contract.rs @@ -10,7 +10,9 @@ use cosmwasm_std::{ Response, StdError, StdResult, SubMsg, }; use cw2::set_contract_version; -use neutron_sdk::interchain_txs::helpers::{register_interchain_account, submit_tx}; +use neutron_sdk::interchain_txs::helpers::{ + query_denom_min_ibc_fee, register_interchain_account, submit_tx, +}; use neutron_sdk::{ interchain_txs::helpers::{decode_message_response, get_port_id}, interchain_txs::v047::helpers::decode_acknowledgement_response, @@ -18,13 +20,11 @@ use neutron_sdk::{ NeutronError, NeutronResult, }; use neutron_std::shim::Timestamp; -use neutron_std::types::cosmos::base::v1beta1::Coin as SDKCoin; use neutron_std::types::cosmos::base::v1beta1::Coin; use neutron_std::types::cosmos::staking::v1beta1::{ MsgDelegate, MsgDelegateResponse, MsgUndelegate, MsgUndelegateResponse, }; use neutron_std::types::ibc::core::channel::v1::Order; -use neutron_std::types::neutron::feerefunder::{Fee, FeerefunderQuerier}; use neutron_std::types::neutron::interchaintxs::v1::{InterchaintxsQuerier, MsgSubmitTxResponse}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -222,7 +222,7 @@ fn execute_delegate( ) -> NeutronResult { // contract must pay for relaying of acknowledgements // See more info here: https://docs.neutron.org/neutron/feerefunder/overview - let fee = min_ntrn_ibc_fee(query_min_fee(deps.as_ref())?); + let fee = query_denom_min_ibc_fee(deps.as_ref(), FEE_DENOM)?; let (delegator, connection_id) = get_ica(deps.as_ref(), &env, &interchain_account_id)?; let delegate_msg = MsgDelegate { delegator_address: delegator, @@ -281,7 +281,7 @@ fn execute_undelegate( ) -> NeutronResult { // contract must pay for relaying of acknowledgements // See more info here: https://docs.neutron.org/neutron/feerefunder/overview - let fee = min_ntrn_ibc_fee(query_min_fee(deps.as_ref())?); + let fee = query_denom_min_ibc_fee(deps.as_ref(), FEE_DENOM)?; let (delegator, connection_id) = get_ica(deps.as_ref(), &env, &interchain_account_id)?; let delegate_msg = MsgUndelegate { delegator_address: delegator, @@ -629,47 +629,3 @@ pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> StdResult { ))), } } - -fn min_ntrn_ibc_fee(fee: Fee) -> Fee { - Fee { - recv_fee: fee - .recv_fee - .iter() - .map(|r| SDKCoin { - denom: r.denom.to_string(), - amount: r.amount.clone(), - }) - .collect(), - ack_fee: fee - .ack_fee - .iter() - .map(|r| SDKCoin { - denom: r.denom.to_string(), - amount: r.amount.clone(), - }) - .filter(|a| a.denom == FEE_DENOM) - .collect(), - timeout_fee: fee - .timeout_fee - .iter() - .map(|r| SDKCoin { - denom: r.denom.to_string(), - amount: r.amount.clone(), - }) - .filter(|a| a.denom == FEE_DENOM) - .collect(), - } -} - -fn query_min_fee(deps: Deps) -> StdResult { - let querier = FeerefunderQuerier::new(&deps.querier); - let params = querier.params()?; - let params_inner = params - .params - .ok_or_else(|| StdError::generic_err("no params found for feerefunder"))?; - let min_fee = params_inner - .min_fee - .ok_or_else(|| StdError::generic_err("no minimum fee param for feerefunder"))?; - - Ok(min_fee) -} diff --git a/packages/neutron-sdk/src/interchain_queries/v045/register_queries.rs b/packages/neutron-sdk/src/interchain_queries/v045/register_queries.rs index 043d0c72..22668c77 100644 --- a/packages/neutron-sdk/src/interchain_queries/v045/register_queries.rs +++ b/packages/neutron-sdk/src/interchain_queries/v045/register_queries.rs @@ -43,6 +43,7 @@ pub fn new_register_balances_query_msg( /// Creates a message to register an Interchain Query to get balance of account on remote chain for a particular denom /// +/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message. /// * **connection_id** is an IBC connection identifier between Neutron and remote chain; /// * **addr** address of an account on remote chain for which you want to get balances; /// * **denom** denomination of the coin for which you want to get balance; @@ -60,6 +61,7 @@ pub fn new_register_balance_query_msg( /// Creates a message to register an Interchain Query to get total supply on remote chain for particular denom /// +/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message. /// * **connection_id** is an IBC connection identifier between Neutron and remote chain; /// * **denom** denomination of the coin for which you want to get total supply; /// * **update_period** is used to say how often the query must be updated. @@ -92,6 +94,7 @@ pub fn new_register_bank_total_supply_query_msg( /// Creates a message to register an Interchain Query to get fee pool on remote chain from distribution module /// +/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message. /// * **connection_id** is an IBC connection identifier between Neutron and remote chain; /// * **update_period** is used to say how often the query must be updated. pub fn new_register_distribution_fee_pool_query_msg( @@ -114,6 +117,7 @@ pub fn new_register_distribution_fee_pool_query_msg( /// Creates a message to register an Interchain Query to get governance proposals on remote chain /// +/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message. /// * **connection_id** is an IBC connection identifier between Neutron and remote chain; /// * **proposals_ids** is a list of proposals ids from remote chain. /// * **update_period** is used to say how often the query must be updated. @@ -135,6 +139,7 @@ pub fn new_register_gov_proposals_query_msg( /// Creates a message to update an Interchain Query to get governance proposals on remote chain /// +/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message. /// * **query_id** is an IBC connection identifier between Neutron and remote chain; /// * **proposals_ids** is a list of proposals ids from remote chain. /// * **new_update_period** is used to update period of how often the query must be updated. @@ -151,6 +156,7 @@ pub fn update_gov_proposals_query_msg( /// Creates a message to register an Interchain Query to get governance proposals votes on the remote chain /// +/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message. /// * **connection_id** is an IBC connection identifier between Neutron and remote chain; /// * **proposals_ids** is a list of proposals ids from remote chain. /// * **voters** is a list of voter to get voting info from remote chain. @@ -174,6 +180,7 @@ pub fn new_register_gov_proposals_voters_votes_query_msg( /// Creates a message to update an Interchain Query to get governance proposals votes on the remote chain /// +/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message. /// * **query_id** is an IBC connection identifier between Neutron and remote chain; /// * **proposals_ids** is a list of proposals ids from remote chain. /// * **voters** is a list of voter to get voting info from remote chain. @@ -192,6 +199,7 @@ pub fn update_gov_proposals_votes_query_msg( /// Creates a message to register an Interchain Query to get validator info on remote chain /// +/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message. /// * **connection_id** is an IBC connection identifier between Neutron and remote chain; /// * **validator** is an validator operator address of an account on remote chain for which you want to get rewards ; /// * **update_period** is used to say how often the query must be updated. @@ -224,6 +232,7 @@ pub fn new_register_staking_validators_query_msg( /// Creates a message to register an Interchain Query to get validators signing infos on remote chain /// +/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message. /// * **connection_id** is an IBC connection identifier between Neutron and remote chain; /// * **validators** is an list of validators valcons addresses of an account on remote chain for which you want to get rewards ; /// * **update_period** is used to say how often the query must be updated. @@ -256,6 +265,7 @@ pub fn new_register_validators_signing_infos_query_msg( /// Creates a message to register an Interchain Query to get delegations of particular delegator on remote chain. /// +/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message. /// * **connection_id** is an IBC connection identifier between Neutron and remote chain; /// * **delegator** is an address of an account on remote chain for which you want to get list of delegations; /// * **validators** is a list of validators addresses for which you want to get delegations from particular **delegator**; @@ -307,6 +317,7 @@ pub fn new_register_delegator_delegations_query_msg( /// Creates a message to register an Interchain Query to get unbonding delegations of particular delegator on remote chain. /// +/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message. /// * **connection_id** is an IBC connection identifier between Neutron and remote chain; /// * **delegator** is an address of an account on remote chain for which you want to get list of unbonding delegations; /// * **validators** is a list of validators addresses for which you want to get unbonding delegations from particular **delegator**; @@ -344,6 +355,7 @@ pub fn new_register_delegator_unbonding_delegations_query_msg( /// Creates a message to register an Interchain Query to get wasm contract store on remote chain /// from **wasm** module /// +/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message. /// * **connection_id** is an IBC connection identifier between Neutron and remote chain; /// * **contract_address** is an address of a contract on a remote chain; /// * **key** is a wasm contract store key; @@ -379,6 +391,7 @@ pub fn new_register_wasm_contract_store_query_msg( /// Creates a message to register an Interchain Query to get transfer events to a recipient on a remote chain. /// +/// * **contract** is an address of the contract that registers the query. Must be contract that sends this message. /// * **connection_id** is an IBC connection identifier between Neutron and remote chain; /// * **recipient** is an address of an account on remote chain for which you want to get list of transfer transactions; /// * **update_period** is used to say how often the query must be updated. diff --git a/packages/neutron-sdk/src/interchain_txs/helpers.rs b/packages/neutron-sdk/src/interchain_txs/helpers.rs index de07ad53..f24f4f5c 100644 --- a/packages/neutron-sdk/src/interchain_txs/helpers.rs +++ b/packages/neutron-sdk/src/interchain_txs/helpers.rs @@ -1,9 +1,9 @@ use cosmos_sdk_proto::traits::Message; -use cosmwasm_std::{Addr, CosmosMsg, StdError, StdResult}; +use cosmwasm_std::{Addr, CosmosMsg, Deps, StdError, StdResult}; use neutron_std::shim::Any; use neutron_std::types::cosmos::base::v1beta1::Coin; use neutron_std::types::ibc::core::channel::v1::Order; -use neutron_std::types::neutron::feerefunder::Fee; +use neutron_std::types::neutron::feerefunder::{Fee, FeerefunderQuerier}; use neutron_std::types::neutron::interchaintxs::v1::{MsgRegisterInterchainAccount, MsgSubmitTx}; /// Decodes protobuf any item into T structure @@ -27,7 +27,8 @@ pub fn get_port_id>(contract_address: R, interchain_account_id: R) + interchain_account_id.as_ref() } -/// Basic helper to define a register interchain account message: +/// Basic helper to define a register interchain account message. +/// /// * **contract** is a contract that registers ICA. Must be the contract address that sends this message. /// * **connection_id** is an IBC connection identifier between Neutron and remote chain; /// * **interchain_account_id** is an identifier of your new interchain account. Can be any string. @@ -49,7 +50,8 @@ pub fn register_interchain_account( .into() } -/// Basic helper to define a submit tx message: +/// Basic helper to define a submit tx message. +/// /// * **contract** is a contract that is sending the message /// * **connection_id** is an IBC connection identifier between Neutron and remote chain; /// * **interchain_account_id** is an identifier of your interchain account from which you want to execute msgs; @@ -77,3 +79,45 @@ pub fn submit_tx( } .into() } + +/// Queries chain for minimum fee for given denom. Returns Err if not found. +/// +/// * **deps** is contract `Deps` +/// * **denom** is a denom which can be used. Function will return Err if denom is not in a list of fee denoms. +pub fn query_denom_min_ibc_fee(deps: Deps, denom: &str) -> StdResult { + let fee = query_min_fee(deps)?; + Ok(Fee { + recv_fee: fee_with_denom(fee.recv_fee, denom)?, + ack_fee: fee_with_denom(fee.ack_fee, denom)?, + timeout_fee: fee_with_denom(fee.timeout_fee, denom)?, + }) +} + +/// Queries chain for all possible minimal fee. Each fee in Vec is a different denom. +/// +/// * **deps** is contract `Deps` +pub fn query_min_fee(deps: Deps) -> StdResult { + let querier = FeerefunderQuerier::new(&deps.querier); + let params = querier.params()?; + let params_inner = params + .params + .ok_or_else(|| StdError::generic_err("no params found for feerefunder"))?; + let min_fee = params_inner + .min_fee + .ok_or_else(|| StdError::generic_err("no minimum fee param for feerefunder"))?; + + Ok(min_fee) +} + +fn fee_with_denom(fee: Vec, denom: &str) -> StdResult> { + Ok(vec![fee + .iter() + .find(|a| a.denom == denom) + .map(|r| Coin { + denom: r.denom.to_string(), + amount: r.amount.clone(), + }) + .ok_or_else(|| { + StdError::not_found(format!("cannot find fee for denom {}", denom)) + })?]) +}