23#include <validation.h>
32#include <boost/test/unit_test.hpp>
73constexpr static struct {
76}
BLOCKINFO[]{{0, 3552706918}, {500, 37506755}, {1000, 948987788}, {400, 524762339}, {800, 258510074}, {300, 102309278},
77 {1300, 54365202}, {600, 1107740426}, {1000, 203094491}, {900, 391178848}, {800, 381177271}, {600, 87188412},
78 {0, 66522866}, {800, 874942736}, {1000, 89200838}, {400, 312638088}, {400, 66263693}, {500, 924648304},
79 {400, 369913599}, {500, 47630099}, {500, 115045364}, {100, 277026602}, {1100, 809621409}, {700, 155345322},
80 {800, 943579953}, {400, 28200730}, {900, 77200495}, {0, 105935488}, {400, 698721821}, {500, 111098863},
81 {1300, 445389594}, {500, 621849894}, {1400, 56010046}, {1100, 370669776}, {1200, 380301940}, {1200, 110654905},
82 {400, 213771024}, {1500, 120014726}, {1200, 835019014}, {1500, 624817237}, {900, 1404297}, {400, 189414558},
83 {400, 293178348}, {1100, 15393789}, {600, 396764180}, {800, 1387046371}, {800, 199368303}, {700, 111496662},
84 {100, 129759616}, {200, 536577982}, {500, 125881300}, {500, 101053391}, {1200, 471590548}, {900, 86957729},
85 {1200, 179604104}, {600, 68658642}, {1000, 203295701}, {500, 139615361}, {900, 233693412}, {300, 153225163},
86 {0, 27616254}, {1200, 9856191}, {100, 220392722}, {200, 66257599}, {1100, 145489641}, {1300, 37859442},
87 {400, 5816075}, {1200, 215752117}, {1400, 32361482}, {1400, 6529223}, {500, 143332977}, {800, 878392},
88 {700, 159290408}, {400, 123197595}, {700, 43988693}, {300, 304224916}, {700, 214771621}, {1100, 274148273},
89 {400, 285632418}, {1100, 923451065}, {600, 12818092}, {1200, 736282054}, {1000, 246683167}, {600, 92950402},
90 {1400, 29223405}, {1000, 841327192}, {700, 174301283}, {1400, 214009854}, {1000, 6989517}, {1200, 278226956},
91 {700, 540219613}, {400, 93663104}, {1100, 152345635}, {1500, 464194499}, {1300, 333850111}, {600, 258311263},
92 {600, 90173162}, {1000, 33590797}, {1500, 332866027}, {100, 204704427}, {1000, 463153545}, {800, 303244785},
93 {600, 88096214}, {0, 137477892}, {1200, 195514506}, {300, 704114595}, {900, 292087369}, {1400, 758684870},
94 {1300, 163493028}, {1200, 53151293}};
98 auto index{std::make_unique<CBlockIndex>()};
100 index->pprev = active_chain_tip;
107void 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;
186 auto should_be_nullptr = block_template->waitNext({.timeout =
MillisecondsDouble{0}, .fee_threshold = 1});
187 BOOST_REQUIRE(should_be_nullptr ==
nullptr);
189 block = block_template->getBlock();
191 for (
size_t i=0; i<block.vtx.size(); ++i) {
192 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeTx);
193 BOOST_CHECK(block.vtx[i]->GetHash() != hashLowFeeTx);
200 tx.
vout[0].nValue -= 2;
205 block_template = block_template->waitNext({.fee_threshold = 1});
206 BOOST_REQUIRE(block_template);
207 block = block_template->getBlock();
208 BOOST_REQUIRE_EQUAL(block.vtx.size(), 6U);
209 BOOST_CHECK(block.vtx[4]->GetHash() == hashFreeTx);
210 BOOST_CHECK(block.vtx[5]->GetHash() == hashLowFeeTx);
215 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
217 tx.
vout[0].nValue = 5000000000LL - 100000000;
218 tx.
vout[1].nValue = 100000000;
223 tx.
vin[0].prevout.hash = hashFreeTx2;
226 tx.
vout[0].nValue = 5000000000LL - 100000000 - feeToUse;
229 block_template = mining->createNewBlock(options);
230 BOOST_REQUIRE(block_template);
231 block = block_template->getBlock();
234 for (
size_t i=0; i<block.vtx.size(); ++i) {
235 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeTx2);
236 BOOST_CHECK(block.vtx[i]->GetHash() != hashLowFeeTx2);
241 tx.
vin[0].prevout.n = 1;
242 tx.
vout[0].nValue = 100000000 - 10000;
244 block_template = mining->createNewBlock(options);
245 BOOST_REQUIRE(block_template);
246 block = block_template->getBlock();
247 BOOST_REQUIRE_EQUAL(block.vtx.size(), 9U);
248 BOOST_CHECK(block.vtx[8]->GetHash() == hashLowFeeTx2);
251void MinerTestingSetup::TestBasicMining(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst,
int baseheight)
265 BOOST_REQUIRE(mining);
267 BlockAssembler::Options options;
268 options.coinbase_output_script = scriptPubKey;
275 auto block_template{mining->createNewBlock(options)};
276 BOOST_REQUIRE(block_template);
277 CBlock block{block_template->getBlock()};
283 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
284 tx.
vin[0].prevout.n = 0;
286 tx.
vout[0].nValue = BLOCKSUBSIDY;
287 for (
unsigned int i = 0; i < 1001; ++i) {
288 tx.
vout[0].nValue -= LOWFEE;
293 tx.
vin[0].prevout.hash = hash;
296 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-blk-sigops"));
303 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
304 tx.
vout[0].nValue = BLOCKSUBSIDY;
305 for (
unsigned int i = 0; i < 1001; ++i) {
306 tx.
vout[0].nValue -= LOWFEE;
311 tx.
vin[0].prevout.hash = hash;
313 BOOST_REQUIRE(mining->createNewBlock(options));
323 std::vector<unsigned char> vchData(520);
324 for (
unsigned int i = 0; i < 18; ++i) {
328 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
329 tx.
vout[0].nValue = BLOCKSUBSIDY;
330 for (
unsigned int i = 0; i < 128; ++i) {
331 tx.
vout[0].nValue -= LOWFEE;
335 tx.
vin[0].prevout.hash = hash;
337 BOOST_REQUIRE(mining->createNewBlock(options));
347 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
356 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
357 tx.
vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
360 tx.
vin[0].prevout.hash = hash;
363 tx.
vin[1].prevout.hash = txFirst[0]->GetHash();
364 tx.
vin[1].prevout.n = 0;
365 tx.
vout[0].nValue = tx.
vout[0].nValue + BLOCKSUBSIDY - HIGHERFEE;
368 BOOST_REQUIRE(mining->createNewBlock(options));
377 tx.
vin[0].prevout.SetNull();
379 tx.
vout[0].nValue = 0;
384 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-cb-multiple"));
392 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
394 tx.
vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
401 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
421 BOOST_REQUIRE(mining->createNewBlock(options));
433 BOOST_REQUIRE(mining->createNewBlock(options));
436 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
437 tx.
vin[0].prevout.n = 0;
439 tx.
vout[0].nValue = BLOCKSUBSIDY - LOWFEE;
444 tx.
vin[0].prevout.hash = hash;
446 tx.
vout[0].nValue -= LOWFEE;
449 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"mandatory-script-verify-flag-failed"));
468 std::vector<int> prevheights;
473 prevheights.resize(1);
474 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
475 tx.
vin[0].prevout.n = 0;
478 prevheights[0] = baseheight + 1;
480 tx.
vout[0].nValue = BLOCKSUBSIDY-HIGHFEE;
494 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
496 prevheights[0] = baseheight + 2;
502 const int SEQUENCE_LOCK_TIME = 512;
512 ancestor->nTime -= SEQUENCE_LOCK_TIME;
516 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
518 prevheights[0] = baseheight + 3;
527 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
529 prevheights.resize(1);
530 prevheights[0] = baseheight + 4;
538 tx.
vin[0].prevout.hash = hash;
539 prevheights[0] =
m_node.
chainman->ActiveChain().Tip()->nHeight + 1;
541 tx.
vin[0].nSequence = 0;
544 tx.
vin[0].nSequence = 1;
551 auto block_template = mining->createNewBlock(options);
552 BOOST_REQUIRE(block_template);
558 CBlock block{block_template->getBlock()};
563 ancestor->nTime += SEQUENCE_LOCK_TIME;
568 block_template = mining->createNewBlock(options);
569 BOOST_REQUIRE(block_template);
570 block = block_template->getBlock();
574void MinerTestingSetup::TestPrioritisedMining(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst)
577 BOOST_REQUIRE(mining);
579 BlockAssembler::Options options;
580 options.coinbase_output_script = scriptPubKey;
590 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
591 tx.
vin[0].prevout.n = 0;
594 tx.
vout[0].nValue = 5000000000LL;
597 tx_mempool.PrioritiseTransaction(hashFreePrioritisedTx, 5 *
COIN);
599 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
600 tx.
vin[0].prevout.n = 0;
601 tx.
vout[0].nValue = 5000000000LL - 1000;
607 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
608 tx.
vout[0].nValue = 5000000000LL - 10000;
611 tx_mempool.PrioritiseTransaction(hashMediumFeeTx, -5 *
COIN);
614 tx.
vin[0].prevout.hash = hashParentTx;
615 tx.
vout[0].nValue = 5000000000LL - 1000 - 1000;
618 tx_mempool.PrioritiseTransaction(hashPrioritsedChild, 2 *
COIN);
626 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
627 tx.
vout[0].nValue = 5000000000LL;
630 tx_mempool.PrioritiseTransaction(hashFreeParent, 10 *
COIN);
632 tx.
vin[0].prevout.hash = hashFreeParent;
633 tx.
vout[0].nValue = 5000000000LL;
636 tx_mempool.PrioritiseTransaction(hashFreeChild, 1 *
COIN);
638 tx.
vin[0].prevout.hash = hashFreeChild;
639 tx.
vout[0].nValue = 5000000000LL;
643 auto block_template = mining->createNewBlock(options);
644 BOOST_REQUIRE(block_template);
645 CBlock block{block_template->getBlock()};
646 BOOST_REQUIRE_EQUAL(block.vtx.size(), 6U);
647 BOOST_CHECK(block.vtx[1]->GetHash() == hashFreeParent);
648 BOOST_CHECK(block.vtx[2]->GetHash() == hashFreePrioritisedTx);
649 BOOST_CHECK(block.vtx[3]->GetHash() == hashParentTx);
650 BOOST_CHECK(block.vtx[4]->GetHash() == hashPrioritsedChild);
651 BOOST_CHECK(block.vtx[5]->GetHash() == hashFreeChild);
652 for (
size_t i=0; i<block.vtx.size(); ++i) {
654 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeGrandchild);
656 BOOST_CHECK(block.vtx[i]->GetHash() != hashMediumFeeTx);
664 BOOST_REQUIRE(mining);
667 CScript scriptPubKey =
CScript() <<
"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"_hex <<
OP_CHECKSIG;
668 BlockAssembler::Options options;
669 options.coinbase_output_script = scriptPubKey;
672 std::unique_ptr<BlockTemplate> block_template = mining->createNewBlock(options);
673 BOOST_REQUIRE(block_template);
675 CBlock block{block_template->getBlock()};
679 BOOST_REQUIRE(!mining->checkBlock(block, {.check_pow = false}, reason, debug));
680 BOOST_REQUIRE_EQUAL(reason,
"bad-txnmrklroot");
681 BOOST_REQUIRE_EQUAL(debug,
"hashMerkleRoot mismatch");
689 BOOST_REQUIRE(mining->checkBlock(block, {.check_pow = false}, reason, debug));
690 BOOST_REQUIRE_EQUAL(reason,
"");
691 BOOST_REQUIRE_EQUAL(debug,
"");
703 BOOST_REQUIRE(!mining->checkBlock(block, {.check_pow = true}, reason, debug));
704 BOOST_REQUIRE_EQUAL(reason,
"high-hash");
705 BOOST_REQUIRE_EQUAL(debug,
"proof of work failed");
711 static_assert(std::size(
BLOCKINFO) == 110,
"Should have 110 blocks to import");
713 std::vector<CTransactionRef> txFirst;
715 const int current_height{mining->getTip()->height};
722 if (current_height % 2 == 0) {
723 block_template = mining->createNewBlock(options);
724 BOOST_REQUIRE(block_template);
727 CBlock block{block_template->getBlock()};
734 txCoinbase.
vin[0].scriptSig =
CScript{} << (current_height + 1) << bi.extranonce;
735 txCoinbase.
vout.resize(1);
738 if (txFirst.size() == 0)
739 baseheight = current_height;
740 if (txFirst.size() < 4)
741 txFirst.push_back(block.vtx[0]);
743 block.nNonce = bi.nonce;
745 std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
749 if (current_height % 2 == 0) {
752 BOOST_REQUIRE(block_template->submitSolution(block.nVersion, block.nTime, block.nNonce,
MakeTransactionRef(txCoinbase)));
759 BOOST_REQUIRE_EQUAL(maybe_new_tip->GetBlockHash(), block.GetHash());
761 if (current_height % 2 == 0) {
762 block_template = block_template->waitNext();
763 BOOST_REQUIRE(block_template);
766 mining->waitTipChanged(block.hashPrevBlock);
772 TestBasicMining(scriptPubKey, txFirst, baseheight);
777 TestPackageSelection(scriptPubKey, txFirst);
782 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...
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params ¶ms)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
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(...)
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.
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
std::chrono::duration< double, std::chrono::milliseconds::period > MillisecondsDouble
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.