From bce1a004531a78cf2fed903e1edfd19f35d2c3f0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 21 Apr 2019 21:22:34 -0700 Subject: [PATCH 1/4] tendermint-rs: /health RPC endpoint --- tendermint-rs/src/rpc/endpoint.rs | 1 + tendermint-rs/src/rpc/endpoint/health.rs | 22 +++++++++++++++++++++ tendermint-rs/tests/rpc.rs | 5 +++++ tendermint-rs/tests/support/rpc/health.json | 5 +++++ 4 files changed, 33 insertions(+) create mode 100644 tendermint-rs/src/rpc/endpoint/health.rs create mode 100644 tendermint-rs/tests/support/rpc/health.json diff --git a/tendermint-rs/src/rpc/endpoint.rs b/tendermint-rs/src/rpc/endpoint.rs index dc7b482..b908470 100644 --- a/tendermint-rs/src/rpc/endpoint.rs +++ b/tendermint-rs/src/rpc/endpoint.rs @@ -5,6 +5,7 @@ pub mod block; pub mod blockchain; pub mod commit; pub mod genesis; +pub mod health; pub mod net_info; pub mod status; pub mod validators; diff --git a/tendermint-rs/src/rpc/endpoint/health.rs b/tendermint-rs/src/rpc/endpoint/health.rs new file mode 100644 index 0000000..41c81f0 --- /dev/null +++ b/tendermint-rs/src/rpc/endpoint/health.rs @@ -0,0 +1,22 @@ +//! `/health` endpoint JSONRPC wrapper + +use crate::rpc; +use serde::{Deserialize, Serialize}; + +/// Perform a basic healthceck of the backend +#[derive(Default)] +pub struct Request; + +impl rpc::Request for Request { + type Response = Response; + + fn path(&self) -> rpc::request::Path { + "/health".parse().unwrap() + } +} + +/// Healthcheck responses +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Response {} + +impl rpc::Response for Response {} diff --git a/tendermint-rs/tests/rpc.rs b/tendermint-rs/tests/rpc.rs index fcc67aa..32199d3 100644 --- a/tendermint-rs/tests/rpc.rs +++ b/tendermint-rs/tests/rpc.rs @@ -79,6 +79,11 @@ mod endpoints { assert_eq!(consensus_params.block_size.max_bytes, 150000); } + #[test] + fn health() { + endpoint::health::Response::from_json(&read_json_fixture("health")).unwrap(); + } + #[test] fn net_info() { let response = diff --git a/tendermint-rs/tests/support/rpc/health.json b/tendermint-rs/tests/support/rpc/health.json new file mode 100644 index 0000000..8656292 --- /dev/null +++ b/tendermint-rs/tests/support/rpc/health.json @@ -0,0 +1,5 @@ +{ + "jsonrpc": "2.0", + "id": "", + "result": {} +} From 9674ab46a23efc8cd5da8cdfc383517052883929 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 22 Apr 2019 09:49:15 -0700 Subject: [PATCH 2/4] tendermint-rs: Initial JSONRPC over HTTP client Adds a hyper-based HTTP client for making JSONRPC requests. Uses a slightly old version of hyper (0.10) which does not yet depend on futures/tokio, the idea being updating to a fully async version should be possible in the future. Adds an integration test which can be used against gaiad locally. This isn't run in CI (yet) but it is built in CI at least to ensure changes still allow it to compile. --- .circleci/config.yml | 6 +- Cargo.lock | 462 ++++++++++++------- tendermint-rs/Cargo.toml | 7 +- tendermint-rs/src/block/commit.rs | 42 +- tendermint-rs/src/block/height.rs | 17 +- tendermint-rs/src/evidence.rs | 2 +- tendermint-rs/src/lib.rs | 2 - tendermint-rs/src/node/info.rs | 25 +- tendermint-rs/src/rpc.rs | 5 +- tendermint-rs/src/rpc/client.rs | 126 +++++ tendermint-rs/src/rpc/endpoint/abci_info.rs | 4 +- tendermint-rs/src/rpc/endpoint/blockchain.rs | 3 +- tendermint-rs/src/rpc/error.rs | 24 +- tendermint-rs/src/rpc/id.rs | 19 +- tendermint-rs/src/rpc/response.rs | 53 ++- tendermint-rs/src/rpc/version.rs | 5 +- tendermint-rs/src/transaction.rs | 8 +- tendermint-rs/tests/integration.rs | 77 ++++ 18 files changed, 666 insertions(+), 221 deletions(-) create mode 100644 tendermint-rs/src/rpc/client.rs create mode 100644 tendermint-rs/tests/integration.rs diff --git a/.circleci/config.yml b/.circleci/config.yml index 2ae1938..f6302db 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -26,7 +26,7 @@ jobs: cargo build --features=yubihsm cargo build --features=ledgertm cargo build --features=yubihsm,ledgertm,softsign - cd tendermint-rs && cargo build --no-default-features + cd tendermint-rs && cargo build --no-default-features && cargo build --features=integration --tests - run: name: build --release command: | @@ -39,8 +39,8 @@ jobs: command: | rustc --version cargo --version - cargo test --all --all-features -- --test-threads 1 - cd tendermint-rs && cargo test --release --all-features + cargo test --all-features -- --test-threads 1 + cd tendermint-rs && cargo test --release --features=amino-types,rpc,secret-connection - run: name: audit command: | diff --git a/Cargo.lock b/Cargo.lock index ab2e552..88a3c26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,9 +14,9 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", "simplelog 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -27,7 +27,7 @@ version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -62,8 +62,17 @@ dependencies = [ [[package]] name = "arc-swap" -version = "0.3.7" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "argon2rs" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "arrayref" @@ -85,7 +94,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -95,15 +104,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "backtrace" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -112,7 +121,16 @@ version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "base64" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -120,12 +138,12 @@ name = "bit-set" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bit-vec" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -133,6 +151,15 @@ name = "bitflags" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "block-buffer" version = "0.3.3" @@ -144,7 +171,7 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "block-padding 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -224,7 +251,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -255,35 +282,9 @@ dependencies = [ ] [[package]] -name = "crossbeam-deque" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-utils" -version = "0.2.2" +name = "constant_time_eq" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "crypto-mac" @@ -330,6 +331,16 @@ dependencies = [ "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "dirs" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ed25519-dalek" version = "1.0.0-pre.1" @@ -344,7 +355,7 @@ dependencies = [ [[package]] name = "either" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -352,7 +363,7 @@ name = "failure" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -362,8 +373,8 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -424,7 +435,7 @@ dependencies = [ "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -446,12 +457,45 @@ dependencies = [ "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "httparse" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "hyper" +version = "0.10.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "idna" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -461,9 +505,9 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -471,7 +515,7 @@ name = "itertools" version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "either 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -479,6 +523,11 @@ name = "itoa" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "language-tags" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "lazy_static" version = "1.3.0" @@ -494,7 +543,7 @@ dependencies = [ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hidapi 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -514,7 +563,7 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.50" +version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -523,7 +572,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bit-set 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "libusb-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -532,7 +581,7 @@ name = "libusb-sys" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -544,6 +593,14 @@ dependencies = [ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "log" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "log" version = "0.4.6" @@ -558,9 +615,12 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "memoffset" -version = "0.2.1" +name = "mime" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "nix" @@ -570,7 +630,7 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -582,7 +642,7 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -609,7 +669,7 @@ name = "num_cpus" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -639,11 +699,11 @@ name = "parking_lot_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -653,9 +713,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "percent-encoding" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "pkg-config" version = "0.3.14" @@ -687,7 +751,7 @@ dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -699,7 +763,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "quote" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", @@ -711,10 +775,10 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -723,7 +787,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -732,7 +796,7 @@ dependencies = [ "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -778,9 +842,9 @@ name = "rand_jitter" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -790,10 +854,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -814,45 +878,35 @@ dependencies = [ ] [[package]] -name = "rayon" -version = "1.0.3" +name = "rdrand" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "rayon-core" -version = "1.4.1" +name = "redox_syscall" +version = "0.1.54" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] -name = "rdrand" -version = "0.4.0" +name = "redox_users" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "redox_syscall" -version = "0.1.51" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "remove_dir_all" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -862,15 +916,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-demangle" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -886,6 +940,16 @@ name = "ryu" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "safemem" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "scopeguard" version = "0.3.3" @@ -914,20 +978,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.89" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.89" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -937,7 +1001,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -956,7 +1020,7 @@ name = "sha2" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -967,8 +1031,8 @@ name = "signal-hook" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -980,7 +1044,7 @@ dependencies = [ "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle-encoding 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle-encoding 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1011,7 +1075,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1036,12 +1100,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "subtle-encoding" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1050,17 +1114,17 @@ version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syn" -version = "0.15.29" +version = "0.15.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1070,8 +1134,8 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1099,11 +1163,11 @@ version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1116,29 +1180,32 @@ dependencies = [ "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "hkdf 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)", "prost-amino 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "prost-amino-derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "signatory 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "signatory-dalek 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle-encoding 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle-encoding 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "tai64 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "term" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1146,14 +1213,14 @@ name = "time" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tiny-bip39" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1185,8 +1252,8 @@ dependencies = [ "prost-amino-derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "signal-hook 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1194,10 +1261,10 @@ dependencies = [ "signatory-dalek 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "signatory-secp256k1 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle-encoding 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle-encoding 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "tendermint 0.7.0-alpha1", - "tiny-bip39 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "yubihsm 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1208,14 +1275,48 @@ name = "toml" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "traitobject" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "typeable" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "typenum" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicase" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "unicode-xid" version = "0.1.0" @@ -1226,14 +1327,29 @@ name = "untrusted" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "url" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "uuid" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "version_check" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "void" version = "1.0.2" @@ -1244,7 +1360,7 @@ name = "wait-timeout" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1254,7 +1370,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1302,14 +1418,14 @@ dependencies = [ "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "signatory 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1341,8 +1457,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)", ] [metadata] @@ -1351,18 +1467,21 @@ dependencies = [ "checksum aes 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "54eb1d8fe354e5fc611daf4f2ea97dd45a765f4f1e4512306ec183ae2e8f20c9" "checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" "checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" -"checksum arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1025aeae2b664ca0ea726a89d574fe8f4e77dd712d443236ad1de00379450cf6" +"checksum arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "bc4662175ead9cd84451d5c35070517777949a2ed84551764129cedb88384841" +"checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" "checksum atomicwrites 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a3420b33cdefd3feb223dddc23739fc05cc034eb0f2be792c763e3d89e1eb6e3" "checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" -"checksum backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5a90e2b463010cd0e0ce9a11d4a9d5d58d9f41d4a6ba3dcaf9e68b466e88b4" +"checksum backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f106c02a3604afcdc0df5d36cc47b44b55917dbaf3d808f71c163a0ddba64637" "checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" +"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" "checksum bit-set 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e6e1e6fb1c9e3d6fcdec57216a74eaa03e41f52a22f13a16438251d8e88b89da" -"checksum bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4440d5cb623bb7390ae27fec0bb6c61111969860f8e3ae198bfa0663645e67cf" +"checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" "checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" -"checksum block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49665c62e0e700857531fa5d3763e91b539ff1abeebd56808d378b495870d60d" +"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" "checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" "checksum block-modes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "283fa06a14026feac8912bf35328fc074f5d68907fd4b9cccad5658a3fc62a30" "checksum block-padding 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d75255892aeb580d3c566f213a2b6fdc1c66667839f45719ee1d30ebf2aea591" @@ -1377,16 +1496,15 @@ dependencies = [ "checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cmac 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f4a435124bcc292eba031f1f725d7abacdaf13cbf9f935450e8c45aa9e96cad" -"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" -"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" -"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" +"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" "checksum curve25519-dalek 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e1f8a6fc0376eb52dc18af94915cc04dfdf8353746c0e8c550ae683a0815e5c1" "checksum dbl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "28dc203b75decc900220c4d9838e738d08413e663c26826ba92b669bed1d0795" "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" +"checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" "checksum ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81956bcf7ef761fb4e1d88de3fa181358a0d26cbcb9755b587a08f9119824b86" -"checksum either 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c67353c641dc847124ea1902d69bd753dee9bb3beff9aa3662ecf86c971d1fac" +"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" @@ -1399,20 +1517,25 @@ dependencies = [ "checksum hidapi 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "25440089a47b7c63b7a3515d1cdfcd0ac3d649fdc360540944e05c4e7899b4fe" "checksum hkdf 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a89c4638cf4e02d9db29750659d2af13d9001b508716f77d4693ec8a1f8bda8" "checksum hmac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f127a908633569f208325f86f71255d3363c79721d7f9fe31cd5569908819771" +"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" +"checksum hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)" = "df0caae6b71d266b91b4a83111a61d2b94ed2e2bea024c532b933dcff867e58c" +"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum isatty 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e31a8281fc93ec9693494da65fbf28c0c2aa60a2eaec25dc58e2f31952e95edc" "checksum itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" +"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" "checksum ledger 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6c9a2f47929b010a64a4bf9cdfe03b0d02175d44db0b91e16283f5a4a731d52c" "checksum ledger-tendermint 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "798701caf0fe437d7d72939eed5f18ae187e9c414eb5f4e9b8eeceaa16f99a23" -"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" +"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" "checksum libusb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f990ddd929cbe53de4ecd6cf26e1f4e0c5b9796e4c629d9046570b03738aa53" "checksum libusb-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4c53b6582563d64ad3e692f54ef95239c3ea8069e82c9eb70ca948869a7ad767" "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" +"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" +"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" "checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17" "checksum nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46f0f3210768d796e8fa79ec70ee6af172dacbe7147f5e69be5240a47778302b" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" @@ -1424,12 +1547,13 @@ dependencies = [ "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" "checksum pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" +"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" "checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" "checksum prost-amino 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04c5c4189b6c3e054c064a0c88d51f9379db268d5f8f6ea6afffd3849aeca1a7" "checksum prost-amino-derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6376b995db84c9791ab5d3f7bc3e315f8bc1a55fe139a0a2da24aa24e27de809" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" -"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" +"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" @@ -1441,21 +1565,22 @@ dependencies = [ "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -"checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473" -"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85" +"checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" +"checksum redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe5204c3a17e97dde73f285d49be585df59ed84b50a872baf416e73b62c3828" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" -"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619" +"checksum rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ccc78bfd5acd7bf3e89cffcf899e5cb1a52d6fafa8dec2739ad70c9577a57288" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" +"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" +"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum secp256k1 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfaccd3a23619349e0878d9a241f34b1982343cdf67367058cd7d078d326b63e" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)" = "92514fb95f900c9b5126e32d020f5c6d40564c27a5ea6d1d7d9f157a96623560" -"checksum serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6eabf4b5914e88e24eea240bb7c9f9a2cbc1bbbe8d961d381975ec3c6b806c" +"checksum serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "aa5f7c20820475babd2c077c3ab5f8c77a31c15e16ea38687b4c02d3e48680f4" +"checksum serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "58fc82bec244f168b23d1963b45c8bf5726e9a15a9d146a067f9081aeed2de79" "checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d" "checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" "checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" @@ -1468,25 +1593,32 @@ dependencies = [ "checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" "checksum subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "702662512f3ddeb74a64ce2fbbf3707ee1b6bb663d28bb054e0779bbc720d926" -"checksum subtle-encoding 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef97d4fddc455c6c661bb2f5ea5addae88d2cb258a4542348a14b2c1d0514844" +"checksum subtle-encoding 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "83357cf892635c468b754d4bd3d99f904464d1d9d3eeb53fab92c5bc1ab82c04" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" -"checksum syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1825685f977249735d510a242a6727b46efe914bb67e38d30c071b1b72b1d5c2" +"checksum syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)" = "846620ec526c1599c070eff393bfeeeb88a93afa2513fc3b49f1fea84cf7b0ed" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum tai64 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aec79c84b38f055fd98013da804b912a165d9691a3fd27fefabc8b46ed8b6901" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b86c784c88d98c801132806dadd3819ed29d8600836c4088e855cdf3e178ed8a" -"checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" +"checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" -"checksum tiny-bip39 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a1415431cb2398d84da64173f8473c792808314427d4a6f2f3ea85ae67239fe3" +"checksum tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060" "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" +"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" +"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" +"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" +"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" -"checksum uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0238db0c5b605dd1cf51de0f21766f97fba2645897024461d6a00c036819a768" +"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +"checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" +"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ee1585dc1484373cbc1cee7aafda26634665cf449436fd6e24bfd1fad230538" diff --git a/tendermint-rs/Cargo.toml b/tendermint-rs/Cargo.toml index 4561db0..1daae43 100644 --- a/tendermint-rs/Cargo.toml +++ b/tendermint-rs/Cargo.toml @@ -34,6 +34,7 @@ chrono = { version = "0.4", features = ["serde"] } digest = "0.8" failure = "0.1" hkdf = { version = "0.7", optional = true } +hyper = { version = "0.10", optional = true } prost-amino = { version = "0.4.0", optional = true } prost-amino-derive = { version = "0.4.0", optional = true } rand_os = { version = "0.1", optional = true } @@ -46,6 +47,7 @@ sha2 = { version = "0.8", default-features = false } subtle = "2" subtle-encoding = { version = "0.3", features = ["bech32-preview"] } tai64 = { version = "1", optional = true, features = ["chrono"] } +uuid = { version = "0.7", optional = true, default-features = false } x25519-dalek = { version = "0.5", optional = true, default-features = false, features = ["u64_backend"] } zeroize = { version = "0.6", optional = true } @@ -55,12 +57,13 @@ serde_json = "1" [features] default = ["serde", "tai64"] amino-types = ["prost-amino", "prost-amino-derive"] -rpc = ["serde", "serde_json"] +integration = [] +rpc = ["hyper", "rand_os", "serde", "serde_json", "uuid"] secret-connection = [ "amino-types", "byteorder", - "hkdf", "rand_os", + "hkdf", "ring", "signatory-dalek", "x25519-dalek", diff --git a/tendermint-rs/src/block/commit.rs b/tendermint-rs/src/block/commit.rs index cf297b6..c20f710 100644 --- a/tendermint-rs/src/block/commit.rs +++ b/tendermint-rs/src/block/commit.rs @@ -3,6 +3,7 @@ use crate::{block, Vote}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +use std::{ops::Deref, slice}; /// Last commit to a particular blockchain: +2/3 precommit signatures. /// @@ -14,5 +15,44 @@ pub struct LastCommit { pub block_id: block::Id, /// Precommits - pub precommits: Vec>, + pub precommits: Precommits, +} + +/// Precommits which certify that a block is valid +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Clone, Debug)] +pub struct Precommits(Option>>); + +impl Precommits { + /// Create a new precommit collection + pub fn new(into_precommits: I) -> Self + where + I: Into>>, + { + Self(Some(into_precommits.into())) + } + + /// Convert this collection of precommits into a vector + pub fn into_vec(self) -> Vec> { + self.iter().cloned().collect() + } + + /// Iterate over the precommits in the collection + pub fn iter(&self) -> slice::Iter> { + self.as_ref().iter() + } +} + +impl AsRef<[Option]> for Precommits { + fn as_ref(&self) -> &[Option] { + self.0.as_ref().map(Vec::as_slice).unwrap_or_else(|| &[]) + } +} + +impl Deref for Precommits { + type Target = [Option]; + + fn deref(&self) -> &[Option] { + self.as_ref() + } } diff --git a/tendermint-rs/src/block/height.rs b/tendermint-rs/src/block/height.rs index db7c3d6..bd05e77 100644 --- a/tendermint-rs/src/block/height.rs +++ b/tendermint-rs/src/block/height.rs @@ -12,16 +12,23 @@ use std::{ pub struct Height(pub u64); impl Height { - /// Parse height from the integer type used in Amino messages - pub fn try_from_i64(n: i64) -> Result { + /// Convert `u64` to block height. + /// + /// Note that 0 is not a valid block height. + pub fn try_from_u64(n: u64) -> Result { // Minimum height is 1 if n > 0 { - Ok(Height(n as u64)) + Ok(Height(n)) } else { Err(Error::OutOfRange) } } + /// Convert `i64` (used in e.g. Amino messages) to block height. + pub fn try_from_i64(n: i64) -> Result { + Self::try_from_u64(n as u64) + } + /// Get inner integer value. Alternative to `.0` or `.into()` pub fn value(self) -> u64 { self.0 @@ -59,7 +66,7 @@ impl From for Height { impl From for Height { fn from(n: u64) -> Height { - Height(n) + Self::try_from_u64(n).unwrap() } } @@ -79,7 +86,7 @@ impl FromStr for Height { type Err = Error; fn from_str(s: &str) -> Result { - Self::try_from_i64(s.parse::().map_err(|_| Error::Parse)?) + Self::try_from_u64(s.parse::().map_err(|_| Error::Parse)?) } } diff --git a/tendermint-rs/src/evidence.rs b/tendermint-rs/src/evidence.rs index 74ffb25..0ae7d3a 100644 --- a/tendermint-rs/src/evidence.rs +++ b/tendermint-rs/src/evidence.rs @@ -73,7 +73,7 @@ impl Data { /// Convert this evidence data into a vector pub fn into_vec(self) -> Vec { - self.evidence.unwrap_or_else(|| vec![]) + self.iter().cloned().collect() } /// Iterate over the evidence data diff --git a/tendermint-rs/src/lib.rs b/tendermint-rs/src/lib.rs index 474481e..b4bece3 100644 --- a/tendermint-rs/src/lib.rs +++ b/tendermint-rs/src/lib.rs @@ -1,5 +1,3 @@ -//! Tendermint blockchain network information types. -//! //! Tendermint is a high-performance blockchain consensus engine that powers //! Byzantine fault tolerant applications written in any programming language. //! This crate provides types for representing information about Tendermint diff --git a/tendermint-rs/src/node/info.rs b/tendermint-rs/src/node/info.rs index 2735ea5..9f4e16d 100644 --- a/tendermint-rs/src/node/info.rs +++ b/tendermint-rs/src/node/info.rs @@ -2,6 +2,7 @@ use crate::{chain, channel::Channels, net, node, serializers, Moniker, Version}; use serde::{Deserialize, Serialize}; +use std::fmt::{self, Display}; /// Node information #[derive(Clone, Debug, Deserialize, Serialize)] @@ -13,7 +14,7 @@ pub struct Info { pub id: node::Id, /// Listen address - pub listen_addr: net::Address, + pub listen_addr: ListenAddress, /// Tendermint network / chain ID, pub network: chain::Id, @@ -56,6 +57,28 @@ pub struct ProtocolVersionInfo { pub app: u64, } +/// Listen address information +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct ListenAddress(String); + +impl ListenAddress { + /// Convert `ListenAddress` to a `net::Address` + pub fn to_net_address(&self) -> Option { + // TODO(tarcieri): validate these and handle them better at parse time + if self.0.starts_with("tcp://") { + self.0.parse().ok() + } else { + format!("tcp://{}", self.0).parse().ok() + } + } +} + +impl Display for ListenAddress { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } +} + /// Other information #[derive(Clone, Debug, Deserialize, Serialize)] pub struct OtherInfo { diff --git a/tendermint-rs/src/rpc.rs b/tendermint-rs/src/rpc.rs index 9177472..58d8dd1 100644 --- a/tendermint-rs/src/rpc.rs +++ b/tendermint-rs/src/rpc.rs @@ -2,6 +2,7 @@ //! //! Wraps the RPC API described at: +mod client; pub mod endpoint; pub mod error; mod id; @@ -9,4 +10,6 @@ pub mod request; pub mod response; mod version; -pub use self::{error::Error, id::Id, request::Request, response::Response, version::Version}; +pub use self::{ + client::Client, error::Error, id::Id, request::Request, response::Response, version::Version, +}; diff --git a/tendermint-rs/src/rpc/client.rs b/tendermint-rs/src/rpc/client.rs new file mode 100644 index 0000000..68bddee --- /dev/null +++ b/tendermint-rs/src/rpc/client.rs @@ -0,0 +1,126 @@ +//! Tendermint RPC client + +#![allow(unused_imports)] + +use crate::{ + block::Height, + net, + rpc::{self, endpoint::*, Error, Response}, + Genesis, +}; +use hyper::header; +use std::io::Read; + +/// Tendermint RPC client. +/// +/// Presently supports JSONRPC via HTTP. +pub struct Client { + /// Address of the RPC server + address: net::Address, +} + +impl Client { + /// Create a new Tendermint RPC client, connecting to the given address + pub fn new(address: &net::Address) -> Result { + let client = Client { + address: address.clone(), + }; + client.health()?; + Ok(client) + } + + /// `/abci_info`: get information about the ABCI application. + pub fn abci_info(&self) -> Result { + Ok(self.perform(abci_info::Request)?.response) + } + + /// `/block`: get block at a given height. + // TODO(tarcieri): support for getting latest block + pub fn block(&self, height: H) -> Result + where + H: Into, + { + self.perform(block::Request::new(height.into())) + } + + /// `/blockchain`: get block headers for `min` <= `height` <= `max`. + /// + /// Block headers are returned in descending order (highest first). + /// + /// Returns at most 20 items. + pub fn blockchain(&self, min: H, max: H) -> Result + where + H: Into, + { + // TODO(tarcieri): return errors for invalid params before making request? + self.perform(blockchain::Request::new(min.into(), max.into())) + } + + /// `/commit`: get block commit at a given height. + // TODO(tarcieri): support for getting latest block + pub fn commit(&self, height: H) -> Result + where + H: Into, + { + self.perform(commit::Request::new(height.into())) + } + + /// `/health`: get node health. + /// + /// Returns empty result (200 OK) on success, no response in case of an error. + pub fn health(&self) -> Result<(), Error> { + self.perform(health::Request)?; + Ok(()) + } + + /// `/genesis`: get genesis file. + pub fn genesis(&self) -> Result { + Ok(self.perform(genesis::Request)?.genesis) + } + + /// `/net_info`: obtain information about P2P and other network connections. + pub fn net_info(&self) -> Result { + self.perform(net_info::Request) + } + + /// `/status`: get Tendermint status including node info, pubkey, latest + /// block hash, app hash, block height and time. + pub fn status(&self) -> Result { + self.perform(status::Request) + } + + /// Perform a request against the RPC endpoint + pub fn perform(&self, request: R) -> Result + where + R: rpc::Request, + { + let (host, port) = match &self.address { + net::Address::Tcp { host, port, .. } => (host, port), + other => Err(Error::invalid_params(&format!( + "invalid RPC address: {:?}", + other + )))?, + }; + + let mut headers = hyper::header::Headers::new(); + + // TODO(tarcieri): persistent connections + headers.set(header::Connection::close()); + headers.set(header::ContentType::json()); + headers.set(header::UserAgent("tendermint.rs RPC client".to_owned())); + + let http_client = hyper::Client::new(); + + let mut res = http_client + .get(&format!("http://{}:{}{}", host, port, request.path())) + .headers(headers) + .send() + .map_err(Error::server_error)?; + + let mut response_body = Vec::new(); + res.read_to_end(&mut response_body) + .map_err(Error::server_error)?; + + R::Response::from_json(&response_body) + } +} diff --git a/tendermint-rs/src/rpc/endpoint/abci_info.rs b/tendermint-rs/src/rpc/endpoint/abci_info.rs index ce45626..b284f2e 100644 --- a/tendermint-rs/src/rpc/endpoint/abci_info.rs +++ b/tendermint-rs/src/rpc/endpoint/abci_info.rs @@ -20,14 +20,14 @@ impl rpc::Request for Request { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Response { /// ABCI info - pub response: AbciInfoResponse, + pub response: AbciInfo, } impl rpc::Response for Response {} /// ABCI information #[derive(Clone, Debug, Deserialize, Serialize)] -pub struct AbciInfoResponse { +pub struct AbciInfo { /// Name of the application pub data: String, diff --git a/tendermint-rs/src/rpc/endpoint/blockchain.rs b/tendermint-rs/src/rpc/endpoint/blockchain.rs index 14d9652..06c27c8 100644 --- a/tendermint-rs/src/rpc/endpoint/blockchain.rs +++ b/tendermint-rs/src/rpc/endpoint/blockchain.rs @@ -31,7 +31,7 @@ impl rpc::Request for Request { fn path(&self) -> rpc::request::Path { // TODO(tarcieri): use a `uri` crate to construct this? - format!("/block?minHeight={}&maxHeight={}", self.min, self.max) + format!("/blockchain?minHeight={}&maxHeight={}", self.min, self.max) .parse() .unwrap() } @@ -44,6 +44,7 @@ pub struct Response { pub last_height: block::Height, /// Block metadata + #[serde(default)] pub block_metas: Vec, } diff --git a/tendermint-rs/src/rpc/error.rs b/tendermint-rs/src/rpc/error.rs index e21293f..b0030eb 100644 --- a/tendermint-rs/src/rpc/error.rs +++ b/tendermint-rs/src/rpc/error.rs @@ -1,6 +1,5 @@ //! JSONRPC error types -use super::Version; use failure::Fail; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::fmt::{self, Display}; @@ -29,6 +28,11 @@ impl Error { } } + /// Create a new invalid parameter error + pub fn invalid_params(data: &str) -> Error { + Error::new(Code::InvalidParams, Some(data.to_string())) + } + /// Create a new parse error pub fn parse_error(error: E) -> Error where @@ -37,12 +41,12 @@ impl Error { Error::new(Code::ParseError, Some(error.to_string())) } - /// Create an unsupported RPC version error - pub fn unsupported_version(version: &Version) -> Error { - Error::new( - Code::ServerError, - Some(format!("server RPC version unsupported: {})", version,)), - ) + /// Create a new server error + pub fn server_error(data: D) -> Error + where + D: Display, + { + Error::new(Code::ServerError, Some(data.to_string())) } /// Obtain the `rpc::error::Code` for this error @@ -82,6 +86,12 @@ impl Fail for Error { } } +impl From for Error { + fn from(hyper_error: hyper::Error) -> Error { + panic!("what am I supposed to do with this? {:?}", hyper_error); + } +} + /// Tendermint RPC error codes. /// /// See `func RPC*Error()` definitions in: diff --git a/tendermint-rs/src/rpc/id.rs b/tendermint-rs/src/rpc/id.rs index b2f8378..d0a73c3 100644 --- a/tendermint-rs/src/rpc/id.rs +++ b/tendermint-rs/src/rpc/id.rs @@ -1,11 +1,28 @@ //! JSONRPC IDs +use rand_os::{rand_core::RngCore, OsRng}; use serde::{Deserialize, Serialize}; -/// JSONRPC ID +/// JSONRPC ID: request-specific identifier #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub struct Id(String); +impl Id { + /// Create a JSONRPC ID containing a UUID v4 (i.e. random) + pub fn uuid_v4() -> Self { + let mut rng = OsRng::new().unwrap(); + let mut bytes = [0; 16]; + rng.fill_bytes(&mut bytes); + + let uuid = uuid::Builder::from_bytes(bytes) + .set_variant(uuid::Variant::RFC4122) + .set_version(uuid::Version::Random) + .build(); + + Id(uuid.to_string()) + } +} + impl AsRef for Id { fn as_ref(&self) -> &str { self.0.as_ref() diff --git a/tendermint-rs/src/rpc/response.rs b/tendermint-rs/src/rpc/response.rs index 4371c5b..2faaf62 100644 --- a/tendermint-rs/src/rpc/response.rs +++ b/tendermint-rs/src/rpc/response.rs @@ -6,43 +6,43 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize}; /// JSONRPC responses pub trait Response: Serialize + DeserializeOwned + Sized { /// Parse a JSONRPC response from a JSON string - fn from_json(response: &str) -> Result { - let wrapper: Wrapper = serde_json::from_str(response).map_err(Error::parse_error)?; + fn from_json(response: T) -> Result + where + T: AsRef<[u8]>, + { + let wrapper: Wrapper = + serde_json::from_slice(response.as_ref()).map_err(Error::parse_error)?; + wrapper.into_result() } } /// JSONRPC response wrapper (i.e. message envelope) #[derive(Debug, Deserialize, Serialize)] -#[serde(untagged)] -enum Wrapper { - /// RPC completed successfully - Success { jsonrpc: Version, id: Id, result: R }, - - /// RPC error - Error { - jsonrpc: Version, - id: Id, - error: Error, - }, +struct Wrapper { + /// JSONRPC version + jsonrpc: Version, + + /// Identifier included in request + id: Id, + + /// Results of request (if successful) + result: Option, + + /// Error message if unsuccessful + error: Option, } impl Wrapper { /// Get JSONRPC version pub fn version(&self) -> &Version { - match self { - Wrapper::Success { jsonrpc, .. } => jsonrpc, - Wrapper::Error { jsonrpc, .. } => jsonrpc, - } + &self.jsonrpc } /// Get JSONRPC ID #[allow(dead_code)] pub fn id(&self) -> &Id { - match self { - Wrapper::Success { id, .. } => id, - Wrapper::Error { id, .. } => id, - } + &self.id } /// Convert this wrapper into a result type @@ -50,9 +50,14 @@ impl Wrapper { // Ensure we're using a supported RPC version self.version().ensure_supported()?; - match self { - Wrapper::Success { result, .. } => Ok(result), - Wrapper::Error { error, .. } => Err(error), + if let Some(error) = self.error { + Err(error) + } else if let Some(result) = self.result { + Ok(result) + } else { + Err(Error::server_error( + "server returned malformatted JSON (no 'result' or 'error')", + )) } } } diff --git a/tendermint-rs/src/rpc/version.rs b/tendermint-rs/src/rpc/version.rs index 11718ad..8cfa260 100644 --- a/tendermint-rs/src/rpc/version.rs +++ b/tendermint-rs/src/rpc/version.rs @@ -22,7 +22,10 @@ impl Version { if self.is_supported() { Ok(()) } else { - Err(Error::unsupported_version(self)) + Err(Error::server_error(&format!( + "server RPC version unsupported: '{}' (only '{}' supported)", + self.0, SUPPORTED_VERSION + ))) } } } diff --git a/tendermint-rs/src/transaction.rs b/tendermint-rs/src/transaction.rs index 47bc58a..c8d7840 100644 --- a/tendermint-rs/src/transaction.rs +++ b/tendermint-rs/src/transaction.rs @@ -68,19 +68,19 @@ pub struct Data { } impl Data { - /// Create a new evidence collection - pub fn new(into_evidence: I) -> Data + /// Create a new transaction data collection + pub fn new(into_transactions: I) -> Data where I: Into>, { Data { - txs: Some(into_evidence.into()), + txs: Some(into_transactions.into()), } } /// Convert this collection into a vector pub fn into_vec(self) -> Vec { - self.txs.unwrap_or_else(|| vec![]) + self.iter().cloned().collect() } /// Iterate over the transactions in the collection diff --git a/tendermint-rs/tests/integration.rs b/tendermint-rs/tests/integration.rs new file mode 100644 index 0000000..c949c6f --- /dev/null +++ b/tendermint-rs/tests/integration.rs @@ -0,0 +1,77 @@ +//! Integration tests + +/// RPC integration tests +/// +/// NOTE: health is tested implicitly when the initial client is created +#[cfg(all(feature = "integration", feature = "rpc"))] +mod rpc { + use tendermint::rpc::Client; + + /// Get the address of the local node + #[cfg(all(feature = "integration", feature = "rpc"))] + pub fn localhost_rpc_client() -> Client { + Client::new(&"tcp://127.0.0.1:26657".parse().unwrap()).unwrap() + } + + /// `/abci_info` endpoint + #[test] + fn abci_info() { + let abci_info = localhost_rpc_client().abci_info().unwrap(); + + // TODO(tarcieri): integration testing support for non-gaia apps + assert_eq!(&abci_info.data, "GaiaApp"); + } + + /// `/block` endpoint + #[test] + fn block() { + let height = 1u64; + let block_info = localhost_rpc_client().block(height).unwrap(); + assert_eq!(block_info.block_meta.header.height.value(), height); + } + + /// `/blockchain` endpoint + #[test] + fn blockchain() { + let blockchain_info = localhost_rpc_client().blockchain(1u64, 10u64).unwrap(); + assert_eq!(blockchain_info.block_metas.len(), 10); + } + + /// `/commit` endpoint + #[test] + fn commit() { + let height = 1u64; + let commit_info = localhost_rpc_client().block(height).unwrap(); + assert_eq!(commit_info.block_meta.header.height.value(), height); + } + + /// `/genesis` endpoint + #[test] + fn genesis() { + let genesis = localhost_rpc_client().genesis().unwrap(); + assert_eq!( + genesis.consensus_params.validator.pub_key_types[0].to_string(), + "ed25519" + ); + } + + /// `/net_info` endpoint integration test + #[test] + fn net_info() { + let net_info = localhost_rpc_client().net_info().unwrap(); + assert!(net_info.listening); + } + + /// `/status` endpoint integration test + #[test] + fn status_integration() { + let status = localhost_rpc_client().status().unwrap(); + + // For lack of better things to test + assert_eq!( + status.validator_info.voting_power.value(), + 0, + "don't integration test against a validator" + ); + } +} From 2d01b9b76eebb1179b35546b36e2e722cb76a48c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 22 Apr 2019 11:48:11 -0700 Subject: [PATCH 3/4] tendermint-rs: Use JSON request bodies for RPC calls This allows us to use POST requests and serde serialization when creating requests, rather than trying to shove things into URIs. --- tendermint-rs/src/public_key.rs | 12 +-- tendermint-rs/src/rpc.rs | 4 +- tendermint-rs/src/rpc/client.rs | 19 +++- tendermint-rs/src/rpc/endpoint/abci_info.rs | 6 +- tendermint-rs/src/rpc/endpoint/block.rs | 12 ++- tendermint-rs/src/rpc/endpoint/blockchain.rs | 21 +++-- tendermint-rs/src/rpc/endpoint/commit.rs | 12 ++- tendermint-rs/src/rpc/endpoint/genesis.rs | 6 +- tendermint-rs/src/rpc/endpoint/health.rs | 6 +- tendermint-rs/src/rpc/endpoint/net_info.rs | 6 +- tendermint-rs/src/rpc/endpoint/status.rs | 6 +- tendermint-rs/src/rpc/endpoint/validators.rs | 8 +- tendermint-rs/src/rpc/error.rs | 5 + tendermint-rs/src/rpc/method.rs | 98 ++++++++++++++++++++ tendermint-rs/src/rpc/request.rs | 58 +++++++----- tendermint-rs/src/rpc/response.rs | 5 +- tendermint-rs/src/rpc/version.rs | 23 ++++- 17 files changed, 230 insertions(+), 77 deletions(-) create mode 100644 tendermint-rs/src/rpc/method.rs diff --git a/tendermint-rs/src/public_key.rs b/tendermint-rs/src/public_key.rs index f55adf0..7e4b9e1 100644 --- a/tendermint-rs/src/public_key.rs +++ b/tendermint-rs/src/public_key.rs @@ -143,6 +143,12 @@ impl Algorithm { } } +impl Display for Algorithm { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.as_str()) + } +} + impl FromStr for Algorithm { type Err = Error; @@ -155,12 +161,6 @@ impl FromStr for Algorithm { } } -impl Display for Algorithm { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.as_str()) - } -} - #[cfg(feature = "serde")] impl Serialize for Algorithm { fn serialize(&self, serializer: S) -> Result { diff --git a/tendermint-rs/src/rpc.rs b/tendermint-rs/src/rpc.rs index 58d8dd1..c509fc3 100644 --- a/tendermint-rs/src/rpc.rs +++ b/tendermint-rs/src/rpc.rs @@ -6,10 +6,12 @@ mod client; pub mod endpoint; pub mod error; mod id; +mod method; pub mod request; pub mod response; mod version; pub use self::{ - client::Client, error::Error, id::Id, request::Request, response::Response, version::Version, + client::Client, error::Error, id::Id, method::Method, request::Request, response::Response, + version::Version, }; diff --git a/tendermint-rs/src/rpc/client.rs b/tendermint-rs/src/rpc/client.rs index 68bddee..1347bb7 100644 --- a/tendermint-rs/src/rpc/client.rs +++ b/tendermint-rs/src/rpc/client.rs @@ -1,7 +1,5 @@ //! Tendermint RPC client -#![allow(unused_imports)] - use crate::{ block::Height, net, @@ -35,7 +33,6 @@ impl Client { } /// `/block`: get block at a given height. - // TODO(tarcieri): support for getting latest block pub fn block(&self, height: H) -> Result where H: Into, @@ -43,6 +40,11 @@ impl Client { self.perform(block::Request::new(height.into())) } + /// `/block`: get the latest block + pub fn latest_block(&self) -> Result { + self.perform(block::Request::default()) + } + /// `/blockchain`: get block headers for `min` <= `height` <= `max`. /// /// Block headers are returned in descending order (highest first). @@ -57,7 +59,6 @@ impl Client { } /// `/commit`: get block commit at a given height. - // TODO(tarcieri): support for getting latest block pub fn commit(&self, height: H) -> Result where H: Into, @@ -65,6 +66,11 @@ impl Client { self.perform(commit::Request::new(height.into())) } + /// `/commit`: get the latest block commit + pub fn latest_commit(&self) -> Result { + self.perform(commit::Request::default()) + } + /// `/health`: get node health. /// /// Returns empty result (200 OK) on success, no response in case of an error. @@ -94,6 +100,8 @@ impl Client { where R: rpc::Request, { + let request_body = request.into_json(); + let (host, port) = match &self.address { net::Address::Tcp { host, port, .. } => (host, port), other => Err(Error::invalid_params(&format!( @@ -112,8 +120,9 @@ impl Client { let http_client = hyper::Client::new(); let mut res = http_client - .get(&format!("http://{}:{}{}", host, port, request.path())) + .request(hyper::Post, &format!("http://{}:{}/", host, port)) .headers(headers) + .body(&request_body[..]) .send() .map_err(Error::server_error)?; diff --git a/tendermint-rs/src/rpc/endpoint/abci_info.rs b/tendermint-rs/src/rpc/endpoint/abci_info.rs index b284f2e..ccdf660 100644 --- a/tendermint-rs/src/rpc/endpoint/abci_info.rs +++ b/tendermint-rs/src/rpc/endpoint/abci_info.rs @@ -5,14 +5,14 @@ use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializ use subtle_encoding::base64; /// Request ABCI information from a node -#[derive(Debug, Default)] +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub struct Request; impl rpc::Request for Request { type Response = Response; - fn path(&self) -> rpc::request::Path { - "/abci_info".parse().unwrap() + fn method(&self) -> rpc::Method { + rpc::Method::AbciInfo } } diff --git a/tendermint-rs/src/rpc/endpoint/block.rs b/tendermint-rs/src/rpc/endpoint/block.rs index 230e632..d833ad6 100644 --- a/tendermint-rs/src/rpc/endpoint/block.rs +++ b/tendermint-rs/src/rpc/endpoint/block.rs @@ -7,24 +7,26 @@ use crate::{ use serde::{Deserialize, Serialize}; /// Get information about a specific block +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] pub struct Request { /// Height of the block to request - height: block::Height, + height: Option, } impl Request { /// Create a new request for information about a particular block pub fn new(height: block::Height) -> Self { - Self { height } + Self { + height: Some(height), + } } } impl rpc::Request for Request { type Response = Response; - fn path(&self) -> rpc::request::Path { - // TODO(tarcieri): use a `uri` crate to construct this? - format!("/block?height={}", self.height).parse().unwrap() + fn method(&self) -> rpc::Method { + rpc::Method::Block } } diff --git a/tendermint-rs/src/rpc/endpoint/blockchain.rs b/tendermint-rs/src/rpc/endpoint/blockchain.rs index 06c27c8..3d6e35e 100644 --- a/tendermint-rs/src/rpc/endpoint/blockchain.rs +++ b/tendermint-rs/src/rpc/endpoint/blockchain.rs @@ -5,18 +5,24 @@ use serde::{Deserialize, Serialize}; use std::ops::Range; /// Get information about a specific block +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub struct Request { /// First block in the sequence to request info about - min: block::Height, + #[serde(rename = "minHeight")] + min_height: block::Height, /// Last block in the sequence to request info about - max: block::Height, + #[serde(rename = "maxHeight")] + max_height: block::Height, } impl Request { /// Request information about a sequence of blocks - pub fn new(min: block::Height, max: block::Height) -> Self { - Self { min, max } + pub fn new(min_height: block::Height, max_height: block::Height) -> Self { + Self { + min_height, + max_height, + } } } @@ -29,11 +35,8 @@ impl From> for Request { impl rpc::Request for Request { type Response = Response; - fn path(&self) -> rpc::request::Path { - // TODO(tarcieri): use a `uri` crate to construct this? - format!("/blockchain?minHeight={}&maxHeight={}", self.min, self.max) - .parse() - .unwrap() + fn method(&self) -> rpc::Method { + rpc::Method::Blockchain } } diff --git a/tendermint-rs/src/rpc/endpoint/commit.rs b/tendermint-rs/src/rpc/endpoint/commit.rs index 7e5fcb6..3b05ead 100644 --- a/tendermint-rs/src/rpc/endpoint/commit.rs +++ b/tendermint-rs/src/rpc/endpoint/commit.rs @@ -5,23 +5,25 @@ use serde::{Deserialize, Serialize}; use std::ops::Deref; /// Get commit information about a specific block +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] pub struct Request { - height: block::Height, + height: Option, } impl Request { /// Create a new request for commit info about a particular block pub fn new(height: block::Height) -> Self { - Self { height } + Self { + height: Some(height), + } } } impl rpc::Request for Request { type Response = Response; - fn path(&self) -> rpc::request::Path { - // TODO(tarcieri): use a `uri` crate to construct this? - format!("/commit?height={}", self.height).parse().unwrap() + fn method(&self) -> rpc::Method { + rpc::Method::Commit } } diff --git a/tendermint-rs/src/rpc/endpoint/genesis.rs b/tendermint-rs/src/rpc/endpoint/genesis.rs index 659ee8f..e2a23df 100644 --- a/tendermint-rs/src/rpc/endpoint/genesis.rs +++ b/tendermint-rs/src/rpc/endpoint/genesis.rs @@ -4,14 +4,14 @@ use crate::{rpc, Genesis}; use serde::{Deserialize, Serialize}; /// Get the genesis state for the current chain -#[derive(Default)] +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub struct Request; impl rpc::Request for Request { type Response = Response; - fn path(&self) -> rpc::request::Path { - "/genesis".parse().unwrap() + fn method(&self) -> rpc::Method { + rpc::Method::Genesis } } diff --git a/tendermint-rs/src/rpc/endpoint/health.rs b/tendermint-rs/src/rpc/endpoint/health.rs index 41c81f0..59aef5a 100644 --- a/tendermint-rs/src/rpc/endpoint/health.rs +++ b/tendermint-rs/src/rpc/endpoint/health.rs @@ -4,14 +4,14 @@ use crate::rpc; use serde::{Deserialize, Serialize}; /// Perform a basic healthceck of the backend -#[derive(Default)] +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub struct Request; impl rpc::Request for Request { type Response = Response; - fn path(&self) -> rpc::request::Path { - "/health".parse().unwrap() + fn method(&self) -> rpc::Method { + rpc::Method::Health } } diff --git a/tendermint-rs/src/rpc/endpoint/net_info.rs b/tendermint-rs/src/rpc/endpoint/net_info.rs index 2f3df5b..6b770ac 100644 --- a/tendermint-rs/src/rpc/endpoint/net_info.rs +++ b/tendermint-rs/src/rpc/endpoint/net_info.rs @@ -9,14 +9,14 @@ use std::{ }; /// Request network information from a node -#[derive(Debug, Default)] +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub struct Request; impl rpc::Request for Request { type Response = Response; - fn path(&self) -> rpc::request::Path { - "/net_info".parse().unwrap() + fn method(&self) -> rpc::Method { + rpc::Method::NetInfo } } diff --git a/tendermint-rs/src/rpc/endpoint/status.rs b/tendermint-rs/src/rpc/endpoint/status.rs index 1f6885e..336d344 100644 --- a/tendermint-rs/src/rpc/endpoint/status.rs +++ b/tendermint-rs/src/rpc/endpoint/status.rs @@ -4,14 +4,14 @@ use crate::{block, node, rpc, validator, Hash, Time}; use serde::{Deserialize, Serialize}; /// Node status request -#[derive(Debug, Default)] +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub struct Request; impl rpc::Request for Request { type Response = Response; - fn path(&self) -> rpc::request::Path { - "/status".parse().unwrap() + fn method(&self) -> rpc::Method { + rpc::Method::Status } } diff --git a/tendermint-rs/src/rpc/endpoint/validators.rs b/tendermint-rs/src/rpc/endpoint/validators.rs index 244ea4f..04cbc42 100644 --- a/tendermint-rs/src/rpc/endpoint/validators.rs +++ b/tendermint-rs/src/rpc/endpoint/validators.rs @@ -4,6 +4,7 @@ use crate::{block, rpc, validator}; use serde::{Deserialize, Serialize}; /// List validators for a specific block +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub struct Request { height: block::Height, } @@ -18,11 +19,8 @@ impl Request { impl rpc::Request for Request { type Response = Response; - fn path(&self) -> rpc::request::Path { - // TODO(tarcieri): use a `uri` crate to construct this? - format!("/validators?height={}", self.height) - .parse() - .unwrap() + fn method(&self) -> rpc::Method { + rpc::Method::Validators } } diff --git a/tendermint-rs/src/rpc/error.rs b/tendermint-rs/src/rpc/error.rs index b0030eb..728e82a 100644 --- a/tendermint-rs/src/rpc/error.rs +++ b/tendermint-rs/src/rpc/error.rs @@ -33,6 +33,11 @@ impl Error { Error::new(Code::InvalidParams, Some(data.to_string())) } + /// Create a new method-not-found error + pub fn method_not_found(name: &str) -> Error { + Error::new(Code::MethodNotFound, Some(name.to_string())) + } + /// Create a new parse error pub fn parse_error(error: E) -> Error where diff --git a/tendermint-rs/src/rpc/method.rs b/tendermint-rs/src/rpc/method.rs new file mode 100644 index 0000000..f697a94 --- /dev/null +++ b/tendermint-rs/src/rpc/method.rs @@ -0,0 +1,98 @@ +//! JSONRPC request methods + +use super::Error; +use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer}; +use std::{ + fmt::{self, Display}, + str::FromStr, +}; + +/// JSONRPC request methods. +/// +/// Serialized as the "method" field of JSONRPC/HTTP requests. +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] +pub enum Method { + /// Get ABCI info + AbciInfo, + + /// Get block info + Block, + + /// Get blockchain info + Blockchain, + + /// Get commit info for a block + Commit, + + /// Get genesis file + Genesis, + + /// Get health info + Health, + + /// Get network info + NetInfo, + + /// Get node status + Status, + + /// Get validator info for a block + Validators, +} + +impl Method { + /// Get a static string which represents this method name + pub fn as_str(self) -> &'static str { + match self { + Method::AbciInfo => "abci_info", + Method::Block => "block", + Method::Blockchain => "blockchain", + Method::Commit => "commit", + Method::Genesis => "genesis", + Method::Health => "health", + Method::NetInfo => "net_info", + Method::Status => "status", + Method::Validators => "validators", + } + } +} + +impl FromStr for Method { + type Err = Error; + + fn from_str(s: &str) -> Result { + Ok(match s { + "abci_info" => Method::AbciInfo, + "block" => Method::Block, + "blockchain" => Method::Blockchain, + "commit" => Method::Commit, + "genesis" => Method::Genesis, + "health" => Method::Health, + "net_info" => Method::NetInfo, + "status" => Method::Status, + "validators" => Method::Validators, + other => Err(Error::method_not_found(other))?, + }) + } +} + +impl Display for Method { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.as_str()) + } +} + +#[cfg(feature = "serde")] +impl Serialize for Method { + fn serialize(&self, serializer: S) -> Result { + self.as_str().serialize(serializer) + } +} + +#[cfg(feature = "serde")] +impl<'de> Deserialize<'de> for Method { + fn deserialize>(deserializer: D) -> Result { + Self::from_str(&String::deserialize(deserializer)?) + .map_err(|e| D::Error::custom(format!("{}", e))) + } +} diff --git a/tendermint-rs/src/rpc/request.rs b/tendermint-rs/src/rpc/request.rs index 9a83528..e74b750 100644 --- a/tendermint-rs/src/rpc/request.rs +++ b/tendermint-rs/src/rpc/request.rs @@ -1,36 +1,50 @@ //! JSONRPC requests -use crate::Error; -use serde::{Deserialize, Serialize}; -use std::{ - fmt::{self, Display}, - str::FromStr, -}; +use super::{Id, Method, Version}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use std::fmt::Debug; /// JSONRPC requests -pub trait Request { +pub trait Request: Debug + DeserializeOwned + Serialize + Sized { /// Response type for this command type Response: super::response::Response; - /// Path for this request - fn path(&self) -> Path; -} - -/// JSONRPC request paths -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] -pub struct Path(String); + /// Request method + fn method(&self) -> Method; -impl Display for Path { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.0) + /// Serialize this request as JSON + fn into_json(self) -> String { + serde_json::to_string_pretty(&Wrapper::new(self)).unwrap() } } -impl FromStr for Path { - type Err = Error; +/// JSONRPC request wrapper (i.e. message envelope) +#[derive(Debug, Deserialize, Serialize)] +struct Wrapper { + /// JSONRPC version + jsonrpc: Version, + + /// Identifier included in request + id: Id, + + /// Request method + method: Method, + + /// Request parameters (i.e. request object) + params: R, +} - /// Parse a request path from a string - fn from_str(path: &str) -> Result { - Ok(Path(path.to_owned())) +impl Wrapper +where + R: Request, +{ + /// Create a new request wrapper from the given request + pub fn new(request: R) -> Self { + Self { + jsonrpc: Version::current(), + id: Id::uuid_v4(), + method: request.method(), + params: request, + } } } diff --git a/tendermint-rs/src/rpc/response.rs b/tendermint-rs/src/rpc/response.rs index 2faaf62..ef0ada3 100644 --- a/tendermint-rs/src/rpc/response.rs +++ b/tendermint-rs/src/rpc/response.rs @@ -33,7 +33,10 @@ struct Wrapper { error: Option, } -impl Wrapper { +impl Wrapper +where + R: Response, +{ /// Get JSONRPC version pub fn version(&self) -> &Version { &self.jsonrpc diff --git a/tendermint-rs/src/rpc/version.rs b/tendermint-rs/src/rpc/version.rs index 8cfa260..13471dc 100644 --- a/tendermint-rs/src/rpc/version.rs +++ b/tendermint-rs/src/rpc/version.rs @@ -2,16 +2,25 @@ use super::error::Error; use serde::{Deserialize, Serialize}; -use std::fmt::{self, Display}; +use std::{ + fmt::{self, Display}, + str::FromStr, +}; /// Supported JSONRPC version -pub const SUPPORTED_VERSION: &str = "2.0"; +const SUPPORTED_VERSION: &str = "2.0"; /// JSONRPC version -#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +// TODO(tarcieri): add restrictions/validations on these formats? Use an `enum`? +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, PartialOrd, Ord, Serialize)] pub struct Version(String); impl Version { + /// Get the currently supported JSONRPC version + pub fn current() -> Self { + Version(SUPPORTED_VERSION.to_owned()) + } + /// Is this JSONRPC version supported? pub fn is_supported(&self) -> bool { self.0.eq(SUPPORTED_VERSION) @@ -35,3 +44,11 @@ impl Display for Version { write!(f, "{}", self.0) } } + +impl FromStr for Version { + type Err = Error; + + fn from_str(s: &str) -> Result { + Ok(Version(s.to_owned())) + } +} From 11fe8dc94ff1729098c9b943d97ed84ce5d8f05f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 24 Apr 2019 18:24:35 +0200 Subject: [PATCH 4/4] tendermint-rs: /broadcast_tx_* RPC endpoints Support for all methods of broadcasting transactions presently provided by the Tendermint RPC API. This implementation has been unit tested against the responses documented at https://tendermint.com/rpc/ but does not yet have live integration tests. --- tendermint-rs/src/account.rs | 16 +- tendermint-rs/src/lib.rs | 1 + tendermint-rs/src/node/id.rs | 18 +-- tendermint-rs/src/rpc/client.rs | 28 +++- tendermint-rs/src/rpc/endpoint.rs | 1 + tendermint-rs/src/rpc/endpoint/broadcast.rs | 145 ++++++++++++++++++ .../src/rpc/endpoint/broadcast/tx_async.rs | 45 ++++++ .../src/rpc/endpoint/broadcast/tx_commit.rs | 63 ++++++++ .../src/rpc/endpoint/broadcast/tx_sync.rs | 45 ++++++ tendermint-rs/src/rpc/method.rs | 15 ++ tendermint-rs/src/transaction.rs | 7 +- tendermint-rs/src/transaction/hash.rs | 102 ++++++++++++ tendermint-rs/tests/rpc.rs | 42 ++++- .../tests/support/rpc/broadcast_tx_async.json | 10 ++ .../support/rpc/broadcast_tx_commit.json | 18 +++ .../tests/support/rpc/broadcast_tx_sync.json | 10 ++ 16 files changed, 544 insertions(+), 22 deletions(-) create mode 100644 tendermint-rs/src/rpc/endpoint/broadcast.rs create mode 100644 tendermint-rs/src/rpc/endpoint/broadcast/tx_async.rs create mode 100644 tendermint-rs/src/rpc/endpoint/broadcast/tx_commit.rs create mode 100644 tendermint-rs/src/rpc/endpoint/broadcast/tx_sync.rs create mode 100644 tendermint-rs/src/transaction/hash.rs create mode 100644 tendermint-rs/tests/support/rpc/broadcast_tx_async.json create mode 100644 tendermint-rs/tests/support/rpc/broadcast_tx_commit.json create mode 100644 tendermint-rs/tests/support/rpc/broadcast_tx_sync.json diff --git a/tendermint-rs/src/account.rs b/tendermint-rs/src/account.rs index 5efbd5e..050dd51 100644 --- a/tendermint-rs/src/account.rs +++ b/tendermint-rs/src/account.rs @@ -13,15 +13,15 @@ use subtle::{self, ConstantTimeEq}; use subtle_encoding::hex; /// Size of an account ID in bytes -pub const ID_LENGTH: usize = 20; +const LENGTH: usize = 20; /// Account IDs #[derive(Copy, Clone, Hash)] -pub struct Id([u8; ID_LENGTH]); +pub struct Id([u8; LENGTH]); impl Id { /// Create a new account ID from raw bytes - pub fn new(bytes: [u8; ID_LENGTH]) -> Id { + pub fn new(bytes: [u8; LENGTH]) -> Id { Id(bytes) } @@ -62,8 +62,8 @@ impl Debug for Id { impl From for Id { fn from(pk: secp256k1::PublicKey) -> Id { let digest = Sha256::digest(pk.as_bytes()); - let mut bytes = [0u8; ID_LENGTH]; - bytes.copy_from_slice(&digest[..ID_LENGTH]); + let mut bytes = [0u8; LENGTH]; + bytes.copy_from_slice(&digest[..LENGTH]); Id(bytes) } } @@ -78,11 +78,11 @@ impl FromStr for Id { .or_else(|_| hex::decode(s)) .map_err(|_| Error::Parse)?; - if bytes.len() != ID_LENGTH { + if bytes.len() != LENGTH { return Err(Error::Parse); } - let mut result_bytes = [0u8; ID_LENGTH]; + let mut result_bytes = [0u8; LENGTH]; result_bytes.copy_from_slice(&bytes); Ok(Id(result_bytes)) } @@ -98,7 +98,7 @@ impl<'de> Deserialize<'de> for Id { Self::from_str(&s).map_err(|_| { de::Error::custom(format!( "expected {}-character hex string, got {:?}", - ID_LENGTH * 2, + LENGTH * 2, s )) }) diff --git a/tendermint-rs/src/lib.rs b/tendermint-rs/src/lib.rs index b4bece3..42fdb10 100644 --- a/tendermint-rs/src/lib.rs +++ b/tendermint-rs/src/lib.rs @@ -65,6 +65,7 @@ pub use crate::{ public_key::{PublicKey, TendermintKey}, signature::Signature, time::Time, + transaction::Transaction, version::Version, vote::Vote, }; diff --git a/tendermint-rs/src/node/id.rs b/tendermint-rs/src/node/id.rs index d6e0569..ab91d5e 100644 --- a/tendermint-rs/src/node/id.rs +++ b/tendermint-rs/src/node/id.rs @@ -12,16 +12,16 @@ use std::{ use subtle::{self, ConstantTimeEq}; use subtle_encoding::hex; -/// Size of a Node ID in bytes -pub const ID_LENGTH: usize = 20; +/// Length of a Node ID in bytes +pub const LENGTH: usize = 20; /// Node IDs #[derive(Copy, Clone, Hash)] -pub struct Id([u8; ID_LENGTH]); +pub struct Id([u8; LENGTH]); impl Id { /// Create a new Node ID from raw bytes - pub fn new(bytes: [u8; ID_LENGTH]) -> Id { + pub fn new(bytes: [u8; LENGTH]) -> Id { Id(bytes) } @@ -62,8 +62,8 @@ impl Debug for Id { impl From for Id { fn from(pk: ed25519::PublicKey) -> Id { let digest = Sha256::digest(pk.as_bytes()); - let mut bytes = [0u8; ID_LENGTH]; - bytes.copy_from_slice(&digest[..ID_LENGTH]); + let mut bytes = [0u8; LENGTH]; + bytes.copy_from_slice(&digest[..LENGTH]); Id(bytes) } } @@ -78,11 +78,11 @@ impl FromStr for Id { .or_else(|_| hex::decode(s)) .map_err(|_| Error::Parse)?; - if bytes.len() != ID_LENGTH { + if bytes.len() != LENGTH { return Err(Error::Parse); } - let mut result_bytes = [0u8; ID_LENGTH]; + let mut result_bytes = [0u8; LENGTH]; result_bytes.copy_from_slice(&bytes); Ok(Id(result_bytes)) } @@ -98,7 +98,7 @@ impl<'de> Deserialize<'de> for Id { Self::from_str(&s).map_err(|_| { de::Error::custom(format!( "expected {}-character hex string, got {:?}", - ID_LENGTH * 2, + LENGTH * 2, s )) }) diff --git a/tendermint-rs/src/rpc/client.rs b/tendermint-rs/src/rpc/client.rs index 1347bb7..6bb60f7 100644 --- a/tendermint-rs/src/rpc/client.rs +++ b/tendermint-rs/src/rpc/client.rs @@ -4,7 +4,7 @@ use crate::{ block::Height, net, rpc::{self, endpoint::*, Error, Response}, - Genesis, + Genesis, Transaction, }; use hyper::header; use std::io::Read; @@ -58,6 +58,32 @@ impl Client { self.perform(blockchain::Request::new(min.into(), max.into())) } + /// `/broadcast_tx_async`: broadcast a transaction, returning immediately. + pub fn broadcast_tx_async( + &self, + tx: Transaction, + ) -> Result { + self.perform(broadcast::tx_async::Request::new(tx)) + } + + /// `/broadcast_tx_sync`: broadcast a transaction, returning the response + /// from `CheckTx`. + pub fn broadcast_tx_sync( + &self, + tx: Transaction, + ) -> Result { + self.perform(broadcast::tx_sync::Request::new(tx)) + } + + /// `/broadcast_tx_sync`: broadcast a transaction, returning the response + /// from `CheckTx`. + pub fn broadcast_tx_commit( + &self, + tx: Transaction, + ) -> Result { + self.perform(broadcast::tx_commit::Request::new(tx)) + } + /// `/commit`: get block commit at a given height. pub fn commit(&self, height: H) -> Result where diff --git a/tendermint-rs/src/rpc/endpoint.rs b/tendermint-rs/src/rpc/endpoint.rs index b908470..125413d 100644 --- a/tendermint-rs/src/rpc/endpoint.rs +++ b/tendermint-rs/src/rpc/endpoint.rs @@ -3,6 +3,7 @@ pub mod abci_info; pub mod block; pub mod blockchain; +pub mod broadcast; pub mod commit; pub mod genesis; pub mod health; diff --git a/tendermint-rs/src/rpc/endpoint/broadcast.rs b/tendermint-rs/src/rpc/endpoint/broadcast.rs new file mode 100644 index 0000000..f198e66 --- /dev/null +++ b/tendermint-rs/src/rpc/endpoint/broadcast.rs @@ -0,0 +1,145 @@ +//! `/broadcast_tx_*` endpoint JSONRPC wrappers + +pub mod tx_async; +pub mod tx_commit; +pub mod tx_sync; + +use crate::Error; +use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer}; +use std::{ + fmt::{self, Display}, + str::FromStr, +}; +use subtle_encoding::hex; + +/// Transaction broadcast response codes. +/// +/// These presently use 0 for success and non-zero for errors, however there +/// is ample discussion about potentially supporting non-zero success cases +/// as well. +#[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 for Code { + fn from(value: u32) -> Code { + match value { + 0 => Code::Ok, + err => Code::Err(err), + } + } +} + +impl From for u32 { + fn from(code: Code) -> u32 { + match code { + Code::Ok => 0, + Code::Err(err) => err, + } + } +} + +impl<'de> Deserialize<'de> for Code { + fn deserialize>(deserializer: D) -> Result { + Ok(Code::from( + String::deserialize(deserializer)? + .parse::() + .map_err(|e| D::Error::custom(format!("{}", e)))?, + )) + } +} + +impl Serialize for Code { + fn serialize(&self, serializer: S) -> Result { + self.value().serialize(serializer) + } +} + +/// Transaction data +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Data(Vec); + +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 { + // 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>(deserializer: D) -> Result { + 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(&self, serializer: S) -> Result { + self.to_string().serialize(serializer) + } +} + +/// Transaction log +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct Log(String); + +impl Display for Log { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } +} diff --git a/tendermint-rs/src/rpc/endpoint/broadcast/tx_async.rs b/tendermint-rs/src/rpc/endpoint/broadcast/tx_async.rs new file mode 100644 index 0000000..76853eb --- /dev/null +++ b/tendermint-rs/src/rpc/endpoint/broadcast/tx_async.rs @@ -0,0 +1,45 @@ +//! `/broadcast_tx_async`: broadcast a transaction and return immediately. + +use super::{Code, Data, Log}; +use crate::{rpc, transaction, Transaction}; +use serde::{Deserialize, Serialize}; + +/// `/broadcast_tx_async`: broadcast a transaction and return immediately. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct Request { + /// Transaction to broadcast + pub tx: Transaction, +} + +impl Request { + /// Create a new async transaction broadcast RPC request + pub fn new(tx: Transaction) -> Request { + Request { tx } + } +} + +impl rpc::Request for Request { + type Response = Response; + + fn method(&self) -> rpc::Method { + rpc::Method::BroadcastTxAsync + } +} + +/// Response from either an async or sync transaction broadcast request. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Response { + /// Code + pub code: Code, + + /// Data + pub data: Data, + + /// Log + pub log: Log, + + /// Transaction hash + pub hash: transaction::Hash, +} + +impl rpc::Response for Response {} diff --git a/tendermint-rs/src/rpc/endpoint/broadcast/tx_commit.rs b/tendermint-rs/src/rpc/endpoint/broadcast/tx_commit.rs new file mode 100644 index 0000000..92cd8f5 --- /dev/null +++ b/tendermint-rs/src/rpc/endpoint/broadcast/tx_commit.rs @@ -0,0 +1,63 @@ +//! `/broadcast_tx_commit`: only returns error if `mempool.CheckTx()` errs or +//! if we timeout waiting for tx to commit. + +use super::{Code, Data, Log}; +use crate::{block, rpc, transaction, Transaction}; +use serde::{Deserialize, Serialize}; + +/// `/broadcast_tx_commit`: only returns error if `mempool.CheckTx()` errs or +/// if we timeout waiting for tx to commit. +/// +/// If `CheckTx` or `DeliverTx` fail, no error will be returned, but the +/// returned result will contain a non-OK ABCI code. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct Request { + /// Transaction to broadcast + pub tx: Transaction, +} + +impl Request { + /// Create a new commit transaction broadcast RPC request + pub fn new(tx: Transaction) -> Request { + Request { tx } + } +} + +impl rpc::Request for Request { + type Response = Response; + + fn method(&self) -> rpc::Method { + rpc::Method::BroadcastTxCommit + } +} + +/// Response from `/broadcast_tx_commit`. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Response { + /// `CheckTx` result + pub check_tx: TxResult, + + /// `DeliverTx` result + pub deliver_tx: TxResult, + + /// Transaction + pub hash: transaction::Hash, + + /// Height + pub height: block::Height, +} + +impl rpc::Response for Response {} + +/// Results from either `CheckTx` or `DeliverTx`. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct TxResult { + /// Code + pub code: Code, + + /// Data + pub data: Data, + + /// Log + pub log: Log, +} diff --git a/tendermint-rs/src/rpc/endpoint/broadcast/tx_sync.rs b/tendermint-rs/src/rpc/endpoint/broadcast/tx_sync.rs new file mode 100644 index 0000000..b1c7e8a --- /dev/null +++ b/tendermint-rs/src/rpc/endpoint/broadcast/tx_sync.rs @@ -0,0 +1,45 @@ +//! `/broadcast_tx_sync`: returns with the response from `CheckTx`. + +use super::{Code, Data, Log}; +use crate::{rpc, transaction, Transaction}; +use serde::{Deserialize, Serialize}; + +/// `/broadcast_tx_sync`: returns with the response from `CheckTx`. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct Request { + /// Transaction to broadcast + pub tx: Transaction, +} + +impl Request { + /// Create a new sync transaction broadcast RPC request + pub fn new(tx: Transaction) -> Request { + Request { tx } + } +} + +impl rpc::Request for Request { + type Response = Response; + + fn method(&self) -> rpc::Method { + rpc::Method::BroadcastTxSync + } +} + +/// Response from either an async or sync transaction broadcast request. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Response { + /// Code + pub code: Code, + + /// Data + pub data: Data, + + /// Log + pub log: Log, + + /// Transaction hash + pub hash: transaction::Hash, +} + +impl rpc::Response for Response {} diff --git a/tendermint-rs/src/rpc/method.rs b/tendermint-rs/src/rpc/method.rs index f697a94..b61b324 100644 --- a/tendermint-rs/src/rpc/method.rs +++ b/tendermint-rs/src/rpc/method.rs @@ -21,6 +21,15 @@ pub enum Method { /// Get blockchain info Blockchain, + /// Broadcast transaction asynchronously + BroadcastTxAsync, + + /// Broadcast transaction synchronously + BroadcastTxSync, + + /// Broadcast transaction commit + BroadcastTxCommit, + /// Get commit info for a block Commit, @@ -47,6 +56,9 @@ impl Method { Method::AbciInfo => "abci_info", Method::Block => "block", Method::Blockchain => "blockchain", + Method::BroadcastTxAsync => "broadcast_tx_async", + Method::BroadcastTxSync => "broadcast_tx_sync", + Method::BroadcastTxCommit => "broadcast_tx_commit", Method::Commit => "commit", Method::Genesis => "genesis", Method::Health => "health", @@ -65,6 +77,9 @@ impl FromStr for Method { "abci_info" => Method::AbciInfo, "block" => Method::Block, "blockchain" => Method::Blockchain, + "broadcast_tx_async" => Method::BroadcastTxAsync, + "broadcast_tx_sync" => Method::BroadcastTxSync, + "broadcast_tx_commit" => Method::BroadcastTxCommit, "commit" => Method::Commit, "genesis" => Method::Genesis, "health" => Method::Health, diff --git a/tendermint-rs/src/transaction.rs b/tendermint-rs/src/transaction.rs index c8d7840..c82a7cd 100644 --- a/tendermint-rs/src/transaction.rs +++ b/tendermint-rs/src/transaction.rs @@ -1,5 +1,8 @@ //! Transactions +mod hash; + +pub use self::hash::Hash; use std::slice; #[cfg(feature = "serde")] use { @@ -9,7 +12,7 @@ use { /// Transactions are arbitrary byte arrays whose contents are validated by the /// underlying Tendermint application. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Eq, PartialEq)] pub struct Transaction(Vec); impl Transaction { @@ -44,7 +47,7 @@ impl<'de> Deserialize<'de> for Transaction { let bytes = base64::decode(String::deserialize(deserializer)?.as_bytes()) .map_err(|e| D::Error::custom(format!("{}", e)))?; - Ok(Transaction::new(bytes)) + Ok(Self::new(bytes)) } } diff --git a/tendermint-rs/src/transaction/hash.rs b/tendermint-rs/src/transaction/hash.rs new file mode 100644 index 0000000..237e5ca --- /dev/null +++ b/tendermint-rs/src/transaction/hash.rs @@ -0,0 +1,102 @@ +//! Transaction hashes + +use crate::error::Error; +#[cfg(feature = "serde")] +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; +use std::{ + fmt::{self, Debug, Display}, + str::FromStr, +}; +use subtle::{self, ConstantTimeEq}; +use subtle_encoding::hex; + +/// Size of a transaction hash in bytes +pub const LENGTH: usize = 20; + +/// Trannsaction hashes +#[derive(Copy, Clone, Hash)] +pub struct Hash([u8; LENGTH]); + +impl Hash { + /// Create a new transaction hash from raw bytes + pub fn new(bytes: [u8; LENGTH]) -> Hash { + Hash(bytes) + } + + /// Borrow the transaction hash as a byte slice + pub fn as_bytes(&self) -> &[u8] { + &self.0[..] + } +} + +impl AsRef<[u8]> for Hash { + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } +} + +impl ConstantTimeEq for Hash { + #[inline] + fn ct_eq(&self, other: &Hash) -> subtle::Choice { + self.as_bytes().ct_eq(other.as_bytes()) + } +} + +impl Display for Hash { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + for byte in &self.0 { + write!(f, "{:02X}", byte)?; + } + Ok(()) + } +} + +impl Debug for Hash { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "transactionn::Hash({})", self) + } +} + +/// Decode transaction hash from hex +impl FromStr for Hash { + type Err = Error; + + fn from_str(s: &str) -> Result { + // Accept either upper or lower case hex + let bytes = hex::decode_upper(s) + .or_else(|_| hex::decode(s)) + .map_err(|_| Error::Parse)?; + + if bytes.len() != LENGTH { + return Err(Error::Parse); + } + + let mut result_bytes = [0u8; LENGTH]; + result_bytes.copy_from_slice(&bytes); + Ok(Hash(result_bytes)) + } +} + +#[cfg(feature = "serde")] +impl<'de> Deserialize<'de> for Hash { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + Self::from_str(&s).map_err(|_| { + de::Error::custom(format!( + "expected {}-character hex string, got {:?}", + LENGTH * 2, + s + )) + }) + } +} + +#[cfg(feature = "serde")] +impl Serialize for Hash { + fn serialize(&self, serializer: S) -> Result { + self.to_string().serialize(serializer) + } +} diff --git a/tendermint-rs/tests/rpc.rs b/tendermint-rs/tests/rpc.rs index 32199d3..ff50d31 100644 --- a/tendermint-rs/tests/rpc.rs +++ b/tendermint-rs/tests/rpc.rs @@ -56,11 +56,49 @@ mod endpoints { assert_eq!(block_meta.header.chain_id.as_str(), EXAMPLE_CHAIN) } + #[test] + fn broadcast_tx_async() { + let response = endpoint::broadcast::tx_async::Response::from_json(&read_json_fixture( + "broadcast_tx_async", + )) + .unwrap(); + + assert_eq!( + &response.hash.to_string(), + "E39AAB7A537ABAA237831742DCE1117F187C3C52" + ); + } + + #[test] + fn broadcast_tx_sync() { + let response = endpoint::broadcast::tx_sync::Response::from_json(&read_json_fixture( + "broadcast_tx_sync", + )) + .unwrap(); + + assert_eq!( + &response.hash.to_string(), + "0D33F2F03A5234F38706E43004489E061AC40A2E" + ); + } + + #[test] + fn broadcast_tx_commit() { + let response = endpoint::broadcast::tx_commit::Response::from_json(&read_json_fixture( + "broadcast_tx_commit", + )) + .unwrap(); + + assert_eq!( + &response.hash.to_string(), + "75CA0F856A4DA078FC4911580360E70CEFB2EBEE" + ); + } + #[test] fn commit() { let response = endpoint::commit::Response::from_json(&read_json_fixture("commit")).unwrap(); let header = response.signed_header.header; - assert_eq!(header.chain_id.as_ref(), EXAMPLE_CHAIN); } @@ -108,8 +146,8 @@ mod endpoints { endpoint::validators::Response::from_json(&read_json_fixture("validators")).unwrap(); assert_eq!(response.block_height.value(), 42); - let validators = response.validators; + let validators = response.validators; assert_eq!(validators.len(), 65); } diff --git a/tendermint-rs/tests/support/rpc/broadcast_tx_async.json b/tendermint-rs/tests/support/rpc/broadcast_tx_async.json new file mode 100644 index 0000000..f042aca --- /dev/null +++ b/tendermint-rs/tests/support/rpc/broadcast_tx_async.json @@ -0,0 +1,10 @@ +{ + "jsonrpc": "2.0", + "id": "", + "result": { + "hash": "E39AAB7A537ABAA237831742DCE1117F187C3C52", + "log": "", + "data": "", + "code": "0" + } +} diff --git a/tendermint-rs/tests/support/rpc/broadcast_tx_commit.json b/tendermint-rs/tests/support/rpc/broadcast_tx_commit.json new file mode 100644 index 0000000..581f9e1 --- /dev/null +++ b/tendermint-rs/tests/support/rpc/broadcast_tx_commit.json @@ -0,0 +1,18 @@ +{ + "jsonrpc": "2.0", + "id": "", + "result": { + "height": "26682", + "hash": "75CA0F856A4DA078FC4911580360E70CEFB2EBEE", + "deliver_tx": { + "log": "", + "data": "", + "code": "0" + }, + "check_tx": { + "log": "", + "data": "", + "code": "0" + } + } +} diff --git a/tendermint-rs/tests/support/rpc/broadcast_tx_sync.json b/tendermint-rs/tests/support/rpc/broadcast_tx_sync.json new file mode 100644 index 0000000..d49c99b --- /dev/null +++ b/tendermint-rs/tests/support/rpc/broadcast_tx_sync.json @@ -0,0 +1,10 @@ +{ + "jsonrpc": "2.0", + "id": "", + "result": { + "code": "0", + "data": "", + "log": "", + "hash": "0D33F2F03A5234F38706E43004489E061AC40A2E" + } +}