Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support custom extension options when building tx #2573

Merged
merged 12 commits into from
Aug 24, 2022
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Support custom extension options to be able to specify `max_priority_price` for Ethermint dynamic tx fee
([#2566](https://github.com/informalsystems/ibc-rs/issues/2566))
11 changes: 8 additions & 3 deletions relayer/src/chain/cosmos/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ pub fn sign_tx(

let signer = encode_signer_info(&config.address_type, account.sequence, key_bytes)?;

let (body, body_bytes) = tx_body_and_bytes(messages, tx_memo)?;
let (body, body_bytes) =
tx_body_and_bytes(messages, tx_memo, config.extension_options.clone())?;

let (auth_info, auth_info_bytes) = auth_info_and_bytes(signer, fee.clone())?;

Expand Down Expand Up @@ -159,13 +160,17 @@ fn auth_info_and_bytes(signer_info: SignerInfo, fee: Fee) -> Result<(AuthInfo, V
Ok((auth_info, auth_buf))
}

fn tx_body_and_bytes(proto_msgs: Vec<Any>, memo: &Memo) -> Result<(TxBody, Vec<u8>), Error> {
fn tx_body_and_bytes(
proto_msgs: Vec<Any>,
memo: &Memo,
extension_options: Vec<Any>,
) -> Result<(TxBody, Vec<u8>), Error> {
// Create TxBody
let body = TxBody {
messages: proto_msgs.to_vec(),
memo: memo.to_string(),
timeout_height: 0_u64,
extension_options: Vec::<Any>::new(),
extension_options,
non_critical_extension_options: Vec::<Any>::new(),
};

Expand Down
9 changes: 9 additions & 0 deletions relayer/src/chain/cosmos/types/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use core::str::FromStr;
use core::time::Duration;
use http::Uri;
use ibc::core::ics24_host::identifier::ChainId;
use ibc_proto::google::protobuf::Any;
use tendermint_rpc::{HttpClient, Url};

use crate::chain::cosmos::types::gas::GasConfig;
Expand All @@ -17,6 +18,7 @@ pub struct TxConfig {
pub grpc_address: Uri,
pub rpc_timeout: Duration,
pub address_type: AddressType,
pub extension_options: Vec<Any>,
}

impl<'a> TryFrom<&'a ChainConfig> for TxConfig {
Expand All @@ -31,6 +33,12 @@ impl<'a> TryFrom<&'a ChainConfig> for TxConfig {

let gas_config = GasConfig::from(config);

let extension_options = config
.extension_options
.iter()
.map(|opt| opt.to_any())
.collect::<Result<_, _>>()?;

Ok(Self {
chain_id: config.id.clone(),
gas_config,
Expand All @@ -39,6 +47,7 @@ impl<'a> TryFrom<&'a ChainConfig> for TxConfig {
grpc_address,
rpc_timeout: config.rpc_timeout,
address_type: config.address_type.clone(),
extension_options,
})
}
}
1 change: 1 addition & 0 deletions relayer/src/chain/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ pub mod test_utils {
address_type: AddressType::default(),
memo_prefix: Default::default(),
proof_specs: Default::default(),
extension_options: Default::default(),
sequential_batch_tx: false,
}
}
Expand Down
41 changes: 41 additions & 0 deletions relayer/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use alloc::collections::BTreeMap;
use core::{fmt, time::Duration};
use std::{fs, fs::File, io::Write, path::Path};

use ibc_proto::google::protobuf::Any;
use serde_derive::{Deserialize, Serialize};
use tendermint_light_client_verifier::types::TrustThreshold;

Expand All @@ -18,6 +19,8 @@ use ibc::timestamp::ZERO_DURATION;

use crate::chain::ChainType;
use crate::config::types::{MaxMsgNum, MaxTxSize, Memo};
use crate::error::Error as RelayerError;
use crate::extension_options::ExtensionOptionDynamicFeeTx;
use crate::keyring::Store;

pub use error::Error;
Expand All @@ -42,6 +45,42 @@ impl fmt::Display for GasPrice {
}
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(
rename_all = "snake_case",
tag = "type",
content = "value",
deny_unknown_fields
)]
pub enum ExtensionOption {
EthermintDynamicFee(String),
}

impl ExtensionOption {
pub fn to_any(&self) -> Result<Any, RelayerError> {
match self {
Self::EthermintDynamicFee(max_priority_price) => ExtensionOptionDynamicFeeTx {
max_priority_price: max_priority_price.into(),
}
.to_any(),
}
}
}

impl fmt::Display for ExtensionOption {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::EthermintDynamicFee(max_priority_price) => {
write!(
f,
"EthermintDynamicFee(max_priority_price: {})",
max_priority_price
)
}
}
}
}

/// Defaults for various fields
pub mod default {
use super::*;
Expand Down Expand Up @@ -383,6 +422,8 @@ pub struct ChainConfig {
pub packet_filter: PacketFilter,
#[serde(default)]
pub address_type: AddressType,
#[serde(default = "Vec::new", skip_serializing_if = "Vec::is_empty")]
pub extension_options: Vec<ExtensionOption>,
}

/// Attempt to load and parse the TOML config file as a `Config`.
Expand Down
25 changes: 25 additions & 0 deletions relayer/src/extension_options.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use ibc_proto::google::protobuf::Any;
use prost::Message;
use serde_derive::{Deserialize, Serialize};

use crate::error::Error;

// ExtensionOptionDynamicFeeTx is an extension option used with ethermint dynamic fee tx.
// protobuf message: https://github.com/evmos/ethermint/blob/main/proto/ethermint/types/v1/dynamic_fee.proto
#[derive(Clone, PartialEq, Eq, Message, Serialize, Deserialize)]
pub struct ExtensionOptionDynamicFeeTx {
#[prost(string, tag = "1")]
pub max_priority_price: ::prost::alloc::string::String,
}

impl ExtensionOptionDynamicFeeTx {
pub fn to_any(&self) -> Result<Any, Error> {
let mut buf = Vec::new();
Message::encode(self, &mut buf)
.map_err(|e| Error::protobuf_encode("ExtensionOptionDynamicFeeTx".into(), e))?;
Ok(Any {
type_url: "/ethermint.types.v1.ExtensionOptionDynamicFeeTx".to_string(),
value: buf,
})
}
}
1 change: 1 addition & 0 deletions relayer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub mod connection;
pub mod denom;
pub mod error;
pub mod event;
pub mod extension_options;
pub mod foreign_client;
pub mod keyring;
pub mod light_client;
Expand Down
3 changes: 3 additions & 0 deletions tools/test-framework/src/relayer/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ pub fn new_tx_config_for_test(

let address_type = Default::default();

let extension_options = Default::default();

Ok(TxConfig {
chain_id,
gas_config,
Expand All @@ -69,6 +71,7 @@ pub fn new_tx_config_for_test(
grpc_address,
rpc_timeout,
address_type,
extension_options,
})
}

Expand Down
1 change: 1 addition & 0 deletions tools/test-framework/src/types/single/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ impl FullNode {
address_type: Default::default(),
memo_prefix: Default::default(),
proof_specs: Default::default(),
extension_options: Default::default(),
sequential_batch_tx: false,
})
}
Expand Down