|
|
@ -124,6 +124,11 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) |
|
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); |
|
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); |
|
|
|
delete pblocktemplate; |
|
|
|
delete pblocktemplate; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const CAmount BLOCKSUBSIDY = 50*COIN; |
|
|
|
|
|
|
|
const CAmount LOWFEE = CENT; |
|
|
|
|
|
|
|
const CAmount HIGHFEE = COIN; |
|
|
|
|
|
|
|
const CAmount HIGHERFEE = 4*COIN; |
|
|
|
|
|
|
|
|
|
|
|
// block sigops > limit: 1000 CHECKMULTISIG + 1
|
|
|
|
// block sigops > limit: 1000 CHECKMULTISIG + 1
|
|
|
|
tx.vin.resize(1); |
|
|
|
tx.vin.resize(1); |
|
|
|
// NOTE: OP_NOP is used to force 20 SigOps for the CHECKMULTISIG
|
|
|
|
// NOTE: OP_NOP is used to force 20 SigOps for the CHECKMULTISIG
|
|
|
@ -131,28 +136,28 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) |
|
|
|
tx.vin[0].prevout.hash = txFirst[0]->GetHash(); |
|
|
|
tx.vin[0].prevout.hash = txFirst[0]->GetHash(); |
|
|
|
tx.vin[0].prevout.n = 0; |
|
|
|
tx.vin[0].prevout.n = 0; |
|
|
|
tx.vout.resize(1); |
|
|
|
tx.vout.resize(1); |
|
|
|
tx.vout[0].nValue = 5000000000LL; |
|
|
|
tx.vout[0].nValue = BLOCKSUBSIDY; |
|
|
|
for (unsigned int i = 0; i < 1001; ++i) |
|
|
|
for (unsigned int i = 0; i < 1001; ++i) |
|
|
|
{ |
|
|
|
{ |
|
|
|
tx.vout[0].nValue -= 1000000; |
|
|
|
tx.vout[0].nValue -= LOWFEE; |
|
|
|
hash = tx.GetHash(); |
|
|
|
hash = tx.GetHash(); |
|
|
|
bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase
|
|
|
|
bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase
|
|
|
|
// If we don't set the # of sig ops in the CTxMemPoolEntry, template creation fails
|
|
|
|
// If we don't set the # of sig ops in the CTxMemPoolEntry, template creation fails
|
|
|
|
mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); |
|
|
|
tx.vin[0].prevout.hash = hash; |
|
|
|
tx.vin[0].prevout.hash = hash; |
|
|
|
} |
|
|
|
} |
|
|
|
BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); |
|
|
|
BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); |
|
|
|
mempool.clear(); |
|
|
|
mempool.clear(); |
|
|
|
|
|
|
|
|
|
|
|
tx.vin[0].prevout.hash = txFirst[0]->GetHash(); |
|
|
|
tx.vin[0].prevout.hash = txFirst[0]->GetHash(); |
|
|
|
tx.vout[0].nValue = 5000000000LL; |
|
|
|
tx.vout[0].nValue = BLOCKSUBSIDY; |
|
|
|
for (unsigned int i = 0; i < 1001; ++i) |
|
|
|
for (unsigned int i = 0; i < 1001; ++i) |
|
|
|
{ |
|
|
|
{ |
|
|
|
tx.vout[0].nValue -= 1000000; |
|
|
|
tx.vout[0].nValue -= LOWFEE; |
|
|
|
hash = tx.GetHash(); |
|
|
|
hash = tx.GetHash(); |
|
|
|
bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase
|
|
|
|
bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase
|
|
|
|
// If we do set the # of sig ops in the CTxMemPoolEntry, template creation passes
|
|
|
|
// If we do set the # of sig ops in the CTxMemPoolEntry, template creation passes
|
|
|
|
mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOps(20).FromTx(tx)); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOps(20).FromTx(tx)); |
|
|
|
tx.vin[0].prevout.hash = hash; |
|
|
|
tx.vin[0].prevout.hash = hash; |
|
|
|
} |
|
|
|
} |
|
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); |
|
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); |
|
|
@ -167,13 +172,13 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) |
|
|
|
tx.vin[0].scriptSig << vchData << OP_DROP; |
|
|
|
tx.vin[0].scriptSig << vchData << OP_DROP; |
|
|
|
tx.vin[0].scriptSig << OP_1; |
|
|
|
tx.vin[0].scriptSig << OP_1; |
|
|
|
tx.vin[0].prevout.hash = txFirst[0]->GetHash(); |
|
|
|
tx.vin[0].prevout.hash = txFirst[0]->GetHash(); |
|
|
|
tx.vout[0].nValue = 5000000000LL; |
|
|
|
tx.vout[0].nValue = BLOCKSUBSIDY; |
|
|
|
for (unsigned int i = 0; i < 128; ++i) |
|
|
|
for (unsigned int i = 0; i < 128; ++i) |
|
|
|
{ |
|
|
|
{ |
|
|
|
tx.vout[0].nValue -= 10000000; |
|
|
|
tx.vout[0].nValue -= 10*LOWFEE; |
|
|
|
hash = tx.GetHash(); |
|
|
|
hash = tx.GetHash(); |
|
|
|
bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase
|
|
|
|
bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase
|
|
|
|
mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); |
|
|
|
tx.vin[0].prevout.hash = hash; |
|
|
|
tx.vin[0].prevout.hash = hash; |
|
|
|
} |
|
|
|
} |
|
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); |
|
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); |
|
|
@ -182,24 +187,24 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) |
|
|
|
|
|
|
|
|
|
|
|
// orphan in mempool, template creation fails
|
|
|
|
// orphan in mempool, template creation fails
|
|
|
|
hash = tx.GetHash(); |
|
|
|
hash = tx.GetHash(); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).FromTx(tx)); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).FromTx(tx)); |
|
|
|
BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); |
|
|
|
BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); |
|
|
|
mempool.clear(); |
|
|
|
mempool.clear(); |
|
|
|
|
|
|
|
|
|
|
|
// child with higher priority than parent
|
|
|
|
// child with higher priority than parent
|
|
|
|
tx.vin[0].scriptSig = CScript() << OP_1; |
|
|
|
tx.vin[0].scriptSig = CScript() << OP_1; |
|
|
|
tx.vin[0].prevout.hash = txFirst[1]->GetHash(); |
|
|
|
tx.vin[0].prevout.hash = txFirst[1]->GetHash(); |
|
|
|
tx.vout[0].nValue = 4900000000LL; |
|
|
|
tx.vout[0].nValue = BLOCKSUBSIDY-HIGHFEE; |
|
|
|
hash = tx.GetHash(); |
|
|
|
hash = tx.GetHash(); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(100000000LL).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); |
|
|
|
tx.vin[0].prevout.hash = hash; |
|
|
|
tx.vin[0].prevout.hash = hash; |
|
|
|
tx.vin.resize(2); |
|
|
|
tx.vin.resize(2); |
|
|
|
tx.vin[1].scriptSig = CScript() << OP_1; |
|
|
|
tx.vin[1].scriptSig = CScript() << OP_1; |
|
|
|
tx.vin[1].prevout.hash = txFirst[0]->GetHash(); |
|
|
|
tx.vin[1].prevout.hash = txFirst[0]->GetHash(); |
|
|
|
tx.vin[1].prevout.n = 0; |
|
|
|
tx.vin[1].prevout.n = 0; |
|
|
|
tx.vout[0].nValue = 5900000000LL; |
|
|
|
tx.vout[0].nValue = tx.vout[0].nValue+BLOCKSUBSIDY-HIGHERFEE; //First txn output + fresh coinbase - new txn fee
|
|
|
|
hash = tx.GetHash(); |
|
|
|
hash = tx.GetHash(); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(400000000LL).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(HIGHERFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); |
|
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); |
|
|
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); |
|
|
|
delete pblocktemplate; |
|
|
|
delete pblocktemplate; |
|
|
|
mempool.clear(); |
|
|
|
mempool.clear(); |
|
|
@ -211,7 +216,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) |
|
|
|
tx.vout[0].nValue = 0; |
|
|
|
tx.vout[0].nValue = 0; |
|
|
|
hash = tx.GetHash(); |
|
|
|
hash = tx.GetHash(); |
|
|
|
// give it a fee so it'll get mined
|
|
|
|
// give it a fee so it'll get mined
|
|
|
|
mempool.addUnchecked(hash, entry.Fee(100000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(LOWFEE/10).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); |
|
|
|
BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); |
|
|
|
BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); |
|
|
|
mempool.clear(); |
|
|
|
mempool.clear(); |
|
|
|
|
|
|
|
|
|
|
@ -219,29 +224,29 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) |
|
|
|
tx.vin[0].prevout.hash = txFirst[0]->GetHash(); |
|
|
|
tx.vin[0].prevout.hash = txFirst[0]->GetHash(); |
|
|
|
tx.vin[0].prevout.n = 0; |
|
|
|
tx.vin[0].prevout.n = 0; |
|
|
|
tx.vin[0].scriptSig = CScript() << OP_1; |
|
|
|
tx.vin[0].scriptSig = CScript() << OP_1; |
|
|
|
tx.vout[0].nValue = 4900000000LL; |
|
|
|
tx.vout[0].nValue = BLOCKSUBSIDY-LOWFEE; |
|
|
|
script = CScript() << OP_0; |
|
|
|
script = CScript() << OP_0; |
|
|
|
tx.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(script)); |
|
|
|
tx.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(script)); |
|
|
|
hash = tx.GetHash(); |
|
|
|
hash = tx.GetHash(); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(10000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); |
|
|
|
tx.vin[0].prevout.hash = hash; |
|
|
|
tx.vin[0].prevout.hash = hash; |
|
|
|
tx.vin[0].scriptSig = CScript() << std::vector<unsigned char>(script.begin(), script.end()); |
|
|
|
tx.vin[0].scriptSig = CScript() << std::vector<unsigned char>(script.begin(), script.end()); |
|
|
|
tx.vout[0].nValue -= 1000000; |
|
|
|
tx.vout[0].nValue -= LOWFEE; |
|
|
|
hash = tx.GetHash(); |
|
|
|
hash = tx.GetHash(); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); |
|
|
|
BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); |
|
|
|
BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); |
|
|
|
mempool.clear(); |
|
|
|
mempool.clear(); |
|
|
|
|
|
|
|
|
|
|
|
// double spend txn pair in mempool, template creation fails
|
|
|
|
// double spend txn pair in mempool, template creation fails
|
|
|
|
tx.vin[0].prevout.hash = txFirst[0]->GetHash(); |
|
|
|
tx.vin[0].prevout.hash = txFirst[0]->GetHash(); |
|
|
|
tx.vin[0].scriptSig = CScript() << OP_1; |
|
|
|
tx.vin[0].scriptSig = CScript() << OP_1; |
|
|
|
tx.vout[0].nValue = 4900000000LL; |
|
|
|
tx.vout[0].nValue = BLOCKSUBSIDY-HIGHFEE; |
|
|
|
tx.vout[0].scriptPubKey = CScript() << OP_1; |
|
|
|
tx.vout[0].scriptPubKey = CScript() << OP_1; |
|
|
|
hash = tx.GetHash(); |
|
|
|
hash = tx.GetHash(); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); |
|
|
|
tx.vout[0].scriptPubKey = CScript() << OP_2; |
|
|
|
tx.vout[0].scriptPubKey = CScript() << OP_2; |
|
|
|
hash = tx.GetHash(); |
|
|
|
hash = tx.GetHash(); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); |
|
|
|
BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); |
|
|
|
BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); |
|
|
|
mempool.clear(); |
|
|
|
mempool.clear(); |
|
|
|
|
|
|
|
|
|
|
@ -298,11 +303,11 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) |
|
|
|
tx.vin[0].nSequence = chainActive.Tip()->nHeight + 1; // txFirst[0] is the 2nd block
|
|
|
|
tx.vin[0].nSequence = chainActive.Tip()->nHeight + 1; // txFirst[0] is the 2nd block
|
|
|
|
prevheights[0] = baseheight + 1; |
|
|
|
prevheights[0] = baseheight + 1; |
|
|
|
tx.vout.resize(1); |
|
|
|
tx.vout.resize(1); |
|
|
|
tx.vout[0].nValue = 4900000000LL; |
|
|
|
tx.vout[0].nValue = BLOCKSUBSIDY-HIGHFEE; |
|
|
|
tx.vout[0].scriptPubKey = CScript() << OP_1; |
|
|
|
tx.vout[0].scriptPubKey = CScript() << OP_1; |
|
|
|
tx.nLockTime = 0; |
|
|
|
tx.nLockTime = 0; |
|
|
|
hash = tx.GetHash(); |
|
|
|
hash = tx.GetHash(); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); |
|
|
|
mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); |
|
|
|
BOOST_CHECK(CheckFinalTx(tx, flags)); // Locktime passes
|
|
|
|
BOOST_CHECK(CheckFinalTx(tx, flags)); // Locktime passes
|
|
|
|
BOOST_CHECK(!TestSequenceLocks(tx, flags)); // Sequence locks fail
|
|
|
|
BOOST_CHECK(!TestSequenceLocks(tx, flags)); // Sequence locks fail
|
|
|
|
BOOST_CHECK(SequenceLocks(tx, flags, &prevheights, CreateBlockIndex(chainActive.Tip()->nHeight + 2))); // Sequence locks pass on 2nd block
|
|
|
|
BOOST_CHECK(SequenceLocks(tx, flags, &prevheights, CreateBlockIndex(chainActive.Tip()->nHeight + 2))); // Sequence locks pass on 2nd block
|
|
|
|