diff --git a/.changelog/unreleased/improvements/ibc-relayer/3966-tendermint-rs-0.36.md b/.changelog/unreleased/improvements/ibc-relayer/3966-tendermint-rs-0.36.md new file mode 100644 index 0000000000..9d2d3f865e --- /dev/null +++ b/.changelog/unreleased/improvements/ibc-relayer/3966-tendermint-rs-0.36.md @@ -0,0 +1,2 @@ +- Update to tendermint-rs v0.36.0 + ([\#3966](https://github.com/informalsystems/hermes/issues/3966)) \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 21d8994814..57fcfc6867 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1409,9 +1409,9 @@ dependencies = [ [[package]] name = "ibc-proto" -version = "0.43.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af781637b107aa33042426c9d17b181ced05ae97b1d88dba50f40f19ad44e36f" +checksum = "66080040d5a4800d52966d55b055400f86b79c34b854b935bef03c87aacda62a" dependencies = [ "base64 0.22.0", "bytes", @@ -1903,17 +1903,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" -[[package]] -name = "num-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.60", -] - [[package]] name = "num-integer" version = "0.1.46" @@ -3173,9 +3162,9 @@ dependencies = [ [[package]] name = "tendermint" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f8a10105d0a7c4af0a242e23ed5a12519afe5cc0e68419da441bb5981a6802" +checksum = "8b50aae6ec24c3429149ad59b5b8d3374d7804d4c7d6125ceb97cb53907fb68d" dependencies = [ "bytes", "digest 0.10.7", @@ -3204,9 +3193,9 @@ dependencies = [ [[package]] name = "tendermint-config" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac6bf36c613bb113737c333e3c1d6dfd3c99f8ac679e84feb58dd6456d77fb2e" +checksum = "e07b383dc8780ebbec04cfb603f3fdaba6ea6663d8dd861425b1ffa7761fe90d" dependencies = [ "flex-error", "serde", @@ -3218,9 +3207,9 @@ dependencies = [ [[package]] name = "tendermint-light-client" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240dbb4b281ab279aa6537bd5000ccf6c8e17d9a076d2af5d27766452c7efb16" +checksum = "331544139bbcf353acb5f56e733093d8e4bf2522cda0491b4bba7039ef0b944e" dependencies = [ "contracts", "crossbeam-channel", @@ -3243,9 +3232,9 @@ dependencies = [ [[package]] name = "tendermint-light-client-detector" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bbad4541ffa3a56b032f3dfc0790a27ed7c1e8ac9a8452382e11b62b88be0a4" +checksum = "73d0ffaf614bd2db605c4762e3a31a536b73cd45488fa5bace050135ca348f28" dependencies = [ "crossbeam-channel", "derive_more", @@ -3266,9 +3255,9 @@ dependencies = [ [[package]] name = "tendermint-light-client-verifier" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35678b66e819659617c2e83f9662b8544425694441990c07137904a07872d871" +checksum = "4216e487165e5dbd7af79952eaa0d5f06c5bde861eb76c690acd7f2d2a19395c" dependencies = [ "derive_more", "flex-error", @@ -3279,14 +3268,12 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff525d5540a9fc535c38dc0d92a98da3ee36fcdfbda99cecb9f3cce5cd4d41d7" +checksum = "46f193d04afde6592c20fd70788a10b8cb3823091c07456db70d8a93f5fb99c1" dependencies = [ "bytes", "flex-error", - "num-derive", - "num-traits", "prost", "prost-types", "serde", @@ -3297,9 +3284,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d8fe61b1772cd50038bdeeadf53773bb37a09e639dd8e6d996668fd220ddb29" +checksum = "21e3c231a3632cab53f92ad4161c730c468c08cfe4f0aa5a6735b53b390aecbd" dependencies = [ "async-trait", "async-tungstenite", @@ -3331,9 +3318,9 @@ dependencies = [ [[package]] name = "tendermint-testgen" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9921053646fe51d03ebd0c642871b734e2f28437233529d4aa6fbff5e477e924" +checksum = "b233cec83c56c413ccc346af866cb9206a14d468fcecf0255080107bc9b103c0" dependencies = [ "ed25519-consensus", "gumdrop", diff --git a/Cargo.toml b/Cargo.toml index 40235420b3..b093009c8b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,13 +30,13 @@ ibc-test-framework = { version = "0.27.2", path = "tools/test-framework" } ibc-integration-test = { version = "0.27.2", path = "tools/integration-test" } # Tendermint dependencies -tendermint = { version = "0.35.0", default-features = false } -tendermint-light-client = { version = "0.35.0", default-features = false } -tendermint-light-client-detector = { version = "0.35.0", default-features = false } -tendermint-light-client-verifier = { version = "0.35.0", default-features = false } -tendermint-proto = "0.35.0" -tendermint-rpc = "0.35.0" -tendermint-testgen = "0.35.0" +tendermint = { version = "0.36.0", default-features = false } +tendermint-light-client = { version = "0.36.0", default-features = false } +tendermint-light-client-detector = { version = "0.36.0", default-features = false } +tendermint-light-client-verifier = { version = "0.36.0", default-features = false } +tendermint-proto = { version = "0.36.0" } +tendermint-rpc = { version = "0.36.0" } +tendermint-testgen = { version = "0.36.0" } # Other dependencies abscissa_core = "=0.6.0" @@ -72,7 +72,7 @@ hex = "0.4.3" http = "0.2.9" humantime = "2.1.0" humantime-serde = "1.1.1" -ibc-proto = "0.43.0" +ibc-proto = "0.44.0" ics23 = "0.11.1" itertools = "0.12.1" moka = "0.12.5" diff --git a/crates/relayer-types/src/applications/ics29_fee/error.rs b/crates/relayer-types/src/applications/ics29_fee/error.rs index 79ba5e1bc2..f8cc66ae65 100644 --- a/crates/relayer-types/src/applications/ics29_fee/error.rs +++ b/crates/relayer-types/src/applications/ics29_fee/error.rs @@ -37,6 +37,10 @@ define_error! { EventAttributeNotFound { key: String } - | e | { format_args!("IBC event attribute not found for key: {}", e.key) }, + | e | { format_args!("IBC event attribute not found for key `{}`", e.key) }, + + EventAttributeInvalidUtf8 + { key: String } + | e | { format_args!("IBC event attribute value for key `{}` is not a valid UTF-8 string", e.key) }, } } diff --git a/crates/relayer-types/src/applications/ics29_fee/events.rs b/crates/relayer-types/src/applications/ics29_fee/events.rs index 34ea98c8c0..1db6ed9deb 100644 --- a/crates/relayer-types/src/applications/ics29_fee/events.rs +++ b/crates/relayer-types/src/applications/ics29_fee/events.rs @@ -26,12 +26,17 @@ fn find_value<'a>(key: &str, entries: &'a [abci::EventAttribute]) -> Result<&'a entries .iter() .find_map(|entry| { - if entry.key == key { - Some(entry.value.as_str()) + if entry.key_bytes() == key.as_bytes() { + Some( + entry + .value_str() + .map_err(|_| Error::event_attribute_invalid_utf8(key.to_owned())), + ) } else { None } }) + .transpose()? .ok_or_else(|| Error::event_attribute_not_found(key.to_owned())) } diff --git a/crates/relayer-types/src/applications/ics31_icq/events.rs b/crates/relayer-types/src/applications/ics31_icq/events.rs index b14a5d668f..eea8511d15 100644 --- a/crates/relayer-types/src/applications/ics31_icq/events.rs +++ b/crates/relayer-types/src/applications/ics31_icq/events.rs @@ -32,21 +32,22 @@ fn find_value<'a>(key: &str, entries: &'a [abci::EventAttribute]) -> Result<&'a entries .iter() .find_map(|entry| { - if entry.key == key { - Some(entry.value.as_str()) + if entry.key_bytes() == key.as_bytes() { + Some(entry.value_str().map_err(|_| { + Error::event(format!( + "attribute value for key {key} is not a valid UTF-8 string" + )) + })) } else { None } }) + .transpose()? .ok_or_else(|| Error::event(format!("attribute not found for key: {key}"))) } fn new_attr(key: &str, value: &str) -> abci::EventAttribute { - abci::EventAttribute { - key: String::from(key), - value: String::from(value), - index: true, - } + abci::EventAttribute::from((key, value, true)) } impl From for abci::Event { diff --git a/crates/relayer-types/src/core/ics02_client/error.rs b/crates/relayer-types/src/core/ics02_client/error.rs index 094a883aa6..a560a499f1 100644 --- a/crates/relayer-types/src/core/ics02_client/error.rs +++ b/crates/relayer-types/src/core/ics02_client/error.rs @@ -280,5 +280,12 @@ define_error! { ClientSpecific { description: String } | e | { format_args!("client specific error: {0}", e.description) }, + + MalformedEventAttributeKey + | _ | { format_args!("event attribute key is not valid UTF-8") }, + + MalformedEventAttributeValue + { key: String } + | e | { format_args!("event attribute value for key {} is not valid UTF-8", e.key) }, } } diff --git a/crates/relayer-types/src/core/ics03_connection/error.rs b/crates/relayer-types/src/core/ics03_connection/error.rs index 068b3ee30a..00b4529f8b 100644 --- a/crates/relayer-types/src/core/ics03_connection/error.rs +++ b/crates/relayer-types/src/core/ics03_connection/error.rs @@ -157,5 +157,12 @@ define_error! { ImplementationSpecific | _ | { "implementation specific error" }, + + MalformedEventAttributeKey + | _ | { format_args!("event attribute key is not valid UTF-8") }, + + MalformedEventAttributeValue + { key: String } + | e | { format_args!("event attribute value for key {} is not valid UTF-8", e.key) }, } } diff --git a/crates/relayer-types/src/core/ics04_channel/error.rs b/crates/relayer-types/src/core/ics04_channel/error.rs index 659ee07d6c..837fae20dc 100644 --- a/crates/relayer-types/src/core/ics04_channel/error.rs +++ b/crates/relayer-types/src/core/ics04_channel/error.rs @@ -359,7 +359,14 @@ define_error! { AbciConversionFailed { abci_event: String } - | e | { format_args!("Failed to convert abci event to IbcEvent: {}", e.abci_event)} + | e | { format_args!("Failed to convert abci event to IbcEvent: {}", e.abci_event)}, + + MalformedEventAttributeKey + | _ | { format_args!("event attribute key is not valid UTF-8") }, + + MalformedEventAttributeValue + { key: String } + | e | { format_args!("event attribute value for key {} is not valid UTF-8", e.key) }, } } diff --git a/crates/relayer/src/event.rs b/crates/relayer/src/event.rs index 6240e6e77a..2a75d8fc55 100644 --- a/crates/relayer/src/event.rs +++ b/crates/relayer/src/event.rs @@ -301,8 +301,14 @@ fn client_extract_attributes_from_tx(event: &AbciEvent) -> Result { attr.client_id = value @@ -328,9 +334,13 @@ fn client_extract_attributes_from_tx(event: &AbciEvent) -> Result Result { for tag in &event.attributes { - if tag.key == HEADER_ATTRIBUTE_KEY { - let header_bytes = hex::decode(tag.value.to_lowercase()) - .map_err(|_| ClientError::malformed_header())?; + if tag.key_bytes() == HEADER_ATTRIBUTE_KEY.as_bytes() { + let header_bytes = hex::decode( + tag.value_str() + .map_err(|_| ClientError::malformed_header())? + .to_lowercase(), + ) + .map_err(|_| ClientError::malformed_header())?; return decode_header(&header_bytes); } } @@ -344,8 +354,14 @@ fn connection_extract_attributes_from_tx( let mut attr = ConnectionAttributes::default(); for tag in &event.attributes { - let key = tag.key.as_str(); - let value = tag.value.as_str(); + let key = tag + .key_str() + .map_err(|_| ConnectionError::malformed_event_attribute_key())?; + + let value = tag + .value_str() + .map_err(|_| ConnectionError::malformed_event_attribute_value(key.to_owned()))?; + match key { connection_events::CONN_ID_ATTRIBUTE_KEY => { attr.connection_id = value.parse().ok(); @@ -373,8 +389,14 @@ fn channel_extract_attributes_from_tx( let mut attr = ChannelAttributes::default(); for tag in &event.attributes { - let key = tag.key.as_str(); - let value = tag.value.as_str(); + let key = tag + .key_str() + .map_err(|_| ChannelError::malformed_event_attribute_key())?; + + let value = tag + .value_str() + .map_err(|_| ChannelError::malformed_event_attribute_value(key.to_owned()))?; + match key { channel_events::PORT_ID_ATTRIBUTE_KEY => { attr.port_id = value.parse().map_err(ChannelError::identifier)? @@ -405,8 +427,13 @@ pub fn extract_packet_and_write_ack_from_tx( let mut write_ack: Vec = Vec::new(); for tag in &event.attributes { - let key = tag.key.as_str(); - let value = tag.value.as_str(); + let key = tag + .key_str() + .map_err(|_| ChannelError::malformed_event_attribute_key())?; + + let value = tag + .value_str() + .map_err(|_| ChannelError::malformed_event_attribute_value(key.to_owned()))?; match key { channel_events::PKT_SRC_PORT_ATTRIBUTE_KEY => { diff --git a/crates/relayer/src/event/source/rpc.rs b/crates/relayer/src/event/source/rpc.rs index 5aac57baef..5a4b4be722 100644 --- a/crates/relayer/src/event/source/rpc.rs +++ b/crates/relayer/src/event/source/rpc.rs @@ -292,7 +292,9 @@ fn dedupe(events: Vec) -> Vec { .attributes .iter() .zip(other.0.attributes.iter()) - .all(|(a, b)| a.key == b.key && a.value == b.value) + .all(|(a, b)| { + a.key_bytes() == b.key_bytes() && a.value_bytes() == b.value_bytes() + }) } } @@ -304,8 +306,8 @@ fn dedupe(events: Vec) -> Vec { for attr in &self.0.attributes { // NOTE: We don't hash the index because it is not deterministic - attr.key.hash(state); - attr.value.hash(state); + attr.key_bytes().hash(state); + attr.value_bytes().hash(state); } } }