Bitcoin Core  29.1.0
P2P Digital Currency
mempool.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2022 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include <rpc/blockchain.h>
7 
8 #include <node/mempool_persist.h>
9 
10 #include <chainparams.h>
11 #include <consensus/validation.h>
12 #include <core_io.h>
13 #include <kernel/mempool_entry.h>
14 #include <net_processing.h>
16 #include <node/types.h>
17 #include <policy/rbf.h>
18 #include <policy/settings.h>
19 #include <primitives/transaction.h>
20 #include <rpc/server.h>
21 #include <rpc/server_util.h>
22 #include <rpc/util.h>
23 #include <txmempool.h>
24 #include <univalue.h>
25 #include <util/fs.h>
26 #include <util/moneystr.h>
27 #include <util/strencodings.h>
28 #include <util/time.h>
29 #include <util/vector.h>
30 
31 #include <utility>
32 
33 using node::DumpMempool;
34 
37 using node::MempoolPath;
38 using node::NodeContext;
40 using util::ToString;
41 
43 {
44  return RPCHelpMan{"sendrawtransaction",
45  "\nSubmit a raw transaction (serialized, hex-encoded) to local node and network.\n"
46  "\nThe transaction will be sent unconditionally to all peers, so using sendrawtransaction\n"
47  "for manual rebroadcast may degrade privacy by leaking the transaction's origin, as\n"
48  "nodes will normally not rebroadcast non-wallet transactions already in their mempool.\n"
49  "\nA specific exception, RPC_TRANSACTION_ALREADY_IN_UTXO_SET, may throw if the transaction cannot be added to the mempool.\n"
50  "\nRelated RPCs: createrawtransaction, signrawtransactionwithkey\n",
51  {
52  {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"},
54  "Reject transactions whose fee rate is higher than the specified value, expressed in " + CURRENCY_UNIT +
55  "/kvB.\nFee rates larger than 1BTC/kvB are rejected.\nSet to 0 to accept any fee rate."},
57  "Reject transactions with provably unspendable outputs (e.g. 'datacarrier' outputs that use the OP_RETURN opcode) greater than the specified value, expressed in " + CURRENCY_UNIT + ".\n"
58  "If burning funds through unspendable outputs is desired, increase this value.\n"
59  "This check is based on heuristics and does not guarantee spendability of outputs.\n"},
60  },
61  RPCResult{
62  RPCResult::Type::STR_HEX, "", "The transaction hash in hex"
63  },
65  "\nCreate a transaction\n"
66  + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
67  "Sign the transaction, and get back the hex\n"
68  + HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"") +
69  "\nSend the transaction (signed hex)\n"
70  + HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
71  "\nAs a JSON-RPC call\n"
72  + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
73  },
74  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
75  {
76  const CAmount max_burn_amount = request.params[2].isNull() ? 0 : AmountFromValue(request.params[2]);
77 
79  if (!DecodeHexTx(mtx, request.params[0].get_str())) {
80  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
81  }
82 
83  for (const auto& out : mtx.vout) {
84  if((out.scriptPubKey.IsUnspendable() || !out.scriptPubKey.HasValidOps()) && out.nValue > max_burn_amount) {
85  throw JSONRPCTransactionError(TransactionError::MAX_BURN_EXCEEDED);
86  }
87  }
88 
89  CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
90 
91  const CFeeRate max_raw_tx_fee_rate{ParseFeeRate(self.Arg<UniValue>("maxfeerate"))};
92 
93  int64_t virtual_size = GetVirtualTransactionSize(*tx);
94  CAmount max_raw_tx_fee = max_raw_tx_fee_rate.GetFee(virtual_size);
95 
96  std::string err_string;
98  NodeContext& node = EnsureAnyNodeContext(request.context);
99  const TransactionError err = BroadcastTransaction(node, tx, err_string, max_raw_tx_fee, /*relay=*/true, /*wait_callback=*/true);
100  if (TransactionError::OK != err) {
101  throw JSONRPCTransactionError(err, err_string);
102  }
103 
104  return tx->GetHash().GetHex();
105  },
106  };
107 }
108 
110 {
111  return RPCHelpMan{"testmempoolaccept",
112  "\nReturns result of mempool acceptance tests indicating if raw transaction(s) (serialized, hex-encoded) would be accepted by mempool.\n"
113  "\nIf multiple transactions are passed in, parents must come before children and package policies apply: the transactions cannot conflict with any mempool transactions or each other.\n"
114  "\nIf one transaction fails, other transactions may not be fully validated (the 'allowed' key will be blank).\n"
115  "\nThe maximum number of transactions allowed is " + ToString(MAX_PACKAGE_COUNT) + ".\n"
116  "\nThis checks if transactions violate the consensus or policy rules.\n"
117  "\nSee sendrawtransaction call.\n",
118  {
119  {"rawtxs", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of hex strings of raw transactions.",
120  {
122  },
123  },
125  "Reject transactions whose fee rate is higher than the specified value, expressed in " + CURRENCY_UNIT +
126  "/kvB.\nFee rates larger than 1BTC/kvB are rejected.\nSet to 0 to accept any fee rate."},
127  },
128  RPCResult{
129  RPCResult::Type::ARR, "", "The result of the mempool acceptance test for each raw transaction in the input array.\n"
130  "Returns results for each transaction in the same order they were passed in.\n"
131  "Transactions that cannot be fully validated due to failures in other transactions will not contain an 'allowed' result.\n",
132  {
133  {RPCResult::Type::OBJ, "", "",
134  {
135  {RPCResult::Type::STR_HEX, "txid", "The transaction hash in hex"},
136  {RPCResult::Type::STR_HEX, "wtxid", "The transaction witness hash in hex"},
137  {RPCResult::Type::STR, "package-error", /*optional=*/true, "Package validation error, if any (only possible if rawtxs had more than 1 transaction)."},
138  {RPCResult::Type::BOOL, "allowed", /*optional=*/true, "Whether this tx would be accepted to the mempool and pass client-specified maxfeerate. "
139  "If not present, the tx was not fully validated due to a failure in another tx in the list."},
140  {RPCResult::Type::NUM, "vsize", /*optional=*/true, "Virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted (only present when 'allowed' is true)"},
141  {RPCResult::Type::OBJ, "fees", /*optional=*/true, "Transaction fees (only present if 'allowed' is true)",
142  {
143  {RPCResult::Type::STR_AMOUNT, "base", "transaction fee in " + CURRENCY_UNIT},
144  {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."},
145  {RPCResult::Type::ARR, "effective-includes", /*optional=*/false, "transactions whose fees and vsizes are included in effective-feerate.",
146  {RPCResult{RPCResult::Type::STR_HEX, "", "transaction wtxid in hex"},
147  }},
148  }},
149  {RPCResult::Type::STR, "reject-reason", /*optional=*/true, "Rejection reason (only present when 'allowed' is false)"},
150  {RPCResult::Type::STR, "reject-details", /*optional=*/true, "Rejection details (only present when 'allowed' is false and rejection details exist)"},
151  }},
152  }
153  },
154  RPCExamples{
155  "\nCreate a transaction\n"
156  + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
157  "Sign the transaction, and get back the hex\n"
158  + HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"") +
159  "\nTest acceptance of the transaction (signed hex)\n"
160  + HelpExampleCli("testmempoolaccept", R"('["signedhex"]')") +
161  "\nAs a JSON-RPC call\n"
162  + HelpExampleRpc("testmempoolaccept", "[\"signedhex\"]")
163  },
164  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
165  {
166  const UniValue raw_transactions = request.params[0].get_array();
167  if (raw_transactions.size() < 1 || raw_transactions.size() > MAX_PACKAGE_COUNT) {
169  "Array must contain between 1 and " + ToString(MAX_PACKAGE_COUNT) + " transactions.");
170  }
171 
172  const CFeeRate max_raw_tx_fee_rate{ParseFeeRate(self.Arg<UniValue>("maxfeerate"))};
173 
174  std::vector<CTransactionRef> txns;
175  txns.reserve(raw_transactions.size());
176  for (const auto& rawtx : raw_transactions.getValues()) {
178  if (!DecodeHexTx(mtx, rawtx.get_str())) {
180  "TX decode failed: " + rawtx.get_str() + " Make sure the tx has at least one input.");
181  }
182  txns.emplace_back(MakeTransactionRef(std::move(mtx)));
183  }
184 
185  NodeContext& node = EnsureAnyNodeContext(request.context);
186  CTxMemPool& mempool = EnsureMemPool(node);
188  Chainstate& chainstate = chainman.ActiveChainstate();
189  const PackageMempoolAcceptResult package_result = [&] {
190  LOCK(::cs_main);
191  if (txns.size() > 1) return ProcessNewPackage(chainstate, mempool, txns, /*test_accept=*/true, /*client_maxfeerate=*/{});
192  return PackageMempoolAcceptResult(txns[0]->GetWitnessHash(),
193  chainman.ProcessTransaction(txns[0], /*test_accept=*/true));
194  }();
195 
196  UniValue rpc_result(UniValue::VARR);
197  // We will check transaction fees while we iterate through txns in order. If any transaction fee
198  // exceeds maxfeerate, we will leave the rest of the validation results blank, because it
199  // doesn't make sense to return a validation result for a transaction if its ancestor(s) would
200  // not be submitted.
201  bool exit_early{false};
202  for (const auto& tx : txns) {
203  UniValue result_inner(UniValue::VOBJ);
204  result_inner.pushKV("txid", tx->GetHash().GetHex());
205  result_inner.pushKV("wtxid", tx->GetWitnessHash().GetHex());
206  if (package_result.m_state.GetResult() == PackageValidationResult::PCKG_POLICY) {
207  result_inner.pushKV("package-error", package_result.m_state.ToString());
208  }
209  auto it = package_result.m_tx_results.find(tx->GetWitnessHash());
210  if (exit_early || it == package_result.m_tx_results.end()) {
211  // Validation unfinished. Just return the txid and wtxid.
212  rpc_result.push_back(std::move(result_inner));
213  continue;
214  }
215  const auto& tx_result = it->second;
216  // Package testmempoolaccept doesn't allow transactions to already be in the mempool.
218  if (tx_result.m_result_type == MempoolAcceptResult::ResultType::VALID) {
219  const CAmount fee = tx_result.m_base_fees.value();
220  // Check that fee does not exceed maximum fee
221  const int64_t virtual_size = tx_result.m_vsize.value();
222  const CAmount max_raw_tx_fee = max_raw_tx_fee_rate.GetFee(virtual_size);
223  if (max_raw_tx_fee && fee > max_raw_tx_fee) {
224  result_inner.pushKV("allowed", false);
225  result_inner.pushKV("reject-reason", "max-fee-exceeded");
226  exit_early = true;
227  } else {
228  // Only return the fee and vsize if the transaction would pass ATMP.
229  // These can be used to calculate the feerate.
230  result_inner.pushKV("allowed", true);
231  result_inner.pushKV("vsize", virtual_size);
232  UniValue fees(UniValue::VOBJ);
233  fees.pushKV("base", ValueFromAmount(fee));
234  fees.pushKV("effective-feerate", ValueFromAmount(tx_result.m_effective_feerate.value().GetFeePerK()));
235  UniValue effective_includes_res(UniValue::VARR);
236  for (const auto& wtxid : tx_result.m_wtxids_fee_calculations.value()) {
237  effective_includes_res.push_back(wtxid.ToString());
238  }
239  fees.pushKV("effective-includes", std::move(effective_includes_res));
240  result_inner.pushKV("fees", std::move(fees));
241  }
242  } else {
243  result_inner.pushKV("allowed", false);
244  const TxValidationState state = tx_result.m_state;
246  result_inner.pushKV("reject-reason", "missing-inputs");
247  } else {
248  result_inner.pushKV("reject-reason", state.GetRejectReason());
249  result_inner.pushKV("reject-details", state.ToString());
250  }
251  }
252  rpc_result.push_back(std::move(result_inner));
253  }
254  return rpc_result;
255  },
256  };
257 }
258 
259 static std::vector<RPCResult> MempoolEntryDescription()
260 {
261  return {
262  RPCResult{RPCResult::Type::NUM, "vsize", "virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted."},
263  RPCResult{RPCResult::Type::NUM, "weight", "transaction weight as defined in BIP 141."},
264  RPCResult{RPCResult::Type::NUM_TIME, "time", "local time transaction entered pool in seconds since 1 Jan 1970 GMT"},
265  RPCResult{RPCResult::Type::NUM, "height", "block height when transaction entered pool"},
266  RPCResult{RPCResult::Type::NUM, "descendantcount", "number of in-mempool descendant transactions (including this one)"},
267  RPCResult{RPCResult::Type::NUM, "descendantsize", "virtual transaction size of in-mempool descendants (including this one)"},
268  RPCResult{RPCResult::Type::NUM, "ancestorcount", "number of in-mempool ancestor transactions (including this one)"},
269  RPCResult{RPCResult::Type::NUM, "ancestorsize", "virtual transaction size of in-mempool ancestors (including this one)"},
270  RPCResult{RPCResult::Type::STR_HEX, "wtxid", "hash of serialized transaction, including witness data"},
271  RPCResult{RPCResult::Type::OBJ, "fees", "",
272  {
273  RPCResult{RPCResult::Type::STR_AMOUNT, "base", "transaction fee, denominated in " + CURRENCY_UNIT},
274  RPCResult{RPCResult::Type::STR_AMOUNT, "modified", "transaction fee with fee deltas used for mining priority, denominated in " + CURRENCY_UNIT},
275  RPCResult{RPCResult::Type::STR_AMOUNT, "ancestor", "transaction fees of in-mempool ancestors (including this one) with fee deltas used for mining priority, denominated in " + CURRENCY_UNIT},
276  RPCResult{RPCResult::Type::STR_AMOUNT, "descendant", "transaction fees of in-mempool descendants (including this one) with fee deltas used for mining priority, denominated in " + CURRENCY_UNIT},
277  }},
278  RPCResult{RPCResult::Type::ARR, "depends", "unconfirmed transactions used as inputs for this transaction",
279  {RPCResult{RPCResult::Type::STR_HEX, "transactionid", "parent transaction id"}}},
280  RPCResult{RPCResult::Type::ARR, "spentby", "unconfirmed transactions spending outputs from this transaction",
281  {RPCResult{RPCResult::Type::STR_HEX, "transactionid", "child transaction id"}}},
282  RPCResult{RPCResult::Type::BOOL, "bip125-replaceable", "Whether this transaction signals BIP125 replaceability or has an unconfirmed ancestor signaling BIP125 replaceability. (DEPRECATED)\n"},
283  RPCResult{RPCResult::Type::BOOL, "unbroadcast", "Whether this transaction is currently unbroadcast (initial broadcast not yet acknowledged by any peers)"},
284  };
285 }
286 
287 static void entryToJSON(const CTxMemPool& pool, UniValue& info, const CTxMemPoolEntry& e) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
288 {
289  AssertLockHeld(pool.cs);
290 
291  info.pushKV("vsize", (int)e.GetTxSize());
292  info.pushKV("weight", (int)e.GetTxWeight());
293  info.pushKV("time", count_seconds(e.GetTime()));
294  info.pushKV("height", (int)e.GetHeight());
295  info.pushKV("descendantcount", e.GetCountWithDescendants());
296  info.pushKV("descendantsize", e.GetSizeWithDescendants());
297  info.pushKV("ancestorcount", e.GetCountWithAncestors());
298  info.pushKV("ancestorsize", e.GetSizeWithAncestors());
299  info.pushKV("wtxid", e.GetTx().GetWitnessHash().ToString());
300 
301  UniValue fees(UniValue::VOBJ);
302  fees.pushKV("base", ValueFromAmount(e.GetFee()));
303  fees.pushKV("modified", ValueFromAmount(e.GetModifiedFee()));
304  fees.pushKV("ancestor", ValueFromAmount(e.GetModFeesWithAncestors()));
305  fees.pushKV("descendant", ValueFromAmount(e.GetModFeesWithDescendants()));
306  info.pushKV("fees", std::move(fees));
307 
308  const CTransaction& tx = e.GetTx();
309  std::set<std::string> setDepends;
310  for (const CTxIn& txin : tx.vin)
311  {
312  if (pool.exists(GenTxid::Txid(txin.prevout.hash)))
313  setDepends.insert(txin.prevout.hash.ToString());
314  }
315 
316  UniValue depends(UniValue::VARR);
317  for (const std::string& dep : setDepends)
318  {
319  depends.push_back(dep);
320  }
321 
322  info.pushKV("depends", std::move(depends));
323 
324  UniValue spent(UniValue::VARR);
325  for (const CTxMemPoolEntry& child : e.GetMemPoolChildrenConst()) {
326  spent.push_back(child.GetTx().GetHash().ToString());
327  }
328 
329  info.pushKV("spentby", std::move(spent));
330 
331  // Add opt-in RBF status
332  bool rbfStatus = false;
333  RBFTransactionState rbfState = IsRBFOptIn(tx, pool);
334  if (rbfState == RBFTransactionState::UNKNOWN) {
335  throw JSONRPCError(RPC_MISC_ERROR, "Transaction is not in mempool");
336  } else if (rbfState == RBFTransactionState::REPLACEABLE_BIP125) {
337  rbfStatus = true;
338  }
339 
340  info.pushKV("bip125-replaceable", rbfStatus);
341  info.pushKV("unbroadcast", pool.IsUnbroadcastTx(tx.GetHash()));
342 }
343 
344 UniValue MempoolToJSON(const CTxMemPool& pool, bool verbose, bool include_mempool_sequence)
345 {
346  if (verbose) {
347  if (include_mempool_sequence) {
348  throw JSONRPCError(RPC_INVALID_PARAMETER, "Verbose results cannot contain mempool sequence values.");
349  }
350  LOCK(pool.cs);
352  for (const CTxMemPoolEntry& e : pool.entryAll()) {
353  UniValue info(UniValue::VOBJ);
354  entryToJSON(pool, info, e);
355  // Mempool has unique entries so there is no advantage in using
356  // UniValue::pushKV, which checks if the key already exists in O(N).
357  // UniValue::pushKVEnd is used instead which currently is O(1).
358  o.pushKVEnd(e.GetTx().GetHash().ToString(), std::move(info));
359  }
360  return o;
361  } else {
363  uint64_t mempool_sequence;
364  {
365  LOCK(pool.cs);
366  for (const CTxMemPoolEntry& e : pool.entryAll()) {
367  a.push_back(e.GetTx().GetHash().ToString());
368  }
369  mempool_sequence = pool.GetSequence();
370  }
371  if (!include_mempool_sequence) {
372  return a;
373  } else {
375  o.pushKV("txids", std::move(a));
376  o.pushKV("mempool_sequence", mempool_sequence);
377  return o;
378  }
379  }
380 }
381 
383 {
384  return RPCHelpMan{"getrawmempool",
385  "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
386  "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n",
387  {
388  {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "True for a json object, false for array of transaction ids"},
389  {"mempool_sequence", RPCArg::Type::BOOL, RPCArg::Default{false}, "If verbose=false, returns a json object with transaction list and mempool sequence number attached."},
390  },
391  {
392  RPCResult{"for verbose = false",
393  RPCResult::Type::ARR, "", "",
394  {
395  {RPCResult::Type::STR_HEX, "", "The transaction id"},
396  }},
397  RPCResult{"for verbose = true",
398  RPCResult::Type::OBJ_DYN, "", "",
399  {
400  {RPCResult::Type::OBJ, "transactionid", "", MempoolEntryDescription()},
401  }},
402  RPCResult{"for verbose = false and mempool_sequence = true",
403  RPCResult::Type::OBJ, "", "",
404  {
405  {RPCResult::Type::ARR, "txids", "",
406  {
407  {RPCResult::Type::STR_HEX, "", "The transaction id"},
408  }},
409  {RPCResult::Type::NUM, "mempool_sequence", "The mempool sequence value."},
410  }},
411  },
412  RPCExamples{
413  HelpExampleCli("getrawmempool", "true")
414  + HelpExampleRpc("getrawmempool", "true")
415  },
416  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
417 {
418  bool fVerbose = false;
419  if (!request.params[0].isNull())
420  fVerbose = request.params[0].get_bool();
421 
422  bool include_mempool_sequence = false;
423  if (!request.params[1].isNull()) {
424  include_mempool_sequence = request.params[1].get_bool();
425  }
426 
427  return MempoolToJSON(EnsureAnyMemPool(request.context), fVerbose, include_mempool_sequence);
428 },
429  };
430 }
431 
433 {
434  return RPCHelpMan{"getmempoolancestors",
435  "\nIf txid is in the mempool, returns all in-mempool ancestors.\n",
436  {
437  {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"},
438  {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "True for a json object, false for array of transaction ids"},
439  },
440  {
441  RPCResult{"for verbose = false",
442  RPCResult::Type::ARR, "", "",
443  {{RPCResult::Type::STR_HEX, "", "The transaction id of an in-mempool ancestor transaction"}}},
444  RPCResult{"for verbose = true",
445  RPCResult::Type::OBJ_DYN, "", "",
446  {
447  {RPCResult::Type::OBJ, "transactionid", "", MempoolEntryDescription()},
448  }},
449  },
450  RPCExamples{
451  HelpExampleCli("getmempoolancestors", "\"mytxid\"")
452  + HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
453  },
454  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
455 {
456  bool fVerbose = false;
457  if (!request.params[1].isNull())
458  fVerbose = request.params[1].get_bool();
459 
460  uint256 hash = ParseHashV(request.params[0], "parameter 1");
461 
462  const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
463  LOCK(mempool.cs);
464 
465  const auto entry{mempool.GetEntry(Txid::FromUint256(hash))};
466  if (entry == nullptr) {
467  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
468  }
469 
470  auto ancestors{mempool.AssumeCalculateMemPoolAncestors(self.m_name, *entry, CTxMemPool::Limits::NoLimits(), /*fSearchForParents=*/false)};
471 
472  if (!fVerbose) {
474  for (CTxMemPool::txiter ancestorIt : ancestors) {
475  o.push_back(ancestorIt->GetTx().GetHash().ToString());
476  }
477  return o;
478  } else {
480  for (CTxMemPool::txiter ancestorIt : ancestors) {
481  const CTxMemPoolEntry &e = *ancestorIt;
482  const uint256& _hash = e.GetTx().GetHash();
483  UniValue info(UniValue::VOBJ);
484  entryToJSON(mempool, info, e);
485  o.pushKV(_hash.ToString(), std::move(info));
486  }
487  return o;
488  }
489 },
490  };
491 }
492 
494 {
495  return RPCHelpMan{"getmempooldescendants",
496  "\nIf txid is in the mempool, returns all in-mempool descendants.\n",
497  {
498  {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"},
499  {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "True for a json object, false for array of transaction ids"},
500  },
501  {
502  RPCResult{"for verbose = false",
503  RPCResult::Type::ARR, "", "",
504  {{RPCResult::Type::STR_HEX, "", "The transaction id of an in-mempool descendant transaction"}}},
505  RPCResult{"for verbose = true",
506  RPCResult::Type::OBJ_DYN, "", "",
507  {
508  {RPCResult::Type::OBJ, "transactionid", "", MempoolEntryDescription()},
509  }},
510  },
511  RPCExamples{
512  HelpExampleCli("getmempooldescendants", "\"mytxid\"")
513  + HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
514  },
515  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
516 {
517  bool fVerbose = false;
518  if (!request.params[1].isNull())
519  fVerbose = request.params[1].get_bool();
520 
521  uint256 hash = ParseHashV(request.params[0], "parameter 1");
522 
523  const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
524  LOCK(mempool.cs);
525 
526  const auto it{mempool.GetIter(hash)};
527  if (!it) {
528  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
529  }
530 
531  CTxMemPool::setEntries setDescendants;
532  mempool.CalculateDescendants(*it, setDescendants);
533  // CTxMemPool::CalculateDescendants will include the given tx
534  setDescendants.erase(*it);
535 
536  if (!fVerbose) {
538  for (CTxMemPool::txiter descendantIt : setDescendants) {
539  o.push_back(descendantIt->GetTx().GetHash().ToString());
540  }
541 
542  return o;
543  } else {
545  for (CTxMemPool::txiter descendantIt : setDescendants) {
546  const CTxMemPoolEntry &e = *descendantIt;
547  const uint256& _hash = e.GetTx().GetHash();
548  UniValue info(UniValue::VOBJ);
549  entryToJSON(mempool, info, e);
550  o.pushKV(_hash.ToString(), std::move(info));
551  }
552  return o;
553  }
554 },
555  };
556 }
557 
559 {
560  return RPCHelpMan{"getmempoolentry",
561  "\nReturns mempool data for given transaction\n",
562  {
563  {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"},
564  },
565  RPCResult{
567  RPCExamples{
568  HelpExampleCli("getmempoolentry", "\"mytxid\"")
569  + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
570  },
571  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
572 {
573  uint256 hash = ParseHashV(request.params[0], "parameter 1");
574 
575  const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
576  LOCK(mempool.cs);
577 
578  const auto entry{mempool.GetEntry(Txid::FromUint256(hash))};
579  if (entry == nullptr) {
580  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
581  }
582 
583  UniValue info(UniValue::VOBJ);
584  entryToJSON(mempool, info, *entry);
585  return info;
586 },
587  };
588 }
589 
591 {
592  return RPCHelpMan{"gettxspendingprevout",
593  "Scans the mempool to find transactions spending any of the given outputs",
594  {
595  {"outputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The transaction outputs that we want to check, and within each, the txid (string) vout (numeric).",
596  {
598  {
599  {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
600  {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
601  },
602  },
603  },
604  },
605  },
606  RPCResult{
607  RPCResult::Type::ARR, "", "",
608  {
609  {RPCResult::Type::OBJ, "", "",
610  {
611  {RPCResult::Type::STR_HEX, "txid", "the transaction id of the checked output"},
612  {RPCResult::Type::NUM, "vout", "the vout value of the checked output"},
613  {RPCResult::Type::STR_HEX, "spendingtxid", /*optional=*/true, "the transaction id of the mempool transaction spending this output (omitted if unspent)"},
614  }},
615  }
616  },
617  RPCExamples{
618  HelpExampleCli("gettxspendingprevout", "\"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":3}]\"")
619  + HelpExampleRpc("gettxspendingprevout", "\"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":3}]\"")
620  },
621  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
622  {
623  const UniValue& output_params = request.params[0].get_array();
624  if (output_params.empty()) {
625  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, outputs are missing");
626  }
627 
628  std::vector<COutPoint> prevouts;
629  prevouts.reserve(output_params.size());
630 
631  for (unsigned int idx = 0; idx < output_params.size(); idx++) {
632  const UniValue& o = output_params[idx].get_obj();
633 
634  RPCTypeCheckObj(o,
635  {
636  {"txid", UniValueType(UniValue::VSTR)},
637  {"vout", UniValueType(UniValue::VNUM)},
638  }, /*fAllowNull=*/false, /*fStrict=*/true);
639 
640  const Txid txid = Txid::FromUint256(ParseHashO(o, "txid"));
641  const int nOutput{o.find_value("vout").getInt<int>()};
642  if (nOutput < 0) {
643  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout cannot be negative");
644  }
645 
646  prevouts.emplace_back(txid, nOutput);
647  }
648 
649  const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
650  LOCK(mempool.cs);
651 
653 
654  for (const COutPoint& prevout : prevouts) {
656  o.pushKV("txid", prevout.hash.ToString());
657  o.pushKV("vout", (uint64_t)prevout.n);
658 
659  const CTransaction* spendingTx = mempool.GetConflictTx(prevout);
660  if (spendingTx != nullptr) {
661  o.pushKV("spendingtxid", spendingTx->GetHash().ToString());
662  }
663 
664  result.push_back(std::move(o));
665  }
666 
667  return result;
668  },
669  };
670 }
671 
673 {
674  // Make sure this call is atomic in the pool.
675  LOCK(pool.cs);
677  ret.pushKV("loaded", pool.GetLoadTried());
678  ret.pushKV("size", (int64_t)pool.size());
679  ret.pushKV("bytes", (int64_t)pool.GetTotalTxSize());
680  ret.pushKV("usage", (int64_t)pool.DynamicMemoryUsage());
681  ret.pushKV("total_fee", ValueFromAmount(pool.GetTotalFee()));
682  ret.pushKV("maxmempool", pool.m_opts.max_size_bytes);
683  ret.pushKV("mempoolminfee", ValueFromAmount(std::max(pool.GetMinFee(), pool.m_opts.min_relay_feerate).GetFeePerK()));
684  ret.pushKV("minrelaytxfee", ValueFromAmount(pool.m_opts.min_relay_feerate.GetFeePerK()));
685  ret.pushKV("incrementalrelayfee", ValueFromAmount(pool.m_opts.incremental_relay_feerate.GetFeePerK()));
686  ret.pushKV("unbroadcastcount", uint64_t{pool.GetUnbroadcastTxs().size()});
687  ret.pushKV("fullrbf", true);
688  return ret;
689 }
690 
692 {
693  return RPCHelpMan{"getmempoolinfo",
694  "Returns details on the active state of the TX memory pool.",
695  {},
696  RPCResult{
697  RPCResult::Type::OBJ, "", "",
698  {
699  {RPCResult::Type::BOOL, "loaded", "True if the initial load attempt of the persisted mempool finished"},
700  {RPCResult::Type::NUM, "size", "Current tx count"},
701  {RPCResult::Type::NUM, "bytes", "Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted"},
702  {RPCResult::Type::NUM, "usage", "Total memory usage for the mempool"},
703  {RPCResult::Type::STR_AMOUNT, "total_fee", "Total fees for the mempool in " + CURRENCY_UNIT + ", ignoring modified fees through prioritisetransaction"},
704  {RPCResult::Type::NUM, "maxmempool", "Maximum memory usage for the mempool"},
705  {RPCResult::Type::STR_AMOUNT, "mempoolminfee", "Minimum fee rate in " + CURRENCY_UNIT + "/kvB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee"},
706  {RPCResult::Type::STR_AMOUNT, "minrelaytxfee", "Current minimum relay fee for transactions"},
707  {RPCResult::Type::NUM, "incrementalrelayfee", "minimum fee rate increment for mempool limiting or replacement in " + CURRENCY_UNIT + "/kvB"},
708  {RPCResult::Type::NUM, "unbroadcastcount", "Current number of transactions that haven't passed initial broadcast yet"},
709  {RPCResult::Type::BOOL, "fullrbf", "True if the mempool accepts RBF without replaceability signaling inspection (DEPRECATED)"},
710  }},
711  RPCExamples{
712  HelpExampleCli("getmempoolinfo", "")
713  + HelpExampleRpc("getmempoolinfo", "")
714  },
715  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
716 {
717  return MempoolInfoToJSON(EnsureAnyMemPool(request.context));
718 },
719  };
720 }
721 
723 {
724  return RPCHelpMan{
725  "importmempool",
726  "Import a mempool.dat file and attempt to add its contents to the mempool.\n"
727  "Warning: Importing untrusted files is dangerous, especially if metadata from the file is taken over.",
728  {
729  {"filepath", RPCArg::Type::STR, RPCArg::Optional::NO, "The mempool file"},
730  {"options",
733  "",
734  {
735  {"use_current_time", RPCArg::Type::BOOL, RPCArg::Default{true},
736  "Whether to use the current system time or use the entry time metadata from the mempool file.\n"
737  "Warning: Importing untrusted metadata may lead to unexpected issues and undesirable behavior."},
738  {"apply_fee_delta_priority", RPCArg::Type::BOOL, RPCArg::Default{false},
739  "Whether to apply the fee delta metadata from the mempool file.\n"
740  "It will be added to any existing fee deltas.\n"
741  "The fee delta can be set by the prioritisetransaction RPC.\n"
742  "Warning: Importing untrusted metadata may lead to unexpected issues and undesirable behavior.\n"
743  "Only set this bool if you understand what it does."},
744  {"apply_unbroadcast_set", RPCArg::Type::BOOL, RPCArg::Default{false},
745  "Whether to apply the unbroadcast set metadata from the mempool file.\n"
746  "Warning: Importing untrusted metadata may lead to unexpected issues and undesirable behavior."},
747  },
748  RPCArgOptions{.oneline_description = "options"}},
749  },
750  RPCResult{RPCResult::Type::OBJ, "", "", std::vector<RPCResult>{}},
751  RPCExamples{HelpExampleCli("importmempool", "/path/to/mempool.dat") + HelpExampleRpc("importmempool", "/path/to/mempool.dat")},
752  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
753  const NodeContext& node{EnsureAnyNodeContext(request.context)};
754 
755  CTxMemPool& mempool{EnsureMemPool(node)};
757  Chainstate& chainstate = chainman.ActiveChainstate();
758 
759  if (chainman.IsInitialBlockDownload()) {
760  throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Can only import the mempool after the block download and sync is done.");
761  }
762 
763  const fs::path load_path{fs::u8path(request.params[0].get_str())};
764  const UniValue& use_current_time{request.params[1]["use_current_time"]};
765  const UniValue& apply_fee_delta{request.params[1]["apply_fee_delta_priority"]};
766  const UniValue& apply_unbroadcast{request.params[1]["apply_unbroadcast_set"]};
768  .use_current_time = use_current_time.isNull() ? true : use_current_time.get_bool(),
769  .apply_fee_delta_priority = apply_fee_delta.isNull() ? false : apply_fee_delta.get_bool(),
770  .apply_unbroadcast_set = apply_unbroadcast.isNull() ? false : apply_unbroadcast.get_bool(),
771  };
772 
773  if (!node::LoadMempool(mempool, load_path, chainstate, std::move(opts))) {
774  throw JSONRPCError(RPC_MISC_ERROR, "Unable to import mempool file, see debug.log for details.");
775  }
776 
778  return ret;
779  },
780  };
781 }
782 
784 {
785  return RPCHelpMan{"savemempool",
786  "\nDumps the mempool to disk. It will fail until the previous dump is fully loaded.\n",
787  {},
788  RPCResult{
789  RPCResult::Type::OBJ, "", "",
790  {
791  {RPCResult::Type::STR, "filename", "the directory and file where the mempool was saved"},
792  }},
793  RPCExamples{
794  HelpExampleCli("savemempool", "")
795  + HelpExampleRpc("savemempool", "")
796  },
797  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
798 {
799  const ArgsManager& args{EnsureAnyArgsman(request.context)};
800  const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
801 
802  if (!mempool.GetLoadTried()) {
803  throw JSONRPCError(RPC_MISC_ERROR, "The mempool was not loaded yet");
804  }
805 
806  const fs::path& dump_path = MempoolPath(args);
807 
808  if (!DumpMempool(mempool, dump_path)) {
809  throw JSONRPCError(RPC_MISC_ERROR, "Unable to dump mempool to disk");
810  }
811 
813  ret.pushKV("filename", dump_path.utf8string());
814 
815  return ret;
816 },
817  };
818 }
819 
820 static std::vector<RPCResult> OrphanDescription()
821 {
822  return {
823  RPCResult{RPCResult::Type::STR_HEX, "txid", "The transaction hash in hex"},
824  RPCResult{RPCResult::Type::STR_HEX, "wtxid", "The transaction witness hash in hex"},
825  RPCResult{RPCResult::Type::NUM, "bytes", "The serialized transaction size in bytes"},
826  RPCResult{RPCResult::Type::NUM, "vsize", "The virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted."},
827  RPCResult{RPCResult::Type::NUM, "weight", "The transaction weight as defined in BIP 141."},
828  RPCResult{RPCResult::Type::NUM_TIME, "entry", "The entry time into the orphanage expressed in " + UNIX_EPOCH_TIME},
829  RPCResult{RPCResult::Type::NUM_TIME, "expiration", "The orphan expiration time expressed in " + UNIX_EPOCH_TIME},
830  RPCResult{RPCResult::Type::ARR, "from", "",
831  {
832  RPCResult{RPCResult::Type::NUM, "peer_id", "Peer ID"},
833  }},
834  };
835 }
836 
838 {
840  o.pushKV("txid", orphan.tx->GetHash().ToString());
841  o.pushKV("wtxid", orphan.tx->GetWitnessHash().ToString());
842  o.pushKV("bytes", orphan.tx->GetTotalSize());
843  o.pushKV("vsize", GetVirtualTransactionSize(*orphan.tx));
844  o.pushKV("weight", GetTransactionWeight(*orphan.tx));
845  o.pushKV("entry", int64_t{TicksSinceEpoch<std::chrono::seconds>(orphan.nTimeExpire - ORPHAN_TX_EXPIRE_TIME)});
846  o.pushKV("expiration", int64_t{TicksSinceEpoch<std::chrono::seconds>(orphan.nTimeExpire)});
847  UniValue from(UniValue::VARR);
848  for (const auto fromPeer: orphan.announcers) {
849  from.push_back(fromPeer);
850  }
851  o.pushKV("from", from);
852  return o;
853 }
854 
856 {
857  return RPCHelpMan{"getorphantxs",
858  "\nShows transactions in the tx orphanage.\n"
859  "\nEXPERIMENTAL warning: this call may be changed in future releases.\n",
860  {
861  {"verbosity", RPCArg::Type::NUM, RPCArg::Default{0}, "0 for an array of txids (may contain duplicates), 1 for an array of objects with tx details, and 2 for details from (1) and tx hex",
862  RPCArgOptions{.skip_type_check = true}},
863  },
864  {
865  RPCResult{"for verbose = 0",
866  RPCResult::Type::ARR, "", "",
867  {
868  {RPCResult::Type::STR_HEX, "txid", "The transaction hash in hex"},
869  }},
870  RPCResult{"for verbose = 1",
871  RPCResult::Type::ARR, "", "",
872  {
874  }},
875  RPCResult{"for verbose = 2",
876  RPCResult::Type::ARR, "", "",
877  {
878  {RPCResult::Type::OBJ, "", "",
879  Cat<std::vector<RPCResult>>(
881  {{RPCResult::Type::STR_HEX, "hex", "The serialized, hex-encoded transaction data"}}
882  )
883  },
884  }},
885  },
886  RPCExamples{
887  HelpExampleCli("getorphantxs", "2")
888  + HelpExampleRpc("getorphantxs", "2")
889  },
890  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
891  {
892  const NodeContext& node = EnsureAnyNodeContext(request.context);
893  PeerManager& peerman = EnsurePeerman(node);
894  std::vector<TxOrphanage::OrphanTxBase> orphanage = peerman.GetOrphanTransactions();
895 
896  int verbosity{ParseVerbosity(request.params[0], /*default_verbosity=*/0, /*allow_bool*/false)};
897 
899 
900  if (verbosity == 0) {
901  for (auto const& orphan : orphanage) {
902  ret.push_back(orphan.tx->GetHash().ToString());
903  }
904  } else if (verbosity == 1) {
905  for (auto const& orphan : orphanage) {
906  ret.push_back(OrphanToJSON(orphan));
907  }
908  } else if (verbosity == 2) {
909  for (auto const& orphan : orphanage) {
910  UniValue o{OrphanToJSON(orphan)};
911  o.pushKV("hex", EncodeHexTx(*orphan.tx));
912  ret.push_back(o);
913  }
914  } else {
915  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid verbosity value " + ToString(verbosity));
916  }
917 
918  return ret;
919  },
920  };
921 }
922 
924 {
925  return RPCHelpMan{"submitpackage",
926  "Submit a package of raw transactions (serialized, hex-encoded) to local node.\n"
927  "The package will be validated according to consensus and mempool policy rules. If any transaction passes, it will be accepted to mempool.\n"
928  "This RPC is experimental and the interface may be unstable. Refer to doc/policy/packages.md for documentation on package policies.\n"
929  "Warning: successful submission does not mean the transactions will propagate throughout the network.\n"
930  ,
931  {
932  {"package", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of raw transactions.\n"
933  "The package must solely consist of a child transaction and all of its unconfirmed parents, if any. None of the parents may depend on each other.\n"
934  "The package must be topologically sorted, with the child being the last element in the array.",
935  {
937  },
938  },
940  "Reject transactions whose fee rate is higher than the specified value, expressed in " + CURRENCY_UNIT +
941  "/kvB.\nFee rates larger than 1BTC/kvB are rejected.\nSet to 0 to accept any fee rate."},
943  "Reject transactions with provably unspendable outputs (e.g. 'datacarrier' outputs that use the OP_RETURN opcode) greater than the specified value, expressed in " + CURRENCY_UNIT + ".\n"
944  "If burning funds through unspendable outputs is desired, increase this value.\n"
945  "This check is based on heuristics and does not guarantee spendability of outputs.\n"
946  },
947  },
948  RPCResult{
949  RPCResult::Type::OBJ, "", "",
950  {
951  {RPCResult::Type::STR, "package_msg", "The transaction package result message. \"success\" indicates all transactions were accepted into or are already in the mempool."},
952  {RPCResult::Type::OBJ_DYN, "tx-results", "transaction results keyed by wtxid",
953  {
954  {RPCResult::Type::OBJ, "wtxid", "transaction wtxid", {
955  {RPCResult::Type::STR_HEX, "txid", "The transaction hash in hex"},
956  {RPCResult::Type::STR_HEX, "other-wtxid", /*optional=*/true, "The wtxid of a different transaction with the same txid but different witness found in the mempool. This means the submitted transaction was ignored."},
957  {RPCResult::Type::NUM, "vsize", /*optional=*/true, "Sigops-adjusted virtual transaction size."},
958  {RPCResult::Type::OBJ, "fees", /*optional=*/true, "Transaction fees", {
959  {RPCResult::Type::STR_AMOUNT, "base", "transaction fee in " + CURRENCY_UNIT},
960  {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."},
961  {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.",
962  {{RPCResult::Type::STR_HEX, "", "transaction wtxid in hex"},
963  }},
964  }},
965  {RPCResult::Type::STR, "error", /*optional=*/true, "The transaction error string, if it was rejected by the mempool"},
966  }}
967  }},
968  {RPCResult::Type::ARR, "replaced-transactions", /*optional=*/true, "List of txids of replaced transactions",
969  {
970  {RPCResult::Type::STR_HEX, "", "The transaction id"},
971  }},
972  },
973  },
974  RPCExamples{
975  HelpExampleRpc("submitpackage", R"(["raw-parent-tx-1", "raw-parent-tx-2", "raw-child-tx"])") +
976  HelpExampleCli("submitpackage", R"('["raw-tx-without-unconfirmed-parents"]')")
977  },
978  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
979  {
980  const UniValue raw_transactions = request.params[0].get_array();
981  if (raw_transactions.empty() || raw_transactions.size() > MAX_PACKAGE_COUNT) {
983  "Array must contain between 1 and " + ToString(MAX_PACKAGE_COUNT) + " transactions.");
984  }
985 
986  // Fee check needs to be run with chainstate and package context
987  const CFeeRate max_raw_tx_fee_rate{ParseFeeRate(self.Arg<UniValue>("maxfeerate"))};
988  std::optional<CFeeRate> client_maxfeerate{max_raw_tx_fee_rate};
989  // 0-value is special; it's mapped to no sanity check
990  if (max_raw_tx_fee_rate == CFeeRate(0)) {
991  client_maxfeerate = std::nullopt;
992  }
993 
994  // Burn sanity check is run with no context
995  const CAmount max_burn_amount = request.params[2].isNull() ? 0 : AmountFromValue(request.params[2]);
996 
997  std::vector<CTransactionRef> txns;
998  txns.reserve(raw_transactions.size());
999  for (const auto& rawtx : raw_transactions.getValues()) {
1000  CMutableTransaction mtx;
1001  if (!DecodeHexTx(mtx, rawtx.get_str())) {
1003  "TX decode failed: " + rawtx.get_str() + " Make sure the tx has at least one input.");
1004  }
1005 
1006  for (const auto& out : mtx.vout) {
1007  if((out.scriptPubKey.IsUnspendable() || !out.scriptPubKey.HasValidOps()) && out.nValue > max_burn_amount) {
1008  throw JSONRPCTransactionError(TransactionError::MAX_BURN_EXCEEDED);
1009  }
1010  }
1011 
1012  txns.emplace_back(MakeTransactionRef(std::move(mtx)));
1013  }
1014  CHECK_NONFATAL(!txns.empty());
1015  if (txns.size() > 1 && !IsChildWithParentsTree(txns)) {
1016  throw JSONRPCTransactionError(TransactionError::INVALID_PACKAGE, "package topology disallowed. not child-with-parents or parents depend on each other.");
1017  }
1018 
1019  NodeContext& node = EnsureAnyNodeContext(request.context);
1020  CTxMemPool& mempool = EnsureMemPool(node);
1022  const auto package_result = WITH_LOCK(::cs_main, return ProcessNewPackage(chainstate, mempool, txns, /*test_accept=*/ false, client_maxfeerate));
1023 
1024  std::string package_msg = "success";
1025 
1026  // First catch package-wide errors, continue if we can
1027  switch(package_result.m_state.GetResult()) {
1029  {
1030  // Belt-and-suspenders check; everything should be successful here
1031  CHECK_NONFATAL(package_result.m_tx_results.size() == txns.size());
1032  for (const auto& tx : txns) {
1033  CHECK_NONFATAL(mempool.exists(GenTxid::Txid(tx->GetHash())));
1034  }
1035  break;
1036  }
1038  {
1039  // This only happens with internal bug; user should stop and report
1040  throw JSONRPCTransactionError(TransactionError::MEMPOOL_ERROR,
1041  package_result.m_state.GetRejectReason());
1042  }
1045  {
1046  // Package-wide error we want to return, but we also want to return individual responses
1047  package_msg = package_result.m_state.ToString();
1048  CHECK_NONFATAL(package_result.m_tx_results.size() == txns.size() ||
1049  package_result.m_tx_results.empty());
1050  break;
1051  }
1052  }
1053 
1054  size_t num_broadcast{0};
1055  for (const auto& tx : txns) {
1056  // We don't want to re-submit the txn for validation in BroadcastTransaction
1057  if (!mempool.exists(GenTxid::Txid(tx->GetHash()))) {
1058  continue;
1059  }
1060 
1061  // We do not expect an error here; we are only broadcasting things already/still in mempool
1062  std::string err_string;
1063  const auto err = BroadcastTransaction(node, tx, err_string, /*max_tx_fee=*/0, /*relay=*/true, /*wait_callback=*/true);
1064  if (err != TransactionError::OK) {
1065  throw JSONRPCTransactionError(err,
1066  strprintf("transaction broadcast failed: %s (%d transactions were broadcast successfully)",
1067  err_string, num_broadcast));
1068  }
1069  num_broadcast++;
1070  }
1071 
1072  UniValue rpc_result{UniValue::VOBJ};
1073  rpc_result.pushKV("package_msg", package_msg);
1074  UniValue tx_result_map{UniValue::VOBJ};
1075  std::set<uint256> replaced_txids;
1076  for (const auto& tx : txns) {
1077  UniValue result_inner{UniValue::VOBJ};
1078  result_inner.pushKV("txid", tx->GetHash().GetHex());
1079  auto it = package_result.m_tx_results.find(tx->GetWitnessHash());
1080  if (it == package_result.m_tx_results.end()) {
1081  // No results, report error and continue
1082  result_inner.pushKV("error", "unevaluated");
1083  continue;
1084  }
1085  const auto& tx_result = it->second;
1086  switch(it->second.m_result_type) {
1088  result_inner.pushKV("other-wtxid", it->second.m_other_wtxid.value().GetHex());
1089  break;
1091  result_inner.pushKV("error", it->second.m_state.ToString());
1092  break;
1095  result_inner.pushKV("vsize", int64_t{it->second.m_vsize.value()});
1096  UniValue fees(UniValue::VOBJ);
1097  fees.pushKV("base", ValueFromAmount(it->second.m_base_fees.value()));
1098  if (tx_result.m_result_type == MempoolAcceptResult::ResultType::VALID) {
1099  // Effective feerate is not provided for MEMPOOL_ENTRY transactions even
1100  // though modified fees is known, because it is unknown whether package
1101  // feerate was used when it was originally submitted.
1102  fees.pushKV("effective-feerate", ValueFromAmount(tx_result.m_effective_feerate.value().GetFeePerK()));
1103  UniValue effective_includes_res(UniValue::VARR);
1104  for (const auto& wtxid : tx_result.m_wtxids_fee_calculations.value()) {
1105  effective_includes_res.push_back(wtxid.ToString());
1106  }
1107  fees.pushKV("effective-includes", std::move(effective_includes_res));
1108  }
1109  result_inner.pushKV("fees", std::move(fees));
1110  for (const auto& ptx : it->second.m_replaced_transactions) {
1111  replaced_txids.insert(ptx->GetHash());
1112  }
1113  break;
1114  }
1115  tx_result_map.pushKV(tx->GetWitnessHash().GetHex(), std::move(result_inner));
1116  }
1117  rpc_result.pushKV("tx-results", std::move(tx_result_map));
1118  UniValue replaced_list(UniValue::VARR);
1119  for (const uint256& hash : replaced_txids) replaced_list.push_back(hash.ToString());
1120  rpc_result.pushKV("replaced-transactions", std::move(replaced_list));
1121  return rpc_result;
1122  },
1123  };
1124 }
1125 
1127 {
1128  static const CRPCCommand commands[]{
1129  {"rawtransactions", &sendrawtransaction},
1130  {"rawtransactions", &testmempoolaccept},
1131  {"blockchain", &getmempoolancestors},
1132  {"blockchain", &getmempooldescendants},
1133  {"blockchain", &getmempoolentry},
1134  {"blockchain", &gettxspendingprevout},
1135  {"blockchain", &getmempoolinfo},
1136  {"blockchain", &getrawmempool},
1137  {"blockchain", &importmempool},
1138  {"blockchain", &savemempool},
1139  {"hidden", &getorphantxs},
1140  {"rawtransactions", &submitpackage},
1141  };
1142  for (const auto& c : commands) {
1143  t.appendCommand(c.name, &c);
1144  }
1145 }
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:423
TransactionError
Definition: types.h:21
void RegisterMempoolRPCCommands(CRPCTable &t)
Definition: mempool.cpp:1126
void push_back(UniValue val)
Definition: univalue.cpp:104
UniValue MempoolToJSON(const CTxMemPool &pool, bool verbose, bool include_mempool_sequence)
Mempool to JSON.
Definition: mempool.cpp:344
int ret
static RPCHelpMan getrawmempool()
Definition: mempool.cpp:382
AssertLockHeld(pool.cs)
const std::vector< UniValue > & getValues() const
RPC command dispatcher.
Definition: server.h:126
uint256 ParseHashO(const UniValue &o, std::string_view strKey)
Definition: util.cpp:129
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
Definition: txmempool.h:393
static constexpr auto ORPHAN_TX_EXPIRE_TIME
Expiration time for orphan transactions.
Definition: txorphanage.h:19
static RPCHelpMan getmempoolancestors()
Definition: mempool.cpp:432
void RPCTypeCheckObj(const UniValue &o, const std::map< std::string, UniValueType > &typesExpected, bool fAllowNull, bool fStrict)
Definition: util.cpp:59
RBFTransactionState IsRBFOptIn(const CTransaction &tx, const CTxMemPool &pool)
Determine whether an unconfirmed transaction is signaling opt-in to RBF according to BIP 125 This inv...
Definition: rbf.cpp:24
bool get_bool() const
The package itself is invalid (e.g. too many transactions).
Required arg.
Valid, transaction was already in the mempool.
Either this tx or a mempool ancestor signals rbf.
CTxMemPool & EnsureMemPool(const NodeContext &node)
Definition: server_util.cpp:34
bool exists(const GenTxid &gtxid) const
Definition: txmempool.h:647
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Definition: validation.h:865
static RPCHelpMan getmempoolinfo()
Definition: mempool.cpp:691
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1172
Unconfirmed tx that does not signal rbf and is not in the mempool.
void CalculateDescendants(txiter it, setEntries &setDescendants) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Populate setDescendants with all in-mempool descendants of hash.
Definition: txmempool.cpp:571
size_t DynamicMemoryUsage() const
Definition: txmempool.cpp:1063
transaction was missing some of its inputs
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:81
Special type that behaves almost exactly like OBJ, defining an options object with a list of pre-defi...
static UniValue OrphanToJSON(const TxOrphanage::OrphanTxBase &orphan)
Definition: mempool.cpp:837
unsigned long size() const
Definition: txmempool.h:629
UniValue MempoolInfoToJSON(const CTxMemPool &pool)
Mempool information to JSON.
Definition: mempool.cpp:672
uint64_t GetSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.h:705
bool IsChildWithParentsTree(const Package &package)
Context-free check that a package IsChildWithParents() and none of the parents depend on each other (...
Definition: packages.cpp:136
std::set< txiter, CompareIteratorByHash > setEntries
Definition: txmempool.h:396
void pushKVEnd(std::string key, UniValue val)
Definition: univalue.cpp:118
const Children & GetMemPoolChildrenConst() const
const UniValue & get_array() const
std::set< NodeId > announcers
Peers added with AddTx or AddAnnouncer.
Definition: txorphanage.h:85
static void entryToJSON(const CTxMemPool &pool, UniValue &info, const CTxMemPoolEntry &e) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
Definition: mempool.cpp:287
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop)
Compute the virtual transaction size (weight reinterpreted as bytes).
Definition: policy.cpp:347
bool skip_type_check
Definition: util.h:167
std::map< Wtxid, MempoolAcceptResult > m_tx_results
Map from wtxid to finished MempoolAcceptResults.
Definition: validation.h:237
Int getInt() const
Definition: univalue.h:138
setEntries AssumeCalculateMemPoolAncestors(std::string_view calling_fn_name, const CTxMemPoolEntry &entry, const Limits &limits, bool fSearchForParents=true) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Same as CalculateMemPoolAncestors, but always returns a (non-optional) setEntries.
Definition: txmempool.cpp:275
static int32_t GetTransactionWeight(const CTransaction &tx)
Definition: validation.h:133
static RPCHelpMan getorphantxs()
Definition: mempool.cpp:855
const std::vector< CTxIn > vin
Definition: transaction.h:306
Invalid, missing or duplicate parameter.
Definition: protocol.h:44
bool DumpMempool(const CTxMemPool &pool, const fs::path &dump_path, FopenFn mockable_fopen_function, bool skip_file_commit)
RBFTransactionState
The rbf state of unconfirmed transactions.
Definition: rbf.h:29
CFeeRate ParseFeeRate(const UniValue &json)
Parse a json number or string, denoting BTC/kvB, into a CFeeRate (sat/kvB).
Definition: util.cpp:113
virtual std::vector< TxOrphanage::OrphanTxBase > GetOrphanTransactions()=0
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
Definition: mempool_entry.h:65
static RPCHelpMan importmempool()
Definition: mempool.cpp:722
bool LoadMempool(CTxMemPool &pool, const fs::path &load_path, Chainstate &active_chainstate, ImportMempoolOptions &&opts)
Import the file and attempt to add its contents to the mempool.
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
const UniValue & find_value(std::string_view key) const
Definition: univalue.cpp:233
std::string oneline_description
Should be empty unless it is supposed to override the auto-generated summary line.
Definition: util.h:168
Special type that is a STR with only hex chars.
NodeContext struct containing references to chain state and connection state.
Definition: context.h:56
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:204
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:70
Special string with only hex chars.
ArgsManager & args
Definition: bitcoind.cpp:277
static CAmount AmountFromValue(const UniValue &value)
Definition: bitcoin-tx.cpp:561
Chainstate stores and provides an API to update our local knowledge of the current best chain...
Definition: validation.h:504
static RPCHelpMan submitpackage()
Definition: mempool.cpp:923
Validation result for package mempool acceptance.
Definition: validation.h:228
An input of a transaction.
Definition: transaction.h:66
#define LOCK(cs)
Definition: sync.h:257
std::string ToString() const
Definition: validation.h:112
Txid hash
Definition: transaction.h:31
std::string ToString() const
bool empty() const
Definition: univalue.h:69
const std::string CURRENCY_UNIT
Definition: feerate.h:17
TransactionError BroadcastTransaction(NodeContext &node, const CTransactionRef tx, std::string &err_string, const CAmount &max_tx_fee, bool relay, bool wait_callback)
Submit a transaction to the mempool and (optionally) relay it to all P2P peers.
Definition: transaction.cpp:34
static RPCHelpMan savemempool()
Definition: mempool.cpp:783
Result GetResult() const
Definition: validation.h:109
General application defined errors.
Definition: protocol.h:40
static std::vector< RPCResult > OrphanDescription()
Definition: mempool.cpp:820
uint64_t GetTotalTxSize() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.h:635
CFeeRate min_relay_feerate
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) ...
std::string ToString() const
Definition: uint256.cpp:47
Invalid address or key.
Definition: protocol.h:42
CTxMemPool & EnsureAnyMemPool(const std::any &context)
Definition: server_util.cpp:42
At least one tx is invalid.
static RPCHelpMan getmempooldescendants()
Definition: mempool.cpp:493
const CTransaction * GetConflictTx(const COutPoint &prevout) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Get the transaction in the pool that spends the same prevout.
Definition: txmempool.cpp:981
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:28
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:186
std::vector< CTxOut > vout
Definition: transaction.h:380
CFeeRate GetMinFee(size_t sizelimit) const
Definition: txmempool.cpp:1126
static RPCHelpMan sendrawtransaction()
Definition: mempool.cpp:42
bool isNull() const
Definition: univalue.h:79
Special numeric to denote unix epoch time.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:301
static RPCHelpMan gettxspendingprevout()
Definition: mempool.cpp:590
static RPCHelpMan getmempoolentry()
Definition: mempool.cpp:558
constexpr int64_t count_seconds(std::chrono::seconds t)
Definition: time.h:81
bool GetLoadTried() const
Definition: txmempool.cpp:1236
static CTransactionRef MakeTransactionRef(Tx &&txIn)
Definition: transaction.h:424
Definition: messages.h:20
std::optional< txiter > GetIter(const uint256 &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Returns an iterator to the given hash, if found.
Definition: txmempool.cpp:987
std::string FormatMoney(const CAmount n)
Money parsing/formatting utilities.
Definition: moneystr.cpp:19
PackageValidationState m_state
Definition: validation.h:230
256-bit opaque blob.
Definition: uint256.h:201
Optional argument for which the default value is omitted from help text for one of two reasons: ...
std::string EncodeHexTx(const CTransaction &tx)
Definition: core_write.cpp:143
const CTxMemPoolEntry * GetEntry(const Txid &txid) const LIFETIMEBOUND EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:877
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49
std::string utf8string() const
Return a UTF-8 representation of the path as a std::string, for compatibility with code using std::st...
Definition: fs.h:63
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:303
auto result
Definition: common-types.h:74
int ParseVerbosity(const UniValue &arg, int default_verbosity, bool allow_bool)
Parses verbosity from provided UniValue.
Definition: util.cpp:86
Special string to represent a floating point amount.
std::set< uint256 > GetUnbroadcastTxs() const
Returns transactions in unbroadcast set.
Definition: txmempool.h:687
static const CAmount DEFAULT_MAX_BURN_AMOUNT
Maximum burn value for sendrawtransaction, submitpackage, and testmempoolaccept RPC calls...
Definition: transaction.h:33
void pushKV(std::string key, UniValue val)
Definition: univalue.cpp:126
static transaction_identifier FromUint256(const uint256 &id)
uint256 ParseHashV(const UniValue &v, std::string_view name)
Utilities: convert hex-encoded Values (throws error if not hex).
Definition: util.cpp:120
const CTransaction & GetTx() const
fs::path MempoolPath(const ArgsManager &argsman)
ChainstateManager & EnsureChainman(const NodeContext &node)
Definition: server_util.cpp:74
CAmount GetTotalFee() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.h:641
const UniValue & get_obj() const
bool IsInitialBlockDownload() const
Check whether we are doing an initial block download (synchronizing from disk or network) ...
PackageMempoolAcceptResult ProcessNewPackage(Chainstate &active_chainstate, CTxMemPool &pool, const Package &package, bool test_accept, const std::optional< CFeeRate > &client_maxfeerate)
Validate (and maybe submit) a package to the mempool.
Special type representing a floating point amount (can be either NUM or STR)
bool DecodeHexTx(CMutableTransaction &tx, const std::string &hex_tx, bool try_no_witness=false, bool try_witness=true)
Definition: core_read.cpp:196
UniValue ValueFromAmount(const CAmount amount)
Definition: core_write.cpp:26
static RPCHelpMan testmempoolaccept()
Definition: mempool.cpp:109
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
Definition: feerate.h:32
ArgsManager & EnsureAnyArgsman(const std::any &context)
Definition: server_util.cpp:69
#define AssertLockNotHeld(cs)
Definition: sync.h:147
PeerManager & EnsurePeerman(const NodeContext &node)
A mutable version of CTransaction.
Definition: transaction.h:377
static constexpr MemPoolLimits NoLimits()
size_t size() const
Definition: univalue.h:71
static constexpr uint32_t MAX_PACKAGE_COUNT
Default maximum number of transactions in a package.
Definition: packages.h:19
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:295
UniValue JSONRPCTransactionError(TransactionError terr, const std::string &err_string)
Definition: util.cpp:432
Special dictionary with keys that are not literals.
std::string GetRejectReason() const
Definition: validation.h:110
Still downloading initial blocks.
Definition: protocol.h:59
is a home for public enum and struct type definitions that are used internally by node code...
static path u8path(const std::string &utf8_str)
Definition: fs.h:75
static const CFeeRate DEFAULT_MAX_RAW_TX_FEE_RATE
Maximum fee rate for sendrawtransaction and testmempoolaccept RPC calls.
Definition: transaction.h:27
Allows providing orphan information externally.
Definition: txorphanage.h:82
COutPoint prevout
Definition: transaction.h:69
Initial value. The package has not yet been rejected.
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:32
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
Definition: cs_main.cpp:8
CAmount GetFeePerK() const
Return the fee in satoshis for a vsize of 1000 vbytes.
Definition: feerate.h:60
Wrapper for UniValue::VType, which includes typeAny: Used to denote don&#39;t care type.
Definition: util.h:79
SnapshotCompletionResult MaybeCompleteSnapshotValidation() EXCLUSIVE_LOCKS_REQUIRED(const CBlockIndex *GetSnapshotBaseBlock() const EXCLUSIVE_LOCKS_REQUIRED(Chainstate ActiveChainstate)() const
Once the background validation chainstate has reached the height which is the base of the UTXO snapsh...
Definition: validation.h:1110
static GenTxid Txid(const uint256 &hash)
Definition: transaction.h:434
std::vector< CTxMemPoolEntryRef > entryAll() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:851
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:233
uint64_t fee
NodeContext & EnsureAnyNodeContext(const std::any &context)
Definition: server_util.cpp:25
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it...
Definition: txmempool.h:390
Error parsing or validating structure in raw format.
Definition: protocol.h:46
const Txid & GetHash() const LIFETIMEBOUND
Definition: transaction.h:343
const std::string UNIX_EPOCH_TIME
String used to describe UNIX epoch time in documentation, factored out to a constant for consistency...
Definition: util.cpp:46
CTransactionRef tx
Definition: txorphanage.h:83
CFeeRate incremental_relay_feerate
static std::vector< RPCResult > MempoolEntryDescription()
Definition: mempool.cpp:259
const Options m_opts
Definition: txmempool.h:439
MempoolAcceptResult ProcessTransaction(const CTransactionRef &tx, bool test_accept=false) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Try to add a transaction to the memory pool.