mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-26 09:12:05 +01:00
Use a fixed script instead of a CReserveKey from the wallet. This does not affect the functionality or result of the tests as they never check the state of the wallet in the first place.
238 lines
9.1 KiB
C++
238 lines
9.1 KiB
C++
|
|
|
|
#include "main.h"
|
|
#include "miner.h"
|
|
#include "uint256.h"
|
|
#include "util.h"
|
|
#include "wallet.h"
|
|
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
extern void SHA256Transform(void* pstate, void* pinput, const void* pinit);
|
|
|
|
BOOST_AUTO_TEST_SUITE(miner_tests)
|
|
|
|
static
|
|
struct {
|
|
unsigned char extranonce;
|
|
unsigned int nonce;
|
|
} blockinfo[] = {
|
|
{4, 0xa4a3e223}, {2, 0x15c32f9e}, {1, 0x0375b547}, {1, 0x7004a8a5},
|
|
{2, 0xce440296}, {2, 0x52cfe198}, {1, 0x77a72cd0}, {2, 0xbb5d6f84},
|
|
{2, 0x83f30c2c}, {1, 0x48a73d5b}, {1, 0xef7dcd01}, {2, 0x6809c6c4},
|
|
{2, 0x0883ab3c}, {1, 0x087bbbe2}, {2, 0x2104a814}, {2, 0xdffb6daa},
|
|
{1, 0xee8a0a08}, {2, 0xba4237c1}, {1, 0xa70349dc}, {1, 0x344722bb},
|
|
{3, 0xd6294733}, {2, 0xec9f5c94}, {2, 0xca2fbc28}, {1, 0x6ba4f406},
|
|
{2, 0x015d4532}, {1, 0x6e119b7c}, {2, 0x43e8f314}, {2, 0x27962f38},
|
|
{2, 0xb571b51b}, {2, 0xb36bee23}, {2, 0xd17924a8}, {2, 0x6bc212d9},
|
|
{1, 0x630d4948}, {2, 0x9a4c4ebb}, {2, 0x554be537}, {1, 0xd63ddfc7},
|
|
{2, 0xa10acc11}, {1, 0x759a8363}, {2, 0xfb73090d}, {1, 0xe82c6a34},
|
|
{1, 0xe33e92d7}, {3, 0x658ef5cb}, {2, 0xba32ff22}, {5, 0x0227a10c},
|
|
{1, 0xa9a70155}, {5, 0xd096d809}, {1, 0x37176174}, {1, 0x830b8d0f},
|
|
{1, 0xc6e3910e}, {2, 0x823f3ca8}, {1, 0x99850849}, {1, 0x7521fb81},
|
|
{1, 0xaacaabab}, {1, 0xd645a2eb}, {5, 0x7aea1781}, {5, 0x9d6e4b78},
|
|
{1, 0x4ce90fd8}, {1, 0xabdc832d}, {6, 0x4a34f32a}, {2, 0xf2524c1c},
|
|
{2, 0x1bbeb08a}, {1, 0xad47f480}, {1, 0x9f026aeb}, {1, 0x15a95049},
|
|
{2, 0xd1cb95b2}, {2, 0xf84bbda5}, {1, 0x0fa62cd1}, {1, 0xe05f9169},
|
|
{1, 0x78d194a9}, {5, 0x3e38147b}, {5, 0x737ba0d4}, {1, 0x63378e10},
|
|
{1, 0x6d5f91cf}, {2, 0x88612eb8}, {2, 0xe9639484}, {1, 0xb7fabc9d},
|
|
{2, 0x19b01592}, {1, 0x5a90dd31}, {2, 0x5bd7e028}, {2, 0x94d00323},
|
|
{1, 0xa9b9c01a}, {1, 0x3a40de61}, {1, 0x56e7eec7}, {5, 0x859f7ef6},
|
|
{1, 0xfd8e5630}, {1, 0x2b0c9f7f}, {1, 0xba700e26}, {1, 0x7170a408},
|
|
{1, 0x70de86a8}, {1, 0x74d64cd5}, {1, 0x49e738a1}, {2, 0x6910b602},
|
|
{0, 0x643c565f}, {1, 0x54264b3f}, {2, 0x97ea6396}, {2, 0x55174459},
|
|
{2, 0x03e8779a}, {1, 0x98f34d8f}, {1, 0xc07b2b07}, {1, 0xdfe29668},
|
|
{1, 0x3141c7c1}, {1, 0xb3b595f4}, {1, 0x735abf08}, {5, 0x623bfbce},
|
|
{2, 0xd351e722}, {1, 0xf4ca48c9}, {1, 0x5b19c670}, {1, 0xa164bf0e},
|
|
{2, 0xbbbeb305}, {2, 0xfe1c810a},
|
|
};
|
|
|
|
// NOTE: These tests rely on CreateNewBlock doing its own self-validation!
|
|
BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
|
{
|
|
CScript scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
|
|
CBlockTemplate *pblocktemplate;
|
|
CTransaction tx;
|
|
CScript script;
|
|
uint256 hash;
|
|
|
|
LOCK(cs_main);
|
|
|
|
// Simple block creation, nothing special yet:
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
|
|
|
|
// We can't make transactions until we have inputs
|
|
// Therefore, load 100 blocks :)
|
|
std::vector<CTransaction*>txFirst;
|
|
for (unsigned int i = 0; i < sizeof(blockinfo)/sizeof(*blockinfo); ++i)
|
|
{
|
|
CBlock *pblock = &pblocktemplate->block; // pointer for convenience
|
|
pblock->nVersion = 1;
|
|
pblock->nTime = chainActive.Tip()->GetMedianTimePast()+1;
|
|
pblock->vtx[0].vin[0].scriptSig = CScript();
|
|
pblock->vtx[0].vin[0].scriptSig.push_back(blockinfo[i].extranonce);
|
|
pblock->vtx[0].vin[0].scriptSig.push_back(chainActive.Height());
|
|
pblock->vtx[0].vout[0].scriptPubKey = CScript();
|
|
if (txFirst.size() < 2)
|
|
txFirst.push_back(new CTransaction(pblock->vtx[0]));
|
|
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
|
|
pblock->nNonce = blockinfo[i].nonce;
|
|
CValidationState state;
|
|
BOOST_CHECK(ProcessBlock(state, NULL, pblock));
|
|
BOOST_CHECK(state.IsValid());
|
|
pblock->hashPrevBlock = pblock->GetHash();
|
|
}
|
|
delete pblocktemplate;
|
|
|
|
// Just to make sure we can still make simple blocks
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
|
|
delete pblocktemplate;
|
|
|
|
// block sigops > limit: 1000 CHECKMULTISIG + 1
|
|
tx.vin.resize(1);
|
|
// NOTE: OP_NOP is used to force 20 SigOps for the CHECKMULTISIG
|
|
tx.vin[0].scriptSig = CScript() << OP_0 << OP_0 << OP_0 << OP_NOP << OP_CHECKMULTISIG << OP_1;
|
|
tx.vin[0].prevout.hash = txFirst[0]->GetHash();
|
|
tx.vin[0].prevout.n = 0;
|
|
tx.vout.resize(1);
|
|
tx.vout[0].nValue = 5000000000LL;
|
|
for (unsigned int i = 0; i < 1001; ++i)
|
|
{
|
|
tx.vout[0].nValue -= 1000000;
|
|
hash = tx.GetHash();
|
|
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
|
|
tx.vin[0].prevout.hash = hash;
|
|
}
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
|
|
delete pblocktemplate;
|
|
mempool.clear();
|
|
|
|
// block size > limit
|
|
tx.vin[0].scriptSig = CScript();
|
|
// 18 * (520char + DROP) + OP_1 = 9433 bytes
|
|
std::vector<unsigned char> vchData(520);
|
|
for (unsigned int i = 0; i < 18; ++i)
|
|
tx.vin[0].scriptSig << vchData << OP_DROP;
|
|
tx.vin[0].scriptSig << OP_1;
|
|
tx.vin[0].prevout.hash = txFirst[0]->GetHash();
|
|
tx.vout[0].nValue = 5000000000LL;
|
|
for (unsigned int i = 0; i < 128; ++i)
|
|
{
|
|
tx.vout[0].nValue -= 10000000;
|
|
hash = tx.GetHash();
|
|
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
|
|
tx.vin[0].prevout.hash = hash;
|
|
}
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
|
|
delete pblocktemplate;
|
|
mempool.clear();
|
|
|
|
// orphan in mempool
|
|
hash = tx.GetHash();
|
|
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
|
|
delete pblocktemplate;
|
|
mempool.clear();
|
|
|
|
// child with higher priority than parent
|
|
tx.vin[0].scriptSig = CScript() << OP_1;
|
|
tx.vin[0].prevout.hash = txFirst[1]->GetHash();
|
|
tx.vout[0].nValue = 4900000000LL;
|
|
hash = tx.GetHash();
|
|
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
|
|
tx.vin[0].prevout.hash = hash;
|
|
tx.vin.resize(2);
|
|
tx.vin[1].scriptSig = CScript() << OP_1;
|
|
tx.vin[1].prevout.hash = txFirst[0]->GetHash();
|
|
tx.vin[1].prevout.n = 0;
|
|
tx.vout[0].nValue = 5900000000LL;
|
|
hash = tx.GetHash();
|
|
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
|
|
delete pblocktemplate;
|
|
mempool.clear();
|
|
|
|
// coinbase in mempool
|
|
tx.vin.resize(1);
|
|
tx.vin[0].prevout.SetNull();
|
|
tx.vin[0].scriptSig = CScript() << OP_0 << OP_1;
|
|
tx.vout[0].nValue = 0;
|
|
hash = tx.GetHash();
|
|
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
|
|
delete pblocktemplate;
|
|
mempool.clear();
|
|
|
|
// invalid (pre-p2sh) txn in mempool
|
|
tx.vin[0].prevout.hash = txFirst[0]->GetHash();
|
|
tx.vin[0].prevout.n = 0;
|
|
tx.vin[0].scriptSig = CScript() << OP_1;
|
|
tx.vout[0].nValue = 4900000000LL;
|
|
script = CScript() << OP_0;
|
|
tx.vout[0].scriptPubKey.SetDestination(script.GetID());
|
|
hash = tx.GetHash();
|
|
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
|
|
tx.vin[0].prevout.hash = hash;
|
|
tx.vin[0].scriptSig = CScript() << (std::vector<unsigned char>)script;
|
|
tx.vout[0].nValue -= 1000000;
|
|
hash = tx.GetHash();
|
|
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
|
|
delete pblocktemplate;
|
|
mempool.clear();
|
|
|
|
// double spend txn pair in mempool
|
|
tx.vin[0].prevout.hash = txFirst[0]->GetHash();
|
|
tx.vin[0].scriptSig = CScript() << OP_1;
|
|
tx.vout[0].nValue = 4900000000LL;
|
|
tx.vout[0].scriptPubKey = CScript() << OP_1;
|
|
hash = tx.GetHash();
|
|
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
|
|
tx.vout[0].scriptPubKey = CScript() << OP_2;
|
|
hash = tx.GetHash();
|
|
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
|
|
delete pblocktemplate;
|
|
mempool.clear();
|
|
|
|
// subsidy changing
|
|
int nHeight = chainActive.Height();
|
|
chainActive.Tip()->nHeight = 209999;
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
|
|
delete pblocktemplate;
|
|
chainActive.Tip()->nHeight = 210000;
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
|
|
delete pblocktemplate;
|
|
chainActive.Tip()->nHeight = nHeight;
|
|
|
|
BOOST_FOREACH(CTransaction *tx, txFirst)
|
|
delete tx;
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(sha256transform_equality)
|
|
{
|
|
unsigned int pSHA256InitState[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
|
|
|
|
|
|
// unsigned char pstate[32];
|
|
unsigned char pinput[64];
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < 32; i++) {
|
|
pinput[i] = i;
|
|
pinput[i+32] = 0;
|
|
}
|
|
|
|
uint256 hash;
|
|
|
|
SHA256Transform(&hash, pinput, pSHA256InitState);
|
|
|
|
BOOST_TEST_MESSAGE(hash.GetHex());
|
|
|
|
uint256 hash_reference("0x2df5e1c65ef9f8cde240d23cae2ec036d31a15ec64bc68f64be242b1da6631f3");
|
|
|
|
BOOST_CHECK(hash == hash_reference);
|
|
}
|
|
|
|
BOOST_AUTO_TEST_SUITE_END()
|