diff options
author | John Newbery <john@johnnewbery.com> | 2022-02-07 10:18:00 +0000 |
---|---|---|
committer | John Newbery <john@johnnewbery.com> | 2022-04-25 08:37:01 +0100 |
commit | b8f17fbcb4a98187b16dd4737f4751e0eee94c49 (patch) | |
tree | 311c42c6db338364531ceecda7811384e203ecbd /src/test/orphanage_tests.cpp | |
parent | b1c5991eebb916755be188f355ad36fe01a3f529 (diff) | |
download | bitcoin-b8f17fbcb4a98187b16dd4737f4751e0eee94c49.tar.xz |
[tests] Move TxOrphange tests to orphange_tests.cpp
Diffstat (limited to 'src/test/orphanage_tests.cpp')
-rw-r--r-- | src/test/orphanage_tests.cpp | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/test/orphanage_tests.cpp b/src/test/orphanage_tests.cpp new file mode 100644 index 0000000000..842daa8bd4 --- /dev/null +++ b/src/test/orphanage_tests.cpp @@ -0,0 +1,137 @@ +// Copyright (c) 2011-2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <arith_uint256.h> +#include <pubkey.h> +#include <script/sign.h> +#include <script/signingprovider.h> +#include <script/standard.h> +#include <test/util/setup_common.h> +#include <txorphanage.h> + +#include <array> +#include <cstdint> + +#include <boost/test/unit_test.hpp> + +BOOST_FIXTURE_TEST_SUITE(orphanage_tests, TestingSetup) + +class TxOrphanageTest : public TxOrphanage +{ +public: + inline size_t CountOrphans() const EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans) + { + return m_orphans.size(); + } + + CTransactionRef RandomOrphan() EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans) + { + std::map<uint256, OrphanTx>::iterator it; + it = m_orphans.lower_bound(InsecureRand256()); + if (it == m_orphans.end()) + it = m_orphans.begin(); + return it->second.tx; + } +}; + +static void MakeNewKeyWithFastRandomContext(CKey& key) +{ + std::vector<unsigned char> keydata; + keydata = g_insecure_rand_ctx.randbytes(32); + key.Set(keydata.data(), keydata.data() + keydata.size(), /*fCompressedIn=*/true); + assert(key.IsValid()); +} + +BOOST_AUTO_TEST_CASE(DoS_mapOrphans) +{ + // This test had non-deterministic coverage due to + // randomly selected seeds. + // This seed is chosen so that all branches of the function + // ecdsa_signature_parse_der_lax are executed during this test. + // Specifically branches that run only when an ECDSA + // signature's R and S values have leading zeros. + g_insecure_rand_ctx = FastRandomContext{uint256{33}}; + + TxOrphanageTest orphanage; + CKey key; + MakeNewKeyWithFastRandomContext(key); + FillableSigningProvider keystore; + BOOST_CHECK(keystore.AddKey(key)); + + LOCK(g_cs_orphans); + + // 50 orphan transactions: + for (int i = 0; i < 50; i++) + { + CMutableTransaction tx; + tx.vin.resize(1); + tx.vin[0].prevout.n = 0; + tx.vin[0].prevout.hash = InsecureRand256(); + tx.vin[0].scriptSig << OP_1; + tx.vout.resize(1); + tx.vout[0].nValue = 1*CENT; + tx.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey())); + + orphanage.AddTx(MakeTransactionRef(tx), i); + } + + // ... and 50 that depend on other orphans: + for (int i = 0; i < 50; i++) + { + CTransactionRef txPrev = orphanage.RandomOrphan(); + + CMutableTransaction tx; + tx.vin.resize(1); + tx.vin[0].prevout.n = 0; + tx.vin[0].prevout.hash = txPrev->GetHash(); + tx.vout.resize(1); + tx.vout[0].nValue = 1*CENT; + tx.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey())); + BOOST_CHECK(SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL)); + + orphanage.AddTx(MakeTransactionRef(tx), i); + } + + // This really-big orphan should be ignored: + for (int i = 0; i < 10; i++) + { + CTransactionRef txPrev = orphanage.RandomOrphan(); + + CMutableTransaction tx; + tx.vout.resize(1); + tx.vout[0].nValue = 1*CENT; + tx.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey())); + tx.vin.resize(2777); + for (unsigned int j = 0; j < tx.vin.size(); j++) + { + tx.vin[j].prevout.n = j; + tx.vin[j].prevout.hash = txPrev->GetHash(); + } + BOOST_CHECK(SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL)); + // Re-use same signature for other inputs + // (they don't have to be valid for this test) + for (unsigned int j = 1; j < tx.vin.size(); j++) + tx.vin[j].scriptSig = tx.vin[0].scriptSig; + + BOOST_CHECK(!orphanage.AddTx(MakeTransactionRef(tx), i)); + } + + // Test EraseOrphansFor: + for (NodeId i = 0; i < 3; i++) + { + size_t sizeBefore = orphanage.CountOrphans(); + orphanage.EraseForPeer(i); + BOOST_CHECK(orphanage.CountOrphans() < sizeBefore); + } + + // Test LimitOrphanTxSize() function: + orphanage.LimitOrphans(40); + BOOST_CHECK(orphanage.CountOrphans() <= 40); + orphanage.LimitOrphans(10); + BOOST_CHECK(orphanage.CountOrphans() <= 10); + orphanage.LimitOrphans(0); + BOOST_CHECK(orphanage.CountOrphans() == 0); +} + +BOOST_AUTO_TEST_SUITE_END() |