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

rpc: Add new dialect for v0.38 in order to fix changes in misbehaviour evidence serialization #1467

Merged
merged 5 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .changelog/unreleased/breaking-changes/1467-v038-dialect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- [tendermint-rpc] Add new dialect for CometBFT v0.38.x
([\#1467](https://github.com/informalsystems/tendermint-rs/pull/1467))
3 changes: 3 additions & 0 deletions .changelog/unreleased/bug-fixes/1467-v038-evidence.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- [tendermint-rpc] Fix serialization of misbehaviour `Evidence`
on CometBFT v0.38.x using the newly introduced dialect
([\#1467](https://github.com/informalsystems/tendermint-rs/pull/1467))
2 changes: 1 addition & 1 deletion proto/src/prost/v0_34/tendermint.abci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ pub struct ResponseCheckTx {
#[prost(int64, tag = "10")]
pub priority: i64,
/// mempool_error is set by CometBFT.
/// ABCI applications creating a ResponseCheckTX should not set mempool_error.
/// ABCI applictions creating a ResponseCheckTX should not set mempool_error.
#[prost(string, tag = "11")]
pub mempool_error: ::prost::alloc::string::String,
}
Expand Down
2 changes: 1 addition & 1 deletion proto/src/prost/v0_37/tendermint.abci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ pub struct ResponseCheckTx {
#[prost(int64, tag = "10")]
pub priority: i64,
/// mempool_error is set by CometBFT.
/// ABCI applications creating a ResponseCheckTX should not set mempool_error.
/// ABCI applictions creating a ResponseCheckTX should not set mempool_error.
#[prost(string, tag = "11")]
pub mempool_error: ::prost::alloc::string::String,
}
Expand Down
2 changes: 1 addition & 1 deletion proto/src/prost/v0_38/tendermint.abci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ pub struct ResponseFinalizeBlock {
#[prost(message, repeated, tag = "1")]
pub events: ::prost::alloc::vec::Vec<Event>,
/// the result of executing each transaction including the events
/// the particular transaction emitted. This should match the order
/// the particular transction emitted. This should match the order
/// of the transactions delivered in the block itself
#[prost(message, repeated, tag = "2")]
pub tx_results: ::prost::alloc::vec::Vec<ExecTxResult>,
Expand Down
9 changes: 5 additions & 4 deletions proto/src/prost/v0_38/tendermint.types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,13 @@ pub struct Vote {
/// Vote extension provided by the application. Only valid for precommit
/// messages.
#[prost(bytes = "vec", tag = "9")]
#[serde(with = "crate::serializers::nullable")]
pub extension: ::prost::alloc::vec::Vec<u8>,
/// Vote extension signature by the validator if they participated in
/// consensus for the associated block.
/// Only valid for precommit messages.
#[prost(bytes = "vec", tag = "10")]
#[serde(with = "crate::serializers::nullable")]
pub extension_signature: ::prost::alloc::vec::Vec<u8>,
}
/// Commit contains the evidence that a block was committed by a set of validators.
Expand Down Expand Up @@ -418,18 +420,17 @@ pub struct DuplicateVoteEvidence {
#[prost(message, optional, tag = "2")]
pub vote_b: ::core::option::Option<Vote>,
#[prost(int64, tag = "3")]
#[serde(rename = "TotalVotingPower", with = "crate::serializers::from_str")]
#[serde(alias = "TotalVotingPower", with = "crate::serializers::from_str")]
pub total_voting_power: i64,
#[prost(int64, tag = "4")]
#[serde(rename = "ValidatorPower", with = "crate::serializers::from_str")]
#[serde(alias = "ValidatorPower", with = "crate::serializers::from_str")]
pub validator_power: i64,
#[prost(message, optional, tag = "5")]
#[serde(rename = "Timestamp")]
#[serde(alias = "Timestamp")]
pub timestamp: ::core::option::Option<crate::google::protobuf::Timestamp>,
}
/// LightClientAttackEvidence contains evidence of a set of validators attempting to mislead a light client.
#[derive(::serde::Deserialize, ::serde::Serialize)]
#[serde(rename_all = "PascalCase")]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct LightClientAttackEvidence {
Expand Down
2 changes: 1 addition & 1 deletion proto/src/tendermint/v0_34.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,5 @@ pub mod version {

pub mod meta {
pub const REPOSITORY: &str = "https://github.com/cometbft/cometbft";
pub const COMMITISH: &str = "v0.34.29";
pub const COMMITISH: &str = "v0.34.35";
}
2 changes: 1 addition & 1 deletion proto/src/tendermint/v0_37.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,5 @@ pub mod version {

pub mod meta {
pub const REPOSITORY: &str = "https://github.com/cometbft/cometbft";
pub const COMMITISH: &str = "v0.37.2";
pub const COMMITISH: &str = "v0.37.11";
}
2 changes: 1 addition & 1 deletion proto/src/tendermint/v0_38.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,5 @@ pub mod version {

pub mod meta {
pub const REPOSITORY: &str = "https://github.com/cometbft/cometbft";
pub const COMMITISH: &str = "v0.38.0";
pub const COMMITISH: &str = "v0.38.12";
}
15 changes: 10 additions & 5 deletions rpc/src/client/compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ pub enum CompatMode {
V0_34,
/// Use version 0.37 of the protocol.
V0_37,
/// Use version 0.38 of the protocol.
V0_38,
// NOTE: When adding a newer version, do not forget to update:
// - CompatMode::latest()
// - CompatMode::from_version()
Expand All @@ -34,7 +36,7 @@ impl Default for CompatMode {
impl CompatMode {
/// The latest supported version, selected by default.
pub const fn latest() -> Self {
Self::V0_37
Self::V0_38
}

/// Parse the Tendermint version string to determine
Expand All @@ -58,7 +60,7 @@ impl CompatMode {
match (version.major, version.minor) {
(0, 34) => Ok(CompatMode::V0_34),
(0, 37) => Ok(CompatMode::V0_37),
(0, 38) => Ok(CompatMode::V0_37),
(0, 38) => Ok(CompatMode::V0_38),
_ => Err(Error::unsupported_tendermint_version(version.to_string())),
}
}
Expand All @@ -69,6 +71,7 @@ impl fmt::Display for CompatMode {
match self {
CompatMode::V0_34 => f.write_str("v0.34"),
CompatMode::V0_37 => f.write_str("v0.37"),
CompatMode::V0_38 => f.write_str("v0.38"),
}
}
}
Expand All @@ -77,12 +80,13 @@ impl FromStr for CompatMode {
type Err = Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
const VALID_COMPAT_MODES: &str = "v0.34, v0.37";
const VALID_COMPAT_MODES: &str = "v0.34, v0.37, v0.38";

// Trim leading 'v', if present
match s.trim_start_matches('v') {
"0.34" => Ok(CompatMode::V0_34),
"0.37" => Ok(CompatMode::V0_37),
"0.38" => Ok(CompatMode::V0_38),
_ => Err(Error::invalid_compat_mode(
s.to_string(),
VALID_COMPAT_MODES,
Expand Down Expand Up @@ -139,7 +143,7 @@ mod tests {
);
assert_eq!(
CompatMode::from_version(parse_version("v0.38.0")).unwrap(),
CompatMode::V0_37
CompatMode::V0_38
);
let res = CompatMode::from_version(parse_version("v0.39.0"));
assert!(res.is_err());
Expand All @@ -153,10 +157,11 @@ mod tests {
fn test_from_str() {
assert_eq!("0.34".parse::<CompatMode>().unwrap(), CompatMode::V0_34);
assert_eq!("0.37".parse::<CompatMode>().unwrap(), CompatMode::V0_37);
assert_eq!("0.38".parse::<CompatMode>().unwrap(), CompatMode::V0_38);

let res = "0.33".parse::<CompatMode>();
assert!(res.is_err());
let res = "0.38".parse::<CompatMode>();
let res = "0.39".parse::<CompatMode>();
assert!(res.is_err());
let res = "foobar".parse::<CompatMode>();
assert!(res.is_err());
Expand Down
5 changes: 5 additions & 0 deletions rpc/src/client/transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ macro_rules! perform_with_compat {
($self:expr, $request:expr) => {{
let request = $request;
match $self.compat {
CompatMode::V0_38 => {
$self
.perform_with_dialect(request, crate::dialect::v0_38::Dialect)
.await
},
CompatMode::V0_37 => {
$self
.perform_with_dialect(request, crate::dialect::v0_37::Dialect)
Expand Down
94 changes: 77 additions & 17 deletions rpc/src/client/transport/http.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
//! HTTP-based transport for Tendermint RPC Client.

use core::str::FromStr;
use core::time::Duration;

use async_trait::async_trait;
use reqwest::{header, Proxy};
use std::time::Duration;

use tendermint::{block::Height, evidence::Evidence, Hash};
use tendermint_config::net;

use super::auth;
use crate::client::{Client, CompatMode};
use crate::dialect::{v0_34, v0_37, v0_38, Dialect, LatestDialect};
use crate::endpoint;
use crate::prelude::*;
use crate::{
client::{Client, CompatMode},
dialect::{v0_34, Dialect, LatestDialect},
endpoint,
query::Query,
request::RequestMessage,
response::Response,
Error, Order, Scheme, SimpleRequest, Url,
};
use crate::query::Query;
use crate::request::RequestMessage;
use crate::response::Response;
use crate::{Error, Order, Scheme, SimpleRequest, Url};

use super::auth;

const USER_AGENT: &str = concat!("tendermint.rs/", env!("CARGO_PKG_VERSION"));

Expand Down Expand Up @@ -258,6 +257,24 @@ impl Client for HttpClient {
self.perform_with_dialect(request, LatestDialect).await
}

async fn block<H>(&self, height: H) -> Result<endpoint::block::Response, Error>
where
H: Into<Height> + Send,
{
perform_with_compat!(self, endpoint::block::Request::new(height.into()))
}

async fn block_by_hash(
&self,
hash: tendermint::Hash,
) -> Result<endpoint::block_by_hash::Response, Error> {
perform_with_compat!(self, endpoint::block_by_hash::Request::new(hash))
}

async fn latest_block(&self) -> Result<endpoint::block::Response, Error> {
perform_with_compat!(self, endpoint::block::Request::default())
}

async fn block_results<H>(&self, height: H) -> Result<endpoint::block_results::Response, Error>
where
H: Into<Height> + Send,
Expand All @@ -269,13 +286,33 @@ impl Client for HttpClient {
perform_with_compat!(self, endpoint::block_results::Request::default())
}

async fn block_search(
&self,
query: Query,
page: u32,
per_page: u8,
order: Order,
) -> Result<endpoint::block_search::Response, Error> {
perform_with_compat!(
self,
endpoint::block_search::Request::new(query, page, per_page, order)
)
}

async fn header<H>(&self, height: H) -> Result<endpoint::header::Response, Error>
where
H: Into<Height> + Send,
{
let height = height.into();
match self.compat {
CompatMode::V0_37 => self.perform(endpoint::header::Request::new(height)).await,
CompatMode::V0_38 => {
self.perform_with_dialect(endpoint::header::Request::new(height), v0_38::Dialect)
.await
},
CompatMode::V0_37 => {
self.perform_with_dialect(endpoint::header::Request::new(height), v0_37::Dialect)
.await
},
CompatMode::V0_34 => {
// Back-fill with a request to /block endpoint and
// taking just the header from the response.
Expand All @@ -292,9 +329,19 @@ impl Client for HttpClient {
hash: Hash,
) -> Result<endpoint::header_by_hash::Response, Error> {
match self.compat {
CompatMode::V0_38 => {
self.perform_with_dialect(
endpoint::header_by_hash::Request::new(hash),
v0_38::Dialect,
)
.await
},
CompatMode::V0_37 => {
self.perform(endpoint::header_by_hash::Request::new(hash))
.await
self.perform_with_dialect(
endpoint::header_by_hash::Request::new(hash),
v0_37::Dialect,
)
.await
},
CompatMode::V0_34 => {
// Back-fill with a request to /block_by_hash endpoint and
Expand All @@ -311,11 +358,24 @@ impl Client for HttpClient {
}

/// `/broadcast_evidence`: broadcast an evidence.
async fn broadcast_evidence(&self, e: Evidence) -> Result<endpoint::evidence::Response, Error> {
async fn broadcast_evidence(
&self,
evidence: Evidence,
) -> Result<endpoint::evidence::Response, Error> {
match self.compat {
CompatMode::V0_37 => self.perform(endpoint::evidence::Request::new(e)).await,
CompatMode::V0_38 => {
let request = endpoint::evidence::Request::new(evidence);
self.perform_with_dialect(request, crate::dialect::v0_38::Dialect)
.await
},
CompatMode::V0_37 => {
let request = endpoint::evidence::Request::new(evidence);
self.perform_with_dialect(request, crate::dialect::v0_37::Dialect)
.await
},
CompatMode::V0_34 => {
self.perform_with_dialect(endpoint::evidence::Request::new(e), v0_34::Dialect)
let request = endpoint::evidence::Request::new(evidence);
self.perform_with_dialect(request, crate::dialect::v0_34::Dialect)
.await
},
}
Expand Down
4 changes: 2 additions & 2 deletions rpc/src/client/transport/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use alloc::collections::BTreeMap as HashMap;

use async_trait::async_trait;

use crate::dialect::{v0_37, Dialect};
use crate::dialect::{v0_38, Dialect};
use crate::{
client::{
subscription::SubscriptionTx,
Expand Down Expand Up @@ -65,7 +65,7 @@ pub struct MockClient<M: MockRequestMatcher> {
impl<M: MockRequestMatcher> Client for MockClient<M> {
async fn perform<R>(&self, request: R) -> Result<R::Output, Error>
where
R: SimpleRequest<v0_37::Dialect>,
R: SimpleRequest<v0_38::Dialect>,
{
self.matcher
.response_for(request)
Expand Down
Loading
Loading