Line data Source code
1 : // Copyright (c) 2014 The Bitcoin Core developers 2 : // Copyright (c) 2014-2015 The Dash developers 3 : // Copyright (c) 2015-2021 The PIVX Core developers 4 : // Distributed under the MIT/X11 software license, see the accompanying 5 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 6 : 7 : #include "test/test_pivx.h" 8 : 9 : #include "blocksignature.h" 10 : #include "net.h" 11 : #include "primitives/transaction.h" 12 : #include "script/sign.h" 13 : #include "validation.h" 14 : 15 : #include <boost/test/unit_test.hpp> 16 : 17 : BOOST_FIXTURE_TEST_SUITE(main_tests, TestingSetup) 18 : 19 : enum BlockSignatureType{ 20 : P2PK, 21 : P2PKH, 22 : P2CS 23 : }; 24 : 25 40 : CScript GetScriptForType(CPubKey pubKey, BlockSignatureType type) 26 : { 27 40 : switch(type){ 28 20 : case P2PK: 29 40 : return CScript() << pubKey << OP_CHECKSIG; 30 20 : default: 31 40 : return GetScriptForDestination(pubKey.GetID()); 32 : } 33 : } 34 : 35 40 : std::vector<unsigned char> CreateDummyScriptSigWithKey(CPubKey pubKey) 36 : { 37 40 : std::vector<unsigned char> vchSig; 38 40 : const CScript scriptCode; 39 40 : DummySignatureCreator(nullptr).CreateSig(vchSig, pubKey.GetID(), scriptCode, SIGVERSION_BASE); 40 40 : return vchSig; 41 : } 42 : 43 40 : CScript GetDummyScriptSigByType(CPubKey pubKey, bool isP2PK) 44 : { 45 80 : CScript script = CScript() << CreateDummyScriptSigWithKey(pubKey); 46 40 : if (!isP2PK) 47 40 : script << ToByteVector(pubKey); 48 40 : return script; 49 : } 50 : 51 40 : CBlock CreateDummyBlockWithSignature(CKey stakingKey, BlockSignatureType type, bool useInputP2PK) 52 : { 53 40 : CMutableTransaction txCoinStake; 54 : // Dummy input 55 120 : CTxIn input(uint256(), 0); 56 : // P2PKH input 57 40 : input.scriptSig = GetDummyScriptSigByType(stakingKey.GetPubKey(), useInputP2PK); 58 : // Add dummy input 59 40 : txCoinStake.vin.emplace_back(input); 60 : // Empty first output 61 40 : txCoinStake.vout.emplace_back(0, CScript()); 62 : // P2PK staking output 63 80 : CScript scriptPubKey = GetScriptForType(stakingKey.GetPubKey(), type); 64 40 : txCoinStake.vout.emplace_back(0, scriptPubKey); 65 : 66 : // Now the block. 67 40 : CBlock block; 68 80 : block.vtx.emplace_back(std::make_shared<const CTransaction>(CTransaction())); // dummy first tx 69 40 : block.vtx.emplace_back(std::make_shared<const CTransaction>(txCoinStake)); 70 40 : SignBlockWithKey(block, stakingKey); 71 : 72 80 : return block; 73 : } 74 : 75 40 : bool TestBlockSignature(const CBlock& block) 76 : { 77 40 : return CheckBlockSignature(block); 78 : } 79 : 80 2 : BOOST_AUTO_TEST_CASE(block_signature_test) 81 : { 82 21 : for (int i = 0; i < 20; ++i) { 83 40 : CKey stakingKey; 84 20 : stakingKey.MakeNewKey(true); 85 20 : bool useInputP2PK = i % 2 == 0; 86 : 87 : // Test P2PK block signature 88 40 : CBlock block = CreateDummyBlockWithSignature(stakingKey, BlockSignatureType::P2PK, useInputP2PK); 89 40 : BOOST_CHECK(TestBlockSignature(block)); 90 : 91 : // Test P2PKH block signature 92 20 : block = CreateDummyBlockWithSignature(stakingKey, BlockSignatureType::P2PKH, useInputP2PK); 93 20 : if (useInputP2PK) { 94 : // If it's using a P2PK scriptsig as input and a P2PKH output 95 : // The block doesn't contain the public key to verify the sig anywhere. 96 : // Must fail. 97 20 : BOOST_CHECK(!TestBlockSignature(block)); 98 : } else { 99 20 : BOOST_CHECK(TestBlockSignature(block)); 100 : } 101 : } 102 1 : } 103 : 104 : CAmount nMoneySupplyPoWEnd = 43199500 * COIN; 105 : 106 2 : BOOST_AUTO_TEST_CASE(subsidy_limit_test) 107 : { 108 1 : CAmount nSum = 0; 109 2 : for (int nHeight = 0; nHeight < 1; nHeight += 1) { 110 : /* premine in block 1 (60,001 PIV) */ 111 1 : CAmount nSubsidy = GetBlockValue(nHeight + 1); 112 2 : BOOST_CHECK(nSubsidy <= 60001 * COIN); 113 1 : nSum += nSubsidy; 114 : } 115 : 116 86400 : for (int nHeight = 1; nHeight < 86400; nHeight += 1) { 117 : /* PoW Phase One */ 118 86399 : CAmount nSubsidy = GetBlockValue(nHeight + 1); 119 172798 : BOOST_CHECK(nSubsidy <= 250 * COIN); 120 86399 : nSum += nSubsidy; 121 : } 122 : 123 64801 : for (int nHeight = 86400; nHeight < 151200; nHeight += 1) { 124 : /* PoW Phase Two */ 125 64800 : CAmount nSubsidy = GetBlockValue(nHeight + 1); 126 129600 : BOOST_CHECK(nSubsidy <= 225 * COIN); 127 64800 : nSum += nSubsidy; 128 : } 129 : 130 108001 : for (int nHeight = 151200; nHeight < 259200; nHeight += 1) { 131 : /* PoW Phase Two */ 132 108000 : CAmount nSubsidy = GetBlockValue(nHeight + 1); 133 216000 : BOOST_CHECK(nSubsidy <= 45 * COIN); 134 324000 : BOOST_CHECK(Params().GetConsensus().MoneyRange(nSubsidy)); 135 108000 : nSum += nSubsidy; 136 216000 : BOOST_CHECK(nSum > 0 && nSum <= nMoneySupplyPoWEnd); 137 : } 138 2 : BOOST_CHECK(nSum == 4109975100000000ULL); 139 1 : } 140 : 141 2 : bool ReturnFalse() { return false; } 142 1 : bool ReturnTrue() { return true; } 143 : 144 2 : BOOST_AUTO_TEST_CASE(test_combiner_all) 145 : { 146 1 : boost::signals2::signal<bool(), CombinerAll> Test; 147 2 : BOOST_CHECK(Test()); 148 2 : Test.connect(&ReturnFalse); 149 2 : BOOST_CHECK(!Test()); 150 2 : Test.connect(&ReturnTrue); 151 2 : BOOST_CHECK(!Test()); 152 1 : Test.disconnect(&ReturnFalse); 153 2 : BOOST_CHECK(Test()); 154 1 : Test.disconnect(&ReturnTrue); 155 2 : BOOST_CHECK(Test()); 156 1 : } 157 : 158 : BOOST_AUTO_TEST_SUITE_END()