Skip to content
This repository has been archived by the owner on Jun 3, 2020. It is now read-only.

tendermint-rs: /block_results RPC endpoint and related types (closes #251) #267

Merged
merged 1 commit into from
Jun 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[![Crate][crate-image]][crate-link]
[![Build Status][build-image]][build-link]
[![Apache 2.0 Licensed][license-image]][license-link]
![Rust 1.35+][rustc-image]

Key Management System for [Tendermint] applications, initially targeting
[Cosmos Validators].
Expand Down Expand Up @@ -215,6 +216,7 @@ limitations under the License.
[build-link]: https://circleci.com/gh/tendermint/kms
[license-image]: https://img.shields.io/badge/license-Apache2.0-blue.svg
[license-link]: https://github.com/tendermint/kms/blob/master/LICENSE
[rustc-image]: https://img.shields.io/badge/rustc-1.35+-blue.svg
[Tendermint]: https://tendermint.com/
[Cosmos Validators]: https://cosmos.network/docs/gaia/validators/validator-faq.html
[YubiHSM 2]: https://github.com/tendermint/kms/blob/master/README.yubihsm.md
Expand Down
34 changes: 23 additions & 11 deletions tendermint-rs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,21 @@
[![Docs][docs-image]][docs-link]
[![Build Status][build-image]][build-link]
[![Apache 2.0 Licensed][license-image]][license-link]
![Rust 1.35+][rustc-image]

[crate-image]: https://img.shields.io/crates/v/tendermint.svg
[crate-link]: https://crates.io/crates/tendermint
[docs-image]: https://docs.rs/tendermint/badge.svg
[docs-link]: https://docs.rs/tendermint/
[build-image]: https://circleci.com/gh/tendermint/kms.svg?style=shield
[build-link]: https://circleci.com/gh/tendermint/kms
[license-image]: https://img.shields.io/badge/license-Apache2.0-blue.svg
[license-link]: https://github.com/tendermint/kms/blob/master/LICENSE

Rust crate for interacting with Tendermint: a high-performance blockchain
Rust crate for interacting with [Tendermint]: a high-performance blockchain
consensus engine that powers Byzantine fault tolerant applications written
in any programming language.

[Documentation][docs-link]

## Requirements

- Rust 1.35+

## License

Copyright © 2018 Tendermint
Copyright © 2018-2019 Tendermint

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -35,3 +31,19 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

[//]: # (badges)

[crate-image]: https://img.shields.io/crates/v/tendermint.svg
[crate-link]: https://crates.io/crates/tendermint
[docs-image]: https://docs.rs/tendermint/badge.svg
[docs-link]: https://docs.rs/tendermint/
[build-image]: https://circleci.com/gh/tendermint/kms.svg?style=shield
[build-link]: https://circleci.com/gh/tendermint/kms
[license-image]: https://img.shields.io/badge/license-Apache2.0-blue.svg
[license-link]: https://github.com/tendermint/kms/blob/master/LICENSE
[rustc-image]: https://img.shields.io/badge/rustc-1.35+-blue.svg

[//]: # (general links)

[Tendermint]: https://github.com/tendermint/tendermint
28 changes: 28 additions & 0 deletions tendermint-rs/src/abci.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//! Application BlockChain Interface (ABCI)
//!
//! NOTE: This module contains types for ABCI responses as consumed from RPC
//! endpoints. It does not contain an ABCI protocol implementation.
//!
//! For that, see:
//!
//! <https://github.com/tendermint/rust-abci>

#[cfg(feature = "rpc")]
mod code;
#[cfg(feature = "rpc")]
mod data;
#[cfg(feature = "rpc")]
mod gas;
#[cfg(feature = "rpc")]
mod info;
#[cfg(feature = "rpc")]
mod log;
#[cfg(feature = "rpc")]
mod responses;
pub mod transaction;

#[cfg(feature = "rpc")]
pub use self::{
code::Code, data::Data, gas::Gas, info::Info, log::Log, responses::Responses,
transaction::Transaction,
};
71 changes: 71 additions & 0 deletions tendermint-rs/src/abci/code.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer};

/// ABCI application response codes.
///
/// These presently use 0 for success and non-zero for errors:
///
/// <https://tendermint.com/docs/spec/abci/abci.html#errors>
///
/// Note that in the future there may potentially be non-zero success codes.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub enum Code {
/// Success
Ok,

/// Error codes
Err(u32),
}

impl Code {
/// Was the response OK?
pub fn is_ok(self) -> bool {
match self {
Code::Ok => true,
Code::Err(_) => false,
}
}

/// Was the response an error?
pub fn is_err(self) -> bool {
!self.is_ok()
}

/// Get the integer error value for this code
pub fn value(self) -> u32 {
u32::from(self)
}
}

impl From<u32> for Code {
fn from(value: u32) -> Code {
match value {
0 => Code::Ok,
err => Code::Err(err),
}
}
}

impl From<Code> for u32 {
fn from(code: Code) -> u32 {
match code {
Code::Ok => 0,
Code::Err(err) => err,
}
}
}

impl<'de> Deserialize<'de> for Code {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(Code::from(
String::deserialize(deserializer)?
.parse::<u32>()
.map_err(|e| D::Error::custom(format!("{}", e)))?,
))
}
}

impl Serialize for Code {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.value().serialize(serializer)
}
}
64 changes: 64 additions & 0 deletions tendermint-rs/src/abci/data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use crate::Error;
use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer};
use std::{
fmt::{self, Display},
str::FromStr,
};
use subtle_encoding::hex;

/// ABCI transaction data.
///
/// Transactions are opaque binary blobs which are validated according to
/// application-specific rules.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Data(Vec<u8>);

impl Data {
/// Borrow the data as bytes
pub fn as_bytes(&self) -> &[u8] {
self.0.as_ref()
}
}

impl AsRef<[u8]> for Data {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}

impl Display for Data {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for byte in &self.0 {
write!(f, "{:02X}", byte)?;
}
Ok(())
}
}

impl FromStr for Data {
type Err = Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
// Accept either upper or lower case hex
let bytes = hex::decode_upper(s)
.or_else(|_| hex::decode(s))
.map_err(|_| Error::Parse)?;

Ok(Data(bytes))
}
}

impl<'de> Deserialize<'de> for Data {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let bytes = hex::decode(String::deserialize(deserializer)?.as_bytes())
.map_err(|e| D::Error::custom(format!("{}", e)))?;

Ok(Self(bytes))
}
}

impl Serialize for Data {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.to_string().serialize(serializer)
}
}
58 changes: 58 additions & 0 deletions tendermint-rs/src/abci/gas.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//! Gas: abstract representation for the cost of resources used by nodes when
//! processing transactions.
//!
//! For more information, see:
//!
//! <https://tendermint.com/docs/spec/abci/apps.html#gas>

use crate::Error;
use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer};
use std::{
fmt::{self, Display},
str::FromStr,
};

/// Gas: representation of transaction processing resource costs
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
pub struct Gas(u64);

impl From<u64> for Gas {
fn from(amount: u64) -> Gas {
Gas(amount)
}
}

impl From<Gas> for u64 {
fn from(gas: Gas) -> u64 {
gas.0
}
}

impl Display for Gas {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}

impl FromStr for Gas {
type Err = Error;

fn from_str(s: &str) -> Result<Self, Error> {
Ok(Self::from(s.parse::<u64>().map_err(|_| Error::Parse)?))
}
}

#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for Gas {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(Self::from_str(&String::deserialize(deserializer)?)
.map_err(|e| D::Error::custom(format!("{}", e)))?)
}
}

#[cfg(feature = "serde")]
impl Serialize for Gas {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.to_string().serialize(serializer)
}
}
18 changes: 18 additions & 0 deletions tendermint-rs/src/abci/info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display};

/// ABCI info
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct Info(String);

impl AsRef<str> for Info {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}

impl Display for Info {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
28 changes: 28 additions & 0 deletions tendermint-rs/src/abci/log.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#[cfg(feature = "serde_json")]
use crate::Error;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display};

/// ABCI log data
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct Log(String);

impl Log {
/// Parse the log data as JSON, returning a `serde_json::Value`
#[cfg(feature = "serde_json")]
pub fn parse_json(&self) -> Result<serde_json::Value, Error> {
serde_json::from_str(&self.0).map_err(|_| Error::Parse)
}
}

impl AsRef<str> for Log {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}

impl Display for Log {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
Loading