[WIP] V2 API Doctest generation (#24)

V2 API Doctest generation
This commit is contained in:
Yeastplume 2019-03-22 12:03:25 +00:00 committed by GitHub
parent 64772e6021
commit 94960b3edd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 1645 additions and 725 deletions

108
Cargo.lock generated
View file

@ -1,3 +1,5 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]] [[package]]
name = "adler32" name = "adler32"
version = "1.0.3" version = "1.0.3"
@ -88,7 +90,7 @@ name = "backtrace-sys"
version = "0.1.28" version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -190,7 +192,7 @@ dependencies = [
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.30" version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -286,7 +288,7 @@ version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"bindgen 0.37.4 (registry+https://github.com/rust-lang/crates.io-index)", "bindgen 0.37.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -473,7 +475,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.6" version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -553,7 +555,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "grin_api" name = "grin_api"
version = "1.1.0" version = "1.1.0"
source = "git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0#c3496b45dd2704b6d542dad3447e8649d25399e4" source = "git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0#2e72ed91f3d1616d9c553e97d489bc2e6b4032b1"
dependencies = [ dependencies = [
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -585,7 +587,7 @@ dependencies = [
[[package]] [[package]]
name = "grin_chain" name = "grin_chain"
version = "1.1.0" version = "1.1.0"
source = "git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0#c3496b45dd2704b6d542dad3447e8649d25399e4" source = "git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0#2e72ed91f3d1616d9c553e97d489bc2e6b4032b1"
dependencies = [ dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -599,7 +601,7 @@ dependencies = [
"grin_util 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", "grin_util 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)",
"lazy_static 1.3.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)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lru-cache 0.1.1 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
@ -608,7 +610,7 @@ dependencies = [
[[package]] [[package]]
name = "grin_core" name = "grin_core"
version = "1.1.0" version = "1.1.0"
source = "git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0#c3496b45dd2704b6d542dad3447e8649d25399e4" source = "git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0#2e72ed91f3d1616d9c553e97d489bc2e6b4032b1"
dependencies = [ dependencies = [
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -621,7 +623,7 @@ dependencies = [
"grin_util 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", "grin_util 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)",
"lazy_static 1.3.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)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lru-cache 0.1.1 (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 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)", "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -634,7 +636,7 @@ dependencies = [
[[package]] [[package]]
name = "grin_keychain" name = "grin_keychain"
version = "1.1.0" version = "1.1.0"
source = "git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0#c3496b45dd2704b6d542dad3447e8649d25399e4" source = "git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0#2e72ed91f3d1616d9c553e97d489bc2e6b4032b1"
dependencies = [ dependencies = [
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -656,7 +658,7 @@ dependencies = [
[[package]] [[package]]
name = "grin_p2p" name = "grin_p2p"
version = "1.1.0" version = "1.1.0"
source = "git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0#c3496b45dd2704b6d542dad3447e8649d25399e4" source = "git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0#2e72ed91f3d1616d9c553e97d489bc2e6b4032b1"
dependencies = [ dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
@ -676,7 +678,7 @@ dependencies = [
[[package]] [[package]]
name = "grin_pool" name = "grin_pool"
version = "1.1.0" version = "1.1.0"
source = "git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0#c3496b45dd2704b6d542dad3447e8649d25399e4" source = "git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0#2e72ed91f3d1616d9c553e97d489bc2e6b4032b1"
dependencies = [ dependencies = [
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -709,7 +711,7 @@ dependencies = [
[[package]] [[package]]
name = "grin_store" name = "grin_store"
version = "1.1.0" version = "1.1.0"
source = "git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0#c3496b45dd2704b6d542dad3447e8649d25399e4" source = "git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0#2e72ed91f3d1616d9c553e97d489bc2e6b4032b1"
dependencies = [ dependencies = [
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"croaring 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "croaring 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -729,7 +731,7 @@ dependencies = [
[[package]] [[package]]
name = "grin_util" name = "grin_util"
version = "1.1.0" version = "1.1.0"
source = "git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0#c3496b45dd2704b6d542dad3447e8649d25399e4" source = "git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0#2e72ed91f3d1616d9c553e97d489bc2e6b4032b1"
dependencies = [ dependencies = [
"backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -777,6 +779,7 @@ dependencies = [
name = "grin_wallet_api" name = "grin_wallet_api"
version = "1.1.0" version = "1.1.0"
dependencies = [ dependencies = [
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"easy-jsonrpc 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "easy-jsonrpc 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -792,7 +795,7 @@ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.39 (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.7 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -839,7 +842,7 @@ dependencies = [
"tokio-core 0.1.17 (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)", "tokio-retry 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -868,7 +871,7 @@ dependencies = [
"tokio 0.1.11 (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-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)", "tokio-retry 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -884,17 +887,18 @@ dependencies = [
"grin_store 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", "grin_store 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)",
"grin_util 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)", "grin_util 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)",
"grin_wallet_config 1.1.0", "grin_wallet_config 1.1.0",
"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.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.6 (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.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.1.16" version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -957,7 +961,7 @@ dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-cpupool 0.1.8 (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.16 (registry+https://github.com/rust-lang/crates.io-index)", "h2 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1063,7 +1067,7 @@ name = "libgit2-sys"
version = "0.7.11" version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.25 (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.14 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1083,7 +1087,7 @@ name = "libloading"
version = "0.5.0" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -1092,7 +1096,7 @@ name = "libz-sys"
version = "1.0.25" version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.50 (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.14 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1110,12 +1114,7 @@ dependencies = [
[[package]] [[package]]
name = "linked-hash-map" name = "linked-hash-map"
version = "0.4.2" version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "linked-hash-map"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -1160,7 +1159,7 @@ dependencies = [
"antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.6 (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)", "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1178,10 +1177,10 @@ dependencies = [
[[package]] [[package]]
name = "lru-cache" name = "lru-cache"
version = "0.1.1" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -1221,7 +1220,7 @@ name = "miniz-sys"
version = "0.1.11" version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -1238,7 +1237,7 @@ name = "miniz_oxide_c_api"
version = "0.2.1" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"crc 1.8.1 (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.50 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1336,7 +1335,7 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1493,7 +1492,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "ordered-float" name = "ordered-float"
version = "1.0.1" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1871,7 +1870,7 @@ name = "ring"
version = "0.13.5" version = "0.13.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2009,7 +2008,7 @@ name = "serde-value"
version = "0.5.3" version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"ordered-float 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -2039,7 +2038,7 @@ version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"linked-hash-map 0.5.1 (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.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
"yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -2308,7 +2307,7 @@ dependencies = [
"slab 0.4.2 (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.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 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-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-sync 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-sync 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -2342,7 +2341,7 @@ dependencies = [
[[package]] [[package]]
name = "tokio-sync" name = "tokio-sync"
version = "0.1.3" version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2525,6 +2524,15 @@ dependencies = [
"serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "uuid"
version = "0.7.2"
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.89 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "vcpkg" name = "vcpkg"
version = "0.2.6" version = "0.2.6"
@ -2656,7 +2664,7 @@ name = "yaml-rust"
version = "0.4.3" version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -2699,7 +2707,7 @@ dependencies = [
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
"checksum cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)" = "d01c69d08ff207f231f07196e30f84c70f1c815b04f980f8b7b01ff01f05eb92" "checksum cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ce8bb087aacff865633f0bd5aeaed910fe2fe55b55f4739527f2e023a2e53d"
"checksum cexpr 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42aac45e9567d97474a834efdee3081b3c942b2205be932092f53354ce503d6c" "checksum cexpr 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42aac45e9567d97474a834efdee3081b3c942b2205be932092f53354ce503d6c"
"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
@ -2732,7 +2740,7 @@ dependencies = [
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2291c165c8e703ee54ef3055ad6188e3d51108e2ded18e9f2476e774fc5ad3d4" "checksum flate2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f87e68aa82b2de08a6e037f1385455759df6e445a8df5e005b4297191dbf18aa"
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
@ -2752,7 +2760,7 @@ dependencies = [
"checksum grin_secp256k1zkp 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "75e9a265f3eeea4c204470f7262e2c6fe18f3d8ddf5fb24340cb550ac4f909c5" "checksum grin_secp256k1zkp 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "75e9a265f3eeea4c204470f7262e2c6fe18f3d8ddf5fb24340cb550ac4f909c5"
"checksum grin_store 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)" = "<none>" "checksum grin_store 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)" = "<none>"
"checksum grin_util 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)" = "<none>" "checksum grin_util 1.1.0 (git+https://github.com/mimblewimble/grin?branch=milestone/1.1.0)" = "<none>"
"checksum h2 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "ddb2b25a33e231484694267af28fec74ac63b5ccf51ee2065a5e313b834d836e" "checksum h2 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "910a5e7be6283a9c91b3982fa5188368c8719cce2a3cf3b86048673bf9d9c36b"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "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 hmac 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "733e1b3ac906631ca01ebb577e9bb0f5e37a454032b9036b5eaea4013ed6f99a"
"checksum http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fe67e3678f2827030e89cc4b9e7ecd16d52f132c0b940ab5005f88e821500f6a" "checksum http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fe67e3678f2827030e89cc4b9e7ecd16d52f132c0b940ab5005f88e821500f6a"
@ -2774,14 +2782,13 @@ dependencies = [
"checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" "checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2"
"checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" "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 linefeed 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5c2abb5810ef55bb5f5f33b010cc280b3ab877764c902681efc7c8c95628004c"
"checksum linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7860ec297f7008ff7a1e3382d7f7e1dcd69efc94751a2284bafc3d013c2aa939" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
"checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e"
"checksum lmdb-zero 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "13416eee745b087c22934f35f1f24da22da41ba2a5ce197143d168ce055cc58d" "checksum lmdb-zero 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "13416eee745b087c22934f35f1f24da22da41ba2a5ce197143d168ce055cc58d"
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum lock_api 0.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.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
"checksum log-mdc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7" "checksum log-mdc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7"
"checksum log4rs 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "25e0fc8737a634116a2deb38d821e4400ed16ce9dcb0d628a978d399260f5902" "checksum log4rs 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "25e0fc8737a634116a2deb38d821e4400ed16ce9dcb0d628a978d399260f5902"
"checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21" "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 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 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.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
@ -2815,7 +2822,7 @@ dependencies = [
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba" "checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
"checksum odds 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "4eae0151b9dacf24fcc170d9995e511669a082856a91f958a2fe380bfab3fb22" "checksum odds 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "4eae0151b9dacf24fcc170d9995e511669a082856a91f958a2fe380bfab3fb22"
"checksum ordered-float 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2f0015e9e8e28ee20c581cfbfe47c650cedeb9ed0721090e0b7ebb10b9cdbcc2" "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" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5"
"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
@ -2911,7 +2918,7 @@ dependencies = [
"checksum tokio-retry 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f05746ae87dca83a2016b4f5dba5b237b897dd12fd324f60afe282112f16969a" "checksum tokio-retry 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f05746ae87dca83a2016b4f5dba5b237b897dd12fd324f60afe282112f16969a"
"checksum tokio-rustls 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "208d62fa3e015426e3c64039d9d20adf054a3c9b4d9445560f1c41c75bef3eab" "checksum tokio-rustls 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "208d62fa3e015426e3c64039d9d20adf054a3c9b4d9445560f1c41c75bef3eab"
"checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162"
"checksum tokio-sync 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1bf2b9dac2a0509b5cfd1df5aa25eafacb616a42a491a13604d6bbeab4486363" "checksum tokio-sync 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fda385df506bf7546e70872767f71e81640f1f251bdf2fd8eb81a0eaec5fe022"
"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119"
"checksum tokio-threadpool 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "742e511f6ce2298aeb86fc9ea0d8df81c2388c6ebae3dc8a7316e8c9df0df801" "checksum tokio-threadpool 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "742e511f6ce2298aeb86fc9ea0d8df81c2388c6ebae3dc8a7316e8c9df0df801"
"checksum tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2910970404ba6fa78c5539126a9ae2045d62e3713041e447f695f41405a120c6" "checksum tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2910970404ba6fa78c5539126a9ae2045d62e3713041e447f695f41405a120c6"
@ -2933,6 +2940,7 @@ dependencies = [
"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" "checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
"checksum uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363" "checksum uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363"
"checksum uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0238db0c5b605dd1cf51de0f21766f97fba2645897024461d6a00c036819a768"
"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" "checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"

View file

@ -14,11 +14,14 @@ edition = "2018"
failure = "0.1" failure = "0.1"
failure_derive = "0.1" failure_derive = "0.1"
log = "0.4" log = "0.4"
uuid = { version = "0.6", features = ["serde", "v4"] } uuid = { version = "0.7", features = ["serde", "v4"] }
serde_json = "1"
easy-jsonrpc = "0.4.1" easy-jsonrpc = "0.4.1"
chrono = { version = "0.4.4", features = ["serde"] }
grin_wallet_libwallet = { path = "../libwallet", version = "1.1.0" } grin_wallet_libwallet = { path = "../libwallet", version = "1.1.0" }
grin_wallet_config = { path = "../config", version = "1.1.0" } grin_wallet_config = { path = "../config", version = "1.1.0" }
grin_wallet_impls = { path = "../impls", version = "1.1.0" }
grin_core = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" } grin_core = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" }
grin_keychain = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" } grin_keychain = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" }
@ -28,6 +31,5 @@ grin_api = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1
grin_store = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" } grin_store = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" }
[dev-dependencies] [dev-dependencies]
grin_wallet_impls = { path = "../impls", version = "1.1.0" }
serde_json = "1" serde_json = "1"
tempfile = "3.0.7" tempfile = "3.0.7"

View file

@ -88,7 +88,7 @@ where
) -> Result<(), Error> { ) -> Result<(), Error> {
let mut w = self.wallet.lock(); let mut w = self.wallet.lock();
w.open_with_credentials()?; w.open_with_credentials()?;
let res = foreign::receive_tx(&mut *w, slate, dest_acct_name, message); let res = foreign::receive_tx(&mut *w, slate, dest_acct_name, message, false);
w.close()?; w.close()?;
res res
} }

View file

@ -29,6 +29,7 @@ extern crate grin_util as util;
extern crate grin_wallet_libwallet as libwallet; extern crate grin_wallet_libwallet as libwallet;
extern crate failure_derive; extern crate failure_derive;
extern crate serde_json;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
@ -41,3 +42,5 @@ pub use crate::foreign::Foreign;
pub use crate::foreign_rpc::ForeignRpc; pub use crate::foreign_rpc::ForeignRpc;
pub use crate::owner::Owner; pub use crate::owner::Owner;
pub use crate::owner_rpc::OwnerRpc; pub use crate::owner_rpc::OwnerRpc;
pub use crate::owner_rpc::run_doctest;

View file

@ -27,6 +27,7 @@
//! seed). //! seed).
use crate::util::Mutex; use crate::util::Mutex;
use chrono::prelude::*;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::sync::Arc; use std::sync::Arc;
use uuid::Uuid; use uuid::Uuid;
@ -36,10 +37,10 @@ use crate::keychain::{Identifier, Keychain};
use crate::libwallet::api_impl::owner; use crate::libwallet::api_impl::owner;
use crate::libwallet::slate::Slate; use crate::libwallet::slate::Slate;
use crate::libwallet::types::{ use crate::libwallet::types::{
AcctPathMapping, NodeClient, OutputData, TxLogEntry, WalletBackend, WalletInfo, AcctPathMapping, NodeClient, OutputCommitMapping, TxEstimation, TxLogEntry, WalletBackend,
WalletInfo,
}; };
use crate::libwallet::Error; use crate::libwallet::Error;
use crate::util::secp::pedersen;
/// Functions intended for use by the owner (e.g. master seed holder) of the wallet. /// Functions intended for use by the owner (e.g. master seed holder) of the wallet.
pub struct Owner<W: ?Sized, C, K> pub struct Owner<W: ?Sized, C, K>
@ -49,8 +50,10 @@ where
K: Keychain, K: Keychain,
{ {
/// A reference-counted mutex to an implementation of the /// A reference-counted mutex to an implementation of the
/// [`WalletBackend`](../types/trait.WalletBackend.html) trait. /// [`WalletBackend`](../grin_wallet_libwallet/types/trait.WalletBackend.html) trait.
pub wallet: Arc<Mutex<W>>, pub wallet: Arc<Mutex<W>>,
/// Flag to normalize some output during testing. Can mostly be ignored.
pub doctest_mode: bool,
phantom: PhantomData<K>, phantom: PhantomData<K>,
phantom_c: PhantomData<C>, phantom_c: PhantomData<C>,
} }
@ -64,37 +67,46 @@ where
/// Create a new API instance with the given wallet instance. All subsequent /// Create a new API instance with the given wallet instance. All subsequent
/// API calls will operate on this instance of the wallet. /// API calls will operate on this instance of the wallet.
/// ///
/// Each method will call the [`WalletBackend`](../types/trait.WalletBackend.html)'s /// Each method will call the [`WalletBackend`](../grin_wallet_libwallet/types/trait.WalletBackend.html)'s
/// [`open_with_credentials`](../types/trait.WalletBackend.html#tymethod.open_with_credentials) /// [`open_with_credentials`](../grin_wallet_libwallet/types/trait.WalletBackend.html#tymethod.open_with_credentials)
/// (initialising a keychain with the master seed,) perform its operation, then close the keychain /// (initialising a keychain with the master seed,) perform its operation, then close the keychain
/// with a call to [`close`](../types/trait.WalletBackend.html#tymethod.close) /// with a call to [`close`](../grin_wallet_libwallet/types/trait.WalletBackend.html#tymethod.close)
/// ///
/// # Arguments /// # Arguments
/// * `wallet_in` - A reference-counted mutex containing an implementation of the /// * `wallet_in` - A reference-counted mutex containing an implementation of the
/// [`WalletBackend`](../types/trait.WalletBackend.html) trait. /// [`WalletBackend`](../grin_wallet_libwallet/types/trait.WalletBackend.html) trait.
/// ///
/// # Returns /// # Returns
/// * An instance of the OwnerApi holding a reference to the provided wallet /// * An instance of the OwnerApi holding a reference to the provided wallet
/// ///
/// # Example /// # Example
/// ``` ignore /// ```
/// # extern crate grin_wallet_config as config; /// use grin_keychain as keychain;
/// # extern crate grin_refwallet as wallet; /// use grin_util as util;
/// # extern crate grin_keychain as keychain; /// use grin_wallet_api as api;
/// # extern crate grin_util as util; /// use grin_wallet_config as config;
/// use grin_wallet_impls as impls;
/// use grin_wallet_libwallet as libwallet;
///
/// use keychain::ExtKeychain;
/// use tempfile::tempdir;
/// ///
/// use std::sync::Arc; /// use std::sync::Arc;
/// use util::Mutex; /// use util::Mutex;
/// ///
/// use keychain::ExtKeychain; /// use api::Owner;
/// use wallet::libwallet::api::Owner;
///
/// // These contain sample implementations of each part needed for a wallet
/// use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend};
/// use config::WalletConfig; /// use config::WalletConfig;
/// use impls::{HTTPNodeClient, LMDBBackend};
/// use libwallet::types::WalletBackend;
/// ///
/// let mut wallet_config = WalletConfig::default(); /// let mut wallet_config = WalletConfig::default();
/// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned(); /// # let dir = tempdir().map_err(|e| format!("{:#?}", e)).unwrap();
/// # let dir = dir
/// # .path()
/// # .to_str()
/// # .ok_or("Failed to convert tmpdir path to string.".to_owned())
/// # .unwrap();
/// # wallet_config.data_file_dir = dir.to_owned();
/// ///
/// // A NodeClient must first be created to handle communication between /// // A NodeClient must first be created to handle communication between
/// // the wallet and the node. /// // the wallet and the node.
@ -113,6 +125,7 @@ where
pub fn new(wallet_in: Arc<Mutex<W>>) -> Self { pub fn new(wallet_in: Arc<Mutex<W>>) -> Self {
Owner { Owner {
wallet: wallet_in, wallet: wallet_in,
doctest_mode: false,
phantom: PhantomData, phantom: PhantomData,
phantom_c: PhantomData, phantom_c: PhantomData,
} }
@ -123,8 +136,8 @@ where
/// ///
/// # Returns /// # Returns
/// * Result Containing: /// * Result Containing:
/// * A Vector of [`AcctPathMapping`](../types/struct.AcctPathMapping.html) data /// * A Vector of [`AcctPathMapping`](../grin_wallet_libwallet/types/struct.AcctPathMapping.html) data
/// * or [`libwallet::Error`](../struct.Error.html) if an error is encountered. /// * or [`libwallet::Error`](../grin_wallet_libwallet/struct.Error.html) if an error is encountered.
/// ///
/// # Remarks /// # Remarks
/// ///
@ -134,24 +147,8 @@ where
/// ///
/// # Example /// # Example
/// Set up as in [`new`](struct.Owner.html#method.new) method above. /// Set up as in [`new`](struct.Owner.html#method.new) method above.
/// ``` ignore /// ```
/// # extern crate grin_wallet_config as config; /// # grin_wallet_api::doctest_helper_setup_doc_env!(wallet, wallet_config);
/// # extern crate grin_refwallet as wallet;
/// # extern crate grin_keychain as keychain;
/// # extern crate grin_util as util;
/// # use std::sync::Arc;
/// # use util::Mutex;
/// # use keychain::ExtKeychain;
/// # use wallet::libwallet::api::Owner;
/// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend};
/// # use config::WalletConfig;
/// # let mut wallet_config = WalletConfig::default();
/// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned();
/// # let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
/// # let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
/// # Arc::new(Mutex::new(
/// # LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap()
/// # ));
/// ///
/// let api_owner = Owner::new(wallet.clone()); /// let api_owner = Owner::new(wallet.clone());
/// ///
@ -175,8 +172,8 @@ where
/// ///
/// # Returns /// # Returns
/// * Result Containing: /// * Result Containing:
/// * A [Keychain Identifier](#) for the new path /// * A [Keychain Identifier](../grin_keychain/struct.Identifier.html) for the new path
/// * or [`libwallet::Error`](../struct.Error.html) if an error is encountered. /// * or [`libwallet::Error`](../grin_wallet_libwallet/struct.Error.html) if an error is encountered.
/// ///
/// # Remarks /// # Remarks
/// ///
@ -192,22 +189,8 @@ where
/// ///
/// # Example /// # Example
/// Set up as in [`new`](struct.Owner.html#method.new) method above. /// Set up as in [`new`](struct.Owner.html#method.new) method above.
/// ``` ignore /// ```
/// # extern crate grin_wallet as wallet; /// # grin_wallet_api::doctest_helper_setup_doc_env!(wallet, wallet_config);
/// # extern crate grin_keychain as keychain;
/// # extern crate grin_util as util;
/// # use std::sync::Arc;
/// # use util::Mutex;
/// # use keychain::ExtKeychain;
/// # use wallet::libwallet::api::Owner;
/// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig};
/// # let mut wallet_config = WalletConfig::default();
/// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned();
/// # let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
/// # let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
/// # Arc::new(Mutex::new(
/// # LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap()
/// # ));
/// ///
/// let api_owner = Owner::new(wallet.clone()); /// let api_owner = Owner::new(wallet.clone());
/// ///
@ -233,7 +216,7 @@ where
/// # Returns /// # Returns
/// * Result Containing: /// * Result Containing:
/// * `Ok(())` if the path was correctly set /// * `Ok(())` if the path was correctly set
/// * or [`libwallet::Error`](../struct.Error.html) if an error is encountered. /// * or [`libwallet::Error`](../grin_wallet_libwallet/struct.Error.html) if an error is encountered.
/// ///
/// # Remarks /// # Remarks
/// ///
@ -246,22 +229,8 @@ where
/// ///
/// # Example /// # Example
/// Set up as in [`new`](struct.Owner.html#method.new) method above. /// Set up as in [`new`](struct.Owner.html#method.new) method above.
/// ``` ignore /// ```
/// # extern crate grin_wallet as wallet; /// # grin_wallet_api::doctest_helper_setup_doc_env!(wallet, wallet_config);
/// # extern crate grin_keychain as keychain;
/// # extern crate grin_util as util;
/// # use std::sync::Arc;
/// # use util::Mutex;
/// # use keychain::ExtKeychain;
/// # use wallet::libwallet::api::Owner;
/// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig};
/// # let mut wallet_config = WalletConfig::default();
/// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned();
/// # let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
/// # let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
/// # Arc::new(Mutex::new(
/// # LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap()
/// # ));
/// ///
/// let api_owner = Owner::new(wallet.clone()); /// let api_owner = Owner::new(wallet.clone());
/// ///
@ -285,7 +254,7 @@ where
/// in the wallet will be returned. If `false`, spent outputs will omitted /// in the wallet will be returned. If `false`, spent outputs will omitted
/// from the results. /// from the results.
/// * `refresh_from_node` - If true, the wallet will attempt to contact /// * `refresh_from_node` - If true, the wallet will attempt to contact
/// a node (via the [`NodeClient`](../types/trait.NodeClient.html) /// a node (via the [`NodeClient`](../grin_wallet_libwallet/types/trait.NodeClient.html)
/// provided during wallet instantiation). If `false`, the results will /// provided during wallet instantiation). If `false`, the results will
/// contain output information that may be out-of-date (from the last time /// contain output information that may be out-of-date (from the last time
/// the wallet's output set was refreshed against the node). /// the wallet's output set was refreshed against the node).
@ -293,32 +262,20 @@ where
/// the transaction log entry of id `i`. /// the transaction log entry of id `i`.
/// ///
/// # Returns /// # Returns
/// * (`bool`, `Vec<OutputData, Commitment>`) - A tuple: /// * `(bool, Vec<OutputCommitMapping>)` - A tuple:
/// * The first `bool` element indicates whether the data was successfully /// * The first `bool` element indicates whether the data was successfully
/// refreshed from the node (note this may be false even if the `refresh_from_node` /// refreshed from the node (note this may be false even if the `refresh_from_node`
/// argument was set to `true`. /// argument was set to `true`.
/// * The second element contains the result set, of which each element is /// * The second element contains a vector of
/// a mapping between the wallet's internal [OutputData](../types/struct.OutputData.html) /// [OutputCommitMapping](../grin_wallet_libwallet/types/struct.OutputCommitMapping.html)
/// of which each element is a mapping between the wallet's internal
/// [OutputData](../grin_wallet_libwallet/types/struct.Output.html)
/// and the Output commitment as identified in the chain's UTXO set /// and the Output commitment as identified in the chain's UTXO set
/// ///
/// # Example /// # Example
/// Set up as in [`new`](struct.Owner.html#method.new) method above. /// Set up as in [`new`](struct.Owner.html#method.new) method above.
/// ``` ignore /// ```
/// # extern crate grin_wallet as wallet; /// # grin_wallet_api::doctest_helper_setup_doc_env!(wallet, wallet_config);
/// # extern crate grin_keychain as keychain;
/// # extern crate grin_util as util;
/// # use std::sync::Arc;
/// # use util::Mutex;
/// # use keychain::ExtKeychain;
/// # use wallet::libwallet::api::Owner;
/// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig};
/// # let mut wallet_config = WalletConfig::default();
/// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned();
/// # let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
/// # let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
/// # Arc::new(Mutex::new(
/// # LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap()
/// # ));
/// ///
/// let api_owner = Owner::new(wallet.clone()); /// let api_owner = Owner::new(wallet.clone());
/// let show_spent = false; /// let show_spent = false;
@ -327,7 +284,7 @@ where
/// ///
/// let result = api_owner.retrieve_outputs(show_spent, update_from_node, tx_id); /// let result = api_owner.retrieve_outputs(show_spent, update_from_node, tx_id);
/// ///
/// if let Ok((was_updated, output_mapping)) = result { /// if let Ok((was_updated, output_mappings)) = result {
/// //... /// //...
/// } /// }
/// ``` /// ```
@ -337,7 +294,7 @@ where
include_spent: bool, include_spent: bool,
refresh_from_node: bool, refresh_from_node: bool,
tx_id: Option<u32>, tx_id: Option<u32>,
) -> Result<(bool, Vec<(OutputData, pedersen::Commitment)>), Error> { ) -> Result<(bool, Vec<OutputCommitMapping>), Error> {
let mut w = self.wallet.lock(); let mut w = self.wallet.lock();
w.open_with_credentials()?; w.open_with_credentials()?;
let res = owner::retrieve_outputs(&mut *w, include_spent, refresh_from_node, tx_id); let res = owner::retrieve_outputs(&mut *w, include_spent, refresh_from_node, tx_id);
@ -345,46 +302,32 @@ where
res res
} }
/// Returns a list of [Transaction Log Entries](../types/struct.TxLogEntry.html) /// Returns a list of [Transaction Log Entries](../grin_wallet_libwallet/types/struct.TxLogEntry.html)
/// from the active account in the wallet. /// from the active account in the wallet.
/// ///
/// # Arguments /// # Arguments
/// * `refresh_from_node` - If true, the wallet will attempt to contact /// * `refresh_from_node` - If true, the wallet will attempt to contact
/// a node (via the [`NodeClient`](../types/trait.NodeClient.html) /// a node (via the [`NodeClient`](../grin_wallet_libwallet/types/trait.NodeClient.html)
/// provided during wallet instantiation). If `false`, the results will /// provided during wallet instantiation). If `false`, the results will
/// contain transaction information that may be out-of-date (from the last time /// contain transaction information that may be out-of-date (from the last time
/// the wallet's output set was refreshed against the node). /// the wallet's output set was refreshed against the node).
/// * `tx_id` - If `Some(i)`, only return the transactions associated with /// * `tx_id` - If `Some(i)`, only return the transactions associated with
/// the transaction log entry of id `i`. /// the transaction log entry of id `i`.
/// * `tx_slate_id` - If `Some(uuid)`, only return transactions associated with /// * `tx_slate_id` - If `Some(uuid)`, only return transactions associated with
/// the given [`Slate`](../../libtx/slate/struct.Slate.html) uuid. /// the given [`Slate`](../grin_wallet_libwallet/slate/struct.Slate.html) uuid.
/// ///
/// # Returns /// # Returns
/// * (`bool`, `Vec<[TxLogEntry](../types/struct.TxLogEntry.html)>`) - A tuple: /// * `(bool, Vec<TxLogEntry)` - A tuple:
/// * The first `bool` element indicates whether the data was successfully /// * The first `bool` element indicates whether the data was successfully
/// refreshed from the node (note this may be false even if the `refresh_from_node` /// refreshed from the node (note this may be false even if the `refresh_from_node`
/// argument was set to `true`. /// argument was set to `true`.
/// * The second element contains the set of retrieved /// * The second element contains the set of retrieved
/// [TxLogEntries](../types/struct/TxLogEntry.html) /// [TxLogEntries](../grin_wallet_libwallet/types/struct.TxLogEntry.html)
/// ///
/// # Example /// # Example
/// Set up as in [`new`](struct.Owner.html#method.new) method above. /// Set up as in [`new`](struct.Owner.html#method.new) method above.
/// ``` ignore /// ```
/// # extern crate grin_wallet as wallet; /// # grin_wallet_api::doctest_helper_setup_doc_env!(wallet, wallet_config);
/// # extern crate grin_keychain as keychain;
/// # extern crate grin_util as util;
/// # use std::sync::Arc;
/// # use util::Mutex;
/// # use keychain::ExtKeychain;
/// # use wallet::libwallet::api::Owner;
/// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig};
/// # let mut wallet_config = WalletConfig::default();
/// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned();
/// # let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
/// # let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
/// # Arc::new(Mutex::new(
/// # LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap()
/// # ));
/// ///
/// let api_owner = Owner::new(wallet.clone()); /// let api_owner = Owner::new(wallet.clone());
/// let update_from_node = true; /// let update_from_node = true;
@ -407,16 +350,27 @@ where
) -> Result<(bool, Vec<TxLogEntry>), Error> { ) -> Result<(bool, Vec<TxLogEntry>), Error> {
let mut w = self.wallet.lock(); let mut w = self.wallet.lock();
w.open_with_credentials()?; w.open_with_credentials()?;
let res = owner::retrieve_txs(&mut *w, refresh_from_node, tx_id, tx_slate_id); let mut res = owner::retrieve_txs(&mut *w, refresh_from_node, tx_id, tx_slate_id)?;
if self.doctest_mode {
res.1 = res
.1
.into_iter()
.map(|mut t| {
t.confirmation_ts = Some(Utc.ymd(2019, 1, 15).and_hms(16, 1, 26));
t.creation_ts = Utc.ymd(2019, 1, 15).and_hms(16, 1, 26);
t
})
.collect();
}
w.close()?; w.close()?;
res Ok(res)
} }
/// Returns summary information from the active account in the wallet. /// Returns summary information from the active account in the wallet.
/// ///
/// # Arguments /// # Arguments
/// * `refresh_from_node` - If true, the wallet will attempt to contact /// * `refresh_from_node` - If true, the wallet will attempt to contact
/// a node (via the [`NodeClient`](../types/trait.NodeClient.html) /// a node (via the [`NodeClient`](../grin_wallet_libwallet/types/trait.NodeClient.html)
/// provided during wallet instantiation). If `false`, the results will /// provided during wallet instantiation). If `false`, the results will
/// contain transaction information that may be out-of-date (from the last time /// contain transaction information that may be out-of-date (from the last time
/// the wallet's output set was refreshed against the node). /// the wallet's output set was refreshed against the node).
@ -424,30 +378,16 @@ where
/// should have before it's included in the 'amount_currently_spendable' total /// should have before it's included in the 'amount_currently_spendable' total
/// ///
/// # Returns /// # Returns
/// * (`bool`, [`WalletInfo`](../types/struct.WalletInfo.html)) - A tuple: /// * (`bool`, [`WalletInfo`](../grin_wallet_libwallet/types/struct.WalletInfo.html)) - A tuple:
/// * The first `bool` element indicates whether the data was successfully /// * The first `bool` element indicates whether the data was successfully
/// refreshed from the node (note this may be false even if the `refresh_from_node` /// refreshed from the node (note this may be false even if the `refresh_from_node`
/// argument was set to `true`. /// argument was set to `true`.
/// * The second element contains the Summary [`WalletInfo`](../types/struct.WalletInfo.html) /// * The second element contains the Summary [`WalletInfo`](../grin_wallet_libwallet/types/struct.WalletInfo.html)
/// ///
/// # Example /// # Example
/// Set up as in [`new`](struct.Owner.html#method.new) method above. /// Set up as in [`new`](struct.Owner.html#method.new) method above.
/// ``` ignore /// ```
/// # extern crate grin_wallet as wallet; /// # grin_wallet_api::doctest_helper_setup_doc_env!(wallet, wallet_config);
/// # extern crate grin_keychain as keychain;
/// # extern crate grin_util as util;
/// # use std::sync::Arc;
/// # use util::Mutex;
/// # use keychain::ExtKeychain;
/// # use wallet::libwallet::api::Owner;
/// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig};
/// # let mut wallet_config = WalletConfig::default();
/// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned();
/// # let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
/// # let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
/// # Arc::new(Mutex::new(
/// # LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap()
/// # ));
/// ///
/// let mut api_owner = Owner::new(wallet.clone()); /// let mut api_owner = Owner::new(wallet.clone());
/// let update_from_node = true; /// let update_from_node = true;
@ -474,10 +414,10 @@ where
} }
/// Initiates a new transaction as the sender, creating a new /// Initiates a new transaction as the sender, creating a new
/// [`Slate`](../../libtx/slate/struct.Slate.html) object containing /// [`Slate`](../grin_wallet_libwallet/slate/struct.Slate.html) object containing
/// the sender's inputs, change outputs, and public signature data. This slate can /// the sender's inputs, change outputs, and public signature data. This slate can
/// then be sent to the recipient to continue the transaction via the /// then be sent to the recipient to continue the transaction via the
/// [Foreign API's `receive_tx`](struct.APIForeign.html#method.receive_tx) method. /// [Foreign API's `receive_tx`](struct.Foreign.html#method.receive_tx) method.
/// ///
/// When a transaction is created, the wallet must also lock inputs (and create unconfirmed /// When a transaction is created, the wallet must also lock inputs (and create unconfirmed
/// outputs) corresponding to the transaction created in the slate, so that the wallet doesn't /// outputs) corresponding to the transaction created in the slate, so that the wallet doesn't
@ -518,16 +458,19 @@ where
/// the convenience of the participants during the exchange; it is not included in the final /// the convenience of the participants during the exchange; it is not included in the final
/// transaction sent to the chain. The message will be truncated to 256 characters. /// transaction sent to the chain. The message will be truncated to 256 characters.
/// Validation of this message is optional. /// Validation of this message is optional.
/// * `target_slate_version` Optionally set the output target slate version (acceptable
/// down to the minimum slate version compatible with the current. If `None` the slate
/// is generated with the latest version.
/// ///
/// # Returns /// # Returns
/// * a result containing: /// * a result containing:
/// * ([`Slate`](../../libtx/slate/struct.Slate.html), lock_function) - A tuple: /// * The transaction [Slate](../grin_wallet_libwallet/slate/struct.Slate.html),
/// * The transaction Slate, which can be forwarded to the recieving party by any means. /// which can be forwarded to the recieving party by any means. Once the caller is relatively
/// * A lock function, which should be called when the caller deems it appropriate to lock /// certain that the transaction has been sent to the recipient, the associated wallet
/// the transaction outputs (i.e. there is relative certaintly that the slate will be /// transaction outputs should be locked via a call to
/// transmitted to the receiving party). Must be called before calling /// [`tx_lock_outputs`](struct.Owner.html#method.tx_lock_outputs). This must be called before calling
/// [`finalize_tx`](struct.Owner.html#method.finalize_tx). /// [`finalize_tx`](struct.Owner.html#method.finalize_tx).
/// * or [`libwallet::Error`](../struct.Error.html) if an error is encountered. /// * or [`libwallet::Error`](../grin_wallet_libwallet/struct.Error.html) if an error is encountered.
/// ///
/// # Remarks /// # Remarks
/// ///
@ -538,22 +481,8 @@ where
/// ///
/// # Example /// # Example
/// Set up as in [new](struct.Owner.html#method.new) method above. /// Set up as in [new](struct.Owner.html#method.new) method above.
/// ``` ignore /// ```
/// # extern crate grin_wallet as wallet; /// # grin_wallet_api::doctest_helper_setup_doc_env!(wallet, wallet_config);
/// # extern crate grin_keychain as keychain;
/// # extern crate grin_util as util;
/// # use std::sync::Arc;
/// # use util::Mutex;
/// # use keychain::ExtKeychain;
/// # use wallet::libwallet::api::Owner;
/// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig};
/// # let mut wallet_config = WalletConfig::default();
/// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned();
/// # let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
/// # let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
/// # Arc::new(Mutex::new(
/// # LMDBBackend::new(wallet_config.clone(), "", node_client).unwrap()
/// # ));
/// ///
/// let mut api_owner = Owner::new(wallet.clone()); /// let mut api_owner = Owner::new(wallet.clone());
/// let amount = 2_000_000_000; /// let amount = 2_000_000_000;
@ -567,13 +496,14 @@ where
/// 1, // num change outputs /// 1, // num change outputs
/// true, // select all outputs /// true, // select all outputs
/// Some("Have some Grins. Love, Yeastplume".to_owned()), /// Some("Have some Grins. Love, Yeastplume".to_owned()),
/// None, // Use the default slate version
/// ); /// );
/// ///
/// if let Ok((slate, lock_fn)) = result { /// if let Ok(slate) = result {
/// // Send slate somehow /// // Send slate somehow
/// // ... /// // ...
/// // Lock our outputs if we're happy the slate was (or is being) sent /// // Lock our outputs if we're happy the slate was (or is being) sent
/// api_owner.tx_lock_outputs(&slate, lock_fn); /// api_owner.tx_lock_outputs(&slate);
/// } /// }
/// ``` /// ```
@ -600,41 +530,44 @@ where
selection_strategy_is_use_all, selection_strategy_is_use_all,
message, message,
target_slate_version, target_slate_version,
self.doctest_mode,
); );
w.close()?; w.close()?;
res res
} }
/// Estimates the amount to be locked and fee for the transaction without creating one /// Estimates the amount to be locked and fee for the transaction without creating one.
/// ///
/// # Arguments /// # Arguments
/// * `src_acct_name` - The human readable account name from which to draw outputs /// * As found in [`initiate_tx`](struct.Owner.html#method.initiate_tx) above.
/// for the transaction, overriding whatever the active account is as set via the
/// [`set_active_account`](struct.Owner.html#method.set_active_account) method.
/// If None, the transaction will use the active account.
/// * `amount` - The amount to send, in nanogrins. (`1 G = 1_000_000_000nG`)
/// * `minimum_confirmations` - The minimum number of confirmations an output
/// should have in order to be included in the transaction.
/// * `max_outputs` - By default, the wallet selects as many inputs as possible in a
/// transaction, to reduce the Output set and the fees. The wallet will attempt to spend
/// include up to `max_outputs` in a transaction, however if this is not enough to cover
/// the whole amount, the wallet will include more outputs. This parameter should be considered
/// a soft limit.
/// * `num_change_outputs` - The target number of change outputs to create in the transaction.
/// The actual number created will be `num_change_outputs` + whatever remainder is needed.
/// * `selection_strategy_is_use_all` - If `true`, attempt to use up as many outputs as
/// possible to create the transaction, up the 'soft limit' of `max_outputs`. This helps
/// to reduce the size of the UTXO set and the amount of data stored in the wallet, and
/// minimizes fees. This will generally result in many inputs and a large change output(s),
/// usually much larger than the amount being sent. If `false`, the transaction will include
/// as many outputs as are needed to meet the amount, (and no more) starting with the smallest
/// value outputs.
/// ///
/// # Returns /// # Returns
/// * a result containing: /// * a result containing a
/// * (total, fee) - A tuple: /// [`TxEstimation`](../grin_wallet_libwallet/types/struct.TxEstimation.html)
/// * Total amount to be locked. ///
/// * Transaction fee /// # Example
/// Set up as in [new](struct.Owner.html#method.new) method above.
/// ```
/// # grin_wallet_api::doctest_helper_setup_doc_env!(wallet, wallet_config);
///
/// let mut api_owner = Owner::new(wallet.clone());
/// let amount = 2_000_000_000;
///
/// // Estimate transaction using default account
/// let result = api_owner.estimate_initiate_tx(
/// None,
/// amount, // amount
/// 10, // minimum confirmations
/// 500, // max outputs
/// 1, // num change outputs
/// true, // select all outputs
/// );
///
/// if let Ok(est) = result {
/// // ...
/// }
/// ```
pub fn estimate_initiate_tx( pub fn estimate_initiate_tx(
&self, &self,
src_acct_name: Option<&str>, src_acct_name: Option<&str>,
@ -643,13 +576,7 @@ where
max_outputs: usize, max_outputs: usize,
num_change_outputs: usize, num_change_outputs: usize,
selection_strategy_is_use_all: bool, selection_strategy_is_use_all: bool,
) -> Result< ) -> Result<TxEstimation, Error> {
(
u64, // total
u64, // fee
),
Error,
> {
let mut w = self.wallet.lock(); let mut w = self.wallet.lock();
w.open_with_credentials()?; w.open_with_credentials()?;
let res = owner::estimate_initiate_tx( let res = owner::estimate_initiate_tx(
@ -665,8 +592,56 @@ where
res res
} }
/// Lock outputs associated with a given slate/transaction /// Locks the outputs associated with the inputs to the transaction in the given
/// and create any outputs needed /// [`Slate`](../grin_wallet_libwallet/slate/struct.Slate.html),
/// making them unavailable for use in further transactions. This function is called
/// by the sender, (or more generally, all parties who have put inputs into the transaction,)
/// and must be called before the corresponding call to [`finalize_tx`](struct.Owner.html#method.finalize_tx)
/// that completes the transaction.
///
/// Outputs will generally remain locked until they are removed from the chain,
/// at which point they will become `Spent`. It is commonplace for transactions not to complete
/// for various reasons over which a particular wallet has no control. For this reason,
/// [`cancel_tx`](struct.Owner.html#method.cancel_tx) can be used to manually unlock outputs
/// and return them to the `Unspent` state.
///
/// # Arguments
/// * `slate` - The transaction [`Slate`](../grin_wallet_libwallet/slate/struct.Slate.html). All
/// elements in the `input` vector of the `tx` field that are found in the wallet's currently
/// active account will be set to status `Locked`
///
/// # Returns
/// * Ok(()) if successful
/// * or [`libwallet::Error`](../grin_wallet_libwallet/struct.Error.html) if an error is encountered.
///
/// # Example
/// Set up as in [`new`](struct.Owner.html#method.new) method above.
/// ```
/// # grin_wallet_api::doctest_helper_setup_doc_env!(wallet, wallet_config);
///
/// let mut api_owner = Owner::new(wallet.clone());
/// let amount = 2_000_000_000;
///
/// // Attempt to create a transaction using the 'default' account
/// let result = api_owner.initiate_tx(
/// None,
/// amount, // amount
/// 10, // minimum confirmations
/// 500, // max outputs
/// 1, // num change outputs
/// true, // select all outputs
/// Some("Remember to lock when we're happy this is sent".to_owned()),
/// None, // Use the default slate version
/// );
///
/// if let Ok(slate) = result {
/// // Send slate somehow
/// // ...
/// // Lock our outputs if we're happy the slate was (or is being) sent
/// api_owner.tx_lock_outputs(&slate);
/// }
/// ```
pub fn tx_lock_outputs(&self, slate: &Slate) -> Result<(), Error> { pub fn tx_lock_outputs(&self, slate: &Slate) -> Result<(), Error> {
let mut w = self.wallet.lock(); let mut w = self.wallet.lock();
w.open_with_credentials()?; w.open_with_credentials()?;
@ -675,38 +650,117 @@ where
res res
} }
/// Sender finalization of the transaction. Takes the file returned by the /// Finalizes a transaction, after all parties
/// sender as well as the private file generate on the first send step. /// have filled in both rounds of Slate generation. This step adds
/// Builds the complete transaction and sends it to a grin node for /// all participants partial signatures to create the final signature,
/// propagation. /// resulting in a final transaction that is ready to post to a node.
pub fn finalize_tx(&self, slate: &mut Slate) -> Result<(), Error> { ///
/// Note that this function DOES NOT POST the transaction to a node
/// for validation. This is done in separately via the
/// [`post_tx`](struct.Owner.html#method.post_tx) function.
///
/// This function also stores the final transaction in the user's wallet files for retrieval
/// via the [`get_stored_tx`](struct.Owner.html#method.get_stored_tx) function.
///
/// # Arguments
/// * `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).
///
/// # Returns
/// * `Ok(())` if successful
/// * or [`libwallet::Error`](../grin_wallet_libwallet/struct.Error.html) if an error is encountered.
///
/// # Example
/// Set up as in [`new`](struct.Owner.html#method.new) method above.
/// ```
/// # grin_wallet_api::doctest_helper_setup_doc_env!(wallet, wallet_config);
///
/// let mut api_owner = Owner::new(wallet.clone());
/// let amount = 2_000_000_000;
///
/// // Attempt to create a transaction using the 'default' account
/// let result = api_owner.initiate_tx(
/// None,
/// amount, // amount
/// 10, // minimum confirmations
/// 500, // max outputs
/// 1, // num change outputs
/// true, // select all outputs
/// Some("Finalize this tx now".to_owned()),
/// None, // Use the default slate version
/// );
///
/// if let Ok(slate) = result {
/// // 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);
/// //
/// // Retrieve slate back from recipient
/// //
/// let res = api_owner.finalize_tx(&slate);
/// }
/// ```
pub fn finalize_tx(&self, slate: &Slate) -> Result<Slate, Error> {
let mut w = self.wallet.lock(); let mut w = self.wallet.lock();
let mut slate = slate.clone();
w.open_with_credentials()?; w.open_with_credentials()?;
let res = owner::finalize_tx(&mut *w, slate); slate = owner::finalize_tx(&mut *w, &slate)?;
w.close()?; w.close()?;
res Ok(slate)
} }
/// Roll back a transaction and all associated outputs with a given /// Posts a completed transaction to the listening node for validation and inclusion in a block
/// transaction id This means delete all change outputs, (or recipient /// for mining.
/// output if you're recipient), and unlock all locked outputs associated ///
/// with the transaction used when a transaction is created but never /// # Arguments
/// posted /// * `tx` - A completed [`Transaction`](../grin_core/core/transaction/struct.Transaction.html),
pub fn cancel_tx(&self, tx_id: Option<u32>, tx_slate_id: Option<Uuid>) -> Result<(), Error> { /// typically the `tx` field in the transaction [`Slate`](../grin_wallet_libwallet/slate/struct.Slate.html).
let mut w = self.wallet.lock(); ///
w.open_with_credentials()?; /// * `fluff` - Instruct the node whether to use the Dandelion protocol when posting the
let res = owner::cancel_tx(&mut *w, tx_id, tx_slate_id); /// transaction. If `true`, the node should skip the Dandelion phase and broadcast the
w.close()?; /// transaction to all peers immediately. If `false`, the node will follow dandelion logic and
res /// initiate the stem phase.
} ///
/// # Returns
/// * `Ok(())` if successful
/// * or [`libwallet::Error`](../grin_wallet_libwallet/struct.Error.html) if an error is encountered.
///
/// # Example
/// Set up as in [`new`](struct.Owner.html#method.new) method above.
/// ```
/// # grin_wallet_api::doctest_helper_setup_doc_env!(wallet, wallet_config);
///
/// let mut api_owner = Owner::new(wallet.clone());
/// let amount = 2_000_000_000;
///
/// // Attempt to create a transaction using the 'default' account
/// let result = api_owner.initiate_tx(
/// None,
/// amount, // amount
/// 10, // minimum confirmations
/// 500, // max outputs
/// 1, // num change outputs
/// true, // select all outputs
/// Some("Finalize this tx now".to_owned()),
/// None, // Use the default slate version
/// );
///
/// if let Ok(slate) = result {
/// // 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);
/// //
/// // Retrieve slate back from recipient
/// //
/// let res = api_owner.finalize_tx(&slate);
/// let res = api_owner.post_tx(&slate.tx, true);
/// }
/// ```
/// Retrieves a stored transaction from a TxLogEntry
pub fn get_stored_tx(&self, entry: &TxLogEntry) -> Result<Option<Transaction>, Error> {
let w = self.wallet.lock();
owner::get_stored_tx(&*w, entry)
}
/// Posts a transaction to the chain
pub fn post_tx(&self, tx: &Transaction, fluff: bool) -> Result<(), Error> { pub fn post_tx(&self, tx: &Transaction, fluff: bool) -> Result<(), Error> {
let client = { let client = {
let mut w = self.wallet.lock(); let mut w = self.wallet.lock();
@ -715,12 +769,150 @@ where
owner::post_tx(&client, tx, fluff) owner::post_tx(&client, tx, fluff)
} }
/// Verifies all messages in the slate match their public keys /// Cancels a transaction. This entails:
/// * Setting the transaction status to either `TxSentCancelled` or `TxReceivedCancelled`
/// * Deleting all change outputs or recipient outputs associated with the transaction
/// * Setting the status of all assocatied inputs from `Locked` to `Spent` so they can be
/// used in new transactions.
///
/// Transactions can be cancelled by transaction log id or slate id (call with either set to
/// Some, not both)
///
/// # Arguments
///
/// * `tx_id` - If present, cancel by the [`TxLogEntry`](../grin_wallet_libwallet/types/struct.TxLogEntry.html) id
/// for the transaction.
///
/// * `tx_slate_id` - If present, cancel by the Slate id.
///
/// # Returns
/// * `Ok(())` if successful
/// * or [`libwallet::Error`](../grin_wallet_libwallet/struct.Error.html) if an error is encountered.
///
/// # Example
/// Set up as in [`new`](struct.Owner.html#method.new) method above.
/// ```
/// # grin_wallet_api::doctest_helper_setup_doc_env!(wallet, wallet_config);
///
/// let mut api_owner = Owner::new(wallet.clone());
/// let amount = 2_000_000_000;
///
/// // Attempt to create a transaction using the 'default' account
/// let result = api_owner.initiate_tx(
/// None,
/// amount, // amount
/// 10, // minimum confirmations
/// 500, // max outputs
/// 1, // num change outputs
/// true, // select all outputs
/// Some("Cancel this tx".to_owned()),
/// None, // Use the default slate version
/// );
///
/// if let Ok(slate) = result {
/// // 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);
/// //
/// // We didn't get the slate back, or something else went wrong
/// //
/// let res = api_owner.cancel_tx(None, Some(slate.id.clone()));
/// }
/// ```
pub fn cancel_tx(&self, tx_id: Option<u32>, tx_slate_id: Option<Uuid>) -> Result<(), Error> {
let mut w = self.wallet.lock();
w.open_with_credentials()?;
let res = owner::cancel_tx(&mut *w, tx_id, tx_slate_id);
w.close()?;
res
}
/// Retrieves the stored transaction associated with a TxLogEntry. Can be used even after the
/// transaction has completed.
///
/// # Arguments
///
/// * `tx_log_entry` - A [`TxLogEntry`](../grin_wallet_libwallet/types/struct.TxLogEntry.html)
///
/// # Returns
/// * Ok with the stored [`Transaction`](../grin_core/core/transaction/struct.Transaction.html)
/// if successful
/// * or [`libwallet::Error`](../grin_wallet_libwallet/struct.Error.html) if an error is encountered.
///
/// # Example
/// Set up as in [`new`](struct.Owner.html#method.new) method above.
/// ```
/// # grin_wallet_api::doctest_helper_setup_doc_env!(wallet, wallet_config);
///
/// let api_owner = Owner::new(wallet.clone());
/// let update_from_node = true;
/// let tx_id = None;
/// let tx_slate_id = None;
///
/// // Return all TxLogEntries
/// let result = api_owner.retrieve_txs(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();
/// //...
/// }
/// ```
// TODO: Should be accepting an id, not an entire entry struct
pub fn get_stored_tx(&self, tx_log_entry: &TxLogEntry) -> Result<Option<Transaction>, Error> {
let w = self.wallet.lock();
owner::get_stored_tx(&*w, tx_log_entry)
}
/// Verifies all messages in the slate match their public keys.
///
/// # Arguments
///
/// * `slate` - The transaction [`Slate`](../grin_wallet_libwallet/slate/struct.Slate.html).
///
/// # Returns
/// * Ok(()) if successful and the signatures validate
/// * or [`libwallet::Error`](../grin_wallet_libwallet/struct.Error.html) if an error is encountered.
///
/// # Example
/// Set up as in [`new`](struct.Owner.html#method.new) method above.
/// ```
/// # grin_wallet_api::doctest_helper_setup_doc_env!(wallet, wallet_config);
///
/// let mut api_owner = Owner::new(wallet.clone());
/// let amount = 2_000_000_000;
///
/// // Attempt to create a transaction using the 'default' account
/// let result = api_owner.initiate_tx(
/// None,
/// amount, // amount
/// 10, // minimum confirmations
/// 500, // max outputs
/// 1, // num change outputs
/// true, // select all outputs
/// Some("Finalize this tx now".to_owned()),
/// None, // Use the default slate version
/// );
///
/// if let Ok(slate) = result {
/// // 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);
/// //
/// // Retrieve slate back from recipient
/// //
/// let res = api_owner.verify_slate_messages(&slate);
/// }
/// ```
pub fn verify_slate_messages(&self, slate: &Slate) -> Result<(), Error> { pub fn verify_slate_messages(&self, slate: &Slate) -> Result<(), Error> {
owner::verify_slate_messages(slate) owner::verify_slate_messages(slate)
} }
/// Attempt to restore contents of wallet /// Attempt to restore contents of wallet
/// TODO: Full docs
pub fn restore(&self) -> Result<(), Error> { pub fn restore(&self) -> Result<(), Error> {
let mut w = self.wallet.lock(); let mut w = self.wallet.lock();
w.open_with_credentials()?; w.open_with_credentials()?;
@ -730,6 +922,7 @@ where
} }
/// Attempt to check and fix the contents of the wallet /// Attempt to check and fix the contents of the wallet
/// TODO: Full docs
pub fn check_repair(&self, delete_unconfirmed: bool) -> Result<(), Error> { pub fn check_repair(&self, delete_unconfirmed: bool) -> Result<(), Error> {
let mut w = self.wallet.lock(); let mut w = self.wallet.lock();
w.open_with_credentials()?; w.open_with_credentials()?;
@ -739,6 +932,7 @@ where
} }
/// Retrieve current height from node /// Retrieve current height from node
// TODO: Should return u64 as string
pub fn node_height(&self) -> Result<(u64, bool), Error> { pub fn node_height(&self) -> Result<(u64, bool), Error> {
let mut w = self.wallet.lock(); let mut w = self.wallet.lock();
w.open_with_credentials()?; w.open_with_credentials()?;
@ -747,3 +941,42 @@ where
res res
} }
} }
#[doc(hidden)]
#[macro_export]
macro_rules! doctest_helper_setup_doc_env {
($wallet:ident, $wallet_config:ident) => {
use grin_keychain as keychain;
use grin_util as util;
use grin_wallet_api as api;
use grin_wallet_config as config;
use grin_wallet_impls as impls;
use grin_wallet_libwallet as libwallet;
use keychain::ExtKeychain;
use tempfile::tempdir;
use std::sync::Arc;
use util::Mutex;
use api::Owner;
use config::WalletConfig;
use impls::{HTTPNodeClient, LMDBBackend, WalletSeed};
use libwallet::types::WalletBackend;
let dir = tempdir().map_err(|e| format!("{:#?}", e)).unwrap();
let dir = dir
.path()
.to_str()
.ok_or("Failed to convert tmpdir path to string.".to_owned())
.unwrap();
let mut wallet_config = WalletConfig::default();
wallet_config.data_file_dir = dir.to_owned();
let pw = "";
let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
let mut $wallet: Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> = Arc::new(
Mutex::new(LMDBBackend::new(wallet_config.clone(), pw, node_client).unwrap()),
);
};
}

File diff suppressed because it is too large Load diff

View file

@ -27,7 +27,7 @@ term = "0.5"
tokio = "= 0.1.11" tokio = "= 0.1.11"
tokio-core = "0.1" tokio-core = "0.1"
tokio-retry = "0.1" tokio-retry = "0.1"
uuid = { version = "0.6", features = ["serde", "v4"] } uuid = { version = "0.7", features = ["serde", "v4"] }
url = "1.7.0" url = "1.7.0"
chrono = { version = "0.4.4", features = ["serde"] } chrono = { version = "0.4.4", features = ["serde"] }

View file

@ -247,7 +247,7 @@ pub fn send(
let strategies = vec!["smallest", "all"] let strategies = vec!["smallest", "all"]
.into_iter() .into_iter()
.map(|strategy| { .map(|strategy| {
let (total, fee) = api let est = api
.estimate_initiate_tx( .estimate_initiate_tx(
None, None,
args.amount, args.amount,
@ -257,7 +257,7 @@ pub fn send(
strategy == "all", strategy == "all",
) )
.unwrap(); .unwrap();
(strategy, total, fee) (strategy, est.total, est.fee)
}) })
.collect(); .collect();
display::estimate(args.amount, strategies, dark_scheme); display::estimate(args.amount, strategies, dark_scheme);
@ -307,7 +307,7 @@ pub fn send(
error!("Error validating participant messages: {}", e); error!("Error validating participant messages: {}", e);
return Err(e); return Err(e);
} }
api.finalize_tx(&mut slate)?; slate = api.finalize_tx(&slate)?;
} else { } else {
adapter.send_tx_async(&args.dest, &slate)?; adapter.send_tx_async(&args.dest, &slate)?;
api.tx_lock_outputs(&slate)?; api.tx_lock_outputs(&slate)?;
@ -378,7 +378,7 @@ pub fn finalize(
error!("Error validating participant messages: {}", e); error!("Error validating participant messages: {}", e);
return Err(e); return Err(e);
} }
let _ = api.finalize_tx(&mut slate).expect("Finalize failed"); slate = api.finalize_tx(&mut slate).expect("Finalize failed");
let result = api.post_tx(&slate.tx, args.fluff); let result = api.post_tx(&slate.tx, args.fluff);
match result { match result {

View file

@ -23,10 +23,9 @@ use crate::impls::{FileWalletCommAdapter, HTTPWalletCommAdapter, KeybaseWalletCo
use crate::keychain::Keychain; use crate::keychain::Keychain;
use crate::libwallet::slate::Slate; use crate::libwallet::slate::Slate;
use crate::libwallet::types::{ use crate::libwallet::types::{
CbData, NodeClient, OutputData, SendTXArgs, TxLogEntry, WalletBackend, WalletInfo, CbData, NodeClient, OutputCommitMapping, SendTXArgs, TxLogEntry, WalletBackend, WalletInfo,
}; };
use crate::libwallet::{Error, ErrorKind}; use crate::libwallet::{Error, ErrorKind};
use crate::util::secp::pedersen;
use crate::util::to_base64; use crate::util::to_base64;
use crate::util::Mutex; use crate::util::Mutex;
use failure::ResultExt; use failure::ResultExt;
@ -187,7 +186,7 @@ where
&self, &self,
req: &Request<Body>, req: &Request<Body>,
api: Owner<T, C, K>, api: Owner<T, C, K>,
) -> Result<(bool, Vec<(OutputData, pedersen::Commitment)>), Error> { ) -> Result<(bool, Vec<OutputCommitMapping>), Error> {
let mut update_from_node = false; let mut update_from_node = false;
let mut id = None; let mut id = None;
let mut show_spent = false; let mut show_spent = false;
@ -373,7 +372,7 @@ where
} }
api.tx_lock_outputs(&slate)?; api.tx_lock_outputs(&slate)?;
if args.method != "file" { if args.method != "file" {
api.finalize_tx(&mut slate)?; slate = api.finalize_tx(&slate)?;
} }
Ok(slate) Ok(slate)
})) }))
@ -385,8 +384,8 @@ where
api: Owner<T, C, K>, api: Owner<T, C, K>,
) -> Box<dyn Future<Item = Slate, Error = Error> + Send> { ) -> Box<dyn Future<Item = Slate, Error = Error> + Send> {
Box::new( Box::new(
parse_body(req).and_then(move |mut slate| match api.finalize_tx(&mut slate) { parse_body(req).and_then(move |slate| match api.finalize_tx(&slate) {
Ok(_) => ok(slate.clone()), Ok(s) => ok(s.clone()),
Err(e) => { Err(e) => {
error!("finalize_tx: failed with error: {}", e); error!("finalize_tx: failed with error: {}", e);
err(e) err(e)

View file

@ -14,10 +14,11 @@
use crate::core::core::{self, amount_to_hr_string}; use crate::core::core::{self, amount_to_hr_string};
use crate::core::global; use crate::core::global;
use crate::libwallet::types::{AcctPathMapping, OutputData, OutputStatus, TxLogEntry, WalletInfo}; use crate::libwallet::types::{
AcctPathMapping, OutputCommitMapping, OutputStatus, TxLogEntry, WalletInfo,
};
use crate::libwallet::Error; use crate::libwallet::Error;
use crate::util; use crate::util;
use crate::util::secp::pedersen;
use prettytable; use prettytable;
use std::io::prelude::Write; use std::io::prelude::Write;
use term; use term;
@ -27,7 +28,7 @@ pub fn outputs(
account: &str, account: &str,
cur_height: u64, cur_height: u64,
validated: bool, validated: bool,
outputs: Vec<(OutputData, pedersen::Commitment)>, outputs: Vec<OutputCommitMapping>,
dark_background_color_scheme: bool, dark_background_color_scheme: bool,
) -> Result<(), Error> { ) -> Result<(), Error> {
let title = format!( let title = format!(
@ -54,25 +55,25 @@ pub fn outputs(
bMG->"Tx" bMG->"Tx"
]); ]);
for (out, commit) in outputs { for m in outputs {
let commit = format!("{}", util::to_hex(commit.as_ref().to_vec())); let commit = format!("{}", util::to_hex(m.commit.as_ref().to_vec()));
let index = match out.mmr_index { let index = match m.output.mmr_index {
None => "None".to_owned(), None => "None".to_owned(),
Some(t) => t.to_string(), Some(t) => t.to_string(),
}; };
let height = format!("{}", out.height); let height = format!("{}", m.output.height);
let lock_height = format!("{}", out.lock_height); let lock_height = format!("{}", m.output.lock_height);
let is_coinbase = format!("{}", out.is_coinbase); let is_coinbase = format!("{}", m.output.is_coinbase);
// Mark unconfirmed coinbase outputs as "Mining" instead of "Unconfirmed" // Mark unconfirmed coinbase outputs as "Mining" instead of "Unconfirmed"
let status = match out.status { let status = match m.output.status {
OutputStatus::Unconfirmed if out.is_coinbase => "Mining".to_string(), OutputStatus::Unconfirmed if m.output.is_coinbase => "Mining".to_string(),
_ => format!("{}", out.status), _ => format!("{}", m.output.status),
}; };
let num_confirmations = format!("{}", out.num_confirmations(cur_height)); let num_confirmations = format!("{}", m.output.num_confirmations(cur_height));
let value = format!("{}", core::amount_to_hr_string(out.value, false)); let value = format!("{}", core::amount_to_hr_string(m.output.value, false));
let tx = match out.tx_log_entry { let tx = match m.output.tx_log_entry {
None => "".to_owned(), None => "".to_owned(),
Some(t) => t.to_string(), Some(t) => t.to_string(),
}; };

View file

@ -111,14 +111,14 @@ fn accounts_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
w.set_parent_key_id_by_name("account1")?; w.set_parent_key_id_by_name("account1")?;
assert_eq!(w.parent_key_id(), ExtKeychain::derive_key_id(2, 1, 0, 0, 0)); 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); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 7, false);
{ {
let mut w = wallet1.lock(); let mut w = wallet1.lock();
w.set_parent_key_id_by_name("account2")?; w.set_parent_key_id_by_name("account2")?;
assert_eq!(w.parent_key_id(), ExtKeychain::derive_key_id(2, 2, 0, 0, 0)); 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); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5, false);
// Should have 5 in account1 (5 spendable), 5 in account (2 spendable) // Should have 5 in account1 (5 spendable), 5 in account (2 spendable)
wallet::controller::owner_single_use(wallet1.clone(), |api| { wallet::controller::owner_single_use(wallet1.clone(), |api| {
@ -188,7 +188,7 @@ fn accounts_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
)?; )?;
slate = client1.send_tx_slate_direct("wallet2", &slate)?; slate = client1.send_tx_slate_direct("wallet2", &slate)?;
api.tx_lock_outputs(&slate)?; api.tx_lock_outputs(&slate)?;
api.finalize_tx(&mut slate)?; slate = api.finalize_tx(&slate)?;
api.post_tx(&slate.tx, false)?; api.post_tx(&slate.tx, false)?;
Ok(()) Ok(())
})?; })?;

View file

@ -38,7 +38,7 @@ macro_rules! send_to_dest {
WalletInst<LocalWalletClient, ExtKeychain>, WalletInst<LocalWalletClient, ExtKeychain>,
LocalWalletClient, LocalWalletClient,
ExtKeychain, ExtKeychain,
>($a, $b, $c, $d) >($a, $b, $c, $d, false)
}; };
} }
@ -111,7 +111,7 @@ fn check_repair_impl(test_dir: &str) -> Result<(), libwallet::Error> {
// Do some mining // Do some mining
let bh = 20u64; let bh = 20u64;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize, false);
// Sanity check contents // Sanity check contents
wallet::controller::owner_single_use(wallet1.clone(), |api| { wallet::controller::owner_single_use(wallet1.clone(), |api| {
@ -135,7 +135,7 @@ fn check_repair_impl(test_dir: &str) -> Result<(), libwallet::Error> {
Ok(()) Ok(())
})?; })?;
let w1_outputs: Vec<libwallet::types::OutputData> = let w1_outputs: Vec<libwallet::types::OutputData> =
w1_outputs_commits.into_iter().map(|o| o.0).collect(); w1_outputs_commits.into_iter().map(|m| m.output).collect();
{ {
let mut w = wallet1.lock(); let mut w = wallet1.lock();
w.open_with_credentials()?; w.open_with_credentials()?;
@ -337,7 +337,7 @@ fn two_wallets_one_seed_impl(test_dir: &str) -> Result<(), libwallet::Error> {
// Do some mining // Do some mining
let mut bh = 20u64; let mut bh = 20u64;
let base_amount = consensus::GRIN_BASE; let base_amount = consensus::GRIN_BASE;
let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), bh as usize); let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), bh as usize, false);
// send some funds to wallets 1 // 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 * 1)?;
@ -360,7 +360,7 @@ fn two_wallets_one_seed_impl(test_dir: &str) -> Result<(), libwallet::Error> {
send_to_dest!(miner.clone(), m_client.clone(), "wallet2", base_amount * 6)?; send_to_dest!(miner.clone(), m_client.clone(), "wallet2", base_amount * 6)?;
bh += 3; bh += 3;
let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm); let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm, false);
bh += cm as u64; bh += cm as u64;
// confirm balances // confirm balances
@ -411,7 +411,7 @@ fn two_wallets_one_seed_impl(test_dir: &str) -> Result<(), libwallet::Error> {
send_to_dest!(miner.clone(), m_client.clone(), "wallet4", base_amount * 9)?; send_to_dest!(miner.clone(), m_client.clone(), "wallet4", base_amount * 9)?;
bh += 3; bh += 3;
let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm); let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm, false);
bh += cm as u64; bh += cm as u64;
wallet::controller::owner_single_use(wallet4.clone(), |api| { wallet::controller::owner_single_use(wallet4.clone(), |api| {
@ -442,7 +442,7 @@ fn two_wallets_one_seed_impl(test_dir: &str) -> Result<(), libwallet::Error> {
send_to_dest!(miner.clone(), m_client.clone(), "wallet6", base_amount * 12)?; send_to_dest!(miner.clone(), m_client.clone(), "wallet6", base_amount * 12)?;
bh += 3; bh += 3;
let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm as usize); let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm as usize, false);
bh += cm as u64; bh += cm as u64;
wallet::controller::owner_single_use(wallet6.clone(), |api| { wallet::controller::owner_single_use(wallet6.clone(), |api| {
@ -487,7 +487,7 @@ fn two_wallets_one_seed_impl(test_dir: &str) -> Result<(), libwallet::Error> {
bh += 3; bh += 3;
// check balances // check balances
let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm); let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm, false);
bh += cm as u64; bh += cm as u64;
wallet::controller::owner_single_use(wallet7.clone(), |api| { wallet::controller::owner_single_use(wallet7.clone(), |api| {
@ -552,7 +552,7 @@ fn two_wallets_one_seed_impl(test_dir: &str) -> Result<(), libwallet::Error> {
Ok(()) Ok(())
})?; })?;
let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm); let _ = test_framework::award_blocks_to_wallet(&chain, miner.clone(), cm, false);
// 7) Ensure check_repair creates missing accounts // 7) Ensure check_repair creates missing accounts
wallet::controller::owner_single_use(wallet10.clone(), |api| { wallet::controller::owner_single_use(wallet10.clone(), |api| {

View file

@ -89,7 +89,7 @@ fn file_exchange_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
w.set_parent_key_id_by_name("mining")?; w.set_parent_key_id_by_name("mining")?;
} }
let mut bh = 10u64; let mut bh = 10u64;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize, false);
let send_file = format!("{}/part_tx_1.tx", test_dir); let send_file = format!("{}/part_tx_1.tx", test_dir);
let receive_file = format!("{}/part_tx_2.tx", test_dir); let receive_file = format!("{}/part_tx_2.tx", test_dir);
@ -153,13 +153,13 @@ fn file_exchange_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
let adapter = FileWalletCommAdapter::new(); let adapter = FileWalletCommAdapter::new();
let mut slate = adapter.receive_tx_async(&receive_file)?; let mut slate = adapter.receive_tx_async(&receive_file)?;
api.verify_slate_messages(&slate)?; api.verify_slate_messages(&slate)?;
api.finalize_tx(&mut slate)?; slate = api.finalize_tx(&slate)?;
api.post_tx(&slate.tx, false)?; api.post_tx(&slate.tx, false)?;
bh += 1; bh += 1;
Ok(()) Ok(())
})?; })?;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
bh += 3; bh += 3;
// Check total in mining account // Check total in mining account

View file

@ -88,7 +88,7 @@ fn file_repost_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
w.set_parent_key_id_by_name("mining")?; w.set_parent_key_id_by_name("mining")?;
} }
let mut bh = 10u64; let mut bh = 10u64;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize, false);
let send_file = format!("{}/part_tx_1.tx", test_dir); let send_file = format!("{}/part_tx_1.tx", test_dir);
let receive_file = format!("{}/part_tx_2.tx", test_dir); let receive_file = format!("{}/part_tx_2.tx", test_dir);
@ -119,7 +119,7 @@ fn file_repost_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
Ok(()) Ok(())
})?; })?;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
bh += 3; bh += 3;
// wallet 1 receives file to different account, completes // wallet 1 receives file to different account, completes
@ -146,7 +146,7 @@ fn file_repost_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
wallet::controller::owner_single_use(wallet1.clone(), |api| { wallet::controller::owner_single_use(wallet1.clone(), |api| {
let adapter = FileWalletCommAdapter::new(); let adapter = FileWalletCommAdapter::new();
slate = adapter.receive_tx_async(&receive_file)?; slate = adapter.receive_tx_async(&receive_file)?;
api.finalize_tx(&mut slate)?; slate = api.finalize_tx(&slate)?;
Ok(()) Ok(())
})?; })?;
@ -159,7 +159,7 @@ fn file_repost_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
Ok(()) Ok(())
})?; })?;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
bh += 3; bh += 3;
// update/test contents of both accounts // update/test contents of both accounts
@ -211,11 +211,11 @@ fn file_repost_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
)?; )?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate)?; sender_api.tx_lock_outputs(&slate)?;
sender_api.finalize_tx(&mut slate)?; slate = sender_api.finalize_tx(&mut slate)?;
Ok(()) Ok(())
})?; })?;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
bh += 3; bh += 3;
// Now repost from cached // Now repost from cached
@ -227,7 +227,7 @@ fn file_repost_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
Ok(()) Ok(())
})?; })?;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
bh += 3; bh += 3;
// //
// update/test contents of both accounts // update/test contents of both accounts

View file

@ -228,7 +228,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> {
}); });
// mine a few blocks // mine a few blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 10); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 10, false);
// assert wallet contents // assert wallet contents
// and a single use api for a send command // and a single use api for a send command
@ -246,13 +246,13 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> {
)?; )?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate)?; sender_api.tx_lock_outputs(&slate)?;
sender_api.finalize_tx(&mut slate)?; slate = sender_api.finalize_tx(&slate)?;
sender_api.post_tx(&slate.tx, false)?; sender_api.post_tx(&slate.tx, false)?;
Ok(()) Ok(())
})?; })?;
// mine a few more blocks // mine a few more blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
// Send some to wallet 3 // Send some to wallet 3
wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { wallet::controller::owner_single_use(wallet1.clone(), |sender_api| {
@ -269,13 +269,13 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> {
)?; )?;
slate = client1.send_tx_slate_direct("wallet3", &slate_i)?; slate = client1.send_tx_slate_direct("wallet3", &slate_i)?;
sender_api.tx_lock_outputs(&slate)?; sender_api.tx_lock_outputs(&slate)?;
sender_api.finalize_tx(&mut slate)?; slate = sender_api.finalize_tx(&slate)?;
sender_api.post_tx(&slate.tx, false)?; sender_api.post_tx(&slate.tx, false)?;
Ok(()) Ok(())
})?; })?;
// mine a few more blocks // mine a few more blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet3.clone(), 10); let _ = test_framework::award_blocks_to_wallet(&chain, wallet3.clone(), 10, false);
// Wallet3 to wallet 2 // Wallet3 to wallet 2
wallet::controller::owner_single_use(wallet3.clone(), |sender_api| { wallet::controller::owner_single_use(wallet3.clone(), |sender_api| {
@ -292,7 +292,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> {
)?; )?;
slate = client3.send_tx_slate_direct("wallet2", &slate_i)?; slate = client3.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate)?; sender_api.tx_lock_outputs(&slate)?;
sender_api.finalize_tx(&mut slate)?; slate = sender_api.finalize_tx(&slate)?;
sender_api.post_tx(&slate.tx, false)?; sender_api.post_tx(&slate.tx, false)?;
Ok(()) Ok(())
})?; })?;
@ -304,7 +304,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> {
} }
// mine a few more blocks // mine a few more blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 2); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 2, false);
// Wallet3 to wallet 2 again (to another account) // Wallet3 to wallet 2 again (to another account)
wallet::controller::owner_single_use(wallet3.clone(), |sender_api| { wallet::controller::owner_single_use(wallet3.clone(), |sender_api| {
@ -321,13 +321,13 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> {
)?; )?;
slate = client3.send_tx_slate_direct("wallet2", &slate_i)?; slate = client3.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate)?; sender_api.tx_lock_outputs(&slate)?;
sender_api.finalize_tx(&mut slate)?; slate = sender_api.finalize_tx(&slate)?;
sender_api.post_tx(&slate.tx, false)?; sender_api.post_tx(&slate.tx, false)?;
Ok(()) Ok(())
})?; })?;
// mine a few more blocks // mine a few more blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5, false);
// update everyone // update everyone
wallet::controller::owner_single_use(wallet1.clone(), |api| { wallet::controller::owner_single_use(wallet1.clone(), |api| {

View file

@ -76,7 +76,7 @@ fn self_send_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
w.set_parent_key_id_by_name("mining")?; w.set_parent_key_id_by_name("mining")?;
} }
let mut bh = 10u64; let mut bh = 10u64;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize, false);
// Should have 5 in account1 (5 spendable), 5 in account (2 spendable) // Should have 5 in account1 (5 spendable), 5 in account (2 spendable)
wallet::controller::owner_single_use(wallet1.clone(), |api| { wallet::controller::owner_single_use(wallet1.clone(), |api| {
@ -101,13 +101,13 @@ fn self_send_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
api.receive_tx(&mut slate, Some("listener"), None)?; api.receive_tx(&mut slate, Some("listener"), None)?;
Ok(()) Ok(())
})?; })?;
api.finalize_tx(&mut slate)?; slate = api.finalize_tx(&slate)?;
api.post_tx(&slate.tx, false)?; // mines a block api.post_tx(&slate.tx, false)?; // mines a block
bh += 1; bh += 1;
Ok(()) Ok(())
})?; })?;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
bh += 3; bh += 3;
// Check total in mining account // Check total in mining account

View file

@ -75,7 +75,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> {
let reward = core::consensus::REWARD; let reward = core::consensus::REWARD;
let cm = global::coinbase_maturity(); // assume all testing precedes soft fork height let cm = global::coinbase_maturity(); // assume all testing precedes soft fork height
// mine a few blocks // mine a few blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 10); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 10, false);
// Check wallet 1 contents are as expected // Check wallet 1 contents are as expected
wallet::controller::owner_single_use(wallet1.clone(), |api| { wallet::controller::owner_single_use(wallet1.clone(), |api| {
@ -114,7 +114,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> {
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate)?; sender_api.tx_lock_outputs(&slate)?;
sender_api.finalize_tx(&mut slate)?; slate = sender_api.finalize_tx(&slate)?;
// Check we have a single kernel and that it is a Plain kernel (no lock_height). // Check we have a single kernel and that it is a Plain kernel (no lock_height).
assert_eq!(slate.tx.kernels().len(), 1); assert_eq!(slate.tx.kernels().len(), 1);
@ -213,7 +213,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> {
})?; })?;
// mine a few more blocks // mine a few more blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
// refresh wallets and retrieve info/tests for each wallet after maturity // refresh wallets and retrieve info/tests for each wallet after maturity
wallet::controller::owner_single_use(wallet1.clone(), |api| { wallet::controller::owner_single_use(wallet1.clone(), |api| {
@ -249,7 +249,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> {
// Estimate fee and locked amount for a transaction // Estimate fee and locked amount for a transaction
wallet::controller::owner_single_use(wallet1.clone(), |sender_api| { wallet::controller::owner_single_use(wallet1.clone(), |sender_api| {
let (total, fee) = sender_api.estimate_initiate_tx( let est = sender_api.estimate_initiate_tx(
None, None,
amount * 2, // amount amount * 2, // amount
2, // minimum confirmations 2, // minimum confirmations
@ -257,10 +257,10 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> {
1, // num change outputs 1, // num change outputs
true, // select all outputs true, // select all outputs
)?; )?;
assert_eq!(total, 600_000_000_000); assert_eq!(est.total, 600_000_000_000);
assert_eq!(fee, 4_000_000); assert_eq!(est.fee, 4_000_000);
let (total, fee) = sender_api.estimate_initiate_tx( let est = sender_api.estimate_initiate_tx(
None, None,
amount * 2, // amount amount * 2, // amount
2, // minimum confirmations 2, // minimum confirmations
@ -268,8 +268,8 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> {
1, // num change outputs 1, // num change outputs
false, // select the smallest amount of outputs false, // select the smallest amount of outputs
)?; )?;
assert_eq!(total, 180_000_000_000); assert_eq!(est.total, 180_000_000_000);
assert_eq!(fee, 6_000_000); assert_eq!(est.fee, 6_000_000);
Ok(()) Ok(())
})?; })?;
@ -290,7 +290,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> {
)?; )?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate)?; sender_api.tx_lock_outputs(&slate)?;
sender_api.finalize_tx(&mut slate)?; slate = sender_api.finalize_tx(&slate)?;
Ok(()) Ok(())
})?; })?;
@ -315,7 +315,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> {
})?; })?;
// mine a few more blocks // mine a few more blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
// check wallet2 has stored transaction // check wallet2 has stored transaction
wallet::controller::owner_single_use(wallet2.clone(), |api| { wallet::controller::owner_single_use(wallet2.clone(), |api| {
@ -371,7 +371,7 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> {
let reward = core::consensus::REWARD; let reward = core::consensus::REWARD;
let cm = global::coinbase_maturity(); // assume all testing precedes soft fork height let cm = global::coinbase_maturity(); // assume all testing precedes soft fork height
// mine a few blocks // mine a few blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5, false);
let amount = 30_000_000_000; let amount = 30_000_000_000;
let mut slate = Slate::blank(1); let mut slate = Slate::blank(1);
@ -387,7 +387,7 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> {
)?; )?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?; slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate)?; sender_api.tx_lock_outputs(&slate)?;
sender_api.finalize_tx(&mut slate)?; slate = sender_api.finalize_tx(&slate)?;
Ok(()) Ok(())
})?; })?;
@ -406,16 +406,16 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> {
let mut locked_count = 0; let mut locked_count = 0;
let mut unconfirmed_count = 0; let mut unconfirmed_count = 0;
// get the tx entry, check outputs are as expected // get the tx entry, check outputs are as expected
let (_, outputs) = api.retrieve_outputs(true, false, Some(tx.unwrap().id))?; let (_, output_mappings) = api.retrieve_outputs(true, false, Some(tx.unwrap().id))?;
for (o, _) in outputs.clone() { for m in output_mappings.clone() {
if o.status == OutputStatus::Locked { if m.output.status == OutputStatus::Locked {
locked_count = locked_count + 1; locked_count = locked_count + 1;
} }
if o.status == OutputStatus::Unconfirmed { if m.output.status == OutputStatus::Unconfirmed {
unconfirmed_count = unconfirmed_count + 1; unconfirmed_count = unconfirmed_count + 1;
} }
} }
assert_eq!(outputs.len(), 3); assert_eq!(output_mappings.len(), 3);
assert_eq!(locked_count, 2); assert_eq!(locked_count, 2);
assert_eq!(unconfirmed_count, 1); assert_eq!(unconfirmed_count, 1);
@ -431,8 +431,8 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> {
assert!(tx.is_some()); assert!(tx.is_some());
// get the tx entry, check outputs are as expected // 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(true, false, Some(tx.unwrap().id))?;
for (o, _) in outputs.clone() { for m in outputs.clone() {
if o.status == OutputStatus::Unconfirmed { if m.output.status == OutputStatus::Unconfirmed {
unconfirmed_count = unconfirmed_count + 1; unconfirmed_count = unconfirmed_count + 1;
} }
} }
@ -447,7 +447,7 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> {
// wallet 1 is bold and doesn't ever post the transaction // wallet 1 is bold and doesn't ever post the transaction
// mine a few more blocks // mine a few more blocks
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 5, false);
// Wallet 1 decides to roll back instead // Wallet 1 decides to roll back instead
wallet::controller::owner_single_use(wallet1.clone(), |api| { wallet::controller::owner_single_use(wallet1.clone(), |api| {

View file

@ -24,7 +24,7 @@ ring = "0.13"
tokio = "= 0.1.11" tokio = "= 0.1.11"
tokio-core = "0.1" tokio-core = "0.1"
tokio-retry = "0.1" tokio-retry = "0.1"
uuid = { version = "0.6", features = ["serde", "v4"] } uuid = { version = "0.7", features = ["serde", "v4"] }
chrono = { version = "0.4.4", features = ["serde"] } chrono = { version = "0.4.4", features = ["serde"] }
grin_wallet_libwallet = { path = "../libwallet", version = "1.1.0" } grin_wallet_libwallet = { path = "../libwallet", version = "1.1.0" }

View file

@ -382,7 +382,7 @@ impl WalletCommAdapter for KeybaseWalletCommAdapter {
let res = { let res = {
let mut w = wallet.lock(); let mut w = wallet.lock();
w.open_with_credentials()?; w.open_with_credentials()?;
let r = foreign::receive_tx(&mut *w, &mut slate, None, None); let r = foreign::receive_tx(&mut *w, &mut slate, None, None, false);
w.close()?; w.close()?;
r r
}; };

View file

@ -32,6 +32,7 @@ use grin_core as core;
use grin_keychain as keychain; use grin_keychain as keychain;
use grin_util as util; use grin_util as util;
use std::sync::Arc; use std::sync::Arc;
use std::thread;
mod testclient; mod testclient;
@ -140,6 +141,7 @@ pub fn award_blocks_to_wallet<C, K>(
chain: &Chain, chain: &Chain,
wallet: Arc<Mutex<dyn WalletInst<C, K>>>, wallet: Arc<Mutex<dyn WalletInst<C, K>>>,
number: usize, number: usize,
pause_between: bool,
) -> Result<(), libwallet::Error> ) -> Result<(), libwallet::Error>
where where
C: NodeClient, C: NodeClient,
@ -147,6 +149,9 @@ where
{ {
for _ in 0..number { for _ in 0..number {
award_block_to_wallet(chain, vec![], wallet.clone())?; award_block_to_wallet(chain, vec![], wallet.clone())?;
if pause_between {
thread::sleep(std::time::Duration::from_millis(100));
}
} }
Ok(()) Ok(())
} }
@ -185,6 +190,7 @@ pub fn send_to_dest<T: ?Sized, C, K>(
client: LocalWalletClient, client: LocalWalletClient,
dest: &str, dest: &str,
amount: u64, amount: u64,
test_mode: bool,
) -> Result<(), libwallet::Error> ) -> Result<(), libwallet::Error>
where where
T: WalletBackend<C, K>, T: WalletBackend<C, K>,
@ -201,11 +207,11 @@ where
500, // max outputs 500, // max outputs
1, // num change outputs 1, // num change outputs
true, // select all outputs true, // select all outputs
None, None, None, None, test_mode,
)?; )?;
let mut slate = client.send_tx_slate_direct(dest, &slate_i)?; let slate = client.send_tx_slate_direct(dest, &slate_i)?;
owner::tx_lock_outputs(&mut *w, &slate)?; owner::tx_lock_outputs(&mut *w, &slate)?;
owner::finalize_tx(&mut *w, &mut slate)?; let slate = owner::finalize_tx(&mut *w, &slate)?;
w.close()?; w.close()?;
slate slate
}; };

View file

@ -220,7 +220,7 @@ where
let mut w = wallet.1.lock(); let mut w = wallet.1.lock();
w.open_with_credentials()?; w.open_with_credentials()?;
// receive tx // receive tx
foreign::receive_tx(&mut *w, &mut slate, None, None)?; foreign::receive_tx(&mut *w, &mut slate, None, None, false)?;
w.close()?; w.close()?;
} }

View file

@ -28,11 +28,11 @@ use grin_keychain as keychain;
use grin_p2p as p2p; use grin_p2p as p2p;
use grin_servers as servers; use grin_servers as servers;
use grin_util as util; use grin_util as util;
use p2p::PeerAddr;
use std::default::Default; use std::default::Default;
use std::ops::Deref; use std::ops::Deref;
use std::sync::Arc; use std::sync::Arc;
use std::{fs, thread, time}; use std::{fs, thread, time};
use p2p::PeerAddr;
/// Just removes all results from previous runs /// Just removes all results from previous runs
pub fn clean_all_output(test_name_dir: &str) { pub fn clean_all_output(test_name_dir: &str) {
@ -197,7 +197,9 @@ impl LocalServerContainer {
if self.config.seed_addr.len() > 0 { if self.config.seed_addr.len() > 0 {
seeding_type = p2p::Seeding::List; seeding_type = p2p::Seeding::List;
seeds = vec![PeerAddr::from_ip(self.config.seed_addr.to_string().parse().unwrap())]; seeds = vec![PeerAddr::from_ip(
self.config.seed_addr.to_string().parse().unwrap(),
)];
} }
let s = servers::Server::new(servers::ServerConfig { let s = servers::Server::new(servers::ServerConfig {
@ -357,8 +359,7 @@ impl LocalServerContainer {
.unwrap_or_else(|e| panic!("Error creating wallet: {:?} Config: {:?}", e, config)); .unwrap_or_else(|e| panic!("Error creating wallet: {:?} Config: {:?}", e, config));
wallet.keychain = Some(keychain); wallet.keychain = Some(keychain);
let parent_id = keychain::ExtKeychain::derive_key_id(2, 0, 0, 0, 0); let parent_id = keychain::ExtKeychain::derive_key_id(2, 0, 0, 0, 0);
let _ = let _ = libwallet::internal::updater::refresh_outputs(&mut wallet, &parent_id, false);
libwallet::internal::updater::refresh_outputs(&mut wallet, &parent_id, false);
libwallet::internal::updater::retrieve_info(&mut wallet, &parent_id, 1).unwrap() libwallet::internal::updater::retrieve_info(&mut wallet, &parent_id, 1).unwrap()
} }
@ -401,7 +402,7 @@ impl LocalServerContainer {
None, None,
)?; )?;
slate = client_w.send_tx_sync(dest, &slate)?; slate = client_w.send_tx_sync(dest, &slate)?;
api.finalize_tx(&mut slate)?; slate = api.finalize_tx(&slate)?;
api.tx_lock_outputs(&slate, lock_fn)?; api.tx_lock_outputs(&slate, lock_fn)?;
println!( println!(
"Tx sent: {} grin to {} (strategy '{}')", "Tx sent: {} grin to {} (strategy '{}')",
@ -655,7 +656,9 @@ pub fn config(n: u16, test_name_dir: &str, seed_n: u16) -> servers::ServerConfig
p2p_config: p2p::P2PConfig { p2p_config: p2p::P2PConfig {
port: 10000 + n, port: 10000 + n,
seeding_type: p2p::Seeding::List, seeding_type: p2p::Seeding::List,
seeds: Some(vec![PeerAddr::from_ip(format!("127.0.0.1:{}", 10000 + seed_n).parse().unwrap())]), seeds: Some(vec![PeerAddr::from_ip(
format!("127.0.0.1:{}", 10000 + seed_n).parse().unwrap(),
)]),
..p2p::P2PConfig::default() ..p2p::P2PConfig::default()
}, },
chain_type: core::global::ChainTypes::AutomatedTesting, chain_type: core::global::ChainTypes::AutomatedTesting,

View file

@ -35,12 +35,12 @@ use grin_keychain as keychain;
use grin_p2p as p2p; use grin_p2p as p2p;
use grin_servers as servers; use grin_servers as servers;
use grin_util as util; use grin_util as util;
use p2p::PeerAddr;
use std::cmp; use std::cmp;
use std::default::Default; use std::default::Default;
use std::process::exit; use std::process::exit;
use std::sync::Arc; use std::sync::Arc;
use std::{thread, time}; use std::{thread, time};
use p2p::PeerAddr;
use crate::framework::{ use crate::framework::{
config, stop_all_servers, LocalServerContainerConfig, LocalServerContainerPool, config, stop_all_servers, LocalServerContainerConfig, LocalServerContainerPool,
@ -948,7 +948,8 @@ fn replicate_tx_fluff_failure() {
for i in 0..dl_nodes { for i in 0..dl_nodes {
// (create some stem nodes) // (create some stem nodes)
let mut s_config = framework::config(3002 + i, "tx_fluff", 3002 + i); let mut s_config = framework::config(3002 + i, "tx_fluff", 3002 + i);
s_config.p2p_config.seeds = Some(vec![PeerAddr::from_ip("127.0.0.1:13000".parse().unwrap())]); s_config.p2p_config.seeds =
Some(vec![PeerAddr::from_ip("127.0.0.1:13000".parse().unwrap())]);
s_config.dandelion_config.embargo_secs = Some(10); s_config.dandelion_config.embargo_secs = Some(10);
s_config.dandelion_config.patience_secs = Some(1); s_config.dandelion_config.patience_secs = Some(1);
s_config.dandelion_config.relay_secs = Some(1); s_config.dandelion_config.relay_secs = Some(1);
@ -973,7 +974,7 @@ fn replicate_tx_fluff_failure() {
None, None,
)?; )?;
slate = client1_w.send_tx_sync(dest, &slate)?; slate = client1_w.send_tx_sync(dest, &slate)?;
api.finalize_tx(&mut slate)?; slate = api.finalize_tx(&slate)?;
api.tx_lock_outputs(&slate, lock_fn)?; api.tx_lock_outputs(&slate, lock_fn)?;
api.post_tx(&slate.tx, false)?; api.post_tx(&slate.tx, false)?;
Ok(()) Ok(())

View file

@ -20,8 +20,9 @@ serde = "1"
serde_derive = "1" serde_derive = "1"
serde_json = "1" serde_json = "1"
log = "0.4" log = "0.4"
uuid = { version = "0.6", features = ["serde", "v4"] } uuid = { version = "0.7", features = ["serde", "v4"] }
chrono = { version = "0.4.4", features = ["serde"] } chrono = { version = "0.4.4", features = ["serde"] }
lazy_static = "1"
grin_core = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" } grin_core = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" }
grin_keychain = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" } grin_keychain = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" }

View file

@ -43,6 +43,7 @@ pub fn receive_tx<T: ?Sized, C, K>(
slate: &mut Slate, slate: &mut Slate,
dest_acct_name: Option<&str>, dest_acct_name: Option<&str>,
message: Option<String>, message: Option<String>,
use_test_rng: bool,
) -> Result<(), Error> ) -> Result<(), Error>
where where
T: WalletBackend<C, K>, T: WalletBackend<C, K>,
@ -75,7 +76,7 @@ where
None => None, None => None,
}; };
tx::add_output_to_slate(&mut *w, slate, &parent_key_id, 1, message)?; tx::add_output_to_slate(&mut *w, slate, &parent_key_id, 1, message, use_test_rng)?;
tx::update_message(&mut *w, slate)?; tx::update_message(&mut *w, slate)?;
Ok(()) Ok(())
} }

View file

@ -24,9 +24,9 @@ use crate::internal::{keys, selection, tx, updater};
use crate::keychain::{Identifier, Keychain}; use crate::keychain::{Identifier, Keychain};
use crate::slate::Slate; use crate::slate::Slate;
use crate::types::{ use crate::types::{
AcctPathMapping, NodeClient, OutputData, TxLogEntry, TxWrapper, WalletBackend, WalletInfo, AcctPathMapping, NodeClient, OutputCommitMapping, TxEstimation, TxLogEntry, TxWrapper,
WalletBackend, WalletInfo,
}; };
use crate::util::secp::pedersen;
use crate::{Error, ErrorKind}; use crate::{Error, ErrorKind};
const USER_MESSAGE_MAX_LEN: usize = 256; const USER_MESSAGE_MAX_LEN: usize = 256;
@ -67,7 +67,7 @@ pub fn retrieve_outputs<T: ?Sized, C, K>(
include_spent: bool, include_spent: bool,
refresh_from_node: bool, refresh_from_node: bool,
tx_id: Option<u32>, tx_id: Option<u32>,
) -> Result<(bool, Vec<(OutputData, pedersen::Commitment)>), Error> ) -> Result<(bool, Vec<OutputCommitMapping>), Error>
where where
T: WalletBackend<C, K>, T: WalletBackend<C, K>,
C: NodeClient, C: NodeClient,
@ -144,6 +144,7 @@ pub fn initiate_tx<T: ?Sized, C, K>(
selection_strategy_is_use_all: bool, selection_strategy_is_use_all: bool,
message: Option<String>, message: Option<String>,
target_slate_version: Option<u16>, target_slate_version: Option<u16>,
use_test_rng: bool,
) -> Result<Slate, Error> ) -> Result<Slate, Error>
where where
T: WalletBackend<C, K>, T: WalletBackend<C, K>,
@ -169,7 +170,7 @@ where
None => None, None => None,
}; };
let mut slate = tx::new_tx_slate(&mut *w, amount, 2)?; let mut slate = tx::new_tx_slate(&mut *w, amount, 2, use_test_rng)?;
let context = tx::add_inputs_to_slate( let context = tx::add_inputs_to_slate(
&mut *w, &mut *w,
@ -181,6 +182,7 @@ where
&parent_key_id, &parent_key_id,
0, 0,
message, message,
use_test_rng,
)?; )?;
// Save the aggsig context in our DB for when we // Save the aggsig context in our DB for when we
@ -205,13 +207,7 @@ pub fn estimate_initiate_tx<T: ?Sized, C, K>(
max_outputs: usize, max_outputs: usize,
num_change_outputs: usize, num_change_outputs: usize,
selection_strategy_is_use_all: bool, selection_strategy_is_use_all: bool,
) -> Result< ) -> Result<TxEstimation, Error>
(
u64, // total
u64, // fee
),
Error,
>
where where
T: WalletBackend<C, K>, T: WalletBackend<C, K>,
C: NodeClient, C: NodeClient,
@ -227,7 +223,7 @@ where
} }
None => w.parent_key_id(), None => w.parent_key_id(),
}; };
tx::estimate_send_tx( let (total, fee) = tx::estimate_send_tx(
&mut *w, &mut *w,
amount, amount,
minimum_confirmations, minimum_confirmations,
@ -235,7 +231,8 @@ where
num_change_outputs, num_change_outputs,
selection_strategy_is_use_all, selection_strategy_is_use_all,
&parent_key_id, &parent_key_id,
) )?;
Ok(TxEstimation { total, fee })
} }
/// Lock sender outputs /// Lock sender outputs
@ -250,22 +247,23 @@ where
} }
/// Finalize slate /// Finalize slate
pub fn finalize_tx<T: ?Sized, C, K>(w: &mut T, slate: &mut Slate) -> Result<(), Error> pub fn finalize_tx<T: ?Sized, C, K>(w: &mut T, slate: &Slate) -> Result<Slate, Error>
where where
T: WalletBackend<C, K>, T: WalletBackend<C, K>,
C: NodeClient, C: NodeClient,
K: Keychain, K: Keychain,
{ {
let context = w.get_private_context(slate.id.as_bytes())?; let mut sl = slate.clone();
tx::complete_tx(&mut *w, slate, 0, &context)?; let context = w.get_private_context(sl.id.as_bytes())?;
tx::update_stored_tx(&mut *w, slate)?; tx::complete_tx(&mut *w, &mut sl, 0, &context)?;
tx::update_message(&mut *w, slate)?; tx::update_stored_tx(&mut *w, &mut sl)?;
tx::update_message(&mut *w, &mut sl)?;
{ {
let mut batch = w.batch()?; let mut batch = w.batch()?;
batch.delete_private_context(slate.id.as_bytes())?; batch.delete_private_context(sl.id.as_bytes())?;
batch.commit()?; batch.commit()?;
} }
Ok(()) Ok(sl)
} }
/// cancel tx /// cancel tx
@ -360,7 +358,7 @@ where
Ok(height) => Ok((height, true)), Ok(height) => Ok((height, true)),
Err(_) => { Err(_) => {
let outputs = retrieve_outputs(w, true, false, None)?; let outputs = retrieve_outputs(w, true, false, None)?;
let height = match outputs.1.iter().map(|(out, _)| out.height).max() { let height = match outputs.1.iter().map(|m| m.output.height).max() {
Some(height) => height, Some(height) => height,
None => 0, None => 0,
}; };

View file

@ -293,14 +293,14 @@ where
// check all definitive outputs exist in the wallet outputs // check all definitive outputs exist in the wallet outputs
for deffo in chain_outs.into_iter() { for deffo in chain_outs.into_iter() {
let matched_out = wallet_outputs.iter().find(|wo| wo.1 == deffo.commit); let matched_out = wallet_outputs.iter().find(|wo| wo.commit == deffo.commit);
match matched_out { match matched_out {
Some(s) => { Some(s) => {
if s.0.status == OutputStatus::Spent { if s.output.status == OutputStatus::Spent {
accidental_spend_outs.push((s.0.clone(), deffo.clone())); accidental_spend_outs.push((s.output.clone(), deffo.clone()));
} }
if s.0.status == OutputStatus::Locked { if s.output.status == OutputStatus::Locked {
locked_outs.push((s.0.clone(), deffo.clone())); locked_outs.push((s.output.clone(), deffo.clone()));
} }
} }
None => missing_outs.push(deffo), None => missing_outs.push(deffo),
@ -351,17 +351,17 @@ where
batch.commit()?; batch.commit()?;
} }
let unconfirmed_outs: Vec<&(OutputData, pedersen::Commitment)> = wallet_outputs let unconfirmed_outs: Vec<&OutputCommitMapping> = wallet_outputs
.iter() .iter()
.filter(|o| o.0.status == OutputStatus::Unconfirmed) .filter(|o| o.output.status == OutputStatus::Unconfirmed)
.collect(); .collect();
// Delete unconfirmed outputs // Delete unconfirmed outputs
for m in unconfirmed_outs.into_iter() { for m in unconfirmed_outs.into_iter() {
let o = m.0.clone(); let o = m.output.clone();
warn!( warn!(
"Unconfirmed output for {} with ID {} ({:?}) not in UTXO set. \ "Unconfirmed output for {} with ID {} ({:?}) not in UTXO set. \
Deleting and cancelling associated transaction log entries.", Deleting and cancelling associated transaction log entries.",
o.value, o.key_id, m.1, o.value, o.key_id, m.commit,
); );
cancel_tx_log_entry(wallet, &o)?; cancel_tx_log_entry(wallet, &o)?;
let mut batch = wallet.batch()?; let mut batch = wallet.batch()?;

View file

@ -36,6 +36,7 @@ pub fn build_send_tx<T: ?Sized, C, K>(
change_outputs: usize, change_outputs: usize,
selection_strategy_is_use_all: bool, selection_strategy_is_use_all: bool,
parent_key_id: Identifier, parent_key_id: Identifier,
use_test_nonce: bool,
) -> Result<Context, Error> ) -> Result<Context, Error>
where where
T: WalletBackend<C, K>, T: WalletBackend<C, K>,
@ -64,6 +65,7 @@ where
wallet.keychain().secp(), wallet.keychain().secp(),
blinding.secret_key(&keychain.secp()).unwrap(), blinding.secret_key(&keychain.secp()).unwrap(),
&parent_key_id, &parent_key_id,
use_test_nonce,
); );
context.fee = fee; context.fee = fee;
@ -171,6 +173,7 @@ pub fn build_recipient_output<T: ?Sized, C, K>(
wallet: &mut T, wallet: &mut T,
slate: &mut Slate, slate: &mut Slate,
parent_key_id: Identifier, parent_key_id: Identifier,
use_test_rng: bool,
) -> Result<(Identifier, Context), Error> ) -> Result<(Identifier, Context), Error>
where where
T: WalletBackend<C, K>, T: WalletBackend<C, K>,
@ -196,6 +199,7 @@ where
.secret_key(wallet.keychain().clone().secp()) .secret_key(wallet.keychain().clone().secp())
.unwrap(), .unwrap(),
&parent_key_id, &parent_key_id,
use_test_rng,
); );
context.add_output(&key_id, &None, amount); context.add_output(&key_id, &None, amount);

View file

@ -21,6 +21,12 @@ use crate::keychain::{Identifier, Keychain};
use crate::slate::Slate; use crate::slate::Slate;
use crate::types::{Context, NodeClient, TxLogEntryType, WalletBackend}; use crate::types::{Context, NodeClient, TxLogEntryType, WalletBackend};
use crate::{Error, ErrorKind}; use crate::{Error, ErrorKind};
use util::Mutex;
/// static for incrementing test UUIDs
lazy_static! {
static ref SLATE_COUNTER: Mutex<u8> = { Mutex::new(0) };
}
/// Creates a new slate for a transaction, can be called by anyone involved in /// Creates a new slate for a transaction, can be called by anyone involved in
/// the transaction (sender(s), receiver(s)) /// the transaction (sender(s), receiver(s))
@ -28,6 +34,7 @@ pub fn new_tx_slate<T: ?Sized, C, K>(
wallet: &mut T, wallet: &mut T,
amount: u64, amount: u64,
num_participants: usize, num_participants: usize,
use_test_rng: bool,
) -> Result<Slate, Error> ) -> Result<Slate, Error>
where where
T: WalletBackend<C, K>, T: WalletBackend<C, K>,
@ -36,6 +43,14 @@ where
{ {
let current_height = wallet.w2n_client().get_chain_height()?; let current_height = wallet.w2n_client().get_chain_height()?;
let mut slate = Slate::blank(num_participants); let mut slate = Slate::blank(num_participants);
if use_test_rng {
{
let sc = SLATE_COUNTER.lock();
let bytes = [4, 54, 67, 12, 43, 2, 98, 76, 32, 50, 87, 5, 1, 33, 43, *sc];
slate.id = Uuid::from_slice(&bytes).unwrap();
}
*SLATE_COUNTER.lock() += 1;
}
slate.amount = amount; slate.amount = amount;
slate.height = current_height; slate.height = current_height;
@ -103,6 +118,7 @@ pub fn add_inputs_to_slate<T: ?Sized, C, K>(
parent_key_id: &Identifier, parent_key_id: &Identifier,
participant_id: usize, participant_id: usize,
message: Option<String>, message: Option<String>,
use_test_rng: bool,
) -> Result<Context, Error> ) -> Result<Context, Error>
where where
T: WalletBackend<C, K>, T: WalletBackend<C, K>,
@ -127,6 +143,7 @@ where
num_change_outputs, num_change_outputs,
selection_strategy_is_use_all, selection_strategy_is_use_all,
parent_key_id.clone(), parent_key_id.clone(),
use_test_rng,
)?; )?;
// Generate a kernel offset and subtract from our context's secret key. Store // Generate a kernel offset and subtract from our context's secret key. Store
@ -138,6 +155,7 @@ where
&context.sec_nonce, &context.sec_nonce,
participant_id, participant_id,
message, message,
use_test_rng,
)?; )?;
Ok(context) Ok(context)
@ -150,6 +168,7 @@ pub fn add_output_to_slate<T: ?Sized, C, K>(
parent_key_id: &Identifier, parent_key_id: &Identifier,
participant_id: usize, participant_id: usize,
message: Option<String>, message: Option<String>,
use_test_rng: bool,
) -> Result<Context, Error> ) -> Result<Context, Error>
where where
T: WalletBackend<C, K>, T: WalletBackend<C, K>,
@ -157,7 +176,8 @@ where
K: Keychain, K: Keychain,
{ {
// create an output using the amount in the slate // create an output using the amount in the slate
let (_, mut context) = selection::build_recipient_output(wallet, slate, parent_key_id.clone())?; let (_, mut context) =
selection::build_recipient_output(wallet, slate, parent_key_id.clone(), use_test_rng)?;
// fill public keys // fill public keys
let _ = slate.fill_round_1( let _ = slate.fill_round_1(
@ -166,6 +186,7 @@ where
&context.sec_nonce, &context.sec_nonce,
1, 1,
message, message,
false,
)?; )?;
// perform partial sig // perform partial sig
@ -233,7 +254,7 @@ where
} }
// get outputs associated with tx // 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, false, Some(tx.id), Some(&parent_key_id))?;
let outputs = res.iter().map(|(out, _)| out).cloned().collect(); 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, tx, outputs, parent_key_id)?;
Ok(()) Ok(())
} }

View file

@ -27,8 +27,8 @@ use crate::error::{Error, ErrorKind};
use crate::internal::keys; use crate::internal::keys;
use crate::keychain::{Identifier, Keychain}; use crate::keychain::{Identifier, Keychain};
use crate::types::{ use crate::types::{
BlockFees, CbData, NodeClient, OutputData, OutputStatus, TxLogEntry, TxLogEntryType, BlockFees, CbData, NodeClient, OutputCommitMapping, OutputData, OutputStatus, TxLogEntry,
WalletBackend, WalletInfo, TxLogEntryType, WalletBackend, WalletInfo,
}; };
use crate::util; use crate::util;
use crate::util::secp::pedersen; use crate::util::secp::pedersen;
@ -39,7 +39,7 @@ pub fn retrieve_outputs<T: ?Sized, C, K>(
show_spent: bool, show_spent: bool,
tx_id: Option<u32>, tx_id: Option<u32>,
parent_key_id: Option<&Identifier>, parent_key_id: Option<&Identifier>,
) -> Result<Vec<(OutputData, pedersen::Commitment)>, Error> ) -> Result<Vec<OutputCommitMapping>, Error>
where where
T: WalletBackend<C, K>, T: WalletBackend<C, K>,
C: NodeClient, C: NodeClient,
@ -72,12 +72,12 @@ where
let res = outputs let res = outputs
.into_iter() .into_iter()
.map(|out| { .map(|output| {
let commit = match out.commit.clone() { let commit = match output.commit.clone() {
Some(c) => pedersen::Commitment::from_vec(util::from_hex(c).unwrap()), Some(c) => pedersen::Commitment::from_vec(util::from_hex(c).unwrap()),
None => keychain.commit(out.value, &out.key_id).unwrap(), None => keychain.commit(output.value, &output.key_id).unwrap(),
}; };
(out, commit) OutputCommitMapping { output, commit }
}) })
.collect(); .collect();
Ok(res) Ok(res)

View file

@ -37,6 +37,8 @@ extern crate failure_derive;
extern crate serde_derive; extern crate serde_derive;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
#[macro_use]
extern crate lazy_static;
pub mod api_impl; pub mod api_impl;
mod error; mod error;

View file

@ -28,6 +28,7 @@ use grin_core::core::committed::Committed;
use grin_core::core::transaction::{kernel_features, kernel_sig_msg, Transaction, Weighting}; use grin_core::core::transaction::{kernel_features, kernel_sig_msg, Transaction, Weighting};
use grin_core::core::verifier_cache::LruVerifierCache; use grin_core::core::verifier_cache::LruVerifierCache;
use grin_core::libtx::{aggsig, build, secp_ser, tx_fee}; use grin_core::libtx::{aggsig, build, secp_ser, tx_fee};
use rand::rngs::mock::StepRng;
use rand::thread_rng; use rand::thread_rng;
use serde_json; use serde_json;
use std::sync::Arc; use std::sync::Arc;
@ -44,6 +45,7 @@ const CURRENT_SLATE_VERSION: u16 = 2;
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ParticipantData { pub struct ParticipantData {
/// Id of participant in the transaction. (For now, 0=sender, 1=rec) /// Id of participant in the transaction. (For now, 0=sender, 1=rec)
#[serde(with = "secp_ser::string_or_u64")]
pub id: u64, pub id: u64,
/// Public key corresponding to private blinding factor /// Public key corresponding to private blinding factor
#[serde(with = "secp_ser::pubkey_serde")] #[serde(with = "secp_ser::pubkey_serde")]
@ -82,6 +84,7 @@ impl ParticipantData {
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ParticipantMessageData { pub struct ParticipantMessageData {
/// id of the particpant in the tx /// id of the particpant in the tx
#[serde(with = "secp_ser::string_or_u64")]
pub id: u64, pub id: u64,
/// Public key /// Public key
#[serde(with = "secp_ser::pubkey_serde")] #[serde(with = "secp_ser::pubkey_serde")]
@ -122,12 +125,16 @@ pub struct Slate {
/// inputs, outputs, kernels, kernel offset /// inputs, outputs, kernels, kernel offset
pub tx: Transaction, pub tx: Transaction,
/// base amount (excluding fee) /// base amount (excluding fee)
#[serde(with = "secp_ser::string_or_u64")]
pub amount: u64, pub amount: u64,
/// fee amount /// fee amount
#[serde(with = "secp_ser::string_or_u64")]
pub fee: u64, pub fee: u64,
/// Block height for the transaction /// Block height for the transaction
#[serde(with = "secp_ser::string_or_u64")]
pub height: u64, pub height: u64,
/// Lock height /// Lock height
#[serde(with = "secp_ser::string_or_u64")]
pub lock_height: u64, pub lock_height: u64,
/// Participant data, each participant in the transaction will /// Participant data, each participant in the transaction will
/// insert their public data here. For now, 0 is sender and 1 /// insert their public data here. For now, 0 is sender and 1
@ -268,13 +275,14 @@ impl Slate {
sec_nonce: &SecretKey, sec_nonce: &SecretKey,
participant_id: usize, participant_id: usize,
message: Option<String>, message: Option<String>,
use_test_rng: bool,
) -> Result<(), Error> ) -> Result<(), Error>
where where
K: Keychain, K: Keychain,
{ {
// Whoever does this first generates the offset // Whoever does this first generates the offset
if self.tx.offset == BlindingFactor::zero() { if self.tx.offset == BlindingFactor::zero() {
self.generate_offset(keychain, sec_key)?; self.generate_offset(keychain, sec_key, use_test_rng)?;
} }
self.add_participant_info( self.add_participant_info(
keychain, keychain,
@ -283,6 +291,7 @@ impl Slate {
participant_id, participant_id,
None, None,
message, message,
use_test_rng,
)?; )?;
Ok(()) Ok(())
} }
@ -379,6 +388,7 @@ impl Slate {
id: usize, id: usize,
part_sig: Option<Signature>, part_sig: Option<Signature>,
message: Option<String>, message: Option<String>,
use_test_rng: bool,
) -> Result<(), Error> ) -> Result<(), Error>
where where
K: Keychain, K: Keychain,
@ -386,12 +396,25 @@ impl Slate {
// Add our public key and nonce to the slate // Add our public key and nonce to the slate
let pub_key = PublicKey::from_secret_key(keychain.secp(), &sec_key)?; let pub_key = PublicKey::from_secret_key(keychain.secp(), &sec_key)?;
let pub_nonce = PublicKey::from_secret_key(keychain.secp(), &sec_nonce)?; let pub_nonce = PublicKey::from_secret_key(keychain.secp(), &sec_nonce)?;
let test_message_nonce = SecretKey::from_slice(&keychain.secp(), &[1; 32]).unwrap();
let message_nonce = match use_test_rng {
false => None,
true => Some(&test_message_nonce),
};
// Sign the provided message // Sign the provided message
let message_sig = { let message_sig = {
if let Some(m) = message.clone() { if let Some(m) = message.clone() {
let hashed = blake2b(secp::constants::MESSAGE_SIZE, &[], &m.as_bytes()[..]); let hashed = blake2b(secp::constants::MESSAGE_SIZE, &[], &m.as_bytes()[..]);
let m = secp::Message::from_slice(&hashed.as_bytes())?; let m = secp::Message::from_slice(&hashed.as_bytes())?;
let res = aggsig::sign_single(&keychain.secp(), &m, &sec_key, Some(&pub_key))?; let res = aggsig::sign_single(
&keychain.secp(),
&m,
&sec_key,
message_nonce,
Some(&pub_key),
)?;
Some(res) Some(res)
} else { } else {
None None
@ -422,15 +445,29 @@ impl Slate {
/// For now, we'll have the transaction initiator be responsible for it /// For now, we'll have the transaction initiator be responsible for it
/// Return offset private key for the participant to use later in the /// Return offset private key for the participant to use later in the
/// transaction /// transaction
fn generate_offset<K>(&mut self, keychain: &K, sec_key: &mut SecretKey) -> Result<(), Error> fn generate_offset<K>(
&mut self,
keychain: &K,
sec_key: &mut SecretKey,
use_test_rng: bool,
) -> Result<(), Error>
where where
K: Keychain, K: Keychain,
{ {
// Generate a random kernel offset here // Generate a random kernel offset here
// and subtract it from the blind_sum so we create // and subtract it from the blind_sum so we create
// the aggsig context with the "split" key // the aggsig context with the "split" key
self.tx.offset = self.tx.offset = match use_test_rng {
BlindingFactor::from_secret_key(SecretKey::new(&keychain.secp(), &mut thread_rng())); false => {
BlindingFactor::from_secret_key(SecretKey::new(&keychain.secp(), &mut thread_rng()))
}
true => {
// allow for consistent test results
let mut test_rng = StepRng::new(1234567890u64, 1);
BlindingFactor::from_secret_key(SecretKey::new(&keychain.secp(), &mut test_rng))
}
};
let blind_offset = keychain.blind_sum( let blind_offset = keychain.blind_sum(
&BlindSum::new() &BlindSum::new()
.add_blinding_factor(BlindingFactor::from_secret_key(sec_key.clone())) .add_blinding_factor(BlindingFactor::from_secret_key(sec_key.clone()))

View file

@ -61,12 +61,16 @@ pub struct SlateV2 {
/// inputs, outputs, kernels, kernel offset /// inputs, outputs, kernels, kernel offset
pub tx: TransactionV2, pub tx: TransactionV2,
/// base amount (excluding fee) /// base amount (excluding fee)
#[serde(with = "secp_ser::string_or_u64")]
pub amount: u64, pub amount: u64,
/// fee amount /// fee amount
#[serde(with = "secp_ser::string_or_u64")]
pub fee: u64, pub fee: u64,
/// Block height for the transaction /// Block height for the transaction
#[serde(with = "secp_ser::string_or_u64")]
pub height: u64, pub height: u64,
/// Lock height /// Lock height
#[serde(with = "secp_ser::string_or_u64")]
pub lock_height: u64, pub lock_height: u64,
/// Participant data, each participant in the transaction will /// Participant data, each participant in the transaction will
/// insert their public data here. For now, 0 is sender and 1 /// insert their public data here. For now, 0 is sender and 1
@ -87,6 +91,7 @@ pub struct VersionCompatInfoV2 {
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ParticipantDataV2 { pub struct ParticipantDataV2 {
/// Id of participant in the transaction. (For now, 0=sender, 1=rec) /// Id of participant in the transaction. (For now, 0=sender, 1=rec)
#[serde(with = "secp_ser::string_or_u64")]
pub id: u64, pub id: u64,
/// Public key corresponding to private blinding factor /// Public key corresponding to private blinding factor
#[serde(with = "secp_ser::pubkey_serde")] #[serde(with = "secp_ser::pubkey_serde")]
@ -164,9 +169,11 @@ pub struct TxKernelV2 {
/// Options for a kernel's structure or use /// Options for a kernel's structure or use
pub features: KernelFeatures, pub features: KernelFeatures,
/// Fee originally included in the transaction this proof is for. /// Fee originally included in the transaction this proof is for.
#[serde(with = "secp_ser::string_or_u64")]
pub fee: u64, pub fee: u64,
/// This kernel is not valid earlier than lock_height blocks /// This kernel is not valid earlier than lock_height blocks
/// The max lock_height of all *inputs* to this transaction /// The max lock_height of all *inputs* to this transaction
#[serde(with = "secp_ser::string_or_u64")]
pub lock_height: u64, pub lock_height: u64,
/// Remainder of the sum of all transaction commitments. If the transaction /// Remainder of the sum of all transaction commitments. If the transaction
/// is well formed, amounts components should sum to zero and the excess /// is well formed, amounts components should sum to zero and the excess

View file

@ -17,7 +17,7 @@
use crate::core::core::hash::Hash; use crate::core::core::hash::Hash;
use crate::core::core::Transaction; use crate::core::core::Transaction;
use crate::core::libtx::aggsig; use crate::core::libtx::{aggsig, secp_ser};
use crate::core::ser; use crate::core::ser;
use crate::error::{Error, ErrorKind}; use crate::error::{Error, ErrorKind};
use crate::keychain::{Identifier, Keychain}; use crate::keychain::{Identifier, Keychain};
@ -253,14 +253,18 @@ pub struct OutputData {
pub commit: Option<String>, pub commit: Option<String>,
/// PMMR Index, used on restore in case of duplicate wallets using the same /// PMMR Index, used on restore in case of duplicate wallets using the same
/// key_id (2 wallets using same seed, for instance /// key_id (2 wallets using same seed, for instance
#[serde(with = "secp_ser::opt_string_or_u64")]
pub mmr_index: Option<u64>, pub mmr_index: Option<u64>,
/// Value of the output, necessary to rebuild the commitment /// Value of the output, necessary to rebuild the commitment
#[serde(with = "secp_ser::string_or_u64")]
pub value: u64, pub value: u64,
/// Current status of the output /// Current status of the output
pub status: OutputStatus, pub status: OutputStatus,
/// Height of the output /// Height of the output
#[serde(with = "secp_ser::string_or_u64")]
pub height: u64, pub height: u64,
/// Height we are locked until /// Height we are locked until
#[serde(with = "secp_ser::string_or_u64")]
pub lock_height: u64, pub lock_height: u64,
/// Is this a coinbase output? Is it subject to coinbase locktime? /// Is this a coinbase output? Is it subject to coinbase locktime?
pub is_coinbase: bool, pub is_coinbase: bool,
@ -369,6 +373,29 @@ impl fmt::Display for OutputStatus {
} }
} }
/// Map Outputdata to commits
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct OutputCommitMapping {
/// Output Data
pub output: OutputData,
/// The commit
#[serde(
serialize_with = "secp_ser::as_hex",
deserialize_with = "secp_ser::commitment_from_hex"
)]
pub commit: pedersen::Commitment,
}
/// Transaction Estimate
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TxEstimation {
/// Total amount to be locked
#[serde(with = "secp_ser::string_or_u64")]
pub total: u64,
/// Transaction Fee
#[serde(with = "secp_ser::string_or_u64")]
pub fee: u64,
}
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
/// Holds the context for a single aggsig transaction /// Holds the context for a single aggsig transaction
pub struct Context { pub struct Context {
@ -391,11 +418,20 @@ pub struct Context {
impl Context { impl Context {
/// Create a new context with defaults /// Create a new context with defaults
pub fn new(secp: &secp::Secp256k1, sec_key: SecretKey, parent_key_id: &Identifier) -> Context { pub fn new(
secp: &secp::Secp256k1,
sec_key: SecretKey,
parent_key_id: &Identifier,
use_test_rng: bool,
) -> Context {
let sec_nonce = match use_test_rng {
false => aggsig::create_secnonce(secp).unwrap(),
true => SecretKey::from_slice(secp, &[1; 32]).unwrap(),
};
Context { Context {
parent_key_id: parent_key_id.clone(), parent_key_id: parent_key_id.clone(),
sec_key: sec_key, sec_key: sec_key,
sec_nonce: aggsig::create_secnonce(secp).unwrap(), sec_nonce,
input_ids: vec![], input_ids: vec![],
output_ids: vec![], output_ids: vec![],
fee: 0, fee: 0,
@ -543,20 +579,28 @@ pub struct CbData {
#[derive(Serialize, Eq, PartialEq, Deserialize, Debug, Clone)] #[derive(Serialize, Eq, PartialEq, Deserialize, Debug, Clone)]
pub struct WalletInfo { pub struct WalletInfo {
/// height from which info was taken /// height from which info was taken
#[serde(with = "secp_ser::string_or_u64")]
pub last_confirmed_height: u64, pub last_confirmed_height: u64,
/// Minimum number of confirmations for an output to be treated as "spendable". /// Minimum number of confirmations for an output to be treated as "spendable".
#[serde(with = "secp_ser::string_or_u64")]
pub minimum_confirmations: u64, pub minimum_confirmations: u64,
/// total amount in the wallet /// total amount in the wallet
#[serde(with = "secp_ser::string_or_u64")]
pub total: u64, pub total: u64,
/// amount awaiting finalization /// amount awaiting finalization
#[serde(with = "secp_ser::string_or_u64")]
pub amount_awaiting_finalization: u64, pub amount_awaiting_finalization: u64,
/// amount awaiting confirmation /// amount awaiting confirmation
#[serde(with = "secp_ser::string_or_u64")]
pub amount_awaiting_confirmation: u64, pub amount_awaiting_confirmation: u64,
/// coinbases waiting for lock height /// coinbases waiting for lock height
#[serde(with = "secp_ser::string_or_u64")]
pub amount_immature: u64, pub amount_immature: u64,
/// amount currently spendable /// amount currently spendable
#[serde(with = "secp_ser::string_or_u64")]
pub amount_currently_spendable: u64, pub amount_currently_spendable: u64,
/// amount locked via previous transactions /// amount locked via previous transactions
#[serde(with = "secp_ser::string_or_u64")]
pub amount_locked: u64, pub amount_locked: u64,
} }
@ -615,10 +659,13 @@ pub struct TxLogEntry {
/// number of outputs involved in TX /// number of outputs involved in TX
pub num_outputs: usize, pub num_outputs: usize,
/// Amount credited via this transaction /// Amount credited via this transaction
#[serde(with = "secp_ser::string_or_u64")]
pub amount_credited: u64, pub amount_credited: u64,
/// Amount debited via this transaction /// Amount debited via this transaction
#[serde(with = "secp_ser::string_or_u64")]
pub amount_debited: u64, pub amount_debited: u64,
/// Fee /// Fee
#[serde(with = "secp_ser::opt_string_or_u64")]
pub fee: Option<u64>, pub fee: Option<u64>,
/// Message data, stored as json /// Message data, stored as json
pub messages: Option<ParticipantMessages>, pub messages: Option<ParticipantMessages>,

View file

@ -72,7 +72,7 @@ fn aggsig_sender_receiver_interaction() {
let blind = blinding_factor.secret_key(&keychain.secp()).unwrap(); let blind = blinding_factor.secret_key(&keychain.secp()).unwrap();
s_cx = Context::new(&keychain.secp(), blind, &parent); s_cx = Context::new(&keychain.secp(), blind, &parent, false);
s_cx.get_public_keys(&keychain.secp()) s_cx.get_public_keys(&keychain.secp())
}; };
@ -86,7 +86,7 @@ fn aggsig_sender_receiver_interaction() {
// let blind = blind_sum.secret_key(&keychain.secp())?; // let blind = blind_sum.secret_key(&keychain.secp())?;
let blind = keychain.derive_key(0, &key_id).unwrap(); let blind = keychain.derive_key(0, &key_id).unwrap();
rx_cx = Context::new(&keychain.secp(), blind, &parent); rx_cx = Context::new(&keychain.secp(), blind, &parent, false);
let (pub_excess, pub_nonce) = rx_cx.get_public_keys(&keychain.secp()); let (pub_excess, pub_nonce) = rx_cx.get_public_keys(&keychain.secp());
rx_cx.add_output(&key_id, &None, 0); rx_cx.add_output(&key_id, &None, 0);
@ -290,7 +290,7 @@ fn aggsig_sender_receiver_interaction_offset() {
let blind = blinding_factor.secret_key(&keychain.secp()).unwrap(); let blind = blinding_factor.secret_key(&keychain.secp()).unwrap();
s_cx = Context::new(&keychain.secp(), blind, &parent); s_cx = Context::new(&keychain.secp(), blind, &parent, false);
s_cx.get_public_keys(&keychain.secp()) s_cx.get_public_keys(&keychain.secp())
}; };
@ -303,7 +303,7 @@ fn aggsig_sender_receiver_interaction_offset() {
let blind = keychain.derive_key(0, &key_id).unwrap(); let blind = keychain.derive_key(0, &key_id).unwrap();
rx_cx = Context::new(&keychain.secp(), blind, &parent); rx_cx = Context::new(&keychain.secp(), blind, &parent, false);
let (pub_excess, pub_nonce) = rx_cx.get_public_keys(&keychain.secp()); let (pub_excess, pub_nonce) = rx_cx.get_public_keys(&keychain.secp());
rx_cx.add_output(&key_id, &None, 0); rx_cx.add_output(&key_id, &None, 0);

View file

@ -29,21 +29,21 @@
"kernels": [ "kernels": [
{ {
"features": "HeightLocked", "features": "HeightLocked",
"fee": 7000000, "fee": "7000000",
"lock_height": 70194, "lock_height": "70194",
"excess": "000000000000000000000000000000000000000000000000000000000000000000", "excess": "000000000000000000000000000000000000000000000000000000000000000000",
"excess_sig": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "excess_sig": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
} }
] ]
} }
}, },
"amount": 84825921007, "amount": "84825921007",
"fee": 7000000, "fee": "7000000",
"height": 70194, "height": "70194",
"lock_height": 70194, "lock_height": "70194",
"participant_data": [ "participant_data": [
{ {
"id": 0, "id": "0",
"public_blind_excess": "0391f8fc74bb5ff4de373352e7dee00860d4fb78ed7a99765585af980d8a31c615", "public_blind_excess": "0391f8fc74bb5ff4de373352e7dee00860d4fb78ed7a99765585af980d8a31c615",
"public_nonce": "0206562c21a7f3a003622722ee93c4ecbbecead4a6ad8ee5d930b51ca4a6ca6d01", "public_nonce": "0206562c21a7f3a003622722ee93c4ecbbecead4a6ad8ee5d930b51ca4a6ca6d01",
"part_sig": null, "part_sig": null,

View file

@ -245,7 +245,7 @@ mod wallet_tests {
})?; })?;
let mut bh = 10u64; let mut bh = 10u64;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), bh as usize, false);
let very_long_message = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef\ let very_long_message = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef\
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef\ ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef\
@ -320,7 +320,7 @@ mod wallet_tests {
Ok(()) Ok(())
})?; })?;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 10); let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 10, false);
bh += 10; bh += 10;
// update info for each // update info for each