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/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/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..42fdb10 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 @@ -67,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/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/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 9177472..c509fc3 100644 --- a/tendermint-rs/src/rpc.rs +++ b/tendermint-rs/src/rpc.rs @@ -2,11 +2,16 @@ //! //! Wraps the RPC API described at: +mod client; pub mod endpoint; pub mod error; mod id; +mod method; 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, method::Method, 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..6bb60f7 --- /dev/null +++ b/tendermint-rs/src/rpc/client.rs @@ -0,0 +1,161 @@ +//! Tendermint RPC client + +use crate::{ + block::Height, + net, + rpc::{self, endpoint::*, Error, Response}, + Genesis, Transaction, +}; +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. + pub fn block(&self, height: H) -> Result + where + H: Into, + { + 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). + /// + /// 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())) + } + + /// `/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 + H: Into, + { + 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. + 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 request_body = request.into_json(); + + 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 + .request(hyper::Post, &format!("http://{}:{}/", host, port)) + .headers(headers) + .body(&request_body[..]) + .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.rs b/tendermint-rs/src/rpc/endpoint.rs index dc7b482..125413d 100644 --- a/tendermint-rs/src/rpc/endpoint.rs +++ b/tendermint-rs/src/rpc/endpoint.rs @@ -3,8 +3,10 @@ pub mod abci_info; pub mod block; pub mod blockchain; +pub mod broadcast; 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/abci_info.rs b/tendermint-rs/src/rpc/endpoint/abci_info.rs index ce45626..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 } } @@ -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/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 14d9652..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!("/block?minHeight={}&maxHeight={}", self.min, self.max) - .parse() - .unwrap() + fn method(&self) -> rpc::Method { + rpc::Method::Blockchain } } @@ -44,6 +47,7 @@ pub struct Response { pub last_height: block::Height, /// Block metadata + #[serde(default)] pub block_metas: Vec, } 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/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 new file mode 100644 index 0000000..59aef5a --- /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(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct Request; + +impl rpc::Request for Request { + type Response = Response; + + fn method(&self) -> rpc::Method { + rpc::Method::Health + } +} + +/// Healthcheck responses +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Response {} + +impl rpc::Response for Response {} 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 e21293f..728e82a 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,16 @@ 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 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 @@ -37,12 +46,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 +91,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/method.rs b/tendermint-rs/src/rpc/method.rs new file mode 100644 index 0000000..b61b324 --- /dev/null +++ b/tendermint-rs/src/rpc/method.rs @@ -0,0 +1,113 @@ +//! 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, + + /// Broadcast transaction asynchronously + BroadcastTxAsync, + + /// Broadcast transaction synchronously + BroadcastTxSync, + + /// Broadcast transaction commit + BroadcastTxCommit, + + /// 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::BroadcastTxAsync => "broadcast_tx_async", + Method::BroadcastTxSync => "broadcast_tx_sync", + Method::BroadcastTxCommit => "broadcast_tx_commit", + 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, + "broadcast_tx_async" => Method::BroadcastTxAsync, + "broadcast_tx_sync" => Method::BroadcastTxSync, + "broadcast_tx_commit" => Method::BroadcastTxCommit, + "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 4371c5b..ef0ada3 100644 --- a/tendermint-rs/src/rpc/response.rs +++ b/tendermint-rs/src/rpc/response.rs @@ -6,43 +6,46 @@ 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 { +impl Wrapper +where + R: Response, +{ /// 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 +53,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..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) @@ -22,7 +31,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 + ))) } } } @@ -32,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())) + } +} diff --git a/tendermint-rs/src/transaction.rs b/tendermint-rs/src/transaction.rs index 47bc58a..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)) } } @@ -68,19 +71,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/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/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" + ); + } +} diff --git a/tendermint-rs/tests/rpc.rs b/tendermint-rs/tests/rpc.rs index fcc67aa..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); } @@ -79,6 +117,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 = @@ -103,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" + } +} 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": {} +}