20 #include <validation.h>
27 #include <boost/test/unit_test.hpp>
57 BOOST_FIXTURE_TEST_SUITE(
miner_tests, MinerTestingSetup)
63 BlockAssembler::Options options;
70 constexpr
static struct {
73 }
BLOCKINFO[]{{8, 582909131}, {0, 971462344}, {2, 1169481553}, {6, 66147495}, {7, 427785981}, {8, 80538907},
74 {8, 207348013}, {2, 1951240923}, {4, 215054351}, {1, 491520534}, {8, 1282281282}, {4, 639565734},
75 {3, 248274685}, {8, 1160085976}, {6, 396349768}, {5, 393780549}, {5, 1096899528}, {4, 965381630},
76 {0, 728758712}, {5, 318638310}, {3, 164591898}, {2, 274234550}, {2, 254411237}, {7, 561761812},
77 {2, 268342573}, {0, 402816691}, {1, 221006382}, {6, 538872455}, {7, 393315655}, {4, 814555937},
78 {7, 504879194}, {6, 467769648}, {3, 925972193}, {2, 200581872}, {3, 168915404}, {8, 430446262},
79 {5, 773507406}, {3, 1195366164}, {0, 433361157}, {3, 297051771}, {0, 558856551}, {2, 501614039},
80 {3, 528488272}, {2, 473587734}, {8, 230125274}, {2, 494084400}, {4, 357314010}, {8, 60361686},
81 {7, 640624687}, {3, 480441695}, {8, 1424447925}, {4, 752745419}, {1, 288532283}, {6, 669170574},
82 {5, 1900907591}, {3, 555326037}, {3, 1121014051}, {0, 545835650}, {8, 189196651}, {5, 252371575},
83 {0, 199163095}, {6, 558895874}, {6, 1656839784}, {6, 815175452}, {6, 718677851}, {5, 544000334},
84 {0, 340113484}, {6, 850744437}, {4, 496721063}, {8, 524715182}, {6, 574361898}, {6, 1642305743},
85 {6, 355110149}, {5, 1647379658}, {8, 1103005356}, {7, 556460625}, {3, 1139533992}, {5, 304736030},
86 {2, 361539446}, {2, 143720360}, {6, 201939025}, {7, 423141476}, {4, 574633709}, {3, 1412254823},
87 {4, 873254135}, {0, 341817335}, {6, 53501687}, {3, 179755410}, {5, 172209688}, {8, 516810279},
88 {4, 1228391489}, {8, 325372589}, {6, 550367589}, {0, 876291812}, {7, 412454120}, {7, 717202854},
89 {2, 222677843}, {6, 251778867}, {7, 842004420}, {7, 194762829}, {4, 96668841}, {1, 925485796},
90 {0, 792342903}, {6, 678455063}, {6, 773251385}, {5, 186617471}, {6, 883189502}, {7, 396077336},
91 {8, 254702874}, {0, 455592851}};
95 auto index{std::make_unique<CBlockIndex>()};
97 index->pprev = active_chain_tip;
104 void MinerTestingSetup::TestPackageSelection(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst)
116 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
117 tx.
vin[0].prevout.n = 0;
119 tx.
vout[0].nValue = 5000000000LL - 1000;
125 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
126 tx.
vout[0].nValue = 5000000000LL - 10000;
131 tx.
vin[0].prevout.hash = hashParentTx;
132 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000;
136 std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
137 BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 4U);
138 BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashParentTx);
139 BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashHighFeeTx);
140 BOOST_CHECK(pblocktemplate->block.vtx[3]->GetHash() == hashMediumFeeTx);
143 tx.
vin[0].prevout.hash = hashHighFeeTx;
144 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000;
146 tx_mempool.addUnchecked(entry.
Fee(0).
FromTx(tx));
153 tx.
vin[0].prevout.hash = hashFreeTx;
154 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse;
156 tx_mempool.addUnchecked(entry.
Fee(feeToUse).
FromTx(tx));
157 pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
159 for (
size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
160 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeTx);
161 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashLowFeeTx);
168 tx.
vout[0].nValue -= 2;
170 tx_mempool.addUnchecked(entry.
Fee(feeToUse + 2).
FromTx(tx));
171 pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
172 BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 6U);
173 BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashFreeTx);
174 BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashLowFeeTx);
179 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
181 tx.
vout[0].nValue = 5000000000LL - 100000000;
182 tx.
vout[1].nValue = 100000000;
187 tx.
vin[0].prevout.hash = hashFreeTx2;
190 tx.
vout[0].nValue = 5000000000LL - 100000000 - feeToUse;
193 pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
196 for (
size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
197 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeTx2);
198 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashLowFeeTx2);
203 tx.
vin[0].prevout.n = 1;
204 tx.
vout[0].nValue = 100000000 - 10000;
205 tx_mempool.addUnchecked(entry.
Fee(10000).
FromTx(tx));
206 pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
207 BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 9U);
208 BOOST_CHECK(pblocktemplate->block.vtx[8]->GetHash() == hashLowFeeTx2);
211 void MinerTestingSetup::TestBasicMining(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst,
int baseheight)
229 auto pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
236 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
237 tx.
vin[0].prevout.n = 0;
239 tx.
vout[0].nValue = BLOCKSUBSIDY;
240 for (
unsigned int i = 0; i < 1001; ++i) {
241 tx.
vout[0].nValue -= LOWFEE;
246 tx.
vin[0].prevout.hash = hash;
249 BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"bad-blk-sigops"));
256 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
257 tx.
vout[0].nValue = BLOCKSUBSIDY;
258 for (
unsigned int i = 0; i < 1001; ++i) {
259 tx.
vout[0].nValue -= LOWFEE;
264 tx.
vin[0].prevout.hash = hash;
266 BOOST_CHECK(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
276 std::vector<unsigned char> vchData(520);
277 for (
unsigned int i = 0; i < 18; ++i) {
281 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
282 tx.
vout[0].nValue = BLOCKSUBSIDY;
283 for (
unsigned int i = 0; i < 128; ++i) {
284 tx.
vout[0].nValue -= LOWFEE;
288 tx.
vin[0].prevout.hash = hash;
290 BOOST_CHECK(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
299 tx_mempool.addUnchecked(entry.
Fee(LOWFEE).
Time(Now<NodeSeconds>()).
FromTx(tx));
300 BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
309 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
310 tx.
vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
313 tx.
vin[0].prevout.hash = hash;
316 tx.
vin[1].prevout.hash = txFirst[0]->GetHash();
317 tx.
vin[1].prevout.n = 0;
318 tx.
vout[0].nValue = tx.
vout[0].nValue + BLOCKSUBSIDY - HIGHERFEE;
321 BOOST_CHECK(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
330 tx.
vin[0].prevout.SetNull();
332 tx.
vout[0].nValue = 0;
337 BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"bad-cb-multiple"));
345 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
347 tx.
vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
354 BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
374 BOOST_CHECK(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
386 BOOST_CHECK(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
389 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
390 tx.
vin[0].prevout.n = 0;
392 tx.
vout[0].nValue = BLOCKSUBSIDY - LOWFEE;
397 tx.
vin[0].prevout.hash = hash;
398 tx.
vin[0].scriptSig =
CScript() << std::vector<unsigned char>(script.
begin(), script.
end());
399 tx.
vout[0].nValue -= LOWFEE;
403 BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"block-validation-failed"));
422 std::vector<int> prevheights;
427 prevheights.resize(1);
428 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
429 tx.
vin[0].prevout.n = 0;
432 prevheights[0] = baseheight + 1;
434 tx.
vout[0].nValue = BLOCKSUBSIDY-HIGHFEE;
448 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
450 prevheights[0] = baseheight + 2;
452 tx_mempool.addUnchecked(entry.
Time(Now<NodeSeconds>()).FromTx(tx));
456 const int SEQUENCE_LOCK_TIME = 512;
466 ancestor->nTime -= SEQUENCE_LOCK_TIME;
470 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
472 prevheights[0] = baseheight + 3;
475 tx_mempool.addUnchecked(entry.
Time(Now<NodeSeconds>()).
FromTx(tx));
481 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
483 prevheights.resize(1);
484 prevheights[0] = baseheight + 4;
486 tx_mempool.addUnchecked(entry.
Time(Now<NodeSeconds>()).
FromTx(tx));
492 tx.
vin[0].prevout.hash = hash;
493 prevheights[0] =
m_node.
chainman->ActiveChain().Tip()->nHeight + 1;
495 tx.
vin[0].nSequence = 0;
498 tx.
vin[0].nSequence = 1;
505 auto pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
516 ancestor->nTime += SEQUENCE_LOCK_TIME;
521 BOOST_CHECK(pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
525 void MinerTestingSetup::TestPrioritisedMining(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst)
535 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
536 tx.
vin[0].prevout.n = 0;
539 tx.
vout[0].nValue = 5000000000LL;
542 tx_mempool.PrioritiseTransaction(hashFreePrioritisedTx, 5 *
COIN);
544 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
545 tx.
vin[0].prevout.n = 0;
546 tx.
vout[0].nValue = 5000000000LL - 1000;
552 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
553 tx.
vout[0].nValue = 5000000000LL - 10000;
556 tx_mempool.PrioritiseTransaction(hashMediumFeeTx, -5 *
COIN);
559 tx.
vin[0].prevout.hash = hashParentTx;
560 tx.
vout[0].nValue = 5000000000LL - 1000 - 1000;
563 tx_mempool.PrioritiseTransaction(hashPrioritsedChild, 2 *
COIN);
571 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
572 tx.
vout[0].nValue = 5000000000LL;
575 tx_mempool.PrioritiseTransaction(hashFreeParent, 10 *
COIN);
577 tx.
vin[0].prevout.hash = hashFreeParent;
578 tx.
vout[0].nValue = 5000000000LL;
581 tx_mempool.PrioritiseTransaction(hashFreeChild, 1 *
COIN);
583 tx.
vin[0].prevout.hash = hashFreeChild;
584 tx.
vout[0].nValue = 5000000000LL;
588 auto pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey);
589 BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 6U);
590 BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashFreeParent);
591 BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashFreePrioritisedTx);
592 BOOST_CHECK(pblocktemplate->block.vtx[3]->GetHash() == hashParentTx);
593 BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashPrioritsedChild);
594 BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashFreeChild);
595 for (
size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
597 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeGrandchild);
599 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashMediumFeeTx);
607 CScript scriptPubKey =
CScript() <<
ParseHex(
"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") <<
OP_CHECKSIG;
608 std::unique_ptr<CBlockTemplate> pblocktemplate;
612 BOOST_CHECK(pblocktemplate = AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey));
616 static_assert(std::size(
BLOCKINFO) == 110,
"Should have 110 blocks to import");
618 std::vector<CTransactionRef> txFirst;
620 CBlock *pblock = &pblocktemplate->block;
628 txCoinbase.
vout.resize(1);
631 if (txFirst.size() == 0)
633 if (txFirst.size() < 4)
634 txFirst.push_back(pblock->
vtx[0]);
636 pblock->
nNonce = bi.nonce;
638 std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock);
645 TestBasicMining(scriptPubKey, txFirst, baseheight);
650 TestPackageSelection(scriptPubKey, txFirst);
655 TestPrioritisedMining(scriptPubKey, txFirst);
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()
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)
static CFeeRate blockMinFeeRate
constexpr static struct @15 BLOCKINFO[]
#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 CTransactionRef MakeTransactionRef(Tx &&txIn)
size_t GetSerializeSize(const T &t, int nVersion=0)
static constexpr CAmount CENT
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
A mutable version of CTransaction.
uint256 GetHash() const
Compute the hash of this CMutableTransaction.
std::vector< CTxOut > vout
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.
@ REPLACED
Removed for replacement.
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 int PROTOCOL_VERSION
network protocol versioning
static const int32_t VERSIONBITS_TOP_BITS
What bits to set in version for versionbits blocks.