diff options
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/fuzz/bech32.cpp | 5 | ||||
-rw-r--r-- | src/test/fuzz/kitchen_sink.cpp | 2 | ||||
-rw-r--r-- | src/test/key_tests.cpp | 41 | ||||
-rw-r--r-- | src/test/miniscript_tests.cpp | 6 | ||||
-rw-r--r-- | src/test/orphanage_tests.cpp | 48 | ||||
-rw-r--r-- | src/test/streams_tests.cpp | 3 |
6 files changed, 93 insertions, 12 deletions
diff --git a/src/test/fuzz/bech32.cpp b/src/test/fuzz/bech32.cpp index ffc5ba518f..daa6e24404 100644 --- a/src/test/fuzz/bech32.cpp +++ b/src/test/fuzz/bech32.cpp @@ -29,8 +29,9 @@ FUZZ_TARGET(bech32) std::vector<unsigned char> input; ConvertBits<8, 5, true>([&](unsigned char c) { input.push_back(c); }, buffer.begin(), buffer.end()); - if (input.size() + 3 + 6 <= 90) { - // If it's possible to encode input in Bech32(m) without exceeding the 90-character limit: + // Input data part + 3 characters for the HRP and separator (bc1) + the checksum characters + if (input.size() + 3 + bech32::CHECKSUM_SIZE <= bech32::CharLimit::BECH32) { + // If it's possible to encode input in Bech32(m) without exceeding the bech32-character limit: for (auto encoding : {bech32::Encoding::BECH32, bech32::Encoding::BECH32M}) { const std::string encoded = bech32::Encode(encoding, "bc", input); assert(!encoded.empty()); diff --git a/src/test/fuzz/kitchen_sink.cpp b/src/test/fuzz/kitchen_sink.cpp index 4468f358d9..62b49106cd 100644 --- a/src/test/fuzz/kitchen_sink.cpp +++ b/src/test/fuzz/kitchen_sink.cpp @@ -23,7 +23,7 @@ using node::TransactionError; namespace { constexpr TransactionError ALL_TRANSACTION_ERROR[] = { TransactionError::MISSING_INPUTS, - TransactionError::ALREADY_IN_CHAIN, + TransactionError::ALREADY_IN_UTXO_SET, TransactionError::MEMPOOL_REJECTED, TransactionError::MEMPOOL_ERROR, TransactionError::MAX_FEE_EXCEEDED, diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index b897a0a153..112d6db193 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -8,6 +8,7 @@ #include <key_io.h> #include <span.h> #include <streams.h> +#include <secp256k1_extrakeys.h> #include <test/util/random.h> #include <test/util/setup_common.h> #include <uint256.h> @@ -299,6 +300,13 @@ BOOST_AUTO_TEST_CASE(bip340_test_vectors) // Verify those signatures for good measure. BOOST_CHECK(pubkey.VerifySchnorr(msg256, sig64)); + // Repeat the same check, but use the KeyPair directly without any merkle tweak + KeyPair keypair = key.ComputeKeyPair(/*merkle_root=*/nullptr); + bool kp_ok = keypair.SignSchnorr(msg256, sig64, aux256); + BOOST_CHECK(kp_ok); + BOOST_CHECK(pubkey.VerifySchnorr(msg256, sig64)); + BOOST_CHECK(std::vector<unsigned char>(sig64, sig64 + 64) == sig); + // Do 10 iterations where we sign with a random Merkle root to tweak, // and compare against the resulting tweaked keys, with random aux. // In iteration i=0 we tweak with empty Merkle tree. @@ -312,6 +320,12 @@ BOOST_AUTO_TEST_CASE(bip340_test_vectors) bool ok = key.SignSchnorr(msg256, sig64, &merkle_root, aux256); BOOST_CHECK(ok); BOOST_CHECK(tweaked_key.VerifySchnorr(msg256, sig64)); + + // Repeat the same check, but use the KeyPair class directly + KeyPair keypair = key.ComputeKeyPair(&merkle_root); + bool kp_ok = keypair.SignSchnorr(msg256, sig64, aux256); + BOOST_CHECK(kp_ok); + BOOST_CHECK(tweaked_key.VerifySchnorr(msg256, sig64)); } } } @@ -345,4 +359,31 @@ BOOST_AUTO_TEST_CASE(bip341_test_h) BOOST_CHECK(XOnlyPubKey::NUMS_H == H); } +BOOST_AUTO_TEST_CASE(key_schnorr_tweak_smoke_test) +{ + // Sanity check to ensure we get the same tweak using CPubKey vs secp256k1 functions + secp256k1_context* secp256k1_context_sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); + + CKey key; + key.MakeNewKey(true); + uint256 merkle_root = InsecureRand256(); + + // secp256k1 functions + secp256k1_keypair keypair; + BOOST_CHECK(secp256k1_keypair_create(secp256k1_context_sign, &keypair, UCharCast(key.begin()))); + secp256k1_xonly_pubkey xonly_pubkey; + BOOST_CHECK(secp256k1_keypair_xonly_pub(secp256k1_context_sign, &xonly_pubkey, nullptr, &keypair)); + unsigned char xonly_bytes[32]; + BOOST_CHECK(secp256k1_xonly_pubkey_serialize(secp256k1_context_sign, xonly_bytes, &xonly_pubkey)); + uint256 tweak_old = XOnlyPubKey(xonly_bytes).ComputeTapTweakHash(&merkle_root); + + // CPubKey + CPubKey pubkey = key.GetPubKey(); + uint256 tweak_new = XOnlyPubKey(pubkey).ComputeTapTweakHash(&merkle_root); + + BOOST_CHECK_EQUAL(tweak_old, tweak_new); + + secp256k1_context_destroy(secp256k1_context_sign); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/miniscript_tests.cpp b/src/test/miniscript_tests.cpp index 2b6b8b807b..815c278b8c 100644 --- a/src/test/miniscript_tests.cpp +++ b/src/test/miniscript_tests.cpp @@ -699,6 +699,12 @@ BOOST_AUTO_TEST_CASE(fixed_tests) const auto insane_sub = ms_ins->FindInsaneSub(); BOOST_CHECK(insane_sub && *insane_sub->ToString(wsh_converter) == "and_b(after(1),a:after(1000000000))"); + // Numbers can't be prefixed by a sign. + BOOST_CHECK(!miniscript::FromString("after(-1)", wsh_converter)); + BOOST_CHECK(!miniscript::FromString("after(+1)", wsh_converter)); + BOOST_CHECK(!miniscript::FromString("thresh(-1,pk(03cdabb7f2dce7bfbd8a0b9570c6fd1e712e5d64045e9d6b517b3d5072251dc204))", wsh_converter)); + BOOST_CHECK(!miniscript::FromString("multi(+1,03cdabb7f2dce7bfbd8a0b9570c6fd1e712e5d64045e9d6b517b3d5072251dc204)", wsh_converter)); + // Timelock tests Test("after(100)", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL); // only heightlock Test("after(1000000000)", "?", "?", TESTMODE_VALID | TESTMODE_NONMAL); // only timelock diff --git a/src/test/orphanage_tests.cpp b/src/test/orphanage_tests.cpp index 082d090d7c..d2dab94526 100644 --- a/src/test/orphanage_tests.cpp +++ b/src/test/orphanage_tests.cpp @@ -112,6 +112,10 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) FillableSigningProvider keystore; BOOST_CHECK(keystore.AddKey(key)); + // Freeze time for length of test + auto now{GetTime<std::chrono::seconds>()}; + SetMockTime(now); + // 50 orphan transactions: for (int i = 0; i < 50; i++) { @@ -170,22 +174,52 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) BOOST_CHECK(!orphanage.AddTx(MakeTransactionRef(tx), i)); } - // Test EraseOrphansFor: + size_t expected_num_orphans = orphanage.CountOrphans(); + + // Non-existent peer; nothing should be deleted + orphanage.EraseForPeer(/*peer=*/-1); + BOOST_CHECK_EQUAL(orphanage.CountOrphans(), expected_num_orphans); + + // Each of first three peers stored + // two transactions each. for (NodeId i = 0; i < 3; i++) { - size_t sizeBefore = orphanage.CountOrphans(); orphanage.EraseForPeer(i); - BOOST_CHECK(orphanage.CountOrphans() < sizeBefore); + expected_num_orphans -= 2; + BOOST_CHECK(orphanage.CountOrphans() == expected_num_orphans); } - // Test LimitOrphanTxSize() function: + // Test LimitOrphanTxSize() function, nothing should timeout: FastRandomContext rng{/*fDeterministic=*/true}; + orphanage.LimitOrphans(/*max_orphans=*/expected_num_orphans, rng); + BOOST_CHECK_EQUAL(orphanage.CountOrphans(), expected_num_orphans); + expected_num_orphans -= 1; + orphanage.LimitOrphans(/*max_orphans=*/expected_num_orphans, rng); + BOOST_CHECK_EQUAL(orphanage.CountOrphans(), expected_num_orphans); + assert(expected_num_orphans > 40); orphanage.LimitOrphans(40, rng); - BOOST_CHECK(orphanage.CountOrphans() <= 40); + BOOST_CHECK_EQUAL(orphanage.CountOrphans(), 40); orphanage.LimitOrphans(10, rng); - BOOST_CHECK(orphanage.CountOrphans() <= 10); + BOOST_CHECK_EQUAL(orphanage.CountOrphans(), 10); orphanage.LimitOrphans(0, rng); - BOOST_CHECK(orphanage.CountOrphans() == 0); + BOOST_CHECK_EQUAL(orphanage.CountOrphans(), 0); + + // Add one more orphan, check timeout logic + auto timeout_tx = MakeTransactionSpending(/*outpoints=*/{}, rng); + orphanage.AddTx(timeout_tx, 0); + orphanage.LimitOrphans(1, rng); + BOOST_CHECK_EQUAL(orphanage.CountOrphans(), 1); + + // One second shy of expiration + SetMockTime(now + ORPHAN_TX_EXPIRE_TIME - 1s); + orphanage.LimitOrphans(1, rng); + BOOST_CHECK_EQUAL(orphanage.CountOrphans(), 1); + + // Jump one more second, orphan should be timed out on limiting + SetMockTime(now + ORPHAN_TX_EXPIRE_TIME); + BOOST_CHECK_EQUAL(orphanage.CountOrphans(), 1); + orphanage.LimitOrphans(1, rng); + BOOST_CHECK_EQUAL(orphanage.CountOrphans(), 0); } BOOST_AUTO_TEST_CASE(same_txid_diff_witness) diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp index eed932b6d2..9296cbb41c 100644 --- a/src/test/streams_tests.cpp +++ b/src/test/streams_tests.cpp @@ -30,8 +30,7 @@ BOOST_AUTO_TEST_CASE(xor_file) } { #ifdef __MINGW64__ - // Our usage of mingw-w64 and the msvcrt runtime does not support - // the x modifier for the _wfopen(). + // Temporary workaround for https://github.com/bitcoin/bitcoin/issues/30210 const char* mode = "wb"; #else const char* mode = "wbx"; |