diff --git a/Cargo.lock b/Cargo.lock index 43eceef3..750cc7ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "addr2line" version = "0.15.2" @@ -16,33 +18,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] -name = "aes" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561" -dependencies = [ - "aes-soft", - "aesni", - "cipher", -] - -[[package]] -name = "aes-soft" -version = "0.6.4" +name = "aead" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" dependencies = [ - "cipher", - "opaque-debug 0.3.0", + "generic-array 0.14.4", ] [[package]] -name = "aesni" -version = "0.10.0" +name = "aes" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" dependencies = [ + "cfg-if 1.0.0", "cipher", + "cpufeatures 0.2.2", "opaque-debug 0.3.0", ] @@ -117,9 +109,9 @@ checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" [[package]] name = "arrayvec" -version = "0.5.2" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] name = "async-stream" @@ -209,6 +201,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "base64ct" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" + [[package]] name = "bech32" version = "0.8.1" @@ -217,58 +215,62 @@ checksum = "cf9ff0bbfd639f15c74af777d81383cf53efb7c93613f6cab67c6c11e05bbf8b" [[package]] name = "bellman" -version = "0.8.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7089887635778eabf0038a166f586eee5413fb85c8fa6c9a754914f0f644f49f" +checksum = "0d96d7f4f3dc9a699bdef1d19648f6f20ef966b51892d224582a4475be669cb5" dependencies = [ - "bitvec 0.18.5", + "bitvec", "blake2s_simd", "byteorder", - "crossbeam", + "crossbeam-channel", "ff", - "futures 0.1.31", - "futures-cpupool", "group", + "lazy_static", + "log", "num_cpus", "pairing", - "rand_core 0.5.1", - "subtle 2.4.0", + "rand_core 0.6.2", + "rayon", + "subtle 2.4.1", ] [[package]] -name = "bitflags" -version = "1.2.1" +name = "bip0039" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "d0830ae4cc96b0617cc912970c2b17e89456fecbf55e8eed53a956f37ab50c41" +dependencies = [ + "hmac 0.11.0", + "pbkdf2 0.9.0", + "rand 0.8.5", + "sha2 0.9.5", + "unicode-normalization", + "zeroize", +] [[package]] -name = "bitvec" -version = "0.18.5" +name = "bitflags" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98fcd36dda4e17b7d7abc64cb549bf0201f4ab71e00700c798ca7e62ed3761fa" -dependencies = [ - "funty", - "radium 0.3.0", - "wyz", -] +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bitvec" -version = "0.19.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55f93d0ef3363c364d5976646a38f04cf67cfe1d4c8d160cdea02cab2c116b33" +checksum = "1489fcb93a5bb47da0462ca93ad252ad6af2145cce58d10d46a83931ba9f016b" dependencies = [ "funty", - "radium 0.5.3", + "radium", "tap", "wyz", ] [[package]] name = "blake2b_simd" -version = "0.5.11" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +checksum = "72936ee4afc7f8f736d1c38383b56480b5497b4617b4a77bdbf1d2ababc76127" dependencies = [ "arrayref", "arrayvec", @@ -277,9 +279,9 @@ dependencies = [ [[package]] name = "blake2s_simd" -version = "0.5.11" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e461a7034e85b211a4acb57ee2e6730b32912b06c08cc242243c39fc21ae6a2" +checksum = "db539cc2b5f6003621f1cd9ef92d7ded8ea5232c7de0f9faa2de251cd98730d4" dependencies = [ "arrayref", "arrayvec", @@ -307,11 +309,20 @@ dependencies = [ "generic-array 0.14.4", ] +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array 0.14.4", +] + [[package]] name = "block-modes" -version = "0.7.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a0e8073e8baa88212fb5823574c02ebccb395136ba9a164ab89379ec6072f0" +checksum = "2cb03d1bed155d89dce0f845b7899b18a9a163e148fd004e1c28421a783e2d8e" dependencies = [ "block-padding 0.2.1", "cipher", @@ -334,16 +345,15 @@ checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" [[package]] name = "bls12_381" -version = "0.3.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4caf0101205582491f772d60a6fcb6bcec19963e68209cb631851eeadb01421f" +checksum = "62250ece575fa9b22068b3a8d59586f01d426dd7785522efd97632959e71c986" dependencies = [ - "bitvec 0.18.5", "ff", "group", "pairing", - "rand_core 0.5.1", - "subtle 2.4.0", + "rand_core 0.6.2", + "subtle 2.4.1", ] [[package]] @@ -407,6 +417,31 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chacha20" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures 0.2.2", + "zeroize", +] + +[[package]] +name = "chacha20poly1305" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b84ed6d1d5f7aa9bdde921a5090e0ca4d934d250ea3b402a5fab3a994e28a2a" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + [[package]] name = "chrono" version = "0.4.19" @@ -422,9 +457,9 @@ dependencies = [ [[package]] name = "cipher" -version = "0.2.5" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" dependencies = [ "generic-array 0.14.4", ] @@ -491,84 +526,82 @@ dependencies = [ ] [[package]] -name = "crc32fast" -version = "1.2.1" +name = "cpufeatures" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" dependencies = [ - "cfg-if 1.0.0", + "libc", ] [[package]] -name = "crossbeam" -version = "0.7.3" +name = "crc32fast" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" +checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" dependencies = [ - "cfg-if 0.1.10", - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", + "cfg-if 1.0.0", ] [[package]] name = "crossbeam-channel" -version = "0.4.4" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" +checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" dependencies = [ + "cfg-if 1.0.0", "crossbeam-utils", - "maybe-uninit", ] [[package]] name = "crossbeam-deque" -version = "0.7.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" dependencies = [ + "cfg-if 1.0.0", "crossbeam-epoch", "crossbeam-utils", - "maybe-uninit", ] [[package]] name = "crossbeam-epoch" -version = "0.8.2" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" +checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" dependencies = [ "autocfg 1.0.1", - "cfg-if 0.1.10", + "cfg-if 1.0.0", "crossbeam-utils", "lazy_static", - "maybe-uninit", "memoffset", "scopeguard 1.1.0", ] [[package]] -name = "crossbeam-queue" -version = "0.2.3" +name = "crossbeam-utils" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" dependencies = [ - "cfg-if 0.1.10", - "crossbeam-utils", - "maybe-uninit", + "cfg-if 1.0.0", + "lazy_static", ] [[package]] -name = "crossbeam-utils" -version = "0.7.2" +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" dependencies = [ - "autocfg 1.0.1", - "cfg-if 0.1.10", - "lazy_static", + "generic-array 0.14.4", + "typenum", ] [[package]] @@ -588,22 +621,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ "generic-array 0.14.4", - "subtle 2.4.0", + "subtle 2.4.1", ] [[package]] -name = "crypto_api" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f855e87e75a4799e18b8529178adcde6fd4f97c1449ff4821e747ff728bb102" - -[[package]] -name = "crypto_api_chachapoly" -version = "0.4.3" +name = "crypto-mac" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d930b6a026ce9d358a17f9c9046c55d90b14bb847f36b6ebb6b19365d4feffb8" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ - "crypto_api", + "generic-array 0.14.4", + "subtle 2.4.1", ] [[package]] @@ -635,11 +663,21 @@ dependencies = [ "generic-array 0.14.4", ] +[[package]] +name = "digest" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +dependencies = [ + "block-buffer 0.10.2", + "crypto-common", +] + [[package]] name = "directories" -version = "3.0.2" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e69600ff1703123957937708eb27f7a564e48885c537782722ed0ba3189ce1d7" +checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" dependencies = [ "dirs-sys", ] @@ -695,7 +733,7 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "equihash" version = "0.1.0" -source = "git+https://github.com/adityapk00/librustzcash?rev=b70edf39e26e4c687b5087daf2ffd40f99fffd67#b70edf39e26e4c687b5087daf2ffd40f99fffd67" +source = "git+https://github.com/adityapk00/librustzcash?rev=7183acd2fe12ebf201cae5b871166e356273c481#7183acd2fe12ebf201cae5b871166e356273c481" dependencies = [ "blake2b_simd", "byteorder", @@ -731,13 +769,13 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "ff" -version = "0.8.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01646e077d4ebda82b73f1bca002ea1e91561a77df2431a9e79729bcc31950ef" +checksum = "df689201f395c6b90dfe87127685f8dbfc083a5e779e613575d8bd7314300c3e" dependencies = [ - "bitvec 0.18.5", - "rand_core 0.5.1", - "subtle 2.4.0", + "bitvec", + "rand_core 0.6.2", + "subtle 2.4.1", ] [[package]] @@ -766,12 +804,13 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fpe" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a25080721bbcd2cd4d765b7d607ea350425fa087ce53cd3e31afcacdab850352" +checksum = "cd910db5f9ca4dc3116f8c46367825807aa2b942f72565f16b4be0b208a00a9e" dependencies = [ - "aes", "block-modes", + "cipher", + "libm", "num-bigint", "num-integer", "num-traits", @@ -785,15 +824,9 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "funty" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" - -[[package]] -name = "futures" -version = "0.1.31" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" @@ -826,16 +859,6 @@ version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1" -[[package]] -name = "futures-cpupool" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -dependencies = [ - "futures 0.1.31", - "num_cpus", -] - [[package]] name = "futures-executor" version = "0.3.15" @@ -948,14 +971,14 @@ checksum = "0e4075386626662786ddb0ec9081e7c7eeb1ba31951f447ca780ef9f5d568189" [[package]] name = "group" -version = "0.8.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc11f9f5fbf1943b48ae7c2bf6846e7d827a512d1be4f23af708f5ca5d01dde1" +checksum = "7391856def869c1c81063a03457c676fbcd419709c3dfb33d8d319de484b154d" dependencies = [ "byteorder", "ff", - "rand_core 0.5.1", - "subtle 2.4.0", + "rand_core 0.6.2", + "subtle 2.4.1", ] [[package]] @@ -977,6 +1000,38 @@ dependencies = [ "tracing", ] +[[package]] +name = "halo2_gadgets" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13f3914f58cc4af5e4fe83d48b02d582be18976bc7e96c3151aa2bf1c98e9f60" +dependencies = [ + "arrayvec", + "bitvec", + "ff", + "group", + "halo2_proofs", + "lazy_static", + "pasta_curves", + "rand 0.8.5", + "subtle 2.4.1", + "uint", +] + +[[package]] +name = "halo2_proofs" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e925780549adee8364c7f2b685c753f6f3df23bde520c67416e93bf615933760" +dependencies = [ + "blake2b_simd", + "ff", + "group", + "pasta_curves", + "rand_core 0.6.2", + "rayon", +] + [[package]] name = "hashbrown" version = "0.1.8" @@ -993,6 +1048,18 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +[[package]] +name = "hdwallet" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cd89bf343be18dbe1e505100e48168bbd084760e842a8fed0317d2361470193" +dependencies = [ + "lazy_static", + "rand_core 0.6.2", + "ring", + "secp256k1", +] + [[package]] name = "heck" version = "0.3.3" @@ -1043,6 +1110,16 @@ dependencies = [ "digest 0.9.0", ] +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac 0.11.1", + "digest 0.9.0", +] + [[package]] name = "http" version = "0.2.4" @@ -1116,6 +1193,15 @@ dependencies = [ "want", ] +[[package]] +name = "incrementalmerkletree" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "068c5bdd31006d55536655cf1eb0d22d84d28de7c725b419480fd5d005c83216" +dependencies = [ + "serde", +] + [[package]] name = "indexmap" version = "1.6.2" @@ -1176,16 +1262,16 @@ checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" [[package]] name = "jubjub" -version = "0.5.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "620638af3b80d23f4df0cae21e3cc9809ac8826767f345066f010bcea66a2c55" +checksum = "a575df5f985fe1cd5b2b05664ff6accfc46559032b954529fd225a2168d27b0f" dependencies = [ - "bitvec 0.18.5", + "bitvec", "bls12_381", "ff", "group", - "rand_core 0.5.1", - "subtle 2.4.0", + "rand_core 0.6.2", + "subtle 2.4.1", ] [[package]] @@ -1194,25 +1280,18 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lexical-core" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" -dependencies = [ - "arrayvec", - "bitflags", - "cfg-if 1.0.0", - "ryu", - "static_assertions", -] - [[package]] name = "libc" version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" +[[package]] +name = "libm" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db" + [[package]] name = "libsodium-sys" version = "0.2.6" @@ -1330,13 +1409,28 @@ checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" [[package]] name = "memoffset" -version = "0.5.6" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg 1.0.1", ] +[[package]] +name = "memuse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f69d25cd7528769ad3d897e99eb942774bff8b23165012af490351a44c5b583b" +dependencies = [ + "nonempty", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.4.4" @@ -1390,17 +1484,20 @@ dependencies = [ [[package]] name = "nom" -version = "6.1.2" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" dependencies = [ - "bitvec 0.19.6", - "funty", - "lexical-core", "memchr", - "version_check", + "minimal-lexical", ] +[[package]] +name = "nonempty" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" + [[package]] name = "ntapi" version = "0.3.6" @@ -1412,9 +1509,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.3.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d0a3d5e207573f948a9e5376662aa743a2ea13f7c50a554d7af443a73fbfeba" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ "autocfg 1.0.1", "num-integer", @@ -1495,6 +1592,33 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" +[[package]] +name = "orchard" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f918076e191a68d55c5517a16e075ecfe58fc63ed112408263f3d6194597bfcf" +dependencies = [ + "aes", + "bitvec", + "blake2b_simd", + "ff", + "fpe", + "group", + "halo2_gadgets", + "halo2_proofs", + "hex 0.4.3", + "incrementalmerkletree", + "lazy_static", + "memuse", + "nonempty", + "pasta_curves", + "rand 0.8.5", + "reddsa", + "serde", + "subtle 2.4.1", + "zcash_note_encryption 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ordered-float" version = "1.1.1" @@ -1515,11 +1639,10 @@ dependencies = [ [[package]] name = "pairing" -version = "0.18.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f702cdbee9e0a6272452c20dec82465bc821116598b4eeb63e9a71a69dbf7fd" +checksum = "135590d8bdba2b31346f9cd1fb2a912329f5135e832a4f422942eb6ead8b6b3b" dependencies = [ - "ff", "group", ] @@ -1571,6 +1694,32 @@ dependencies = [ "winapi", ] +[[package]] +name = "password-hash" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8" +dependencies = [ + "base64ct", + "rand_core 0.6.2", + "subtle 2.4.1", +] + +[[package]] +name = "pasta_curves" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "369d7785168ad7ff0cbe467d968ca3e19a927d8536b11ef9c21b4e454b15ba42" +dependencies = [ + "blake2b_simd", + "ff", + "group", + "lazy_static", + "rand 0.8.5", + "static_assertions", + "subtle 2.4.1", +] + [[package]] name = "pbkdf2" version = "0.3.0" @@ -1590,6 +1739,16 @@ dependencies = [ "crypto-mac 0.8.0", ] +[[package]] +name = "pbkdf2" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" +dependencies = [ + "crypto-mac 0.11.1", + "password-hash", +] + [[package]] name = "percent-encoding" version = "2.1.0" @@ -1644,13 +1803,24 @@ version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +[[package]] +name = "poly1305" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" +dependencies = [ + "cpufeatures 0.2.2", + "opaque-debug 0.3.0", + "universal-hash", +] + [[package]] name = "portpicker" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b497d05c16fe00939445c00a4fe2fa4f3d3dfc9c0401a3ab5c577afda2debb9" +checksum = "be97d76faf1bfab666e1375477b23fde79eccf0276e9b63b92a39d676a889ba9" dependencies = [ - "rand 0.6.5", + "rand 0.8.5", ] [[package]] @@ -1733,24 +1903,24 @@ dependencies = [ [[package]] name = "protobuf" -version = "2.23.0" +version = "2.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45604fc7a88158e7d514d8e22e14ac746081e7a70d7690074dd0029ee37458d6" +checksum = "cf7e6d18738ecd0902d30d1ad232c9125985a3422929b16c65517b38adc14f96" [[package]] name = "protobuf-codegen" -version = "2.23.0" +version = "2.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb87f342b585958c1c086313dbc468dcac3edf5e90362111c26d7a58127ac095" +checksum = "aec1632b7c8f2e620343439a7dfd1f3c47b18906c4be58982079911482b5d707" dependencies = [ "protobuf", ] [[package]] name = "protobuf-codegen-pure" -version = "2.23.0" +version = "2.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca6e0e2f898f7856a6328650abc9b2df71b7c1a5f39be0800d19051ad0214b2" +checksum = "9f8122fdb18e55190c796b088a16bdb70cd7acdcd48f7a8b796b58c62e532cc6" dependencies = [ "protobuf", "protobuf-codegen", @@ -1773,15 +1943,9 @@ dependencies = [ [[package]] name = "radium" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" - -[[package]] -name = "radium" -version = "0.5.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" @@ -1830,14 +1994,13 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.0", "rand_core 0.6.2", - "rand_hc 0.3.0", ] [[package]] @@ -1921,15 +2084,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rand_hc" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" -dependencies = [ - "rand_core 0.6.2", -] - [[package]] name = "rand_isaac" version = "0.1.1" @@ -1983,6 +2137,30 @@ dependencies = [ "rand_core 0.3.1", ] +[[package]] +name = "rayon" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" +dependencies = [ + "autocfg 1.0.1", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + [[package]] name = "rdrand" version = "0.4.0" @@ -1992,6 +2170,23 @@ dependencies = [ "rand_core 0.3.1", ] +[[package]] +name = "reddsa" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cc8038c8b7e481bdf688d0585d4897ed0e9e0cee10aa365dde51238c20e4182" +dependencies = [ + "blake2b_simd", + "byteorder", + "group", + "jubjub", + "pasta_curves", + "rand_core 0.6.2", + "serde", + "thiserror", + "zeroize", +] + [[package]] name = "redox_syscall" version = "0.1.57" @@ -2058,6 +2253,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "ripemd" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1facec54cb5e0dc08553501fa740091086d0259ad0067e0d4103448e4cb22ed3" +dependencies = [ + "digest 0.10.3", +] + [[package]] name = "ripemd160" version = "0.9.1" @@ -2215,18 +2419,18 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.20.2" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee5070fdc6f26ca5be6dcfc3d07c76fdb974a63a8b246b459854274145f5a258" +checksum = "9c42e6f1735c5f00f51e43e28d6634141f2bcad10931b2609ddd74a86d751260" dependencies = [ "secp256k1-sys", ] [[package]] name = "secp256k1-sys" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e4b6455ee49f5901c8985b88f98fb0a0e1d90a6661f5a03f4888bd987dad29" +checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" dependencies = [ "cc", ] @@ -2367,7 +2571,7 @@ checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", - "cpufeatures", + "cpufeatures 0.1.4", "digest 0.9.0", "opaque-debug 0.3.0", ] @@ -2517,9 +2721,9 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "subtle" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" @@ -2568,7 +2772,7 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ "cfg-if 1.0.0", "libc", - "rand 0.8.3", + "rand 0.8.5", "redox_syscall 0.2.8", "remove_dir_all", "winapi", @@ -2830,7 +3034,7 @@ dependencies = [ "futures-util", "indexmap", "pin-project", - "rand 0.8.3", + "rand 0.8.5", "slab", "tokio", "tokio-stream", @@ -2918,9 +3122,21 @@ dependencies = [ [[package]] name = "typenum" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "uint" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" +dependencies = [ + "byteorder", + "crunchy", + "hex 0.4.3", + "static_assertions", +] [[package]] name = "unicode-normalization" @@ -2949,6 +3165,16 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +[[package]] +name = "universal-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array 0.14.4", + "subtle 2.4.1", +] + [[package]] name = "unsafe-any" version = "0.4.2" @@ -3147,9 +3373,12 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "wyz" -version = "0.2.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" +checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e" +dependencies = [ + "tap", +] [[package]] name = "yaml-rust" @@ -3163,7 +3392,7 @@ dependencies = [ [[package]] name = "zcash_client_backend" version = "0.5.0" -source = "git+https://github.com/adityapk00/librustzcash?rev=b70edf39e26e4c687b5087daf2ffd40f99fffd67#b70edf39e26e4c687b5087daf2ffd40f99fffd67" +source = "git+https://github.com/adityapk00/librustzcash?rev=7183acd2fe12ebf201cae5b871166e356273c481#7183acd2fe12ebf201cae5b871166e356273c481" dependencies = [ "base64", "bech32", @@ -3173,49 +3402,90 @@ dependencies = [ "group", "hex 0.4.3", "jubjub", + "log", "nom", "percent-encoding", "protobuf", "protobuf-codegen-pure", - "rand_core 0.5.1", - "subtle 2.4.0", + "rand_core 0.6.2", + "subtle 2.4.1", "time 0.2.27", + "zcash_note_encryption 0.1.0 (git+https://github.com/adityapk00/librustzcash?rev=7183acd2fe12ebf201cae5b871166e356273c481)", "zcash_primitives", ] +[[package]] +name = "zcash_encoding" +version = "0.1.0" +source = "git+https://github.com/adityapk00/librustzcash?rev=7183acd2fe12ebf201cae5b871166e356273c481#7183acd2fe12ebf201cae5b871166e356273c481" +dependencies = [ + "byteorder", + "nonempty", +] + +[[package]] +name = "zcash_note_encryption" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33f84ae538f05a8ac74c82527f06b77045ed9553a0871d9db036166a4c344e3a" +dependencies = [ + "chacha20", + "chacha20poly1305", + "rand_core 0.6.2", + "subtle 2.4.1", +] + +[[package]] +name = "zcash_note_encryption" +version = "0.1.0" +source = "git+https://github.com/adityapk00/librustzcash?rev=7183acd2fe12ebf201cae5b871166e356273c481#7183acd2fe12ebf201cae5b871166e356273c481" +dependencies = [ + "chacha20", + "chacha20poly1305", + "rand_core 0.6.2", + "subtle 2.4.1", +] + [[package]] name = "zcash_primitives" -version = "0.5.0" -source = "git+https://github.com/adityapk00/librustzcash?rev=b70edf39e26e4c687b5087daf2ffd40f99fffd67#b70edf39e26e4c687b5087daf2ffd40f99fffd67" +version = "0.6.0" +source = "git+https://github.com/adityapk00/librustzcash?rev=7183acd2fe12ebf201cae5b871166e356273c481#7183acd2fe12ebf201cae5b871166e356273c481" dependencies = [ "aes", - "bitvec 0.18.5", + "bip0039", + "bitvec", "blake2b_simd", "blake2s_simd", "bls12_381", + "bs58", "byteorder", - "crypto_api_chachapoly", + "chacha20poly1305", "equihash", "ff", "fpe", - "funty", "group", + "hdwallet", "hex 0.4.3", + "incrementalmerkletree", "jubjub", "lazy_static", - "log", - "rand 0.7.3", - "rand_core 0.5.1", - "ripemd160", + "memuse", + "nonempty", + "orchard", + "rand 0.8.5", + "rand_core 0.6.2", + "ripemd", "secp256k1", "sha2 0.9.5", - "subtle 2.4.0", + "subtle 2.4.1", + "zcash_encoding", + "zcash_note_encryption 0.1.0 (git+https://github.com/adityapk00/librustzcash?rev=7183acd2fe12ebf201cae5b871166e356273c481)", ] [[package]] name = "zcash_proofs" -version = "0.5.0" -source = "git+https://github.com/adityapk00/librustzcash?rev=b70edf39e26e4c687b5087daf2ffd40f99fffd67#b70edf39e26e4c687b5087daf2ffd40f99fffd67" +version = "0.6.0" +source = "git+https://github.com/adityapk00/librustzcash?rev=7183acd2fe12ebf201cae5b871166e356273c481#7183acd2fe12ebf201cae5b871166e356273c481" dependencies = [ "bellman", "blake2b_simd", @@ -3226,13 +3496,13 @@ dependencies = [ "group", "jubjub", "lazy_static", - "rand_core 0.5.1", + "rand_core 0.6.2", "zcash_primitives", ] [[package]] name = "zecwallet-cli" -version = "1.7.12" +version = "1.7.13" dependencies = [ "byteorder", "clap", @@ -3258,7 +3528,7 @@ dependencies = [ "bytes 0.4.12", "dirs 3.0.2", "ff", - "futures 0.3.15", + "futures", "group", "hex 0.3.2", "http", @@ -3270,7 +3540,7 @@ dependencies = [ "pairing", "portpicker", "prost", - "rand 0.7.3", + "rand 0.8.5", "ring", "ripemd160", "rust-embed", @@ -3286,6 +3556,8 @@ dependencies = [ "tonic-build", "webpki-roots", "zcash_client_backend", + "zcash_encoding", + "zcash_note_encryption 0.1.0 (git+https://github.com/adityapk00/librustzcash?rev=7183acd2fe12ebf201cae5b871166e356273c481)", "zcash_primitives", "zcash_proofs", ] diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 9cd806ff..8656fac6 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zecwallet-cli" -version = "1.7.12" +version = "1.7.13" edition = "2018" [dependencies] diff --git a/cli/src/version.rs b/cli/src/version.rs index 3cdb4516..56498f54 100644 --- a/cli/src/version.rs +++ b/cli/src/version.rs @@ -1 +1 @@ -pub const VERSION: &str = "1.7.12"; +pub const VERSION: &str = "1.7.13"; diff --git a/lib/Cargo.toml b/lib/Cargo.toml index aff18d2c..ac29c13a 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -16,7 +16,7 @@ arr_macro = "0.1.3" base64 = "0.13.0" bytes = "0.4" log4rs = "1.0.0" -rand = "0.7.3" +rand = "0.8.5" http = "0.2.4" tonic = {version = "0.4.3", features = ["tls", "tls-roots"]} prost = "0.7.0" @@ -32,7 +32,7 @@ json = "0.12.4" webpki-roots = "0.21.0" lazy_static = "1.4.0" -secp256k1 = "=0.20.2" +secp256k1 = "=0.21.3" ripemd160 = "0.9.1" sha2 = "0.9.5" base58 = "0.1.0" @@ -40,20 +40,23 @@ tiny-bip39 = "0.8.0" sodiumoxide = "0.2.5" byteorder = "1" -pairing = "0.18.0" -ff = "0.8" -jubjub = "0.5.1" -bls12_381 = "0.3.1" -group = "0.8" +pairing = "0.22" +ff = "0.12" +jubjub = "0.9.0" +bls12_381 = "0.7" +group = "0.12" rust-embed = { version = "5.1.0", features = ["debug-embed"] } -zcash_primitives = { git = "https://github.com/adityapk00/librustzcash", rev = "b70edf39e26e4c687b5087daf2ffd40f99fffd67", features = ["transparent-inputs"] } -zcash_client_backend = { git = "https://github.com/adityapk00/librustzcash", rev = "b70edf39e26e4c687b5087daf2ffd40f99fffd67"} -zcash_proofs = { git = "https://github.com/adityapk00/librustzcash", rev = "b70edf39e26e4c687b5087daf2ffd40f99fffd67", features = ["multicore"]} +zcash_primitives = { git = "https://github.com/adityapk00/librustzcash", rev = "7183acd2fe12ebf201cae5b871166e356273c481", features = ["transparent-inputs"] } +# zcash_primitives = { path = "../../librustzcash/zcash_primitives", features = ["transparent-inputs"] } +zcash_client_backend = { git = "https://github.com/adityapk00/librustzcash", rev = "7183acd2fe12ebf201cae5b871166e356273c481"} +zcash_proofs = { git = "https://github.com/adityapk00/librustzcash", rev = "7183acd2fe12ebf201cae5b871166e356273c481", features = ["multicore"]} +zcash_encoding = { git = "https://github.com/adityapk00/librustzcash", rev = "7183acd2fe12ebf201cae5b871166e356273c481"} +zcash_note_encryption = { git = "https://github.com/adityapk00/librustzcash", rev = "7183acd2fe12ebf201cae5b871166e356273c481", features = ["pre-zip-212"]} [dev-dependencies] -portpicker = "0.1.0" +portpicker = "0.1.1" tempdir = "0.3.7" [build-dependencies] diff --git a/lib/src/blaze/block_witness_data.rs b/lib/src/blaze/block_witness_data.rs index 1252c78c..0fcd997d 100644 --- a/lib/src/blaze/block_witness_data.rs +++ b/lib/src/blaze/block_witness_data.rs @@ -25,8 +25,7 @@ use tokio::{ use zcash_primitives::{ consensus::BlockHeight, merkle_tree::{CommitmentTree, IncrementalWitness}, - primitives::Nullifier, - sapling::Node, + sapling::{Node, Nullifier}, transaction::TxId, }; diff --git a/lib/src/blaze/fetch_full_tx.rs b/lib/src/blaze/fetch_full_tx.rs index 5d42822b..57225bf5 100644 --- a/lib/src/blaze/fetch_full_tx.rs +++ b/lib/src/blaze/fetch_full_tx.rs @@ -31,7 +31,7 @@ use zcash_primitives::{ consensus::BlockHeight, legacy::TransparentAddress, memo::Memo, - note_encryption::{try_sapling_note_decryption, try_sapling_output_recovery}, + sapling::note_encryption::{try_sapling_note_decryption, try_sapling_output_recovery}, transaction::{Transaction, TxId}, }; @@ -163,27 +163,29 @@ impl FetchFullTxns { let taddrs_set: HashSet<_> = taddrs.iter().map(|t| t.clone()).collect(); // Step 1: Scan all transparent outputs to see if we recieved any money - for (n, vout) in tx.vout.iter().enumerate() { - match vout.script_pubkey.address() { - Some(TransparentAddress::PublicKey(hash)) => { - let output_taddr = hash.to_base58check(&config.base58_pubkey_address(), &[]); - if taddrs_set.contains(&output_taddr) { - // This is our address. Add this as an output to the txid - wallet_txns.write().await.add_new_taddr_output( - tx.txid(), - output_taddr.clone(), - height.into(), - unconfirmed, - block_time as u64, - &vout, - n as u32, - ); - - // Ensure that we add any new HD addresses - keys.write().await.ensure_hd_taddresses(&output_taddr); + if let Some(t_bundle) = tx.transparent_bundle() { + for (n, vout) in t_bundle.vout.iter().enumerate() { + match vout.script_pubkey.address() { + Some(TransparentAddress::PublicKey(hash)) => { + let output_taddr = hash.to_base58check(&config.base58_pubkey_address(), &[]); + if taddrs_set.contains(&output_taddr) { + // This is our address. Add this as an output to the txid + wallet_txns.write().await.add_new_taddr_output( + tx.txid(), + output_taddr.clone(), + height.into(), + unconfirmed, + block_time as u64, + &vout, + n as u32, + ); + + // Ensure that we add any new HD addresses + keys.write().await.ensure_hd_taddresses(&output_taddr); + } } + _ => {} } - _ => {} } } @@ -198,21 +200,23 @@ impl FetchFullTxns { { let current = &wallet_txns.read().await.current; - for vin in tx.vin.iter() { - // Find the prev txid that was spent - let prev_txid = TxId { 0: *vin.prevout.hash() }; - let prev_n = vin.prevout.n() as u64; - - if let Some(wtx) = current.get(&prev_txid) { - // One of the tx outputs is a match - if let Some(spent_utxo) = wtx - .utxos - .iter() - .find(|u| u.txid == prev_txid && u.output_index == prev_n) - { - info!("Spent: utxo from {} was spent in {}", prev_txid, tx.txid()); - total_transparent_value_spent += spent_utxo.value; - spent_utxos.push((prev_txid, prev_n as u32, tx.txid(), height)); + if let Some(t_bundle) = tx.transparent_bundle() { + for vin in t_bundle.vin.iter() { + // Find the prev txid that was spent + let prev_txid = TxId::from_bytes(*vin.prevout.hash()); + let prev_n = vin.prevout.n() as u64; + + if let Some(wtx) = current.get(&prev_txid) { + // One of the tx outputs is a match + if let Some(spent_utxo) = wtx + .utxos + .iter() + .find(|u| u.txid == prev_txid && u.output_index == prev_n) + { + info!("Spent: utxo from {} was spent in {}", prev_txid, tx.txid()); + total_transparent_value_spent += spent_utxo.value; + spent_utxos.push((prev_txid, prev_n as u32, tx.txid(), height)); + } } } } @@ -246,17 +250,19 @@ impl FetchFullTxns { // because for txns in the block, we will check the nullifiers from the blockdata if unconfirmed { let unspent_nullifiers = wallet_txns.read().await.get_unspent_nullifiers(); - for s in tx.shielded_spends.iter() { - if let Some((nf, value, txid)) = unspent_nullifiers.iter().find(|(nf, _, _)| *nf == s.nullifier) { - wallet_txns.write().await.add_new_spent( - tx.txid(), - height, - unconfirmed, - block_time, - *nf, - *value, - *txid, - ); + if let Some(s_bundle) = tx.sapling_bundle() { + for s in s_bundle.shielded_spends.iter() { + if let Some((nf, value, txid)) = unspent_nullifiers.iter().find(|(nf, _, _)| *nf == s.nullifier) { + wallet_txns.write().await.add_new_spent( + tx.txid(), + height, + unconfirmed, + block_time, + *nf, + *value, + *txid, + ); + } } } } @@ -281,88 +287,76 @@ impl FetchFullTxns { // a second time by the Full Tx Fetcher let mut outgoing_metadatas = vec![]; - for output in tx.shielded_outputs.iter() { - let cmu = output.cmu; - let ct = output.enc_ciphertext; - - // Search all of our keys - for (i, ivk) in ivks.iter().enumerate() { - let epk_prime = output.ephemeral_key; - - let (note, to, memo_bytes) = - match try_sapling_note_decryption(&config.get_params(), height, &ivk, &epk_prime, &cmu, &ct) { - Some(ret) => ret, - None => continue, - }; + if let Some(s_bundle) = tx.sapling_bundle() { + for output in s_bundle.shielded_outputs.iter() { + // Search all of our keys + for (i, ivk) in ivks.iter().enumerate() { + let (note, to, memo_bytes) = + match try_sapling_note_decryption(&config.get_params(), height, &ivk, output) { + Some(ret) => ret, + None => continue, + }; + + // info!("A sapling note was received into the wallet in {}", tx.txid()); + if unconfirmed { + wallet_txns.write().await.add_pending_note( + tx.txid(), + height, + block_time as u64, + note.clone(), + to, + &extfvks.get(i).unwrap(), + ); + } - // info!("A sapling note was received into the wallet in {}", tx.txid()); - if unconfirmed { - wallet_txns.write().await.add_pending_note( - tx.txid(), - height, - block_time as u64, - note.clone(), - to, - &extfvks.get(i).unwrap(), - ); + let memo = memo_bytes.clone().try_into().unwrap_or(Memo::Future(memo_bytes)); + wallet_txns.write().await.add_memo_to_note(&tx.txid(), note, memo); } - let memo = memo_bytes.clone().try_into().unwrap_or(Memo::Future(memo_bytes)); - wallet_txns.write().await.add_memo_to_note(&tx.txid(), note, memo); - } - - // Also scan the output to see if it can be decoded with our OutgoingViewKey - // If it can, then we sent this transaction, so we should be able to get - // the memo and value for our records - - // Search all ovks that we have - let omds = ovks - .iter() - .filter_map(|ovk| { - match try_sapling_output_recovery( - &config.get_params(), - height, - &ovk, - &output.cv, - &output.cmu, - &output.ephemeral_key, - &output.enc_ciphertext, - &output.out_ciphertext, - ) { - Some((note, payment_address, memo_bytes)) => { - // Mark this tx as an outgoing tx, so we can grab all outgoing metadata - is_outgoing_tx = true; - - let address = encode_payment_address(config.hrp_sapling_address(), &payment_address); - - // Check if this is change, and if it also doesn't have a memo, don't add - // to the outgoing metadata. - // If this is change (i.e., funds sent to ourself) AND has a memo, then - // presumably the users is writing a memo to themself, so we will add it to - // the outgoing metadata, even though it might be confusing in the UI, but hopefully - // the user can make sense of it. - match Memo::try_from(memo_bytes) { - Err(_) => None, - Ok(memo) => { - if z_addresses.contains(&address) && memo == Memo::Empty { - None - } else { - Some(OutgoingTxMetadata { - address, - value: note.value, - memo, - }) + // Also scan the output to see if it can be decoded with our OutgoingViewKey + // If it can, then we sent this transaction, so we should be able to get + // the memo and value for our records + + // Search all ovks that we have + let omds = ovks + .iter() + .filter_map(|ovk| { + match try_sapling_output_recovery(&config.get_params(), height, &ovk, &output) { + Some((note, payment_address, memo_bytes)) => { + // Mark this tx as an outgoing tx, so we can grab all outgoing metadata + is_outgoing_tx = true; + + let address = encode_payment_address(config.hrp_sapling_address(), &payment_address); + + // Check if this is change, and if it also doesn't have a memo, don't add + // to the outgoing metadata. + // If this is change (i.e., funds sent to ourself) AND has a memo, then + // presumably the users is writing a memo to themself, so we will add it to + // the outgoing metadata, even though it might be confusing in the UI, but hopefully + // the user can make sense of it. + match Memo::try_from(memo_bytes) { + Err(_) => None, + Ok(memo) => { + if z_addresses.contains(&address) && memo == Memo::Empty { + None + } else { + Some(OutgoingTxMetadata { + address, + value: note.value, + memo, + }) + } } } } + None => None, } - None => None, - } - }) - .collect::>(); + }) + .collect::>(); - // Add it to the overall outgoing metadatas - outgoing_metadatas.extend(omds); + // Add it to the overall outgoing metadatas + outgoing_metadatas.extend(omds); + } } // Step 5. Process t-address outputs @@ -373,22 +367,24 @@ impl FetchFullTxns { } if is_outgoing_tx { - for vout in &tx.vout { - let taddr = keys.read().await.address_from_pubkeyhash(vout.script_pubkey.address()); - - if taddr.is_some() && !taddrs_set.contains(taddr.as_ref().unwrap()) { - outgoing_metadatas.push(OutgoingTxMetadata { - address: taddr.unwrap(), - value: vout.value.into(), - memo: Memo::Empty, - }); + if let Some(t_bundle) = tx.transparent_bundle() { + for vout in &t_bundle.vout { + let taddr = keys.read().await.address_from_pubkeyhash(vout.script_pubkey.address()); + + if taddr.is_some() && !taddrs_set.contains(taddr.as_ref().unwrap()) { + outgoing_metadatas.push(OutgoingTxMetadata { + address: taddr.unwrap(), + value: vout.value.into(), + memo: Memo::Empty, + }); + } } - } - // Also, if this is an outgoing transaction, then mark all the *incoming* sapling notes to this Tx as change. - // Note that this is also done in `WalletTxns::add_new_spent`, but that doesn't take into account transparent spends, - // so we'll do it again here. - wallet_txns.write().await.check_notes_mark_change(&tx.txid()); + // Also, if this is an outgoing transaction, then mark all the *incoming* sapling notes to this Tx as change. + // Note that this is also done in `WalletTxns::add_new_spent`, but that doesn't take into account transparent spends, + // so we'll do it again here. + wallet_txns.write().await.check_notes_mark_change(&tx.txid()); + } } if !outgoing_metadatas.is_empty() { diff --git a/lib/src/blaze/fetch_taddr_txns.rs b/lib/src/blaze/fetch_taddr_txns.rs index bcb5e1c4..0570a482 100644 --- a/lib/src/blaze/fetch_taddr_txns.rs +++ b/lib/src/blaze/fetch_taddr_txns.rs @@ -12,6 +12,8 @@ use tokio::{ }; use zcash_primitives::consensus::BlockHeight; +use zcash_primitives::consensus::BranchId; +use zcash_primitives::consensus::Parameters; use zcash_primitives::transaction::Transaction; pub struct FetchTaddrTxns { @@ -32,6 +34,7 @@ impl FetchTaddrTxns { oneshot::Sender>>>, )>, full_tx_scanner: UnboundedSender<(Transaction, BlockHeight)>, + network: &'static (impl Parameters + Sync), ) -> JoinHandle> { let keys = self.keys.clone(); @@ -113,7 +116,11 @@ impl FetchTaddrTxns { } prev_height = rtx.height; - let tx = Transaction::read(&rtx.data[..]).map_err(|e| format!("Error reading Tx: {}", e))?; + let tx = Transaction::read( + &rtx.data[..], + BranchId::for_height(network, BlockHeight::from_u32(rtx.height as u32)), + ) + .map_err(|e| format!("Error reading Tx: {}", e))?; full_tx_scanner .send((tx, BlockHeight::from_u32(rtx.height as u32))) .unwrap(); @@ -144,9 +151,10 @@ mod test { use tokio::sync::oneshot::{self}; use tokio::sync::RwLock; use tokio::{sync::mpsc::unbounded_channel, task::JoinHandle}; - use zcash_primitives::consensus::BlockHeight; + use zcash_primitives::consensus::{BlockHeight, TEST_NETWORK}; use crate::compact_formats::RawTransaction; + use crate::lightclient::faketx; use zcash_primitives::transaction::{Transaction, TransactionData}; use crate::lightwallet::keys::Keys; @@ -184,17 +192,17 @@ mod test { let mut rng = rand::thread_rng(); // Generate between 50 and 200 txns per taddr - let num_txns = rng.gen_range(50, 200); + let num_txns = rng.gen_range(50..200); let mut rtxs = (0..num_txns) .into_iter() - .map(|_| rng.gen_range(1, 100)) + .map(|_| rng.gen_range(1..100)) .map(|h| { let mut rtx = RawTransaction::default(); rtx.height = h; let mut b = vec![]; - TransactionData::new().freeze().unwrap().write(&mut b).unwrap(); + faketx::new_transactiondata().freeze().unwrap().write(&mut b).unwrap(); rtx.data = b; rtx @@ -238,7 +246,9 @@ mod test { Ok(total) }); - let h3 = ftt.start(100, 1, taddr_fetcher_tx, full_tx_scanner_tx).await; + let h3 = ftt + .start(100, 1, taddr_fetcher_tx, full_tx_scanner_tx, &TEST_NETWORK) + .await; let (total_sent, total_recieved) = join!(h1, h2); assert_eq!(total_sent.unwrap().unwrap(), total_recieved.unwrap().unwrap()); diff --git a/lib/src/blaze/test_utils.rs b/lib/src/blaze/test_utils.rs index 2ebabf59..ad744f50 100644 --- a/lib/src/blaze/test_utils.rs +++ b/lib/src/blaze/test_utils.rs @@ -2,33 +2,39 @@ use std::{convert::TryInto, sync::Arc}; use crate::{ compact_formats::{CompactBlock, CompactOutput, CompactSpend, CompactTx}, - lightclient::test_server::TestServerData, + lightclient::{ + faketx::{clone_transactiondata, new_transactiondata}, + test_server::TestServerData, + }, lightwallet::{data::BlockData, keys::ToBase58Check}, }; use ff::{Field, PrimeField}; use group::GroupEncoding; -use jubjub::ExtendedPoint; use prost::Message; use rand::{rngs::OsRng, RngCore}; use secp256k1::PublicKey; use sha2::{Digest, Sha256}; use tokio::sync::RwLock; +use zcash_note_encryption::{EphemeralKeyBytes, NoteEncryption, ShieldedOutput}; use zcash_primitives::{ block::BlockHash, + consensus::{BlockHeight, BranchId, TEST_NETWORK}, constants::SPENDING_KEY_GENERATOR, keys::OutgoingViewingKey, legacy::{Script, TransparentAddress}, memo::Memo, merkle_tree::{CommitmentTree, Hashable, IncrementalWitness, MerklePath}, - note_encryption::SaplingNoteEncryption, - primitives::{Diversifier, Note, Nullifier, PaymentAddress, ProofGenerationKey, Rseed, ValueCommitment}, - prover::TxProver, - redjubjub::Signature, - sapling::Node, + sapling::{ + note_encryption::SaplingDomain, + prover::TxProver, + redjubjub::{self, Signature}, + Node, + }, + sapling::{Diversifier, Note, Nullifier, PaymentAddress, ProofGenerationKey, Rseed, ValueCommitment}, transaction::{ - components::{Amount, OutPoint, OutputDescription, TxIn, TxOut, GROTH_PROOF_SIZE}, - Transaction, TransactionData, TxId, + components::{transparent, Amount, OutPoint, OutputDescription, TxIn, TxOut, GROTH_PROOF_SIZE}, + Authorized, Transaction, TransactionData, TxId, }, zip32::{ExtendedFullViewingKey, ExtendedSpendingKey}, }; @@ -72,7 +78,7 @@ pub fn list_all_witness_nodes(cb: &CompactBlock) -> Vec { pub struct FakeTransaction { pub ctx: CompactTx, - pub td: TransactionData, + pub td: TransactionData, pub taddrs_involved: Vec, } @@ -80,7 +86,7 @@ impl FakeTransaction { pub fn new() -> Self { Self { ctx: CompactTx::default(), - td: TransactionData::new(), + td: new_transactiondata(), taddrs_involved: vec![], } } @@ -90,14 +96,23 @@ impl FakeTransaction { fn add_sapling_output(&mut self, value: u64, ovk: Option, to: &PaymentAddress) -> Note { // Create a fake Note for the account let mut rng = OsRng; + + let mut rseed_bytes = [0u8; 32]; + rng.fill_bytes(&mut rseed_bytes); + let note = Note { g_d: to.diversifier().g_d().unwrap(), pk_d: to.pk_d().clone(), value, - rseed: Rseed::BeforeZip212(jubjub::Fr::random(rng)), + rseed: Rseed::AfterZip212(rseed_bytes), }; - let mut encryptor = SaplingNoteEncryption::new(ovk, note.clone(), to.clone(), Memo::default().into(), &mut rng); + let encryptor = NoteEncryption::>::new( + ovk, + note.clone(), + to.clone(), + Memo::default().into(), + ); let mut rng = OsRng; let rcv = jubjub::Fr::random(&mut rng); @@ -110,9 +125,9 @@ impl FakeTransaction { let od = OutputDescription { cv: cv.commitment().into(), cmu: note.cmu(), - ephemeral_key: ExtendedPoint::from(*encryptor.epk()), + ephemeral_key: EphemeralKeyBytes(encryptor.epk().to_bytes()), enc_ciphertext: encryptor.encrypt_note_plaintext(), - out_ciphertext: encryptor.encrypt_outgoing_plaintext(&cv.commitment().into(), &cmu), + out_ciphertext: encryptor.encrypt_outgoing_plaintext(&cv.commitment().into(), &cmu, &mut rng), zkproof: [0; GROTH_PROOF_SIZE], }; @@ -128,8 +143,9 @@ impl FakeTransaction { cout.epk = epk; cout.ciphertext = enc_ciphertext[..52].to_vec(); - self.td.shielded_outputs.push(od); - self.td.binding_sig = Signature::read(&vec![0u8; 64][..]).ok(); + let mut sapling_bundle = self.td.sapling_bundle().unwrap().clone(); + sapling_bundle.shielded_outputs.push(od); + self.td.sapling_bundle = Some(sapling_bundle); self.ctx.outputs.push(cout); @@ -150,7 +166,7 @@ impl FakeTransaction { // Add a new tx into the block, paying the given address the amount. // Returns the nullifier of the new note. pub fn add_tx_paying(&mut self, extfvk: &ExtendedFullViewingKey, value: u64) -> Note { - let to = extfvk.default_address().unwrap().1; + let to = extfvk.default_address().1; let note = self.add_sapling_output(value, None, &to); note @@ -163,27 +179,52 @@ impl FakeTransaction { let taddr_bytes = hash160.finalize(); - self.td.vout.push(TxOut { + // let mut t_bundle = self.td.transparent_bundle().unwrap().clone(); + + let mut t_bundle = if self.td.transparent_bundle().is_some() { + self.td.transparent_bundle().unwrap().clone() + } else { + transparent::Bundle { + vin: vec![], + vout: vec![], + authorization: transparent::Authorized {}, + } + }; + + t_bundle.vout.push(TxOut { value: Amount::from_u64(value).unwrap(), script_pubkey: TransparentAddress::PublicKey(taddr_bytes.try_into().unwrap()).script(), }); + self.td.transparent_bundle = Some(t_bundle); self.taddrs_involved.push(taddr) } // Spend the given utxo pub fn add_t_input(&mut self, txid: TxId, n: u32, taddr: String) { - self.td.vin.push(TxIn { - prevout: OutPoint::new(txid.0, n), + let mut t_bundle = if self.td.transparent_bundle().is_some() { + self.td.transparent_bundle().unwrap().clone() + } else { + transparent::Bundle { + vin: vec![], + vout: vec![], + authorization: transparent::Authorized {}, + } + }; + + t_bundle.vin.push(TxIn { + prevout: OutPoint::new(*txid.as_ref(), n), script_sig: Script { 0: vec![] }, sequence: 0, }); + self.td.transparent_bundle = Some(t_bundle); + self.taddrs_involved.push(taddr); } pub fn into_tx(mut self) -> (CompactTx, Transaction, Vec) { let tx = self.td.freeze().unwrap(); - self.ctx.hash = tx.txid().clone().0.to_vec(); + self.ctx.hash = tx.txid().as_ref().to_vec(); (self.ctx, tx, self.taddrs_involved) } @@ -211,6 +252,7 @@ impl FakeCompactBlock { } pub fn add_txs(&mut self, ctxs: Vec) { + println!("Adding {} txns to fake server", ctxs.len()); self.block.vtx.extend(ctxs); } @@ -220,7 +262,7 @@ impl FakeCompactBlock { let xsk_m = ExtendedSpendingKey::master(&[1u8; 32]); let extfvk = ExtendedFullViewingKey::from(&xsk_m); - let to = extfvk.default_address().unwrap().1; + let to = extfvk.default_address().1; let value = Amount::from_u64(1).unwrap(); let mut ctx = CompactTx::default(); @@ -238,6 +280,8 @@ impl FakeCompactBlock { // Create a fake CompactBlock containing the note let mut cout = CompactOutput::default(); cout.cmu = note.cmu().to_bytes().to_vec(); + cout.epk = [0u8; 32].to_vec(); + cout.ciphertext = [0u8; 52].to_vec(); ctx.outputs.push(cout); } @@ -282,57 +326,69 @@ impl FakeCompactBlockList { let sent_txns = data.write().await.sent_txns.split_off(0); for rtx in sent_txns { - let tx = Transaction::read(&rtx.data[..]).unwrap(); + let tx = Transaction::read( + &rtx.data[..], + BranchId::for_height(&TEST_NETWORK, BlockHeight::from_u32(rtx.height as u32)), + ) + .unwrap(); let mut ctx = CompactTx::default(); - for out in &tx.shielded_outputs { - let mut cout = CompactOutput::default(); - cout.cmu = out.cmu.to_repr().to_vec(); - cout.epk = out.ephemeral_key.to_bytes().to_vec(); - cout.ciphertext = out.enc_ciphertext[..52].to_vec(); + if let Some(s_bundle) = tx.sapling_bundle() { + for out in &s_bundle.shielded_outputs { + let mut cout = CompactOutput::default(); + cout.cmu = out.cmu.to_repr().to_vec(); + cout.epk = out.ephemeral_key.0.to_vec(); + cout.ciphertext = out.enc_ciphertext[..52].to_vec(); - ctx.outputs.push(cout); - } + ctx.outputs.push(cout); + } - for spend in &tx.shielded_spends { - let mut cs = CompactSpend::default(); - cs.nf = spend.nullifier.to_vec(); + for spend in &s_bundle.shielded_spends { + let mut cs = CompactSpend::default(); + cs.nf = spend.nullifier.to_vec(); - ctx.spends.push(cs); + ctx.spends.push(cs); + } } let config = data.read().await.config.clone(); - let taddrs = tx - .vout - .iter() - .filter_map(|vout| { - if let Some(TransparentAddress::PublicKey(taddr_hash)) = vout.script_pubkey.address() { - let taddr = taddr_hash.to_base58check(&config.base58_pubkey_address(), &[]); - Some(taddr) - } else { - None - } - }) - .collect::>(); + let taddrs = if let Some(t_bundle) = tx.transparent_bundle() { + t_bundle + .vout + .iter() + .filter_map(|vout| { + if let Some(TransparentAddress::PublicKey(taddr_hash)) = vout.script_pubkey.address() { + let taddr = taddr_hash.to_base58check(&config.base58_pubkey_address(), &[]); + Some(taddr) + } else { + None + } + }) + .collect::>() + } else { + vec![] + }; let new_block_height = { let new_block = self.add_empty_block(); - ctx.hash = tx.txid().0.to_vec(); + ctx.hash = tx.txid().as_ref().to_vec(); new_block.add_txs(vec![ctx]); new_block.height }; - self.txns.push((tx.clone(), new_block_height, taddrs)); + self.txns.push((tx, new_block_height, taddrs)); } } pub fn add_ftx(&mut self, ftx: FakeTransaction) -> (Transaction, u64) { let (ctx, tx, taddrs) = ftx.into_tx(); + let (tx1, tx2) = clone_transactiondata(tx.into_data()); + let height = self.next_height; - self.txns.push((tx.clone(), height, taddrs)); + self.txns.push((tx1.freeze().unwrap(), height, taddrs)); self.add_empty_block().add_txs(vec![ctx]); - (tx, height) + (tx2.freeze().unwrap(), height) } pub fn add_tx_spending( @@ -430,14 +486,7 @@ impl TxProver for FakeTxProver { value: u64, _anchor: bls12_381::Scalar, _merkle_path: MerklePath, - ) -> Result< - ( - [u8; GROTH_PROOF_SIZE], - jubjub::ExtendedPoint, - zcash_primitives::redjubjub::PublicKey, - ), - (), - > { + ) -> Result<([u8; GROTH_PROOF_SIZE], jubjub::ExtendedPoint, redjubjub::PublicKey), ()> { let zkproof = [0u8; GROTH_PROOF_SIZE]; let mut rng = OsRng; @@ -448,8 +497,7 @@ impl TxProver for FakeTxProver { // Compute value commitment let value_commitment: jubjub::ExtendedPoint = cv.commitment().into(); - let rk = zcash_primitives::redjubjub::PublicKey(proof_generation_key.ak.clone().into()) - .randomize(ar, SPENDING_KEY_GENERATOR); + let rk = redjubjub::PublicKey(proof_generation_key.ak.clone().into()).randomize(ar, SPENDING_KEY_GENERATOR); Ok((zkproof, value_commitment, rk)) } diff --git a/lib/src/blaze/trial_decryptions.rs b/lib/src/blaze/trial_decryptions.rs index fb4c4097..573f2843 100644 --- a/lib/src/blaze/trial_decryptions.rs +++ b/lib/src/blaze/trial_decryptions.rs @@ -1,10 +1,23 @@ -use crate::{compact_formats::CompactBlock, lightwallet::{MemoDownloadOption, data::WalletTx, keys::Keys, wallet_txns::WalletTxns}}; +use crate::{ + compact_formats::CompactBlock, + lightwallet::{data::WalletTx, keys::Keys, wallet_txns::WalletTxns, MemoDownloadOption}, +}; use futures::{stream::FuturesUnordered, StreamExt}; use log::info; use std::sync::Arc; -use tokio::{sync::{RwLock, mpsc::{unbounded_channel, UnboundedSender}, oneshot}, task::JoinHandle}; - -use zcash_primitives::{consensus::BlockHeight, note_encryption::try_sapling_compact_note_decryption, primitives::{Nullifier, SaplingIvk}, transaction::{Transaction, TxId}}; +use tokio::{ + sync::{ + mpsc::{unbounded_channel, UnboundedSender}, + oneshot, RwLock, + }, + task::JoinHandle, +}; + +use zcash_primitives::{ + consensus::BlockHeight, + sapling::{note_encryption::try_sapling_compact_note_decryption, Nullifier, SaplingIvk}, + transaction::{Transaction, TxId}, +}; use super::syncdata::BlazeSyncData; @@ -107,23 +120,12 @@ impl TrialDecryptions { for (tx_num, ctx) in cb.vtx.iter().enumerate() { let mut wallet_tx = false; - - for (output_num, co) in ctx.outputs.iter().enumerate() { - let cmu = co.cmu().map_err(|_| "No CMU".to_string())?; - let epk = match co.epk() { - Err(_) => continue, - Ok(epk) => epk, - }; + for (output_num, co) in ctx.outputs.iter().enumerate() { for (i, ivk) in ivks.iter().enumerate() { - if let Some((note, to)) = try_sapling_compact_note_decryption( - &config.get_params(), - height, - &ivk, - &epk, - &cmu, - &co.ciphertext, - ) { + if let Some((note, to)) = + try_sapling_compact_note_decryption(&config.get_params(), height, &ivk, co) + { wallet_tx = true; let keys = keys.clone(); @@ -163,7 +165,7 @@ impl TrialDecryptions { ); info!("Trial decrypt Detected txid {}", &txid); - + detected_txid_sender .send((txid, nullifier, height, Some(output_num as u32))) .unwrap(); @@ -187,7 +189,6 @@ impl TrialDecryptions { // Discard the result, because this was not a wallet tx. rx.await.unwrap().map(|_r| ()) })); - } } } diff --git a/lib/src/blaze/update_notes.rs b/lib/src/blaze/update_notes.rs index 843ea894..cc8cc6e2 100644 --- a/lib/src/blaze/update_notes.rs +++ b/lib/src/blaze/update_notes.rs @@ -10,7 +10,7 @@ use tokio::sync::{mpsc::unbounded_channel, RwLock}; use tokio::{sync::mpsc::UnboundedSender, task::JoinHandle}; use zcash_primitives::consensus::BlockHeight; -use zcash_primitives::primitives::Nullifier; +use zcash_primitives::sapling::Nullifier; use zcash_primitives::transaction::TxId; use super::syncdata::BlazeSyncData; diff --git a/lib/src/compact_formats.rs b/lib/src/compact_formats.rs index 62e179c4..5bb0f078 100644 --- a/lib/src/compact_formats.rs +++ b/lib/src/compact_formats.rs @@ -2,9 +2,12 @@ use ff::PrimeField; use group::GroupEncoding; use std::convert::TryInto; +use std::convert::TryFrom; +use zcash_note_encryption::{EphemeralKeyBytes, ShieldedOutput}; use zcash_primitives::{ block::{BlockHash, BlockHeader}, - consensus::BlockHeight, + consensus::{BlockHeight, Parameters}, + sapling::note_encryption::SaplingDomain, }; tonic::include_proto!("cash.z.wallet.sdk.rpc"); @@ -76,7 +79,12 @@ impl CompactOutput { pub fn cmu(&self) -> Result { let mut repr = [0; 32]; repr.as_mut().copy_from_slice(&self.cmu[..]); - bls12_381::Scalar::from_repr(repr).ok_or(()) + let r = bls12_381::Scalar::from_repr(repr); + if bool::from(r.is_some()) { + Ok(r.unwrap()) + } else { + Err(()) + } } /// Returns the ephemeral public key for this output. @@ -93,3 +101,19 @@ impl CompactOutput { } } } + +impl ShieldedOutput, 52_usize> for CompactOutput { + fn ephemeral_key(&self) -> EphemeralKeyBytes { + EphemeralKeyBytes(*vec_to_array(&self.epk)) + } + fn cmstar_bytes(&self) -> [u8; 32] { + *vec_to_array(&self.cmu) + } + fn enc_ciphertext(&self) -> &[u8; 52] { + vec_to_array(&self.ciphertext) + } +} + +fn vec_to_array<'a, T, const N: usize>(vec: &'a Vec) -> &'a [T; N] { + <&[T; N]>::try_from(&vec[..]).unwrap() +} diff --git a/lib/src/grpc_connector.rs b/lib/src/grpc_connector.rs index bb55963f..da28fc7e 100644 --- a/lib/src/grpc_connector.rs +++ b/lib/src/grpc_connector.rs @@ -21,6 +21,7 @@ use tonic::{ transport::{Channel, Error}, Request, }; +use zcash_primitives::consensus::{BlockHeight, BranchId, Parameters}; use zcash_primitives::transaction::{Transaction, TxId}; #[derive(Clone)] @@ -124,6 +125,7 @@ impl GrpcConnector { pub async fn start_fulltx_fetcher( &self, + network: &'static (impl Parameters + Sync), ) -> ( JoinHandle<()>, UnboundedSender<(TxId, oneshot::Sender>)>, @@ -136,7 +138,9 @@ impl GrpcConnector { while let Some((txid, result_tx)) = rx.recv().await { let uri = uri.clone(); workers.push(tokio::spawn(async move { - result_tx.send(Self::get_full_tx(uri.clone(), &txid).await).unwrap() + result_tx + .send(Self::get_full_tx(uri.clone(), &txid, network).await) + .unwrap() })); // Do only 16 API calls in parallel, otherwise it might overflow OS's limit of @@ -188,15 +192,19 @@ impl GrpcConnector { Ok(()) } - async fn get_full_tx(uri: http::Uri, txid: &TxId) -> Result { + async fn get_full_tx( + uri: http::Uri, + txid: &TxId, + network: &'static (impl Parameters + Sync), + ) -> Result { let client = Arc::new(GrpcConnector::new(uri)); let request = Request::new(TxFilter { block: None, index: 0, - hash: txid.0.to_vec(), + hash: txid.as_ref().to_vec(), }); - // log::info!("Full fetching {}", txid); + log::info!("Full fetching {}", txid); let mut client = client .get_client() @@ -205,7 +213,12 @@ impl GrpcConnector { let response = client.get_transaction(request).await.map_err(|e| format!("{}", e))?; - Transaction::read(&response.into_inner().data[..]).map_err(|e| format!("Error parsing Transaction: {}", e)) + let height = response.get_ref().height as u32; + Transaction::read( + &response.into_inner().data[..], + BranchId::for_height(network, BlockHeight::from_u32(height)), + ) + .map_err(|e| format!("Error parsing Transaction: {}", e)) } async fn get_taddr_txns( diff --git a/lib/src/lightclient.rs b/lib/src/lightclient.rs index 84d6ffb5..2d9a49c4 100644 --- a/lib/src/lightclient.rs +++ b/lib/src/lightclient.rs @@ -32,7 +32,7 @@ use tokio::{ use zcash_client_backend::encoding::{decode_payment_address, encode_payment_address}; use zcash_primitives::{ block::BlockHash, - consensus::{BlockHeight, BranchId}, + consensus::{BlockHeight, BranchId, MAIN_NETWORK, TEST_NETWORK}, memo::{Memo, MemoBytes}, transaction::{components::amount::DEFAULT_FEE, Transaction, TxId}, }; @@ -1138,7 +1138,17 @@ impl LightClient { let price = lc1.wallet.price.clone(); while let Some(rtx) = mempool_rx.recv().await { - if let Ok(tx) = Transaction::read(&rtx.data[..]) { + if let Ok(tx) = match config.chain_name.as_str() { + "main" => Transaction::read( + &rtx.data[..], + BranchId::for_height(&MAIN_NETWORK, BlockHeight::from_u32(rtx.height as u32)), + ), + "test" => Transaction::read( + &rtx.data[..], + BranchId::for_height(&TEST_NETWORK, BlockHeight::from_u32(rtx.height as u32)), + ), + _ => panic!("Unrecognized network"), + } { let price = price.read().await.clone(); //info!("Mempool attempting to scan {}", tx.txid()); @@ -1263,7 +1273,7 @@ impl LightClient { // Re-read the last scanned height let last_scanned_height = self.wallet.last_scanned_height().await; - let batch_size = 500_000; + let batch_size = 300_000; let mut latest_block_batches = vec![]; let mut prev = last_scanned_height; @@ -1351,7 +1361,11 @@ impl LightClient { .await; // Full Tx GRPC fetcher - let (fulltx_fetcher_handle, fulltx_fetcher_tx) = grpc_connector.start_fulltx_fetcher().await; + let (fulltx_fetcher_handle, fulltx_fetcher_tx) = match self.config.chain_name.as_str() { + "main" => grpc_connector.start_fulltx_fetcher(&MAIN_NETWORK).await, + "test" => grpc_connector.start_fulltx_fetcher(&TEST_NETWORK).await, + _ => panic!("Unrecognized network"), + }; // Transparent Transactions Fetcher let (taddr_fetcher_handle, taddr_fetcher_tx) = grpc_connector.start_taddr_txn_fetcher().await; @@ -1392,9 +1406,31 @@ impl LightClient { let earliest_block = block_and_witness_handle.await.unwrap().unwrap(); // 1. Fetch the transparent txns only after reorgs are done. - let taddr_txns_handle = FetchTaddrTxns::new(self.wallet.keys()) - .start(start_block, earliest_block, taddr_fetcher_tx, fetch_taddr_txns_tx) - .await; + let taddr_txns_handle = match self.config.chain_name.as_str() { + "main" => { + FetchTaddrTxns::new(self.wallet.keys()) + .start( + start_block, + earliest_block, + taddr_fetcher_tx, + fetch_taddr_txns_tx, + &MAIN_NETWORK, + ) + .await + } + "test" => { + FetchTaddrTxns::new(self.wallet.keys()) + .start( + start_block, + earliest_block, + taddr_fetcher_tx, + fetch_taddr_txns_tx, + &TEST_NETWORK, + ) + .await + } + _ => panic!("Unrecognized network"), + }; // 2. Notify the notes updater that the blocks are done updating blocks_done_tx.send(earliest_block).unwrap(); @@ -1486,7 +1522,6 @@ impl LightClient { .get(0) .map(|s| s.clone())) .unwrap(); - let branch_id = self.consensus_branch_id().await; let result = { let _lock = self.sync_lock.lock().await; @@ -1495,7 +1530,7 @@ impl LightClient { let prover = LocalTxProver::from_bytes(&sapling_spend, &sapling_output); self.wallet - .send_to_address(branch_id, prover, true, vec![(&addr, tbal - fee, None)], |txbytes| { + .send_to_address(prover, true, vec![(&addr, tbal - fee, None)], |txbytes| { GrpcConnector::send_transaction(self.get_server_uri(), txbytes) }) .await @@ -1504,18 +1539,7 @@ impl LightClient { result.map(|(txid, _)| txid) } - async fn consensus_branch_id(&self) -> u32 { - let height = self.wallet.last_scanned_height().await; - - let branch: BranchId = BranchId::for_height(&self.config.get_params(), BlockHeight::from_u32(height as u32)); - let branch_id: u32 = u32::from(branch); - - branch_id - } - pub async fn do_send(&self, addrs: Vec<(&str, u64, Option)>) -> Result { - // First, get the concensus branch ID - let branch_id = self.consensus_branch_id().await; info!("Creating transaction"); // println!("BranchID {:x}", branch_id); @@ -1527,7 +1551,7 @@ impl LightClient { let prover = LocalTxProver::from_bytes(&sapling_spend, &sapling_output); self.wallet - .send_to_address(branch_id, prover, false, addrs, |txbytes| { + .send_to_address(prover, false, addrs, |txbytes| { GrpcConnector::send_transaction(self.get_server_uri(), txbytes) }) .await @@ -1538,8 +1562,6 @@ impl LightClient { #[cfg(test)] pub async fn test_do_send(&self, addrs: Vec<(&str, u64, Option)>) -> Result { - // First, get the concensus branch ID - let branch_id = self.consensus_branch_id().await; info!("Creating transaction"); let result = { @@ -1547,7 +1569,7 @@ impl LightClient { let prover = crate::blaze::test_utils::FakeTxProver {}; self.wallet - .send_to_address(branch_id, prover, false, addrs, |txbytes| { + .send_to_address(prover, false, addrs, |txbytes| { GrpcConnector::send_transaction(self.get_server_uri(), txbytes) }) .await @@ -1562,3 +1584,6 @@ pub mod tests; #[cfg(test)] pub(crate) mod test_server; + +#[cfg(test)] +pub(crate) mod faketx; diff --git a/lib/src/lightclient/faketx.rs b/lib/src/lightclient/faketx.rs new file mode 100644 index 00000000..d7b55794 --- /dev/null +++ b/lib/src/lightclient/faketx.rs @@ -0,0 +1,60 @@ +use zcash_primitives::consensus::BranchId; +use zcash_primitives::sapling::redjubjub::Signature; +use zcash_primitives::transaction::components::{sapling, Amount}; +use zcash_primitives::transaction::{Authorized, TransactionData, TxVersion}; + +// Create a fake tx data +pub fn new_transactiondata() -> TransactionData { + let td: TransactionData = TransactionData::from_parts( + TxVersion::Sapling, + BranchId::Sapling, + 0, + 0u32.into(), + None, + None, + None, + None, + ); + + td +} + +pub fn clone_transactiondata( + t: TransactionData, +) -> (TransactionData, TransactionData) { + let sapling_bundle = if t.sapling_bundle().is_some() { + Some(t.sapling_bundle().unwrap().clone()) + } else { + None + }; + + let transparent_bundle = if t.transparent_bundle().is_some() { + Some(t.transparent_bundle().unwrap().clone()) + } else { + None + }; + + let td1: TransactionData = TransactionData::from_parts( + TxVersion::Sapling, + BranchId::Sapling, + 0, + 0u32.into(), + transparent_bundle.clone(), + None, + sapling_bundle.clone(), + None, + ); + + let td2: TransactionData = TransactionData::from_parts( + TxVersion::Sapling, + BranchId::Sapling, + 0, + 0u32.into(), + transparent_bundle, + None, + sapling_bundle, + None, + ); + + (td1, td2) +} diff --git a/lib/src/lightclient/test_server.rs b/lib/src/lightclient/test_server.rs index 3c5006a3..906096aa 100644 --- a/lib/src/lightclient/test_server.rs +++ b/lib/src/lightclient/test_server.rs @@ -23,6 +23,7 @@ use tokio_stream::wrappers::ReceiverStream; use tonic::transport::Server; use tonic::{Request, Response, Status}; use zcash_primitives::block::BlockHash; +use zcash_primitives::consensus::{BlockHeight, BranchId, TEST_NETWORK}; use zcash_primitives::merkle_tree::CommitmentTree; use zcash_primitives::sapling::Node; use zcash_primitives::transaction::{Transaction, TxId}; @@ -113,12 +114,14 @@ pub async fn mine_pending_blocks( // Add all the t-addr spend's t-addresses into the maps, so the test grpc server // knows to serve this tx when the txns for this particular taddr are requested. for (t, _h, taddrs) in v.iter_mut() { - for vin in &t.vin { - let prev_txid = WalletTx::new_txid(&vin.prevout.hash().to_vec()); - if let Some(wtx) = lc.wallet.txns.read().await.current.get(&prev_txid) { - if let Some(utxo) = wtx.utxos.iter().find(|u| u.output_index as u32 == vin.prevout.n()) { - if !taddrs.contains(&utxo.address) { - taddrs.push(utxo.address.clone()); + if let Some(t_bundle) = t.transparent_bundle() { + for vin in &t_bundle.vin { + let prev_txid = WalletTx::new_txid(&vin.prevout.hash().to_vec()); + if let Some(wtx) = lc.wallet.txns.read().await.current.get(&prev_txid) { + if let Some(utxo) = wtx.utxos.iter().find(|u| u.output_index as u32 == vin.prevout.n()) { + if !taddrs.contains(&utxo.address) { + taddrs.push(utxo.address.clone()); + } } } } @@ -210,7 +213,7 @@ impl TestGRPCService { } async fn wait_random() { - let msecs = OsRng.gen_range(0, 100); + let msecs = OsRng.gen_range(0..100); sleep(std::time::Duration::from_millis(msecs)).await; } } @@ -298,7 +301,12 @@ impl CompactTxStreamer for TestGRPCService { async fn send_transaction(&self, request: Request) -> Result, Status> { let rtx = request.into_inner(); - let txid = Transaction::read(&rtx.data[..]).unwrap().txid(); + let txid = Transaction::read( + &rtx.data[..], + BranchId::for_height(&TEST_NETWORK, BlockHeight::from_u32(rtx.height as u32)), + ) + .unwrap() + .txid(); self.data.write().await.sent_txns.push(rtx); Ok(Response::new(SendResponse { diff --git a/lib/src/lightclient/tests.rs b/lib/src/lightclient/tests.rs index e51965db..7cc5dae1 100644 --- a/lib/src/lightclient/tests.rs +++ b/lib/src/lightclient/tests.rs @@ -1,8 +1,8 @@ use ff::{Field, PrimeField}; use group::GroupEncoding; use json::JsonValue; -use jubjub::ExtendedPoint; use rand::rngs::OsRng; +use rand::RngCore; use tempdir::TempDir; use tokio::runtime::Runtime; use tonic::transport::Channel; @@ -12,16 +12,19 @@ use zcash_client_backend::address::RecipientAddress; use zcash_client_backend::encoding::{ encode_extended_full_viewing_key, encode_extended_spending_key, encode_payment_address, }; -use zcash_primitives::consensus::BlockHeight; +use zcash_note_encryption::{EphemeralKeyBytes, NoteEncryption}; +use zcash_primitives::consensus::{BlockHeight, BranchId, TEST_NETWORK}; use zcash_primitives::memo::Memo; use zcash_primitives::merkle_tree::{CommitmentTree, IncrementalWitness}; -use zcash_primitives::note_encryption::SaplingNoteEncryption; -use zcash_primitives::primitives::{Note, Rseed, ValueCommitment}; -use zcash_primitives::redjubjub::Signature; +use zcash_primitives::sapling::note_encryption::SaplingDomain; +use zcash_primitives::sapling::redjubjub::Signature; +use zcash_primitives::transaction::components::{sapling, Amount}; + use zcash_primitives::sapling::Node; +use zcash_primitives::sapling::{Note, Rseed, ValueCommitment}; use zcash_primitives::transaction::components::amount::DEFAULT_FEE; use zcash_primitives::transaction::components::{OutputDescription, GROTH_PROOF_SIZE}; -use zcash_primitives::transaction::{Transaction, TransactionData}; +use zcash_primitives::transaction::Transaction; use zcash_primitives::zip32::{ExtendedFullViewingKey, ExtendedSpendingKey}; use crate::blaze::fetch_full_tx::FetchFullTxns; @@ -29,6 +32,7 @@ use crate::blaze::test_utils::{FakeCompactBlockList, FakeTransaction}; use crate::compact_formats::compact_tx_streamer_client::CompactTxStreamerClient; use crate::compact_formats::{CompactOutput, CompactTx, Empty}; +use crate::lightclient::faketx::new_transactiondata; use crate::lightclient::test_server::{create_test_server, mine_pending_blocks, mine_random_blocks}; use crate::lightclient::LightClient; use crate::lightwallet::data::WalletTx; @@ -317,25 +321,33 @@ async fn multiple_incoming_same_tx() { assert_eq!(lc.wallet.last_scanned_height().await, 10); // 2. Construct the Fake tx. - let to = extfvk1.default_address().unwrap().1; + let to = extfvk1.default_address().1; // Create fake note for the account let mut ctx = CompactTx::default(); - let mut td = TransactionData::new(); + let mut td = new_transactiondata(); // Add 4 outputs for i in 0..4 { let mut rng = OsRng; let value = value + i; + + let mut rseed_bytes = [0u8; 32]; + rng.fill_bytes(&mut rseed_bytes); + let note = Note { g_d: to.diversifier().g_d().unwrap(), pk_d: to.pk_d().clone(), value, - rseed: Rseed::BeforeZip212(jubjub::Fr::random(rng)), + rseed: Rseed::AfterZip212(rseed_bytes), }; - let mut encryptor = - SaplingNoteEncryption::new(None, note.clone(), to.clone(), Memo::default().into(), &mut rng); + let encryptor = NoteEncryption::>::new( + None, + note.clone(), + to.clone(), + Memo::default().into(), + ); let mut rng = OsRng; let rcv = jubjub::Fr::random(&mut rng); @@ -348,9 +360,9 @@ async fn multiple_incoming_same_tx() { let od = OutputDescription { cv: cv.commitment().into(), cmu: note.cmu(), - ephemeral_key: ExtendedPoint::from(*encryptor.epk()), + ephemeral_key: EphemeralKeyBytes(encryptor.epk().to_bytes()), enc_ciphertext: encryptor.encrypt_note_plaintext(), - out_ciphertext: encryptor.encrypt_outgoing_plaintext(&cv.commitment().into(), &cmu), + out_ciphertext: encryptor.encrypt_outgoing_plaintext(&cv.commitment().into(), &cmu, &mut rng), zkproof: [0; GROTH_PROOF_SIZE], }; @@ -367,15 +379,30 @@ async fn multiple_incoming_same_tx() { cout.ciphertext = enc_ciphertext[..52].to_vec(); ctx.outputs.push(cout); - td.shielded_outputs.push(od); + let mut sapling_bundle = if td.sapling_bundle.is_some() { + td.sapling_bundle().unwrap().clone() + } else { + sapling::Bundle { + shielded_spends: vec![], + shielded_outputs: vec![], + value_balance: Amount::zero(), + authorization: sapling::Authorized { + binding_sig: Signature::read(&vec![0u8; 64][..]).expect("Signature error"), + }, + } + }; + + sapling_bundle.shielded_outputs.push(od); + td.sapling_bundle = Some(sapling_bundle); } - td.binding_sig = Signature::read(&vec![0u8; 64][..]).ok(); + // td.binding_sig = Signature::read(&vec![0u8; 64][..]).ok(); let tx = td.freeze().unwrap(); - ctx.hash = tx.txid().clone().0.to_vec(); + let txid = tx.txid().to_string(); + ctx.hash = tx.txid().as_ref().to_vec(); // Add and mine the block - fcbl.txns.push((tx.clone(), fcbl.next_height, vec![])); + fcbl.txns.push((tx, fcbl.next_height, vec![])); fcbl.add_empty_block().add_txs(vec![ctx]); mine_pending_blocks(&mut fcbl, &data, &lc).await; assert_eq!(lc.wallet.last_scanned_height().await, 11); @@ -404,7 +431,7 @@ async fn multiple_incoming_same_tx() { sorted_txns.sort_by_cached_key(|t| t["amount"].as_u64().unwrap()); for i in 0..4 { - assert_eq!(sorted_txns[i]["txid"], tx.txid().to_string()); + assert_eq!(sorted_txns[i]["txid"], txid); assert_eq!(sorted_txns[i]["block_height"].as_u64().unwrap(), 11); assert_eq!( sorted_txns[i]["address"], @@ -581,7 +608,7 @@ async fn z_incoming_viewkey() { // 2. Create a new Viewkey and import it let iextsk = ExtendedSpendingKey::master(&[1u8; 32]); let iextfvk = ExtendedFullViewingKey::from(&iextsk); - let iaddr = encode_payment_address(config.hrp_sapling_address(), &iextfvk.default_address().unwrap().1); + let iaddr = encode_payment_address(config.hrp_sapling_address(), &iextfvk.default_address().1); let addrs = lc .do_import_vk( encode_extended_full_viewing_key(config.hrp_sapling_viewing_key(), &iextfvk), @@ -696,6 +723,7 @@ async fn t_incoming_t_outgoing() { // 5. Test the unconfirmed send. let list = lc.do_list_transactions(false).await; + println!("{}", list.pretty(2)); assert_eq!(list[1]["block_height"].as_u64().unwrap(), 12); assert_eq!(list[1]["txid"], sent_txid); assert_eq!( @@ -977,6 +1005,8 @@ async fn no_change() { ready_rx.await.unwrap(); let lc = LightClient::test_new(&config, None, 0).await.unwrap(); + lc.init_logging().unwrap(); + let mut fcbl = FakeCompactBlockList::new(0); // 1. Mine 10 blocks @@ -990,6 +1020,9 @@ async fn no_change() { mine_pending_blocks(&mut fcbl, &data, &lc).await; mine_random_blocks(&mut fcbl, &data, &lc, 5).await; + let notes = lc.do_list_notes(true).await; + println!("{}", notes.pretty(2)); + // 3. Send an incoming t-address txn let sk = lc.wallet.keys().read().await.tkeys[0].clone(); let pk = sk.pubkey().unwrap(); @@ -1258,7 +1291,11 @@ async fn mempool_clearing() { let notes_before = lc.do_list_notes(true).await; let txns_before = lc.do_list_transactions(false).await; - let tx = Transaction::read(&sent_tx.data[..]).unwrap(); + let tx = Transaction::read( + &sent_tx.data[..], + BranchId::for_height(&TEST_NETWORK, BlockHeight::from_u32(sent_tx.height as u32)), + ) + .unwrap(); FetchFullTxns::scan_full_tx( config, tx, diff --git a/lib/src/lightwallet.rs b/lib/src/lightwallet.rs index a6d92c09..51263c06 100644 --- a/lib/src/lightwallet.rs +++ b/lib/src/lightwallet.rs @@ -12,12 +12,12 @@ use crate::{ use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use futures::Future; use log::{error, info, warn}; +use std::sync::mpsc; use std::{ cmp, collections::HashMap, - convert::TryFrom, io::{self, Error, ErrorKind, Read, Write}, - sync::{atomic::AtomicU64, mpsc::channel, Arc}, + sync::{atomic::AtomicU64, Arc}, time::SystemTime, }; use tokio::sync::RwLock; @@ -25,13 +25,13 @@ use zcash_client_backend::{ address, encoding::{decode_extended_full_viewing_key, decode_extended_spending_key, encode_payment_address}, }; -use zcash_primitives::serialize::Optional; +use zcash_encoding::{Optional, Vector}; +use zcash_primitives::memo::MemoBytes; +use zcash_primitives::sapling::prover::TxProver; use zcash_primitives::{ - consensus::{BlockHeight, BranchId}, + consensus::{BlockHeight}, legacy::Script, memo::Memo, - prover::TxProver, - serialize::Vector, transaction::{ builder::Builder, components::{amount::DEFAULT_FEE, Amount, OutPoint, TxOut}, @@ -334,7 +334,7 @@ impl LightWallet { // in case of rescans etc... writer.write_u64::(self.get_birthday().await)?; - Optional::write(&mut writer, &self.verified_tree.read().await.as_ref(), |w, t| { + Optional::write(&mut writer, self.verified_tree.read().await.as_ref(), |w, t| { use prost::Message; let mut buf = vec![]; @@ -879,7 +879,7 @@ impl LightWallet { .values() .flat_map(|wtx| { wtx.notes.iter().map(|n| { - let (_, pa) = n.extfvk.default_address().unwrap(); + let (_, pa) = n.extfvk.default_address(); let zaddr = encode_payment_address(self.config.hrp_sapling_address(), &pa); zaddrs.iter().position(|za| *za == zaddr).unwrap_or(zaddrs.len()) }) @@ -976,7 +976,7 @@ impl LightWallet { // Check how much we've selected let transparent_value_selected = utxos.iter().fold(Amount::zero(), |prev, utxo| { - prev + Amount::from_u64(utxo.value).unwrap() + (prev + Amount::from_u64(utxo.value).unwrap()).unwrap() }); // If we are allowed only transparent funds or we've selected enough then return @@ -1012,7 +1012,7 @@ impl LightWallet { let notes = candidate_notes .into_iter() .scan(Amount::zero(), |running_total, spendable| { - if *running_total >= target_amount - transparent_value_selected { + if *running_total >= (target_amount - transparent_value_selected).unwrap() { None } else { *running_total += Amount::from_u64(spendable.note.value).unwrap(); @@ -1021,11 +1021,15 @@ impl LightWallet { }) .collect::>(); let sapling_value_selected = notes.iter().fold(Amount::zero(), |prev, sn| { - prev + Amount::from_u64(sn.note.value).unwrap() + (prev + Amount::from_u64(sn.note.value).unwrap()).unwrap() }); - if sapling_value_selected + transparent_value_selected >= target_amount { - return (notes, utxos, sapling_value_selected + transparent_value_selected); + if sapling_value_selected + transparent_value_selected >= Some(target_amount) { + return ( + notes, + utxos, + (sapling_value_selected + transparent_value_selected).unwrap(), + ); } } @@ -1035,7 +1039,6 @@ impl LightWallet { pub async fn send_to_address( &self, - consensus_branch_id: u32, prover: P, transparent_only: bool, tos: Vec<(&str, u64, Option)>, @@ -1050,7 +1053,7 @@ impl LightWallet { // Call the internal function match self - .send_to_address_internal(consensus_branch_id, prover, transparent_only, tos, broadcast_fn) + .send_to_address_internal(prover, transparent_only, tos, broadcast_fn) .await { Ok((txid, rawtx)) => { @@ -1066,7 +1069,6 @@ impl LightWallet { async fn send_to_address_internal( &self, - consensus_branch_id: u32, prover: P, transparent_only: bool, tos: Vec<(&str, u64, Option)>, @@ -1120,17 +1122,21 @@ impl LightWallet { None => return Err("No blocks in wallet to target, please sync first".to_string()), }; + let (progress_notifier, progress_notifier_rx) = mpsc::channel(); let mut builder = Builder::new(self.config.get_params().clone(), target_height); + builder.with_progress_notifier(progress_notifier); // Create a map from address -> sk for all taddrs, so we can spend from the // right address let address_to_sk = self.keys.read().await.get_taddr_to_sk_map(); - let (notes, utxos, selected_value) = self.select_notes_and_utxos(target_amount, transparent_only, true).await; - if selected_value < target_amount { + let (notes, utxos, selected_value) = self + .select_notes_and_utxos(target_amount.unwrap(), transparent_only, true) + .await; + if selected_value < target_amount.unwrap() { let e = format!( "Insufficient verified funds. Have {} zats, need {} zats. NOTE: funds need at least {} confirmations before they can be spent.", - u64::from(selected_value), u64::from(target_amount), self.config.anchor_offset.last().unwrap() + 1 + u64::from(selected_value), u64::from(target_amount.unwrap()), self.config.anchor_offset.last().unwrap() + 1 ); error!("{}", e); return Err(e); @@ -1162,7 +1168,7 @@ impl LightWallet { let e = format!("Couldn't find the secreykey for taddr {}", utxo.address); error!("{}", e); - Err(zcash_primitives::transaction::builder::Error::InvalidAddress) + Err(zcash_primitives::transaction::builder::Error::InvalidAmount) } } }) @@ -1198,12 +1204,12 @@ impl LightWallet { for (to, value, memo) in recepients { // Compute memo if it exists let encoded_memo = match memo { - None => None, + None => MemoBytes::empty(), Some(s) => { // If the string starts with an "0x", and contains only hex chars ([a-f0-9]+) then // interpret it as a hex match utils::interpret_memo_string(s) { - Ok(m) => Some(m), + Ok(m) => m, Err(e) => { error!("{}", e); return Err(e); @@ -1228,14 +1234,13 @@ impl LightWallet { } // Set up a channel to recieve updates on the progress of building the transaction. - let (tx, rx) = channel::(); let progress = self.send_progress.clone(); // Use a separate thread to handle sending from std::mpsc to tokio::sync::mpsc let (tx2, mut rx2) = tokio::sync::mpsc::unbounded_channel(); std::thread::spawn(move || { - while let Ok(r) = rx.recv() { - tx2.send(r).unwrap(); + while let Ok(r) = progress_notifier_rx.recv() { + tx2.send(r.cur()).unwrap(); } }); @@ -1256,11 +1261,7 @@ impl LightWallet { } println!("{}: Building transaction", now() - start_time); - let (tx, _) = match builder.build_with_progress_notifier( - BranchId::try_from(consensus_branch_id).unwrap(), - &prover, - Some(tx), - ) { + let (tx, _) = match builder.build(&prover) { Ok(res) => res, Err(e) => { let e = format!("Error creating transaction: {:?}", e); diff --git a/lib/src/lightwallet/data.rs b/lib/src/lightwallet/data.rs index 76c59821..305c60c7 100644 --- a/lib/src/lightwallet/data.rs +++ b/lib/src/lightwallet/data.rs @@ -4,6 +4,7 @@ use prost::Message; use std::convert::TryFrom; use std::io::{self, Read, Write}; use std::usize; +use zcash_encoding::{Optional, Vector}; use zcash_primitives::memo::MemoBytes; use crate::blaze::fixed_size_buffer::FixedSizeBuffer; @@ -11,9 +12,8 @@ use zcash_primitives::{consensus::BlockHeight, zip32::ExtendedSpendingKey}; use zcash_primitives::{ memo::Memo, merkle_tree::{CommitmentTree, IncrementalWitness}, - primitives::{Diversifier, Note, Nullifier, Rseed}, sapling::Node, - serialize::{Optional, Vector}, + sapling::{Diversifier, Note, Nullifier, Rseed}, transaction::{components::OutPoint, TxId}, zip32::ExtendedFullViewingKey, }; @@ -299,7 +299,7 @@ impl SaplingNoteData { let spent = Optional::read(&mut reader, |r| { let mut txid_bytes = [0u8; 32]; r.read_exact(&mut txid_bytes)?; - Ok(TxId { 0: txid_bytes }) + Ok(TxId::from_bytes(txid_bytes)) })?; let spent_at_height = if version >= 2 { @@ -318,7 +318,7 @@ impl SaplingNoteData { let mut txid_bytes = [0u8; 32]; r.read_exact(&mut txid_bytes)?; let height = r.read_u32::()?; - Ok((TxId { 0: txid_bytes }, height)) + Ok((TxId::from_bytes(txid_bytes), height)) })? }; @@ -330,7 +330,7 @@ impl SaplingNoteData { r.read_exact(&mut txbytes)?; let height = r.read_u32::()?; - Ok((TxId { 0: txbytes }, height)) + Ok((TxId::from_bytes(txbytes), height)) })? }; @@ -392,17 +392,19 @@ impl SaplingNoteData { writer.write_all(&self.nullifier.0)?; - Optional::write(&mut writer, &self.spent, |w, (txid, h)| { - w.write_all(&txid.0)?; - w.write_u32::(*h) + Optional::write(&mut writer, self.spent, |w, (txid, h)| { + w.write_all(txid.as_ref())?; + w.write_u32::(h) })?; - Optional::write(&mut writer, &self.unconfirmed_spent, |w, (txid, height)| { - w.write_all(&txid.0)?; - w.write_u32::(*height) + Optional::write(&mut writer, self.unconfirmed_spent, |w, (txid, height)| { + w.write_all(txid.as_ref())?; + w.write_u32::(height) })?; - Optional::write(&mut writer, &self.memo, |w, m| w.write_all(m.encode().as_array()))?; + Optional::write(&mut writer, self.memo.as_ref(), |w, m| { + w.write_all(m.encode().as_array()) + })?; writer.write_u8(if self.is_change { 1 } else { 0 })?; @@ -438,7 +440,7 @@ impl Utxo { } pub fn to_outpoint(&self) -> OutPoint { - OutPoint::new(self.txid.0, self.output_index as u32) + OutPoint::new(*self.txid.as_ref(), self.output_index as u32) } pub fn read(mut reader: R) -> io::Result { @@ -452,7 +454,7 @@ impl Utxo { let mut txid_bytes = [0; 32]; reader.read_exact(&mut txid_bytes)?; - let txid = TxId { 0: txid_bytes }; + let txid = TxId::from_bytes(txid_bytes); let output_index = reader.read_u64::()?; let value = reader.read_u64::()?; @@ -467,7 +469,7 @@ impl Utxo { let spent = Optional::read(&mut reader, |r| { let mut txbytes = [0u8; 32]; r.read_exact(&mut txbytes)?; - Ok(TxId { 0: txbytes }) + Ok(TxId::from_bytes(txbytes)) })?; let spent_at_height = if version <= 1 { @@ -484,7 +486,7 @@ impl Utxo { r.read_exact(&mut txbytes)?; let height = r.read_u32::()?; - Ok((TxId { 0: txbytes }, height)) + Ok((TxId::from_bytes(txbytes), height)) })? }; @@ -507,7 +509,7 @@ impl Utxo { writer.write_u32::(self.address.as_bytes().len() as u32)?; writer.write_all(self.address.as_bytes())?; - writer.write_all(&self.txid.0)?; + writer.write_all(self.txid.as_ref())?; writer.write_u64::(self.output_index)?; writer.write_u64::(self.value)?; @@ -515,15 +517,13 @@ impl Utxo { Vector::write(&mut writer, &self.script, |w, b| w.write_all(&[*b]))?; - Optional::write(&mut writer, &self.spent, |w, txid| w.write_all(&txid.0))?; + Optional::write(&mut writer, self.spent, |w, txid| w.write_all(txid.as_ref()))?; - Optional::write(&mut writer, &self.spent_at_height, |w, s| { - w.write_i32::(*s) - })?; + Optional::write(&mut writer, self.spent_at_height, |w, s| w.write_i32::(s))?; - Optional::write(&mut writer, &self.unconfirmed_spent, |w, (txid, height)| { - w.write_all(&txid.0)?; - w.write_u32::(*height) + Optional::write(&mut writer, self.unconfirmed_spent, |w, (txid, height)| { + w.write_all(txid.as_ref())?; + w.write_u32::(height) })?; Ok(()) @@ -619,7 +619,7 @@ impl WalletTx { pub fn new_txid(txid: &Vec) -> TxId { let mut txid_bytes = [0u8; 32]; txid_bytes.copy_from_slice(txid); - TxId { 0: txid_bytes } + TxId::from_bytes(txid_bytes) } pub fn get_price(datetime: u64, price: &WalletZecPriceInfo) -> Option { @@ -670,7 +670,7 @@ impl WalletTx { let mut txid_bytes = [0u8; 32]; reader.read_exact(&mut txid_bytes)?; - let txid = TxId { 0: txid_bytes }; + let txid = TxId::from_bytes(txid_bytes); let notes = Vector::read(&mut reader, |r| SaplingNoteData::read(r))?; let utxos = Vector::read(&mut reader, |r| Utxo::read(r))?; @@ -725,7 +725,7 @@ impl WalletTx { writer.write_u64::(self.datetime)?; - writer.write_all(&self.txid.0)?; + writer.write_all(self.txid.as_ref())?; Vector::write(&mut writer, &self.notes, |w, nd| nd.write(w))?; Vector::write(&mut writer, &self.utxos, |w, u| u.write(w))?; @@ -738,7 +738,7 @@ impl WalletTx { writer.write_u8(if self.full_tx_scanned { 1 } else { 0 })?; - Optional::write(&mut writer, &self.zec_price, |w, p| w.write_f64::(*p))?; + Optional::write(&mut writer, self.zec_price, |w, p| w.write_f64::(p))?; Vector::write(&mut writer, &self.spent_nullifiers, |w, n| w.write_all(&n.0))?; @@ -844,8 +844,8 @@ impl WalletZecPriceInfo { writer.write_u64::(Self::serialized_version())?; // We don't write the currency zec price or the currency yet. - Optional::write(&mut writer, &self.last_historical_prices_fetched_at, |w, t| { - w.write_u64::(*t) + Optional::write(&mut writer, self.last_historical_prices_fetched_at, |w, t| { + w.write_u64::(t) })?; writer.write_u64::(self.historical_prices_retry_count)?; diff --git a/lib/src/lightwallet/keys.rs b/lib/src/lightwallet/keys.rs index a6e76c99..314b690e 100644 --- a/lib/src/lightwallet/keys.rs +++ b/lib/src/lightwallet/keys.rs @@ -14,10 +14,10 @@ use zcash_client_backend::{ address, encoding::{encode_extended_full_viewing_key, encode_extended_spending_key, encode_payment_address}, }; +use zcash_encoding::Vector; use zcash_primitives::{ legacy::TransparentAddress, - primitives::PaymentAddress, - serialize::Vector, + sapling::PaymentAddress, zip32::{ChildIndex, ExtendedFullViewingKey, ExtendedSpendingKey}, }; @@ -219,7 +219,7 @@ impl Keys { // Calculate the addresses let addresses = extfvks .iter() - .map(|fvk| fvk.default_address().unwrap().1) + .map(|fvk| fvk.default_address().1) .collect::>(); // If extsks is of len 0, then this wallet is locked @@ -783,7 +783,7 @@ impl Keys { ], ); let extfvk = ExtendedFullViewingKey::from(&extsk); - let address = extfvk.default_address().unwrap().1; + let address = extfvk.default_address().1; (extsk, extfvk, address) } diff --git a/lib/src/lightwallet/message.rs b/lib/src/lightwallet/message.rs index f191a397..bbe9c7b4 100644 --- a/lib/src/lightwallet/message.rs +++ b/lib/src/lightwallet/message.rs @@ -7,15 +7,17 @@ use std::{ convert::TryInto, io::{self, ErrorKind, Read}, }; +use zcash_note_encryption::{ + EphemeralKeyBytes, NoteEncryption, OutgoingCipherKey, ShieldedOutput, ENC_CIPHERTEXT_SIZE, OUT_CIPHERTEXT_SIZE, +}; use zcash_primitives::{ - consensus::{BlockHeight, MAIN_NETWORK}, + consensus::{BlockHeight, MainNetwork, MAIN_NETWORK}, keys::OutgoingViewingKey, memo::Memo, - note_encryption::{ - prf_ock, try_sapling_note_decryption, OutgoingCipherKey, SaplingNoteEncryption, ENC_CIPHERTEXT_SIZE, - OUT_CIPHERTEXT_SIZE, + sapling::{ + note_encryption::{prf_ock, try_sapling_note_decryption, SaplingDomain}, + PaymentAddress, Rseed, SaplingIvk, ValueCommitment, }, - primitives::{PaymentAddress, Rseed, SaplingIvk, ValueCommitment}, }; pub struct Message { @@ -63,7 +65,9 @@ impl Message { let cv = value_commitment.commitment().into(); // Use a rseed from pre-canopy. It doesn't really matter, but this is what is tested out. - let rseed = Rseed::BeforeZip212(jubjub::Fr::random(&mut rng)); + let mut rseed_bytes = [0u8; 32]; + rng.fill_bytes(&mut rseed_bytes); + let rseed = Rseed::AfterZip212(rseed_bytes); // 0-value note with the rseed let note = self.to.create_note(value, rseed).unwrap(); @@ -73,24 +77,29 @@ impl Message { let cmu = note.cmu(); // Create the note encrytion object - let mut ne = SaplingNoteEncryption::new(ovk, note, self.to.clone(), self.memo.clone().into(), &mut rng); + let ne = NoteEncryption::>::new( + ovk, + note, + self.to.clone(), + self.memo.clone().into(), + ); // EPK, which needs to be sent to the reciever. - let epk = ne.epk().clone().into(); + let epk = EphemeralKeyBytes::from(ne.epk().to_bytes()); // enc_ciphertext is the encrypted note, out_ciphertext is the outgoing cipher text that the // sender can recover let enc_ciphertext = ne.encrypt_note_plaintext(); - let out_ciphertext = ne.encrypt_outgoing_plaintext(&cv, &cmu); + let out_ciphertext = ne.encrypt_outgoing_plaintext(&cv, &cmu, &mut rng); // OCK is used to recover outgoing encrypted notes let ock = if ovk.is_some() { - Some(prf_ock(&ovk.unwrap(), &cv, &cmu, &epk)) + Some(prf_ock(&ovk.unwrap(), &cv, &cmu.to_bytes(), &epk)) } else { None }; - Ok((ock, cv, cmu, epk, enc_ciphertext, out_ciphertext)) + Ok((ock, cv, cmu, *ne.epk(), enc_ciphertext, out_ciphertext)) } pub fn encrypt(&self) -> Result, String> { @@ -163,16 +172,34 @@ impl Message { let mut enc_bytes = [0u8; ENC_CIPHERTEXT_SIZE]; reader.read_exact(&mut enc_bytes)?; - // Attempt decryption. We attempt at main_network at 1,000,000 height, but it doesn't - // really apply, since this note is not spendable anyway, so the rseed and the note iteself - // are not usable. + #[derive(Debug)] + struct Unspendable { + cmu_bytes: [u8; 32], + epk_bytes: [u8; 32], + enc_bytes: [u8; ENC_CIPHERTEXT_SIZE], + } + + impl ShieldedOutput, ENC_CIPHERTEXT_SIZE> for Unspendable { + fn ephemeral_key(&self) -> EphemeralKeyBytes { + EphemeralKeyBytes(self.epk_bytes) + } + fn cmstar_bytes(&self) -> [u8; 32] { + self.cmu_bytes + } + fn enc_ciphertext(&self) -> &[u8; ENC_CIPHERTEXT_SIZE] { + &self.enc_bytes + } + } + match try_sapling_note_decryption( &MAIN_NETWORK, BlockHeight::from_u32(1_000_000), &ivk, - &epk.unwrap(), - &cmu.unwrap(), - &enc_bytes, + &Unspendable { + cmu_bytes, + epk_bytes, + enc_bytes, + }, ) { Some((_note, address, memo)) => Ok(Self::new( address, @@ -186,12 +213,11 @@ impl Message { #[cfg(test)] pub mod tests { - use ff::Field; use group::GroupEncoding; - use rand::{rngs::OsRng, Rng}; + use rand::{rngs::OsRng, Rng, RngCore}; use zcash_primitives::{ memo::Memo, - primitives::{PaymentAddress, Rseed, SaplingIvk}, + sapling::{PaymentAddress, Rseed, SaplingIvk}, zip32::{ExtendedFullViewingKey, ExtendedSpendingKey}, }; @@ -204,7 +230,7 @@ pub mod tests { let extsk = ExtendedSpendingKey::master(&seed); let ivk = ExtendedFullViewingKey::from(&extsk); - let (_, addr) = ivk.default_address().unwrap(); + let (_, addr) = ivk.default_address(); (extsk, ivk.fvk.vk.ivk(), addr) } @@ -278,9 +304,11 @@ pub mod tests { assert!(dec_success.is_err()); // Create a new, random EPK - let note = to - .create_note(0, Rseed::BeforeZip212(jubjub::Fr::random(&mut rng))) - .unwrap(); + + let mut rseed_bytes = [0u8; 32]; + rng.fill_bytes(&mut rseed_bytes); + let rseed = Rseed::AfterZip212(rseed_bytes); + let note = to.create_note(0, rseed).unwrap(); let esk = note.generate_or_derive_esk(&mut rng); let epk_bad: jubjub::ExtendedPoint = (note.g_d * esk).into(); diff --git a/lib/src/lightwallet/wallet_txns.rs b/lib/src/lightwallet/wallet_txns.rs index 12649daa..f57b9668 100644 --- a/lib/src/lightwallet/wallet_txns.rs +++ b/lib/src/lightwallet/wallet_txns.rs @@ -5,13 +5,13 @@ use std::{ use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use log::error; +use zcash_encoding::Vector; use zcash_primitives::{ consensus::BlockHeight, memo::Memo, merkle_tree::IncrementalWitness, - primitives::{Note, Nullifier, PaymentAddress}, sapling::Node, - serialize::Vector, + sapling::{Note, Nullifier, PaymentAddress}, transaction::{components::TxOut, TxId}, zip32::ExtendedFullViewingKey, }; @@ -45,7 +45,7 @@ impl WalletTxns { let mut txid_bytes = [0u8; 32]; r.read_exact(&mut txid_bytes)?; - Ok((TxId { 0: txid_bytes }, WalletTx::read(r).unwrap())) + Ok((TxId::from_bytes(txid_bytes), WalletTx::read(r).unwrap())) })?; let txs = txs_tuples.into_iter().collect::>(); @@ -69,7 +69,7 @@ impl WalletTxns { let mut txid_bytes = [0u8; 32]; r.read_exact(&mut txid_bytes)?; - Ok((TxId { 0: txid_bytes }, WalletTx::read(r).unwrap())) + Ok((TxId::from_bytes(txid_bytes), WalletTx::read(r).unwrap())) })?; let current = txs_tuples.into_iter().collect::>(); @@ -90,7 +90,7 @@ impl WalletTxns { r.read_exact(&mut txid_bytes)?; let wtx = WalletTx::read(r)?; - Ok((TxId { 0: txid_bytes }, wtx)) + Ok((TxId::from_bytes(txid_bytes), wtx)) })? .into_iter() .collect() @@ -112,7 +112,7 @@ impl WalletTxns { txns.sort_by(|a, b| a.0.partial_cmp(b.0).unwrap()); Vector::write(&mut writer, &txns, |w, (k, v)| { - w.write_all(&k.0)?; + w.write_all(k.as_ref())?; v.write(w) })?; } diff --git a/lib/src/lightwallet/wallettkey.rs b/lib/src/lightwallet/wallettkey.rs index e210190b..c28ac8b4 100644 --- a/lib/src/lightwallet/wallettkey.rs +++ b/lib/src/lightwallet/wallettkey.rs @@ -5,7 +5,7 @@ use ripemd160::Digest; use secp256k1::SecretKey; use sha2::Sha256; use sodiumoxide::crypto::secretbox; -use zcash_primitives::serialize::{Optional, Vector}; +use zcash_encoding::{Optional, Vector}; use crate::{ lightclient::lightclient_config::LightClientConfig, @@ -85,8 +85,11 @@ impl WalletTKey { let suffix = bytes.split_off(32); // Assert the suffix - if suffix.len() !=1 || suffix[0] != 0x01 { - return Err(io::Error::new(ErrorKind::InvalidData, format!("Invalid Suffix: {:?}", suffix))); + if suffix.len() != 1 || suffix[0] != 0x01 { + return Err(io::Error::new( + ErrorKind::InvalidData, + format!("Invalid Suffix: {:?}", suffix), + )); } let key = SecretKey::from_slice(&bytes).map_err(|e| io::Error::new(ErrorKind::InvalidData, e))?; @@ -203,18 +206,20 @@ impl WalletTKey { out.write_u8(self.locked as u8)?; - Optional::write(&mut out, &self.key, |w, sk| w.write_all(&sk[..]))?; + Optional::write(&mut out, self.key, |w, sk| w.write_all(&sk[..]))?; utils::write_string(&mut out, &self.address)?; - Optional::write(&mut out, &self.hdkey_num, |o, n| o.write_u32::(*n))?; + Optional::write(&mut out, self.hdkey_num, |o, n| o.write_u32::(n))?; // Write enc_key - Optional::write(&mut out, &self.enc_key, |o, v| { - Vector::write(o, v, |o, n| o.write_u8(*n)) + Optional::write(&mut out, self.enc_key.as_ref(), |o, v| { + Vector::write(o, &v[..], |o, n| o.write_u8(*n)) })?; // Write nonce - Optional::write(&mut out, &self.nonce, |o, v| Vector::write(o, v, |o, n| o.write_u8(*n))) + Optional::write(&mut out, self.nonce.as_ref(), |o, v| { + Vector::write(o, &v[..], |o, n| o.write_u8(*n)) + }) } pub fn lock(&mut self) -> io::Result<()> { diff --git a/lib/src/lightwallet/walletzkey.rs b/lib/src/lightwallet/walletzkey.rs index addae77a..d1b03b8d 100644 --- a/lib/src/lightwallet/walletzkey.rs +++ b/lib/src/lightwallet/walletzkey.rs @@ -5,9 +5,9 @@ use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use sodiumoxide::crypto::secretbox; +use zcash_encoding::{Optional, Vector}; use zcash_primitives::{ - primitives::PaymentAddress, - serialize::{Optional, Vector}, + sapling::PaymentAddress, zip32::{ExtendedFullViewingKey, ExtendedSpendingKey}, }; @@ -42,7 +42,7 @@ pub struct WalletZKey { impl WalletZKey { pub fn new_hdkey(hdkey_num: u32, extsk: ExtendedSpendingKey) -> Self { let extfvk = ExtendedFullViewingKey::from(&extsk); - let zaddress = extfvk.default_address().unwrap().1; + let zaddress = extfvk.default_address().1; WalletZKey { keytype: WalletZKeyType::HdKey, @@ -57,7 +57,7 @@ impl WalletZKey { } pub fn new_locked_hdkey(hdkey_num: u32, extfvk: ExtendedFullViewingKey) -> Self { - let zaddress = extfvk.default_address().unwrap().1; + let zaddress = extfvk.default_address().1; WalletZKey { keytype: WalletZKeyType::HdKey, @@ -73,7 +73,7 @@ impl WalletZKey { pub fn new_imported_sk(extsk: ExtendedSpendingKey) -> Self { let extfvk = ExtendedFullViewingKey::from(&extsk); - let zaddress = extfvk.default_address().unwrap().1; + let zaddress = extfvk.default_address().1; WalletZKey { keytype: WalletZKeyType::ImportedSpendingKey, @@ -88,7 +88,7 @@ impl WalletZKey { } pub fn new_imported_viewkey(extfvk: ExtendedFullViewingKey) -> Self { - let zaddress = extfvk.default_address().unwrap().1; + let zaddress = extfvk.default_address().1; WalletZKey { keytype: WalletZKeyType::ImportedViewKey, @@ -132,7 +132,7 @@ impl WalletZKey { let extsk = Optional::read(&mut inp, |r| ExtendedSpendingKey::read(r))?; let extfvk = ExtendedFullViewingKey::read(&mut inp)?; - let zaddress = extfvk.default_address().unwrap().1; + let zaddress = extfvk.default_address().1; let hdkey_num = Optional::read(&mut inp, |r| r.read_u32::())?; @@ -158,19 +158,23 @@ impl WalletZKey { out.write_u8(self.locked as u8)?; - Optional::write(&mut out, &self.extsk, |w, sk| ExtendedSpendingKey::write(sk, w))?; + Optional::write(&mut out, self.extsk.as_ref(), |w, sk| { + ExtendedSpendingKey::write(&sk, w) + })?; ExtendedFullViewingKey::write(&self.extfvk, &mut out)?; - Optional::write(&mut out, &self.hdkey_num, |o, n| o.write_u32::(*n))?; + Optional::write(&mut out, self.hdkey_num, |o, n| o.write_u32::(n))?; // Write enc_key - Optional::write(&mut out, &self.enc_key, |o, v| { - Vector::write(o, v, |o, n| o.write_u8(*n)) + Optional::write(&mut out, self.enc_key.as_ref(), |o, v| { + Vector::write(o, &v[..], |o, n| o.write_u8(*n)) })?; // Write nonce - Optional::write(&mut out, &self.nonce, |o, v| Vector::write(o, v, |o, n| o.write_u8(*n))) + Optional::write(&mut out, self.nonce.as_ref(), |o, v| { + Vector::write(o, &v[..], |o, n| o.write_u8(*n)) + }) } pub fn lock(&mut self) -> io::Result<()> { @@ -393,7 +397,7 @@ pub mod tests { { assert!(wzk.extsk.is_none()); assert_eq!(wzk.locked, true); - assert_eq!(wzk.zaddress, wzk.extfvk.default_address().unwrap().1); + assert_eq!(wzk.zaddress, wzk.extfvk.default_address().1); } // Can't remove encryption without unlocking @@ -445,7 +449,7 @@ pub mod tests { { assert!(wzk.extsk.is_none()); assert_eq!(wzk.locked, true); - assert_eq!(wzk.zaddress, wzk.extfvk.default_address().unwrap().1); + assert_eq!(wzk.zaddress, wzk.extfvk.default_address().1); } // Can't remove encryption without unlocking diff --git a/rust-toolchain b/rust-toolchain index d96ae405..43c989b5 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.52 +1.56.1