Convert node client to use V2 Node API (#329)

* add beginnings of jsonrpc node client, get_chain_tip implementation

* version info and outputs from node

* return async split up of get_output requests

* add and test get kernel functionality

* height range to pmmr indices

* test fixes

* outputs by pmmr index
This commit is contained in:
Yeastplume 2020-02-14 09:16:43 +00:00 committed by GitHub
parent a92b8d44b3
commit 4bb0398e21
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 671 additions and 230 deletions

178
Cargo.lock generated
View file

@ -615,6 +615,15 @@ dependencies = [
"termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "error-chain"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "failure"
version = "0.1.6"
@ -1054,6 +1063,8 @@ dependencies = [
"hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper-rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-client-core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-client-http 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1181,6 +1192,32 @@ dependencies = [
"quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hyper"
version = "0.11.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (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.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hyper"
version = "0.12.19"
@ -1288,6 +1325,44 @@ dependencies = [
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "jsonrpc-client-core"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "jsonrpc-client-http"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-client-core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "jsonrpc-core"
version = "8.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "jsonrpc-core"
version = "10.1.0"
@ -1314,6 +1389,11 @@ dependencies = [
"winapi-build 0.1.1 (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.4.0"
@ -1407,6 +1487,14 @@ dependencies = [
"scopeguard 1.0.0 (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.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "log"
version = "0.4.8"
@ -1493,6 +1581,11 @@ dependencies = [
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mime"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "miniz_oxide"
version = "0.3.6"
@ -2195,6 +2288,14 @@ name = "regex-syntax"
version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "relay"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "remove_dir_all"
version = "0.5.2"
@ -2448,6 +2549,11 @@ name = "siphasher"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "slab"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "slab"
version = "0.4.2"
@ -2461,6 +2567,11 @@ dependencies = [
"smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "smallvec"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "smallvec"
version = "0.6.13"
@ -2572,6 +2683,11 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "take"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "tempfile"
version = "3.1.0"
@ -2756,6 +2872,23 @@ dependencies = [
"tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-proto"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-reactor"
version = "0.1.11"
@ -2904,6 +3037,11 @@ name = "traitobject"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "try-lock"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "try-lock"
version = "0.2.2"
@ -2922,6 +3060,14 @@ name = "typenum"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicase"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-bidi"
version = "0.3.4"
@ -3020,6 +3166,11 @@ name = "version_check"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "version_check"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "void"
version = "1.0.2"
@ -3035,6 +3186,16 @@ dependencies = [
"winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "want"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "want"
version = "0.0.6"
@ -3243,6 +3404,7 @@ dependencies = [
"checksum encode_unicode 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
"checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180"
"checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38"
"checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9"
"checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9"
"checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
@ -3275,6 +3437,7 @@ dependencies = [
"checksum http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0"
"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
"checksum hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)" = "34a590ca09d341e94cddf8e5af0bbccde205d5fbc2fa3c09dd67c7f85cea59d7"
"checksum hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)" = "f1ebec079129e43af5e234ef36ee3d7e6085687d145b7ea653b262d16c6b65f1"
"checksum hyper-rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68f2aa6b1681795bf4da8063f718cd23145aa0c9a5143d9787b345aa60d38ee4"
"checksum hyper-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ec7c8e526ed674ce148323e1f2010f76f546fcdca99a2c721e04bc7bf5b6f7"
@ -3284,9 +3447,13 @@ dependencies = [
"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
"checksum jobserver 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
"checksum jsonrpc-client-core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f29cb249837420fb0cee7fb0fbf1d22679e121b160e71bb5e0d90b9df241c23e"
"checksum jsonrpc-client-http 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e642eb74423b9dfcb4512fda167148746b76f788a823cd712fadf409f31d302"
"checksum jsonrpc-core 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc15eef5f8b6bef5ac5f7440a957ff95d036e2f98706947741bfc93d1976db4c"
"checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c"
"checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
"checksum libgit2-sys 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4870c781f6063efb83150cd22c1ddf6ecf58531419e7570cdcced46970f64a16"
@ -3298,6 +3465,7 @@ dependencies = [
"checksum lmdb-zero 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "13416eee745b087c22934f35f1f24da22da41ba2a5ce197143d168ce055cc58d"
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
"checksum lock_api 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
"checksum log-mdc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7"
"checksum log4rs 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "100052474df98158c0738a7d3f4249c99978490178b5f9f68cd835ac57adbd1b"
@ -3308,6 +3476,7 @@ dependencies = [
"checksum memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223"
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
"checksum mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
"checksum miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5"
"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f"
"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
@ -3384,6 +3553,7 @@ dependencies = [
"checksum redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
"checksum regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8"
"checksum regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06"
"checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a"
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
"checksum ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a"
"checksum ripemd160 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "482aa56cc68aaeccdaaff1cc5a72c247da8bbad3beb174ca5741f274c22883fb"
@ -3414,8 +3584,10 @@ dependencies = [
"checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0"
"checksum sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf"
"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum smallstr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa65bb4d5b2bbc90d36af64e29802f788aa614783fa1d0df011800ddcec6e8e"
"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013"
"checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
"checksum smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc"
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
@ -3430,6 +3602,7 @@ dependencies = [
"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
"checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
"checksum sysinfo 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6f4b2468c629cffba39c0a4425849ab3cdb03d9dfacba69684609aea04d08ff9"
"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5"
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
"checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42"
"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
@ -3447,6 +3620,7 @@ dependencies = [
"checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af"
"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926"
"checksum tokio-io-timeout 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "135ce81f15cfd7982fac684f9057a1299eebeb79e98a8a709969b9aa51123129"
"checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389"
"checksum tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6732fe6b53c8d11178dcb77ac6d9682af27fc6d4cb87789449152e5377377146"
"checksum tokio-retry 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f05746ae87dca83a2016b4f5dba5b237b897dd12fd324f60afe282112f16969a"
"checksum tokio-rustls 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "208d62fa3e015426e3c64039d9d20adf054a3c9b4d9445560f1c41c75bef3eab"
@ -3460,9 +3634,11 @@ dependencies = [
"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
"checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
"checksum try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee2aa4715743892880f70885373966c83d73ef1b0838a664ef0c76fffd35e7c2"
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
"checksum typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6"
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
"checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
"checksum unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4"
"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
@ -3478,8 +3654,10 @@ dependencies = [
"checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
"checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
"checksum want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a05d9d966753fa4b5c8db73fcab5eed4549cfe0e1e4e66911e5564a0085c35d1"
"checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3"
"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
"checksum webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "17d7967316d8411ca3b01821ee6c332bde138ba4363becdb492f12e514daa17f"

View file

@ -26,6 +26,8 @@ tokio-core = "0.1"
tokio-retry = "0.1"
uuid = { version = "0.7", features = ["serde", "v4"] }
chrono = { version = "0.4.4", features = ["serde"] }
jsonrpc-client-core = "0.5.0"
jsonrpc-client-http = "0.5.0"
#http client (copied from grin)
http = "0.1.5"

View file

@ -79,7 +79,7 @@ impl HttpSlateSender {
if err_string.contains("404") {
// Report that the other version of the wallet is out of date
report = "Other wallet is incompatible and requires an upgrade. \
Please urge the other wallet owner to upgrade and try the transaction again."
Please urge the other wallet owner to upgrade and try the transaction again."
.to_string();
}
error!("{}", report);

View file

@ -120,7 +120,7 @@ impl Client {
/// Helper function to easily issue an async HTTP GET request against a given
/// URL that returns a future. Handles request building, JSON deserialization
/// and response code checking.
pub fn get_async<'a, T>(
pub fn _get_async<'a, T>(
&self,
url: &'a str,
api_secret: Option<String>,
@ -147,7 +147,7 @@ impl Client {
/// object as body on a given URL that returns a JSON object. Handles request
/// building, JSON serialization and deserialization, and response code
/// checking.
pub fn _post<IN, OUT>(
pub fn post<IN, OUT>(
&self,
url: &str,
api_secret: Option<String>,
@ -165,7 +165,7 @@ impl Client {
/// provided JSON object as body on a given URL that returns a future. Handles
/// request building, JSON serialization and deserialization, and response code
/// checking.
pub fn _post_async<IN, OUT>(
pub fn post_async<IN, OUT>(
&self,
url: &str,
input: &IN,
@ -186,7 +186,7 @@ impl Client {
/// object as body on a given URL that returns nothing. Handles request
/// building, JSON serialization, and response code
/// checking.
pub fn post_no_ret<IN>(
pub fn _post_no_ret<IN>(
&self,
url: &str,
api_secret: Option<String>,

View file

@ -0,0 +1,276 @@
// Copyright 2020 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Derived from https://github.com/apoelstra/rust-jsonrpc
//! JSON RPC Client functionality
use std::{error, fmt};
use hyper;
use serde_json;
/// Builds a request
pub fn build_request<'a, 'b>(name: &'a str, params: &'b serde_json::Value) -> Request<'a, 'b> {
Request {
method: name,
params: params,
id: From::from(1),
jsonrpc: Some("2.0"),
}
}
#[derive(Debug, Clone, PartialEq, Serialize)]
/// A JSONRPC request object
pub struct Request<'a, 'b> {
/// The name of the RPC call
pub method: &'a str,
/// Parameters to the RPC call
pub params: &'b serde_json::Value,
/// Identifier for this Request, which should appear in the response
pub id: serde_json::Value,
/// jsonrpc field, MUST be "2.0"
pub jsonrpc: Option<&'a str>,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
/// A JSONRPC response object
pub struct Response {
/// A result if there is one, or null
pub result: Option<serde_json::Value>,
/// An error if there is one, or null
pub error: Option<RpcError>,
/// Identifier for this Request, which should match that of the request
pub id: serde_json::Value,
/// jsonrpc field, MUST be "2.0"
pub jsonrpc: Option<String>,
}
impl Response {
/// Extract the result from a response
pub fn result<T: serde::de::DeserializeOwned>(&self) -> Result<T, Error> {
if let Some(ref e) = self.error {
return Err(Error::Rpc(e.clone()));
}
let result = match self.result.clone() {
Some(r) => serde_json::from_value(r["Ok"].clone()).map_err(Error::Json),
None => serde_json::from_value(serde_json::Value::Null).map_err(Error::Json),
}?;
Ok(result)
}
/// Extract the result from a response, consuming the response
pub fn into_result<T: serde::de::DeserializeOwned>(self) -> Result<T, Error> {
if let Some(e) = self.error {
return Err(Error::Rpc(e));
}
self.result()
}
/// Return the RPC error, if there was one, but do not check the result
pub fn _check_error(self) -> Result<(), Error> {
if let Some(e) = self.error {
Err(Error::Rpc(e))
} else {
Ok(())
}
}
/// Returns whether or not the `result` field is empty
pub fn _is_none(&self) -> bool {
self.result.is_none()
}
}
/// A library error
#[derive(Debug)]
pub enum Error {
/// Json error
Json(serde_json::Error),
/// Client error
Hyper(hyper::error::Error),
/// Error response
Rpc(RpcError),
/// Response to a request did not have the expected nonce
_NonceMismatch,
/// Response to a request had a jsonrpc field other than "2.0"
_VersionMismatch,
/// Batches can't be empty
_EmptyBatch,
/// Too many responses returned in batch
_WrongBatchResponseSize,
/// Batch response contained a duplicate ID
_BatchDuplicateResponseId(serde_json::Value),
/// Batch response contained an ID that didn't correspond to any request ID
_WrongBatchResponseId(serde_json::Value),
}
impl From<serde_json::Error> for Error {
fn from(e: serde_json::Error) -> Error {
Error::Json(e)
}
}
impl From<hyper::error::Error> for Error {
fn from(e: hyper::error::Error) -> Error {
Error::Hyper(e)
}
}
impl From<RpcError> for Error {
fn from(e: RpcError) -> Error {
Error::Rpc(e)
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::Json(ref e) => write!(f, "JSON decode error: {}", e),
Error::Hyper(ref e) => write!(f, "Hyper error: {}", e),
Error::Rpc(ref r) => write!(f, "RPC error response: {:?}", r),
Error::_BatchDuplicateResponseId(ref v) => {
write!(f, "duplicate RPC batch response ID: {}", v)
}
Error::_WrongBatchResponseId(ref v) => write!(f, "wrong RPC batch response ID: {}", v),
_ => f.write_str(std::error::Error::description(self)),
}
}
}
impl std::error::Error for Error {
fn description(&self) -> &str {
match *self {
Error::Json(_) => "JSON decode error",
Error::Hyper(_) => "Hyper error",
Error::Rpc(_) => "RPC error response",
Error::_NonceMismatch => "Nonce of response did not match nonce of request",
Error::_VersionMismatch => "`jsonrpc` field set to non-\"2.0\"",
Error::_EmptyBatch => "batches can't be empty",
Error::_WrongBatchResponseSize => "too many responses returned in batch",
Error::_BatchDuplicateResponseId(_) => "batch response contained a duplicate ID",
Error::_WrongBatchResponseId(_) => {
"batch response contained an ID that didn't correspond to any request ID"
}
}
}
fn cause(&self) -> Option<&dyn error::Error> {
match *self {
Error::Json(ref e) => Some(e),
Error::Hyper(ref e) => Some(e),
_ => None,
}
}
}
/// Standard error responses, as described at at
/// http://www.jsonrpc.org/specification#error_object
///
/// # Documentation Copyright
/// Copyright (C) 2007-2010 by the JSON-RPC Working Group
///
/// This document and translations of it may be used to implement JSON-RPC, it
/// may be copied and furnished to others, and derivative works that comment
/// on or otherwise explain it or assist in its implementation may be prepared,
/// copied, published and distributed, in whole or in part, without restriction
/// of any kind, provided that the above copyright notice and this paragraph
/// are included on all such copies and derivative works. However, this document
/// itself may not be modified in any way.
///
/// The limited permissions granted above are perpetual and will not be revoked.
///
/// This document and the information contained herein is provided "AS IS" and
/// ALL WARRANTIES, EXPRESS OR IMPLIED are DISCLAIMED, INCLUDING BUT NOT LIMITED
/// TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY
/// RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
/// PARTICULAR PURPOSE.
///
#[allow(dead_code)]
#[derive(Debug)]
pub enum StandardError {
/// Invalid JSON was received by the server.
/// An error occurred on the server while parsing the JSON text.
ParseError,
/// The JSON sent is not a valid Request object.
InvalidRequest,
/// The method does not exist / is not available.
MethodNotFound,
/// Invalid method parameter(s).
InvalidParams,
/// Internal JSON-RPC error.
InternalError,
}
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
/// A JSONRPC error object
pub struct RpcError {
/// The integer identifier of the error
pub code: i32,
/// A string describing the error
pub message: String,
/// Additional data specific to the error
pub data: Option<serde_json::Value>,
}
/// Create a standard error responses
pub fn _standard_error(code: StandardError, data: Option<serde_json::Value>) -> RpcError {
match code {
StandardError::ParseError => RpcError {
code: -32700,
message: "Parse error".to_string(),
data: data,
},
StandardError::InvalidRequest => RpcError {
code: -32600,
message: "Invalid Request".to_string(),
data: data,
},
StandardError::MethodNotFound => RpcError {
code: -32601,
message: "Method not found".to_string(),
data: data,
},
StandardError::InvalidParams => RpcError {
code: -32602,
message: "Invalid params".to_string(),
data: data,
},
StandardError::InternalError => RpcError {
code: -32603,
message: "Internal error".to_string(),
data: data,
},
}
}
/// Converts a Rust `Result` to a JSONRPC response object
pub fn _result_to_response(
result: Result<serde_json::Value, RpcError>,
id: serde_json::Value,
) -> Response {
match result {
Ok(data) => Response {
result: Some(data),
error: None,
id: id,
jsonrpc: Some(String::from("2.0")),
},
Err(err) => Response {
result: None,
error: Some(err),
id: id,
jsonrpc: Some(String::from("2.0")),
},
}
}

View file

@ -13,6 +13,7 @@
// limitations under the License.
mod client;
pub mod json_rpc;
mod socksv5;
pub use self::socksv5::Socksv5Connector;

View file

@ -22,6 +22,8 @@ use blake2_rfc as blake2;
extern crate serde_derive;
#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_json;
use grin_wallet_libwallet as libwallet;
use grin_wallet_util::grin_api as api;
use grin_wallet_util::grin_chain as chain;

View file

@ -13,14 +13,11 @@
// limitations under the License.
//! Client functions, implementations of the NodeClient trait
//! specific to the FileWallet
use crate::api::{self, LocatedTxKernel, OutputListing, OutputPrintable};
use crate::core::core::{Transaction, TxKernel};
use crate::libwallet::{NodeClient, NodeVersionInfo};
use futures::{stream, Stream};
use crate::api::{self, LocatedTxKernel};
use crate::core::core::TxKernel;
use crate::libwallet::{NodeClient, NodeVersionInfo, TxWrapper};
use semver::Version;
use std::collections::HashMap;
use std::env;
use tokio::runtime::Runtime;
@ -30,6 +27,11 @@ use crate::libwallet;
use crate::util::secp::pedersen;
use crate::util::{self, to_hex};
use super::resp_types::*;
use crate::client_utils::json_rpc::*;
const ENDPOINT: &str = "/v2/foreign";
#[derive(Clone)]
pub struct HTTPNodeClient {
node_url: String,
@ -51,6 +53,34 @@ impl HTTPNodeClient {
pub fn chain_height(&self) -> Result<(u64, String), libwallet::Error> {
self.get_chain_tip()
}
fn send_json_request<D: serde::de::DeserializeOwned>(
&self,
method: &str,
params: &serde_json::Value,
) -> Result<D, libwallet::Error> {
let url = format!("{}{}", self.node_url(), ENDPOINT);
let client = Client::new();
let req = build_request(method, params);
let res = client.post::<Request, Response>(url.as_str(), self.node_api_secret(), &req);
match res {
Err(e) => {
let report = format!("Error calling {}: {}", method, e);
error!("{}", report);
Err(libwallet::ErrorKind::ClientCallback(report).into())
}
Ok(inner) => match inner.clone().into_result() {
Ok(r) => Ok(r),
Err(e) => {
error!("{:?}", inner);
let report = format!("Unable to parse response for {}: {}", method, e);
error!("{}", report);
Err(libwallet::ErrorKind::ClientCallback(report).into())
}
},
}
}
}
impl NodeClient for HTTPNodeClient {
@ -73,10 +103,14 @@ impl NodeClient for HTTPNodeClient {
if let Some(v) = self.node_version_info.as_ref() {
return Some(v.clone());
}
let url = format!("{}/v1/version", self.node_url());
let client = Client::new();
let mut retval = match client.get::<NodeVersionInfo>(url.as_str(), self.node_api_secret()) {
Ok(n) => n,
let retval = match self
.send_json_request::<GetVersionResp>("get_version", &serde_json::Value::Null)
{
Ok(n) => NodeVersionInfo {
node_version: n.node_version,
block_header_version: n.block_header_version,
verified: Some(true),
},
Err(e) => {
// If node isn't available, allow offline functions
// unfortunately have to parse string due to error structure
@ -93,44 +127,21 @@ impl NodeClient for HTTPNodeClient {
}
}
};
retval.verified = Some(true);
self.node_version_info = Some(retval.clone());
Some(retval)
}
/// Posts a transaction to a grin node
fn post_tx(&self, tx: &TxWrapper, fluff: bool) -> Result<(), libwallet::Error> {
let url;
let dest = self.node_url();
if fluff {
url = format!("{}/v1/pool/push_tx?fluff", dest);
} else {
url = format!("{}/v1/pool/push_tx", dest);
}
let client = Client::new();
let res = client.post_no_ret(url.as_str(), self.node_api_secret(), tx);
if let Err(e) = res {
let report = format!("Posting transaction to node: {}", e);
error!("Post TX Error: {}", e);
return Err(libwallet::ErrorKind::ClientCallback(report).into());
}
fn post_tx(&self, tx: &Transaction, fluff: bool) -> Result<(), libwallet::Error> {
let params = json!([tx, fluff]);
self.send_json_request::<serde_json::Value>("push_transaction", &params)?;
Ok(())
}
/// Return the chain tip from a given node
fn get_chain_tip(&self) -> Result<(u64, String), libwallet::Error> {
let addr = self.node_url();
let url = format!("{}/v1/chain", addr);
let client = Client::new();
let res = client.get::<api::Tip>(url.as_str(), self.node_api_secret());
match res {
Err(e) => {
let report = format!("Getting chain height from node: {}", e);
error!("Get chain height error: {}", e);
Err(libwallet::ErrorKind::ClientCallback(report).into())
}
Ok(r) => Ok((r.height, r.last_block_pushed)),
}
let result = self.send_json_request::<GetTipResp>("get_tip", &serde_json::Value::Null)?;
Ok((result.height, result.last_block_pushed))
}
/// Get kernel implementation
@ -140,44 +151,34 @@ impl NodeClient for HTTPNodeClient {
min_height: Option<u64>,
max_height: Option<u64>,
) -> Result<Option<(TxKernel, u64, u64)>, libwallet::Error> {
let version = self
.get_version_info()
.ok_or_else(|| libwallet::ErrorKind::ClientCallback("Unable to get version".into()))?;
let version = Version::parse(&version.node_version)
.map_err(|_| libwallet::ErrorKind::ClientCallback("Unable to parse version".into()))?;
if version <= Version::new(2, 0, 0) {
return Err(libwallet::ErrorKind::ClientCallback(
"Kernel lookup not supported by node, please upgrade it".into(),
)
.into());
}
let mut query = String::new();
if let Some(h) = min_height {
query += &format!("min_height={}", h);
}
if let Some(h) = max_height {
if !query.is_empty() {
query += "&";
}
query += &format!("max_height={}", h);
}
if !query.is_empty() {
query.insert_str(0, "?");
}
let url = format!(
"{}/v1/chain/kernels/{}{}",
self.node_url(),
to_hex(excess.0.to_vec()),
query
);
let method = "get_kernel";
let params = json!([to_hex(excess.0.to_vec()), min_height, max_height]);
// have to handle this manually since the error needs to be parsed
let url = format!("{}{}", self.node_url(), ENDPOINT);
let client = Client::new();
let res: Option<LocatedTxKernel> = client
.get(url.as_str(), self.node_api_secret())
.map_err(|e| libwallet::ErrorKind::ClientCallback(format!("Kernel lookup: {}", e)))?;
let req = build_request(method, &params);
let res = client.post::<Request, Response>(url.as_str(), self.node_api_secret(), &req);
Ok(res.map(|k| (k.tx_kernel, k.height, k.mmr_index)))
match res {
Err(e) => {
let report = format!("Error calling {}: {}", method, e);
error!("{}", report);
Err(libwallet::ErrorKind::ClientCallback(report).into())
}
Ok(inner) => match inner.clone().into_result::<LocatedTxKernel>() {
Ok(r) => Ok(Some((r.tx_kernel, r.height, r.mmr_index))),
Err(e) => {
let contents = format!("{:?}", inner);
if contents.contains("NotFound") {
Ok(None)
} else {
let report = format!("Unable to parse response for {}: {}", method, e);
error!("{}", report);
Err(libwallet::ErrorKind::ClientCallback(report).into())
}
}
},
}
}
/// Retrieve outputs from node
@ -185,24 +186,25 @@ impl NodeClient for HTTPNodeClient {
&self,
wallet_outputs: Vec<pedersen::Commitment>,
) -> Result<HashMap<pedersen::Commitment, (String, u64, u64)>, libwallet::Error> {
let addr = self.node_url();
// build the necessary query params -
// ?id=xxx&id=yyy&id=zzz
let query_params: Vec<String> = wallet_outputs
.iter()
.map(|commit| format!("id={}", util::to_hex(commit.as_ref().to_vec())))
.collect();
// build a map of api outputs by commit so we can look them up efficiently
let mut api_outputs: HashMap<pedersen::Commitment, (String, u64, u64)> = HashMap::new();
if wallet_outputs.is_empty() {
return Ok(api_outputs);
}
// build vec of commits for inclusion in query
let query_params: Vec<String> = wallet_outputs
.iter()
.map(|commit| format!("{}", util::to_hex(commit.as_ref().to_vec())))
.collect();
let mut tasks = Vec::new();
let client = Client::new();
// Using an environment variable here, as this is a temporary fix
// and doesn't need to be permeated throughout the application
// configuration
let chunk_default = 200;
// going to leave this here even though we're moving
// to the json RPC api to keep the functionality of
// parallelizing larger requests. Will raise default
// from 200 to 500, however
let chunk_default = 500;
let chunk_size = match env::var("GRIN_OUTPUT_QUERY_SIZE") {
Ok(s) => match s.parse::<usize>() {
Ok(c) => c,
@ -220,16 +222,37 @@ impl NodeClient for HTTPNodeClient {
trace!("Output query chunk size is: {}", chunk_size);
let url = format!("{}{}", self.node_url(), ENDPOINT);
let client = Client::new();
/*let res = client.post::<Request, Response>(url.as_str(), self.node_api_secret(), &req);*/
for query_chunk in query_params.chunks(chunk_size) {
let url = format!("{}/v1/chain/outputs/byids?{}", addr, query_chunk.join("&"),);
tasks.push(client.get_async::<Vec<api::Output>>(url.as_str(), self.node_api_secret()));
let params = json!([query_chunk, null, null, false, false]);
let req = build_request("get_outputs", &params);
tasks.push(client.post_async::<Request, Response>(
url.as_str(),
&req,
self.node_api_secret(),
));
}
let task = stream::futures_unordered(tasks).collect();
let mut rt = Runtime::new().unwrap();
let results = match rt.block_on(task) {
Ok(outputs) => outputs,
let results: Vec<OutputPrintable> = match rt.block_on(task) {
Ok(resps) => {
let mut results = vec![];
for r in resps {
match r.into_result::<Vec<OutputPrintable>>() {
Ok(mut r) => results.append(&mut r),
Err(e) => {
let report = format!("Unable to parse response for get_outputs: {}", e);
error!("{}", report);
return Err(libwallet::ErrorKind::ClientCallback(report).into());
}
};
}
results
}
Err(e) => {
let report = format!("Getting outputs by id: {}", e);
error!("Outputs by id failed: {}", e);
@ -237,13 +260,18 @@ impl NodeClient for HTTPNodeClient {
}
};
for res in results {
for out in res {
api_outputs.insert(
out.commit.commit(),
(util::to_hex(out.commit.to_vec()), out.height, out.mmr_index),
);
}
for out in results.iter() {
let height = match out.block_height {
Some(h) => h,
None => {
let msg = format!("Missing block height for output {:?}", out.commit);
return Err(libwallet::ErrorKind::ClientCallback(msg).into());
}
};
api_outputs.insert(
out.commit,
(util::to_hex(out.commit.0.to_vec()), height, out.mmr_index),
);
}
Ok(api_outputs)
}
@ -261,68 +289,47 @@ impl NodeClient for HTTPNodeClient {
),
libwallet::Error,
> {
let addr = self.node_url();
let mut query_param = format!("start_index={}&max={}", start_index, max_outputs);
if let Some(e) = end_index {
query_param = format!("{}&end_index={}", query_param, e);
};
let url = format!("{}/v1/txhashset/outputs?{}", addr, query_param,);
let mut api_outputs: Vec<(pedersen::Commitment, pedersen::RangeProof, bool, u64, u64)> =
Vec::new();
let client = Client::new();
match client.get::<api::OutputListing>(url.as_str(), self.node_api_secret()) {
Ok(o) => {
for out in o.outputs {
let is_coinbase = match out.output_type {
api::OutputType::Coinbase => true,
api::OutputType::Transaction => false,
};
let range_proof = match out.range_proof() {
Ok(r) => r,
Err(e) => {
let msg = format!("Unexpected error in returned output (missing range proof): {:?}. {:?}, {}",
out.commit,
out,
e);
error!("{}", msg);
return Err(libwallet::ErrorKind::ClientCallback(msg).into());
}
};
let block_height = match out.block_height {
Some(h) => h,
None => {
let msg = format!("Unexpected error in returned output (missing block height): {:?}. {:?}",
out.commit,
out);
error!("{}", msg);
return Err(libwallet::ErrorKind::ClientCallback(msg).into());
}
};
api_outputs.push((
out.commit,
range_proof,
is_coinbase,
block_height,
out.mmr_index,
));
let params = json!([start_index, end_index, max_outputs, Some(true)]);
let res = self.send_json_request::<OutputListing>("get_unspent_outputs", &params)?;
for out in res.outputs {
let is_coinbase = match out.output_type {
api::OutputType::Coinbase => true,
api::OutputType::Transaction => false,
};
let range_proof = match out.range_proof() {
Ok(r) => r,
Err(e) => {
let msg = format!(
"Unexpected error in returned output (missing range proof): {:?}. {:?}, {}",
out.commit, out, e
);
error!("{}", msg);
return Err(libwallet::ErrorKind::ClientCallback(msg).into());
}
Ok((o.highest_index, o.last_retrieved_index, api_outputs))
}
Err(e) => {
// if we got anything other than 200 back from server, bye
error!(
"get_outputs_by_pmmr_index: error contacting {}. Error: {}",
addr, e
);
let report = format!("outputs by pmmr index: {}", e);
Err(libwallet::ErrorKind::ClientCallback(report).into())
}
};
let block_height = match out.block_height {
Some(h) => h,
None => {
let msg = format!(
"Unexpected error in returned output (missing block height): {:?}. {:?}",
out.commit, out
);
error!("{}", msg);
return Err(libwallet::ErrorKind::ClientCallback(msg).into());
}
};
api_outputs.push((
out.commit,
range_proof,
is_coinbase,
block_height,
out.mmr_index,
));
}
Ok((res.highest_index, res.last_retrieved_index, api_outputs))
}
fn height_range_to_pmmr_indices(
@ -330,52 +337,9 @@ impl NodeClient for HTTPNodeClient {
start_height: u64,
end_height: Option<u64>,
) -> Result<(u64, u64), libwallet::Error> {
debug!("Indices start");
let addr = self.node_url();
let mut query_param = format!("start_height={}", start_height);
if let Some(e) = end_height {
query_param = format!("{}&end_height={}", query_param, e);
};
let params = json!([start_height, end_height]);
let res = self.send_json_request::<OutputListing>("get_pmmr_indices", &params)?;
let url = format!("{}/v1/txhashset/heightstopmmr?{}", addr, query_param,);
let client = Client::new();
match client.get::<api::OutputListing>(url.as_str(), self.node_api_secret()) {
Ok(o) => Ok((o.last_retrieved_index, o.highest_index)),
Err(e) => {
// if we got anything other than 200 back from server, bye
error!("heightstopmmr: error contacting {}. Error: {}", addr, e);
let report = format!(": {}", e);
Err(libwallet::ErrorKind::ClientCallback(report).into())
}
}
Ok((res.last_retrieved_index, res.highest_index))
}
}
/*
/// Call the wallet API to create a coinbase output for the given block_fees.
/// Will retry based on default "retry forever with backoff" behavior.
pub fn create_coinbase(dest: &str, block_fees: &BlockFees) -> Result<CbData, Error> {
let url = format!("{}/v1/wallet/foreign/build_coinbase", dest);
match single_create_coinbase(&url, &block_fees) {
Err(e) => {
error!(
"Failed to get coinbase from {}. Run grin-wallet listen?",
url
);
error!("Underlying Error: {}", e.cause().unwrap());
error!("Backtrace: {}", e.backtrace().unwrap());
Err(e)?
}
Ok(res) => Ok(res),
}
}
/// Makes a single request to the wallet API to create a new coinbase output.
fn single_create_coinbase(url: &str, block_fees: &BlockFees) -> Result<CbData, Error> {
let res = Client::post(url, None, block_fees).context(ErrorKind::GenericError(
"Posting create coinbase".to_string(),
))?;
Ok(res)
}*/

View file

@ -13,5 +13,6 @@
// limitations under the License.
mod http;
mod resp_types;
pub use self::http::HTTPNodeClient;

View file

@ -0,0 +1,30 @@
// Copyright 2020 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Derived from https://github.com/apoelstra/rust-jsonrpc
//! JSON RPC Types for V2 node client
#[derive(Debug, Deserialize)]
pub struct GetTipResp {
pub height: u64,
pub last_block_pushed: String,
pub prev_block_to_last: String,
pub total_difficulty: u64,
}
#[derive(Debug, Deserialize)]
pub struct GetVersionResp {
pub node_version: String,
pub block_header_version: u16,
}

View file

@ -22,14 +22,12 @@ use crate::chain::Chain;
use crate::core::core::verifier_cache::LruVerifierCache;
use crate::core::core::{Transaction, TxKernel};
use crate::core::global::{set_mining_mode, ChainTypes};
use crate::core::{pow, ser};
use crate::core::pow;
use crate::keychain::Keychain;
use crate::libwallet;
use crate::libwallet::api_impl::foreign;
use crate::libwallet::slate_versions::v3::SlateV3;
use crate::libwallet::{
NodeClient, NodeVersionInfo, Slate, TxWrapper, WalletInst, WalletLCProvider,
};
use crate::libwallet::{NodeClient, NodeVersionInfo, Slate, WalletInst, WalletLCProvider};
use crate::util;
use crate::util::secp::key::SecretKey;
use crate::util::secp::pedersen;
@ -177,16 +175,8 @@ where
fn post_tx(&mut self, m: WalletProxyMessage) -> Result<WalletProxyMessage, libwallet::Error> {
let dest_wallet = self.wallets.get_mut(&m.sender_id).unwrap().1.clone();
let dest_wallet_mask = self.wallets.get_mut(&m.sender_id).unwrap().2.clone();
let wrapper: TxWrapper = serde_json::from_str(&m.body).context(
libwallet::ErrorKind::ClientCallback("Error parsing TxWrapper".to_owned()),
)?;
let tx_bin = util::from_hex(wrapper.tx_hex).context(
libwallet::ErrorKind::ClientCallback("Error parsing TxWrapper: tx_bin".to_owned()),
)?;
let tx: Transaction = ser::deserialize(&mut &tx_bin[..], ser::ProtocolVersion(1)).context(
libwallet::ErrorKind::ClientCallback("Error parsing TxWrapper: tx".to_owned()),
let tx: Transaction = serde_json::from_str(&m.body).context(
libwallet::ErrorKind::ClientCallback("Error parsing Transaction".to_owned()),
)?;
super::award_block_to_wallet(
@ -441,7 +431,7 @@ impl NodeClient for LocalWalletClient {
}
/// Posts a transaction to a grin node
/// In this case it will create a new block with award rewarded to
fn post_tx(&self, tx: &TxWrapper, _fluff: bool) -> Result<(), libwallet::Error> {
fn post_tx(&self, tx: &Transaction, _fluff: bool) -> Result<(), libwallet::Error> {
let m = WalletProxyMessage {
sender_id: self.id.clone(),
dest: self.node_url().to_owned(),

View file

@ -18,8 +18,6 @@ use uuid::Uuid;
use crate::grin_core::core::hash::Hashed;
use crate::grin_core::core::Transaction;
use crate::grin_core::ser;
use crate::grin_util;
use crate::grin_util::secp::key::SecretKey;
use crate::grin_util::Mutex;
use crate::util::OnionV3Address;
@ -28,7 +26,7 @@ use crate::api_impl::owner_updater::StatusMessage;
use crate::grin_keychain::{Identifier, Keychain};
use crate::internal::{keys, scan, selection, tx, updater};
use crate::slate::{PaymentInfo, Slate};
use crate::types::{AcctPathMapping, NodeClient, TxLogEntry, TxWrapper, WalletBackend, WalletInfo};
use crate::types::{AcctPathMapping, NodeClient, TxLogEntry, WalletBackend, WalletInfo};
use crate::{
address, wallet_lock, InitTxArgs, IssueInvoiceTxArgs, NodeHeightResult, OutputCommitMapping,
PaymentProof, ScannedBlockInfo, TxLogEntryType, WalletInitStatus, WalletInst, WalletLCProvider,
@ -632,8 +630,7 @@ pub fn post_tx<'a, C>(client: &C, tx: &Transaction, fluff: bool) -> Result<(), E
where
C: NodeClient + 'a,
{
let tx_hex = grin_util::to_hex(ser::ser_vec(tx, ser::ProtocolVersion(1)).unwrap());
let res = client.post_tx(&TxWrapper { tx_hex: tx_hex }, fluff);
let res = client.post_tx(tx, fluff);
if let Err(e) = res {
error!("api: post_tx: failed with error: {}", e);
Err(e)

View file

@ -329,7 +329,7 @@ pub trait NodeClient: Send + Sync + Clone {
fn set_node_api_secret(&mut self, node_api_secret: Option<String>);
/// Posts a transaction to a grin node
fn post_tx(&self, tx: &TxWrapper, fluff: bool) -> Result<(), Error>;
fn post_tx(&self, tx: &Transaction, fluff: bool) -> Result<(), Error>;
/// Returns the api version string and block header version as reported
/// by the node. Result can be cached for later use