From 6d755a2564403ed40c60d09c462d2755c2f82dee Mon Sep 17 00:00:00 2001 From: Mikhail Zabaluev Date: Fri, 5 May 2023 00:07:04 +0300 Subject: [PATCH] tendermint: add v0_38 request types Add the v0_38::abci::Request enum and the new request domain types representing request messages added in CometBFT 0.38. --- tendermint/src/abci.rs | 4 +- tendermint/src/abci/doc/request-extendvote.md | 1 + .../src/abci/doc/request-finalizeblock.md | 1 + .../abci/doc/request-verifyvoteextension.md | 1 + tendermint/src/abci/request.rs | 12 + tendermint/src/abci/request/extend_vote.rs | 40 +++ tendermint/src/abci/request/finalize_block.rs | 85 +++++++ .../src/abci/request/prepare_proposal.rs | 136 ++++++---- .../src/abci/request/process_proposal.rs | 136 ++++++---- .../src/abci/request/verify_vote_extension.rs | 47 ++++ tendermint/src/lib.rs | 1 + tendermint/src/v0_34/abci/request.rs | 21 +- tendermint/src/v0_37/abci/request.rs | 5 +- tendermint/src/v0_38.rs | 1 + tendermint/src/v0_38/abci.rs | 5 + tendermint/src/v0_38/abci/request.rs | 232 ++++++++++++++++++ tendermint/src/v0_38/abci/response.rs | 204 +++++++++++++++ 17 files changed, 841 insertions(+), 91 deletions(-) create mode 100644 tendermint/src/abci/doc/request-extendvote.md create mode 100644 tendermint/src/abci/doc/request-finalizeblock.md create mode 100644 tendermint/src/abci/doc/request-verifyvoteextension.md create mode 100644 tendermint/src/abci/request/extend_vote.rs create mode 100644 tendermint/src/abci/request/finalize_block.rs create mode 100644 tendermint/src/abci/request/verify_vote_extension.rs create mode 100644 tendermint/src/v0_38.rs create mode 100644 tendermint/src/v0_38/abci.rs create mode 100644 tendermint/src/v0_38/abci/request.rs create mode 100644 tendermint/src/v0_38/abci/response.rs diff --git a/tendermint/src/abci.rs b/tendermint/src/abci.rs index fd347398d..6019cfde0 100644 --- a/tendermint/src/abci.rs +++ b/tendermint/src/abci.rs @@ -44,8 +44,8 @@ pub mod request; pub mod response; pub mod types; -pub use crate::v0_37::abci::request::Request; -pub use crate::v0_37::abci::response::Response; +pub use crate::v0_38::abci::request::Request; +pub use crate::v0_38::abci::response::Response; pub use event::{Event, EventAttribute, EventAttributeIndexExt, TypedEvent}; diff --git a/tendermint/src/abci/doc/request-extendvote.md b/tendermint/src/abci/doc/request-extendvote.md new file mode 100644 index 000000000..2a390a1e2 --- /dev/null +++ b/tendermint/src/abci/doc/request-extendvote.md @@ -0,0 +1 @@ +[ABCI documentation](https://github.com/cometbft/cometbft/blob/v0.38.x/spec/abci/abci++_methods.md#extendvote) diff --git a/tendermint/src/abci/doc/request-finalizeblock.md b/tendermint/src/abci/doc/request-finalizeblock.md new file mode 100644 index 000000000..c6b89c887 --- /dev/null +++ b/tendermint/src/abci/doc/request-finalizeblock.md @@ -0,0 +1 @@ +[ABCI documentation](https://github.com/cometbft/cometbft/blob/v0.38.x/spec/abci/abci++_methods.md#finalizeblock) diff --git a/tendermint/src/abci/doc/request-verifyvoteextension.md b/tendermint/src/abci/doc/request-verifyvoteextension.md new file mode 100644 index 000000000..66affbb35 --- /dev/null +++ b/tendermint/src/abci/doc/request-verifyvoteextension.md @@ -0,0 +1 @@ +[ABCI documentation](https://github.com/cometbft/cometbft/blob/v0.38.x/spec/abci/abci++_methods.md#verifyvoteextension) diff --git a/tendermint/src/abci/request.rs b/tendermint/src/abci/request.rs index 40f9bbdcf..1e1cde728 100644 --- a/tendermint/src/abci/request.rs +++ b/tendermint/src/abci/request.rs @@ -26,6 +26,8 @@ pub(super) mod check_tx; pub(super) mod deliver_tx; pub(super) mod echo; pub(super) mod end_block; +pub(super) mod extend_vote; +pub(super) mod finalize_block; pub(super) mod info; pub(super) mod init_chain; pub(super) mod load_snapshot_chunk; @@ -34,6 +36,7 @@ pub(super) mod prepare_proposal; pub(super) mod process_proposal; pub(super) mod query; pub(super) mod set_option; +pub(super) mod verify_vote_extension; pub use apply_snapshot_chunk::ApplySnapshotChunk; pub use begin_block::BeginBlock; @@ -41,6 +44,8 @@ pub use check_tx::{CheckTx, CheckTxKind}; pub use deliver_tx::DeliverTx; pub use echo::Echo; pub use end_block::EndBlock; +pub use extend_vote::ExtendVote; +pub use finalize_block::FinalizeBlock; pub use info::Info; pub use init_chain::InitChain; pub use load_snapshot_chunk::LoadSnapshotChunk; @@ -49,6 +54,7 @@ pub use prepare_proposal::PrepareProposal; pub use process_proposal::ProcessProposal; pub use query::Query; pub use set_option::SetOption; +pub use verify_vote_extension::VerifyVoteExtension; /// The consensus category of ABCI requests. #[allow(clippy::large_enum_variant)] @@ -68,6 +74,12 @@ pub enum ConsensusRequest { EndBlock(EndBlock), #[doc = include_str!("doc/request-commit.md")] Commit, + #[doc = include_str!("doc/request-extendvote.md")] + ExtendVote(ExtendVote), + #[doc = include_str!("doc/request-verifyvoteextension.md")] + VerifyVoteExtension(VerifyVoteExtension), + #[doc = include_str!("doc/request-finalizeblock.md")] + FinalizeBlock(FinalizeBlock), } /// The mempool category of ABCI requests. diff --git a/tendermint/src/abci/request/extend_vote.rs b/tendermint/src/abci/request/extend_vote.rs new file mode 100644 index 000000000..5f7fef403 --- /dev/null +++ b/tendermint/src/abci/request/extend_vote.rs @@ -0,0 +1,40 @@ +use crate::{block, Hash}; + +#[doc = include_str!("../doc/request-extendvote.md")] +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct ExtendVote { + pub hash: Hash, + pub height: block::Height, +} + +// ============================================================================= +// Protobuf conversions +// ============================================================================= + +mod v0_38 { + use super::ExtendVote; + use tendermint_proto::v0_38 as pb; + use tendermint_proto::Protobuf; + + impl From for pb::abci::RequestExtendVote { + fn from(extend_vote: ExtendVote) -> Self { + Self { + hash: extend_vote.hash.into(), + height: extend_vote.height.into(), + } + } + } + + impl TryFrom for ExtendVote { + type Error = crate::Error; + + fn try_from(message: pb::abci::RequestExtendVote) -> Result { + Ok(Self { + hash: message.hash.try_into()?, + height: message.height.try_into()?, + }) + } + } + + impl Protobuf for ExtendVote {} +} diff --git a/tendermint/src/abci/request/finalize_block.rs b/tendermint/src/abci/request/finalize_block.rs new file mode 100644 index 000000000..9bc829a90 --- /dev/null +++ b/tendermint/src/abci/request/finalize_block.rs @@ -0,0 +1,85 @@ +use crate::prelude::*; +use crate::{ + abci::types::{CommitInfo, Misbehavior}, + account, block, Hash, Time, +}; +use bytes::Bytes; + +#[doc = include_str!("../doc/request-finalizeblock.md")] +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct FinalizeBlock { + /// List of transactions committed as part of the block. + pub txs: Vec, + /// Information about the last commit, obtained from the block that was just decided. + /// + /// This includes the round, the list of validators, and which validators + /// signed the last block. + pub decided_last_commit: CommitInfo, + /// Evidence of validator misbehavior. + pub misbehavior: Vec, + /// Merkle root hash of the fields of the decided block. + pub hash: Hash, + /// The height of the finalized block. + pub height: block::Height, + /// Timestamp of the finalized block. + pub time: Time, + /// Merkle root of the next validator set. + pub next_validators_hash: Hash, + /// The address of the public key of the original proposer of the block. + pub proposer_address: account::Id, +} + +// ============================================================================= +// Protobuf conversions +// ============================================================================= + +mod v0_38 { + use super::FinalizeBlock; + use crate::Error; + use tendermint_proto::v0_38 as pb; + use tendermint_proto::Protobuf; + + impl From for pb::abci::RequestFinalizeBlock { + fn from(value: FinalizeBlock) -> Self { + Self { + txs: value.txs, + decided_last_commit: Some(value.decided_last_commit.into()), + misbehavior: value.misbehavior.into_iter().map(Into::into).collect(), + hash: value.hash.into(), + height: value.height.into(), + time: Some(value.time.into()), + next_validators_hash: value.next_validators_hash.into(), + proposer_address: value.proposer_address.into(), + } + } + } + + impl TryFrom for FinalizeBlock { + type Error = Error; + + fn try_from(message: pb::abci::RequestFinalizeBlock) -> Result { + Ok(Self { + txs: message.txs, + decided_last_commit: message + .decided_last_commit + .ok_or_else(Error::missing_last_commit_info)? + .try_into()?, + misbehavior: message + .misbehavior + .into_iter() + .map(TryInto::try_into) + .collect::>()?, + hash: message.hash.try_into()?, + height: message.height.try_into()?, + time: message + .time + .ok_or_else(Error::missing_timestamp)? + .try_into()?, + next_validators_hash: message.next_validators_hash.try_into()?, + proposer_address: message.proposer_address.try_into()?, + }) + } + } + + impl Protobuf for FinalizeBlock {} +} diff --git a/tendermint/src/abci/request/prepare_proposal.rs b/tendermint/src/abci/request/prepare_proposal.rs index a95dc691e..4ee512f36 100644 --- a/tendermint/src/abci/request/prepare_proposal.rs +++ b/tendermint/src/abci/request/prepare_proposal.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use crate::{ abci::types::{CommitInfo, Misbehavior}, - account, block, Error, Hash, Time, + account, block, Hash, Time, }; use bytes::Bytes; @@ -27,52 +27,106 @@ pub struct PrepareProposal { // Protobuf conversions // ============================================================================= -// The PrepareProposal request has been added in 0.37. +mod v0_37 { + use super::PrepareProposal; + use crate::{prelude::*, Error}; + use tendermint_proto::v0_37::abci as pb; + use tendermint_proto::Protobuf; -use tendermint_proto::v0_37::abci as pb; -use tendermint_proto::Protobuf; + impl From for pb::RequestPrepareProposal { + fn from(value: PrepareProposal) -> Self { + Self { + max_tx_bytes: value.max_tx_bytes, + txs: value.txs, + local_last_commit: value.local_last_commit.map(Into::into), + misbehavior: value.misbehavior.into_iter().map(Into::into).collect(), + height: value.height.into(), + time: Some(value.time.into()), + next_validators_hash: value.next_validators_hash.into(), + proposer_address: value.proposer_address.into(), + } + } + } + + impl TryFrom for PrepareProposal { + type Error = Error; -impl From for pb::RequestPrepareProposal { - fn from(value: PrepareProposal) -> Self { - Self { - max_tx_bytes: value.max_tx_bytes, - txs: value.txs, - local_last_commit: value.local_last_commit.map(Into::into), - misbehavior: value.misbehavior.into_iter().map(Into::into).collect(), - height: value.height.into(), - time: Some(value.time.into()), - next_validators_hash: value.next_validators_hash.into(), - proposer_address: value.proposer_address.into(), + fn try_from(message: pb::RequestPrepareProposal) -> Result { + let req = Self { + max_tx_bytes: message.max_tx_bytes, + txs: message.txs, + local_last_commit: message + .local_last_commit + .map(TryInto::try_into) + .transpose()?, + misbehavior: message + .misbehavior + .into_iter() + .map(TryInto::try_into) + .collect::, _>>()?, + height: message.height.try_into()?, + time: message + .time + .ok_or_else(Error::missing_timestamp)? + .try_into()?, + next_validators_hash: message.next_validators_hash.try_into()?, + proposer_address: message.proposer_address.try_into()?, + }; + Ok(req) } } + + impl Protobuf for PrepareProposal {} } -impl TryFrom for PrepareProposal { - type Error = Error; +mod v0_38 { + use super::PrepareProposal; + use crate::{prelude::*, Error}; + use tendermint_proto::v0_38::abci as pb; + use tendermint_proto::Protobuf; - fn try_from(message: pb::RequestPrepareProposal) -> Result { - let req = Self { - max_tx_bytes: message.max_tx_bytes, - txs: message.txs, - local_last_commit: message - .local_last_commit - .map(TryInto::try_into) - .transpose()?, - misbehavior: message - .misbehavior - .into_iter() - .map(TryInto::try_into) - .collect::, _>>()?, - height: message.height.try_into()?, - time: message - .time - .ok_or_else(Error::missing_timestamp)? - .try_into()?, - next_validators_hash: message.next_validators_hash.try_into()?, - proposer_address: message.proposer_address.try_into()?, - }; - Ok(req) + impl From for pb::RequestPrepareProposal { + fn from(value: PrepareProposal) -> Self { + Self { + max_tx_bytes: value.max_tx_bytes, + txs: value.txs, + local_last_commit: value.local_last_commit.map(Into::into), + misbehavior: value.misbehavior.into_iter().map(Into::into).collect(), + height: value.height.into(), + time: Some(value.time.into()), + next_validators_hash: value.next_validators_hash.into(), + proposer_address: value.proposer_address.into(), + } + } } -} -impl Protobuf for PrepareProposal {} + impl TryFrom for PrepareProposal { + type Error = Error; + + fn try_from(message: pb::RequestPrepareProposal) -> Result { + let req = Self { + max_tx_bytes: message.max_tx_bytes, + txs: message.txs, + local_last_commit: message + .local_last_commit + .map(TryInto::try_into) + .transpose()?, + misbehavior: message + .misbehavior + .into_iter() + .map(TryInto::try_into) + .collect::, _>>()?, + height: message.height.try_into()?, + time: message + .time + .ok_or_else(Error::missing_timestamp)? + .try_into()?, + next_validators_hash: message.next_validators_hash.try_into()?, + proposer_address: message.proposer_address.try_into()?, + }; + Ok(req) + } + } + + impl Protobuf for PrepareProposal {} +} diff --git a/tendermint/src/abci/request/process_proposal.rs b/tendermint/src/abci/request/process_proposal.rs index bb3020048..2eafa2930 100644 --- a/tendermint/src/abci/request/process_proposal.rs +++ b/tendermint/src/abci/request/process_proposal.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use crate::{ abci::types::{CommitInfo, Misbehavior}, - account, block, Error, Hash, Time, + account, block, Hash, Time, }; use bytes::Bytes; @@ -26,52 +26,106 @@ pub struct ProcessProposal { // Protobuf conversions // ============================================================================= -// The ProcessProposal request has been added in 0.37. +mod v0_37 { + use super::ProcessProposal; + use crate::{prelude::*, Error}; + use tendermint_proto::v0_37::abci as pb; + use tendermint_proto::Protobuf; -use tendermint_proto::v0_37::abci as pb; -use tendermint_proto::Protobuf; + impl From for pb::RequestProcessProposal { + fn from(value: ProcessProposal) -> Self { + Self { + txs: value.txs, + proposed_last_commit: value.proposed_last_commit.map(Into::into), + misbehavior: value.misbehavior.into_iter().map(Into::into).collect(), + hash: value.hash.into(), + height: value.height.into(), + time: Some(value.time.into()), + next_validators_hash: value.next_validators_hash.into(), + proposer_address: value.proposer_address.into(), + } + } + } + + impl TryFrom for ProcessProposal { + type Error = Error; -impl From for pb::RequestProcessProposal { - fn from(value: ProcessProposal) -> Self { - Self { - txs: value.txs, - proposed_last_commit: value.proposed_last_commit.map(Into::into), - misbehavior: value.misbehavior.into_iter().map(Into::into).collect(), - hash: value.hash.into(), - height: value.height.into(), - time: Some(value.time.into()), - next_validators_hash: value.next_validators_hash.into(), - proposer_address: value.proposer_address.into(), + fn try_from(message: pb::RequestProcessProposal) -> Result { + let req = Self { + txs: message.txs, + proposed_last_commit: message + .proposed_last_commit + .map(TryInto::try_into) + .transpose()?, + misbehavior: message + .misbehavior + .into_iter() + .map(TryInto::try_into) + .collect::, _>>()?, + hash: message.hash.try_into()?, + height: message.height.try_into()?, + time: message + .time + .ok_or_else(Error::missing_timestamp)? + .try_into()?, + next_validators_hash: message.next_validators_hash.try_into()?, + proposer_address: message.proposer_address.try_into()?, + }; + Ok(req) } } + + impl Protobuf for ProcessProposal {} } -impl TryFrom for ProcessProposal { - type Error = Error; +mod v0_38 { + use super::ProcessProposal; + use crate::{prelude::*, Error}; + use tendermint_proto::v0_38::abci as pb; + use tendermint_proto::Protobuf; - fn try_from(message: pb::RequestProcessProposal) -> Result { - let req = Self { - txs: message.txs, - proposed_last_commit: message - .proposed_last_commit - .map(TryInto::try_into) - .transpose()?, - misbehavior: message - .misbehavior - .into_iter() - .map(TryInto::try_into) - .collect::, _>>()?, - hash: message.hash.try_into()?, - height: message.height.try_into()?, - time: message - .time - .ok_or_else(Error::missing_timestamp)? - .try_into()?, - next_validators_hash: message.next_validators_hash.try_into()?, - proposer_address: message.proposer_address.try_into()?, - }; - Ok(req) + impl From for pb::RequestProcessProposal { + fn from(value: ProcessProposal) -> Self { + Self { + txs: value.txs, + proposed_last_commit: value.proposed_last_commit.map(Into::into), + misbehavior: value.misbehavior.into_iter().map(Into::into).collect(), + hash: value.hash.into(), + height: value.height.into(), + time: Some(value.time.into()), + next_validators_hash: value.next_validators_hash.into(), + proposer_address: value.proposer_address.into(), + } + } } -} -impl Protobuf for ProcessProposal {} + impl TryFrom for ProcessProposal { + type Error = Error; + + fn try_from(message: pb::RequestProcessProposal) -> Result { + let req = Self { + txs: message.txs, + proposed_last_commit: message + .proposed_last_commit + .map(TryInto::try_into) + .transpose()?, + misbehavior: message + .misbehavior + .into_iter() + .map(TryInto::try_into) + .collect::, _>>()?, + hash: message.hash.try_into()?, + height: message.height.try_into()?, + time: message + .time + .ok_or_else(Error::missing_timestamp)? + .try_into()?, + next_validators_hash: message.next_validators_hash.try_into()?, + proposer_address: message.proposer_address.try_into()?, + }; + Ok(req) + } + } + + impl Protobuf for ProcessProposal {} +} diff --git a/tendermint/src/abci/request/verify_vote_extension.rs b/tendermint/src/abci/request/verify_vote_extension.rs new file mode 100644 index 000000000..031cb3b86 --- /dev/null +++ b/tendermint/src/abci/request/verify_vote_extension.rs @@ -0,0 +1,47 @@ +use crate::{account, block, Hash}; +use bytes::Bytes; + +#[doc = include_str!("../doc/request-verifyvoteextension.md")] +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct VerifyVoteExtension { + pub hash: Hash, + pub validator_address: account::Id, + pub height: block::Height, + pub vote_extension: Bytes, +} + +// ============================================================================= +// Protobuf conversions +// ============================================================================= + +mod v0_38 { + use super::VerifyVoteExtension; + use tendermint_proto::v0_38 as pb; + use tendermint_proto::Protobuf; + + impl From for pb::abci::RequestVerifyVoteExtension { + fn from(value: VerifyVoteExtension) -> Self { + Self { + hash: value.hash.into(), + validator_address: value.validator_address.into(), + height: value.height.into(), + vote_extension: value.vote_extension, + } + } + } + + impl TryFrom for VerifyVoteExtension { + type Error = crate::Error; + + fn try_from(message: pb::abci::RequestVerifyVoteExtension) -> Result { + Ok(Self { + hash: message.hash.try_into()?, + validator_address: message.validator_address.try_into()?, + height: message.height.try_into()?, + vote_extension: message.vote_extension, + }) + } + } + + impl Protobuf for VerifyVoteExtension {} +} diff --git a/tendermint/src/lib.rs b/tendermint/src/lib.rs index edc358010..96315820f 100644 --- a/tendermint/src/lib.rs +++ b/tendermint/src/lib.rs @@ -58,6 +58,7 @@ pub mod vote; pub mod v0_34; pub mod v0_37; +pub mod v0_38; #[cfg(test)] mod test; diff --git a/tendermint/src/v0_34/abci/request.rs b/tendermint/src/v0_34/abci/request.rs index 6199750b8..d31c04d42 100644 --- a/tendermint/src/v0_34/abci/request.rs +++ b/tendermint/src/v0_34/abci/request.rs @@ -74,16 +74,25 @@ impl From for Request { fn from(req: ConsensusRequest) -> Self { match req { ConsensusRequest::InitChain(x) => Self::InitChain(x), - ConsensusRequest::PrepareProposal(_) => { - panic!("Cannot convert PrepareProposal into a v0.34 Request") - }, - ConsensusRequest::ProcessProposal(_) => { - panic!("Cannot convert ProcessProposal into a v0.34 Request") - }, ConsensusRequest::BeginBlock(x) => Self::BeginBlock(x), ConsensusRequest::DeliverTx(x) => Self::DeliverTx(x), ConsensusRequest::EndBlock(x) => Self::EndBlock(x), ConsensusRequest::Commit => Self::Commit, + ConsensusRequest::PrepareProposal(_) => { + panic!("cannot convert PrepareProposal into a v0.34 Request") + }, + ConsensusRequest::ProcessProposal(_) => { + panic!("cannot convert ProcessProposal into a v0.34 Request") + }, + ConsensusRequest::ExtendVote(_) => { + panic!("cannot convert ExtendVote into a v0.34 Request") + }, + ConsensusRequest::VerifyVoteExtension(_) => { + panic!("cannot convert VerifyVoteExtension into a v0.34 Request") + }, + ConsensusRequest::FinalizeBlock(_) => { + panic!("cannot convert FinalizeBlock into a v0.34 Request") + }, } } } diff --git a/tendermint/src/v0_37/abci/request.rs b/tendermint/src/v0_37/abci/request.rs index fce4d19c8..1cc23b2e1 100644 --- a/tendermint/src/v0_37/abci/request.rs +++ b/tendermint/src/v0_37/abci/request.rs @@ -83,6 +83,9 @@ impl From for Request { ConsensusRequest::DeliverTx(x) => Self::DeliverTx(x), ConsensusRequest::EndBlock(x) => Self::EndBlock(x), ConsensusRequest::Commit => Self::Commit, + ConsensusRequest::ExtendVote(_) => panic!("cannot be used with v0.37"), + ConsensusRequest::VerifyVoteExtension(_) => panic!("cannot be used with v0.37"), + ConsensusRequest::FinalizeBlock(_) => panic!("cannot be used with v0.37"), } } } @@ -127,7 +130,7 @@ impl From for Request { InfoRequest::Info(x) => Self::Info(x), InfoRequest::Query(x) => Self::Query(x), InfoRequest::Echo(x) => Self::Echo(x), - InfoRequest::SetOption(_) => panic!("cannot be used with v0.37"), + InfoRequest::SetOption(_) => panic!("SetOption cannot be used with v0.37"), } } } diff --git a/tendermint/src/v0_38.rs b/tendermint/src/v0_38.rs new file mode 100644 index 000000000..c52eb0a4c --- /dev/null +++ b/tendermint/src/v0_38.rs @@ -0,0 +1 @@ +pub mod abci; diff --git a/tendermint/src/v0_38/abci.rs b/tendermint/src/v0_38/abci.rs new file mode 100644 index 000000000..601e534df --- /dev/null +++ b/tendermint/src/v0_38/abci.rs @@ -0,0 +1,5 @@ +pub mod request; +pub mod response; + +pub use request::Request; +pub use response::Response; diff --git a/tendermint/src/v0_38/abci/request.rs b/tendermint/src/v0_38/abci/request.rs new file mode 100644 index 000000000..57552590f --- /dev/null +++ b/tendermint/src/v0_38/abci/request.rs @@ -0,0 +1,232 @@ +use tendermint_proto::v0_38::abci as pb; +use tendermint_proto::Protobuf; + +use crate::abci::request::{ConsensusRequest, InfoRequest, MempoolRequest, SnapshotRequest}; +use crate::abci::MethodKind; +use crate::Error; + +pub use crate::abci::request::{ + ApplySnapshotChunk, CheckTx, CheckTxKind, Echo, ExtendVote, FinalizeBlock, Info, InitChain, + LoadSnapshotChunk, OfferSnapshot, PrepareProposal, ProcessProposal, Query, VerifyVoteExtension, +}; + +/// All possible ABCI requests. +#[allow(clippy::large_enum_variant)] +#[derive(Clone, PartialEq, Eq, Debug)] +pub enum Request { + #[doc = include_str!("../../abci/doc/request-echo.md")] + Echo(Echo), + #[doc = include_str!("../../abci/doc/request-flush.md")] + Flush, + #[doc = include_str!("../../abci/doc/request-info.md")] + Info(Info), + #[doc = include_str!("../../abci/doc/request-initchain.md")] + InitChain(InitChain), + #[doc = include_str!("../../abci/doc/request-query.md")] + Query(Query), + #[doc = include_str!("../../abci/doc/request-checktx.md")] + CheckTx(CheckTx), + #[doc = include_str!("../../abci/doc/request-commit.md")] + Commit, + #[doc = include_str!("../../abci/doc/request-listsnapshots.md")] + ListSnapshots, + #[doc = include_str!("../../abci/doc/request-offersnapshot.md")] + OfferSnapshot(OfferSnapshot), + #[doc = include_str!("../../abci/doc/request-loadsnapshotchunk.md")] + LoadSnapshotChunk(LoadSnapshotChunk), + #[doc = include_str!("../../abci/doc/request-applysnapshotchunk.md")] + ApplySnapshotChunk(ApplySnapshotChunk), + #[doc = include_str!("../../abci/doc/request-prepareproposal.md")] + PrepareProposal(PrepareProposal), + #[doc = include_str!("../../abci/doc/request-processproposal.md")] + ProcessProposal(ProcessProposal), + #[doc = include_str!("../../abci/doc/request-extendvote.md")] + ExtendVote(ExtendVote), + #[doc = include_str!("../../abci/doc/request-verifyvoteextension.md")] + VerifyVoteExtension(VerifyVoteExtension), + #[doc = include_str!("../../abci/doc/request-finalizeblock.md")] + FinalizeBlock(FinalizeBlock), +} + +impl Request { + /// Get the method kind for this request. + pub fn kind(&self) -> MethodKind { + use Request::*; + match self { + Flush => MethodKind::Flush, + InitChain(_) => MethodKind::Consensus, + Commit => MethodKind::Consensus, + PrepareProposal(_) => MethodKind::Consensus, + ProcessProposal(_) => MethodKind::Consensus, + ExtendVote(_) => MethodKind::Consensus, + VerifyVoteExtension(_) => MethodKind::Consensus, + FinalizeBlock(_) => MethodKind::Consensus, + CheckTx(_) => MethodKind::Mempool, + ListSnapshots => MethodKind::Snapshot, + OfferSnapshot(_) => MethodKind::Snapshot, + LoadSnapshotChunk(_) => MethodKind::Snapshot, + ApplySnapshotChunk(_) => MethodKind::Snapshot, + Info(_) => MethodKind::Info, + Query(_) => MethodKind::Info, + Echo(_) => MethodKind::Info, + } + } +} + +impl From for Request { + fn from(req: ConsensusRequest) -> Self { + match req { + ConsensusRequest::InitChain(x) => Self::InitChain(x), + ConsensusRequest::PrepareProposal(x) => Self::PrepareProposal(x), + ConsensusRequest::ProcessProposal(x) => Self::ProcessProposal(x), + ConsensusRequest::Commit => Self::Commit, + ConsensusRequest::ExtendVote(x) => Self::ExtendVote(x), + ConsensusRequest::VerifyVoteExtension(x) => Self::VerifyVoteExtension(x), + ConsensusRequest::FinalizeBlock(x) => Self::FinalizeBlock(x), + ConsensusRequest::BeginBlock(_) => panic!("cannot be used with v0.38"), + ConsensusRequest::DeliverTx(_) => panic!("cannot be used with v0.38"), + ConsensusRequest::EndBlock(_) => panic!("cannot be used with v0.38"), + } + } +} + +impl TryFrom for ConsensusRequest { + type Error = Error; + fn try_from(req: Request) -> Result { + match req { + Request::InitChain(x) => Ok(Self::InitChain(x)), + Request::PrepareProposal(x) => Ok(Self::PrepareProposal(x)), + Request::ProcessProposal(x) => Ok(Self::ProcessProposal(x)), + Request::Commit => Ok(Self::Commit), + Request::ExtendVote(x) => Ok(Self::ExtendVote(x)), + Request::VerifyVoteExtension(x) => Ok(Self::VerifyVoteExtension(x)), + Request::FinalizeBlock(x) => Ok(Self::FinalizeBlock(x)), + _ => Err(Error::invalid_abci_request_type()), + } + } +} + +impl From for Request { + fn from(req: MempoolRequest) -> Self { + match req { + MempoolRequest::CheckTx(x) => Self::CheckTx(x), + } + } +} + +impl TryFrom for MempoolRequest { + type Error = Error; + fn try_from(req: Request) -> Result { + match req { + Request::CheckTx(x) => Ok(Self::CheckTx(x)), + _ => Err(Error::invalid_abci_request_type()), + } + } +} + +impl From for Request { + fn from(req: InfoRequest) -> Self { + match req { + InfoRequest::Info(x) => Self::Info(x), + InfoRequest::Query(x) => Self::Query(x), + InfoRequest::Echo(x) => Self::Echo(x), + InfoRequest::SetOption(_) => panic!("cannot be used with v0.37"), + } + } +} + +impl TryFrom for InfoRequest { + type Error = Error; + fn try_from(req: Request) -> Result { + match req { + Request::Info(x) => Ok(Self::Info(x)), + Request::Query(x) => Ok(Self::Query(x)), + Request::Echo(x) => Ok(Self::Echo(x)), + _ => Err(Error::invalid_abci_request_type()), + } + } +} + +impl From for Request { + fn from(req: SnapshotRequest) -> Self { + match req { + SnapshotRequest::ListSnapshots => Self::ListSnapshots, + SnapshotRequest::OfferSnapshot(x) => Self::OfferSnapshot(x), + SnapshotRequest::LoadSnapshotChunk(x) => Self::LoadSnapshotChunk(x), + SnapshotRequest::ApplySnapshotChunk(x) => Self::ApplySnapshotChunk(x), + } + } +} + +impl TryFrom for SnapshotRequest { + type Error = Error; + fn try_from(req: Request) -> Result { + match req { + Request::ListSnapshots => Ok(Self::ListSnapshots), + Request::OfferSnapshot(x) => Ok(Self::OfferSnapshot(x)), + Request::LoadSnapshotChunk(x) => Ok(Self::LoadSnapshotChunk(x)), + Request::ApplySnapshotChunk(x) => Ok(Self::ApplySnapshotChunk(x)), + _ => Err(Error::invalid_abci_request_type()), + } + } +} + +// ============================================================================= +// Protobuf conversions +// ============================================================================= + +impl From for pb::Request { + fn from(request: Request) -> pb::Request { + use pb::request::Value; + let value = match request { + Request::Echo(x) => Some(Value::Echo(x.into())), + Request::Flush => Some(Value::Flush(Default::default())), + Request::Info(x) => Some(Value::Info(x.into())), + Request::InitChain(x) => Some(Value::InitChain(x.into())), + Request::Query(x) => Some(Value::Query(x.into())), + Request::CheckTx(x) => Some(Value::CheckTx(x.into())), + Request::Commit => Some(Value::Commit(Default::default())), + Request::ListSnapshots => Some(Value::ListSnapshots(Default::default())), + Request::OfferSnapshot(x) => Some(Value::OfferSnapshot(x.into())), + Request::LoadSnapshotChunk(x) => Some(Value::LoadSnapshotChunk(x.into())), + Request::ApplySnapshotChunk(x) => Some(Value::ApplySnapshotChunk(x.into())), + Request::PrepareProposal(x) => Some(Value::PrepareProposal(x.into())), + Request::ProcessProposal(x) => Some(Value::ProcessProposal(x.into())), + Request::ExtendVote(x) => Some(Value::ExtendVote(x.into())), + Request::VerifyVoteExtension(x) => Some(Value::VerifyVoteExtension(x.into())), + Request::FinalizeBlock(x) => Some(Value::FinalizeBlock(x.into())), + }; + pb::Request { value } + } +} + +impl TryFrom for Request { + type Error = Error; + + fn try_from(request: pb::Request) -> Result { + use pb::request::Value; + + let value = request.value.ok_or_else(|| Error::missing_data())?; + let request = match value { + Value::Echo(x) => Request::Echo(x.try_into()?), + Value::Flush(pb::RequestFlush {}) => Request::Flush, + Value::Info(x) => Request::Info(x.try_into()?), + Value::InitChain(x) => Request::InitChain(x.try_into()?), + Value::Query(x) => Request::Query(x.try_into()?), + Value::CheckTx(x) => Request::CheckTx(x.try_into()?), + Value::Commit(pb::RequestCommit {}) => Request::Commit, + Value::ListSnapshots(pb::RequestListSnapshots {}) => Request::ListSnapshots, + Value::OfferSnapshot(x) => Request::OfferSnapshot(x.try_into()?), + Value::LoadSnapshotChunk(x) => Request::LoadSnapshotChunk(x.try_into()?), + Value::ApplySnapshotChunk(x) => Request::ApplySnapshotChunk(x.try_into()?), + Value::PrepareProposal(x) => Request::PrepareProposal(x.try_into()?), + Value::ProcessProposal(x) => Request::ProcessProposal(x.try_into()?), + Value::ExtendVote(x) => Request::ExtendVote(x.try_into()?), + Value::VerifyVoteExtension(x) => Request::VerifyVoteExtension(x.try_into()?), + Value::FinalizeBlock(x) => Request::FinalizeBlock(x.try_into()?), + }; + Ok(request) + } +} + +impl Protobuf for Request {} diff --git a/tendermint/src/v0_38/abci/response.rs b/tendermint/src/v0_38/abci/response.rs new file mode 100644 index 000000000..831f2783c --- /dev/null +++ b/tendermint/src/v0_38/abci/response.rs @@ -0,0 +1,204 @@ +pub use crate::abci::response::{ + ApplySnapshotChunk, BeginBlock, CheckTx, Commit, DeliverTx, Echo, EndBlock, Exception, Info, + InitChain, ListSnapshots, LoadSnapshotChunk, OfferSnapshot, PrepareProposal, ProcessProposal, + Query, +}; +use crate::abci::response::{ConsensusResponse, InfoResponse, MempoolResponse, SnapshotResponse}; +use crate::Error; + +/// All possible ABCI responses for this protocol version. +#[derive(Clone, PartialEq, Eq, Debug)] +pub enum Response { + #[doc = include_str!("../../abci/doc/response-exception.md")] + Exception(Exception), + #[doc = include_str!("../../abci/doc/response-echo.md")] + Echo(Echo), + #[doc = include_str!("../../abci/doc/response-flush.md")] + Flush, + #[doc = include_str!("../../abci/doc/response-info.md")] + Info(Info), + #[doc = include_str!("../../abci/doc/response-initchain.md")] + InitChain(InitChain), + #[doc = include_str!("../../abci/doc/response-query.md")] + Query(Query), + #[doc = include_str!("../../abci/doc/response-beginblock.md")] + BeginBlock(BeginBlock), + #[doc = include_str!("../../abci/doc/response-checktx.md")] + CheckTx(CheckTx), + #[doc = include_str!("../../abci/doc/response-delivertx.md")] + DeliverTx(DeliverTx), + #[doc = include_str!("../../abci/doc/response-endblock.md")] + EndBlock(EndBlock), + #[doc = include_str!("../../abci/doc/response-commit.md")] + Commit(Commit), + #[doc = include_str!("../../abci/doc/response-listsnapshots.md")] + ListSnapshots(ListSnapshots), + #[doc = include_str!("../../abci/doc/response-offersnapshot.md")] + OfferSnapshot(OfferSnapshot), + #[doc = include_str!("../../abci/doc/response-loadsnapshotchunk.md")] + LoadSnapshotChunk(LoadSnapshotChunk), + #[doc = include_str!("../../abci/doc/response-applysnapshotchunk.md")] + ApplySnapshotChunk(ApplySnapshotChunk), + #[doc = include_str!("../../abci/doc/response-prepareproposal.md")] + PrepareProposal(PrepareProposal), + #[doc = include_str!("../../abci/doc/response-processproposal.md")] + ProcessProposal(ProcessProposal), +} + +impl From for Response { + fn from(req: ConsensusResponse) -> Self { + match req { + ConsensusResponse::InitChain(x) => Self::InitChain(x), + ConsensusResponse::PrepareProposal(x) => Self::PrepareProposal(x), + ConsensusResponse::ProcessProposal(x) => Self::ProcessProposal(x), + ConsensusResponse::BeginBlock(x) => Self::BeginBlock(x), + ConsensusResponse::DeliverTx(x) => Self::DeliverTx(x), + ConsensusResponse::EndBlock(x) => Self::EndBlock(x), + ConsensusResponse::Commit(x) => Self::Commit(x), + } + } +} + +impl TryFrom for ConsensusResponse { + type Error = Error; + fn try_from(req: Response) -> Result { + match req { + Response::InitChain(x) => Ok(Self::InitChain(x)), + Response::PrepareProposal(x) => Ok(Self::PrepareProposal(x)), + Response::ProcessProposal(x) => Ok(Self::ProcessProposal(x)), + Response::BeginBlock(x) => Ok(Self::BeginBlock(x)), + Response::DeliverTx(x) => Ok(Self::DeliverTx(x)), + Response::EndBlock(x) => Ok(Self::EndBlock(x)), + Response::Commit(x) => Ok(Self::Commit(x)), + _ => Err(Error::invalid_abci_response_type()), + } + } +} + +impl From for Response { + fn from(req: MempoolResponse) -> Self { + match req { + MempoolResponse::CheckTx(x) => Self::CheckTx(x), + } + } +} + +impl TryFrom for MempoolResponse { + type Error = Error; + fn try_from(req: Response) -> Result { + match req { + Response::CheckTx(x) => Ok(Self::CheckTx(x)), + _ => Err(Error::invalid_abci_response_type()), + } + } +} + +impl From for Response { + fn from(req: InfoResponse) -> Self { + match req { + InfoResponse::Echo(x) => Self::Echo(x), + InfoResponse::Info(x) => Self::Info(x), + InfoResponse::Query(x) => Self::Query(x), + InfoResponse::SetOption(_) => panic!("cannot be used with v0.37"), + } + } +} + +impl TryFrom for InfoResponse { + type Error = Error; + fn try_from(req: Response) -> Result { + match req { + Response::Echo(x) => Ok(Self::Echo(x)), + Response::Info(x) => Ok(Self::Info(x)), + Response::Query(x) => Ok(Self::Query(x)), + _ => Err(Error::invalid_abci_response_type()), + } + } +} + +impl From for Response { + fn from(req: SnapshotResponse) -> Self { + match req { + SnapshotResponse::ListSnapshots(x) => Self::ListSnapshots(x), + SnapshotResponse::OfferSnapshot(x) => Self::OfferSnapshot(x), + SnapshotResponse::LoadSnapshotChunk(x) => Self::LoadSnapshotChunk(x), + SnapshotResponse::ApplySnapshotChunk(x) => Self::ApplySnapshotChunk(x), + } + } +} + +impl TryFrom for SnapshotResponse { + type Error = Error; + fn try_from(req: Response) -> Result { + match req { + Response::ListSnapshots(x) => Ok(Self::ListSnapshots(x)), + Response::OfferSnapshot(x) => Ok(Self::OfferSnapshot(x)), + Response::LoadSnapshotChunk(x) => Ok(Self::LoadSnapshotChunk(x)), + Response::ApplySnapshotChunk(x) => Ok(Self::ApplySnapshotChunk(x)), + _ => Err(Error::invalid_abci_response_type()), + } + } +} + +// ============================================================================= +// Protobuf conversions +// ============================================================================= + +use tendermint_proto::v0_37::abci as pb; +use tendermint_proto::Protobuf; + +impl From for pb::Response { + fn from(response: Response) -> pb::Response { + use pb::response::Value; + let value = match response { + Response::Exception(x) => Some(Value::Exception(x.into())), + Response::Echo(x) => Some(Value::Echo(x.into())), + Response::Flush => Some(Value::Flush(Default::default())), + Response::Info(x) => Some(Value::Info(x.into())), + Response::InitChain(x) => Some(Value::InitChain(x.into())), + Response::Query(x) => Some(Value::Query(x.into())), + Response::BeginBlock(x) => Some(Value::BeginBlock(x.into())), + Response::CheckTx(x) => Some(Value::CheckTx(x.into())), + Response::DeliverTx(x) => Some(Value::DeliverTx(x.into())), + Response::EndBlock(x) => Some(Value::EndBlock(x.into())), + Response::Commit(x) => Some(Value::Commit(x.into())), + Response::ListSnapshots(x) => Some(Value::ListSnapshots(x.into())), + Response::OfferSnapshot(x) => Some(Value::OfferSnapshot(x.into())), + Response::LoadSnapshotChunk(x) => Some(Value::LoadSnapshotChunk(x.into())), + Response::ApplySnapshotChunk(x) => Some(Value::ApplySnapshotChunk(x.into())), + Response::PrepareProposal(x) => Some(Value::PrepareProposal(x.into())), + Response::ProcessProposal(x) => Some(Value::ProcessProposal(x.into())), + }; + pb::Response { value } + } +} + +impl TryFrom for Response { + type Error = Error; + + fn try_from(response: pb::Response) -> Result { + use pb::response::Value; + match response.value { + Some(Value::Exception(x)) => Ok(Response::Exception(x.try_into()?)), + Some(Value::Echo(x)) => Ok(Response::Echo(x.try_into()?)), + Some(Value::Flush(_)) => Ok(Response::Flush), + Some(Value::Info(x)) => Ok(Response::Info(x.try_into()?)), + Some(Value::InitChain(x)) => Ok(Response::InitChain(x.try_into()?)), + Some(Value::Query(x)) => Ok(Response::Query(x.try_into()?)), + Some(Value::BeginBlock(x)) => Ok(Response::BeginBlock(x.try_into()?)), + Some(Value::CheckTx(x)) => Ok(Response::CheckTx(x.try_into()?)), + Some(Value::DeliverTx(x)) => Ok(Response::DeliverTx(x.try_into()?)), + Some(Value::EndBlock(x)) => Ok(Response::EndBlock(x.try_into()?)), + Some(Value::Commit(x)) => Ok(Response::Commit(x.try_into()?)), + Some(Value::ListSnapshots(x)) => Ok(Response::ListSnapshots(x.try_into()?)), + Some(Value::OfferSnapshot(x)) => Ok(Response::OfferSnapshot(x.try_into()?)), + Some(Value::LoadSnapshotChunk(x)) => Ok(Response::LoadSnapshotChunk(x.try_into()?)), + Some(Value::ApplySnapshotChunk(x)) => Ok(Response::ApplySnapshotChunk(x.try_into()?)), + Some(Value::PrepareProposal(x)) => Ok(Response::PrepareProposal(x.try_into()?)), + Some(Value::ProcessProposal(x)) => Ok(Response::ProcessProposal(x.try_into()?)), + None => Err(crate::Error::missing_data()), + } + } +} + +impl Protobuf for Response {}