Skip to content

Commit

Permalink
Merge branch 'master' into anca/clear_cli_sequences
Browse files Browse the repository at this point in the history
  • Loading branch information
ancazamfir committed Jan 7, 2024
2 parents 9007d09 + 3ec02fe commit 882f3aa
Show file tree
Hide file tree
Showing 32 changed files with 420 additions and 152 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Add a `client_refresh_rate` setting to specify the rate at which to
refresh clients referencing this chain, relative to its trusting period.
([\#3402](https://github.com/informalsystems/hermes/issues/3402))
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- Add a `query_packets_chunk_size` config option and a `--query-
packets-chunk-size flag to the `clear packets` CLI to configure how
many packets to query at once from the chain when clearing pending
packets. Lower this setting if one or more of packets you are
trying to clear are huge and make the packet query time out or fail.
([\#3743](https://github.com/informalsystems/hermes/issues/3743))
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Update compatibility check to allow IBC-Go 4.1.1 to 8.x and SDK 0.45.x to 0.50.x.
([\#3745](https://github.com/informalsystems/hermes/issues/3745))
2 changes: 1 addition & 1 deletion .github/codespell/codespell.ini
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[codespell]
skip = *.js,*.ts,*.css,*.svg,./target
skip = *.js,*.ts,*.css,*.svg,*.html,*.json,./target,./tools/integration-test/data,./tools/check-guide/target,./ci/misbehaviour/data
ignore-words = .github/codespell/words.txt
2 changes: 1 addition & 1 deletion .github/workflows/codespell.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ jobs:
- uses: actions/checkout@v4
- uses: codespell-project/actions-codespell@v2
with:
skip: '*.js,*.ts,*.css,*.svg,./target'
skip: '*.js,*.ts,*.css,*.svg,*.html,*.json,./target,./tools/integration-test/data,./tools/check-guide/target,./ci/misbehaviour/data'
ignore_words_file: .github/codespell/words.txt

19 changes: 16 additions & 3 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ max_msg_num = 30
# Default: 2097152 (2 MiB)
max_tx_size = 2097152

# How many packets to fetch at once from the chain when clearing packets.
# Default: 50
query_packets_chunk_size = 50

# Specify the maximum amount of time to tolerate a clock drift.
# The clock drift parameter defines how much new (untrusted) header's time
# can drift into the future. Default: 5s
Expand All @@ -314,14 +318,23 @@ max_block_time = '30s'
# Specify the amount of time to be used as the light client trusting period.
# It should be significantly less than the unbonding period
# (e.g. unbonding period = 3 weeks, trusting period = 2 weeks).
#
# Default: 2/3 of the `unbonding period` for Cosmos SDK chains
trusting_period = '14days'

# The rate at which to refresh the client referencing this chain,
# expressed as a fraction of the trusting period.
#
# Default: 1/3 (ie. three times per trusting period)
client_refresh_rate = '1/3'

# Specify the trust threshold for the light client, ie. the minimum fraction of validators
# which must overlap across two blocks during light client verification.
# Default: { numerator = '2', denominator = '3' }, ie. 2/3.
#
# Warning: This is an advanced feature! Modify with caution.
trust_threshold = { numerator = '2', denominator = '3' }
#
# Default: 2/3
trust_threshold = '2/3'

# Specify a string that Hermes will use as a memo for each transaction it submits
# to this chain. The string is limited to 50 characters. Default: '' (empty).
Expand Down Expand Up @@ -413,5 +426,5 @@ max_tx_size = 2097152
clock_drift = '5s'
max_block_time = '30s'
trusting_period = '14days'
trust_threshold = { numerator = '2', denominator = '3' }
trust_threshold = '2/3'
address_type = { derivation = 'cosmos' }
5 changes: 3 additions & 2 deletions crates/relayer-cli/src/chain_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@ use ibc_chain_registry::querier::*;
use ibc_relayer::chain::cosmos::config::CosmosSdkConfig;
use ibc_relayer::config::filter::{FilterPattern, PacketFilter};
use ibc_relayer::config::gas_multiplier::GasMultiplier;
use ibc_relayer::config::types::{MaxMsgNum, MaxTxSize, Memo};
use ibc_relayer::config::types::{MaxMsgNum, MaxTxSize, Memo, TrustThreshold};
use ibc_relayer::config::{default, AddressType, ChainConfig, EventSourceMode, GasPrice};
use ibc_relayer::keyring::Store;

use tendermint_light_client_verifier::types::TrustThreshold;
use tendermint_rpc::Url;

const MAX_HEALTHY_QUERY_RETRIES: u8 = 5;
Expand Down Expand Up @@ -145,9 +144,11 @@ where
max_msg_num: MaxMsgNum::default(),
max_tx_size: MaxTxSize::default(),
max_grpc_decoding_size: default::max_grpc_decoding_size(),
query_packets_chunk_size: default::query_packets_chunk_size(),
clock_drift: default::clock_drift(),
max_block_time: default::max_block_time(),
trusting_period: None,
client_refresh_rate: default::client_refresh_rate(),
ccv_consumer_chain: false,
memo_prefix: Memo::default(),
proof_specs: Default::default(),
Expand Down
50 changes: 49 additions & 1 deletion crates/relayer-cli/src/commands/clear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ pub struct ClearPacketsCmd {
help = "use the given signing key for the counterparty chain (default: `counterparty_key_name` config)"
)]
counterparty_key_name: Option<String>,

#[clap(
long = "query-packets-chunk-size",
help = "number of packets to fetch at once from the chain (default: `query_packets_chunk_size` config)"
)]
query_packets_chunk_size: Option<usize>,
}

impl Override<Config> for ClearPacketsCmd {
Expand Down Expand Up @@ -120,6 +126,17 @@ impl Runnable for ClearPacketsCmd {
}
}

// If `query_packets_chunk_size` is provided, overwrite the chain's
// `query_packets_chunk_size` parameter
if let Some(chunk_size) = self.query_packets_chunk_size {
match chains.src.config() {
Ok(mut src_chain_cfg) => {
src_chain_cfg.set_query_packets_chunk_size(chunk_size);
}
Err(e) => Output::error(e).exit(),
}
}

let mut ev_list = vec![];

// Construct links in both directions.
Expand Down Expand Up @@ -195,6 +212,7 @@ mod tests {
packet_sequences: vec![],
key_name: None,
counterparty_key_name: None,
query_packets_chunk_size: None
},
ClearPacketsCmd::parse_from([
"test",
Expand All @@ -217,7 +235,8 @@ mod tests {
channel_id: ChannelId::from_str("channel-07").unwrap(),
packet_sequences: vec![],
key_name: None,
counterparty_key_name: None
counterparty_key_name: None,
query_packets_chunk_size: None
},
ClearPacketsCmd::parse_from([
"test",
Expand All @@ -241,6 +260,7 @@ mod tests {
packet_sequences: vec![],
key_name: Some("key_name".to_owned()),
counterparty_key_name: None,
query_packets_chunk_size: None
},
ClearPacketsCmd::parse_from([
"test",
Expand All @@ -266,6 +286,7 @@ mod tests {
packet_sequences: vec![],
key_name: None,
counterparty_key_name: Some("counterparty_key_name".to_owned()),
query_packets_chunk_size: None
},
ClearPacketsCmd::parse_from([
"test",
Expand All @@ -281,6 +302,33 @@ mod tests {
)
}

#[test]
fn test_clear_packets_query_packets_chunk_size() {
assert_eq!(
ClearPacketsCmd {

Check failure on line 308 in crates/relayer-cli/src/commands/clear.rs

View workflow job for this annotation

GitHub Actions / clippy-all-features

missing field `packet_sequences` in initializer of `commands::clear::ClearPacketsCmd`

error[E0063]: missing field `packet_sequences` in initializer of `commands::clear::ClearPacketsCmd` --> crates/relayer-cli/src/commands/clear.rs:308:13 | 308 | ClearPacketsCmd { | ^^^^^^^^^^^^^^^ missing `packet_sequences`

Check failure on line 308 in crates/relayer-cli/src/commands/clear.rs

View workflow job for this annotation

GitHub Actions / clippy-no-default-features

missing field `packet_sequences` in initializer of `commands::clear::ClearPacketsCmd`

error[E0063]: missing field `packet_sequences` in initializer of `commands::clear::ClearPacketsCmd` --> crates/relayer-cli/src/commands/clear.rs:308:13 | 308 | ClearPacketsCmd { | ^^^^^^^^^^^^^^^ missing `packet_sequences`

Check failure on line 308 in crates/relayer-cli/src/commands/clear.rs

View workflow job for this annotation

GitHub Actions / test-stable

missing field `packet_sequences` in initializer of `ClearPacketsCmd`
chain_id: ChainId::from_string("chain_id"),
port_id: PortId::from_str("port_id").unwrap(),
channel_id: ChannelId::from_str("channel-07").unwrap(),
key_name: None,
counterparty_key_name: Some("counterparty_key_name".to_owned()),
query_packets_chunk_size: Some(100),
},
ClearPacketsCmd::parse_from([
"test",
"--chain",
"chain_id",
"--port",
"port_id",
"--channel",
"channel-07",
"--counterparty-key-name",
"counterparty_key_name",
"--query-packets-chunk-size",
"100"
])
)
}

#[test]
fn test_clear_packets_no_chan() {
assert!(ClearPacketsCmd::try_parse_from([
Expand Down
2 changes: 1 addition & 1 deletion crates/relayer-cli/src/commands/config/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl Runnable for ValidateCmd {
// No need to output the underlying error, this is done already when the application boots.
// See `application::CliApp::after_config`.
match config.validate_config() {
Ok(_) => Output::success("configuration is valid").exit(),
Ok(_) => Output::success_msg("configuration is valid").exit(),
Err(_) => Output::error("configuration is invalid").exit(),
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,6 @@ impl ClientState {
})
}

/// Get the refresh time to ensure the state does not expire
pub fn refresh_time(&self) -> Option<Duration> {
Some(2 * self.trusting_period / 3)
}

/// Helper method to produce a [`Options`] struct for use in
/// Tendermint-specific light client verification.
pub fn as_light_client_options(&self) -> Options {
Expand Down
127 changes: 110 additions & 17 deletions crates/relayer-types/src/core/ics02_client/trust_threshold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use std::convert::TryFrom;
use std::fmt::{Display, Error as FmtError, Formatter};
use std::str::FromStr;

use ibc_proto::Protobuf;
use num_rational::Ratio;
Expand Down Expand Up @@ -121,23 +122,37 @@ impl Display for TrustThreshold {
}
}

impl FromStr for TrustThreshold {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let parts: Vec<&str> = s.split('/').collect();

if parts.len() != 2 {
return Err(format!("invalid trust threshold, must be a fraction: {s}"));
}

let (num, denom) = (parts[0].parse(), parts[1].parse());

if let (Ok(num), Ok(denom)) = (num, denom) {
TrustThreshold::new(num, denom).map_err(|e| e.to_string())
} else {
Err(format!("invalid trust threshold, must be a fraction: {s}",))
}
}
}

impl Serialize for TrustThreshold {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
#[derive(Serialize)]
struct TrustThreshold {
numerator: u64,
denominator: u64,
}
use serde::ser::SerializeStruct;

let tt = TrustThreshold {
numerator: self.numerator(),
denominator: self.denominator(),
};

tt.serialize(serializer)
let mut s = serializer.serialize_struct("TrustThreshold", 2)?;
s.serialize_field("numerator", &self.numerator())?;
s.serialize_field("denominator", &self.denominator())?;
s.end()
}
}

Expand All @@ -146,13 +161,91 @@ impl<'de> Deserialize<'de> for TrustThreshold {
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
struct TrustThreshold {
numerator: u64,
denominator: u64,
use serde::de::{self, Visitor};
use std::fmt;

// This is a Visitor that forwards string types to T's `FromStr` impl and
// forwards map types to T's `Deserialize` impl. The `PhantomData` is to
// keep the compiler from complaining about T being an unused generic type
// parameter. We need T in order to know the Value type for the Visitor
// impl.
struct StringOrStruct;

impl<'de> Visitor<'de> for StringOrStruct {
type Value = TrustThreshold;

fn expecting(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
formatter.write_str(
"string (eg. '1/3') or map `{ numerator = <int>, denominator = <int> }`",
)
}

fn visit_str<E>(self, value: &str) -> Result<TrustThreshold, E>
where
E: de::Error,
{
Ok(FromStr::from_str(value).unwrap())
}

fn visit_map<M>(self, map: M) -> Result<TrustThreshold, M::Error>
where
M: de::MapAccess<'de>,
{
#[derive(Deserialize)]
struct TT {
#[serde(deserialize_with = "string_or_int")]
numerator: u64,
#[serde(deserialize_with = "string_or_int")]
denominator: u64,
}

let tt = TT::deserialize(de::value::MapAccessDeserializer::new(map))?;

TrustThreshold::new(tt.numerator, tt.denominator).map_err(de::Error::custom)
}
}

let tt = TrustThreshold::deserialize(deserializer)?;
Self::new(tt.numerator, tt.denominator).map_err(serde::de::Error::custom)
deserializer.deserialize_any(StringOrStruct)
}
}

fn string_or_int<'de, D>(deserializer: D) -> Result<u64, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::de::{self, Visitor};
use std::fmt;

struct StringOrInt;

impl<'de> Visitor<'de> for StringOrInt {
type Value = u64;

fn expecting(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
formatter.write_str("string or int")
}

fn visit_str<E>(self, value: &str) -> Result<u64, E>
where
E: de::Error,
{
FromStr::from_str(value).map_err(de::Error::custom)
}

fn visit_i64<E>(self, value: i64) -> Result<u64, E>
where
E: de::Error,
{
Ok(value as u64)
}

fn visit_u64<E>(self, value: u64) -> Result<u64, E>
where
E: de::Error,
{
Ok(value)
}
}

deserializer.deserialize_any(StringOrInt)
}
4 changes: 0 additions & 4 deletions crates/relayer-types/src/mock/client_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ impl MockClientState {
pub fn latest_height(&self) -> Height {
self.header.height()
}

pub fn refresh_time(&self) -> Option<Duration> {
None
}
}

impl Protobuf<RawMockClientState> for MockClientState {}
Expand Down
2 changes: 1 addition & 1 deletion crates/relayer/src/chain/cosmos/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl Settings {

let trust_threshold = options
.trust_threshold
.unwrap_or_else(|| src_chain_config.trust_threshold.into());
.unwrap_or(src_chain_config.trust_threshold);

Settings {
max_clock_drift,
Expand Down
Loading

0 comments on commit 882f3aa

Please sign in to comment.