Skip to content

Commit

Permalink
Support custom extension options when building tx (informalsystems#2573)
Browse files Browse the repository at this point in the history
Closes: informalsystems#2566

* Support custom extension options when building tx

* Cargo.lock is outdated

* optimize serde encoding

* fix clippy and test

* Add changelog entry

* Fix clippy warnings

* Fix compilation

* Fix clippy warnings

Co-authored-by: Sean Chen <[email protected]>
Co-authored-by: Romain Ruetschi <[email protected]>
  • Loading branch information
3 people authored Aug 24, 2022
1 parent 738e4b0 commit 8860b33
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 3 deletions.
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

0 comments on commit 8860b33

Please sign in to comment.