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;
183 block_template = mining->createNewBlock(options);
184 BOOST_REQUIRE(block_template);
185 block = block_template->getBlock();
187 for (
size_t i=0; i<block.vtx.size(); ++i) {
188 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeTx);
189 BOOST_CHECK(block.vtx[i]->GetHash() != hashLowFeeTx);
196 tx.
vout[0].nValue -= 2;
199 block_template = mining->createNewBlock(options);
200 BOOST_REQUIRE(block_template);
201 block = block_template->getBlock();
202 BOOST_REQUIRE_EQUAL(block.vtx.size(), 6U);
203 BOOST_CHECK(block.vtx[4]->GetHash() == hashFreeTx);
204 BOOST_CHECK(block.vtx[5]->GetHash() == hashLowFeeTx);
209 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
211 tx.
vout[0].nValue = 5000000000LL - 100000000;
212 tx.
vout[1].nValue = 100000000;
217 tx.
vin[0].prevout.hash = hashFreeTx2;
220 tx.
vout[0].nValue = 5000000000LL - 100000000 - feeToUse;
223 block_template = mining->createNewBlock(options);
224 BOOST_REQUIRE(block_template);
225 block = block_template->getBlock();
228 for (
size_t i=0; i<block.vtx.size(); ++i) {
229 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeTx2);
230 BOOST_CHECK(block.vtx[i]->GetHash() != hashLowFeeTx2);
235 tx.
vin[0].prevout.n = 1;
236 tx.
vout[0].nValue = 100000000 - 10000;
238 block_template = mining->createNewBlock(options);
239 BOOST_REQUIRE(block_template);
240 block = block_template->getBlock();
241 BOOST_REQUIRE_EQUAL(block.vtx.size(), 9U);
242 BOOST_CHECK(block.vtx[8]->GetHash() == hashLowFeeTx2);
245void MinerTestingSetup::TestBasicMining(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst,
int baseheight)
259 BOOST_REQUIRE(mining);
261 BlockAssembler::Options options;
262 options.coinbase_output_script = scriptPubKey;
269 auto block_template{mining->createNewBlock(options)};
270 BOOST_REQUIRE(block_template);
271 CBlock block{block_template->getBlock()};
277 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
278 tx.
vin[0].prevout.n = 0;
280 tx.
vout[0].nValue = BLOCKSUBSIDY;
281 for (
unsigned int i = 0; i < 1001; ++i) {
282 tx.
vout[0].nValue -= LOWFEE;
287 tx.
vin[0].prevout.hash = hash;
290 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-blk-sigops"));
297 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
298 tx.
vout[0].nValue = BLOCKSUBSIDY;
299 for (
unsigned int i = 0; i < 1001; ++i) {
300 tx.
vout[0].nValue -= LOWFEE;
305 tx.
vin[0].prevout.hash = hash;
307 BOOST_REQUIRE(mining->createNewBlock(options));
317 std::vector<unsigned char> vchData(520);
318 for (
unsigned int i = 0; i < 18; ++i) {
322 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
323 tx.
vout[0].nValue = BLOCKSUBSIDY;
324 for (
unsigned int i = 0; i < 128; ++i) {
325 tx.
vout[0].nValue -= LOWFEE;
329 tx.
vin[0].prevout.hash = hash;
331 BOOST_REQUIRE(mining->createNewBlock(options));
341 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
350 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
351 tx.
vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
354 tx.
vin[0].prevout.hash = hash;
357 tx.
vin[1].prevout.hash = txFirst[0]->GetHash();
358 tx.
vin[1].prevout.n = 0;
359 tx.
vout[0].nValue = tx.
vout[0].nValue + BLOCKSUBSIDY - HIGHERFEE;
362 BOOST_REQUIRE(mining->createNewBlock(options));
371 tx.
vin[0].prevout.SetNull();
373 tx.
vout[0].nValue = 0;
378 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-cb-multiple"));
386 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
388 tx.
vout[0].nValue = BLOCKSUBSIDY - HIGHFEE;
395 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
415 BOOST_REQUIRE(mining->createNewBlock(options));
427 BOOST_REQUIRE(mining->createNewBlock(options));
430 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
431 tx.
vin[0].prevout.n = 0;
433 tx.
vout[0].nValue = BLOCKSUBSIDY - LOWFEE;
438 tx.
vin[0].prevout.hash = hash;
440 tx.
vout[0].nValue -= LOWFEE;
443 BOOST_CHECK_EXCEPTION(mining->createNewBlock(options), std::runtime_error,
HasReason(
"mandatory-script-verify-flag-failed"));
462 std::vector<int> prevheights;
467 prevheights.resize(1);
468 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
469 tx.
vin[0].prevout.n = 0;
472 prevheights[0] = baseheight + 1;
474 tx.
vout[0].nValue = BLOCKSUBSIDY-HIGHFEE;
488 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
490 prevheights[0] = baseheight + 2;
496 const int SEQUENCE_LOCK_TIME = 512;
506 ancestor->nTime -= SEQUENCE_LOCK_TIME;
510 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
512 prevheights[0] = baseheight + 3;
521 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
523 prevheights.resize(1);
524 prevheights[0] = baseheight + 4;
532 tx.
vin[0].prevout.hash = hash;
533 prevheights[0] =
m_node.
chainman->ActiveChain().Tip()->nHeight + 1;
535 tx.
vin[0].nSequence = 0;
538 tx.
vin[0].nSequence = 1;
545 auto block_template = mining->createNewBlock(options);
546 BOOST_REQUIRE(block_template);
552 CBlock block{block_template->getBlock()};
557 ancestor->nTime += SEQUENCE_LOCK_TIME;
562 block_template = mining->createNewBlock(options);
563 BOOST_REQUIRE(block_template);
564 block = block_template->getBlock();
568void MinerTestingSetup::TestPrioritisedMining(
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst)
571 BOOST_REQUIRE(mining);
573 BlockAssembler::Options options;
574 options.coinbase_output_script = scriptPubKey;
584 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
585 tx.
vin[0].prevout.n = 0;
588 tx.
vout[0].nValue = 5000000000LL;
591 tx_mempool.PrioritiseTransaction(hashFreePrioritisedTx, 5 *
COIN);
593 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
594 tx.
vin[0].prevout.n = 0;
595 tx.
vout[0].nValue = 5000000000LL - 1000;
601 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
602 tx.
vout[0].nValue = 5000000000LL - 10000;
605 tx_mempool.PrioritiseTransaction(hashMediumFeeTx, -5 *
COIN);
608 tx.
vin[0].prevout.hash = hashParentTx;
609 tx.
vout[0].nValue = 5000000000LL - 1000 - 1000;
612 tx_mempool.PrioritiseTransaction(hashPrioritsedChild, 2 *
COIN);
620 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
621 tx.
vout[0].nValue = 5000000000LL;
624 tx_mempool.PrioritiseTransaction(hashFreeParent, 10 *
COIN);
626 tx.
vin[0].prevout.hash = hashFreeParent;
627 tx.
vout[0].nValue = 5000000000LL;
630 tx_mempool.PrioritiseTransaction(hashFreeChild, 1 *
COIN);
632 tx.
vin[0].prevout.hash = hashFreeChild;
633 tx.
vout[0].nValue = 5000000000LL;
637 auto block_template = mining->createNewBlock(options);
638 BOOST_REQUIRE(block_template);
639 CBlock block{block_template->getBlock()};
640 BOOST_REQUIRE_EQUAL(block.vtx.size(), 6U);
641 BOOST_CHECK(block.vtx[1]->GetHash() == hashFreeParent);
642 BOOST_CHECK(block.vtx[2]->GetHash() == hashFreePrioritisedTx);
643 BOOST_CHECK(block.vtx[3]->GetHash() == hashParentTx);
644 BOOST_CHECK(block.vtx[4]->GetHash() == hashPrioritsedChild);
645 BOOST_CHECK(block.vtx[5]->GetHash() == hashFreeChild);
646 for (
size_t i=0; i<block.vtx.size(); ++i) {
648 BOOST_CHECK(block.vtx[i]->GetHash() != hashFreeGrandchild);
650 BOOST_CHECK(block.vtx[i]->GetHash() != hashMediumFeeTx);
658 BOOST_REQUIRE(mining);
661 CScript scriptPubKey =
CScript() <<
"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"_hex <<
OP_CHECKSIG;
662 BlockAssembler::Options options;
663 options.coinbase_output_script = scriptPubKey;
664 std::unique_ptr<BlockTemplate> block_template;
668 static_assert(std::size(
BLOCKINFO) == 110,
"Should have 110 blocks to import");
670 std::vector<CTransactionRef> txFirst;
672 const int current_height{mining->getTip()->height};
675 block_template = mining->createNewBlock(options);
676 BOOST_REQUIRE(block_template);
678 CBlock block{block_template->getBlock()};
685 txCoinbase.
vin[0].scriptSig =
CScript{} << (current_height + 1) << bi.extranonce;
686 txCoinbase.
vout.resize(1);
689 if (txFirst.size() == 0)
690 baseheight = current_height;
691 if (txFirst.size() < 4)
692 txFirst.push_back(block.vtx[0]);
694 block.nNonce = bi.nonce;
696 std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
700 if (current_height % 2 == 0) {
703 BOOST_REQUIRE(block_template->submitSolution(block.nVersion, block.nTime, block.nNonce,
MakeTransactionRef(txCoinbase)));
710 BOOST_REQUIRE_EQUAL(maybe_new_tip->GetBlockHash(), block.GetHash());
713 mining->waitTipChanged(block.hashPrevBlock);
718 TestBasicMining(scriptPubKey, txFirst, baseheight);
723 TestPackageSelection(scriptPubKey, txFirst);
728 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.
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.