19 #include <validation.h> 26 #include <boost/test/unit_test.hpp> 45 BOOST_FIXTURE_TEST_SUITE(
miner_tests, MinerTestingSetup)
51 BlockAssembler::Options options;
58 constexpr
static struct {
61 }
BLOCKINFO[]{{8, 582909131}, {0, 971462344}, {2, 1169481553}, {6, 66147495}, {7, 427785981}, {8, 80538907},
62 {8, 207348013}, {2, 1951240923}, {4, 215054351}, {1, 491520534}, {8, 1282281282}, {4, 639565734},
63 {3, 248274685}, {8, 1160085976}, {6, 396349768}, {5, 393780549}, {5, 1096899528}, {4, 965381630},
64 {0, 728758712}, {5, 318638310}, {3, 164591898}, {2, 274234550}, {2, 254411237}, {7, 561761812},
65 {2, 268342573}, {0, 402816691}, {1, 221006382}, {6, 538872455}, {7, 393315655}, {4, 814555937},
66 {7, 504879194}, {6, 467769648}, {3, 925972193}, {2, 200581872}, {3, 168915404}, {8, 430446262},
67 {5, 773507406}, {3, 1195366164}, {0, 433361157}, {3, 297051771}, {0, 558856551}, {2, 501614039},
68 {3, 528488272}, {2, 473587734}, {8, 230125274}, {2, 494084400}, {4, 357314010}, {8, 60361686},
69 {7, 640624687}, {3, 480441695}, {8, 1424447925}, {4, 752745419}, {1, 288532283}, {6, 669170574},
70 {5, 1900907591}, {3, 555326037}, {3, 1121014051}, {0, 545835650}, {8, 189196651}, {5, 252371575},
71 {0, 199163095}, {6, 558895874}, {6, 1656839784}, {6, 815175452}, {6, 718677851}, {5, 544000334},
72 {0, 340113484}, {6, 850744437}, {4, 496721063}, {8, 524715182}, {6, 574361898}, {6, 1642305743},
73 {6, 355110149}, {5, 1647379658}, {8, 1103005356}, {7, 556460625}, {3, 1139533992}, {5, 304736030},
74 {2, 361539446}, {2, 143720360}, {6, 201939025}, {7, 423141476}, {4, 574633709}, {3, 1412254823},
75 {4, 873254135}, {0, 341817335}, {6, 53501687}, {3, 179755410}, {5, 172209688}, {8, 516810279},
76 {4, 1228391489}, {8, 325372589}, {6, 550367589}, {0, 876291812}, {7, 412454120}, {7, 717202854},
77 {2, 222677843}, {6, 251778867}, {7, 842004420}, {7, 194762829}, {4, 96668841}, {1, 925485796},
78 {0, 792342903}, {6, 678455063}, {6, 773251385}, {5, 186617471}, {6, 883189502}, {7, 396077336},
79 {8, 254702874}, {0, 455592851}};
85 index.
pprev = active_chain_tip;
92 void MinerTestingSetup::TestPackageSelection(
const CChainParams& chainparams,
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst)
102 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
103 tx.
vin[0].prevout.n = 0;
105 tx.
vout[0].nValue = 5000000000LL - 1000;
111 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
112 tx.
vout[0].nValue = 5000000000LL - 10000;
117 tx.
vin[0].prevout.hash = hashParentTx;
118 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000;
122 std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
123 BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 4U);
124 BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashParentTx);
125 BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashHighFeeTx);
126 BOOST_CHECK(pblocktemplate->block.vtx[3]->GetHash() == hashMediumFeeTx);
129 tx.
vin[0].prevout.hash = hashHighFeeTx;
130 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000;
139 tx.
vin[0].prevout.hash = hashFreeTx;
140 tx.
vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse;
143 pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
145 for (
size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
146 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeTx);
147 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashLowFeeTx);
154 tx.
vout[0].nValue -= 2;
157 pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
158 BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 6U);
159 BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashFreeTx);
160 BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashLowFeeTx);
165 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
167 tx.
vout[0].nValue = 5000000000LL - 100000000;
168 tx.
vout[1].nValue = 100000000;
173 tx.
vin[0].prevout.hash = hashFreeTx2;
176 tx.
vout[0].nValue = 5000000000LL - 100000000 - feeToUse;
179 pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
182 for (
size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
183 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeTx2);
184 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashLowFeeTx2);
189 tx.
vin[0].prevout.n = 1;
190 tx.
vout[0].nValue = 100000000 - 10000;
192 pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
193 BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 9U);
194 BOOST_CHECK(pblocktemplate->block.vtx[8]->GetHash() == hashLowFeeTx2);
197 void MinerTestingSetup::TestBasicMining(
const CChainParams& chainparams,
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst,
int baseheight)
206 auto pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
218 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
219 tx.
vin[0].prevout.n = 0;
221 tx.
vout[0].nValue = BLOCKSUBSIDY;
222 for (
unsigned int i = 0; i < 1001; ++i)
224 tx.
vout[0].nValue -= LOWFEE;
229 tx.
vin[0].prevout.hash = hash;
232 BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"bad-blk-sigops"));
235 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
236 tx.
vout[0].nValue = BLOCKSUBSIDY;
237 for (
unsigned int i = 0; i < 1001; ++i)
239 tx.
vout[0].nValue -= LOWFEE;
244 tx.
vin[0].prevout.hash = hash;
246 BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
252 std::vector<unsigned char> vchData(520);
253 for (
unsigned int i = 0; i < 18; ++i)
256 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
257 tx.
vout[0].nValue = BLOCKSUBSIDY;
258 for (
unsigned int i = 0; i < 128; ++i)
260 tx.
vout[0].nValue -= LOWFEE;
264 tx.
vin[0].prevout.hash = hash;
266 BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
272 BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
277 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
278 tx.
vout[0].nValue = BLOCKSUBSIDY-HIGHFEE;
281 tx.
vin[0].prevout.hash = hash;
284 tx.
vin[1].prevout.hash = txFirst[0]->GetHash();
285 tx.
vin[1].prevout.n = 0;
286 tx.
vout[0].nValue = tx.
vout[0].nValue+BLOCKSUBSIDY-HIGHERFEE;
289 BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
294 tx.
vin[0].prevout.SetNull();
296 tx.
vout[0].nValue = 0;
301 BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"bad-cb-multiple"));
305 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
307 tx.
vout[0].nValue = BLOCKSUBSIDY-HIGHFEE;
314 BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"bad-txns-inputs-missingorspent"));
330 BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
342 BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
345 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
346 tx.
vin[0].prevout.n = 0;
348 tx.
vout[0].nValue = BLOCKSUBSIDY-LOWFEE;
353 tx.
vin[0].prevout.hash = hash;
354 tx.
vin[0].scriptSig =
CScript() << std::vector<unsigned char>(script.
begin(), script.
end());
355 tx.
vout[0].nValue -= LOWFEE;
359 BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error,
HasReason(
"block-validation-failed"));
375 std::vector<int> prevheights;
380 prevheights.resize(1);
381 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
382 tx.
vin[0].prevout.n = 0;
385 prevheights[0] = baseheight + 1;
387 tx.
vout[0].nValue = BLOCKSUBSIDY-HIGHFEE;
401 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
403 prevheights[0] = baseheight + 2;
409 const int SEQUENCE_LOCK_TIME = 512;
419 ancestor->nTime -= SEQUENCE_LOCK_TIME;
423 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
425 prevheights[0] = baseheight + 3;
434 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
436 prevheights.resize(1);
437 prevheights[0] = baseheight + 4;
445 tx.
vin[0].prevout.hash = hash;
446 prevheights[0] =
m_node.
chainman->ActiveChain().Tip()->nHeight + 1;
448 tx.
vin[0].nSequence = 0;
451 tx.
vin[0].nSequence = 1;
458 BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
468 ancestor->nTime += SEQUENCE_LOCK_TIME;
473 BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
477 void MinerTestingSetup::TestPrioritisedMining(
const CChainParams& chainparams,
const CScript& scriptPubKey,
const std::vector<CTransactionRef>& txFirst)
484 tx.
vin[0].prevout.hash = txFirst[0]->GetHash();
485 tx.
vin[0].prevout.n = 0;
488 tx.
vout[0].nValue = 5000000000LL;
493 tx.
vin[0].prevout.hash = txFirst[1]->GetHash();
494 tx.
vin[0].prevout.n = 0;
495 tx.
vout[0].nValue = 5000000000LL - 1000;
501 tx.
vin[0].prevout.hash = txFirst[2]->GetHash();
502 tx.
vout[0].nValue = 5000000000LL - 10000;
508 tx.
vin[0].prevout.hash = hashParentTx;
509 tx.
vout[0].nValue = 5000000000LL - 1000 - 1000;
520 tx.
vin[0].prevout.hash = txFirst[3]->GetHash();
521 tx.
vout[0].nValue = 5000000000LL;
526 tx.
vin[0].prevout.hash = hashFreeParent;
527 tx.
vout[0].nValue = 5000000000LL;
532 tx.
vin[0].prevout.hash = hashFreeChild;
533 tx.
vout[0].nValue = 5000000000LL;
537 auto pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
538 BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 6U);
539 BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashFreeParent);
540 BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashFreePrioritisedTx);
541 BOOST_CHECK(pblocktemplate->block.vtx[3]->GetHash() == hashParentTx);
542 BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashPrioritsedChild);
543 BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashFreeChild);
544 for (
size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
546 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeGrandchild);
548 BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashMediumFeeTx);
558 CScript scriptPubKey =
CScript() <<
ParseHex(
"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") <<
OP_CHECKSIG;
559 std::unique_ptr<CBlockTemplate> pblocktemplate;
564 BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
568 static_assert(std::size(
BLOCKINFO) == 110,
"Should have 110 blocks to import");
570 std::vector<CTransactionRef> txFirst;
572 CBlock *pblock = &pblocktemplate->block;
580 txCoinbase.
vout.resize(1);
583 if (txFirst.size() == 0)
585 if (txFirst.size() < 4)
586 txFirst.push_back(pblock->
vtx[0]);
588 pblock->
nNonce = bi.nonce;
590 std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock);
592 pblock->hashPrevBlock = pblock->GetHash();
598 TestBasicMining(chainparams, scriptPubKey, txFirst, baseheight);
604 TestPackageSelection(chainparams, scriptPubKey, txFirst);
610 TestPrioritisedMining(chainparams, scriptPubKey, txFirst);
BlockAssembler AssemblerForTest(const CChainParams ¶ms)
static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE
Flags for nSequence and nLockTime locks.
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...
bool CheckFinalTxAtTip(const CBlockIndex &active_chain_tip, const CTransaction &tx)
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.
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system...
CTxMemPoolEntry FromTx(const CMutableTransaction &tx) const
BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
bool CheckFinalTxAtTip(const CBlockIndex &active_chain_tip, const CTransaction &tx) EXCLUSIVE_LOCKS_REQUIRED(bool CheckSequenceLocksAtTip(CBlockIndex *tip, const CCoinsView &coins_view, const CTransaction &tx, LockPoints *lp=nullptr, bool useExistingLockPoints=false)
Check if transaction will be final in the next block to be created.
size_t GetSerializeSize(const T &t, int nVersion=0)
std::unique_ptr< CTxMemPool > mempool
static const std::string MAIN
Chain name strings.
static const unsigned int MAX_BLOCK_WEIGHT
The maximum allowed weight for a block, see BIP 141 (network rule)
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.
std::vector< Byte > ParseHex(std::string_view str)
Parse the hex string into bytes (uint8_t or std::byte).
void TestPackageSelection(const CChainParams &chainparams, const CScript &scriptPubKey, const std::vector< CTransactionRef > &txFirst) EXCLUSIVE_LOCKS_REQUIRED(void TestBasicMining(const CChainParams &chainparams, const CScript &scriptPubKey, const std::vector< CTransactionRef > &txFirst, int baseheight) EXCLUSIVE_LOCKS_REQUIRED(void TestPrioritisedMining(const CChainParams &chainparams, const CScript &scriptPubKey, const std::vector< CTransactionRef > &txFirst) EXCLUSIVE_LOCKS_REQUIRED(bool TestSequenceLocks(const CTransaction &tx) EXCLUSIVE_LOCKS_REQUIRED(
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_EXCEPTION predicates to check the specific validation error.
static constexpr struct @15 BLOCKINFO[]
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
void BuildSkip()
Build the skiplist pointer for this entry.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
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
static CTransactionRef MakeTransactionRef(Tx &&txIn)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::vector< CTransactionRef > vtx
uint256 GetHash() const
Compute the hash of this CMutableTransaction.
#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.
static const int PROTOCOL_VERSION
network protocol versioning
static const int32_t VERSIONBITS_TOP_BITS
What bits to set in version for versionbits blocks.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
TestMemPoolEntryHelper & Time(int64_t _time)
TestMemPoolEntryHelper & SigOpsCost(unsigned int _sigopsCost)
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...
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. ...
static CBlockIndex CreateBlockIndex(int nHeight, CBlockIndex *active_chain_tip) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
int nHeight
height of the entry in the chain. The genesis block has height 0
static uint256 InsecureRand256()
int64_t GetTime()
DEPRECATED, see GetTime.
CCoinsView that brings transactions from a mempool into view.
std::unique_ptr< ChainstateManager > chainman
Testing setup that configures a complete environment.
#define Assert(val)
Identity function.
#define BOOST_CHECK(expr)
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
std::unique_ptr< const CChainParams > CreateChainParams(const ArgsManager &args, const std::string &chain)
Creates and returns a std::unique_ptr<CChainParams> of the chosen chain.