diff --git a/.changelog/unreleased/breaking-changes/1467-v038-dialect.md b/.changelog/unreleased/breaking-changes/1467-v038-dialect.md new file mode 100644 index 000000000..ff265392b --- /dev/null +++ b/.changelog/unreleased/breaking-changes/1467-v038-dialect.md @@ -0,0 +1,2 @@ +- [tendermint-rpc] Add new dialect for CometBFT v0.38.x + ([\#1467](https://github.com/informalsystems/tendermint-rs/pull/1467)) \ No newline at end of file diff --git a/.changelog/unreleased/bug-fixes/1467-v038-evidence.md b/.changelog/unreleased/bug-fixes/1467-v038-evidence.md new file mode 100644 index 000000000..596b4daef --- /dev/null +++ b/.changelog/unreleased/bug-fixes/1467-v038-evidence.md @@ -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)) \ No newline at end of file diff --git a/proto/src/prost/v0_34/tendermint.abci.rs b/proto/src/prost/v0_34/tendermint.abci.rs index 291a8a163..1719f446a 100644 --- a/proto/src/prost/v0_34/tendermint.abci.rs +++ b/proto/src/prost/v0_34/tendermint.abci.rs @@ -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, } diff --git a/proto/src/prost/v0_37/tendermint.abci.rs b/proto/src/prost/v0_37/tendermint.abci.rs index 6419a690d..ba11419cc 100644 --- a/proto/src/prost/v0_37/tendermint.abci.rs +++ b/proto/src/prost/v0_37/tendermint.abci.rs @@ -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, } diff --git a/proto/src/prost/v0_38/tendermint.abci.rs b/proto/src/prost/v0_38/tendermint.abci.rs index e97cd43c9..a30f9bdc7 100644 --- a/proto/src/prost/v0_38/tendermint.abci.rs +++ b/proto/src/prost/v0_38/tendermint.abci.rs @@ -706,7 +706,7 @@ pub struct ResponseFinalizeBlock { #[prost(message, repeated, tag = "1")] pub events: ::prost::alloc::vec::Vec, /// 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, diff --git a/proto/src/prost/v0_38/tendermint.types.rs b/proto/src/prost/v0_38/tendermint.types.rs index 4e1651388..be4517585 100644 --- a/proto/src/prost/v0_38/tendermint.types.rs +++ b/proto/src/prost/v0_38/tendermint.types.rs @@ -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, /// 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, } /// Commit contains the evidence that a block was committed by a set of validators. @@ -418,18 +420,17 @@ pub struct DuplicateVoteEvidence { #[prost(message, optional, tag = "2")] pub vote_b: ::core::option::Option, #[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, } /// 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 { diff --git a/proto/src/tendermint/v0_34.rs b/proto/src/tendermint/v0_34.rs index 0fe8d876a..7f5ef8d09 100644 --- a/proto/src/tendermint/v0_34.rs +++ b/proto/src/tendermint/v0_34.rs @@ -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"; } diff --git a/proto/src/tendermint/v0_37.rs b/proto/src/tendermint/v0_37.rs index 56c9112ee..78325e653 100644 --- a/proto/src/tendermint/v0_37.rs +++ b/proto/src/tendermint/v0_37.rs @@ -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"; } diff --git a/proto/src/tendermint/v0_38.rs b/proto/src/tendermint/v0_38.rs index 932299c6b..6eca5ebe3 100644 --- a/proto/src/tendermint/v0_38.rs +++ b/proto/src/tendermint/v0_38.rs @@ -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"; } diff --git a/rpc/src/client/compat.rs b/rpc/src/client/compat.rs index 0a419cf9f..fb5a5a08c 100644 --- a/rpc/src/client/compat.rs +++ b/rpc/src/client/compat.rs @@ -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() @@ -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 @@ -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())), } } @@ -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"), } } } @@ -77,12 +80,13 @@ impl FromStr for CompatMode { type Err = Error; fn from_str(s: &str) -> Result { - 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, @@ -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()); @@ -153,10 +157,11 @@ mod tests { fn test_from_str() { assert_eq!("0.34".parse::().unwrap(), CompatMode::V0_34); assert_eq!("0.37".parse::().unwrap(), CompatMode::V0_37); + assert_eq!("0.38".parse::().unwrap(), CompatMode::V0_38); let res = "0.33".parse::(); assert!(res.is_err()); - let res = "0.38".parse::(); + let res = "0.39".parse::(); assert!(res.is_err()); let res = "foobar".parse::(); assert!(res.is_err()); diff --git a/rpc/src/client/transport.rs b/rpc/src/client/transport.rs index 658fedd97..57ce5e6d4 100644 --- a/rpc/src/client/transport.rs +++ b/rpc/src/client/transport.rs @@ -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) diff --git a/rpc/src/client/transport/http.rs b/rpc/src/client/transport/http.rs index b5293e26f..2885d63b9 100644 --- a/rpc/src/client/transport/http.rs +++ b/rpc/src/client/transport/http.rs @@ -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")); @@ -258,6 +257,24 @@ impl Client for HttpClient { self.perform_with_dialect(request, LatestDialect).await } + async fn block(&self, height: H) -> Result + where + H: Into + Send, + { + perform_with_compat!(self, endpoint::block::Request::new(height.into())) + } + + async fn block_by_hash( + &self, + hash: tendermint::Hash, + ) -> Result { + perform_with_compat!(self, endpoint::block_by_hash::Request::new(hash)) + } + + async fn latest_block(&self) -> Result { + perform_with_compat!(self, endpoint::block::Request::default()) + } + async fn block_results(&self, height: H) -> Result where H: Into + Send, @@ -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 { + perform_with_compat!( + self, + endpoint::block_search::Request::new(query, page, per_page, order) + ) + } + async fn header(&self, height: H) -> Result where H: Into + 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. @@ -292,9 +329,19 @@ impl Client for HttpClient { hash: Hash, ) -> Result { 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 @@ -311,11 +358,24 @@ impl Client for HttpClient { } /// `/broadcast_evidence`: broadcast an evidence. - async fn broadcast_evidence(&self, e: Evidence) -> Result { + async fn broadcast_evidence( + &self, + evidence: Evidence, + ) -> Result { 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 }, } diff --git a/rpc/src/client/transport/mock.rs b/rpc/src/client/transport/mock.rs index bc05e1892..deac1a3dc 100644 --- a/rpc/src/client/transport/mock.rs +++ b/rpc/src/client/transport/mock.rs @@ -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, @@ -65,7 +65,7 @@ pub struct MockClient { impl Client for MockClient { async fn perform(&self, request: R) -> Result where - R: SimpleRequest, + R: SimpleRequest, { self.matcher .response_for(request) diff --git a/rpc/src/client/transport/websocket.rs b/rpc/src/client/transport/websocket.rs index 585d3f1ab..a52312391 100644 --- a/rpc/src/client/transport/websocket.rs +++ b/rpc/src/client/transport/websocket.rs @@ -234,6 +234,24 @@ impl Client for WebSocketClient { self.perform_with_dialect(request, LatestDialect).await } + async fn block(&self, height: H) -> Result + where + H: Into + Send, + { + perform_with_compat!(self, endpoint::block::Request::new(height.into())) + } + + async fn block_by_hash( + &self, + hash: tendermint::Hash, + ) -> Result { + perform_with_compat!(self, endpoint::block_by_hash::Request::new(hash)) + } + + async fn latest_block(&self) -> Result { + perform_with_compat!(self, endpoint::block::Request::default()) + } + async fn block_results(&self, height: H) -> Result where H: Into + Send, @@ -245,12 +263,26 @@ impl Client for WebSocketClient { perform_with_compat!(self, endpoint::block_results::Request::default()) } + async fn block_search( + &self, + query: Query, + page: u32, + per_page: u8, + order: Order, + ) -> Result { + perform_with_compat!( + self, + endpoint::block_search::Request::new(query, page, per_page, order) + ) + } + async fn header(&self, height: H) -> Result where H: Into + Send, { let height = height.into(); match self.compat { + CompatMode::V0_38 => self.perform(endpoint::header::Request::new(height)).await, CompatMode::V0_37 => self.perform(endpoint::header::Request::new(height)).await, CompatMode::V0_34 => { // Back-fill with a request to /block endpoint and @@ -268,6 +300,10 @@ impl Client for WebSocketClient { hash: Hash, ) -> Result { match self.compat { + CompatMode::V0_38 => { + self.perform(endpoint::header_by_hash::Request::new(hash)) + .await + }, CompatMode::V0_37 => { self.perform(endpoint::header_by_hash::Request::new(hash)) .await @@ -885,9 +921,11 @@ impl WebSocketClientDriver { async fn handle_text_msg(&mut self, msg: String) -> Result<(), Error> { let parse_res = match self.compat { + CompatMode::V0_38 => event::v0_38::DeEvent::from_string(&msg).map(Into::into), CompatMode::V0_37 => event::v0_37::DeEvent::from_string(&msg).map(Into::into), CompatMode::V0_34 => event::v0_34::DeEvent::from_string(&msg).map(Into::into), }; + if let Ok(ev) = parse_res { debug!("JSON-RPC event: {}", msg); self.publish_event(ev).await; diff --git a/rpc/src/dialect.rs b/rpc/src/dialect.rs index 4d33a409e..ba21369f0 100644 --- a/rpc/src/dialect.rs +++ b/rpc/src/dialect.rs @@ -3,7 +3,8 @@ pub mod v0_34; pub mod v0_37; -pub use v0_37::Dialect as LatestDialect; +pub mod v0_38; +pub use v0_38::Dialect as LatestDialect; mod begin_block; mod check_tx; @@ -29,4 +30,5 @@ mod sealed { impl Sealed for super::v0_34::Dialect {} impl Sealed for super::v0_37::Dialect {} + impl Sealed for super::v0_38::Dialect {} } diff --git a/rpc/src/dialect/v0_37.rs b/rpc/src/dialect/v0_37.rs index e3f3317a5..bc6def9da 100644 --- a/rpc/src/dialect/v0_37.rs +++ b/rpc/src/dialect/v0_37.rs @@ -39,3 +39,9 @@ impl From for Evidence { Self(evidence) } } + +impl From for evidence::Evidence { + fn from(evidence: Evidence) -> Self { + evidence.0 + } +} diff --git a/rpc/src/dialect/v0_38.rs b/rpc/src/dialect/v0_38.rs new file mode 100644 index 000000000..610cea660 --- /dev/null +++ b/rpc/src/dialect/v0_38.rs @@ -0,0 +1,41 @@ +use tendermint::evidence; +use tendermint_proto::v0_38 as raw; + +use crate::prelude::*; +use serde::{Deserialize, Serialize}; + +/// The Event serialization in the latest RPC dialect is the canonical +/// serialization for the ABCI domain type. +pub use tendermint::abci::Event; + +#[derive(Default, Clone)] +pub struct Dialect; + +impl crate::dialect::Dialect for Dialect { + type Event = Event; + type Evidence = Evidence; +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(into = "raw::types::Evidence", try_from = "raw::types::Evidence")] +pub struct Evidence(evidence::Evidence); + +impl From for raw::types::Evidence { + fn from(evidence: Evidence) -> Self { + evidence.0.into() + } +} + +impl TryFrom for Evidence { + type Error = >::Error; + + fn try_from(value: raw::types::Evidence) -> Result { + Ok(Self(evidence::Evidence::try_from(value)?)) + } +} + +impl From for Evidence { + fn from(evidence: evidence::Evidence) -> Self { + Self(evidence) + } +} diff --git a/rpc/src/endpoint/block.rs b/rpc/src/endpoint/block.rs index 558f7dc0e..8380bf0ab 100644 --- a/rpc/src/endpoint/block.rs +++ b/rpc/src/endpoint/block.rs @@ -3,7 +3,8 @@ use serde::{Deserialize, Serialize}; use tendermint::block::{self, Block}; -use crate::{dialect::Dialect, request::RequestMessage}; +use crate::dialect::{self, Dialect}; +use crate::request::RequestMessage; /// Get information about a specific block #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] @@ -29,11 +30,23 @@ impl RequestMessage for Request { } } -impl crate::Request for Request { +impl crate::Request for Request { type Response = Response; } -impl crate::SimpleRequest for Request { +impl crate::Request for Request { + type Response = Response; +} + +impl crate::Request for Request { + type Response = self::v0_38::DialectResponse; +} + +impl crate::SimpleRequest for Request +where + Self: crate::Request, + Response: From, +{ type Output = Response; } @@ -48,3 +61,81 @@ pub struct Response { } impl crate::Response for Response {} + +pub mod v0_38 { + use std::vec::Vec; + + use block::{Commit, Header}; + use tendermint::evidence; + + use tendermint_proto::v0_38::types::Block as RawBlock; + + use super::*; + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct DialectResponse { + /// Block ID + pub block_id: block::Id, + + /// Block data + pub block: DialectBlock, + } + + impl crate::Response for DialectResponse {} + + impl From for Response { + fn from(msg: DialectResponse) -> Self { + Self { + block_id: msg.block_id, + block: msg.block.into(), + } + } + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + #[serde(try_from = "RawBlock", into = "RawBlock")] + pub struct DialectBlock { + /// Block header + pub header: Header, + + /// Transaction data + pub data: Vec>, + + /// Evidence of malfeasance + pub evidence: evidence::List, + + /// Last commit, should be `None` for the initial block. + pub last_commit: Option, + } + + impl From for RawBlock { + fn from(msg: DialectBlock) -> Self { + RawBlock::from(Block::from(msg)) + } + } + + impl TryFrom for DialectBlock { + type Error = >::Error; + + fn try_from(value: RawBlock) -> Result { + Block::try_from(value).map(DialectBlock::from) + } + } + + impl From for Block { + fn from(msg: DialectBlock) -> Self { + Self::new(msg.header, msg.data, msg.evidence, msg.last_commit) + } + } + + impl From for DialectBlock { + fn from(msg: Block) -> Self { + Self { + header: msg.header, + data: msg.data, + evidence: msg.evidence, + last_commit: msg.last_commit, + } + } + } +} diff --git a/rpc/src/endpoint/block_by_hash.rs b/rpc/src/endpoint/block_by_hash.rs index 84a16e212..05786c760 100644 --- a/rpc/src/endpoint/block_by_hash.rs +++ b/rpc/src/endpoint/block_by_hash.rs @@ -6,7 +6,8 @@ use tendermint::{ Hash, }; -use crate::{dialect::Dialect, request::RequestMessage}; +use crate::dialect::{self, Dialect}; +use crate::request::RequestMessage; /// Get information about a specific block by its hash #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] @@ -38,11 +39,23 @@ impl RequestMessage for Request { } } -impl crate::Request for Request { +impl crate::Request for Request { type Response = Response; } -impl crate::SimpleRequest for Request { +impl crate::Request for Request { + type Response = Response; +} + +impl crate::Request for Request { + type Response = self::v0_38::DialectResponse; +} + +impl crate::SimpleRequest for Request +where + Self: crate::Request, + Response: From, +{ type Output = Response; } @@ -57,3 +70,28 @@ pub struct Response { } impl crate::Response for Response {} + +pub mod v0_38 { + use super::*; + use crate::endpoint::block::v0_38::DialectBlock; + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct DialectResponse { + /// Block ID + pub block_id: block::Id, + + /// Block data + pub block: Option, + } + + impl crate::Response for DialectResponse {} + + impl From for Response { + fn from(msg: DialectResponse) -> Self { + Self { + block_id: msg.block_id, + block: msg.block.map(Into::into), + } + } + } +} diff --git a/rpc/src/endpoint/block_results.rs b/rpc/src/endpoint/block_results.rs index a633154f6..9f40509ad 100644 --- a/rpc/src/endpoint/block_results.rs +++ b/rpc/src/endpoint/block_results.rs @@ -40,6 +40,10 @@ impl crate::Request for Request { type Response = Response; } +impl crate::Request for Request { + type Response = Response; +} + impl crate::SimpleRequest for Request where Self: crate::Request, diff --git a/rpc/src/endpoint/block_search.rs b/rpc/src/endpoint/block_search.rs index 2cfc92f0f..6d15117fe 100644 --- a/rpc/src/endpoint/block_search.rs +++ b/rpc/src/endpoint/block_search.rs @@ -2,8 +2,14 @@ use serde::{Deserialize, Serialize}; +use crate::dialect; +use crate::dialect::Dialect; +use crate::prelude::*; +use crate::request::RequestMessage; +use crate::serializers; +use crate::{Method, Order}; + pub use super::{block, block_results}; -use crate::{dialect::Dialect, prelude::*, request::RequestMessage, serializers, Method, Order}; /// Request for searching for blocks by their BeginBlock and EndBlock events. #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] @@ -34,11 +40,23 @@ impl RequestMessage for Request { } } -impl crate::Request for Request { +impl crate::Request for Request { + type Response = Response; +} + +impl crate::Request for Request { type Response = Response; } -impl crate::SimpleRequest for Request { +impl crate::Request for Request { + type Response = self::v0_38::DialectResponse; +} + +impl crate::SimpleRequest for Request +where + Self: crate::Request, + Response: From, +{ type Output = Response; } @@ -50,3 +68,26 @@ pub struct Response { } impl crate::Response for Response {} + +pub mod v0_38 { + use super::*; + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct DialectResponse { + pub blocks: Vec, + + #[serde(with = "serializers::from_str")] + pub total_count: u32, + } + + impl crate::Response for DialectResponse {} + + impl From for Response { + fn from(response: DialectResponse) -> Self { + Response { + blocks: response.blocks.into_iter().map(Into::into).collect(), + total_count: response.total_count, + } + } + } +} diff --git a/rpc/src/endpoint/broadcast/tx_commit.rs b/rpc/src/endpoint/broadcast/tx_commit.rs index a1ffd5ee7..32d769cea 100644 --- a/rpc/src/endpoint/broadcast/tx_commit.rs +++ b/rpc/src/endpoint/broadcast/tx_commit.rs @@ -41,6 +41,10 @@ impl crate::Request for Request { type Response = Response; } +impl crate::Request for Request { + type Response = Response; +} + impl crate::SimpleRequest for Request where Self: crate::Request, diff --git a/rpc/src/endpoint/header.rs b/rpc/src/endpoint/header.rs index ad1506205..372b3a31e 100644 --- a/rpc/src/endpoint/header.rs +++ b/rpc/src/endpoint/header.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use tendermint::block::{self, Header}; -use crate::dialect::v0_37; +use crate::dialect::{v0_37, v0_38, Dialect}; use crate::request::RequestMessage; /// Get information about a specific block @@ -34,7 +34,15 @@ impl crate::Request for Request { type Response = Response; } -impl crate::SimpleRequest for Request { +impl crate::Request for Request { + type Response = Response; +} + +impl crate::SimpleRequest for Request +where + Self: crate::Request, + Response: From, +{ type Output = Response; } diff --git a/rpc/src/endpoint/header_by_hash.rs b/rpc/src/endpoint/header_by_hash.rs index e887944e2..21a2bf361 100644 --- a/rpc/src/endpoint/header_by_hash.rs +++ b/rpc/src/endpoint/header_by_hash.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use tendermint::{block::Header, Hash}; -use crate::dialect::v0_37; +use crate::dialect::{v0_37, v0_38, Dialect}; use crate::request::RequestMessage; /// Get information about a specific block by its hash @@ -40,7 +40,15 @@ impl crate::Request for Request { type Response = Response; } -impl crate::SimpleRequest for Request { +impl crate::Request for Request { + type Response = Response; +} + +impl crate::SimpleRequest for Request +where + Self: crate::Request, + Response: From, +{ type Output = Response; } diff --git a/rpc/src/endpoint/tx.rs b/rpc/src/endpoint/tx.rs index d5bc7630e..c69bf80d4 100644 --- a/rpc/src/endpoint/tx.rs +++ b/rpc/src/endpoint/tx.rs @@ -41,6 +41,10 @@ impl crate::Request for Request { type Response = Response; } +impl crate::Request for Request { + type Response = Response; +} + impl crate::SimpleRequest for Request where Self: crate::Request, diff --git a/rpc/src/endpoint/tx_search.rs b/rpc/src/endpoint/tx_search.rs index e936405db..6a100528a 100644 --- a/rpc/src/endpoint/tx_search.rs +++ b/rpc/src/endpoint/tx_search.rs @@ -56,6 +56,10 @@ impl crate::Request for Request { type Response = Response; } +impl crate::Request for Request { + type Response = Response; +} + impl crate::SimpleRequest for Request where Self: crate::Request, diff --git a/rpc/tests/kvstore_fixtures/v0_37/incoming/block_search_evidence.json b/rpc/tests/kvstore_fixtures/v0_37/incoming/block_search_evidence.json new file mode 100644 index 000000000..7363a261a --- /dev/null +++ b/rpc/tests/kvstore_fixtures/v0_37/incoming/block_search_evidence.json @@ -0,0 +1,170 @@ +{ + "jsonrpc": "2.0", + "id": "4aa76fe8-0ad1-4888-a610-49e41aab79be", + "result": { + "blocks": [ + { + "block_id": { + "hash": "13B17D2A7FF6F58F14A88D29B53CBA328776E391DE09D73D43CA5BB54B760F4D", + "parts": { + "total": 1, + "hash": "207A23AE9F86FC843DBBCA7BB63164807492EE340C9193ACF8281C8755C5F7E7" + } + }, + "block": { + "header": { + "version": { + "block": "11" + }, + "chain_id": "provider", + "height": "8011", + "time": "2022-09-12T19:49:56.057476304Z", + "last_block_id": { + "hash": "0F7E242B58D28545269E89CD131DFB662F5221166F26E0CF374EA8402EED5200", + "parts": { + "total": 1, + "hash": "57D5DA87B690945E8C6C1C85924C47B8B3A885E4149D12C207CED8EEB0C4FB5B" + } + }, + "last_commit_hash": "7E929B00540980E5D8B6F35200C371A57C3FDDA38F6E16B5058BDDA56CF3FEA2", + "data_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", + "validators_hash": "1BD8973AC098D625531DFAE3B57551E90136667C554ED268C9A8A5E94E9BE948", + "next_validators_hash": "1BD8973AC098D625531DFAE3B57551E90136667C554ED268C9A8A5E94E9BE948", + "consensus_hash": "048091BC7DDC283F77BFBF91D73C44DA58C3DF8A9CBC867405D8B7F3DAADA22F", + "app_hash": "69EF014ECC4C2EFE97EC253CABE132118D9A57A82A06D2ABA777E6E209B233A7", + "last_results_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", + "evidence_hash": "91D5E877F2C5634E2666A7B4E684D1FB545E2B859514E526BE15CF09C6A37AB6", + "proposer_address": "B218725A22B9319FC8340E83601588438FEF11BD" + }, + "data": { + "txs": [] + }, + "evidence": { + "evidence": [ + { + "type": "tendermint/DuplicateVoteEvidence", + "value": { + "vote_a": { + "type": 2, + "height": "8009", + "round": 0, + "block_id": { + "hash": "", + "parts": { + "total": 0, + "hash": "" + } + }, + "timestamp": "2022-09-07T22:52:09.078399096Z", + "validator_address": "9319035301DA526CC78DCF174A47A74F81401291", + "validator_index": 8, + "signature": "wjyIJ6WxLl38O0gKAWPmCjP0c3HhTfyNjRfc5LlDzQ4jw/7XHmu4tNbW8NV1C7DeuceLYT2OGAAgf1g1R7QXDw==" + }, + "vote_b": { + "type": 2, + "height": "8009", + "round": 0, + "block_id": { + "hash": "7A2840217294E52F4E4C2F1E9B3E7DFEC0B34605B66EC042B02EF82B7C5E70FB", + "parts": { + "total": 1, + "hash": "1B20410D8B8876F51E5272A86E2C73CFF00783DD8D1BF09C6638B812606A9CFB" + } + }, + "timestamp": "2022-09-12T19:49:53.28054099Z", + "validator_address": "9319035301DA526CC78DCF174A47A74F81401291", + "validator_index": 8, + "signature": "9Ugzwmw3N4FZrK5VxMmUYLU8MjlT+I03VoQmqt9nDQSHexVDRaZPnMDiP13lci9IKhnBKG8wVTldJKv0ystKDQ==" + }, + "TotalVotingPower": "121", + "ValidatorPower": "1", + "Timestamp": "2022-09-12T19:49:49.984608464Z" + } + } + ] + }, + "last_commit": { + "height": "8010", + "round": 0, + "block_id": { + "hash": "0F7E242B58D28545269E89CD131DFB662F5221166F26E0CF374EA8402EED5200", + "parts": { + "total": 1, + "hash": "57D5DA87B690945E8C6C1C85924C47B8B3A885E4149D12C207CED8EEB0C4FB5B" + } + }, + "signatures": [ + { + "block_id_flag": 2, + "validator_address": "B218725A22B9319FC8340E83601588438FEF11BD", + "timestamp": "2022-09-12T19:49:56.057476304Z", + "signature": "vMva0A+SVY382TuluaOTpnLiahWSFDwLQoSLUyuRGC7QwS4FCZ326kONExt7DMOF2e1DoxfmDv2VbBwsisEzCg==" + }, + { + "block_id_flag": 3, + "validator_address": "A49DAB77379B869F28E2AA35BF4D7F07866B0C10", + "timestamp": "2022-09-12T19:49:56.325571749Z", + "signature": "jhynVaXG3eN69pRG55wRHZX4lUxmQwol2E8Q3W56axYAGd28YxSmCDnC+SRh85+EBBFGhM79OkcP0xbvxNv+CQ==" + }, + { + "block_id_flag": 3, + "validator_address": "ED46DA41B6942355F8308433764A18318223D9EB", + "timestamp": "2022-09-12T19:49:56.147905252Z", + "signature": "WwaxUwcyPBiwOV5XnZBO+rYPWhlnhBG3VIz5cr/c1vd7gtPrdvqYlRlFNr0rGloU9R3FKqdkdMZdGZhCRs+eCw==" + }, + { + "block_id_flag": 3, + "validator_address": "090AA8D83370208D7B5907072666C8CCE92B0AE4", + "timestamp": "2022-09-12T19:49:56.30837796Z", + "signature": "iADSIvtFsCN7LYMoj4sYc7mzn+k5v40twSmRSRpkcA58O3x1zxPjOXHOXi9Q36qCMRtTHhouUWLEgXhOb0/wCg==" + }, + { + "block_id_flag": 3, + "validator_address": "54443EF34125BDBDF74D8E1FD1EC3857160EF3CC", + "timestamp": "2022-09-12T19:49:56.328293863Z", + "signature": "agsLAHg5/7TeKCJM9UAUeUsGW7EVpmo+F84s9IHpSMIaEItNXdP7JOJrb62UNXJzPRdNJYGPfaFKeUUrs9m/DA==" + }, + { + "block_id_flag": 3, + "validator_address": "A2CE10C56A0F44BA30116535DC67409130BF5E7E", + "timestamp": "2022-09-12T19:49:56.273003947Z", + "signature": "jQDmNCeQ+w62W5bMvQ5JpTD/Jv1KyKfwWO9yswQkbI9yodk6j7ElnlfJ8vzlK9a7iea0SEt6YGRWfhH9uq7LDA==" + }, + { + "block_id_flag": 3, + "validator_address": "E4C657BC63B89319BE7C62E48DF5CE85B1543D00", + "timestamp": "2022-09-12T19:49:56.266262774Z", + "signature": "ZHpV742hZPrLvu3jfMofGHUA8MzIDVxQXgfPG+wCwDyiP9NQlpvceUX53nJ9MW58A80soN17KZvt1Np+PUweBw==" + }, + { + "block_id_flag": 3, + "validator_address": "0ED9646BBC2A58146C5F67E66BF4EC33AD83368D", + "timestamp": "2022-09-12T19:49:56.273836856Z", + "signature": "jXeBSvHO43NfLEwZJAeGmBQ/rQHDoHVNZ0c3JjJwt5kOAVOONAG/iL4tZj9/f4qZZFBaueU8zcANQllzL/S7AQ==" + }, + { + "block_id_flag": 3, + "validator_address": "9319035301DA526CC78DCF174A47A74F81401291", + "timestamp": "2022-09-07T22:52:12.094618273Z", + "signature": "BRySEQjgpaqCy2huVg6v+Wpksrql8NMlIaJbHEsCqqmAeb7ieS/SHOPAgho8fQ1ODzWsL4PiXwYO9Fgx0Ll7DQ==" + }, + { + "block_id_flag": 3, + "validator_address": "9901CCDA42B948EDDC835FB5C8AB06730A9C23CD", + "timestamp": "2022-09-12T19:49:56.165888573Z", + "signature": "Uhsp575gJkKG67YB6iuuj8ojp8Su46LRWgH6rK6eizxpG8cFmRdpRWsu/G29zx7r44sxtqa6RjxYdkanQdpSCg==" + }, + { + "block_id_flag": 3, + "validator_address": "F7DF9EF920DFBCDCA1F382151685A69500BAF630", + "timestamp": "2022-09-12T19:49:56.156036054Z", + "signature": "vtyX9kzMUyb2Sksly7fUZkXhs8e29Eu3dmi4mu9zBvYSwc8vI3GTckSutDMb6jgDv3qD7SjYGhX89TbproUiCg==" + } + ] + } + } + } + ], + "total_count": "1" + } +} diff --git a/rpc/tests/kvstore_fixtures/v0_38.rs b/rpc/tests/kvstore_fixtures/v0_38.rs index 8bece5bc1..b8827fea8 100644 --- a/rpc/tests/kvstore_fixtures/v0_38.rs +++ b/rpc/tests/kvstore_fixtures/v0_38.rs @@ -332,7 +332,7 @@ fn incoming_fixtures() { } }, "block_at_height_1" => { - let result = endpoint::block::Response::from_string(content).unwrap(); + let result = endpoint::block::v0_38::DialectResponse::from_string(content).unwrap(); assert!(result.block.data.first().is_none()); assert!(result.block.evidence.iter().next().is_none()); assert_eq!(result.block.header.app_hash.as_bytes(), [0u8; 8]); @@ -373,7 +373,7 @@ fn incoming_fixtures() { assert_eq!(result.block_id.part_set_header.total, 1); }, "block_at_height_10" => { - let result = endpoint::block::Response::from_string(content).unwrap(); + let result = endpoint::block::v0_38::DialectResponse::from_string(content).unwrap(); assert!(result.block.data.first().is_none()); assert!(result.block.evidence.iter().next().is_none()); assert_eq!(result.block.header.app_hash.as_bytes(), &[0u8; 8]); @@ -429,21 +429,24 @@ fn incoming_fixtures() { assert!(result.validator_updates.is_empty()); }, "block_by_hash" => { - let result = endpoint::block_by_hash::Response::from_string(content).unwrap(); + let result = + endpoint::block_by_hash::v0_38::DialectResponse::from_string(content).unwrap(); assert_eq!( result.block_id.hash.to_string(), "47493B51E102705F6DCCE5981E05B7C025BB5BF19CF5E4B54FE28CAFE9D20C8A" ); }, "block_search" => { - let result = endpoint::block_search::Response::from_string(content).unwrap(); + let result = + endpoint::block_search::v0_38::DialectResponse::from_string(content).unwrap(); assert_eq!(result.total_count as usize, result.blocks.len()); for response in result.blocks { assert!(response.block.header.height.value() > 1); } }, "block_search_evidence" => { - let result = endpoint::block_search::Response::from_string(content).unwrap(); + let result = + endpoint::block_search::v0_38::DialectResponse::from_string(content).unwrap(); assert_eq!(result.total_count as usize, result.blocks.len()); // Test a few selected attributes of the results. @@ -454,21 +457,21 @@ fn incoming_fixtures() { fn check_vote(vote: &Vote) { assert_eq!(vote.vote_type, vote::Type::Precommit); - assert_eq!(vote.height.value(), 8009); + assert_eq!(vote.height.value(), 547); assert_eq!(vote.round.value(), 0); assert_eq!( vote.validator_address, - "9319035301DA526CC78DCF174A47A74F81401291".parse().unwrap(), + "C888306A908A217B9A943D1DAD8790044D0947A4".parse().unwrap(), ); - assert_eq!(vote.validator_index.value(), 8); + assert_eq!(vote.validator_index.value(), 2); } if let Evidence::DuplicateVote(dup) = evidence { - assert_eq!(dup.total_voting_power.value(), 121); - assert_eq!(dup.validator_power.value(), 1); + assert_eq!(dup.total_voting_power.value(), 1509); + assert_eq!(dup.validator_power.value(), 99); assert_eq!( dup.timestamp, - "2022-09-12T19:49:49.984608464Z".parse().unwrap() + "2024-09-13T15:58:27.05956617Z".parse().unwrap() ); check_vote(&dup.vote_a); diff --git a/rpc/tests/kvstore_fixtures/v0_38/incoming/block_search_evidence.json b/rpc/tests/kvstore_fixtures/v0_38/incoming/block_search_evidence.json new file mode 100644 index 000000000..1f86d052c --- /dev/null +++ b/rpc/tests/kvstore_fixtures/v0_38/incoming/block_search_evidence.json @@ -0,0 +1,126 @@ +{ + "jsonrpc": "2.0", + "id": "c360ec3e-cf3b-4213-9bf5-1a4bc2a74e3d", + "result": { + "blocks": [ + { + "block_id": { + "hash": "9A32DFAD3F04AB0573D91D08F12766A159E5ADFE4FA14DFD569B234DA5933ADB", + "parts": { + "total": 1, + "hash": "D3C3646B934B783DF7F469EF0BC610AE0CE713A5DDE2A452B5F9395513CF542E" + } + }, + "block": { + "header": { + "version": { + "block": "11" + }, + "chain_id": "provi", + "height": "549", + "time": "2024-09-13T15:58:29.677606671Z", + "last_block_id": { + "hash": "02E7201800A013798DE9CC5E158D227F465C6082C02891C27967CBB2E8D8322E", + "parts": { + "total": 1, + "hash": "F60555618ED4ABB2BECBA4A5D3C8B366FD1B2040F660774275B02ADEB6E8F1CA" + } + }, + "last_commit_hash": "BA41D70D0B4133C8E088D627034AD9B0AB1C4B7B471F11CBE078E54FB78F8459", + "data_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", + "validators_hash": "CD0FED96CC6A2F96F9D6220901E3FF609DC6B8C80A32D90C9F466ED14F97AF30", + "next_validators_hash": "FAE16F233FBF640966E76C54102B09010A54786E227A26227353E4BD4F0EDF54", + "consensus_hash": "048091BC7DDC283F77BFBF91D73C44DA58C3DF8A9CBC867405D8B7F3DAADA22F", + "app_hash": "EEDC3EA34934725E9D2BF94C1D861B9E4438D7CBB76275B7F6C0C9EE23134238", + "last_results_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", + "evidence_hash": "051CD844C65A51852281128722BC6BE700F2CC288F6C4AB808E06D9EF82170E5", + "proposer_address": "99BD3A72EF12CD024E7584B3AC900AE3743C6ADF" + }, + "data": { + "txs": [] + }, + "evidence": { + "evidence": [ + { + "type": "tendermint/DuplicateVoteEvidence", + "value": { + "vote_a": { + "type": 2, + "height": "547", + "round": 0, + "block_id": { + "hash": "", + "parts": { + "total": 0, + "hash": "" + } + }, + "timestamp": "2024-09-13T15:58:28.469186921Z", + "validator_address": "C888306A908A217B9A943D1DAD8790044D0947A4", + "validator_index": 2, + "signature": "hU7N6J45TKKHg7/xsbzLzSvZsu5xJhDC1wSUFpYLqM/tcadaugwn7BDRwXFheKVdoGVR/b4g83bXMNeOOICABg==", + "extension": null, + "extension_signature": null + }, + "vote_b": { + "type": 2, + "height": "547", + "round": 0, + "block_id": { + "hash": "36A6DC9D9DC15034156C81083294FE0F48F62CBBECBAB58D50E6873323ADC1DE", + "parts": { + "total": 1, + "hash": "BA930F53061BDAEFB9C761E44CAB36817009DAC8BDE1B1E16B2A527B4B30F30C" + } + }, + "timestamp": "2024-09-13T15:58:28.364807546Z", + "validator_address": "C888306A908A217B9A943D1DAD8790044D0947A4", + "validator_index": 2, + "signature": "0xL4svhxUvQrsZFZqXaer+pKI00d4j0Xi03uqYIIMzB0YKgGqVlJfC828oJiZTX3iD9bt/xQK72eKMqhdXS3Cg==", + "extension": null, + "extension_signature": null + }, + "total_voting_power": "1509", + "validator_power": "99", + "timestamp": "2024-09-13T15:58:27.05956617Z" + } + } + ] + }, + "last_commit": { + "height": "548", + "round": 0, + "block_id": { + "hash": "02E7201800A013798DE9CC5E158D227F465C6082C02891C27967CBB2E8D8322E", + "parts": { + "total": 1, + "hash": "F60555618ED4ABB2BECBA4A5D3C8B366FD1B2040F660774275B02ADEB6E8F1CA" + } + }, + "signatures": [ + { + "block_id_flag": 2, + "validator_address": "06C0F3E47CC5C748269088DC2F36411D3AAA27C6", + "timestamp": "2024-09-13T15:58:29.677606671Z", + "signature": "9v+PFHLp0ySOxvVaUy0khcShvAUcR3lNETQjjqD2OcYvwUSsSta3/mCtuDESCN6FVl/08NkjkPmsRr0Adih5Dg==" + }, + { + "block_id_flag": 2, + "validator_address": "99BD3A72EF12CD024E7584B3AC900AE3743C6ADF", + "timestamp": "2024-09-13T15:58:29.574657588Z", + "signature": "iMYwtOEjrElYQfv5dr41AJbWn5QHQFbpDh1GDtH+oF+E8jmda7dA5KUZWN4FuHwKUi+cLqkNr0AifK6izhDSCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "C888306A908A217B9A943D1DAD8790044D0947A4", + "timestamp": "2024-09-13T15:58:29.575293338Z", + "signature": "gIOsYg44s2yPbwFH1z8sNqgFb8BCmFtL5GyUoMfIk8AOM255eOpTBdc8a4uN/aVvKFLlVdY+zocLbXro7T1cCA==" + } + ] + } + } + } + ], + "total_count": "1" + } +} diff --git a/tools/proto-compiler/src/constants.rs b/tools/proto-compiler/src/constants.rs index edc603b03..279b2ef22 100644 --- a/tools/proto-compiler/src/constants.rs +++ b/tools/proto-compiler/src/constants.rs @@ -19,17 +19,17 @@ pub const TENDERMINT_VERSIONS: &[TendermintVersion] = &[ TendermintVersion { repo: "https://github.com/cometbft/cometbft", ident: "v0_34", - commitish: "v0.34.29", + commitish: "v0.34.35", }, TendermintVersion { repo: "https://github.com/cometbft/cometbft", ident: "v0_37", - commitish: "v0.37.2", + commitish: "v0.37.11", }, TendermintVersion { repo: "https://github.com/cometbft/cometbft", ident: "v0_38", - commitish: "v0.38.0", + commitish: "v0.38.12", }, ]; @@ -65,7 +65,12 @@ const RENAME_TOTAL_VOTING_POWER_QUOTED: &str = r#"#[serde(rename = "TotalVotingPower", with = "crate::serializers::from_str")]"#; const RENAME_VALIDATOR_POWER_QUOTED: &str = r#"#[serde(rename = "ValidatorPower", with = "crate::serializers::from_str")]"#; +const ALIAS_TOTAL_VOTING_POWER_QUOTED: &str = + r#"#[serde(alias = "TotalVotingPower", with = "crate::serializers::from_str")]"#; +const ALIAS_VALIDATOR_POWER_QUOTED: &str = + r#"#[serde(alias = "ValidatorPower", with = "crate::serializers::from_str")]"#; const RENAME_TIMESTAMP: &str = r#"#[serde(rename = "Timestamp")]"#; +const ALIAS_TIMESTAMP: &str = r#"#[serde(alias = "Timestamp")]"#; const RENAME_PARTS: &str = r#"#[serde(rename = "parts", alias = "part_set_header")]"#; /// Custom type attributes applied on top of protobuf structs @@ -73,7 +78,7 @@ const RENAME_PARTS: &str = r#"#[serde(rename = "parts", alias = "part_set_header /// the second item is the string that should be added as annotation. /// The first item is a path as defined in the prost_build::Config::btree_map here: /// https://docs.rs/prost-build/0.6.1/prost_build/struct.Config.html#method.btree_map -pub static CUSTOM_TYPE_ATTRIBUTES: &[(&str, &str)] = &[ +pub static CUSTOM_TYPE_ATTRIBUTES_COMMON: &[(&str, &str)] = &[ (".tendermint.abci", SERIALIZED), (".tendermint.crypto.Proof", SERIALIZED), (".tendermint.crypto.ProofOp", SERIALIZED), @@ -101,10 +106,6 @@ pub static CUSTOM_TYPE_ATTRIBUTES: &[(&str, &str)] = &[ (".tendermint.types.Header", SERIALIZED), (".tendermint.types.LightBlock", SERIALIZED), (".tendermint.types.LightClientAttackEvidence", SERIALIZED), - ( - ".tendermint.types.LightClientAttackEvidence", - RENAME_ALL_PASCALCASE, - ), (".tendermint.types.PartSetHeader", SERIALIZED), (".tendermint.types.SignedHeader", SERIALIZED), (".tendermint.types.TxProof", SERIALIZED), @@ -117,6 +118,18 @@ pub static CUSTOM_TYPE_ATTRIBUTES: &[(&str, &str)] = &[ (".tendermint.version.Consensus", SERIALIZED), ]; +pub static CUSTOM_TYPE_ATTRIBUTES_V_034: &[(&str, &str)] = &[( + ".tendermint.types.LightClientAttackEvidence", + RENAME_ALL_PASCALCASE, +)]; + +pub static CUSTOM_TYPE_ATTRIBUTES_V_037: &[(&str, &str)] = &[( + ".tendermint.types.LightClientAttackEvidence", + RENAME_ALL_PASCALCASE, +)]; + +pub static CUSTOM_TYPE_ATTRIBUTES_V_038: &[(&str, &str)] = &[]; + /// Custom field attributes applied on top of protobuf fields in (a) struct(s) /// The first item in the tuple defines the field where the annotation should apply and /// the second item is the string that should be added as annotation. @@ -174,16 +187,12 @@ pub static CUSTOM_FIELD_ATTRIBUTES: &[(&str, &str)] = &[ (".tendermint.types.CommitSig.timestamp", OPTIONAL), (".tendermint.types.CommitSig.signature", BASE64STRING), ( - ".tendermint.types.DuplicateVoteEvidence.total_voting_power", - RENAME_TOTAL_VOTING_POWER_QUOTED, - ), - ( - ".tendermint.types.DuplicateVoteEvidence.validator_power", - RENAME_VALIDATOR_POWER_QUOTED, + ".tendermint.types.Evidence.sum.duplicate_vote_evidence", + RENAME_DUPLICATEVOTE, ), ( - ".tendermint.types.DuplicateVoteEvidence.timestamp", - RENAME_TIMESTAMP, + ".tendermint.types.Evidence.sum.light_client_attack_evidence", + RENAME_LIGHTCLIENTATTACK, ), ( ".tendermint.types.LightClientAttackEvidence.common_height", @@ -197,6 +206,8 @@ pub static CUSTOM_FIELD_ATTRIBUTES: &[(&str, &str)] = &[ (".tendermint.types.Vote.validator_address", HEXSTRING), (".tendermint.types.Vote.signature", BASE64STRING), (".tendermint.types.Vote.timestamp", OPTIONAL), + (".tendermint.types.Vote.extension", NULLABLE), + (".tendermint.types.Vote.extension_signature", NULLABLE), (".tendermint.types.Validator.address", HEXSTRING), ( ".tendermint.types.Validator.voting_power", @@ -224,14 +235,6 @@ pub static CUSTOM_FIELD_ATTRIBUTES: &[(&str, &str)] = &[ RENAME_SECPPUBKEY, ), (".tendermint.crypto.PublicKey.sum.sr25519", RENAME_SRPUBKEY), - ( - ".tendermint.types.Evidence.sum.duplicate_vote_evidence", - RENAME_DUPLICATEVOTE, - ), - ( - ".tendermint.types.Evidence.sum.light_client_attack_evidence", - RENAME_LIGHTCLIENTATTACK, - ), (".tendermint.types.TxProof.data", BASE64STRING), (".tendermint.types.TxProof.root_hash", HEXSTRING), (".tendermint.crypto.Proof.index", QUOTED), @@ -239,3 +242,66 @@ pub static CUSTOM_FIELD_ATTRIBUTES: &[(&str, &str)] = &[ (".tendermint.crypto.Proof.aunts", VEC_BASE64STRING), (".tendermint.crypto.Proof.leaf_hash", BASE64STRING), ]; + +pub static CUSTOM_FIELD_ATTRIBUTES_V_034: &[(&str, &str)] = &[ + ( + ".tendermint.types.DuplicateVoteEvidence.total_voting_power", + RENAME_TOTAL_VOTING_POWER_QUOTED, + ), + ( + ".tendermint.types.DuplicateVoteEvidence.validator_power", + RENAME_VALIDATOR_POWER_QUOTED, + ), + ( + ".tendermint.types.DuplicateVoteEvidence.timestamp", + RENAME_TIMESTAMP, + ), +]; + +pub static CUSTOM_FIELD_ATTRIBUTES_V_037: &[(&str, &str)] = &[ + ( + ".tendermint.types.DuplicateVoteEvidence.total_voting_power", + RENAME_TOTAL_VOTING_POWER_QUOTED, + ), + ( + ".tendermint.types.DuplicateVoteEvidence.validator_power", + RENAME_VALIDATOR_POWER_QUOTED, + ), + ( + ".tendermint.types.DuplicateVoteEvidence.timestamp", + RENAME_TIMESTAMP, + ), +]; + +pub static CUSTOM_FIELD_ATTRIBUTES_V_038: &[(&str, &str)] = &[ + ( + ".tendermint.types.DuplicateVoteEvidence.total_voting_power", + ALIAS_TOTAL_VOTING_POWER_QUOTED, + ), + ( + ".tendermint.types.DuplicateVoteEvidence.validator_power", + ALIAS_VALIDATOR_POWER_QUOTED, + ), + ( + ".tendermint.types.DuplicateVoteEvidence.timestamp", + ALIAS_TIMESTAMP, + ), +]; + +pub fn get_custom_field_attributes(version: &TendermintVersion) -> &[(&str, &str)] { + match version.ident { + "v0_34" => CUSTOM_FIELD_ATTRIBUTES_V_034, + "v0_37" => CUSTOM_FIELD_ATTRIBUTES_V_037, + "v0_38" => CUSTOM_FIELD_ATTRIBUTES_V_038, + _ => unreachable!(), + } +} + +pub fn get_custom_type_attributes(version: &TendermintVersion) -> &[(&str, &str)] { + match version.ident { + "v0_34" => CUSTOM_TYPE_ATTRIBUTES_V_034, + "v0_37" => CUSTOM_TYPE_ATTRIBUTES_V_037, + "v0_38" => CUSTOM_TYPE_ATTRIBUTES_V_038, + _ => unreachable!(), + } +} diff --git a/tools/proto-compiler/src/main.rs b/tools/proto-compiler/src/main.rs index 4d1439a14..f952413a6 100644 --- a/tools/proto-compiler/src/main.rs +++ b/tools/proto-compiler/src/main.rs @@ -16,7 +16,7 @@ use functions::{ }; mod constants; -use constants::{CUSTOM_FIELD_ATTRIBUTES, CUSTOM_TYPE_ATTRIBUTES, TENDERMINT_VERSIONS}; +use constants::*; fn main() { let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); @@ -35,7 +35,8 @@ fn main() { "[info] => Fetching {} at {} into {tendermint_dir:?}", version.repo, version.commitish, ); - get_commitish(&tendermint_dir, &version.repo, &version.commitish); // This panics if it fails. + + get_commitish(&tendermint_dir, version.repo, version.commitish); // This panics if it fails. let proto_path = tendermint_dir.join("proto"); @@ -90,22 +91,35 @@ fn main() { // Compile proto files with added annotations, exchange prost_types to our own pb.out_dir(&out_dir); - for type_attribute in CUSTOM_TYPE_ATTRIBUTES { + + for type_attribute in CUSTOM_TYPE_ATTRIBUTES_COMMON { pb.type_attribute(type_attribute.0, type_attribute.1); } + + for type_attribute in get_custom_type_attributes(version) { + pb.type_attribute(type_attribute.0, type_attribute.1); + } + for field_attribute in CUSTOM_FIELD_ATTRIBUTES { pb.field_attribute(field_attribute.0, field_attribute.1); } + + for field_attribute in get_custom_field_attributes(version) { + pb.field_attribute(field_attribute.0, field_attribute.1); + } + // The below in-place path redirection replaces references to the // Duration, Timestamp, and Any "well-know types" with our own versions. pb.extern_path( ".google.protobuf.Duration", "crate::google::protobuf::Duration", ); + pb.extern_path( ".google.protobuf.Timestamp", "crate::google::protobuf::Timestamp", ); + pb.extern_path(".google.protobuf.Any", "crate::google::protobuf::Any"); println!("[info] => Creating structs and interfaces."); @@ -133,6 +147,7 @@ fn main() { copy_files(&out_dir, &ver_target_dir); // This panics if it fails. generate_tendermint_mod(&out_dir, version, &ver_module_dir); } + generate_tendermint_lib(TENDERMINT_VERSIONS, &target_dir.join("tendermint.rs")); println!("[info] => Done!");