Skip to content

Commit

Permalink
split A.3, abci-in-rpc
Browse files Browse the repository at this point in the history
  • Loading branch information
hdevalence committed Sep 20, 2022
1 parent b7f3125 commit 8bc6a97
Show file tree
Hide file tree
Showing 33 changed files with 917 additions and 78 deletions.
2 changes: 1 addition & 1 deletion light-client-verifier/src/prelude.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Re-export according to alloc::prelude::v1 because it is not yet stabilized
// https://doc.rust-lang.org/src/alloc/prelude/v1.rs.html
pub use alloc::borrow::ToOwned;
pub use alloc::{
borrow::ToOwned,
boxed::Box,
format,
string::{String, ToString},
Expand Down
2 changes: 1 addition & 1 deletion light-client/src/evidence.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Fork evidence data structures and interfaces.

use contracts::contract_trait;
use tendermint::abci::transaction::Hash;
pub use tendermint::evidence::Evidence;
use tendermint_rpc::abci::transaction::Hash;

use crate::{components::io::IoError, verifier::types::PeerId};

Expand Down
2 changes: 1 addition & 1 deletion light-client/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ use std::{collections::HashMap, time::Duration};
use contracts::contract_trait;
use serde::{Deserialize, Serialize};
use tendermint::{
abci::transaction::Hash,
block::Height as HeightStr,
evidence::{Duration as DurationStr, Evidence},
};
use tendermint_rpc as rpc;
use tendermint_rpc::abci::transaction::Hash;

use crate::{
components::{
Expand Down
1 change: 1 addition & 0 deletions rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ subtle-encoding = { version = "0.5", default-features = false, features = ["bech
url = { version = "2.2", default-features = false }
walkdir = { version = "2.3", default-features = false }
flex-error = { version = "0.4.4", default-features = false }
subtle = { version = "2", default-features = false }

# Optional dependencies
async-trait = { version = "0.1", optional = true, default-features = false }
Expand Down
34 changes: 34 additions & 0 deletions rpc/src/abci.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//! Old ABCI structures, formerly defined in `tendermint::abci`.
//!
//! The original contents of `tendermint::abci` were created only to model RPC
//! responses, not to model ABCI itself:
//!
//! > NOTE: This module contains types for ABCI responses as consumed from RPC
//! endpoints. It does not contain an ABCI protocol implementation.
//!
//! The old types should be eliminated and
//! merged with the new ABCI domain types. Moving them here in the meantime
//! disentangles improving the ABCI domain modeling from changes to the RPC
//! interface.

mod code;
mod data;
mod gas;
mod info;
mod log;
mod path;

pub mod responses;
pub mod tag;
pub mod transaction;

pub use self::{
code::Code,
data::Data,
gas::Gas,
info::Info,
log::Log,
path::Path,
responses::{DeliverTx, Event, Responses},
transaction::Transaction,
};
108 changes: 108 additions & 0 deletions rpc/src/abci/code.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
use core::{fmt, num::NonZeroU32};

use serde::{
de::{Deserialize, Deserializer, Visitor},
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(NonZeroU32),
}

impl Default for Code {
fn default() -> Code {
Code::Ok
}
}

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 NonZeroU32::new(value) {
Some(value) => Code::Err(value),
None => Code::Ok,
}
}
}

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

impl Serialize for Code {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.value().serialize(serializer)
}
}

impl<'de> Deserialize<'de> for Code {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct CodeVisitor;

impl<'de> Visitor<'de> for CodeVisitor {
type Value = Code;

fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.write_str("integer or string")
}

fn visit_u64<E>(self, val: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Code::from(val as u32))
}

fn visit_str<E>(self, val: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
match val.parse::<u64>() {
Ok(val) => self.visit_u64(val),
Err(_) => Err(E::custom("failed to parse integer")),
}
}
}

deserializer.deserialize_any(CodeVisitor)
}
}
60 changes: 60 additions & 0 deletions rpc/src/abci/data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use serde::{Deserialize, Serialize};

use crate::prelude::*;

/// ABCI transaction data.
///
/// Transactions are opaque binary blobs which are validated according to
/// application-specific rules.
#[derive(Clone, Debug, Eq, PartialEq, Default, Serialize, Deserialize)]
#[serde(transparent)]
pub struct Data(#[serde(with = "tendermint::serializers::bytes::base64string")] Vec<u8>);

impl From<Vec<u8>> for Data {
fn from(value: Vec<u8>) -> Self {
Self(value)
}
}

impl From<Data> for Vec<u8> {
fn from(value: Data) -> Self {
value.0
}
}

impl Data {
/// Get value
pub fn value(&self) -> &Vec<u8> {
&self.0
}
}

#[cfg(test)]
mod tests {
use crate::{abci::Data, prelude::*};

#[test]
fn test_deserialization() {
let json = "\"ChYKFGNvbm5lY3Rpb25fb3Blbl9pbml0\"";
let mydata: Data = serde_json::from_str(json).unwrap();
assert_eq!(
mydata.0,
vec![
// By chance this is a protobuf struct.
10, // Field 1 is a String
22, // Field 1 length is 22
10, // Sub-field 1 is String
20, // Sub-field 1 length is 20
99, 111, 110, 110, 101, 99, 116, 105, 111, 110, 95, 111, 112, 101, 110, 95, 105,
110, 105, 116 // "connection_open_init"
]
);
}

#[test]
fn test_serialization() {
let mydata: Data = vec![1, 2, 3, 4].into();
let json = serde_json::to_string(&mydata).unwrap();
assert_eq!(json, "\"AQIDBA==\"");
}
}
71 changes: 71 additions & 0 deletions rpc/src/abci/gas.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//! 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 core::{
fmt::{self, Display},
str::FromStr,
};

use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer};
use tendermint::error::Error;

use crate::prelude::*;

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

impl Gas {
/// Get the inner integer value
pub fn value(self) -> u64 {
self.0
}
}

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> {
let res = s
.parse::<u64>()
.map_err(|e| Error::parse_int(s.to_string(), e))?
.into();

Ok(res)
}
}

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

impl Serialize for Gas {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.to_string().serialize(serializer)
}
}
21 changes: 21 additions & 0 deletions rpc/src/abci/info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use core::fmt::{self, Display};

use serde::{Deserialize, Serialize};

use crate::prelude::*;

/// ABCI info
#[derive(Clone, Debug, Default, 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)
}
}
35 changes: 35 additions & 0 deletions rpc/src/abci/log.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use core::{fmt, fmt::Display};

use serde::{Deserialize, Serialize};

use crate::prelude::*;

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

impl Log {
/// Convenience function: get value
pub fn value(&self) -> &String {
&self.0
}
}

impl From<&str> for Log {
fn from(s: &str) -> Self {
Log(s.to_owned())
}
}

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

0 comments on commit 8bc6a97

Please sign in to comment.