Repository: bitcoin/bitcoin
File: src/rpc/mempool.cpp (C++)

Code before:
            return ret;
        },
    };
}

static RPCHelpMan abortprivatebroadcast()
{
    return RPCHelpMan{
        "abortprivatebroadcast",
        "Abort private broadcast attempts for a transaction currently being privately broadcast.\n"
        "The transaction will be removed from the private broadcast queue.\n",
        {
            {"id", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "A transaction identifier to abort. It will be matched against both txid and wtxid for all transactions in the private broadcast queue.\n"
                                                                "If the provided id matches a txid that corresponds to multiple transactions with different wtxids, multiple transactions will be removed and returned."},
        },
        RPCResult{
            RPCResult::Type::OBJ, "", "",
            {
                {RPCResult::Type::ARR, "removed_transactions", "Transactions removed from the private broadcast queue",
                    {
                        {RPCResult::Type::OBJ, "", "",
                            {
                                {RPCResult::Type::STR_HEX, "txid", "The transaction hash in hex"},
                                {RPCResult::Type::STR_HEX, "wtxid", "The transaction witness hash in hex"},
                                {RPCResult::Type::STR_HEX, "hex", "The serialized, hex-encoded transaction data"},
                            }},
                    }},
            }
        },
        RPCExamples{
            HelpExampleCli("abortprivatebroadcast", "\"id\"")
            + HelpExampleRpc("abortprivatebroadcast", "\"id\"")
        },
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
        {
            const uint256 id{ParseHashV(self.Arg<UniValue>("id"), "id")};

            const NodeContext& node{EnsureAnyNodeContext(request.context)};
            PeerManager& peerman{EnsurePeerman(node)};

            const auto removed_txs{peerman.AbortPrivateBroadcast(id)};
            if (removed_txs.empty()) {
                throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in private broadcast queue. Check getprivatebroadcastinfo.");
            }

            UniValue removed_transactions(UniValue::VARR);
            for (const auto& tx : removed_txs) {
                UniValue o(UniValue::VOBJ);
                o.pushKV("txid", tx->GetHash().ToString());
                o.pushKV("wtxid", tx->GetWitnessHash().ToString());
                o.pushKV("hex", EncodeHexTx(*tx));

Review comment (suggestion):
`RPC_INVALID_ADDRESS_OR_KEY` is typically used for Bitcoin address/key validation errors. Maybe `RPC_INVALID_PARAMETER` would be more accurate.

Code after:
            {
                {RPCResult::Type::ARR, "removed_transactions", "Transactions removed from the private broadcast queue",
                    {
                        {RPCResult::Type::OBJ, "", "",
                            {
                                {RPCResult::Type::STR_HEX, "txid", "The transaction hash in hex"},
                                {RPCResult::Type::STR_HEX, "wtxid", "The transaction witness hash in hex"},
                                {RPCResult::Type::STR_HEX, "hex", "The serialized, hex-encoded transaction data"},
                            }},
                    }},
            }
        },
        RPCExamples{
            HelpExampleCli("abortprivatebroadcast", "\"id\"")
            + HelpExampleRpc("abortprivatebroadcast", "\"id\"")
        },
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
        {
            const uint256 id{ParseHashV(self.Arg<UniValue>("id"), "id")};

            const NodeContext& node{EnsureAnyNodeContext(request.context)};
            PeerManager& peerman{EnsurePeerman(node)};

            const auto removed_txs{peerman.AbortPrivateBroadcast(id)};
            if (removed_txs.empty()) {
                throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in private broadcast queue. Check getprivatebroadcastinfo.");
            }

            UniValue removed_transactions(UniValue::VARR);
            for (const auto& tx : removed_txs) {
                UniValue o(UniValue::VOBJ);
                o.pushKV("txid", tx->GetHash().ToString());
                o.pushKV("wtxid", tx->GetWitnessHash().ToString());
                o.pushKV("hex", EncodeHexTx(*tx));
                removed_transactions.push_back(std::move(o));
            }
            UniValue ret(UniValue::VOBJ);
            ret.pushKV("removed_transactions", std::move(removed_transactions));
            return ret;
        },
    };
}

static RPCHelpMan testmempoolaccept()
{
    return RPCHelpMan{
        "testmempoolaccept",
        "Returns result of mempool acceptance tests indicating if raw transaction(s) (serialized, hex-encoded) would be accepted by mempool.\n"
        "\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"
        "\nIf one transaction fails, other transactions may not be fully validated (the 'allowed' key will be blank).\n"
        "\nThe maximum number of transactions allowed is " + ToString(MAX_PACKAGE_COUNT) + ".\n"