mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-10 22:18:54 +01:00
Merge bitcoin/bitcoin#22674: validation: mempool validation and submission for packages of 1 child + parents
046e8ff264[unit test] package submission (glozow)e12fafda2d[validation] de-duplicate package transactions already in mempool (glozow)8310d942e0[packages] add sanity checks for package vs mempool limits (glozow)be3ff151a1[validation] full package accept + mempool submission (glozow)144a29099a[policy] require submitted packages to be child-with-unconfirmed-parents (glozow)d59ddc5c3d[packages/doc] define and document package rules (glozow)ba26169f60[unit test] context-free package checks (glozow)9b2fdca7f0[packages] add static IsChildWithParents function (glozow) Pull request description: This is 1 chunk of [Package Mempool Accept](https://gist.github.com/glozow/dc4e9d5c5b14ade7cdfac40f43adb18a); it restricts packages to 1 child with its parents, doesn't allow conflicts, and doesn't have CPFP (yet). Future PRs (see #22290) will add RBF and CPFP within packages. ACKs for top commit: laanwj: Code review ACK046e8ff264Tree-SHA512: 37dbba37d527712f8efef71ee05c90a8308992615af35f5e0cfeafc60d859cc792737d125aac526e37742fe7683ac8c155ac24af562426213904333c01260c95
This commit is contained in:
@@ -60,6 +60,16 @@ static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT = 101;
|
||||
static const unsigned int DEFAULT_DESCENDANT_LIMIT = 25;
|
||||
/** Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants */
|
||||
static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT = 101;
|
||||
|
||||
// If a package is submitted, it must be within the mempool's ancestor/descendant limits. Since a
|
||||
// submitted package must be child-with-unconfirmed-parents (all of the transactions are an ancestor
|
||||
// of the child), package limits are ultimately bounded by mempool package limits. Ensure that the
|
||||
// defaults reflect this constraint.
|
||||
static_assert(DEFAULT_DESCENDANT_LIMIT >= MAX_PACKAGE_COUNT);
|
||||
static_assert(DEFAULT_ANCESTOR_LIMIT >= MAX_PACKAGE_COUNT);
|
||||
static_assert(DEFAULT_ANCESTOR_SIZE_LIMIT >= MAX_PACKAGE_SIZE);
|
||||
static_assert(DEFAULT_DESCENDANT_SIZE_LIMIT >= MAX_PACKAGE_SIZE);
|
||||
|
||||
/** Default for -mempoolexpiry, expiration time for mempool transactions in hours */
|
||||
static const unsigned int DEFAULT_MEMPOOL_EXPIRY = 336;
|
||||
/** Maximum number of dedicated script-checking threads allowed */
|
||||
@@ -151,17 +161,19 @@ struct MempoolAcceptResult {
|
||||
enum class ResultType {
|
||||
VALID, //!> Fully validated, valid.
|
||||
INVALID, //!> Invalid.
|
||||
MEMPOOL_ENTRY, //!> Valid, transaction was already in the mempool.
|
||||
};
|
||||
const ResultType m_result_type;
|
||||
const TxValidationState m_state;
|
||||
|
||||
// The following fields are only present when m_result_type = ResultType::VALID
|
||||
// The following fields are only present when m_result_type = ResultType::VALID or MEMPOOL_ENTRY
|
||||
/** Mempool transactions replaced by the tx per BIP 125 rules. */
|
||||
const std::optional<std::list<CTransactionRef>> m_replaced_transactions;
|
||||
/** Virtual size as used by the mempool, calculated using serialized size and sigops. */
|
||||
const std::optional<int64_t> m_vsize;
|
||||
/** Raw base fees in satoshis. */
|
||||
const std::optional<CAmount> m_base_fees;
|
||||
|
||||
static MempoolAcceptResult Failure(TxValidationState state) {
|
||||
return MempoolAcceptResult(state);
|
||||
}
|
||||
@@ -170,6 +182,10 @@ struct MempoolAcceptResult {
|
||||
return MempoolAcceptResult(std::move(replaced_txns), vsize, fees);
|
||||
}
|
||||
|
||||
static MempoolAcceptResult MempoolTx(int64_t vsize, CAmount fees) {
|
||||
return MempoolAcceptResult(vsize, fees);
|
||||
}
|
||||
|
||||
// Private constructors. Use static methods MempoolAcceptResult::Success, etc. to construct.
|
||||
private:
|
||||
/** Constructor for failure case */
|
||||
@@ -182,6 +198,10 @@ private:
|
||||
explicit MempoolAcceptResult(std::list<CTransactionRef>&& replaced_txns, int64_t vsize, CAmount fees)
|
||||
: m_result_type(ResultType::VALID),
|
||||
m_replaced_transactions(std::move(replaced_txns)), m_vsize{vsize}, m_base_fees(fees) {}
|
||||
|
||||
/** Constructor for already-in-mempool case. It wouldn't replace any transactions. */
|
||||
explicit MempoolAcceptResult(int64_t vsize, CAmount fees)
|
||||
: m_result_type(ResultType::MEMPOOL_ENTRY), m_vsize{vsize}, m_base_fees(fees) {}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -191,7 +211,7 @@ struct PackageMempoolAcceptResult
|
||||
{
|
||||
const PackageValidationState m_state;
|
||||
/**
|
||||
* Map from wtxid to finished MempoolAcceptResults. The client is responsible
|
||||
* Map from (w)txid to finished MempoolAcceptResults. The client is responsible
|
||||
* for keeping track of the transaction objects themselves. If a result is not
|
||||
* present, it means validation was unfinished for that transaction. If there
|
||||
* was a package-wide error (see result in m_state), m_tx_results will be empty.
|
||||
@@ -225,16 +245,12 @@ MempoolAcceptResult AcceptToMemoryPool(CChainState& active_chainstate, const CTr
|
||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
||||
/**
|
||||
* Atomically test acceptance of a package. If the package only contains one tx, package rules still
|
||||
* apply. Package validation does not allow BIP125 replacements, so the transaction(s) cannot spend
|
||||
* the same inputs as any transaction in the mempool.
|
||||
* @param[in] txns Group of transactions which may be independent or contain
|
||||
* parent-child dependencies. The transactions must not conflict
|
||||
* with each other, i.e., must not spend the same inputs. If any
|
||||
* dependencies exist, parents must appear anywhere in the list
|
||||
* before their children.
|
||||
* Validate (and maybe submit) a package to the mempool. See doc/policy/packages.md for full details
|
||||
* on package validation rules.
|
||||
* @param[in] test_accept When true, run validation checks but don't submit to mempool.
|
||||
* @returns a PackageMempoolAcceptResult which includes a MempoolAcceptResult for each transaction.
|
||||
* If a transaction fails, validation will exit early and some results may be missing.
|
||||
* If a transaction fails, validation will exit early and some results may be missing. It is also
|
||||
* possible for the package to be partially submitted.
|
||||
*/
|
||||
PackageMempoolAcceptResult ProcessNewPackage(CChainState& active_chainstate, CTxMemPool& pool,
|
||||
const Package& txns, bool test_accept)
|
||||
|
||||
Reference in New Issue
Block a user