| 775 | } |
| 776 | |
| 777 | static RPCHelpMan getmempooldescendants() |
| 778 | { |
| 779 | return RPCHelpMan{"getmempooldescendants", |
| 780 | "\nIf txid is in the mempool, returns all in-mempool descendants.\n", |
| 781 | { |
| 782 | {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"}, |
| 783 | {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "True for a json object, false for array of transaction ids"}, |
| 784 | }, |
| 785 | { |
| 786 | RPCResult{"for verbose = false", |
| 787 | RPCResult::Type::ARR, "", "", |
| 788 | {{RPCResult::Type::STR_HEX, "", "The transaction id of an in-mempool descendant transaction"}}}, |
| 789 | RPCResult{"for verbose = true", |
| 790 | RPCResult::Type::OBJ_DYN, "", "", |
| 791 | { |
| 792 | {RPCResult::Type::OBJ, "transactionid", "", MempoolEntryDescription()}, |
| 793 | }}, |
| 794 | }, |
| 795 | RPCExamples{ |
| 796 | HelpExampleCli("getmempooldescendants", "\"mytxid\"") |
| 797 | + HelpExampleRpc("getmempooldescendants", "\"mytxid\"") |
| 798 | }, |
| 799 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 800 | { |
| 801 | bool fVerbose = false; |
| 802 | if (!request.params[1].isNull()) |
| 803 | fVerbose = request.params[1].get_bool(); |
| 804 | |
| 805 | uint256 hash = ParseHashV(request.params[0], "parameter 1"); |
| 806 | |
| 807 | const CTxMemPool& mempool = EnsureAnyMemPool(request.context); |
| 808 | LOCK(mempool.cs); |
| 809 | |
| 810 | CTxMemPool::txiter it = mempool.mapTx.find(hash); |
| 811 | if (it == mempool.mapTx.end()) { |
| 812 | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool"); |
| 813 | } |
| 814 | |
| 815 | CTxMemPool::setEntries setDescendants; |
| 816 | mempool.CalculateDescendants(it, setDescendants); |
| 817 | // CTxMemPool::CalculateDescendants will include the given tx |
| 818 | setDescendants.erase(it); |
| 819 | |
| 820 | if (!fVerbose) { |
| 821 | UniValue o(UniValue::VARR); |
| 822 | for (CTxMemPool::txiter descendantIt : setDescendants) { |
| 823 | o.push_back(descendantIt->GetTx().GetHash().ToString()); |
| 824 | } |
| 825 | |
| 826 | return o; |
| 827 | } else { |
| 828 | UniValue o(UniValue::VOBJ); |
| 829 | for (CTxMemPool::txiter descendantIt : setDescendants) { |
| 830 | const CTxMemPoolEntry &e = *descendantIt; |
| 831 | const uint256& _hash = e.GetTx().GetHash(); |
| 832 | UniValue info(UniValue::VOBJ); |
| 833 | entryToJSON(mempool, info, e); |
| 834 | o.pushKV(_hash.ToString(), info); |
nothing calls this directly
no test coverage detected