From 954a89db6c834da1c75a56ae438f15af4ce62aba Mon Sep 17 00:00:00 2001 From: HuangYi Date: Wed, 17 Aug 2022 17:30:47 +0800 Subject: [PATCH 1/8] Support custom extension options when building tx Closes: #2566 --- relayer/src/chain/cosmos/encode.rs | 11 +++++-- relayer/src/chain/cosmos/types/config.rs | 7 ++++ relayer/src/config.rs | 32 +++++++++++++++++++ relayer/src/extension_options.rs | 26 +++++++++++++++ relayer/src/lib.rs | 1 + tools/test-framework/src/relayer/tx.rs | 3 ++ tools/test-framework/src/types/single/node.rs | 1 + 7 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 relayer/src/extension_options.rs diff --git a/relayer/src/chain/cosmos/encode.rs b/relayer/src/chain/cosmos/encode.rs index 416bc049d0..d804c7adc9 100644 --- a/relayer/src/chain/cosmos/encode.rs +++ b/relayer/src/chain/cosmos/encode.rs @@ -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())?; @@ -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, memo: &Memo) -> Result<(TxBody, Vec), Error> { +fn tx_body_and_bytes( + proto_msgs: Vec, + memo: &Memo, + extension_options: Vec, +) -> Result<(TxBody, Vec), Error> { // Create TxBody let body = TxBody { messages: proto_msgs.to_vec(), memo: memo.to_string(), timeout_height: 0_u64, - extension_options: Vec::::new(), + extension_options, non_critical_extension_options: Vec::::new(), }; diff --git a/relayer/src/chain/cosmos/types/config.rs b/relayer/src/chain/cosmos/types/config.rs index fa2f924d2d..c1fbfeb1f6 100644 --- a/relayer/src/chain/cosmos/types/config.rs +++ b/relayer/src/chain/cosmos/types/config.rs @@ -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; @@ -17,6 +18,7 @@ pub struct TxConfig { pub grpc_address: Uri, pub rpc_timeout: Duration, pub address_type: AddressType, + pub extension_options: Vec, } impl<'a> TryFrom<&'a ChainConfig> for TxConfig { @@ -39,6 +41,11 @@ impl<'a> TryFrom<&'a ChainConfig> for TxConfig { grpc_address, rpc_timeout: config.rpc_timeout, address_type: config.address_type.clone(), + extension_options: config + .extension_options + .iter() + .map(|opt| opt.to_any()) + .collect::>()?, }) } } diff --git a/relayer/src/config.rs b/relayer/src/config.rs index 3a48bd1d61..5b87756cb1 100644 --- a/relayer/src/config.rs +++ b/relayer/src/config.rs @@ -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; @@ -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; @@ -42,6 +45,33 @@ impl fmt::Display for GasPrice { } } +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub enum ExtensionOption { + EthermintDynamicFee(ExtensionOptionDynamicFeeTx), +} + +impl ExtensionOption { + pub fn to_any(&self) -> Result { + match self { + Self::EthermintDynamicFee(ext) => ext.to_any(), + } + } +} + +impl fmt::Display for ExtensionOption { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::EthermintDynamicFee(ext) => { + write!( + f, + "EthermintDynamicFee(max_priority_price: {})", + ext.max_priority_price + ) + } + } + } +} + /// Defaults for various fields pub mod default { use super::*; @@ -375,6 +405,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, } /// Attempt to load and parse the TOML config file as a `Config`. diff --git a/relayer/src/extension_options.rs b/relayer/src/extension_options.rs new file mode 100644 index 0000000000..3a8304d55e --- /dev/null +++ b/relayer/src/extension_options.rs @@ -0,0 +1,26 @@ +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, Message, Serialize, Deserialize)] +#[serde(transparent)] +pub struct ExtensionOptionDynamicFeeTx { + #[prost(string, tag = "1")] + pub max_priority_price: ::prost::alloc::string::String, +} + +impl ExtensionOptionDynamicFeeTx { + pub fn to_any(&self) -> Result { + 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, + }) + } +} diff --git a/relayer/src/lib.rs b/relayer/src/lib.rs index c448542d54..0d62339d1e 100644 --- a/relayer/src/lib.rs +++ b/relayer/src/lib.rs @@ -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; diff --git a/tools/test-framework/src/relayer/tx.rs b/tools/test-framework/src/relayer/tx.rs index 1cce4ca4f3..c54d9e9bb6 100644 --- a/tools/test-framework/src/relayer/tx.rs +++ b/tools/test-framework/src/relayer/tx.rs @@ -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, @@ -69,6 +71,7 @@ pub fn new_tx_config_for_test( grpc_address, rpc_timeout, address_type, + extension_options, }) } diff --git a/tools/test-framework/src/types/single/node.rs b/tools/test-framework/src/types/single/node.rs index 1d2a1a27d7..ca84746578 100644 --- a/tools/test-framework/src/types/single/node.rs +++ b/tools/test-framework/src/types/single/node.rs @@ -151,6 +151,7 @@ impl FullNode { address_type: Default::default(), memo_prefix: Default::default(), proof_specs: Default::default(), + extension_options: Default::default(), }) } From 359605493fcfdcedea6c63d77ee67d7bbce79e58 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Wed, 17 Aug 2022 17:44:48 +0800 Subject: [PATCH 2/8] Cargo.lock is outdated --- Cargo.lock | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 268e378f70..cf23eaee42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2612,12 +2612,6 @@ dependencies = [ "base64", ] -[[package]] -name = "rustversion" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" - [[package]] name = "ryu" version = "1.0.11" @@ -2917,10 +2911,11 @@ dependencies = [ [[package]] name = "serial_test" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eec42e7232e5ca56aa59d63af3c7f991fe71ee6a3ddd2d3480834cf3902b007" +checksum = "92761393ee4dc3ff8f4af487bd58f4307c9329bbedea02cac0089ad9c411e153" dependencies = [ + "dashmap 5.3.4", "futures", "lazy_static", "log", @@ -2930,14 +2925,13 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1b95bb2f4f624565e8fe8140c789af7e2082c0e0561b5a82a1b678baa9703dc" +checksum = "4b6f5d1c3087fb119617cff2966fe3808a80e5eb59a8c1601d5994d66f4346a5" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "rustversion", "syn", ] From e33cceaa247d5eda7650c24bd3968dea6a05248a Mon Sep 17 00:00:00 2001 From: HuangYi Date: Wed, 17 Aug 2022 18:41:21 +0800 Subject: [PATCH 3/8] optimize serde encoding --- relayer/src/config.rs | 17 +++++++++++++---- relayer/src/extension_options.rs | 1 - 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/relayer/src/config.rs b/relayer/src/config.rs index 5b87756cb1..effaf312b6 100644 --- a/relayer/src/config.rs +++ b/relayer/src/config.rs @@ -46,14 +46,23 @@ impl fmt::Display for GasPrice { } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[serde( + rename_all = "snake_case", + tag = "type", + content = "value", + deny_unknown_fields +)] pub enum ExtensionOption { - EthermintDynamicFee(ExtensionOptionDynamicFeeTx), + EthermintDynamicFee(String), } impl ExtensionOption { pub fn to_any(&self) -> Result { match self { - Self::EthermintDynamicFee(ext) => ext.to_any(), + Self::EthermintDynamicFee(max_priority_price) => ExtensionOptionDynamicFeeTx { + max_priority_price: max_priority_price.into(), + } + .to_any(), } } } @@ -61,11 +70,11 @@ impl ExtensionOption { impl fmt::Display for ExtensionOption { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Self::EthermintDynamicFee(ext) => { + Self::EthermintDynamicFee(max_priority_price) => { write!( f, "EthermintDynamicFee(max_priority_price: {})", - ext.max_priority_price + max_priority_price ) } } diff --git a/relayer/src/extension_options.rs b/relayer/src/extension_options.rs index 3a8304d55e..ffa5f2ede2 100644 --- a/relayer/src/extension_options.rs +++ b/relayer/src/extension_options.rs @@ -7,7 +7,6 @@ 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, Message, Serialize, Deserialize)] -#[serde(transparent)] pub struct ExtensionOptionDynamicFeeTx { #[prost(string, tag = "1")] pub max_priority_price: ::prost::alloc::string::String, From 0fbcd007534b143f3253fbb2e74f6dc7767b3c66 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Thu, 18 Aug 2022 11:14:33 +0800 Subject: [PATCH 4/8] fix clippy and test --- relayer/src/chain/mock.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/relayer/src/chain/mock.rs b/relayer/src/chain/mock.rs index 6eec7cfe06..aa7e843f46 100644 --- a/relayer/src/chain/mock.rs +++ b/relayer/src/chain/mock.rs @@ -515,6 +515,7 @@ pub mod test_utils { address_type: AddressType::default(), memo_prefix: Default::default(), proof_specs: Default::default(), + extension_options: Default::default(), } } } From d4bd4d0293c6abdd2a073f3c064ac66fc55c90cd Mon Sep 17 00:00:00 2001 From: Romain Ruetschi Date: Tue, 23 Aug 2022 15:48:59 +0200 Subject: [PATCH 5/8] Add changelog entry --- .changelog/unreleased/features/ibc-relayer/2566-2566.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/unreleased/features/ibc-relayer/2566-2566.md diff --git a/.changelog/unreleased/features/ibc-relayer/2566-2566.md b/.changelog/unreleased/features/ibc-relayer/2566-2566.md new file mode 100644 index 0000000000..ed03910465 --- /dev/null +++ b/.changelog/unreleased/features/ibc-relayer/2566-2566.md @@ -0,0 +1,3 @@ +- 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)) \ No newline at end of file From 8b57cdbf8755abfab0c79ab3db188222385aa019 Mon Sep 17 00:00:00 2001 From: Romain Ruetschi Date: Tue, 23 Aug 2022 15:49:56 +0200 Subject: [PATCH 6/8] Fix clippy warnings --- relayer/src/config.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/relayer/src/config.rs b/relayer/src/config.rs index effaf312b6..fcb2ee46ae 100644 --- a/relayer/src/config.rs +++ b/relayer/src/config.rs @@ -27,7 +27,7 @@ pub use error::Error; pub use filter::PacketFilter; -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct GasPrice { pub price: f64, pub denom: String, @@ -45,7 +45,7 @@ impl fmt::Display for GasPrice { } } -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde( rename_all = "snake_case", tag = "type", From 314ad22041da9ffbef61a936dee46209eba1b40a Mon Sep 17 00:00:00 2001 From: Romain Ruetschi Date: Tue, 23 Aug 2022 16:45:25 +0200 Subject: [PATCH 7/8] Fix compilation --- relayer/src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relayer/src/config.rs b/relayer/src/config.rs index fcb2ee46ae..2993ecd9e1 100644 --- a/relayer/src/config.rs +++ b/relayer/src/config.rs @@ -27,7 +27,7 @@ pub use error::Error; pub use filter::PacketFilter; -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct GasPrice { pub price: f64, pub denom: String, From a79117ed8476709127a0bca82e6aa87f3dc84c9a Mon Sep 17 00:00:00 2001 From: Romain Ruetschi Date: Wed, 24 Aug 2022 10:46:25 +0200 Subject: [PATCH 8/8] Fix clippy warnings --- .../unreleased/features/ibc-relayer/2566-2566.md | 3 --- .../features/ibc-relayer/2566-extension-options.md | 2 ++ relayer/src/chain/cosmos/types/config.rs | 12 +++++++----- relayer/src/extension_options.rs | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) delete mode 100644 .changelog/unreleased/features/ibc-relayer/2566-2566.md create mode 100644 .changelog/unreleased/features/ibc-relayer/2566-extension-options.md diff --git a/.changelog/unreleased/features/ibc-relayer/2566-2566.md b/.changelog/unreleased/features/ibc-relayer/2566-2566.md deleted file mode 100644 index ed03910465..0000000000 --- a/.changelog/unreleased/features/ibc-relayer/2566-2566.md +++ /dev/null @@ -1,3 +0,0 @@ -- 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)) \ No newline at end of file diff --git a/.changelog/unreleased/features/ibc-relayer/2566-extension-options.md b/.changelog/unreleased/features/ibc-relayer/2566-extension-options.md new file mode 100644 index 0000000000..407ca7f72b --- /dev/null +++ b/.changelog/unreleased/features/ibc-relayer/2566-extension-options.md @@ -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)) diff --git a/relayer/src/chain/cosmos/types/config.rs b/relayer/src/chain/cosmos/types/config.rs index c1fbfeb1f6..eda8a8716d 100644 --- a/relayer/src/chain/cosmos/types/config.rs +++ b/relayer/src/chain/cosmos/types/config.rs @@ -33,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::>()?; + Ok(Self { chain_id: config.id.clone(), gas_config, @@ -41,11 +47,7 @@ impl<'a> TryFrom<&'a ChainConfig> for TxConfig { grpc_address, rpc_timeout: config.rpc_timeout, address_type: config.address_type.clone(), - extension_options: config - .extension_options - .iter() - .map(|opt| opt.to_any()) - .collect::>()?, + extension_options, }) } } diff --git a/relayer/src/extension_options.rs b/relayer/src/extension_options.rs index ffa5f2ede2..b796a5cbbe 100644 --- a/relayer/src/extension_options.rs +++ b/relayer/src/extension_options.rs @@ -6,7 +6,7 @@ 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, Message, Serialize, Deserialize)] +#[derive(Clone, PartialEq, Eq, Message, Serialize, Deserialize)] pub struct ExtensionOptionDynamicFeeTx { #[prost(string, tag = "1")] pub max_priority_price: ::prost::alloc::string::String,