diff options
author | Gavin Andresen <gavinandresen@gmail.com> | 2012-02-29 10:14:18 -0500 |
---|---|---|
committer | Gavin Andresen <gavinandresen@gmail.com> | 2012-02-29 11:46:46 -0500 |
commit | 142e604184e3ab6dcbe02cebcbe08e5623182b81 (patch) | |
tree | 0906a390af4ec3314983a62e9fa2ae66dd348ab0 /src/test/DoS_tests.cpp | |
parent | 722d9387be4b267b689d7b7d78daeb7157bd12d8 (diff) |
DoS fix for mapOrphanTransactionsv0.6.0rc2
Diffstat (limited to 'src/test/DoS_tests.cpp')
-rw-r--r-- | src/test/DoS_tests.cpp | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index f29f036eb3..0b89414048 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -12,6 +12,12 @@ #include <stdint.h> +// Tests this internal-to-main.cpp method: +extern void AddOrphanTx(const CDataStream& vMsg); +extern int LimitOrphanTxSize(int nMaxOrphans); +extern std::map<uint256, CDataStream*> mapOrphanTransactions; +extern std::multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev; + CService ip(uint32_t i) { struct in_addr s; @@ -123,4 +129,77 @@ BOOST_AUTO_TEST_CASE(DoS_checknbits) } +static uint256 RandomHash() +{ + std::vector<unsigned char> randbytes(32); + RAND_bytes(&randbytes[0], 32); + uint256 randomhash(randbytes); + return randomhash; +} + +CTransaction RandomOrphan() +{ + std::map<uint256, CDataStream*>::iterator it; + it = mapOrphanTransactions.lower_bound(RandomHash()); + if (it == mapOrphanTransactions.end()) + it = mapOrphanTransactions.begin(); + const CDataStream* pvMsg = it->second; + CTransaction tx; + CDataStream(*pvMsg) >> tx; + return tx; +} + +BOOST_AUTO_TEST_CASE(DoS_mapOrphans) +{ + CKey key; + key.MakeNewKey(true); + CBasicKeyStore keystore; + keystore.AddKey(key); + + // 50 orphan transactions: + for (int i = 0; i < 50; i++) + { + CTransaction tx; + tx.vin.resize(1); + tx.vin[0].prevout.n = 0; + tx.vin[0].prevout.hash = RandomHash(); + tx.vin[0].scriptSig << OP_1; + tx.vout.resize(1); + tx.vout[0].nValue = 1*CENT; + tx.vout[0].scriptPubKey.SetBitcoinAddress(key.GetPubKey()); + + CDataStream ds; + ds << tx; + AddOrphanTx(ds); + } + + // ... and 50 that depend on other orphans: + for (int i = 0; i < 50; i++) + { + CTransaction txPrev = RandomOrphan(); + + CTransaction 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.SetBitcoinAddress(key.GetPubKey()); + SignSignature(keystore, txPrev, tx, 0); + + CDataStream ds; + ds << tx; + AddOrphanTx(ds); + } + + // Test LimitOrphanTxSize() function: + LimitOrphanTxSize(40); + BOOST_CHECK(mapOrphanTransactions.size() <= 40); + LimitOrphanTxSize(10); + BOOST_CHECK(mapOrphanTransactions.size() <= 10); + LimitOrphanTxSize(0); + BOOST_CHECK(mapOrphanTransactions.empty()); + BOOST_CHECK(mapOrphanTransactionsByPrev.empty()); +} + BOOST_AUTO_TEST_SUITE_END() |