Skip to content

Commit 2600257

Browse files
committed
Merge bitcoin/bitcoin#26646: validation, bugfix: provide more info in *MempoolAcceptResult
264f9ef [validation] return MempoolAcceptResult for every tx on PCKG_TX failure (glozow) dae81e0 [refactor] rename variables in AcceptPackage for clarity (glozow) da484bc [doc] release note effective-feerate and effective-includes RPC results (glozow) 5eab397 [validation] remove PackageMempoolAcceptResult::m_package_feerate (glozow) 601bac8 [rpc] return effective-includes in testmempoolaccept and submitpackage (glozow) 1691eaa [rpc] return effective-feerate in testmempoolaccept and submitpackage (glozow) d6c7b78 [validation] return wtxids of other transactions whose fees were used (glozow) 1605886 [validation] return effective feerate from mempool validation (glozow) 5d35b4a [test] package validation quits early due to non-policy, non-missing-inputs failure (glozow) be2e4d9 [validation] when quitting early in AcceptPackage, set package_state and tx result (glozow) Pull request description: This PR fixes a bug and improves the mempool accept interface to return information more predictably. Bug: In package validation, we first try the transactions individually (see doc/policy/packages.md for more explanation) and, if they all failed for missing inputs and policy-related (i.e. fee) reasons, we'll try package validation. Otherwise, we'll just "quit early" since, for example, if a transaction had an invalid signature, adding a child will not help make it valid. Currently, when we quit early, we're not setting the `package_state` to be invalid, so the caller might think it succeeded. Also, we're returning no results - it makes more sense to return the individual transaction failure. Thanks instagibbs for catching bitcoin/bitcoin#25038 (comment)! Also, make the package results interface generally more useful/predictable: - Always return the feerate at which a transaction was considered for `CheckFeeRate` in `MempoolAcceptResult::m_effective_feerate` when it was successful. This can replace the current `PackageMempoolAcceptResult::m_package_feerate`, which only sometimes exists. - Always provide an entry for every transaction in `PackageMempoolAcceptResult::m_tx_results` when the error is `PCKG_TX`. ACKs for top commit: instagibbs: reACK bitcoin/bitcoin@264f9ef achow101: ACK 264f9ef naumenkogs: reACK 264f9ef Tree-SHA512: ce7fd9927a80030317cc6157822596e85a540feff5dbf5eea7c62da2eb50c917cdddc9da1e2ff62cc18b98b27d360151811546bd9d498859679a04bbee090837
2 parents dbca00e + 264f9ef commit 2600257

File tree

8 files changed

+266
-123
lines changed

8 files changed

+266
-123
lines changed

release-notes-26646.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
JSON-RPC
2+
--------
3+
4+
The `testmempoolaccept` RPC now returns 2 additional results within the "fees" result:
5+
"effective-feerate" is the feerate including fees and sizes of transactions validated together if
6+
package validation was used, and also includes any modified fees from prioritisetransaction. The
7+
"effective-includes" result lists the wtxids of transactions whose modified fees and sizes were used
8+
in the effective-feerate (#26646).

src/rpc/mempool.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ static RPCHelpMan testmempoolaccept()
126126
{RPCResult::Type::OBJ, "fees", /*optional=*/true, "Transaction fees (only present if 'allowed' is true)",
127127
{
128128
{RPCResult::Type::STR_AMOUNT, "base", "transaction fee in " + CURRENCY_UNIT},
129+
{RPCResult::Type::STR_AMOUNT, "effective-feerate", /*optional=*/false, "the effective feerate in " + CURRENCY_UNIT + " per KvB. May differ from the base feerate if, for example, there are modified fees from prioritisetransaction or a package feerate was used."},
130+
{RPCResult::Type::ARR, "effective-includes", /*optional=*/false, "transactions whose fees and vsizes are included in effective-feerate.",
131+
{RPCResult{RPCResult::Type::STR_HEX, "", "transaction wtxid in hex"},
132+
}},
129133
}},
130134
{RPCResult::Type::STR, "reject-reason", /*optional=*/true, "Rejection string (only present when 'allowed' is false)"},
131135
}},
@@ -217,6 +221,12 @@ static RPCHelpMan testmempoolaccept()
217221
result_inner.pushKV("vsize", virtual_size);
218222
UniValue fees(UniValue::VOBJ);
219223
fees.pushKV("base", ValueFromAmount(fee));
224+
fees.pushKV("effective-feerate", ValueFromAmount(tx_result.m_effective_feerate.value().GetFeePerK()));
225+
UniValue effective_includes_res(UniValue::VARR);
226+
for (const auto& wtxid : tx_result.m_wtxids_fee_calculations.value()) {
227+
effective_includes_res.push_back(wtxid.ToString());
228+
}
229+
fees.pushKV("effective-includes", effective_includes_res);
220230
result_inner.pushKV("fees", fees);
221231
}
222232
} else {
@@ -768,10 +778,13 @@ static RPCHelpMan submitpackage()
768778
{RPCResult::Type::NUM, "vsize", "Virtual transaction size as defined in BIP 141."},
769779
{RPCResult::Type::OBJ, "fees", "Transaction fees", {
770780
{RPCResult::Type::STR_AMOUNT, "base", "transaction fee in " + CURRENCY_UNIT},
781+
{RPCResult::Type::STR_AMOUNT, "effective-feerate", /*optional=*/true, "if the transaction was not already in the mempool, the effective feerate in " + CURRENCY_UNIT + " per KvB. For example, the package feerate and/or feerate with modified fees from prioritisetransaction."},
782+
{RPCResult::Type::ARR, "effective-includes", /*optional=*/true, "if effective-feerate is provided, the wtxids of the transactions whose fees and vsizes are included in effective-feerate.",
783+
{{RPCResult::Type::STR_HEX, "", "transaction wtxid in hex"},
784+
}},
771785
}},
772786
}}
773787
}},
774-
{RPCResult::Type::STR_AMOUNT, "package-feerate", /*optional=*/true, "package feerate used for feerate checks in " + CURRENCY_UNIT + " per KvB. Excludes transactions which were deduplicated or accepted individually."},
775788
{RPCResult::Type::ARR, "replaced-transactions", /*optional=*/true, "List of txids of replaced transactions",
776789
{
777790
{RPCResult::Type::STR_HEX, "", "The transaction id"},
@@ -856,6 +869,7 @@ static RPCHelpMan submitpackage()
856869
CHECK_NONFATAL(it != package_result.m_tx_results.end());
857870
UniValue result_inner{UniValue::VOBJ};
858871
result_inner.pushKV("txid", tx->GetHash().GetHex());
872+
const auto& tx_result = it->second;
859873
if (it->second.m_result_type == MempoolAcceptResult::ResultType::DIFFERENT_WITNESS) {
860874
result_inner.pushKV("other-wtxid", it->second.m_other_wtxid.value().GetHex());
861875
}
@@ -864,6 +878,17 @@ static RPCHelpMan submitpackage()
864878
result_inner.pushKV("vsize", int64_t{it->second.m_vsize.value()});
865879
UniValue fees(UniValue::VOBJ);
866880
fees.pushKV("base", ValueFromAmount(it->second.m_base_fees.value()));
881+
if (tx_result.m_result_type == MempoolAcceptResult::ResultType::VALID) {
882+
// Effective feerate is not provided for MEMPOOL_ENTRY transactions even
883+
// though modified fees is known, because it is unknown whether package
884+
// feerate was used when it was originally submitted.
885+
fees.pushKV("effective-feerate", ValueFromAmount(tx_result.m_effective_feerate.value().GetFeePerK()));
886+
UniValue effective_includes_res(UniValue::VARR);
887+
for (const auto& wtxid : tx_result.m_wtxids_fee_calculations.value()) {
888+
effective_includes_res.push_back(wtxid.ToString());
889+
}
890+
fees.pushKV("effective-includes", effective_includes_res);
891+
}
867892
result_inner.pushKV("fees", fees);
868893
if (it->second.m_replaced_transactions.has_value()) {
869894
for (const auto& ptx : it->second.m_replaced_transactions.value()) {
@@ -874,9 +899,6 @@ static RPCHelpMan submitpackage()
874899
tx_result_map.pushKV(tx->GetWitnessHash().GetHex(), result_inner);
875900
}
876901
rpc_result.pushKV("tx-results", tx_result_map);
877-
if (package_result.m_package_feerate.has_value()) {
878-
rpc_result.pushKV("package-feerate", ValueFromAmount(package_result.m_package_feerate.value().GetFeePerK()));
879-
}
880902
UniValue replaced_list(UniValue::VARR);
881903
for (const uint256& hash : replaced_txids) replaced_list.push_back(hash.ToString());
882904
rpc_result.pushKV("replaced-transactions", replaced_list);

0 commit comments

Comments
 (0)