LCOV - code coverage report
Current view: top level - src/test - miner_tests.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 162 162 100.0 %
Date: 2015-10-12 22:39:14 Functions: 4 6 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2011-2014 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.
       4             : 
       5             : #include "chainparams.h"
       6             : #include "coins.h"
       7             : #include "consensus/validation.h"
       8             : #include "main.h"
       9             : #include "miner.h"
      10             : #include "pubkey.h"
      11             : #include "script/standard.h"
      12             : #include "txmempool.h"
      13             : #include "uint256.h"
      14             : #include "util.h"
      15             : #include "utilstrencodings.h"
      16             : 
      17             : #include "test/test_bitcoin.h"
      18             : 
      19             : #include <boost/test/unit_test.hpp>
      20             : 
      21           1 : BOOST_FIXTURE_TEST_SUITE(miner_tests, TestingSetup)
      22             : 
      23             : static
      24             : struct {
      25             :     unsigned char extranonce;
      26             :     unsigned int nonce;
      27             : } blockinfo[] = {
      28             :     {4, 0xa4a3e223}, {2, 0x15c32f9e}, {1, 0x0375b547}, {1, 0x7004a8a5},
      29             :     {2, 0xce440296}, {2, 0x52cfe198}, {1, 0x77a72cd0}, {2, 0xbb5d6f84},
      30             :     {2, 0x83f30c2c}, {1, 0x48a73d5b}, {1, 0xef7dcd01}, {2, 0x6809c6c4},
      31             :     {2, 0x0883ab3c}, {1, 0x087bbbe2}, {2, 0x2104a814}, {2, 0xdffb6daa},
      32             :     {1, 0xee8a0a08}, {2, 0xba4237c1}, {1, 0xa70349dc}, {1, 0x344722bb},
      33             :     {3, 0xd6294733}, {2, 0xec9f5c94}, {2, 0xca2fbc28}, {1, 0x6ba4f406},
      34             :     {2, 0x015d4532}, {1, 0x6e119b7c}, {2, 0x43e8f314}, {2, 0x27962f38},
      35             :     {2, 0xb571b51b}, {2, 0xb36bee23}, {2, 0xd17924a8}, {2, 0x6bc212d9},
      36             :     {1, 0x630d4948}, {2, 0x9a4c4ebb}, {2, 0x554be537}, {1, 0xd63ddfc7},
      37             :     {2, 0xa10acc11}, {1, 0x759a8363}, {2, 0xfb73090d}, {1, 0xe82c6a34},
      38             :     {1, 0xe33e92d7}, {3, 0x658ef5cb}, {2, 0xba32ff22}, {5, 0x0227a10c},
      39             :     {1, 0xa9a70155}, {5, 0xd096d809}, {1, 0x37176174}, {1, 0x830b8d0f},
      40             :     {1, 0xc6e3910e}, {2, 0x823f3ca8}, {1, 0x99850849}, {1, 0x7521fb81},
      41             :     {1, 0xaacaabab}, {1, 0xd645a2eb}, {5, 0x7aea1781}, {5, 0x9d6e4b78},
      42             :     {1, 0x4ce90fd8}, {1, 0xabdc832d}, {6, 0x4a34f32a}, {2, 0xf2524c1c},
      43             :     {2, 0x1bbeb08a}, {1, 0xad47f480}, {1, 0x9f026aeb}, {1, 0x15a95049},
      44             :     {2, 0xd1cb95b2}, {2, 0xf84bbda5}, {1, 0x0fa62cd1}, {1, 0xe05f9169},
      45             :     {1, 0x78d194a9}, {5, 0x3e38147b}, {5, 0x737ba0d4}, {1, 0x63378e10},
      46             :     {1, 0x6d5f91cf}, {2, 0x88612eb8}, {2, 0xe9639484}, {1, 0xb7fabc9d},
      47             :     {2, 0x19b01592}, {1, 0x5a90dd31}, {2, 0x5bd7e028}, {2, 0x94d00323},
      48             :     {1, 0xa9b9c01a}, {1, 0x3a40de61}, {1, 0x56e7eec7}, {5, 0x859f7ef6},
      49             :     {1, 0xfd8e5630}, {1, 0x2b0c9f7f}, {1, 0xba700e26}, {1, 0x7170a408},
      50             :     {1, 0x70de86a8}, {1, 0x74d64cd5}, {1, 0x49e738a1}, {2, 0x6910b602},
      51             :     {0, 0x643c565f}, {1, 0x54264b3f}, {2, 0x97ea6396}, {2, 0x55174459},
      52             :     {2, 0x03e8779a}, {1, 0x98f34d8f}, {1, 0xc07b2b07}, {1, 0xdfe29668},
      53             :     {1, 0x3141c7c1}, {1, 0xb3b595f4}, {1, 0x735abf08}, {5, 0x623bfbce},
      54             :     {2, 0xd351e722}, {1, 0xf4ca48c9}, {1, 0x5b19c670}, {1, 0xa164bf0e},
      55             :     {2, 0xbbbeb305}, {2, 0xfe1c810a},
      56             : };
      57             : 
      58             : // NOTE: These tests rely on CreateNewBlock doing its own self-validation!
      59           6 : BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
      60             : {
      61           4 :     CScript scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
      62             :     CBlockTemplate *pblocktemplate;
      63           1 :     CMutableTransaction tx,tx2;
      64             :     CScript script;
      65             :     uint256 hash;
      66             : 
      67           1 :     LOCK(cs_main);
      68           1 :     fCheckpointsEnabled = false;
      69             : 
      70             :     // Simple block creation, nothing special yet:
      71           8 :     BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
      72             : 
      73             :     // We can't make transactions until we have inputs
      74             :     // Therefore, load 100 blocks :)
      75             :     std::vector<CTransaction*>txFirst;
      76         111 :     for (unsigned int i = 0; i < sizeof(blockinfo)/sizeof(*blockinfo); ++i)
      77             :     {
      78         110 :         CBlock *pblock = &pblocktemplate->block; // pointer for convenience
      79         110 :         pblock->nVersion = 1;
      80         110 :         pblock->nTime = chainActive.Tip()->GetMedianTimePast()+1;
      81         110 :         CMutableTransaction txCoinbase(pblock->vtx[0]);
      82         110 :         txCoinbase.nVersion = 1;
      83         220 :         txCoinbase.vin[0].scriptSig = CScript();
      84         110 :         txCoinbase.vin[0].scriptSig.push_back(blockinfo[i].extranonce);
      85         110 :         txCoinbase.vin[0].scriptSig.push_back(chainActive.Height());
      86         220 :         txCoinbase.vout[0].scriptPubKey = CScript();
      87         220 :         pblock->vtx[0] = CTransaction(txCoinbase);
      88         220 :         if (txFirst.size() < 2)
      89           2 :             txFirst.push_back(new CTransaction(pblock->vtx[0]));
      90         110 :         pblock->hashMerkleRoot = pblock->ComputeMerkleRoot();
      91         110 :         pblock->nNonce = blockinfo[i].nonce;
      92         110 :         CValidationState state;
      93         880 :         BOOST_CHECK(ProcessNewBlock(state, NULL, pblock, true, NULL));
      94         990 :         BOOST_CHECK(state.IsValid());
      95         110 :         pblock->hashPrevBlock = pblock->GetHash();
      96             :     }
      97           1 :     delete pblocktemplate;
      98             : 
      99             :     // Just to make sure we can still make simple blocks
     100           8 :     BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
     101           1 :     delete pblocktemplate;
     102             : 
     103             :     // block sigops > limit: 1000 CHECKMULTISIG + 1
     104           2 :     tx.vin.resize(1);
     105             :     // NOTE: OP_NOP is used to force 20 SigOps for the CHECKMULTISIG
     106           2 :     tx.vin[0].scriptSig = CScript() << OP_0 << OP_0 << OP_0 << OP_NOP << OP_CHECKMULTISIG << OP_1;
     107           1 :     tx.vin[0].prevout.hash = txFirst[0]->GetHash();
     108           1 :     tx.vin[0].prevout.n = 0;
     109           2 :     tx.vout.resize(1);
     110           1 :     tx.vout[0].nValue = 5000000000LL;
     111        1002 :     for (unsigned int i = 0; i < 1001; ++i)
     112             :     {
     113        1001 :         tx.vout[0].nValue -= 1000000;
     114        1001 :         hash = tx.GetHash();
     115        3003 :         mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
     116        1001 :         tx.vin[0].prevout.hash = hash;
     117             :     }
     118           8 :     BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
     119           1 :     delete pblocktemplate;
     120           1 :     mempool.clear();
     121             : 
     122             :     // block size > limit
     123           2 :     tx.vin[0].scriptSig = CScript();
     124             :     // 18 * (520char + DROP) + OP_1 = 9433 bytes
     125           2 :     std::vector<unsigned char> vchData(520);
     126          19 :     for (unsigned int i = 0; i < 18; ++i)
     127          18 :         tx.vin[0].scriptSig << vchData << OP_DROP;
     128           1 :     tx.vin[0].scriptSig << OP_1;
     129           1 :     tx.vin[0].prevout.hash = txFirst[0]->GetHash();
     130           1 :     tx.vout[0].nValue = 5000000000LL;
     131         129 :     for (unsigned int i = 0; i < 128; ++i)
     132             :     {
     133         128 :         tx.vout[0].nValue -= 10000000;
     134         128 :         hash = tx.GetHash();
     135         384 :         mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
     136         128 :         tx.vin[0].prevout.hash = hash;
     137             :     }
     138           8 :     BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
     139           1 :     delete pblocktemplate;
     140           1 :     mempool.clear();
     141             : 
     142             :     // orphan in mempool
     143           1 :     hash = tx.GetHash();
     144           3 :     mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
     145           8 :     BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
     146           1 :     delete pblocktemplate;
     147           1 :     mempool.clear();
     148             : 
     149             :     // child with higher priority than parent
     150           2 :     tx.vin[0].scriptSig = CScript() << OP_1;
     151           1 :     tx.vin[0].prevout.hash = txFirst[1]->GetHash();
     152           1 :     tx.vout[0].nValue = 4900000000LL;
     153           1 :     hash = tx.GetHash();
     154           3 :     mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
     155           1 :     tx.vin[0].prevout.hash = hash;
     156           2 :     tx.vin.resize(2);
     157           2 :     tx.vin[1].scriptSig = CScript() << OP_1;
     158           1 :     tx.vin[1].prevout.hash = txFirst[0]->GetHash();
     159           1 :     tx.vin[1].prevout.n = 0;
     160           1 :     tx.vout[0].nValue = 5900000000LL;
     161           1 :     hash = tx.GetHash();
     162           3 :     mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
     163           8 :     BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
     164           1 :     delete pblocktemplate;
     165           1 :     mempool.clear();
     166             : 
     167             :     // coinbase in mempool
     168           2 :     tx.vin.resize(1);
     169           1 :     tx.vin[0].prevout.SetNull();
     170           2 :     tx.vin[0].scriptSig = CScript() << OP_0 << OP_1;
     171           1 :     tx.vout[0].nValue = 0;
     172           1 :     hash = tx.GetHash();
     173           3 :     mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
     174           8 :     BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
     175           1 :     delete pblocktemplate;
     176           1 :     mempool.clear();
     177             : 
     178             :     // invalid (pre-p2sh) txn in mempool
     179           1 :     tx.vin[0].prevout.hash = txFirst[0]->GetHash();
     180           1 :     tx.vin[0].prevout.n = 0;
     181           2 :     tx.vin[0].scriptSig = CScript() << OP_1;
     182           1 :     tx.vout[0].nValue = 4900000000LL;
     183           2 :     script = CScript() << OP_0;
     184           4 :     tx.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(script));
     185           1 :     hash = tx.GetHash();
     186           3 :     mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
     187           1 :     tx.vin[0].prevout.hash = hash;
     188           4 :     tx.vin[0].scriptSig = CScript() << (std::vector<unsigned char>)script;
     189           1 :     tx.vout[0].nValue -= 1000000;
     190           1 :     hash = tx.GetHash();
     191           3 :     mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
     192           8 :     BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
     193           1 :     delete pblocktemplate;
     194           1 :     mempool.clear();
     195             : 
     196             :     // double spend txn pair in mempool
     197           1 :     tx.vin[0].prevout.hash = txFirst[0]->GetHash();
     198           2 :     tx.vin[0].scriptSig = CScript() << OP_1;
     199           1 :     tx.vout[0].nValue = 4900000000LL;
     200           2 :     tx.vout[0].scriptPubKey = CScript() << OP_1;
     201           1 :     hash = tx.GetHash();
     202           3 :     mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
     203           2 :     tx.vout[0].scriptPubKey = CScript() << OP_2;
     204           1 :     hash = tx.GetHash();
     205           3 :     mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
     206           8 :     BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
     207           1 :     delete pblocktemplate;
     208           1 :     mempool.clear();
     209             : 
     210             :     // subsidy changing
     211           1 :     int nHeight = chainActive.Height();
     212           1 :     chainActive.Tip()->nHeight = 209999;
     213           8 :     BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
     214           1 :     delete pblocktemplate;
     215           1 :     chainActive.Tip()->nHeight = 210000;
     216           8 :     BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
     217           1 :     delete pblocktemplate;
     218           1 :     chainActive.Tip()->nHeight = nHeight;
     219             : 
     220             :     // non-final txs in mempool
     221           1 :     SetMockTime(chainActive.Tip()->GetMedianTimePast()+1);
     222             : 
     223             :     // height locked
     224           1 :     tx.vin[0].prevout.hash = txFirst[0]->GetHash();
     225           2 :     tx.vin[0].scriptSig = CScript() << OP_1;
     226           1 :     tx.vin[0].nSequence = 0;
     227           1 :     tx.vout[0].nValue = 4900000000LL;
     228           2 :     tx.vout[0].scriptPubKey = CScript() << OP_1;
     229           1 :     tx.nLockTime = chainActive.Tip()->nHeight+1;
     230           1 :     hash = tx.GetHash();
     231           3 :     mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
     232           9 :     BOOST_CHECK(!CheckFinalTx(tx));
     233             : 
     234             :     // time locked
     235           2 :     tx2.vin.resize(1);
     236           1 :     tx2.vin[0].prevout.hash = txFirst[1]->GetHash();
     237           1 :     tx2.vin[0].prevout.n = 0;
     238           2 :     tx2.vin[0].scriptSig = CScript() << OP_1;
     239           1 :     tx2.vin[0].nSequence = 0;
     240           2 :     tx2.vout.resize(1);
     241           1 :     tx2.vout[0].nValue = 4900000000LL;
     242           2 :     tx2.vout[0].scriptPubKey = CScript() << OP_1;
     243           1 :     tx2.nLockTime = chainActive.Tip()->GetMedianTimePast()+1;
     244           1 :     hash = tx2.GetHash();
     245           3 :     mempool.addUnchecked(hash, CTxMemPoolEntry(tx2, 11, GetTime(), 111.0, 11));
     246           9 :     BOOST_CHECK(!CheckFinalTx(tx2));
     247             : 
     248           8 :     BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
     249             : 
     250             :     // Neither tx should have make it into the template.
     251           6 :     BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1);
     252           1 :     delete pblocktemplate;
     253             : 
     254             :     // However if we advance height and time by one, both will.
     255           1 :     chainActive.Tip()->nHeight++;
     256           1 :     SetMockTime(chainActive.Tip()->GetMedianTimePast()+2);
     257             : 
     258             :     // FIXME: we should *actually* create a new block so the following test
     259             :     //        works; CheckFinalTx() isn't fooled by monkey-patching nHeight.
     260             :     //BOOST_CHECK(CheckFinalTx(tx));
     261             :     //BOOST_CHECK(CheckFinalTx(tx2));
     262             : 
     263           8 :     BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
     264           6 :     BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3);
     265           1 :     delete pblocktemplate;
     266             : 
     267           1 :     chainActive.Tip()->nHeight--;
     268           1 :     SetMockTime(0);
     269           1 :     mempool.clear();
     270             : 
     271          18 :     BOOST_FOREACH(CTransaction *tx, txFirst)
     272           4 :         delete tx;
     273             : 
     274           1 :     fCheckpointsEnabled = true;
     275           1 : }
     276             : 
     277           3 : BOOST_AUTO_TEST_SUITE_END()

Generated by: LCOV version 1.11