-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement dynamic gas fee for Cosmos (#471)
* Add memo to ibc_token_transfer * Add GasToFeeConverter to chose between static and dynamic gas fee * Move CanConvertGasToFee to cosmos_chain_components::traits * Extract Hermes v1 gas_amount_to_fee in Hermes SDK * Improve gas to fee converter for Cosmos * Fix issue after merging main * Fix LegacyCosmosBootstrap fields in cosmos_integration_tests_legacy * Implement Dynamic Gas Component and add it as field of Bootstrap for tests * Implement CanQueryEipBaseFee component * Remove InConverter from DynamicConvertCosmosGasToFee * Improve dynamic gas fee computation * Update crates/cosmos/cosmos-chain-components/src/traits/eip_query.rs Co-authored-by: Soares Chen <[email protected]> * Wire EipQuerierComponent * Extract Dynamic Gas Configuration for tests * Remove hardcoded EIP endpoint * Add DispatchQueryEip implementation * Set FeeMarket as default EIP query type * Move structs used for EIP query to their own file * Remove unnecessary CanRaiseError * Add default implementation for DynamicGasConfig * Use ReturnNoDynamicGas for LegacyCosmosBootstrap * cargo fmt * Move EIP query type in Dynamic Gas Config * Remove dependecy from Hermes v1 TxConfig * Remove unnecessary dependencies from DispatchQueryEip * Remove unnecessary dependencies from StaticConvertCosmosGasToFee and DynamicConvertCosmosGasToFee * Fix FeeMarket url * Disable dynamic gas fees for simd in WASM tests * Fix dynamic gas configuration in bootstrap * Disable dynamic gas fees for both_wasm_cosmos test * Remove enabled field from DynamicGasConfig * Remove U128 and Decimal struct used for dynamic gas * Remove dynamic_gas field from LegacyCosmosBootstrap --------- Co-authored-by: Soares Chen <[email protected]>
- Loading branch information
1 parent
7f4e3d6
commit cb2d629
Showing
54 changed files
with
1,223 additions
and
61 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
crates/cosmos/cosmos-chain-components/src/impls/queries/eip/dispatch.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
use cgp::core::Async; | ||
use cgp::prelude::HasErrorType; | ||
|
||
use crate::impls::queries::eip::feemarket::QueryEipFromFeeMarket; | ||
use crate::impls::queries::eip::osmosis::OsmosisQueryEip; | ||
use crate::traits::eip::eip_query::EipQuerier; | ||
use crate::types::config::gas::dynamic_gas_config::DynamicGasConfig; | ||
use crate::types::config::gas::eip_type::EipQueryType; | ||
|
||
pub struct DispatchQueryEip; | ||
|
||
impl<Chain> EipQuerier<Chain> for DispatchQueryEip | ||
where | ||
QueryEipFromFeeMarket: EipQuerier<Chain>, | ||
OsmosisQueryEip: EipQuerier<Chain>, | ||
Chain: HasErrorType + Async, | ||
{ | ||
async fn query_eip_base_fee( | ||
chain: &Chain, | ||
dynamic_gas_config: &DynamicGasConfig, | ||
) -> Result<f64, Chain::Error> { | ||
match dynamic_gas_config.eip_query_type { | ||
EipQueryType::FeeMarket => { | ||
QueryEipFromFeeMarket::query_eip_base_fee(chain, dynamic_gas_config).await | ||
} | ||
EipQueryType::Osmosis => { | ||
OsmosisQueryEip::query_eip_base_fee(chain, dynamic_gas_config).await | ||
} | ||
} | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
crates/cosmos/cosmos-chain-components/src/impls/queries/eip/feemarket.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
use cgp::core::error::CanRaiseError; | ||
use core::str::FromStr; | ||
use prost::DecodeError; | ||
use subtle_encoding::base64; | ||
|
||
use crate::impls::queries::eip::types::EipBaseFeeHTTPResult; | ||
use crate::impls::queries::eip::types::EipQueryError; | ||
use crate::impls::queries::eip::types::GasPriceResponse; | ||
use crate::traits::eip::eip_query::EipQuerier; | ||
use crate::traits::rpc_client::HasRpcClient; | ||
use crate::types::config::gas::dynamic_gas_config::DynamicGasConfig; | ||
|
||
/// Query EIP-1559 base fee using Skip's feemarket endpoint and decode it using | ||
/// `GasPriceResponse` | ||
pub struct QueryEipFromFeeMarket; | ||
|
||
impl<Chain> EipQuerier<Chain> for QueryEipFromFeeMarket | ||
where | ||
Chain: HasRpcClient | ||
+ CanRaiseError<reqwest::Error> | ||
+ CanRaiseError<subtle_encoding::Error> | ||
+ CanRaiseError<DecodeError> | ||
+ CanRaiseError<core::num::ParseIntError> | ||
+ CanRaiseError<core::num::ParseFloatError> | ||
+ CanRaiseError<&'static str> | ||
+ CanRaiseError<EipQueryError>, | ||
{ | ||
async fn query_eip_base_fee( | ||
chain: &Chain, | ||
dynamic_gas_config: &DynamicGasConfig, | ||
) -> Result<f64, Chain::Error> { | ||
let url = format!( | ||
"{}abci_query?path=\"/feemarket.feemarket.v1.Query/GasPrices\"&denom={}", | ||
chain.rpc_address(), | ||
dynamic_gas_config.denom, | ||
); | ||
|
||
let response = reqwest::get(&url).await.map_err(Chain::raise_error)?; | ||
|
||
if !response.status().is_success() { | ||
return Err(Chain::raise_error(EipQueryError { response })); | ||
} | ||
|
||
let result: EipBaseFeeHTTPResult = response.json().await.map_err(Chain::raise_error)?; | ||
|
||
let decoded = base64::decode(result.result.response.value).map_err(Chain::raise_error)?; | ||
|
||
let gas_price_response: GasPriceResponse = | ||
prost::Message::decode(decoded.as_ref()).map_err(Chain::raise_error)?; | ||
let dec_coin = gas_price_response | ||
.price | ||
.ok_or_else(|| Chain::raise_error("missing price in GasPriceRespone"))?; | ||
|
||
let raw_amount = f64::from_str(&dec_coin.amount).map_err(Chain::raise_error)?; | ||
let amount = raw_amount / 1000000000000000000.0; | ||
|
||
Ok(amount) | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
crates/cosmos/cosmos-chain-components/src/impls/queries/eip/mod.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
pub mod dispatch; | ||
pub mod feemarket; | ||
pub mod osmosis; | ||
pub mod types; |
55 changes: 55 additions & 0 deletions
55
crates/cosmos/cosmos-chain-components/src/impls/queries/eip/osmosis.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
use cgp::core::error::CanRaiseError; | ||
use core::str::FromStr; | ||
use prost::DecodeError; | ||
use subtle_encoding::base64; | ||
|
||
use ibc_proto::cosmos::base::v1beta1::DecProto; | ||
|
||
use crate::impls::queries::eip::types::EipBaseFeeHTTPResult; | ||
use crate::impls::queries::eip::types::EipQueryError; | ||
use crate::traits::eip::eip_query::EipQuerier; | ||
use crate::traits::rpc_client::HasRpcClient; | ||
use crate::types::config::gas::dynamic_gas_config::DynamicGasConfig; | ||
|
||
/// Query EIP-1559 base fee using Osmosis endpoint and decode it using | ||
/// Cosmos SDK proto `DecProto` | ||
pub struct OsmosisQueryEip; | ||
|
||
impl<Chain> EipQuerier<Chain> for OsmosisQueryEip | ||
where | ||
Chain: HasRpcClient | ||
+ CanRaiseError<reqwest::Error> | ||
+ CanRaiseError<subtle_encoding::Error> | ||
+ CanRaiseError<DecodeError> | ||
+ CanRaiseError<core::num::ParseIntError> | ||
+ CanRaiseError<core::num::ParseFloatError> | ||
+ CanRaiseError<EipQueryError>, | ||
{ | ||
async fn query_eip_base_fee( | ||
chain: &Chain, | ||
_dynamic_gas_config: &DynamicGasConfig, | ||
) -> Result<f64, Chain::Error> { | ||
let url = format!( | ||
"{}abci_query?path=\"/osmosis.txfees.v1beta1.Query/GetEipBaseFee\"", | ||
chain.rpc_address() | ||
); | ||
|
||
let response = reqwest::get(&url).await.map_err(Chain::raise_error)?; | ||
|
||
if !response.status().is_success() { | ||
return Err(Chain::raise_error(EipQueryError { response })); | ||
} | ||
|
||
let result: EipBaseFeeHTTPResult = response.json().await.map_err(Chain::raise_error)?; | ||
|
||
let decoded = base64::decode(result.result.response.value).map_err(Chain::raise_error)?; | ||
|
||
let dec_proto: DecProto = | ||
prost::Message::decode(decoded.as_ref()).map_err(Chain::raise_error)?; | ||
|
||
let raw_amount = f64::from_str(&dec_proto.dec).map_err(Chain::raise_error)?; | ||
let amount = raw_amount / 1000000000000000000.0; | ||
|
||
Ok(amount) | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
crates/cosmos/cosmos-chain-components/src/impls/queries/eip/types.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
use reqwest::Response; | ||
use serde::Deserialize; | ||
|
||
use ibc_proto::cosmos::base::v1beta1::DecCoin; | ||
|
||
#[derive(Debug)] | ||
pub struct EipQueryError { | ||
pub response: Response, | ||
} | ||
|
||
#[derive(Deserialize)] | ||
pub struct EipBaseFeeHTTPResult { | ||
pub result: EipBaseFeeResult, | ||
} | ||
|
||
#[derive(Deserialize)] | ||
pub struct EipBaseFeeResult { | ||
pub response: EipBaseFeeResponse, | ||
} | ||
|
||
#[derive(Deserialize)] | ||
pub struct EipBaseFeeResponse { | ||
pub value: String, | ||
} | ||
|
||
/// GasPriceResponse is the response type for the Query/GasPrice RPC method. | ||
/// Returns a gas price in specified denom. | ||
#[allow(clippy::derive_partial_eq_without_eq)] | ||
#[derive(Clone, PartialEq, ::prost::Message)] | ||
pub struct GasPriceResponse { | ||
#[prost(message, optional, tag = "1")] | ||
pub price: ::core::option::Option<DecCoin>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.