23#include <validation.h>
31#include <boost/test/unit_test.hpp>
72constexpr static struct {
75}
BLOCKINFO[]{{8, 582909131}, {0, 971462344}, {2, 1169481553}, {6, 66147495}, {7, 427785981}, {8, 80538907},
76 {8, 207348013}, {2, 1951240923}, {4, 215054351}, {1, 491520534}, {8, 1282281282}, {4, 639565734},
77 {3, 248274685}, {8, 1160085976}, {6, 396349768}, {5, 393780549}, {5, 1096899528}, {4, 965381630},
78 {0, 728758712}, {5, 318638310}, {3, 164591898}, {2, 274234550}, {2, 254411237}, {7, 561761812},
79 {2, 268342573}, {0, 402816691}, {1, 221006382}, {6, 538872455}, {7, 393315655}, {4, 814555937},
80 {7, 504879194}, {6, 467769648}, {3, 925972193}, {2, 200581872}, {3, 168915404}, {8, 430446262},
81 {5, 773507406}, {3, 1195366164}, {0, 433361157}, {3, 297051771}, {0, 558856551}, {2, 501614039},
82 {3, 528488272}, {2, 473587734}, {8, 230125274}, {2, 494084400}, {4, 357314010}, {8, 60361686},
83 {7, 640624687}, {3, 480441695}, {8, 1424447925}, {4, 752745419}, {1, 288532283}, {6, 669170574},
84 {5, 1900907591}, {3, 555326037}, {3, 1121014051}, {0, 545835650}, {8, 189196651}, {5, 252371575},
85 {0, 199163095}, {6, 558895874}, {6, 1656839784}, {6, 815175452}, {6, 718677851}, {5, 544000334},
86 {0, 340113484}, {6, 850744437}, {4, 496721063}, {8, 524715182}, {6, 574361898}, {6, 1642305743},
87 {6, 355110149}, {5, 1647379658}, {8, 1103005356}, {7, 556460625}, {3, 1139533992}, {5, 304736030},
88 {2, 361539446}, {2, 143720360}, {6, 201939025}, {7, 423141476}, {4, 574633709}, {3, 1412254823},
89 {4, 873254135}, {0, 341817335}, {6, 53501687}, {3, 179755410}, {5, 172209688}, {8, 516810279},
90 {4, 1228391489}, {8, 325372589}, {6, 550367589}, {0, 876291812}, {7, 412454120}, {7, 717202854},
91 {2, 222677843}, {6, 251778867}, {7, 842004420}, {7, 194762829}, {4, 96668841}, {1, 925485796},
92 {0, 792342903}, {6, 678455063}, {6, 773251385}, {5, 186617471}, {6, 883189502}, {7, 396077336},
93 {8, 254702874}, {0, 455592851}};
97 auto index{std::make_unique<CBlockIndex>()};
99 index->pprev = active_chain_tip;
106void MinerTestingSetup::TestPackageSelection(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst)
110 BlockAssembler::Options options;
111 options.coinbase_output_script = scriptPubKey;
122 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
123 tx.
vin[0].prevout.n = 0;
125 tx.
vout[0].nValue = 5000000000LL - 1000;
132 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
133 tx.
vout[0].nValue = 5000000000LL - 10000;
139 tx.
vin[0].prevout.hash = hashParentTx;
140 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000;
145 std::unique_ptr<BlockTemplate> block_template = mining->createNewBlock(options);
146 BOOST_REQUIRE(block_template);
147 CBlock block{block_template->getBlock()};
148 BOOST_REQUIRE_EQUAL(block.vtx.size(), 4U);
149 BOOST_CHECK(block.vtx[1]->GetHash() == hashParentTx);
150 BOOST_CHECK(block.vtx[2]->GetHash() == hashHighFeeTx);
151 BOOST_CHECK(block.vtx[3]->GetHash() == hashMediumFeeTx);
154 const auto block_package_feerates =
BlockAssembler{
m_node.
chainman->ActiveChainstate(), &tx_mempool, options}.CreateNewBlock()->m_package_feerates;
158 const auto combined_txs_fee = parent_tx.GetFee() + high_fee_tx.GetFee();
159 const auto combined_txs_size = parent_tx.GetTxSize() + high_fee_tx.GetTxSize();
160 FeeFrac package_feefrac{combined_txs_fee, combined_txs_size};
162 BOOST_CHECK(block_package_feerates[0] == package_feefrac);
165 FeeFrac medium_tx_feefrac{medium_fee_tx.GetFee(), medium_fee_tx.GetTxSize()};
166 BOOST_CHECK(block_package_feerates[1] == medium_tx_feefrac);
169 tx.
vin[0].prevout.hash = hashHighFeeTx;
170 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000;
179 tx.
vin[0].prevout.hash = hashFreeTx;
180 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse;
185 auto should_be_nullptr = block_template->waitNext({.timeout =
MillisecondsDouble{0}, .fee_threshold = 1});
186 BOOST_REQUIRE(should_be_nullptr ==
nullptr);
188 block = block_template->getBlock();
190 for (
size_t i=0; i<block.vtx.size(); ++i) {
191 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeTx);
192 BOOST_CHECK(block.vtx[i]->GetHash() != hashLowFeeTx);
199 tx.
vout[0].nValue -= 2;
204 block_template = block_template->waitNext({.fee_threshold = 1});
205 BOOST_REQUIRE(block_template);
206 block = block_template->getBlock();
207 BOOST_REQUIRE_EQUAL(block.vtx.size(), 6U);
208 BOOST_CHECK(block.vtx[4]->GetHash() == hashFreeTx);
209 BOOST_CHECK(block.vtx[5]->GetHash() == hashLowFeeTx);
214 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
216 tx.
vout[0].nValue = 5000000000LL - 100000000;
217 tx.
vout[1].nValue = 100000000;
222 tx.
vin[0].prevout.hash = hashFreeTx2;
225 tx.
vout[0].nValue = 5000000000LL - 100000000 - feeToUse;
228 block_template = mining->createNewBlock(options);
229 BOOST_REQUIRE(block_template);
230 block = block_template->getBlock();
233 for (
size_t i=0; i<block.vtx.size(); ++i) {
234 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeTx2);
235 BOOST_CHECK(block.vtx[i]->GetHash() != hashLowFeeTx2);
240 tx.
vin[0].prevout.n = 1;
241 tx.
vout[0].nValue = 100000000 - 10000;
243 block_template = mining->createNewBlock(options);
244 BOOST_REQUIRE(block_template);
245 block = block_template->getBlock();
246 BOOST_REQUIRE_EQUAL(block.vtx.size(), 9U);
247 BOOST_CHECK(block.vtx[8]->GetHash() == hashLowFeeTx2);
250void MinerTestingSetup::TestBasicMining(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst,
int baseheight)
264 BOOST_REQUIRE(mining);
266 BlockAssembler::Options options;
267 options.coinbase_output_script = scriptPubKey;
274 auto block_template{mining->createNewBlock(options)};
275 BOOST_REQUIRE(block_template);
276 CBlock block{block_template->getBlock()};
282 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
283 tx.
vin[0].prevout.n = 0;
285 tx.
vout[0].nValue = BLOCKSUBSIDY;
286 for (
unsigned int i = 0; i < 1001; ++i) {
287 tx.
vout[0].nValue -= LOWFEE;
292 tx.
vin[0].prevout.hash = hash;
295 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-blk-sigops"));
302 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
303 tx.
vout[0].nValue = BLOCKSUBSIDY;
304 for (
unsigned int i = 0; i < 1001; ++i) {
305 tx.
vout[0].nValue -= LOWFEE;
310 tx.
vin[0].prevout.hash = hash;
312 BOOST_REQUIRE(mining->createNewBlock(options));
322 std::vector<unsigned char> vchData(520);
323 for (
unsigned int i = 0; i < 18; ++i) {
327 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
328 tx.
vout[0].nValue = BLOCKSUBSIDY;
329 for (
unsigned int i = 0; i < 128; ++i) {
330 tx.
vout[0].nValue -= LOWFEE;
334 tx.
vin[0].prevout.hash = hash;
336 BOOST_REQUIRE(mining->createNewBlock(options));
346 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
355 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
356 tx.
vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
359 tx.
vin[0].prevout.hash = hash;
362 tx.
vin[1].prevout.hash = txFirst[0]->GetHash();
363 tx.
vin[1].prevout.n = 0;
364 tx.
vout[0].nValue = tx.
vout[0].nValue + BLOCKSUBSIDY - HIGHERFEE;
367 BOOST_REQUIRE(mining->createNewBlock(options));
376 tx.
vin[0].prevout.SetNull();
378 tx.
vout[0].nValue = 0;
383 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-cb-multiple"));
391 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
393 tx.
vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
400 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
420 BOOST_REQUIRE(mining->createNewBlock(options));
432 BOOST_REQUIRE(mining->createNewBlock(options));
435 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
436 tx.
vin[0].prevout.n = 0;
438 tx.
vout[0].nValue = BLOCKSUBSIDY - LOWFEE;
443 tx.
vin[0].prevout.hash = hash;
445 tx.
vout[0].nValue -= LOWFEE;
448 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"mandatory-script-verify-flag-failed"));
467 std::vector<int> prevheights;
472 prevheights.resize(1);
473 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
474 tx.
vin[0].prevout.n = 0;
477 prevheights[0] = baseheight + 1;
479 tx.
vout[0].nValue = BLOCKSUBSIDY-HIGHFEE;
493 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
495 prevheights[0] = baseheight + 2;
501 const int SEQUENCE_LOCK_TIME = 512;
511 ancestor->nTime -= SEQUENCE_LOCK_TIME;
515 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
517 prevheights[0] = baseheight + 3;
526 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
528 prevheights.resize(1);
529 prevheights[0] = baseheight + 4;
537 tx.
vin[0].prevout.hash = hash;
538 prevheights[0] =
m_node.
chainman->ActiveChain().Tip()->nHeight + 1;
540 tx.
vin[0].nSequence = 0;
543 tx.
vin[0].nSequence = 1;
550 auto block_template = mining->createNewBlock(options);
551 BOOST_REQUIRE(block_template);
557 CBlock block{block_template->getBlock()};
562 ancestor->nTime += SEQUENCE_LOCK_TIME;
567 block_template = mining->createNewBlock(options);
568 BOOST_REQUIRE(block_template);
569 block = block_template->getBlock();
573void MinerTestingSetup::TestPrioritisedMining(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst)
576 BOOST_REQUIRE(mining);
578 BlockAssembler::Options options;
579 options.coinbase_output_script = scriptPubKey;
589 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
590 tx.
vin[0].prevout.n = 0;
593 tx.
vout[0].nValue = 5000000000LL;
596 tx_mempool.PrioritiseTransaction(hashFreePrioritisedTx, 5 *
COIN);
598 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
599 tx.
vin[0].prevout.n = 0;
600 tx.
vout[0].nValue = 5000000000LL - 1000;
606 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
607 tx.
vout[0].nValue = 5000000000LL - 10000;
610 tx_mempool.PrioritiseTransaction(hashMediumFeeTx, -5 *
COIN);
613 tx.
vin[0].prevout.hash = hashParentTx;
614 tx.
vout[0].nValue = 5000000000LL - 1000 - 1000;
617 tx_mempool.PrioritiseTransaction(hashPrioritsedChild, 2 *
COIN);
625 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
626 tx.
vout[0].nValue = 5000000000LL;
629 tx_mempool.PrioritiseTransaction(hashFreeParent, 10 *
COIN);
631 tx.
vin[0].prevout.hash = hashFreeParent;
632 tx.
vout[0].nValue = 5000000000LL;
635 tx_mempool.PrioritiseTransaction(hashFreeChild, 1 *
COIN);
637 tx.
vin[0].prevout.hash = hashFreeChild;
638 tx.
vout[0].nValue = 5000000000LL;
642 auto block_template = mining->createNewBlock(options);
643 BOOST_REQUIRE(block_template);
644 CBlock block{block_template->getBlock()};
645 BOOST_REQUIRE_EQUAL(block.vtx.size(), 6U);
646 BOOST_CHECK(block.vtx[1]->GetHash() == hashFreeParent);
647 BOOST_CHECK(block.vtx[2]->GetHash() == hashFreePrioritisedTx);
648 BOOST_CHECK(block.vtx[3]->GetHash() == hashParentTx);
649 BOOST_CHECK(block.vtx[4]->GetHash() == hashPrioritsedChild);
650 BOOST_CHECK(block.vtx[5]->GetHash() == hashFreeChild);
651 for (
size_t i=0; i<block.vtx.size(); ++i) {
653 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeGrandchild);
655 BOOST_CHECK(block.vtx[i]->GetHash() != hashMediumFeeTx);
663 BOOST_REQUIRE(mining);
666 CScript scriptPubKey =
CScript() <<
"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"_hex <<
OP_CHECKSIG;
667 BlockAssembler::Options options;
668 options.coinbase_output_script = scriptPubKey;
669 std::unique_ptr<BlockTemplate> block_template;
673 static_assert(std::size(
BLOCKINFO) == 110,
"Should have 110 blocks to import");
675 std::vector<CTransactionRef> txFirst;
677 const int current_height{mining->getTip()->height};
684 if (current_height % 2 == 0) {
685 block_template = mining->createNewBlock(options);
686 BOOST_REQUIRE(block_template);
689 CBlock block{block_template->getBlock()};
696 txCoinbase.
vin[0].scriptSig =
CScript{} << (current_height + 1) << bi.extranonce;
697 txCoinbase.
vout.resize(1);
700 if (txFirst.size() == 0)
701 baseheight = current_height;
702 if (txFirst.size() < 4)
703 txFirst.push_back(block.vtx[0]);
705 block.nNonce = bi.nonce;
707 std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
711 if (current_height % 2 == 0) {
714 BOOST_REQUIRE(block_template->submitSolution(block.nVersion, block.nTime, block.nNonce,
MakeTransactionRef(txCoinbase)));
721 BOOST_REQUIRE_EQUAL(maybe_new_tip->GetBlockHash(), block.GetHash());
723 if (current_height % 2 == 0) {
724 block_template = block_template->waitNext();
725 BOOST_REQUIRE(block_template);
728 mining->waitTipChanged(block.hashPrevBlock);
734 TestBasicMining(scriptPubKey, txFirst, baseheight);
739 TestPackageSelection(scriptPubKey, txFirst);
744 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.
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.
Block template interface.
Interface giving clients (RPC, Stratum v2 Template Provider in the future) ability to create block te...
Generate a new block, without valid proof-of-work.
static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE
Flags for nSequence and nLockTime locks.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
AddToMempool(pool, CTxMemPoolEntry(tx, fee, nTime, nHeight, sequence, spendsCoinbase, sigOpCost, lp))
@ 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)
static constexpr struct @14 BLOCKINFO[]
static CFeeRate blockMinFeeRate
std::unique_ptr< Mining > MakeMining(node::NodeContext &node)
Return implementation of Mining interface.
""_hex is a compile-time user-defined literal returning a std::array<std::byte>, equivalent to ParseH...
#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
A mutable version of CTransaction.
std::vector< CTxOut > vout
Txid GetHash() const
Compute the hash of this CMutableTransaction.
Data structure storing a fee and size, ordered by increasing fee/size.
TestMemPoolEntryHelper & SigOpsCost(unsigned int _sigopsCost)
TestMemPoolEntryHelper & Time(NodeSeconds tp)
CTxMemPoolEntry FromTx(const CMutableTransaction &tx) const
TestMemPoolEntryHelper & SpendsCoinbase(bool _flag)
TestMemPoolEntryHelper & Fee(CAmount _fee)
Testing setup that configures a complete environment.
std::unique_ptr< Mining > MakeMining()
CTxMemPool & MakeMempool()
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(
std::unique_ptr< CTxMemPool > mempool
std::unique_ptr< ChainstateManager > chainman
CTxMemPool::Options MemPoolOptionsForTest(const NodeContext &node)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
std::chrono::duration< double, std::chrono::milliseconds::period > MillisecondsDouble
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.