forked from bitcoin/bitcoin
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[tests] Move TxOrphange tests to orphange_tests.cpp
- Loading branch information
Showing
3 changed files
with
138 additions
and
118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |