21 #include <validation.h> 28 #include <boost/test/unit_test.hpp> 60 BOOST_FIXTURE_TEST_SUITE(
miner_tests, MinerTestingSetup)
66 BlockAssembler::Options options;
73 constexpr
static struct {
76 }
BLOCKINFO[]{{8, 582909131}, {0, 971462344}, {2, 1169481553}, {6, 66147495}, {7, 427785981}, {8, 80538907},
77 {8, 207348013}, {2, 1951240923}, {4, 215054351}, {1, 491520534}, {8, 1282281282}, {4, 639565734},
78 {3, 248274685}, {8, 1160085976}, {6, 396349768}, {5, 393780549}, {5, 1096899528}, {4, 965381630},
79 {0, 728758712}, {5, 318638310}, {3, 164591898}, {2, 274234550}, {2, 254411237}, {7, 561761812},
80 {2, 268342573}, {0, 402816691}, {1, 221006382}, {6, 538872455}, {7, 393315655}, {4, 814555937},
81 {7, 504879194}, {6, 467769648}, {3, 925972193}, {2, 200581872}, {3, 168915404}, {8, 430446262},
82 {5, 773507406}, {3, 1195366164}, {0, 433361157}, {3, 297051771}, {0, 558856551}, {2, 501614039},
83 {3, 528488272}, {2, 473587734}, {8, 230125274}, {2, 494084400}, {4, 357314010}, {8, 60361686},
84 {7, 640624687}, {3, 480441695}, {8, 1424447925}, {4, 752745419}, {1, 288532283}, {6, 669170574},
85 {5, 1900907591}, {3, 555326037}, {3, 1121014051}, {0, 545835650}, {8, 189196651}, {5, 252371575},
86 {0, 199163095}, {6, 558895874}, {6, 1656839784}, {6, 815175452}, {6, 718677851}, {5, 544000334},
87 {0, 340113484}, {6, 850744437}, {4, 496721063}, {8, 524715182}, {6, 574361898}, {6, 1642305743},
88 {6, 355110149}, {5, 1647379658}, {8, 1103005356}, {7, 556460625}, {3, 1139533992}, {5, 304736030},
89 {2, 361539446}, {2, 143720360}, {6, 201939025}, {7, 423141476}, {4, 574633709}, {3, 1412254823},
90 {4, 873254135}, {0, 341817335}, {6, 53501687}, {3, 179755410}, {5, 172209688}, {8, 516810279},
91 {4, 1228391489}, {8, 325372589}, {6, 550367589}, {0, 876291812}, {7, 412454120}, {7, 717202854},
92 {2, 222677843}, {6, 251778867}, {7, 842004420}, {7, 194762829}, {4, 96668841}, {1, 925485796},
93 {0, 792342903}, {6, 678455063}, {6, 773251385}, {5, 186617471}, {6, 883189502}, {7, 396077336},
94 {8, 254702874}, {0, 455592851}};
98 auto index{std::make_unique<CBlockIndex>()};
100 index->pprev = active_chain_tip;
107 void MinerTestingSetup::TestPackageSelection(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst)
119 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
120 tx.
vin[0].prevout.n = 0;
122 tx.
vout[0].nValue = 5000000000LL - 1000;
128 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
129 tx.
vout[0].nValue = 5000000000LL - 10000;
134 tx.
vin[0].prevout.hash = hashParentTx;
135 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000;
139 std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
140 BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 4U);
141 BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashParentTx);
142 BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashHighFeeTx);
143 BOOST_CHECK(pblocktemplate->block.vtx[3]->GetHash() == hashMediumFeeTx);
146 tx.
vin[0].prevout.hash = hashHighFeeTx;
147 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000;
149 tx_mempool.addUnchecked(entry.
Fee(0).
FromTx(tx));
156 tx.
vin[0].prevout.hash = hashFreeTx;
157 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse;
159 tx_mempool.addUnchecked(entry.
Fee(feeToUse).
FromTx(tx));
160 pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
162 for (
size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
163 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeTx);
164 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashLowFeeTx);
171 tx.
vout[0].nValue -= 2;
173 tx_mempool.addUnchecked(entry.
Fee(feeToUse + 2).
FromTx(tx));
174 pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
175 BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 6U);
176 BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashFreeTx);
177 BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashLowFeeTx);
182 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
184 tx.
vout[0].nValue = 5000000000LL - 100000000;
185 tx.
vout[1].nValue = 100000000;
190 tx.
vin[0].prevout.hash = hashFreeTx2;
193 tx.
vout[0].nValue = 5000000000LL - 100000000 - feeToUse;
196 pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
199 for (
size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
200 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeTx2);
201 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashLowFeeTx2);
206 tx.
vin[0].prevout.n = 1;
207 tx.
vout[0].nValue = 100000000 - 10000;
208 tx_mempool.addUnchecked(entry.
Fee(10000).
FromTx(tx));
209 pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
210 BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 9U);
211 BOOST_CHECK(pblocktemplate->block.vtx[8]->GetHash() == hashLowFeeTx2);
214 void MinerTestingSetup::TestBasicMining(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst,
int baseheight)
232 auto pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
239 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
240 tx.
vin[0].prevout.n = 0;
242 tx.
vout[0].nValue = BLOCKSUBSIDY;
243 for (
unsigned int i = 0; i < 1001; ++i) {
244 tx.
vout[0].nValue -= LOWFEE;
249 tx.
vin[0].prevout.hash = hash;
252 BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"bad-blk-sigops"));
259 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
260 tx.
vout[0].nValue = BLOCKSUBSIDY;
261 for (
unsigned int i = 0; i < 1001; ++i) {
262 tx.
vout[0].nValue -= LOWFEE;
267 tx.
vin[0].prevout.hash = hash;
269 BOOST_CHECK(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
279 std::vector<unsigned char> vchData(520);
280 for (
unsigned int i = 0; i < 18; ++i) {
284 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
285 tx.
vout[0].nValue = BLOCKSUBSIDY;
286 for (
unsigned int i = 0; i < 128; ++i) {
287 tx.
vout[0].nValue -= LOWFEE;
291 tx.
vin[0].prevout.hash = hash;
293 BOOST_CHECK(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
302 tx_mempool.addUnchecked(entry.
Fee(LOWFEE).
Time(Now<NodeSeconds>()).
FromTx(tx));
303 BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
312 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
313 tx.
vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
316 tx.
vin[0].prevout.hash = hash;
319 tx.
vin[1].prevout.hash = txFirst[0]->GetHash();
320 tx.
vin[1].prevout.n = 0;
321 tx.
vout[0].nValue = tx.
vout[0].nValue + BLOCKSUBSIDY - HIGHERFEE;
324 BOOST_CHECK(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
333 tx.
vin[0].prevout.SetNull();
335 tx.
vout[0].nValue = 0;
340 BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"bad-cb-multiple"));
348 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
350 tx.
vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
357 BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
377 BOOST_CHECK(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
389 BOOST_CHECK(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
392 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
393 tx.
vin[0].prevout.n = 0;
395 tx.
vout[0].nValue = BLOCKSUBSIDY - LOWFEE;
400 tx.
vin[0].prevout.hash = hash;
402 tx.
vout[0].nValue -= LOWFEE;
406 BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"block-validation-failed"));
425 std::vector<int> prevheights;
430 prevheights.resize(1);
431 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
432 tx.
vin[0].prevout.n = 0;
435 prevheights[0] = baseheight + 1;
437 tx.
vout[0].nValue = BLOCKSUBSIDY-HIGHFEE;
451 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
453 prevheights[0] = baseheight + 2;
455 tx_mempool.addUnchecked(entry.
Time(Now<NodeSeconds>()).
FromTx(tx));
459 const int SEQUENCE_LOCK_TIME = 512;
469 ancestor->nTime -= SEQUENCE_LOCK_TIME;
473 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
475 prevheights[0] = baseheight + 3;
478 tx_mempool.addUnchecked(entry.
Time(Now<NodeSeconds>()).
FromTx(tx));
484 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
486 prevheights.resize(1);
487 prevheights[0] = baseheight + 4;
489 tx_mempool.addUnchecked(entry.
Time(Now<NodeSeconds>()).
FromTx(tx));
495 tx.
vin[0].prevout.hash = hash;
496 prevheights[0] =
m_node.
chainman->ActiveChain().Tip()->nHeight + 1;
498 tx.
vin[0].nSequence = 0;
501 tx.
vin[0].nSequence = 1;
508 auto pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
519 ancestor->nTime += SEQUENCE_LOCK_TIME;
524 BOOST_CHECK(pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
528 void MinerTestingSetup::TestPrioritisedMining(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst)
538 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
539 tx.
vin[0].prevout.n = 0;
542 tx.
vout[0].nValue = 5000000000LL;
545 tx_mempool.PrioritiseTransaction(hashFreePrioritisedTx, 5 *
COIN);
547 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
548 tx.
vin[0].prevout.n = 0;
549 tx.
vout[0].nValue = 5000000000LL - 1000;
555 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
556 tx.
vout[0].nValue = 5000000000LL - 10000;
559 tx_mempool.PrioritiseTransaction(hashMediumFeeTx, -5 *
COIN);
562 tx.
vin[0].prevout.hash = hashParentTx;
563 tx.
vout[0].nValue = 5000000000LL - 1000 - 1000;
566 tx_mempool.PrioritiseTransaction(hashPrioritsedChild, 2 *
COIN);
574 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
575 tx.
vout[0].nValue = 5000000000LL;
578 tx_mempool.PrioritiseTransaction(hashFreeParent, 10 *
COIN);
580 tx.
vin[0].prevout.hash = hashFreeParent;
581 tx.
vout[0].nValue = 5000000000LL;
584 tx_mempool.PrioritiseTransaction(hashFreeChild, 1 *
COIN);
586 tx.
vin[0].prevout.hash = hashFreeChild;
587 tx.
vout[0].nValue = 5000000000LL;
591 auto pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
592 BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 6U);
593 BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashFreeParent);
594 BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashFreePrioritisedTx);
595 BOOST_CHECK(pblocktemplate->block.vtx[3]->GetHash() == hashParentTx);
596 BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashPrioritsedChild);
597 BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashFreeChild);
598 for (
size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
600 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeGrandchild);
602 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashMediumFeeTx);
610 CScript scriptPubKey =
CScript() <<
ParseHex(
"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") <<
OP_CHECKSIG;
611 std::unique_ptr<CBlockTemplate> pblocktemplate;
615 BOOST_CHECK(pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
619 static_assert(std::size(
BLOCKINFO) == 110,
"Should have 110 blocks to import");
621 std::vector<CTransactionRef> txFirst;
623 CBlock *pblock = &pblocktemplate->block;
631 txCoinbase.
vout.resize(1);
634 if (txFirst.size() == 0)
636 if (txFirst.size() < 4)
637 txFirst.push_back(pblock->
vtx[0]);
639 pblock->
nNonce = bi.nonce;
641 std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock);
643 pblock->hashPrevBlock = pblock->GetHash();
648 TestBasicMining(scriptPubKey, txFirst, baseheight);
653 TestPackageSelection(scriptPubKey, txFirst);
658 TestPrioritisedMining(scriptPubKey, txFirst);
static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE
Flags for nSequence and nLockTime locks.
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
Generate a new block, without valid proof-of-work.
CBlockIndex * pprev
pointer to the index of the predecessor of this block
TestMemPoolEntryHelper & Fee(CAmount _fee)
BlockAssembler AssemblerForTest(CTxMemPool &tx_mempool)
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...
size_t GetSerializeSize(const T &t)
bool CheckFinalTxAtTip(const CBlockIndex &active_chain_tip, const CTransaction &tx)
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(
static CFeeRate blockMinFeeRate
static const int SEQUENCE_LOCKTIME_GRANULARITY
In order to use the same number of bits to encode roughly the same wall-clock duration, and because blocks are naturally limited to occur every 600s on average, the minimum granularity for time-based relative lock-time is fixed at 512 seconds.
CTxMemPoolEntry FromTx(const CMutableTransaction &tx) const
BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
std::unique_ptr< CTxMemPool > mempool
static const unsigned int MAX_BLOCK_WEIGHT
The maximum allowed weight for a block, see BIP 141 (network rule)
static std::unique_ptr< CBlockIndex > CreateBlockIndex(int nHeight, CBlockIndex *active_chain_tip) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
int64_t CAmount
Amount in satoshis (Can be negative)
TestMemPoolEntryHelper & SpendsCoinbase(bool _flag)
static constexpr int nMedianTimeSpan
uint256 GetBlockHash() const
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_EXCEPTION predicates to check the specific validation error.
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
void BuildSkip()
Build the skiplist pointer for this entry.
Txid GetHash() const
Compute the hash of this CMutableTransaction.
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 uint256 InsecureRand256()
std::vector< CTxOut > vout
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.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
static CTransactionRef MakeTransactionRef(Tx &&txIn)
static constexpr struct @13 BLOCKINFO[]
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::vector< CTransactionRef > vtx
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
#define BOOST_CHECK_EQUAL(v1, v2)
The block chain is a tree shaped structure starting with the genesis block at the root...
Serialized script, used inside transaction inputs and outputs.
TestMemPoolEntryHelper & Time(NodeSeconds tp)
static const int32_t VERSIONBITS_TOP_BITS
What bits to set in version for versionbits blocks.
TestMemPoolEntryHelper & SigOpsCost(unsigned int _sigopsCost)
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.
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...
A mutable version of CTransaction.
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 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...
static constexpr CAmount CENT
static const uint32_t MAX_SEQUENCE_NONFINAL
This is the maximum sequence number that enables both nLockTime and OP_CHECKLOCKTIMEVERIFY (BIP 65)...
The basic transaction that is broadcasted on the network and contained in blocks. ...
int nHeight
height of the entry in the chain. The genesis block has height 0
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
CCoinsView that brings transactions from a mempool into view.
CTxMemPool & MakeMempool()
std::unique_ptr< ChainstateManager > chainman
Testing setup that configures a complete environment.
#define Assert(val)
Identity function.
static constexpr TransactionSerParams TX_WITH_WITNESS
#define BOOST_CHECK(expr)
CTxMemPool::Options MemPoolOptionsForTest(const NodeContext &node)
static constexpr CAmount COIN
The amount of satoshis in one BTC.
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex