-
Notifications
You must be signed in to change notification settings - Fork 224
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
These types mirror the generated types in tendermint_proto, but have better naming. The documentation is filled in from the ABCI methods & types documentation.
- Loading branch information
1 parent
5b9748f
commit 45c3946
Showing
33 changed files
with
3,139 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
//! Application BlockChain Interface ([ABCI]) is the interface between Tendermint | ||
//! (a consensus engine for Byzantine-fault-tolerant replication of a state | ||
//! machine) and an application (the state machine to be replicated). | ||
//! | ||
//! Using ABCI involves writing an application driven by ABCI methods, exposing | ||
//! that application as an ABCI server, and having Tendermint connect to the | ||
//! server as an ABCI client. | ||
//! | ||
//! This module does not include an ABCI server implementation itself. Instead, | ||
//! it provides a common set of Rust domain types that model the ABCI protocol, | ||
//! which can be used by both ABCI applications and ABCI server implementations. | ||
//! | ||
//! One ABCI server implementation is provided by the [`tendermint_abci`][tmabci] | ||
//! crate. | ||
//! | ||
//! Each ABCI method corresponds to a request/response pair. ABCI requests are | ||
//! modeled by the [`Request`] enum, and responses are modeled by the | ||
//! [`Response`] enum. As described in the [methods and types][mat] page, ABCI | ||
//! methods are split into four categories. Tendermint opens one ABCI connection | ||
//! for each category of messages. These categories are modeled by the | ||
//! [`MethodKind`] enum and by per-category request and response enums: | ||
//! | ||
//! * [`ConsensusRequest`] / [`ConsensusResponse`] for [`MethodKind::Consensus`] methods; | ||
//! * [`MempoolRequest`] / [`MempoolResponse`] for [`MethodKind::Mempool`] methods; | ||
//! * [`InfoRequest`] / [`InfoResponse`] for [`MethodKind::Info`] methods; | ||
//! * [`SnapshotRequest`] / [`SnapshotResponse`] for [`MethodKind::Snapshot`] methods. | ||
//! | ||
//! The domain types in this module have conversions to and from the Protobuf | ||
//! types defined in the [`tendermint_proto`] crate. These conversions are | ||
//! required for ABCI server implementations, which use the protobufs to | ||
//! communicate with Tendermint, but should not be required for ABCI | ||
//! applications, which should use the domain types in an interface defined by | ||
//! their choice of ABCI server implementation. | ||
//! | ||
//! [ABCI]: https://docs.tendermint.com/master/spec/abci/ | ||
//! [mat]: https://docs.tendermint.com/master/spec/abci/abci.html | ||
//! [tmabci]: https://github.com/informalsystems/tendermint-rs/tree/master/abci | ||
|
||
mod kind; | ||
|
||
/// Events. Hide this later once types are merged. | ||
pub mod event; | ||
//pub use event::{Event, EventAttribute}; | ||
|
||
pub mod params; | ||
pub mod request; | ||
pub mod response; | ||
pub mod types; | ||
|
||
#[doc(inline)] | ||
pub use self::{ | ||
kind::MethodKind, | ||
request::{ConsensusRequest, InfoRequest, MempoolRequest, Request, SnapshotRequest}, | ||
response::{ConsensusResponse, InfoResponse, MempoolResponse, Response, SnapshotResponse}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
/// An event that occurred while processing a request. | ||
/// | ||
/// Application developers can attach additional information to | ||
/// [`BeginBlock`](super::response::BeginBlock), | ||
/// [`EndBlock`](super::response::EndBlock), | ||
/// [`CheckTx`](super::response::CheckTx), and | ||
/// [`DeliverTx`](super::response::DeliverTx) responses. Later, transactions may | ||
/// be queried using these events. | ||
/// | ||
/// [ABCI documentation](https://docs.tendermint.com/master/spec/abci/abci.html#events) | ||
#[derive(Clone, PartialEq, Eq, Debug)] | ||
pub struct Event { | ||
/// The kind of event. | ||
/// | ||
/// Tendermint calls this the `type`, but we use `kind` to avoid confusion | ||
/// with Rust types and follow Rust conventions. | ||
pub kind: String, | ||
/// A list of [`EventAttribute`]s describing the event. | ||
pub attributes: Vec<EventAttribute>, | ||
} | ||
|
||
impl Event { | ||
/// Construct an event from generic data. | ||
/// | ||
/// The `From` impls on [`EventAttribute`] and the [`EventAttributeIndexExt`] | ||
/// trait allow ergonomic event construction, as in this example: | ||
/// | ||
/// ``` | ||
/// use tendermint::abci::event::{Event, EventAttributeIndexExt}; | ||
/// | ||
/// let event = Event::new( | ||
/// "app", | ||
/// vec![ | ||
/// ("key1", "value1").index(), | ||
/// ("key2", "value2").index(), | ||
/// ("key3", "value3").no_index(), // will not be indexed | ||
/// ], | ||
/// ); | ||
/// ``` | ||
// XXX(hdevalence): remove vec! from example after https://github.com/rust-lang/rust/pull/65819 | ||
pub fn new<K, I>(kind: K, attributes: I) -> Self | ||
where | ||
K: Into<String>, | ||
I: IntoIterator, | ||
I::Item: Into<EventAttribute>, | ||
{ | ||
Self { | ||
kind: kind.into(), | ||
attributes: attributes.into_iter().map(Into::into).collect(), | ||
} | ||
} | ||
} | ||
|
||
/// A key-value pair describing an [`Event`]. | ||
/// | ||
/// Generic methods are provided for more ergonomic attribute construction, see | ||
/// [`Event::new`] for details. | ||
/// | ||
/// [ABCI documentation](https://docs.tendermint.com/master/spec/abci/abci.html#events) | ||
#[derive(Clone, PartialEq, Eq, Debug)] | ||
pub struct EventAttribute { | ||
/// The event key. | ||
pub key: String, | ||
/// The event value. | ||
pub value: String, | ||
/// Whether Tendermint's indexer should index this event. | ||
/// | ||
/// **This field is nondeterministic**. | ||
pub index: bool, | ||
} | ||
|
||
impl<K: Into<String>, V: Into<String>> From<(K, V, bool)> for EventAttribute { | ||
fn from((key, value, index): (K, V, bool)) -> Self { | ||
EventAttribute { | ||
key: key.into(), | ||
value: value.into(), | ||
index, | ||
} | ||
} | ||
} | ||
|
||
/// Adds convenience methods to tuples for more ergonomic [`EventAttribute`] | ||
/// construction. | ||
/// | ||
/// See [`Event::new`] for details. | ||
#[allow(missing_docs)] | ||
pub trait EventAttributeIndexExt: private::Sealed { | ||
type Key; | ||
type Value; | ||
|
||
/// Indicate that this key/value pair should be indexed by Tendermint. | ||
fn index(self) -> (Self::Key, Self::Value, bool); | ||
/// Indicate that this key/value pair should not be indexed by Tendermint. | ||
fn no_index(self) -> (Self::Key, Self::Value, bool); | ||
} | ||
|
||
impl<K: Into<String>, V: Into<String>> EventAttributeIndexExt for (K, V) { | ||
type Key = K; | ||
type Value = V; | ||
fn index(self) -> (K, V, bool) { | ||
let (key, value) = self; | ||
(key, value, true) | ||
} | ||
fn no_index(self) -> (K, V, bool) { | ||
let (key, value) = self; | ||
(key, value, false) | ||
} | ||
} | ||
|
||
mod private { | ||
pub trait Sealed {} | ||
|
||
impl<K: Into<String>, V: Into<String>> Sealed for (K, V) {} | ||
} | ||
|
||
impl<K: Into<String>, V: Into<String>> From<(K, V)> for EventAttribute { | ||
fn from((key, value): (K, V)) -> Self { | ||
(key, value, false).into() | ||
} | ||
} | ||
|
||
// ============================================================================= | ||
// Protobuf conversions | ||
// ============================================================================= | ||
|
||
// XXX(hdevalence): these all use &'static str for now, this should be fixed | ||
// to align with the crate's error-handling strategy. | ||
|
||
use std::convert::{TryFrom, TryInto}; | ||
|
||
use tendermint_proto::abci as pb; | ||
use tendermint_proto::Protobuf; | ||
|
||
impl From<EventAttribute> for pb::EventAttribute { | ||
fn from(event: EventAttribute) -> Self { | ||
Self { | ||
key: event.key, | ||
value: event.value, | ||
index: event.index, | ||
} | ||
} | ||
} | ||
|
||
impl TryFrom<pb::EventAttribute> for EventAttribute { | ||
type Error = crate::Error; | ||
|
||
fn try_from(event: pb::EventAttribute) -> Result<Self, Self::Error> { | ||
Ok(Self { | ||
key: event.key, | ||
value: event.value, | ||
index: event.index, | ||
}) | ||
} | ||
} | ||
|
||
impl Protobuf<pb::EventAttribute> for EventAttribute {} | ||
|
||
impl From<Event> for pb::Event { | ||
fn from(event: Event) -> Self { | ||
Self { | ||
r#type: event.kind, | ||
attributes: event.attributes.into_iter().map(Into::into).collect(), | ||
} | ||
} | ||
} | ||
|
||
impl TryFrom<pb::Event> for Event { | ||
type Error = crate::Error; | ||
|
||
fn try_from(event: pb::Event) -> Result<Self, Self::Error> { | ||
Ok(Self { | ||
kind: event.r#type, | ||
attributes: event | ||
.attributes | ||
.into_iter() | ||
.map(TryInto::try_into) | ||
.collect::<Result<_, _>>()?, | ||
}) | ||
} | ||
} | ||
|
||
impl Protobuf<pb::Event> for Event {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/// A category of ABCI method. | ||
/// | ||
/// ABCI methods are split into four categories. Tendermint opens one ABCI | ||
/// connection for each category and refers to these categories as *connections*, | ||
/// but nothing actually restricts an ABCI connection from calling methods in | ||
/// multiple categories. | ||
/// | ||
/// This enum breaks out the `Flush` method as a distinct category, since it is | ||
/// used to control the execution of other methods. | ||
pub enum MethodKind { | ||
/// A consensus method, driven by the consensus protocol and responsible for | ||
/// block execution. | ||
Consensus, | ||
/// A mempool method, used for validating new transactions before they're | ||
/// shared or included in a block. | ||
Mempool, | ||
/// A snapshot method, used for serving and restoring state snapshots. | ||
Snapshot, | ||
/// An info method, used for initialization and user queries. | ||
Info, | ||
/// The flush method requests that all pending method requests are fully executed. | ||
Flush, | ||
} |
Oops, something went wrong.