17 #include <boost/test/unit_test.hpp> 31 coinbaseTx.vin.resize(1);
32 coinbaseTx.vout.resize(1);
34 coinbaseTx.vout[0].nValue = 1 *
CENT;
35 coinbaseTx.vout[0].scriptPubKey = scriptPubKey;
57 std::vector<COutPoint> outpoints;
58 for (
size_t i{0}; i < num_outpoints; ++i) {
64 static inline std::vector<CPubKey>
random_keys(
size_t num_keys) {
65 std::vector<CPubKey> keys;
66 keys.reserve(num_keys);
67 for (
size_t i{0}; i < num_keys; ++i) {
80 mtx.
vin.resize(inputs.size());
82 for (
size_t i{0}; i < inputs.size(); ++i) {
83 mtx.
vin[i].prevout = inputs[i];
85 for (
auto i{0}; i < 25; ++i) {
87 mtx.
vout[i].nValue = 10000;
98 std::set<Txid> empty_conflicts_set;
115 const auto expected_error_str{
strprintf(
"non-v3 tx %s (wtxid=%s) cannot spend from v3 tx %s (wtxid=%s)",
116 tx_v2_from_v3->GetHash().ToString(), tx_v2_from_v3->GetWitnessHash().ToString(),
117 mempool_tx_v3->GetHash().ToString(), mempool_tx_v3->GetWitnessHash().ToString())};
120 Package package_v3_v2{mempool_tx_v3, tx_v2_from_v3};
128 auto tx_v2_from_v2_and_v3 =
make_tx({
COutPoint{mempool_tx_v3->GetHash(), 0},
COutPoint{mempool_tx_v2->GetHash(), 0}}, 2);
130 const auto expected_error_str_2{
strprintf(
"non-v3 tx %s (wtxid=%s) cannot spend from v3 tx %s (wtxid=%s)",
131 tx_v2_from_v2_and_v3->GetHash().ToString(), tx_v2_from_v2_and_v3->GetWitnessHash().ToString(),
132 mempool_tx_v3->GetHash().ToString(), mempool_tx_v3->GetWitnessHash().ToString())};
134 == expected_error_str_2);
136 Package package_v3_v2_v2{mempool_tx_v3, mempool_tx_v2, tx_v2_from_v2_and_v3};
147 const auto expected_error_str{
strprintf(
"v3 tx %s (wtxid=%s) cannot spend from non-v3 tx %s (wtxid=%s)",
148 tx_v3_from_v2->GetHash().ToString(), tx_v3_from_v2->GetWitnessHash().ToString(),
149 mempool_tx_v2->GetHash().ToString(), mempool_tx_v2->GetWitnessHash().ToString())};
152 Package package_v2_v3{mempool_tx_v2, tx_v3_from_v2};
160 auto tx_v3_from_v2_and_v3 =
make_tx({
COutPoint{mempool_tx_v3->GetHash(), 0},
COutPoint{mempool_tx_v2->GetHash(), 0}}, 3);
162 const auto expected_error_str_2{
strprintf(
"v3 tx %s (wtxid=%s) cannot spend from non-v3 tx %s (wtxid=%s)",
163 tx_v3_from_v2_and_v3->GetHash().ToString(), tx_v3_from_v2_and_v3->GetWitnessHash().ToString(),
164 mempool_tx_v2->GetHash().ToString(), mempool_tx_v2->GetWitnessHash().ToString())};
166 == expected_error_str_2);
169 const auto expected_error_str_3{
strprintf(
"tx %s (wtxid=%s) would have too many ancestors",
170 tx_v3_from_v2_and_v3->GetHash().ToString(), tx_v3_from_v2_and_v3->GetWitnessHash().ToString())};
171 Package package_v3_v2_v3{mempool_tx_v3, mempool_tx_v2, tx_v3_from_v2_and_v3};
184 Package package_v3_v3{mempool_tx_v3, tx_v3_from_v3};
195 Package package_v2_v2{mempool_tx_v2, tx_v2_from_v2};
203 std::vector<COutPoint> mempool_outpoints;
204 mempool_outpoints.emplace_back(mempool_tx_v3->GetHash(), 0);
205 package_multi_parents.emplace_back(mempool_tx_v3);
206 for (
size_t i{0}; i < 2; ++i) {
209 mempool_outpoints.emplace_back(mempool_tx->GetHash(), 0);
210 package_multi_parents.emplace_back(mempool_tx);
212 auto tx_v3_multi_parent =
make_tx(mempool_outpoints, 3);
213 package_multi_parents.emplace_back(tx_v3_multi_parent);
216 const auto expected_error_str{
strprintf(
"tx %s (wtxid=%s) would have too many ancestors",
217 tx_v3_multi_parent->GetHash().ToString(), tx_v3_multi_parent->GetWitnessHash().ToString())};
230 for (
size_t i{0}; i < 2; ++i) {
231 auto mempool_tx =
make_tx({last_outpoint}, 3);
233 last_outpoint =
COutPoint{mempool_tx->GetHash(), 0};
234 package_multi_gen.emplace_back(mempool_tx);
235 if (i == 1) middle_tx = mempool_tx;
237 auto tx_v3_multi_gen =
make_tx({last_outpoint}, 3);
238 package_multi_gen.emplace_back(tx_v3_multi_gen);
240 const auto expected_error_str{
strprintf(
"tx %s (wtxid=%s) would have too many ancestors",
241 tx_v3_multi_gen->GetHash().ToString(), tx_v3_multi_gen->GetWitnessHash().ToString())};
252 many_inputs.emplace_back(mempool_tx_v3->GetHash(), 0);
254 auto tx_v3_child_big =
make_tx(many_inputs, 3);
257 const auto expected_error_str{
strprintf(
"v3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
258 tx_v3_child_big->GetHash().ToString(), tx_v3_child_big->GetWitnessHash().ToString(), vsize,
V3_CHILD_MAX_VSIZE)};
262 Package package_child_big{mempool_tx_v3, tx_v3_child_big};
270 multisig_outpoints.emplace_back(mempool_tx_v3->GetHash(), 0);
273 script_multisig <<
OP_1;
274 for (
const auto& key : keys) {
281 for (
const auto& outpoint : multisig_outpoints) {
282 mtx_many_sigops.
vin.emplace_back(outpoint);
283 mtx_many_sigops.
vin.back().scriptWitness.stack.emplace_back(script_multisig.
begin(), script_multisig.
end());
285 mtx_many_sigops.
vout.resize(1);
287 mtx_many_sigops.
vout.back().nValue = 10000;
292 const int64_t total_sigops{
static_cast<int64_t
>(tx_many_sigops->vin.size()) * static_cast<int64_t>(script_multisig.
GetSigOpCount(
false))};
298 const auto expected_error_str{
strprintf(
"v3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
299 tx_many_sigops->GetHash().ToString(), tx_many_sigops->GetWitnessHash().ToString(),
305 Package package_child_sigops{mempool_tx_v3, tx_many_sigops};
311 auto tx_mempool_v3_child =
make_tx({
COutPoint{mempool_tx_v3->GetHash(), 0}}, 3);
318 Package package_v3_1p1c{mempool_tx_v3, tx_mempool_v3_child};
327 const auto expected_error_str{
strprintf(
"tx %s (wtxid=%s) would exceed descendant count limit",
328 mempool_tx_v3->GetHash().ToString(), mempool_tx_v3->GetWitnessHash().ToString())};
335 Package package_v3_1p2c{mempool_tx_v3, tx_mempool_v3_child, tx_v3_child2};
std::shared_ptr< const CTransaction > CTransactionRef
unsigned int GetSigOpCount(bool fAccurate) const
Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs as 20 sigops.
invalid by consensus rules
static const int WITNESS_SCALE_FACTOR
Options struct containing limit options for a CTxMemPool.
CPubKey GetPubKey() const
Compute the public key from a private key.
uint256 GetRandHash() noexcept
std::vector< CTransactionRef > Package
A package is an ordered list of transactions.
std::optional< std::string > SingleV3Checks(const CTransactionRef &ptx, const CTxMemPool::setEntries &mempool_ancestors, const std::set< Txid > &direct_conflicts, int64_t vsize)
Must be called for every transaction, even if not v3.
std::set< txiter, CompareIteratorByHash > setEntries
const TxValidationState m_state
Contains information about why the transaction failed.
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop)
Compute the virtual transaction size (weight reinterpreted as bytes).
CTxMemPoolEntry FromTx(const CMutableTransaction &tx) const
const ResultType m_result_type
Result type.
static constexpr unsigned int DEFAULT_BYTES_PER_SIGOP
Default for -bytespersigop.
static const int MAX_PUBKEYS_PER_MULTISIG
static int32_t GetTransactionWeight(const CTransaction &tx)
util::Result< setEntries > CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, const Limits &limits, bool fSearchForParents=true) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Try to calculate all in-mempool ancestors of entry.
std::unique_ptr< CTxMemPool > mempool
static std::vector< CPubKey > random_keys(size_t num_keys)
static CTransactionRef make_tx(const std::vector< COutPoint > &inputs, int32_t version)
BOOST_AUTO_TEST_SUITE_END()
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Testing fixture that pre-creates a 100-block REGTEST-mode block chain.
An outpoint - a combination of a transaction hash and an index n into its vout.
std::vector< CTxOut > vout
Validation result for a transaction evaluated by MemPoolAccept (single or package).
std::optional< std::string > PackageV3Checks(const CTransactionRef &ptx, int64_t vsize, const Package &package, const CTxMemPool::setEntries &mempool_ancestors)
Must be called for every transaction that is submitted within a package, even if not v3...
static CTransactionRef MakeTransactionRef(Tx &&txIn)
static constexpr int64_t V3_CHILD_MAX_VSIZE
Maximum sigop-adjusted virtual size of a tx which spends from an unconfirmed v3 transaction.
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void addUnchecked(const CTxMemPoolEntry &entry) EXCLUSIVE_LOCKS_REQUIRED(cs
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup)
Ensure that the mempool won't accept coinbase transactions.
std::optional< txiter > GetIter(const uint256 &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Returns an iterator to the given hash, if found.
std::vector< unsigned char > ToByteVector(const T &in)
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
#define BOOST_CHECK_EQUAL(v1, v2)
Serialized script, used inside transaction inputs and outputs.
static transaction_identifier FromUint256(const uint256 &id)
BOOST_AUTO_TEST_SUITE(cuckoocache_tests)
Test Suite for CuckooCache.
A mutable version of CTransaction.
static std::vector< COutPoint > random_outpoints(size_t num_outpoints)
static constexpr CAmount CENT
An encapsulated private key.
The basic transaction that is broadcasted on the network and contained in blocks. ...
std::string GetRejectReason() const
Identical to TestingSetup, but chain set to regtest.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
std::unique_ptr< ChainstateManager > chainman
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it...
#define Assert(val)
Identity function.
#define BOOST_CHECK(expr)