19 #include <validation.h>
26 #include <boost/test/unit_test.hpp>
56 BOOST_FIXTURE_TEST_SUITE(
miner_tests, MinerTestingSetup)
62 BlockAssembler::Options options;
69 constexpr
static struct {
72 }
BLOCKINFO[]{{8, 582909131}, {0, 971462344}, {2, 1169481553}, {6, 66147495}, {7, 427785981}, {8, 80538907},
73 {8, 207348013}, {2, 1951240923}, {4, 215054351}, {1, 491520534}, {8, 1282281282}, {4, 639565734},
74 {3, 248274685}, {8, 1160085976}, {6, 396349768}, {5, 393780549}, {5, 1096899528}, {4, 965381630},
75 {0, 728758712}, {5, 318638310}, {3, 164591898}, {2, 274234550}, {2, 254411237}, {7, 561761812},
76 {2, 268342573}, {0, 402816691}, {1, 221006382}, {6, 538872455}, {7, 393315655}, {4, 814555937},
77 {7, 504879194}, {6, 467769648}, {3, 925972193}, {2, 200581872}, {3, 168915404}, {8, 430446262},
78 {5, 773507406}, {3, 1195366164}, {0, 433361157}, {3, 297051771}, {0, 558856551}, {2, 501614039},
79 {3, 528488272}, {2, 473587734}, {8, 230125274}, {2, 494084400}, {4, 357314010}, {8, 60361686},
80 {7, 640624687}, {3, 480441695}, {8, 1424447925}, {4, 752745419}, {1, 288532283}, {6, 669170574},
81 {5, 1900907591}, {3, 555326037}, {3, 1121014051}, {0, 545835650}, {8, 189196651}, {5, 252371575},
82 {0, 199163095}, {6, 558895874}, {6, 1656839784}, {6, 815175452}, {6, 718677851}, {5, 544000334},
83 {0, 340113484}, {6, 850744437}, {4, 496721063}, {8, 524715182}, {6, 574361898}, {6, 1642305743},
84 {6, 355110149}, {5, 1647379658}, {8, 1103005356}, {7, 556460625}, {3, 1139533992}, {5, 304736030},
85 {2, 361539446}, {2, 143720360}, {6, 201939025}, {7, 423141476}, {4, 574633709}, {3, 1412254823},
86 {4, 873254135}, {0, 341817335}, {6, 53501687}, {3, 179755410}, {5, 172209688}, {8, 516810279},
87 {4, 1228391489}, {8, 325372589}, {6, 550367589}, {0, 876291812}, {7, 412454120}, {7, 717202854},
88 {2, 222677843}, {6, 251778867}, {7, 842004420}, {7, 194762829}, {4, 96668841}, {1, 925485796},
89 {0, 792342903}, {6, 678455063}, {6, 773251385}, {5, 186617471}, {6, 883189502}, {7, 396077336},
90 {8, 254702874}, {0, 455592851}};
94 auto index{std::make_unique<CBlockIndex>()};
96 index->pprev = active_chain_tip;
103 void MinerTestingSetup::TestPackageSelection(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst)
115 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
116 tx.
vin[0].prevout.n = 0;
118 tx.
vout[0].nValue = 5000000000LL - 1000;
124 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
125 tx.
vout[0].nValue = 5000000000LL - 10000;
130 tx.
vin[0].prevout.hash = hashParentTx;
131 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000;
135 std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
136 BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 4U);
137 BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashParentTx);
138 BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashHighFeeTx);
139 BOOST_CHECK(pblocktemplate->block.vtx[3]->GetHash() == hashMediumFeeTx);
142 tx.
vin[0].prevout.hash = hashHighFeeTx;
143 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000;
145 tx_mempool.addUnchecked(entry.
Fee(0).
FromTx(tx));
152 tx.
vin[0].prevout.hash = hashFreeTx;
153 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse;
155 tx_mempool.addUnchecked(entry.
Fee(feeToUse).
FromTx(tx));
156 pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
158 for (
size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
159 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeTx);
160 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashLowFeeTx);
167 tx.
vout[0].nValue -= 2;
169 tx_mempool.addUnchecked(entry.
Fee(feeToUse + 2).
FromTx(tx));
170 pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
171 BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 6U);
172 BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashFreeTx);
173 BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashLowFeeTx);
178 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
180 tx.
vout[0].nValue = 5000000000LL - 100000000;
181 tx.
vout[1].nValue = 100000000;
186 tx.
vin[0].prevout.hash = hashFreeTx2;
189 tx.
vout[0].nValue = 5000000000LL - 100000000 - feeToUse;
192 pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
195 for (
size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
196 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeTx2);
197 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashLowFeeTx2);
202 tx.
vin[0].prevout.n = 1;
203 tx.
vout[0].nValue = 100000000 - 10000;
204 tx_mempool.addUnchecked(entry.
Fee(10000).
FromTx(tx));
205 pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
206 BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 9U);
207 BOOST_CHECK(pblocktemplate->block.vtx[8]->GetHash() == hashLowFeeTx2);
210 void MinerTestingSetup::TestBasicMining(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst,
int baseheight)
228 auto pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
235 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
236 tx.
vin[0].prevout.n = 0;
238 tx.
vout[0].nValue = BLOCKSUBSIDY;
239 for (
unsigned int i = 0; i < 1001; ++i) {
240 tx.
vout[0].nValue -= LOWFEE;
245 tx.
vin[0].prevout.hash = hash;
248 BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"bad-blk-sigops"));
255 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
256 tx.
vout[0].nValue = BLOCKSUBSIDY;
257 for (
unsigned int i = 0; i < 1001; ++i) {
258 tx.
vout[0].nValue -= LOWFEE;
263 tx.
vin[0].prevout.hash = hash;
265 BOOST_CHECK(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
275 std::vector<unsigned char> vchData(520);
276 for (
unsigned int i = 0; i < 18; ++i) {
280 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
281 tx.
vout[0].nValue = BLOCKSUBSIDY;
282 for (
unsigned int i = 0; i < 128; ++i) {
283 tx.
vout[0].nValue -= LOWFEE;
287 tx.
vin[0].prevout.hash = hash;
289 BOOST_CHECK(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
298 tx_mempool.addUnchecked(entry.
Fee(LOWFEE).
Time(Now<NodeSeconds>()).
FromTx(tx));
299 BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
308 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
309 tx.
vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
312 tx.
vin[0].prevout.hash = hash;
315 tx.
vin[1].prevout.hash = txFirst[0]->GetHash();
316 tx.
vin[1].prevout.n = 0;
317 tx.
vout[0].nValue = tx.
vout[0].nValue + BLOCKSUBSIDY - HIGHERFEE;
320 BOOST_CHECK(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
329 tx.
vin[0].prevout.SetNull();
331 tx.
vout[0].nValue = 0;
336 BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"bad-cb-multiple"));
344 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
346 tx.
vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
353 BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
373 BOOST_CHECK(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
385 BOOST_CHECK(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
388 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
389 tx.
vin[0].prevout.n = 0;
391 tx.
vout[0].nValue = BLOCKSUBSIDY - LOWFEE;
396 tx.
vin[0].prevout.hash = hash;
397 tx.
vin[0].scriptSig =
CScript() << std::vector<unsigned char>(script.
begin(), script.
end());
398 tx.
vout[0].nValue -= LOWFEE;
402 BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"block-validation-failed"));
421 std::vector<int> prevheights;
426 prevheights.resize(1);
427 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
428 tx.
vin[0].prevout.n = 0;
431 prevheights[0] = baseheight + 1;
433 tx.
vout[0].nValue = BLOCKSUBSIDY-HIGHFEE;
447 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
449 prevheights[0] = baseheight + 2;
451 tx_mempool.addUnchecked(entry.
Time(Now<NodeSeconds>()).FromTx(tx));
455 const int SEQUENCE_LOCK_TIME = 512;
465 ancestor->nTime -= SEQUENCE_LOCK_TIME;
469 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
471 prevheights[0] = baseheight + 3;
474 tx_mempool.addUnchecked(entry.
Time(Now<NodeSeconds>()).
FromTx(tx));
480 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
482 prevheights.resize(1);
483 prevheights[0] = baseheight + 4;
485 tx_mempool.addUnchecked(entry.
Time(Now<NodeSeconds>()).
FromTx(tx));
491 tx.
vin[0].prevout.hash = hash;
492 prevheights[0] =
m_node.
chainman->ActiveChain().Tip()->nHeight + 1;
494 tx.
vin[0].nSequence = 0;
497 tx.
vin[0].nSequence = 1;
504 auto pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
515 ancestor->nTime += SEQUENCE_LOCK_TIME;
520 BOOST_CHECK(pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
524 void MinerTestingSetup::TestPrioritisedMining(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst)
534 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
535 tx.
vin[0].prevout.n = 0;
538 tx.
vout[0].nValue = 5000000000LL;
541 tx_mempool.PrioritiseTransaction(hashFreePrioritisedTx, 5 *
COIN);
543 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
544 tx.
vin[0].prevout.n = 0;
545 tx.
vout[0].nValue = 5000000000LL - 1000;
551 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
552 tx.
vout[0].nValue = 5000000000LL - 10000;
555 tx_mempool.PrioritiseTransaction(hashMediumFeeTx, -5 *
COIN);
558 tx.
vin[0].prevout.hash = hashParentTx;
559 tx.
vout[0].nValue = 5000000000LL - 1000 - 1000;
562 tx_mempool.PrioritiseTransaction(hashPrioritsedChild, 2 *
COIN);
570 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
571 tx.
vout[0].nValue = 5000000000LL;
574 tx_mempool.PrioritiseTransaction(hashFreeParent, 10 *
COIN);
576 tx.
vin[0].prevout.hash = hashFreeParent;
577 tx.
vout[0].nValue = 5000000000LL;
580 tx_mempool.PrioritiseTransaction(hashFreeChild, 1 *
COIN);
582 tx.
vin[0].prevout.hash = hashFreeChild;
583 tx.
vout[0].nValue = 5000000000LL;
587 auto pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
588 BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 6U);
589 BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashFreeParent);
590 BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashFreePrioritisedTx);
591 BOOST_CHECK(pblocktemplate->block.vtx[3]->GetHash() == hashParentTx);
592 BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashPrioritsedChild);
593 BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashFreeChild);
594 for (
size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
596 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeGrandchild);
598 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashMediumFeeTx);
606 CScript scriptPubKey =
CScript() <<
ParseHex(
"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") <<
OP_CHECKSIG;
607 std::unique_ptr<CBlockTemplate> pblocktemplate;
611 BOOST_CHECK(pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
615 static_assert(std::size(
BLOCKINFO) == 110,
"Should have 110 blocks to import");
617 std::vector<CTransactionRef> txFirst;
619 CBlock *pblock = &pblocktemplate->block;
627 txCoinbase.
vout.resize(1);
630 if (txFirst.size() == 0)
632 if (txFirst.size() < 4)
633 txFirst.push_back(pblock->
vtx[0]);
635 pblock->
nNonce = bi.nonce;
637 std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock);
644 TestBasicMining(scriptPubKey, txFirst, baseheight);
649 TestPackageSelection(scriptPubKey, txFirst);
654 TestPrioritisedMining(scriptPubKey, txFirst);
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
int64_t CAmount
Amount in satoshis (Can be negative)
static constexpr CAmount COIN
The amount of satoshis in one BTC.
#define Assert(val)
Identity function.
std::vector< CTransactionRef > vtx
The block chain is a tree shaped structure starting with the genesis block at the root,...
CBlockIndex * pprev
pointer to the index of the predecessor of this block
void BuildSkip()
Build the skiplist pointer for this entry.
uint256 GetBlockHash() const
int nHeight
height of the entry in the chain. The genesis block has height 0
static constexpr int nMedianTimeSpan
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
CCoinsView that brings transactions from a mempool into view.
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
CAmount GetFee(uint32_t num_bytes) const
Return the fee in satoshis for the given vsize in vbytes.
Serialized script, used inside transaction inputs and outputs.
The basic transaction that is broadcasted on the network and contained in blocks.
static const uint32_t MAX_SEQUENCE_NONFINAL
This is the maximum sequence number that enables both nLockTime and OP_CHECKLOCKTIMEVERIFY (BIP 65).
static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG
If CTxIn::nSequence encodes a relative lock-time and this flag is set, the relative lock-time has uni...
static const int SEQUENCE_LOCKTIME_GRANULARITY
In order to use the same number of bits to encode roughly the same wall-clock duration,...
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
BOOST_CHECK_EXCEPTION predicates to check the specific validation error.
Generate a new block, without valid proof-of-work.
static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE
Flags for nSequence and nLockTime locks.
static const unsigned int MAX_BLOCK_WEIGHT
The maximum allowed weight for a block, see BIP 141 (network rule)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
BOOST_AUTO_TEST_SUITE_END()
@ REPLACED
Removed for replacement.
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
static std::unique_ptr< CBlockIndex > CreateBlockIndex(int nHeight, CBlockIndex *active_chain_tip) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
constexpr static struct @13 BLOCKINFO[]
static CFeeRate blockMinFeeRate
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
static constexpr unsigned int DEFAULT_BLOCK_MIN_TX_FEE
Default for -blockmintxfee, which sets the minimum feerate for a transaction in blocks created by min...
static constexpr TransactionSerParams TX_WITH_WITNESS
static CTransactionRef MakeTransactionRef(Tx &&txIn)
size_t GetSerializeSize(const T &t)
static constexpr CAmount CENT
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
A mutable version of CTransaction.
std::vector< CTxOut > vout
Txid GetHash() const
Compute the hash of this CMutableTransaction.
TestMemPoolEntryHelper & SpendsCoinbase(bool _flag)
TestMemPoolEntryHelper & SigOpsCost(unsigned int _sigopsCost)
CTxMemPoolEntry FromTx(const CMutableTransaction &tx) const
TestMemPoolEntryHelper & Time(NodeSeconds tp)
TestMemPoolEntryHelper & Fee(CAmount _fee)
Testing setup that configures a complete environment.
BlockAssembler AssemblerForTest(CTxMemPool &tx_mempool)
void TestPackageSelection(const CScript &scriptPubKey, const std::vector< CTransactionRef > &txFirst) EXCLUSIVE_LOCKS_REQUIRED(void TestBasicMining(const CScript &scriptPubKey, const std::vector< CTransactionRef > &txFirst, int baseheight) EXCLUSIVE_LOCKS_REQUIRED(void TestPrioritisedMining(const CScript &scriptPubKey, const std::vector< CTransactionRef > &txFirst) EXCLUSIVE_LOCKS_REQUIRED(bool TestSequenceLocks(const CTransaction &tx, CTxMemPool &tx_mempool) EXCLUSIVE_LOCKS_REQUIRED(
CTxMemPool & MakeMempool()
std::unique_ptr< CTxMemPool > mempool
std::unique_ptr< ChainstateManager > chainman
static uint256 InsecureRand256()
CTxMemPool::Options MemPoolOptionsForTest(const NodeContext &node)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
bool SequenceLocks(const CTransaction &tx, int flags, std::vector< int > &prevHeights, const CBlockIndex &block)
Check if transaction is final per BIP 68 sequence numbers and can be included in a block.
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
Check if transaction is final and can be included in a block with the specified height and time.
bool CheckFinalTxAtTip(const CBlockIndex &active_chain_tip, const CTransaction &tx)
bool CheckSequenceLocksAtTip(CBlockIndex *tip, const LockPoints &lock_points)
Check if transaction will be BIP68 final in the next block to be created on top of tip.
bool CheckFinalTxAtTip(const CBlockIndex &active_chain_tip, const CTransaction &tx) EXCLUSIVE_LOCKS_REQUIRED(std::optional< LockPoints > CalculateLockPointsAtTip(CBlockIndex *tip, const CCoinsView &coins_view, const CTransaction &tx)
Check if transaction will be final in the next block to be created.
static const int32_t VERSIONBITS_TOP_BITS
What bits to set in version for versionbits blocks.