diff --git a/.cargo/config.offline b/.cargo/config.offline index 260b4c3ae..1f8659ab3 100644 --- a/.cargo/config.offline +++ b/.cargo/config.offline @@ -1,29 +1,9 @@ [source.crates-io] replace-with = "vendored-sources" -[source."https://github.com/ZcashFoundation/ed25519-zebra.git"] -git = "https://github.com/ZcashFoundation/ed25519-zebra.git" -rev = "d3512400227a362d08367088ffaa9bd4142a69c7" -replace-with = "vendored-sources" - -[source."https://github.com/str4d/redjubjub.git"] -git = "https://github.com/str4d/redjubjub.git" -rev = "416a6a8ebf8bd42c114c938883016c04f338de72" -replace-with = "vendored-sources" - -[source."https://github.com/zcash/incrementalmerkletree"] -git = "https://github.com/zcash/incrementalmerkletree" -rev = "b7bd6246122a6e9ace8edb51553fbf5228906cbb" -replace-with = "vendored-sources" - [source."https://github.com/zcash/librustzcash.git"] git = "https://github.com/zcash/librustzcash.git" -rev = "53d0a51d33a421cb76d3e3124d1e4c1c9036068e" -replace-with = "vendored-sources" - -[source."https://github.com/zcash/orchard.git"] -git = "https://github.com/zcash/orchard.git" -rev = "2c8241f25b943aa05203eacf9905db117c69bd29" +rev = "5622b060b1f57de7afc3d0b4e425b9b4b22482a0" replace-with = "vendored-sources" [source.vendored-sources] diff --git a/Cargo.lock b/Cargo.lock index a2119f065..3398f845f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,7 +17,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cipher", "cpufeatures", "opaque-debug", @@ -72,11 +72,11 @@ checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] name = "atomic-shim" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20fdac7156779a1a30d970e838195558b4810dd06aa69e7c7461bdc518edf9b" +checksum = "67cd4b51d303cf3501c301e8125df442128d3c6d7c69f71b27833d253de47e77" dependencies = [ - "crossbeam", + "crossbeam-utils", ] [[package]] @@ -104,9 +104,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0944d18a9a37691b87733b39c9360c9950af9aa5f97e2455bc108d8eb64fc1c1" dependencies = [ "bitvec", - "blake2s_simd", + "blake2s_simd 0.5.11", "byteorder", - "crossbeam-channel 0.5.1", + "crossbeam-channel", "ff", "group", "lazy_static", @@ -171,6 +171,17 @@ dependencies = [ "constant_time_eq", ] +[[package]] +name = "blake2b_simd" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72936ee4afc7f8f736d1c38383b56480b5497b4617b4a77bdbf1d2ababc76127" +dependencies = [ + "arrayref", + "arrayvec 0.7.2", + "constant_time_eq", +] + [[package]] name = "blake2s_simd" version = "0.5.11" @@ -182,6 +193,17 @@ dependencies = [ "constant_time_eq", ] +[[package]] +name = "blake2s_simd" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db539cc2b5f6003621f1cd9ef92d7ded8ea5232c7de0f9faa2de251cd98730d4" +dependencies = [ + "arrayref", + "arrayvec 0.7.2", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -247,12 +269,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -265,7 +281,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cipher", "cpufeatures", "zeroize", @@ -308,49 +324,14 @@ dependencies = [ "libc", ] -[[package]] -name = "crossbeam" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" -dependencies = [ - "cfg-if 0.1.10", - "crossbeam-channel 0.4.4", - "crossbeam-deque 0.7.4", - "crossbeam-epoch 0.8.2", - "crossbeam-queue", - "crossbeam-utils 0.7.2", -] - -[[package]] -name = "crossbeam-channel" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" -dependencies = [ - "crossbeam-utils 0.7.2", - "maybe-uninit", -] - [[package]] name = "crossbeam-channel" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils 0.8.5", -] - -[[package]] -name = "crossbeam-deque" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20ff29ded3204c5106278a81a38f4b482636ed4fa1e6cfbeef193291beb29ed" -dependencies = [ - "crossbeam-epoch 0.8.2", - "crossbeam-utils 0.7.2", - "maybe-uninit", + "cfg-if", + "crossbeam-utils", ] [[package]] @@ -359,24 +340,9 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" dependencies = [ - "cfg-if 1.0.0", - "crossbeam-epoch 0.9.5", - "crossbeam-utils 0.8.5", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" -dependencies = [ - "autocfg", - "cfg-if 0.1.10", - "crossbeam-utils 0.7.2", - "lazy_static", - "maybe-uninit", - "memoffset 0.5.6", - "scopeguard", + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", ] [[package]] @@ -385,42 +351,20 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils 0.8.5", + "cfg-if", + "crossbeam-utils", "lazy_static", - "memoffset 0.6.4", + "memoffset", "scopeguard", ] -[[package]] -name = "crossbeam-queue" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" -dependencies = [ - "cfg-if 0.1.10", - "crossbeam-utils 0.7.2", - "maybe-uninit", -] - -[[package]] -name = "crossbeam-utils" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -dependencies = [ - "autocfg", - "cfg-if 0.1.10", - "lazy_static", -] - [[package]] name = "crossbeam-utils" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "lazy_static", ] @@ -459,7 +403,7 @@ version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "num_cpus", ] @@ -494,8 +438,9 @@ dependencies = [ [[package]] name = "ed25519-zebra" -version = "2.2.0" -source = "git+https://github.com/ZcashFoundation/ed25519-zebra.git?rev=d3512400227a362d08367088ffaa9bd4142a69c7#d3512400227a362d08367088ffaa9bd4142a69c7" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" dependencies = [ "curve25519-dalek", "hex", @@ -521,18 +466,18 @@ checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" [[package]] name = "equihash" version = "0.1.0" -source = "git+https://github.com/zcash/librustzcash.git?rev=69c3b4b5e143bb349cca76c677b7cd0a8556b28f#69c3b4b5e143bb349cca76c677b7cd0a8556b28f" +source = "git+https://github.com/zcash/librustzcash.git?rev=5622b060b1f57de7afc3d0b4e425b9b4b22482a0#5622b060b1f57de7afc3d0b4e425b9b4b22482a0" dependencies = [ - "blake2b_simd", + "blake2b_simd 1.0.0", "byteorder", ] [[package]] name = "f4jumble" version = "0.0.0" -source = "git+https://github.com/zcash/librustzcash.git?rev=69c3b4b5e143bb349cca76c677b7cd0a8556b28f#69c3b4b5e143bb349cca76c677b7cd0a8556b28f" +source = "git+https://github.com/zcash/librustzcash.git?rev=5622b060b1f57de7afc3d0b4e425b9b4b22482a0#5622b060b1f57de7afc3d0b4e425b9b4b22482a0" dependencies = [ - "blake2b_simd", + "blake2b_simd 1.0.0", ] [[package]] @@ -622,7 +567,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi 0.9.0+wasi-snapshot-preview1", ] @@ -633,7 +578,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi 0.10.2+wasi-snapshot-preview1", ] @@ -656,7 +601,7 @@ version = "0.1.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f186b85ed81082fb1cf59d52b0111f02915e89a4ac61d292b38d075e570f3a9" dependencies = [ - "blake2b_simd", + "blake2b_simd 0.5.11", "ff", "group", "pasta_curves", @@ -757,8 +702,9 @@ dependencies = [ [[package]] name = "incrementalmerkletree" -version = "0.1.0" -source = "git+https://github.com/zcash/incrementalmerkletree?rev=b7bd6246122a6e9ace8edb51553fbf5228906cbb#b7bd6246122a6e9ace8edb51553fbf5228906cbb" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186fd3ab92aeac865d4b80b410de9a7b341d31ba8281373caed0b6d17b2b5e96" dependencies = [ "serde", ] @@ -779,7 +725,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -825,9 +771,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.106" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "libm" @@ -840,8 +786,8 @@ name = "librustzcash" version = "0.2.0" dependencies = [ "bellman", - "blake2b_simd", - "blake2s_simd", + "blake2b_simd 1.0.0", + "blake2s_simd 1.0.0", "bls12_381", "byteorder", "ed25519-zebra", @@ -887,7 +833,7 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -908,12 +854,6 @@ dependencies = [ "regex-automata", ] -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - [[package]] name = "memchr" version = "2.4.1" @@ -922,18 +862,9 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "memoffset" -version = "0.5.6" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" -dependencies = [ - "autocfg", -] - -[[package]] -name = "memoffset" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg", ] @@ -990,15 +921,15 @@ dependencies = [ [[package]] name = "metrics-util" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74c9b6aee519e1461b678952d3671652bb341d0664b1188f895a436a4e2e6ffa" +checksum = "1174223789e331d9d47a4a953dac36e397db60fa8d2a111ac505388c6c7fe32e" dependencies = [ "ahash", "aho-corasick", "atomic-shim", - "crossbeam-epoch 0.9.5", - "crossbeam-utils 0.8.5", + "crossbeam-epoch", + "crossbeam-utils", "dashmap", "hashbrown", "indexmap", @@ -1099,9 +1030,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" [[package]] name = "opaque-debug" @@ -1111,14 +1042,15 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "orchard" -version = "0.0.0" -source = "git+https://github.com/zcash/orchard.git?rev=68b790c7dadade049f44ad4aafa0ff71a3a10e91#68b790c7dadade049f44ad4aafa0ff71a3a10e91" +version = "0.1.0-beta.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31f03b6d0aee6d993cac35388b818e04f076ded0ab284979e4d7cd5a8b3c2be" dependencies = [ "aes", "arrayvec 0.7.2", "bigint", "bitvec", - "blake2b_simd", + "blake2b_simd 1.0.0", "ff", "fpe", "group", @@ -1170,7 +1102,7 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "instant", "libc", "redox_syscall", @@ -1195,7 +1127,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d647d91972bad78120fd61e06b225fcda117805c9bbf17676b51bd03a251278b" dependencies = [ - "blake2b_simd", + "blake2b_simd 0.5.11", "ff", "group", "lazy_static", @@ -1271,9 +1203,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.32" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1" dependencies = [ "unicode-xid", ] @@ -1284,7 +1216,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20afe714292d5e879d8b12740aa223c6a88f118af41870e8b6196e39a02238a8" dependencies = [ - "crossbeam-utils 0.8.5", + "crossbeam-utils", "libc", "mach", "once_cell", @@ -1384,7 +1316,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" dependencies = [ "autocfg", - "crossbeam-deque 0.8.1", + "crossbeam-deque", "either", "rayon-core", ] @@ -1395,9 +1327,9 @@ version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" dependencies = [ - "crossbeam-channel 0.5.1", - "crossbeam-deque 0.8.1", - "crossbeam-utils 0.8.5", + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", "lazy_static", "num_cpus", ] @@ -1408,7 +1340,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a90e2c94bca3445cae0d55dff7370e29c24885d2403a1665ce19c106c79455e6" dependencies = [ - "blake2b_simd", + "blake2b_simd 0.5.11", "byteorder", "digest", "group", @@ -1473,18 +1405,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.130" +version = "1.0.131" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "b4ad69dfbd3e45369132cc64e6748c2d65cdfb001a2b1c232d128b4ad60561c1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.131" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "b710a83c4e0dff6a3d511946b95274ad9ca9e5d3ae497b63fda866ac955358d2" dependencies = [ "proc-macro2", "quote", @@ -1498,7 +1430,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" dependencies = [ "block-buffer", - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest", "opaque-debug", @@ -1531,7 +1463,7 @@ version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "winapi", ] @@ -1550,9 +1482,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" +checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" dependencies = [ "proc-macro2", "quote", @@ -1608,9 +1540,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99beeb0daeac2bd1e86ac2c21caddecb244b39a093594da1a661ec2060c7aedd" +checksum = "41effe7cfa8af36f439fac33861b66b049edc6f9a32331e2312660529c1c24ad" dependencies = [ "itoa", "libc", @@ -1618,9 +1550,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83b2a3d4d9091d0abd7eba4dc2710b1718583bd4d8992e2190720ea38f391f7" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" dependencies = [ "tinyvec_macros", ] @@ -1633,11 +1565,10 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "588b2d10a336da58d877567cd8fb8a14b463e2104910f8132cd054b4b96e29ee" +checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" dependencies = [ - "autocfg", "libc", "mio", "pin-project-lite", @@ -1647,9 +1578,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.5.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "114383b041aa6212c579467afa0075fbbdd0718de036100bc0ba7961d8cb9095" +checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" dependencies = [ "proc-macro2", "quote", @@ -1668,7 +1599,7 @@ version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1680,7 +1611,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94571df2eae3ed4353815ea5a90974a594a1792d8782ff2cbcc9392d1101f366" dependencies = [ - "crossbeam-channel 0.5.1", + "crossbeam-channel", "time", "tracing-subscriber", ] @@ -1707,9 +1638,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80a4ddde70311d8da398062ecf6fc2c309337de6b0f77d6c27aff8d53f6fca52" +checksum = "245da694cc7fc4729f3f418b304cb57789f1bed2a78c575407ab8a23f53cb4d3" dependencies = [ "ansi_term", "lazy_static", @@ -1793,7 +1724,7 @@ version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] @@ -1885,10 +1816,10 @@ dependencies = [ [[package]] name = "zcash_address" version = "0.0.0" -source = "git+https://github.com/zcash/librustzcash.git?rev=69c3b4b5e143bb349cca76c677b7cd0a8556b28f#69c3b4b5e143bb349cca76c677b7cd0a8556b28f" +source = "git+https://github.com/zcash/librustzcash.git?rev=5622b060b1f57de7afc3d0b4e425b9b4b22482a0#5622b060b1f57de7afc3d0b4e425b9b4b22482a0" dependencies = [ "bech32", - "blake2b_simd", + "blake2b_simd 1.0.0", "bs58", "f4jumble", "zcash_encoding", @@ -1897,7 +1828,7 @@ dependencies = [ [[package]] name = "zcash_encoding" version = "0.0.0" -source = "git+https://github.com/zcash/librustzcash.git?rev=69c3b4b5e143bb349cca76c677b7cd0a8556b28f#69c3b4b5e143bb349cca76c677b7cd0a8556b28f" +source = "git+https://github.com/zcash/librustzcash.git?rev=5622b060b1f57de7afc3d0b4e425b9b4b22482a0#5622b060b1f57de7afc3d0b4e425b9b4b22482a0" dependencies = [ "byteorder", "nonempty", @@ -1906,24 +1837,20 @@ dependencies = [ [[package]] name = "zcash_history" version = "0.2.0" -source = "git+https://github.com/zcash/librustzcash.git?rev=69c3b4b5e143bb349cca76c677b7cd0a8556b28f#69c3b4b5e143bb349cca76c677b7cd0a8556b28f" +source = "git+https://github.com/zcash/librustzcash.git?rev=5622b060b1f57de7afc3d0b4e425b9b4b22482a0#5622b060b1f57de7afc3d0b4e425b9b4b22482a0" dependencies = [ "bigint", - "blake2b_simd", + "blake2b_simd 1.0.0", "byteorder", ] [[package]] name = "zcash_note_encryption" -version = "0.0.0" -source = "git+https://github.com/zcash/librustzcash.git?rev=69c3b4b5e143bb349cca76c677b7cd0a8556b28f#69c3b4b5e143bb349cca76c677b7cd0a8556b28f" +version = "0.1.0" +source = "git+https://github.com/zcash/librustzcash.git?rev=5622b060b1f57de7afc3d0b4e425b9b4b22482a0#5622b060b1f57de7afc3d0b4e425b9b4b22482a0" dependencies = [ - "blake2b_simd", - "byteorder", "chacha20", "chacha20poly1305", - "ff", - "group", "rand_core 0.6.3", "subtle", ] @@ -1931,13 +1858,13 @@ dependencies = [ [[package]] name = "zcash_primitives" version = "0.5.0" -source = "git+https://github.com/zcash/librustzcash.git?rev=69c3b4b5e143bb349cca76c677b7cd0a8556b28f#69c3b4b5e143bb349cca76c677b7cd0a8556b28f" +source = "git+https://github.com/zcash/librustzcash.git?rev=5622b060b1f57de7afc3d0b4e425b9b4b22482a0#5622b060b1f57de7afc3d0b4e425b9b4b22482a0" dependencies = [ "aes", "bip0039", "bitvec", - "blake2b_simd", - "blake2s_simd", + "blake2b_simd 1.0.0", + "blake2s_simd 1.0.0", "bls12_381", "byteorder", "chacha20poly1305", @@ -1965,10 +1892,10 @@ dependencies = [ [[package]] name = "zcash_proofs" version = "0.5.0" -source = "git+https://github.com/zcash/librustzcash.git?rev=69c3b4b5e143bb349cca76c677b7cd0a8556b28f#69c3b4b5e143bb349cca76c677b7cd0a8556b28f" +source = "git+https://github.com/zcash/librustzcash.git?rev=5622b060b1f57de7afc3d0b4e425b9b4b22482a0#5622b060b1f57de7afc3d0b4e425b9b4b22482a0" dependencies = [ "bellman", - "blake2b_simd", + "blake2b_simd 1.0.0", "bls12_381", "byteorder", "directories", diff --git a/Cargo.toml b/Cargo.toml index 9e7113993..ff661db05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,17 +27,17 @@ crate-type = ["staticlib"] [dependencies] bellman = "0.11" -blake2b_simd = "0.5" -blake2s_simd = "0.5" +blake2b_simd = "1" +blake2s_simd = "1" bls12_381 = "0.6" byteorder = "1" group = "0.11" -incrementalmerkletree = "0.1" +incrementalmerkletree = "0.2" libc = "0.2" jubjub = "0.8" memuse = "0.2" nonempty = "0.7" -orchard = "0.0" +orchard = "=0.1.0-beta.1" subtle = "2.2" rand_core = "0.6" tracing = "0.1" @@ -45,10 +45,10 @@ tracing-core = "0.1" tracing-appender = "0.2" zcash_address = "0.0" zcash_history = "0.2" -zcash_note_encryption = "0.0" +zcash_note_encryption = "0.1" zcash_primitives = "0.5" zcash_proofs = "0.5" -ed25519-zebra = "2.2.0" +ed25519-zebra = "3" zeroize = "1.4.2" # Metrics @@ -70,11 +70,8 @@ panic = 'abort' codegen-units = 1 [patch.crates-io] -ed25519-zebra = { git = "https://github.com/ZcashFoundation/ed25519-zebra.git", rev = "d3512400227a362d08367088ffaa9bd4142a69c7" } -incrementalmerkletree = { git = "https://github.com/zcash/incrementalmerkletree", rev = "b7bd6246122a6e9ace8edb51553fbf5228906cbb" } -orchard = { git = "https://github.com/zcash/orchard.git", rev = "68b790c7dadade049f44ad4aafa0ff71a3a10e91" } -zcash_address = { git = "https://github.com/zcash/librustzcash.git", rev = "69c3b4b5e143bb349cca76c677b7cd0a8556b28f" } -zcash_history = { git = "https://github.com/zcash/librustzcash.git", rev = "69c3b4b5e143bb349cca76c677b7cd0a8556b28f" } -zcash_note_encryption = { git = "https://github.com/zcash/librustzcash.git", rev = "69c3b4b5e143bb349cca76c677b7cd0a8556b28f" } -zcash_primitives = { git = "https://github.com/zcash/librustzcash.git", rev = "69c3b4b5e143bb349cca76c677b7cd0a8556b28f" } -zcash_proofs = { git = "https://github.com/zcash/librustzcash.git", rev = "69c3b4b5e143bb349cca76c677b7cd0a8556b28f" } +zcash_address = { git = "https://github.com/zcash/librustzcash.git", rev = "5622b060b1f57de7afc3d0b4e425b9b4b22482a0" } +zcash_history = { git = "https://github.com/zcash/librustzcash.git", rev = "5622b060b1f57de7afc3d0b4e425b9b4b22482a0" } +zcash_note_encryption = { git = "https://github.com/zcash/librustzcash.git", rev = "5622b060b1f57de7afc3d0b4e425b9b4b22482a0" } +zcash_primitives = { git = "https://github.com/zcash/librustzcash.git", rev = "5622b060b1f57de7afc3d0b4e425b9b4b22482a0" } +zcash_proofs = { git = "https://github.com/zcash/librustzcash.git", rev = "5622b060b1f57de7afc3d0b4e425b9b4b22482a0" } diff --git a/README.md b/README.md index 230a51221..5a276efa5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Zcash 4.5.1-1 +Zcash 4.6.0-1 =========== diff --git a/configure.ac b/configure.ac index cbd7e8c65..4162fa308 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 4) -define(_CLIENT_VERSION_MINOR, 5) -define(_CLIENT_VERSION_REVISION, 1) +define(_CLIENT_VERSION_MINOR, 6) +define(_CLIENT_VERSION_REVISION, 0) define(_CLIENT_VERSION_BUILD, 51) define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50))) define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1))) diff --git a/contrib/debian/changelog b/contrib/debian/changelog index 244daae21..84754abf5 100644 --- a/contrib/debian/changelog +++ b/contrib/debian/changelog @@ -1,3 +1,21 @@ +zcash (4.6.0+1) stable; urgency=medium + + * 4.6.0-1 release. + + -- Electric Coin Company Wed, 05 Jan 2022 20:18:43 +0000 + +zcash (4.6.0) stable; urgency=medium + + * 4.6.0 release. + + -- Electric Coin Company Thu, 23 Dec 2021 00:35:41 +0000 + +zcash (4.6.0~rc1) stable; urgency=medium + + * 4.6.0-rc1 release. + + -- Electric Coin Company Sat, 18 Dec 2021 04:25:50 +0000 + zcash (4.5.1+1) stable; urgency=medium * 4.5.1-1 release. diff --git a/contrib/devtools/update-rust-hashes.sh b/contrib/devtools/update-rust-hashes.sh new file mode 100755 index 000000000..ad036bebf --- /dev/null +++ b/contrib/devtools/update-rust-hashes.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +export LC_ALL=C + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +RUST_PACKAGE="$SCRIPT_DIR/../../depends/packages/native_rust.mk" + +RUST_VERSION=$( cat $RUST_PACKAGE | grep -oP "_version=\K.*" ) + +update_hash() { + url="https://static.rust-lang.org/dist/$1-$RUST_VERSION-$2.tar.gz" + echo "Fetching $url" + hash=$( curl $url | sha256sum | awk '{print $1}' ) + sed -i "/\$(package)_$3_$4=/c\\\$(package)_$3_$4=$hash" $RUST_PACKAGE +} + +update_rust_hash() { + update_hash rust $1 sha256_hash $2 +} + +update_stdlib_hash() { + update_hash rust-std $1 rust_std_sha256_hash $1 +} + +# For native targets +# update_rust_hash RUST_TARGET MAKEFILE_PACKAGE_IDENTIFIER +update_rust_hash aarch64-unknown-linux-gnu aarch64_linux +update_rust_hash x86_64-apple-darwin darwin +update_rust_hash x86_64-unknown-linux-gnu linux +update_rust_hash x86_64-unknown-freebsd freebsd + +# For cross-compilation targets +# update_stdlib_hash RUST_TARGET +update_stdlib_hash aarch64-unknown-linux-gnu +update_stdlib_hash x86_64-apple-darwin +update_stdlib_hash x86_64-pc-windows-gnu +update_stdlib_hash x86_64-unknown-freebsd diff --git a/contrib/docker/README.md b/contrib/docker/README.md index 912604517..69f5b7e9d 100644 --- a/contrib/docker/README.md +++ b/contrib/docker/README.md @@ -76,7 +76,7 @@ mkdir {./zcash-params-dir,./zcash-data-dir} sudo chown -R 2001.2001 {./zcash-params-dir,./zcash-data-dir} docker run -d --name my_zcashd \ -v $(pwd)/zcash-data-dir:/srv/zcashd/.zcash \ - -v $(pwd)/zcash-params-dir/srv/zcashd/.zcash-params \ + -v $(pwd)/zcash-params-dir:/srv/zcashd/.zcash-params \ electriccoinco/zcashd ``` diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 4f6f2cdfb..69db0cca2 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -1,5 +1,5 @@ --- -name: "zcash-4.5.1-1" +name: "zcash-4.6.0-1" enable_cache: true distro: "debian" suites: @@ -18,6 +18,7 @@ packages: - "g++-multilib" - "git-core" - "libc6-dev" +- "libtinfo5" - "libtool" - "libxml2" - "m4" diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 2f961fa7b..f64c3474e 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,8 +1,8 @@ package=boost -$(package)_version=1_77_0 +$(package)_version=1_78_0 $(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$(subst _,.,$($(package)_version))/source/ $(package)_file_name=boost_$($(package)_version).tar.bz2 -$(package)_sha256_hash=fc9f85fc030e233142908241af7a846e60630aa7388de9a5fafb1f3a26840854 +$(package)_sha256_hash=8681f175d4bdb26c52222665793eef08490d7758529330f98d3b29dd0735bccc $(package)_dependencies=native_b2 ifneq ($(host_os),darwin) diff --git a/depends/packages/native_rust.mk b/depends/packages/native_rust.mk index 045df4444..3b3f0ea4c 100644 --- a/depends/packages/native_rust.mk +++ b/depends/packages/native_rust.mk @@ -1,14 +1,14 @@ package=native_rust -$(package)_version=1.56.1 +$(package)_version=1.57.0 $(package)_download_path=https://static.rust-lang.org/dist $(package)_file_name_linux=rust-$($(package)_version)-x86_64-unknown-linux-gnu.tar.gz -$(package)_sha256_hash_linux=a6be5d045183a0b12dddf0d81633e2a64e63e4c2dfa44eb7593970c1ef93a98f +$(package)_sha256_hash_linux=ea0253784b2e5c22659ff148d492a68d2e11da734491714ebc61cc93896efcda $(package)_file_name_darwin=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz -$(package)_sha256_hash_darwin=8d65ef02a123c23be00101fb204d28b60498b9145dd2ee8edabf0afde6e01e55 +$(package)_sha256_hash_darwin=15ceffc4743434c19d08f73fb4edd6642b7fd8162ed7101d3e6ca2c691fcb699 $(package)_file_name_freebsd=rust-$($(package)_version)-x86_64-unknown-freebsd.tar.gz -$(package)_sha256_hash_freebsd=94e2c8b44af125ca8ba1a1ded7e7b9c5acb27e52acec4ab483d5ed9a8528c5a9 +$(package)_sha256_hash_freebsd=ebe96fa1f15e8d70c91e81aab7e0c341717b909225029f37d52fbdfa506e3fab $(package)_file_name_aarch64_linux=rust-$($(package)_version)-aarch64-unknown-linux-gnu.tar.gz -$(package)_sha256_hash_aarch64_linux=69792887357c8dd78c5424f0b4a624578296796d99edf6c30ebe2acc2b939aa3 +$(package)_sha256_hash_aarch64_linux=d66847f7cf7b548ecb328c400ac4f691ee2aea6ff5cd9286ad8733239569556c # Mapping from GCC canonical hosts to Rust targets # If a mapping is not present, we assume they are identical, unless $host_os is @@ -17,9 +17,10 @@ $(package)_rust_target_x86_64-pc-linux-gnu=x86_64-unknown-linux-gnu $(package)_rust_target_x86_64-w64-mingw32=x86_64-pc-windows-gnu # Mapping from Rust targets to SHA-256 hashes -$(package)_rust_std_sha256_hash_aarch64-unknown-linux-gnu=d577c25879cf160ec1a04d5101971dd684f9b4f87b3cb463a7521b676dc3df89 -$(package)_rust_std_sha256_hash_x86_64-apple-darwin=a1cedfaea1508bf3bfc8a77d82d15c693b41e70e56fad930d24f21f0bce5052a -$(package)_rust_std_sha256_hash_x86_64-pc-windows-gnu=8c5d425d2882a93827850672a70bfc2e643cae425aaffa9dafa6808fcd4bc798 +$(package)_rust_std_sha256_hash_aarch64-unknown-linux-gnu=4c70901d1cbddec9ea99fbd62b20f454d30e1ffbb48a21169ac823b3f02a1fbc +$(package)_rust_std_sha256_hash_x86_64-apple-darwin=c1eb892ddb50ebeed288b7aa8171ad46d62362bb26b2d82d2b463dfd45606dc2 +$(package)_rust_std_sha256_hash_x86_64-pc-windows-gnu=75c910899ed36a90b155e3a01c21b863000675867efc56f2b68c44edd4b7e18c +$(package)_rust_std_sha256_hash_x86_64-unknown-freebsd=1528a4bc7e3ba42da164bcc7b952dfa73048333c5b9254ce2d03db6bab6081e8 define rust_target $(if $($(1)_rust_target_$(2)),$($(1)_rust_target_$(2)),$(if $(findstring darwin,$(3)),x86_64-apple-darwin,$(if $(findstring freebsd,$(3)),x86_64-unknown-freebsd,$(2)))) diff --git a/doc/authors.md b/doc/authors.md index 60093355b..c7d8886dd 100644 --- a/doc/authors.md +++ b/doc/authors.md @@ -1,29 +1,29 @@ Zcash Contributors ================== -Jack Grigg (1123) +Jack Grigg (1127) Simon Liu (460) Sean Bowe (367) Daira Hopwood (270) Eirik Ogilvie-Wigley (216) -Kris Nuttycombe (174) +Kris Nuttycombe (181) Wladimir J. van der Laan (150) Alfredo Garcia (116) Taylor Hornby (114) -Marshall Gaucher (110) +Marshall Gaucher (111) Pieter Wuille (102) Jonas Schnelli (89) Jay Graber (89) -Marco Falke (81) +Marco Falke (82) Cory Fields (75) -Larry Ruane (61) +Larry Ruane (72) Ying Tong Lai (56) Nathan Wilcox (56) Matt Corallo (52) practicalswift (38) Kevin Gallagher (38) fanquake (36) -Dimitris Apostolou (34) +Dimitris Apostolou (35) Carl Dong (26) Gregory Maxwell (23) Jorge Timón (22) @@ -46,12 +46,13 @@ Alex Morcos (11) Philip Kaufmann (10) Peter Todd (10) João Barbosa (10) +Charlie O'Keefe (10) nomnombtc (9) Marius Kjærstad (9) +teor (8) kozyilmaz (8) Jeremy Rubin (8) Jeff Garzik (8) -Charlie O'Keefe (8) Ben Wilson (8) Karl-Johan Alm (7) ying tong (6) @@ -63,6 +64,7 @@ Chun Kuan Lee (6) Casey Rodarmor (6) jnewbery (5) ca333 (5) +Sasha (5) MeshCollider (5) Johnathan Corgan (5) George Tankersley (5) @@ -75,6 +77,7 @@ WO (4) Sjors Provoost (4) Russell Yanofsky (4) Nate Wilcox (4) +Alex Wied (4) mruddy (3) lpescher (3) isle2983 (3) @@ -90,7 +93,6 @@ Eric Lombrozo (3) Danny Willems (3) Anthony Towns (3) Alfie John (3) -Alex Wied (3) whythat (2) rofl0r (2) ptschip (2) @@ -134,7 +136,7 @@ vim88 (1) unsystemizer (1) tulip (1) tpantin (1) -teor (1) +sgmoore (1) randy-waterhouse (1) plutoforever (1) murrayn (1) @@ -202,6 +204,7 @@ Josh Ellithorpe (1) Jonas Nick (1) Jesse Cohen (1) Jeffrey Walton (1) +Janito Vaqueiro Ferreira Filho (1) Jainan-Tandel (1) Igor Cota (1) Ian T (1) diff --git a/doc/man/zcash-cli.1 b/doc/man/zcash-cli.1 index 152d423b1..51ebcfcf1 100644 --- a/doc/man/zcash-cli.1 +++ b/doc/man/zcash-cli.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13. -.TH ZCASH-CLI "1" "October 2021" "zcash-cli v4.5.1-1" "User Commands" +.TH ZCASH-CLI "1" "January 2022" "zcash-cli v4.6.0-1" "User Commands" .SH NAME -zcash-cli \- manual page for zcash-cli v4.5.1-1 +zcash-cli \- manual page for zcash-cli v4.6.0-1 .SH DESCRIPTION -Zcash RPC client version v4.5.1\-1 +Zcash RPC client version v4.6.0\-1 .PP In order to ensure you are adequately protecting your privacy when using Zcash, please see . diff --git a/doc/man/zcash-tx.1 b/doc/man/zcash-tx.1 index 07d0a5b9e..ddb563fcf 100644 --- a/doc/man/zcash-tx.1 +++ b/doc/man/zcash-tx.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13. -.TH ZCASH-TX "1" "October 2021" "zcash-tx v4.5.1-1" "User Commands" +.TH ZCASH-TX "1" "January 2022" "zcash-tx v4.6.0-1" "User Commands" .SH NAME -zcash-tx \- manual page for zcash-tx v4.5.1-1 +zcash-tx \- manual page for zcash-tx v4.6.0-1 .SH DESCRIPTION -Zcash zcash\-tx utility version v4.5.1\-1 +Zcash zcash\-tx utility version v4.6.0\-1 .SS "Usage:" .TP zcash\-tx [options] [commands] diff --git a/doc/man/zcashd.1 b/doc/man/zcashd.1 index d86cd12b8..cb512e41c 100644 --- a/doc/man/zcashd.1 +++ b/doc/man/zcashd.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13. -.TH ZCASHD "1" "October 2021" "zcashd v4.5.1-1" "User Commands" +.TH ZCASHD "1" "January 2022" "zcashd v4.6.0-1" "User Commands" .SH NAME -zcashd \- manual page for zcashd v4.5.1-1 +zcashd \- manual page for zcashd v4.6.0-1 .SH DESCRIPTION -Zcash Daemon version v4.5.1\-1 +Zcash Daemon version v4.6.0\-1 .PP In order to ensure you are adequately protecting your privacy when using Zcash, please see . diff --git a/doc/release-notes/release-notes-4.6.0-1.md b/doc/release-notes/release-notes-4.6.0-1.md new file mode 100644 index 000000000..975376aa1 --- /dev/null +++ b/doc/release-notes/release-notes-4.6.0-1.md @@ -0,0 +1,37 @@ +`getblocktemplate` regression fix +================================= + +We added support for the NU5 consensus rules in v4.5.0, which alters the +block header to contain a `hashBlockCommitments` value instead of the +chain history root. However, the output of `getblocktemplate` wasn't +returning this value; once NU5 activated, the `blockcommitmentshash` +field was being set to "null" (all-zeroes). + +In v4.6.0 we added full NU5 support to `getblocktemplate`, by adding a +`defaultroots` field that gave default values for `hashBlockCommitments` +and the components required to derive it. However, in doing so we +introduced a regression in the (now-deprecated) legacy fields, where +prior to NU5 activation they contained nonsense. + +This release fixes the output of `getblocktemplate` to have the intended +semantics for all fields: + +- The `blockcommitmentshash` and `authdataroot` fields in `defaultroots` + are now omitted from block templates for heights before NU5 activation. + +- The legacy fields now always contain the default value to be placed + into the block header (regaining their previous semantics). + +Changelog +========= + +Jack Grigg (3): + rpc: Fix regression in getblocktemplate output + make-release.py: Versioning changes for 4.6.0-1. + make-release.py: Updated manpages for 4.6.0-1. + +Larry Ruane (3): + assert that the return value of submitblock is None + test: check getblocktemplate output before and after NU5 + test: Fix ZIP 244 implementation + diff --git a/doc/release-notes/release-notes-4.6.0-rc1.md b/doc/release-notes/release-notes-4.6.0-rc1.md new file mode 100644 index 000000000..1bfd543d0 --- /dev/null +++ b/doc/release-notes/release-notes-4.6.0-rc1.md @@ -0,0 +1,111 @@ +Notable changes +=============== + +Wallet +------ + +From this release, newly-created wallets will save the chain name ("Zcash") and +network identifier (e.g. "main") to the `wallet.dat` file. This will enable the +`zcashd` node to check on subsequent starts that the `wallet.dat` file matches +the node's configuration. Existing wallets will start saving this information in +a later release. + +`libzcash_script` +----------------- + +Two new APIs have been added to this library (`zcash_script_legacy_sigop_count` +and `zcash_script_legacy_sigop_count_precomputed`), for counting the number of +signature operations in the transparent inputs and outputs of a transaction. +The presence of these APIs is indicated by a library API version of 2. + +Updated RPCs +------------ + +- Fixed an issue where `ERROR: spent index not enabled` would be logged + unnecessarily on nodes that have either insightexplorer or lightwalletd + configuration options enabled. + +- The `getmininginfo` RPC now omits `currentblockize` and `currentblocktx` + when a block was never assembled via RPC on this node during its current + process instantiation. (#5404) + +Changelog +========= + +Alex Wied (1): + Update support for FreeBSD + +Charlie O'Keefe (1): + Add buster to the list of suites used by gitian + +Dimitris Apostolou (1): + Fix typos + +Jack Grigg (22): + contrib: Update Debian copyright file to follow the v1 format + contrib: Add license information for libc++ and libevent + cargo update + tracing-subscriber 0.3 + Bump all postponed dependencies + depends: Update Rust to 1.56.1 + depends: Update Clang / libcxx to LLVM 13 + rust: Move `incremental_sinsemilla_tree_ffi` into crate root + CI: Add Pyflakes to lints workflow + cargo update + ed25519-zebra 3 + cargo update + cargo update + depends: Update Boost to 1.78.0 + depends Update Rust to 1.57.0 + qa: Postpone recent CCache releases + Revert "lint: Fix false positive" + rust: Remove misleading log message + Migrate to latest revisions of Zcash Rust crates + Update release notes + make-release.py: Versioning changes for 4.6.0-rc1. + make-release.py: Updated manpages for 4.6.0-rc1. + +Janito Vaqueiro Ferreira Filho (1): + Move `CurrentTxVersionInfo` into a new file + +Kris Nuttycombe (7): + Add BIP 44 coin type to persisted wallet state. + Persist network id string instead of bip44 coin type. + Add a check to test that wallet load fails if we're on the wrong network. + Remove unused `AddDestData` method. + Fix wallet-related wording in doc/reduce-traffic.md + Rename OrchardMerkleTree -> OrchardMerkleFrontier + Batch-verify Orchard transactions at the block level. + +Larry Ruane (6): + add TestSetIBD(bool) for testing + Disable IBD for all boost tests + better wallet network info error handling + test: automatically add missing nuparams + Don't log 'ERROR: spent index not enabled' + getblocktemplate: add NU5 commitments to new `defaultroots` section + +Marco Falke (1): + [rpc] mining: Omit uninitialized currentblockweight, currentblocktx + +Marshall Gaucher (1): + Update entrypoint.sh + +Sasha (1): + fix typo in docker run's volume argument + +sgmoore (1): + Update reduce-traffic.md - add one word + +Jack Grigg (1): + contrib: Add space between URL and period + +teor (7): + Add sigop count functions to zcash_script library + Increment the zcash_script API version + Remove an unused header + Use correct copyright header + Remove redundant variable + Explain UINT_MAX error return value + Explain how to get rid of a tiny duplicated function + diff --git a/doc/release-notes/release-notes-4.6.0.md b/doc/release-notes/release-notes-4.6.0.md new file mode 100644 index 000000000..26e1f3652 --- /dev/null +++ b/doc/release-notes/release-notes-4.6.0.md @@ -0,0 +1,126 @@ +Notable changes +=============== + +Wallet +------ + +From this release, newly-created wallets will save the chain name ("Zcash") and +network identifier (e.g. "main") to the `wallet.dat` file. This will enable the +`zcashd` node to check on subsequent starts that the `wallet.dat` file matches +the node's configuration. Existing wallets will start saving this information in +a later release. + +`libzcash_script` +----------------- + +Two new APIs have been added to this library (`zcash_script_legacy_sigop_count` +and `zcash_script_legacy_sigop_count_precomputed`), for counting the number of +signature operations in the transparent inputs and outputs of a transaction. +The presence of these APIs is indicated by a library API version of 2. + +Updated RPCs +------------ + +- The `getblocktemplate` RPC method output now includes a `defaultroots` field, + which provides various tree roots and block commitments matching the contents + of the block template. If any part of the block template marked as `mutable` + in the RPC method output is mutated, these roots may need to be recomputed. + For more information on the derivation process, see the block header changes + in [ZIP 244](https://zips.z.cash/zip-0244#block-header-changes). + +- Fixed an issue where `ERROR: spent index not enabled` would be logged + unnecessarily on nodes that have either `-insightexplorer` or `-lightwalletd` + configuration options enabled. + +- The `getmininginfo` RPC now omits `currentblocksize` and `currentblocktx` + when a block was never assembled via RPC on this node during its current + process instantiation. (#5404) + +Changelog +========= + +Alex Wied (1): + Update support for FreeBSD + +Charlie O'Keefe (2): + Add buster to the list of suites used by gitian + Add libtinfo5 to gitian packages list + +Dimitris Apostolou (1): + Fix typos + +Jack Grigg (23): + contrib: Update Debian copyright file to follow the v1 format + contrib: Add license information for libc++ and libevent + cargo update + tracing-subscriber 0.3 + Bump all postponed dependencies + depends: Update Rust to 1.56.1 + depends: Update Clang / libcxx to LLVM 13 + rust: Move `incremental_sinsemilla_tree_ffi` into crate root + CI: Add Pyflakes to lints workflow + cargo update + ed25519-zebra 3 + cargo update + cargo update + depends: Update Boost to 1.78.0 + depends Update Rust to 1.57.0 + qa: Postpone recent CCache releases + Revert "lint: Fix false positive" + rust: Remove misleading log message + Migrate to latest revisions of Zcash Rust crates + Update release notes + make-release.py: Versioning changes for 4.6.0-rc1. + make-release.py: Updated manpages for 4.6.0-rc1. + make-release.py: Updated release notes and changelog for 4.6.0-rc1. + +Janito Vaqueiro Ferreira Filho (1): + Move `CurrentTxVersionInfo` into a new file + +Kris Nuttycombe (7): + Add BIP 44 coin type to persisted wallet state. + Persist network id string instead of bip44 coin type. + Add a check to test that wallet load fails if we're on the wrong network. + Remove unused `AddDestData` method. + Fix wallet-related wording in doc/reduce-traffic.md + Rename OrchardMerkleTree -> OrchardMerkleFrontier + Batch-verify Orchard transactions at the block level. + +Larry Ruane (8): + add TestSetIBD(bool) for testing + Disable IBD for all boost tests + better wallet network info error handling + test: automatically add missing nuparams + Don't log 'ERROR: spent index not enabled' + getblocktemplate: add NU5 commitments to new `defaultroots` section + test: fix bugs in test framework + test: Use result of getblocktemplate to submitblock + +Marco Falke (1): + [rpc] mining: Omit uninitialized currentblockweight, currentblocktx + +Marshall Gaucher (1): + Update entrypoint.sh + +Sasha (5): + fix typo in docker run's volume argument + update hash for librustzcash + only librustzcash in config.offline + make-release.py: Versioning changes for 4.6.0. + make-release.py: Updated manpages for 4.6.0. + +sgmoore (1): + Update reduce-traffic.md - add one word + +Jack Grigg (1): + contrib: Add space between URL and period + +teor (7): + Add sigop count functions to zcash_script library + Increment the zcash_script API version + Remove an unused header + Use correct copyright header + Remove redundant variable + Explain UINT_MAX error return value + Explain how to get rid of a tiny duplicated function + diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 9f36dbc18..0db8b16b0 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -103,6 +103,7 @@ BASE_SCRIPTS= [ 'disablewallet.py', 'keypool.py', 'getblocktemplate.py', + 'getmininginfo.py', 'bip65-cltv-p2p.py', 'bipdersig-p2p.py', 'invalidblockrequest.py', @@ -122,6 +123,7 @@ BASE_SCRIPTS= [ 'feature_zip239.py', 'feature_zip244_blockcommitments.py', 'upgrade_golden.py', + 'nuparams.py', 'post_heartwood_rollback.py', 'feature_logging.py', 'feature_walletfile.py', diff --git a/qa/rpc-tests/getblocktemplate.py b/qa/rpc-tests/getblocktemplate.py index 223132da4..da3f638f9 100755 --- a/qa/rpc-tests/getblocktemplate.py +++ b/qa/rpc-tests/getblocktemplate.py @@ -3,63 +3,185 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or https://www.opensource.org/licenses/mit-license.php . +from io import BytesIO +import codecs from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, connect_nodes_bi, \ - start_nodes - +from test_framework.util import ( + assert_equal, + CANOPY_BRANCH_ID, + NU5_BRANCH_ID, + hex_str_to_bytes, + nuparams, + start_nodes, + wait_and_assert_operationid_status, +) +from test_framework.mininode import ( + CTransaction, + uint256_from_str, +) +from test_framework.blocktools import ( + create_block +) +from decimal import Decimal class GetBlockTemplateTest(BitcoinTestFramework): ''' - Test getblocktemplate. + Test getblocktemplate, ensure that a block created from its result + can be submitted and accepted. ''' def __init__(self): super().__init__() - self.num_nodes = 2 + self.num_nodes = 1 self.setup_clean_chain = True def setup_network(self, split=False): - self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) - connect_nodes_bi(self.nodes,0,1) - self.is_network_split=False + args = [ + nuparams(CANOPY_BRANCH_ID, 115), + nuparams(NU5_BRANCH_ID, 130), + ] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [args] * self.num_nodes) + self.is_network_split = False + self.node = self.nodes[0] + + def add_nu5_v4_tx_to_mempool(self): + node = self.node + # sprout to transparent (v4) + recipients = [{"address": self.transparent_addr, "amount": Decimal('0.1')}] + myopid = node.z_sendmany(self.sprout_addr, recipients) + wait_and_assert_operationid_status(node, myopid) + + def add_transparent_tx_to_mempool(self): + node = self.node + # transparent to transparent (v5 after nu5) + outputs = {self.transparent_addr: 0.1} + node.sendmany('', outputs) + + def gbt_submitblock(self, nu5_active): + node = self.node + mempool_tx_list = node.getrawmempool() + + gbt = node.getblocktemplate() + + # make sure no transactions were left out (or added) + assert_equal(len(mempool_tx_list), len(gbt['transactions'])) + assert_equal(set(mempool_tx_list), set([tx['hash'] for tx in gbt['transactions']])) + + prevhash = int(gbt['previousblockhash'], 16) + nTime = gbt['mintime'] + nBits = int(gbt['bits'], 16) + + if nu5_active: + blockcommitmentshash = int(gbt['defaultroots']['blockcommitmentshash'], 16) + else: + blockcommitmentshash = int(gbt['defaultroots']['chainhistoryroot'], 16) + assert 'blockcommitmentshash' not in gbt['defaultroots'] + # Confirm that the legacy fields match this default value. + assert_equal(blockcommitmentshash, int(gbt['blockcommitmentshash'], 16)) + assert_equal(blockcommitmentshash, int(gbt['lightclientroothash'], 16)) + assert_equal(blockcommitmentshash, int(gbt['finalsaplingroothash'], 16)) + + f = BytesIO(hex_str_to_bytes(gbt['coinbasetxn']['data'])) + coinbase = CTransaction() + coinbase.deserialize(f) + coinbase.calc_sha256() + assert_equal(coinbase.hash, gbt['coinbasetxn']['hash']) + assert_equal(coinbase.auth_digest_hex, gbt['coinbasetxn']['authdigest']) + + block = create_block(prevhash, coinbase, nTime, nBits, blockcommitmentshash) + + # copy the non-coinbase transactions from the block template to the block + for gbt_tx in gbt['transactions']: + f = BytesIO(hex_str_to_bytes(gbt_tx['data'])) + tx = CTransaction() + tx.deserialize(f) + tx.calc_sha256() + assert_equal(tx.auth_digest_hex, node.getrawtransaction(tx.hash, 1)['authdigest']) + block.vtx.append(tx) + block.hashMerkleRoot = int(gbt['defaultroots']['merkleroot'], 16) + assert_equal(block.hashMerkleRoot, block.calc_merkle_root(), "merkleroot") + assert_equal(len(block.vtx), len(gbt['transactions']) + 1, "number of transactions") + assert_equal(block.hashPrevBlock, int(gbt['previousblockhash'], 16), "prevhash") + if nu5_active: + assert_equal(uint256_from_str(block.calc_auth_data_root()), int(gbt['defaultroots']['authdataroot'], 16)) + else: + assert 'authdataroot' not in gbt['defaultroots'] + block.solve() + block.calc_sha256() + + submitblock_reply = node.submitblock(codecs.encode(block.serialize(), 'hex_codec')) + assert_equal(None, submitblock_reply) + assert_equal(block.hash, node.getbestblockhash()) + # Wait until the wallet has been notified of all blocks, so that it doesn't try to + # double-spend transparent coins in subsequent test phases. self.sync_all() def run_test(self): - node = self.nodes[0] - node.generate(1) # Mine a block to leave initial block download + node = self.node - # Test 1: Default to coinbasetxn - tmpl = node.getblocktemplate() - assert('coinbasetxn' in tmpl) - assert('coinbasevalue' not in tmpl) + # Generate Sprout funds before Canopy activates; using the Sprout address will + # force the generation of v4 transactions from NU5. + print("Generating pre-Canopy blocks to create sprout funds") + # coinbase only becomes mature after 100 blocks, so make one mature. + node.generate(105) - # Test 2: Get coinbasetxn if requested - tmpl = node.getblocktemplate({'capabilities': ['coinbasetxn']}) - assert('coinbasetxn' in tmpl) - assert('coinbasevalue' not in tmpl) + self.sprout_addr = node.z_getnewaddress('sprout') + myopid = node.z_shieldcoinbase('*', self.sprout_addr)['opid'] + wait_and_assert_operationid_status(node, myopid) - # Test 3: coinbasevalue not supported if requested - tmpl = node.getblocktemplate({'capabilities': ['coinbasevalue']}) - assert('coinbasetxn' in tmpl) - assert('coinbasevalue' not in tmpl) + self.transparent_addr = node.getnewaddress() + node.generate(15) - # Test 4: coinbasevalue not supported if both requested - tmpl = node.getblocktemplate({'capabilities': ['coinbasetxn', 'coinbasevalue']}) - assert('coinbasetxn' in tmpl) - assert('coinbasevalue' not in tmpl) + # at height 120, NU5 is not active + assert_equal(node.getblockchaininfo()['upgrades']['37519621']['status'], 'pending') - # Test 5: General checks - tmpl = node.getblocktemplate() - assert_equal(16, len(tmpl['noncerange'])) + print("Testing getblocktemplate for pre-NU5") - # Test 6: coinbasetxn checks - assert('foundersreward' in tmpl['coinbasetxn']) - assert(tmpl['coinbasetxn']['required']) + # Only the coinbase; this covers the case where the Merkle root + # is equal to the coinbase txid. + print("- only coinbase") + self.gbt_submitblock(False) + + # Adding one transaction triggering a single Merkle digest. + print("- one transaction (plus coinbase)") + self.add_transparent_tx_to_mempool() + self.gbt_submitblock(False) + + # Adding two transactions to trigger hash Merkle root edge case. + print("- two transactions (plus coinbase)") + self.add_transparent_tx_to_mempool() + self.add_transparent_tx_to_mempool() + self.gbt_submitblock(False) + + # Activate NU5, repeat the above cases + node.generate(7) + assert_equal(node.getblockchaininfo()['upgrades']['37519621']['status'], 'active') + + print("Testing getblocktemplate for post-NU5") + + # Only the coinbase; this covers the case where the block authdata root + # is equal to the coinbase authdata + print("- only coinbase") + self.gbt_submitblock(True) + + # Adding one transaction triggering a single Merkle digest. + print("- one transaction (plus coinbase)") + self.add_transparent_tx_to_mempool() + self.gbt_submitblock(True) + + # Adding two transactions to trigger hash Merkle root edge case. + print("- two transactions (plus coinbase)") + self.add_transparent_tx_to_mempool() + self.add_transparent_tx_to_mempool() + self.gbt_submitblock(True) + + # Adding both v4 and v5 to cover legacy auth digest. + print("- both v4 and v5 transactions (plus coinbase)") + self.add_nu5_v4_tx_to_mempool() + self.add_transparent_tx_to_mempool() + self.add_transparent_tx_to_mempool() + self.gbt_submitblock(True) - # Test 7: hashFinalSaplingRoot checks - assert('finalsaplingroothash' in tmpl) - finalsaplingroothash = '3e49b5f954aa9d3545bc6c37744661eea48d7c34e3000d82b7f0010c30f4c2fb' - assert_equal(finalsaplingroothash, tmpl['finalsaplingroothash']) if __name__ == '__main__': GetBlockTemplateTest().main() diff --git a/qa/rpc-tests/getmininginfo.py b/qa/rpc-tests/getmininginfo.py new file mode 100755 index 000000000..a1edaf12e --- /dev/null +++ b/qa/rpc-tests/getmininginfo.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# Copyright (c) 2021 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import start_nodes + + +class GetMiningInfoTest(BitcoinTestFramework): + ''' + Test getmininginfo. + ''' + + def __init__(self): + super().__init__() + self.num_nodes = 1 + self.setup_clean_chain = True + + def setup_network(self, split=False): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) + self.is_network_split = False + self.sync_all() + + def run_test(self): + node = self.nodes[0] + + info = node.getmininginfo() + assert(info['blocks'] == 0) + # No blocks have been mined yet, so these fields should not be present. + assert('currentblocksize' not in info) + assert('currentblocktx' not in info) + + node.generate(1) + + info = node.getmininginfo() + assert(info['blocks'] == 1) + # One block has been mined, so these fields should now be present. + assert('currentblocksize' in info) + assert('currentblocktx' in info) + assert(info['currentblocksize'] > 0) + # The transaction count doesn't include the coinbase + assert(info['currentblocktx'] == 0) + + +if __name__ == '__main__': + GetMiningInfoTest().main() diff --git a/qa/rpc-tests/nuparams.py b/qa/rpc-tests/nuparams.py new file mode 100755 index 000000000..4482f116a --- /dev/null +++ b/qa/rpc-tests/nuparams.py @@ -0,0 +1,217 @@ +#!/usr/bin/env python3 +# Copyright (c) 2021 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + start_nodes, + nuparams, + HEARTWOOD_BRANCH_ID, + NU5_BRANCH_ID, +) + + +class NuparamsTest(BitcoinTestFramework): + ''' + Test that unspecified network upgrades are activated automatically; + this is really more of a test of the test framework. + ''' + + def __init__(self): + super().__init__() + self.num_nodes = 1 + self.setup_clean_chain = True + + def setup_network(self, split=False): + args = [[ + nuparams(HEARTWOOD_BRANCH_ID, 3), + nuparams(NU5_BRANCH_ID, 5), + ] * self.num_nodes] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, args) + self.is_network_split = False + self.sync_all() + + def run_test(self): + node = self.nodes[0] + # No blocks have been created, only the genesis block exists (height 0) + bci = node.getblockchaininfo() + assert_equal(bci['blocks'], 0) + upgrades = bci['upgrades'] + + overwinter = upgrades['5ba81b19'] + assert_equal(overwinter['name'], 'Overwinter') + assert_equal(overwinter['activationheight'], 1) + assert_equal(overwinter['status'], 'pending') + + sapling = upgrades['76b809bb'] + assert_equal(sapling['name'], 'Sapling') + assert_equal(sapling['activationheight'], 1) + assert_equal(sapling['status'], 'pending') + + blossom = upgrades['2bb40e60'] + assert_equal(blossom['name'], 'Blossom') + assert_equal(blossom['activationheight'], 3) + assert_equal(blossom['status'], 'pending') + + heartwood = upgrades['f5b9230b'] + assert_equal(heartwood['name'], 'Heartwood') + assert_equal(heartwood['activationheight'], 3) + assert_equal(heartwood['status'], 'pending') + + canopy = upgrades['e9ff75a6'] + assert_equal(canopy['name'], 'Canopy') + assert_equal(canopy['activationheight'], 5) + assert_equal(canopy['status'], 'pending') + + nu5 = upgrades['37519621'] + assert_equal(nu5['name'], 'NU5') + assert_equal(nu5['activationheight'], 5) + assert_equal(nu5['status'], 'pending') + + node.generate(1) + + # start_node() hardcodes Sapling and Overwinter to activate a height 1 + bci = node.getblockchaininfo() + assert_equal(bci['blocks'], 1) + upgrades = bci['upgrades'] + + overwinter = upgrades['5ba81b19'] + assert_equal(overwinter['name'], 'Overwinter') + assert_equal(overwinter['activationheight'], 1) + assert_equal(overwinter['status'], 'active') + + sapling = upgrades['76b809bb'] + assert_equal(sapling['name'], 'Sapling') + assert_equal(sapling['activationheight'], 1) + assert_equal(sapling['status'], 'active') + + blossom = upgrades['2bb40e60'] + assert_equal(blossom['name'], 'Blossom') + assert_equal(blossom['activationheight'], 3) + assert_equal(blossom['status'], 'pending') + + heartwood = upgrades['f5b9230b'] + assert_equal(heartwood['name'], 'Heartwood') + assert_equal(heartwood['activationheight'], 3) + assert_equal(heartwood['status'], 'pending') + + canopy = upgrades['e9ff75a6'] + assert_equal(canopy['name'], 'Canopy') + assert_equal(canopy['activationheight'], 5) + assert_equal(canopy['status'], 'pending') + + nu5 = upgrades['37519621'] + assert_equal(nu5['name'], 'NU5') + assert_equal(nu5['activationheight'], 5) + assert_equal(nu5['status'], 'pending') + + node.generate(1) + bci = node.getblockchaininfo() + assert_equal(bci['blocks'], 2) + upgrades = bci['upgrades'] + + overwinter = upgrades['5ba81b19'] + assert_equal(overwinter['name'], 'Overwinter') + assert_equal(overwinter['activationheight'], 1) + assert_equal(overwinter['status'], 'active') + + sapling = upgrades['76b809bb'] + assert_equal(sapling['name'], 'Sapling') + assert_equal(sapling['activationheight'], 1) + assert_equal(sapling['status'], 'active') + + blossom = upgrades['2bb40e60'] + assert_equal(blossom['name'], 'Blossom') + assert_equal(blossom['activationheight'], 3) + assert_equal(blossom['status'], 'pending') + + heartwood = upgrades['f5b9230b'] + assert_equal(heartwood['name'], 'Heartwood') + assert_equal(heartwood['activationheight'], 3) + assert_equal(heartwood['status'], 'pending') + + canopy = upgrades['e9ff75a6'] + assert_equal(canopy['name'], 'Canopy') + assert_equal(canopy['activationheight'], 5) + assert_equal(canopy['status'], 'pending') + + nu5 = upgrades['37519621'] + assert_equal(nu5['name'], 'NU5') + assert_equal(nu5['activationheight'], 5) + assert_equal(nu5['status'], 'pending') + + node.generate(2) + bci = node.getblockchaininfo() + assert_equal(bci['blocks'], 4) + upgrades = bci['upgrades'] + + overwinter = upgrades['5ba81b19'] + assert_equal(overwinter['name'], 'Overwinter') + assert_equal(overwinter['activationheight'], 1) + assert_equal(overwinter['status'], 'active') + + sapling = upgrades['76b809bb'] + assert_equal(sapling['name'], 'Sapling') + assert_equal(sapling['activationheight'], 1) + assert_equal(sapling['status'], 'active') + + blossom = upgrades['2bb40e60'] + assert_equal(blossom['name'], 'Blossom') + assert_equal(blossom['activationheight'], 3) + assert_equal(blossom['status'], 'active') + + heartwood = upgrades['f5b9230b'] + assert_equal(heartwood['name'], 'Heartwood') + assert_equal(heartwood['activationheight'], 3) + assert_equal(heartwood['status'], 'active') + + canopy = upgrades['e9ff75a6'] + assert_equal(canopy['name'], 'Canopy') + assert_equal(canopy['activationheight'], 5) + assert_equal(canopy['status'], 'pending') + + nu5 = upgrades['37519621'] + assert_equal(nu5['name'], 'NU5') + assert_equal(nu5['activationheight'], 5) + assert_equal(nu5['status'], 'pending') + + node.generate(1) + bci = node.getblockchaininfo() + assert_equal(bci['blocks'], 5) + upgrades = bci['upgrades'] + + overwinter = upgrades['5ba81b19'] + assert_equal(overwinter['name'], 'Overwinter') + assert_equal(overwinter['activationheight'], 1) + assert_equal(overwinter['status'], 'active') + + sapling = upgrades['76b809bb'] + assert_equal(sapling['name'], 'Sapling') + assert_equal(sapling['activationheight'], 1) + assert_equal(sapling['status'], 'active') + + blossom = upgrades['2bb40e60'] + assert_equal(blossom['name'], 'Blossom') + assert_equal(blossom['activationheight'], 3) + assert_equal(blossom['status'], 'active') + + heartwood = upgrades['f5b9230b'] + assert_equal(heartwood['name'], 'Heartwood') + assert_equal(heartwood['activationheight'], 3) + assert_equal(heartwood['status'], 'active') + + canopy = upgrades['e9ff75a6'] + assert_equal(canopy['name'], 'Canopy') + assert_equal(canopy['activationheight'], 5) + assert_equal(canopy['status'], 'active') + + nu5 = upgrades['37519621'] + assert_equal(nu5['name'], 'NU5') + assert_equal(nu5['activationheight'], 5) + assert_equal(nu5['status'], 'active') + + +if __name__ == '__main__': + NuparamsTest().main() diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 1a6b10837..2c51f4421 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -660,7 +660,7 @@ class OutputDescription(object): self.encCiphertext = f.read(580) self.outCiphertext = f.read(80) self.zkproof = Groth16Proof() - self.zkproof.deserialize() + self.zkproof.deserialize(f) def serialize(self): r = b"" @@ -971,6 +971,8 @@ class CTransaction(object): self.nLockTime = 0 self.nExpiryHeight = 0 self.valueBalance = 0 + self.saplingBundle = SaplingBundle() + self.orchardBundle = OrchardBundle() self.shieldedSpends = [] self.shieldedOutputs = [] self.vJoinSplit = [] @@ -988,6 +990,8 @@ class CTransaction(object): self.nLockTime = tx.nLockTime self.nExpiryHeight = tx.nExpiryHeight self.valueBalance = tx.valueBalance + self.saplingBundle = copy.deepcopy(tx.saplingBundle) + self.orchardBundle = copy.deepcopy(tx.orchardBundle) self.shieldedSpends = copy.deepcopy(tx.shieldedSpends) self.shieldedOutputs = copy.deepcopy(tx.shieldedOutputs) self.vJoinSplit = copy.deepcopy(tx.vJoinSplit) @@ -1075,6 +1079,7 @@ class CTransaction(object): # Common transaction fields r += struct.pack("= 5: from . import zip244 txid = zip244.txid_digest(self) + self.auth_digest = zip244.auth_digest(self) else: txid = hash256(self.serialize()) + self.auth_digest = b'\xFF'*32 if self.sha256 is None: self.sha256 = uint256_from_str(txid) self.hash = encode(txid[::-1], 'hex_codec').decode('ascii') + self.auth_digest_hex = encode(self.auth_digest[::-1], 'hex_codec').decode('ascii') def is_valid(self): self.calc_sha256() @@ -1258,6 +1266,27 @@ class CBlock(CBlockHeader): hashes = newhashes return uint256_from_str(hashes[0]) + def calc_auth_data_root(self): + hashes = [] + nleaves = 0 + for tx in self.vtx: + tx.calc_sha256() + hashes.append(tx.auth_digest) + nleaves += 1 + # Continue adding leaves (of zeros) until reaching a power of 2 + while nleaves & (nleaves-1) > 0: + hashes.append(b'\x00'*32) + nleaves += 1 + while len(hashes) > 1: + newhashes = [] + for i in range(0, len(hashes), 2): + digest = blake2b(digest_size=32, person=b'ZcashAuthDatHash') + digest.update(hashes[i]) + digest.update(hashes[i+1]) + newhashes.append(digest.digest()) + hashes = newhashes + return hashes[0] + def is_valid(self, n=48, k=5): # H(I||... digest = blake2b(digest_size=(512//n)*n//8, person=zcash_person(n, k)) diff --git a/qa/rpc-tests/test_framework/zip244.py b/qa/rpc-tests/test_framework/zip244.py index 33c43e523..f9cd5ceee 100644 --- a/qa/rpc-tests/test_framework/zip244.py +++ b/qa/rpc-tests/test_framework/zip244.py @@ -15,7 +15,7 @@ import struct from pyblake2 import blake2b -from .mininode import ser_uint256 +from .mininode import ser_string, ser_uint256 from .script import ( SIGHASH_ANYONECANPAY, SIGHASH_NONE, @@ -41,7 +41,7 @@ def transparent_digest(tx): def transparent_scripts_digest(tx): digest = blake2b(digest_size=32, person=b'ZTxAuthTransHash') for x in tx.vin: - digest.update(bytes(x.scriptSig)) + digest.update(ser_string(x.scriptSig)) return digest.digest() # Sapling @@ -52,7 +52,7 @@ def sapling_digest(saplingBundle): if len(saplingBundle.spends) + len(saplingBundle.outputs) > 0: digest.update(sapling_spends_digest(saplingBundle)) digest.update(sapling_outputs_digest(saplingBundle)) - digest.update(struct.pack('= Consensus::BASE_SPROUT + 1; --i) { + if (consensus.vUpgrades[i].nActivationHeight == Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT) { + UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex(i), nActivationHeight); + } + nActivationHeight = consensus.vUpgrades[i].nActivationHeight; + } } if (mapArgs.count("-nurejectoldversions")) { diff --git a/src/main.cpp b/src/main.cpp index 91863a38f..a3f1d506e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2019,27 +2019,31 @@ bool AcceptToMemoryPool( bool GetTimestampIndex(unsigned int high, unsigned int low, bool fActiveOnly, std::vector > &hashes) { - if (!fTimestampIndex) - return error("Timestamp index not enabled"); - - if (!pblocktree->ReadTimestampIndex(high, low, fActiveOnly, hashes)) - return error("Unable to get hashes for timestamps"); - + if (!fTimestampIndex) { + LogPrint("rpc", "Timestamp index not enabled"); + return false; + } + if (!pblocktree->ReadTimestampIndex(high, low, fActiveOnly, hashes)) { + LogPrint("rpc", "Unable to get hashes for timestamps"); + return false; + } return true; } bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value) { AssertLockHeld(cs_main); - if (!fSpentIndex) - return error("Spent index not enabled"); - + if (!fSpentIndex) { + LogPrint("rpc", "Spent index not enabled"); + return false; + } if (mempool.getSpentIndex(key, value)) return true; - if (!pblocktree->ReadSpentIndex(key, value)) - return error("Unable to get spent index information"); - + if (!pblocktree->ReadSpentIndex(key, value)) { + LogPrint("rpc", "Unable to get spent index information"); + return false; + } return true; } @@ -2047,24 +2051,28 @@ bool GetAddressIndex(const uint160& addressHash, int type, std::vector& addressIndex, int start, int end) { - if (!fAddressIndex) - return error("address index not enabled"); - - if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end)) - return error("unable to get txids for address"); - + if (!fAddressIndex) { + LogPrint("rpc", "address index not enabled"); + return false; + } + if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end)) { + LogPrint("rpc", "unable to get txids for address"); + return false; + } return true; } bool GetAddressUnspent(const uint160& addressHash, int type, std::vector& unspentOutputs) { - if (!fAddressIndex) - return error("address index not enabled"); - - if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs)) - return error("unable to get txids for address"); - + if (!fAddressIndex) { + LogPrint("rpc", "address index not enabled"); + return false; + } + if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs)) { + LogPrint("rpc", "unable to get txids for address"); + return false; + } return true; } @@ -5374,12 +5382,13 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, // Flags used to permit skipping checks for efficiency auto verifier = ProofVerifier::Disabled(); // No need to verify JoinSplits twice bool fCheckTransactions = true; - // We may as well check Orchard authorizations if we are checking - // transactions, since we can batch-validate them. - auto orchardAuth = orchard::AuthValidator::Batch(); for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) { + // We may as well check Orchard authorizations if we are checking + // transactions, since we can batch-validate them. + auto orchardAuth = orchard::AuthValidator::Batch(); + boost::this_thread::interruption_point(); uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))))); if (pindex->nHeight < chainActive.Height()-nCheckDepth) @@ -5421,6 +5430,10 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, } } + if (!orchardAuth.Validate()) { + return error("VerifyDB(): Orchard batch validation failed for block at height %d", pindex->nHeight); + } + if (ShutdownRequested()) return true; } diff --git a/src/main.h b/src/main.h index ab2cb54b8..a76fe63e6 100644 --- a/src/main.h +++ b/src/main.h @@ -157,8 +157,8 @@ extern CCriticalSection cs_main; extern CTxMemPool mempool; typedef boost::unordered_map BlockMap; extern BlockMap mapBlockIndex; -extern uint64_t nLastBlockTx; -extern uint64_t nLastBlockSize; +extern std::optional last_block_num_txs; +extern std::optional last_block_size; extern const std::string strMessageMagic; extern CWaitableCriticalSection csBestBlock; extern CConditionVariable cvBlockChange; diff --git a/src/miner.cpp b/src/miner.cpp index f48137860..0ed57273e 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -71,8 +71,8 @@ public: } }; -uint64_t nLastBlockTx = 0; -uint64_t nLastBlockSize = 0; +std::optional last_block_num_txs; +std::optional last_block_size; // We want to sort transactions by priority and fee rate, so: typedef boost::tuple TxPriority; @@ -610,8 +610,8 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const MinerAddre } } - nLastBlockTx = nBlockTx; - nLastBlockSize = nBlockSize; + last_block_num_txs = nBlockTx; + last_block_size = nBlockSize; LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize); // Create coinbase tx @@ -642,14 +642,38 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const MinerAddre pblock->hashPrevBlock = pindexPrev->GetBlockHash(); if (chainparams.GetConsensus().NetworkUpgradeActive(nHeight, Consensus::UPGRADE_NU5)) { // hashBlockCommitments depends on the block transactions, so we have to - // update it whenever the coinbase transaction changes. Leave it unset here, - // like hashMerkleRoot, and instead cache what we will need to calculate it. + // update it whenever the coinbase transaction changes. + // + // - For the internal miner (either directly or via the `generate` RPC), this + // will occur in `IncrementExtraNonce()`, like for `hashMerkleRoot`. + // - For `getblocktemplate`, we have two sets of fields to handle: + // - The `defaultroots` fields, which contain both the default value (if + // nothing in the template is altered), and the roots that can be used to + // recalculate it (if some or all of the template is altered). + // - The legacy `finalsaplingroothash`, `lightclientroothash`, and + // `blockcommitmentshash` fields, which had the semantics of "place this + // value into the block header and things will work" (except for in + // v4.6.0 where they were accidentally set to always be the NU5 value). + // + // To accommodate all use cases, we calculate the `hashBlockCommitments` + // default value here (unlike `hashMerkleRoot`), and additionally cache the + // values necessary to recalculate it. pblocktemplate->hashChainHistoryRoot = view.GetHistoryRoot(prevConsensusBranchId); + pblocktemplate->hashAuthDataRoot = pblock->BuildAuthDataMerkleTree(); + pblock->hashBlockCommitments = DeriveBlockCommitmentsHash( + pblocktemplate->hashChainHistoryRoot, + pblocktemplate->hashAuthDataRoot); } else if (IsActivationHeight(nHeight, chainparams.GetConsensus(), Consensus::UPGRADE_HEARTWOOD)) { + pblocktemplate->hashChainHistoryRoot.SetNull(); + pblocktemplate->hashAuthDataRoot.SetNull(); pblock->hashBlockCommitments.SetNull(); } else if (chainparams.GetConsensus().NetworkUpgradeActive(nHeight, Consensus::UPGRADE_HEARTWOOD)) { - pblock->hashBlockCommitments = view.GetHistoryRoot(prevConsensusBranchId); + pblocktemplate->hashChainHistoryRoot = view.GetHistoryRoot(prevConsensusBranchId); + pblocktemplate->hashAuthDataRoot.SetNull(); + pblock->hashBlockCommitments = pblocktemplate->hashChainHistoryRoot; } else { + pblocktemplate->hashChainHistoryRoot.SetNull(); + pblocktemplate->hashAuthDataRoot.SetNull(); pblock->hashBlockCommitments = sapling_tree.root(); } UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); @@ -727,9 +751,10 @@ void IncrementExtraNonce( pblock->vtx[0] = txCoinbase; pblock->hashMerkleRoot = pblock->BuildMerkleTree(); if (consensusParams.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_NU5)) { + pblocktemplate->hashAuthDataRoot = pblock->BuildAuthDataMerkleTree(); pblock->hashBlockCommitments = DeriveBlockCommitmentsHash( pblocktemplate->hashChainHistoryRoot, - pblock->BuildAuthDataMerkleTree()); + pblocktemplate->hashAuthDataRoot); } } diff --git a/src/miner.h b/src/miner.h index 9b76ec6ba..52ac1a29d 100644 --- a/src/miner.h +++ b/src/miner.h @@ -110,6 +110,10 @@ struct CBlockTemplate // Cached whenever we update `block`, so we can update hashBlockCommitments // when we change the coinbase transaction. uint256 hashChainHistoryRoot; + // Cached whenever we update `block`, so we can return it from `getblocktemplate` + // (enabling the caller to update `hashBlockCommitments` when they change + // `hashPrevBlock`). + uint256 hashAuthDataRoot; std::vector vTxFees; std::vector vTxSigOps; }; diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 76b6d35f8..c9f6fc73d 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -322,8 +322,8 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) "\nResult:\n" "{\n" " \"blocks\": nnn, (numeric) The current block\n" - " \"currentblocksize\": nnn, (numeric) The last block size\n" - " \"currentblocktx\": nnn, (numeric) The last block transaction\n" + " \"currentblocksize\": nnn, (numeric, optional) The block size of the last assembled block (only present if a block was ever assembled)\n" + " \"currentblocktx\": nnn, (numeric, optional) The number of block non-coinbase transactions of the last assembled block (only present if a block was ever assembled)\n" " \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n" " \"errors\": \"...\" (string) Current errors\n" " \"generate\": true|false (boolean) If the generation is on or off (see getgenerate or setgenerate calls)\n" @@ -344,8 +344,8 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) UniValue obj(UniValue::VOBJ); obj.pushKV("blocks", (int)chainActive.Height()); - obj.pushKV("currentblocksize", (uint64_t)nLastBlockSize); - obj.pushKV("currentblocktx", (uint64_t)nLastBlockTx); + if (last_block_size.has_value()) obj.pushKV("currentblocksize", last_block_size.value()); + if (last_block_num_txs.has_value()) obj.pushKV("currentblocktx", last_block_num_txs.value()); obj.pushKV("difficulty", (double)GetNetworkDifficulty()); auto warnings = GetWarnings("statusbar"); obj.pushKV("errors", warnings.first); @@ -428,6 +428,11 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) "amounts, use 'getblocksubsidy HEIGHT' passing in the height returned\n" "by this API.\n" + "\nThe roots returned in 'defaultroots' are only valid if the block template is\n" + "used unmodified. If any part of the block template marked as 'mutable' in the\n" + "output is mutated, these roots may need to be recomputed. For more information\n" + "on the derivation process, see ZIP 244.\n" + "\nArguments:\n" "1. \"jsonrequestobject\" (string, optional) A json object in the following spec\n" " {\n" @@ -444,9 +449,15 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) "{\n" " \"version\" : n, (numeric) The block version\n" " \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n" - " \"blockcommitmentshash\" : \"xxxx\", (string) The hash of the block commitments field in the block header\n" + " \"blockcommitmentshash\" : \"xxxx\", (string) (DEPRECATED) The hash of the block commitments field in the block header\n" " \"lightclientroothash\" : \"xxxx\", (string) (DEPRECATED) The hash of the light client root field in the block header\n" " \"finalsaplingroothash\" : \"xxxx\", (string) (DEPRECATED) The hash of the light client root field in the block header\n" + " \"defaultroots\" : { (json object) root hashes that need to be recomputed if the transaction set is modified\n" + " \"merkleroot\" : \"xxxx\" (string) The hash of the transactions in the block header\n" + " \"chainhistoryroot\" : \"xxxx\" (string) The hash of the chain history\n" + " \"authdataroot\" : \"xxxx\" (string) (From NU5) The hash of the authorizing data merkel tree\n" + " \"blockcommitmentshash\" : \"xxxx\" (string) (From NU5) The hash of the block commitments field in the block header\n" + " }\n" " \"transactions\" : [ (array) contents of non-coinbase transactions that should be included in the next block\n" " {\n" " \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n" @@ -712,6 +723,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) entry.pushKV("data", EncodeHexTx(tx)); entry.pushKV("hash", txHash.GetHex()); + entry.pushKV("authdigest", tx.GetAuthDigest().GetHex()); UniValue deps(UniValue::VARR); for (const CTxIn &in : tx.vin) @@ -757,11 +769,23 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) result.pushKV("capabilities", aCaps); result.pushKV("version", pblock->nVersion); result.pushKV("previousblockhash", pblock->hashPrevBlock.GetHex()); + // The following 3 are deprecated; remove in a future release. result.pushKV("blockcommitmentshash", pblock->hashBlockCommitments.GetHex()); - // Deprecated; remove in a future release. result.pushKV("lightclientroothash", pblock->hashBlockCommitments.GetHex()); - // Deprecated; remove in a future release. result.pushKV("finalsaplingroothash", pblock->hashBlockCommitments.GetHex()); + { + // These are items in the result object that are valid only if the + // block template returned by this RPC is used unmodified. Otherwise, + // these values must be recomputed. + UniValue defaults(UniValue::VOBJ); + defaults.pushKV("merkleroot", pblock->BuildMerkleTree().GetHex()); + defaults.pushKV("chainhistoryroot", pblocktemplate->hashChainHistoryRoot.GetHex()); + if (consensus.NetworkUpgradeActive(pindexPrev->nHeight+1, Consensus::UPGRADE_NU5)) { + defaults.pushKV("authdataroot", pblocktemplate->hashAuthDataRoot.GetHex()); + defaults.pushKV("blockcommitmentshash", pblock->hashBlockCommitments.GetHex()); + } + result.pushKV("defaultroots", defaults); + } result.pushKV("transactions", transactions); if (coinbasetxn) { assert(txCoinbase.isObject()); diff --git a/src/rust/src/address_ffi.rs b/src/rust/src/address_ffi.rs index a670d1815..0344ec416 100644 --- a/src/rust/src/address_ffi.rs +++ b/src/rust/src/address_ffi.rs @@ -142,8 +142,8 @@ pub extern "C" fn zcash_address_parse_unified( let ua: UnifiedAddressHelper = match addr.convert() { Ok(ua) => ua, - Err(e) => { - tracing::error!("{}", e); + Err(_) => { + // `KeyIO::DecodePaymentAddress` handles the rest of the address kinds. return false; } }; diff --git a/zcutil/fetch-params.sh b/zcutil/fetch-params.sh index fba5de078..69d2e964d 100755 --- a/zcutil/fetch-params.sh +++ b/zcutil/fetch-params.sh @@ -21,7 +21,7 @@ DOWNLOAD_URL="https://download.z.cash/downloads" IPFS_HASH="/ipfs/QmXRHVGLQBiKwvNq7c2vPxAKz1zRVmMYbmt7G5TQss7tY7" SHA256CMD="$(command -v sha256sum || echo shasum)" -SHA256ARGS="$(command -v sha256sum >/dev/null || echo \"-a 256\")" +SHA256ARGS="$(command -v sha256sum >/dev/null || echo '-a 256')" WGETCMD="$(command -v wget || echo '')" IPFSCMD="$(command -v ipfs || echo '')"