Files

368 lines
15 KiB
C++
Raw Permalink Normal View History

2017-11-09 19:34:51 +01:00
/*
* This file is part of the Flowee project
* Copyright (C) 2011-2015 The Bitcoin Core developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2013-04-13 00:13:08 -05:00
2015-07-05 14:17:46 +02:00
#include "chainparams.h"
#include "consensus/consensus.h"
2020-04-01 22:51:47 +02:00
#include <merkle.h>
#include "consensus/validation.h"
2012-05-22 21:55:15 +00:00
#include "main.h"
2013-04-13 00:13:08 -05:00
#include "miner.h"
2023-11-24 18:01:36 +01:00
#include "primitives/PublicKey.h"
2015-07-05 14:17:46 +02:00
#include "script/standard.h"
#include "txmempool.h"
#include "uint256.h"
2012-04-17 20:37:47 +02:00
#include "util.h"
2026-05-14 13:13:40 +02:00
#include "utiltime.h"
2015-07-05 14:17:46 +02:00
#include "utilstrencodings.h"
#include <primitives/Block.h>
#include <utxo/UnspentOutputDatabase.h>
2018-01-15 15:26:12 +00:00
#include "BlocksDB_p.h" // to access the blockMap directly and use erase
#include "test/test_bitcoin.h"
2013-04-13 00:13:08 -05:00
#include <boost/test/unit_test.hpp>
2018-12-30 15:33:11 +01:00
#include <boost/foreach.hpp>
2013-04-13 00:13:08 -05:00
2018-01-15 15:26:12 +00:00
BOOST_FIXTURE_TEST_SUITE(miner_tests, MainnetTestingSetup)
2018-01-15 15:26:12 +00:00
CBlockIndex CreateBlockIndex(CBlockIndex *parent, int offset)
2015-12-07 15:44:16 -05:00
{
CBlockIndex index;
2018-01-15 15:26:12 +00:00
index.nHeight = parent->nHeight + offset;
index.pprev = parent;
2015-12-07 15:44:16 -05:00
return index;
}
2018-01-15 15:26:12 +00:00
bool TestSequenceLocks(CTxMemPool &mempool, const CTransaction &tx, int flags)
2015-12-07 15:44:16 -05:00
{
LOCK(mempool.cs);
2018-01-15 15:26:12 +00:00
return CheckSequenceLocks(mempool, tx, flags);
2015-12-07 15:44:16 -05:00
}
2012-05-22 21:55:15 +00:00
// 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;
2012-05-22 21:55:15 +00:00
CScript script;
uint256 hash;
TestMemPoolEntryHelper entry;
entry.nFee = 11;
entry.dPriority = 111.0;
entry.nHeight = 11;
2012-05-22 21:55:15 +00:00
fCheckpointsEnabled = false;
2018-01-15 15:26:12 +00:00
BOOST_CHECK_EQUAL(bv.blockchain()->Height(), 0);
2012-05-22 21:55:15 +00:00
// Simple block creation, nothing special yet:
2016-05-05 14:36:07 +01:00
Mining miner;
miner.SetCoinbase(scriptPubKey);
2018-01-15 15:26:12 +00:00
BOOST_CHECK(pblocktemplate = miner.CreateNewBlock(bv));
BOOST_CHECK_EQUAL(bv.blockchain()->Height(), 0);
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1);
delete pblocktemplate;
2012-05-22 21:55:15 +00:00
// We can't make transactions until we have inputs
2020-04-12 23:48:32 +02:00
// Therefore, load 110 blocks :)
2018-01-15 15:26:12 +00:00
int baseheight = bv.blockchain()->Height();
auto chain = bv.appendChain(110, MockBlockValidation::EmptyOutScript);
2012-05-22 21:55:15 +00:00
std::vector<CTransaction*>txFirst;
2018-01-15 15:26:12 +00:00
for (int i = 0; i < 4; ++i) {
2021-11-02 09:36:09 +01:00
MutableBlock block = chain[i].createOldBlock();
2018-01-15 15:26:12 +00:00
txFirst.push_back(new CTransaction(block.vtx[0]));
2012-05-22 21:55:15 +00:00
}
2018-01-15 15:26:12 +00:00
BOOST_CHECK_EQUAL(bv.blockchain()->Height(), 110);
2012-05-22 21:55:15 +00:00
// Just to make sure we can still make simple blocks
2018-01-15 15:26:12 +00:00
BOOST_CHECK(pblocktemplate = miner.CreateNewBlock(bv));
2013-09-19 00:01:36 +02:00
delete pblocktemplate;
2012-05-22 21:55:15 +00:00
// block sigops > limit: 1000 CHECKMULTISIG + 1
2020-04-12 23:48:32 +02:00
CMutableTransaction tx;
2012-05-22 21:55:15 +00:00
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;
2018-01-15 15:26:12 +00:00
for (unsigned int i = 0; i < 1; ++i) {
2015-11-03 10:35:39 -05:00
tx.vout[0].nValue -= 1000000;
hash = tx.GetHash();
2018-01-15 15:26:12 +00:00
const bool spendsCoinbase = i == 0; // only first tx spends coinbase
2015-11-03 10:35:39 -05:00
// If we do set the # of sig ops in the CTxMemPoolEntry, template creation passes
2020-04-12 23:48:32 +02:00
bv.mp.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx));
2012-05-22 21:55:15 +00:00
tx.vin[0].prevout.hash = hash;
}
2018-01-15 15:26:12 +00:00
BOOST_CHECK(pblocktemplate = miner.CreateNewBlock(bv));
BOOST_CHECK(pblocktemplate->block.vtx.size() > 1);
delete pblocktemplate;
2018-01-15 15:26:12 +00:00
bv.mp.clear();
2012-05-22 21:55:15 +00:00
// 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();
2015-10-29 14:06:13 -04:00
bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase
2018-01-15 15:26:12 +00:00
bv.mp.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx));
2012-05-22 21:55:15 +00:00
tx.vin[0].prevout.hash = hash;
}
2018-01-15 15:26:12 +00:00
BOOST_CHECK(pblocktemplate = miner.CreateNewBlock(bv));
delete pblocktemplate;
2018-01-15 15:26:12 +00:00
bv.mp.clear();
2012-05-22 21:55:15 +00:00
// orphan in mempool not mined
2012-05-22 21:55:15 +00:00
hash = tx.GetHash();
2018-01-15 15:26:12 +00:00
bv.mp.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).FromTx(tx));
BOOST_CHECK(pblocktemplate = miner.CreateNewBlock(bv));
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1);
delete pblocktemplate;
2018-01-15 15:26:12 +00:00
bv.mp.clear();
2012-05-22 21:55:15 +00:00
// 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();
2018-01-15 15:26:12 +00:00
bv.mp.addUnchecked(hash, entry.Fee(100000000LL).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
2012-05-22 21:55:15 +00:00
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();
2018-01-15 15:26:12 +00:00
bv.mp.addUnchecked(hash, entry.Fee(400000000LL).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
BOOST_CHECK(pblocktemplate = miner.CreateNewBlock(bv));
delete pblocktemplate;
2018-01-15 15:26:12 +00:00
bv.mp.clear();
2012-05-22 21:55:15 +00:00
2015-11-03 10:35:39 -05:00
// coinbase in mempool, template creation fails
2012-05-22 21:55:15 +00:00
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();
2015-11-03 10:35:39 -05:00
// give it a fee so it'll get mined
2018-01-15 15:26:12 +00:00
bv.mp.addUnchecked(hash, entry.Fee(100000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
BOOST_CHECK(pblocktemplate = miner.CreateNewBlock(bv));
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1);
delete pblocktemplate;
2018-01-15 15:26:12 +00:00
bv.mp.clear();
2012-05-22 21:55:15 +00:00
// invalid (pre-p2sh) txn in mempool, don't mine
2012-05-22 21:55:15 +00:00
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 = GetScriptForDestination(CScriptID(script));
2012-05-22 21:55:15 +00:00
hash = tx.GetHash();
2018-01-15 15:26:12 +00:00
bv.mp.addUnchecked(hash, entry.Fee(10000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
2012-05-22 21:55:15 +00:00
tx.vin[0].prevout.hash = hash;
2015-10-29 07:11:24 +01:00
tx.vin[0].scriptSig = CScript() << std::vector<unsigned char>(script.begin(), script.end());
2012-05-22 21:55:15 +00:00
tx.vout[0].nValue -= 1000000;
hash = tx.GetHash();
2018-01-15 15:26:12 +00:00
bv.mp.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
BOOST_CHECK(pblocktemplate = miner.CreateNewBlock(bv));
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1); // Just coinbase
delete pblocktemplate;
2018-01-15 15:26:12 +00:00
bv.mp.clear();
2012-05-22 21:55:15 +00:00
// double spend txn pair in mempool, don't mine
2012-05-22 21:55:15 +00:00
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();
2018-01-15 15:26:12 +00:00
bv.mp.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
2012-05-22 21:55:15 +00:00
tx.vout[0].scriptPubKey = CScript() << OP_2;
hash = tx.GetHash();
2018-01-15 15:26:12 +00:00
bv.mp.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
BOOST_CHECK(pblocktemplate = miner.CreateNewBlock(bv));
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1); // Just coinbase
delete pblocktemplate;
2018-01-15 15:26:12 +00:00
bv.mp.clear();
2012-05-22 21:55:15 +00:00
// subsidy changing
2018-01-15 15:26:12 +00:00
int nHeight = bv.blockchain()->Height();
2016-02-15 05:13:27 +01:00
// Create an actual 209999-long block chain (without valid blocks).
2018-01-15 15:26:12 +00:00
while (bv.blockchain()->Tip()->nHeight < 209999) {
CBlockIndex* prev = bv.blockchain()->Tip();
2016-02-15 05:13:27 +01:00
CBlockIndex* next = new CBlockIndex();
2018-01-15 15:26:12 +00:00
2016-02-15 05:13:27 +01:00
next->pprev = prev;
next->nHeight = prev->nHeight + 1;
2018-01-15 15:26:12 +00:00
next->phashBlock = Blocks::Index::insert(GetRandHash(), next);
next->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
2016-02-15 05:13:27 +01:00
next->BuildSkip();
2018-01-15 15:26:12 +00:00
bv.blockchain()->SetTip(next);
g_utxo->blockFinished(next->nHeight, next->GetBlockHash());
2018-01-15 15:26:12 +00:00
Blocks::DB::instance()->appendHeader(next);
2016-02-15 05:13:27 +01:00
}
2018-01-15 15:26:12 +00:00
BOOST_CHECK(pblocktemplate = miner.CreateNewBlock(bv));
delete pblocktemplate;
2016-02-15 05:13:27 +01:00
// Extend to a 210000-long block chain.
2018-01-15 15:26:12 +00:00
while (bv.blockchain()->Tip()->nHeight < 210000) {
CBlockIndex* prev = bv.blockchain()->Tip();
2016-02-15 05:13:27 +01:00
CBlockIndex* next = new CBlockIndex();
2018-01-15 15:26:12 +00:00
2016-02-15 05:13:27 +01:00
next->pprev = prev;
next->nHeight = prev->nHeight + 1;
2018-01-15 15:26:12 +00:00
next->phashBlock = Blocks::Index::insert(GetRandHash(), next);
next->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
2016-02-15 05:13:27 +01:00
next->BuildSkip();
2018-01-15 15:26:12 +00:00
bv.blockchain()->SetTip(next);
g_utxo->blockFinished(next->nHeight, next->GetBlockHash());
2018-01-15 15:26:12 +00:00
Blocks::DB::instance()->appendHeader(next);
2016-02-15 05:13:27 +01:00
}
2018-01-15 15:26:12 +00:00
BOOST_CHECK(pblocktemplate = miner.CreateNewBlock(bv));
delete pblocktemplate;
2016-02-15 05:13:27 +01:00
// Delete the dummy blocks again.
2018-01-15 15:26:12 +00:00
while (bv.blockchain()->Tip()->nHeight > nHeight) {
CBlockIndex* del = bv.blockchain()->Tip();
del->nStatus |= BLOCK_FAILED_VALID;
Blocks::DB::instance()->appendHeader(del);
bv.blockchain()->SetTip(del->pprev);
g_utxo->blockFinished(del->pprev->nHeight, del->pprev->GetBlockHash());
2018-01-15 15:26:12 +00:00
Blocks::DB::instance()->priv()->indexMap.erase(del->GetBlockHash());
2016-02-15 05:13:27 +01:00
delete del;
}
2013-09-19 00:01:36 +02:00
2014-01-26 21:50:15 -05:00
// non-final txs in mempool
2018-01-15 15:26:12 +00:00
SetMockTime(bv.blockchain()->Tip()->GetMedianTimePast()+1);
2015-12-07 15:44:16 -05:00
int flags = LOCKTIME_VERIFY_SEQUENCE|LOCKTIME_MEDIAN_TIME_PAST;
// height map
std::vector<int> prevheights;
2014-01-26 21:50:15 -05:00
2015-12-07 15:44:16 -05:00
// relative height locked
tx.nVersion = 2;
tx.vin.resize(1);
prevheights.resize(1);
tx.vin[0].prevout.hash = txFirst[0]->GetHash(); // only 1 transaction
tx.vin[0].prevout.n = 0;
2014-01-26 21:50:15 -05:00
tx.vin[0].scriptSig = CScript() << OP_1;
2018-01-15 15:26:12 +00:00
tx.vin[0].nSequence = bv.blockchain()->Tip()->nHeight + 1; // txFirst[0] is the 2nd block
2015-12-07 15:44:16 -05:00
prevheights[0] = baseheight + 1;
tx.vout.resize(1);
2014-01-26 21:50:15 -05:00
tx.vout[0].nValue = 4900000000LL;
tx.vout[0].scriptPubKey = CScript() << OP_1;
2015-12-07 15:44:16 -05:00
tx.nLockTime = 0;
2014-01-26 21:50:15 -05:00
hash = tx.GetHash();
2018-01-15 15:26:12 +00:00
bv.mp.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
Tx newTx = Tx::fromOldTransaction(tx);
BOOST_CHECK(CheckFinalTx(newTx, flags)); // Locktime passes
2018-01-15 15:26:12 +00:00
BOOST_CHECK(!TestSequenceLocks(bv.mp, tx, flags)); // Sequence locks fail
BOOST_CHECK(SequenceLocks(tx, flags, &prevheights, CreateBlockIndex(bv.blockchain()->Tip(), 2))); // Sequence locks pass on 2nd block
2014-01-26 21:50:15 -05:00
2015-12-07 15:44:16 -05:00
// relative time locked
tx.vin[0].prevout.hash = txFirst[1]->GetHash();
2018-01-15 15:26:12 +00:00
tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | (((bv.blockchain()->Tip()->GetMedianTimePast()+1-(*bv.blockchain())[1]->GetMedianTimePast()) >> CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) + 1); // txFirst[1] is the 3rd block
2015-12-07 15:44:16 -05:00
prevheights[0] = baseheight + 2;
hash = tx.GetHash();
2018-01-15 15:26:12 +00:00
bv.mp.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
newTx = Tx::fromOldTransaction(tx);
BOOST_CHECK(CheckFinalTx(newTx, flags)); // Locktime passes
2018-01-15 15:26:12 +00:00
BOOST_CHECK(!TestSequenceLocks(bv.mp, tx, flags)); // Sequence locks fail
2015-12-07 15:44:16 -05:00
for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++)
2018-01-15 15:26:12 +00:00
bv.blockchain()->Tip()->GetAncestor(bv.blockchain()->Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast
BOOST_CHECK(SequenceLocks(tx, flags, &prevheights, CreateBlockIndex(bv.blockchain()->Tip(), 1))); // Sequence locks pass 512 seconds later
2015-12-07 15:44:16 -05:00
for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++)
2018-01-15 15:26:12 +00:00
bv.blockchain()->Tip()->GetAncestor(bv.blockchain()->Tip()->nHeight - i)->nTime -= 512; //undo tricked MTP
2015-12-07 15:44:16 -05:00
// absolute height locked
tx.vin[0].prevout.hash = txFirst[2]->GetHash();
tx.vin[0].nSequence = CTxIn::SEQUENCE_FINAL - 1;
prevheights[0] = baseheight + 3;
2018-01-15 15:26:12 +00:00
tx.nLockTime = bv.blockchain()->Tip()->nHeight + 1;
2015-12-07 15:44:16 -05:00
hash = tx.GetHash();
2018-01-15 15:26:12 +00:00
bv.mp.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
newTx = Tx::fromOldTransaction(tx);
BOOST_CHECK(!CheckFinalTx(newTx, flags)); // Locktime fails
2018-01-15 15:26:12 +00:00
BOOST_CHECK(TestSequenceLocks(bv.mp, tx, flags)); // Sequence locks pass
BOOST_CHECK(IsFinalTx(newTx, bv.blockchain()->Tip()->nHeight + 2, bv.blockchain()->Tip()->GetMedianTimePast())); // Locktime passes on 2nd block
2015-12-07 15:44:16 -05:00
// absolute time locked
tx.vin[0].prevout.hash = txFirst[3]->GetHash();
2018-01-15 15:26:12 +00:00
tx.nLockTime = bv.blockchain()->Tip()->GetMedianTimePast();
2015-12-07 15:44:16 -05:00
prevheights.resize(1);
prevheights[0] = baseheight + 4;
hash = tx.GetHash();
2018-01-15 15:26:12 +00:00
bv.mp.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
newTx = Tx::fromOldTransaction(tx);
BOOST_CHECK(!CheckFinalTx(newTx, flags)); // Locktime fails
2018-01-15 15:26:12 +00:00
BOOST_CHECK(TestSequenceLocks(bv.mp, tx, flags)); // Sequence locks pass
BOOST_CHECK(IsFinalTx(newTx, bv.blockchain()->Tip()->nHeight + 2, bv.blockchain()->Tip()->GetMedianTimePast() + 1)); // Locktime passes 1 second later
2015-12-07 15:44:16 -05:00
// mempool-dependent transactions (not added)
tx.vin[0].prevout.hash = hash;
2018-01-15 15:26:12 +00:00
prevheights[0] = bv.blockchain()->Tip()->nHeight + 1;
2015-12-07 15:44:16 -05:00
tx.nLockTime = 0;
tx.vin[0].nSequence = 0;
newTx = Tx::fromOldTransaction(tx);
BOOST_CHECK(CheckFinalTx(newTx, flags)); // Locktime passes
2018-01-15 15:26:12 +00:00
BOOST_CHECK(TestSequenceLocks(bv.mp, tx, flags)); // Sequence locks pass
2015-12-07 15:44:16 -05:00
tx.vin[0].nSequence = 1;
2018-01-15 15:26:12 +00:00
BOOST_CHECK(!TestSequenceLocks(bv.mp, tx, flags)); // Sequence locks fail
2015-12-07 15:44:16 -05:00
tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG;
2018-01-15 15:26:12 +00:00
BOOST_CHECK(TestSequenceLocks(bv.mp, tx, flags)); // Sequence locks pass
2015-12-07 15:44:16 -05:00
tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | 1;
2018-01-15 15:26:12 +00:00
BOOST_CHECK(!TestSequenceLocks(bv.mp, tx, flags)); // Sequence locks fail
2014-01-26 21:50:15 -05:00
2018-01-15 15:26:12 +00:00
BOOST_CHECK(pblocktemplate = miner.CreateNewBlock(bv));
2014-01-26 21:50:15 -05:00
2015-12-07 15:44:16 -05:00
// None of the of the absolute height/time locked tx should have made
// it into the template because we still check IsFinalTx in CreateNewBlock,
// but relative locked txs will if inconsistently added to mempool.
// For now these will still generate a valid template until BIP68 soft fork
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3);
2014-01-26 21:50:15 -05:00
delete pblocktemplate;
2015-12-07 15:44:16 -05:00
// However if we advance height by 1 and time by 512, all of them should be mined
2018-01-15 15:26:12 +00:00
bv.appendChain(1);
2015-12-07 15:44:16 -05:00
for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++)
2018-01-15 15:26:12 +00:00
bv.blockchain()->Tip()->GetAncestor(bv.blockchain()->Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast
SetMockTime(bv.blockchain()->Tip()->GetMedianTimePast() + 1);
2014-01-26 21:50:15 -05:00
2018-01-15 15:26:12 +00:00
BOOST_CHECK(pblocktemplate = miner.CreateNewBlock(bv));
2015-12-07 15:44:16 -05:00
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5);
2014-01-26 21:50:15 -05:00
delete pblocktemplate;
2018-01-15 15:26:12 +00:00
bv.blockchain()->Tip()->nHeight--;
2014-01-26 21:50:15 -05:00
SetMockTime(0);
2018-01-15 15:26:12 +00:00
bv.mp.clear();
2014-01-26 21:50:15 -05:00
2013-09-19 00:01:36 +02:00
BOOST_FOREACH(CTransaction *tx, txFirst)
delete tx;
2014-01-26 21:50:15 -05:00
fCheckpointsEnabled = true;
2012-05-22 21:55:15 +00:00
}
BOOST_AUTO_TEST_SUITE_END()