Merge pull request #218 from zcash/feature/autoshielding-poc
Feature/autoshielding poc
This commit is contained in:
commit
5c57b0808f
|
@ -75,4 +75,4 @@ fraget/
|
|||
# other
|
||||
DecompileChecker.kt
|
||||
backup-dbs/
|
||||
|
||||
*.db
|
||||
|
|
|
@ -17,34 +17,33 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
|||
|
||||
[[package]]
|
||||
name = "aes"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd2bc6d3f370b5666245ff421e231cba4353df936e26986d2918e61a8fd6aef6"
|
||||
checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561"
|
||||
dependencies = [
|
||||
"aes-soft",
|
||||
"aesni",
|
||||
"block-cipher",
|
||||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aes-soft"
|
||||
version = "0.5.0"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63dd91889c49327ad7ef3b500fd1109dbd3c509a03db0d4a9ce413b79f575cb6"
|
||||
checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072"
|
||||
dependencies = [
|
||||
"block-cipher",
|
||||
"byteorder",
|
||||
"opaque-debug 0.3.0",
|
||||
"cipher",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aesni"
|
||||
version = "0.8.0"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a6fe808308bb07d393e2ea47780043ec47683fcf19cf5efc8ca51c50cc8c68a"
|
||||
checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce"
|
||||
dependencies = [
|
||||
"block-cipher",
|
||||
"opaque-debug 0.3.0",
|
||||
"cipher",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -134,12 +133,6 @@ version = "0.11.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.0"
|
||||
|
@ -148,9 +141,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
|||
|
||||
[[package]]
|
||||
name = "bech32"
|
||||
version = "0.7.3"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dabbe35f96fb9507f7330793dc490461b2962659ac5d427181e451a623751d1"
|
||||
checksum = "6c7f7096bc256f5e5cb960f60dfc4f4ef979ca65abe7fb9d5a4f77150d3783d4"
|
||||
|
||||
[[package]]
|
||||
name = "bellman"
|
||||
|
@ -158,7 +151,7 @@ version = "0.8.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7089887635778eabf0038a166f586eee5413fb85c8fa6c9a754914f0f644f49f"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"bitvec 0.18.5",
|
||||
"blake2s_simd",
|
||||
"byteorder",
|
||||
"crossbeam",
|
||||
|
@ -185,7 +178,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "98fcd36dda4e17b7d7abc64cb549bf0201f4ab71e00700c798ca7e62ed3761fa"
|
||||
dependencies = [
|
||||
"funty",
|
||||
"radium",
|
||||
"radium 0.3.0",
|
||||
"wyz",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
version = "0.19.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321"
|
||||
dependencies = [
|
||||
"funty",
|
||||
"radium 0.5.3",
|
||||
"tap",
|
||||
"wyz",
|
||||
]
|
||||
|
||||
|
@ -211,53 +216,23 @@ dependencies = [
|
|||
"constant_time_eq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||
dependencies = [
|
||||
"block-padding 0.1.5",
|
||||
"byte-tools",
|
||||
"byteorder",
|
||||
"generic-array 0.12.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
||||
dependencies = [
|
||||
"generic-array 0.14.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-cipher"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f337a3e6da609650eb74e02bc9fac7b735049f7623ab12f2e4c719316fcc7e80"
|
||||
dependencies = [
|
||||
"generic-array 0.14.4",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-modes"
|
||||
version = "0.6.1"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c9b14fd8a4739e6548d4b6018696cf991dcf8c6effd9ef9eb33b29b8a650972"
|
||||
checksum = "57a0e8073e8baa88212fb5823574c02ebccb395136ba9a164ab89379ec6072f0"
|
||||
dependencies = [
|
||||
"block-cipher",
|
||||
"block-padding 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
|
||||
dependencies = [
|
||||
"byte-tools",
|
||||
"block-padding",
|
||||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -272,7 +247,7 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4caf0101205582491f772d60a6fcb6bcec19963e68209cb631851eeadb01421f"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"bitvec 0.18.5",
|
||||
"ff",
|
||||
"group",
|
||||
"pairing",
|
||||
|
@ -282,11 +257,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bs58"
|
||||
version = "0.3.1"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb"
|
||||
checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
|
||||
dependencies = [
|
||||
"sha2 0.8.2",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -295,12 +270,6 @@ version = "3.6.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
|
@ -343,6 +312,15 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cipher"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
|
@ -364,9 +342,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "const_fn"
|
||||
version = "0.4.5"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6"
|
||||
checksum = "076a6803b0dacd6a88cfe64deba628b01533ff5ef265687e6938280c1afd0a28"
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
|
@ -478,22 +456,13 @@ dependencies = [
|
|||
"crypto_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
dependencies = [
|
||||
"generic-array 0.12.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
|
||||
dependencies = [
|
||||
"generic-array 0.14.4",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -535,7 +504,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "equihash"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/nuttycom/librustzcash?branch=autoshield-poc-daa#4253f8ef810d199bef0808a6fe3fbf809a5558c8"
|
||||
source = "git+https://github.com/gmale/librustzcash?branch=autoshield-poc-daa-taddr3#74434f370cf474156b73bfb685cb62e8cd5bcd42"
|
||||
dependencies = [
|
||||
"blake2b_simd",
|
||||
"byteorder",
|
||||
|
@ -572,12 +541,6 @@ dependencies = [
|
|||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
|
||||
[[package]]
|
||||
name = "fallible-iterator"
|
||||
version = "0.2.0"
|
||||
|
@ -596,16 +559,16 @@ version = "0.8.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01646e077d4ebda82b73f1bca002ea1e91561a77df2431a9e79729bcc31950ef"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"bitvec 0.18.5",
|
||||
"rand_core 0.5.1",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fpe"
|
||||
version = "0.3.1"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef2196a22f6d98bbde79ae510eb4f397bd446cfbd6c26425e25ec81442a31bab"
|
||||
checksum = "a25080721bbcd2cd4d765b7d607ea350425fa087ce53cd3e31afcacdab850352"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"block-modes",
|
||||
|
@ -650,9 +613,9 @@ checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"
|
|||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f55667319111d593ba876406af7c409c0ebb44dc4be6132a783ccf163ea14c1"
|
||||
checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
@ -665,9 +628,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939"
|
||||
checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
|
@ -675,9 +638,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94"
|
||||
checksum = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815"
|
||||
|
||||
[[package]]
|
||||
name = "futures-cpupool"
|
||||
|
@ -691,9 +654,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "891a4b7b96d84d5940084b2a37632dd65deeae662c114ceaa2c879629c9c0ad1"
|
||||
checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
|
@ -702,15 +665,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71c2c65c57704c32f5241c1223167c2c3294fd34ac020c807ddbe6db287ba59"
|
||||
checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea405816a5139fb39af82c2beb921d52143f556038378d6db21183a5c37fbfb7"
|
||||
checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
|
@ -720,21 +683,21 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85754d98985841b7d4f5e8e6fbfa4a4ac847916893ec511a2917ccd8525b8bb3"
|
||||
checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80"
|
||||
checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1"
|
||||
checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
@ -750,15 +713,6 @@ dependencies = [
|
|||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.4"
|
||||
|
@ -806,7 +760,7 @@ checksum = "f61e21f9181e4f3732976a62a81f2b53f1195867d99325b5b9408b19219137e2"
|
|||
dependencies = [
|
||||
"base64 0.9.3",
|
||||
"bytes 0.5.6",
|
||||
"futures 0.3.13",
|
||||
"futures 0.3.14",
|
||||
"httpbis",
|
||||
"log",
|
||||
"log-ndc",
|
||||
|
@ -855,6 +809,18 @@ dependencies = [
|
|||
"secp256k1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hdwallet"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2033326faddc94885c26775db24683819bf3ae9461e016c45df18b910bdeedd7"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"rand_core 0.6.2",
|
||||
"ring",
|
||||
"secp256k1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.18"
|
||||
|
@ -877,7 +843,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "3d3e4404f8f87938a2db89336609bde64363f5a556b15af936343e7252c9648d"
|
||||
dependencies = [
|
||||
"bytes 0.5.6",
|
||||
"futures 0.3.13",
|
||||
"futures 0.3.14",
|
||||
"log",
|
||||
"log-ndc",
|
||||
"net2",
|
||||
|
@ -926,9 +892,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
|||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.48"
|
||||
version = "0.3.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc9f84f9b115ce7843d60706df1422a916680bfdfcbdb0447c5614ff9d7e4d78"
|
||||
checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
@ -939,7 +905,7 @@ version = "0.5.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "620638af3b80d23f4df0cae21e3cc9809ac8826767f345066f010bcea66a2c55"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"bitvec 0.18.5",
|
||||
"bls12_381",
|
||||
"ff",
|
||||
"group",
|
||||
|
@ -978,9 +944,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.88"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a"
|
||||
checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
|
||||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
|
@ -1106,10 +1072,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "5.1.2"
|
||||
version = "6.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
|
||||
checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2"
|
||||
dependencies = [
|
||||
"bitvec 0.19.5",
|
||||
"funty",
|
||||
"lexical-core",
|
||||
"memchr",
|
||||
"version_check",
|
||||
|
@ -1167,12 +1135,6 @@ version = "1.7.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.3.0"
|
||||
|
@ -1239,36 +1201,36 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "2.22.0"
|
||||
version = "2.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73f72884896d22e0da0e5b266cb9a780b791f6c3b2f5beab6368d6cd4f0dbb86"
|
||||
checksum = "1b7f4a129bb3754c25a4e04032a90173c68f85168f77118ac4cb4936e7f06f92"
|
||||
dependencies = [
|
||||
"bytes 1.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf-codegen"
|
||||
version = "2.22.0"
|
||||
version = "2.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8217a1652dbc91d19c509c558234145faed729191a966896414e5889f62d543"
|
||||
checksum = "e5d2fa3a461857508103b914da60dd7b489c1a834967c2e214ecc1496f0c486a"
|
||||
dependencies = [
|
||||
"protobuf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf-codegen-pure"
|
||||
version = "2.22.0"
|
||||
version = "2.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f239d71417bdc5f8d83c07aeb265f911346e5540a1a6c4285f9c3d1966ed6e3"
|
||||
checksum = "b3a2520307dbb0df861ed77603770dc23b0ec15e5048272416d6447de98e862b"
|
||||
dependencies = [
|
||||
"protobuf",
|
||||
"protobuf-codegen",
|
||||
|
@ -1289,6 +1251,12 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac"
|
||||
|
||||
[[package]]
|
||||
name = "radium"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.5.6"
|
||||
|
@ -1383,21 +1351,20 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.4.3"
|
||||
version = "1.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
|
||||
checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.22"
|
||||
version = "0.6.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
|
||||
checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
|
@ -1420,9 +1387,9 @@ version = "0.9.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251"
|
||||
dependencies = [
|
||||
"block-buffer 0.9.0",
|
||||
"digest 0.9.0",
|
||||
"opaque-debug 0.3.0",
|
||||
"block-buffer",
|
||||
"digest",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1510,9 +1477,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|||
|
||||
[[package]]
|
||||
name = "sct"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c"
|
||||
checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
|
@ -1553,15 +1520,15 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.124"
|
||||
version = "1.0.125"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f"
|
||||
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.124"
|
||||
version = "1.0.125"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b"
|
||||
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1585,29 +1552,17 @@ version = "0.6.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
|
||||
dependencies = [
|
||||
"block-buffer 0.7.3",
|
||||
"digest 0.8.1",
|
||||
"fake-simd",
|
||||
"opaque-debug 0.2.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de"
|
||||
dependencies = [
|
||||
"block-buffer 0.9.0",
|
||||
"block-buffer",
|
||||
"cfg-if 1.0.0",
|
||||
"cpuid-bool",
|
||||
"digest 0.9.0",
|
||||
"opaque-debug 0.3.0",
|
||||
"digest",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1630,9 +1585,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
|||
|
||||
[[package]]
|
||||
name = "standback"
|
||||
version = "0.2.15"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2beb4d1860a61f571530b3f855a1b538d0200f7871c63331ecd6f17b1f014f8"
|
||||
checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
@ -1700,9 +1655,9 @@ checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.63"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd9bc7ccc2688b3344c2f48b9b546648b25ce0b20fc717ee7fa7981a8ca9717"
|
||||
checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1722,19 +1677,16 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.3"
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.2.25"
|
||||
version = "0.2.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1195b046942c221454c2539395f85413b33383a067449d78aab2b7b052a142f7"
|
||||
checksum = "08a8cbfbf47955132d0202d1662f49b2423ae35862aee471f3ba4b133358f372"
|
||||
dependencies = [
|
||||
"const_fn",
|
||||
"libc",
|
||||
|
@ -1821,9 +1773,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.12.0"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
|
||||
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
|
@ -1849,15 +1801,15 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
|||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.11"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
|
||||
checksum = "cbdbff6266a24120518560b5dc983096efb98462e51d0d68169895b237be3e5d"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.2"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||
|
||||
[[package]]
|
||||
name = "void"
|
||||
|
@ -1867,9 +1819,9 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
|||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.1"
|
||||
version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
|
||||
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi 0.3.9",
|
||||
|
@ -1884,9 +1836,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.71"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ee1280240b7c461d6a0071313e08f34a60b0365f14260362e5a2b17d1d31aa7"
|
||||
checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
|
@ -1894,9 +1846,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.71"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b7d8b6942b8bb3a9b0e73fc79b98095a27de6fa247615e59d096754a3bc2aa8"
|
||||
checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
|
@ -1909,9 +1861,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.71"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5ac38da8ef716661f0f36c0d8320b89028efe10c7c0afde65baffb496ce0d3b"
|
||||
checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
|
@ -1919,9 +1871,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.71"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc053ec74d454df287b9374ee8abb36ffd5acb95ba87da3ba5b7d3fe20eb401e"
|
||||
checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1932,15 +1884,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.71"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d6f8ec44822dd71f5f221a5847fb34acd9060535c1211b70a05844c0f6383b1"
|
||||
checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.48"
|
||||
version = "0.3.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec600b26223b2948cedfde2a0aa6756dcf1fef616f43d7b3097aaf53a6c4d92b"
|
||||
checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
|
@ -2031,10 +1983,10 @@ dependencies = [
|
|||
"android_logger",
|
||||
"bls12_381",
|
||||
"failure",
|
||||
"futures 0.3.13",
|
||||
"futures 0.3.14",
|
||||
"grpc",
|
||||
"grpc-protobuf",
|
||||
"hdwallet",
|
||||
"hdwallet 0.2.5",
|
||||
"hex",
|
||||
"httpbis",
|
||||
"jni",
|
||||
|
@ -2052,18 +2004,19 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zcash_client_backend"
|
||||
version = "0.4.0"
|
||||
source = "git+https://github.com/nuttycom/librustzcash?branch=autoshield-poc-daa#4253f8ef810d199bef0808a6fe3fbf809a5558c8"
|
||||
version = "0.5.0"
|
||||
source = "git+https://github.com/gmale/librustzcash?branch=autoshield-poc-daa-taddr3#74434f370cf474156b73bfb685cb62e8cd5bcd42"
|
||||
dependencies = [
|
||||
"base64 0.12.3",
|
||||
"base64 0.13.0",
|
||||
"bech32",
|
||||
"bls12_381",
|
||||
"bs58",
|
||||
"ff",
|
||||
"group",
|
||||
"hdwallet",
|
||||
"hdwallet 0.3.0",
|
||||
"hex",
|
||||
"jubjub",
|
||||
"log",
|
||||
"nom",
|
||||
"percent-encoding",
|
||||
"protobuf",
|
||||
|
@ -2071,16 +2024,17 @@ dependencies = [
|
|||
"rand_core 0.5.1",
|
||||
"ripemd160",
|
||||
"secp256k1",
|
||||
"sha2 0.9.3",
|
||||
"sha2",
|
||||
"subtle",
|
||||
"time",
|
||||
"zcash_note_encryption",
|
||||
"zcash_primitives",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zcash_client_sqlite"
|
||||
version = "0.2.1"
|
||||
source = "git+https://github.com/nuttycom/librustzcash?branch=autoshield-poc-daa#4253f8ef810d199bef0808a6fe3fbf809a5558c8"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/gmale/librustzcash?branch=autoshield-poc-daa-taddr3#74434f370cf474156b73bfb685cb62e8cd5bcd42"
|
||||
dependencies = [
|
||||
"bech32",
|
||||
"bs58",
|
||||
|
@ -2090,18 +2044,33 @@ dependencies = [
|
|||
"protobuf",
|
||||
"rand_core 0.5.1",
|
||||
"rusqlite",
|
||||
"secp256k1",
|
||||
"time",
|
||||
"zcash_client_backend",
|
||||
"zcash_primitives",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zcash_note_encryption"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/gmale/librustzcash?branch=autoshield-poc-daa-taddr3#74434f370cf474156b73bfb685cb62e8cd5bcd42"
|
||||
dependencies = [
|
||||
"blake2b_simd",
|
||||
"byteorder",
|
||||
"crypto_api_chachapoly",
|
||||
"ff",
|
||||
"group",
|
||||
"rand_core 0.5.1",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zcash_primitives"
|
||||
version = "0.4.0"
|
||||
source = "git+https://github.com/nuttycom/librustzcash?branch=autoshield-poc-daa#4253f8ef810d199bef0808a6fe3fbf809a5558c8"
|
||||
version = "0.5.0"
|
||||
source = "git+https://github.com/gmale/librustzcash?branch=autoshield-poc-daa-taddr3#74434f370cf474156b73bfb685cb62e8cd5bcd42"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"bitvec",
|
||||
"bitvec 0.18.5",
|
||||
"blake2b_simd",
|
||||
"blake2s_simd",
|
||||
"bls12_381",
|
||||
|
@ -2110,6 +2079,7 @@ dependencies = [
|
|||
"equihash",
|
||||
"ff",
|
||||
"fpe",
|
||||
"funty",
|
||||
"group",
|
||||
"hex",
|
||||
"jubjub",
|
||||
|
@ -2119,14 +2089,15 @@ dependencies = [
|
|||
"rand_core 0.5.1",
|
||||
"ripemd160",
|
||||
"secp256k1",
|
||||
"sha2 0.9.3",
|
||||
"sha2",
|
||||
"subtle",
|
||||
"zcash_note_encryption",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zcash_proofs"
|
||||
version = "0.4.0"
|
||||
source = "git+https://github.com/nuttycom/librustzcash?branch=autoshield-poc-daa#4253f8ef810d199bef0808a6fe3fbf809a5558c8"
|
||||
version = "0.5.0"
|
||||
source = "git+https://github.com/gmale/librustzcash?branch=autoshield-poc-daa-taddr3#74434f370cf474156b73bfb685cb62e8cd5bcd42"
|
||||
dependencies = [
|
||||
"bellman",
|
||||
"blake2b_simd",
|
||||
|
|
22
Cargo.toml
22
Cargo.toml
|
@ -16,10 +16,10 @@ hex = "0.4"
|
|||
jni = { version = "0.17", default-features = false }
|
||||
log = "0.4"
|
||||
log-panics = "2.0.0"
|
||||
zcash_client_backend = "0.4"
|
||||
zcash_client_sqlite = "0.2.1"
|
||||
zcash_primitives = "0.4"
|
||||
zcash_proofs = "0.4"
|
||||
zcash_client_backend = "0.5"
|
||||
zcash_client_sqlite = "0.3"
|
||||
zcash_primitives = "0.5"
|
||||
zcash_proofs = "0.5"
|
||||
|
||||
#### Temporary additions: ####################################
|
||||
#base58 = "0.1.0"
|
||||
|
@ -50,7 +50,7 @@ protobuf-codegen-pure = "2.14"
|
|||
#zcash_primitives = { git = 'https://github.com/zcash/librustzcash.git', rev='04a2bd4ad86980e0c2862706bd402b85b9dd1965' }
|
||||
#zcash_proofs = { git = 'https://github.com/zcash/librustzcash.git', rev='04a2bd4ad86980e0c2862706bd402b85b9dd1965' }
|
||||
|
||||
# Uncomment this to test librustzcash changes locally
|
||||
## Uncomment this to test librustzcash changes locally
|
||||
#[patch.crates-io]
|
||||
#zcash_client_backend = { path = '../../clones/librustzcash/zcash_client_backend' }
|
||||
#zcash_client_sqlite = { path = '../../clones/librustzcash/zcash_client_sqlite' }
|
||||
|
@ -59,14 +59,14 @@ protobuf-codegen-pure = "2.14"
|
|||
|
||||
# Uncomment this to test someone else's librustzcash changes in a branch
|
||||
[patch.crates-io]
|
||||
zcash_client_backend = {git = "https://github.com/nuttycom/librustzcash", branch = "autoshield-poc-daa"}
|
||||
zcash_client_sqlite = {git = "https://github.com/nuttycom/librustzcash", branch = "autoshield-poc-daa"}
|
||||
zcash_primitives = {git = "https://github.com/nuttycom/librustzcash", branch = "autoshield-poc-daa"}
|
||||
zcash_proofs = {git = "https://github.com/nuttycom/librustzcash", branch = "autoshield-poc-daa"}
|
||||
zcash_client_backend = {git = "https://github.com/gmale/librustzcash", branch = "autoshield-poc-daa-taddr3"}
|
||||
zcash_client_sqlite = {git = "https://github.com/gmale/librustzcash", branch = "autoshield-poc-daa-taddr3"}
|
||||
zcash_primitives = {git = "https://github.com/gmale/librustzcash", branch = "autoshield-poc-daa-taddr3"}
|
||||
zcash_proofs = {git = "https://github.com/gmale/librustzcash", branch = "autoshield-poc-daa-taddr3"}
|
||||
|
||||
[features]
|
||||
mainnet = ["zcash_client_sqlite/mainnet", "zcash_client_sqlite/transparent-inputs", "zcash_client_backend/transparent-inputs", "zcash_primitives/transparent-inputs"]
|
||||
testnet = ["zcash_client_backend/transparent-inputs", "zcash_client_sqlite/transparent-inputs", "zcash_primitives/transparent-inputs"]
|
||||
mainnet = ["zcash_client_sqlite/mainnet"]
|
||||
testnet = []
|
||||
updater = ["bls12_381", "futures", "grpc", "grpc-protobuf", "httpbis", "tls-api", "tls-api-rustls"]
|
||||
|
||||
[lib]
|
||||
|
|
22
README.md
22
README.md
|
@ -22,10 +22,12 @@ This lightweight SDK connects Android to Zcash. It welds together Rust and Kotli
|
|||
|
||||
## Contents
|
||||
|
||||
- [Requirements](#requirements)
|
||||
- [Structure](#structure)
|
||||
- [Overview](#overview)
|
||||
- [Components](#components)
|
||||
- [Quickstart](#quickstart)
|
||||
- [Examples](#examples)
|
||||
- [Compiling Sources](#compiling-sources)
|
||||
- [Versioning](#versioning)
|
||||
- [Examples](#examples)
|
||||
|
@ -126,6 +128,26 @@ Send funds to another address
|
|||
synchronizer.sendToAddress(spendingKey, zatoshi, address, memo)
|
||||
```
|
||||
|
||||
[Back to contents](#contents)
|
||||
|
||||
## Examples
|
||||
|
||||
Full working examples can be found in the [demo app](https://github.com/zcash/zcash-android-wallet-sdk/tree/master/samples/demo-app), covering all major functionality of the SDK. Each demo strives to be self-contained so that a developer can understand everything required for it to work. Testnet builds of the demo app will soon be available to [download as github releases](https://github.com/zcash/zcash-android-wallet-sdk/releases).
|
||||
|
||||
### Demos
|
||||
|
||||
Menu Item|Related Code|Description
|
||||
:-----|:-----|:-----
|
||||
Get Private Key|[GetPrivateKeyFragment.kt](app/src/main/java/cash/z/ecc/android/sdk/demoapp/demos/getprivatekey/GetPrivateKeyFragment.kt)|Given a seed, display its viewing key and spending key
|
||||
Get Address|[GetAddressFragment.kt](app/src/main/java/cash/z/ecc/android/sdk/demoapp/demos/getaddress/GetAddressFragment.kt)|Given a seed, display its z-addr
|
||||
Get Balance|[GetBalanceFragment.kt](app/src/main/java/cash/z/ecc/android/sdk/demoapp/demos/getbalance/GetBalanceFragment.kt)|Display the balance
|
||||
Get Latest Height|[GetLatestHeightFragment.kt](app/src/main/java/cash/z/ecc/android/sdk/demoapp/demos/getlatestheight/GetLatestHeightFragment.kt)|Given a lightwalletd server, retrieve the latest block height
|
||||
Get Block|[GetBlockFragment.kt](app/src/main/java/cash/z/ecc/android/sdk/demoapp/demos/getblock/GetBlockFragment.kt)|Given a lightwalletd server, retrieve a compact block
|
||||
Get Block Range|[GetBlockRangeFragment.kt](app/src/main/java/cash/z/ecc/android/sdk/demoapp/demos/getblockrange/GetBlockRangeFragment.kt)|Given a lightwalletd server, retrieve a range of compact blocks
|
||||
List Transactions|[ListTransactionsFragment.kt](app/src/main/java/cash/z/ecc/android/sdk/demoapp/demos/listtransactions/ListTransactionsFragment.kt)|Given a seed, list all related shielded transactions
|
||||
Send|[SendFragment.kt](app/src/main/java/cash/z/ecc/android/sdk/demoapp/demos/send/SendFragment.kt)|Send and monitor a transaction, the most complex demo
|
||||
|
||||
|
||||
[Back to contents](#contents)
|
||||
|
||||
## Compiling Sources
|
||||
|
|
188
build.gradle
188
build.gradle
|
@ -1,23 +1,16 @@
|
|||
import cash.z.ecc.android.Deps
|
||||
loadConfig('config.gradle')
|
||||
|
||||
// Publishing settings
|
||||
project.group = config.publish.group
|
||||
project.version = config.publish.versionName
|
||||
project.ext.POM_ARTIFACT_ID = config.publish.artifactId
|
||||
|
||||
buildscript {
|
||||
ext.buildConfig = [
|
||||
'compileSdkVersion': 30,
|
||||
'minSdkVersion': 16,
|
||||
'targetSdkVersion': 30
|
||||
]
|
||||
ext.versions = [
|
||||
'architectureComponents': [
|
||||
'lifecycle': '2.2.0',
|
||||
'room': '2.2.5',
|
||||
'paging': '2.1.2'
|
||||
],
|
||||
'grpc':'1.34.1',
|
||||
'coroutines': '1.4.2',
|
||||
'junitJupiter': '5.6.1'
|
||||
]
|
||||
ext.kotlinVersion = '1.4.31'
|
||||
repositories {
|
||||
mavenLocal()
|
||||
google()
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
maven {
|
||||
url 'https://jitpack.io'
|
||||
|
@ -27,43 +20,30 @@ buildscript {
|
|||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.0.2'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${Deps.kotlinVersion}"
|
||||
classpath "org.jetbrains.kotlin:kotlin-allopen:${Deps.kotlinVersion}"
|
||||
classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.10.1"
|
||||
classpath "com.github.ben-manes:gradle-versions-plugin:0.31.0"
|
||||
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
|
||||
classpath 'com.android.tools.build:gradle:4.1.3'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}"
|
||||
classpath "org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}"
|
||||
classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.4.30"
|
||||
classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.14"
|
||||
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:1.0.2'
|
||||
classpath 'com.github.str4d:rust-android-gradle:68b4ecc053'
|
||||
classpath 'org.owasp:dependency-check-gradle:6.0.0'
|
||||
classpath "gradle.plugin.com.dorongold.plugins:task-tree:1.5"
|
||||
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5'
|
||||
classpath 'com.vanniktech:gradle-maven-publish-plugin:0.14.2'
|
||||
}
|
||||
}
|
||||
|
||||
apply from: 'custom-tasks.gradle'
|
||||
apply from: "$rootDir/ktlint.gradle"
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'com.jfrog.bintray'
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
apply plugin: 'kotlin-allopen'
|
||||
apply plugin: 'org.jetbrains.dokka'
|
||||
apply plugin: 'com.google.protobuf'
|
||||
apply plugin: 'com.github.ben-manes.versions'
|
||||
apply plugin: 'com.github.dcendents.android-maven'
|
||||
apply plugin: 'com.getkeepsafe.dexcount'
|
||||
apply plugin: 'org.mozilla.rust-android-gradle.rust-android'
|
||||
apply plugin: 'org.owasp.dependencycheck'
|
||||
apply plugin: "com.dorongold.task-tree"
|
||||
apply from: 'ci.gradle'
|
||||
apply from: 'publish.gradle'
|
||||
apply plugin: 'com.vanniktech.maven.publish'
|
||||
//apply from: 'ci.gradle'
|
||||
|
||||
group = Deps.group
|
||||
version = Deps.versionName
|
||||
|
||||
repositories {
|
||||
google()
|
||||
|
@ -72,21 +52,21 @@ repositories {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion buildConfig.compileSdkVersion
|
||||
compileSdkVersion config.compileSdkVersion
|
||||
|
||||
useLibrary 'android.test.runner'
|
||||
|
||||
ndkVersion "21.1.6352462"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion buildConfig.minSdkVersion
|
||||
targetSdkVersion buildConfig.targetSdkVersion
|
||||
versionCode = Deps.versionCode
|
||||
versionName = Deps.versionName
|
||||
minSdkVersion config.minSdkVersion
|
||||
targetSdkVersion config.targetSdkVersion
|
||||
versionCode = config.publish.versionCode
|
||||
versionName = config.publish.versionName
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
testInstrumentationRunnerArguments clearPackageData: 'true'
|
||||
multiDexEnabled true
|
||||
archivesBaseName = "zcash-android-sdk-${Deps.versionName}"
|
||||
archivesBaseName = "zcash-android-sdk-${config.publish.name}"
|
||||
|
||||
javaCompileOptions {
|
||||
annotationProcessorOptions {
|
||||
|
@ -109,19 +89,6 @@ android {
|
|||
}
|
||||
}
|
||||
|
||||
flavorDimensions 'network'
|
||||
|
||||
productFlavors {
|
||||
// would rather name them "testnet" and "mainnet" but product flavor names cannot start with the word "test"
|
||||
zcashtestnet {
|
||||
dimension 'network'
|
||||
}
|
||||
|
||||
zcashmainnet {
|
||||
dimension 'network'
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
|
@ -157,6 +124,9 @@ android {
|
|||
exclude 'META-INF/LICENSE-notice.md'
|
||||
}
|
||||
}
|
||||
mavenPublish {
|
||||
androidVariantToPublish = config.publish.target
|
||||
}
|
||||
|
||||
allOpen {
|
||||
// marker for classes that we want to be able to extend in debug builds for testing purposes
|
||||
|
@ -167,16 +137,23 @@ clean {
|
|||
delete "$project.projectDir/src/generated/source/grpc"
|
||||
}
|
||||
|
||||
dokka {
|
||||
outputFormat = 'html'
|
||||
outputDirectory = "$buildDir/docs/rtd"
|
||||
dokkaHtml.configure {
|
||||
dokkaSourceSets {
|
||||
configureEach {
|
||||
outputDirectory.set(file("build/docs/rtd"))
|
||||
displayName.set("Zcash Android SDK")
|
||||
includes.from("packages.md")
|
||||
// samples.from("samples/basic.kt", "samples/advanced.kt")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protobuf {
|
||||
generatedFilesBaseDir = "$projectDir/src/generated/source/grpc"
|
||||
protoc { artifact = 'com.google.protobuf:protoc:3.14.0' }
|
||||
plugins {
|
||||
grpc { artifact = "io.grpc:protoc-gen-grpc-java:${versions.grpc}" }
|
||||
grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.37.0" }
|
||||
}
|
||||
generateProtoTasks {
|
||||
all().each { task ->
|
||||
|
@ -206,53 +183,44 @@ cargo {
|
|||
profile = "release"
|
||||
forceTargets = true
|
||||
prebuiltToolchains = true
|
||||
variants {
|
||||
zcashmainnetDebug {
|
||||
defaultFeaturesAnd("mainnet")
|
||||
}
|
||||
zcashmainnetRelease {
|
||||
defaultFeaturesAnd("mainnet")
|
||||
}
|
||||
zcashtestnetDebug {
|
||||
defaultFeaturesAnd("testnet")
|
||||
}
|
||||
zcashtestnetRelease {
|
||||
defaultFeaturesAnd("testnet")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.3.0-alpha02'
|
||||
implementation AndroidX.appCompat
|
||||
|
||||
// Architecture Components: Lifecycle
|
||||
implementation "androidx.lifecycle:lifecycle-runtime:${versions.architectureComponents.lifecycle}"
|
||||
implementation "androidx.lifecycle:lifecycle-extensions:${versions.architectureComponents.lifecycle}"
|
||||
implementation "androidx.lifecycle:lifecycle-common-java8:${versions.architectureComponents.lifecycle}"
|
||||
implementation AndroidX.lifecycle.runtimeKtx
|
||||
implementation AndroidX.lifecycle.commonJava8
|
||||
|
||||
// Architecture Components: Room
|
||||
implementation "androidx.room:room-runtime:${versions.architectureComponents.room}"
|
||||
implementation "androidx.room:room-common:${versions.architectureComponents.room}"
|
||||
implementation "androidx.room:room-ktx:${versions.architectureComponents.room}"
|
||||
implementation "androidx.paging:paging-runtime-ktx:${versions.architectureComponents.paging}"
|
||||
kapt "androidx.room:room-compiler:${versions.architectureComponents.room}"
|
||||
implementation AndroidX.room.runtime
|
||||
implementation AndroidX.room.common
|
||||
implementation AndroidX.room.ktx
|
||||
implementation AndroidX.room.compiler
|
||||
implementation AndroidX.paging.runtimeKtx
|
||||
kapt AndroidX.room.compiler
|
||||
|
||||
// Kotlin
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${Deps.kotlinVersion}"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${versions.coroutines}"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:${versions.coroutines}"
|
||||
implementation Kotlin.stdlib.jdk8
|
||||
implementation KotlinX.coroutines.core
|
||||
implementation KotlinX.coroutines.android
|
||||
|
||||
// grpc-java
|
||||
implementation "io.grpc:grpc-okhttp:${versions.grpc}"
|
||||
implementation "io.grpc:grpc-android:${versions.grpc}"
|
||||
implementation "io.grpc:grpc-protobuf-lite:${versions.grpc}"
|
||||
implementation "io.grpc:grpc-stub:${versions.grpc}"
|
||||
compileOnly 'javax.annotation:javax.annotation-api:1.3.2'
|
||||
implementation "io.grpc:grpc-okhttp:_"
|
||||
implementation "io.grpc:grpc-android:_"
|
||||
implementation "io.grpc:grpc-protobuf-lite:_"
|
||||
implementation "io.grpc:grpc-stub:_"
|
||||
compileOnly 'javax.annotation:javax.annotation-api:_'
|
||||
|
||||
|
||||
//
|
||||
// Locked Versions
|
||||
// these should be checked regularly and removed when possible
|
||||
|
||||
// solves error: Duplicate class com.google.common.util.concurrent.ListenableFuture found in modules jetified-guava-26.0-android.jar (com.google.guava:guava:26.0-android) and listenablefuture-1.0.jar (com.google.guava:listenablefuture:1.0)
|
||||
// per this recommendation from Chris Povirk, given guava's decision to split ListenableFuture away from Guava: https://groups.google.com/d/msg/guava-discuss/GghaKwusjcY/bCIAKfzOEwAJ
|
||||
implementation 'com.google.guava:guava:30.0-android'
|
||||
|
||||
// Transitive dependencies used because they're already necessary for other libraries
|
||||
// GSON is available as a transitive dependency from several places so we use it for processing
|
||||
// checkpoints but also document that by explicitly including here. If dependencies like Room
|
||||
|
@ -260,18 +228,18 @@ dependencies {
|
|||
implementation 'com.google.code.gson:gson:2.8.6'
|
||||
// OKIO is a transitive dependency used when writing param files to disk. Like GSON, this can be
|
||||
// replaced if needed. For compatibility, we match the library version used in grpc-okhttp:
|
||||
// https://github.com/grpc/grpc-java/blob/v1.34.x/build.gradle#L154
|
||||
implementation 'com.squareup.okio:okio:1.13.0'
|
||||
// https://github.com/grpc/grpc-java/blob/v1.37.x/build.gradle#L159
|
||||
implementation 'com.squareup.okio:okio:1.17.5'
|
||||
|
||||
// Tests
|
||||
testImplementation 'androidx.multidex:multidex:2.0.1'
|
||||
testImplementation "org.jetbrains.kotlin:kotlin-reflect:${Deps.kotlinVersion}"
|
||||
testImplementation "org.jetbrains.kotlin:kotlin-reflect:_"
|
||||
testImplementation 'org.mockito:mockito-junit-jupiter:3.5.10'
|
||||
testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0'
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api:${versions.junitJupiter}"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-engine:${versions.junitJupiter}"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-migrationsupport:${versions.junitJupiter}"
|
||||
testImplementation "io.grpc:grpc-testing:${versions.grpc}"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api:_"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-engine:_"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-migrationsupport:_"
|
||||
testImplementation "io.grpc:grpc-testing:_"
|
||||
|
||||
// NOTE: androidTests will use JUnit4, while src/test/java tests will leverage Junit5
|
||||
// Attempting to use JUnit5 via https://github.com/mannodermaus/android-junit5 was painful. The plugin configuration
|
||||
|
@ -280,21 +248,24 @@ dependencies {
|
|||
androidTestImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0'
|
||||
androidTestImplementation 'org.mockito:mockito-android:3.5.10'
|
||||
androidTestImplementation "androidx.test:runner:1.3.0"
|
||||
androidTestImplementation 'com.android.support:support-annotations:28.0.0'
|
||||
androidTestImplementation "androidx.test:core:1.3.0"
|
||||
androidTestImplementation "androidx.arch.core:core-testing:2.1.0"
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
androidTestImplementation 'androidx.test:runner:1.3.0'
|
||||
androidTestImplementation 'ru.gildor.coroutines:kotlin-coroutines-okhttp:1.0'
|
||||
// used by 'ru.gildor.coroutines.okhttp.await' (to make simple suspended requests) and breaks on versions higher than 3.8.0
|
||||
androidTestImplementation "com.squareup.okhttp3:okhttp:3.8.0"
|
||||
|
||||
// sample mnemonic plugin
|
||||
androidTestImplementation 'com.github.zcash:zcash-android-wallet-plugins:1.0.1'
|
||||
androidTestImplementation 'cash.z.ecc.android:kotlin-bip39:1.0.1'
|
||||
androidTestImplementation 'cash.z.ecc.android:kotlin-bip39:1.0.2'
|
||||
}
|
||||
|
||||
taskTree{
|
||||
noRepeat = true //do not print a sub-tree in the task-tree more than once
|
||||
impliesSubProjects = true //do not print task-tree for child projects in a multi-project
|
||||
taskDepth = 2 // limit tree depth to 3. Equivalent to running with the --task-depth option.
|
||||
}
|
||||
//taskTree{
|
||||
// noRepeat = true //do not print a sub-tree in the task-tree more than once
|
||||
// impliesSubProjects = true //do not print task-tree for child projects in a multi-project
|
||||
// taskDepth = 2 // limit tree depth to 3. Equivalent to running with the --task-depth option.
|
||||
//}
|
||||
|
||||
defaultTasks 'ciBuild'
|
||||
|
||||
|
@ -302,4 +273,9 @@ preBuild.dependsOn('ktlintFormat')
|
|||
preBuild.dependsOn('ktlint')
|
||||
preBuild.dependsOn includeDirBugFix
|
||||
|
||||
check.dependsOn dependencyCheckAggregate
|
||||
//check.dependsOn dependencyCheckAggregate
|
||||
|
||||
def loadConfig(fileName) {
|
||||
def config = new ConfigSlurper().parse(file(fileName).toURL())
|
||||
project.ext.config = config
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
plugins {
|
||||
`kotlin-dsl`
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
package cash.z.ecc.android
|
||||
|
||||
object Deps {
|
||||
// For use in the top-level build.gradle which gives an error when provided
|
||||
// `Deps.Kotlin.version` directly
|
||||
const val kotlinVersion = "1.4.21"
|
||||
const val group = "cash.z.ecc.android"
|
||||
const val artifactName = "zcash-android-sdk"
|
||||
const val versionName = "1.2.1-beta05"
|
||||
const val versionCode = 1_02_01_105 // last digits are alpha(0XX) beta(2XX) rc(4XX) release(8XX). Ex: 1_08_04_401 is an release candidate build of version 1.8.4 and 1_08_04_800 would be the final release.
|
||||
const val description = "This lightweight SDK connects Android to Zcash. It welds together Rust and Kotlin in a minimal way, allowing third-party Android apps to send and receive shielded transactions easily, securely and privately."
|
||||
const val githubUrl = "https://github.com/zcash/zcash-android-wallet-sdk"
|
||||
|
||||
// publishing
|
||||
// NOTE: to upload run: ./gradlew bintrayUpload after setting BINTRAY_USER and BINTRAY_API_KEY as environment variable
|
||||
// to publish for local development run: ./gradlew publishToMavenLocal
|
||||
// Remember: publish both mainnet and testnet!
|
||||
const val publishingDryRun = true
|
||||
val publishingTarget = Publication.Testnet
|
||||
|
||||
object Publication {
|
||||
object Mainnet {
|
||||
const val variant = "zcashmainnetRelease"
|
||||
const val artifactId = "zcash-android-sdk-mainnet"
|
||||
}
|
||||
object Testnet {
|
||||
const val variant = "zcashtestnetRelease"
|
||||
const val artifactId = "zcash-android-sdk-testnet"
|
||||
}
|
||||
}
|
||||
|
||||
object Kotlin : Version(kotlinVersion) {
|
||||
val STDLIB = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$version"
|
||||
}
|
||||
}
|
||||
|
||||
open class Version(@JvmField val version: String)
|
|
@ -0,0 +1,16 @@
|
|||
/////////////////////////////////////////
|
||||
// Publishing
|
||||
/////////////////////////////////////////
|
||||
|
||||
// general
|
||||
compileSdkVersion = 30
|
||||
minSdkVersion = 16
|
||||
targetSdkVersion = 30
|
||||
|
||||
publish {
|
||||
group = 'cash.z.ecc.android'
|
||||
versionName = '1.3.0-beta04'
|
||||
versionCode = 1_03_00_204 // last digits are alpha(0XX) beta(2XX) rc(4XX) release(8XX). Ex: 1_08_04_401 is an release candidate build of version 1.8.4 and 1_08_04_800 would be the final release.
|
||||
artifactId = 'zcash-android-sdk'
|
||||
target = 'release'
|
||||
}
|
|
@ -5,21 +5,3 @@ tasks.register("includeDirBugFix") {
|
|||
mkdir(protoIncludeDir)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register("updateDocs", Copy) {
|
||||
dependsOn dokka
|
||||
|
||||
from("$buildDir/docs/zcash-android-wallet-sdk/cash.z.ecc.android.sdk.data/") {
|
||||
include '-synchronizer/'
|
||||
include '-sdk-synchronizer/'
|
||||
include '-mock-synchronizer/'
|
||||
include '-twig/'
|
||||
rename 'index.md', 'README.md'
|
||||
}
|
||||
from("$buildDir/docs/zcash-android-wallet-sdk/cash.z.ecc.android.sdk.secure/") {
|
||||
include '-wallet/'
|
||||
rename 'index.md', 'README.md'
|
||||
}
|
||||
into "docs"
|
||||
includeEmptyDirs = false
|
||||
}
|
||||
|
|
|
@ -19,4 +19,18 @@ android.useAndroidX=true
|
|||
android.enableJetifier=true
|
||||
# Kotlin code style for this project: "official" or "obsolete":
|
||||
kotlin.code.style=official
|
||||
android.enableR8=false
|
||||
|
||||
# Publishing Constants
|
||||
POM_NAME=Zcash Android Wallet SDK
|
||||
POM_DESCRIPTION=This lightweight SDK connects Android to Zcash. It welds together Rust and Kotlin in a minimal way, allowing third-party Android apps to send and receive shielded transactions easily, securely and privately.
|
||||
POM_INCEPTION_YEAR=2018
|
||||
POM_URL=https://github.com/zcash/zcash-android-wallet-sdk/
|
||||
POM_SCM_URL=https://github.com/zcash/zcash-android-wallet-sdk/
|
||||
POM_SCM_CONNECTION=scm:git:git://github.com/zcash/zcash-android-wallet-sdk.git
|
||||
POM_SCM_DEV_CONNECTION=scm:git:ssh://git@github.com/zcash/zcash-android-wallet-sdk.git
|
||||
POM_LICENCE_NAME=The MIT License
|
||||
POM_LICENCE_URL=http://opensource.org/licenses/MIT
|
||||
POM_LICENCE_DIST=repo
|
||||
POM_DEVELOPER_ID=gmale
|
||||
POM_DEVELOPER_NAME=Kevin Gorham
|
||||
POM_DEVELOPER_URL=https://github.com/gmale/
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-all.zip
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# Module zcash-android-sdk
|
||||
|
||||
SDK connecting Android to Zcash. It welds together Rust and Kotlin in a minimal way, allowing third-party Android apps to send and receive shielded transactions easily, securely and privately.
|
||||
|
||||
# Package cash.z.ecc.android.sdk.block
|
||||
|
||||
Integration tests designed to be executed with darksidewalletd.
|
116
publish.gradle
116
publish.gradle
|
@ -1,116 +0,0 @@
|
|||
import cash.z.ecc.android.Deps
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Publishing
|
||||
/////////////////////////////////////////
|
||||
|
||||
group = Deps.group
|
||||
version = Deps.versionName
|
||||
|
||||
// Create the pom configuration:
|
||||
def pomConfig = {
|
||||
licenses {
|
||||
license {
|
||||
name "MIT-style"
|
||||
url "http://opensource.org/licenses/MIT"
|
||||
distribution "repo"
|
||||
}
|
||||
}
|
||||
developers {
|
||||
developer {
|
||||
id "gmale"
|
||||
name "Kevin Gorham"
|
||||
email "kevin.gorham@z.cash"
|
||||
}
|
||||
}
|
||||
|
||||
scm {
|
||||
url Deps.githubUrl
|
||||
}
|
||||
}
|
||||
|
||||
// Jar containing Kotlin sources
|
||||
task sourcesJar(type: Jar) {
|
||||
archiveClassifier = 'sources'
|
||||
from kotlin.sourceSets.main.kotlin.srcDirs
|
||||
}
|
||||
|
||||
// Jar containing docs
|
||||
task docsJar(type: Jar) {
|
||||
archiveClassifier = "javadoc"
|
||||
group = JavaBasePlugin.DOCUMENTATION_GROUP
|
||||
dependsOn dokka
|
||||
from dokka
|
||||
}
|
||||
|
||||
def activePublication = Deps.publishingTarget
|
||||
publishing {
|
||||
publications {
|
||||
android.libraryVariants.all { variant ->
|
||||
if (variant.name != activePublication.variant) return
|
||||
|
||||
Production(MavenPublication) {
|
||||
artifact variant.outputs[0].packageLibrary // the AAR
|
||||
artifact sourcesJar
|
||||
artifact docsJar
|
||||
groupId Deps.group
|
||||
artifactId activePublication.artifactId
|
||||
version Deps.versionName
|
||||
|
||||
pom.withXml {
|
||||
def root = asNode()
|
||||
root.appendNode('description', Deps.description)
|
||||
root.appendNode('name', activePublication.artifactId)
|
||||
root.appendNode('url', )
|
||||
root.children().last() + pomConfig
|
||||
|
||||
// AAR-specific: we must explicitly add dependencies for an AAR
|
||||
def depsNode = root["dependencies"][0] ?: root.appendNode("dependencies")
|
||||
def addDep = {
|
||||
if (it.group == null) return // Avoid empty dependency nodes
|
||||
def dependencyNode = depsNode.appendNode('dependency')
|
||||
dependencyNode.appendNode('groupId', it.group)
|
||||
dependencyNode.appendNode('artifactId', it.name)
|
||||
dependencyNode.appendNode('version', it.version)
|
||||
if (it.hasProperty('type')) {
|
||||
dependencyNode.appendNode('type', it.type)
|
||||
}
|
||||
if (it.hasProperty('scope')) {
|
||||
dependencyNode.appendNode('scope', it.scope)
|
||||
}
|
||||
if (it.hasProperty('optional') && it.optional) {
|
||||
dependencyNode.appendNode('optional', 'true')
|
||||
}
|
||||
}
|
||||
// run the 'addDep' closure over each dependency
|
||||
configurations.implementation.allDependencies.each addDep
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bintray {
|
||||
user = project.findProperty('bintrayUser') ?: System.getenv('BINTRAY_USER')
|
||||
key = project.findProperty('bintrayApiKey') ?: System.getenv('BINTRAY_API_KEY')
|
||||
publications = ['Production']
|
||||
override = true
|
||||
pkg {
|
||||
repo = 'android'
|
||||
name = activePublication.artifactId
|
||||
description = Deps.description
|
||||
publish = true
|
||||
publicDownloadNumbers = true
|
||||
userOrg = 'ecc-mobile'
|
||||
labels = ['aar', 'native', 'android', 'zcash', 'ecc', 'sdk', 'kotlin', 'mobile', 'electric coin company', 'open source', 'crypto', 'cryptocurrency', 'cryptography', 'privacy']
|
||||
licenses = ['MIT']
|
||||
vcsUrl = Deps.githubUrl
|
||||
dryRun = Deps.publishingDryRun
|
||||
version {
|
||||
name = Deps.versionName
|
||||
desc = Deps.description
|
||||
released = new Date()
|
||||
vcsTag = this.version
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ package cash.z.ecc.android.sdk.demoapp
|
|||
|
||||
data class DemoConfig(
|
||||
val alias: String = "SdkDemo",
|
||||
val host: String = "lightwalletd.electriccoin.co",
|
||||
val host: String = "mainnet.lightwalletd.com",
|
||||
val port: Int = 9067,
|
||||
val birthdayHeight: Int = 968000,
|
||||
val utxoEndHeight: Int = 968085,
|
||||
|
|
|
@ -2,7 +2,7 @@ package cash.z.ecc.android.sdk.demoapp
|
|||
|
||||
data class DemoConfig(
|
||||
val alias: String = "SdkDemo",
|
||||
val host: String = "lightwalletd.testnet.electriccoin.co",
|
||||
val host: String = "testnet.lightwalletd.com",
|
||||
val port: Int = 9067,
|
||||
val birthdayHeight: Int = 954_500,
|
||||
val utxoEndHeight: Int = 1075590,
|
||||
|
|
|
@ -0,0 +1,425 @@
|
|||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 7,
|
||||
"identityHash": "8e6d7ff0e82352e1fa54e951a5006ba9",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "transactions",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id_tx` INTEGER, `txid` BLOB NOT NULL, `tx_index` INTEGER, `created` TEXT, `expiry_height` INTEGER, `block` INTEGER, `raw` BLOB, PRIMARY KEY(`id_tx`), FOREIGN KEY(`block`) REFERENCES `blocks`(`height`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id_tx",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "transactionId",
|
||||
"columnName": "txid",
|
||||
"affinity": "BLOB",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "transactionIndex",
|
||||
"columnName": "tx_index",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "created",
|
||||
"columnName": "created",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "expiryHeight",
|
||||
"columnName": "expiry_height",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "minedHeight",
|
||||
"columnName": "block",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "raw",
|
||||
"columnName": "raw",
|
||||
"affinity": "BLOB",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"id_tx"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "blocks",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"block"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"height"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "blocks",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`height` INTEGER, `hash` BLOB NOT NULL, `time` INTEGER NOT NULL, `sapling_tree` BLOB NOT NULL, PRIMARY KEY(`height`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "height",
|
||||
"columnName": "height",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "hash",
|
||||
"columnName": "hash",
|
||||
"affinity": "BLOB",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "time",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "saplingTree",
|
||||
"columnName": "sapling_tree",
|
||||
"affinity": "BLOB",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"height"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "received_notes",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id_note` INTEGER, `tx` INTEGER NOT NULL, `output_index` INTEGER NOT NULL, `account` INTEGER NOT NULL, `value` INTEGER NOT NULL, `spent` INTEGER, `diversifier` BLOB NOT NULL, `rcm` BLOB NOT NULL, `nf` BLOB NOT NULL, `is_change` INTEGER NOT NULL, `memo` BLOB, PRIMARY KEY(`id_note`), FOREIGN KEY(`tx`) REFERENCES `transactions`(`id_tx`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`account`) REFERENCES `accounts`(`account`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`spent`) REFERENCES `transactions`(`id_tx`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id_note",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "transactionId",
|
||||
"columnName": "tx",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "outputIndex",
|
||||
"columnName": "output_index",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "account",
|
||||
"columnName": "account",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "value",
|
||||
"columnName": "value",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "spent",
|
||||
"columnName": "spent",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "diversifier",
|
||||
"columnName": "diversifier",
|
||||
"affinity": "BLOB",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "rcm",
|
||||
"columnName": "rcm",
|
||||
"affinity": "BLOB",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "nf",
|
||||
"columnName": "nf",
|
||||
"affinity": "BLOB",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isChange",
|
||||
"columnName": "is_change",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "memo",
|
||||
"columnName": "memo",
|
||||
"affinity": "BLOB",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"id_note"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "transactions",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"tx"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id_tx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "accounts",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"account"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"account"
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "transactions",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"spent"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id_tx"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "accounts",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`account` INTEGER, `extfvk` TEXT NOT NULL, `address` TEXT NOT NULL, `transparent_address` TEXT NOT NULL, PRIMARY KEY(`account`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "account",
|
||||
"columnName": "account",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "extendedFullViewingKey",
|
||||
"columnName": "extfvk",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "address",
|
||||
"columnName": "address",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "transparentAddress",
|
||||
"columnName": "transparent_address",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"account"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "sent_notes",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id_note` INTEGER, `tx` INTEGER NOT NULL, `output_index` INTEGER NOT NULL, `from_account` INTEGER NOT NULL, `address` TEXT NOT NULL, `value` INTEGER NOT NULL, `memo` BLOB, PRIMARY KEY(`id_note`), FOREIGN KEY(`tx`) REFERENCES `transactions`(`id_tx`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`from_account`) REFERENCES `accounts`(`account`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id_note",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "transactionId",
|
||||
"columnName": "tx",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "outputIndex",
|
||||
"columnName": "output_index",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "account",
|
||||
"columnName": "from_account",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "address",
|
||||
"columnName": "address",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "value",
|
||||
"columnName": "value",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "memo",
|
||||
"columnName": "memo",
|
||||
"affinity": "BLOB",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"id_note"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "transactions",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"tx"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id_tx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "accounts",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"from_account"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"account"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "utxos",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id_utxo` INTEGER, `address` TEXT NOT NULL, `prevout_txid` BLOB NOT NULL, `prevout_idx` INTEGER NOT NULL, `script` BLOB NOT NULL, `value_zat` INTEGER NOT NULL, `height` INTEGER NOT NULL, `spent_in_tx` INTEGER, PRIMARY KEY(`id_utxo`), FOREIGN KEY(`spent_in_tx`) REFERENCES `transactions`(`id_tx`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id_utxo",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "address",
|
||||
"columnName": "address",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "txid",
|
||||
"columnName": "prevout_txid",
|
||||
"affinity": "BLOB",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "transactionIndex",
|
||||
"columnName": "prevout_idx",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "script",
|
||||
"columnName": "script",
|
||||
"affinity": "BLOB",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "value",
|
||||
"columnName": "value_zat",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "height",
|
||||
"columnName": "height",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "spent",
|
||||
"columnName": "spent_in_tx",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"id_utxo"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "transactions",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"spent_in_tx"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id_tx"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '8e6d7ff0e82352e1fa54e951a5006ba9')"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1 +1,10 @@
|
|||
import de.fayard.refreshVersions.RefreshVersionsSetup
|
||||
|
||||
buildscript {
|
||||
repositories { gradlePluginPortal() }
|
||||
dependencies.classpath("de.fayard.refreshVersions:refreshVersions:0.9.7")
|
||||
}
|
||||
|
||||
RefreshVersionsSetup.bootstrap(settings)
|
||||
|
||||
rootProject.name = 'zcash-android-sdk'
|
||||
|
|
|
@ -1,110 +1,98 @@
|
|||
package cash.z.ecc.android.sdk
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import cash.z.ecc.android.sdk.exception.InitializerException
|
||||
import cash.z.ecc.android.sdk.ext.TroubleshootingTwig
|
||||
import cash.z.ecc.android.sdk.ext.Twig
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertNotEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
class InitializerTest {
|
||||
|
||||
lateinit var initializer: Initializer
|
||||
|
||||
@After
|
||||
fun cleanUp() {
|
||||
// don't leave databases sitting around after this test is run
|
||||
if (::initializer.isInitialized) initializer.erase()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInit() {
|
||||
val height = 980000
|
||||
|
||||
initializer = Initializer(context) { config ->
|
||||
config.importedWalletBirthday(height)
|
||||
config.setViewingKeys(
|
||||
"zxviews1qvn6j50dqqqqpqxqkvqgx2sp63jccr4k5t8zefadpzsu0yy73vczfznwc794xz6lvy3yp5ucv43lww48zz95ey5vhrsq83dqh0ky9junq0cww2wjp9c3cd45n5l5x8l2g9atnx27e9jgyy8zasjy26gugjtefphan9al3tx208m8ekev5kkx3ug6pd0qk4gq4j4wfuxajn388pfpq54wklwktqkyjz9e6gam0n09xjc35ncd3yah5aa9ezj55lk4u7v7hn0v86vz7ygq4qj2v",
|
||||
"zxviews1qv886f6hqqqqpqy2ajg9sm22vs4gm4hhajthctfkfws34u45pjtut3qmz0eatpqzvllgsvlk3x0y35ktx5fnzqqzueyph20k3328kx46y3u5xs4750cwuwjuuccfp7la6rh8yt2vjz6tylsrwzy3khtjjzw7etkae6gw3vq608k7quka4nxkeqdxxsr9xxdagv2rhhwugs6w0cquu2ykgzgaln2vyv6ah3ram2h6lrpxuznyczt2xl3lyxcwlk4wfz5rh7wzfd7642c2ae5d7"
|
||||
)
|
||||
config.alias = "VkInitTest1"
|
||||
}
|
||||
assertEquals(height, initializer.birthday.height)
|
||||
initializer.erase()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testErase() {
|
||||
val alias = "VkInitTest2"
|
||||
initializer = Initializer(context) { config ->
|
||||
config.importedWalletBirthday(1_419_900)
|
||||
config.setViewingKeys(
|
||||
"zxviews1qvn6j50dqqqqpqxqkvqgx2sp63jccr4k5t8zefadpzsu0yy73vczfznwc794xz6lvy3yp5ucv43lww48zz95ey5vhrsq83dqh0ky9junq0cww2wjp9c3cd45n5l5x8l2g9atnx27e9jgyy8zasjy26gugjtefphan9al3tx208m8ekev5kkx3ug6pd0qk4gq4j4wfuxajn388pfpq54wklwktqkyjz9e6gam0n09xjc35ncd3yah5aa9ezj55lk4u7v7hn0v86vz7ygq4qj2v",
|
||||
"zxviews1qv886f6hqqqqpqy2ajg9sm22vs4gm4hhajthctfkfws34u45pjtut3qmz0eatpqzvllgsvlk3x0y35ktx5fnzqqzueyph20k3328kx46y3u5xs4750cwuwjuuccfp7la6rh8yt2vjz6tylsrwzy3khtjjzw7etkae6gw3vq608k7quka4nxkeqdxxsr9xxdagv2rhhwugs6w0cquu2ykgzgaln2vyv6ah3ram2h6lrpxuznyczt2xl3lyxcwlk4wfz5rh7wzfd7642c2ae5d7"
|
||||
)
|
||||
config.alias = alias
|
||||
}
|
||||
|
||||
assertTrue("Failed to erase initializer", Initializer.erase(context, alias))
|
||||
assertFalse("Expected false when erasing nothing.", Initializer.erase(context))
|
||||
}
|
||||
|
||||
@Test(expected = InitializerException.MissingDefaultBirthdayException::class)
|
||||
fun testMissingBirthday() {
|
||||
val config = Initializer.Config { config ->
|
||||
config.setViewingKeys("vk1")
|
||||
}
|
||||
config.validate()
|
||||
}
|
||||
|
||||
@Test(expected = InitializerException.InvalidBirthdayHeightException::class)
|
||||
fun testOutOfBoundsBirthday() {
|
||||
val config = Initializer.Config { config ->
|
||||
config.setViewingKeys("vk1")
|
||||
config.setBirthdayHeight(ZcashSdk.SAPLING_ACTIVATION_HEIGHT - 1)
|
||||
}
|
||||
config.validate()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testImportedWalletUsesSaplingActivation() {
|
||||
initializer = Initializer(context) { config ->
|
||||
config.setViewingKeys("vk1")
|
||||
config.importWallet(ByteArray(32))
|
||||
}
|
||||
assertEquals("Incorrect height used for import.", ZcashSdk.SAPLING_ACTIVATION_HEIGHT, initializer.birthday.height)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDefaultToOldestHeight_true() {
|
||||
initializer = Initializer(context) { config ->
|
||||
config.setViewingKeys("vk1")
|
||||
config.setBirthdayHeight(null, true)
|
||||
}
|
||||
assertEquals("Height should equal sapling activation height when defaultToOldestHeight is true", ZcashSdk.SAPLING_ACTIVATION_HEIGHT, initializer.birthday.height)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDefaultToOldestHeight_false() {
|
||||
val initialHeight = 750_000
|
||||
initializer = Initializer(context) { config ->
|
||||
config.setViewingKeys("vk1")
|
||||
config.setBirthdayHeight(initialHeight, false)
|
||||
}
|
||||
val h = initializer.birthday.height
|
||||
assertNotEquals("Height should not equal sapling activation height when defaultToOldestHeight is false", ZcashSdk.SAPLING_ACTIVATION_HEIGHT, h)
|
||||
assertTrue("expected $h to be higher", h >= initialHeight)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val context = InstrumentationRegistry.getInstrumentation().context
|
||||
init {
|
||||
Twig.plant(TroubleshootingTwig())
|
||||
}
|
||||
}
|
||||
// lateinit var initializer: Initializer
|
||||
//
|
||||
// @After
|
||||
// fun cleanUp() {
|
||||
// // don't leave databases sitting around after this test is run
|
||||
// if (::initializer.isInitialized) initializer.erase()
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// fun testInit() {
|
||||
// val height = 980000
|
||||
//
|
||||
// initializer = Initializer(context) { config ->
|
||||
// config.importedWalletBirthday(height)
|
||||
// config.setViewingKeys(
|
||||
// "zxviews1qvn6j50dqqqqpqxqkvqgx2sp63jccr4k5t8zefadpzsu0yy73vczfznwc794xz6lvy3yp5ucv43lww48zz95ey5vhrsq83dqh0ky9junq0cww2wjp9c3cd45n5l5x8l2g9atnx27e9jgyy8zasjy26gugjtefphan9al3tx208m8ekev5kkx3ug6pd0qk4gq4j4wfuxajn388pfpq54wklwktqkyjz9e6gam0n09xjc35ncd3yah5aa9ezj55lk4u7v7hn0v86vz7ygq4qj2v",
|
||||
// "zxviews1qv886f6hqqqqpqy2ajg9sm22vs4gm4hhajthctfkfws34u45pjtut3qmz0eatpqzvllgsvlk3x0y35ktx5fnzqqzueyph20k3328kx46y3u5xs4750cwuwjuuccfp7la6rh8yt2vjz6tylsrwzy3khtjjzw7etkae6gw3vq608k7quka4nxkeqdxxsr9xxdagv2rhhwugs6w0cquu2ykgzgaln2vyv6ah3ram2h6lrpxuznyczt2xl3lyxcwlk4wfz5rh7wzfd7642c2ae5d7"
|
||||
// )
|
||||
// config.alias = "VkInitTest1"
|
||||
// }
|
||||
// assertEquals(height, initializer.birthday.height)
|
||||
// initializer.erase()
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// fun testErase() {
|
||||
// val alias = "VkInitTest2"
|
||||
// initializer = Initializer(context) { config ->
|
||||
// config.importedWalletBirthday(1_419_900)
|
||||
// config.setViewingKeys(
|
||||
// "zxviews1qvn6j50dqqqqpqxqkvqgx2sp63jccr4k5t8zefadpzsu0yy73vczfznwc794xz6lvy3yp5ucv43lww48zz95ey5vhrsq83dqh0ky9junq0cww2wjp9c3cd45n5l5x8l2g9atnx27e9jgyy8zasjy26gugjtefphan9al3tx208m8ekev5kkx3ug6pd0qk4gq4j4wfuxajn388pfpq54wklwktqkyjz9e6gam0n09xjc35ncd3yah5aa9ezj55lk4u7v7hn0v86vz7ygq4qj2v",
|
||||
// "zxviews1qv886f6hqqqqpqy2ajg9sm22vs4gm4hhajthctfkfws34u45pjtut3qmz0eatpqzvllgsvlk3x0y35ktx5fnzqqzueyph20k3328kx46y3u5xs4750cwuwjuuccfp7la6rh8yt2vjz6tylsrwzy3khtjjzw7etkae6gw3vq608k7quka4nxkeqdxxsr9xxdagv2rhhwugs6w0cquu2ykgzgaln2vyv6ah3ram2h6lrpxuznyczt2xl3lyxcwlk4wfz5rh7wzfd7642c2ae5d7"
|
||||
// )
|
||||
// config.alias = alias
|
||||
// }
|
||||
//
|
||||
// assertTrue("Failed to erase initializer", Initializer.erase(context, alias))
|
||||
// assertFalse("Expected false when erasing nothing.", Initializer.erase(context))
|
||||
// }
|
||||
//
|
||||
// @Test(expected = InitializerException.MissingDefaultBirthdayException::class)
|
||||
// fun testMissingBirthday() {
|
||||
// val config = Initializer.Config { config ->
|
||||
// config.setViewingKeys("vk1")
|
||||
// }
|
||||
// config.validate()
|
||||
// }
|
||||
//
|
||||
// @Test(expected = InitializerException.InvalidBirthdayHeightException::class)
|
||||
// fun testOutOfBoundsBirthday() {
|
||||
// val config = Initializer.Config { config ->
|
||||
// config.setViewingKeys("vk1")
|
||||
// config.setBirthdayHeight(ZcashSdk.SAPLING_ACTIVATION_HEIGHT - 1)
|
||||
// }
|
||||
// config.validate()
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// fun testImportedWalletUsesSaplingActivation() {
|
||||
// initializer = Initializer(context) { config ->
|
||||
// config.setViewingKeys("vk1")
|
||||
// config.importWallet(ByteArray(32))
|
||||
// }
|
||||
// assertEquals("Incorrect height used for import.", ZcashSdk.SAPLING_ACTIVATION_HEIGHT, initializer.birthday.height)
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// fun testDefaultToOldestHeight_true() {
|
||||
// initializer = Initializer(context) { config ->
|
||||
// config.setViewingKeys("vk1")
|
||||
// config.setBirthdayHeight(null, true)
|
||||
// }
|
||||
// assertEquals("Height should equal sapling activation height when defaultToOldestHeight is true", ZcashSdk.SAPLING_ACTIVATION_HEIGHT, initializer.birthday.height)
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// fun testDefaultToOldestHeight_false() {
|
||||
// val initialHeight = 750_000
|
||||
// initializer = Initializer(context) { config ->
|
||||
// config.setViewingKeys("vk1")
|
||||
// config.setBirthdayHeight(initialHeight, false)
|
||||
// }
|
||||
// val h = initializer.birthday.height
|
||||
// assertNotEquals("Height should not equal sapling activation height when defaultToOldestHeight is false", ZcashSdk.SAPLING_ACTIVATION_HEIGHT, h)
|
||||
// assertTrue("expected $h to be higher", h >= initialHeight)
|
||||
// }
|
||||
//
|
||||
// companion object {
|
||||
// private val context = InstrumentationRegistry.getInstrumentation().context
|
||||
// init {
|
||||
// Twig.plant(TroubleshootingTwig())
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package cash.z.ecc.android.sdk.annotation
|
||||
|
||||
enum class TestPurpose {
|
||||
|
||||
/**
|
||||
* These tests are explicitly designed to preserve behavior that we do not want to lose after
|
||||
* major upgrades or refactors. It is acceptable for these test to run long and require
|
||||
* additional infrastructure.
|
||||
*/
|
||||
REGRESSION,
|
||||
|
||||
/**
|
||||
* These tests are designed to be run against new pull requests and generally before any changes
|
||||
* are committed. It is not ideal for these tests to run long.
|
||||
*/
|
||||
COMMIT,
|
||||
|
||||
/**
|
||||
* These tests require a running instance of [darksidewalletd](https://github.com/zcash/lightwalletd/blob/master/docs/darksidewalletd.md).
|
||||
*/
|
||||
DARKSIDE,
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals that this test is explicitly intended to be maintained and run regularly in order to
|
||||
* achieve the given purpose. Eventually, we will run all such tests nightly.
|
||||
*/
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
annotation class MaintainedTest(vararg val purpose: TestPurpose)
|
|
@ -3,6 +3,8 @@ package cash.z.ecc.android.sdk.ext
|
|||
import android.content.Context
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import cash.z.ecc.android.sdk.Initializer
|
||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
||||
import cash.z.ecc.android.sdk.util.DarksideTestCoordinator
|
||||
import cash.z.ecc.android.sdk.util.SimpleMnemonics
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
|
@ -12,14 +14,18 @@ import kotlinx.coroutines.delay
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.newFixedThreadPoolContext
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import org.json.JSONObject
|
||||
import org.junit.After
|
||||
import org.junit.AfterClass
|
||||
import org.junit.Before
|
||||
import org.junit.BeforeClass
|
||||
import ru.gildor.coroutines.okhttp.await
|
||||
import java.util.concurrent.TimeoutException
|
||||
|
||||
fun Initializer.Config.seedPhrase(seedPhrase: String) {
|
||||
setSeed(SimpleMnemonics().toSeed(seedPhrase.toCharArray()))
|
||||
fun Initializer.Config.seedPhrase(seedPhrase: String, network: ZcashNetwork) {
|
||||
setSeed(SimpleMnemonics().toSeed(seedPhrase.toCharArray()), network)
|
||||
}
|
||||
|
||||
open class ScopedTest(val defaultTimeout: Long = 2000L) {
|
||||
|
@ -93,6 +99,39 @@ open class ScopedTest(val defaultTimeout: Long = 2000L) {
|
|||
}
|
||||
}
|
||||
|
||||
open class DarksideTest(name: String = javaClass.simpleName) : ScopedTest() {
|
||||
val sithLord = DarksideTestCoordinator(host = host, port = port)
|
||||
val validator = sithLord.validator
|
||||
|
||||
fun runOnce(block: () -> Unit) {
|
||||
if (!ranOnce) {
|
||||
sithLord.enterTheDarkside()
|
||||
sithLord.synchronizer.start(classScope)
|
||||
block()
|
||||
ranOnce = true
|
||||
}
|
||||
}
|
||||
companion object {
|
||||
// set the host for all tests. Someday, this will need to be set by CI
|
||||
// so have it read from the environment first and give that precidence
|
||||
var host = "192.168.1.134"
|
||||
val port: Int = 9067
|
||||
private var ranOnce = false
|
||||
}
|
||||
}
|
||||
|
||||
object BlockExplorer {
|
||||
suspend fun fetchLatestHeight(): Int {
|
||||
val client = OkHttpClient()
|
||||
val request = Request.Builder()
|
||||
.url("https://api.blockchair.com/zcash/blocks?limit=1")
|
||||
.build()
|
||||
val result = client.newCall(request).await()
|
||||
val body = result.body()?.string()
|
||||
return JSONObject(body).getJSONArray("data").getJSONObject(0).getInt("id")
|
||||
}
|
||||
}
|
||||
|
||||
object Transactions {
|
||||
val outbound = arrayOf(
|
||||
"https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/transactions/t-shielded-spend.txt",
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
package cash.z.ecc.android.sdk.integration
|
||||
|
||||
import cash.z.ecc.android.sdk.annotation.MaintainedTest
|
||||
import cash.z.ecc.android.sdk.annotation.TestPurpose
|
||||
import cash.z.ecc.android.sdk.ext.BlockExplorer
|
||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
||||
import cash.z.ecc.android.sdk.util.TestWallet
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
|
||||
/**
|
||||
* This test is intended to run to make sure that basic things are functional and pinpoint what is
|
||||
* not working. It was originally developed after a major refactor to find what broke.
|
||||
*/
|
||||
@MaintainedTest(TestPurpose.COMMIT)
|
||||
@RunWith(Parameterized::class)
|
||||
class SanityTest(
|
||||
private val wallet: TestWallet,
|
||||
private val extfvk: String,
|
||||
private val extpub: String,
|
||||
private val birthday: Int,
|
||||
|
||||
) {
|
||||
|
||||
val networkName = wallet.networkName
|
||||
val name = "$networkName wallet"
|
||||
|
||||
@Test
|
||||
fun testNotPlaintext() {
|
||||
val message =
|
||||
"is using plaintext. This will cause problems for the test. Ensure that the `lightwalletd_allow_very_insecure_connections` resource value is false"
|
||||
assertFalse("$name $message", wallet.service.connectionInfo.usePlaintext)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFilePaths() {
|
||||
assertEquals(
|
||||
"$name has invalid DataDB file",
|
||||
"/data/user/0/cash.z.ecc.android.sdk.test/databases/TestWallet_${networkName}_Data.db",
|
||||
wallet.initializer.rustBackend.pathDataDb
|
||||
)
|
||||
assertEquals(
|
||||
"$name has invalid CacheDB file",
|
||||
"/data/user/0/cash.z.ecc.android.sdk.test/databases/TestWallet_${networkName}_Cache.db",
|
||||
wallet.initializer.rustBackend.pathCacheDb
|
||||
)
|
||||
assertEquals(
|
||||
"$name has invalid CacheDB params dir",
|
||||
"/data/user/0/cash.z.ecc.android.sdk.test/cache/params",
|
||||
wallet.initializer.rustBackend.pathParamsDir
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testBirthday() {
|
||||
assertEquals(
|
||||
"$name has invalid birthday height",
|
||||
birthday,
|
||||
wallet.initializer.birthday.height
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testViewingKeys() {
|
||||
assertEquals(
|
||||
"$name has invalid extfvk",
|
||||
extfvk,
|
||||
wallet.initializer.viewingKeys[0].extfvk
|
||||
)
|
||||
assertEquals(
|
||||
"$name has invalid extpub",
|
||||
extpub,
|
||||
wallet.initializer.viewingKeys[0].extpub
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testServerConnection() {
|
||||
assertEquals(
|
||||
"$name has an invalid server connection",
|
||||
"$networkName.lightwalletd.com:9067?usePlaintext=false",
|
||||
wallet.connectionInfo
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLatestHeight() = runBlocking {
|
||||
if (wallet.networkName == "mainnet") {
|
||||
val expectedHeight = BlockExplorer.fetchLatestHeight()
|
||||
// fetch height directly because the synchronizer hasn't started, yet
|
||||
val downloaderHeight = wallet.service.getLatestBlockHeight()
|
||||
val info = wallet.connectionInfo
|
||||
assertTrue(
|
||||
"$info\n ${wallet.networkName} Lightwalletd is too far behind. Downloader height $downloaderHeight is more than 10 blocks behind block explorer height $expectedHeight",
|
||||
expectedHeight - 10 < downloaderHeight
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSingleBlockDownload() = runBlocking {
|
||||
// fetch block directly because the synchronizer hasn't started, yet
|
||||
val height = 1_000_000
|
||||
val block = wallet.service.getBlockRange(height..height)[0]
|
||||
assertTrue("$networkName failed to return a proper block. Height was ${block.height} but we expected $height", block.height.toInt() == height)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@Parameterized.Parameters
|
||||
fun wallets() = listOf(
|
||||
// Testnet wallet
|
||||
arrayOf(
|
||||
TestWallet(TestWallet.Backups.SAMPLE_WALLET),
|
||||
"zxviewtestsapling1qv0ue89kqqqqpqqyt4cl5wvssx4wqq30e5m948p07dnwl9x3u75vvnzvjwwpjkrf8yk2gva0kkxk9p8suj4xawlzw9pajuxgap83wykvsuyzfrm33a2p2m4jz2205kgzx0l2lj2kyegtnuph6crkyvyjqmfxut84nu00wxgrstu5fy3eu49nzl8jzr4chmql4ysgg2t8htn9dtvxy8c7wx9rvcerqsjqm6lqln9syk3g8rr3xpy3l4nj0kawenzpcdtnv9qmy98vdhqzaf063",
|
||||
"0234965f30c8611253d035f44e68d4e2ce82150e8665c95f41ccbaf916b16c69d8",
|
||||
1320000
|
||||
),
|
||||
// Mainnet wallet
|
||||
arrayOf(
|
||||
TestWallet(TestWallet.Backups.SAMPLE_WALLET, ZcashNetwork.Mainnet),
|
||||
"zxviews1q0hxkupsqqqqpqzsffgrk2smjuccedua7zswf5e3rgtv3ga9nhvhjug670egshd6me53r5n083s2m9mf4va4z7t39ltd3wr7hawnjcw09eu85q0ammsg0tsgx24p4ma0uvr4p8ltx5laum2slh2whc23ctwlnxme9w4dw92kalwk5u4wyem8dynknvvqvs68ktvm8qh7nx9zg22xfc77acv8hk3qqll9k3x4v2fa26puu2939ea7hy4hh60ywma69xtqhcy4037ne8g2sg8sq",
|
||||
"031c6355641237643317e2d338f5e8734c57e8aa8ce960ee22283cf2d76bef73be",
|
||||
1195000
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package cash.z.ecc.android.sdk.integration
|
||||
|
||||
import androidx.test.filters.MediumTest
|
||||
import cash.z.ecc.android.sdk.annotation.MaintainedTest
|
||||
import cash.z.ecc.android.sdk.annotation.TestPurpose
|
||||
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
|
||||
import cash.z.ecc.android.sdk.util.TestWallet
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* This test is intended to run to make sure that basic things are functional and pinpoint what is
|
||||
* not working. It was originally developed after a major refactor to find what broke.
|
||||
*/
|
||||
@MaintainedTest(TestPurpose.COMMIT)
|
||||
@MediumTest
|
||||
class SmokeTest {
|
||||
|
||||
@Test
|
||||
fun testNotPlaintext() {
|
||||
val service =
|
||||
wallet.synchronizer.processor.downloader.lightWalletService as LightWalletGrpcService
|
||||
Assert.assertFalse(
|
||||
"Wallet is using plaintext. This will cause problems for the test. Ensure that the `lightwalletd_allow_very_insecure_connections` resource value is false",
|
||||
service.connectionInfo.usePlaintext
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFilePaths() {
|
||||
Assert.assertEquals("Invalid DataDB file", "/data/user/0/cash.z.ecc.android.sdk.test/databases/TestWallet_testnet_Data.db", wallet.initializer.rustBackend.pathDataDb)
|
||||
Assert.assertEquals("Invalid CacheDB file", "/data/user/0/cash.z.ecc.android.sdk.test/databases/TestWallet_testnet_Cache.db", wallet.initializer.rustBackend.pathCacheDb)
|
||||
Assert.assertEquals("Invalid CacheDB params dir", "/data/user/0/cash.z.ecc.android.sdk.test/cache/params", wallet.initializer.rustBackend.pathParamsDir)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testBirthday() {
|
||||
Assert.assertEquals("Invalid birthday height", 1_320_000, wallet.initializer.birthday.height)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testViewingKeys() {
|
||||
Assert.assertEquals("Invalid extfvk", "zxviewtestsapling1qv0ue89kqqqqpqqyt4cl5wvssx4wqq30e5m948p07dnwl9x3u75vvnzvjwwpjkrf8yk2gva0kkxk9p8suj4xawlzw9pajuxgap83wykvsuyzfrm33a2p2m4jz2205kgzx0l2lj2kyegtnuph6crkyvyjqmfxut84nu00wxgrstu5fy3eu49nzl8jzr4chmql4ysgg2t8htn9dtvxy8c7wx9rvcerqsjqm6lqln9syk3g8rr3xpy3l4nj0kawenzpcdtnv9qmy98vdhqzaf063", wallet.initializer.viewingKeys[0].extfvk)
|
||||
Assert.assertEquals("Invalid extpub", "0234965f30c8611253d035f44e68d4e2ce82150e8665c95f41ccbaf916b16c69d8", wallet.initializer.viewingKeys[0].extpub)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSync() = runBlocking<Unit> {
|
||||
wallet.sync(120_000L)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val wallet = TestWallet(TestWallet.Backups.SAMPLE_WALLET)
|
||||
}
|
||||
}
|
|
@ -1,12 +1,20 @@
|
|||
package cash.z.ecc.android.sdk.integration
|
||||
package cash.z.wallet.sdk.integration
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import cash.z.ecc.android.sdk.Initializer
|
||||
import cash.z.ecc.android.sdk.Synchronizer
|
||||
import cash.z.ecc.android.sdk.Synchronizer.Status.SYNCED
|
||||
import cash.z.ecc.android.sdk.db.entity.isSubmitSuccess
|
||||
import cash.z.ecc.android.sdk.jni.RustBackend
|
||||
import cash.z.ecc.android.sdk.ext.ScopedTest
|
||||
import cash.z.ecc.android.sdk.ext.TroubleshootingTwig
|
||||
import cash.z.ecc.android.sdk.ext.Twig
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||
import cash.z.ecc.android.sdk.ext.onFirst
|
||||
import cash.z.ecc.android.sdk.ext.twig
|
||||
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
|
||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||
import cash.z.ecc.android.sdk.tool.WalletBirthdayTool
|
||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.first
|
||||
|
@ -22,22 +30,22 @@ import java.util.concurrent.CountDownLatch
|
|||
class TestnetIntegrationTest : ScopedTest() {
|
||||
|
||||
var stopWatch = CountDownLatch(1)
|
||||
val saplingActivation = synchronizer.network.saplingActivationHeight
|
||||
|
||||
@Test
|
||||
fun testLatestBlockTest() {
|
||||
val service = LightWalletGrpcService(
|
||||
context,
|
||||
host,
|
||||
port
|
||||
)
|
||||
val height = service.getLatestBlockHeight()
|
||||
assertTrue(height > ZcashSdk.SAPLING_ACTIVATION_HEIGHT)
|
||||
assertTrue(height > saplingActivation)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLoadBirthday() {
|
||||
val (height, hash, time, tree) = Initializer.DefaultBirthdayStore.loadBirthdayFromAssets(context, ZcashSdk.SAPLING_ACTIVATION_HEIGHT + 1)
|
||||
assertEquals(ZcashSdk.SAPLING_ACTIVATION_HEIGHT, height)
|
||||
val (height, hash, time, tree) = WalletBirthdayTool.loadNearest(context, synchronizer.network, saplingActivation + 1)
|
||||
assertEquals(saplingActivation, height)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -74,7 +82,7 @@ class TestnetIntegrationTest : ScopedTest() {
|
|||
}
|
||||
|
||||
private suspend fun sendFunds(): Boolean {
|
||||
val spendingKey = RustBackend().deriveSpendingKeys(seed)[0]
|
||||
val spendingKey = DerivationTool.deriveSpendingKeys(seed, synchronizer.network)[0]
|
||||
log("sending to address")
|
||||
synchronizer.sendToAddress(
|
||||
spendingKey,
|
||||
|
@ -96,7 +104,6 @@ class TestnetIntegrationTest : ScopedTest() {
|
|||
init { Twig.plant(TroubleshootingTwig()) }
|
||||
|
||||
const val host = "lightwalletd.testnet.z.cash"
|
||||
const val port = 9067
|
||||
private const val birthdayHeight = 963150
|
||||
private const val targetHeight = 663250
|
||||
private const val seedPhrase = "still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread"
|
||||
|
@ -105,13 +112,15 @@ class TestnetIntegrationTest : ScopedTest() {
|
|||
val toAddress = "zs1vp7kvlqr4n9gpehztr76lcn6skkss9p8keqs3nv8avkdtjrcctrvmk9a7u494kluv756jeee5k0"
|
||||
|
||||
private val context = InstrumentationRegistry.getInstrumentation().context
|
||||
private val initializer = Initializer(context, host, port, "TestnetIntegrationTests")
|
||||
private val initializer = Initializer(context) { config ->
|
||||
config.setNetwork(ZcashNetwork.Testnet, host)
|
||||
config.importWallet(seed, birthdayHeight, ZcashNetwork.Testnet)
|
||||
}
|
||||
private lateinit var synchronizer: Synchronizer
|
||||
|
||||
@JvmStatic
|
||||
@BeforeClass
|
||||
fun startUp() {
|
||||
initializer.importPhrase(seedPhrase, birthdayHeight, "TestnetIntegrationTests", false)
|
||||
synchronizer = Synchronizer(initializer)
|
||||
synchronizer.start(classScope)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// package cash.z.ecc.android.sdk.integration
|
||||
package cash.z.ecc.android.sdk.integration.darkside // package cash.z.ecc.android.sdk.integration
|
||||
//
|
||||
// import cash.z.ecc.android.sdk.ext.ScopedTest
|
||||
// import cash.z.ecc.android.sdk.ext.twigTask
|
|
@ -1,4 +1,4 @@
|
|||
package cash.z.ecc.android.sdk.integration
|
||||
package cash.z.ecc.android.sdk.integration.darkside
|
||||
|
||||
// import cash.z.ecc.android.sdk.SdkSynchronizer
|
||||
// import cash.z.ecc.android.sdk.db.entity.isSubmitSuccess
|
|
@ -1,4 +1,4 @@
|
|||
// package cash.z.ecc.android.sdk.integration
|
||||
package cash.z.ecc.android.sdk.integration.darkside // package cash.z.ecc.android.sdk.integration
|
||||
//
|
||||
// import cash.z.ecc.android.sdk.ext.ScopedTest
|
||||
// import cash.z.ecc.android.sdk.ext.twig
|
|
@ -1,4 +1,4 @@
|
|||
// package cash.z.ecc.android.sdk.integration
|
||||
package cash.z.ecc.android.sdk.integration.darkside // package cash.z.ecc.android.sdk.integration
|
||||
//
|
||||
// import cash.z.ecc.android.sdk.ext.ScopedTest
|
||||
// import cash.z.ecc.android.sdk.util.DarksideTestCoordinator
|
|
@ -0,0 +1,24 @@
|
|||
package cash.z.ecc.android.sdk.integration.darkside
|
||||
|
||||
import cash.z.ecc.android.sdk.annotation.MaintainedTest
|
||||
import cash.z.ecc.android.sdk.annotation.TestPurpose.DARKSIDE
|
||||
import cash.z.ecc.android.sdk.annotation.TestPurpose.REGRESSION
|
||||
import cash.z.ecc.android.sdk.ext.DarksideTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* Integration test to run in order to catch any regressions in transparent behavior.
|
||||
*/
|
||||
@MaintainedTest(DARKSIDE, REGRESSION)
|
||||
class TransparentIntegrationTest : DarksideTest() {
|
||||
@Before
|
||||
fun setup() = runOnce {
|
||||
sithLord.await()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sanityTest() {
|
||||
validator.validateTxCount(5)
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package cash.z.ecc.android.sdk.integration.reorgs
|
||||
package cash.z.ecc.android.sdk.integration.darkside.reorgs
|
||||
|
||||
import cash.z.ecc.android.sdk.ext.ScopedTest
|
||||
import cash.z.ecc.android.sdk.ext.twig
|
|
@ -1,4 +1,4 @@
|
|||
// package cash.z.ecc.android.sdk.integration
|
||||
package cash.z.ecc.android.sdk.integration.darkside.reorgs // package cash.z.ecc.android.sdk.integration
|
||||
//
|
||||
// import cash.z.ecc.android.sdk.ext.ScopedTest
|
||||
// import cash.z.ecc.android.sdk.util.DarksideTestCoordinator
|
|
@ -1,4 +1,4 @@
|
|||
// package cash.z.ecc.android.sdk.integration
|
||||
package cash.z.ecc.android.sdk.integration.darkside.reorgs // package cash.z.ecc.android.sdk.integration
|
||||
//
|
||||
// import androidx.test.platform.app.InstrumentationRegistry
|
||||
// import cash.z.ecc.android.sdk.Initializer
|
|
@ -1,4 +1,4 @@
|
|||
package cash.z.ecc.android.sdk.integration
|
||||
package cash.z.ecc.android.sdk.integration.darkside.reorgs
|
||||
|
||||
import cash.z.ecc.android.sdk.ext.ScopedTest
|
||||
import cash.z.ecc.android.sdk.util.DarksideTestCoordinator
|
|
@ -1,4 +1,4 @@
|
|||
package cash.z.ecc.android.sdk.integration
|
||||
package cash.z.ecc.android.sdk.integration.darkside.reorgs
|
||||
|
||||
import cash.z.ecc.android.sdk.ext.ScopedTest
|
||||
import cash.z.ecc.android.sdk.ext.twig
|
|
@ -1,4 +1,4 @@
|
|||
package cash.z.ecc.android.sdk.integration.reorgs
|
||||
package cash.z.ecc.android.sdk.integration.darkside.reorgs
|
||||
|
||||
import cash.z.ecc.android.sdk.ext.ScopedTest
|
||||
import cash.z.ecc.android.sdk.ext.toHex
|
|
@ -0,0 +1,29 @@
|
|||
package cash.z.ecc.android.sdk.integration.darkside.reproduce
|
||||
|
||||
import cash.z.ecc.android.sdk.ext.DarksideTest
|
||||
import org.junit.Before
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Test
|
||||
|
||||
class ReproduceZ2TFailureTest : DarksideTest() {
|
||||
@Before
|
||||
fun setup() {
|
||||
println("dBUG RUNNING")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun once() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun twice() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@BeforeClass
|
||||
fun beforeAll() {
|
||||
println("dBUG BEFOERE IOT ALL")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +1,18 @@
|
|||
package cash.z.ecc.android.sdk.integration.service
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import cash.z.ecc.android.sdk.annotation.MaintainedTest
|
||||
import cash.z.ecc.android.sdk.annotation.TestPurpose
|
||||
import cash.z.ecc.android.sdk.block.CompactBlockDownloader
|
||||
import cash.z.ecc.android.sdk.block.CompactBlockStore
|
||||
import cash.z.ecc.android.sdk.exception.LightWalletException.ChangeServerException.ChainInfoNotMatching
|
||||
import cash.z.ecc.android.sdk.exception.LightWalletException.ChangeServerException.StatusException
|
||||
import cash.z.ecc.android.sdk.ext.ScopedTest
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||
import cash.z.ecc.android.sdk.ext.twig
|
||||
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
|
||||
import cash.z.ecc.android.sdk.service.LightWalletService
|
||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
@ -24,15 +27,19 @@ import org.mockito.Mock
|
|||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.Spy
|
||||
|
||||
@MaintainedTest(TestPurpose.REGRESSION)
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@SmallTest
|
||||
class ChangeServiceTest : ScopedTest() {
|
||||
|
||||
val network = ZcashNetwork.Mainnet
|
||||
|
||||
@Mock
|
||||
lateinit var mockBlockStore: CompactBlockStore
|
||||
var mockCloseable: AutoCloseable? = null
|
||||
|
||||
@Spy
|
||||
val service = LightWalletGrpcService(context, ZcashSdk.DEFAULT_LIGHTWALLETD_HOST)
|
||||
val service = LightWalletGrpcService(context, network)
|
||||
|
||||
lateinit var downloader: CompactBlockDownloader
|
||||
lateinit var otherService: LightWalletService
|
||||
|
@ -41,7 +48,7 @@ class ChangeServiceTest : ScopedTest() {
|
|||
fun setup() {
|
||||
initMocks()
|
||||
downloader = CompactBlockDownloader(service, mockBlockStore)
|
||||
otherService = LightWalletGrpcService(context, "lightwalletd.electriccoin.co", 9067)
|
||||
otherService = LightWalletGrpcService(context, "lightwalletd.electriccoin.co")
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -56,7 +63,7 @@ class ChangeServiceTest : ScopedTest() {
|
|||
@Test
|
||||
fun testSanityCheck() {
|
||||
val result = service.getLatestBlockHeight()
|
||||
assertTrue(result > ZcashSdk.SAPLING_ACTIVATION_HEIGHT)
|
||||
assertTrue(result > network.saplingActivationHeight)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -66,16 +73,20 @@ class ChangeServiceTest : ScopedTest() {
|
|||
assertEquals(1_001, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeatedly connect to servers and download a range of blocks. Switch part way through and
|
||||
* verify that the servers change over, even while actively downloading.
|
||||
*/
|
||||
@Test
|
||||
fun testSwitchWhileActive() = runBlocking {
|
||||
val start = 900_000
|
||||
val count = 5
|
||||
val vendors = mutableListOf<String>()
|
||||
var oldVendor = downloader.getServerInfo().vendor
|
||||
val differentiators = mutableListOf<String>()
|
||||
var initialValue = downloader.getServerInfo().buildUser
|
||||
val job = testScope.launch {
|
||||
repeat(count) {
|
||||
vendors.add(downloader.getServerInfo().vendor)
|
||||
twig("downloading from ${vendors.last()}")
|
||||
differentiators.add(downloader.getServerInfo().buildUser)
|
||||
twig("downloading from ${differentiators.last()}")
|
||||
downloader.downloadBlockRange(start..(start + 100 * it))
|
||||
delay(10L)
|
||||
}
|
||||
|
@ -85,8 +96,8 @@ class ChangeServiceTest : ScopedTest() {
|
|||
downloader.changeService(otherService)
|
||||
}
|
||||
job.join()
|
||||
assertTrue(vendors.count { it == oldVendor } < vendors.size)
|
||||
assertEquals(count, vendors.size)
|
||||
assertTrue(differentiators.count { it == initialValue } < differentiators.size)
|
||||
assertEquals(count, differentiators.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -105,7 +116,7 @@ class ChangeServiceTest : ScopedTest() {
|
|||
@Test
|
||||
fun testSwitchToTestnetFails() = runBlocking {
|
||||
var caughtException: Throwable? = null
|
||||
downloader.changeService(LightWalletGrpcService(context, "lightwalletd.testnet.electriccoin.co", 9067)) {
|
||||
downloader.changeService(LightWalletGrpcService(context, ZcashNetwork.Testnet)) {
|
||||
caughtException = it
|
||||
}
|
||||
assertNotNull("Using an invalid host should generate an exception.", caughtException)
|
||||
|
@ -114,7 +125,7 @@ class ChangeServiceTest : ScopedTest() {
|
|||
caughtException is ChainInfoNotMatching
|
||||
)
|
||||
(caughtException as ChainInfoNotMatching).propertyNames.let { props ->
|
||||
arrayOf("consensusBranchId", "saplingActivationHeight", "chainName").forEach {
|
||||
arrayOf("saplingActivationHeight", "chainName").forEach {
|
||||
assertTrue(
|
||||
"$it should be a non-matching property but properties were [$props]", props.contains(it, true)
|
||||
)
|
||||
|
|
|
@ -1,59 +1,82 @@
|
|||
package cash.z.ecc.android.sdk.jni
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import cash.z.ecc.android.bip39.Mnemonics.MnemonicCode
|
||||
import cash.z.ecc.android.bip39.toSeed
|
||||
import cash.z.ecc.android.sdk.annotation.MaintainedTest
|
||||
import cash.z.ecc.android.sdk.annotation.TestPurpose
|
||||
import cash.z.ecc.android.sdk.ext.TroubleshootingTwig
|
||||
import cash.z.ecc.android.sdk.ext.Twig
|
||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@MaintainedTest(TestPurpose.REGRESSION)
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@SmallTest
|
||||
class TransparentTest {
|
||||
|
||||
lateinit var expected: Expected
|
||||
lateinit var network: ZcashNetwork
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
// TODO: parameterize this for both networks
|
||||
// if (BuildConfig.FLAVOR == "zcashtestnet") {
|
||||
expected = ExpectedTestnet
|
||||
network = ZcashNetwork.Testnet
|
||||
// } else {
|
||||
// expected = ExpectedMainnet
|
||||
// network = ZcashNetwork.Mainnet
|
||||
// }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun deriveTransparentSecretKeyTest() {
|
||||
assertEquals(Expected.tskCompressed, DerivationTool.deriveTransparentSecretKey(SEED))
|
||||
assertEquals(expected.tskCompressed, DerivationTool.deriveTransparentSecretKey(SEED, network = network))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun deriveTransparentAddressTest() {
|
||||
assertEquals(Expected.tAddr, DerivationTool.deriveTransparentAddress(SEED))
|
||||
assertEquals(expected.tAddr, DerivationTool.deriveTransparentAddress(SEED, network = network))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun deriveTransparentAddressFromSecretKeyTest() {
|
||||
assertEquals(Expected.tAddr, DerivationTool.deriveTransparentAddress(Expected.tskCompressed))
|
||||
assertEquals(expected.tAddr, DerivationTool.deriveTransparentAddressFromPrivateKey(expected.tskCompressed, network = network))
|
||||
}
|
||||
|
||||
// @Test
|
||||
// fun deriveTransparentAddressFromSecretKeyTest2() {
|
||||
// while(false) {
|
||||
// MnemonicCode(COUNT_24).let { phrase ->
|
||||
// val addr = DerivationTool.deriveShieldedAddress(phrase.toSeed())
|
||||
// twig("$addr${String(phrase.chars)}\t")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@Test
|
||||
fun deriveUnifiedViewingKeysFromSeedTest() {
|
||||
val uvks = DerivationTool.deriveUnifiedViewingKeys(SEED, network = network)
|
||||
assertEquals(1, uvks.size)
|
||||
val uvk = uvks.first()
|
||||
assertEquals(expected.zAddr, DerivationTool.deriveShieldedAddress(uvk.extfvk, network = network))
|
||||
assertEquals(expected.tAddr, DerivationTool.deriveTransparentAddressFromPublicKey(uvk.extpub, network = network))
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val PHRASE = "deputy visa gentle among clean scout farm drive comfort patch skin salt ranch cool ramp warrior drink narrow normal lunch behind salt deal person"
|
||||
val MNEMONIC = MnemonicCode(PHRASE)
|
||||
val SEED = MNEMONIC.toSeed()
|
||||
|
||||
object Expected {
|
||||
val tAddr = "t1PKtYdJJHhc3Pxowmznkg7vdTwnhEsCvR4"
|
||||
object ExpectedMainnet : Expected {
|
||||
override val tAddr = "t1PKtYdJJHhc3Pxowmznkg7vdTwnhEsCvR4"
|
||||
override val zAddr = "zs1yc4sgtfwwzz6xfsy2xsradzr6m4aypgxhfw2vcn3hatrh5ryqsr08sgpemlg39vdh9kfupx20py"
|
||||
override val tskCompressed = "L4BvDC33yLjMRxipZvdiUmdYeRfZmR8viziwsVwe72zJdGbiJPv2"
|
||||
override val tpk = "03b1d7fb28d17c125b504d06b1530097e0a3c76ada184237e3bc0925041230a5af"
|
||||
}
|
||||
|
||||
// private key in compressed Wallet Import Format (WIF)
|
||||
val tskCompressed = "L4BvDC33yLjMRxipZvdiUmdYeRfZmR8viziwsVwe72zJdGbiJPv2"
|
||||
object ExpectedTestnet : Expected {
|
||||
override val tAddr = "tm9v3KTsjXK8XWSqiwFjic6Vda6eHY9Mjjq"
|
||||
override val zAddr = "ztestsapling1wn3tw9w5rs55x5yl586gtk72e8hcfdq8zsnjzcu8p7ghm8lrx54axc74mvm335q7lmy3g0sqje6"
|
||||
override val tskCompressed = "KzVugoXxR7AtTMdR5sdJtHxCNvMzQ4H196k7ATv4nnjoummsRC9G"
|
||||
override val tpk = "03b1d7fb28d17c125b504d06b1530097e0a3c76ada184237e3bc0925041230a5af"
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
|
@ -62,4 +85,11 @@ class TransparentTest {
|
|||
Twig.plant(TroubleshootingTwig(formatter = { "@TWIG $it" }))
|
||||
}
|
||||
}
|
||||
|
||||
interface Expected {
|
||||
val tAddr: String
|
||||
val zAddr: String
|
||||
val tskCompressed: String
|
||||
val tpk: String
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import cash.z.ecc.android.sdk.ext.TroubleshootingTwig
|
|||
import cash.z.ecc.android.sdk.ext.Twig
|
||||
import cash.z.ecc.android.sdk.ext.twig
|
||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||
import cash.z.ecc.android.sdk.type.ZcashNetwork.Testnet
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.flow.catch
|
||||
|
@ -28,9 +29,6 @@ class ShieldFundsSample {
|
|||
|
||||
val SEED_PHRASE = "wish puppy smile loan doll curve hole maze file ginger hair nose key relax knife witness cannon grab despair throw review deal slush frame" // \"still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread\"//\"deputy visa gentle among clean scout farm drive comfort patch skin salt ranch cool ramp warrior drink narrow normal lunch behind salt deal person"//"deputy visa gentle among clean scout farm drive comfort patch skin salt ranch cool ramp warrior drink narrow normal lunch behind salt deal person"
|
||||
|
||||
// simple flag to turn off actually spending funds
|
||||
val IS_DRY_RUN = true
|
||||
|
||||
/**
|
||||
* This test will construct a t2z transaction. It is safe to run this repeatedly, because
|
||||
* nothing is submitted to the network (because the keys don't match the address so the encoding
|
||||
|
@ -51,22 +49,25 @@ class ShieldFundsSample {
|
|||
|
||||
// when startHeight is null, it will use the latest checkpoint
|
||||
class SimpleWallet(seedPhrase: String, startHeight: Int? = null) {
|
||||
// simple flag to turn off actually spending funds
|
||||
val IS_DRY_RUN = true
|
||||
|
||||
val walletScope = CoroutineScope(
|
||||
SupervisorJob() + newFixedThreadPoolContext(3, this.javaClass.simpleName)
|
||||
)
|
||||
private val context = InstrumentationRegistry.getInstrumentation().context
|
||||
private val seed: ByteArray = Mnemonics.MnemonicCode(seedPhrase).toSeed()
|
||||
private val shieldedSpendingKey = DerivationTool.deriveSpendingKeys(seed)[0]
|
||||
private val transparentSecretKey = DerivationTool.deriveTransparentSecretKey(seed)
|
||||
private val shieldedAddress = DerivationTool.deriveShieldedAddress(seed)
|
||||
private val shieldedSpendingKey = DerivationTool.deriveSpendingKeys(seed, Testnet)[0]
|
||||
private val transparentSecretKey = DerivationTool.deriveTransparentSecretKey(seed, Testnet)
|
||||
private val shieldedAddress = DerivationTool.deriveShieldedAddress(seed, Testnet)
|
||||
|
||||
// t1b9Y6PESSGavavgge3ruTtX9X83817V29s
|
||||
private val transparentAddress = DerivationTool.deriveTransparentAddress(seed)
|
||||
|
||||
private val transparentAddress = DerivationTool.deriveTransparentAddress(seed, Testnet)
|
||||
private val host = "lightwalletd.testnet.electriccoin.co"
|
||||
private val config = Initializer.Config {
|
||||
it.setSeed(seed)
|
||||
it.setSeed(seed, Testnet)
|
||||
it.setBirthdayHeight(startHeight, false)
|
||||
it.server("lightwalletd.electriccoin.co", 9067)
|
||||
it.setNetwork(Testnet, host)
|
||||
}
|
||||
|
||||
val synchronizer = Synchronizer(Initializer(context, config))
|
||||
|
|
|
@ -0,0 +1,229 @@
|
|||
package cash.z.ecc.android.sdk.sample
|
||||
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||
import cash.z.ecc.android.sdk.ext.twig
|
||||
import cash.z.ecc.android.sdk.type.ZcashNetwork.Testnet
|
||||
import cash.z.ecc.android.sdk.util.TestWallet
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* Sample tests are used to demonstrate functionality. This one attempts to setup a scenario where
|
||||
* one wallet shields funds and the other restores from the blockchain. Ultimately, they should have
|
||||
* the same data.
|
||||
*/
|
||||
class TransparentRestoreSample {
|
||||
|
||||
val TX_VALUE = ZcashSdk.MINERS_FEE_ZATOSHI / 2
|
||||
|
||||
// val walletA = SimpleWallet(SEED_PHRASE, "WalletA")
|
||||
|
||||
// the wallet that only restores what everyone else did
|
||||
// val walletB = SimpleWallet(SEED_PHRASE, "WalletB")
|
||||
// // the wallet that sends Z2T transactions
|
||||
//
|
||||
// // sandbox wallet
|
||||
// val walletSandbox = SimpleWallet(SEED_PHRASE, "WalletC")
|
||||
// val walletZ2T = SimpleWallet(SEED_PHRASE, "WalletZ2T")
|
||||
// val externalTransparentAddress =
|
||||
// DerivationTool.deriveTransparentAddress(Mnemonics.MnemonicCode(RANDOM_PHRASE).toSeed(), Testnet)
|
||||
|
||||
// @Test
|
||||
fun sendZ2Texternal() = runBlocking {
|
||||
twig("Syncing WalletExt")
|
||||
val extWallet = TestWallet(TestWallet.Backups.ALICE, alias = "WalletE")
|
||||
extWallet.sync()
|
||||
// extWallet.send(542, walletSandbox.transparentAddress, "External funds memo is lost, though")
|
||||
delay(1000)
|
||||
twig("Done sending funds to external address (Z->T COMPLETE!)")
|
||||
}
|
||||
|
||||
// @Test
|
||||
fun sendZ2T() = runBlocking {
|
||||
// walletSandbox.sync()
|
||||
// walletZ2T.send(543, externalTransparentAddress, "External funds memo is lost, though")
|
||||
delay(1000)
|
||||
twig("Done sending funds to external address (Z->T COMPLETE!)")
|
||||
}
|
||||
|
||||
// @Test
|
||||
fun autoShield() = runBlocking<Unit> {
|
||||
val wallet = TestWallet(TestWallet.Backups.SAMPLE_WALLET, alias = "WalletC")
|
||||
wallet.sync()
|
||||
twig("Done syncing wallet!")
|
||||
val tbalance = wallet.transparentBalance()
|
||||
val address = wallet.transparentAddress
|
||||
|
||||
twig("t-avail: ${tbalance.availableZatoshi} t-total: ${tbalance.totalZatoshi}")
|
||||
Assert.assertTrue("Not enough funds to run sample. Expected some Zatoshi but found ${tbalance.availableZatoshi}. Try adding funds to $address", tbalance.availableZatoshi > 0)
|
||||
|
||||
twig("Shielding available transparent funds!")
|
||||
// wallet.shieldFunds()
|
||||
}
|
||||
|
||||
// @Test
|
||||
fun cli() = runBlocking<Unit> {
|
||||
// val wallet = SimpleWallet(SEED_PHRASE, "WalletCli")
|
||||
// wallet.sync()
|
||||
// wallet.rewindToHeight(1343500).join(45_000)
|
||||
val wallet = TestWallet(TestWallet.Backups.SAMPLE_WALLET, alias = "WalletC")
|
||||
// wallet.sync().rewindToHeight(1339178).join(10000)
|
||||
wallet.sync().rewindToHeight(1339178).send(
|
||||
"ztestsapling17zazsl8rryl8kjaqxnr2r29rw9d9a2mud37ugapm0s8gmyv0ue43h9lqwmhdsp3nu9dazeqfs6l",
|
||||
"is send broken?"
|
||||
).join(5)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun kris() = runBlocking<Unit> {
|
||||
val wallet0 = TestWallet(TestWallet.Backups.SAMPLE_WALLET.seedPhrase, "tmpabc", Testnet, startHeight = 1330190)
|
||||
// val wallet1 = SimpleWallet(WALLET0_PHRASE, "Wallet1")
|
||||
|
||||
wallet0.sync() // .shieldFunds()
|
||||
// .send(amount = 1543L, memo = "")
|
||||
.join()
|
||||
// wallet1.sync().join(5_000L)
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sanity check that the wallet has enough funds for the test
|
||||
*/
|
||||
// @Test
|
||||
fun hasFunds() = runBlocking<Unit> {
|
||||
val walletSandbox = TestWallet(TestWallet.Backups.SAMPLE_WALLET.seedPhrase, "WalletC", Testnet, startHeight = 1330190)
|
||||
// val job = walletA.walletScope.launch {
|
||||
// twig("Syncing WalletA")
|
||||
// walletA.sync()
|
||||
// }
|
||||
twig("Syncing WalletSandbox")
|
||||
walletSandbox.sync()
|
||||
// job.join()
|
||||
delay(500)
|
||||
|
||||
twig("Done syncing both wallets!")
|
||||
// val value = walletA.available
|
||||
// val address = walletA.shieldedAddress
|
||||
// Assert.assertTrue("Not enough funds to run sample. Expected at least $TX_VALUE Zatoshi but found $value. Try adding funds to $address", value >= TX_VALUE)
|
||||
|
||||
// send z->t
|
||||
// walletA.send(TX_VALUE, walletA.transparentAddress, "${TransparentRestoreSample::class.java.simpleName} z->t")
|
||||
|
||||
walletSandbox.rewindToHeight(1339178)
|
||||
twig("Done REWINDING!")
|
||||
twig("T-ADDR (for the win!): ${walletSandbox.transparentAddress}")
|
||||
delay(500)
|
||||
// walletB.sync()
|
||||
// rewind database B to height then rescan
|
||||
}
|
||||
|
||||
// // when startHeight is null, it will use the latest checkpoint
|
||||
// class SimpleWallet(
|
||||
// seedPhrase: String,
|
||||
// alias: String = ZcashSdk.DEFAULT_ALIAS,
|
||||
// startHeight: Int? = null
|
||||
// ) {
|
||||
// val walletScope = CoroutineScope(
|
||||
// SupervisorJob() + newFixedThreadPoolContext(3, this.javaClass.simpleName)
|
||||
// )
|
||||
// private val context = InstrumentationRegistry.getInstrumentation().context
|
||||
// private val seed: ByteArray = Mnemonics.MnemonicCode(seedPhrase).toSeed()
|
||||
// private val shieldedSpendingKey = DerivationTool.deriveSpendingKeys(seed, Testnet)[0]
|
||||
// private val transparentSecretKey = DerivationTool.deriveTransparentSecretKey(seed, Testnet)
|
||||
// private val host = "lightwalletd.testnet.electriccoin.co"
|
||||
// private val initializer = Initializer(context) { config ->
|
||||
// config.importWallet(seed, startHeight)
|
||||
// config.setNetwork(Testnet, host)
|
||||
// config.alias = alias
|
||||
// }
|
||||
//
|
||||
// val synchronizer = Synchronizer(initializer)
|
||||
// val available get() = synchronizer.latestBalance.availableZatoshi
|
||||
// val shieldedAddress = DerivationTool.deriveShieldedAddress(seed, Testnet)
|
||||
// val transparentAddress = DerivationTool.deriveTransparentAddress(seed, Testnet)
|
||||
// val birthdayHeight get() = synchronizer.latestBirthdayHeight
|
||||
//
|
||||
// suspend fun transparentBalance(): WalletBalance {
|
||||
// synchronizer.refreshUtxos(transparentAddress, synchronizer.latestBirthdayHeight)
|
||||
// return synchronizer.getTransparentBalance(transparentAddress)
|
||||
// }
|
||||
//
|
||||
// suspend fun sync(): SimpleWallet {
|
||||
// if (!synchronizer.isStarted) {
|
||||
// twig("Starting sync")
|
||||
// synchronizer.start(walletScope)
|
||||
// } else {
|
||||
// twig("Awaiting next SYNCED status")
|
||||
// }
|
||||
//
|
||||
// // block until synced
|
||||
// synchronizer.status.first { it == SYNCED }
|
||||
// twig("Synced!")
|
||||
// return this
|
||||
// }
|
||||
//
|
||||
// suspend fun send(address: String = transparentAddress, memo: String = "", amount: Long = 500L): SimpleWallet {
|
||||
// synchronizer.sendToAddress(shieldedSpendingKey, amount, address, memo)
|
||||
// .takeWhile { it.isPending() }
|
||||
// .collect {
|
||||
// twig("Updated transaction: $it")
|
||||
// }
|
||||
// return this
|
||||
// }
|
||||
//
|
||||
// suspend fun rewindToHeight(height: Int): SimpleWallet {
|
||||
// synchronizer.rewindToHeight(height, false)
|
||||
// return this
|
||||
// }
|
||||
//
|
||||
// suspend fun shieldFunds(): SimpleWallet {
|
||||
// twig("checking $transparentAddress for transactions!")
|
||||
// synchronizer.refreshUtxos(transparentAddress, 935000).let { count ->
|
||||
// twig("FOUND $count new UTXOs")
|
||||
// }
|
||||
//
|
||||
// synchronizer.getTransparentBalance(transparentAddress).let { walletBalance ->
|
||||
// twig("FOUND utxo balance of total: ${walletBalance.totalZatoshi} available: ${walletBalance.availableZatoshi}")
|
||||
//
|
||||
// if (walletBalance.availableZatoshi > 0L) {
|
||||
// synchronizer.shieldFunds(shieldedSpendingKey, transparentSecretKey)
|
||||
// .onCompletion { twig("done shielding funds") }
|
||||
// .catch { twig("Failed with $it") }
|
||||
// .collect()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return this
|
||||
// }
|
||||
//
|
||||
// suspend fun join(timeout: Long? = null): SimpleWallet {
|
||||
// // block until stopped
|
||||
// twig("Staying alive until synchronizer is stopped!")
|
||||
// if (timeout != null) {
|
||||
// twig("Scheduling a stop in ${timeout}ms")
|
||||
// walletScope.launch {
|
||||
// delay(timeout)
|
||||
// synchronizer.stop()
|
||||
// }
|
||||
// }
|
||||
// synchronizer.status.first { it == Synchronizer.Status.STOPPED }
|
||||
// twig("Stopped!")
|
||||
// return this
|
||||
// }
|
||||
//
|
||||
// companion object {
|
||||
// init {
|
||||
// Twig.plant(TroubleshootingTwig())
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
package cash.z.ecc.android.sdk.transaction
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import cash.z.ecc.android.sdk.annotation.MaintainedTest
|
||||
import cash.z.ecc.android.sdk.annotation.TestPurpose
|
||||
import cash.z.ecc.android.sdk.db.entity.EncodedTransaction
|
||||
import cash.z.ecc.android.sdk.db.entity.PendingTransaction
|
||||
import cash.z.ecc.android.sdk.db.entity.isCancelled
|
||||
|
@ -29,7 +32,9 @@ import org.junit.runner.RunWith
|
|||
import org.mockito.Mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@MaintainedTest(TestPurpose.REGRESSION)
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@SmallTest
|
||||
class PersistentTransactionManagerTest : ScopedTest() {
|
||||
|
||||
@Mock lateinit var mockEncoder: TransactionEncoder
|
||||
|
|
|
@ -2,6 +2,7 @@ package cash.z.ecc.android.sdk.util
|
|||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.flow
|
||||
|
@ -35,7 +36,7 @@ class AddressGeneratorUtil {
|
|||
.map { seedPhrase ->
|
||||
mnemonics.toSeed(seedPhrase.toCharArray())
|
||||
}.map { seed ->
|
||||
DerivationTool.deriveShieldedAddress(seed)
|
||||
DerivationTool.deriveShieldedAddress(seed, ZcashNetwork.Mainnet)
|
||||
}.collect { address ->
|
||||
println("xrxrx2\t$address")
|
||||
assertTrue(address.startsWith("zs1"))
|
||||
|
|
|
@ -7,6 +7,8 @@ import cash.z.ecc.android.sdk.ext.TroubleshootingTwig
|
|||
import cash.z.ecc.android.sdk.ext.Twig
|
||||
import cash.z.ecc.android.sdk.ext.twig
|
||||
import cash.z.ecc.android.sdk.tool.WalletBirthdayTool
|
||||
import cash.z.ecc.android.sdk.type.WalletBirthday
|
||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.flow
|
||||
|
@ -25,8 +27,7 @@ import java.io.IOException
|
|||
@ExperimentalCoroutinesApi
|
||||
class BalancePrinterUtil {
|
||||
|
||||
private val host = "lightd-main.zecwallet.co"
|
||||
private val port = 443
|
||||
private val network = ZcashNetwork.Mainnet
|
||||
private val downloadBatchSize = 9_000
|
||||
private val birthdayHeight = 523240
|
||||
|
||||
|
@ -44,14 +45,14 @@ class BalancePrinterUtil {
|
|||
|
||||
// private val rustBackend = RustBackend.init(context, cacheDbName, dataDbName)
|
||||
|
||||
private lateinit var birthday: WalletBirthdayTool.WalletBirthday
|
||||
private lateinit var birthday: WalletBirthday
|
||||
private var synchronizer: Synchronizer? = null
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
Twig.plant(TroubleshootingTwig())
|
||||
cacheBlocks()
|
||||
birthday = WalletBirthdayTool.loadNearest(context, birthdayHeight)
|
||||
birthday = WalletBirthdayTool.loadNearest(context, network, birthdayHeight)
|
||||
}
|
||||
|
||||
private fun cacheBlocks() = runBlocking {
|
||||
|
@ -78,8 +79,8 @@ class BalancePrinterUtil {
|
|||
}.collect { seed ->
|
||||
// TODO: clear the dataDb but leave the cacheDb
|
||||
val initializer = Initializer(context) { config ->
|
||||
config.importWallet(seed, birthdayHeight)
|
||||
config.server(host, port)
|
||||
config.importWallet(seed, birthdayHeight, network)
|
||||
config.setNetwork(network)
|
||||
config.alias = alias
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -2,9 +2,9 @@ package cash.z.ecc.android.sdk.util
|
|||
|
||||
import android.content.Context
|
||||
import cash.z.ecc.android.sdk.R
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||
import cash.z.ecc.android.sdk.ext.twig
|
||||
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
|
||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
||||
import cash.z.wallet.sdk.rpc.Darkside
|
||||
import cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL
|
||||
import cash.z.wallet.sdk.rpc.DarksideStreamerGrpc
|
||||
|
@ -23,7 +23,7 @@ class DarksideApi(
|
|||
constructor(
|
||||
appContext: Context,
|
||||
host: String,
|
||||
port: Int = ZcashSdk.DEFAULT_LIGHTWALLETD_PORT,
|
||||
port: Int = ZcashNetwork.Mainnet.defaultPort,
|
||||
usePlainText: Boolean = appContext.resources.getBoolean(
|
||||
R.bool.lightwalletd_allow_very_insecure_connections
|
||||
)
|
||||
|
@ -42,8 +42,8 @@ class DarksideApi(
|
|||
|
||||
fun reset(
|
||||
saplingActivationHeight: Int = 419200,
|
||||
branchId: String = "2bb40e60", // Blossom,
|
||||
chainName: String = "darkside"
|
||||
branchId: String = "e9ff75a6", // Canopy,
|
||||
chainName: String = "darkside${ZcashNetwork.Mainnet.networkName}"
|
||||
) = apply {
|
||||
twig("resetting darksidewalletd with saplingActivation=$saplingActivationHeight branchId=$branchId chainName=$chainName")
|
||||
Darkside.DarksideMetaState.newBuilder()
|
||||
|
|
|
@ -1,32 +1,35 @@
|
|||
package cash.z.ecc.android.sdk.util
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import cash.z.ecc.android.sdk.Initializer
|
||||
import cash.z.ecc.android.sdk.SdkSynchronizer
|
||||
import cash.z.ecc.android.sdk.Synchronizer
|
||||
import cash.z.ecc.android.sdk.ext.Twig
|
||||
import cash.z.ecc.android.sdk.ext.ScopedTest
|
||||
import cash.z.ecc.android.sdk.ext.seedPhrase
|
||||
import cash.z.ecc.android.sdk.ext.twig
|
||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
||||
import io.grpc.StatusRuntimeException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
|
||||
class DarksideTestCoordinator(val host: String = "127.0.0.1", val testName: String = "DarksideTestCoordinator") {
|
||||
private val port = 9067
|
||||
private val birthdayHeight = 663150
|
||||
class DarksideTestCoordinator(val wallet: TestWallet) {
|
||||
constructor(
|
||||
alias: String = "DarksideTestCoordinator",
|
||||
seedPhrase: String = DEFAULT_SEED_PHRASE,
|
||||
startHeight: Int = DEFAULT_START_HEIGHT,
|
||||
host: String = "127.0.0.1",
|
||||
network: ZcashNetwork = ZcashNetwork.Mainnet,
|
||||
port: Int = network.defaultPort,
|
||||
) : this(TestWallet(seedPhrase, alias, network, host, port, startHeight))
|
||||
|
||||
private val targetHeight = 663250
|
||||
private val seedPhrase =
|
||||
"still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread"
|
||||
private val context = InstrumentationRegistry.getInstrumentation().context
|
||||
|
||||
// dependencies: private
|
||||
|
@ -35,11 +38,10 @@ class DarksideTestCoordinator(val host: String = "127.0.0.1", val testName: Stri
|
|||
// dependencies: public
|
||||
val validator = DarksideTestValidator()
|
||||
val chainMaker = DarksideChainMaker()
|
||||
// var initializer = Initializer(context, Initializer.Builder(host, port, testName))
|
||||
lateinit var synchronizer: SdkSynchronizer
|
||||
|
||||
val spendingKey: String get() = DerivationTool.deriveSpendingKeys(SimpleMnemonics().toSeed(seedPhrase.toCharArray()))[0]
|
||||
|
||||
// wallet delegates
|
||||
val synchronizer get() = wallet.synchronizer
|
||||
val send get() = wallet::send
|
||||
//
|
||||
// High-level APIs
|
||||
//
|
||||
|
@ -74,14 +76,9 @@ class DarksideTestCoordinator(val host: String = "127.0.0.1", val testName: Stri
|
|||
*/
|
||||
fun initiate() {
|
||||
twig("*************** INITIALIZING TEST COORDINATOR (ONLY ONCE) ***********************")
|
||||
val initializer = Initializer(context) { config ->
|
||||
config.seedPhrase(seedPhrase)
|
||||
config.setBirthdayHeight(birthdayHeight)
|
||||
config.alias = testName
|
||||
}
|
||||
synchronizer = Synchronizer(initializer) as SdkSynchronizer
|
||||
val channel = (synchronizer as SdkSynchronizer).channel
|
||||
val channel = synchronizer.channel
|
||||
darkside = DarksideApi(channel)
|
||||
darkside.reset()
|
||||
}
|
||||
|
||||
// fun triggerSmallReorg() {
|
||||
|
@ -96,6 +93,7 @@ class DarksideTestCoordinator(val host: String = "127.0.0.1", val testName: Stri
|
|||
synchronizer.start(scope)
|
||||
}
|
||||
|
||||
// redo this as a call to wallet but add delay time to wallet join() function
|
||||
/**
|
||||
* Waits for, at most, the given amount of time for the synchronizer to download and scan blocks
|
||||
* and reach a 'SYNCED' status.
|
||||
|
@ -124,27 +122,19 @@ class DarksideTestCoordinator(val host: String = "127.0.0.1", val testName: Stri
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a transaction and wait until it has been fully created and successfully submitted, which
|
||||
* takes about 10 seconds.
|
||||
*/
|
||||
suspend fun createAndSubmitTx(
|
||||
zatoshi: Long,
|
||||
toAddress: String,
|
||||
memo: String = "",
|
||||
fromAccountIndex: Int = 0
|
||||
) = coroutineScope {
|
||||
Twig.sprout("sending")
|
||||
var job: Job? = null
|
||||
job = synchronizer
|
||||
.sendToAddress(spendingKey, zatoshi, toAddress, memo, fromAccountIndex)
|
||||
.onEach {
|
||||
twig("got an update submitted yet? ${it.isSubmitSuccess()}")
|
||||
if (it.isSubmitSuccess()) job?.cancel()
|
||||
}.launchIn(this)
|
||||
job.join()
|
||||
Twig.clip("sending")
|
||||
}
|
||||
// /**
|
||||
// * Send a transaction and wait until it has been fully created and successfully submitted, which
|
||||
// * takes about 10 seconds.
|
||||
// */
|
||||
// suspend fun createAndSubmitTx(
|
||||
// zatoshi: Long,
|
||||
// toAddress: String,
|
||||
// memo: String = "",
|
||||
// fromAccountIndex: Int = 0
|
||||
// ) = coroutineScope {
|
||||
//
|
||||
// wallet.send(toAddress, memo, zatoshi, fromAccountIndex)
|
||||
// }
|
||||
|
||||
fun stall(delay: Long = 5000L) = runBlocking {
|
||||
twig("*** Stalling for ${delay}ms ***")
|
||||
|
@ -225,7 +215,7 @@ class DarksideTestCoordinator(val host: String = "127.0.0.1", val testName: Stri
|
|||
}
|
||||
}
|
||||
suspend fun validateBalance(available: Long = -1, total: Long = -1, accountIndex: Int = 0) {
|
||||
val balance = synchronizer.processor.getBalanceInfo(accountIndex)
|
||||
val balance = (synchronizer as SdkSynchronizer).processor.getBalanceInfo(accountIndex)
|
||||
if (available > 0) {
|
||||
assertEquals("invalid available balance", available, balance.availableZatoshi)
|
||||
}
|
||||
|
@ -314,5 +304,7 @@ class DarksideTestCoordinator(val host: String = "127.0.0.1", val testName: Stri
|
|||
private const val largeReorg =
|
||||
"https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/basic-reorg/after-large-reorg.txt"
|
||||
private const val DEFAULT_START_HEIGHT = 663150
|
||||
private const val DEFAULT_SEED_PHRASE =
|
||||
"still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
package cash.z.ecc.android.sdk.util
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import cash.z.ecc.android.bip39.Mnemonics
|
||||
import cash.z.ecc.android.bip39.toSeed
|
||||
import cash.z.ecc.android.sdk.Initializer
|
||||
import cash.z.ecc.android.sdk.SdkSynchronizer
|
||||
import cash.z.ecc.android.sdk.Synchronizer
|
||||
import cash.z.ecc.android.sdk.db.entity.isPending
|
||||
import cash.z.ecc.android.sdk.ext.Twig
|
||||
import cash.z.ecc.android.sdk.ext.twig
|
||||
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
|
||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||
import cash.z.ecc.android.sdk.type.WalletBalance
|
||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.onCompletion
|
||||
import kotlinx.coroutines.flow.takeWhile
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.newFixedThreadPoolContext
|
||||
import java.util.concurrent.TimeoutException
|
||||
|
||||
/**
|
||||
* A simple wallet that connects to testnet for integration testing. The intention is that it is
|
||||
* easy to drive and nice to use.
|
||||
*/
|
||||
class TestWallet(
|
||||
val seedPhrase: String,
|
||||
val alias: String = "TestWallet",
|
||||
val network: ZcashNetwork = ZcashNetwork.Testnet,
|
||||
val host: String = network.defaultHost,
|
||||
startHeight: Int? = null,
|
||||
val port: Int = network.defaultPort,
|
||||
) {
|
||||
constructor(
|
||||
backup: Backups,
|
||||
network: ZcashNetwork = ZcashNetwork.Testnet,
|
||||
alias: String = "TestWallet"
|
||||
) : this(
|
||||
backup.seedPhrase,
|
||||
network = network,
|
||||
startHeight = backup.testnetBirthday,
|
||||
alias = alias
|
||||
)
|
||||
|
||||
val walletScope = CoroutineScope(
|
||||
SupervisorJob() + newFixedThreadPoolContext(3, this.javaClass.simpleName)
|
||||
)
|
||||
private val context = InstrumentationRegistry.getInstrumentation().context
|
||||
private val seed: ByteArray = Mnemonics.MnemonicCode(seedPhrase).toSeed()
|
||||
private val shieldedSpendingKey = DerivationTool.deriveSpendingKeys(seed, network = network)[0]
|
||||
private val transparentSecretKey = DerivationTool.deriveTransparentSecretKey(seed, network = network)
|
||||
val initializer = Initializer(context) { config ->
|
||||
config.importWallet(seed, startHeight, network, host, alias = alias)
|
||||
}
|
||||
val synchronizer: SdkSynchronizer = Synchronizer(initializer) as SdkSynchronizer
|
||||
val service = (synchronizer.processor.downloader.lightWalletService as LightWalletGrpcService)
|
||||
|
||||
val available get() = synchronizer.latestBalance.availableZatoshi
|
||||
val shieldedAddress = DerivationTool.deriveShieldedAddress(seed, network = network)
|
||||
val transparentAddress = DerivationTool.deriveTransparentAddress(seed, network = network)
|
||||
val birthdayHeight get() = synchronizer.latestBirthdayHeight
|
||||
val networkName get() = synchronizer.network.networkName
|
||||
val connectionInfo get() = service.connectionInfo.toString()
|
||||
|
||||
suspend fun transparentBalance(): WalletBalance {
|
||||
synchronizer.refreshUtxos(transparentAddress, synchronizer.latestBirthdayHeight)
|
||||
return synchronizer.getTransparentBalance(transparentAddress)
|
||||
}
|
||||
|
||||
suspend fun sync(timeout: Long = -1): TestWallet {
|
||||
val killSwitch = walletScope.launch {
|
||||
if (timeout > 0) {
|
||||
delay(timeout)
|
||||
throw TimeoutException("Failed to sync wallet within ${timeout}ms")
|
||||
}
|
||||
}
|
||||
if (!synchronizer.isStarted) {
|
||||
twig("Starting sync")
|
||||
synchronizer.start(walletScope)
|
||||
} else {
|
||||
twig("Awaiting next SYNCED status")
|
||||
}
|
||||
|
||||
// block until synced
|
||||
synchronizer.status.first { it == Synchronizer.Status.SYNCED }
|
||||
killSwitch.cancel()
|
||||
twig("Synced!")
|
||||
return this
|
||||
}
|
||||
|
||||
suspend fun send(address: String = transparentAddress, memo: String = "", amount: Long = 500L, fromAccountIndex: Int = 0): TestWallet {
|
||||
Twig.sprout("$alias sending")
|
||||
synchronizer.sendToAddress(shieldedSpendingKey, amount, address, memo, fromAccountIndex)
|
||||
.takeWhile { it.isPending() }
|
||||
.collect {
|
||||
twig("Updated transaction: $it")
|
||||
}
|
||||
Twig.clip("$alias sending")
|
||||
return this
|
||||
}
|
||||
|
||||
suspend fun rewindToHeight(height: Int): TestWallet {
|
||||
synchronizer.rewindToHeight(height, false)
|
||||
return this
|
||||
}
|
||||
|
||||
suspend fun shieldFunds(): TestWallet {
|
||||
twig("checking $transparentAddress for transactions!")
|
||||
synchronizer.refreshUtxos(transparentAddress, 935000).let { count ->
|
||||
twig("FOUND $count new UTXOs")
|
||||
}
|
||||
|
||||
synchronizer.getTransparentBalance(transparentAddress).let { walletBalance ->
|
||||
twig("FOUND utxo balance of total: ${walletBalance.totalZatoshi} available: ${walletBalance.availableZatoshi}")
|
||||
|
||||
if (walletBalance.availableZatoshi > 0L) {
|
||||
synchronizer.shieldFunds(shieldedSpendingKey, transparentSecretKey)
|
||||
.onCompletion { twig("done shielding funds") }
|
||||
.catch { twig("Failed with $it") }
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
suspend fun join(timeout: Long? = null): TestWallet {
|
||||
// block until stopped
|
||||
twig("Staying alive until synchronizer is stopped!")
|
||||
if (timeout != null) {
|
||||
twig("Scheduling a stop in ${timeout}ms")
|
||||
walletScope.launch {
|
||||
delay(timeout)
|
||||
synchronizer.stop()
|
||||
}
|
||||
}
|
||||
synchronizer.status.first { it == Synchronizer.Status.STOPPED }
|
||||
twig("Stopped!")
|
||||
return this
|
||||
}
|
||||
|
||||
companion object {
|
||||
init {
|
||||
Twig.enabled(true)
|
||||
}
|
||||
}
|
||||
|
||||
enum class Backups(val seedPhrase: String, val testnetBirthday: Int) {
|
||||
DEFAULT("column rhythm acoustic gym cost fit keen maze fence seed mail medal shrimp tell relief clip cannon foster soldier shallow refuse lunar parrot banana", 1_355_928),
|
||||
SAMPLE_WALLET("input frown warm senior anxiety abuse yard prefer churn reject people glimpse govern glory crumble swallow verb laptop switch trophy inform friend permit purpose", 1_330_190),
|
||||
ALICE("quantum whisper lion route fury lunar pelican image job client hundred sauce chimney barely life cliff spirit admit weekend message recipe trumpet impact kitten", 1_330_190),
|
||||
BOB("canvas wine sugar acquire garment spy tongue odor hole cage year habit bullet make label human unit option top calm neutral try vocal arena", 1_330_190),
|
||||
;
|
||||
}
|
||||
}
|
|
@ -3,16 +3,17 @@ package cash.z.ecc.android.sdk.util
|
|||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import cash.z.ecc.android.sdk.ext.TroubleshootingTwig
|
||||
import cash.z.ecc.android.sdk.ext.Twig
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||
import cash.z.ecc.android.sdk.ext.twig
|
||||
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
|
||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
|
||||
class TransactionCounterUtil {
|
||||
|
||||
private val network = ZcashNetwork.Mainnet
|
||||
private val context = InstrumentationRegistry.getInstrumentation().context
|
||||
private val service = LightWalletGrpcService(context, ZcashSdk.DEFAULT_LIGHTWALLETD_HOST, ZcashSdk.DEFAULT_LIGHTWALLETD_PORT)
|
||||
private val service = LightWalletGrpcService(context, network)
|
||||
|
||||
init {
|
||||
Twig.plant(TroubleshootingTwig())
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"network": "main",
|
||||
"height": 663150,
|
||||
"hash": "0000000002fd3be4c24c437bd22620901617125ec2a3a6c902ec9a6c06f734fc",
|
||||
"time": 1576821833,
|
||||
"tree": "01ec6278a1bed9e1b080fd60ef50eb17411645e3746ff129283712bc4757ecc833001001b4e1d4a26ac4a2810b57a14f4ffb69395f55dde5674ecd2462af96f9126e054701a36afb68534f640938bdffd80dfcb3f4d5e232488abbf67d049b33a761e7ed6901a16e35205fb7fe626a9b13fc43e1d2b98a9c241f99f93d5e93a735454073025401f5b9bcbf3d0e3c83f95ee79299e8aeadf30af07717bda15ffb7a3d00243b58570001fa6d4c2390e205f81d86b85ace0b48f3ce0afb78eeef3e14c70bcfd7c5f0191c0000011bc9521263584de20822f9483e7edb5af54150c4823c775b2efc6a1eded9625501a6030f8d4b588681eddb66cad63f09c5c7519db49500fc56ebd481ce5e903c22000163f4eec5a2fe00a5f45e71e1542ff01e937d2210c99f03addcce5314a5278b2d0163ab01f46a3bb6ea46f5a19d5bdd59eb3f81e19cfa6d10ab0fd5566c7a16992601fa6980c053d84f809b6abcf35690f03a11f87b28e3240828e32e3f57af41e54e01319312241b0031e3a255b0d708750b4cb3f3fe79e3503fe488cc8db1dd00753801754bb593ea42d231a7ddf367640f09bbf59dc00f2c1d2003cc340e0c016b5b13"
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
package cash.z.ecc.android.sdk.integration
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import cash.z.ecc.android.sdk.Initializer
|
||||
import cash.z.ecc.android.sdk.Synchronizer
|
||||
import cash.z.ecc.android.sdk.Synchronizer.Status.SYNCED
|
||||
import cash.z.ecc.android.sdk.db.entity.isSubmitSuccess
|
||||
import cash.z.ecc.android.sdk.ext.TroubleshootingTwig
|
||||
import cash.z.ecc.android.sdk.ext.Twig
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||
import cash.z.ecc.android.sdk.ext.onFirst
|
||||
import cash.z.ecc.android.sdk.ext.twig
|
||||
import cash.z.ecc.android.sdk.service.LightWalletGrpcService
|
||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||
import cash.z.ecc.android.sdk.tool.WalletBirthdayTool
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.AfterClass
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import java.util.concurrent.CountDownLatch
|
||||
|
||||
class IntegrationTest {
|
||||
|
||||
var stopWatch = CountDownLatch(1)
|
||||
|
||||
@Test
|
||||
fun testLatestBlockTest() {
|
||||
val service = LightWalletGrpcService(
|
||||
context,
|
||||
host,
|
||||
port
|
||||
)
|
||||
val height = service.getLatestBlockHeight()
|
||||
assertTrue(height > ZcashSdk.SAPLING_ACTIVATION_HEIGHT)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLoadBirthday() {
|
||||
val (height, hash, time, tree) = WalletBirthdayTool.loadNearest(context, ZcashSdk.SAPLING_ACTIVATION_HEIGHT + 1)
|
||||
assertEquals(ZcashSdk.SAPLING_ACTIVATION_HEIGHT, height)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getAddress() = runBlocking {
|
||||
assertEquals(address, synchronizer.getAddress())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testBalance() = runBlocking {
|
||||
var availableBalance: Long = 0L
|
||||
synchronizer.balances.onFirst {
|
||||
availableBalance = it.availableZatoshi
|
||||
}
|
||||
|
||||
synchronizer.status.filter { it == SYNCED }.onFirst {
|
||||
delay(100)
|
||||
}
|
||||
|
||||
assertTrue(
|
||||
"No funds available when we expected a balance greater than zero!",
|
||||
availableBalance > 0
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
fun testSpend() = runBlocking {
|
||||
var success = false
|
||||
synchronizer.balances.filter { it.availableZatoshi > 0 }.onEach {
|
||||
success = sendFunds()
|
||||
}.first()
|
||||
log("asserting $success")
|
||||
assertTrue(success)
|
||||
}
|
||||
|
||||
private suspend fun sendFunds(): Boolean {
|
||||
val spendingKey = DerivationTool.deriveSpendingKeys(seed)[0]
|
||||
log("sending to address")
|
||||
synchronizer.sendToAddress(
|
||||
spendingKey,
|
||||
ZcashSdk.MINERS_FEE_ZATOSHI,
|
||||
toAddress,
|
||||
"first mainnet tx from the SDK"
|
||||
).filter { it.isSubmitSuccess() }.onFirst {
|
||||
log("DONE SENDING!!!")
|
||||
}
|
||||
log("returning true from sendFunds")
|
||||
return true
|
||||
}
|
||||
|
||||
fun log(message: String) {
|
||||
twig("\n---\n[TESTLOG]: $message\n---\n")
|
||||
}
|
||||
|
||||
companion object {
|
||||
init { Twig.plant(TroubleshootingTwig()) }
|
||||
|
||||
const val host = "lightd-main.zecwallet.co"
|
||||
const val port = 443
|
||||
val seed = "cash.z.ecc.android.sdk.integration.IntegrationTest.seed.value.64bytes".toByteArray()
|
||||
val birthdayHeight = 843_000
|
||||
val address = "zs1m30y59wxut4zk9w24d6ujrdnfnl42hpy0ugvhgyhr8s0guszutqhdj05c7j472dndjstulph74m"
|
||||
val toAddress = "zs1vp7kvlqr4n9gpehztr76lcn6skkss9p8keqs3nv8avkdtjrcctrvmk9a7u494kluv756jeee5k0"
|
||||
|
||||
private val context = InstrumentationRegistry.getInstrumentation().context
|
||||
private val initializer = Initializer(context) { config ->
|
||||
config.setSeed(seed)
|
||||
config.server(host, port)
|
||||
config.setBirthdayHeight(birthdayHeight)
|
||||
}
|
||||
private val synchronizer: Synchronizer = Synchronizer(initializer)
|
||||
|
||||
@JvmStatic
|
||||
@BeforeClass
|
||||
fun startUp() {
|
||||
synchronizer.start()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@AfterClass
|
||||
fun tearDown() {
|
||||
synchronizer.stop()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"network": "main",
|
||||
"height": 663150,
|
||||
"hash": "0000000002fd3be4c24c437bd22620901617125ec2a3a6c902ec9a6c06f734fc",
|
||||
"time": 1576821833,
|
||||
"tree": "01ec6278a1bed9e1b080fd60ef50eb17411645e3746ff129283712bc4757ecc833001001b4e1d4a26ac4a2810b57a14f4ffb69395f55dde5674ecd2462af96f9126e054701a36afb68534f640938bdffd80dfcb3f4d5e232488abbf67d049b33a761e7ed6901a16e35205fb7fe626a9b13fc43e1d2b98a9c241f99f93d5e93a735454073025401f5b9bcbf3d0e3c83f95ee79299e8aeadf30af07717bda15ffb7a3d00243b58570001fa6d4c2390e205f81d86b85ace0b48f3ce0afb78eeef3e14c70bcfd7c5f0191c0000011bc9521263584de20822f9483e7edb5af54150c4823c775b2efc6a1eded9625501a6030f8d4b588681eddb66cad63f09c5c7519db49500fc56ebd481ce5e903c22000163f4eec5a2fe00a5f45e71e1542ff01e937d2210c99f03addcce5314a5278b2d0163ab01f46a3bb6ea46f5a19d5bdd59eb3f81e19cfa6d10ab0fd5566c7a16992601fa6980c053d84f809b6abcf35690f03a11f87b28e3240828e32e3f57af41e54e01319312241b0031e3a255b0d708750b4cb3f3fe79e3503fe488cc8db1dd00753801754bb593ea42d231a7ddf367640f09bbf59dc00f2c1d2003cc340e0c016b5b13"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"network": "main",
|
||||
"height": 1180000,
|
||||
"hash": "0000000000521c0d55ce1765092caff595acb5d546147b192fa9272051f55f42",
|
||||
"time": 1615778593,
|
||||
"tree": "0102a70ba9e31d6c24be0fc283577072d815d418da5e1b14cc81923f7bed308460016d9d5c674c15bdaec54c70d528e94be910994213683e3aac2fc94092fd8b4a5b1301dce7f293aee6c2769fe616dd47d46e79b51568c8bc08c67198b20d28eaf12c6f000001ff83e392690a332103433465b2034df2ab6cf35c164149a3951bf0d2bcf2a96601d019ed97502d718643c32851eb1acf6307861a3fe0ce3174697b0c2df4568568011d8eb058dd0a73a4314e04f12a6de50dd18879ee891db5a20c890e1c707f6f01000001cda4d5ff76022119fed8ffb94b8d3a26a0db37a1a886a0f31a57d1c0ce03f106014fb59c2d5dd4cc176d226c57b48d4dfc4d200088d5b69cce675f84e885ee5c1b017d5b561bf80be788ebf12e901e4c544cad95e24d0b21e6145e1718ec9dbfe91101678fbb171e5715c63bfc888d345e755c69c6dbfc2818f05b6e6ca32211ffd44400000001089a1f9d50a037cc66aba4400b1703bcbb66f5f2993fd0dd3bb726e35940916700000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"network": "main",
|
||||
"height": 1190000,
|
||||
"hash": "00000000019caeb64ab8caa12e1dcdd9a8f391b063ec252887c91526b7ac5e0c",
|
||||
"time": 1616531745,
|
||||
"tree": "017ae2fbedf5cad68ee80df0ae9caef9e0168914780bfd14eae016e2fb89068071001301c78a8f9bfddd9a1f0076048c48d1d58298ac6f4368472a39b0b240d540117c4301b58c9284084704437af784307ab0a334dc9c7aef588bf7d26491274d79c4471301b0af0fff110293b555f17d5ced0a598693ff4cde3e680d988c6ccf498846753e01bb9d0f21f621448c03ee49de4ef3bf0faa4844544f9668197ef5921164d2401601a15d695922c5441e80aa770861f91a97dd460561515d32c9d06bd3c6f98ce26f000000014a772e6ce520bcedf07793ded6148fd3415ecbdd89c3efe183b6048f1fb4791c0001e281c5ec71bc1a301ad0d285f6f1aa2552907645b02f9d43160f5354c2be7c63012b4d8d83df48c8b5c35752268eb71a428aa05103809a887fb36519dedbc8de27017b610946256293c523b36cf95ec60f2c346d866d98d1276bbaba22e46815516d000001089a1f9d50a037cc66aba4400b1703bcbb66f5f2993fd0dd3bb726e35940916700000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"network": "main",
|
||||
"height": 1195000,
|
||||
"hash": "000000000092911166fef6c93bf73b74028232eb4c35e4ec5311879b68e5591d",
|
||||
"time": 1616908352,
|
||||
"tree": "01c5abce4daea8caa6672e27d46f092aa950300fa97a80c16c194fe1ff72b05e150013000001d5bbb87f5debb41e36d1a65756a3ba27550a82c84917259ab0a9ee690ec58c1c0000000198cb8ff247cf5cbf818671cba86eccf6a55a9661377f10a0988b2b365da53159015d6b83b48a32db003767a096733b47204700f6c74f079440de990ecf1fc3651c01b96b3b201de78a38a9f88aa45ceeebe5b153843a0cee1856a6334248b287450d01f2d01bb461547e10e4da64a1751ffe65e5cc5cc3e647f0edd6b174b5c7b4156c00000001df26abb60966dedb257d90ef08aa7232474229e08e62ba390336a07c4775a7260001089a1f9d50a037cc66aba4400b1703bcbb66f5f2993fd0dd3bb726e35940916700000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue