Bitcoin Core  24.99.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 
9 
10 #include <chainparams.h>
11 #include <core_io.h>
12 #include <fs.h>
14 #include <policy/rbf.h>
15 #include <policy/settings.h>
16 #include <primitives/transaction.h>
17 #include <rpc/server.h>
18 #include <rpc/server_util.h>
19 #include <rpc/util.h>
20 #include <txmempool.h>
21 #include <univalue.h>
22 #include <util/moneystr.h>
23 #include <util/time.h>
24 
26 
28 using node::MempoolPath;
29 using node::NodeContext;
30 
32 {
33  return RPCHelpMan{"sendrawtransaction",
34  "\nSubmit a raw transaction (serialized, hex-encoded) to local node and network.\n"
35  "\nThe transaction will be sent unconditionally to all peers, so using sendrawtransaction\n"
36  "for manual rebroadcast may degrade privacy by leaking the transaction's origin, as\n"
37  "nodes will normally not rebroadcast non-wallet transactions already in their mempool.\n"
38  "\nA specific exception, RPC_TRANSACTION_ALREADY_IN_CHAIN, may throw if the transaction cannot be added to the mempool.\n"
39  "\nRelated RPCs: createrawtransaction, signrawtransactionwithkey\n",
40  {
41  {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"},
43  "Reject transactions whose fee rate is higher than the specified value, expressed in " + CURRENCY_UNIT +
44  "/kvB.\nSet to 0 to accept any fee rate.\n"},
45  },
46  RPCResult{
47  RPCResult::Type::STR_HEX, "", "The transaction hash in hex"
48  },
50  "\nCreate a transaction\n"
51  + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
52  "Sign the transaction, and get back the hex\n"
53  + HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"") +
54  "\nSend the transaction (signed hex)\n"
55  + HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
56  "\nAs a JSON-RPC call\n"
57  + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
58  },
59  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
60  {
61  RPCTypeCheck(request.params, {
62  UniValue::VSTR,
63  UniValueType(), // VNUM or VSTR, checked inside AmountFromValue()
64  });
65 
67  if (!DecodeHexTx(mtx, request.params[0].get_str())) {
68  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
69  }
70  CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
71 
72  const CFeeRate max_raw_tx_fee_rate = request.params[1].isNull() ?
74  CFeeRate(AmountFromValue(request.params[1]));
75 
76  int64_t virtual_size = GetVirtualTransactionSize(*tx);
77  CAmount max_raw_tx_fee = max_raw_tx_fee_rate.GetFee(virtual_size);
78 
79  std::string err_string;
81  NodeContext& node = EnsureAnyNodeContext(request.context);
82  const TransactionError err = BroadcastTransaction(node, tx, err_string, max_raw_tx_fee, /*relay=*/true, /*wait_callback=*/true);
83  if (TransactionError::OK != err) {
84  throw JSONRPCTransactionError(err, err_string);
85  }
86 
87  return tx->GetHash().GetHex();
88  },
89  };
90 }
91 
93 {
94  return RPCHelpMan{"testmempoolaccept",
95  "\nReturns result of mempool acceptance tests indicating if raw transaction(s) (serialized, hex-encoded) would be accepted by mempool.\n"
96  "\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"
97  "\nIf one transaction fails, other transactions may not be fully validated (the 'allowed' key will be blank).\n"
98  "\nThe maximum number of transactions allowed is " + ToString(MAX_PACKAGE_COUNT) + ".\n"
99  "\nThis checks if transactions violate the consensus or policy rules.\n"
100  "\nSee sendrawtransaction call.\n",
101  {
102  {"rawtxs", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of hex strings of raw transactions.",
103  {
105  },
106  },
108  "Reject transactions whose fee rate is higher than the specified value, expressed in " + CURRENCY_UNIT + "/kvB\n"},
109  },
110  RPCResult{
111  RPCResult::Type::ARR, "", "The result of the mempool acceptance test for each raw transaction in the input array.\n"
112  "Returns results for each transaction in the same order they were passed in.\n"
113  "Transactions that cannot be fully validated due to failures in other transactions will not contain an 'allowed' result.\n",
114  {
115  {RPCResult::Type::OBJ, "", "",
116  {
117  {RPCResult::Type::STR_HEX, "txid", "The transaction hash in hex"},
118  {RPCResult::Type::STR_HEX, "wtxid", "The transaction witness hash in hex"},
119  {RPCResult::Type::STR, "package-error", /*optional=*/true, "Package validation error, if any (only possible if rawtxs had more than 1 transaction)."},
120  {RPCResult::Type::BOOL, "allowed", /*optional=*/true, "Whether this tx would be accepted to the mempool and pass client-specified maxfeerate. "
121  "If not present, the tx was not fully validated due to a failure in another tx in the list."},
122  {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)"},
123  {RPCResult::Type::OBJ, "fees", /*optional=*/true, "Transaction fees (only present if 'allowed' is true)",
124  {
125  {RPCResult::Type::STR_AMOUNT, "base", "transaction fee in " + CURRENCY_UNIT},
126  }},
127  {RPCResult::Type::STR, "reject-reason", /*optional=*/true, "Rejection string (only present when 'allowed' is false)"},
128  }},
129  }
130  },
131  RPCExamples{
132  "\nCreate a transaction\n"
133  + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
134  "Sign the transaction, and get back the hex\n"
135  + HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"") +
136  "\nTest acceptance of the transaction (signed hex)\n"
137  + HelpExampleCli("testmempoolaccept", R"('["signedhex"]')") +
138  "\nAs a JSON-RPC call\n"
139  + HelpExampleRpc("testmempoolaccept", "[\"signedhex\"]")
140  },
141  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
142  {
143  RPCTypeCheck(request.params, {
144  UniValue::VARR,
145  UniValueType(), // VNUM or VSTR, checked inside AmountFromValue()
146  });
147  const UniValue raw_transactions = request.params[0].get_array();
148  if (raw_transactions.size() < 1 || raw_transactions.size() > MAX_PACKAGE_COUNT) {
150  "Array must contain between 1 and " + ToString(MAX_PACKAGE_COUNT) + " transactions.");
151  }
152 
153  const CFeeRate max_raw_tx_fee_rate = request.params[1].isNull() ?
155  CFeeRate(AmountFromValue(request.params[1]));
156 
157  std::vector<CTransactionRef> txns;
158  txns.reserve(raw_transactions.size());
159  for (const auto& rawtx : raw_transactions.getValues()) {
161  if (!DecodeHexTx(mtx, rawtx.get_str())) {
163  "TX decode failed: " + rawtx.get_str() + " Make sure the tx has at least one input.");
164  }
165  txns.emplace_back(MakeTransactionRef(std::move(mtx)));
166  }
167 
168  NodeContext& node = EnsureAnyNodeContext(request.context);
169  CTxMemPool& mempool = EnsureMemPool(node);
171  Chainstate& chainstate = chainman.ActiveChainstate();
172  const PackageMempoolAcceptResult package_result = [&] {
173  LOCK(::cs_main);
174  if (txns.size() > 1) return ProcessNewPackage(chainstate, mempool, txns, /*test_accept=*/true);
175  return PackageMempoolAcceptResult(txns[0]->GetWitnessHash(),
176  chainman.ProcessTransaction(txns[0], /*test_accept=*/true));
177  }();
178 
179  UniValue rpc_result(UniValue::VARR);
180  // We will check transaction fees while we iterate through txns in order. If any transaction fee
181  // exceeds maxfeerate, we will leave the rest of the validation results blank, because it
182  // doesn't make sense to return a validation result for a transaction if its ancestor(s) would
183  // not be submitted.
184  bool exit_early{false};
185  for (const auto& tx : txns) {
186  UniValue result_inner(UniValue::VOBJ);
187  result_inner.pushKV("txid", tx->GetHash().GetHex());
188  result_inner.pushKV("wtxid", tx->GetWitnessHash().GetHex());
189  if (package_result.m_state.GetResult() == PackageValidationResult::PCKG_POLICY) {
190  result_inner.pushKV("package-error", package_result.m_state.GetRejectReason());
191  }
192  auto it = package_result.m_tx_results.find(tx->GetWitnessHash());
193  if (exit_early || it == package_result.m_tx_results.end()) {
194  // Validation unfinished. Just return the txid and wtxid.
195  rpc_result.push_back(result_inner);
196  continue;
197  }
198  const auto& tx_result = it->second;
199  // Package testmempoolaccept doesn't allow transactions to already be in the mempool.
201  if (tx_result.m_result_type == MempoolAcceptResult::ResultType::VALID) {
202  const CAmount fee = tx_result.m_base_fees.value();
203  // Check that fee does not exceed maximum fee
204  const int64_t virtual_size = tx_result.m_vsize.value();
205  const CAmount max_raw_tx_fee = max_raw_tx_fee_rate.GetFee(virtual_size);
206  if (max_raw_tx_fee && fee > max_raw_tx_fee) {
207  result_inner.pushKV("allowed", false);
208  result_inner.pushKV("reject-reason", "max-fee-exceeded");
209  exit_early = true;
210  } else {
211  // Only return the fee and vsize if the transaction would pass ATMP.
212  // These can be used to calculate the feerate.
213  result_inner.pushKV("allowed", true);
214  result_inner.pushKV("vsize", virtual_size);
215  UniValue fees(UniValue::VOBJ);
216  fees.pushKV("base", ValueFromAmount(fee));
217  result_inner.pushKV("fees", fees);
218  }
219  } else {
220  result_inner.pushKV("allowed", false);
221  const TxValidationState state = tx_result.m_state;
223  result_inner.pushKV("reject-reason", "missing-inputs");
224  } else {
225  result_inner.pushKV("reject-reason", state.GetRejectReason());
226  }
227  }
228  rpc_result.push_back(result_inner);
229  }
230  return rpc_result;
231  },
232  };
233 }
234 
235 static std::vector<RPCResult> MempoolEntryDescription()
236 {
237  return {
238  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."},
239  RPCResult{RPCResult::Type::NUM, "weight", "transaction weight as defined in BIP 141."},
240  RPCResult{RPCResult::Type::NUM_TIME, "time", "local time transaction entered pool in seconds since 1 Jan 1970 GMT"},
241  RPCResult{RPCResult::Type::NUM, "height", "block height when transaction entered pool"},
242  RPCResult{RPCResult::Type::NUM, "descendantcount", "number of in-mempool descendant transactions (including this one)"},
243  RPCResult{RPCResult::Type::NUM, "descendantsize", "virtual transaction size of in-mempool descendants (including this one)"},
244  RPCResult{RPCResult::Type::NUM, "ancestorcount", "number of in-mempool ancestor transactions (including this one)"},
245  RPCResult{RPCResult::Type::NUM, "ancestorsize", "virtual transaction size of in-mempool ancestors (including this one)"},
246  RPCResult{RPCResult::Type::STR_HEX, "wtxid", "hash of serialized transaction, including witness data"},
247  RPCResult{RPCResult::Type::OBJ, "fees", "",
248  {
249  RPCResult{RPCResult::Type::STR_AMOUNT, "base", "transaction fee, denominated in " + CURRENCY_UNIT},
250  RPCResult{RPCResult::Type::STR_AMOUNT, "modified", "transaction fee with fee deltas used for mining priority, denominated in " + CURRENCY_UNIT},
251  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},
252  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},
253  }},
254  RPCResult{RPCResult::Type::ARR, "depends", "unconfirmed transactions used as inputs for this transaction",
255  {RPCResult{RPCResult::Type::STR_HEX, "transactionid", "parent transaction id"}}},
256  RPCResult{RPCResult::Type::ARR, "spentby", "unconfirmed transactions spending outputs from this transaction",
257  {RPCResult{RPCResult::Type::STR_HEX, "transactionid", "child transaction id"}}},
258  RPCResult{RPCResult::Type::BOOL, "bip125-replaceable", "Whether this transaction signals BIP125 replaceability or has an unconfirmed ancestor signaling BIP125 replaceability.\n"},
259  RPCResult{RPCResult::Type::BOOL, "unbroadcast", "Whether this transaction is currently unbroadcast (initial broadcast not yet acknowledged by any peers)"},
260  };
261 }
262 
263 static void entryToJSON(const CTxMemPool& pool, UniValue& info, const CTxMemPoolEntry& e) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
264 {
265  AssertLockHeld(pool.cs);
266 
267  info.pushKV("vsize", (int)e.GetTxSize());
268  info.pushKV("weight", (int)e.GetTxWeight());
269  info.pushKV("time", count_seconds(e.GetTime()));
270  info.pushKV("height", (int)e.GetHeight());
271  info.pushKV("descendantcount", e.GetCountWithDescendants());
272  info.pushKV("descendantsize", e.GetSizeWithDescendants());
273  info.pushKV("ancestorcount", e.GetCountWithAncestors());
274  info.pushKV("ancestorsize", e.GetSizeWithAncestors());
275  info.pushKV("wtxid", pool.vTxHashes[e.vTxHashesIdx].first.ToString());
276 
277  UniValue fees(UniValue::VOBJ);
278  fees.pushKV("base", ValueFromAmount(e.GetFee()));
279  fees.pushKV("modified", ValueFromAmount(e.GetModifiedFee()));
280  fees.pushKV("ancestor", ValueFromAmount(e.GetModFeesWithAncestors()));
281  fees.pushKV("descendant", ValueFromAmount(e.GetModFeesWithDescendants()));
282  info.pushKV("fees", fees);
283 
284  const CTransaction& tx = e.GetTx();
285  std::set<std::string> setDepends;
286  for (const CTxIn& txin : tx.vin)
287  {
288  if (pool.exists(GenTxid::Txid(txin.prevout.hash)))
289  setDepends.insert(txin.prevout.hash.ToString());
290  }
291 
292  UniValue depends(UniValue::VARR);
293  for (const std::string& dep : setDepends)
294  {
295  depends.push_back(dep);
296  }
297 
298  info.pushKV("depends", depends);
299 
300  UniValue spent(UniValue::VARR);
301  const CTxMemPool::txiter& it = pool.mapTx.find(tx.GetHash());
302  const CTxMemPoolEntry::Children& children = it->GetMemPoolChildrenConst();
303  for (const CTxMemPoolEntry& child : children) {
304  spent.push_back(child.GetTx().GetHash().ToString());
305  }
306 
307  info.pushKV("spentby", spent);
308 
309  // Add opt-in RBF status
310  bool rbfStatus = false;
311  RBFTransactionState rbfState = IsRBFOptIn(tx, pool);
312  if (rbfState == RBFTransactionState::UNKNOWN) {
313  throw JSONRPCError(RPC_MISC_ERROR, "Transaction is not in mempool");
314  } else if (rbfState == RBFTransactionState::REPLACEABLE_BIP125) {
315  rbfStatus = true;
316  }
317 
318  info.pushKV("bip125-replaceable", rbfStatus);
319  info.pushKV("unbroadcast", pool.IsUnbroadcastTx(tx.GetHash()));
320 }
321 
322 UniValue MempoolToJSON(const CTxMemPool& pool, bool verbose, bool include_mempool_sequence)
323 {
324  if (verbose) {
325  if (include_mempool_sequence) {
326  throw JSONRPCError(RPC_INVALID_PARAMETER, "Verbose results cannot contain mempool sequence values.");
327  }
328  LOCK(pool.cs);
330  for (const CTxMemPoolEntry& e : pool.mapTx) {
331  const uint256& hash = e.GetTx().GetHash();
332  UniValue info(UniValue::VOBJ);
333  entryToJSON(pool, info, e);
334  // Mempool has unique entries so there is no advantage in using
335  // UniValue::pushKV, which checks if the key already exists in O(N).
336  // UniValue::__pushKV is used instead which currently is O(1).
337  o.__pushKV(hash.ToString(), info);
338  }
339  return o;
340  } else {
341  uint64_t mempool_sequence;
342  std::vector<uint256> vtxid;
343  {
344  LOCK(pool.cs);
345  pool.queryHashes(vtxid);
346  mempool_sequence = pool.GetSequence();
347  }
349  for (const uint256& hash : vtxid)
350  a.push_back(hash.ToString());
351 
352  if (!include_mempool_sequence) {
353  return a;
354  } else {
356  o.pushKV("txids", a);
357  o.pushKV("mempool_sequence", mempool_sequence);
358  return o;
359  }
360  }
361 }
362 
364 {
365  return RPCHelpMan{"getrawmempool",
366  "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
367  "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n",
368  {
369  {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "True for a json object, false for array of transaction ids"},
370  {"mempool_sequence", RPCArg::Type::BOOL, RPCArg::Default{false}, "If verbose=false, returns a json object with transaction list and mempool sequence number attached."},
371  },
372  {
373  RPCResult{"for verbose = false",
374  RPCResult::Type::ARR, "", "",
375  {
376  {RPCResult::Type::STR_HEX, "", "The transaction id"},
377  }},
378  RPCResult{"for verbose = true",
379  RPCResult::Type::OBJ_DYN, "", "",
380  {
381  {RPCResult::Type::OBJ, "transactionid", "", MempoolEntryDescription()},
382  }},
383  RPCResult{"for verbose = false and mempool_sequence = true",
384  RPCResult::Type::OBJ, "", "",
385  {
386  {RPCResult::Type::ARR, "txids", "",
387  {
388  {RPCResult::Type::STR_HEX, "", "The transaction id"},
389  }},
390  {RPCResult::Type::NUM, "mempool_sequence", "The mempool sequence value."},
391  }},
392  },
393  RPCExamples{
394  HelpExampleCli("getrawmempool", "true")
395  + HelpExampleRpc("getrawmempool", "true")
396  },
397  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
398 {
399  bool fVerbose = false;
400  if (!request.params[0].isNull())
401  fVerbose = request.params[0].get_bool();
402 
403  bool include_mempool_sequence = false;
404  if (!request.params[1].isNull()) {
405  include_mempool_sequence = request.params[1].get_bool();
406  }
407 
408  return MempoolToJSON(EnsureAnyMemPool(request.context), fVerbose, include_mempool_sequence);
409 },
410  };
411 }
412 
414 {
415  return RPCHelpMan{"getmempoolancestors",
416  "\nIf txid is in the mempool, returns all in-mempool ancestors.\n",
417  {
418  {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"},
419  {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "True for a json object, false for array of transaction ids"},
420  },
421  {
422  RPCResult{"for verbose = false",
423  RPCResult::Type::ARR, "", "",
424  {{RPCResult::Type::STR_HEX, "", "The transaction id of an in-mempool ancestor transaction"}}},
425  RPCResult{"for verbose = true",
426  RPCResult::Type::OBJ_DYN, "", "",
427  {
428  {RPCResult::Type::OBJ, "transactionid", "", MempoolEntryDescription()},
429  }},
430  },
431  RPCExamples{
432  HelpExampleCli("getmempoolancestors", "\"mytxid\"")
433  + HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
434  },
435  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
436 {
437  bool fVerbose = false;
438  if (!request.params[1].isNull())
439  fVerbose = request.params[1].get_bool();
440 
441  uint256 hash = ParseHashV(request.params[0], "parameter 1");
442 
443  const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
444  LOCK(mempool.cs);
445 
446  CTxMemPool::txiter it = mempool.mapTx.find(hash);
447  if (it == mempool.mapTx.end()) {
448  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
449  }
450 
451  CTxMemPool::setEntries setAncestors;
452  uint64_t noLimit = std::numeric_limits<uint64_t>::max();
453  std::string dummy;
454  mempool.CalculateMemPoolAncestors(*it, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false);
455 
456  if (!fVerbose) {
458  for (CTxMemPool::txiter ancestorIt : setAncestors) {
459  o.push_back(ancestorIt->GetTx().GetHash().ToString());
460  }
461  return o;
462  } else {
464  for (CTxMemPool::txiter ancestorIt : setAncestors) {
465  const CTxMemPoolEntry &e = *ancestorIt;
466  const uint256& _hash = e.GetTx().GetHash();
467  UniValue info(UniValue::VOBJ);
468  entryToJSON(mempool, info, e);
469  o.pushKV(_hash.ToString(), info);
470  }
471  return o;
472  }
473 },
474  };
475 }
476 
478 {
479  return RPCHelpMan{"getmempooldescendants",
480  "\nIf txid is in the mempool, returns all in-mempool descendants.\n",
481  {
482  {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"},
483  {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "True for a json object, false for array of transaction ids"},
484  },
485  {
486  RPCResult{"for verbose = false",
487  RPCResult::Type::ARR, "", "",
488  {{RPCResult::Type::STR_HEX, "", "The transaction id of an in-mempool descendant transaction"}}},
489  RPCResult{"for verbose = true",
490  RPCResult::Type::OBJ_DYN, "", "",
491  {
492  {RPCResult::Type::OBJ, "transactionid", "", MempoolEntryDescription()},
493  }},
494  },
495  RPCExamples{
496  HelpExampleCli("getmempooldescendants", "\"mytxid\"")
497  + HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
498  },
499  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
500 {
501  bool fVerbose = false;
502  if (!request.params[1].isNull())
503  fVerbose = request.params[1].get_bool();
504 
505  uint256 hash = ParseHashV(request.params[0], "parameter 1");
506 
507  const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
508  LOCK(mempool.cs);
509 
510  CTxMemPool::txiter it = mempool.mapTx.find(hash);
511  if (it == mempool.mapTx.end()) {
512  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
513  }
514 
515  CTxMemPool::setEntries setDescendants;
516  mempool.CalculateDescendants(it, setDescendants);
517  // CTxMemPool::CalculateDescendants will include the given tx
518  setDescendants.erase(it);
519 
520  if (!fVerbose) {
522  for (CTxMemPool::txiter descendantIt : setDescendants) {
523  o.push_back(descendantIt->GetTx().GetHash().ToString());
524  }
525 
526  return o;
527  } else {
529  for (CTxMemPool::txiter descendantIt : setDescendants) {
530  const CTxMemPoolEntry &e = *descendantIt;
531  const uint256& _hash = e.GetTx().GetHash();
532  UniValue info(UniValue::VOBJ);
533  entryToJSON(mempool, info, e);
534  o.pushKV(_hash.ToString(), info);
535  }
536  return o;
537  }
538 },
539  };
540 }
541 
543 {
544  return RPCHelpMan{"getmempoolentry",
545  "\nReturns mempool data for given transaction\n",
546  {
547  {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"},
548  },
549  RPCResult{
551  RPCExamples{
552  HelpExampleCli("getmempoolentry", "\"mytxid\"")
553  + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
554  },
555  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
556 {
557  uint256 hash = ParseHashV(request.params[0], "parameter 1");
558 
559  const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
560  LOCK(mempool.cs);
561 
562  CTxMemPool::txiter it = mempool.mapTx.find(hash);
563  if (it == mempool.mapTx.end()) {
564  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
565  }
566 
567  const CTxMemPoolEntry &e = *it;
568  UniValue info(UniValue::VOBJ);
569  entryToJSON(mempool, info, e);
570  return info;
571 },
572  };
573 }
574 
576 {
577  return RPCHelpMan{"gettxspendingprevout",
578  "Scans the mempool to find transactions spending any of the given outputs",
579  {
580  {"outputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The transaction outputs that we want to check, and within each, the txid (string) vout (numeric).",
581  {
583  {
584  {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
585  {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
586  },
587  },
588  },
589  },
590  },
591  RPCResult{
592  RPCResult::Type::ARR, "", "",
593  {
594  {RPCResult::Type::OBJ, "", "",
595  {
596  {RPCResult::Type::STR_HEX, "txid", "the transaction id of the checked output"},
597  {RPCResult::Type::NUM, "vout", "the vout value of the checked output"},
598  {RPCResult::Type::STR_HEX, "spendingtxid", /*optional=*/true, "the transaction id of the mempool transaction spending this output (omitted if unspent)"},
599  }},
600  }
601  },
602  RPCExamples{
603  HelpExampleCli("gettxspendingprevout", "\"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":3}]\"")
604  + HelpExampleRpc("gettxspendingprevout", "\"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":3}]\"")
605  },
606  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
607  {
608  const UniValue& output_params = request.params[0].get_array();
609  if (output_params.empty()) {
610  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, outputs are missing");
611  }
612 
613  std::vector<COutPoint> prevouts;
614  prevouts.reserve(output_params.size());
615 
616  for (unsigned int idx = 0; idx < output_params.size(); idx++) {
617  const UniValue& o = output_params[idx].get_obj();
618 
619  RPCTypeCheckObj(o,
620  {
621  {"txid", UniValueType(UniValue::VSTR)},
622  {"vout", UniValueType(UniValue::VNUM)},
623  }, /*fAllowNull=*/false, /*fStrict=*/true);
624 
625  const uint256 txid(ParseHashO(o, "txid"));
626  const int nOutput{find_value(o, "vout").getInt<int>()};
627  if (nOutput < 0) {
628  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout cannot be negative");
629  }
630 
631  prevouts.emplace_back(txid, nOutput);
632  }
633 
634  const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
635  LOCK(mempool.cs);
636 
637  UniValue result{UniValue::VARR};
638 
639  for (const COutPoint& prevout : prevouts) {
641  o.pushKV("txid", prevout.hash.ToString());
642  o.pushKV("vout", (uint64_t)prevout.n);
643 
644  const CTransaction* spendingTx = mempool.GetConflictTx(prevout);
645  if (spendingTx != nullptr) {
646  o.pushKV("spendingtxid", spendingTx->GetHash().ToString());
647  }
648 
649  result.push_back(o);
650  }
651 
652  return result;
653  },
654  };
655 }
656 
658 {
659  // Make sure this call is atomic in the pool.
660  LOCK(pool.cs);
662  ret.pushKV("loaded", pool.GetLoadTried());
663  ret.pushKV("size", (int64_t)pool.size());
664  ret.pushKV("bytes", (int64_t)pool.GetTotalTxSize());
665  ret.pushKV("usage", (int64_t)pool.DynamicMemoryUsage());
666  ret.pushKV("total_fee", ValueFromAmount(pool.GetTotalFee()));
667  ret.pushKV("maxmempool", pool.m_max_size_bytes);
668  ret.pushKV("mempoolminfee", ValueFromAmount(std::max(pool.GetMinFee(), pool.m_min_relay_feerate).GetFeePerK()));
669  ret.pushKV("minrelaytxfee", ValueFromAmount(pool.m_min_relay_feerate.GetFeePerK()));
670  ret.pushKV("incrementalrelayfee", ValueFromAmount(pool.m_incremental_relay_feerate.GetFeePerK()));
671  ret.pushKV("unbroadcastcount", uint64_t{pool.GetUnbroadcastTxs().size()});
672  ret.pushKV("fullrbf", pool.m_full_rbf);
673  return ret;
674 }
675 
677 {
678  return RPCHelpMan{"getmempoolinfo",
679  "Returns details on the active state of the TX memory pool.",
680  {},
681  RPCResult{
682  RPCResult::Type::OBJ, "", "",
683  {
684  {RPCResult::Type::BOOL, "loaded", "True if the mempool is fully loaded"},
685  {RPCResult::Type::NUM, "size", "Current tx count"},
686  {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"},
687  {RPCResult::Type::NUM, "usage", "Total memory usage for the mempool"},
688  {RPCResult::Type::STR_AMOUNT, "total_fee", "Total fees for the mempool in " + CURRENCY_UNIT + ", ignoring modified fees through prioritisetransaction"},
689  {RPCResult::Type::NUM, "maxmempool", "Maximum memory usage for the mempool"},
690  {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"},
691  {RPCResult::Type::STR_AMOUNT, "minrelaytxfee", "Current minimum relay fee for transactions"},
692  {RPCResult::Type::NUM, "incrementalrelayfee", "minimum fee rate increment for mempool limiting or replacement in " + CURRENCY_UNIT + "/kvB"},
693  {RPCResult::Type::NUM, "unbroadcastcount", "Current number of transactions that haven't passed initial broadcast yet"},
694  {RPCResult::Type::BOOL, "fullrbf", "True if the mempool accepts RBF without replaceability signaling inspection"},
695  }},
696  RPCExamples{
697  HelpExampleCli("getmempoolinfo", "")
698  + HelpExampleRpc("getmempoolinfo", "")
699  },
700  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
701 {
702  return MempoolInfoToJSON(EnsureAnyMemPool(request.context));
703 },
704  };
705 }
706 
708 {
709  return RPCHelpMan{"savemempool",
710  "\nDumps the mempool to disk. It will fail until the previous dump is fully loaded.\n",
711  {},
712  RPCResult{
713  RPCResult::Type::OBJ, "", "",
714  {
715  {RPCResult::Type::STR, "filename", "the directory and file where the mempool was saved"},
716  }},
717  RPCExamples{
718  HelpExampleCli("savemempool", "")
719  + HelpExampleRpc("savemempool", "")
720  },
721  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
722 {
723  const ArgsManager& args{EnsureAnyArgsman(request.context)};
724  const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
725 
726  if (!mempool.GetLoadTried()) {
727  throw JSONRPCError(RPC_MISC_ERROR, "The mempool was not loaded yet");
728  }
729 
730  const fs::path& dump_path = MempoolPath(args);
731 
732  if (!DumpMempool(mempool, dump_path)) {
733  throw JSONRPCError(RPC_MISC_ERROR, "Unable to dump mempool to disk");
734  }
735 
737  ret.pushKV("filename", dump_path.u8string());
738 
739  return ret;
740 },
741  };
742 }
743 
745 {
746  return RPCHelpMan{"submitpackage",
747  "Submit a package of raw transactions (serialized, hex-encoded) to local node (-regtest only).\n"
748  "The package will be validated according to consensus and mempool policy rules. If all transactions pass, they will be accepted to mempool.\n"
749  "This RPC is experimental and the interface may be unstable. Refer to doc/policy/packages.md for documentation on package policies.\n"
750  "Warning: until package relay is in use, successful submission does not mean the transaction will propagate to other nodes on the network.\n"
751  "Currently, each transaction is broadcasted individually after submission, which means they must meet other nodes' feerate requirements alone.\n"
752  ,
753  {
754  {"package", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of raw transactions.",
755  {
757  },
758  },
759  },
760  RPCResult{
761  RPCResult::Type::OBJ, "", "",
762  {
763  {RPCResult::Type::OBJ_DYN, "tx-results", "transaction results keyed by wtxid",
764  {
765  {RPCResult::Type::OBJ, "wtxid", "transaction wtxid", {
766  {RPCResult::Type::STR_HEX, "txid", "The transaction hash in hex"},
767  {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."},
768  {RPCResult::Type::NUM, "vsize", "Virtual transaction size as defined in BIP 141."},
769  {RPCResult::Type::OBJ, "fees", "Transaction fees", {
770  {RPCResult::Type::STR_AMOUNT, "base", "transaction fee in " + CURRENCY_UNIT},
771  }},
772  }}
773  }},
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."},
775  {RPCResult::Type::ARR, "replaced-transactions", /*optional=*/true, "List of txids of replaced transactions",
776  {
777  {RPCResult::Type::STR_HEX, "", "The transaction id"},
778  }},
779  },
780  },
781  RPCExamples{
782  HelpExampleCli("testmempoolaccept", "[rawtx1, rawtx2]") +
783  HelpExampleCli("submitpackage", "[rawtx1, rawtx2]")
784  },
785  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
786  {
787  if (!Params().IsMockableChain()) {
788  throw std::runtime_error("submitpackage is for regression testing (-regtest mode) only");
789  }
790  RPCTypeCheck(request.params, {
791  UniValue::VARR,
792  });
793  const UniValue raw_transactions = request.params[0].get_array();
794  if (raw_transactions.size() < 1 || raw_transactions.size() > MAX_PACKAGE_COUNT) {
796  "Array must contain between 1 and " + ToString(MAX_PACKAGE_COUNT) + " transactions.");
797  }
798 
799  std::vector<CTransactionRef> txns;
800  txns.reserve(raw_transactions.size());
801  for (const auto& rawtx : raw_transactions.getValues()) {
803  if (!DecodeHexTx(mtx, rawtx.get_str())) {
805  "TX decode failed: " + rawtx.get_str() + " Make sure the tx has at least one input.");
806  }
807  txns.emplace_back(MakeTransactionRef(std::move(mtx)));
808  }
809 
810  NodeContext& node = EnsureAnyNodeContext(request.context);
811  CTxMemPool& mempool = EnsureMemPool(node);
813  const auto package_result = WITH_LOCK(::cs_main, return ProcessNewPackage(chainstate, mempool, txns, /*test_accept=*/ false));
814 
815  // First catch any errors.
816  switch(package_result.m_state.GetResult()) {
819  {
821  package_result.m_state.GetRejectReason());
822  }
824  {
826  package_result.m_state.GetRejectReason());
827  }
829  {
830  for (const auto& tx : txns) {
831  auto it = package_result.m_tx_results.find(tx->GetWitnessHash());
832  if (it != package_result.m_tx_results.end() && it->second.m_state.IsInvalid()) {
834  strprintf("%s failed: %s", tx->GetHash().ToString(), it->second.m_state.GetRejectReason()));
835  }
836  }
837  // If a PCKG_TX error was returned, there must have been an invalid transaction.
839  }
840  }
841  for (const auto& tx : txns) {
842  size_t num_submitted{0};
843  std::string err_string;
844  const auto err = BroadcastTransaction(node, tx, err_string, 0, true, true);
845  if (err != TransactionError::OK) {
846  throw JSONRPCTransactionError(err,
847  strprintf("transaction broadcast failed: %s (all transactions were submitted, %d transactions were broadcast successfully)",
848  err_string, num_submitted));
849  }
850  }
851  UniValue rpc_result{UniValue::VOBJ};
852  UniValue tx_result_map{UniValue::VOBJ};
853  std::set<uint256> replaced_txids;
854  for (const auto& tx : txns) {
855  auto it = package_result.m_tx_results.find(tx->GetWitnessHash());
856  CHECK_NONFATAL(it != package_result.m_tx_results.end());
857  UniValue result_inner{UniValue::VOBJ};
858  result_inner.pushKV("txid", tx->GetHash().GetHex());
859  if (it->second.m_result_type == MempoolAcceptResult::ResultType::DIFFERENT_WITNESS) {
860  result_inner.pushKV("other-wtxid", it->second.m_other_wtxid.value().GetHex());
861  }
862  if (it->second.m_result_type == MempoolAcceptResult::ResultType::VALID ||
863  it->second.m_result_type == MempoolAcceptResult::ResultType::MEMPOOL_ENTRY) {
864  result_inner.pushKV("vsize", int64_t{it->second.m_vsize.value()});
865  UniValue fees(UniValue::VOBJ);
866  fees.pushKV("base", ValueFromAmount(it->second.m_base_fees.value()));
867  result_inner.pushKV("fees", fees);
868  if (it->second.m_replaced_transactions.has_value()) {
869  for (const auto& ptx : it->second.m_replaced_transactions.value()) {
870  replaced_txids.insert(ptx->GetHash());
871  }
872  }
873  }
874  tx_result_map.pushKV(tx->GetWitnessHash().GetHex(), result_inner);
875  }
876  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  }
880  UniValue replaced_list(UniValue::VARR);
881  for (const uint256& hash : replaced_txids) replaced_list.push_back(hash.ToString());
882  rpc_result.pushKV("replaced-transactions", replaced_list);
883  return rpc_result;
884  },
885  };
886 }
887 
889 {
890  static const CRPCCommand commands[]{
891  {"rawtransactions", &sendrawtransaction},
892  {"rawtransactions", &testmempoolaccept},
893  {"blockchain", &getmempoolancestors},
894  {"blockchain", &getmempooldescendants},
895  {"blockchain", &getmempoolentry},
896  {"blockchain", &gettxspendingprevout},
897  {"blockchain", &getmempoolinfo},
898  {"blockchain", &getrawmempool},
899  {"blockchain", &savemempool},
900  {"hidden", &submitpackage},
901  };
902  for (const auto& c : commands) {
903  t.appendCommand(c.name, &c);
904  }
905 }
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
int ret
static CAmount AmountFromValue(const UniValue &value)
Definition: bitcoin-tx.cpp:550
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: validation.cpp:121
const CChainParams & Params()
Return the currently selected parameters.
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:47
#define NONFATAL_UNREACHABLE()
NONFATAL_UNREACHABLE() is a macro that is used to mark unreachable code.
Definition: check.h:92
bool IsMockableChain() const
If this chain allows time to be mocked.
Definition: chainparams.h:103
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
Definition: feerate.h:33
CAmount GetFee(uint32_t num_bytes) const
Return the fee in satoshis for the given vsize in vbytes.
Definition: feerate.cpp:23
CAmount GetFeePerK() const
Return the fee in satoshis for a vsize of 1000 vbytes.
Definition: feerate.h:65
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:35
uint256 hash
Definition: transaction.h:37
RPC command dispatcher.
Definition: server.h:126
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:288
const uint256 & GetHash() const
Definition: transaction.h:330
const std::vector< CTxIn > vin
Definition: transaction.h:298
An input of a transaction.
Definition: transaction.h:74
COutPoint prevout
Definition: transaction.h:76
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
Definition: txmempool.h:89
const CTransaction & GetTx() const
Definition: txmempool.h:129
std::set< CTxMemPoolEntryRef, CompareIteratorByHash > Children
Definition: txmempool.h:94
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:432
bool GetLoadTried() const
Definition: txmempool.cpp:1189
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
Definition: txmempool.h:521
CFeeRate GetMinFee(size_t sizelimit) const
Definition: txmempool.cpp:1080
const bool m_full_rbf
Definition: txmempool.h:577
const int64_t m_max_size_bytes
Definition: txmempool.h:569
size_t DynamicMemoryUsage() const
Definition: txmempool.cpp:1009
bool CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents=true) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Try to calculate all in-mempool ancestors of entry.
Definition: txmempool.cpp:270
std::set< txiter, CompareIteratorByHash > setEntries
Definition: txmempool.h:527
std::set< uint256 > GetUnbroadcastTxs() const
Returns transactions in unbroadcast set.
Definition: txmempool.h:800
void queryHashes(std::vector< uint256 > &vtxid) const
Definition: txmempool.cpp:851
const CFeeRate m_min_relay_feerate
Definition: txmempool.h:572
uint64_t GetSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.h:818
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
Definition: txmempool.h:524
const CFeeRate m_incremental_relay_feerate
Definition: txmempool.h:571
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:946
void CalculateDescendants(txiter it, setEntries &setDescendants) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Populate setDescendants with all in-mempool descendants of hash.
Definition: txmempool.cpp:555
unsigned long size() const
Definition: txmempool.h:749
CAmount GetTotalFee() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.h:761
uint64_t GetTotalTxSize() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.h:755
Chainstate stores and provides an API to update our local knowledge of the current best chain.
Definition: validation.h:438
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Definition: validation.h:800
MempoolAcceptResult ProcessTransaction(const CTransactionRef &tx, bool test_accept=false) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Try to add a transaction to the memory pool.
Chainstate & ActiveChainstate() const
The most-work chain.
static GenTxid Txid(const uint256 &hash)
Definition: transaction.h:425
void push_back(UniValue val)
Definition: univalue.cpp:104
@ VOBJ
Definition: univalue.h:20
@ VSTR
Definition: univalue.h:20
@ VARR
Definition: univalue.h:20
@ VNUM
Definition: univalue.h:20
const UniValue & get_obj() const
void __pushKV(std::string key, UniValue val)
Definition: univalue.cpp:118
size_t size() const
Definition: univalue.h:70
const std::vector< UniValue > & getValues() const
bool empty() const
Definition: univalue.h:68
Int getInt() const
Definition: univalue.h:142
const UniValue & get_array() const
void pushKV(std::string key, UniValue val)
Definition: univalue.cpp:126
bool get_bool() const
std::string GetRejectReason() const
Definition: validation.h:125
Result GetResult() const
Definition: validation.h:124
std::string ToString() const
Definition: uint256.cpp:64
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:31
std::string u8string() const
Definition: fs.h:55
256-bit opaque blob.
Definition: uint256.h:119
@ TX_MISSING_INPUTS
transaction was missing some of its inputs
UniValue ValueFromAmount(const CAmount amount)
Definition: core_write.cpp:26
bool DecodeHexTx(CMutableTransaction &tx, const std::string &hex_tx, bool try_no_witness=false, bool try_witness=true)
Definition: core_read.cpp:195
TransactionError
Definition: error.h:22
const std::string CURRENCY_UNIT
Definition: feerate.h:17
static RPCHelpMan getmempoolinfo()
Definition: mempool.cpp:676
static RPCHelpMan sendrawtransaction()
Definition: mempool.cpp:31
static void entryToJSON(const CTxMemPool &pool, UniValue &info, const CTxMemPoolEntry &e) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
Definition: mempool.cpp:263
static std::vector< RPCResult > MempoolEntryDescription()
Definition: mempool.cpp:235
void RegisterMempoolRPCCommands(CRPCTable &t)
Definition: mempool.cpp:888
static RPCHelpMan getrawmempool()
Definition: mempool.cpp:363
static RPCHelpMan getmempoolentry()
Definition: mempool.cpp:542
UniValue MempoolInfoToJSON(const CTxMemPool &pool)
Mempool information to JSON.
Definition: mempool.cpp:657
static RPCHelpMan gettxspendingprevout()
Definition: mempool.cpp:575
static RPCHelpMan submitpackage()
Definition: mempool.cpp:744
UniValue MempoolToJSON(const CTxMemPool &pool, bool verbose, bool include_mempool_sequence)
Mempool to JSON.
Definition: mempool.cpp:322
static RPCHelpMan testmempoolaccept()
Definition: mempool.cpp:92
static RPCHelpMan getmempooldescendants()
Definition: mempool.cpp:477
static RPCHelpMan getmempoolancestors()
Definition: mempool.cpp:413
static RPCHelpMan savemempool()
Definition: mempool.cpp:707
std::string FormatMoney(const CAmount n)
Money parsing/formatting utilities.
Definition: moneystr.cpp:16
bool DumpMempool(const CTxMemPool &pool, const fs::path &dump_path, FopenFn mockable_fopen_function, bool skip_file_commit)
Definition: init.h:25
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:33
fs::path MempoolPath(const ArgsManager &argsman)
static const CFeeRate DEFAULT_MAX_RAW_TX_FEE_RATE
Maximum fee rate for sendrawtransaction and testmempoolaccept RPC calls.
Definition: transaction.h:26
ArgsManager args
static constexpr uint32_t MAX_PACKAGE_COUNT
Default maximum number of transactions in a package.
Definition: packages.h:17
@ PCKG_POLICY
The package itself is invalid (e.g. too many transactions).
@ PCKG_RESULT_UNSET
Initial value. The package has not yet been rejected.
@ PCKG_MEMPOOL_ERROR
Mempool logic error.
@ PCKG_TX
At least one tx is invalid.
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:20
RBFTransactionState
The rbf state of unconfirmed transactions.
Definition: rbf.h:27
@ UNKNOWN
Unconfirmed tx that does not signal rbf and is not in the mempool.
@ REPLACEABLE_BIP125
Either this tx or a mempool ancestor signals rbf.
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:295
static CTransactionRef MakeTransactionRef(Tx &&txIn)
Definition: transaction.h:415
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:414
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:56
@ RPC_MISC_ERROR
General application defined errors.
Definition: protocol.h:39
@ RPC_INVALID_PARAMETER
Invalid, missing or duplicate parameter.
Definition: protocol.h:43
@ RPC_DESERIALIZATION_ERROR
Error parsing or validating structure in raw format.
Definition: protocol.h:45
@ RPC_INVALID_ADDRESS_OR_KEY
Invalid address or key.
Definition: protocol.h:41
void RPCTypeCheck(const UniValue &params, const std::list< UniValueType > &typesExpected, bool fAllowNull)
Type-check arguments; throws JSONRPCError if wrong type given.
Definition: util.cpp:33
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:166
UniValue JSONRPCTransactionError(TransactionError terr, const std::string &err_string)
Definition: util.cpp:369
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:184
uint256 ParseHashO(const UniValue &o, std::string strKey)
Definition: util.cpp:109
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded Values (throws error if not hex).
Definition: util.cpp:100
void RPCTypeCheckObj(const UniValue &o, const std::map< std::string, UniValueType > &typesExpected, bool fAllowNull, bool fStrict)
Definition: util.cpp:58
ArgsManager & EnsureAnyArgsman(const std::any &context)
Definition: server_util.cpp:50
CTxMemPool & EnsureAnyMemPool(const std::any &context)
Definition: server_util.cpp:37
NodeContext & EnsureAnyNodeContext(const std::any &context)
Definition: server_util.cpp:20
CTxMemPool & EnsureMemPool(const NodeContext &node)
Definition: server_util.cpp:29
ChainstateManager & EnsureChainman(const NodeContext &node)
Definition: server_util.cpp:55
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:109
A mutable version of CTransaction.
Definition: transaction.h:373
@ DIFFERENT_WITNESS
Valid, transaction was already in the mempool.
Validation result for package mempool acceptance.
Definition: validation.h:203
std::map< const uint256, const MempoolAcceptResult > m_tx_results
Map from wtxid to finished MempoolAcceptResults.
Definition: validation.h:211
const PackageValidationState m_state
Definition: validation.h:204
@ STR_HEX
Special type that is a STR with only hex chars.
@ AMOUNT
Special type representing a floating point amount (can be either NUM or STR)
@ OMITTED
Optional argument with default value omitted because they are implicitly clear.
@ NO
Required arg.
@ NUM_TIME
Special numeric to denote unix epoch time.
@ OBJ_DYN
Special dictionary with keys that are not literals.
@ STR_HEX
Special string with only hex chars.
@ STR_AMOUNT
Special string to represent a floating point amount.
Wrapper for UniValue::VType, which includes typeAny: Used to denote don't care type.
Definition: util.h:58
NodeContext struct containing references to chain state and connection state.
Definition: context.h:43
#define AssertLockNotHeld(cs)
Definition: sync.h:148
#define LOCK(cs)
Definition: sync.h:261
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:305
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49
constexpr int64_t count_seconds(std::chrono::seconds t)
Definition: time.h:54
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
const UniValue & find_value(const UniValue &obj, const std::string &name)
Definition: univalue.cpp:233
PackageMempoolAcceptResult ProcessNewPackage(Chainstate &active_chainstate, CTxMemPool &pool, const Package &package, bool test_accept)
Validate (and maybe submit) a package to the mempool.
AssertLockHeld(pool.cs)