From 5d9ae0ba6399e5200d5e9c8059eb5de51ab96d72 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Mon, 4 Jul 2022 15:46:57 +0000 Subject: [PATCH 1/3] bench: Add `ConnectBlock` benchmark using block 1723244 This block has 470 transactions, containing a total of 452 Sapling spends and 1862 outputs, making for a nice benchmark of verification performance. --- qa/zcash/create_benchmark_archive.py | 6 ++++ qa/zcash/performance-measurements.sh | 16 +++++++++ src/wallet/rpcwallet.cpp | 5 +++ src/zcbenchmarks.cpp | 51 ++++++++++++++++++++++++++++ src/zcbenchmarks.h | 1 + 5 files changed, 79 insertions(+) diff --git a/qa/zcash/create_benchmark_archive.py b/qa/zcash/create_benchmark_archive.py index dc682bf8a..440d90eea 100644 --- a/qa/zcash/create_benchmark_archive.py +++ b/qa/zcash/create_benchmark_archive.py @@ -176,6 +176,11 @@ def create_benchmark_archive(blk_hash): unique_inputs = {} for i in sorted(inputs): + if i[0] in blk['tx']: + # This is a child transaction spending the output of a parent transaction in + # the same block. We don't want to store the parent coin in the inputs table, + # or this will fail the BIP 30 consensus rule. + continue if i[0] in unique_inputs: unique_inputs[i[0]].append(i[1]) else: @@ -262,3 +267,4 @@ if __name__ == '__main__': check_deps() create_benchmark_archive('0000000007cdb809e48e51dd0b530e8f5073e0a9e9bd7ae920fe23e874658c74') create_benchmark_archive('0000000000651d7fb11f0dd1be8dc87c29dca74cbf91140c6aafbacc09e7da04') + create_benchmark_archive('00000000012e0b5a8fb0d67c995b92e7c097ddeeab1151de61c4f484611fde11') diff --git a/qa/zcash/performance-measurements.sh b/qa/zcash/performance-measurements.sh index b94fcee8d..aedcf560e 100755 --- a/qa/zcash/performance-measurements.sh +++ b/qa/zcash/performance-measurements.sh @@ -164,6 +164,10 @@ function extract_benchmark_data_1708048 { extract_benchmark_data block-1708048 bdae4b1baf528fa93d86b902e1032d4d1fc3d3080f76cd284635787e472f2534 } +function extract_benchmark_data_1723244 { + extract_benchmark_data block-1723244 94acfef482103a61c848ddaa3129877cba987c4a00fa42425f4cf030b7c3fa4c +} + if [ $# -lt 2 ] then @@ -229,6 +233,10 @@ case "$1" in extract_benchmark_data_107134 zcash_rpc zcbenchmark connectblockslow 10 ;; + connectblocksapling) + extract_benchmark_data_1723244 + zcash_rpc zcbenchmark connectblocksapling 10 + ;; connectblockorchard) extract_benchmark_data_1708048 zcash_rpc zcbenchmark connectblockorchard 10 @@ -295,6 +303,10 @@ case "$1" in extract_benchmark_data_107134 zcash_rpc zcbenchmark connectblockslow 1 ;; + connectblocksapling) + extract_benchmark_data_1723244 + zcash_rpc zcbenchmark connectblocksapling 1 + ;; connectblockorchard) extract_benchmark_data_1708048 zcash_rpc zcbenchmark connectblockorchard 1 @@ -359,6 +371,10 @@ case "$1" in extract_benchmark_data_107134 zcash_rpc zcbenchmark connectblockslow 1 ;; + connectblocksapling) + extract_benchmark_data_1723244 + zcash_rpc zcbenchmark connectblocksapling 1 + ;; connectblockorchard) extract_benchmark_data_1708048 zcash_rpc zcbenchmark connectblockorchard 1 diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 8ae1c410a..294e347bf 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2890,6 +2890,11 @@ UniValue zc_benchmark(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_TYPE_ERROR, "Benchmark must be run in regtest mode"); } sample_times.push_back(benchmark_connectblock_slow()); + } else if (benchmarktype == "connectblocksapling") { + if (Params().NetworkIDString() != "regtest") { + throw JSONRPCError(RPC_TYPE_ERROR, "Benchmark must be run in regtest mode"); + } + sample_times.push_back(benchmark_connectblock_sapling()); } else if (benchmarktype == "connectblockorchard") { if (Params().NetworkIDString() != "regtest") { throw JSONRPCError(RPC_TYPE_ERROR, "Benchmark must be run in regtest mode"); diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index be7de3f1b..6d0a59905 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -604,6 +604,57 @@ double benchmark_connectblock_slow() return duration; } +double benchmark_connectblock_sapling() +{ + // Test for slowness encountered on 2022-07-01 + SelectParams(CBaseChainParams::MAIN); + CBlock block; + FILE* fp = fsbridge::fopen(GetDataDir() / "benchmark/block-1723244.dat", "rb"); + if (!fp) throw new std::runtime_error("Failed to open block data file"); + CAutoFile blkFile(fp, SER_DISK, CLIENT_VERSION); + blkFile >> block; + blkFile.fclose(); + + // Fake its inputs + auto hashPrev = uint256S("0000000001286c016284523a1b343e731539bdf1fac4159f96d70a711cf9c960"); + FakeCoinsViewDB fakeDB("benchmark/block-1723244-inputs", hashPrev); + fakeDB.SetSaplingTrees({ + "012380d4632f51d9aff726d9f2d0013691c86da31279e110e852d49e4737ce7c14001401c4dedf5f6a0e5be05be051fec4608153084b0fdb74cd92f01d8deb77e72b6a5f01d5891ebfeae46b30846a301f8aaba34d64428e91fc406d0db13fcf723100753100018b4af5e391e5720a2b7a20c289a7691bb6a29ffcda574e06eaf4d6597048fd2200017cc935f49a763d29f9e876fe0a85c6dbbd32ab5b632bc2da058c44c652f713190191cac78cfcb2ca0eaaad52778c93cc2549c6ae0460c37f0b304843ccf8c15e3301c4a86822bec7ea056f984aa72a059a566addd797c08be929289123f698a4631d01e7cbe9d650e4c7dfbc78b328744515345f3e0988ea8d0dd5ce2af025d56d710001278234295da81c7fbfbb336719718f78c16025032ef9cc6007bc49351213d701014656c38189b9f768a492ee90758c63d4be59c92e21b3e9d00916acf1e528774601add4db5d8e6357c91d3b1fc605c0961353b5aa683520923f47daa51b2864563c00000001a02e924803cc430e6360a63732092f621a116b1f156ccdc3e0f815c30a01b2510001bcefb8862360baae2a9a164c1367df2c27372d0c6963068c9ea4b1f84f5c526d00015ec9e9b1295908beed437df4126032ca57ada8e3ebb67067cd22a73c79a84009", + "0159a96b6b5a6dc61154f9b0cb66121ac04050978fdee3d1cf6deadac0b3118d4801318d4e70e26b35a2af00ee10cd4370553cfd6c058d762a9b37e7d43fba96a41f14013addafd08d0b8fcc60723f7ac79b589e6fd1e0209ec1865ef521ddc9537d010000018636e49531fdf3d5d7f817ed1488babf61ef0e750255e59f93cc111f521d800a0001a19338964f3cf13d3a74868b8a53c15dfd6b28f6aef345238372f0051dc3bc1d011f386f8123ec951aed8d51e25c549e3e007429c3d3882dc5daebf8d70e878e4d0001c4a86822bec7ea056f984aa72a059a566addd797c08be929289123f698a4631d01e7cbe9d650e4c7dfbc78b328744515345f3e0988ea8d0dd5ce2af025d56d710001278234295da81c7fbfbb336719718f78c16025032ef9cc6007bc49351213d701014656c38189b9f768a492ee90758c63d4be59c92e21b3e9d00916acf1e528774601add4db5d8e6357c91d3b1fc605c0961353b5aa683520923f47daa51b2864563c00000001a02e924803cc430e6360a63732092f621a116b1f156ccdc3e0f815c30a01b2510001bcefb8862360baae2a9a164c1367df2c27372d0c6963068c9ea4b1f84f5c526d00015ec9e9b1295908beed437df4126032ca57ada8e3ebb67067cd22a73c79a84009", + "0175638110ef078c9c5e45f34399131e652d7e7e4e3ea28fa13702854c3e889d38001401b445b70b61de6c561ae9203c5ddcd594c3da14550493154a4fb6e770bff2d65901981edfb711be11868d221643fdbc0403f607b8ec06f6c2b7968c8ddb2e0968080001b97e4e33d8c0c08cabf8ee7a897d09d1b2e6a395bc43214b61d7ae7cea560e650001060784c088dee8e54ec94a47e7de9308cab6069e77d7303e1ac9f8fbc920a45a000001e7cbe9d650e4c7dfbc78b328744515345f3e0988ea8d0dd5ce2af025d56d710001278234295da81c7fbfbb336719718f78c16025032ef9cc6007bc49351213d701014656c38189b9f768a492ee90758c63d4be59c92e21b3e9d00916acf1e528774601add4db5d8e6357c91d3b1fc605c0961353b5aa683520923f47daa51b2864563c00000001a02e924803cc430e6360a63732092f621a116b1f156ccdc3e0f815c30a01b2510001bcefb8862360baae2a9a164c1367df2c27372d0c6963068c9ea4b1f84f5c526d00015ec9e9b1295908beed437df4126032ca57ada8e3ebb67067cd22a73c79a84009", + "01ca5608a4c5e15340674e0a91ad1c128a49c04230141a955a9d87f2c84734ee2401ed8561fa9f71a0283dcc4865dc44dc886ceb8a91c36abbbb139795bc86cbba321401e2488b560f9f641e4371cadb8569776df9170f82888869c7902f80909aae5f1e01ad01014509c3242d3fbf6754e485f8c87eca413ceace72a742e033947e3f014c0001e6de90c780bf39b4a40dedee586a89686133013b138529eea245add88685e15c00013c16c0b1a41f32caebe41ec1322521b8eaf0303c3969044fa6daaa8a20948d2100000000000001591e0969b34ce995643b3f043be0b07f45b641dd90fce7f4713b90b4a545fa16000001a02e924803cc430e6360a63732092f621a116b1f156ccdc3e0f815c30a01b2510001bcefb8862360baae2a9a164c1367df2c27372d0c6963068c9ea4b1f84f5c526d00015ec9e9b1295908beed437df4126032ca57ada8e3ebb67067cd22a73c79a84009", + "01cb51537fbdc52f8c92ab7d14156dc3d81d9d433fa438d479f4b822924f4fb64500140139c4c235ce18df178bff8169c4d2ecd5c1eb1d112a0dbde3bc22349a2a7a1e590000014c998c0f24b3cc9640acccca4af19cba8c1dd728570fc7080ed7487e7a232c4100011f386f8123ec951aed8d51e25c549e3e007429c3d3882dc5daebf8d70e878e4d0001c4a86822bec7ea056f984aa72a059a566addd797c08be929289123f698a4631d01e7cbe9d650e4c7dfbc78b328744515345f3e0988ea8d0dd5ce2af025d56d710001278234295da81c7fbfbb336719718f78c16025032ef9cc6007bc49351213d701014656c38189b9f768a492ee90758c63d4be59c92e21b3e9d00916acf1e528774601add4db5d8e6357c91d3b1fc605c0961353b5aa683520923f47daa51b2864563c00000001a02e924803cc430e6360a63732092f621a116b1f156ccdc3e0f815c30a01b2510001bcefb8862360baae2a9a164c1367df2c27372d0c6963068c9ea4b1f84f5c526d00015ec9e9b1295908beed437df4126032ca57ada8e3ebb67067cd22a73c79a84009", + "01dffd4c5286c411a7efc955f740f311f979d6ceb39f37f12e2530e45610452b4200140001180211de427aaf56cc398c972a158fa0ac1a4fc79c76746972907fb2e7b668360001be1c46b85e67695418b39e799aa8bcc19a8634463e3fa293c3e75c471fb8475301072f3b28b20e0306b48c1b1fa25b2d845b6125069299df3028d58cfd360b4953010ed297014c2acf3d0840b3dad9038071e150935054c3dcc0f8981dfeb822821501b5cf5b5ac994c75a11e2e47a0d8077d39d01e79a9ac24a1b83b108128a86f35d0001e7cbe9d650e4c7dfbc78b328744515345f3e0988ea8d0dd5ce2af025d56d710001278234295da81c7fbfbb336719718f78c16025032ef9cc6007bc49351213d701014656c38189b9f768a492ee90758c63d4be59c92e21b3e9d00916acf1e528774601add4db5d8e6357c91d3b1fc605c0961353b5aa683520923f47daa51b2864563c00000001a02e924803cc430e6360a63732092f621a116b1f156ccdc3e0f815c30a01b2510001bcefb8862360baae2a9a164c1367df2c27372d0c6963068c9ea4b1f84f5c526d00015ec9e9b1295908beed437df4126032ca57ada8e3ebb67067cd22a73c79a84009" + }); + fakeDB.SetOrchardTrees({ + "01a8fb1700000000002b768d317551b491c8b993cd7e74c9196f3028b2a1a7a3f22971f7f4007c833e000e7005f57c540bf3e32695854f52d27a0456ca1be179bd073d9ca87acc92248413aeacb64a31a230338cfa6a2907f12bc5321a709ef298fb93ced3082c444f8a3814764dc108e86dc2c6d7c20a6e1759027d87029b5dc7e1e6b5be970ecbed913a186d95ac66b184f8844e57fece62a4d64cfeb73e7ed6e99146e79aacae7f5e002f9cd86767aea1f11147f65c588f94dce188315c40b22c0fa8751365ba453c28130cfb41380fdd7836985e2c4c488fdc3d1d1bd4390f350f0e1b8a448f47ac1c2bcbdd308beca04006b18928c4418aad2b3650677289b1b45ea5a21095c53103100ed4d0a8a440b03f1254ce1efb2d82a94cf001cffa0e7fd6ada813a2688b2430a69de998b87aebcd4c556503a45e559a422ecfbdf2f0e6318a8427e41a7b097676cfe97afff13797f82f8d631bd29edde424854139c64ab8241e2a23315514da371f0d3294843fd8f645019a04c07607342c70cf4cc793068355eaccdd6716bc79f0119f97113775379bf58f3f5d9d122766909b797947127b28248ff07205c1eb3aa1717c2a696ce0aba6c5b5bda44c4eda5cf69ae376cc8b334a2c23fb2b374feb2041bfd423c6cc3e064ee2b4705748a082836d39dd723515357fb06e30", + }); + CCoinsViewCache view(&fakeDB); + + // Fake the chain + CBlockIndex index(block); + index.nHeight = 1723244; + CBlockIndex indexPrev; + indexPrev.phashBlock = &hashPrev; + indexPrev.nHeight = index.nHeight - 1; + indexPrev.hashFinalSaplingRoot = uint256S("3922921f92d9abe9e440bb5a21fa901a0647057aa85c201e38d150a5e00043b8"); + indexPrev.hashFinalOrchardRoot = uint256S("0e9a0a55e201062a5677b8ab15c96e9f4983726af31cd96b14b71ac6a931aea2"); + index.pprev = &indexPrev; + mapBlockIndex.insert(std::make_pair(hashPrev, &indexPrev)); + + CValidationState state; + struct timeval tv_start; + timer_start(tv_start); + assert(ConnectBlock(block, state, &index, view, Params(), true, false)); + auto duration = timer_stop(tv_start); + + // Undo alterations to global state + mapBlockIndex.erase(hashPrev); + SelectParams(ChainNameFromCommandLine()); + + return duration; +} + double benchmark_connectblock_orchard() { // Test for slowness encountered on 2022-06-20 diff --git a/src/zcbenchmarks.h b/src/zcbenchmarks.h index bd51f9cd0..f032ae8af 100644 --- a/src/zcbenchmarks.h +++ b/src/zcbenchmarks.h @@ -17,6 +17,7 @@ extern double benchmark_try_decrypt_sapling_notes(size_t nAddrs); extern double benchmark_increment_sprout_note_witnesses(size_t nTxs); extern double benchmark_increment_sapling_note_witnesses(size_t nTxs); extern double benchmark_connectblock_slow(); +extern double benchmark_connectblock_sapling(); extern double benchmark_connectblock_orchard(); extern double benchmark_sendtoaddress(CAmount amount); extern double benchmark_loadwallet(); From 90f13641b9e2b5e247cdafdb233e0b52057da4a8 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Mon, 4 Jul 2022 17:33:07 +0000 Subject: [PATCH 2/3] Use batch validation for Sapling proofs and signatures --- Cargo.lock | 26 +++- Cargo.toml | 2 +- qa/supply-chain/audits.toml | 12 ++ qa/supply-chain/config.toml | 4 + src/gtest/test_checktransaction.cpp | 39 ++--- src/main.cpp | 57 +++++--- src/main.h | 2 + src/rust/src/rustzcash.rs | 17 ++- src/rust/src/sapling.rs | 212 ++++++++++++++++++++++++++-- src/test/transaction_tests.cpp | 18 ++- src/uint256.h | 2 +- 11 files changed, 334 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7fe0d3660..1ed905210 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -120,9 +120,9 @@ checksum = "cf9ff0bbfd639f15c74af777d81383cf53efb7c93613f6cab67c6c11e05bbf8b" [[package]] name = "bellman" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d96d7f4f3dc9a699bdef1d19648f6f20ef966b51892d224582a4475be669cb5" +checksum = "a4dd656ef4fdf7debb6d87d4dd92642fcbcdb78cbf6600c13e25c87e4d1a3807" dependencies = [ "bitvec", "blake2s_simd", @@ -1641,6 +1641,22 @@ dependencies = [ "zeroize", ] +[[package]] +name = "redjubjub" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6039ff156887caf92df308cbaccdc058c9d3155a913da046add6e48c4cdbd91d" +dependencies = [ + "blake2b_simd", + "byteorder", + "digest 0.9.0", + "jubjub", + "rand_core 0.6.3", + "serde", + "thiserror", + "zeroize", +] + [[package]] name = "redox_syscall" version = "0.2.13" @@ -2320,9 +2336,9 @@ dependencies = [ [[package]] name = "zcash_proofs" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92c0928a33ab146a4e93e2a1141ce589de1bbe93c90219965dcccadc15f4e4e8" +checksum = "98bf5f6af051dd929263f279b21b9c04c1f30116c70f3c190de2566677f245ef" dependencies = [ "bellman", "blake2b_simd", @@ -2334,6 +2350,8 @@ dependencies = [ "jubjub", "lazy_static", "rand_core 0.6.3", + "redjubjub", + "tracing", "zcash_primitives", ] diff --git a/Cargo.toml b/Cargo.toml index 097a07c0f..72aaca016 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,7 +56,7 @@ zcash_encoding = "0.1" zcash_history = "0.3" zcash_note_encryption = "0.1" zcash_primitives = { version = "0.7", features = ["transparent-inputs"] } -zcash_proofs = "0.7" +zcash_proofs = "0.7.1" ed25519-zebra = "3" zeroize = "1.4.2" diff --git a/qa/supply-chain/audits.toml b/qa/supply-chain/audits.toml index 6f6305140..fab661322 100644 --- a/qa/supply-chain/audits.toml +++ b/qa/supply-chain/audits.toml @@ -7,6 +7,12 @@ description = "The cryptographic code in this crate has been reviewed for correc [criteria.license-reviewed] description = "The license of this crate has been reviewed for compatibility with its usage in this repository. If the crate is not available under the MIT license, `contrib/debian/copyright` has been updated with a corresponding copyright notice for files under `depends/*/vendored-sources/CRATE_NAME`." +[[audits.bellman]] +who = "Jack Grigg " +criteria = ["crypto-reviewed", "safe-to-deploy"] +delta = "0.13.0 -> 0.13.1" +notes = "Adds multi-threaded batch validation, which I checked against the existing single-threaded batch validation." + [[audits.equihash]] who = "Jack Grigg " criteria = "safe-to-deploy" @@ -151,3 +157,9 @@ criteria = ["crypto-reviewed", "safe-to-deploy"] delta = "0.6.0 -> 0.7.0" notes = "The ECC core team maintains this crate, and we have reviewed every line." +[[audits.zcash_proofs]] +who = "Jack Grigg " +criteria = ["crypto-reviewed", "safe-to-deploy"] +delta = "0.7.0 -> 0.7.1" +notes = "The ECC core team maintains this crate, and we have reviewed every line." + diff --git a/qa/supply-chain/config.toml b/qa/supply-chain/config.toml index d21981794..37e22e438 100644 --- a/qa/supply-chain/config.toml +++ b/qa/supply-chain/config.toml @@ -632,6 +632,10 @@ criteria = "safe-to-deploy" version = "0.3.0" criteria = "safe-to-deploy" +[[unaudited.redjubjub]] +version = "0.5.0" +criteria = "safe-to-deploy" + [[unaudited.redox_syscall]] version = "0.2.13" criteria = "safe-to-deploy" diff --git a/src/gtest/test_checktransaction.cpp b/src/gtest/test_checktransaction.cpp index f25bd30b9..ea2bc1f57 100644 --- a/src/gtest/test_checktransaction.cpp +++ b/src/gtest/test_checktransaction.cpp @@ -11,6 +11,7 @@ #include #include +#include #include // Subclass of CTransaction which doesn't call UpdateHash when constructing @@ -534,6 +535,7 @@ TEST(ChecktransactionTests, BadTxnsPrevoutNull) { TEST(ContextualCheckShieldedInputsTest, BadTxnsInvalidJoinsplitSignature) { SelectParams(CBaseChainParams::REGTEST); auto consensus = Params().GetConsensus(); + std::optional> saplingAuth = std::nullopt; auto orchardAuth = orchard::AuthValidator::Disabled(); CMutableTransaction mtx = GetValidTransaction(); @@ -551,20 +553,21 @@ TEST(ContextualCheckShieldedInputsTest, BadTxnsInvalidJoinsplitSignature) { // during initial block download, for transactions being accepted into the // mempool (and thus not mined), DoS ban score should be zero, else 10 EXPECT_CALL(state, DoS(0, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1); - ContextualCheckShieldedInputs(tx, txdata, state, view, orchardAuth, consensus, 0, false, false, [](const Consensus::Params&) { return true; }); + ContextualCheckShieldedInputs(tx, txdata, state, view, saplingAuth, orchardAuth, consensus, 0, false, false, [](const Consensus::Params&) { return true; }); EXPECT_CALL(state, DoS(10, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1); - ContextualCheckShieldedInputs(tx, txdata, state, view, orchardAuth, consensus, 0, false, false, [](const Consensus::Params&) { return false; }); + ContextualCheckShieldedInputs(tx, txdata, state, view, saplingAuth, orchardAuth, consensus, 0, false, false, [](const Consensus::Params&) { return false; }); // for transactions that have been mined in a block, DoS ban score should // always be 100. EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1); - ContextualCheckShieldedInputs(tx, txdata, state, view, orchardAuth, consensus, 0, false, true, [](const Consensus::Params&) { return true; }); + ContextualCheckShieldedInputs(tx, txdata, state, view, saplingAuth, orchardAuth, consensus, 0, false, true, [](const Consensus::Params&) { return true; }); EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1); - ContextualCheckShieldedInputs(tx, txdata, state, view, orchardAuth, consensus, 0, false, true, [](const Consensus::Params&) { return false; }); + ContextualCheckShieldedInputs(tx, txdata, state, view, saplingAuth, orchardAuth, consensus, 0, false, true, [](const Consensus::Params&) { return false; }); } TEST(ContextualCheckShieldedInputsTest, JoinsplitSignatureDetectsOldBranchId) { SelectParams(CBaseChainParams::REGTEST); auto consensus = Params().GetConsensus(); + std::optional> saplingAuth = std::nullopt; auto orchardAuth = orchard::AuthValidator::Disabled(); auto saplingBranchId = NetworkUpgradeInfo[Consensus::UPGRADE_SAPLING].nBranchId; @@ -585,7 +588,7 @@ TEST(ContextualCheckShieldedInputsTest, JoinsplitSignatureDetectsOldBranchId) { CCoinsViewCache view(&baseView); // Ensure that the transaction validates against Sapling. EXPECT_TRUE(ContextualCheckShieldedInputs( - tx, txdata, state, view, orchardAuth, consensus, saplingBranchId, false, false, + tx, txdata, state, view, saplingAuth, orchardAuth, consensus, saplingBranchId, false, false, [](const Consensus::Params&) { return false; })); // Attempt to validate the inputs against Blossom. We should be notified @@ -597,7 +600,7 @@ TEST(ContextualCheckShieldedInputsTest, JoinsplitSignatureDetectsOldBranchId) { HexInt(saplingBranchId)), false, "")).Times(1); EXPECT_FALSE(ContextualCheckShieldedInputs( - tx, txdata, state, view, orchardAuth, consensus, blossomBranchId, false, false, + tx, txdata, state, view, saplingAuth, orchardAuth, consensus, blossomBranchId, false, false, [](const Consensus::Params&) { return false; })); // Attempt to validate the inputs against Heartwood. All we should learn is @@ -607,13 +610,14 @@ TEST(ContextualCheckShieldedInputsTest, JoinsplitSignatureDetectsOldBranchId) { 10, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1); EXPECT_FALSE(ContextualCheckShieldedInputs( - tx, txdata, state, view, orchardAuth, consensus, heartwoodBranchId, false, false, + tx, txdata, state, view, saplingAuth, orchardAuth, consensus, heartwoodBranchId, false, false, [](const Consensus::Params&) { return false; })); } TEST(ContextualCheckShieldedInputsTest, NonCanonicalEd25519Signature) { SelectParams(CBaseChainParams::REGTEST); auto consensus = Params().GetConsensus(); + std::optional> saplingAuth = std::nullopt; auto orchardAuth = orchard::AuthValidator::Disabled(); AssumeShieldedInputsExistAndAreSpendable baseView; @@ -631,7 +635,7 @@ TEST(ContextualCheckShieldedInputsTest, NonCanonicalEd25519Signature) { CTransaction tx(mtx); const PrecomputedTransactionData txdata(tx, allPrevOutputs); MockCValidationState state; - EXPECT_TRUE(ContextualCheckShieldedInputs(tx, txdata, state, view, orchardAuth, consensus, saplingBranchId, false, true)); + EXPECT_TRUE(ContextualCheckShieldedInputs(tx, txdata, state, view, saplingAuth, orchardAuth, consensus, saplingBranchId, false, true)); } // Copied from libsodium/crypto_sign/ed25519/ref10/open.c @@ -655,15 +659,15 @@ TEST(ContextualCheckShieldedInputsTest, NonCanonicalEd25519Signature) { // during initial block download, for transactions being accepted into the // mempool (and thus not mined), DoS ban score should be zero, else 10 EXPECT_CALL(state, DoS(0, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1); - ContextualCheckShieldedInputs(tx, txdata, state, view, orchardAuth, consensus, saplingBranchId, false, false, [](const Consensus::Params&) { return true; }); + ContextualCheckShieldedInputs(tx, txdata, state, view, saplingAuth, orchardAuth, consensus, saplingBranchId, false, false, [](const Consensus::Params&) { return true; }); EXPECT_CALL(state, DoS(10, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1); - ContextualCheckShieldedInputs(tx, txdata, state, view, orchardAuth, consensus, saplingBranchId, false, false, [](const Consensus::Params&) { return false; }); + ContextualCheckShieldedInputs(tx, txdata, state, view, saplingAuth, orchardAuth, consensus, saplingBranchId, false, false, [](const Consensus::Params&) { return false; }); // for transactions that have been mined in a block, DoS ban score should // always be 100. EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1); - ContextualCheckShieldedInputs(tx, txdata, state, view, orchardAuth, consensus, saplingBranchId, false, true, [](const Consensus::Params&) { return true; }); + ContextualCheckShieldedInputs(tx, txdata, state, view, saplingAuth, orchardAuth, consensus, saplingBranchId, false, true, [](const Consensus::Params&) { return true; }); EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1); - ContextualCheckShieldedInputs(tx, txdata, state, view, orchardAuth, consensus, saplingBranchId, false, true, [](const Consensus::Params&) { return false; }); + ContextualCheckShieldedInputs(tx, txdata, state, view, saplingAuth, orchardAuth, consensus, saplingBranchId, false, true, [](const Consensus::Params&) { return false; }); } TEST(ChecktransactionTests, OverwinterConstructors) { @@ -1321,20 +1325,23 @@ TEST(ChecktransactionTests, HeartwoodEnforcesSaplingRulesOnShieldedCoinbase) { // Coinbase transaction should pass contextual checks. EXPECT_TRUE(ContextualCheckTransaction(tx, state, chainparams, 10, 57)); + std::optional> saplingAuth = sapling::init_batch_validator(); auto orchardAuth = orchard::AuthValidator::Disabled(); auto heartwoodBranchId = NetworkUpgradeInfo[Consensus::UPGRADE_HEARTWOOD].nBranchId; // Coinbase transaction does not pass shielded input checks, as bindingSig - // consensus rule is enforced. + // consensus rule is enforced. ContextualCheckShieldedInputs passes because + // the rest of the input checks pass, but saplingAuth fails when it attempts + // to validate the batch of signatures that includes bindingSig. // - Note that coinbase txs don't have a previous output corresponding to // their transparent input; ZIP 244 handles this by making the coinbase // sighash the txid. PrecomputedTransactionData txdata(tx, {}); AssumeShieldedInputsExistAndAreSpendable baseView; CCoinsViewCache view(&baseView); - EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-sapling-binding-signature-invalid", false, "")).Times(1); - EXPECT_FALSE(ContextualCheckShieldedInputs( - tx, txdata, state, view, orchardAuth, chainparams.GetConsensus(), heartwoodBranchId, false, true)); + EXPECT_TRUE(ContextualCheckShieldedInputs( + tx, txdata, state, view, saplingAuth, orchardAuth, chainparams.GetConsensus(), heartwoodBranchId, false, true)); + EXPECT_FALSE(saplingAuth.value()->validate()); RegtestDeactivateHeartwood(); } diff --git a/src/main.cpp b/src/main.cpp index 2e35d00e3..37b991bd6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,7 +47,6 @@ #include #include -#include using namespace std; @@ -1246,6 +1245,7 @@ bool ContextualCheckShieldedInputs( const PrecomputedTransactionData& txdata, CValidationState &state, const CCoinsViewCache &view, + std::optional>& saplingAuth, std::optional& orchardAuth, const Consensus::Params& consensus, uint32_t consensusBranchId, @@ -1318,17 +1318,16 @@ bool ContextualCheckShieldedInputs( if (!tx.vShieldedSpend.empty() || !tx.vShieldedOutput.empty()) { - auto ctx = sapling::init_verifier(); + auto assembler = sapling::new_bundle_assembler(); for (const SpendDescription &spend : tx.vShieldedSpend) { - if (!ctx->check_spend( + if (!assembler->add_spend( spend.cv.GetRawBytes(), spend.anchor.GetRawBytes(), spend.nullifier.GetRawBytes(), spend.rk.GetRawBytes(), spend.zkproof, - spend.spendAuthSig, - dataToBeSigned.GetRawBytes() + spend.spendAuthSig )) { return state.DoS( dosLevelPotentiallyRelaxing, @@ -1338,10 +1337,12 @@ bool ContextualCheckShieldedInputs( } for (const OutputDescription &output : tx.vShieldedOutput) { - if (!ctx->check_output( + if (!assembler->add_output( output.cv.GetRawBytes(), output.cmu.GetRawBytes(), output.ephemeralKey.GetRawBytes(), + output.encCiphertext, + output.outCiphertext, output.zkproof )) { // This should be a non-contextual check, but we check it here @@ -1352,15 +1353,19 @@ bool ContextualCheckShieldedInputs( } } - if (!ctx->final_check( + auto bundle = sapling::finish_bundle_assembly( + std::move(assembler), tx.GetValueBalanceSapling(), - tx.bindingSig, - dataToBeSigned.GetRawBytes() - )) { - return state.DoS( - dosLevelPotentiallyRelaxing, - error("ContextualCheckShieldedInputs(): Sapling binding signature invalid"), - REJECT_INVALID, "bad-txns-sapling-binding-signature-invalid"); + tx.bindingSig); + + // Queue Sapling bundle to be batch-validated. This also checks some consensus rules. + if (saplingAuth.has_value()) { + if (!saplingAuth.value()->check_bundle(std::move(bundle), dataToBeSigned.GetRawBytes())) { + return state.DoS( + dosLevelPotentiallyRelaxing, + error("ContextualCheckShieldedInputs(): Sapling bundle invalid"), + REJECT_INVALID, "bad-txns-sapling-bundle-invalid"); + } } } @@ -1986,6 +1991,11 @@ bool AcceptToMemoryPool( __func__, hash.ToString(), FormatStateMessage(state)); } + // This will be a single-transaction batch, which will be more efficient + // than unbatched if the transaction contains at least one Sapling Spend + // or at least two Sapling Outputs. + std::optional> saplingAuth = sapling::init_batch_validator(); + // This will be a single-transaction batch, which is still more efficient as every // Orchard bundle contains at least two signatures. std::optional orchardAuth = orchard::AuthValidator::Batch(); @@ -1996,6 +2006,7 @@ bool AcceptToMemoryPool( txdata, state, view, + saplingAuth, orchardAuth, chainparams.GetConsensus(), consensusBranchId, @@ -2005,7 +2016,11 @@ bool AcceptToMemoryPool( return false; } - // Check Orchard bundle authorizations. `orchardAuth` here is known to be non-null + // Check Sapling and Orchard bundle authorizations. + // `saplingAuth` and `orchardAuth` are known here to be non-null. + if (!saplingAuth.value()->validate()) { + return state.DoS(100, false, REJECT_INVALID, "bad-sapling-bundle-authorization"); + } if (!orchardAuth.value().Validate()) { return state.DoS(100, false, REJECT_INVALID, "bad-orchard-bundle-authorization"); } @@ -3059,7 +3074,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // proof verification is expensive, disable if possible auto verifier = fExpensiveChecks ? ProofVerifier::Strict() : ProofVerifier::Disabled(); - // Disable Orchard batch signature validation if possible. + // Disable Sapling and Orchard batch validation if possible. + std::optional> saplingAuth = fExpensiveChecks ? + std::optional(sapling::init_batch_validator()) : std::nullopt; std::optional orchardAuth = fExpensiveChecks ? orchard::AuthValidator::Batch() : orchard::AuthValidator::Disabled(); @@ -3302,6 +3319,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin txdata.back(), state, view, + saplingAuth, orchardAuth, chainparams.GetConsensus(), consensusBranchId, @@ -3502,6 +3520,13 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin block.vtx[0].GetValueOut(), blockReward), REJECT_INVALID, "bad-cb-amount"); + // Ensure Sapling authorizations are valid (if we are checking them) + if (saplingAuth.has_value() && !saplingAuth.value()->validate()) { + return state.DoS(100, + error("ConnectBlock(): a Sapling bundle within the block is invalid"), + REJECT_INVALID, "bad-sapling-bundle-authorization"); + } + // Ensure Orchard signatures are valid (if we are checking them) if (orchardAuth.has_value() && !orchardAuth.value().Validate()) { return state.DoS(100, diff --git a/src/main.h b/src/main.h index ccb151835..cceb17424 100644 --- a/src/main.h +++ b/src/main.h @@ -43,6 +43,7 @@ #include #include +#include #include #include @@ -402,6 +403,7 @@ bool ContextualCheckShieldedInputs( const PrecomputedTransactionData& txdata, CValidationState &state, const CCoinsViewCache &view, + std::optional>& saplingAuth, std::optional& orchardAuth, const Consensus::Params& consensus, uint32_t consensusBranchId, diff --git a/src/rust/src/rustzcash.rs b/src/rust/src/rustzcash.rs index 9783c4939..8d66b41f8 100644 --- a/src/rust/src/rustzcash.rs +++ b/src/rust/src/rustzcash.rs @@ -19,7 +19,7 @@ // See https://github.com/rust-lang/rfcs/pull/2585 for more background. #![allow(clippy::not_unsafe_ptr_arg_deref)] -use bellman::groth16::{Parameters, PreparedVerifyingKey}; +use bellman::groth16::{self, prepare_verifying_key, Parameters, PreparedVerifyingKey}; use blake2s_simd::Params as Blake2sParams; use bls12_381::Bls12; use group::{cofactor::CofactorGroup, GroupEncoding}; @@ -88,8 +88,8 @@ mod test_harness_ffi; mod tests; static PROOF_PARAMETERS_LOADED: Once = Once::new(); -static mut SAPLING_SPEND_VK: Option> = None; -static mut SAPLING_OUTPUT_VK: Option> = None; +static mut SAPLING_SPEND_VK: Option> = None; +static mut SAPLING_OUTPUT_VK: Option> = None; static mut SPROUT_GROTH16_VK: Option> = None; static mut SAPLING_SPEND_PARAMS: Option> = None; @@ -179,6 +179,11 @@ pub extern "C" fn librustzcash_init_zksnark_params( let sapling_spend_params = params.spend_params; let sapling_output_params = params.output_params; + // We need to clone these because we aren't necessarily storing the proving + // parameters in memory. + let sapling_spend_vk = sapling_spend_params.vk.clone(); + let sapling_output_vk = sapling_output_params.vk.clone(); + // Generate Orchard parameters. info!(target: "main", "Loading Orchard parameters"); let orchard_pk = load_proving_keys.then(orchard::circuit::ProvingKey::build); @@ -191,8 +196,8 @@ pub extern "C" fn librustzcash_init_zksnark_params( SAPLING_OUTPUT_PARAMS = load_proving_keys.then(|| sapling_output_params); SPROUT_GROTH16_PARAMS_PATH = sprout_path.map(|p| p.to_owned()); - SAPLING_SPEND_VK = Some(params.spend_vk); - SAPLING_OUTPUT_VK = Some(params.output_vk); + SAPLING_SPEND_VK = Some(sapling_spend_vk); + SAPLING_OUTPUT_VK = Some(sapling_output_vk); SPROUT_GROTH16_VK = params.sprout_vk; ORCHARD_PK = orchard_pk; @@ -845,7 +850,7 @@ pub extern "C" fn librustzcash_sapling_spend_proof( anchor, merkle_path, unsafe { SAPLING_SPEND_PARAMS.as_ref() }.unwrap(), - unsafe { SAPLING_SPEND_VK.as_ref() }.unwrap(), + &prepare_verifying_key(unsafe { SAPLING_SPEND_VK.as_ref() }.unwrap()), ) .expect("proving should not fail"); diff --git a/src/rust/src/sapling.rs b/src/rust/src/sapling.rs index 79955a053..e8fa8f2e3 100644 --- a/src/rust/src/sapling.rs +++ b/src/rust/src/sapling.rs @@ -7,14 +7,19 @@ // on the entire module. #![allow(clippy::too_many_arguments)] -use bellman::groth16::Proof; +use bellman::groth16::{prepare_verifying_key, Proof}; use group::GroupEncoding; +use rand_core::OsRng; +use zcash_note_encryption::EphemeralKeyBytes; use zcash_primitives::{ - sapling::redjubjub::{self, Signature}, - transaction::components::Amount, + sapling::{ + redjubjub::{self, Signature}, + Nullifier, + }, + transaction::components::{sapling, Amount}, }; -use zcash_proofs::sapling::SaplingVerificationContext; +use zcash_proofs::sapling::{self as sapling_proofs, SaplingVerificationContext}; use super::GROTH_PROOF_SIZE; use super::{de_ct, SAPLING_OUTPUT_VK, SAPLING_SPEND_VK}; @@ -22,11 +27,38 @@ use super::{de_ct, SAPLING_OUTPUT_VK, SAPLING_SPEND_VK}; #[cxx::bridge(namespace = "sapling")] mod ffi { extern "Rust" { + type Bundle; + type BundleAssembler; + fn new_bundle_assembler() -> Box; + fn add_spend( + self: &mut BundleAssembler, + cv: &[u8; 32], + anchor: &[u8; 32], + nullifier: [u8; 32], + rk: &[u8; 32], + zkproof: [u8; 192], // GROTH_PROOF_SIZE + spend_auth_sig: &[u8; 64], + ) -> bool; + fn add_output( + self: &mut BundleAssembler, + cv: &[u8; 32], + cmu: &[u8; 32], + ephemeral_key: [u8; 32], + enc_ciphertext: [u8; 580], + out_ciphertext: [u8; 80], + zkproof: [u8; 192], // GROTH_PROOF_SIZE + ) -> bool; + fn finish_bundle_assembly( + assembler: Box, + value_balance: i64, + binding_sig: [u8; 64], + ) -> Box; + type Verifier; fn init_verifier() -> Box; fn check_spend( - &mut self, + self: &mut Verifier, cv: &[u8; 32], anchor: &[u8; 32], nullifier: &[u8; 32], @@ -36,21 +68,139 @@ mod ffi { sighash_value: &[u8; 32], ) -> bool; fn check_output( - &mut self, + self: &mut Verifier, cv: &[u8; 32], cm: &[u8; 32], ephemeral_key: &[u8; 32], zkproof: &[u8; 192], // GROTH_PROOF_SIZE ) -> bool; fn final_check( - &self, + self: &Verifier, value_balance: i64, binding_sig: &[u8; 64], sighash_value: &[u8; 32], ) -> bool; + + type BatchValidator; + fn init_batch_validator() -> Box; + fn check_bundle(self: &mut BatchValidator, bundle: Box, sighash: [u8; 32]) -> bool; + fn validate(self: &mut BatchValidator) -> bool; } } +struct Bundle(sapling::Bundle); + +struct BundleAssembler { + shielded_spends: Vec>, + shielded_outputs: Vec>, // GROTH_PROOF_SIZE +} + +fn new_bundle_assembler() -> Box { + Box::new(BundleAssembler { + shielded_spends: vec![], + shielded_outputs: vec![], + }) +} + +impl BundleAssembler { + fn add_spend( + self: &mut BundleAssembler, + cv: &[u8; 32], + anchor: &[u8; 32], + nullifier: [u8; 32], + rk: &[u8; 32], + zkproof: [u8; 192], // GROTH_PROOF_SIZE + spend_auth_sig: &[u8; 64], + ) -> bool { + // Deserialize the value commitment + let cv = match de_ct(jubjub::ExtendedPoint::from_bytes(cv)) { + Some(p) => p, + None => return false, + }; + + // Deserialize the anchor, which should be an element + // of Fr. + let anchor = match de_ct(bls12_381::Scalar::from_bytes(anchor)) { + Some(a) => a, + None => return false, + }; + + // Deserialize rk + let rk = match redjubjub::PublicKey::read(&rk[..]) { + Ok(p) => p, + Err(_) => return false, + }; + + // Deserialize the signature + let spend_auth_sig = match Signature::read(&spend_auth_sig[..]) { + Ok(sig) => sig, + Err(_) => return false, + }; + + self.shielded_spends.push(sapling::SpendDescription { + cv, + anchor, + nullifier: Nullifier(nullifier), + rk, + zkproof, + spend_auth_sig, + }); + + true + } + + fn add_output( + self: &mut BundleAssembler, + cv: &[u8; 32], + cm: &[u8; 32], + ephemeral_key: [u8; 32], + enc_ciphertext: [u8; 580], + out_ciphertext: [u8; 80], + zkproof: [u8; 192], // GROTH_PROOF_SIZE + ) -> bool { + // Deserialize the value commitment + let cv = match de_ct(jubjub::ExtendedPoint::from_bytes(cv)) { + Some(p) => p, + None => return false, + }; + + // Deserialize the commitment, which should be an element + // of Fr. + let cmu = match de_ct(bls12_381::Scalar::from_bytes(cm)) { + Some(a) => a, + None => return false, + }; + + self.shielded_outputs.push(sapling::OutputDescription { + cv, + cmu, + ephemeral_key: EphemeralKeyBytes(ephemeral_key), + enc_ciphertext, + out_ciphertext, + zkproof, + }); + + true + } +} + +#[allow(clippy::boxed_local)] +fn finish_bundle_assembly( + assembler: Box, + value_balance: i64, + binding_sig: [u8; 64], +) -> Box { + let value_balance = Amount::from_i64(value_balance).expect("parsed elsewhere"); + let binding_sig = redjubjub::Signature::read(&binding_sig[..]).expect("parsed elsewhere"); + + Box::new(Bundle(sapling::Bundle { + shielded_spends: assembler.shielded_spends, + shielded_outputs: assembler.shielded_outputs, + value_balance, + authorization: sapling::Authorized { binding_sig }, + })) +} + struct Verifier(SaplingVerificationContext); fn init_verifier() -> Box { @@ -110,7 +260,7 @@ impl Verifier { sighash_value, spend_auth_sig, zkproof, - unsafe { SAPLING_SPEND_VK.as_ref() }.unwrap(), + &prepare_verifying_key(unsafe { SAPLING_SPEND_VK.as_ref() }.unwrap()), ) } fn check_output( @@ -134,7 +284,7 @@ impl Verifier { }; // Deserialize the ephemeral key - let ephemeral_key = match de_ct(jubjub::ExtendedPoint::from_bytes(ephemeral_key)) { + let epk = match de_ct(jubjub::ExtendedPoint::from_bytes(ephemeral_key)) { Some(p) => p, None => return false, }; @@ -148,9 +298,9 @@ impl Verifier { self.0.check_output( cv, cm, - ephemeral_key, + epk, zkproof, - unsafe { SAPLING_OUTPUT_VK.as_ref() }.unwrap(), + &prepare_verifying_key(unsafe { SAPLING_OUTPUT_VK.as_ref() }.unwrap()), ) } fn final_check( @@ -174,3 +324,43 @@ impl Verifier { .final_check(value_balance, sighash_value, binding_sig) } } + +struct BatchValidator(Option); + +fn init_batch_validator() -> Box { + Box::new(BatchValidator(Some(sapling_proofs::BatchValidator::new()))) +} + +impl BatchValidator { + /// Checks the bundle against Sapling-specific consensus rules, and queues its + /// authorization for validation. + /// + /// Returns `false` if the bundle doesn't satisfy the checked consensus rules. This + /// `BatchValidator` can continue to be used regardless, but some or all of the proofs + /// and signatures from this bundle may have already been added to the batch even if + /// it fails other consensus rules. + /// + /// `sighash` must be for the transaction this bundle is within. + #[allow(clippy::boxed_local)] + fn check_bundle(&mut self, bundle: Box, sighash: [u8; 32]) -> bool { + if let Some(validator) = &mut self.0 { + validator.check_bundle(bundle.0, sighash) + } else { + tracing::error!("sapling::BatchValidator has already been used"); + false + } + } + + fn validate(&mut self) -> bool { + if let Some(validator) = self.0.take() { + validator.validate( + unsafe { SAPLING_SPEND_VK.as_ref() }.unwrap(), + unsafe { SAPLING_OUTPUT_VK.as_ref() }.unwrap(), + OsRng, + ) + } else { + tracing::error!("sapling::BatchValidator has already been used"); + false + } + } +} diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index d56e952fe..b7899f1c1 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -36,6 +36,7 @@ #include #include +#include #include #include @@ -356,6 +357,7 @@ void test_simple_sapling_invalidity(uint32_t consensusBranchId, CMutableTransact void test_simple_joinsplit_invalidity(uint32_t consensusBranchId, CMutableTransaction tx) { auto verifier = ProofVerifier::Strict(); + std::optional> saplingAuth = std::nullopt; auto orchardAuth = orchard::AuthValidator::Disabled(); { // Ensure that empty vin/vout remain invalid without @@ -390,7 +392,13 @@ void test_simple_joinsplit_invalidity(uint32_t consensusBranchId, CMutableTransa BOOST_CHECK(CheckTransactionWithoutProofVerification(newTx, state)); BOOST_CHECK(ContextualCheckTransaction(newTx, state, Params(), 0, true)); - BOOST_CHECK(!ContextualCheckShieldedInputs(newTx, txdata, state, view, orchardAuth, Params().GetConsensus(), consensusBranchId, false, true)); + BOOST_CHECK(!ContextualCheckShieldedInputs( + newTx, txdata, + state, view, + saplingAuth, orchardAuth, + Params().GetConsensus(), + consensusBranchId, + false, true)); BOOST_CHECK(state.GetRejectReason() == "bad-txns-invalid-joinsplit-signature"); // Empty output script. @@ -406,7 +414,13 @@ void test_simple_joinsplit_invalidity(uint32_t consensusBranchId, CMutableTransa state = CValidationState(); BOOST_CHECK(CheckTransactionWithoutProofVerification(newTx, state)); BOOST_CHECK(ContextualCheckTransaction(newTx, state, Params(), 0, true)); - BOOST_CHECK(ContextualCheckShieldedInputs(newTx, txdata, state, view, orchardAuth, Params().GetConsensus(), consensusBranchId, false, true)); + BOOST_CHECK(ContextualCheckShieldedInputs( + newTx, txdata, + state, view, + saplingAuth, orchardAuth, + Params().GetConsensus(), + consensusBranchId, + false, true)); BOOST_CHECK_EQUAL(state.GetRejectReason(), ""); } { diff --git a/src/uint256.h b/src/uint256.h index a8c9bbe5c..b5ab2f736 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -92,7 +92,7 @@ public: std::array GetRawBytes() const { std::array buf = {}; - memcpy(buf.data(), this->begin(), WIDTH); + std::memcpy(buf.data(), this->begin(), WIDTH); return buf; } From af59b2adb726dca30be5c9793be3b39a5df07d32 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 5 Jul 2022 18:16:34 +0000 Subject: [PATCH 3/3] qa: Reformat for latest cargo-vet --- qa/supply-chain/audits.toml | 56 +---- qa/supply-chain/config.toml | 461 ++++++++++++++++++------------------ 2 files changed, 234 insertions(+), 283 deletions(-) diff --git a/qa/supply-chain/audits.toml b/qa/supply-chain/audits.toml index fab661322..93083eb57 100644 --- a/qa/supply-chain/audits.toml +++ b/qa/supply-chain/audits.toml @@ -27,25 +27,13 @@ notes = "The ECC core team maintains this crate, and we have reviewed every line [[audits.f4jumble]] who = "Jack Grigg " -criteria = "crypto-reviewed" -version = "0.1.0" -notes = "The ECC core team maintains this crate, and we have reviewed every line." - -[[audits.f4jumble]] -who = "Jack Grigg " -criteria = "safe-to-deploy" +criteria = ["crypto-reviewed", "safe-to-deploy"] version = "0.1.0" notes = "The ECC core team maintains this crate, and we have reviewed every line." [[audits.halo2_gadgets]] who = "Jack Grigg " -criteria = "crypto-reviewed" -version = "0.1.0" -notes = "The ECC core team maintains this crate, and we have reviewed every line." - -[[audits.halo2_gadgets]] -who = "Jack Grigg " -criteria = "safe-to-deploy" +criteria = ["crypto-reviewed", "safe-to-deploy"] version = "0.1.0" notes = "The ECC core team maintains this crate, and we have reviewed every line." @@ -57,13 +45,7 @@ notes = "The ECC core team maintains this crate, and we have reviewed every line [[audits.halo2_proofs]] who = "Jack Grigg " -criteria = "crypto-reviewed" -version = "0.1.0" -notes = "The ECC core team maintains this crate, and we have reviewed every line." - -[[audits.halo2_proofs]] -who = "Jack Grigg " -criteria = "safe-to-deploy" +criteria = ["crypto-reviewed", "safe-to-deploy"] version = "0.1.0" notes = "The ECC core team maintains this crate, and we have reviewed every line." @@ -75,13 +57,7 @@ notes = "The ECC core team maintains this crate, and we have reviewed every line [[audits.orchard]] who = "Jack Grigg " -criteria = "crypto-reviewed" -version = "0.1.0" -notes = "The ECC core team maintains this crate, and we have reviewed every line." - -[[audits.orchard]] -who = "Jack Grigg " -criteria = "safe-to-deploy" +criteria = ["crypto-reviewed", "safe-to-deploy"] version = "0.1.0" notes = "The ECC core team maintains this crate, and we have reviewed every line." @@ -111,25 +87,13 @@ notes = "The ECC core team maintains this crate, and we have reviewed every line [[audits.zcash_note_encryption]] who = "Jack Grigg " -criteria = "crypto-reviewed" -version = "0.1.0" -notes = "The ECC core team maintains this crate, and we have reviewed every line." - -[[audits.zcash_note_encryption]] -who = "Jack Grigg " -criteria = "safe-to-deploy" +criteria = ["crypto-reviewed", "safe-to-deploy"] version = "0.1.0" notes = "The ECC core team maintains this crate, and we have reviewed every line." [[audits.zcash_primitives]] who = "Jack Grigg " -criteria = "crypto-reviewed" -version = "0.6.0" -notes = "The ECC core team maintains this crate, and we have reviewed every line." - -[[audits.zcash_primitives]] -who = "Jack Grigg " -criteria = "safe-to-deploy" +criteria = ["crypto-reviewed", "safe-to-deploy"] version = "0.6.0" notes = "The ECC core team maintains this crate, and we have reviewed every line." @@ -141,13 +105,7 @@ notes = "The ECC core team maintains this crate, and we have reviewed every line [[audits.zcash_proofs]] who = "Jack Grigg " -criteria = "crypto-reviewed" -version = "0.6.0" -notes = "The ECC core team maintains this crate, and we have reviewed every line." - -[[audits.zcash_proofs]] -who = "Jack Grigg " -criteria = "safe-to-deploy" +criteria = ["crypto-reviewed", "safe-to-deploy"] version = "0.6.0" notes = "The ECC core team maintains this crate, and we have reviewed every line." diff --git a/qa/supply-chain/config.toml b/qa/supply-chain/config.toml index 37e22e438..38011c6dc 100644 --- a/qa/supply-chain/config.toml +++ b/qa/supply-chain/config.toml @@ -1,914 +1,907 @@ # cargo-vet config file -[[unaudited.addr2line]] + +[[exemptions.addr2line]] version = "0.17.0" criteria = "safe-to-deploy" -[[unaudited.adler]] +[[exemptions.adler]] version = "1.0.2" criteria = "safe-to-deploy" -[[unaudited.aead]] +[[exemptions.aead]] version = "0.4.3" criteria = "safe-to-deploy" -[[unaudited.aes]] +[[exemptions.aes]] version = "0.7.5" criteria = "safe-to-deploy" -[[unaudited.ahash]] +[[exemptions.ahash]] version = "0.7.6" criteria = "safe-to-deploy" -[[unaudited.ansi_term]] +[[exemptions.ansi_term]] version = "0.12.1" criteria = "safe-to-deploy" -[[unaudited.anyhow]] +[[exemptions.anyhow]] version = "1.0.56" criteria = "safe-to-deploy" -[[unaudited.arrayref]] +[[exemptions.arrayref]] version = "0.3.6" criteria = "safe-to-deploy" -[[unaudited.arrayvec]] -version = "0.5.2" -criteria = "safe-to-deploy" - -[[unaudited.arrayvec]] +[[exemptions.arrayvec]] version = "0.7.2" criteria = "safe-to-deploy" -[[unaudited.atomic-shim]] +[[exemptions.atomic-shim]] version = "0.2.0" criteria = "safe-to-deploy" -[[unaudited.autocfg]] +[[exemptions.autocfg]] version = "1.1.0" criteria = "safe-to-deploy" -[[unaudited.backtrace]] +[[exemptions.backtrace]] version = "0.3.64" criteria = "safe-to-deploy" -[[unaudited.base64ct]] +[[exemptions.base64ct]] version = "1.0.1" criteria = "safe-to-deploy" -[[unaudited.bech32]] +[[exemptions.bech32]] version = "0.8.1" criteria = "safe-to-deploy" -[[unaudited.bellman]] +[[exemptions.bellman]] version = "0.13.0" criteria = "safe-to-deploy" -[[unaudited.bip0039]] +[[exemptions.bip0039]] version = "0.9.0" criteria = "safe-to-deploy" -[[unaudited.bitflags]] +[[exemptions.bitflags]] version = "1.3.2" criteria = "safe-to-deploy" -[[unaudited.bitvec]] +[[exemptions.bitvec]] version = "1.0.0" criteria = "safe-to-deploy" -[[unaudited.blake2b_simd]] -version = "0.5.11" -criteria = "safe-to-deploy" - -[[unaudited.blake2b_simd]] +[[exemptions.blake2b_simd]] version = "1.0.0" criteria = "safe-to-deploy" -[[unaudited.blake2s_simd]] +[[exemptions.blake2s_simd]] version = "1.0.0" criteria = "safe-to-deploy" -[[unaudited.block-buffer]] +[[exemptions.block-buffer]] version = "0.9.0" criteria = "safe-to-deploy" -[[unaudited.block-buffer]] +[[exemptions.block-buffer]] version = "0.10.2" criteria = "safe-to-deploy" -[[unaudited.block-modes]] +[[exemptions.block-modes]] version = "0.8.1" criteria = "safe-to-deploy" -[[unaudited.block-padding]] +[[exemptions.block-padding]] version = "0.2.1" criteria = "safe-to-deploy" -[[unaudited.bls12_381]] +[[exemptions.bls12_381]] version = "0.7.0" criteria = "safe-to-deploy" -[[unaudited.bs58]] +[[exemptions.bs58]] version = "0.4.0" criteria = "safe-to-deploy" -[[unaudited.bumpalo]] +[[exemptions.bumpalo]] version = "3.8.0" criteria = "safe-to-deploy" -[[unaudited.byte-slice-cast]] +[[exemptions.byte-slice-cast]] version = "1.2.1" criteria = "safe-to-deploy" -[[unaudited.byteorder]] +[[exemptions.byteorder]] version = "1.4.3" criteria = "safe-to-deploy" -[[unaudited.bytes]] +[[exemptions.bytes]] version = "1.1.0" criteria = "safe-to-deploy" -[[unaudited.cc]] +[[exemptions.cc]] version = "1.0.73" criteria = "safe-to-deploy" -[[unaudited.cfg-if]] +[[exemptions.cfg-if]] version = "0.1.10" criteria = "safe-to-deploy" -[[unaudited.cfg-if]] +[[exemptions.cfg-if]] version = "1.0.0" criteria = "safe-to-deploy" -[[unaudited.chacha20]] +[[exemptions.chacha20]] version = "0.8.1" criteria = "safe-to-deploy" -[[unaudited.chacha20poly1305]] +[[exemptions.chacha20poly1305]] version = "0.9.0" criteria = "safe-to-deploy" -[[unaudited.cipher]] +[[exemptions.cipher]] version = "0.3.0" criteria = "safe-to-deploy" -[[unaudited.clearscreen]] +[[exemptions.clearscreen]] version = "1.0.9" criteria = "safe-to-deploy" -[[unaudited.constant_time_eq]] +[[exemptions.constant_time_eq]] version = "0.1.5" criteria = "safe-to-deploy" -[[unaudited.cpufeatures]] +[[exemptions.cpufeatures]] version = "0.2.2" criteria = "safe-to-deploy" -[[unaudited.crossbeam-channel]] +[[exemptions.crossbeam-channel]] version = "0.5.4" criteria = "safe-to-deploy" -[[unaudited.crossbeam-deque]] +[[exemptions.crossbeam-deque]] version = "0.8.1" criteria = "safe-to-deploy" -[[unaudited.crossbeam-epoch]] +[[exemptions.crossbeam-epoch]] version = "0.9.8" criteria = "safe-to-deploy" -[[unaudited.crossbeam-utils]] +[[exemptions.crossbeam-utils]] version = "0.8.8" criteria = "safe-to-deploy" -[[unaudited.crunchy]] +[[exemptions.crunchy]] version = "0.2.2" criteria = "safe-to-deploy" -[[unaudited.crypto-common]] +[[exemptions.crypto-common]] version = "0.1.3" criteria = "safe-to-deploy" -[[unaudited.crypto-mac]] +[[exemptions.crypto-mac]] version = "0.11.1" criteria = "safe-to-deploy" -[[unaudited.curve25519-dalek]] +[[exemptions.curve25519-dalek]] version = "3.2.0" criteria = "safe-to-deploy" -[[unaudited.cxx]] +[[exemptions.cxx]] version = "1.0.68" criteria = "safe-to-deploy" -[[unaudited.cxxbridge-flags]] +[[exemptions.cxxbridge-flags]] version = "1.0.68" criteria = "safe-to-deploy" -[[unaudited.cxxbridge-macro]] +[[exemptions.cxxbridge-macro]] version = "1.0.68" criteria = "safe-to-deploy" -[[unaudited.digest]] +[[exemptions.digest]] version = "0.9.0" criteria = "safe-to-deploy" -[[unaudited.digest]] +[[exemptions.digest]] version = "0.10.3" criteria = "safe-to-deploy" -[[unaudited.directories]] +[[exemptions.directories]] version = "4.0.1" criteria = "safe-to-deploy" -[[unaudited.dirs]] +[[exemptions.dirs]] version = "2.0.2" criteria = "safe-to-deploy" -[[unaudited.dirs-sys]] +[[exemptions.dirs-sys]] version = "0.3.7" criteria = "safe-to-deploy" -[[unaudited.ed25519-zebra]] +[[exemptions.ed25519-zebra]] version = "3.0.0" criteria = "safe-to-deploy" -[[unaudited.either]] +[[exemptions.either]] version = "1.6.1" criteria = "safe-to-deploy" -[[unaudited.ff]] +[[exemptions.ff]] version = "0.12.0" criteria = "safe-to-deploy" -[[unaudited.fixed-hash]] +[[exemptions.fixed-hash]] version = "0.7.0" criteria = "safe-to-deploy" -[[unaudited.fnv]] +[[exemptions.fnv]] version = "1.0.7" criteria = "safe-to-deploy" -[[unaudited.fpe]] +[[exemptions.fpe]] version = "0.5.1" criteria = "safe-to-deploy" -[[unaudited.funty]] +[[exemptions.funty]] version = "2.0.0" criteria = "safe-to-deploy" -[[unaudited.futures-channel]] +[[exemptions.futures-channel]] version = "0.3.21" criteria = "safe-to-deploy" -[[unaudited.futures-core]] +[[exemptions.futures-core]] version = "0.3.21" criteria = "safe-to-deploy" -[[unaudited.futures-task]] +[[exemptions.futures-task]] version = "0.3.21" criteria = "safe-to-deploy" -[[unaudited.futures-util]] +[[exemptions.futures-util]] version = "0.3.21" criteria = "safe-to-deploy" -[[unaudited.generic-array]] +[[exemptions.generic-array]] version = "0.14.5" criteria = "safe-to-deploy" -[[unaudited.getrandom]] +[[exemptions.getrandom]] version = "0.1.16" criteria = "safe-to-deploy" -[[unaudited.getrandom]] +[[exemptions.getrandom]] version = "0.2.6" criteria = "safe-to-deploy" -[[unaudited.gimli]] +[[exemptions.gimli]] version = "0.26.1" criteria = "safe-to-deploy" -[[unaudited.group]] +[[exemptions.group]] version = "0.12.0" criteria = "safe-to-deploy" -[[unaudited.gumdrop]] +[[exemptions.gumdrop]] version = "0.8.1" criteria = "safe-to-deploy" -[[unaudited.gumdrop_derive]] +[[exemptions.gumdrop_derive]] version = "0.8.1" criteria = "safe-to-deploy" -[[unaudited.hashbrown]] +[[exemptions.hashbrown]] version = "0.11.2" criteria = "safe-to-deploy" -[[unaudited.hdwallet]] +[[exemptions.hdwallet]] version = "0.3.1" criteria = "safe-to-deploy" -[[unaudited.hermit-abi]] +[[exemptions.hermit-abi]] version = "0.1.19" criteria = "safe-to-deploy" -[[unaudited.hex]] +[[exemptions.hex]] version = "0.4.3" criteria = "safe-to-deploy" -[[unaudited.hmac]] +[[exemptions.hmac]] version = "0.11.0" criteria = "safe-to-deploy" -[[unaudited.http]] +[[exemptions.http]] version = "0.2.6" criteria = "safe-to-deploy" -[[unaudited.http-body]] +[[exemptions.http-body]] version = "0.4.4" criteria = "safe-to-deploy" -[[unaudited.httparse]] +[[exemptions.httparse]] version = "1.6.0" criteria = "safe-to-deploy" -[[unaudited.httpdate]] +[[exemptions.httpdate]] version = "1.0.2" criteria = "safe-to-deploy" -[[unaudited.hyper]] +[[exemptions.hyper]] version = "0.14.18" criteria = "safe-to-deploy" -[[unaudited.impl-codec]] +[[exemptions.impl-codec]] version = "0.6.0" criteria = "safe-to-deploy" -[[unaudited.impl-trait-for-tuples]] +[[exemptions.impl-trait-for-tuples]] version = "0.2.2" criteria = "safe-to-deploy" -[[unaudited.incrementalmerkletree]] +[[exemptions.incrementalmerkletree]] version = "0.3.0" criteria = "safe-to-deploy" -[[unaudited.indexmap]] +[[exemptions.indexmap]] version = "1.8.1" criteria = "safe-to-deploy" -[[unaudited.instant]] +[[exemptions.instant]] version = "0.1.12" criteria = "safe-to-deploy" -[[unaudited.ipnet]] +[[exemptions.ipnet]] version = "2.4.0" criteria = "safe-to-deploy" -[[unaudited.itoa]] +[[exemptions.itoa]] version = "1.0.1" criteria = "safe-to-deploy" -[[unaudited.js-sys]] +[[exemptions.js-sys]] version = "0.3.57" criteria = "safe-to-deploy" -[[unaudited.jubjub]] +[[exemptions.jubjub]] version = "0.9.0" criteria = "safe-to-deploy" -[[unaudited.lazy_static]] +[[exemptions.lazy_static]] version = "1.4.0" criteria = "safe-to-deploy" -[[unaudited.libc]] +[[exemptions.libc]] version = "0.2.122" criteria = "safe-to-deploy" -[[unaudited.libm]] +[[exemptions.libm]] version = "0.2.2" criteria = "safe-to-deploy" -[[unaudited.link-cplusplus]] +[[exemptions.link-cplusplus]] version = "1.0.6" criteria = "safe-to-deploy" -[[unaudited.lock_api]] +[[exemptions.lock_api]] version = "0.4.7" criteria = "safe-to-deploy" -[[unaudited.log]] +[[exemptions.log]] version = "0.4.16" criteria = "safe-to-deploy" -[[unaudited.mach]] +[[exemptions.mach]] version = "0.3.2" criteria = "safe-to-deploy" -[[unaudited.matchers]] +[[exemptions.matchers]] version = "0.1.0" criteria = "safe-to-deploy" -[[unaudited.memchr]] +[[exemptions.memchr]] version = "2.4.1" criteria = "safe-to-deploy" -[[unaudited.memoffset]] +[[exemptions.memoffset]] version = "0.6.5" criteria = "safe-to-deploy" -[[unaudited.memuse]] +[[exemptions.memuse]] version = "0.2.0" criteria = "safe-to-deploy" -[[unaudited.metrics]] +[[exemptions.metrics]] version = "0.19.0" criteria = "safe-to-deploy" -[[unaudited.metrics-exporter-prometheus]] +[[exemptions.metrics-exporter-prometheus]] version = "0.10.0" criteria = "safe-to-deploy" -[[unaudited.metrics-macros]] +[[exemptions.metrics-macros]] version = "0.5.1" criteria = "safe-to-deploy" -[[unaudited.metrics-util]] +[[exemptions.metrics-util]] version = "0.13.0" criteria = "safe-to-deploy" -[[unaudited.miniz_oxide]] +[[exemptions.miniz_oxide]] version = "0.4.4" criteria = "safe-to-deploy" -[[unaudited.mio]] +[[exemptions.mio]] version = "0.8.2" criteria = "safe-to-deploy" -[[unaudited.miow]] +[[exemptions.miow]] version = "0.3.7" criteria = "safe-to-deploy" -[[unaudited.nix]] +[[exemptions.nix]] version = "0.22.3" criteria = "safe-to-deploy" -[[unaudited.nom]] +[[exemptions.nom]] version = "5.1.2" criteria = "safe-to-deploy" -[[unaudited.nonempty]] +[[exemptions.nonempty]] version = "0.7.0" criteria = "safe-to-deploy" -[[unaudited.ntapi]] +[[exemptions.ntapi]] version = "0.3.7" criteria = "safe-to-deploy" -[[unaudited.num-bigint]] +[[exemptions.num-bigint]] version = "0.4.3" criteria = "safe-to-deploy" -[[unaudited.num-integer]] +[[exemptions.num-integer]] version = "0.1.44" criteria = "safe-to-deploy" -[[unaudited.num-traits]] +[[exemptions.num-traits]] version = "0.2.14" criteria = "safe-to-deploy" -[[unaudited.num_cpus]] +[[exemptions.num_cpus]] version = "1.13.1" criteria = "safe-to-deploy" -[[unaudited.num_threads]] +[[exemptions.num_threads]] version = "0.1.5" criteria = "safe-to-deploy" -[[unaudited.object]] +[[exemptions.object]] version = "0.27.1" criteria = "safe-to-deploy" -[[unaudited.once_cell]] +[[exemptions.once_cell]] version = "1.10.0" criteria = "safe-to-deploy" -[[unaudited.opaque-debug]] +[[exemptions.opaque-debug]] version = "0.3.0" criteria = "safe-to-deploy" -[[unaudited.pairing]] +[[exemptions.pairing]] version = "0.22.0" criteria = "safe-to-deploy" -[[unaudited.parity-scale-codec]] +[[exemptions.parity-scale-codec]] version = "3.1.2" criteria = "safe-to-deploy" -[[unaudited.parity-scale-codec-derive]] +[[exemptions.parity-scale-codec-derive]] version = "3.1.2" criteria = "safe-to-deploy" -[[unaudited.parking_lot]] +[[exemptions.parking_lot]] version = "0.11.2" criteria = "safe-to-deploy" -[[unaudited.parking_lot_core]] +[[exemptions.parking_lot_core]] version = "0.8.5" criteria = "safe-to-deploy" -[[unaudited.password-hash]] +[[exemptions.password-hash]] version = "0.3.2" criteria = "safe-to-deploy" -[[unaudited.pasta_curves]] +[[exemptions.pasta_curves]] version = "0.4.0" criteria = "safe-to-deploy" -[[unaudited.pbkdf2]] +[[exemptions.pbkdf2]] version = "0.9.0" criteria = "safe-to-deploy" -[[unaudited.phf]] +[[exemptions.phf]] version = "0.8.0" criteria = "safe-to-deploy" -[[unaudited.phf_codegen]] +[[exemptions.phf_codegen]] version = "0.8.0" criteria = "safe-to-deploy" -[[unaudited.phf_generator]] +[[exemptions.phf_generator]] version = "0.8.0" criteria = "safe-to-deploy" -[[unaudited.phf_shared]] +[[exemptions.phf_shared]] version = "0.8.0" criteria = "safe-to-deploy" -[[unaudited.pin-project-lite]] +[[exemptions.pin-project-lite]] version = "0.2.8" criteria = "safe-to-deploy" -[[unaudited.pin-utils]] +[[exemptions.pin-utils]] version = "0.1.0" criteria = "safe-to-deploy" -[[unaudited.poly1305]] +[[exemptions.poly1305]] version = "0.7.2" criteria = "safe-to-deploy" -[[unaudited.ppv-lite86]] +[[exemptions.ppv-lite86]] version = "0.2.16" criteria = "safe-to-deploy" -[[unaudited.primitive-types]] +[[exemptions.primitive-types]] version = "0.11.1" criteria = "safe-to-deploy" -[[unaudited.proc-macro-crate]] +[[exemptions.proc-macro-crate]] version = "1.1.3" criteria = "safe-to-deploy" -[[unaudited.proc-macro2]] +[[exemptions.proc-macro2]] version = "1.0.37" criteria = "safe-to-deploy" -[[unaudited.quanta]] +[[exemptions.quanta]] version = "0.9.3" criteria = "safe-to-deploy" -[[unaudited.quote]] +[[exemptions.quote]] version = "1.0.17" criteria = "safe-to-deploy" -[[unaudited.radium]] +[[exemptions.radium]] version = "0.7.0" criteria = "safe-to-deploy" -[[unaudited.rand]] +[[exemptions.rand]] version = "0.7.3" criteria = "safe-to-deploy" -[[unaudited.rand]] +[[exemptions.rand]] version = "0.8.5" criteria = "safe-to-deploy" -[[unaudited.rand_chacha]] +[[exemptions.rand_chacha]] version = "0.2.2" criteria = "safe-to-deploy" -[[unaudited.rand_chacha]] +[[exemptions.rand_chacha]] version = "0.3.1" criteria = "safe-to-deploy" -[[unaudited.rand_core]] +[[exemptions.rand_core]] version = "0.5.1" criteria = "safe-to-deploy" -[[unaudited.rand_core]] +[[exemptions.rand_core]] version = "0.6.3" criteria = "safe-to-deploy" -[[unaudited.rand_hc]] +[[exemptions.rand_hc]] version = "0.2.0" criteria = "safe-to-deploy" -[[unaudited.rand_pcg]] +[[exemptions.rand_pcg]] version = "0.2.1" criteria = "safe-to-deploy" -[[unaudited.raw-cpuid]] +[[exemptions.raw-cpuid]] version = "10.3.0" criteria = "safe-to-deploy" -[[unaudited.rayon]] +[[exemptions.rayon]] version = "1.5.1" criteria = "safe-to-deploy" -[[unaudited.rayon-core]] +[[exemptions.rayon-core]] version = "1.9.1" criteria = "safe-to-deploy" -[[unaudited.reddsa]] +[[exemptions.reddsa]] version = "0.3.0" criteria = "safe-to-deploy" -[[unaudited.redjubjub]] +[[exemptions.redjubjub]] version = "0.5.0" criteria = "safe-to-deploy" -[[unaudited.redox_syscall]] +[[exemptions.redox_syscall]] version = "0.2.13" criteria = "safe-to-deploy" -[[unaudited.redox_users]] +[[exemptions.redox_users]] version = "0.4.3" criteria = "safe-to-deploy" -[[unaudited.regex]] +[[exemptions.regex]] version = "1.5.5" criteria = "safe-to-deploy" -[[unaudited.regex-automata]] +[[exemptions.regex-automata]] version = "0.1.10" criteria = "safe-to-deploy" -[[unaudited.regex-syntax]] +[[exemptions.regex-syntax]] version = "0.6.25" criteria = "safe-to-deploy" -[[unaudited.ring]] +[[exemptions.ring]] version = "0.16.20" criteria = "safe-to-deploy" -[[unaudited.ripemd]] +[[exemptions.ripemd]] version = "0.1.1" criteria = "safe-to-deploy" -[[unaudited.rustc-demangle]] +[[exemptions.rustc-demangle]] version = "0.1.21" criteria = "safe-to-deploy" -[[unaudited.rustc-hex]] +[[exemptions.rustc-hex]] version = "2.1.0" criteria = "safe-to-deploy" -[[unaudited.scopeguard]] +[[exemptions.scopeguard]] version = "1.1.0" criteria = "safe-to-deploy" -[[unaudited.secp256k1]] +[[exemptions.secp256k1]] version = "0.21.3" criteria = "safe-to-deploy" -[[unaudited.secp256k1-sys]] +[[exemptions.secp256k1-sys]] version = "0.4.2" criteria = "safe-to-deploy" -[[unaudited.secrecy]] +[[exemptions.secrecy]] version = "0.8.0" criteria = "safe-to-deploy" -[[unaudited.serde]] +[[exemptions.serde]] version = "1.0.136" criteria = "safe-to-deploy" -[[unaudited.serde_derive]] +[[exemptions.serde_derive]] version = "1.0.136" criteria = "safe-to-deploy" -[[unaudited.sha2]] +[[exemptions.sha2]] version = "0.9.9" criteria = "safe-to-deploy" -[[unaudited.sharded-slab]] +[[exemptions.sharded-slab]] version = "0.1.4" criteria = "safe-to-deploy" -[[unaudited.siphasher]] +[[exemptions.siphasher]] version = "0.3.10" criteria = "safe-to-deploy" -[[unaudited.sketches-ddsketch]] +[[exemptions.sketches-ddsketch]] version = "0.1.3" criteria = "safe-to-deploy" -[[unaudited.smallvec]] +[[exemptions.smallvec]] version = "1.8.0" criteria = "safe-to-deploy" -[[unaudited.socket2]] +[[exemptions.socket2]] version = "0.4.4" criteria = "safe-to-deploy" -[[unaudited.spin]] +[[exemptions.spin]] version = "0.5.2" criteria = "safe-to-deploy" -[[unaudited.static_assertions]] +[[exemptions.static_assertions]] version = "1.1.0" criteria = "safe-to-deploy" -[[unaudited.subtle]] +[[exemptions.subtle]] version = "2.4.1" criteria = "safe-to-deploy" -[[unaudited.syn]] +[[exemptions.syn]] version = "1.0.91" criteria = "safe-to-deploy" -[[unaudited.synstructure]] +[[exemptions.synstructure]] version = "0.12.6" criteria = "safe-to-deploy" -[[unaudited.tap]] +[[exemptions.tap]] version = "1.0.1" criteria = "safe-to-deploy" -[[unaudited.terminfo]] +[[exemptions.terminfo]] version = "0.7.3" criteria = "safe-to-deploy" -[[unaudited.thiserror]] +[[exemptions.thiserror]] version = "1.0.30" criteria = "safe-to-deploy" -[[unaudited.thiserror-impl]] +[[exemptions.thiserror-impl]] version = "1.0.30" criteria = "safe-to-deploy" -[[unaudited.thread_local]] +[[exemptions.thread_local]] version = "1.1.4" criteria = "safe-to-deploy" -[[unaudited.time]] +[[exemptions.time]] version = "0.3.9" criteria = "safe-to-deploy" -[[unaudited.time-macros]] +[[exemptions.time-macros]] version = "0.2.4" criteria = "safe-to-deploy" -[[unaudited.tinyvec]] +[[exemptions.tinyvec]] version = "1.5.1" criteria = "safe-to-deploy" -[[unaudited.tinyvec_macros]] +[[exemptions.tinyvec_macros]] version = "0.1.0" criteria = "safe-to-deploy" -[[unaudited.tokio]] +[[exemptions.tokio]] version = "1.17.0" criteria = "safe-to-deploy" -[[unaudited.toml]] +[[exemptions.toml]] version = "0.5.9" criteria = "safe-to-deploy" -[[unaudited.tower-service]] +[[exemptions.tower-service]] version = "0.3.1" criteria = "safe-to-deploy" -[[unaudited.tracing]] +[[exemptions.tracing]] version = "0.1.32" criteria = "safe-to-deploy" -[[unaudited.tracing-appender]] +[[exemptions.tracing-appender]] version = "0.2.2" criteria = "safe-to-deploy" -[[unaudited.tracing-attributes]] +[[exemptions.tracing-attributes]] version = "0.1.20" criteria = "safe-to-deploy" -[[unaudited.tracing-core]] +[[exemptions.tracing-core]] version = "0.1.24" criteria = "safe-to-deploy" -[[unaudited.tracing-subscriber]] +[[exemptions.tracing-subscriber]] version = "0.3.10" criteria = "safe-to-deploy" -[[unaudited.try-lock]] +[[exemptions.try-lock]] version = "0.2.3" criteria = "safe-to-deploy" -[[unaudited.typenum]] +[[exemptions.typenum]] version = "1.15.0" criteria = "safe-to-deploy" -[[unaudited.uint]] +[[exemptions.uint]] version = "0.9.3" criteria = "safe-to-deploy" -[[unaudited.unicode-normalization]] +[[exemptions.unicode-normalization]] version = "0.1.19" criteria = "safe-to-deploy" -[[unaudited.unicode-xid]] +[[exemptions.unicode-xid]] version = "0.2.2" criteria = "safe-to-deploy" -[[unaudited.universal-hash]] +[[exemptions.universal-hash]] version = "0.4.1" criteria = "safe-to-deploy" -[[unaudited.untrusted]] +[[exemptions.untrusted]] version = "0.7.1" criteria = "safe-to-deploy" -[[unaudited.valuable]] +[[exemptions.valuable]] version = "0.1.0" criteria = "safe-to-deploy" -[[unaudited.version_check]] +[[exemptions.version_check]] version = "0.9.4" criteria = "safe-to-deploy" -[[unaudited.want]] +[[exemptions.want]] version = "0.3.0" criteria = "safe-to-deploy" -[[unaudited.wasi]] +[[exemptions.wasi]] version = "0.9.0+wasi-snapshot-preview1" criteria = "safe-to-deploy" -[[unaudited.wasi]] +[[exemptions.wasi]] version = "0.10.2+wasi-snapshot-preview1" criteria = "safe-to-deploy" -[[unaudited.wasi]] +[[exemptions.wasi]] version = "0.11.0+wasi-snapshot-preview1" criteria = "safe-to-deploy" -[[unaudited.wasm-bindgen]] +[[exemptions.wasm-bindgen]] version = "0.2.80" criteria = "safe-to-deploy" -[[unaudited.wasm-bindgen-backend]] +[[exemptions.wasm-bindgen-backend]] version = "0.2.80" criteria = "safe-to-deploy" -[[unaudited.wasm-bindgen-macro]] +[[exemptions.wasm-bindgen-macro]] version = "0.2.80" criteria = "safe-to-deploy" -[[unaudited.wasm-bindgen-macro-support]] +[[exemptions.wasm-bindgen-macro-support]] version = "0.2.80" criteria = "safe-to-deploy" -[[unaudited.wasm-bindgen-shared]] +[[exemptions.wasm-bindgen-shared]] version = "0.2.80" criteria = "safe-to-deploy" -[[unaudited.web-sys]] +[[exemptions.web-sys]] version = "0.3.57" criteria = "safe-to-deploy" -[[unaudited.which]] +[[exemptions.which]] version = "4.2.5" criteria = "safe-to-deploy" -[[unaudited.winapi]] +[[exemptions.winapi]] version = "0.3.9" criteria = "safe-to-deploy" -[[unaudited.winapi-i686-pc-windows-gnu]] +[[exemptions.winapi-i686-pc-windows-gnu]] version = "0.4.0" criteria = "safe-to-deploy" -[[unaudited.winapi-x86_64-pc-windows-gnu]] +[[exemptions.winapi-x86_64-pc-windows-gnu]] version = "0.4.0" criteria = "safe-to-deploy" -[[unaudited.wyz]] +[[exemptions.wyz]] version = "0.5.0" criteria = "safe-to-deploy" -[[unaudited.zeroize]] +[[exemptions.zeroize]] version = "1.4.3" criteria = "safe-to-deploy" -[[unaudited.zeroize_derive]] +[[exemptions.zeroize_derive]] version = "1.3.2" criteria = "safe-to-deploy"