24 #include <validation.h> 32 #include <boost/test/unit_test.hpp> 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)
111 BlockAssembler::Options options;
112 options.coinbase_output_script = scriptPubKey;
123 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
124 tx.
vin[0].prevout.n = 0;
126 tx.
vout[0].nValue = 5000000000LL - 1000;
133 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
134 tx.
vout[0].nValue = 5000000000LL - 10000;
140 tx.
vin[0].prevout.hash = hashParentTx;
141 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000;
146 std::unique_ptr<BlockTemplate> block_template = mining->createNewBlock(options);
147 BOOST_REQUIRE(block_template);
148 CBlock block{block_template->getBlock()};
149 BOOST_REQUIRE_EQUAL(block.vtx.size(), 4U);
150 BOOST_CHECK(block.vtx[1]->GetHash() == hashParentTx);
151 BOOST_CHECK(block.vtx[2]->GetHash() == hashHighFeeTx);
152 BOOST_CHECK(block.vtx[3]->GetHash() == hashMediumFeeTx);
155 const auto block_package_feerates =
BlockAssembler{
m_node.
chainman->ActiveChainstate(), &tx_mempool, options}.CreateNewBlock()->m_package_feerates;
159 const auto combined_txs_fee = parent_tx.GetFee() + high_fee_tx.GetFee();
160 const auto combined_txs_size = parent_tx.GetTxSize() + high_fee_tx.GetTxSize();
161 FeeFrac package_feefrac{combined_txs_fee, combined_txs_size};
163 BOOST_CHECK(block_package_feerates[0] == package_feefrac);
166 FeeFrac medium_tx_feefrac{medium_fee_tx.GetFee(), medium_fee_tx.GetTxSize()};
167 BOOST_CHECK(block_package_feerates[1] == medium_tx_feefrac);
170 tx.
vin[0].prevout.hash = hashHighFeeTx;
171 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000;
180 tx.
vin[0].prevout.hash = hashFreeTx;
181 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse;
184 block_template = mining->createNewBlock(options);
185 BOOST_REQUIRE(block_template);
186 block = block_template->getBlock();
188 for (
size_t i=0; i<block.vtx.size(); ++i) {
189 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeTx);
190 BOOST_CHECK(block.vtx[i]->GetHash() != hashLowFeeTx);
197 tx.
vout[0].nValue -= 2;
200 block_template = mining->createNewBlock(options);
201 BOOST_REQUIRE(block_template);
202 block = block_template->getBlock();
203 BOOST_REQUIRE_EQUAL(block.vtx.size(), 6U);
204 BOOST_CHECK(block.vtx[4]->GetHash() == hashFreeTx);
205 BOOST_CHECK(block.vtx[5]->GetHash() == hashLowFeeTx);
210 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
212 tx.
vout[0].nValue = 5000000000LL - 100000000;
213 tx.
vout[1].nValue = 100000000;
221 tx.
vin[0].prevout.hash = hashFreeTx2;
224 tx.
vout[0].nValue = 5000000000LL - 100000000 - feeToUse;
227 block_template = mining->createNewBlock(options);
228 BOOST_REQUIRE(block_template);
229 block = block_template->getBlock();
232 for (
size_t i=0; i<block.vtx.size(); ++i) {
233 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeTx2);
234 BOOST_CHECK(block.vtx[i]->GetHash() != hashLowFeeTx2);
239 tx.
vin[0].prevout.n = 1;
240 tx.
vout[0].nValue = 100000000 - 10000;
242 block_template = mining->createNewBlock(options);
243 BOOST_REQUIRE(block_template);
244 block = block_template->getBlock();
245 BOOST_REQUIRE_EQUAL(block.vtx.size(), 9U);
246 BOOST_CHECK(block.vtx[8]->GetHash() == hashLowFeeTx2);
249 void MinerTestingSetup::TestBasicMining(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst,
int baseheight)
263 BOOST_REQUIRE(mining);
265 BlockAssembler::Options options;
266 options.coinbase_output_script = scriptPubKey;
273 auto block_template{mining->createNewBlock(options)};
274 BOOST_REQUIRE(block_template);
275 CBlock block{block_template->getBlock()};
281 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
282 tx.
vin[0].prevout.n = 0;
284 tx.
vout[0].nValue = BLOCKSUBSIDY;
285 for (
unsigned int i = 0; i < 1001; ++i) {
286 tx.
vout[0].nValue -= LOWFEE;
291 tx.
vin[0].prevout.hash = hash;
294 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-blk-sigops"));
301 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
302 tx.
vout[0].nValue = BLOCKSUBSIDY;
303 for (
unsigned int i = 0; i < 1001; ++i) {
304 tx.
vout[0].nValue -= LOWFEE;
309 tx.
vin[0].prevout.hash = hash;
311 BOOST_REQUIRE(mining->createNewBlock(options));
321 std::vector<unsigned char> vchData(520);
322 for (
unsigned int i = 0; i < 18; ++i) {
326 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
327 tx.
vout[0].nValue = BLOCKSUBSIDY;
328 for (
unsigned int i = 0; i < 128; ++i) {
329 tx.
vout[0].nValue -= LOWFEE;
333 tx.
vin[0].prevout.hash = hash;
335 BOOST_REQUIRE(mining->createNewBlock(options));
345 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
354 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
355 tx.
vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
358 tx.
vin[0].prevout.hash = hash;
361 tx.
vin[1].prevout.hash = txFirst[0]->GetHash();
362 tx.
vin[1].prevout.n = 0;
363 tx.
vout[0].nValue = tx.
vout[0].nValue + BLOCKSUBSIDY - HIGHERFEE;
366 BOOST_REQUIRE(mining->createNewBlock(options));
375 tx.
vin[0].prevout.SetNull();
377 tx.
vout[0].nValue = 0;
382 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-cb-multiple"));
390 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
392 tx.
vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
399 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
419 BOOST_REQUIRE(mining->createNewBlock(options));
431 BOOST_REQUIRE(mining->createNewBlock(options));
434 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
435 tx.
vin[0].prevout.n = 0;
437 tx.
vout[0].nValue = BLOCKSUBSIDY - LOWFEE;
442 tx.
vin[0].prevout.hash = hash;
444 tx.
vout[0].nValue -= LOWFEE;
447 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"mandatory-script-verify-flag-failed"));
466 std::vector<int> prevheights;
471 prevheights.resize(1);
472 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
473 tx.
vin[0].prevout.n = 0;
476 prevheights[0] = baseheight + 1;
478 tx.
vout[0].nValue = BLOCKSUBSIDY-HIGHFEE;
492 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
494 prevheights[0] = baseheight + 2;
500 const int SEQUENCE_LOCK_TIME = 512;
510 ancestor->nTime -= SEQUENCE_LOCK_TIME;
514 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
516 prevheights[0] = baseheight + 3;
525 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
527 prevheights.resize(1);
528 prevheights[0] = baseheight + 4;
536 tx.
vin[0].prevout.hash = hash;
537 prevheights[0] =
m_node.
chainman->ActiveChain().Tip()->nHeight + 1;
539 tx.
vin[0].nSequence = 0;
542 tx.
vin[0].nSequence = 1;
549 auto block_template = mining->createNewBlock(options);
550 BOOST_REQUIRE(block_template);
556 CBlock block{block_template->getBlock()};
561 ancestor->nTime += SEQUENCE_LOCK_TIME;
566 block_template = mining->createNewBlock(options);
567 BOOST_REQUIRE(block_template);
568 block = block_template->getBlock();
572 void MinerTestingSetup::TestPrioritisedMining(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst)
575 BOOST_REQUIRE(mining);
577 BlockAssembler::Options options;
578 options.coinbase_output_script = scriptPubKey;
588 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
589 tx.
vin[0].prevout.n = 0;
592 tx.
vout[0].nValue = 5000000000LL;
595 tx_mempool.PrioritiseTransaction(hashFreePrioritisedTx, 5 *
COIN);
597 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
598 tx.
vin[0].prevout.n = 0;
599 tx.
vout[0].nValue = 5000000000LL - 1000;
605 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
606 tx.
vout[0].nValue = 5000000000LL - 10000;
609 tx_mempool.PrioritiseTransaction(hashMediumFeeTx, -5 *
COIN);
612 tx.
vin[0].prevout.hash = hashParentTx;
613 tx.
vout[0].nValue = 5000000000LL - 1000 - 1000;
616 tx_mempool.PrioritiseTransaction(hashPrioritsedChild, 2 *
COIN);
624 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
625 tx.
vout[0].nValue = 5000000000LL;
628 tx_mempool.PrioritiseTransaction(hashFreeParent, 10 *
COIN);
630 tx.
vin[0].prevout.hash = hashFreeParent;
631 tx.
vout[0].nValue = 5000000000LL;
634 tx_mempool.PrioritiseTransaction(hashFreeChild, 1 *
COIN);
636 tx.
vin[0].prevout.hash = hashFreeChild;
637 tx.
vout[0].nValue = 5000000000LL;
641 auto block_template = mining->createNewBlock(options);
642 BOOST_REQUIRE(block_template);
643 CBlock block{block_template->getBlock()};
644 BOOST_REQUIRE_EQUAL(block.vtx.size(), 6U);
645 BOOST_CHECK(block.vtx[1]->GetHash() == hashFreeParent);
646 BOOST_CHECK(block.vtx[2]->GetHash() == hashFreePrioritisedTx);
647 BOOST_CHECK(block.vtx[3]->GetHash() == hashParentTx);
648 BOOST_CHECK(block.vtx[4]->GetHash() == hashPrioritsedChild);
649 BOOST_CHECK(block.vtx[5]->GetHash() == hashFreeChild);
650 for (
size_t i=0; i<block.vtx.size(); ++i) {
652 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeGrandchild);
654 BOOST_CHECK(block.vtx[i]->GetHash() != hashMediumFeeTx);
662 BOOST_REQUIRE(mining);
665 CScript scriptPubKey =
CScript() <<
"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"_hex <<
OP_CHECKSIG;
666 BlockAssembler::Options options;
667 options.coinbase_output_script = scriptPubKey;
668 std::unique_ptr<BlockTemplate> block_template;
672 static_assert(std::size(
BLOCKINFO) == 110,
"Should have 110 blocks to import");
674 std::vector<CTransactionRef> txFirst;
676 const int current_height{mining->getTip()->height};
679 block_template = mining->createNewBlock(options);
680 BOOST_REQUIRE(block_template);
682 CBlock block{block_template->getBlock()};
689 txCoinbase.
vin[0].scriptSig =
CScript{} << (current_height + 1) << bi.extranonce;
690 txCoinbase.
vout.resize(1);
693 if (txFirst.size() == 0)
694 baseheight = current_height;
695 if (txFirst.size() < 4)
696 txFirst.push_back(block.vtx[0]);
698 block.nNonce = bi.nonce;
700 std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
704 if (current_height % 2 == 0) {
707 BOOST_REQUIRE(block_template->submitSolution(block.nVersion, block.nTime, block.nNonce,
MakeTransactionRef(txCoinbase)));
714 BOOST_REQUIRE_EQUAL(maybe_new_tip->GetBlockHash(), block.GetHash());
717 mining->waitTipChanged(block.hashPrevBlock);
722 TestBasicMining(scriptPubKey, txFirst, baseheight);
727 TestPackageSelection(scriptPubKey, txFirst);
732 TestPrioritisedMining(scriptPubKey, txFirst);
static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE
Flags for nSequence and nLockTime locks.
Block template interface.
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)
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)
void BulkTransaction(CMutableTransaction &tx, int32_t target_weight)
std::unique_ptr< CTxMemPool > mempool
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.
static constexpr struct @14 BLOCKINFO[]
Interface giving clients (RPC, Stratum v2 Template Provider in the future) ability to create block te...
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
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.
""_hex is a compile-time user-defined literal returning a std::array<std::byte>, equivalent to ParseH...
Txid GetHash() const
Compute the hash of this CMutableTransaction.
AddToMempool(pool, CTxMemPoolEntry(tx, fee, nTime, nHeight, sequence, spendsCoinbase, sigOpCost, lp))
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...
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)
std::unique_ptr< Mining > MakeMining()
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Data structure storing a fee and size, ordered by increasing fee/size.
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)
std::unique_ptr< Mining > MakeMining(node::NodeContext &node)
Return implementation of Mining interface.
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