util: Work around (virtual) memory exhaustion on 32-bit w/ glibc
[bitcoinplatinum.git] / src / test / txvalidationcache_tests.cpp
blobc5367208baaef50c803c446cc61cbaef1242a7c0
1 // Copyright (c) 2011-2016 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #include "consensus/validation.h"
6 #include "key.h"
7 #include "validation.h"
8 #include "miner.h"
9 #include "pubkey.h"
10 #include "txmempool.h"
11 #include "random.h"
12 #include "script/standard.h"
13 #include "test/test_bitcoin.h"
14 #include "utiltime.h"
16 #include <boost/test/unit_test.hpp>
18 BOOST_AUTO_TEST_SUITE(tx_validationcache_tests)
20 static bool
21 ToMemPool(CMutableTransaction& tx)
23 LOCK(cs_main);
25 CValidationState state;
26 return AcceptToMemoryPool(mempool, state, MakeTransactionRef(tx), false, NULL, NULL, true, 0);
29 BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
31 // Make sure skipping validation of transctions that were
32 // validated going into the memory pool does not allow
33 // double-spends in blocks to pass validation when they should not.
35 CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
37 // Create a double-spend of mature coinbase txn:
38 std::vector<CMutableTransaction> spends;
39 spends.resize(2);
40 for (int i = 0; i < 2; i++)
42 spends[i].nVersion = 1;
43 spends[i].vin.resize(1);
44 spends[i].vin[0].prevout.hash = coinbaseTxns[0].GetHash();
45 spends[i].vin[0].prevout.n = 0;
46 spends[i].vout.resize(1);
47 spends[i].vout[0].nValue = 11*CENT;
48 spends[i].vout[0].scriptPubKey = scriptPubKey;
50 // Sign:
51 std::vector<unsigned char> vchSig;
52 uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, SIGHASH_ALL, 0, SIGVERSION_BASE);
53 BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
54 vchSig.push_back((unsigned char)SIGHASH_ALL);
55 spends[i].vin[0].scriptSig << vchSig;
58 CBlock block;
60 // Test 1: block with both of those transactions should be rejected.
61 block = CreateAndProcessBlock(spends, scriptPubKey);
62 BOOST_CHECK(chainActive.Tip()->GetBlockHash() != block.GetHash());
64 // Test 2: ... and should be rejected if spend1 is in the memory pool
65 BOOST_CHECK(ToMemPool(spends[0]));
66 block = CreateAndProcessBlock(spends, scriptPubKey);
67 BOOST_CHECK(chainActive.Tip()->GetBlockHash() != block.GetHash());
68 mempool.clear();
70 // Test 3: ... and should be rejected if spend2 is in the memory pool
71 BOOST_CHECK(ToMemPool(spends[1]));
72 block = CreateAndProcessBlock(spends, scriptPubKey);
73 BOOST_CHECK(chainActive.Tip()->GetBlockHash() != block.GetHash());
74 mempool.clear();
76 // Final sanity test: first spend in mempool, second in block, that's OK:
77 std::vector<CMutableTransaction> oneSpend;
78 oneSpend.push_back(spends[0]);
79 BOOST_CHECK(ToMemPool(spends[1]));
80 block = CreateAndProcessBlock(oneSpend, scriptPubKey);
81 BOOST_CHECK(chainActive.Tip()->GetBlockHash() == block.GetHash());
82 // spends[1] should have been removed from the mempool when the
83 // block with spends[0] is accepted:
84 BOOST_CHECK_EQUAL(mempool.size(), 0);
87 BOOST_AUTO_TEST_SUITE_END()