diff --git a/Cargo.lock b/Cargo.lock index 15eb5e2f7..d7b17eac4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,10 +7,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "aho-corasick" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -56,7 +56,7 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -64,37 +64,36 @@ dependencies = [ [[package]] name = "atty" -version = "0.2.11" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "autocfg" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "backtrace" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace-sys 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "backtrace-sys" -version = "0.1.29" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -103,7 +102,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "safemem 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -117,11 +116,11 @@ dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "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)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "which 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -145,7 +144,7 @@ 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)", + "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -158,18 +157,13 @@ dependencies = [ "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "build_const" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "built" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "git2 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -193,9 +187,18 @@ dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "c2-chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cc" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -216,10 +219,10 @@ name = "chrono" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -229,8 +232,8 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "libloading 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -239,7 +242,7 @@ version = "2.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -261,14 +264,6 @@ name = "constant_time_eq" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "crc" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "crc32fast" version = "1.2.0" @@ -283,7 +278,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "croaring-sys 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -292,8 +287,8 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bindgen 0.37.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -301,21 +296,21 @@ name = "crossbeam-deque" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-epoch" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (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)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -323,12 +318,12 @@ name = "crossbeam-queue" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-utils" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -389,7 +384,7 @@ name = "dirs" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (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)", ] @@ -407,8 +402,8 @@ dependencies = [ "easy-jsonrpc-proc-macro 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -418,8 +413,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (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.38 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -440,10 +435,10 @@ name = "env_logger" version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -452,7 +447,7 @@ name = "failure" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -462,8 +457,8 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (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.38 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -478,9 +473,9 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide_c_api 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz_oxide_c_api 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -534,16 +529,25 @@ dependencies = [ "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "getrandom" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "git2" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "libgit2-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -554,7 +558,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "grin_api" version = "2.0.1-beta.1" -source = "git+https://github.com/mimblewimble/grin#e6bdc5987cab272cb47a54a992947bc9cf88d6a5" +source = "git+https://github.com/mimblewimble/grin#705fcbb1a62a1cfddb1e8b4fc9c30bab4a388818" 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)", @@ -565,17 +569,17 @@ dependencies = [ "grin_pool 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", "grin_store 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", "grin_util 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", - "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", - "regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-rustls 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -586,7 +590,7 @@ dependencies = [ [[package]] name = "grin_chain" version = "2.0.1-beta.1" -source = "git+https://github.com/mimblewimble/grin#e6bdc5987cab272cb47a54a992947bc9cf88d6a5" +source = "git+https://github.com/mimblewimble/grin#705fcbb1a62a1cfddb1e8b4fc9c30bab4a388818" dependencies = [ "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -599,17 +603,17 @@ dependencies = [ "grin_store 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", "grin_util 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", "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)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "grin_core" version = "2.0.1-beta.1" -source = "git+https://github.com/mimblewimble/grin#e6bdc5987cab272cb47a54a992947bc9cf88d6a5" +source = "git+https://github.com/mimblewimble/grin#705fcbb1a62a1cfddb1e8b4fc9c30bab4a388818" dependencies = [ "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -621,22 +625,22 @@ dependencies = [ "grin_keychain 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", "grin_util 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", "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)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", "siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "grin_keychain" version = "2.0.1-beta.1" -source = "git+https://github.com/mimblewimble/grin#e6bdc5987cab272cb47a54a992947bc9cf88d6a5" +source = "git+https://github.com/mimblewimble/grin#705fcbb1a62a1cfddb1e8b4fc9c30bab4a388818" dependencies = [ "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -644,22 +648,22 @@ dependencies = [ "grin_util 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", "hmac 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "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)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "pbkdf2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "ripemd160 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "grin_p2p" version = "2.0.1-beta.1" -source = "git+https://github.com/mimblewimble/grin#e6bdc5987cab272cb47a54a992947bc9cf88d6a5" +source = "git+https://github.com/mimblewimble/grin#705fcbb1a62a1cfddb1e8b4fc9c30bab4a388818" dependencies = [ "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -669,19 +673,19 @@ dependencies = [ "grin_core 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", "grin_store 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", "grin_util 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "grin_pool" version = "2.0.1-beta.1" -source = "git+https://github.com/mimblewimble/grin#e6bdc5987cab272cb47a54a992947bc9cf88d6a5" +source = "git+https://github.com/mimblewimble/grin#705fcbb1a62a1cfddb1e8b4fc9c30bab4a388818" dependencies = [ "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -691,10 +695,10 @@ dependencies = [ "grin_keychain 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", "grin_store 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", "grin_util 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -703,19 +707,19 @@ version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "grin_store" version = "2.0.1-beta.1" -source = "git+https://github.com/mimblewimble/grin#e6bdc5987cab272cb47a54a992947bc9cf88d6a5" +source = "git+https://github.com/mimblewimble/grin#705fcbb1a62a1cfddb1e8b4fc9c30bab4a388818" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "croaring 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -724,34 +728,34 @@ dependencies = [ "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "grin_core 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", "grin_util 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "lmdb-zero 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "grin_util" version = "2.0.1-beta.1" -source = "git+https://github.com/mimblewimble/grin#e6bdc5987cab272cb47a54a992947bc9cf88d6a5" +source = "git+https://github.com/mimblewimble/grin#705fcbb1a62a1cfddb1e8b4fc9c30bab4a388818" dependencies = [ - "backtrace 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "grin_secp256k1zkp 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "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)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "log4rs 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "zip 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "zip 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -770,7 +774,7 @@ dependencies = [ "grin_wallet_libwallet 2.1.0-beta.1", "grin_wallet_util 2.1.0-beta.1", "linefeed 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "prettytable-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -788,9 +792,11 @@ dependencies = [ "grin_wallet_impls 2.1.0-beta.1", "grin_wallet_libwallet 2.1.0-beta.1", "grin_wallet_util 2.1.0-beta.1", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.0.8 (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.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -802,8 +808,8 @@ dependencies = [ "grin_wallet_util 2.1.0-beta.1", "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -823,13 +829,13 @@ dependencies = [ "grin_wallet_util 2.1.0-beta.1", "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", "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)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "prettytable-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -850,12 +856,12 @@ dependencies = [ "grin_wallet_config 2.1.0-beta.1", "grin_wallet_libwallet 2.1.0-beta.1", "grin_wallet_util 2.1.0-beta.1", - "log 0.4.6 (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)", "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-retry 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -874,11 +880,11 @@ dependencies = [ "grin_wallet_config 2.1.0-beta.1", "grin_wallet_util 2.1.0-beta.1", "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)", + "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)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -897,25 +903,25 @@ dependencies = [ "grin_util 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)", "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "h2" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "string 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -938,7 +944,7 @@ dependencies = [ [[package]] name = "http" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -948,7 +954,7 @@ dependencies = [ [[package]] name = "httparse" -version = "1.3.3" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -967,20 +973,20 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "h2 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.18 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -992,7 +998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ct-logs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1013,6 +1019,16 @@ dependencies = [ "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "idna" +version = "0.2.0" +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 = "indexmap" version = "1.0.2" @@ -1023,7 +1039,7 @@ name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1038,10 +1054,10 @@ version = "10.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (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.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1060,18 +1076,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.58" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libgit2-sys" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1080,15 +1096,15 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libloading" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1097,10 +1113,10 @@ name = "libz-sys" version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1124,7 +1140,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "liblmdb-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "supercow 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1140,11 +1156,11 @@ dependencies = [ [[package]] name = "log" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1163,13 +1179,13 @@ dependencies = [ "flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "log-mdc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", "serde-value 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)", "thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1194,12 +1210,12 @@ name = "memchr" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "memchr" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1207,27 +1223,30 @@ name = "memmap" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "memoffset" -version = "0.2.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "miniz-sys" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "miniz_oxide" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1235,13 +1254,13 @@ dependencies = [ [[package]] name = "miniz_oxide_c_api" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz_oxide 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1253,8 +1272,8 @@ dependencies = [ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1267,7 +1286,7 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1288,7 +1307,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallstr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "terminfo 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1297,22 +1316,13 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "msdos_time" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "net2" version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1323,7 +1333,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1335,9 +1345,9 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1359,7 +1369,7 @@ name = "nom" version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1423,7 +1433,7 @@ name = "num-complex" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1432,7 +1442,7 @@ name = "num-integer" version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1441,7 +1451,7 @@ name = "num-iter" version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1462,7 +1472,7 @@ name = "num-rational" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1481,7 +1491,7 @@ name = "num-traits" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1489,14 +1499,9 @@ name = "num_cpus" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "numtoa" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "odds" version = "0.2.26" @@ -1541,7 +1546,7 @@ name = "parking_lot_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.6 (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.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1553,7 +1558,7 @@ name = "parking_lot_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (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.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1585,6 +1590,11 @@ name = "percent-encoding" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "percent-encoding" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "phf" version = "0.7.24" @@ -1621,7 +1631,7 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1629,6 +1639,11 @@ name = "podio" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ppv-lite86" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "pretty_assertions" version = "0.5.1" @@ -1643,7 +1658,7 @@ name = "prettytable-rs" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "csv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1682,7 +1697,7 @@ dependencies = [ [[package]] name = "quote" -version = "0.6.12" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1693,7 +1708,7 @@ name = "rand" version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1703,7 +1718,7 @@ 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.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (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.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1716,7 +1731,7 @@ 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.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1726,8 +1741,8 @@ name = "rand" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (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)", @@ -1739,15 +1754,36 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_chacha" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.5 (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 = "rand_chacha" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_core" version = "0.3.1" @@ -1761,6 +1797,14 @@ name = "rand_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rand_core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_hc" version = "0.1.0" @@ -1769,6 +1813,14 @@ dependencies = [ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_isaac" version = "0.1.1" @@ -1782,7 +1834,7 @@ name = "rand_jitter" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (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.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1794,7 +1846,7 @@ 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.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (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.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1805,7 +1857,7 @@ name = "rand_pcg" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1827,17 +1879,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.54" +version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "redox_termios" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "redox_users" version = "0.3.0" @@ -1846,27 +1890,27 @@ dependencies = [ "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)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "1.1.7" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.6.7" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1882,9 +1926,9 @@ name = "ring" version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (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.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1904,7 +1948,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1940,7 +1984,7 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "sct 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1949,17 +1993,17 @@ dependencies = [ [[package]] name = "ryu" -version = "0.2.8" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "safemem" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "same-file" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1980,6 +2024,11 @@ name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "scopeguard" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "sct" version = "0.4.0" @@ -2009,10 +2058,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.93" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2021,27 +2070,27 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.93" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (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.38 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.39" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2051,7 +2100,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2096,7 +2145,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "string" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2119,8 +2168,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (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.38 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2130,11 +2179,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "syn" -version = "0.15.38" +version = "0.15.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2144,20 +2193,20 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (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.38 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.42 (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 = "tempfile" -version = "3.0.8" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (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.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2191,17 +2240,6 @@ dependencies = [ "phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "termion" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "textwrap" version = "0.11.0" @@ -2215,8 +2253,8 @@ name = "thread-id" version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2233,8 +2271,8 @@ name = "time" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2248,12 +2286,12 @@ dependencies = [ "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2277,11 +2315,11 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2293,15 +2331,15 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-executor" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2312,7 +2350,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2322,7 +2360,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2330,15 +2368,15 @@ name = "tokio-reactor" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "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)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2396,18 +2434,18 @@ dependencies = [ [[package]] name = "tokio-threadpool" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2415,10 +2453,10 @@ name = "tokio-timer" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2428,7 +2466,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2443,8 +2481,8 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2457,7 +2495,7 @@ name = "toml" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2465,7 +2503,7 @@ name = "toml" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2493,7 +2531,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ucd-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2550,6 +2588,16 @@ dependencies = [ "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "url" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "utf8-ranges" version = "1.0.3" @@ -2562,7 +2610,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2571,12 +2619,12 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "vcpkg" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2596,10 +2644,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "walkdir" -version = "2.2.8" +version = "2.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "same-file 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)", "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2610,7 +2658,7 @@ version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (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.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2637,7 +2685,7 @@ name = "which" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2710,47 +2758,46 @@ dependencies = [ [[package]] name = "zeroize" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "zeroize_derive 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize_derive 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "zeroize_derive" -version = "0.9.0" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (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.38 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "zip" -version = "0.4.2" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "msdos_time 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [metadata] "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" -"checksum aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c" +"checksum aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b7aa1ccb7d7ea3f437cf025a2ab1c47cc6c1bc9fc84918ff449def12f5e282" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5" "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.3.25 (registry+https://github.com/rust-lang/crates.io-index)" = "06f59fe10306bb78facd90d28c2038ad23ffaaefa85bac43c8a434cde383334f" -"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" -"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" -"checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf" -"checksum backtrace 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "18b50f5258d1a9ad8396d2d345827875de4261b158124d4c819d9b351454fae5" -"checksum backtrace-sys 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "12cb9f1eef1d1fc869ad5a26c9fa48516339a15e54a227a25460fc304815fdb3" +"checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba" +"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" +"checksum autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "22130e92352b948e7e82a49cdb0aa94f2211761117f29e052dd397c1ac33542b" +"checksum backtrace 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)" = "b5164d292487f037ece34ec0de2fcede2faa162f085dd96d2385ab81b12765ba" +"checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b" "checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" "checksum bindgen 0.37.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1b25ab82877ea8fe6ce1ce1f8ac54361f0218bad900af9eb11803994bf67c221" "checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3" @@ -2758,12 +2805,12 @@ dependencies = [ "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" "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 build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" "checksum built 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e7bff98465f9ff426a6e99829629b69acb0048504584934c1fb8b5822457535" "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -"checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d" +"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" +"checksum cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "ce400c638d48ee0e9ab75aef7997609ec57367ccfe1463f21bf53c3eca67bf46" "checksum cexpr 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42aac45e9567d97474a834efdee3081b3c942b2205be932092f53354ce503d6c" "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" "checksum chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "77d81f58b7301084de3b958691458a53c3f7e0b1d702f77e550b6a88e3a88abe" @@ -2771,14 +2818,13 @@ dependencies = [ "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" -"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" "checksum croaring 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "71152d60cec9dfdc5d9d793bccfa9ad95927372b80cd00e983db5eb2ce103e3b" "checksum croaring-sys 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ac84a4f975e67fc418be3911b7ca9aa74ee8a9717ca75452da7d6839421e2d67" "checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" -"checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4" +"checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9" "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" -"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" +"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" "checksum crypto-mac 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7afa06d05a046c7a47c3a849907ec303504608c927f4e85f7bfff22b7180d971" "checksum csv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7ef22b37c7a51c564a365892c012dc0271221fdcc64c69b19ba4d6fa8bd96d9c" "checksum ct-logs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95a4bf5107667e12bf6ce31a3a5066d67acc88942b6742117a41198734aaccaa" @@ -2804,7 +2850,8 @@ dependencies = [ "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" -"checksum git2 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "924b2e7d2986e625dcad89e8a429a7b3adee3c3d71e585f4a66c4f7e78715e31" +"checksum getrandom 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8e190892c840661957ba9f32dacfb3eb405e657f9f9f60485605f0bb37d6f8" +"checksum git2 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8cb400360e8a4d61b10e648285bbfa919bbf9519d0d5d5720354456f44349226" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum grin_api 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)" = "" "checksum grin_chain 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)" = "" @@ -2815,47 +2862,47 @@ dependencies = [ "checksum grin_secp256k1zkp 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "23027a7673df2c2b20fb9589d742ff400a10a9c3e4c769a77e9fa3bd19586822" "checksum grin_store 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)" = "" "checksum grin_util 2.0.1-beta.1 (git+https://github.com/mimblewimble/grin)" = "" -"checksum h2 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "69b2a5a3092cbebbc951fe55408402e696ee2ed09019137d1800fc2c411265d2" +"checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum hmac 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "733e1b3ac906631ca01ebb577e9bb0f5e37a454032b9036b5eaea4013ed6f99a" -"checksum http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "eed324f0f0daf6ec10c474f150505af2c143f251722bf9dbd1261bd1f2ee2c1a" -"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" +"checksum http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "372bcb56f939e449117fb0869c2e8fd8753a8223d92a172c6e808cf123a5b6e4" +"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" "checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" "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 idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum jsonrpc-core 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc15eef5f8b6bef5ac5f7440a957ff95d036e2f98706947741bfc93d1976db4c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" -"checksum libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "6281b86796ba5e4366000be6e9e18bf35580adf9e63fbe2294aadb587613a319" -"checksum libgit2-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "941a41e23f77323b8c9d2ee118aec9ee39dfc176078c18b4757d3bad049d9ff7" +"checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb" +"checksum libgit2-sys 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4c179ed6d19cd3a051e68c177fbbc214e79ac4724fac3a850ec9f3d3eb8a5578" "checksum liblmdb-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "feed38a3a580f60bf61aaa067b0ff4123395966839adeaf67258a9e50c4d2e49" -"checksum libloading 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a5692f82b51823e27c4118b3e5c0d98aee9be90633ebc71ad12afef380b50219" +"checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" "checksum linefeed 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5c2abb5810ef55bb5f5f33b010cc280b3ab877764c902681efc7c8c95628004c" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "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 log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" +"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" "checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" -"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" +"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" -"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" +"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" "checksum miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9e3ae51cea1576ceba0dde3d484d30e6e5b86dee0b2d412fe3a16a15c98202" -"checksum miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c468f2369f07d651a5d0bb2c9079f8488a66d5466efe42d0c5c6466edcb7f71e" -"checksum miniz_oxide_c_api 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7fe927a42e3807ef71defb191dc87d4e24479b221e67015fe38ae2b7b447bab" +"checksum miniz_oxide 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c061edee74a88eb35d876ce88b94d77a0448a201de111c244b70d047f5820516" +"checksum miniz_oxide_c_api 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6c675792957b0d19933816c4e1d56663c341dd9bfa31cb2140ff2267c1d8ecf4" "checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum mortal 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "26153280e6a955881f761354b130aa7838f9983836f3de438ac0a8f22cfab1ff" -"checksum msdos_time 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aad9dfe950c057b1bfe9c1f2aa51583a8468ef2a5baba2ebbe06d775efeb7729" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" "checksum nix 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0d95c5fa8b641c10ad0b8887454ebaafa3c92b5cd5350f8fc693adafd178e7b" @@ -2875,7 +2922,6 @@ dependencies = [ "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" -"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" "checksum odds 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "4eae0151b9dacf24fcc170d9995e511669a082856a91f958a2fe380bfab3fb22" "checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" @@ -2886,38 +2932,43 @@ dependencies = [ "checksum pbkdf2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0c09cddfbfc98de7f76931acf44460972edb4023eb14d0c6d4018800e552d8e0" "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +"checksum percent-encoding 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba4f28a6faf4ffea762ba8f4baef48c61a6db348647c73095034041fc79dd954" "checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" "checksum phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" "checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" "checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" -"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" +"checksum pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c1d2cfa5a714db3b5f24f0915e74fcdf91d09d496ba61329705dda7774d2af" "checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd" +"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" "checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6" "checksum prettytable-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5511ca4c805aa35f0abff6be7923231d664408b60c09f44ef715f2bce106cd9e" "checksum proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" -"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" +"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" "checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" "checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "615e683324e75af5d43d8f7a39ffe3ee4a9dc42c5c701167a71dc59c3a493aca" "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" "checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" "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 rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe5204c3a17e97dde73f285d49be585df59ed84b50a872baf416e73b62c3828" -"checksum regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0b2f0808e7d7e4fb1cb07feb6ff2f4bc827938f24f8c2e6a3beb7370af544bdd" -"checksum regex-syntax 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d76410686f9e3a17f06128962e0ecc5755870bb890c34820c7af7f1db2e1d48" +"checksum regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b23da8dfd98a84bd7e08700190a5d9f7d2d38abd4369dd1dae651bc40bfd2cc" +"checksum regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5485bf1523a9ed51c4964273f22f63f24e31632adb5dad134f488f86a3875c" "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" @@ -2927,20 +2978,21 @@ dependencies = [ "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "942b71057b31981152970d57399c25f72e27a6ee0d207a669d8304cabf44705b" -"checksum ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "b96a9549dc8d48f2c283938303c4b5a77aa29bfbc5b54b084fb1630408899a8f" -"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" -"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" +"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" +"checksum safemem 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e133ccc4f4d1cd4f89cc8a7ff618287d56dc7f638b8e38fc32c5fdcadc339dd5" +"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" "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 scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" "checksum sct 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb8f61f9e6eadd062a71c380043d28036304a4706b3c4dd001ff3387ed00745a" "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" "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.93 (registry+https://github.com/rust-lang/crates.io-index)" = "960e29cf7004b3b6e65fc5002981400eb3ccc017a08a2406940823e58e7179a9" +"checksum serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5626ac617da2f2d9c48af5515a21d5a480dbd151e01bb1c355e26a3e68113" "checksum serde-value 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7a663f873dedc4eac1a559d4c6bc0d0b2c34dc5ac4702e105014b8281489e44f" -"checksum serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)" = "c4cce6663696bd38272e90bf34a0267e1226156c33f52d3f3915a2dd5d802085" -"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d" +"checksum serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "01e69e1b8a631f245467ee275b8c757b818653c6d704cdbcaeb56b56767b529c" +"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" "checksum serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)" = "38b08a9a90e5260fe01c6480ec7c811606df6d3a660415808c3c3fa8ed95b582" "checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" "checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" @@ -2948,18 +3000,17 @@ dependencies = [ "checksum smallstr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa65bb4d5b2bbc90d36af64e29802f788aa614783fa1d0df011800ddcec6e8e" "checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" -"checksum string 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0bbfb8937e38e34c3444ff00afb28b0811d9554f15c5ad64d12b0308d1d1995" +"checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1c33039533f051704951680f1adfd468fd37ac46816ded0d9ee068e60f05f" "checksum strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "47cd23f5c7dee395a00fa20135e2ec0fffcdfa151c56182966d7a3261343432e" "checksum supercow 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "171758edb47aa306a78dfa4ab9aeb5167405bd4e3dc2b64e88f6a84bbe98bd63" -"checksum syn 0.15.38 (registry+https://github.com/rust-lang/crates.io-index)" = "37ea458a750f59ab679b47fef9b6722c586c5742f4cfe18a120bbc807e5e01fd" +"checksum syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)" = "eadc09306ca51a40555dd6fc2b415538e9e18bc9f870e47b1a524a79fe2dcf5e" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" -"checksum tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7dc4738f2e68ed2855de5ac9cdbe05c9216773ecde4739b2f095002ab03a13ef" +"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.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" "checksum terminfo 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8e51065bafd2abe106b6036483b69d1741f4a1ec56ce8a2378de341637de689e" -"checksum termion 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a8fb22f7cde82c8220e5aeacb3258ed7ce996142c77cba193f203515e26c330" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" @@ -2968,7 +3019,7 @@ dependencies = [ "checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" "checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" -"checksum tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "83ea44c6c0773cc034771693711c35c677b4b5a4b21b9e7071704c54de7d555e" +"checksum tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f27ee0e6db01c5f0b2973824547ce7e637b2ed79b891a9677b0de9bd532b6ac" "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-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce" @@ -2977,7 +3028,7 @@ dependencies = [ "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" "checksum tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2162248ff317e2bc713b261f242b69dbb838b85248ed20bb21df56d60ea4cae7" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" -"checksum tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72558af20be886ea124595ea0f806dd5703b8958e4705429dd58b3d8231f72f2" +"checksum tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "90ca01319dea1e376a001e8dc192d42ebde6dd532532a5bad988ac37db365b19" "checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e" "checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" "checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" @@ -2987,7 +3038,7 @@ dependencies = [ "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.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" -"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" +"checksum ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b3b49edd3468c0e6565d85783f51af95212b6fa3986a5500954f00b460874" "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-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" @@ -2996,14 +3047,15 @@ dependencies = [ "checksum unsafe-any 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +"checksum url 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77ddaf52e65c6b81c56b7e957c0b1970f7937f21c5c6774c4e56fcb4e20b48c6" "checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde" "checksum uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363" "checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" -"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" +"checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95" "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 void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum walkdir 2.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c7904a7e2bb3cdf0cf5e783f44204a85a37a93151738fa349f06680f59a98b45" +"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" "checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" "checksum webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "17d7967316d8411ca3b01821ee6c332bde138ba4363becdb492f12e514daa17f" "checksum webpki-roots 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85d1f408918fd590908a70d36b7ac388db2edc221470333e4d6e5b598e44cabf" @@ -3018,6 +3070,6 @@ dependencies = [ "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" "checksum yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d" -"checksum zeroize 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e2ea4afc22e9497e26b42bf047083c30f7e3ca566f3bcd7187f83d18b327043" -"checksum zeroize_derive 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afd1469e4bbca3b96606d26ba6e9bd6d3aed3b1299c82b92ec94377d22d78dbc" -"checksum zip 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "36b9e08fb518a65cf7e08a1e482573eb87a2f4f8c6619316612a3c1f162fe822" +"checksum zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" +"checksum zeroize_derive 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "080616bd0e31f36095288bb0acdf1f78ef02c2fa15527d7e993f2a6c7591643e" +"checksum zip 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c18fc320faf909036e46ac785ea827f72e485304877faf1a3a39538d3714dbc3" diff --git a/api/Cargo.toml b/api/Cargo.toml index 4829a4244..f82fd0905 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -14,6 +14,8 @@ failure = "0.1" failure_derive = "0.1" log = "0.4" uuid = { version = "0.7", features = ["serde", "v4"] } +serde = "1" +serde_derive = "1" serde_json = "1" easy-jsonrpc = "0.5.1" chrono = { version = "0.4.4", features = ["serde"] } diff --git a/api/src/foreign.rs b/api/src/foreign.rs index aa6ffc5ec..1a0a35d66 100644 --- a/api/src/foreign.rs +++ b/api/src/foreign.rs @@ -20,6 +20,7 @@ use crate::libwallet::{ BlockFees, CbData, Error, NodeClient, NodeVersionInfo, Slate, VersionInfo, WalletInst, WalletLCProvider, }; +use crate::util::secp::key::SecretKey; use crate::util::Mutex; use std::sync::Arc; @@ -67,6 +68,8 @@ where pub doctest_mode: bool, /// foreign check middleware middleware: Option, + /// Stored keychain mask (in case the stored wallet seed is tokenized) + keychain_mask: Option, } impl<'a, L, C, K> Foreign<'a, L, C, K> @@ -86,6 +89,9 @@ where /// # Arguments /// * `wallet_in` - A reference-counted mutex containing an implementation of the /// [`WalletBackend`](../grin_wallet_libwallet/types/trait.WalletBackend.html) trait. + /// * `keychain_mask` - Mask value stored internally to use when calling a wallet + /// whose seed has been XORed with a token value (such as when running the foreign + /// and owner listeners in the same instance) /// * middleware - Option middleware which containts the NodeVersionInfo and can call /// a predefined function with the slate to check if the operation should continue /// @@ -142,24 +148,26 @@ where /// /// // Wallet must be opened with the password (TBD) /// let pw = ZeroingString::from("wallet_password"); - /// lc.open_wallet(None, pw); + /// lc.open_wallet(None, pw, false, false); /// /// // All wallet functions operate on an Arc::Mutex to allow multithreading where needed /// let mut wallet = Arc::new(Mutex::new(wallet)); /// - /// let api_foreign = Foreign::new(wallet.clone(), None); + /// let api_foreign = Foreign::new(wallet.clone(), None, None); /// // .. perform wallet operations /// /// ``` pub fn new( wallet_inst: Arc>>>, + keychain_mask: Option, middleware: Option, ) -> Self { Foreign { wallet_inst, doctest_mode: false, middleware, + keychain_mask, } } @@ -173,7 +181,7 @@ where /// ``` /// # grin_wallet_api::doctest_helper_setup_doc_env_foreign!(wallet, wallet_config); /// - /// let mut api_foreign = Foreign::new(wallet.clone(), None); + /// let mut api_foreign = Foreign::new(wallet.clone(), None, None); /// /// let version_info = api_foreign.check_version(); /// // check and proceed accordingly @@ -225,7 +233,7 @@ where /// ``` /// # grin_wallet_api::doctest_helper_setup_doc_env_foreign!(wallet, wallet_config); /// - /// let mut api_foreign = Foreign::new(wallet.clone(), None); + /// let mut api_foreign = Foreign::new(wallet.clone(), None, None); /// /// let block_fees = BlockFees { /// fees: 800000, @@ -252,7 +260,12 @@ where None, )?; } - foreign::build_coinbase(&mut **w, block_fees, self.doctest_mode) + foreign::build_coinbase( + &mut **w, + (&self.keychain_mask).as_ref(), + block_fees, + self.doctest_mode, + ) } /// Verifies all messages in the slate match their public keys. @@ -276,7 +289,7 @@ where /// ``` /// # grin_wallet_api::doctest_helper_setup_doc_env_foreign!(wallet, wallet_config); /// - /// let mut api_foreign = Foreign::new(wallet.clone(), None); + /// let mut api_foreign = Foreign::new(wallet.clone(), None, None); /// /// # let slate = Slate::blank(2); /// // Receive a slate via some means @@ -349,7 +362,7 @@ where /// ``` /// # grin_wallet_api::doctest_helper_setup_doc_env_foreign!(wallet, wallet_config); /// - /// let mut api_foreign = Foreign::new(wallet.clone(), None); + /// let mut api_foreign = Foreign::new(wallet.clone(), None, None); /// # let slate = Slate::blank(2); /// /// // . . . @@ -377,7 +390,14 @@ where Some(slate), )?; } - foreign::receive_tx(&mut **w, slate, dest_acct_name, message, self.doctest_mode) + foreign::receive_tx( + &mut **w, + (&self.keychain_mask).as_ref(), + slate, + dest_acct_name, + message, + self.doctest_mode, + ) } /// Finalizes an invoice transaction initiated by this wallet's Owner api. @@ -408,7 +428,7 @@ where /// # grin_wallet_api::doctest_helper_setup_doc_env_foreign!(wallet, wallet_config); /// /// let mut api_owner = Owner::new(wallet.clone()); - /// let mut api_foreign = Foreign::new(wallet.clone(), None); + /// let mut api_foreign = Foreign::new(wallet.clone(), None, None); /// /// // . . . /// // Issue the invoice tx via the owner API @@ -416,7 +436,7 @@ where /// amount: 10_000_000_000, /// ..Default::default() /// }; - /// let result = api_owner.issue_invoice_tx(args); + /// let result = api_owner.issue_invoice_tx(None, args); /// /// // If result okay, send to payer, who will apply the transaction via their /// // owner API, then send back the slate @@ -437,7 +457,7 @@ where Some(slate), )?; } - foreign::finalize_invoice_tx(&mut **w, slate) + foreign::finalize_invoice_tx(&mut **w, (&self.keychain_mask).as_ref(), slate) } } @@ -487,7 +507,7 @@ macro_rules! doctest_helper_setup_doc_env_foreign { >; let lc = wallet.lc_provider().unwrap(); lc.set_wallet_directory(&wallet_config.data_file_dir); - lc.open_wallet(None, pw); + lc.open_wallet(None, pw, false, false); let mut $wallet = Arc::new(Mutex::new(wallet)); }; } diff --git a/api/src/foreign_rpc.rs b/api/src/foreign_rpc.rs index 11d865ce4..63fdaf136 100644 --- a/api/src/foreign_rpc.rs +++ b/api/src/foreign_rpc.rs @@ -58,13 +58,13 @@ pub trait ForeignRpc { } } # "# - # , 0, false, false); + # ,false, 0, false, false); ``` */ fn check_version(&self) -> Result; /** - Networked version of [Foreign::build_coinbase](struct.Foreign.html#method.build_coinbase). + Networked Legacy (non-secure token) version of [Foreign::build_coinbase](struct.Foreign.html#method.build_coinbase). # Json rpc example @@ -108,9 +108,10 @@ pub trait ForeignRpc { } } # "# - # , 4, false, false); + # ,false, 4, false, false); ``` */ + fn build_coinbase(&self, block_fees: &BlockFees) -> Result; /** @@ -188,7 +189,7 @@ pub trait ForeignRpc { } } # "# - # ,1 ,false, false); + # ,false, 1 ,false, false); ``` */ fn verify_slate_messages(&self, slate: &Slate) -> Result<(), ErrorKind>; @@ -341,7 +342,7 @@ pub trait ForeignRpc { } } # "# - # , 5, true, false); + # ,false, 5, true, false); ``` */ fn receive_tx( @@ -509,7 +510,7 @@ pub trait ForeignRpc { } } # "# - # , 5, false, true); + # ,false, 5, false, true); ``` */ fn finalize_invoice_tx(&self, slate: &Slate) -> Result; @@ -571,6 +572,7 @@ fn test_check_middleware( pub fn run_doctest_foreign( request: serde_json::Value, test_dir: &str, + use_token: bool, blocks_to_mine: u64, init_tx: bool, init_invoice_tx: bool, @@ -622,10 +624,21 @@ pub fn run_doctest_foreign( lc.set_wallet_directory(&format!("{}/wallet1", test_dir)); lc.create_wallet(None, Some(rec_phrase_1), 32, empty_string.clone()) .unwrap(); - lc.open_wallet(None, empty_string.clone()).unwrap(); + let mask1 = lc + .open_wallet(None, empty_string.clone(), use_token, true) + .unwrap(); let wallet1 = Arc::new(Mutex::new(wallet1)); - wallet_proxy.add_wallet("wallet1", client1.get_send_instance(), wallet1.clone()); + if mask1.is_some() { + println!("WALLET 1 MASK: {:?}", mask1.clone().unwrap()); + } + + wallet_proxy.add_wallet( + "wallet1", + client1.get_send_instance(), + wallet1.clone(), + mask1.clone(), + ); let rec_phrase_2 = util::ZeroingString::from( "hour kingdom ripple lunch razor inquiry coyote clay stamp mean \ @@ -646,10 +659,17 @@ pub fn run_doctest_foreign( lc.set_wallet_directory(&format!("{}/wallet2", test_dir)); lc.create_wallet(None, Some(rec_phrase_2), 32, empty_string.clone()) .unwrap(); - lc.open_wallet(None, empty_string.clone()).unwrap(); + let mask2 = lc + .open_wallet(None, empty_string.clone(), use_token, true) + .unwrap(); let wallet2 = Arc::new(Mutex::new(wallet2)); - wallet_proxy.add_wallet("wallet2", client2.get_send_instance(), wallet2.clone()); + wallet_proxy.add_wallet( + "wallet2", + client2.get_send_instance(), + wallet2.clone(), + mask2.clone(), + ); // Set the wallet proxy listener running thread::spawn(move || { @@ -660,12 +680,18 @@ pub fn run_doctest_foreign( // Mine a few blocks to wallet 1 so there's something to send for _ in 0..blocks_to_mine { - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 1 as usize, false); + let _ = test_framework::award_blocks_to_wallet( + &chain, + wallet1.clone(), + (&mask1).as_ref(), + 1 as usize, + false, + ); //update local outputs after each block, so transaction IDs stay consistent let mut w_lock = wallet1.lock(); let w = w_lock.lc_provider().unwrap().wallet_inst().unwrap(); let (wallet_refreshed, _) = - api_impl::owner::retrieve_summary_info(&mut **w, true, 1).unwrap(); + api_impl::owner::retrieve_summary_info(&mut **w, (&mask1).as_ref(), true, 1).unwrap(); assert!(wallet_refreshed); } @@ -678,7 +704,7 @@ pub fn run_doctest_foreign( amount, ..Default::default() }; - api_impl::owner::issue_invoice_tx(&mut **w, args, true).unwrap() + api_impl::owner::issue_invoice_tx(&mut **w, (&mask2).as_ref(), args, true).unwrap() }; slate = { let mut w_lock = wallet1.lock(); @@ -692,7 +718,8 @@ pub fn run_doctest_foreign( selection_strategy_is_use_all: true, ..Default::default() }; - api_impl::owner::process_invoice_tx(&mut **w, &slate, args, true).unwrap() + api_impl::owner::process_invoice_tx(&mut **w, (&mask1).as_ref(), &slate, args, true) + .unwrap() }; println!("INIT INVOICE SLATE"); // Spit out slate for input to finalize_invoice_tx @@ -712,15 +739,15 @@ pub fn run_doctest_foreign( selection_strategy_is_use_all: true, ..Default::default() }; - let slate = api_impl::owner::init_send_tx(&mut **w, args, true).unwrap(); + let slate = api_impl::owner::init_send_tx(&mut **w, (&mask1).as_ref(), args, true).unwrap(); println!("INIT SLATE"); // Spit out slate for input to finalize_tx println!("{}", serde_json::to_string_pretty(&slate).unwrap()); } let mut api_foreign = match init_invoice_tx { - false => Foreign::new(wallet1, Some(test_check_middleware)), - true => Foreign::new(wallet2, Some(test_check_middleware)), + false => Foreign::new(wallet1, mask1, Some(test_check_middleware)), + true => Foreign::new(wallet2, mask2, Some(test_check_middleware)), }; api_foreign.doctest_mode = true; let foreign_api = &api_foreign as &dyn ForeignRpc; @@ -730,7 +757,7 @@ pub fn run_doctest_foreign( #[doc(hidden)] #[macro_export] macro_rules! doctest_helper_json_rpc_foreign_assert_response { - ($request:expr, $expected_response:expr, $blocks_to_mine:expr, $init_tx:expr, $init_invoice_tx:expr) => { + ($request:expr, $expected_response:expr, $use_token:expr, $blocks_to_mine:expr, $init_tx:expr, $init_invoice_tx:expr) => { // create temporary wallet, run jsonrpc request on owner api of wallet, delete wallet, return // json response. // In order to prevent leaking tempdirs, This function should not panic. @@ -752,6 +779,7 @@ macro_rules! doctest_helper_json_rpc_foreign_assert_response { let response = run_doctest_foreign( request_val, dir, + $use_token, $blocks_to_mine, $init_tx, $init_invoice_tx, diff --git a/api/src/lib.rs b/api/src/lib.rs index 3a798b3ed..1e8826572 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -29,6 +29,8 @@ extern crate grin_wallet_impls as impls; extern crate grin_wallet_libwallet as libwallet; extern crate failure_derive; +#[macro_use] +extern crate serde_derive; extern crate serde_json; #[macro_use] @@ -39,12 +41,25 @@ mod foreign_rpc; mod owner; mod owner_rpc; +mod owner_rpc_s; pub use crate::foreign::{Foreign, ForeignCheckMiddleware, ForeignCheckMiddlewareFn}; pub use crate::foreign_rpc::ForeignRpc; pub use crate::owner::Owner; pub use crate::owner_rpc::OwnerRpc; +pub use crate::owner_rpc_s::OwnerRpcS; pub use crate::foreign_rpc::foreign_rpc as foreign_rpc_client; pub use crate::foreign_rpc::run_doctest_foreign; pub use crate::owner_rpc::run_doctest_owner; + +use grin_wallet_util::grin_core::libtx::secp_ser; +use util::secp::key::SecretKey; + +/// Wrapper for API Tokens +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(transparent)] +pub struct Token { + #[serde(with = "secp_ser::option_seckey_serde")] + keychain_mask: Option, +} diff --git a/api/src/owner.rs b/api/src/owner.rs index 85a310faa..df363c414 100644 --- a/api/src/owner.rs +++ b/api/src/owner.rs @@ -26,6 +26,7 @@ use crate::libwallet::{ NodeHeightResult, OutputCommitMapping, Slate, TxLogEntry, WalletInfo, WalletInst, WalletLCProvider, }; +use crate::util::secp::key::SecretKey; use crate::util::Mutex; use std::sync::Arc; @@ -126,7 +127,7 @@ where /// /// // Wallet must be opened with the password (TBD) /// let pw = ZeroingString::from("wallet_password"); - /// lc.open_wallet(None, pw); + /// lc.open_wallet(None, pw, false, false); /// /// // All wallet functions operate on an Arc::Mutex to allow multithreading where needed /// let mut wallet = Arc::new(Mutex::new(wallet)); @@ -145,6 +146,9 @@ where /// Returns a list of accounts stored in the wallet (i.e. mappings between /// user-specified labels and BIP32 derivation paths. + /// # Arguments + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// /// # Returns /// * Result Containing: @@ -164,16 +168,21 @@ where /// /// let api_owner = Owner::new(wallet.clone()); /// - /// let result = api_owner.accounts(); + /// let result = api_owner.accounts(None); /// /// if let Ok(accts) = result { /// //... /// } /// ``` - pub fn accounts(&self) -> Result, Error> { + pub fn accounts( + &self, + keychain_mask: Option<&SecretKey>, + ) -> Result, Error> { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; + // Test keychain mask, to keep API consistent + let _ = w.keychain(keychain_mask)?; owner::accounts(&mut **w) } @@ -181,6 +190,9 @@ where /// label to a BIP32 path /// /// # Arguments + /// + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// * `label` - A human readable label to which to map the new BIP32 Path /// /// # Returns @@ -207,23 +219,29 @@ where /// /// let api_owner = Owner::new(wallet.clone()); /// - /// let result = api_owner.create_account_path("account1"); + /// let result = api_owner.create_account_path(None, "account1"); /// /// if let Ok(identifier) = result { /// //... /// } /// ``` - pub fn create_account_path(&self, label: &str) -> Result { + pub fn create_account_path( + &self, + keychain_mask: Option<&SecretKey>, + label: &str, + ) -> Result { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; - owner::create_account_path(&mut **w, label) + owner::create_account_path(&mut **w, keychain_mask, label) } /// Sets the wallet's currently active account. This sets the /// BIP32 parent path used for most key-derivation operations. /// /// # Arguments + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// * `label` - The human readable label for the account. Accounts can be retrieved via /// the [`account`](struct.Owner.html#method.accounts) method /// @@ -248,23 +266,31 @@ where /// /// let api_owner = Owner::new(wallet.clone()); /// - /// let result = api_owner.create_account_path("account1"); + /// let result = api_owner.create_account_path(None, "account1"); /// /// if let Ok(identifier) = result { /// // set the account active - /// let result2 = api_owner.set_active_account("account1"); + /// let result2 = api_owner.set_active_account(None, "account1"); /// } /// ``` - pub fn set_active_account(&self, label: &str) -> Result<(), Error> { + pub fn set_active_account( + &self, + keychain_mask: Option<&SecretKey>, + label: &str, + ) -> Result<(), Error> { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; + // Test keychain mask, to keep API consistent + let _ = w.keychain(keychain_mask)?; owner::set_active_account(&mut **w, label) } /// Returns a list of outputs from the active account in the wallet. /// /// # Arguments + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// * `include_spent` - If `true`, outputs that have been marked as 'spent' /// in the wallet will be returned. If `false`, spent outputs will omitted /// from the results. @@ -297,7 +323,7 @@ where /// let update_from_node = true; /// let tx_id = None; /// - /// let result = api_owner.retrieve_outputs(show_spent, update_from_node, tx_id); + /// let result = api_owner.retrieve_outputs(None, show_spent, update_from_node, tx_id); /// /// if let Ok((was_updated, output_mappings)) = result { /// //... @@ -306,19 +332,28 @@ where pub fn retrieve_outputs( &self, + keychain_mask: Option<&SecretKey>, include_spent: bool, refresh_from_node: bool, tx_id: Option, ) -> Result<(bool, Vec), Error> { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; - owner::retrieve_outputs(&mut **w, include_spent, refresh_from_node, tx_id) + owner::retrieve_outputs( + &mut **w, + keychain_mask, + include_spent, + refresh_from_node, + tx_id, + ) } /// Returns a list of [Transaction Log Entries](../grin_wallet_libwallet/types/struct.TxLogEntry.html) /// from the active account in the wallet. /// /// # Arguments + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// * `refresh_from_node` - If true, the wallet will attempt to contact /// a node (via the [`NodeClient`](../grin_wallet_libwallet/types/trait.NodeClient.html) /// provided during wallet instantiation). If `false`, the results will @@ -348,7 +383,7 @@ where /// let tx_slate_id = None; /// /// // Return all TxLogEntries - /// let result = api_owner.retrieve_txs(update_from_node, tx_id, tx_slate_id); + /// let result = api_owner.retrieve_txs(None, update_from_node, tx_id, tx_slate_id); /// /// if let Ok((was_updated, tx_log_entries)) = result { /// //... @@ -357,13 +392,20 @@ where pub fn retrieve_txs( &self, + keychain_mask: Option<&SecretKey>, refresh_from_node: bool, tx_id: Option, tx_slate_id: Option, ) -> Result<(bool, Vec), Error> { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; - let mut res = owner::retrieve_txs(&mut **w, refresh_from_node, tx_id, tx_slate_id)?; + let mut res = owner::retrieve_txs( + &mut **w, + keychain_mask, + refresh_from_node, + tx_id, + tx_slate_id, + )?; if self.doctest_mode { res.1 = res .1 @@ -381,6 +423,8 @@ where /// Returns summary information from the active account in the wallet. /// /// # Arguments + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// * `refresh_from_node` - If true, the wallet will attempt to contact /// a node (via the [`NodeClient`](../grin_wallet_libwallet/types/trait.NodeClient.html) /// provided during wallet instantiation). If `false`, the results will @@ -406,7 +450,7 @@ where /// let minimum_confirmations=10; /// /// // Return summary info for active account - /// let result = api_owner.retrieve_summary_info(update_from_node, minimum_confirmations); + /// let result = api_owner.retrieve_summary_info(None, update_from_node, minimum_confirmations); /// /// if let Ok((was_updated, summary_info)) = result { /// //... @@ -415,12 +459,18 @@ where pub fn retrieve_summary_info( &self, + keychain_mask: Option<&SecretKey>, refresh_from_node: bool, minimum_confirmations: u64, ) -> Result<(bool, WalletInfo), Error> { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; - owner::retrieve_summary_info(&mut **w, refresh_from_node, minimum_confirmations) + owner::retrieve_summary_info( + &mut **w, + keychain_mask, + refresh_from_node, + minimum_confirmations, + ) } /// Initiates a new transaction as the sender, creating a new @@ -447,6 +497,8 @@ where /// the `finalize` field is set. /// /// # Arguments + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// * `args` - [`InitTxArgs`](../grin_wallet_libwallet/types/struct.InitTxArgs.html), /// transaction initialization arguments. See struct documentation for further detail. /// @@ -485,6 +537,7 @@ where /// ..Default::default() /// }; /// let result = api_owner.init_send_tx( + /// None, /// args, /// ); /// @@ -492,16 +545,20 @@ where /// // Send slate somehow /// // ... /// // Lock our outputs if we're happy the slate was (or is being) sent - /// api_owner.tx_lock_outputs(&slate, 0); + /// api_owner.tx_lock_outputs(None, &slate, 0); /// } /// ``` - pub fn init_send_tx(&self, args: InitTxArgs) -> Result { + pub fn init_send_tx( + &self, + keychain_mask: Option<&SecretKey>, + args: InitTxArgs, + ) -> Result { let send_args = args.send_args.clone(); let mut slate = { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; - owner::init_send_tx(&mut **w, args, self.doctest_mode)? + owner::init_send_tx(&mut **w, keychain_mask, args, self.doctest_mode)? }; // Helper functionality. If send arguments exist, attempt to send match send_args { @@ -520,14 +577,14 @@ where let comm_adapter = create_sender(&sa.method, &sa.dest) .map_err(|e| ErrorKind::GenericError(format!("{}", e)))?; slate = comm_adapter.send_tx(&slate)?; - self.tx_lock_outputs(&slate, 0)?; + self.tx_lock_outputs(keychain_mask, &slate, 0)?; let slate = match sa.finalize { - true => self.finalize_tx(&slate)?, + true => self.finalize_tx(keychain_mask, &slate)?, false => slate, }; if sa.post_tx { - self.post_tx(&slate.tx, sa.fluff)?; + self.post_tx(keychain_mask, &slate.tx, sa.fluff)?; } Ok(slate) } @@ -542,6 +599,8 @@ where /// via the [Foreign API's `finalize_invoice_tx`](struct.Foreign.html#method.finalize_invoice_tx) method. /// /// # Arguments + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// * `args` - [`IssueInvoiceTxArgs`](../grin_wallet_libwallet/types/struct.IssueInvoiceTxArgs.html), /// invoice transaction initialization arguments. See struct documentation for further detail. /// @@ -561,17 +620,21 @@ where /// amount: 60_000_000_000, /// ..Default::default() /// }; - /// let result = api_owner.issue_invoice_tx(args); + /// let result = api_owner.issue_invoice_tx(None, args); /// /// if let Ok(slate) = result { /// // if okay, send to the payer to add their inputs /// // . . . /// } /// ``` - pub fn issue_invoice_tx(&self, args: IssueInvoiceTxArgs) -> Result { + pub fn issue_invoice_tx( + &self, + keychain_mask: Option<&SecretKey>, + args: IssueInvoiceTxArgs, + ) -> Result { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; - owner::issue_invoice_tx(&mut **w, args, self.doctest_mode) + owner::issue_invoice_tx(&mut **w, keychain_mask, args, self.doctest_mode) } /// Processes an invoice tranaction created by another party, essentially @@ -589,6 +652,8 @@ where /// via the [`get_stored_tx`](struct.Owner.html#method.get_stored_tx) function. /// /// # Arguments + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// * `slate` - The transaction [`Slate`](../grin_wallet_libwallet/slate/struct.Slate.html). The /// payer should have filled in round 1 and 2. /// * `args` - [`InitTxArgs`](../grin_wallet_libwallet/types/struct.InitTxArgs.html), @@ -619,7 +684,7 @@ where /// ..Default::default() /// }; /// - /// let result = api_owner.process_invoice_tx(&slate, args); + /// let result = api_owner.process_invoice_tx(None, &slate, args); /// /// if let Ok(slate) = result { /// // If result okay, send back to the invoicer @@ -627,10 +692,15 @@ where /// } /// ``` - pub fn process_invoice_tx(&self, slate: &Slate, args: InitTxArgs) -> Result { + pub fn process_invoice_tx( + &self, + keychain_mask: Option<&SecretKey>, + slate: &Slate, + args: InitTxArgs, + ) -> Result { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; - owner::process_invoice_tx(&mut **w, slate, args, self.doctest_mode) + owner::process_invoice_tx(&mut **w, keychain_mask, slate, args, self.doctest_mode) } /// Locks the outputs associated with the inputs to the transaction in the given @@ -647,6 +717,8 @@ where /// and return them to the `Unspent` state. /// /// # Arguments + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// * `slate` - The transaction [`Slate`](../grin_wallet_libwallet/slate/struct.Slate.html). All /// * `participant_id` - The participant id, generally 0 for the party putting in funds, 1 for the /// party receiving. @@ -674,6 +746,7 @@ where /// ..Default::default() /// }; /// let result = api_owner.init_send_tx( + /// None, /// args, /// ); /// @@ -681,14 +754,19 @@ where /// // Send slate somehow /// // ... /// // Lock our outputs if we're happy the slate was (or is being) sent - /// api_owner.tx_lock_outputs(&slate, 0); + /// api_owner.tx_lock_outputs(None, &slate, 0); /// } /// ``` - pub fn tx_lock_outputs(&self, slate: &Slate, participant_id: usize) -> Result<(), Error> { + pub fn tx_lock_outputs( + &self, + keychain_mask: Option<&SecretKey>, + slate: &Slate, + participant_id: usize, + ) -> Result<(), Error> { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; - owner::tx_lock_outputs(&mut **w, slate, participant_id) + owner::tx_lock_outputs(&mut **w, keychain_mask, slate, participant_id) } /// Finalizes a transaction, after all parties @@ -704,6 +782,8 @@ where /// via the [`get_stored_tx`](struct.Owner.html#method.get_stored_tx) function. /// /// # Arguments + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// * `slate` - The transaction [`Slate`](../grin_wallet_libwallet/slate/struct.Slate.html). All /// participants must have filled in both rounds, and the sender should have locked their /// outputs (via the [`tx_lock_outputs`](struct.Owner.html#method.tx_lock_outputs) function). @@ -730,6 +810,7 @@ where /// ..Default::default() /// }; /// let result = api_owner.init_send_tx( + /// None, /// args, /// ); /// @@ -737,27 +818,32 @@ where /// // Send slate somehow /// // ... /// // Lock our outputs if we're happy the slate was (or is being) sent - /// let res = api_owner.tx_lock_outputs(&slate, 0); + /// let res = api_owner.tx_lock_outputs(None, &slate, 0); /// // /// // Retrieve slate back from recipient /// // - /// let res = api_owner.finalize_tx(&slate); + /// let res = api_owner.finalize_tx(None, &slate); /// } /// ``` - pub fn finalize_tx(&self, slate: &Slate) -> Result { + pub fn finalize_tx( + &self, + keychain_mask: Option<&SecretKey>, + slate: &Slate, + ) -> Result { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; - owner::finalize_tx(&mut **w, &slate) + owner::finalize_tx(&mut **w, keychain_mask, &slate) } /// Posts a completed transaction to the listening node for validation and inclusion in a block /// for mining. /// /// # Arguments + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// * `tx` - A completed [`Transaction`](../grin_core/core/transaction/struct.Transaction.html), /// typically the `tx` field in the transaction [`Slate`](../grin_wallet_libwallet/slate/struct.Slate.html). - /// /// * `fluff` - Instruct the node whether to use the Dandelion protocol when posting the /// transaction. If `true`, the node should skip the Dandelion phase and broadcast the /// transaction to all peers immediately. If `false`, the node will follow dandelion logic and @@ -784,6 +870,7 @@ where /// ..Default::default() /// }; /// let result = api_owner.init_send_tx( + /// None, /// args, /// ); /// @@ -791,19 +878,26 @@ where /// // Send slate somehow /// // ... /// // Lock our outputs if we're happy the slate was (or is being) sent - /// let res = api_owner.tx_lock_outputs(&slate, 0); + /// let res = api_owner.tx_lock_outputs(None, &slate, 0); /// // /// // Retrieve slate back from recipient /// // - /// let res = api_owner.finalize_tx(&slate); - /// let res = api_owner.post_tx(&slate.tx, true); + /// let res = api_owner.finalize_tx(None, &slate); + /// let res = api_owner.post_tx(None, &slate.tx, true); /// } /// ``` - pub fn post_tx(&self, tx: &Transaction, fluff: bool) -> Result<(), Error> { + pub fn post_tx( + &self, + keychain_mask: Option<&SecretKey>, + tx: &Transaction, + fluff: bool, + ) -> Result<(), Error> { let client = { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; + // Test keychain mask, to keep API consistent + let _ = w.keychain(keychain_mask)?; w.w2n_client().clone() }; owner::post_tx(&client, tx, fluff) @@ -820,6 +914,8 @@ where /// /// # Arguments /// + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// * `tx_id` - If present, cancel by the [`TxLogEntry`](../grin_wallet_libwallet/types/struct.TxLogEntry.html) id /// for the transaction. /// @@ -846,6 +942,7 @@ where /// ..Default::default() /// }; /// let result = api_owner.init_send_tx( + /// None, /// args, /// ); /// @@ -853,18 +950,23 @@ where /// // Send slate somehow /// // ... /// // Lock our outputs if we're happy the slate was (or is being) sent - /// let res = api_owner.tx_lock_outputs(&slate, 0); + /// let res = api_owner.tx_lock_outputs(None, &slate, 0); /// // /// // We didn't get the slate back, or something else went wrong /// // - /// let res = api_owner.cancel_tx(None, Some(slate.id.clone())); + /// let res = api_owner.cancel_tx(None, None, Some(slate.id.clone())); /// } /// ``` - pub fn cancel_tx(&self, tx_id: Option, tx_slate_id: Option) -> Result<(), Error> { + pub fn cancel_tx( + &self, + keychain_mask: Option<&SecretKey>, + tx_id: Option, + tx_slate_id: Option, + ) -> Result<(), Error> { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; - owner::cancel_tx(&mut **w, tx_id, tx_slate_id) + owner::cancel_tx(&mut **w, keychain_mask, tx_id, tx_slate_id) } /// Retrieves the stored transaction associated with a TxLogEntry. Can be used even after the @@ -872,6 +974,8 @@ where /// /// # Arguments /// + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// * `tx_log_entry` - A [`TxLogEntry`](../grin_wallet_libwallet/types/struct.TxLogEntry.html) /// /// # Returns @@ -890,18 +994,24 @@ where /// let tx_slate_id = None; /// /// // Return all TxLogEntries - /// let result = api_owner.retrieve_txs(update_from_node, tx_id, tx_slate_id); + /// let result = api_owner.retrieve_txs(None, update_from_node, tx_id, tx_slate_id); /// /// if let Ok((was_updated, tx_log_entries)) = result { - /// let stored_tx = api_owner.get_stored_tx(&tx_log_entries[0]).unwrap(); + /// let stored_tx = api_owner.get_stored_tx(None, &tx_log_entries[0]).unwrap(); /// //... /// } /// ``` // TODO: Should be accepting an id, not an entire entry struct - pub fn get_stored_tx(&self, tx_log_entry: &TxLogEntry) -> Result, Error> { + pub fn get_stored_tx( + &self, + keychain_mask: Option<&SecretKey>, + tx_log_entry: &TxLogEntry, + ) -> Result, Error> { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; + // Test keychain mask, to keep API consistent + let _ = w.keychain(keychain_mask)?; owner::get_stored_tx(&**w, tx_log_entry) } @@ -915,6 +1025,8 @@ where /// /// # Arguments /// + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// * `slate` - The transaction [`Slate`](../grin_wallet_libwallet/slate/struct.Slate.html). /// /// # Returns @@ -938,6 +1050,7 @@ where /// ..Default::default() /// }; /// let result = api_owner.init_send_tx( + /// None, /// args, /// ); /// @@ -945,14 +1058,24 @@ where /// // Send slate somehow /// // ... /// // Lock our outputs if we're happy the slate was (or is being) sent - /// let res = api_owner.tx_lock_outputs(&slate, 0); + /// let res = api_owner.tx_lock_outputs(None, &slate, 0); /// // /// // Retrieve slate back from recipient /// // - /// let res = api_owner.verify_slate_messages(&slate); + /// let res = api_owner.verify_slate_messages(None, &slate); /// } /// ``` - pub fn verify_slate_messages(&self, slate: &Slate) -> Result<(), Error> { + pub fn verify_slate_messages( + &self, + keychain_mask: Option<&SecretKey>, + slate: &Slate, + ) -> Result<(), Error> { + { + let mut w_lock = self.wallet_inst.lock(); + let w = w_lock.lc_provider()?.wallet_inst()?; + // Test keychain mask, to keep API consistent + let _ = w.keychain(keychain_mask)?; + } owner::verify_slate_messages(slate) } @@ -971,7 +1094,8 @@ where /// /// # Arguments /// - /// * None + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// /// # Returns /// * `Ok(())` if successful @@ -983,17 +1107,17 @@ where /// # grin_wallet_api::doctest_helper_setup_doc_env!(wallet, wallet_config); /// /// let mut api_owner = Owner::new(wallet.clone()); - /// let result = api_owner.restore(); + /// let result = api_owner.restore(None); /// /// if let Ok(_) = result { /// // Wallet outputs should be consistent with what's on chain /// // ... /// } /// ``` - pub fn restore(&self) -> Result<(), Error> { + pub fn restore(&self, keychain_mask: Option<&SecretKey>) -> Result<(), Error> { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; - let res = owner::restore(&mut **w); + let res = owner::restore(&mut **w, keychain_mask); res } @@ -1013,6 +1137,8 @@ where /// /// # Arguments /// + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// * `delete_unconfirmed` - if `false`, the check_repair process will be non-destructive, and /// mostly limited to restoring missing outputs. It will leave unconfirmed transaction logs entries /// and unconfirmed outputs intact. If `true`, the process will unlock all locked outputs, @@ -1034,6 +1160,7 @@ where /// /// let mut api_owner = Owner::new(wallet.clone()); /// let result = api_owner.check_repair( + /// None, /// false, /// ); /// @@ -1043,10 +1170,14 @@ where /// } /// ``` - pub fn check_repair(&self, delete_unconfirmed: bool) -> Result<(), Error> { + pub fn check_repair( + &self, + keychain_mask: Option<&SecretKey>, + delete_unconfirmed: bool, + ) -> Result<(), Error> { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; - owner::check_repair(&mut **w, delete_unconfirmed) + owner::check_repair(&mut **w, keychain_mask, delete_unconfirmed) } /// Retrieves the last known height known by the wallet. This is determined as follows: @@ -1061,7 +1192,8 @@ where /// /// # Arguments /// - /// * None + /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if + /// being used. /// /// # Returns /// * Ok with a [`NodeHeightResult`](../grin_wallet_libwallet/types/struct.NodeHeightResult.html) @@ -1075,7 +1207,7 @@ where /// # grin_wallet_api::doctest_helper_setup_doc_env!(wallet, wallet_config); /// /// let api_owner = Owner::new(wallet.clone()); - /// let result = api_owner.node_height(); + /// let result = api_owner.node_height(None); /// /// if let Ok(node_height_result) = result { /// if node_height_result.updated_from_node { @@ -1086,10 +1218,15 @@ where /// } /// ``` - pub fn node_height(&self) -> Result { + pub fn node_height( + &self, + keychain_mask: Option<&SecretKey>, + ) -> Result { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; - owner::node_height(&mut **w) + // Test keychain mask, to keep API consistent + let _ = w.keychain(keychain_mask)?; + owner::node_height(&mut **w, keychain_mask) } } @@ -1139,7 +1276,7 @@ macro_rules! doctest_helper_setup_doc_env { >; let lc = wallet.lc_provider().unwrap(); lc.set_wallet_directory(&wallet_config.data_file_dir); - lc.open_wallet(None, pw); + lc.open_wallet(None, pw, false, false); let mut $wallet = Arc::new(Mutex::new(wallet)); }; } diff --git a/api/src/owner_rpc.rs b/api/src/owner_rpc.rs index f8134630b..44503e707 100644 --- a/api/src/owner_rpc.rs +++ b/api/src/owner_rpc.rs @@ -23,7 +23,7 @@ use crate::libwallet::{ WalletLCProvider, }; use crate::util::Mutex; -use crate::Owner; +use crate::{Owner, OwnerRpcS}; use easy_jsonrpc; use std::sync::Arc; @@ -63,7 +63,7 @@ pub trait OwnerRpc { "id": 1 } # "# - # , 4, false, false, false); + # , false, 4, false, false, false); ``` */ fn accounts(&self) -> Result, ErrorKind>; @@ -93,7 +93,7 @@ pub trait OwnerRpc { "id": 1 } # "# - # ,4, false, false, false); + # ,false, 4, false, false, false); ``` */ fn create_account_path(&self, label: &String) -> Result; @@ -123,7 +123,7 @@ pub trait OwnerRpc { "id": 1 } # "# - # , 4, false, false, false); + # , false, 4, false, false, false); ``` */ fn set_active_account(&self, label: &String) -> Result<(), ErrorKind>; @@ -189,7 +189,7 @@ pub trait OwnerRpc { } } # "# - # , 2, false, false, false); + # , false, 2, false, false, false); ``` */ fn retrieve_outputs( @@ -260,7 +260,7 @@ pub trait OwnerRpc { } } # "# - # , 2, false, false, false); + # , false, 2, false, false, false); ``` */ @@ -306,7 +306,7 @@ pub trait OwnerRpc { } } # "# - # ,4, false, false, false); + # ,false, 4, false, false, false); ``` */ @@ -400,7 +400,7 @@ pub trait OwnerRpc { } } # "# - # ,4, false, false, false); + # ,false, 4, false, false, false); ``` */ @@ -480,7 +480,7 @@ pub trait OwnerRpc { } } # "# - # ,4, false, false, false); + # ,false, 4, false, false, false); ``` */ @@ -628,7 +628,7 @@ pub trait OwnerRpc { } } # "# - # ,4, false, false, false); + # ,false, 4, false, false, false); ``` */ @@ -712,7 +712,7 @@ pub trait OwnerRpc { } } # "# - # ,5 ,true, false, false); + # ,false, 5 ,true, false, false); ``` */ @@ -879,7 +879,7 @@ pub trait OwnerRpc { } } # "# - # , 5, true, true, false); + # , false, 5, true, true, false); ``` */ fn finalize_tx(&self, slate: VersionedSlate) -> Result; @@ -945,7 +945,7 @@ pub trait OwnerRpc { } } # "# - # , 5, true, true, true); + # , false, 5, true, true, true); ``` */ @@ -975,7 +975,7 @@ pub trait OwnerRpc { } } # "# - # , 5, true, true, false); + # , false, 5, true, true, false); ``` */ fn cancel_tx(&self, tx_id: Option, tx_slate_id: Option) -> Result<(), ErrorKind>; @@ -1070,7 +1070,7 @@ pub trait OwnerRpc { } } # "# - # , 5, true, true, false); + # , false, 5, true, true, false); ``` */ fn get_stored_tx(&self, tx: &TxLogEntry) -> Result, ErrorKind>; @@ -1148,7 +1148,7 @@ pub trait OwnerRpc { } } # "# - # ,5 ,true, false, false); + # ,false, 5 ,true, false, false); ``` */ fn verify_slate_messages(&self, slate: VersionedSlate) -> Result<(), ErrorKind>; @@ -1177,7 +1177,7 @@ pub trait OwnerRpc { } } # "# - # , 1, false, false, false); + # , false, 1, false, false, false); ``` */ fn restore(&self) -> Result<(), ErrorKind>; @@ -1206,7 +1206,7 @@ pub trait OwnerRpc { } } # "# - # , 1, false, false, false); + # , false, 1, false, false, false); ``` */ fn check_repair(&self, delete_unconfirmed: bool) -> Result<(), ErrorKind>; @@ -1238,7 +1238,7 @@ pub trait OwnerRpc { } } # "# - # , 5, false, false, false); + # , false, 5, false, false, false); ``` */ fn node_height(&self) -> Result; @@ -1251,15 +1251,15 @@ where K: Keychain + 'a, { fn accounts(&self) -> Result, ErrorKind> { - Owner::accounts(self).map_err(|e| e.kind()) + Owner::accounts(self, None).map_err(|e| e.kind()) } fn create_account_path(&self, label: &String) -> Result { - Owner::create_account_path(self, label).map_err(|e| e.kind()) + Owner::create_account_path(self, None, label).map_err(|e| e.kind()) } fn set_active_account(&self, label: &String) -> Result<(), ErrorKind> { - Owner::set_active_account(self, label).map_err(|e| e.kind()) + Owner::set_active_account(self, None, label).map_err(|e| e.kind()) } fn retrieve_outputs( @@ -1268,7 +1268,8 @@ where refresh_from_node: bool, tx_id: Option, ) -> Result<(bool, Vec), ErrorKind> { - Owner::retrieve_outputs(self, include_spent, refresh_from_node, tx_id).map_err(|e| e.kind()) + Owner::retrieve_outputs(self, None, include_spent, refresh_from_node, tx_id) + .map_err(|e| e.kind()) } fn retrieve_txs( @@ -1277,7 +1278,7 @@ where tx_id: Option, tx_slate_id: Option, ) -> Result<(bool, Vec), ErrorKind> { - Owner::retrieve_txs(self, refresh_from_node, tx_id, tx_slate_id).map_err(|e| e.kind()) + Owner::retrieve_txs(self, None, refresh_from_node, tx_id, tx_slate_id).map_err(|e| e.kind()) } fn retrieve_summary_info( @@ -1285,18 +1286,18 @@ where refresh_from_node: bool, minimum_confirmations: u64, ) -> Result<(bool, WalletInfo), ErrorKind> { - Owner::retrieve_summary_info(self, refresh_from_node, minimum_confirmations) + Owner::retrieve_summary_info(self, None, refresh_from_node, minimum_confirmations) .map_err(|e| e.kind()) } fn init_send_tx(&self, args: InitTxArgs) -> Result { - let slate = Owner::init_send_tx(self, args).map_err(|e| e.kind())?; + let slate = Owner::init_send_tx(self, None, args).map_err(|e| e.kind())?; let version = SlateVersion::V2; Ok(VersionedSlate::into_version(slate, version)) } fn issue_invoice_tx(&self, args: IssueInvoiceTxArgs) -> Result { - let slate = Owner::issue_invoice_tx(self, args).map_err(|e| e.kind())?; + let slate = Owner::issue_invoice_tx(self, None, args).map_err(|e| e.kind())?; let version = SlateVersion::V2; Ok(VersionedSlate::into_version(slate, version)) } @@ -1307,14 +1308,15 @@ where args: InitTxArgs, ) -> Result { let in_slate = Slate::from(slate); - let out_slate = Owner::process_invoice_tx(self, &in_slate, args).map_err(|e| e.kind())?; + let out_slate = + Owner::process_invoice_tx(self, None, &in_slate, args).map_err(|e| e.kind())?; let version = SlateVersion::V2; Ok(VersionedSlate::into_version(out_slate, version)) } fn finalize_tx(&self, slate: VersionedSlate) -> Result { let in_slate = Slate::from(slate); - let out_slate = Owner::finalize_tx(self, &in_slate).map_err(|e| e.kind())?; + let out_slate = Owner::finalize_tx(self, None, &in_slate).map_err(|e| e.kind())?; let version = SlateVersion::V2; Ok(VersionedSlate::into_version(out_slate, version)) } @@ -1325,36 +1327,36 @@ where participant_id: usize, ) -> Result<(), ErrorKind> { let in_slate = Slate::from(slate); - Owner::tx_lock_outputs(self, &in_slate, participant_id).map_err(|e| e.kind()) + Owner::tx_lock_outputs(self, None, &in_slate, participant_id).map_err(|e| e.kind()) } fn cancel_tx(&self, tx_id: Option, tx_slate_id: Option) -> Result<(), ErrorKind> { - Owner::cancel_tx(self, tx_id, tx_slate_id).map_err(|e| e.kind()) + Owner::cancel_tx(self, None, tx_id, tx_slate_id).map_err(|e| e.kind()) } fn get_stored_tx(&self, tx: &TxLogEntry) -> Result, ErrorKind> { - Owner::get_stored_tx(self, tx).map_err(|e| e.kind()) + Owner::get_stored_tx(self, None, tx).map_err(|e| e.kind()) } fn post_tx(&self, tx: &Transaction, fluff: bool) -> Result<(), ErrorKind> { - Owner::post_tx(self, tx, fluff).map_err(|e| e.kind()) + Owner::post_tx(self, None, tx, fluff).map_err(|e| e.kind()) } fn verify_slate_messages(&self, slate: VersionedSlate) -> Result<(), ErrorKind> { let in_slate = Slate::from(slate); - Owner::verify_slate_messages(self, &in_slate).map_err(|e| e.kind()) + Owner::verify_slate_messages(self, None, &in_slate).map_err(|e| e.kind()) } fn restore(&self) -> Result<(), ErrorKind> { - Owner::restore(self).map_err(|e| e.kind()) + Owner::restore(self, None).map_err(|e| e.kind()) } fn check_repair(&self, delete_unconfirmed: bool) -> Result<(), ErrorKind> { - Owner::check_repair(self, delete_unconfirmed).map_err(|e| e.kind()) + Owner::check_repair(self, None, delete_unconfirmed).map_err(|e| e.kind()) } fn node_height(&self) -> Result { - Owner::node_height(self).map_err(|e| e.kind()) + Owner::node_height(self, None).map_err(|e| e.kind()) } } @@ -1362,6 +1364,7 @@ where pub fn run_doctest_owner( request: serde_json::Value, test_dir: &str, + use_token: bool, blocks_to_mine: u64, perform_tx: bool, lock_tx: bool, @@ -1412,10 +1415,21 @@ pub fn run_doctest_owner( lc.set_wallet_directory(&format!("{}/wallet1", test_dir)); lc.create_wallet(None, Some(rec_phrase_1), 32, empty_string.clone()) .unwrap(); - lc.open_wallet(None, empty_string.clone()).unwrap(); + let mask1 = lc + .open_wallet(None, empty_string.clone(), use_token, true) + .unwrap(); let wallet1 = Arc::new(Mutex::new(wallet1)); - wallet_proxy.add_wallet("wallet1", client1.get_send_instance(), wallet1.clone()); + if mask1.is_some() { + println!("WALLET 1 MASK: {:?}", mask1.clone().unwrap()); + } + + wallet_proxy.add_wallet( + "wallet1", + client1.get_send_instance(), + wallet1.clone(), + mask1.clone(), + ); let rec_phrase_2 = util::ZeroingString::from( "hour kingdom ripple lunch razor inquiry coyote clay stamp mean \ @@ -1436,10 +1450,21 @@ pub fn run_doctest_owner( lc.set_wallet_directory(&format!("{}/wallet2", test_dir)); lc.create_wallet(None, Some(rec_phrase_2), 32, empty_string.clone()) .unwrap(); - lc.open_wallet(None, empty_string.clone()).unwrap(); + let mask2 = lc + .open_wallet(None, empty_string.clone(), use_token, true) + .unwrap(); let wallet2 = Arc::new(Mutex::new(wallet2)); - wallet_proxy.add_wallet("wallet2", client2.get_send_instance(), wallet2.clone()); + if mask2.is_some() { + println!("WALLET 2 MASK: {:?}", mask2.clone().unwrap()); + } + + wallet_proxy.add_wallet( + "wallet2", + client2.get_send_instance(), + wallet2.clone(), + mask2.clone(), + ); // Set the wallet proxy listener running thread::spawn(move || { @@ -1450,12 +1475,18 @@ pub fn run_doctest_owner( // Mine a few blocks to wallet 1 so there's something to send for _ in 0..blocks_to_mine { - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 1 as usize, false); + let _ = test_framework::award_blocks_to_wallet( + &chain, + wallet1.clone(), + (&mask1).as_ref(), + 1 as usize, + false, + ); //update local outputs after each block, so transaction IDs stay consistent let mut w_lock = wallet1.lock(); let w = w_lock.lc_provider().unwrap().wallet_inst().unwrap(); let (wallet_refreshed, _) = - api_impl::owner::retrieve_summary_info(&mut **w, true, 1).unwrap(); + api_impl::owner::retrieve_summary_info(&mut **w, (&mask1).as_ref(), true, 1).unwrap(); assert!(wallet_refreshed); } @@ -1472,23 +1503,32 @@ pub fn run_doctest_owner( selection_strategy_is_use_all: true, ..Default::default() }; - let mut slate = api_impl::owner::init_send_tx(&mut **w, args, true).unwrap(); + let mut slate = + api_impl::owner::init_send_tx(&mut **w, (&mask1).as_ref(), args, true).unwrap(); println!("INITIAL SLATE"); println!("{}", serde_json::to_string_pretty(&slate).unwrap()); { let mut w_lock = wallet2.lock(); let w2 = w_lock.lc_provider().unwrap().wallet_inst().unwrap(); - slate = api_impl::foreign::receive_tx(&mut **w2, &slate, None, None, true).unwrap(); + slate = api_impl::foreign::receive_tx( + &mut **w2, + (&mask2).as_ref(), + &slate, + None, + None, + true, + ) + .unwrap(); w2.close().unwrap(); } // Spit out slate for input to finalize_tx if lock_tx { - api_impl::owner::tx_lock_outputs(&mut **w, &slate, 0).unwrap(); + api_impl::owner::tx_lock_outputs(&mut **w, (&mask2).as_ref(), &slate, 0).unwrap(); } println!("RECEIPIENT SLATE"); println!("{}", serde_json::to_string_pretty(&slate).unwrap()); if finalize_tx { - slate = api_impl::owner::finalize_tx(&mut **w, &slate).unwrap(); + slate = api_impl::owner::finalize_tx(&mut **w, (&mask2).as_ref(), &slate).unwrap(); error!("FINALIZED TX SLATE"); println!("{}", serde_json::to_string_pretty(&slate).unwrap()); } @@ -1496,19 +1536,30 @@ pub fn run_doctest_owner( if perform_tx && lock_tx && finalize_tx { // mine to move the chain on - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3 as usize, false); + let _ = test_framework::award_blocks_to_wallet( + &chain, + wallet1.clone(), + (&mask1).as_ref(), + 3 as usize, + false, + ); } let mut api_owner = Owner::new(wallet1); api_owner.doctest_mode = true; - let owner_api = &api_owner as &dyn OwnerRpc; - Ok(owner_api.handle_request(request).as_option()) + if use_token { + let owner_api = &api_owner as &dyn OwnerRpcS; + Ok(owner_api.handle_request(request).as_option()) + } else { + let owner_api = &api_owner as &dyn OwnerRpc; + Ok(owner_api.handle_request(request).as_option()) + } } #[doc(hidden)] #[macro_export] macro_rules! doctest_helper_json_rpc_owner_assert_response { - ($request:expr, $expected_response:expr, $blocks_to_mine:expr, $perform_tx:expr, $lock_tx:expr, $finalize_tx:expr) => { + ($request:expr, $expected_response:expr, $use_token:expr, $blocks_to_mine:expr, $perform_tx:expr, $lock_tx:expr, $finalize_tx:expr) => { // create temporary wallet, run jsonrpc request on owner api of wallet, delete wallet, return // json response. // In order to prevent leaking tempdirs, This function should not panic. @@ -1530,6 +1581,7 @@ macro_rules! doctest_helper_json_rpc_owner_assert_response { let response = run_doctest_owner( request_val, dir, + $use_token, $blocks_to_mine, $perform_tx, $lock_tx, diff --git a/api/src/owner_rpc_s.rs b/api/src/owner_rpc_s.rs new file mode 100644 index 000000000..b95ecb56a --- /dev/null +++ b/api/src/owner_rpc_s.rs @@ -0,0 +1,1474 @@ +// Copyright 2019 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. + +//! JSON-RPC Stub generation for the Owner API +use uuid::Uuid; + +use crate::core::core::Transaction; +use crate::keychain::{Identifier, Keychain}; +use crate::libwallet::{ + AcctPathMapping, ErrorKind, InitTxArgs, IssueInvoiceTxArgs, NodeClient, NodeHeightResult, + OutputCommitMapping, Slate, SlateVersion, TxLogEntry, VersionedSlate, WalletInfo, + WalletLCProvider, +}; +use crate::{Owner, Token}; +use easy_jsonrpc; + +/// Public definition used to generate Owner jsonrpc api. +/// Secure version, that should be used when running the owner API in 'Secure' Mode +#[easy_jsonrpc::rpc] +pub trait OwnerRpcS { + /** + Networked version of [Owner::accounts](struct.Owner.html#method.accounts). + + # Json rpc example + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "accounts", + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000" + }, + "id": 1 + } + # "# + # , + # r#" + { + "jsonrpc": "2.0", + "result": { + "Ok": [ + { + "label": "default", + "path": "0200000000000000000000000000000000" + } + ] + }, + "id": 1 + } + # "# + # , true, 4, false, false, false); + ``` + */ + fn accounts(&self, token: Token) -> Result, ErrorKind>; + + /** + Networked version of [Owner::create_account_path](struct.Owner.html#method.create_account_path). + + # Json rpc example + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "create_account_path", + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "label": "account1" + }, + "id": 1 + } + # "# + # , + # r#" + { + "jsonrpc": "2.0", + "result": { + "Ok": "0200000001000000000000000000000000" + }, + "id": 1 + } + # "# + # ,true, 4, false, false, false); + ``` + */ + fn create_account_path(&self, token: Token, label: &String) -> Result; + + /** + Networked version of [Owner::set_active_account](struct.Owner.html#method.set_active_account). + + # Json rpc example + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "set_active_account", + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "label": "default" + }, + "id": 1 + } + # "# + # , + # r#" + { + "jsonrpc": "2.0", + "result": { + "Ok": null + }, + "id": 1 + } + # "# + # , true, 4, false, false, false); + ``` + */ + fn set_active_account(&self, token: Token, label: &String) -> Result<(), ErrorKind>; + + /** + Networked version of [Owner::retrieve_outputs](struct.Owner.html#method.retrieve_outputs). + + # Json rpc example + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "retrieve_outputs", + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "include_spent": false, + "refresh_from_node": true, + "tx_id": null + }, + "id": 1 + } + # "# + # , + # r#" + { + "id": 1, + "jsonrpc": "2.0", + "result": { + "Ok": [ + true, + [ + { + "commit": "08e1da9e6dc4d6e808a718b2f110a991dd775d65ce5ae408a4e1f002a4961aa9e7", + "output": { + "commit": "08e1da9e6dc4d6e808a718b2f110a991dd775d65ce5ae408a4e1f002a4961aa9e7", + "height": "1", + "is_coinbase": true, + "key_id": "0300000000000000000000000000000000", + "lock_height": "4", + "mmr_index": null, + "n_child": 0, + "root_key_id": "0200000000000000000000000000000000", + "status": "Unspent", + "tx_log_entry": 0, + "value": "60000000000" + } + }, + { + "commit": "087df32304c5d4ae8b2af0bc31e700019d722910ef87dd4eec3197b80b207e3045", + "output": { + "commit": "087df32304c5d4ae8b2af0bc31e700019d722910ef87dd4eec3197b80b207e3045", + "height": "2", + "is_coinbase": true, + "key_id": "0300000000000000000000000100000000", + "lock_height": "5", + "mmr_index": null, + "n_child": 1, + "root_key_id": "0200000000000000000000000000000000", + "status": "Unspent", + "tx_log_entry": 1, + "value": "60000000000" + } + } + ] + ] + } + } + # "# + # , true, 2, false, false, false); + ``` + */ + fn retrieve_outputs( + &self, + token: Token, + include_spent: bool, + refresh_from_node: bool, + tx_id: Option, + ) -> Result<(bool, Vec), ErrorKind>; + + /** + Networked version of [Owner::retrieve_txs](struct.Owner.html#method.retrieve_txs). + + # Json rpc example + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "retrieve_txs", + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "refresh_from_node": true, + "tx_id": null, + "tx_slate_id": null + }, + "id": 1 + } + # "# + # , + # r#" + { + "id": 1, + "jsonrpc": "2.0", + "result": { + "Ok": [ + true, + [ + { + "amount_credited": "60000000000", + "amount_debited": "0", + "confirmation_ts": "2019-01-15T16:01:26Z", + "confirmed": true, + "creation_ts": "2019-01-15T16:01:26Z", + "fee": null, + "id": 0, + "messages": null, + "num_inputs": 0, + "num_outputs": 1, + "parent_key_id": "0200000000000000000000000000000000", + "stored_tx": null, + "tx_slate_id": null, + "tx_type": "ConfirmedCoinbase" + }, + { + "amount_credited": "60000000000", + "amount_debited": "0", + "confirmation_ts": "2019-01-15T16:01:26Z", + "confirmed": true, + "creation_ts": "2019-01-15T16:01:26Z", + "fee": null, + "id": 1, + "messages": null, + "num_inputs": 0, + "num_outputs": 1, + "parent_key_id": "0200000000000000000000000000000000", + "stored_tx": null, + "tx_slate_id": null, + "tx_type": "ConfirmedCoinbase" + } + ] + ] + } + } + # "# + # , true, 2, false, false, false); + ``` + */ + + fn retrieve_txs( + &self, + token: Token, + refresh_from_node: bool, + tx_id: Option, + tx_slate_id: Option, + ) -> Result<(bool, Vec), ErrorKind>; + + /** + Networked version of [Owner::retrieve_summary_info](struct.Owner.html#method.retrieve_summary_info). + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "retrieve_summary_info", + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "refresh_from_node": true, + "minimum_confirmations": 1 + }, + "id": 1 + } + # "# + # , + # r#" + { + "id": 1, + "jsonrpc": "2.0", + "result": { + "Ok": [ + true, + { + "amount_awaiting_confirmation": "0", + "amount_awaiting_finalization": "0", + "amount_currently_spendable": "60000000000", + "amount_immature": "180000000000", + "amount_locked": "0", + "last_confirmed_height": "4", + "minimum_confirmations": "1", + "total": "240000000000" + } + ] + } + } + # "# + # ,true, 4, false, false, false); + ``` + */ + + fn retrieve_summary_info( + &self, + token: Token, + refresh_from_node: bool, + minimum_confirmations: u64, + ) -> Result<(bool, WalletInfo), ErrorKind>; + + /** + Networked version of [Owner::init_send_tx](struct.Owner.html#method.init_send_tx). + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "init_send_tx", + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "args": { + "src_acct_name": null, + "amount": "6000000000", + "minimum_confirmations": 2, + "max_outputs": 500, + "num_change_outputs": 1, + "selection_strategy_is_use_all": true, + "message": "my message", + "target_slate_version": null, + "send_args": null + } + }, + "id": 1 + } + # "# + # , + # r#" + { + "id": 1, + "jsonrpc": "2.0", + "result": { + "Ok": { + "amount": "6000000000", + "fee": "8000000", + "height": "4", + "id": "0436430c-2b02-624c-2032-570501212b00", + "lock_height": "0", + "num_participants": 2, + "participant_data": [ + { + "id": "0", + "message": "my message", + "message_sig": "8f07ddd5e9f5179cff19486034181ed76505baaad53e5d994064127b56c5841b1d4c1358be398f801eb90d933774b5218fa7e769b11c4c640402253353656f75", + "part_sig": null, + "public_blind_excess": "034b4df2f0558b73ea72a1ca5c4ab20217c66bbe0829056fca7abe76888e9349ee", + "public_nonce": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f" + } + ], + "tx": { + "body": { + "inputs": [ + { + "commit": "08e1da9e6dc4d6e808a718b2f110a991dd775d65ce5ae408a4e1f002a4961aa9e7", + "features": "Coinbase" + } + ], + "kernels": [ + { + "excess": "000000000000000000000000000000000000000000000000000000000000000000", + "excess_sig": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "features": "Plain", + "fee": "8000000", + "lock_height": "0" + } + ], + "outputs": [ + { + "commit": "094be57c91787fc2033d5d97fae099f1a6ddb37ea48370f1a138f09524c767fdd3", + "features": "Plain", + "proof": "1319630b26d02363861ebdb15514086dc8b0772b4bb63ef9b828704e0ac348efada6747dd7a29848138d630c7b403e573c9cde04be5d25f2d344db4b010d6b890dd6c54cc0911c0cadc7a8a225b2ec3f2dcac88189a17aa62257e969eef9de9172009d8e864e413f1953998b28531e580d3ea495a512d320e8d4ff50e7495a6c283c6e544d16364d34272805893526f1e3b6fd176ef4adc5671b165cf28efcfb8d25c0dfcd018a2c5e65beeb9201f3983194e5a521c0844d05c700654dfaed1b9b39dae08cc9afab9cb891256bc0237ad2ce78da8b44586580f52dd346dcafde5e471917f16e4c4b51e966e1946f13e31771503c85bb0f1b41d1c7fcc953e70af55400638a35e7f5610f9f4c5b881a35060a693deaf46e1839c54a8f7d2c626b05acd3450b72ae8f2e0f8721bcbbd8562141d3fef851c6ac3c8069fa6389389bc4fcba5e4fb49709a3b63a59ba96a82827dfbd6f16de849ef95f3114593d207aff6e030152929fa220b0c3b54ca419cfcbffb7a0106dd3154e858878c7d8f38cadcc376c502bdc50292b494484936d0846fc3fac10910962bca4ddcca5c80b458fd7df15e9a6c2f39b516425a2190a97c9d0e2e2f105ee29905f36e3a648a135ebf387d0bb2a6b61d95b215319d6dc9ee8b4b2798810fb6e01c007041b288c2b39e805c9af86c88dd4a380b6a346b4a0e67bba6aaac5acc70088ac3297486b90cfe371d9464552747a2f7680f42d5629fb09bed835382d842234712c0574c5b4f256c226e77602429983e4def71541cff80ccf4cd3b761685c91463c8e1c7bf828699c688509282b85e752424df3da670b3cfacdea2f66cfb804fecdf8b7eb056e8917fdae78d83c011964e3d5a0748873f817d0abf4b04c20452733eac35c318b96e100a5ace0f54085bd24f968b8fc5b276e0d7b134f01db50b3d2771cdcf1423d44" + } + ] + }, + "offset": "d202964900000000d302964900000000d402964900000000d502964900000000" + }, + "version_info": { + "orig_version": 2, + "version": 2, + "block_header_version": 1 + } + } + } + } + # "# + # ,true, 4, false, false, false); + ``` + */ + + fn init_send_tx(&self, token: Token, args: InitTxArgs) -> Result; + + /** + Networked version of [Owner::issue_invoice_tx](struct.Owner.html#method.issue_invoice_tx). + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "issue_invoice_tx", + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "args": { + "amount": "6000000000", + "message": "Please give me your grins", + "dest_acct_name": null, + "target_slate_version": null + } + }, + "id": 1 + } + # "# + # , + # r#" + { + "id": 1, + "jsonrpc": "2.0", + "result": { + "Ok": { + "amount": "6000000000", + "fee": "0", + "height": "4", + "id": "0436430c-2b02-624c-2032-570501212b00", + "lock_height": "0", + "num_participants": 2, + "participant_data": [ + { + "id": "1", + "message": "Please give me your grins", + "message_sig": "8f07ddd5e9f5179cff19486034181ed76505baaad53e5d994064127b56c5841bd9bccdcf5d3a402bccc77d36346d3a899259a884f643e90266984289b39a59d2", + "part_sig": null, + "public_blind_excess": "028e95921cc0d5be5922362265d352c9bdabe51a9e1502a3f0d4a10387f1893f40", + "public_nonce": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f" + } + ], + "tx": { + "body": { + "inputs": [], + "kernels": [ + { + "excess": "000000000000000000000000000000000000000000000000000000000000000000", + "excess_sig": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "features": "Plain", + "fee": "0", + "lock_height": "0" + } + ], + "outputs": [ + { + "commit": "09cf47204446c326e361a1a92f34b174deff732daaedb80d7339fbe3db5ca2f6ba", + "features": "Plain", + "proof": "b368448efb3bfae95e7f18381883d64cbc9f01390e9c677d5d9f3523df43754dd174811768b7ffcafbfb284ae7413bdf56640ecb06918a5c38a5dae6cb33baff099c7cca6b052e07f915faecedee50a11ceaf41a7809bd33b51e22306ddf42620f7118133a418802f6e98222a8f3683cf3d5a5314155d0bf5f2e8be68e81ebe049ece23b0135d7b878c1ecebbf03de69fb8cbaf5f9611a430ae3083f71e0a74db8899b0083123a9e1924db8d340fdcc0bba4816afc613a0c6622fa89a84f31982cd4298a3b4c4de9d5f67800f48c6b37b4b49fb527290ec92f1551f4570abe42ac6ac42b05e3579b33533b784061ccbd2507af419079c3ea846f1af1aa2bfb04837166c60eab8207fed9000d3c2f5166e655e9220051223b90fb5751becc8a18cf10fb43cbc1cdeb8d0f11f5d0eb9dffdd4480abd69a49737f526b41b78f3c00bd7ef10f6ad3d8704f9ac6e79196c57b315a37265ca561fa333733e9c9275a2a4dc703b509b3ff11e6d983dd43a06566c82832ae0da9c8e9759038c6c86b30a05dd5cacc42c10fad496dee8cf63127233ae0bd27c766aed7448ebd7afbaa35c5491795fca7441b5373c4912e99ffbded6c7082d67f0b688f5af662be375f76699a69fcccb9c1c1841056fb4b6ec3f1c4dc40f032675fc2c87bab58e3375dac567533c4d0e3f1521e561029e231f3675368bde5817d177bd9c20b8cd7eb3b94260b0794f207bb33b9b8157518dbac8d725352b27ffa0e2aaa95d04592a87a6ee68deebaf1c51183704bea8ddd4298616fa353bc411936eafa1b31cc667a41a13a2d1a91db48464ea26c39ee1f68e67cbdd652165b040b43df2c80beda6af53dfbe0aa3aeb06c1887f9be83ed19b4b7094ba35700dad3ea4090594e662ae2a1c276b969751ab6d5d49a2c727d7ee2c80ffdc3d1ba040a20269b9bfc45930f467dbb43f64" + } + ] + }, + "offset": "d202964900000000d302964900000000d402964900000000d502964900000000" + }, + "version_info": { + "orig_version": 2, + "version": 2, + "block_header_version": 1 + } + } + } + } + # "# + # ,true, 4, false, false, false); + ``` + */ + + fn issue_invoice_tx( + &self, + token: Token, + args: IssueInvoiceTxArgs, + ) -> Result; + + /** + Networked version of [Owner::process_invoice_tx](struct.Owner.html#method.process_invoice_tx). + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "process_invoice_tx", + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "slate": { + "amount": "6000000000", + "fee": "0", + "height": "4", + "id": "0436430c-2b02-624c-2032-570501212b00", + "lock_height": "0", + "num_participants": 2, + "participant_data": [ + { + "id": "1", + "message": "Please give me your grins", + "message_sig": "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078fd2599ab38942986602e943f684a85992893a6d34367dc7cc2b403a5dcfcdbcd9", + "part_sig": null, + "public_blind_excess": "028e95921cc0d5be5922362265d352c9bdabe51a9e1502a3f0d4a10387f1893f40", + "public_nonce": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f" + } + ], + "tx": { + "body": { + "inputs": [], + "kernels": [ + { + "excess": "000000000000000000000000000000000000000000000000000000000000000000", + "excess_sig": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "features": "Plain", + "fee": "0", + "lock_height": "0" + } + ], + "outputs": [ + { + "commit": "09cf47204446c326e361a1a92f34b174deff732daaedb80d7339fbe3db5ca2f6ba", + "features": "Plain", + "proof": "8f511614315626b5f39224482351d766f5a8ef136262befc050d839be8479b0a13470cd88f4436346d213d83847a4055c6e0ac63681556470349a1aab47034a3015eb64d8163955998e2dd4165dd24386b1e279974b05deb5d46ba2bc321f7000c0784f8f10690605ffe717119d045e02b141ed12d8fc6d20930483a8af889ef533495eb442fcff36d98ebc104f13fc645c28431b3296e4a11f7c991ff97f9abbc2f8886762d7f29fdacb31d52c6850e6ccf5386117d89e8ea4ca3071c56c218dd5d3bcd65f6c06ed9f51f848507ca1d594f41796d1cf99f68a5c3f0c5dd9873602284cff31269b102fcc6c68607565faaf0adb04ed4ff3ea5d41f3b5235ac6cb90e4046c808c9c48c27172c891b20085c56a99913ef47fd8b3dc4920cef50534b9319a7cefe0df10a0206a634ac837e11da92df83ff58b1a14de81313400988aa48b946fcbe1b81f0e79e13f7c6c639b1c10983b424bda08d0ce593a20f1f47e0aa01473e7144f116b76d9ebc60599053d8f1542d60747793d99064e51fce8f8866390325d48d6e8e3bbdbc1822c864303451525c6cb4c6902f105a70134186fb32110d8192fc2528a9483fc8a4001f4bdeab1dd7b3d1ccb9ae2e746a78013ef74043f0b2436f0ca49627af1768b7c791c669bd331fd18c16ef88ad0a29861db70f2f76f3e74fde5accb91b73573e31333333223693d6fbc786e740c085e4fc6e7bde0a3f54e9703f816c54f012d3b1f41ec4d253d9337af61e7f1f1383bd929421ac346e3d2771dfee0b60503b33938e7c83eb37af3b6bf66041a3519a2b4cb557b34e3b9afcf95524f9a011425a34d32e7b6e9f255291094930acae26e8f7a1e4e6bc405d0f88e919f354f3ba85356a34f1aba5f7da1fad88e2692f4129cc1fb80a2122b2d996c6ccf7f08d8248e511d92af9ce49039de728848a2dc74101f4e94a" + } + ] + }, + "offset": "d202964900000000d302964900000000d402964900000000d502964900000000" + }, + "version_info": { + "orig_version": 2, + "version": 2, + "block_header_version": 2 + } + }, + "args": { + "src_acct_name": null, + "amount": "0", + "minimum_confirmations": 2, + "max_outputs": 500, + "num_change_outputs": 1, + "selection_strategy_is_use_all": true, + "message": "Ok, here are your grins", + "target_slate_version": null, + "send_args": null + } + }, + "id": 1 + } + # "# + # , + # r#" + { + "id": 1, + "jsonrpc": "2.0", + "result": { + "Ok": { + "amount": "6000000000", + "fee": "8000000", + "height": "4", + "id": "0436430c-2b02-624c-2032-570501212b00", + "lock_height": "0", + "num_participants": 2, + "participant_data": [ + { + "id": "1", + "message": "Please give me your grins", + "message_sig": "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078fd2599ab38942986602e943f684a85992893a6d34367dc7cc2b403a5dcfcdbcd9", + "part_sig": null, + "public_blind_excess": "028e95921cc0d5be5922362265d352c9bdabe51a9e1502a3f0d4a10387f1893f40", + "public_nonce": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f" + }, + { + "id": "0", + "message": "Ok, here are your grins", + "message_sig": "8f07ddd5e9f5179cff19486034181ed76505baaad53e5d994064127b56c5841be91ae0f6b50fabc39eefa28118cccdd8fbf5b5afe96972630450f47b72433646", + "part_sig": "8f07ddd5e9f5179cff19486034181ed76505baaad53e5d994064127b56c5841b619d40fb6a6fb60449ef9727aeb782e7a5b50fdbfd2d735b49ccc55b477cd319", + "public_blind_excess": "0309e22f2adaa9b81f51414b775b86acd096e17794eb8159bfcfef27caa4bf5c90", + "public_nonce": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f" + } + ], + "tx": { + "body": { + "inputs": [ + { + "commit": "08e1da9e6dc4d6e808a718b2f110a991dd775d65ce5ae408a4e1f002a4961aa9e7", + "features": "Coinbase" + } + ], + "kernels": [ + { + "excess": "000000000000000000000000000000000000000000000000000000000000000000", + "excess_sig": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "features": "Plain", + "fee": "8000000", + "lock_height": "0" + } + ], + "outputs": [ + { + "commit": "09cf47204446c326e361a1a92f34b174deff732daaedb80d7339fbe3db5ca2f6ba", + "features": "Plain", + "proof": "8f511614315626b5f39224482351d766f5a8ef136262befc050d839be8479b0a13470cd88f4436346d213d83847a4055c6e0ac63681556470349a1aab47034a3015eb64d8163955998e2dd4165dd24386b1e279974b05deb5d46ba2bc321f7000c0784f8f10690605ffe717119d045e02b141ed12d8fc6d20930483a8af889ef533495eb442fcff36d98ebc104f13fc645c28431b3296e4a11f7c991ff97f9abbc2f8886762d7f29fdacb31d52c6850e6ccf5386117d89e8ea4ca3071c56c218dd5d3bcd65f6c06ed9f51f848507ca1d594f41796d1cf99f68a5c3f0c5dd9873602284cff31269b102fcc6c68607565faaf0adb04ed4ff3ea5d41f3b5235ac6cb90e4046c808c9c48c27172c891b20085c56a99913ef47fd8b3dc4920cef50534b9319a7cefe0df10a0206a634ac837e11da92df83ff58b1a14de81313400988aa48b946fcbe1b81f0e79e13f7c6c639b1c10983b424bda08d0ce593a20f1f47e0aa01473e7144f116b76d9ebc60599053d8f1542d60747793d99064e51fce8f8866390325d48d6e8e3bbdbc1822c864303451525c6cb4c6902f105a70134186fb32110d8192fc2528a9483fc8a4001f4bdeab1dd7b3d1ccb9ae2e746a78013ef74043f0b2436f0ca49627af1768b7c791c669bd331fd18c16ef88ad0a29861db70f2f76f3e74fde5accb91b73573e31333333223693d6fbc786e740c085e4fc6e7bde0a3f54e9703f816c54f012d3b1f41ec4d253d9337af61e7f1f1383bd929421ac346e3d2771dfee0b60503b33938e7c83eb37af3b6bf66041a3519a2b4cb557b34e3b9afcf95524f9a011425a34d32e7b6e9f255291094930acae26e8f7a1e4e6bc405d0f88e919f354f3ba85356a34f1aba5f7da1fad88e2692f4129cc1fb80a2122b2d996c6ccf7f08d8248e511d92af9ce49039de728848a2dc74101f4e94a" + }, + { + "commit": "094be57c91787fc2033d5d97fae099f1a6ddb37ea48370f1a138f09524c767fdd3", + "features": "Plain", + "proof": "1319630b26d02363861ebdb15514086dc8b0772b4bb63ef9b828704e0ac348efada6747dd7a29848138d630c7b403e573c9cde04be5d25f2d344db4b010d6b890dd6c54cc0911c0cadc7a8a225b2ec3f2dcac88189a17aa62257e969eef9de9172009d8e864e413f1953998b28531e580d3ea495a512d320e8d4ff50e7495a6c283c6e544d16364d34272805893526f1e3b6fd176ef4adc5671b165cf28efcfb8d25c0dfcd018a2c5e65beeb9201f3983194e5a521c0844d05c700654dfaed1b9b39dae08cc9afab9cb891256bc0237ad2ce78da8b44586580f52dd346dcafde5e471917f16e4c4b51e966e1946f13e31771503c85bb0f1b41d1c7fcc953e70af55400638a35e7f5610f9f4c5b881a35060a693deaf46e1839c54a8f7d2c626b05acd3450b72ae8f2e0f8721bcbbd8562141d3fef851c6ac3c8069fa6389389bc4fcba5e4fb49709a3b63a59ba96a82827dfbd6f16de849ef95f3114593d207aff6e030152929fa220b0c3b54ca419cfcbffb7a0106dd3154e858878c7d8f38cadcc376c502bdc50292b494484936d0846fc3fac10910962bca4ddcca5c80b458fd7df15e9a6c2f39b516425a2190a97c9d0e2e2f105ee29905f36e3a648a135ebf387d0bb2a6b61d95b215319d6dc9ee8b4b2798810fb6e01c007041b288c2b39e805c9af86c88dd4a380b6a346b4a0e67bba6aaac5acc70088ac3297486b90cfe371d9464552747a2f7680f42d5629fb09bed835382d842234712c0574c5b4f256c226e77602429983e4def71541cff80ccf4cd3b761685c91463c8e1c7bf828699c688509282b85e752424df3da670b3cfacdea2f66cfb804fecdf8b7eb056e8917fdae78d83c011964e3d5a0748873f817d0abf4b04c20452733eac35c318b96e100a5ace0f54085bd24f968b8fc5b276e0d7b134f01db50b3d2771cdcf1423d44" + } + ] + }, + "offset": "d202964900000000d302964900000000d402964900000000d502964900000000" + }, + "version_info": { + "orig_version": 2, + "version": 2, + "block_header_version": 2 + } + } + } + } + # "# + # ,true, 4, false, false, false); + ``` + */ + + fn process_invoice_tx( + &self, + token: Token, + slate: VersionedSlate, + args: InitTxArgs, + ) -> Result; + + /** + Networked version of [Owner::tx_lock_outputs](struct.Owner.html#method.tx_lock_outputs). + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "tx_lock_outputs", + "id": 1, + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "slate": { + "amount": "6000000000", + "fee": "8000000", + "height": "4", + "id": "0436430c-2b02-624c-2032-570501212b00", + "lock_height": "4", + "num_participants": 2, + "participant_data": [ + { + "id": "0", + "message": "my message", + "message_sig": "8f07ddd5e9f5179cff19486034181ed76505baaad53e5d994064127b56c5841b1d4c1358be398f801eb90d933774b5218fa7e769b11c4c640402253353656f75", + "part_sig": null, + "public_blind_excess": "034b4df2f0558b73ea72a1ca5c4ab20217c66bbe0829056fca7abe76888e9349ee", + "public_nonce": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f" + } + ], + "tx": { + "body": { + "inputs": [ + { + "commit": "08e1da9e6dc4d6e808a718b2f110a991dd775d65ce5ae408a4e1f002a4961aa9e7", + "features": "Coinbase" + } + ], + "kernels": [ + { + "excess": "000000000000000000000000000000000000000000000000000000000000000000", + "excess_sig": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "features": "HeightLocked", + "fee": "8000000", + "lock_height": "4" + } + ], + "outputs": [ + { + "commit": "094be57c91787fc2033d5d97fae099f1a6ddb37ea48370f1a138f09524c767fdd3", + "features": "Plain", + "proof": "2a42e9e902b70ce44e1fccb14de87ee0a97100bddf12c6bead1b9c5f4eb60300f29c13094fa12ffeee238fb4532b18f6b61cf51b23c1c7e1ad2e41560dc27edc0a2b9e647a0b3e4e806fced5b65e61d0f1f5197d3e2285c632d359e27b6b9206b2caffea4f67e0c7a2812e7a22c134b98cf89bd43d9f28b8bec25cce037a0ac5b1ae8f667e54e1250813a5263004486b4465ad4e641ab2b535736ea26535a11013564f08f483b7dab1c2bcc3ee38eadf2f7850eff7e3459a4bbabf9f0cf6c50d0c0a4120565cd4a2ce3e354c11721cd695760a24c70e0d5a0dfc3c5dcd51dfad6de2c237a682f36dc0b271f21bb3655e5333016aaa42c2efa1446e5f3c0a79ec417c4d30f77556951cb0f05dbfafb82d9f95951a9ea241fda2a6388f73ace036b98acce079f0e4feebccc96290a86dcc89118a901210b245f2d114cf94396e4dbb461e82aa26a0581389707957968c7cdc466213bb1cd417db207ef40c05842ab67a01a9b96eb1430ebc26e795bb491258d326d5174ad549401059e41782121e506744af8af9d8e493644a87d613600888541cbbe538c625883f3eb4aa3102c5cfcc25de8e97af8927619ce6a731b3b8462d51d993066b935b0648d2344ad72e4fd70f347fbd81041042e5ea31cc7b2e3156a920b80ecba487b950ca32ca95fae85b759c936246ecf441a9fdd95e8fee932d6782cdec686064018c857efc47fb4b2a122600d5fdd79af2486f44df7e629184e1c573bc0a9b3feb40b190ef2861a1ab45e2ac2201b9cd42e495deea247269820ed32389a2810ad6c0f9a296d2a2d9c54089fed50b7f5ecfcd33ab9954360e1d7f5598c32128cfcf2a1d8bf14616818da8a5343bfa88f0eedf392e9d4ab1ace1b60324129cd4852c2e27813a9cf71a6ae6229a4fcecc1a756b3e664c5f50af333082616815a3bec8fc0b75b8e4e767d719" + } + ] + }, + "offset": "d202964900000000d302964900000000d402964900000000d502964900000000" + }, + "version_info": { + "orig_version": 2, + "version": 2, + "block_header_version": 2 + } + }, + "participant_id": 0 + } + } + # "# + # , + # r#" + { + "jsonrpc": "2.0", + "id": 1, + "result": { + "Ok": null + } + } + # "# + # ,true, 5 ,true, false, false); + + ``` + */ + fn tx_lock_outputs( + &self, + token: Token, + slate: VersionedSlate, + participant_id: usize, + ) -> Result<(), ErrorKind>; + + /** + Networked version of [Owner::finalize_tx](struct.Owner.html#method.finalize_tx). + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "finalize_tx", + "id": 1, + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "slate": { + "version_info": { + "version": 2, + "orig_version": 2, + "block_header_version": 2 + }, + "num_participants": 2, + "id": "0436430c-2b02-624c-2032-570501212b00", + "tx": { + "offset": "d202964900000000d302964900000000d402964900000000d502964900000000", + "body": { + "inputs": [ + { + "features": "Coinbase", + "commit": "087df32304c5d4ae8b2af0bc31e700019d722910ef87dd4eec3197b80b207e3045" + }, + { + "features": "Coinbase", + "commit": "08e1da9e6dc4d6e808a718b2f110a991dd775d65ce5ae408a4e1f002a4961aa9e7" + } + ], + "outputs": [ + { + "features": "Plain", + "commit": "099b48cfb1f80a2347dc89818449e68e76a3c6817a532a8e9ef2b4a5ccf4363850", + "proof": "7ebcd2ed9bf5fb29854033ba3d0e720613bdf7dfacc586d2f6084c1cde0a2b72e955d4ce625916701dc7c347132f40d0f102a34e801d745ee54b49b765d08aae0bb801c60403e57cafade3b4b174e795b633ab9e402b5b1b6e1243fd10bbcf9368a75cb6a6c375c7bdf02da9e03b7f210df45d942e6fba2729cd512a372e6ed91a1b5c9c22831febea843e3f85adcf198f39ac9f7b73b70c60bfb474aa69878ea8d1d32fef30166b59caacaec3fd024de29a90f1587e08d2c36b3d5c560cabf658e212e0a40a4129b3e5c35557058def5551f4eb395759597ba808b3c34eac3bfb9716e4480d7931c5789c538463ec75be0eb807c894047fda6cbcd22682d3c6d3823cb330f090a2099e3510a3706b57d46c95224394d7f1c0a20d99cc314b8f1d9d02668e2e435f62e1194de0be6a1f50f72ed777ed51c8819f527a94918d1aa8df6461e98ed4c2b18210de50fbcf8c3df210bfe326d41f1dc0ad748cb0320ae28401c85ab4f7dcb99d88a052e95dc85b76d22b36cabd60e06ab84bb7e4ddfdab9c9730c8a986583237ed1ecbb323ee8e79b8cadca4b438b7c09531670b471dda6a2eb3e747916c88ce7d9d8e1b7f61660eeb9e5a13c60e4dfe89d1177d81d6f6570fda85158e646a15f1e8b9e977494dc19a339aab2e0e478670d80092d6ba37646e60714ef64eb4a3d37fe15f8f38b59114af34b235489eed3f69b7781c5fe496eb43ffe245c14bd740f745844a38cf0d904347aaa2b64f51add18822dac009d8b63fa3e4c9b1fa72187f9a4acba1ab315daa1b04c9a41f3be846ac420b37990e6c947a16cc9d5c0671b292bf77d7d8b8974d2ad3afae95ba7772c37432840f53a007f31e0195f3abdf100c4477723cc6c6d5da14894a73dfac342833731036487488fdade7b9d556c06f26173b6b67598d3769447ce2828d71dd45ac5af436c6b0" + }, + { + "features": "Plain", + "commit": "0812276cc788e6870612296d926cba9f0e7b9810670710b5a6e6f1ba006d395774", + "proof": "dcff6175390c602bfa92c2ffd1a9b2d84dcc9ea941f6f317bdd0f875244ef23e696fd17c71df79760ce5ce1a96aab1d15dd057358dc835e972febeb86d50ccec0dad7cfe0246d742eb753cf7b88c045d15bc7123f8cf7155647ccf663fca92a83c9a65d0ed756ea7ebffd2cac90c380a102ed9caaa355d175ed0bf58d3ac2f5e909d6c447dfc6b605e04925c2b17c33ebd1908c965a5541ea5d2ed45a0958e6402f89d7a56df1992e036d836e74017e73ccad5cb3a82b8e139e309792a31b15f3ffd72ed033253428c156c2b9799458a25c1da65b719780a22de7fe7f437ae2fccd22cf7ea357ab5aa66a5ef7d71fb0dc64aa0b5761f68278062bb39bb296c787e4cabc5e2a2933a416ce1c9a9696160386449c437e9120f7bb26e5b0e74d1f2e7d5bcd7aafb2a92b87d1548f1f911fb06af7bd6cc13cee29f7c9cb79021aed18186272af0e9d189ec107c81a8a3aeb4782b0d950e4881aa51b776bb6844b25bce97035b48a9bdb2aea3608687bcdd479d4fa998b5a839ff88558e4a29dff0ed13b55900abb5d439b70793d902ae9ad34587b18c919f6b875c91d14deeb1c373f5e76570d59a6549758f655f1128a54f162dfe8868e1587028e26ad91e528c5ae7ee9335fa58fb59022b5de29d80f0764a9917390d46db899acc6a5b416e25ecc9dccb7153646addcc81cadb5f0078febc7e05d7735aba494f39ef05697bbcc9b47b2ccc79595d75fc13c80678b5e237edce58d731f34c05b1ddcaa649acf2d865bbbc3ceda10508bcdd29d0496744644bf1c3516f6687dfeef5649c7dff90627d642739a59d91a8d1d0c4dc55d74a949e1074427664b467992c9e0f7d3af9d6ea79513e8946ddc0d356bac49878e64e6a95b0a30214214faf2ce317fa622ff3266b32a816e10a18e6d789a5da1f23e67b4f970a68a7bcd9e18825ee274b0483896a40" + } + ], + "kernels": [ + { + "features": "Plain", + "fee": "7000000", + "lock_height": "0", + "excess": "000000000000000000000000000000000000000000000000000000000000000000", + "excess_sig": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + ] + } + }, + "amount": "60000000000", + "fee": "7000000", + "height": "5", + "lock_height": "0", + "participant_data": [ + { + "id": "0", + "public_blind_excess": "033ac2158fa0077f087de60c19d8e431753baa5b63b6e1477f05a2a6e7190d4592", + "public_nonce": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f", + "part_sig": null, + "message": null, + "message_sig": null + }, + { + "id": "1", + "public_blind_excess": "024f9bc78c984c78d6e916d3a00746aa30fa1172124c8dbc0cbddcb7b486719bc7", + "public_nonce": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f", + "part_sig": "8f07ddd5e9f5179cff19486034181ed76505baaad53e5d994064127b56c5841ba9c6dd6185c2b819799700fa1a69201f96cc6dfb9ca205a0ef7c35fb81d57dac", + "message": null, + "message_sig": null + } + ] + } + } + } + # "# + # , + # r#" + { + "jsonrpc": "2.0", + "id": 1, + "result": { + "Ok": { + "amount": "60000000000", + "fee": "7000000", + "height": "5", + "id": "0436430c-2b02-624c-2032-570501212b00", + "lock_height": "0", + "num_participants": 2, + "participant_data": [ + { + "id": "0", + "message": null, + "message_sig": null, + "part_sig": "8f07ddd5e9f5179cff19486034181ed76505baaad53e5d994064127b56c5841b38641aefa907a2fc1c051b1f73202794fffb6d422e328516a5c6b2ef41e935f8", + "public_blind_excess": "033ac2158fa0077f087de60c19d8e431753baa5b63b6e1477f05a2a6e7190d4592", + "public_nonce": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f" + }, + { + "id": "1", + "message": null, + "message_sig": null, + "part_sig": "8f07ddd5e9f5179cff19486034181ed76505baaad53e5d994064127b56c5841ba9c6dd6185c2b819799700fa1a69201f96cc6dfb9ca205a0ef7c35fb81d57dac", + "public_blind_excess": "024f9bc78c984c78d6e916d3a00746aa30fa1172124c8dbc0cbddcb7b486719bc7", + "public_nonce": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f" + } + ], + "tx": { + "body": { + "inputs": [ + { + "commit": "087df32304c5d4ae8b2af0bc31e700019d722910ef87dd4eec3197b80b207e3045", + "features": "Coinbase" + }, + { + "commit": "08e1da9e6dc4d6e808a718b2f110a991dd775d65ce5ae408a4e1f002a4961aa9e7", + "features": "Coinbase" + } + ], + "kernels": [ + { + "excess": "09bac6083b05a32a9d9b37710c70dd0a1ef9329fde0848558976b6f1b81d80ceed", + "excess_sig": "66074d25a751c4743342c90ad8ead9454daa00d9b9aed29bca321036d16c4b4da0e9c180a26b88565afcd269a7ac98f896c8db3dcbd48ab69443e8eac3beb3a4", + "features": "Plain", + "fee": "7000000", + "lock_height": "0" + } + ], + "outputs": [ + { + "commit": "099b48cfb1f80a2347dc89818449e68e76a3c6817a532a8e9ef2b4a5ccf4363850", + "features": "Plain", + "proof": "7ebcd2ed9bf5fb29854033ba3d0e720613bdf7dfacc586d2f6084c1cde0a2b72e955d4ce625916701dc7c347132f40d0f102a34e801d745ee54b49b765d08aae0bb801c60403e57cafade3b4b174e795b633ab9e402b5b1b6e1243fd10bbcf9368a75cb6a6c375c7bdf02da9e03b7f210df45d942e6fba2729cd512a372e6ed91a1b5c9c22831febea843e3f85adcf198f39ac9f7b73b70c60bfb474aa69878ea8d1d32fef30166b59caacaec3fd024de29a90f1587e08d2c36b3d5c560cabf658e212e0a40a4129b3e5c35557058def5551f4eb395759597ba808b3c34eac3bfb9716e4480d7931c5789c538463ec75be0eb807c894047fda6cbcd22682d3c6d3823cb330f090a2099e3510a3706b57d46c95224394d7f1c0a20d99cc314b8f1d9d02668e2e435f62e1194de0be6a1f50f72ed777ed51c8819f527a94918d1aa8df6461e98ed4c2b18210de50fbcf8c3df210bfe326d41f1dc0ad748cb0320ae28401c85ab4f7dcb99d88a052e95dc85b76d22b36cabd60e06ab84bb7e4ddfdab9c9730c8a986583237ed1ecbb323ee8e79b8cadca4b438b7c09531670b471dda6a2eb3e747916c88ce7d9d8e1b7f61660eeb9e5a13c60e4dfe89d1177d81d6f6570fda85158e646a15f1e8b9e977494dc19a339aab2e0e478670d80092d6ba37646e60714ef64eb4a3d37fe15f8f38b59114af34b235489eed3f69b7781c5fe496eb43ffe245c14bd740f745844a38cf0d904347aaa2b64f51add18822dac009d8b63fa3e4c9b1fa72187f9a4acba1ab315daa1b04c9a41f3be846ac420b37990e6c947a16cc9d5c0671b292bf77d7d8b8974d2ad3afae95ba7772c37432840f53a007f31e0195f3abdf100c4477723cc6c6d5da14894a73dfac342833731036487488fdade7b9d556c06f26173b6b67598d3769447ce2828d71dd45ac5af436c6b0" + }, + { + "commit": "0812276cc788e6870612296d926cba9f0e7b9810670710b5a6e6f1ba006d395774", + "features": "Plain", + "proof": "dcff6175390c602bfa92c2ffd1a9b2d84dcc9ea941f6f317bdd0f875244ef23e696fd17c71df79760ce5ce1a96aab1d15dd057358dc835e972febeb86d50ccec0dad7cfe0246d742eb753cf7b88c045d15bc7123f8cf7155647ccf663fca92a83c9a65d0ed756ea7ebffd2cac90c380a102ed9caaa355d175ed0bf58d3ac2f5e909d6c447dfc6b605e04925c2b17c33ebd1908c965a5541ea5d2ed45a0958e6402f89d7a56df1992e036d836e74017e73ccad5cb3a82b8e139e309792a31b15f3ffd72ed033253428c156c2b9799458a25c1da65b719780a22de7fe7f437ae2fccd22cf7ea357ab5aa66a5ef7d71fb0dc64aa0b5761f68278062bb39bb296c787e4cabc5e2a2933a416ce1c9a9696160386449c437e9120f7bb26e5b0e74d1f2e7d5bcd7aafb2a92b87d1548f1f911fb06af7bd6cc13cee29f7c9cb79021aed18186272af0e9d189ec107c81a8a3aeb4782b0d950e4881aa51b776bb6844b25bce97035b48a9bdb2aea3608687bcdd479d4fa998b5a839ff88558e4a29dff0ed13b55900abb5d439b70793d902ae9ad34587b18c919f6b875c91d14deeb1c373f5e76570d59a6549758f655f1128a54f162dfe8868e1587028e26ad91e528c5ae7ee9335fa58fb59022b5de29d80f0764a9917390d46db899acc6a5b416e25ecc9dccb7153646addcc81cadb5f0078febc7e05d7735aba494f39ef05697bbcc9b47b2ccc79595d75fc13c80678b5e237edce58d731f34c05b1ddcaa649acf2d865bbbc3ceda10508bcdd29d0496744644bf1c3516f6687dfeef5649c7dff90627d642739a59d91a8d1d0c4dc55d74a949e1074427664b467992c9e0f7d3af9d6ea79513e8946ddc0d356bac49878e64e6a95b0a30214214faf2ce317fa622ff3266b32a816e10a18e6d789a5da1f23e67b4f970a68a7bcd9e18825ee274b0483896a40" + } + ] + }, + "offset": "d202964900000000d302964900000000d402964900000000d502964900000000" + }, + "version_info": { + "orig_version": 2, + "version": 2, + "block_header_version": 2 + } + } + } + } + # "# + # , true, 5, true, true, false); + ``` + */ + fn finalize_tx(&self, token: Token, slate: VersionedSlate) + -> Result; + + /** + Networked version of [Owner::post_tx](struct.Owner.html#method.post_tx). + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "id": 1, + "method": "post_tx", + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "tx": { + "offset": "d202964900000000d302964900000000d402964900000000d502964900000000", + "body": { + "inputs": [ + { + "features": "Coinbase", + "commit": "087df32304c5d4ae8b2af0bc31e700019d722910ef87dd4eec3197b80b207e3045" + }, + { + "features": "Coinbase", + "commit": "08e1da9e6dc4d6e808a718b2f110a991dd775d65ce5ae408a4e1f002a4961aa9e7" + } + ], + "outputs": [ + { + "features": "Plain", + "commit": "099b48cfb1f80a2347dc89818449e68e76a3c6817a532a8e9ef2b4a5ccf4363850", + "proof": "7ebcd2ed9bf5fb29854033ba3d0e720613bdf7dfacc586d2f6084c1cde0a2b72e955d4ce625916701dc7c347132f40d0f102a34e801d745ee54b49b765d08aae0bb801c60403e57cafade3b4b174e795b633ab9e402b5b1b6e1243fd10bbcf9368a75cb6a6c375c7bdf02da9e03b7f210df45d942e6fba2729cd512a372e6ed91a1b5c9c22831febea843e3f85adcf198f39ac9f7b73b70c60bfb474aa69878ea8d1d32fef30166b59caacaec3fd024de29a90f1587e08d2c36b3d5c560cabf658e212e0a40a4129b3e5c35557058def5551f4eb395759597ba808b3c34eac3bfb9716e4480d7931c5789c538463ec75be0eb807c894047fda6cbcd22682d3c6d3823cb330f090a2099e3510a3706b57d46c95224394d7f1c0a20d99cc314b8f1d9d02668e2e435f62e1194de0be6a1f50f72ed777ed51c8819f527a94918d1aa8df6461e98ed4c2b18210de50fbcf8c3df210bfe326d41f1dc0ad748cb0320ae28401c85ab4f7dcb99d88a052e95dc85b76d22b36cabd60e06ab84bb7e4ddfdab9c9730c8a986583237ed1ecbb323ee8e79b8cadca4b438b7c09531670b471dda6a2eb3e747916c88ce7d9d8e1b7f61660eeb9e5a13c60e4dfe89d1177d81d6f6570fda85158e646a15f1e8b9e977494dc19a339aab2e0e478670d80092d6ba37646e60714ef64eb4a3d37fe15f8f38b59114af34b235489eed3f69b7781c5fe496eb43ffe245c14bd740f745844a38cf0d904347aaa2b64f51add18822dac009d8b63fa3e4c9b1fa72187f9a4acba1ab315daa1b04c9a41f3be846ac420b37990e6c947a16cc9d5c0671b292bf77d7d8b8974d2ad3afae95ba7772c37432840f53a007f31e0195f3abdf100c4477723cc6c6d5da14894a73dfac342833731036487488fdade7b9d556c06f26173b6b67598d3769447ce2828d71dd45ac5af436c6b0" + }, + { + "features": "Plain", + "commit": "0812276cc788e6870612296d926cba9f0e7b9810670710b5a6e6f1ba006d395774", + "proof": "dcff6175390c602bfa92c2ffd1a9b2d84dcc9ea941f6f317bdd0f875244ef23e696fd17c71df79760ce5ce1a96aab1d15dd057358dc835e972febeb86d50ccec0dad7cfe0246d742eb753cf7b88c045d15bc7123f8cf7155647ccf663fca92a83c9a65d0ed756ea7ebffd2cac90c380a102ed9caaa355d175ed0bf58d3ac2f5e909d6c447dfc6b605e04925c2b17c33ebd1908c965a5541ea5d2ed45a0958e6402f89d7a56df1992e036d836e74017e73ccad5cb3a82b8e139e309792a31b15f3ffd72ed033253428c156c2b9799458a25c1da65b719780a22de7fe7f437ae2fccd22cf7ea357ab5aa66a5ef7d71fb0dc64aa0b5761f68278062bb39bb296c787e4cabc5e2a2933a416ce1c9a9696160386449c437e9120f7bb26e5b0e74d1f2e7d5bcd7aafb2a92b87d1548f1f911fb06af7bd6cc13cee29f7c9cb79021aed18186272af0e9d189ec107c81a8a3aeb4782b0d950e4881aa51b776bb6844b25bce97035b48a9bdb2aea3608687bcdd479d4fa998b5a839ff88558e4a29dff0ed13b55900abb5d439b70793d902ae9ad34587b18c919f6b875c91d14deeb1c373f5e76570d59a6549758f655f1128a54f162dfe8868e1587028e26ad91e528c5ae7ee9335fa58fb59022b5de29d80f0764a9917390d46db899acc6a5b416e25ecc9dccb7153646addcc81cadb5f0078febc7e05d7735aba494f39ef05697bbcc9b47b2ccc79595d75fc13c80678b5e237edce58d731f34c05b1ddcaa649acf2d865bbbc3ceda10508bcdd29d0496744644bf1c3516f6687dfeef5649c7dff90627d642739a59d91a8d1d0c4dc55d74a949e1074427664b467992c9e0f7d3af9d6ea79513e8946ddc0d356bac49878e64e6a95b0a30214214faf2ce317fa622ff3266b32a816e10a18e6d789a5da1f23e67b4f970a68a7bcd9e18825ee274b0483896a40" + } + ], + "kernels": [ + { + "features": "Plain", + "fee": "7000000", + "lock_height": "0", + "excess": "09bac6083b05a32a9d9b37710c70dd0a1ef9329fde0848558976b6f1b81d80ceed", + "excess_sig": "66074d25a751c4743342c90ad8ead9454daa00d9b9aed29bca321036d16c4b4da0e9c180a26b88565afcd269a7ac98f896c8db3dcbd48ab69443e8eac3beb3a4" + } + ] + } + }, + "fluff": false + } + } + # "# + # , + # r#" + { + "id": 1, + "jsonrpc": "2.0", + "result": { + "Ok": null + } + } + # "# + # , true, 5, true, true, true); + ``` + */ + + fn post_tx(&self, token: Token, tx: &Transaction, fluff: bool) -> Result<(), ErrorKind>; + + /** + Networked version of [Owner::cancel_tx](struct.Owner.html#method.cancel_tx). + + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "cancel_tx", + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "tx_id": null, + "tx_slate_id": "0436430c-2b02-624c-2032-570501212b00" + }, + "id": 1 + } + # "# + # , + # r#" + { + "id": 1, + "jsonrpc": "2.0", + "result": { + "Ok": null + } + } + # "# + # , true, 5, true, true, false); + ``` + */ + fn cancel_tx( + &self, + token: Token, + tx_id: Option, + tx_slate_id: Option, + ) -> Result<(), ErrorKind>; + + /** + Networked version of [Owner::get_stored_tx](struct.Owner.html#method.get_stored_tx). + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "get_stored_tx", + "id": 1, + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "tx": { + "amount_credited": "59993000000", + "amount_debited": "120000000000", + "confirmation_ts": "2019-01-15T16:01:26Z", + "confirmed": false, + "creation_ts": "2019-01-15T16:01:26Z", + "fee": "7000000", + "id": 5, + "messages": { + "messages": [ + { + "id": "0", + "message": null, + "message_sig": null, + "public_key": "033ac2158fa0077f087de60c19d8e431753baa5b63b6e1477f05a2a6e7190d4592" + }, + { + "id": "1", + "message": null, + "message_sig": null, + "public_key": "024f9bc78c984c78d6e916d3a00746aa30fa1172124c8dbc0cbddcb7b486719bc7" + } + ] + }, + "num_inputs": 2, + "num_outputs": 1, + "parent_key_id": "0200000000000000000000000000000000", + "stored_tx": "0436430c-2b02-624c-2032-570501212b00.grintx", + "tx_slate_id": "0436430c-2b02-624c-2032-570501212b00", + "tx_type": "TxSent" + } + } + } + # "# + # , + # r#" + { + "jsonrpc": "2.0", + "id": 1, + "result": { + "Ok": { + "body": { + "inputs": [ + { + "commit": "087df32304c5d4ae8b2af0bc31e700019d722910ef87dd4eec3197b80b207e3045", + "features": "Coinbase" + }, + { + "commit": "08e1da9e6dc4d6e808a718b2f110a991dd775d65ce5ae408a4e1f002a4961aa9e7", + "features": "Coinbase" + } + ], + "kernels": [ + { + "excess": "000000000000000000000000000000000000000000000000000000000000000000", + "excess_sig": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "features": "Plain", + "fee": "7000000", + "lock_height": "0" + } + ], + "outputs": [ + { + "commit": "099b48cfb1f80a2347dc89818449e68e76a3c6817a532a8e9ef2b4a5ccf4363850", + "features": "Plain", + "proof": "29701ceae262cac77b79b868c883a292e61e6de8192b868edcd1300b0973d91396b156ace6bd673402a303de10ddd8a5e6b7f17ba6557a574a672bd04cc273ab04ed8e2ca80bac483345c0ec843f521814ce1301ec9adc38956a12b4d948acce71295a4f52bcdeb8a1c9f2d6b2da5d731262a5e9c0276ef904df9ef8d48001420cd59f75a2f1ae5c7a1c7c6b9f140e7613e52ef9e249f29f9340b7efb80699e460164324616f98fd4cde3db52497c919e95222fffeacb7e65deca7e368a80ce713c19de7da5369726228ee336f5bd494538c12ccbffeb1b9bfd5fc8906d1c64245b516f103fa96d9c56975837652c1e0fa5803d7ccf1147d8f927e36da717f7ad79471dbe192f5f50f87a79fc3fe030dba569b634b92d2cf307993cce545633af263897cd7e6ebf4dcafb176d07358bdc38d03e45a49dfa9c8c6517cd68d167ffbf6c3b4de0e2dd21909cbad4c467b84e5700be473a39ac59c669d7c155c4bcab9b8026eea3431c779cd277e4922d2b9742e1f6678cbe869ec3b5b7ef4132ddb6cdd06cf27dbeb28be72b949fa897610e48e3a0d789fd2eea75abc97b3dc7e00e5c8b3d24e40c6f24112adb72352b89a2bef0599345338e9e76202a3c46efa6370952b2aca41aadbae0ea32531acafcdab6dd066d769ebf50cf4f3c0a59d2d5fa79600a207b9417c623f76ad05e8cccfcd4038f9448bc40f127ca7c0d372e46074e334fe49f5a956ec0056f4da601e6af80eb1a6c4951054869e665b296d8c14f344ca2dc5fdd5df4a3652536365a1615ad9b422165c77bf8fe65a835c8e0c41e070014eb66ef8c525204e990b3a3d663c1e42221b496895c37a2f0c1bf05e91235409c3fe3d89a9a79d6c78609ab18a463311911f71fa37bb73b15fcd38143d1404fd2ce81004dc7ff89cf1115dcc0c35ce1c1bf9941586fb959770f2618ccb7118a7" + }, + { + "commit": "0812276cc788e6870612296d926cba9f0e7b9810670710b5a6e6f1ba006d395774", + "features": "Plain", + "proof": "284b9f9199411c6bbf7227eae15cc9fa7ed30534af3ecff85b0d016da329cae1f1edf79f01426434cb90afcc2f0a1fb296e5c51a91b5e57a1f0230fda4f8c5950e7986fa379b99d64b6039a86cc7e35e040ba192b781043959851268ca9874a918805ea958c84f7fee8d3ab4262f032f5a3f840ebcdd273b29be810114e6e86a959d8e4c080572e3ef249edd6ad68503ec3bc4486548520ea2775a41aea67aac99945fce9e7a7769d71f893ad7f0d0108692f6b6852312cae6f9857063055bda59dce521927c70040b8026a41b6517cae0a1c947ca244984a5c0adf7c6483b0939346c48f61cac37d501f46a1c5878b67cee0d0723f4eeadc9f5d71ed5e9f33b4294b58d3ebeefeaa13f20357599be549ce18e6e2eb1d50e1235ccc40ec9184c68a623741a7238ce69aa3a1d25156b3b7eb38fdd6fbe5473979feee3317df279c60d48a289826aa4c76dbce24d526890d4e6e2f83e80f674a1248fc1dc037d982009012ae1133f5e158ae6cdadb18c8d53e4a8ae5595c758782c67aa0c20f146d52085cf45a35794cec45702830f8952a69744718fbe6fe0d3da66e348dd3473a0aced7080fbf5494c3e7e141916f3b135b33277f998fcd9acfbca8709814866e9838a5dcda4c29422cf157293e6fc2ccc2d25423517843bd8e21c61ced72312c0b48814c312021b0d31598d2389b0b329baa1169922a4c34173dd5f540545be5066a0f291f1a870e1aaff94c19f0a855254882a17984baeda08e8ead53d1563e9ee4bc36742789cef4f3ab158054d7ddfe2a2b37b5a8a30be84ff7df9a7d758a9b76751a3622057721a3ec5b873582d0c91cd1febbc153662739854ea15c9903023c193c6b5768b55484108f897cdc47d13a9088b32558e57f12f5807668649c99a17b51905127340e8b49c42775f1b3cab072dfad33d33cc1e4ba5964d728ed0a905" + } + ] + }, + "offset": "d202964900000000d302964900000000d402964900000000d502964900000000" + } + } + } + # "# + # , true, 5, true, true, false); + ``` + */ + fn get_stored_tx( + &self, + token: Token, + tx: &TxLogEntry, + ) -> Result, ErrorKind>; + + /** + Networked version of [Owner::verify_slate_messages](struct.Owner.html#method.verify_slate_messages). + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "verify_slate_messages", + "id": 1, + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "slate": { + "amount": "6000000000", + "fee": "8000000", + "height": "4", + "id": "0436430c-2b02-624c-2032-570501212b00", + "lock_height": "4", + "num_participants": 2, + "participant_data": [ + { + "id": "0", + "message": "my message", + "message_sig": "8f07ddd5e9f5179cff19486034181ed76505baaad53e5d994064127b56c5841b1d4c1358be398f801eb90d933774b5218fa7e769b11c4c640402253353656f75", + "part_sig": null, + "public_blind_excess": "034b4df2f0558b73ea72a1ca5c4ab20217c66bbe0829056fca7abe76888e9349ee", + "public_nonce": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f" + } + ], + "tx": { + "body": { + "inputs": [ + { + "commit": "08e1da9e6dc4d6e808a718b2f110a991dd775d65ce5ae408a4e1f002a4961aa9e7", + "features": "Coinbase" + } + ], + "kernels": [ + { + "excess": "000000000000000000000000000000000000000000000000000000000000000000", + "excess_sig": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "features": "HeightLocked", + "fee": "8000000", + "lock_height": "4" + } + ], + "outputs": [ + { + "commit": "094be57c91787fc2033d5d97fae099f1a6ddb37ea48370f1a138f09524c767fdd3", + "features": "Plain", + "proof": "2a42e9e902b70ce44e1fccb14de87ee0a97100bddf12c6bead1b9c5f4eb60300f29c13094fa12ffeee238fb4532b18f6b61cf51b23c1c7e1ad2e41560dc27edc0a2b9e647a0b3e4e806fced5b65e61d0f1f5197d3e2285c632d359e27b6b9206b2caffea4f67e0c7a2812e7a22c134b98cf89bd43d9f28b8bec25cce037a0ac5b1ae8f667e54e1250813a5263004486b4465ad4e641ab2b535736ea26535a11013564f08f483b7dab1c2bcc3ee38eadf2f7850eff7e3459a4bbabf9f0cf6c50d0c0a4120565cd4a2ce3e354c11721cd695760a24c70e0d5a0dfc3c5dcd51dfad6de2c237a682f36dc0b271f21bb3655e5333016aaa42c2efa1446e5f3c0a79ec417c4d30f77556951cb0f05dbfafb82d9f95951a9ea241fda2a6388f73ace036b98acce079f0e4feebccc96290a86dcc89118a901210b245f2d114cf94396e4dbb461e82aa26a0581389707957968c7cdc466213bb1cd417db207ef40c05842ab67a01a9b96eb1430ebc26e795bb491258d326d5174ad549401059e41782121e506744af8af9d8e493644a87d613600888541cbbe538c625883f3eb4aa3102c5cfcc25de8e97af8927619ce6a731b3b8462d51d993066b935b0648d2344ad72e4fd70f347fbd81041042e5ea31cc7b2e3156a920b80ecba487b950ca32ca95fae85b759c936246ecf441a9fdd95e8fee932d6782cdec686064018c857efc47fb4b2a122600d5fdd79af2486f44df7e629184e1c573bc0a9b3feb40b190ef2861a1ab45e2ac2201b9cd42e495deea247269820ed32389a2810ad6c0f9a296d2a2d9c54089fed50b7f5ecfcd33ab9954360e1d7f5598c32128cfcf2a1d8bf14616818da8a5343bfa88f0eedf392e9d4ab1ace1b60324129cd4852c2e27813a9cf71a6ae6229a4fcecc1a756b3e664c5f50af333082616815a3bec8fc0b75b8e4e767d719" + } + ] + }, + "offset": "d202964900000000d302964900000000d402964900000000d502964900000000" + }, + "version_info": { + "orig_version": 2, + "version": 2, + "block_header_version": 2 + } + } + } + } + # "# + # , + # r#" + { + "jsonrpc": "2.0", + "id": 1, + "result": { + "Ok": null + } + } + # "# + # ,true, 5 ,true, false, false); + ``` + */ + fn verify_slate_messages(&self, token: Token, slate: VersionedSlate) -> Result<(), ErrorKind>; + + /** + Networked version of [Owner::restore](struct.Owner.html#method.restore). + + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "restore", + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000" + }, + "id": 1 + } + # "# + # , + # r#" + { + "id": 1, + "jsonrpc": "2.0", + "result": { + "Ok": null + } + } + # "# + # , true, 1, false, false, false); + ``` + */ + fn restore(&self, token: Token) -> Result<(), ErrorKind>; + + /** + Networked version of [Owner::check_repair](struct.Owner.html#method.check_repair). + + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "check_repair", + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "delete_unconfirmed": false + }, + "id": 1 + } + # "# + # , + # r#" + { + "id": 1, + "jsonrpc": "2.0", + "result": { + "Ok": null + } + } + # "# + # , true, 1, false, false, false); + ``` + */ + fn check_repair(&self, token: Token, delete_unconfirmed: bool) -> Result<(), ErrorKind>; + + /** + Networked version of [Owner::node_height](struct.Owner.html#method.node_height). + + + ``` + # grin_wallet_api::doctest_helper_json_rpc_owner_assert_response!( + # r#" + { + "jsonrpc": "2.0", + "method": "node_height", + "params": { + "token": "d202964900000000d302964900000000d402964900000000d502964900000000" + }, + "id": 1 + } + # "# + # , + # r#" + { + "id": 1, + "jsonrpc": "2.0", + "result": { + "Ok": { + "height": "5", + "updated_from_node": true + } + } + } + # "# + # , true, 5, false, false, false); + ``` + */ + fn node_height(&self, token: Token) -> Result; +} + +impl<'a, L, C, K> OwnerRpcS for Owner<'a, L, C, K> +where + L: WalletLCProvider<'a, C, K>, + C: NodeClient + 'a, + K: Keychain + 'a, +{ + fn accounts(&self, token: Token) -> Result, ErrorKind> { + Owner::accounts(self, (&token.keychain_mask).as_ref()).map_err(|e| e.kind()) + } + + fn create_account_path(&self, token: Token, label: &String) -> Result { + Owner::create_account_path(self, (&token.keychain_mask).as_ref(), label) + .map_err(|e| e.kind()) + } + + fn set_active_account(&self, token: Token, label: &String) -> Result<(), ErrorKind> { + Owner::set_active_account(self, (&token.keychain_mask).as_ref(), label) + .map_err(|e| e.kind()) + } + + fn retrieve_outputs( + &self, + token: Token, + include_spent: bool, + refresh_from_node: bool, + tx_id: Option, + ) -> Result<(bool, Vec), ErrorKind> { + Owner::retrieve_outputs( + self, + (&token.keychain_mask).as_ref(), + include_spent, + refresh_from_node, + tx_id, + ) + .map_err(|e| e.kind()) + } + + fn retrieve_txs( + &self, + token: Token, + refresh_from_node: bool, + tx_id: Option, + tx_slate_id: Option, + ) -> Result<(bool, Vec), ErrorKind> { + Owner::retrieve_txs( + self, + (&token.keychain_mask).as_ref(), + refresh_from_node, + tx_id, + tx_slate_id, + ) + .map_err(|e| e.kind()) + } + + fn retrieve_summary_info( + &self, + token: Token, + refresh_from_node: bool, + minimum_confirmations: u64, + ) -> Result<(bool, WalletInfo), ErrorKind> { + Owner::retrieve_summary_info( + self, + (&token.keychain_mask).as_ref(), + refresh_from_node, + minimum_confirmations, + ) + .map_err(|e| e.kind()) + } + + fn init_send_tx(&self, token: Token, args: InitTxArgs) -> Result { + let slate = Owner::init_send_tx(self, (&token.keychain_mask).as_ref(), args) + .map_err(|e| e.kind())?; + let version = SlateVersion::V2; + Ok(VersionedSlate::into_version(slate, version)) + } + + fn issue_invoice_tx( + &self, + token: Token, + args: IssueInvoiceTxArgs, + ) -> Result { + let slate = Owner::issue_invoice_tx(self, (&token.keychain_mask).as_ref(), args) + .map_err(|e| e.kind())?; + let version = SlateVersion::V2; + Ok(VersionedSlate::into_version(slate, version)) + } + + fn process_invoice_tx( + &self, + token: Token, + slate: VersionedSlate, + args: InitTxArgs, + ) -> Result { + let in_slate = Slate::from(slate); + let out_slate = + Owner::process_invoice_tx(self, (&token.keychain_mask).as_ref(), &in_slate, args) + .map_err(|e| e.kind())?; + let version = SlateVersion::V2; + Ok(VersionedSlate::into_version(out_slate, version)) + } + + fn finalize_tx( + &self, + token: Token, + slate: VersionedSlate, + ) -> Result { + let in_slate = Slate::from(slate); + let out_slate = Owner::finalize_tx(self, (&token.keychain_mask).as_ref(), &in_slate) + .map_err(|e| e.kind())?; + let version = SlateVersion::V2; + Ok(VersionedSlate::into_version(out_slate, version)) + } + + fn tx_lock_outputs( + &self, + token: Token, + slate: VersionedSlate, + participant_id: usize, + ) -> Result<(), ErrorKind> { + let in_slate = Slate::from(slate); + Owner::tx_lock_outputs( + self, + (&token.keychain_mask).as_ref(), + &in_slate, + participant_id, + ) + .map_err(|e| e.kind()) + } + + fn cancel_tx( + &self, + token: Token, + tx_id: Option, + tx_slate_id: Option, + ) -> Result<(), ErrorKind> { + Owner::cancel_tx(self, (&token.keychain_mask).as_ref(), tx_id, tx_slate_id) + .map_err(|e| e.kind()) + } + + fn get_stored_tx( + &self, + token: Token, + tx: &TxLogEntry, + ) -> Result, ErrorKind> { + Owner::get_stored_tx(self, (&token.keychain_mask).as_ref(), tx).map_err(|e| e.kind()) + } + + fn post_tx(&self, token: Token, tx: &Transaction, fluff: bool) -> Result<(), ErrorKind> { + Owner::post_tx(self, (&token.keychain_mask).as_ref(), tx, fluff).map_err(|e| e.kind()) + } + + fn verify_slate_messages(&self, token: Token, slate: VersionedSlate) -> Result<(), ErrorKind> { + let in_slate = Slate::from(slate); + Owner::verify_slate_messages(self, (&token.keychain_mask).as_ref(), &in_slate) + .map_err(|e| e.kind()) + } + + fn restore(&self, token: Token) -> Result<(), ErrorKind> { + Owner::restore(self, (&token.keychain_mask).as_ref()).map_err(|e| e.kind()) + } + + fn check_repair(&self, token: Token, delete_unconfirmed: bool) -> Result<(), ErrorKind> { + Owner::check_repair(self, (&token.keychain_mask).as_ref(), delete_unconfirmed) + .map_err(|e| e.kind()) + } + + fn node_height(&self, token: Token) -> Result { + Owner::node_height(self, (&token.keychain_mask).as_ref()).map_err(|e| e.kind()) + } +} diff --git a/api/tests/slate_versioning.rs b/api/tests/slate_versioning.rs index 197c1e126..9047b58cf 100644 --- a/api/tests/slate_versioning.rs +++ b/api/tests/slate_versioning.rs @@ -52,7 +52,7 @@ fn _receive_versioned_slate() { let request_val: Value = serde_json::from_str(v1_req).unwrap(); let expected_response: Value = serde_json::from_str(v1_resp).unwrap(); - let response = run_doctest_foreign(request_val, dir, 5, true, false) + let response = run_doctest_foreign(request_val, dir, false, 5, true, false) .unwrap() .unwrap(); diff --git a/controller/src/command.rs b/controller/src/command.rs index 78419f0bc..7ea4bd201 100644 --- a/controller/src/command.rs +++ b/controller/src/command.rs @@ -22,6 +22,7 @@ use crate::impls::{create_sender, KeybaseAllChannels, SlateGetter as _, SlateRec use crate::impls::{PathToSlate, SlatePutter}; use crate::keychain; use crate::libwallet::{InitTxArgs, IssueInvoiceTxArgs, NodeClient, WalletInst, WalletLCProvider}; +use crate::util::secp::key::SecretKey; use crate::util::{Mutex, ZeroingString}; use crate::{controller, display}; use serde_json as json; @@ -120,6 +121,7 @@ pub struct ListenArgs { pub fn listen<'a, L, C, K>( wallet: Arc>>>, + keychain_mask: Option, config: &WalletConfig, args: &ListenArgs, g_args: &GlobalArgs, @@ -132,6 +134,7 @@ where let res = match args.method.as_str() { "http" => controller::foreign_listener( wallet.clone(), + keychain_mask, &config.api_listen_addr(), g_args.tls_conf.clone(), ), @@ -158,6 +161,7 @@ where pub fn owner_api( wallet: Arc>>>, + keychain_mask: Option, config: &WalletConfig, g_args: &GlobalArgs, ) -> Result<(), Error> @@ -168,6 +172,7 @@ where { let res = controller::owner_listener( wallet, + keychain_mask, config.owner_api_listen_addr().as_str(), g_args.node_api_secret.clone(), g_args.tls_conf.clone(), @@ -186,6 +191,7 @@ pub struct AccountArgs { pub fn account<'a, L, C, K>( wallet: Arc>>>, + keychain_mask: Option<&SecretKey>, args: AccountArgs, ) -> Result<(), Error> where @@ -194,8 +200,8 @@ where K: keychain::Keychain + 'a, { if args.create.is_none() { - let res = controller::owner_single_use(wallet, |api| { - let acct_mappings = api.accounts()?; + let res = controller::owner_single_use(wallet, keychain_mask, |api, m| { + let acct_mappings = api.accounts(m)?; // give logging thread a moment to catch up thread::sleep(Duration::from_millis(200)); display::accounts(acct_mappings); @@ -207,8 +213,8 @@ where } } else { let label = args.create.unwrap(); - let res = controller::owner_single_use(wallet, |api| { - api.create_account_path(&label)?; + let res = controller::owner_single_use(wallet, keychain_mask, |api, m| { + api.create_account_path(m, &label)?; thread::sleep(Duration::from_millis(200)); info!("Account: '{}' Created!", label); Ok(()) @@ -239,6 +245,7 @@ pub struct SendArgs { pub fn send<'a, L, C, K>( wallet: Arc>>>, + keychain_mask: Option<&SecretKey>, args: SendArgs, dark_scheme: bool, ) -> Result<(), Error> @@ -247,7 +254,7 @@ where C: NodeClient + 'a, K: keychain::Keychain + 'a, { - controller::owner_single_use(wallet.clone(), |api| { + controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| { if args.estimate_selection_strategies { let strategies = vec!["smallest", "all"] .into_iter() @@ -262,7 +269,7 @@ where estimate_only: Some(true), ..Default::default() }; - let slate = api.init_send_tx(init_args).unwrap(); + let slate = api.init_send_tx(m, init_args).unwrap(); (strategy, slate.amount, slate.fee) }) .collect(); @@ -280,7 +287,7 @@ where send_args: None, ..Default::default() }; - let result = api.init_send_tx(init_args); + let result = api.init_send_tx(m, init_args); let mut slate = match result { Ok(s) => { info!( @@ -300,12 +307,16 @@ where match args.method.as_str() { "file" => { PathToSlate((&args.dest).into()).put_tx(&slate)?; - api.tx_lock_outputs(&slate, 0)?; + api.tx_lock_outputs(m, &slate, 0)?; return Ok(()); } "self" => { - api.tx_lock_outputs(&slate, 0)?; - controller::foreign_single_use(wallet, |api| { + api.tx_lock_outputs(m, &slate, 0)?; + let km = match keychain_mask.as_ref() { + None => None, + Some(&m) => Some(m.to_owned()), + }; + controller::foreign_single_use(wallet, km, |api| { slate = api.receive_tx(&slate, Some(&args.dest), None)?; Ok(()) })?; @@ -313,16 +324,16 @@ where method => { let sender = create_sender(method, &args.dest)?; slate = sender.send_tx(&slate)?; - api.tx_lock_outputs(&slate, 0)?; + api.tx_lock_outputs(m, &slate, 0)?; } } - api.verify_slate_messages(&slate).map_err(|e| { + api.verify_slate_messages(m, &slate).map_err(|e| { error!("Error validating participant messages: {}", e); e })?; - slate = api.finalize_tx(&slate)?; - let result = api.post_tx(&slate.tx, args.fluff); + slate = api.finalize_tx(m, &slate)?; + let result = api.post_tx(m, &slate.tx, args.fluff); match result { Ok(_) => { info!("Tx sent ok",); @@ -347,6 +358,7 @@ pub struct ReceiveArgs { pub fn receive<'a, L, C, K>( wallet: Arc>>>, + keychain_mask: Option<&SecretKey>, g_args: &GlobalArgs, args: ReceiveArgs, ) -> Result<(), Error> @@ -356,7 +368,11 @@ where K: keychain::Keychain + 'a, { let mut slate = PathToSlate((&args.input).into()).get_tx()?; - controller::foreign_single_use(wallet, |api| { + let km = match keychain_mask.as_ref() { + None => None, + Some(&m) => Some(m.to_owned()), + }; + controller::foreign_single_use(wallet, km, |api| { if let Err(e) = api.verify_slate_messages(&slate) { error!("Error validating participant messages: {}", e); return Err(e); @@ -380,6 +396,7 @@ pub struct FinalizeArgs { pub fn finalize<'a, L, C, K>( wallet: Arc>>>, + keychain_mask: Option<&SecretKey>, args: FinalizeArgs, ) -> Result<(), Error> where @@ -408,7 +425,11 @@ where }; if is_invoice { - controller::foreign_single_use(wallet.clone(), |api| { + let km = match keychain_mask.as_ref() { + None => None, + Some(&m) => Some(m.to_owned()), + }; + controller::foreign_single_use(wallet.clone(), km, |api| { if let Err(e) = api.verify_slate_messages(&slate) { error!("Error validating participant messages: {}", e); return Err(e); @@ -417,18 +438,18 @@ where Ok(()) })?; } else { - controller::owner_single_use(wallet.clone(), |api| { - if let Err(e) = api.verify_slate_messages(&slate) { + controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| { + if let Err(e) = api.verify_slate_messages(m, &slate) { error!("Error validating participant messages: {}", e); return Err(e); } - slate = api.finalize_tx(&mut slate)?; + slate = api.finalize_tx(m, &mut slate)?; Ok(()) })?; } - controller::owner_single_use(wallet.clone(), |api| { - let result = api.post_tx(&slate.tx, args.fluff); + controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| { + let result = api.post_tx(m, &slate.tx, args.fluff); match result { Ok(_) => { info!("Transaction sent successfully, check the wallet again for confirmation."); @@ -454,6 +475,7 @@ pub struct IssueInvoiceArgs { pub fn issue_invoice_tx<'a, L, C, K>( wallet: Arc>>>, + keychain_mask: Option<&SecretKey>, args: IssueInvoiceArgs, ) -> Result<(), Error> where @@ -461,8 +483,8 @@ where C: NodeClient + 'a, K: keychain::Keychain + 'a, { - controller::owner_single_use(wallet.clone(), |api| { - let slate = api.issue_invoice_tx(args.issue_args)?; + controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| { + let slate = api.issue_invoice_tx(m, args.issue_args)?; let mut tx_file = File::create(args.dest.clone())?; tx_file.write_all(json::to_string(&slate).unwrap().as_bytes())?; tx_file.sync_all()?; @@ -486,6 +508,7 @@ pub struct ProcessInvoiceArgs { /// Process invoice pub fn process_invoice<'a, L, C, K>( wallet: Arc>>>, + keychain_mask: Option<&SecretKey>, args: ProcessInvoiceArgs, dark_scheme: bool, ) -> Result<(), Error> @@ -495,7 +518,7 @@ where K: keychain::Keychain + 'a, { let slate = PathToSlate((&args.input).into()).get_tx()?; - controller::owner_single_use(wallet.clone(), |api| { + controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| { if args.estimate_selection_strategies { let strategies = vec!["smallest", "all"] .into_iter() @@ -510,7 +533,7 @@ where estimate_only: Some(true), ..Default::default() }; - let slate = api.init_send_tx(init_args).unwrap(); + let slate = api.init_send_tx(m, init_args).unwrap(); (strategy, slate.amount, slate.fee) }) .collect(); @@ -527,11 +550,11 @@ where send_args: None, ..Default::default() }; - if let Err(e) = api.verify_slate_messages(&slate) { + if let Err(e) = api.verify_slate_messages(m, &slate) { error!("Error validating participant messages: {}", e); return Err(e); } - let result = api.process_invoice_tx(&slate, init_args); + let result = api.process_invoice_tx(m, &slate, init_args); let mut slate = match result { Ok(s) => { info!( @@ -552,11 +575,15 @@ where "file" => { let slate_putter = PathToSlate((&args.dest).into()); slate_putter.put_tx(&slate)?; - api.tx_lock_outputs(&slate, 0)?; + api.tx_lock_outputs(m, &slate, 0)?; } "self" => { - api.tx_lock_outputs(&slate, 0)?; - controller::foreign_single_use(wallet, |api| { + api.tx_lock_outputs(m, &slate, 0)?; + let km = match keychain_mask.as_ref() { + None => None, + Some(&m) => Some(m.to_owned()), + }; + controller::foreign_single_use(wallet, km, |api| { slate = api.finalize_invoice_tx(&slate)?; Ok(()) })?; @@ -564,7 +591,7 @@ where method => { let sender = create_sender(method, &args.dest)?; slate = sender.send_tx(&slate)?; - api.tx_lock_outputs(&slate, 0)?; + api.tx_lock_outputs(m, &slate, 0)?; } } } @@ -579,6 +606,7 @@ pub struct InfoArgs { pub fn info<'a, L, C, K>( wallet: Arc>>>, + keychain_mask: Option<&SecretKey>, g_args: &GlobalArgs, args: InfoArgs, dark_scheme: bool, @@ -588,9 +616,9 @@ where C: NodeClient + 'a, K: keychain::Keychain + 'a, { - controller::owner_single_use(wallet.clone(), |api| { + controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| { let (validated, wallet_info) = - api.retrieve_summary_info(true, args.minimum_confirmations)?; + api.retrieve_summary_info(m, true, args.minimum_confirmations)?; display::info(&g_args.account, &wallet_info, validated, dark_scheme); Ok(()) })?; @@ -599,6 +627,7 @@ where pub fn outputs<'a, L, C, K>( wallet: Arc>>>, + keychain_mask: Option<&SecretKey>, g_args: &GlobalArgs, dark_scheme: bool, ) -> Result<(), Error> @@ -607,9 +636,9 @@ where C: NodeClient + 'a, K: keychain::Keychain + 'a, { - controller::owner_single_use(wallet.clone(), |api| { - let res = api.node_height()?; - let (validated, outputs) = api.retrieve_outputs(g_args.show_spent, true, None)?; + controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| { + let res = api.node_height(m)?; + let (validated, outputs) = api.retrieve_outputs(m, g_args.show_spent, true, None)?; display::outputs(&g_args.account, res.height, validated, outputs, dark_scheme)?; Ok(()) })?; @@ -624,6 +653,7 @@ pub struct TxsArgs { pub fn txs<'a, L, C, K>( wallet: Arc>>>, + keychain_mask: Option<&SecretKey>, g_args: &GlobalArgs, args: TxsArgs, dark_scheme: bool, @@ -633,9 +663,9 @@ where C: NodeClient + 'a, K: keychain::Keychain + 'a, { - controller::owner_single_use(wallet.clone(), |api| { - let res = api.node_height()?; - let (validated, txs) = api.retrieve_txs(true, args.id, args.tx_slate_id)?; + controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| { + let res = api.node_height(m)?; + let (validated, txs) = api.retrieve_txs(m, true, args.id, args.tx_slate_id)?; let include_status = !args.id.is_some() && !args.tx_slate_id.is_some(); display::txs( &g_args.account, @@ -662,7 +692,7 @@ where }; if id.is_some() { - let (_, outputs) = api.retrieve_outputs(true, false, id)?; + let (_, outputs) = api.retrieve_outputs(m, true, false, id)?; display::outputs(&g_args.account, res.height, validated, outputs, dark_scheme)?; // should only be one here, but just in case for tx in txs { @@ -684,6 +714,7 @@ pub struct RepostArgs { pub fn repost<'a, L, C, K>( wallet: Arc>>>, + keychain_mask: Option<&SecretKey>, args: RepostArgs, ) -> Result<(), Error> where @@ -691,9 +722,9 @@ where C: NodeClient + 'a, K: keychain::Keychain + 'a, { - controller::owner_single_use(wallet.clone(), |api| { - let (_, txs) = api.retrieve_txs(true, Some(args.id), None)?; - let stored_tx = api.get_stored_tx(&txs[0])?; + controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| { + let (_, txs) = api.retrieve_txs(m, true, Some(args.id), None)?; + let stored_tx = api.get_stored_tx(m, &txs[0])?; if stored_tx.is_none() { error!( "Transaction with id {} does not have transaction data. Not reposting.", @@ -710,7 +741,7 @@ where ); return Ok(()); } - api.post_tx(&stored_tx.unwrap(), args.fluff)?; + api.post_tx(m, &stored_tx.unwrap(), args.fluff)?; info!("Reposted transaction at {}", args.id); return Ok(()); } @@ -735,6 +766,7 @@ pub struct CancelArgs { pub fn cancel<'a, L, C, K>( wallet: Arc>>>, + keychain_mask: Option<&SecretKey>, args: CancelArgs, ) -> Result<(), Error> where @@ -742,8 +774,8 @@ where C: NodeClient + 'a, K: keychain::Keychain + 'a, { - controller::owner_single_use(wallet.clone(), |api| { - let result = api.cancel_tx(args.tx_id, args.tx_slate_id); + controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| { + let result = api.cancel_tx(m, args.tx_id, args.tx_slate_id); match result { Ok(_) => { info!("Transaction {} Cancelled", args.tx_id_string); @@ -760,14 +792,15 @@ where pub fn restore<'a, L, C, K>( wallet: Arc>>>, + keychain_mask: Option<&SecretKey>, ) -> Result<(), Error> where L: WalletLCProvider<'a, C, K>, C: NodeClient + 'a, K: keychain::Keychain + 'a, { - controller::owner_single_use(wallet.clone(), |api| { - let result = api.restore(); + controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| { + let result = api.restore(m); match result { Ok(_) => { warn!("Wallet restore complete",); @@ -790,6 +823,7 @@ pub struct CheckArgs { pub fn check_repair<'a, L, C, K>( wallet: Arc>>>, + keychain_mask: Option<&SecretKey>, args: CheckArgs, ) -> Result<(), Error> where @@ -797,10 +831,10 @@ where C: NodeClient + 'a, K: keychain::Keychain + 'a, { - controller::owner_single_use(wallet.clone(), |api| { + controller::owner_single_use(wallet.clone(), keychain_mask, |api, m| { warn!("Starting wallet check...",); warn!("Updating all wallet outputs, please wait ...",); - let result = api.check_repair(args.delete_unconfirmed); + let result = api.check_repair(m, args.delete_unconfirmed); match result { Ok(_) => { warn!("Wallet check complete",); diff --git a/controller/src/controller.rs b/controller/src/controller.rs index 5c9875792..18c73a905 100644 --- a/controller/src/controller.rs +++ b/controller/src/controller.rs @@ -20,6 +20,7 @@ use crate::libwallet::{ Error, ErrorKind, NodeClient, NodeVersionInfo, Slate, WalletInst, WalletLCProvider, CURRENT_SLATE_VERSION, GRIN_BLOCK_HEADER_VERSION, }; +use crate::util::secp::key::SecretKey; use crate::util::{to_base64, Mutex}; use failure::ResultExt; use futures::future::{err, ok}; @@ -73,23 +74,25 @@ fn check_middleware( /// Instantiate wallet Owner API for a single-use (command line) call /// Return a function containing a loaded API context to call pub fn owner_single_use<'a, L, F, C, K>( - lc_provider: Arc>>>, + wallet: Arc>>>, + keychain_mask: Option<&SecretKey>, f: F, ) -> Result<(), Error> where L: WalletLCProvider<'a, C, K>, - F: FnOnce(&mut Owner<'a, L, C, K>) -> Result<(), Error>, + F: FnOnce(&mut Owner<'a, L, C, K>, Option<&SecretKey>) -> Result<(), Error>, C: NodeClient + 'a, K: Keychain + 'a, { - f(&mut Owner::new(lc_provider))?; + f(&mut Owner::new(wallet), keychain_mask)?; Ok(()) } /// Instantiate wallet Foreign API for a single-use (command line) call /// Return a function containing a loaded API context to call pub fn foreign_single_use<'a, L, F, C, K>( - lc_provider: Arc>>>, + wallet: Arc>>>, + keychain_mask: Option, f: F, ) -> Result<(), Error> where @@ -98,14 +101,21 @@ where C: NodeClient + 'a, K: Keychain + 'a, { - f(&mut Foreign::new(lc_provider, Some(check_middleware)))?; + f(&mut Foreign::new( + wallet, + keychain_mask, + Some(check_middleware), + ))?; Ok(()) } /// Listener version, providing same API but listening for requests on a /// port and wrapping the calls +/// Note keychain mask is only provided here in case the foreign listener is also being used +/// in the same wallet instance pub fn owner_listener( wallet: Arc + 'static>>>, + keychain_mask: Option, addr: &str, api_secret: Option, tls_config: Option, @@ -136,7 +146,7 @@ where // If so configured, add the foreign API to the same port if owner_api_include_foreign.unwrap_or(false) { warn!("Starting HTTP Foreign API on Owner server at {}.", addr); - let foreign_api_handler_v2 = ForeignAPIHandlerV2::new(wallet); + let foreign_api_handler_v2 = ForeignAPIHandlerV2::new(wallet, keychain_mask); router .add_route("/v2/foreign", Arc::new(foreign_api_handler_v2)) .map_err(|_| ErrorKind::GenericError("Router failed to add route".to_string()))?; @@ -160,6 +170,7 @@ where /// port and wrapping the calls pub fn foreign_listener( wallet: Arc + 'static>>>, + keychain_mask: Option, addr: &str, tls_config: Option, ) -> Result<(), Error> @@ -168,7 +179,7 @@ where C: NodeClient + 'static, K: Keychain + 'static, { - let api_handler_v2 = ForeignAPIHandlerV2::new(wallet); + let api_handler_v2 = ForeignAPIHandlerV2::new(wallet, keychain_mask); let mut router = Router::new(); @@ -275,6 +286,8 @@ where { /// Wallet instance pub wallet: Arc + 'static>>>, + /// Keychain mask + pub keychain_mask: Option, } impl ForeignAPIHandlerV2 @@ -286,8 +299,12 @@ where /// Create a new foreign API handler for GET methods pub fn new( wallet: Arc + 'static>>>, + keychain_mask: Option, ) -> ForeignAPIHandlerV2 { - ForeignAPIHandlerV2 { wallet } + ForeignAPIHandlerV2 { + wallet, + keychain_mask, + } } fn call_api( @@ -309,7 +326,11 @@ where } fn handle_post_request(&self, req: Request) -> WalletResponseFuture { - let api = Foreign::new(self.wallet.clone(), Some(check_middleware)); + let api = Foreign::new( + self.wallet.clone(), + self.keychain_mask.clone(), + Some(check_middleware), + ); Box::new( self.call_api(req, api) .and_then(|resp| ok(json_response_pretty(&resp))), diff --git a/controller/tests/accounts.rs b/controller/tests/accounts.rs index 198dfa1e3..06948bc56 100644 --- a/controller/tests/accounts.rs +++ b/controller/tests/accounts.rs @@ -43,20 +43,29 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { create_wallet_and_add!( client1, wallet1, + mask1_i, test_dir, "wallet1", None, - &mut wallet_proxy + &mut wallet_proxy, + false ); + + let mask1 = (&mask1_i).as_ref(); + create_wallet_and_add!( client2, wallet2, + mask2_i, test_dir, "wallet2", None, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask2 = (&mask2_i).as_ref(); + // Set the wallet proxy listener running thread::spawn(move || { if let Err(e) = wallet_proxy.run() { @@ -69,30 +78,30 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { let cm = global::coinbase_maturity(); // assume all testing precedes soft fork height // test default accounts exist - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let accounts = api.accounts()?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let accounts = api.accounts(m)?; assert_eq!(accounts[0].label, "default"); assert_eq!(accounts[0].path, ExtKeychain::derive_key_id(2, 0, 0, 0, 0)); Ok(()) })?; // add some accounts - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let new_path = api.create_account_path("account1").unwrap(); + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let new_path = api.create_account_path(m, "account1").unwrap(); assert_eq!(new_path, ExtKeychain::derive_key_id(2, 1, 0, 0, 0)); - let new_path = api.create_account_path("account2").unwrap(); + let new_path = api.create_account_path(m, "account2").unwrap(); assert_eq!(new_path, ExtKeychain::derive_key_id(2, 2, 0, 0, 0)); - let new_path = api.create_account_path("account3").unwrap(); + let new_path = api.create_account_path(m, "account3").unwrap(); assert_eq!(new_path, ExtKeychain::derive_key_id(2, 3, 0, 0, 0)); // trying to add same label again should fail - let res = api.create_account_path("account1"); + let res = api.create_account_path(m, "account1"); assert!(res.is_err()); Ok(()) })?; // add account to wallet 2 - wallet::controller::owner_single_use(wallet2.clone(), |api| { - let new_path = api.create_account_path("listener_account").unwrap(); + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + let new_path = api.create_account_path(m, "listener_account").unwrap(); assert_eq!(new_path, ExtKeychain::derive_key_id(2, 1, 0, 0, 0)); Ok(()) })?; @@ -109,24 +118,24 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { w.set_parent_key_id_by_name("account1")?; assert_eq!(w.parent_key_id(), ExtKeychain::derive_key_id(2, 1, 0, 0, 0)); } - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 7, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 7, false); { wallet_inst!(wallet1, w); w.set_parent_key_id_by_name("account2")?; assert_eq!(w.parent_key_id(), ExtKeychain::derive_key_id(2, 2, 0, 0, 0)); } - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 5, false); // Should have 5 in account1 (5 spendable), 5 in account (2 spendable) - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet1_refreshed); assert_eq!(wallet1_info.last_confirmed_height, 12); assert_eq!(wallet1_info.total, 5 * reward); assert_eq!(wallet1_info.amount_currently_spendable, (5 - cm) * reward); // check tx log as well - let (_, txs) = api.retrieve_txs(true, None, None)?; + let (_, txs) = api.retrieve_txs(m, true, None, None)?; assert_eq!(txs.len(), 5); Ok(()) })?; @@ -137,17 +146,17 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { let w = lc.wallet_inst()?; w.set_parent_key_id_by_name("account1")?; } - wallet::controller::owner_single_use(wallet1.clone(), |api| { + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { // check last confirmed height on this account is different from above (should be 0) - let (_, wallet1_info) = api.retrieve_summary_info(false, 1)?; + let (_, wallet1_info) = api.retrieve_summary_info(m, false, 1)?; assert_eq!(wallet1_info.last_confirmed_height, 0); - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet1_refreshed); assert_eq!(wallet1_info.last_confirmed_height, 12); assert_eq!(wallet1_info.total, 7 * reward); assert_eq!(wallet1_info.amount_currently_spendable, 7 * reward); // check tx log as well - let (_, txs) = api.retrieve_txs(true, None, None)?; + let (_, txs) = api.retrieve_txs(m, true, None, None)?; assert_eq!(txs.len(), 7); Ok(()) })?; @@ -157,16 +166,16 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { wallet_inst!(wallet1, w); w.set_parent_key_id_by_name("default")?; } - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (_, wallet1_info) = api.retrieve_summary_info(false, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (_, wallet1_info) = api.retrieve_summary_info(m, false, 1)?; assert_eq!(wallet1_info.last_confirmed_height, 0); - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet1_refreshed); assert_eq!(wallet1_info.last_confirmed_height, 12); assert_eq!(wallet1_info.total, 0,); assert_eq!(wallet1_info.amount_currently_spendable, 0,); // check tx log as well - let (_, txs) = api.retrieve_txs(true, None, None)?; + let (_, txs) = api.retrieve_txs(m, true, None, None)?; assert_eq!(txs.len(), 0); Ok(()) })?; @@ -177,7 +186,7 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { w.set_parent_key_id_by_name("account1")?; } - wallet::controller::owner_single_use(wallet1.clone(), |api| { + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { let args = InitTxArgs { src_acct_name: None, amount: reward, @@ -187,19 +196,19 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { selection_strategy_is_use_all: true, ..Default::default() }; - let mut slate = api.init_send_tx(args)?; + let mut slate = api.init_send_tx(m, args)?; slate = client1.send_tx_slate_direct("wallet2", &slate)?; - api.tx_lock_outputs(&slate, 0)?; - slate = api.finalize_tx(&slate)?; - api.post_tx(&slate.tx, false)?; + api.tx_lock_outputs(m, &slate, 0)?; + slate = api.finalize_tx(m, &slate)?; + api.post_tx(m, &slate.tx, false)?; Ok(()) })?; - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet1_refreshed); assert_eq!(wallet1_info.last_confirmed_height, 13); - let (_, txs) = api.retrieve_txs(true, None, None)?; + let (_, txs) = api.retrieve_txs(m, true, None, None)?; assert_eq!(txs.len(), 9); Ok(()) })?; @@ -209,23 +218,23 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { wallet_inst!(wallet1, w); w.set_parent_key_id_by_name("account2")?; } - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (_, wallet1_info) = api.retrieve_summary_info(false, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (_, wallet1_info) = api.retrieve_summary_info(m, false, 1)?; assert_eq!(wallet1_info.last_confirmed_height, 12); - let (_, wallet1_info) = api.retrieve_summary_info(true, 1)?; + let (_, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert_eq!(wallet1_info.last_confirmed_height, 13); - let (_, txs) = api.retrieve_txs(true, None, None)?; + let (_, txs) = api.retrieve_txs(m, true, None, None)?; println!("{:?}", txs); assert_eq!(txs.len(), 5); Ok(()) })?; // wallet 2 should only have this tx on the listener account - wallet::controller::owner_single_use(wallet2.clone(), |api| { - let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet2_refreshed); assert_eq!(wallet2_info.last_confirmed_height, 13); - let (_, txs) = api.retrieve_txs(true, None, None)?; + let (_, txs) = api.retrieve_txs(m, true, None, None)?; assert_eq!(txs.len(), 1); Ok(()) })?; @@ -234,16 +243,16 @@ fn accounts_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { wallet_inst!(wallet2, w); w.set_parent_key_id_by_name("default")?; } - wallet::controller::owner_single_use(wallet2.clone(), |api| { - let (_, wallet2_info) = api.retrieve_summary_info(false, 1)?; + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + let (_, wallet2_info) = api.retrieve_summary_info(m, false, 1)?; assert_eq!(wallet2_info.last_confirmed_height, 0); - let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?; + let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet2_refreshed); assert_eq!(wallet2_info.last_confirmed_height, 13); assert_eq!(wallet2_info.total, 0,); assert_eq!(wallet2_info.amount_currently_spendable, 0,); // check tx log as well - let (_, txs) = api.retrieve_txs(true, None, None)?; + let (_, txs) = api.retrieve_txs(m, true, None, None)?; assert_eq!(txs.len(), 0); Ok(()) })?; diff --git a/controller/tests/check.rs b/controller/tests/check.rs index 53e024de0..27ea04af5 100644 --- a/controller/tests/check.rs +++ b/controller/tests/check.rs @@ -35,14 +35,14 @@ mod common; use common::{create_wallet_proxy, setup}; macro_rules! send_to_dest { - ($a:expr, $b:expr, $c:expr, $d:expr) => { - test_framework::send_to_dest($a, $b, $c, $d, false) + ($a:expr, $m: expr, $b:expr, $c:expr, $d:expr) => { + test_framework::send_to_dest($a, $m, $b, $c, $d, false) }; } macro_rules! wallet_info { - ($a:expr) => { - test_framework::wallet_info($a) + ($a:expr, $m:expr) => { + test_framework::wallet_info($a, $m) }; } @@ -59,19 +59,25 @@ fn check_repair_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { create_wallet_and_add!( client1, wallet1, + mask1_i, test_dir, "wallet1", None, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask1 = (&mask1_i).as_ref(); create_wallet_and_add!( client2, wallet2, + mask2_i, test_dir, "wallet2", None, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask2 = (&mask2_i).as_ref(); // Set the wallet proxy listener running thread::spawn(move || { @@ -85,34 +91,35 @@ fn check_repair_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { let cm = global::coinbase_maturity() as u64; // assume all testing precedes soft fork height // add some accounts - wallet::controller::owner_single_use(wallet1.clone(), |api| { - api.create_account_path("account_1")?; - api.create_account_path("account_2")?; - api.create_account_path("account_3")?; - api.set_active_account("account_1")?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + api.create_account_path(m, "account_1")?; + api.create_account_path(m, "account_2")?; + api.create_account_path(m, "account_3")?; + api.set_active_account(m, "account_1")?; Ok(()) })?; // add account to wallet 2 - wallet::controller::owner_single_use(wallet2.clone(), |api| { - api.create_account_path("account_1")?; - api.set_active_account("account_1")?; + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + api.create_account_path(m, "account_1")?; + api.set_active_account(m, "account_1")?; Ok(()) })?; // Do some mining let bh = 20u64; - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize, false); + let _ = + test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, bh as usize, false); // Sanity check contents - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet1_refreshed); assert_eq!(wallet1_info.last_confirmed_height, bh); assert_eq!(wallet1_info.total, bh * reward); assert_eq!(wallet1_info.amount_currently_spendable, (bh - cm) * reward); // check tx log as well - let (_, txs) = api.retrieve_txs(true, None, None)?; + let (_, txs) = api.retrieve_txs(m, true, None, None)?; let (c, _) = libwallet::TxLogEntry::sum_confirmed(&txs); assert_eq!(wallet1_info.total, c); assert_eq!(txs.len(), bh as usize); @@ -121,8 +128,8 @@ fn check_repair_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { // Accidentally delete some outputs let mut w1_outputs_commits = vec![]; - wallet::controller::owner_single_use(wallet1.clone(), |api| { - w1_outputs_commits = api.retrieve_outputs(false, true, None)?.1; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + w1_outputs_commits = api.retrieve_outputs(m, false, true, None)?.1; Ok(()) })?; let w1_outputs: Vec = @@ -130,7 +137,7 @@ fn check_repair_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { { wallet_inst!(wallet1, w); { - let mut batch = w.batch()?; + let mut batch = w.batch(mask1)?; batch.delete(&w1_outputs[4].key_id, &None)?; batch.delete(&w1_outputs[10].key_id, &None)?; let mut accidental_spent = w1_outputs[13].clone(); @@ -141,30 +148,30 @@ fn check_repair_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { } // check we have a problem now - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (_, wallet1_info) = api.retrieve_summary_info(true, 1)?; - let (_, txs) = api.retrieve_txs(true, None, None)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (_, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; + let (_, txs) = api.retrieve_txs(m, true, None, None)?; let (c, _) = libwallet::TxLogEntry::sum_confirmed(&txs); assert!(wallet1_info.total != c); Ok(()) })?; // this should restore our missing outputs - wallet::controller::owner_single_use(wallet1.clone(), |api| { - api.check_repair(true)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + api.check_repair(m, true)?; Ok(()) })?; // check our outputs match again - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet1_refreshed); assert_eq!(wallet1_info.total, bh * reward); Ok(()) })?; // perform a transaction, but don't let it finish - wallet::controller::owner_single_use(wallet1.clone(), |api| { + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { // send to send let args = InitTxArgs { src_acct_name: None, @@ -175,30 +182,30 @@ fn check_repair_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { selection_strategy_is_use_all: true, ..Default::default() }; - let slate = api.init_send_tx(args)?; + let slate = api.init_send_tx(m, args)?; // output tx file let send_file = format!("{}/part_tx_1.tx", test_dir); PathToSlate(send_file.into()).put_tx(&slate)?; - api.tx_lock_outputs(&slate, 0)?; + api.tx_lock_outputs(m, &slate, 0)?; Ok(()) })?; // check we're all locked - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (_, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (_, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet1_info.amount_currently_spendable == 0); Ok(()) })?; // unlock/restore - wallet::controller::owner_single_use(wallet1.clone(), |api| { - api.check_repair(true)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + api.check_repair(m, true)?; Ok(()) })?; // check spendable amount again - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (_, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (_, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert_eq!(wallet1_info.amount_currently_spendable, (bh - cm) * reward); Ok(()) })?; @@ -221,94 +228,134 @@ fn two_wallets_one_seed_impl(test_dir: &'static str) -> Result<(), libwallet::Er // Create a new wallet test client, and set its queues to communicate with the // proxy - create_wallet_and_add!(m_client, miner, test_dir, "miner", None, &mut wallet_proxy); + create_wallet_and_add!( + m_client, + miner, + miner_mask_i, + test_dir, + "miner", + None, + &mut wallet_proxy, + false + ); + let miner_mask = (&miner_mask_i).as_ref(); // non-mining recipient wallets create_wallet_and_add!( client1, wallet1, + mask1_i, test_dir, "wallet1", seed_phrase, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask1 = (&mask1_i).as_ref(); create_wallet_and_add!( client2, wallet2, + mask2_i, test_dir, "wallet2", seed_phrase, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask2 = (&mask2_i).as_ref(); // we'll restore into here create_wallet_and_add!( client3, wallet3, + mask3_i, test_dir, "wallet3", seed_phrase, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask3 = (&mask3_i).as_ref(); // also restore into here create_wallet_and_add!( client4, wallet4, + mask4_i, test_dir, "wallet4", seed_phrase, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask4 = (&mask4_i).as_ref(); // Simulate a recover from seed without restore into here create_wallet_and_add!( client5, wallet5, + mask5_i, test_dir, "wallet5", seed_phrase, - &mut wallet_proxy + &mut wallet_proxy, + false ); //simulate a recover from seed without restore into here + let mask5 = (&mask5_i).as_ref(); create_wallet_and_add!( client6, wallet6, + mask6_i, test_dir, "wallet6", seed_phrase, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask6 = (&mask6_i).as_ref(); create_wallet_and_add!( client7, wallet7, + mask7_i, test_dir, "wallet7", seed_phrase, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask7 = (&mask7_i).as_ref(); create_wallet_and_add!( client8, wallet8, + mask8_i, test_dir, "wallet8", seed_phrase, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask8 = (&mask8_i).as_ref(); create_wallet_and_add!( client9, wallet9, + mask9_i, test_dir, "wallet9", seed_phrase, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask9 = (&mask9_i).as_ref(); create_wallet_and_add!( client10, wallet10, + mask10_i, test_dir, "wallet10", seed_phrase, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask10 = (&mask10_i).as_ref(); // Set the wallet proxy listener running thread::spawn(move || { @@ -324,38 +371,80 @@ fn two_wallets_one_seed_impl(test_dir: &'static str) -> Result<(), libwallet::Er // Do some mining let mut bh = 20u64; let base_amount = consensus::GRIN_BASE; - let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), bh as usize, false); + let _ = test_framework::award_blocks_to_wallet( + &chain, + miner.clone(), + miner_mask, + bh as usize, + false, + ); // send some funds to wallets 1 - send_to_dest!(miner.clone(), m_client.clone(), "wallet1", base_amount * 1)?; - send_to_dest!(miner.clone(), m_client.clone(), "wallet1", base_amount * 2)?; - send_to_dest!(miner.clone(), m_client.clone(), "wallet1", base_amount * 3)?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet1", + base_amount * 1 + )?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet1", + base_amount * 2 + )?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet1", + base_amount * 3 + )?; bh += 3; // 0) Check repair when all is okay should leave wallet contents alone - wallet::controller::owner_single_use(wallet1.clone(), |api| { - api.check_repair(true)?; - let info = wallet_info!(wallet1.clone())?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + api.check_repair(m, true)?; + let info = wallet_info!(wallet1.clone(), m)?; assert_eq!(info.amount_currently_spendable, base_amount * 6); assert_eq!(info.total, base_amount * 6); Ok(()) })?; // send some funds to wallet 2 - send_to_dest!(miner.clone(), m_client.clone(), "wallet2", base_amount * 4)?; - send_to_dest!(miner.clone(), m_client.clone(), "wallet2", base_amount * 5)?; - send_to_dest!(miner.clone(), m_client.clone(), "wallet2", base_amount * 6)?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet2", + base_amount * 4 + )?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet2", + base_amount * 5 + )?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet2", + base_amount * 6 + )?; bh += 3; - let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm, false); + let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), miner_mask, cm, false); bh += cm as u64; // confirm balances - let info = wallet_info!(wallet1.clone())?; + let info = wallet_info!(wallet1.clone(), mask1)?; assert_eq!(info.amount_currently_spendable, base_amount * 6); assert_eq!(info.total, base_amount * 6); - let info = wallet_info!(wallet2.clone())?; + let info = wallet_info!(wallet2.clone(), mask2)?; assert_eq!(info.amount_currently_spendable, base_amount * 15); assert_eq!(info.total, base_amount * 15); @@ -363,14 +452,14 @@ fn two_wallets_one_seed_impl(test_dir: &'static str) -> Result<(), libwallet::Er // seed + BIP32 path. // 1) a full restore should recover all of them: - wallet::controller::owner_single_use(wallet3.clone(), |api| { - api.restore()?; + wallet::controller::owner_single_use(wallet3.clone(), mask3, |api, m| { + api.restore(m)?; Ok(()) })?; - wallet::controller::owner_single_use(wallet3.clone(), |api| { - let info = wallet_info!(wallet3.clone())?; - let outputs = api.retrieve_outputs(true, false, None)?.1; + wallet::controller::owner_single_use(wallet3.clone(), mask3, |api, m| { + let info = wallet_info!(wallet3.clone(), m)?; + let outputs = api.retrieve_outputs(m, true, false, None)?.1; assert_eq!(outputs.len(), 6); assert_eq!(info.amount_currently_spendable, base_amount * 21); assert_eq!(info.total, base_amount * 21); @@ -378,14 +467,14 @@ fn two_wallets_one_seed_impl(test_dir: &'static str) -> Result<(), libwallet::Er })?; // 2) check_repair should recover them into a single wallet - wallet::controller::owner_single_use(wallet1.clone(), |api| { - api.check_repair(true)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + api.check_repair(m, true)?; Ok(()) })?; - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let info = wallet_info!(wallet1.clone())?; - let outputs = api.retrieve_outputs(true, false, None)?.1; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let info = wallet_info!(wallet1.clone(), m)?; + let outputs = api.retrieve_outputs(m, true, false, None)?.1; assert_eq!(outputs.len(), 6); assert_eq!(info.amount_currently_spendable, base_amount * 21); Ok(()) @@ -393,30 +482,48 @@ fn two_wallets_one_seed_impl(test_dir: &'static str) -> Result<(), libwallet::Er // 3) If I recover from seed and start using the wallet without restoring, // check_repair should restore the older outputs - send_to_dest!(miner.clone(), m_client.clone(), "wallet4", base_amount * 7)?; - send_to_dest!(miner.clone(), m_client.clone(), "wallet4", base_amount * 8)?; - send_to_dest!(miner.clone(), m_client.clone(), "wallet4", base_amount * 9)?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet4", + base_amount * 7 + )?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet4", + base_amount * 8 + )?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet4", + base_amount * 9 + )?; bh += 3; - let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm, false); + let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), miner_mask, cm, false); bh += cm as u64; - wallet::controller::owner_single_use(wallet4.clone(), |api| { - let info = wallet_info!(wallet4.clone())?; - let outputs = api.retrieve_outputs(true, false, None)?.1; + wallet::controller::owner_single_use(wallet4.clone(), mask4, |api, m| { + let info = wallet_info!(wallet4.clone(), m)?; + let outputs = api.retrieve_outputs(m, true, false, None)?.1; assert_eq!(outputs.len(), 3); assert_eq!(info.amount_currently_spendable, base_amount * 24); Ok(()) })?; - wallet::controller::owner_single_use(wallet5.clone(), |api| { - api.restore()?; + wallet::controller::owner_single_use(wallet5.clone(), mask5, |api, m| { + api.restore(m)?; Ok(()) })?; - wallet::controller::owner_single_use(wallet5.clone(), |api| { - let info = wallet_info!(wallet5.clone())?; - let outputs = api.retrieve_outputs(true, false, None)?.1; + wallet::controller::owner_single_use(wallet5.clone(), mask5, |api, m| { + let info = wallet_info!(wallet5.clone(), m)?; + let outputs = api.retrieve_outputs(m, true, false, None)?.1; assert_eq!(outputs.len(), 9); assert_eq!(info.amount_currently_spendable, base_amount * (45)); Ok(()) @@ -424,30 +531,54 @@ fn two_wallets_one_seed_impl(test_dir: &'static str) -> Result<(), libwallet::Er // 4) If I recover from seed and start using the wallet without restoring, // check_repair should restore the older outputs - send_to_dest!(miner.clone(), m_client.clone(), "wallet6", base_amount * 10)?; - send_to_dest!(miner.clone(), m_client.clone(), "wallet6", base_amount * 11)?; - send_to_dest!(miner.clone(), m_client.clone(), "wallet6", base_amount * 12)?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet6", + base_amount * 10 + )?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet6", + base_amount * 11 + )?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet6", + base_amount * 12 + )?; bh += 3; - let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm as usize, false); + let _ = test_framework::award_blocks_to_wallet( + &chain, + miner.clone(), + miner_mask, + cm as usize, + false, + ); bh += cm as u64; - wallet::controller::owner_single_use(wallet6.clone(), |api| { - let info = wallet_info!(wallet6.clone())?; - let outputs = api.retrieve_outputs(true, false, None)?.1; + wallet::controller::owner_single_use(wallet6.clone(), mask6, |api, m| { + let info = wallet_info!(wallet6.clone(), m)?; + let outputs = api.retrieve_outputs(m, true, false, None)?.1; assert_eq!(outputs.len(), 3); assert_eq!(info.amount_currently_spendable, base_amount * 33); Ok(()) })?; - wallet::controller::owner_single_use(wallet6.clone(), |api| { - api.check_repair(true)?; + wallet::controller::owner_single_use(wallet6.clone(), mask6, |api, m| { + api.check_repair(m, true)?; Ok(()) })?; - wallet::controller::owner_single_use(wallet6.clone(), |api| { - let info = wallet_info!(wallet6.clone())?; - let outputs = api.retrieve_outputs(true, false, None)?.1; + wallet::controller::owner_single_use(wallet6.clone(), mask6, |api, m| { + let info = wallet_info!(wallet6.clone(), m)?; + let outputs = api.retrieve_outputs(m, true, false, None)?.1; assert_eq!(outputs.len(), 12); assert_eq!(info.amount_currently_spendable, base_amount * (78)); Ok(()) @@ -456,49 +587,85 @@ fn two_wallets_one_seed_impl(test_dir: &'static str) -> Result<(), libwallet::Er // 5) Start using same seed with a different account, amounts should // be distinct and restore should return funds from other account - send_to_dest!(miner.clone(), m_client.clone(), "wallet7", base_amount * 13)?; - send_to_dest!(miner.clone(), m_client.clone(), "wallet7", base_amount * 14)?; - send_to_dest!(miner.clone(), m_client.clone(), "wallet7", base_amount * 15)?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet7", + base_amount * 13 + )?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet7", + base_amount * 14 + )?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet7", + base_amount * 15 + )?; bh += 3; // mix it up a bit - wallet::controller::owner_single_use(wallet7.clone(), |api| { - api.create_account_path("account_1")?; - api.set_active_account("account_1")?; + wallet::controller::owner_single_use(wallet7.clone(), mask7, |api, m| { + api.create_account_path(m, "account_1")?; + api.set_active_account(m, "account_1")?; Ok(()) })?; - send_to_dest!(miner.clone(), m_client.clone(), "wallet7", base_amount * 1)?; - send_to_dest!(miner.clone(), m_client.clone(), "wallet7", base_amount * 2)?; - send_to_dest!(miner.clone(), m_client.clone(), "wallet7", base_amount * 3)?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet7", + base_amount * 1 + )?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet7", + base_amount * 2 + )?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet7", + base_amount * 3 + )?; bh += 3; // check balances - let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm, false); + let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), miner_mask, cm, false); bh += cm as u64; - wallet::controller::owner_single_use(wallet7.clone(), |api| { - let info = wallet_info!(wallet7.clone())?; - let outputs = api.retrieve_outputs(true, false, None)?.1; + wallet::controller::owner_single_use(wallet7.clone(), mask7, |api, m| { + let info = wallet_info!(wallet7.clone(), m)?; + let outputs = api.retrieve_outputs(m, true, false, None)?.1; assert_eq!(outputs.len(), 3); assert_eq!(info.amount_currently_spendable, base_amount * 6); - api.set_active_account("default")?; - let info = wallet_info!(wallet7.clone())?; - let outputs = api.retrieve_outputs(true, false, None)?.1; + api.set_active_account(m, "default")?; + let info = wallet_info!(wallet7.clone(), m)?; + let outputs = api.retrieve_outputs(m, true, false, None)?.1; assert_eq!(outputs.len(), 3); assert_eq!(info.amount_currently_spendable, base_amount * 42); Ok(()) })?; - wallet::controller::owner_single_use(wallet8.clone(), |api| { - api.restore()?; - let info = wallet_info!(wallet8.clone())?; - let outputs = api.retrieve_outputs(true, false, None)?.1; + wallet::controller::owner_single_use(wallet8.clone(), mask8, |api, m| { + api.restore(m)?; + let info = wallet_info!(wallet8.clone(), m)?; + let outputs = api.retrieve_outputs(m, true, false, None)?.1; assert_eq!(outputs.len(), 15); assert_eq!(info.amount_currently_spendable, base_amount * 120); - api.set_active_account("account_1")?; - let info = wallet_info!(wallet8.clone())?; - let outputs = api.retrieve_outputs(true, false, None)?.1; + api.set_active_account(m, "account_1")?; + let info = wallet_info!(wallet8.clone(), m)?; + let outputs = api.retrieve_outputs(m, true, false, None)?.1; assert_eq!(outputs.len(), 3); assert_eq!(info.amount_currently_spendable, base_amount * 6); Ok(()) @@ -508,51 +675,69 @@ fn two_wallets_one_seed_impl(test_dir: &'static str) -> Result<(), libwallet::Er // ids on account 2 as well, check_repair should get all outputs created // to now into 2 accounts - wallet::controller::owner_single_use(wallet9.clone(), |api| { - api.create_account_path("account_1")?; - api.set_active_account("account_1")?; + wallet::controller::owner_single_use(wallet9.clone(), mask9, |api, m| { + api.create_account_path(m, "account_1")?; + api.set_active_account(m, "account_1")?; Ok(()) })?; - send_to_dest!(miner.clone(), m_client.clone(), "wallet9", base_amount * 4)?; - send_to_dest!(miner.clone(), m_client.clone(), "wallet9", base_amount * 5)?; - send_to_dest!(miner.clone(), m_client.clone(), "wallet9", base_amount * 6)?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet9", + base_amount * 4 + )?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet9", + base_amount * 5 + )?; + send_to_dest!( + miner.clone(), + miner_mask, + m_client.clone(), + "wallet9", + base_amount * 6 + )?; bh += 3; let _bh = bh; - wallet::controller::owner_single_use(wallet9.clone(), |api| { - let info = wallet_info!(wallet9.clone())?; - let outputs = api.retrieve_outputs(true, false, None)?.1; + wallet::controller::owner_single_use(wallet9.clone(), mask9, |api, m| { + let info = wallet_info!(wallet9.clone(), m)?; + let outputs = api.retrieve_outputs(m, true, false, None)?.1; assert_eq!(outputs.len(), 3); assert_eq!(info.amount_currently_spendable, base_amount * 15); - api.check_repair(true)?; - let info = wallet_info!(wallet9.clone())?; - let outputs = api.retrieve_outputs(true, false, None)?.1; + api.check_repair(m, true)?; + let info = wallet_info!(wallet9.clone(), m)?; + let outputs = api.retrieve_outputs(m, true, false, None)?.1; assert_eq!(outputs.len(), 6); assert_eq!(info.amount_currently_spendable, base_amount * 21); - api.set_active_account("default")?; - let info = wallet_info!(wallet9.clone())?; - let outputs = api.retrieve_outputs(true, false, None)?.1; + api.set_active_account(m, "default")?; + let info = wallet_info!(wallet9.clone(), m)?; + let outputs = api.retrieve_outputs(m, true, false, None)?.1; assert_eq!(outputs.len(), 15); assert_eq!(info.amount_currently_spendable, base_amount * 120); Ok(()) })?; - let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm, false); + let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), miner_mask, cm, false); // 7) Ensure check_repair creates missing accounts - wallet::controller::owner_single_use(wallet10.clone(), |api| { - api.check_repair(true)?; - api.set_active_account("account_1")?; - let info = wallet_info!(wallet10.clone())?; - let outputs = api.retrieve_outputs(true, false, None)?.1; + wallet::controller::owner_single_use(wallet10.clone(), mask10, |api, m| { + api.check_repair(m, true)?; + api.set_active_account(m, "account_1")?; + let info = wallet_info!(wallet10.clone(), m)?; + let outputs = api.retrieve_outputs(m, true, false, None)?.1; assert_eq!(outputs.len(), 6); assert_eq!(info.amount_currently_spendable, base_amount * 21); - api.set_active_account("default")?; - let info = wallet_info!(wallet10.clone())?; - let outputs = api.retrieve_outputs(true, false, None)?.1; + api.set_active_account(m, "default")?; + let info = wallet_info!(wallet10.clone(), m)?; + let outputs = api.retrieve_outputs(m, true, false, None)?.1; assert_eq!(outputs.len(), 15); assert_eq!(info.amount_currently_spendable, base_amount * 120); Ok(()) diff --git a/controller/tests/common/mod.rs b/controller/tests/common/mod.rs index 5f40ae7f4..c1ef72b35 100644 --- a/controller/tests/common/mod.rs +++ b/controller/tests/common/mod.rs @@ -28,6 +28,7 @@ use impls::test_framework::{LocalWalletClient, WalletProxy}; use impls::{DefaultLCProvider, DefaultWalletImpl}; use std::fs; use std::sync::Arc; +use util::secp::key::SecretKey; use util::{Mutex, ZeroingString}; #[macro_export] @@ -41,20 +42,36 @@ macro_rules! wallet_inst { #[macro_export] macro_rules! create_wallet_and_add { - ($client:ident, $wallet: ident, $test_dir: expr, $name: expr, $seed_phrase: expr, $proxy: expr) => { + ($client:ident, $wallet: ident, $mask: ident, $test_dir: expr, $name: expr, $seed_phrase: expr, $proxy: expr, $create_mask: expr) => { let $client = LocalWalletClient::new($name, $proxy.tx.clone()); - let $wallet = - common::create_local_wallet($test_dir, $name, $seed_phrase.clone(), $client.clone()); - $proxy.add_wallet($name, $client.get_send_instance(), $wallet.clone()); + let ($wallet, $mask) = common::create_local_wallet( + $test_dir, + $name, + $seed_phrase.clone(), + $client.clone(), + $create_mask, + ); + $proxy.add_wallet( + $name, + $client.get_send_instance(), + $wallet.clone(), + $mask.clone(), + ); }; } #[macro_export] macro_rules! open_wallet_and_add { - ($client:ident, $wallet: ident, $test_dir: expr, $name: expr, $proxy: expr) => { + ($client:ident, $wallet: ident, $mask: ident, $test_dir: expr, $name: expr, $proxy: expr, $create_mask: expr) => { let $client = LocalWalletClient::new($name, $proxy.tx.clone()); - let $wallet = common::open_local_wallet($test_dir, $name, $client.clone()); - $proxy.add_wallet($name, $client.get_send_instance(), $wallet.clone()); + let ($wallet, $mask) = + common::open_local_wallet($test_dir, $name, $client.clone(), $create_mask); + $proxy.add_wallet( + $name, + $client.get_send_instance(), + $wallet.clone(), + $mask.clone(), + ); }; } pub fn clean_output_dir(test_dir: &str) { @@ -79,18 +96,22 @@ pub fn create_local_wallet( name: &str, mnemonic: Option, client: LocalWalletClient, -) -> Arc< - Mutex< - Box< - WalletInst< - 'static, - DefaultLCProvider<'static, LocalWalletClient, ExtKeychain>, - LocalWalletClient, - ExtKeychain, + create_mask: bool, +) -> ( + Arc< + Mutex< + Box< + WalletInst< + 'static, + DefaultLCProvider<'static, LocalWalletClient, ExtKeychain>, + LocalWalletClient, + ExtKeychain, + >, >, >, >, -> { + Option, +) { let mut wallet = Box::new(DefaultWalletImpl::::new(client).unwrap()) as Box< WalletInst< @@ -103,26 +124,32 @@ pub fn create_local_wallet( lc.set_wallet_directory(&format!("{}/{}", test_dir, name)); lc.create_wallet(None, mnemonic, 32, ZeroingString::from("")) .unwrap(); - lc.open_wallet(None, ZeroingString::from("")).unwrap(); - Arc::new(Mutex::new(wallet)) + let mask = lc + .open_wallet(None, ZeroingString::from(""), create_mask, false) + .unwrap(); + (Arc::new(Mutex::new(wallet)), mask) } pub fn open_local_wallet( test_dir: &str, name: &str, client: LocalWalletClient, -) -> Arc< - Mutex< - Box< - WalletInst< - 'static, - DefaultLCProvider<'static, LocalWalletClient, ExtKeychain>, - LocalWalletClient, - ExtKeychain, + create_mask: bool, +) -> ( + Arc< + Mutex< + Box< + WalletInst< + 'static, + DefaultLCProvider<'static, LocalWalletClient, ExtKeychain>, + LocalWalletClient, + ExtKeychain, + >, >, >, >, -> { + Option, +) { let mut wallet = Box::new(DefaultWalletImpl::::new(client).unwrap()) as Box< WalletInst< @@ -133,6 +160,8 @@ pub fn open_local_wallet( >; let lc = wallet.lc_provider().unwrap(); lc.set_wallet_directory(&format!("{}/{}", test_dir, name)); - lc.open_wallet(None, ZeroingString::from("")).unwrap(); - Arc::new(Mutex::new(wallet)) + let mask = lc + .open_wallet(None, ZeroingString::from(""), create_mask, false) + .unwrap(); + (Arc::new(Mutex::new(wallet)), mask) } diff --git a/controller/tests/file.rs b/controller/tests/file.rs index d0747d5d0..fbdba439a 100644 --- a/controller/tests/file.rs +++ b/controller/tests/file.rs @@ -46,19 +46,25 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro create_wallet_and_add!( client1, wallet1, + mask1_i, test_dir, "wallet1", None, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask1 = (&mask1_i).as_ref(); create_wallet_and_add!( client2, wallet2, + mask2_i, test_dir, "wallet2", None, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask2 = (&mask2_i).as_ref(); // Set the wallet proxy listener running thread::spawn(move || { @@ -71,16 +77,16 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro let reward = core::consensus::REWARD; // add some accounts - wallet::controller::owner_single_use(wallet1.clone(), |api| { - api.create_account_path("mining")?; - api.create_account_path("listener")?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + api.create_account_path(m, "mining")?; + api.create_account_path(m, "listener")?; Ok(()) })?; // add some accounts - wallet::controller::owner_single_use(wallet2.clone(), |api| { - api.create_account_path("account1")?; - api.create_account_path("account2")?; + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + api.create_account_path(m, "account1")?; + api.create_account_path(m, "account2")?; Ok(()) })?; @@ -90,7 +96,8 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro w.set_parent_key_id_by_name("mining")?; } let mut bh = 10u64; - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize, false); + let _ = + test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, bh as usize, false); let send_file = format!("{}/part_tx_1.tx", test_dir); let receive_file = format!("{}/part_tx_2.tx", test_dir); @@ -99,8 +106,8 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro let message = "sender test message, sender test message"; // Should have 5 in account1 (5 spendable), 5 in account (2 spendable) - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet1_refreshed); assert_eq!(wallet1_info.last_confirmed_height, bh); assert_eq!(wallet1_info.total, bh * reward); @@ -115,10 +122,10 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro message: Some(message.to_owned()), ..Default::default() }; - let mut slate = api.init_send_tx(args)?; + let mut slate = api.init_send_tx(m, args)?; // output tx file PathToSlate((&send_file).into()).put_tx(&mut slate)?; - api.tx_lock_outputs(&slate, 0)?; + api.tx_lock_outputs(m, &slate, 0)?; Ok(()) })?; @@ -133,37 +140,37 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro naughty_slate.participant_data[0].message = Some("I changed the message".to_owned()); // verify messages on slate match - wallet::controller::owner_single_use(wallet1.clone(), |api| { - api.verify_slate_messages(&slate)?; - assert!(api.verify_slate_messages(&naughty_slate).is_err()); + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + api.verify_slate_messages(m, &slate)?; + assert!(api.verify_slate_messages(m, &naughty_slate).is_err()); Ok(()) })?; let sender2_message = "And this is sender 2's message".to_owned(); // wallet 2 receives file, completes, sends file back - wallet::controller::foreign_single_use(wallet2.clone(), |api| { + wallet::controller::foreign_single_use(wallet2.clone(), mask2_i.clone(), |api| { slate = api.receive_tx(&slate, None, Some(sender2_message.clone()))?; PathToSlate((&receive_file).into()).put_tx(&slate)?; Ok(()) })?; // wallet 1 finalises and posts - wallet::controller::owner_single_use(wallet1.clone(), |api| { + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { let mut slate = PathToSlate(receive_file.into()).get_tx()?; - api.verify_slate_messages(&slate)?; - slate = api.finalize_tx(&slate)?; - api.post_tx(&slate.tx, false)?; + api.verify_slate_messages(m, &slate)?; + slate = api.finalize_tx(m, &slate)?; + api.post_tx(m, &slate.tx, false)?; bh += 1; Ok(()) })?; - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false); bh += 3; // Check total in mining account - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet1_refreshed); assert_eq!(wallet1_info.last_confirmed_height, bh); assert_eq!(wallet1_info.total, bh * reward - reward * 2); @@ -171,8 +178,8 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro })?; // Check total in 'wallet 2' account - wallet::controller::owner_single_use(wallet2.clone(), |api| { - let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet2_refreshed); assert_eq!(wallet2_info.last_confirmed_height, bh); assert_eq!(wallet2_info.total, 2 * reward); @@ -180,8 +187,8 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro })?; // Check messages, all participants should have both - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (_, tx) = api.retrieve_txs(true, None, Some(slate.id))?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (_, tx) = api.retrieve_txs(m, true, None, Some(slate.id))?; assert_eq!( tx[0].clone().messages.unwrap().messages[0].message, Some(message.to_owned()) @@ -196,8 +203,8 @@ fn file_exchange_test_impl(test_dir: &'static str) -> Result<(), libwallet::Erro Ok(()) })?; - wallet::controller::owner_single_use(wallet2.clone(), |api| { - let (_, tx) = api.retrieve_txs(true, None, Some(slate.id))?; + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + let (_, tx) = api.retrieve_txs(m, true, None, Some(slate.id))?; assert_eq!( tx[0].clone().messages.unwrap().messages[0].message, Some(message.to_owned()) diff --git a/controller/tests/invoice.rs b/controller/tests/invoice.rs index de959880c..d21f43a1d 100644 --- a/controller/tests/invoice.rs +++ b/controller/tests/invoice.rs @@ -41,19 +41,25 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { create_wallet_and_add!( client1, wallet1, + mask1_i, test_dir, "wallet1", None, - &mut wallet_proxy + &mut wallet_proxy, + true ); + let mask1 = (&mask1_i).as_ref(); create_wallet_and_add!( client2, wallet2, + mask2_i, test_dir, "wallet2", None, - &mut wallet_proxy + &mut wallet_proxy, + true ); + let mask2 = (&mask2_i).as_ref(); // Set the wallet proxy listener running thread::spawn(move || { @@ -66,9 +72,9 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { let reward = core::consensus::REWARD; // add some accounts - wallet::controller::owner_single_use(wallet1.clone(), |api| { - api.create_account_path("mining")?; - api.create_account_path("listener")?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + api.create_account_path(m, "mining")?; + api.create_account_path(m, "listener")?; Ok(()) })?; @@ -78,11 +84,17 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { w.set_parent_key_id_by_name("mining")?; } let mut bh = 10u64; - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize, false); + let _ = test_framework::award_blocks_to_wallet( + &chain, + wallet1.clone(), + mask1, + bh as usize, + false, + ); // Sanity check wallet 1 contents - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet1_refreshed); assert_eq!(wallet1_info.last_confirmed_height, bh); assert_eq!(wallet1_info.total, bh * reward); @@ -91,17 +103,17 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { let mut slate = Slate::blank(2); - wallet::controller::owner_single_use(wallet2.clone(), |api| { + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { // Wallet 2 inititates an invoice transaction, requesting payment let args = IssueInvoiceTxArgs { amount: reward * 2, ..Default::default() }; - slate = api.issue_invoice_tx(args)?; + slate = api.issue_invoice_tx(m, args)?; Ok(()) })?; - wallet::controller::owner_single_use(wallet1.clone(), |api| { + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { // Wallet 1 receives the invoice transaction let args = InitTxArgs { src_acct_name: None, @@ -112,32 +124,32 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { selection_strategy_is_use_all: true, ..Default::default() }; - slate = api.process_invoice_tx(&slate, args)?; - api.tx_lock_outputs(&slate, 0)?; + slate = api.process_invoice_tx(m, &slate, args)?; + api.tx_lock_outputs(m, &slate, 0)?; Ok(()) })?; // wallet 2 finalizes and posts - wallet::controller::foreign_single_use(wallet2.clone(), |api| { + wallet::controller::foreign_single_use(wallet2.clone(), mask2_i.clone(), |api| { // Wallet 2 receives the invoice transaction slate = api.finalize_invoice_tx(&slate)?; Ok(()) })?; // wallet 1 posts so wallet 2 doesn't get the mined amount - wallet::controller::owner_single_use(wallet1.clone(), |api| { - api.post_tx(&slate.tx, false)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + api.post_tx(m, &slate.tx, false)?; Ok(()) })?; bh += 1; - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false); bh += 3; // Check transaction log for wallet 2 - wallet::controller::owner_single_use(wallet2.clone(), |api| { - let (_, wallet2_info) = api.retrieve_summary_info(true, 1)?; - let (refreshed, txs) = api.retrieve_txs(true, None, None)?; + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + let (_, wallet2_info) = api.retrieve_summary_info(m, true, 1)?; + let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?; assert!(refreshed); assert!(txs.len() == 1); println!( @@ -151,9 +163,9 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { // Check transaction log for wallet 1, ensure only 1 entry // exists - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (_, wallet1_info) = api.retrieve_summary_info(true, 1)?; - let (refreshed, txs) = api.retrieve_txs(true, None, None)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (_, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; + let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?; assert!(refreshed); assert_eq!(txs.len() as u64, bh + 1); println!( @@ -164,13 +176,13 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { })?; // Test self-sending - wallet::controller::owner_single_use(wallet1.clone(), |api| { + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { // Wallet 1 inititates an invoice transaction, requesting payment let args = IssueInvoiceTxArgs { amount: reward * 2, ..Default::default() }; - slate = api.issue_invoice_tx(args)?; + slate = api.issue_invoice_tx(m, args)?; // Wallet 1 receives the invoice transaction let args = InitTxArgs { src_acct_name: None, @@ -181,19 +193,19 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { selection_strategy_is_use_all: true, ..Default::default() }; - slate = api.process_invoice_tx(&slate, args)?; - api.tx_lock_outputs(&slate, 0)?; + slate = api.process_invoice_tx(m, &slate, args)?; + api.tx_lock_outputs(m, &slate, 0)?; Ok(()) })?; // wallet 1 finalizes and posts - wallet::controller::foreign_single_use(wallet1.clone(), |api| { + wallet::controller::foreign_single_use(wallet1.clone(), mask1_i.clone(), |api| { // Wallet 2 receives the invoice transaction slate = api.finalize_invoice_tx(&slate)?; Ok(()) })?; - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false); //bh += 3; // let logging finish diff --git a/controller/tests/repost.rs b/controller/tests/repost.rs index 006a44275..d65cfba64 100644 --- a/controller/tests/repost.rs +++ b/controller/tests/repost.rs @@ -43,19 +43,25 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> create_wallet_and_add!( client1, wallet1, + mask1_i, test_dir, "wallet1", None, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask1 = (&mask1_i).as_ref(); create_wallet_and_add!( client2, wallet2, + mask2_i, test_dir, "wallet2", None, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask2 = (&mask2_i).as_ref(); // Set the wallet proxy listener running thread::spawn(move || { @@ -68,16 +74,16 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> let reward = core::consensus::REWARD; // add some accounts - wallet::controller::owner_single_use(wallet1.clone(), |api| { - api.create_account_path("mining")?; - api.create_account_path("listener")?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + api.create_account_path(m, "mining")?; + api.create_account_path(m, "listener")?; Ok(()) })?; // add some accounts - wallet::controller::owner_single_use(wallet2.clone(), |api| { - api.create_account_path("account1")?; - api.create_account_path("account2")?; + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + api.create_account_path(m, "account1")?; + api.create_account_path(m, "account2")?; Ok(()) })?; @@ -87,7 +93,8 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> w.set_parent_key_id_by_name("mining")?; } let mut bh = 10u64; - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize, false); + let _ = + test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, bh as usize, false); let send_file = format!("{}/part_tx_1.tx", test_dir); let receive_file = format!("{}/part_tx_2.tx", test_dir); @@ -95,8 +102,8 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> let mut slate = Slate::blank(2); // Should have 5 in account1 (5 spendable), 5 in account (2 spendable) - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet1_refreshed); assert_eq!(wallet1_info.last_confirmed_height, bh); assert_eq!(wallet1_info.total, bh * reward); @@ -110,13 +117,13 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> selection_strategy_is_use_all: true, ..Default::default() }; - let slate = api.init_send_tx(args)?; + let slate = api.init_send_tx(m, args)?; PathToSlate((&send_file).into()).put_tx(&slate)?; - api.tx_lock_outputs(&slate, 0)?; + api.tx_lock_outputs(m, &slate, 0)?; Ok(()) })?; - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false); bh += 3; // wallet 1 receives file to different account, completes @@ -125,7 +132,7 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> w.set_parent_key_id_by_name("listener")?; } - wallet::controller::foreign_single_use(wallet1.clone(), |api| { + wallet::controller::foreign_single_use(wallet1.clone(), mask1_i.clone(), |api| { slate = PathToSlate((&send_file).into()).get_tx()?; slate = api.receive_tx(&slate, None, None)?; PathToSlate((&receive_file).into()).put_tx(&slate)?; @@ -139,27 +146,27 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> } // wallet 1 finalize - wallet::controller::owner_single_use(wallet1.clone(), |api| { + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { slate = PathToSlate((&receive_file).into()).get_tx()?; - slate = api.finalize_tx(&slate)?; + slate = api.finalize_tx(m, &slate)?; Ok(()) })?; // Now repost from cached - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (_, txs) = api.retrieve_txs(true, None, Some(slate.id))?; - let stored_tx = api.get_stored_tx(&txs[0])?; - api.post_tx(&stored_tx.unwrap(), false)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (_, txs) = api.retrieve_txs(m, true, None, Some(slate.id))?; + let stored_tx = api.get_stored_tx(m, &txs[0])?; + api.post_tx(m, &stored_tx.unwrap(), false)?; bh += 1; Ok(()) })?; - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false); bh += 3; // update/test contents of both accounts - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet1_refreshed); assert_eq!(wallet1_info.last_confirmed_height, bh); assert_eq!(wallet1_info.total, bh * reward - reward * 2); @@ -171,8 +178,8 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> w.set_parent_key_id_by_name("listener")?; } - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet2_refreshed); assert_eq!(wallet2_info.last_confirmed_height, bh); assert_eq!(wallet2_info.total, 2 * reward); @@ -192,7 +199,7 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> let mut slate = Slate::blank(2); let amount = 60_000_000_000; - wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { + wallet::controller::owner_single_use(wallet1.clone(), mask1, |sender_api, m| { // note this will increment the block count as part of the transaction "Posting" let args = InitTxArgs { src_acct_name: None, @@ -203,39 +210,39 @@ fn file_repost_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> selection_strategy_is_use_all: true, ..Default::default() }; - let slate_i = sender_api.init_send_tx(args)?; + let slate_i = sender_api.init_send_tx(m, args)?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; - sender_api.tx_lock_outputs(&slate, 0)?; - slate = sender_api.finalize_tx(&mut slate)?; + sender_api.tx_lock_outputs(m, &slate, 0)?; + slate = sender_api.finalize_tx(m, &mut slate)?; Ok(()) })?; - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false); bh += 3; // Now repost from cached - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (_, txs) = api.retrieve_txs(true, None, Some(slate.id))?; - let stored_tx = api.get_stored_tx(&txs[0])?; - api.post_tx(&stored_tx.unwrap(), false)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (_, txs) = api.retrieve_txs(m, true, None, Some(slate.id))?; + let stored_tx = api.get_stored_tx(m, &txs[0])?; + api.post_tx(m, &stored_tx.unwrap(), false)?; bh += 1; Ok(()) })?; - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false); bh += 3; // // update/test contents of both accounts - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet1_refreshed); assert_eq!(wallet1_info.last_confirmed_height, bh); assert_eq!(wallet1_info.total, bh * reward - reward * 4); Ok(()) })?; - wallet::controller::owner_single_use(wallet2.clone(), |api| { - let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet2_refreshed); assert_eq!(wallet2_info.last_confirmed_height, bh); assert_eq!(wallet2_info.total, 2 * amount); diff --git a/controller/tests/restore.rs b/controller/tests/restore.rs index a826efc27..2bdb77c1d 100644 --- a/controller/tests/restore.rs +++ b/controller/tests/restore.rs @@ -41,10 +41,12 @@ fn restore_wallet(base_dir: &'static str, wallet_dir: &str) -> Result<(), libwal create_wallet_and_add!( client, wallet, + mask, base_dir, &dest_wallet_name, None, - &mut wallet_proxy + &mut wallet_proxy, + false ); // close created wallet let mut w_lock = wallet.lock(); @@ -59,10 +61,13 @@ fn restore_wallet(base_dir: &'static str, wallet_dir: &str) -> Result<(), libwal open_wallet_and_add!( client, wallet, + mask_i, &base_dir, &dest_wallet_name, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask = (&mask_i).as_ref(); // Set the wallet proxy listener running let wp_running = wallet_proxy.running.clone(); @@ -73,9 +78,9 @@ fn restore_wallet(base_dir: &'static str, wallet_dir: &str) -> Result<(), libwal }); // perform the restore and update wallet info - wallet::controller::owner_single_use(wallet.clone(), |api| { - let _ = api.restore()?; - let _ = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet.clone(), mask, |api, m| { + let _ = api.restore(m)?; + let _ = api.retrieve_summary_info(m, true, 1)?; Ok(()) })?; @@ -96,17 +101,23 @@ fn compare_wallet_restore( open_wallet_and_add!( client, wallet_source, + source_mask_i, &base_dir, &wallet_dir, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let source_mask = (&source_mask_i).as_ref(); open_wallet_and_add!( client, wallet_dest, + dest_mask_i, &base_dir, &restore_name, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let dest_mask = (&dest_mask_i).as_ref(); { wallet_inst!(wallet_source, w); @@ -136,17 +147,17 @@ fn compare_wallet_restore( let mut dest_accts: Option> = None; // Overall wallet info should be the same - wallet::controller::owner_single_use(wallet_source.clone(), |api| { - src_info = Some(api.retrieve_summary_info(true, 1)?.1); - src_txs = Some(api.retrieve_txs(true, None, None)?.1); - src_accts = Some(api.accounts()?); + wallet::controller::owner_single_use(wallet_source.clone(), source_mask, |api, m| { + src_info = Some(api.retrieve_summary_info(m, true, 1)?.1); + src_txs = Some(api.retrieve_txs(m, true, None, None)?.1); + src_accts = Some(api.accounts(m)?); Ok(()) })?; - wallet::controller::owner_single_use(wallet_dest.clone(), |api| { - dest_info = Some(api.retrieve_summary_info(true, 1)?.1); - dest_txs = Some(api.retrieve_txs(true, None, None)?.1); - dest_accts = Some(api.accounts()?); + wallet::controller::owner_single_use(wallet_dest.clone(), dest_mask, |api, m| { + dest_info = Some(api.retrieve_summary_info(m, true, 1)?.1); + dest_txs = Some(api.retrieve_txs(m, true, None, None)?.1); + dest_accts = Some(api.accounts(m)?); Ok(()) })?; @@ -194,24 +205,30 @@ fn setup_restore(test_dir: &'static str) -> Result<(), libwallet::Error> { create_wallet_and_add!( client1, wallet1, + mask1_i, test_dir, "wallet1", None, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask1 = (&mask1_i).as_ref(); create_wallet_and_add!( client2, wallet2, + mask2_i, test_dir, "wallet2", None, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask2 = (&mask2_i).as_ref(); // wallet 2 will use another account - wallet::controller::owner_single_use(wallet2.clone(), |api| { - api.create_account_path("account1")?; - api.create_account_path("account2")?; + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + api.create_account_path(m, "account1")?; + api.create_account_path(m, "account2")?; Ok(()) })?; @@ -225,11 +242,14 @@ fn setup_restore(test_dir: &'static str) -> Result<(), libwallet::Error> { create_wallet_and_add!( client3, wallet3, + mask3_i, test_dir, "wallet3", None, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask3 = (&mask3_i).as_ref(); // Set the wallet proxy listener running let wp_running = wallet_proxy.running.clone(); @@ -240,13 +260,13 @@ fn setup_restore(test_dir: &'static str) -> Result<(), libwallet::Error> { }); // mine a few blocks - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 10, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 10, false); // assert wallet contents // and a single use api for a send command let amount = 60_000_000_000; let mut slate = Slate::blank(1); - wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { + wallet::controller::owner_single_use(wallet1.clone(), mask1, |sender_api, m| { // note this will increment the block count as part of the transaction "Posting" let args = InitTxArgs { src_acct_name: None, @@ -257,19 +277,19 @@ fn setup_restore(test_dir: &'static str) -> Result<(), libwallet::Error> { selection_strategy_is_use_all: true, ..Default::default() }; - let slate_i = sender_api.init_send_tx(args)?; + let slate_i = sender_api.init_send_tx(m, args)?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; - sender_api.tx_lock_outputs(&slate, 0)?; - slate = sender_api.finalize_tx(&slate)?; - sender_api.post_tx(&slate.tx, false)?; + sender_api.tx_lock_outputs(m, &slate, 0)?; + slate = sender_api.finalize_tx(m, &slate)?; + sender_api.post_tx(m, &slate.tx, false)?; Ok(()) })?; // mine a few more blocks - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false); // Send some to wallet 3 - wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { + wallet::controller::owner_single_use(wallet1.clone(), mask1, |sender_api, m| { // note this will increment the block count as part of the transaction "Posting" let args = InitTxArgs { src_acct_name: None, @@ -280,19 +300,19 @@ fn setup_restore(test_dir: &'static str) -> Result<(), libwallet::Error> { selection_strategy_is_use_all: true, ..Default::default() }; - let slate_i = sender_api.init_send_tx(args)?; + let slate_i = sender_api.init_send_tx(m, args)?; slate = client1.send_tx_slate_direct("wallet3", &slate_i)?; - sender_api.tx_lock_outputs(&slate, 0)?; - slate = sender_api.finalize_tx(&slate)?; - sender_api.post_tx(&slate.tx, false)?; + sender_api.tx_lock_outputs(m, &slate, 0)?; + slate = sender_api.finalize_tx(m, &slate)?; + sender_api.post_tx(m, &slate.tx, false)?; Ok(()) })?; // mine a few more blocks - let _ = test_framework::award_blocks_to_wallet(&chain, wallet3.clone(), 10, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet3.clone(), mask3, 10, false); // Wallet3 to wallet 2 - wallet::controller::owner_single_use(wallet3.clone(), |sender_api| { + wallet::controller::owner_single_use(wallet3.clone(), mask3, |sender_api, m| { // note this will increment the block count as part of the transaction "Posting" let args = InitTxArgs { src_acct_name: None, @@ -303,11 +323,11 @@ fn setup_restore(test_dir: &'static str) -> Result<(), libwallet::Error> { selection_strategy_is_use_all: true, ..Default::default() }; - let slate_i = sender_api.init_send_tx(args)?; + let slate_i = sender_api.init_send_tx(m, args)?; slate = client3.send_tx_slate_direct("wallet2", &slate_i)?; - sender_api.tx_lock_outputs(&slate, 0)?; - slate = sender_api.finalize_tx(&slate)?; - sender_api.post_tx(&slate.tx, false)?; + sender_api.tx_lock_outputs(m, &slate, 0)?; + slate = sender_api.finalize_tx(m, &slate)?; + sender_api.post_tx(m, &slate.tx, false)?; Ok(()) })?; @@ -318,10 +338,10 @@ fn setup_restore(test_dir: &'static str) -> Result<(), libwallet::Error> { } // mine a few more blocks - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 2, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 2, false); // Wallet3 to wallet 2 again (to another account) - wallet::controller::owner_single_use(wallet3.clone(), |sender_api| { + wallet::controller::owner_single_use(wallet3.clone(), mask3, |sender_api, m| { // note this will increment the block count as part of the transaction "Posting" let args = InitTxArgs { src_acct_name: None, @@ -332,28 +352,28 @@ fn setup_restore(test_dir: &'static str) -> Result<(), libwallet::Error> { selection_strategy_is_use_all: true, ..Default::default() }; - let slate_i = sender_api.init_send_tx(args)?; + let slate_i = sender_api.init_send_tx(m, args)?; slate = client3.send_tx_slate_direct("wallet2", &slate_i)?; - sender_api.tx_lock_outputs(&slate, 0)?; - slate = sender_api.finalize_tx(&slate)?; - sender_api.post_tx(&slate.tx, false)?; + sender_api.tx_lock_outputs(m, &slate, 0)?; + slate = sender_api.finalize_tx(m, &slate)?; + sender_api.post_tx(m, &slate.tx, false)?; Ok(()) })?; // mine a few more blocks - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 5, false); // update everyone - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let _ = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let _ = api.retrieve_summary_info(m, true, 1)?; Ok(()) })?; - wallet::controller::owner_single_use(wallet2.clone(), |api| { - let _ = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + let _ = api.retrieve_summary_info(m, true, 1)?; Ok(()) })?; - wallet::controller::owner_single_use(wallet3.clone(), |api| { - let _ = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet3.clone(), mask3, |api, m| { + let _ = api.retrieve_summary_info(m, true, 1)?; Ok(()) })?; diff --git a/controller/tests/self_send.rs b/controller/tests/self_send.rs index fd572a36c..11c885fc7 100644 --- a/controller/tests/self_send.rs +++ b/controller/tests/self_send.rs @@ -41,11 +41,14 @@ fn self_send_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { create_wallet_and_add!( client1, wallet1, + mask1_i, test_dir, "wallet1", None, - &mut wallet_proxy + &mut wallet_proxy, + true ); + let mask1 = (&mask1_i).as_ref(); // Set the wallet proxy listener running thread::spawn(move || { @@ -58,9 +61,9 @@ fn self_send_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { let reward = core::consensus::REWARD; // add some accounts - wallet::controller::owner_single_use(wallet1.clone(), |api| { - api.create_account_path("mining")?; - api.create_account_path("listener")?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + api.create_account_path(m, "mining")?; + api.create_account_path(m, "listener")?; Ok(()) })?; @@ -70,11 +73,12 @@ fn self_send_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { w.set_parent_key_id_by_name("mining")?; } let mut bh = 10u64; - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize, false); + let _ = + test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, bh as usize, false); // Should have 5 in account1 (5 spendable), 5 in account (2 spendable) - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet1_refreshed); assert_eq!(wallet1_info.last_confirmed_height, bh); assert_eq!(wallet1_info.total, bh * reward); @@ -88,25 +92,25 @@ fn self_send_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { selection_strategy_is_use_all: true, ..Default::default() }; - let mut slate = api.init_send_tx(args)?; - api.tx_lock_outputs(&slate, 0)?; + let mut slate = api.init_send_tx(m, args)?; + api.tx_lock_outputs(m, &slate, 0)?; // Send directly to self - wallet::controller::foreign_single_use(wallet1.clone(), |api| { + wallet::controller::foreign_single_use(wallet1.clone(), mask1_i.clone(), |api| { slate = api.receive_tx(&slate, Some("listener"), None)?; Ok(()) })?; - slate = api.finalize_tx(&slate)?; - api.post_tx(&slate.tx, false)?; // mines a block + slate = api.finalize_tx(m, &slate)?; + api.post_tx(m, &slate.tx, false)?; // mines a block bh += 1; Ok(()) })?; - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false); bh += 3; // Check total in mining account - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet1_refreshed); assert_eq!(wallet1_info.last_confirmed_height, bh); assert_eq!(wallet1_info.total, bh * reward - reward * 2); @@ -118,8 +122,8 @@ fn self_send_test_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { wallet_inst!(wallet1, w); w.set_parent_key_id_by_name("listener")?; } - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet1_refreshed); assert_eq!(wallet1_info.last_confirmed_height, bh); assert_eq!(wallet1_info.total, 2 * reward); diff --git a/controller/tests/transaction.rs b/controller/tests/transaction.rs index f3a17a57d..99ef809b6 100644 --- a/controller/tests/transaction.rs +++ b/controller/tests/transaction.rs @@ -42,19 +42,27 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error> create_wallet_and_add!( client1, wallet1, + mask1_i, test_dir, "wallet1", None, - &mut wallet_proxy + &mut wallet_proxy, + true ); + let mask1 = (&mask1_i).as_ref(); + println!("Mask1: {:?}", mask1); create_wallet_and_add!( client2, wallet2, + mask2_i, test_dir, "wallet2", None, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask2 = (&mask2_i).as_ref(); + println!("Mask2: {:?}", mask2); // Set the wallet proxy listener running thread::spawn(move || { @@ -67,11 +75,11 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error> let reward = core::consensus::REWARD; let cm = global::coinbase_maturity(); // mine a few blocks - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 10, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 10, false); // Check wallet 1 contents are as expected - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; debug!( "Wallet 1 Info Pre-Transaction, after {} blocks: {:?}", wallet1_info.last_confirmed_height, wallet1_info @@ -89,7 +97,7 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error> // and a single use api for a send command let amount = 60_000_000_000; let mut slate = Slate::blank(1); - wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { + wallet::controller::owner_single_use(wallet1.clone(), mask1, |sender_api, m| { // note this will increment the block count as part of the transaction "Posting" let args = InitTxArgs { src_acct_name: None, @@ -100,15 +108,15 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error> selection_strategy_is_use_all: true, ..Default::default() }; - let slate_i = sender_api.init_send_tx(args)?; + let slate_i = sender_api.init_send_tx(m, args)?; // Check we are creating a tx with the expected lock_height of 0. // We will check this produces a Plain kernel later. assert_eq!(0, slate.lock_height); slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; - sender_api.tx_lock_outputs(&slate, 0)?; - slate = sender_api.finalize_tx(&slate)?; + sender_api.tx_lock_outputs(m, &slate, 0)?; + slate = sender_api.finalize_tx(m, &slate)?; // Check we have a single kernel and that it is a Plain kernel (no lock_height). assert_eq!(slate.tx.kernels().len(), 1); @@ -125,9 +133,9 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error> })?; // Check transaction log for wallet 1 - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (_, wallet1_info) = api.retrieve_summary_info(true, 1)?; - let (refreshed, txs) = api.retrieve_txs(true, None, None)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (_, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; + let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?; assert!(refreshed); let fee = core::libtx::tx_fee( wallet1_info.last_confirmed_height as usize - cm as usize, @@ -148,8 +156,8 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error> })?; // Check transaction log for wallet 2 - wallet::controller::owner_single_use(wallet2.clone(), |api| { - let (refreshed, txs) = api.retrieve_txs(true, None, None)?; + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?; assert!(refreshed); // we should have a transaction entry for this slate let tx = txs.iter().find(|t| t.tx_slate_id == Some(slate.id)); @@ -164,14 +172,14 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error> })?; // post transaction - wallet::controller::owner_single_use(wallet1.clone(), |api| { - api.post_tx(&slate.tx, false)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + api.post_tx(m, &slate.tx, false)?; Ok(()) })?; // Check wallet 1 contents are as expected - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; debug!( "Wallet 1 Info Post Transaction, after {} blocks: {:?}", wallet1_info.last_confirmed_height, wallet1_info @@ -195,7 +203,7 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error> assert_eq!(wallet1_info.amount_immature, cm * reward + fee); // check tx log entry is confirmed - let (refreshed, txs) = api.retrieve_txs(true, None, None)?; + let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?; assert!(refreshed); let tx = txs.iter().find(|t| t.tx_slate_id == Some(slate.id)); assert!(tx.is_some()); @@ -207,11 +215,11 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error> })?; // mine a few more blocks - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false); // refresh wallets and retrieve info/tests for each wallet after maturity - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (wallet1_refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; debug!("Wallet 1 Info: {:?}", wallet1_info); assert!(wallet1_refreshed); assert_eq!( @@ -225,13 +233,13 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error> Ok(()) })?; - wallet::controller::owner_single_use(wallet2.clone(), |api| { - let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet2_refreshed); assert_eq!(wallet2_info.amount_currently_spendable, amount); // check tx log entry is confirmed - let (refreshed, txs) = api.retrieve_txs(true, None, None)?; + let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?; assert!(refreshed); let tx = txs.iter().find(|t| t.tx_slate_id == Some(slate.id)); assert!(tx.is_some()); @@ -242,7 +250,7 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error> })?; // Estimate fee and locked amount for a transaction - wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { + wallet::controller::owner_single_use(wallet1.clone(), mask1, |sender_api, m| { let init_args = InitTxArgs { src_acct_name: None, amount: amount * 2, @@ -253,7 +261,7 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error> estimate_only: Some(true), ..Default::default() }; - let est = sender_api.init_send_tx(init_args)?; + let est = sender_api.init_send_tx(m, init_args)?; assert_eq!(est.amount, 600_000_000_000); assert_eq!(est.fee, 4_000_000); @@ -267,7 +275,7 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error> estimate_only: Some(true), ..Default::default() }; - let est = sender_api.init_send_tx(init_args)?; + let est = sender_api.init_send_tx(m, init_args)?; assert_eq!(est.amount, 180_000_000_000); assert_eq!(est.fee, 6_000_000); @@ -276,7 +284,7 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error> // Send another transaction, but don't post to chain immediately and use // the stored transaction instead - wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { + wallet::controller::owner_single_use(wallet1.clone(), mask1, |sender_api, m| { // note this will increment the block count as part of the transaction "Posting" let args = InitTxArgs { src_acct_name: None, @@ -287,25 +295,25 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error> selection_strategy_is_use_all: true, ..Default::default() }; - let slate_i = sender_api.init_send_tx(args)?; + let slate_i = sender_api.init_send_tx(m, args)?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; - sender_api.tx_lock_outputs(&slate, 0)?; - slate = sender_api.finalize_tx(&slate)?; + sender_api.tx_lock_outputs(m, &slate, 0)?; + slate = sender_api.finalize_tx(m, &slate)?; Ok(()) })?; - wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { - let (refreshed, _wallet1_info) = sender_api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |sender_api, m| { + let (refreshed, _wallet1_info) = sender_api.retrieve_summary_info(m, true, 1)?; assert!(refreshed); - let (_, txs) = sender_api.retrieve_txs(true, None, None)?; + let (_, txs) = sender_api.retrieve_txs(m, true, None, None)?; // find the transaction let tx = txs .iter() .find(|t| t.tx_slate_id == Some(slate.id)) .unwrap(); - let stored_tx = sender_api.get_stored_tx(&tx)?; - sender_api.post_tx(&stored_tx.unwrap(), false)?; - let (_, wallet1_info) = sender_api.retrieve_summary_info(true, 1)?; + let stored_tx = sender_api.get_stored_tx(m, &tx)?; + sender_api.post_tx(m, &stored_tx.unwrap(), false)?; + let (_, wallet1_info) = sender_api.retrieve_summary_info(m, true, 1)?; // should be mined now assert_eq!( wallet1_info.total, @@ -315,16 +323,16 @@ fn basic_transaction_api(test_dir: &'static str) -> Result<(), libwallet::Error> })?; // mine a few more blocks - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false); // check wallet2 has stored transaction - wallet::controller::owner_single_use(wallet2.clone(), |api| { - let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + let (wallet2_refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?; assert!(wallet2_refreshed); assert_eq!(wallet2_info.amount_currently_spendable, amount * 3); // check tx log entry is confirmed - let (refreshed, txs) = api.retrieve_txs(true, None, None)?; + let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?; assert!(refreshed); let tx = txs.iter().find(|t| t.tx_slate_id == Some(slate.id)); assert!(tx.is_some()); @@ -350,19 +358,25 @@ fn tx_rollback(test_dir: &'static str) -> Result<(), libwallet::Error> { create_wallet_and_add!( client1, wallet1, + mask1_i, test_dir, "wallet1", None, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask1 = (&mask1_i).as_ref(); create_wallet_and_add!( client2, wallet2, + mask2_i, test_dir, "wallet2", None, - &mut wallet_proxy + &mut wallet_proxy, + false ); + let mask2 = (&mask2_i).as_ref(); // Set the wallet proxy listener running thread::spawn(move || { @@ -375,11 +389,11 @@ fn tx_rollback(test_dir: &'static str) -> Result<(), libwallet::Error> { let reward = core::consensus::REWARD; let cm = global::coinbase_maturity(); // assume all testing precedes soft fork height // mine a few blocks - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 5, false); let amount = 30_000_000_000; let mut slate = Slate::blank(1); - wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { + wallet::controller::owner_single_use(wallet1.clone(), mask1, |sender_api, m| { // note this will increment the block count as part of the transaction "Posting" let args = InitTxArgs { src_acct_name: None, @@ -391,29 +405,29 @@ fn tx_rollback(test_dir: &'static str) -> Result<(), libwallet::Error> { ..Default::default() }; - let slate_i = sender_api.init_send_tx(args)?; + let slate_i = sender_api.init_send_tx(m, args)?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; - sender_api.tx_lock_outputs(&slate, 0)?; - slate = sender_api.finalize_tx(&slate)?; + sender_api.tx_lock_outputs(m, &slate, 0)?; + slate = sender_api.finalize_tx(m, &slate)?; Ok(()) })?; // Check transaction log for wallet 1 - wallet::controller::owner_single_use(wallet1.clone(), |api| { - let (refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + let (refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; println!( "last confirmed height: {}", wallet1_info.last_confirmed_height ); assert!(refreshed); - let (_, txs) = api.retrieve_txs(true, None, None)?; + let (_, txs) = api.retrieve_txs(m, true, None, None)?; // we should have a transaction entry for this slate let tx = txs.iter().find(|t| t.tx_slate_id == Some(slate.id)); assert!(tx.is_some()); let mut locked_count = 0; let mut unconfirmed_count = 0; // get the tx entry, check outputs are as expected - let (_, output_mappings) = api.retrieve_outputs(true, false, Some(tx.unwrap().id))?; + let (_, output_mappings) = api.retrieve_outputs(m, true, false, Some(tx.unwrap().id))?; for m in output_mappings.clone() { if m.output.status == OutputStatus::Locked { locked_count = locked_count + 1; @@ -430,14 +444,14 @@ fn tx_rollback(test_dir: &'static str) -> Result<(), libwallet::Error> { })?; // Check transaction log for wallet 2 - wallet::controller::owner_single_use(wallet2.clone(), |api| { - let (refreshed, txs) = api.retrieve_txs(true, None, None)?; + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?; assert!(refreshed); let mut unconfirmed_count = 0; let tx = txs.iter().find(|t| t.tx_slate_id == Some(slate.id)); assert!(tx.is_some()); // get the tx entry, check outputs are as expected - let (_, outputs) = api.retrieve_outputs(true, false, Some(tx.unwrap().id))?; + let (_, outputs) = api.retrieve_outputs(m, true, false, Some(tx.unwrap().id))?; for m in outputs.clone() { if m.output.status == OutputStatus::Unconfirmed { unconfirmed_count = unconfirmed_count + 1; @@ -445,7 +459,7 @@ fn tx_rollback(test_dir: &'static str) -> Result<(), libwallet::Error> { } assert_eq!(outputs.len(), 1); assert_eq!(unconfirmed_count, 1); - let (refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?; + let (refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?; assert!(refreshed); assert_eq!(wallet2_info.amount_currently_spendable, 0,); assert_eq!(wallet2_info.amount_awaiting_finalization, amount); @@ -454,20 +468,20 @@ fn tx_rollback(test_dir: &'static str) -> Result<(), libwallet::Error> { // wallet 1 is bold and doesn't ever post the transaction // mine a few more blocks - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 5, false); // Wallet 1 decides to roll back instead - wallet::controller::owner_single_use(wallet1.clone(), |api| { + wallet::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { // can't roll back coinbase - let res = api.cancel_tx(Some(1), None); + let res = api.cancel_tx(m, Some(1), None); assert!(res.is_err()); - let (_, txs) = api.retrieve_txs(true, None, None)?; + let (_, txs) = api.retrieve_txs(m, true, None, None)?; let tx = txs .iter() .find(|t| t.tx_slate_id == Some(slate.id)) .unwrap(); - api.cancel_tx(Some(tx.id), None)?; - let (refreshed, wallet1_info) = api.retrieve_summary_info(true, 1)?; + api.cancel_tx(m, Some(tx.id), None)?; + let (refreshed, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert!(refreshed); println!( "last confirmed height: {}", @@ -480,27 +494,27 @@ fn tx_rollback(test_dir: &'static str) -> Result<(), libwallet::Error> { (wallet1_info.last_confirmed_height - cm) * reward ); // can't roll back again - let res = api.cancel_tx(Some(tx.id), None); + let res = api.cancel_tx(m, Some(tx.id), None); assert!(res.is_err()); Ok(()) })?; // Wallet 2 rolls back - wallet::controller::owner_single_use(wallet2.clone(), |api| { - let (_, txs) = api.retrieve_txs(true, None, None)?; + wallet::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + let (_, txs) = api.retrieve_txs(m, true, None, None)?; let tx = txs .iter() .find(|t| t.tx_slate_id == Some(slate.id)) .unwrap(); - api.cancel_tx(Some(tx.id), None)?; - let (refreshed, wallet2_info) = api.retrieve_summary_info(true, 1)?; + api.cancel_tx(m, Some(tx.id), None)?; + let (refreshed, wallet2_info) = api.retrieve_summary_info(m, true, 1)?; assert!(refreshed); // check all eligible inputs should be now be spendable assert_eq!(wallet2_info.amount_currently_spendable, 0,); assert_eq!(wallet2_info.total, 0,); // can't roll back again - let res = api.cancel_tx(Some(tx.id), None); + let res = api.cancel_tx(m, Some(tx.id), None); assert!(res.is_err()); Ok(()) diff --git a/impls/src/adapters/http.rs b/impls/src/adapters/http.rs index 327990732..cc3ce942d 100644 --- a/impls/src/adapters/http.rs +++ b/impls/src/adapters/http.rs @@ -28,7 +28,7 @@ pub struct HttpSlateSender { impl HttpSlateSender { /// Create, return Err if scheme is not "http" pub fn new(base_url: Url) -> Result { - if base_url.scheme() != "http" { + if base_url.scheme() != "http" && base_url.scheme() != "https" { Err(SchemeNotHttp) } else { Ok(HttpSlateSender { base_url }) diff --git a/impls/src/adapters/keybase.rs b/impls/src/adapters/keybase.rs index 5b0919525..ce22847da 100644 --- a/impls/src/adapters/keybase.rs +++ b/impls/src/adapters/keybase.rs @@ -368,7 +368,7 @@ impl SlateReceiver for KeybaseAllChannels { >; let lc = wallet.lc_provider().unwrap(); lc.set_wallet_directory(&config.data_file_dir); - lc.open_wallet(None, passphrase)?; + let mask = lc.open_wallet(None, passphrase, true, false)?; let wallet_inst = lc.wallet_inst()?; wallet_inst.set_parent_key_id_by_name(account)?; @@ -411,8 +411,14 @@ impl SlateReceiver for KeybaseAllChannels { return Err(e); } let res = { - let r = - foreign::receive_tx(&mut **wallet_inst, &slate, None, None, false); + let r = foreign::receive_tx( + &mut **wallet_inst, + Some(mask.as_ref().unwrap()), + &slate, + None, + None, + false, + ); r }; match res { diff --git a/impls/src/backends/lmdb.rs b/impls/src/backends/lmdb.rs index fcfaf1ee0..a7222ef4f 100644 --- a/impls/src/backends/lmdb.rs +++ b/impls/src/backends/lmdb.rs @@ -24,7 +24,7 @@ use std::path::Path; use failure::ResultExt; use uuid::Uuid; -use crate::blake2::blake2b::Blake2b; +use crate::blake2::blake2b::{Blake2b, Blake2bResult}; use crate::keychain::{ChildNumber, ExtKeychain, Identifier, Keychain, SwitchCommitmentType}; use crate::store::{self, option_to_not_found, to_key, to_key_u64}; @@ -36,8 +36,12 @@ use crate::libwallet::{ AcctPathMapping, Context, Error, ErrorKind, NodeClient, OutputData, TxLogEntry, WalletBackend, WalletOutputBatch, }; -use crate::util; use crate::util::secp::constants::SECRET_KEY_SIZE; +use crate::util::secp::key::SecretKey; +use crate::util::{self, secp}; + +use rand::rngs::mock::StepRng; +use rand::thread_rng; pub const DB_DIR: &'static str = "db"; pub const TX_SAVE_DIR: &'static str = "saved_txs"; @@ -99,6 +103,8 @@ where data_file_dir: String, /// Keychain pub keychain: Option, + /// Check value for XORed keychain seed + pub master_checksum: Box>, /// Parent path to use by default for output operations parent_key_id: Identifier, /// wallet to node client @@ -144,6 +150,7 @@ where db: store, data_file_dir: data_file_dir.to_owned(), keychain: None, + master_checksum: Box::new(None), parent_key_id: LMDBBackend::::default_path(), w2n_client: n_client, _phantom: &PhantomData, @@ -172,23 +179,68 @@ where K: Keychain + 'ck, { /// Set the keychain, which should already have been opened - fn set_keychain(&mut self, k: Box) { + fn set_keychain( + &mut self, + mut k: Box, + mask: bool, + use_test_rng: bool, + ) -> Result, Error> { + // store hash of master key, so it can be verified later after unmasking + let root_key = k.derive_key(0, &K::root_key_id(), &SwitchCommitmentType::Regular)?; + let mut hasher = Blake2b::new(SECRET_KEY_SIZE); + hasher.update(&root_key.0[..]); + self.master_checksum = Box::new(Some(hasher.finalize())); + + let mask_value = { + match mask { + true => { + // Random value that must be XORed against the stored wallet seed + // before it is used + let mask_value = match use_test_rng { + true => { + let mut test_rng = StepRng::new(1234567890u64, 1); + secp::key::SecretKey::new(&k.secp(), &mut test_rng) + } + false => secp::key::SecretKey::new(&k.secp(), &mut thread_rng()), + }; + k.mask_master_key(&mask_value)?; + Some(mask_value) + } + false => None, + } + }; + self.keychain = Some(*k); + Ok(mask_value) } /// Close wallet fn close(&mut self) -> Result<(), Error> { - //TODO: Ensure this is zeroed? self.keychain = None; Ok(()) } - /// Return the keychain being used - fn keychain(&mut self) -> Result<&mut K, Error> { - if self.keychain.is_some() { - Ok(self.keychain.as_mut().unwrap()) - } else { - Err(ErrorKind::KeychainDoesntExist.into()) + /// Return the keychain being used, cloned with XORed token value + /// for temporary use + fn keychain(&self, mask: Option<&SecretKey>) -> Result { + match self.keychain.as_ref() { + Some(k) => { + let mut k_masked = k.clone(); + if let Some(m) = mask { + k_masked.mask_master_key(m)?; + } + // Check if master seed is what is expected (especially if it's been xored) + let root_key = + k_masked.derive_key(0, &K::root_key_id(), &SwitchCommitmentType::Regular)?; + let mut hasher = Blake2b::new(SECRET_KEY_SIZE); + hasher.update(&root_key.0[..]); + if *self.master_checksum != Some(hasher.finalize()) { + error!("Supplied keychain mask is invalid"); + return Err(ErrorKind::InvalidKeychainMask.into()); + } + Ok(k_masked) + } + None => Err(ErrorKind::KeychainDoesntExist.into()), } } @@ -200,6 +252,7 @@ where /// return the version of the commit for caching fn calc_commit_for_cache( &mut self, + keychain_mask: Option<&SecretKey>, amount: u64, id: &Identifier, ) -> Result, Error> { @@ -209,7 +262,7 @@ where Ok(None) } else {*/ Ok(Some(util::to_hex( - self.keychain()? + self.keychain(keychain_mask)? .commit(amount, &id, &SwitchCommitmentType::Regular)? .0 .to_vec(), // TODO: proper support for different switch commitment schemes @@ -261,6 +314,7 @@ where fn get_private_context( &mut self, + keychain_mask: Option<&SecretKey>, slate_id: &[u8], participant_id: usize, ) -> Result { @@ -269,7 +323,8 @@ where &mut slate_id.to_vec(), participant_id as u64, ); - let (blind_xor_key, nonce_xor_key) = private_ctx_xor_keys(self.keychain()?, slate_id)?; + let (blind_xor_key, nonce_xor_key) = + private_ctx_xor_keys(&self.keychain(keychain_mask)?, slate_id)?; let mut ctx: Context = option_to_not_found( self.db.get_ser(&ctx_key), @@ -305,7 +360,7 @@ where .join(filename); let path_buf = Path::new(&path).to_path_buf(); let mut stored_tx = File::create(path_buf)?; - let tx_hex = util::to_hex(ser::ser_vec(tx).unwrap());; + let tx_hex = util::to_hex(ser::ser_vec(tx, ser::ProtocolVersion::local()).unwrap());; stored_tx.write_all(&tx_hex.as_bytes())?; stored_tx.sync_all()?; Ok(()) @@ -325,19 +380,23 @@ where tx_f.read_to_string(&mut content)?; let tx_bin = util::from_hex(content).unwrap(); Ok(Some( - ser::deserialize::(&mut &tx_bin[..]).unwrap(), + ser::deserialize::(&mut &tx_bin[..], ser::ProtocolVersion::local()) + .unwrap(), )) } - fn batch<'a>(&'a mut self) -> Result + 'a>, Error> { + fn batch<'a>( + &'a mut self, + keychain_mask: Option<&SecretKey>, + ) -> Result + 'a>, Error> { Ok(Box::new(Batch { _store: self, db: RefCell::new(Some(self.db.batch()?)), - keychain: self.keychain.clone(), + keychain: Some(self.keychain(keychain_mask)?), })) } - fn next_child<'a>(&mut self) -> Result { + fn next_child<'a>(&mut self, keychain_mask: Option<&SecretKey>) -> Result { let parent_key_id = self.parent_key_id.clone(); let mut deriv_idx = { let batch = self.db.batch()?; @@ -351,7 +410,7 @@ where return_path.depth = return_path.depth + 1; return_path.path[return_path.depth as usize - 1] = ChildNumber::from(deriv_idx); deriv_idx = deriv_idx + 1; - let mut batch = self.batch()?; + let mut batch = self.batch(keychain_mask)?; batch.save_child_index(&parent_key_id, deriv_idx)?; batch.commit()?; Ok(Identifier::from_path(&return_path)) @@ -370,13 +429,17 @@ where Ok(last_confirmed_height) } - fn restore(&mut self) -> Result<(), Error> { - restore(self).context(ErrorKind::Restore)?; + fn restore(&mut self, keychain_mask: Option<&SecretKey>) -> Result<(), Error> { + restore(self, keychain_mask).context(ErrorKind::Restore)?; Ok(()) } - fn check_repair(&mut self, delete_unconfirmed: bool) -> Result<(), Error> { - check_repair(self, delete_unconfirmed).context(ErrorKind::Restore)?; + fn check_repair( + &mut self, + keychain_mask: Option<&SecretKey>, + delete_unconfirmed: bool, + ) -> Result<(), Error> { + check_repair(self, keychain_mask, delete_unconfirmed).context(ErrorKind::Restore)?; Ok(()) } } diff --git a/impls/src/lifecycle/default.rs b/impls/src/lifecycle/default.rs index 4341e24d3..e73fa7d08 100644 --- a/impls/src/lifecycle/default.rs +++ b/impls/src/lifecycle/default.rs @@ -19,6 +19,7 @@ use crate::core::global; use crate::keychain::Keychain; use crate::libwallet::{Error, ErrorKind, NodeClient, WalletBackend, WalletLCProvider}; use crate::lifecycle::seed::WalletSeed; +use crate::util::secp::key::SecretKey; use crate::util::ZeroingString; use crate::LMDBBackend; use failure::ResultExt; @@ -131,7 +132,13 @@ where Ok(()) } - fn open_wallet(&mut self, _name: Option<&str>, password: ZeroingString) -> Result<(), Error> { + fn open_wallet( + &mut self, + _name: Option<&str>, + password: ZeroingString, + create_mask: bool, + use_test_rng: bool, + ) -> Result, Error> { let mut data_dir_name = PathBuf::from(self.data_dir.clone()); data_dir_name.push(GRIN_WALLET_DIR); let data_dir_name = data_dir_name.to_str().unwrap(); @@ -148,9 +155,10 @@ where let keychain = wallet_seed .derive_keychain(global::is_floonet()) .context(ErrorKind::Lifecycle("Error deriving keychain".into()))?; - wallet.set_keychain(Box::new(keychain)); + + let mask = wallet.set_keychain(Box::new(keychain), create_mask, use_test_rng)?; self.backend = Some(Box::new(wallet)); - Ok(()) + Ok(mask) } fn close_wallet(&mut self, _name: Option<&str>) -> Result<(), Error> { diff --git a/impls/src/test_framework/mod.rs b/impls/src/test_framework/mod.rs index b45e02e4b..3e8a8b593 100644 --- a/impls/src/test_framework/mod.rs +++ b/impls/src/test_framework/mod.rs @@ -24,6 +24,7 @@ use crate::libwallet::api_impl::{foreign, owner}; use crate::libwallet::{ BlockFees, CbData, InitTxArgs, NodeClient, WalletInfo, WalletInst, WalletLCProvider, }; +use crate::util::secp::key::SecretKey; use crate::util::secp::pedersen; use crate::util::Mutex; use chrono::Duration; @@ -105,6 +106,7 @@ pub fn award_block_to_wallet<'a, L, C, K>( chain: &Chain, txs: Vec<&Transaction>, wallet: Arc + 'a>>>, + keychain_mask: Option<&SecretKey>, ) -> Result<(), libwallet::Error> where L: WalletLCProvider<'a, C, K>, @@ -123,7 +125,7 @@ where let coinbase_tx = { let mut w_lock = wallet.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; - let res = foreign::build_coinbase(&mut **w, &block_fees, false)?; + let res = foreign::build_coinbase(&mut **w, keychain_mask, &block_fees, false)?; res }; add_block_with_reward(chain, txs, coinbase_tx.clone()); @@ -134,6 +136,7 @@ where pub fn award_blocks_to_wallet<'a, L, C, K>( chain: &Chain, wallet: Arc + 'a>>>, + keychain_mask: Option<&SecretKey>, number: usize, pause_between: bool, ) -> Result<(), libwallet::Error> @@ -143,7 +146,7 @@ where K: keychain::Keychain + 'a, { for _ in 0..number { - award_block_to_wallet(chain, vec![], wallet.clone())?; + award_block_to_wallet(chain, vec![], wallet.clone(), keychain_mask)?; if pause_between { thread::sleep(std::time::Duration::from_millis(100)); } @@ -154,6 +157,7 @@ where /// send an amount to a destination pub fn send_to_dest<'a, L, C, K>( wallet: Arc>>>, + keychain_mask: Option<&SecretKey>, client: LocalWalletClient, dest: &str, amount: u64, @@ -176,10 +180,10 @@ where selection_strategy_is_use_all: true, ..Default::default() }; - let slate_i = owner::init_send_tx(&mut **w, args, test_mode)?; + let slate_i = owner::init_send_tx(&mut **w, keychain_mask, args, test_mode)?; let slate = client.send_tx_slate_direct(dest, &slate_i)?; - owner::tx_lock_outputs(&mut **w, &slate, 0)?; - let slate = owner::finalize_tx(&mut **w, &slate)?; + owner::tx_lock_outputs(&mut **w, keychain_mask, &slate, 0)?; + let slate = owner::finalize_tx(&mut **w, keychain_mask, &slate)?; slate }; let client = { @@ -194,6 +198,7 @@ where /// get wallet info totals pub fn wallet_info<'a, L, C, K>( wallet: Arc>>>, + keychain_mask: Option<&SecretKey>, ) -> Result where L: WalletLCProvider<'a, C, K>, @@ -202,7 +207,8 @@ where { let mut w_lock = wallet.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; - let (wallet_refreshed, wallet_info) = owner::retrieve_summary_info(&mut **w, true, 1)?; + let (wallet_refreshed, wallet_info) = + owner::retrieve_summary_info(&mut **w, keychain_mask, true, 1)?; assert!(wallet_refreshed); Ok(wallet_info) } diff --git a/impls/src/test_framework/testclient.rs b/impls/src/test_framework/testclient.rs index b63fcfe0b..0c9b67f72 100644 --- a/impls/src/test_framework/testclient.rs +++ b/impls/src/test_framework/testclient.rs @@ -30,6 +30,7 @@ use crate::libwallet::{ NodeClient, NodeVersionInfo, Slate, TxWrapper, WalletInst, WalletLCProvider, }; use crate::util; +use crate::util::secp::key::SecretKey; use crate::util::secp::pedersen; use crate::util::secp::pedersen::Commitment; use crate::util::{Mutex, RwLock}; @@ -73,6 +74,7 @@ where ( Sender, Arc + 'a>>>, + Option, ), >, /// simulate json send to another client @@ -123,8 +125,10 @@ where addr: &str, tx: Sender, wallet: Arc + 'a>>>, + keychain_mask: Option, ) { - self.wallets.insert(addr.to_owned(), (tx, wallet)); + self.wallets + .insert(addr.to_owned(), (tx, wallet, keychain_mask)); } pub fn stop(&mut self) { @@ -170,6 +174,7 @@ where /// post transaction to the chain (and mine it, taking the reward) fn post_tx(&mut self, m: WalletProxyMessage) -> Result { 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()), )?; @@ -178,11 +183,17 @@ where libwallet::ErrorKind::ClientCallback("Error parsing TxWrapper: tx_bin".to_owned()), )?; - let tx: Transaction = ser::deserialize(&mut &tx_bin[..]).context( - libwallet::ErrorKind::ClientCallback("Error parsing TxWrapper: tx".to_owned()), - )?; + let tx: Transaction = ser::deserialize(&mut &tx_bin[..], ser::ProtocolVersion::local()) + .context(libwallet::ErrorKind::ClientCallback( + "Error parsing TxWrapper: tx".to_owned(), + ))?; - super::award_block_to_wallet(&self.chain, vec![&tx], dest_wallet)?; + super::award_block_to_wallet( + &self.chain, + vec![&tx], + dest_wallet, + (&dest_wallet_mask).as_ref(), + )?; Ok(WalletProxyMessage { sender_id: "node".to_owned(), @@ -210,8 +221,9 @@ where { let mut w_lock = wallet.1.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; + let mask = wallet.2.clone(); // receive tx - slate = foreign::receive_tx(&mut **w, &slate, None, None, false)?; + slate = foreign::receive_tx(&mut **w, (&mask).as_ref(), &slate, None, None, false)?; } Ok(WalletProxyMessage { diff --git a/libwallet/src/api_impl/foreign.rs b/libwallet/src/api_impl/foreign.rs index dc2a05125..6b6ae788f 100644 --- a/libwallet/src/api_impl/foreign.rs +++ b/libwallet/src/api_impl/foreign.rs @@ -16,6 +16,7 @@ use strum::IntoEnumIterator; use crate::grin_keychain::Keychain; +use crate::grin_util::secp::key::SecretKey; use crate::internal::{tx, updater}; use crate::slate_versions::SlateVersion; use crate::{ @@ -37,6 +38,7 @@ pub fn check_version() -> VersionInfo { /// Build a coinbase transaction pub fn build_coinbase<'a, T: ?Sized, C, K>( w: &mut T, + keychain_mask: Option<&SecretKey>, block_fees: &BlockFees, test_mode: bool, ) -> Result @@ -45,7 +47,7 @@ where C: NodeClient + 'a, K: Keychain + 'a, { - updater::build_coinbase(&mut *w, block_fees, test_mode) + updater::build_coinbase(&mut *w, keychain_mask, block_fees, test_mode) } /// verify slate messages @@ -56,6 +58,7 @@ pub fn verify_slate_messages(slate: &Slate) -> Result<(), Error> { /// Receive a tx as recipient pub fn receive_tx<'a, T: ?Sized, C, K>( w: &mut T, + keychain_mask: Option<&SecretKey>, slate: &Slate, dest_acct_name: Option<&str>, message: Option, @@ -101,6 +104,7 @@ where tx::add_output_to_slate( &mut *w, + keychain_mask, &mut ret_slate, &parent_key_id, 1, @@ -108,24 +112,28 @@ where false, use_test_rng, )?; - tx::update_message(&mut *w, &mut ret_slate)?; + tx::update_message(&mut *w, keychain_mask, &mut ret_slate)?; Ok(ret_slate) } /// Receive an tx that this wallet has issued -pub fn finalize_invoice_tx<'a, T: ?Sized, C, K>(w: &mut T, slate: &Slate) -> Result +pub fn finalize_invoice_tx<'a, T: ?Sized, C, K>( + w: &mut T, + keychain_mask: Option<&SecretKey>, + slate: &Slate, +) -> Result where T: WalletBackend<'a, C, K>, C: NodeClient + 'a, K: Keychain + 'a, { let mut sl = slate.clone(); - let context = w.get_private_context(sl.id.as_bytes(), 1)?; - tx::complete_tx(&mut *w, &mut sl, 1, &context)?; + let context = w.get_private_context(keychain_mask, sl.id.as_bytes(), 1)?; + tx::complete_tx(&mut *w, keychain_mask, &mut sl, 1, &context)?; tx::update_stored_tx(&mut *w, &mut sl, true)?; - tx::update_message(&mut *w, &mut sl)?; + tx::update_message(&mut *w, keychain_mask, &mut sl)?; { - let mut batch = w.batch()?; + let mut batch = w.batch(keychain_mask)?; batch.delete_private_context(sl.id.as_bytes(), 1)?; batch.commit()?; } diff --git a/libwallet/src/api_impl/owner.rs b/libwallet/src/api_impl/owner.rs index 3cf38df6d..f18da3b2d 100644 --- a/libwallet/src/api_impl/owner.rs +++ b/libwallet/src/api_impl/owner.rs @@ -20,6 +20,7 @@ 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_keychain::{Identifier, Keychain}; use crate::internal::{keys, selection, tx, updater}; @@ -43,13 +44,17 @@ where } /// new account path -pub fn create_account_path<'a, T: ?Sized, C, K>(w: &mut T, label: &str) -> Result +pub fn create_account_path<'a, T: ?Sized, C, K>( + w: &mut T, + keychain_mask: Option<&SecretKey>, + label: &str, +) -> Result where T: WalletBackend<'a, C, K>, C: NodeClient + 'a, K: Keychain + 'a, { - keys::new_acct_path(&mut *w, label) + keys::new_acct_path(&mut *w, keychain_mask, label) } /// set active account @@ -65,6 +70,7 @@ where /// retrieve outputs pub fn retrieve_outputs<'a, T: ?Sized, C, K>( w: &mut T, + keychain_mask: Option<&SecretKey>, include_spent: bool, refresh_from_node: bool, tx_id: Option, @@ -78,18 +84,25 @@ where let mut validated = false; if refresh_from_node { - validated = update_outputs(w, false); + validated = update_outputs(w, keychain_mask, false); } Ok(( validated, - updater::retrieve_outputs(&mut *w, include_spent, tx_id, Some(&parent_key_id))?, + updater::retrieve_outputs( + &mut *w, + keychain_mask, + include_spent, + tx_id, + Some(&parent_key_id), + )?, )) } /// Retrieve txs pub fn retrieve_txs<'a, T: ?Sized, C, K>( w: &mut T, + keychain_mask: Option<&SecretKey>, refresh_from_node: bool, tx_id: Option, tx_slate_id: Option, @@ -103,7 +116,7 @@ where let mut validated = false; if refresh_from_node { - validated = update_outputs(w, false); + validated = update_outputs(w, keychain_mask, false); } Ok(( @@ -115,6 +128,7 @@ where /// Retrieve summary info pub fn retrieve_summary_info<'a, T: ?Sized, C, K>( w: &mut T, + keychain_mask: Option<&SecretKey>, refresh_from_node: bool, minimum_confirmations: u64, ) -> Result<(bool, WalletInfo), Error> @@ -127,7 +141,7 @@ where let mut validated = false; if refresh_from_node { - validated = update_outputs(w, false); + validated = update_outputs(w, keychain_mask, false); } let wallet_info = updater::retrieve_info(&mut *w, &parent_key_id, minimum_confirmations)?; @@ -137,6 +151,7 @@ where /// Initiate tx as sender pub fn init_send_tx<'a, T: ?Sized, C, K>( w: &mut T, + keychain_mask: Option<&SecretKey>, args: InitTxArgs, use_test_rng: bool, ) -> Result @@ -171,6 +186,7 @@ where if let Some(true) = args.estimate_only { let (total, fee) = tx::estimate_send_tx( &mut *w, + keychain_mask, args.amount, args.minimum_confirmations, args.max_outputs as usize, @@ -185,6 +201,7 @@ where let context = tx::add_inputs_to_slate( &mut *w, + keychain_mask, &mut slate, args.minimum_confirmations, args.max_outputs as usize, @@ -200,7 +217,7 @@ where // Save the aggsig context in our DB for when we // recieve the transaction back { - let mut batch = w.batch()?; + let mut batch = w.batch(keychain_mask)?; batch.save_private_context(slate.id.as_bytes(), 0, &context)?; batch.commit()?; } @@ -213,6 +230,7 @@ where /// Initiate a transaction as the recipient (invoicing) pub fn issue_invoice_tx<'a, T: ?Sized, C, K>( w: &mut T, + keychain_mask: Option<&SecretKey>, args: IssueInvoiceTxArgs, use_test_rng: bool, ) -> Result @@ -243,6 +261,7 @@ where let mut slate = tx::new_tx_slate(&mut *w, args.amount, 2, use_test_rng)?; let context = tx::add_output_to_slate( &mut *w, + keychain_mask, &mut slate, &parent_key_id, 1, @@ -254,7 +273,7 @@ where // Save the aggsig context in our DB for when we // recieve the transaction back { - let mut batch = w.batch()?; + let mut batch = w.batch(keychain_mask)?; batch.save_private_context(slate.id.as_bytes(), 1, &context)?; batch.commit()?; } @@ -270,6 +289,7 @@ where /// output was specified pub fn process_invoice_tx<'a, T: ?Sized, C, K>( w: &mut T, + keychain_mask: Option<&SecretKey>, slate: &Slate, args: InitTxArgs, use_test_rng: bool, @@ -317,6 +337,7 @@ where let context = tx::add_inputs_to_slate( &mut *w, + keychain_mask, &mut ret_slate, args.minimum_confirmations, args.max_outputs as usize, @@ -332,7 +353,7 @@ where // Save the aggsig context in our DB for when we // recieve the transaction back { - let mut batch = w.batch()?; + let mut batch = w.batch(keychain_mask)?; batch.save_private_context(slate.id.as_bytes(), 0, &context)?; batch.commit()?; } @@ -347,6 +368,7 @@ where /// Lock sender outputs pub fn tx_lock_outputs<'a, T: ?Sized, C, K>( w: &mut T, + keychain_mask: Option<&SecretKey>, slate: &Slate, participant_id: usize, ) -> Result<(), Error> @@ -355,24 +377,28 @@ where C: NodeClient + 'a, K: Keychain + 'a, { - let context = w.get_private_context(slate.id.as_bytes(), participant_id)?; - selection::lock_tx_context(&mut *w, slate, &context) + let context = w.get_private_context(keychain_mask, slate.id.as_bytes(), participant_id)?; + selection::lock_tx_context(&mut *w, keychain_mask, slate, &context) } /// Finalize slate -pub fn finalize_tx<'a, T: ?Sized, C, K>(w: &mut T, slate: &Slate) -> Result +pub fn finalize_tx<'a, T: ?Sized, C, K>( + w: &mut T, + keychain_mask: Option<&SecretKey>, + slate: &Slate, +) -> Result where T: WalletBackend<'a, C, K>, C: NodeClient + 'a, K: Keychain + 'a, { let mut sl = slate.clone(); - let context = w.get_private_context(sl.id.as_bytes(), 0)?; - tx::complete_tx(&mut *w, &mut sl, 0, &context)?; + let context = w.get_private_context(keychain_mask, sl.id.as_bytes(), 0)?; + tx::complete_tx(&mut *w, keychain_mask, &mut sl, 0, &context)?; tx::update_stored_tx(&mut *w, &mut sl, false)?; - tx::update_message(&mut *w, &mut sl)?; + tx::update_message(&mut *w, keychain_mask, &mut sl)?; { - let mut batch = w.batch()?; + let mut batch = w.batch(keychain_mask)?; batch.delete_private_context(sl.id.as_bytes(), 0)?; batch.commit()?; } @@ -382,6 +408,7 @@ where /// cancel tx pub fn cancel_tx<'a, T: ?Sized, C, K>( w: &mut T, + keychain_mask: Option<&SecretKey>, tx_id: Option, tx_slate_id: Option, ) -> Result<(), Error> @@ -391,12 +418,12 @@ where K: Keychain + 'a, { let parent_key_id = w.parent_key_id(); - if !update_outputs(w, false) { + if !update_outputs(w, keychain_mask, false) { return Err(ErrorKind::TransactionCancellationError( "Can't contact running Grin node. Not Cancelling.", ))?; } - tx::cancel_tx(&mut *w, &parent_key_id, tx_id, tx_slate_id) + tx::cancel_tx(&mut *w, keychain_mask, &parent_key_id, tx_id, tx_slate_id) } /// get stored tx @@ -418,7 +445,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).unwrap()); + let tx_hex = grin_util::to_hex(ser::ser_vec(tx, ser::ProtocolVersion::local()).unwrap()); let res = client.post_tx(&TxWrapper { tx_hex: tx_hex }, fluff); if let Err(e) = res { error!("api: post_tx: failed with error: {}", e); @@ -439,28 +466,38 @@ pub fn verify_slate_messages(slate: &Slate) -> Result<(), Error> { } /// Attempt to restore contents of wallet -pub fn restore<'a, T: ?Sized, C, K>(w: &mut T) -> Result<(), Error> +pub fn restore<'a, T: ?Sized, C, K>( + w: &mut T, + keychain_mask: Option<&SecretKey>, +) -> Result<(), Error> where T: WalletBackend<'a, C, K>, C: NodeClient + 'a, K: Keychain + 'a, { - w.restore() + w.restore(keychain_mask) } /// check repair -pub fn check_repair<'a, T: ?Sized, C, K>(w: &mut T, delete_unconfirmed: bool) -> Result<(), Error> +pub fn check_repair<'a, T: ?Sized, C, K>( + w: &mut T, + keychain_mask: Option<&SecretKey>, + delete_unconfirmed: bool, +) -> Result<(), Error> where T: WalletBackend<'a, C, K>, C: NodeClient + 'a, K: Keychain + 'a, { - update_outputs(w, true); - w.check_repair(delete_unconfirmed) + update_outputs(w, keychain_mask, true); + w.check_repair(keychain_mask, delete_unconfirmed) } /// node height -pub fn node_height<'a, T: ?Sized, C, K>(w: &mut T) -> Result +pub fn node_height<'a, T: ?Sized, C, K>( + w: &mut T, + keychain_mask: Option<&SecretKey>, +) -> Result where T: WalletBackend<'a, C, K>, C: NodeClient + 'a, @@ -473,7 +510,7 @@ where updated_from_node: true, }), Err(_) => { - let outputs = retrieve_outputs(w, true, false, None)?; + let outputs = retrieve_outputs(w, keychain_mask, true, false, None)?; let height = match outputs.1.iter().map(|m| m.output.height).max() { Some(height) => height, None => 0, @@ -487,14 +524,18 @@ where } /// Attempt to update outputs in wallet, return whether it was successful -fn update_outputs<'a, T: ?Sized, C, K>(w: &mut T, update_all: bool) -> bool +fn update_outputs<'a, T: ?Sized, C, K>( + w: &mut T, + keychain_mask: Option<&SecretKey>, + update_all: bool, +) -> bool where T: WalletBackend<'a, C, K>, C: NodeClient + 'a, K: Keychain + 'a, { let parent_key_id = w.parent_key_id(); - match updater::refresh_outputs(&mut *w, &parent_key_id, update_all) { + match updater::refresh_outputs(&mut *w, keychain_mask, &parent_key_id, update_all) { Ok(_) => true, Err(_) => false, } diff --git a/libwallet/src/error.rs b/libwallet/src/error.rs index a7595d61e..2cabe1f61 100644 --- a/libwallet/src/error.rs +++ b/libwallet/src/error.rs @@ -205,6 +205,10 @@ pub enum ErrorKind { #[fail(display = "Lifecycle Error: {}", _0)] Lifecycle(String), + /// Invalid Keychain Mask Error + #[fail(display = "Supplied Keychain Mask Token is incorrect")] + InvalidKeychainMask, + /// Other #[fail(display = "Generic error: {}", _0)] GenericError(String), diff --git a/libwallet/src/internal/keys.rs b/libwallet/src/internal/keys.rs index 1466b9bf8..394fcaa0b 100644 --- a/libwallet/src/internal/keys.rs +++ b/libwallet/src/internal/keys.rs @@ -15,16 +15,20 @@ //! Wallet key management functions use crate::error::{Error, ErrorKind}; use crate::grin_keychain::{ChildNumber, ExtKeychain, Identifier, Keychain}; +use crate::grin_util::secp::key::SecretKey; use crate::types::{AcctPathMapping, NodeClient, WalletBackend}; /// Get next available key in the wallet for a given parent -pub fn next_available_key<'a, T: ?Sized, C, K>(wallet: &mut T) -> Result +pub fn next_available_key<'a, T: ?Sized, C, K>( + wallet: &mut T, + keychain_mask: Option<&SecretKey>, +) -> Result where T: WalletBackend<'a, C, K>, C: NodeClient + 'a, K: Keychain + 'a, { - let child = wallet.next_child()?; + let child = wallet.next_child(keychain_mask)?; Ok(child) } @@ -56,7 +60,11 @@ where } /// Adds an new parent account path with a given label -pub fn new_acct_path<'a, T: ?Sized, C, K>(wallet: &mut T, label: &str) -> Result +pub fn new_acct_path<'a, T: ?Sized, C, K>( + wallet: &mut T, + keychain_mask: Option<&SecretKey>, + label: &str, +) -> Result where T: WalletBackend<'a, C, K>, C: NodeClient + 'a, @@ -90,7 +98,7 @@ where path: return_id.clone(), }; - let mut batch = wallet.batch()?; + let mut batch = wallet.batch(keychain_mask)?; batch.save_acct_path(save_path)?; batch.commit()?; Ok(return_id) @@ -99,6 +107,7 @@ where /// Adds/sets a particular account path with a given label pub fn set_acct_path<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, label: &str, path: &Identifier, ) -> Result<(), Error> @@ -113,7 +122,7 @@ where path: path.clone(), }; - let mut batch = wallet.batch()?; + let mut batch = wallet.batch(keychain_mask)?; batch.save_acct_path(save_path)?; batch.commit()?; Ok(()) diff --git a/libwallet/src/internal/restore.rs b/libwallet/src/internal/restore.rs index cc71ceb13..7ff5703f1 100644 --- a/libwallet/src/internal/restore.rs +++ b/libwallet/src/internal/restore.rs @@ -18,6 +18,7 @@ use crate::grin_core::core::HeaderVersion; use crate::grin_core::global; use crate::grin_core::libtx::proof; use crate::grin_keychain::{ExtKeychain, Identifier, Keychain, SwitchCommitmentType}; +use crate::grin_util::secp::key::SecretKey; use crate::grin_util::secp::pedersen; use crate::internal::{keys, updater}; use crate::types::*; @@ -60,6 +61,7 @@ struct RestoredTxStats { fn identify_utxo_outputs<'a, T, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, outputs: Vec<(pedersen::Commitment, pedersen::RangeProof, bool, u64, u64)>, ) -> Result, Error> where @@ -74,9 +76,9 @@ where outputs.len(), ); - let keychain = wallet.keychain()?; - let legacy_builder = proof::LegacyProofBuilder::new(keychain); - let builder = proof::ProofBuilder::new(keychain); + let keychain = wallet.keychain(keychain_mask)?; + let legacy_builder = proof::LegacyProofBuilder::new(&keychain); + let builder = proof::ProofBuilder::new(&keychain); let legacy_version = HeaderVersion(1); for output in outputs.iter() { @@ -136,7 +138,10 @@ where Ok(wallet_outputs) } -fn collect_chain_outputs<'a, T, C, K>(wallet: &mut T) -> Result, Error> +fn collect_chain_outputs<'a, T, C, K>( + wallet: &mut T, + keychain_mask: Option<&SecretKey>, +) -> Result, Error> where T: WalletBackend<'a, C, K>, C: NodeClient + 'a, @@ -156,7 +161,11 @@ where last_retrieved_index, ); - result_vec.append(&mut identify_utxo_outputs(wallet, outputs.clone())?); + result_vec.append(&mut identify_utxo_outputs( + wallet, + keychain_mask, + outputs.clone(), + )?); if highest_index == last_retrieved_index { break; @@ -169,6 +178,7 @@ where /// fn restore_missing_output<'a, T, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, output: OutputResult, found_parents: &mut HashMap, tx_stats: &mut Option<&mut HashMap>, @@ -178,8 +188,8 @@ where C: NodeClient + 'a, K: Keychain + 'a, { - let commit = wallet.calc_commit_for_cache(output.value, &output.key_id)?; - let mut batch = wallet.batch()?; + let commit = wallet.calc_commit_for_cache(keychain_mask, output.value, &output.key_id)?; + let mut batch = wallet.batch(keychain_mask)?; let parent_key_id = output.key_id.parent_path(); if !found_parents.contains_key(&parent_key_id) { @@ -250,7 +260,11 @@ where } /// -fn cancel_tx_log_entry<'a, T, C, K>(wallet: &mut T, output: &OutputData) -> Result<(), Error> +fn cancel_tx_log_entry<'a, T, C, K>( + wallet: &mut T, + keychain_mask: Option<&SecretKey>, + output: &OutputData, +) -> Result<(), Error> where T: WalletBackend<'a, C, K>, C: NodeClient + 'a, @@ -279,7 +293,7 @@ where } else { None }; - let mut batch = wallet.batch()?; + let mut batch = wallet.batch(keychain_mask)?; if let Some(t) = updated_tx_entry { batch.save_tx_log_entry(t, &parent_key_id)?; } @@ -290,7 +304,11 @@ where /// Check / repair wallet contents /// assume wallet contents have been freshly updated with contents /// of latest block -pub fn check_repair<'a, T, C, K>(wallet: &mut T, delete_unconfirmed: bool) -> Result<(), Error> +pub fn check_repair<'a, T, C, K>( + wallet: &mut T, + keychain_mask: Option<&SecretKey>, + delete_unconfirmed: bool, +) -> Result<(), Error> where T: WalletBackend<'a, C, K>, C: NodeClient + 'a, @@ -298,7 +316,7 @@ where { // First, get a definitive list of outputs we own from the chain warn!("Starting wallet check."); - let chain_outs = collect_chain_outputs(wallet)?; + let chain_outs = collect_chain_outputs(wallet, keychain_mask)?; warn!( "Identified {} wallet_outputs as belonging to this wallet", chain_outs.len(), @@ -306,7 +324,7 @@ where // Now, get all outputs owned by this wallet (regardless of account) let wallet_outputs = { - let res = updater::retrieve_outputs(&mut *wallet, true, None, None)?; + let res = updater::retrieve_outputs(&mut *wallet, keychain_mask, true, None, None)?; res }; @@ -340,8 +358,8 @@ where ); o.status = OutputStatus::Unspent; // any transactions associated with this should be cancelled - cancel_tx_log_entry(wallet, &o)?; - let mut batch = wallet.batch()?; + cancel_tx_log_entry(wallet, keychain_mask, &o)?; + let mut batch = wallet.batch(keychain_mask)?; batch.save(o)?; batch.commit()?; } @@ -355,7 +373,7 @@ where Restoring.", m.value, m.key_id, m.commit, ); - restore_missing_output(wallet, m, &mut found_parents, &mut None)?; + restore_missing_output(wallet, keychain_mask, m, &mut found_parents, &mut None)?; } if delete_unconfirmed { @@ -368,8 +386,8 @@ where o.value, o.key_id, m.1.commit, ); o.status = OutputStatus::Unspent; - cancel_tx_log_entry(wallet, &o)?; - let mut batch = wallet.batch()?; + cancel_tx_log_entry(wallet, keychain_mask, &o)?; + let mut batch = wallet.batch(keychain_mask)?; batch.save(o)?; batch.commit()?; } @@ -386,8 +404,8 @@ where Deleting and cancelling associated transaction log entries.", o.value, o.key_id, m.commit, ); - cancel_tx_log_entry(wallet, &o)?; - let mut batch = wallet.batch()?; + cancel_tx_log_entry(wallet, keychain_mask, &o)?; + let mut batch = wallet.batch(keychain_mask)?; batch.delete(&o.key_id, &o.mmr_index)?; batch.commit()?; } @@ -400,10 +418,10 @@ where // default path already exists if *path != ExtKeychain::derive_key_id(2, 0, 0, 0, 0) { let label = format!("{}_{}", label_base, acct_index); - keys::set_acct_path(wallet, &label, path)?; + keys::set_acct_path(wallet, keychain_mask, &label, path)?; acct_index += 1; } - let mut batch = wallet.batch()?; + let mut batch = wallet.batch(keychain_mask)?; debug!("Next child for account {} is {}", path, max_child_index + 1); batch.save_child_index(path, max_child_index + 1)?; batch.commit()?; @@ -412,7 +430,7 @@ where } /// Restore a wallet -pub fn restore<'a, T, C, K>(wallet: &mut T) -> Result<(), Error> +pub fn restore<'a, T, C, K>(wallet: &mut T, keychain_mask: Option<&SecretKey>) -> Result<(), Error> where T: WalletBackend<'a, C, K>, C: NodeClient + 'a, @@ -428,7 +446,7 @@ where let now = Instant::now(); warn!("Starting restore."); - let result_vec = collect_chain_outputs(wallet)?; + let result_vec = collect_chain_outputs(wallet, keychain_mask)?; warn!( "Identified {} wallet_outputs as belonging to this wallet", @@ -442,6 +460,7 @@ where for output in result_vec { restore_missing_output( wallet, + keychain_mask, output, &mut found_parents, &mut Some(&mut restore_stats), @@ -455,12 +474,12 @@ where // default path already exists if *path != ExtKeychain::derive_key_id(2, 0, 0, 0, 0) { let label = format!("{}_{}", label_base, acct_index); - keys::set_acct_path(wallet, &label, path)?; + keys::set_acct_path(wallet, keychain_mask, &label, path)?; acct_index += 1; } // restore tx log entry for non-coinbase outputs if let Some(s) = restore_stats.get(path) { - let mut batch = wallet.batch()?; + let mut batch = wallet.batch(keychain_mask)?; let mut t = TxLogEntry::new(path.clone(), TxLogEntryType::TxReceived, s.log_id); t.confirmed = true; t.amount_credited = s.amount_credited; @@ -469,7 +488,7 @@ where batch.save_tx_log_entry(t, &path)?; batch.commit()?; } - let mut batch = wallet.batch()?; + let mut batch = wallet.batch(keychain_mask)?; batch.save_child_index(path, max_child_index + 1)?; debug!("Next child for account {} is {}", path, max_child_index + 1); batch.commit()?; diff --git a/libwallet/src/internal/selection.rs b/libwallet/src/internal/selection.rs index 09e1c0bde..d4793cbc4 100644 --- a/libwallet/src/internal/selection.rs +++ b/libwallet/src/internal/selection.rs @@ -22,6 +22,7 @@ use crate::grin_core::libtx::{ tx_fee, }; use crate::grin_keychain::{Identifier, Keychain}; +use crate::grin_util::secp::key::SecretKey; use crate::internal::keys; use crate::slate::Slate; use crate::types::*; @@ -34,6 +35,8 @@ use std::collections::HashMap; pub fn build_send_tx<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain: &K, + keychain_mask: Option<&SecretKey>, slate: &mut Slate, minimum_confirmations: u64, max_outputs: usize, @@ -49,6 +52,7 @@ where { let (elems, inputs, change_amounts_derivations, fee) = select_send_tx( wallet, + keychain_mask, slate.amount, slate.height, minimum_confirmations, @@ -58,7 +62,6 @@ where selection_strategy_is_use_all, &parent_key_id, )?; - let keychain = wallet.keychain()?; let blinding = slate.add_transaction_elements(keychain, &ProofBuilder::new(keychain), elems)?; slate.fee = fee; @@ -86,7 +89,7 @@ where context.add_output(&id, &mmr_index, *change_amount); commits.insert( id.clone(), - wallet.calc_commit_for_cache(*change_amount, &id)?, + wallet.calc_commit_for_cache(keychain_mask, *change_amount, &id)?, ); } @@ -97,6 +100,7 @@ where /// change outputs and tx log entry pub fn lock_tx_context<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, slate: &Slate, context: &Context, ) -> Result<(), Error> @@ -111,7 +115,7 @@ where output_commits.insert( id.clone(), ( - wallet.calc_commit_for_cache(*change_amount, &id)?, + wallet.calc_commit_for_cache(keychain_mask, *change_amount, &id)?, *change_amount, ), ); @@ -123,7 +127,7 @@ where let slate_id = slate.id; let height = slate.height; let parent_key_id = context.parent_key_id.clone(); - let mut batch = wallet.batch()?; + let mut batch = wallet.batch(keychain_mask)?; let log_id = batch.next_tx_log_id(&parent_key_id)?; let mut t = TxLogEntry::new(parent_key_id.clone(), TxLogEntryType::TxSent, log_id); t.tx_slate_id = Some(slate_id.clone()); @@ -174,6 +178,7 @@ where /// Also creates a new transaction containing the output pub fn build_recipient_output<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, slate: &mut Slate, parent_key_id: Identifier, use_test_rng: bool, @@ -184,8 +189,8 @@ where K: Keychain + 'a, { // Create a potential output for this transaction - let key_id = keys::next_available_key(wallet).unwrap(); - let keychain = wallet.keychain()?.clone(); + let key_id = keys::next_available_key(wallet, keychain_mask).unwrap(); + let keychain = wallet.keychain(keychain_mask)?; let key_id_inner = key_id.clone(); let amount = slate.amount; let height = slate.height; @@ -201,7 +206,7 @@ where let mut context = Context::new( keychain.secp(), blinding - .secret_key(wallet.keychain()?.clone().secp()) + .secret_key(wallet.keychain(keychain_mask)?.secp()) .unwrap(), &parent_key_id, use_test_rng, @@ -210,8 +215,8 @@ where context.add_output(&key_id, &None, amount); let messages = Some(slate.participant_messages()); - let commit = wallet.calc_commit_for_cache(amount, &key_id_inner)?; - let mut batch = wallet.batch()?; + let commit = wallet.calc_commit_for_cache(keychain_mask, amount, &key_id_inner)?; + let mut batch = wallet.batch(keychain_mask)?; let log_id = batch.next_tx_log_id(&parent_key_id)?; let mut t = TxLogEntry::new(parent_key_id.clone(), TxLogEntryType::TxReceived, log_id); t.tx_slate_id = Some(slate_id); @@ -242,6 +247,7 @@ where /// selecting outputs to spend and building the change. pub fn select_send_tx<'a, T: ?Sized, C, K, B>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, amount: u64, current_height: u64, minimum_confirmations: u64, @@ -278,7 +284,7 @@ where // build transaction skeleton with inputs and change let (mut parts, change_amounts_derivations) = - inputs_and_change(&coins, wallet, amount, fee, change_outputs)?; + inputs_and_change(&coins, wallet, keychain_mask, amount, fee, change_outputs)?; // This is more proof of concept than anything but here we set lock_height // on tx being sent (based on current chain height via api). @@ -396,6 +402,7 @@ where pub fn inputs_and_change<'a, T: ?Sized, C, K, B>( coins: &Vec, wallet: &mut T, + keychain_mask: Option<&SecretKey>, amount: u64, fee: u64, num_change_outputs: usize, @@ -454,7 +461,7 @@ where part_change }; - let change_key = wallet.next_child().unwrap(); + let change_key = wallet.next_child(keychain_mask).unwrap(); change_amounts_derivations.push((change_amount, change_key.clone(), None)); parts.push(build::output(change_amount, change_key)); diff --git a/libwallet/src/internal/tx.rs b/libwallet/src/internal/tx.rs index 546243da8..b11fbd20e 100644 --- a/libwallet/src/internal/tx.rs +++ b/libwallet/src/internal/tx.rs @@ -19,6 +19,7 @@ use uuid::Uuid; use crate::grin_core::consensus::valid_header_version; use crate::grin_core::core::HeaderVersion; use crate::grin_keychain::{Identifier, Keychain}; +use crate::grin_util::secp::key::SecretKey; use crate::grin_util::Mutex; use crate::internal::{selection, updater}; use crate::slate::Slate; @@ -70,6 +71,7 @@ where /// Estimates locked amount and fee for the transaction without creating one pub fn estimate_send_tx<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, amount: u64, minimum_confirmations: u64, max_outputs: usize, @@ -91,7 +93,7 @@ where // Get lock height let current_height = wallet.w2n_client().get_chain_height()?; // ensure outputs we're selecting are up to date - updater::refresh_outputs(wallet, parent_key_id, false)?; + updater::refresh_outputs(wallet, keychain_mask, parent_key_id, false)?; // Sender selects outputs into a new slate and save our corresponding keys in // a transaction context. The secret key in our transaction context will be @@ -116,6 +118,7 @@ where /// Add inputs to the slate (effectively becoming the sender) pub fn add_inputs_to_slate<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, slate: &mut Slate, minimum_confirmations: u64, max_outputs: usize, @@ -133,7 +136,7 @@ where K: Keychain + 'a, { // sender should always refresh outputs - updater::refresh_outputs(wallet, parent_key_id, false)?; + updater::refresh_outputs(wallet, keychain_mask, parent_key_id, false)?; // Sender selects outputs into a new slate and save our corresponding keys in // a transaction context. The secret key in our transaction context will be @@ -144,6 +147,8 @@ where // this process can be split up in any way let mut context = selection::build_send_tx( wallet, + &wallet.keychain(keychain_mask)?, + keychain_mask, slate, minimum_confirmations, max_outputs, @@ -157,7 +162,7 @@ where // the offset in the slate's transaction kernel, and adds our public key // information to the slate let _ = slate.fill_round_1( - wallet.keychain()?, + &wallet.keychain(keychain_mask)?, &mut context.sec_key, &context.sec_nonce, participant_id, @@ -168,7 +173,7 @@ where if !is_initator { // perform partial sig let _ = slate.fill_round_2( - wallet.keychain()?, + &wallet.keychain(keychain_mask)?, &context.sec_key, &context.sec_nonce, participant_id, @@ -181,6 +186,7 @@ where /// Add receiver output to the slate pub fn add_output_to_slate<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, slate: &mut Slate, parent_key_id: &Identifier, participant_id: usize, @@ -194,12 +200,17 @@ where K: Keychain + 'a, { // create an output using the amount in the slate - let (_, mut context) = - selection::build_recipient_output(wallet, slate, parent_key_id.clone(), use_test_rng)?; + let (_, mut context) = selection::build_recipient_output( + wallet, + keychain_mask, + slate, + parent_key_id.clone(), + use_test_rng, + )?; // fill public keys let _ = slate.fill_round_1( - wallet.keychain()?, + &wallet.keychain(keychain_mask)?, &mut context.sec_key, &context.sec_nonce, 1, @@ -210,7 +221,7 @@ where if !is_initiator { // perform partial sig let _ = slate.fill_round_2( - wallet.keychain()?, + &wallet.keychain(keychain_mask)?, &context.sec_key, &context.sec_nonce, participant_id, @@ -223,6 +234,7 @@ where /// Complete a transaction pub fn complete_tx<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, slate: &mut Slate, participant_id: usize, context: &Context, @@ -233,20 +245,21 @@ where K: Keychain + 'a, { let _ = slate.fill_round_2( - wallet.keychain()?, + &wallet.keychain(keychain_mask)?, &context.sec_key, &context.sec_nonce, participant_id, )?; // Final transaction can be built by anyone at this stage - slate.finalize(wallet.keychain()?)?; + slate.finalize(&wallet.keychain(keychain_mask)?)?; Ok(()) } /// Rollback outputs associated with a transaction in the wallet pub fn cancel_tx<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, parent_key_id: &Identifier, tx_id: Option, tx_slate_id: Option, @@ -274,9 +287,15 @@ where return Err(ErrorKind::TransactionNotCancellable(tx_id_string))?; } // get outputs associated with tx - let res = updater::retrieve_outputs(wallet, false, Some(tx.id), Some(&parent_key_id))?; + let res = updater::retrieve_outputs( + wallet, + keychain_mask, + false, + Some(tx.id), + Some(&parent_key_id), + )?; let outputs = res.iter().map(|m| m.output.clone()).collect(); - updater::cancel_tx_and_outputs(wallet, tx, outputs, parent_key_id)?; + updater::cancel_tx_and_outputs(wallet, keychain_mask, tx, outputs, parent_key_id)?; Ok(()) } @@ -314,7 +333,11 @@ where } /// Update the transaction participant messages -pub fn update_message<'a, T: ?Sized, C, K>(wallet: &mut T, slate: &Slate) -> Result<(), Error> +pub fn update_message<'a, T: ?Sized, C, K>( + wallet: &mut T, + keychain_mask: Option<&SecretKey>, + slate: &Slate, +) -> Result<(), Error> where T: WalletBackend<'a, C, K>, C: NodeClient + 'a, @@ -324,7 +347,7 @@ where if tx_vec.is_empty() { return Err(ErrorKind::TransactionDoesntExist(slate.id.to_string()))?; } - let mut batch = wallet.batch()?; + let mut batch = wallet.batch(keychain_mask)?; for mut tx in tx_vec.into_iter() { tx.messages = Some(slate.participant_messages()); let parent_key = tx.parent_key_id.clone(); diff --git a/libwallet/src/internal/updater.rs b/libwallet/src/internal/updater.rs index 33f4afbd6..3306afc6c 100644 --- a/libwallet/src/internal/updater.rs +++ b/libwallet/src/internal/updater.rs @@ -26,6 +26,7 @@ use crate::grin_core::libtx::proof::ProofBuilder; use crate::grin_core::libtx::reward; use crate::grin_keychain::{Identifier, Keychain, SwitchCommitmentType}; use crate::grin_util as util; +use crate::grin_util::secp::key::SecretKey; use crate::grin_util::secp::pedersen; use crate::internal::keys; use crate::types::{ @@ -36,6 +37,7 @@ use crate::{BlockFees, CbData, OutputCommitMapping}; /// Retrieve all of the outputs (doesn't attempt to update from node) pub fn retrieve_outputs<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, show_spent: bool, tx_id: Option, parent_key_id: Option<&Identifier>, @@ -68,7 +70,7 @@ where } outputs.sort_by_key(|out| out.n_child); - let keychain = wallet.keychain()?.clone(); + let keychain = wallet.keychain(keychain_mask)?; let res = outputs .into_iter() @@ -133,6 +135,7 @@ where /// from a node pub fn refresh_outputs<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, parent_key_id: &Identifier, update_all: bool, ) -> Result<(), Error> @@ -142,7 +145,7 @@ where K: Keychain + 'a, { let height = wallet.w2n_client().get_chain_height()?; - refresh_output_state(wallet, height, parent_key_id, update_all)?; + refresh_output_state(wallet, keychain_mask, height, parent_key_id, update_all)?; Ok(()) } @@ -150,6 +153,7 @@ where /// and a list of outputs we want to query the node for pub fn map_wallet_outputs<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, parent_key_id: &Identifier, update_all: bool, ) -> Result)>, Error> @@ -160,7 +164,7 @@ where { let mut wallet_outputs: HashMap)> = HashMap::new(); - let keychain = wallet.keychain()?.clone(); + let keychain = wallet.keychain(keychain_mask)?; let unspents: Vec = wallet .iter() .filter(|x| x.root_key_id == *parent_key_id && x.status != OutputStatus::Spent) @@ -201,6 +205,7 @@ where /// Cancel transaction and associated outputs pub fn cancel_tx_and_outputs<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, tx: TxLogEntry, outputs: Vec, parent_key_id: &Identifier, @@ -210,7 +215,7 @@ where C: NodeClient + 'a, K: Keychain + 'a, { - let mut batch = wallet.batch()?; + let mut batch = wallet.batch(keychain_mask)?; for mut o in outputs { // unlock locked outputs @@ -237,6 +242,7 @@ where /// Apply refreshed API output data to the wallet pub fn apply_api_outputs<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, wallet_outputs: &HashMap)>, api_outputs: &HashMap, height: u64, @@ -262,7 +268,7 @@ where warn!("Please wait for sync on node to complete or fork to resolve and try again."); return Ok(()); } - let mut batch = wallet.batch()?; + let mut batch = wallet.batch(keychain_mask)?; for (commit, (id, mmr_index)) in wallet_outputs.iter() { if let Ok(mut output) = batch.get(id, mmr_index) { match api_outputs.get(&commit) { @@ -317,6 +323,7 @@ where /// So we can refresh the local wallet outputs. fn refresh_output_state<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, height: u64, parent_key_id: &Identifier, update_all: bool, @@ -330,19 +337,30 @@ where // build a local map of wallet outputs keyed by commit // and a list of outputs we want to query the node for - let wallet_outputs = map_wallet_outputs(wallet, parent_key_id, update_all)?; + let wallet_outputs = map_wallet_outputs(wallet, keychain_mask, parent_key_id, update_all)?; let wallet_output_keys = wallet_outputs.keys().map(|commit| commit.clone()).collect(); let api_outputs = wallet .w2n_client() .get_outputs_from_node(wallet_output_keys)?; - apply_api_outputs(wallet, &wallet_outputs, &api_outputs, height, parent_key_id)?; - clean_old_unconfirmed(wallet, height)?; + apply_api_outputs( + wallet, + keychain_mask, + &wallet_outputs, + &api_outputs, + height, + parent_key_id, + )?; + clean_old_unconfirmed(wallet, keychain_mask, height)?; Ok(()) } -fn clean_old_unconfirmed<'a, T: ?Sized, C, K>(wallet: &mut T, height: u64) -> Result<(), Error> +fn clean_old_unconfirmed<'a, T: ?Sized, C, K>( + wallet: &mut T, + keychain_mask: Option<&SecretKey>, + height: u64, +) -> Result<(), Error> where T: WalletBackend<'a, C, K>, C: NodeClient + 'a, @@ -361,7 +379,7 @@ where ids_to_del.push(out.key_id.clone()) } } - let mut batch = wallet.batch()?; + let mut batch = wallet.batch(keychain_mask)?; for id in ids_to_del { batch.delete(&id, &None)?; } @@ -436,6 +454,7 @@ where /// Build a coinbase output and insert into wallet pub fn build_coinbase<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, block_fees: &BlockFees, test_mode: bool, ) -> Result @@ -444,7 +463,7 @@ where C: NodeClient + 'a, K: Keychain + 'a, { - let (out, kern, block_fees) = receive_coinbase(wallet, block_fees, test_mode)?; + let (out, kern, block_fees) = receive_coinbase(wallet, keychain_mask, block_fees, test_mode)?; Ok(CbData { output: out, @@ -457,6 +476,7 @@ where /// Build a coinbase output and the corresponding kernel pub fn receive_coinbase<'a, T: ?Sized, C, K>( wallet: &mut T, + keychain_mask: Option<&SecretKey>, block_fees: &BlockFees, test_mode: bool, ) -> Result<(Output, TxKernel, BlockFees), Error> @@ -473,16 +493,16 @@ where let key_id = match key_id { Some(key_id) => match keys::retrieve_existing_key(wallet, key_id, None) { Ok(k) => k.0, - Err(_) => keys::next_available_key(wallet)?, + Err(_) => keys::next_available_key(wallet, keychain_mask)?, }, - None => keys::next_available_key(wallet)?, + None => keys::next_available_key(wallet, keychain_mask)?, }; { // Now acquire the wallet lock and write the new output. let amount = reward(block_fees.fees); - let commit = wallet.calc_commit_for_cache(amount, &key_id)?; - let mut batch = wallet.batch()?; + let commit = wallet.calc_commit_for_cache(keychain_mask, amount, &key_id)?; + let mut batch = wallet.batch(keychain_mask)?; batch.save(OutputData { root_key_id: parent_key_id, key_id: key_id.clone(), @@ -510,10 +530,10 @@ where debug!("receive_coinbase: {:?}", block_fees); - let keychain = wallet.keychain()?; + let keychain = wallet.keychain(keychain_mask)?; let (out, kern) = reward::output( - keychain, - &ProofBuilder::new(keychain), + &keychain, + &ProofBuilder::new(&keychain), &key_id, block_fees.fees, test_mode, diff --git a/libwallet/src/types.rs b/libwallet/src/types.rs index c843fd048..5102713c0 100644 --- a/libwallet/src/types.rs +++ b/libwallet/src/types.rs @@ -67,7 +67,13 @@ where ) -> Result<(), Error>; /// - fn open_wallet(&mut self, name: Option<&str>, password: ZeroingString) -> Result<(), Error>; + fn open_wallet( + &mut self, + name: Option<&str>, + password: ZeroingString, + create_mask: bool, + use_test_rng: bool, + ) -> Result, Error>; /// fn close_wallet(&mut self, name: Option<&str>) -> Result<(), Error>; @@ -113,13 +119,22 @@ where K: Keychain + 'ck, { /// Set the keychain, which should already be initialized - fn set_keychain(&mut self, k: Box); + /// Optionally return a token value used to XOR the stored + /// key value + fn set_keychain( + &mut self, + k: Box, + mask: bool, + use_test_rng: bool, + ) -> Result, Error>; /// Close wallet and remove any stored credentials (TBD) fn close(&mut self) -> Result<(), Error>; - /// Return the keychain being used - fn keychain(&mut self) -> Result<&mut K, Error>; + /// Return the keychain being used. Ensure a cloned copy so it will be dropped + /// and zeroized by the caller + /// Can optionally take a mask value + fn keychain(&self, mask: Option<&SecretKey>) -> Result; /// Return the client being used to communicate with the node fn w2n_client(&mut self) -> &mut C; @@ -127,6 +142,7 @@ where /// return the commit for caching if allowed, none otherwise fn calc_commit_for_cache( &mut self, + keychain_mask: Option<&SecretKey>, amount: u64, id: &Identifier, ) -> Result, Error>; @@ -153,6 +169,7 @@ where /// Retrieves the private context associated with a given slate id fn get_private_context( &mut self, + keychain_mask: Option<&SecretKey>, slate_id: &[u8], participant_id: usize, ) -> Result; @@ -173,19 +190,26 @@ where fn get_stored_tx(&self, entry: &TxLogEntry) -> Result, Error>; /// Create a new write batch to update or remove output data - fn batch<'a>(&'a mut self) -> Result + 'a>, Error>; + fn batch<'a>( + &'a mut self, + keychain_mask: Option<&SecretKey>, + ) -> Result + 'a>, Error>; /// Next child ID when we want to create a new output, based on current parent - fn next_child<'a>(&mut self) -> Result; + fn next_child<'a>(&mut self, keychain_mask: Option<&SecretKey>) -> Result; /// last verified height of outputs directly descending from the given parent key fn last_confirmed_height<'a>(&mut self) -> Result; /// Attempt to restore the contents of a wallet from seed - fn restore(&mut self) -> Result<(), Error>; + fn restore(&mut self, keychain_mask: Option<&SecretKey>) -> Result<(), Error>; /// Attempt to check and fix wallet state - fn check_repair(&mut self, delete_unconfirmed: bool) -> Result<(), Error>; + fn check_repair( + &mut self, + keychain_mask: Option<&SecretKey>, + delete_unconfirmed: bool, + ) -> Result<(), Error>; } /// Batch trait to update the output data backend atomically. Trying to use a diff --git a/src/bin/cmd/wallet_args.rs b/src/bin/cmd/wallet_args.rs index bb4f12861..8424a8a3d 100644 --- a/src/bin/cmd/wallet_args.rs +++ b/src/bin/cmd/wallet_args.rs @@ -806,19 +806,27 @@ where } // don't open wallet for certain lifecycle commands - match wallet_args.subcommand() { - ("init", Some(_)) => {} - ("recover", _) => {} + let keychain_mask = match wallet_args.subcommand() { + ("init", Some(_)) => None, + ("recover", _) => None, _ => { let mut wallet_lock = wallet.lock(); let lc = wallet_lock.lc_provider().unwrap(); - lc.open_wallet(None, prompt_password(&global_wallet_args.password))?; + let mask = lc.open_wallet( + None, + prompt_password(&global_wallet_args.password), + true, + false, + )?; if let Some(account) = wallet_args.value_of("account") { let wallet_inst = lc.wallet_inst()?; wallet_inst.set_parent_key_id_by_name(account)?; } + mask } - } + }; + + let km = (&keychain_mask).as_ref(); let res = match wallet_args.subcommand() { ("init", Some(args)) => { @@ -841,42 +849,46 @@ where ("listen", Some(args)) => { let mut c = wallet_config.clone(); let a = arg_parse!(parse_listen_args(&mut c, &args)); - command::listen(wallet, &c, &a, &global_wallet_args.clone()) + command::listen(wallet, keychain_mask, &c, &a, &global_wallet_args.clone()) } ("owner_api", Some(_)) => { let mut g = global_wallet_args.clone(); g.tls_conf = None; - command::owner_api(wallet, &wallet_config, &g) + command::owner_api(wallet, keychain_mask, &wallet_config, &g) + } + ("web", Some(_)) => { + command::owner_api(wallet, keychain_mask, &wallet_config, &global_wallet_args) } - ("web", Some(_)) => command::owner_api(wallet, &wallet_config, &global_wallet_args), ("account", Some(args)) => { let a = arg_parse!(parse_account_args(&args)); - command::account(wallet, a) + command::account(wallet, km, a) } ("send", Some(args)) => { let a = arg_parse!(parse_send_args(&args)); command::send( wallet, + km, a, wallet_config.dark_background_color_scheme.unwrap_or(true), ) } ("receive", Some(args)) => { let a = arg_parse!(parse_receive_args(&args)); - command::receive(wallet, &global_wallet_args, a) + command::receive(wallet, km, &global_wallet_args, a) } ("finalize", Some(args)) => { let a = arg_parse!(parse_finalize_args(&args)); - command::finalize(wallet, a) + command::finalize(wallet, km, a) } ("invoice", Some(args)) => { let a = arg_parse!(parse_issue_invoice_args(&args)); - command::issue_invoice_tx(wallet, a) + command::issue_invoice_tx(wallet, km, a) } ("pay", Some(args)) => { let a = arg_parse!(parse_process_invoice_args(&args)); command::process_invoice( wallet, + km, a, wallet_config.dark_background_color_scheme.unwrap_or(true), ) @@ -885,6 +897,7 @@ where let a = arg_parse!(parse_info_args(&args)); command::info( wallet, + km, &global_wallet_args, a, wallet_config.dark_background_color_scheme.unwrap_or(true), @@ -892,6 +905,7 @@ where } ("outputs", Some(_)) => command::outputs( wallet, + km, &global_wallet_args, wallet_config.dark_background_color_scheme.unwrap_or(true), ), @@ -899,6 +913,7 @@ where let a = arg_parse!(parse_txs_args(&args)); command::txs( wallet, + km, &global_wallet_args, a, wallet_config.dark_background_color_scheme.unwrap_or(true), @@ -906,16 +921,16 @@ where } ("repost", Some(args)) => { let a = arg_parse!(parse_repost_args(&args)); - command::repost(wallet, a) + command::repost(wallet, km, a) } ("cancel", Some(args)) => { let a = arg_parse!(parse_cancel_args(&args)); - command::cancel(wallet, a) + command::cancel(wallet, km, a) } - ("restore", Some(_)) => command::restore(wallet), + ("restore", Some(_)) => command::restore(wallet, km), ("check", Some(args)) => { let a = arg_parse!(parse_check_args(&args)); - command::check_repair(wallet, a) + command::check_repair(wallet, km, a) } _ => { let msg = format!("Unknown wallet command, use 'grin help wallet' for details"); diff --git a/src/bin/cmd/wallet_tests.rs b/src/bin/cmd/wallet_tests.rs index 8b8a8d7ef..1f12a3db8 100644 --- a/src/bin/cmd/wallet_tests.rs +++ b/src/bin/cmd/wallet_tests.rs @@ -32,6 +32,7 @@ mod wallet_tests { use grin_wallet_libwallet::WalletInst; use grin_wallet_util::grin_core::global::{self, ChainTypes}; use grin_wallet_util::grin_keychain::ExtKeychain; + use util::secp::key::SecretKey; use super::super::wallet_args; @@ -123,18 +124,21 @@ mod wallet_tests { passphrase: &str, account: &str, ) -> Result< - Arc< - Mutex< - Box< - WalletInst< - 'static, - DefaultLCProvider<'static, LocalWalletClient, ExtKeychain>, - LocalWalletClient, - ExtKeychain, + ( + Arc< + Mutex< + Box< + WalletInst< + 'static, + DefaultLCProvider<'static, LocalWalletClient, ExtKeychain>, + LocalWalletClient, + ExtKeychain, + >, >, >, >, - >, + Option, + ), grin_wallet_controller::Error, > { wallet_config.chain_type = None; @@ -156,11 +160,12 @@ mod wallet_tests { wallet_config.data_file_dir = top_level_wallet_dir.to_str().unwrap().into(); } lc.set_wallet_directory(&wallet_config.data_file_dir); - lc.open_wallet(None, ZeroingString::from(passphrase)) + let keychain_mask = lc + .open_wallet(None, ZeroingString::from(passphrase), true, false) .unwrap(); let wallet_inst = lc.wallet_inst()?; wallet_inst.set_parent_key_id_by_name(account)?; - Ok(Arc::new(Mutex::new(wallet))) + Ok((Arc::new(Mutex::new(wallet)), keychain_mask)) } fn execute_command( @@ -206,16 +211,28 @@ mod wallet_tests { // add wallet to proxy //let wallet1 = test_framework::create_wallet(&format!("{}/wallet1", test_dir), client1.clone()); let config1 = initial_setup_wallet(test_dir, "wallet1"); - let wallet1 = instantiate_wallet(config1.clone(), client1.clone(), "password", "default")?; - wallet_proxy.add_wallet("wallet1", client1.get_send_instance(), wallet1.clone()); + let (wallet1, mask1_i) = + instantiate_wallet(config1.clone(), client1.clone(), "password", "default")?; + wallet_proxy.add_wallet( + "wallet1", + client1.get_send_instance(), + wallet1.clone(), + mask1_i.clone(), + ); // Create wallet 2 let client2 = LocalWalletClient::new("wallet2", wallet_proxy.tx.clone()); execute_command(&app, test_dir, "wallet2", &client2, arg_vec.clone())?; let config2 = initial_setup_wallet(test_dir, "wallet2"); - let wallet2 = instantiate_wallet(config2.clone(), client2.clone(), "password", "default")?; - wallet_proxy.add_wallet("wallet2", client2.get_send_instance(), wallet2.clone()); + let (wallet2, mask2_i) = + instantiate_wallet(config2.clone(), client2.clone(), "password", "default")?; + wallet_proxy.add_wallet( + "wallet2", + client2.get_send_instance(), + wallet2.clone(), + mask2_i.clone(), + ); // Set the wallet proxy listener running thread::spawn(move || { @@ -271,14 +288,22 @@ mod wallet_tests { // Mine a bit into wallet 1 so we have something to send // (TODO: Be able to stop listeners so we can test this better) - let wallet1 = instantiate_wallet(config1.clone(), client1.clone(), "password", "default")?; - grin_wallet_controller::controller::owner_single_use(wallet1.clone(), |api| { - api.set_active_account("mining")?; + let (wallet1, mask1_i) = + instantiate_wallet(config1.clone(), client1.clone(), "password", "default")?; + let mask1 = (&mask1_i).as_ref(); + grin_wallet_controller::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + api.set_active_account(m, "mining")?; Ok(()) })?; let mut bh = 10u64; - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize, false); + let _ = test_framework::award_blocks_to_wallet( + &chain, + wallet1.clone(), + mask1, + bh as usize, + false, + ); let very_long_message = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef\ ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef\ @@ -342,18 +367,20 @@ mod wallet_tests { execute_command(&app, test_dir, "wallet1", &client1, arg_vec)?; bh += 1; - let wallet1 = instantiate_wallet(config1.clone(), client1.clone(), "password", "default")?; + let (wallet1, mask1_i) = + instantiate_wallet(config1.clone(), client1.clone(), "password", "default")?; + let mask1 = (&mask1_i).as_ref(); // Check our transaction log, should have 10 entries - grin_wallet_controller::controller::owner_single_use(wallet1.clone(), |api| { - api.set_active_account("mining")?; - let (refreshed, txs) = api.retrieve_txs(true, None, None)?; + grin_wallet_controller::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + api.set_active_account(m, "mining")?; + let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?; assert!(refreshed); assert_eq!(txs.len(), bh as usize); Ok(()) })?; - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 10, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 10, false); bh += 10; // update info for each @@ -364,10 +391,13 @@ mod wallet_tests { execute_command(&app, test_dir, "wallet2", &client1, arg_vec)?; // check results in wallet 2 - let wallet2 = instantiate_wallet(config2.clone(), client2.clone(), "password", "default")?; - grin_wallet_controller::controller::owner_single_use(wallet2.clone(), |api| { - api.set_active_account("account_1")?; - let (_, wallet1_info) = api.retrieve_summary_info(true, 1)?; + let (wallet2, mask2_i) = + instantiate_wallet(config2.clone(), client2.clone(), "password", "default")?; + let mask2 = (&mask2_i).as_ref(); + + grin_wallet_controller::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + api.set_active_account(m, "account_1")?; + let (_, wallet1_info) = api.retrieve_summary_info(m, true, 1)?; assert_eq!(wallet1_info.last_confirmed_height, bh); assert_eq!(wallet1_info.amount_currently_spendable, 10_000_000_000); Ok(()) @@ -419,11 +449,13 @@ mod wallet_tests { bh += 1; // Check our transaction log, should have bh entries + one for the self receive - let wallet1 = instantiate_wallet(config1.clone(), client1.clone(), "password", "default")?; + let (wallet1, mask1_i) = + instantiate_wallet(config1.clone(), client1.clone(), "password", "default")?; + let mask1 = (&mask1_i).as_ref(); - grin_wallet_controller::controller::owner_single_use(wallet1.clone(), |api| { - api.set_active_account("mining")?; - let (refreshed, txs) = api.retrieve_txs(true, None, None)?; + grin_wallet_controller::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + api.set_active_account(m, "mining")?; + let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?; assert!(refreshed); assert_eq!(txs.len(), bh as usize + 1); Ok(()) @@ -453,11 +485,13 @@ mod wallet_tests { bh += 1; // Check our transaction log, should have bh entries + 2 for the self receives - let wallet1 = instantiate_wallet(config1.clone(), client1.clone(), "password", "default")?; + let (wallet1, mask1_i) = + instantiate_wallet(config1.clone(), client1.clone(), "password", "default")?; + let mask1 = (&mask1_i).as_ref(); - grin_wallet_controller::controller::owner_single_use(wallet1.clone(), |api| { - api.set_active_account("mining")?; - let (refreshed, txs) = api.retrieve_txs(true, None, None)?; + grin_wallet_controller::controller::owner_single_use(wallet1.clone(), mask1, |api, m| { + api.set_active_account(m, "mining")?; + let (refreshed, txs) = api.retrieve_txs(m, true, None, None)?; assert!(refreshed); assert_eq!(txs.len(), bh as usize + 2); Ok(()) @@ -559,7 +593,7 @@ mod wallet_tests { execute_command(&app, test_dir, "wallet2", &client2, arg_vec)?; // bit more mining - let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5, false); + let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 5, false); //bh += 5; // txs and outputs (mostly spit out for a visual in test logs) @@ -591,9 +625,9 @@ mod wallet_tests { // get tx output via -tx parameter let mut tx_id = "".to_string(); - grin_wallet_controller::controller::owner_single_use(wallet2.clone(), |api| { - api.set_active_account("default")?; - let (_, txs) = api.retrieve_txs(true, None, None)?; + grin_wallet_controller::controller::owner_single_use(wallet2.clone(), mask2, |api, m| { + api.set_active_account(m, "default")?; + let (_, txs) = api.retrieve_txs(m, true, None, None)?; let some_tx_id = txs[0].tx_slate_id.clone(); assert!(some_tx_id.is_some()); tx_id = some_tx_id.unwrap().to_hyphenated().to_string().clone(); diff --git a/util/Cargo.toml b/util/Cargo.toml index ca4046930..2700825a8 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -41,12 +41,12 @@ grin_api = { git = "https://github.com/mimblewimble/grin", branch = "master" } grin_store = { git = "https://github.com/mimblewimble/grin", branch = "master" } # For local testing -#grin_core = { path = "../../grin/core", version= "2.0.0-beta.2"} -#grin_keychain = { path = "../../grin/keychain", version= "2.0.0-beta.2"} -#grin_chain = { path = "../../grin/chain", version= "2.0.0-beta.2"} -#grin_util = { path = "../../grin/util", version= "2.0.0-beta.2"} -#grin_api = { path = "../../grin/api", version= "2.0.0-beta.2"} -#grin_store = { path = "../../grin/store", version= "2.0.0-beta.2"} +#grin_core = { path = "../../grin/core", version= "2.0.1-beta.1"} +#grin_keychain = { path = "../../grin/keychain", version= "2.0.1-beta.1"} +#grin_chain = { path = "../../grin/chain", version= "2.0.1-beta.1"} +#grin_util = { path = "../../grin/util", version= "2.0.1-beta.1"} +#grin_api = { path = "../../grin/api", version= "2.0.1-beta.1"} +#grin_store = { path = "../../grin/store", version= "2.0.1-beta.1"} [dev-dependencies] pretty_assertions = "0.5.1"