24#include <validation.h>
33#include <boost/test/unit_test.hpp>
74constexpr static struct {
77}
BLOCKINFO[]{{0, 3552706918}, {500, 37506755}, {1000, 948987788}, {400, 524762339}, {800, 258510074}, {300, 102309278},
78 {1300, 54365202}, {600, 1107740426}, {1000, 203094491}, {900, 391178848}, {800, 381177271}, {600, 87188412},
79 {0, 66522866}, {800, 874942736}, {1000, 89200838}, {400, 312638088}, {400, 66263693}, {500, 924648304},
80 {400, 369913599}, {500, 47630099}, {500, 115045364}, {100, 277026602}, {1100, 809621409}, {700, 155345322},
81 {800, 943579953}, {400, 28200730}, {900, 77200495}, {0, 105935488}, {400, 698721821}, {500, 111098863},
82 {1300, 445389594}, {500, 621849894}, {1400, 56010046}, {1100, 370669776}, {1200, 380301940}, {1200, 110654905},
83 {400, 213771024}, {1500, 120014726}, {1200, 835019014}, {1500, 624817237}, {900, 1404297}, {400, 189414558},
84 {400, 293178348}, {1100, 15393789}, {600, 396764180}, {800, 1387046371}, {800, 199368303}, {700, 111496662},
85 {100, 129759616}, {200, 536577982}, {500, 125881300}, {500, 101053391}, {1200, 471590548}, {900, 86957729},
86 {1200, 179604104}, {600, 68658642}, {1000, 203295701}, {500, 139615361}, {900, 233693412}, {300, 153225163},
87 {0, 27616254}, {1200, 9856191}, {100, 220392722}, {200, 66257599}, {1100, 145489641}, {1300, 37859442},
88 {400, 5816075}, {1200, 215752117}, {1400, 32361482}, {1400, 6529223}, {500, 143332977}, {800, 878392},
89 {700, 159290408}, {400, 123197595}, {700, 43988693}, {300, 304224916}, {700, 214771621}, {1100, 274148273},
90 {400, 285632418}, {1100, 923451065}, {600, 12818092}, {1200, 736282054}, {1000, 246683167}, {600, 92950402},
91 {1400, 29223405}, {1000, 841327192}, {700, 174301283}, {1400, 214009854}, {1000, 6989517}, {1200, 278226956},
92 {700, 540219613}, {400, 93663104}, {1100, 152345635}, {1500, 464194499}, {1300, 333850111}, {600, 258311263},
93 {600, 90173162}, {1000, 33590797}, {1500, 332866027}, {100, 204704427}, {1000, 463153545}, {800, 303244785},
94 {600, 88096214}, {0, 137477892}, {1200, 195514506}, {300, 704114595}, {900, 292087369}, {1400, 758684870},
95 {1300, 163493028}, {1200, 53151293}};
99 auto index{std::make_unique<CBlockIndex>()};
101 index->pprev = active_chain_tip;
108void MinerTestingSetup::TestPackageSelection(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst)
112 BlockAssembler::Options options;
113 options.coinbase_output_script = scriptPubKey;
124 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
125 tx.
vin[0].prevout.n = 0;
127 tx.
vout[0].nValue = 5000000000LL - 1000;
134 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
135 tx.
vout[0].nValue = 5000000000LL - 10000;
141 tx.
vin[0].prevout.hash = hashParentTx;
142 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000;
147 std::unique_ptr<BlockTemplate> block_template = mining->createNewBlock(options);
148 BOOST_REQUIRE(block_template);
149 CBlock block{block_template->getBlock()};
150 BOOST_REQUIRE_EQUAL(block.vtx.size(), 4U);
151 BOOST_CHECK(block.vtx[1]->GetHash() == hashParentTx);
152 BOOST_CHECK(block.vtx[2]->GetHash() == hashHighFeeTx);
153 BOOST_CHECK(block.vtx[3]->GetHash() == hashMediumFeeTx);
156 const auto block_package_feerates =
BlockAssembler{
m_node.
chainman->ActiveChainstate(), &tx_mempool, options}.CreateNewBlock()->m_package_feerates;
160 const auto combined_txs_fee = parent_tx.GetFee() + high_fee_tx.GetFee();
161 const auto combined_txs_size = parent_tx.GetTxSize() + high_fee_tx.GetTxSize();
162 FeeFrac package_feefrac{combined_txs_fee, combined_txs_size};
164 BOOST_CHECK(block_package_feerates[0] == package_feefrac);
167 FeeFrac medium_tx_feefrac{medium_fee_tx.GetFee(), medium_fee_tx.GetTxSize()};
168 BOOST_CHECK(block_package_feerates[1] == medium_tx_feefrac);
171 tx.
vin[0].prevout.hash = hashHighFeeTx;
172 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000;
181 tx.
vin[0].prevout.hash = hashFreeTx;
182 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse;
187 auto should_be_nullptr = block_template->waitNext({.timeout =
MillisecondsDouble{0}, .fee_threshold = 1});
188 BOOST_REQUIRE(should_be_nullptr ==
nullptr);
190 block = block_template->getBlock();
192 for (
size_t i=0; i<block.vtx.size(); ++i) {
193 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeTx);
194 BOOST_CHECK(block.vtx[i]->GetHash() != hashLowFeeTx);
201 tx.
vout[0].nValue -= 2;
206 block_template = block_template->waitNext({.fee_threshold = 1});
207 BOOST_REQUIRE(block_template);
208 block = block_template->getBlock();
209 BOOST_REQUIRE_EQUAL(block.vtx.size(), 6U);
210 BOOST_CHECK(block.vtx[4]->GetHash() == hashFreeTx);
211 BOOST_CHECK(block.vtx[5]->GetHash() == hashLowFeeTx);
216 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
218 tx.
vout[0].nValue = 5000000000LL - 100000000;
219 tx.
vout[1].nValue = 100000000;
228 tx.
vin[0].prevout.hash = hashFreeTx2;
231 tx.
vout[0].nValue = 5000000000LL - 100000000 - feeToUse;
234 block_template = mining->createNewBlock(options);
235 BOOST_REQUIRE(block_template);
236 block = block_template->getBlock();
239 for (
size_t i=0; i<block.vtx.size(); ++i) {
240 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeTx2);
241 BOOST_CHECK(block.vtx[i]->GetHash() != hashLowFeeTx2);
246 tx.
vin[0].prevout.n = 1;
247 tx.
vout[0].nValue = 100000000 - 10000;
249 block_template = mining->createNewBlock(options);
250 BOOST_REQUIRE(block_template);
251 block = block_template->getBlock();
252 BOOST_REQUIRE_EQUAL(block.vtx.size(), 9U);
253 BOOST_CHECK(block.vtx[8]->GetHash() == hashLowFeeTx2);
256void MinerTestingSetup::TestBasicMining(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst,
int baseheight)
270 BOOST_REQUIRE(mining);
272 BlockAssembler::Options options;
273 options.coinbase_output_script = scriptPubKey;
280 auto block_template{mining->createNewBlock(options)};
281 BOOST_REQUIRE(block_template);
282 CBlock block{block_template->getBlock()};
288 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
289 tx.
vin[0].prevout.n = 0;
291 tx.
vout[0].nValue = BLOCKSUBSIDY;
292 for (
unsigned int i = 0; i < 1001; ++i) {
293 tx.
vout[0].nValue -= LOWFEE;
298 tx.
vin[0].prevout.hash = hash;
301 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-blk-sigops"));
308 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
309 tx.
vout[0].nValue = BLOCKSUBSIDY;
310 for (
unsigned int i = 0; i < 1001; ++i) {
311 tx.
vout[0].nValue -= LOWFEE;
316 tx.
vin[0].prevout.hash = hash;
318 BOOST_REQUIRE(mining->createNewBlock(options));
328 std::vector<unsigned char> vchData(520);
329 for (
unsigned int i = 0; i < 18; ++i) {
333 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
334 tx.
vout[0].nValue = BLOCKSUBSIDY;
335 for (
unsigned int i = 0; i < 128; ++i) {
336 tx.
vout[0].nValue -= LOWFEE;
340 tx.
vin[0].prevout.hash = hash;
342 BOOST_REQUIRE(mining->createNewBlock(options));
352 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
361 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
362 tx.
vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
365 tx.
vin[0].prevout.hash = hash;
368 tx.
vin[1].prevout.hash = txFirst[0]->GetHash();
369 tx.
vin[1].prevout.n = 0;
370 tx.
vout[0].nValue = tx.
vout[0].nValue + BLOCKSUBSIDY - HIGHERFEE;
373 BOOST_REQUIRE(mining->createNewBlock(options));
382 tx.
vin[0].prevout.SetNull();
384 tx.
vout[0].nValue = 0;
389 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-cb-multiple"));
397 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
399 tx.
vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
406 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
426 BOOST_REQUIRE(mining->createNewBlock(options));
438 BOOST_REQUIRE(mining->createNewBlock(options));
441 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
442 tx.
vin[0].prevout.n = 0;
444 tx.
vout[0].nValue = BLOCKSUBSIDY - LOWFEE;
449 tx.
vin[0].prevout.hash = hash;
451 tx.
vout[0].nValue -= LOWFEE;
454 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"block-script-verify-flag-failed"));
473 std::vector<int> prevheights;
478 prevheights.resize(1);
479 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
480 tx.
vin[0].prevout.n = 0;
483 prevheights[0] = baseheight + 1;
485 tx.
vout[0].nValue = BLOCKSUBSIDY-HIGHFEE;
499 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
501 prevheights[0] = baseheight + 2;
507 const int SEQUENCE_LOCK_TIME = 512;
517 ancestor->nTime -= SEQUENCE_LOCK_TIME;
521 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
523 prevheights[0] = baseheight + 3;
536 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
538 prevheights.resize(1);
539 prevheights[0] = baseheight + 4;
547 tx.
vin[0].prevout.hash = hash;
548 prevheights[0] =
m_node.
chainman->ActiveChain().Tip()->nHeight + 1;
550 tx.
vin[0].nSequence = 0;
553 tx.
vin[0].nSequence = 1;
560 auto block_template = mining->createNewBlock(options);
561 BOOST_REQUIRE(block_template);
567 CBlock block{block_template->getBlock()};
572 ancestor->nTime += SEQUENCE_LOCK_TIME;
577 block_template = mining->createNewBlock(options);
578 BOOST_REQUIRE(block_template);
579 block = block_template->getBlock();
583void MinerTestingSetup::TestPrioritisedMining(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst)
586 BOOST_REQUIRE(mining);
588 BlockAssembler::Options options;
589 options.coinbase_output_script = scriptPubKey;
599 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
600 tx.
vin[0].prevout.n = 0;
603 tx.
vout[0].nValue = 5000000000LL;
606 tx_mempool.PrioritiseTransaction(hashFreePrioritisedTx, 5 *
COIN);
608 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
609 tx.
vin[0].prevout.n = 0;
610 tx.
vout[0].nValue = 5000000000LL - 1000;
616 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
617 tx.
vout[0].nValue = 5000000000LL - 10000;
620 tx_mempool.PrioritiseTransaction(hashMediumFeeTx, -5 *
COIN);
623 tx.
vin[0].prevout.hash = hashParentTx;
624 tx.
vout[0].nValue = 5000000000LL - 1000 - 1000;
627 tx_mempool.PrioritiseTransaction(hashPrioritsedChild, 2 *
COIN);
635 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
636 tx.
vout[0].nValue = 5000000000LL;
639 tx_mempool.PrioritiseTransaction(hashFreeParent, 10 *
COIN);
641 tx.
vin[0].prevout.hash = hashFreeParent;
642 tx.
vout[0].nValue = 5000000000LL;
645 tx_mempool.PrioritiseTransaction(hashFreeChild, 1 *
COIN);
647 tx.
vin[0].prevout.hash = hashFreeChild;
648 tx.
vout[0].nValue = 5000000000LL;
652 auto block_template = mining->createNewBlock(options);
653 BOOST_REQUIRE(block_template);
654 CBlock block{block_template->getBlock()};
655 BOOST_REQUIRE_EQUAL(block.vtx.size(), 6U);
656 BOOST_CHECK(block.vtx[1]->GetHash() == hashFreeParent);
657 BOOST_CHECK(block.vtx[2]->GetHash() == hashFreePrioritisedTx);
658 BOOST_CHECK(block.vtx[3]->GetHash() == hashParentTx);
659 BOOST_CHECK(block.vtx[4]->GetHash() == hashPrioritsedChild);
660 BOOST_CHECK(block.vtx[5]->GetHash() == hashFreeChild);
661 for (
size_t i=0; i<block.vtx.size(); ++i) {
663 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeGrandchild);
665 BOOST_CHECK(block.vtx[i]->GetHash() != hashMediumFeeTx);
673 BOOST_REQUIRE(mining);
676 CScript scriptPubKey =
CScript() <<
"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"_hex <<
OP_CHECKSIG;
677 BlockAssembler::Options options;
678 options.coinbase_output_script = scriptPubKey;
681 std::unique_ptr<BlockTemplate> block_template = mining->createNewBlock(options);
682 BOOST_REQUIRE(block_template);
684 CBlock block{block_template->getBlock()};
688 BOOST_REQUIRE(!mining->checkBlock(block, {.check_pow = false}, reason, debug));
689 BOOST_REQUIRE_EQUAL(reason,
"bad-txnmrklroot");
690 BOOST_REQUIRE_EQUAL(debug,
"hashMerkleRoot mismatch");
698 BOOST_REQUIRE(mining->checkBlock(block, {.check_pow = false}, reason, debug));
699 BOOST_REQUIRE_EQUAL(reason,
"");
700 BOOST_REQUIRE_EQUAL(debug,
"");
712 BOOST_REQUIRE(!mining->checkBlock(block, {.check_pow = true}, reason, debug));
713 BOOST_REQUIRE_EQUAL(reason,
"high-hash");
714 BOOST_REQUIRE_EQUAL(debug,
"proof of work failed");
720 static_assert(std::size(
BLOCKINFO) == 110,
"Should have 110 blocks to import");
722 std::vector<CTransactionRef> txFirst;
724 const int current_height{mining->getTip()->height};
731 if (current_height % 2 == 0) {
732 block_template = mining->createNewBlock(options);
733 BOOST_REQUIRE(block_template);
736 CBlock block{block_template->getBlock()};
743 txCoinbase.
vin[0].scriptSig =
CScript{} << (current_height + 1) << bi.extranonce;
744 txCoinbase.
vout.resize(1);
747 if (txFirst.size() == 0)
748 baseheight = current_height;
749 if (txFirst.size() < 4)
750 txFirst.push_back(block.vtx[0]);
752 block.nNonce = bi.nonce;
754 std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
758 if (current_height % 2 == 0) {
761 BOOST_REQUIRE(block_template->submitSolution(block.nVersion, block.nTime, block.nNonce,
MakeTransactionRef(txCoinbase)));
768 BOOST_REQUIRE_EQUAL(maybe_new_tip->GetBlockHash(), block.GetHash());
770 if (current_height % 2 == 0) {
771 block_template = block_template->waitNext();
772 BOOST_REQUIRE(block_template);
775 mining->waitTipChanged(block.hashPrevBlock);
781 TestBasicMining(scriptPubKey, txFirst, baseheight);
786 TestPackageSelection(scriptPubKey, txFirst);
791 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.
AddToMempool(pool, CTxMemPoolEntry(tx, fee, 0, 1, 0, false, 4, lp))
#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 virtualbyte: CAmount / vB the feerate is represented internally as FeeFrac.
CAmount GetFee(int32_t virtual_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.
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
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()
@ REPLACED
Removed for replacement.
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(...)
void BulkTransaction(CMutableTransaction &tx, int32_t target_weight)
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.