Created
April 29, 2022 22:47
-
-
Save luke-jr/beb37abb2cfc2f7db86605f74bc4b934 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp | |
index d82e596e60e..396c18c5bf8 100644 | |
--- a/src/rpc/blockchain.cpp | |
+++ b/src/rpc/blockchain.cpp | |
@@ -1416,6 +1416,11 @@ static RPCHelpMan gettxspendingprevout() | |
}, | |
}, | |
}, | |
+ {"options", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED_NAMED_ARG, "", | |
+ { | |
+ {"mempool_only", RPCArg::Type::BOOL, RPCArg::DefaultHint{"true if txospenderindex unavailable, otherwise false"}, "If true, txospenderindex will not be used even if mempool lacks a relevant spend. If false and txospenderindex is unavailable, throws an exception if any outpoint lacks a mempool spend."}, | |
+ }, | |
+ "options"}, | |
}, | |
RPCResult{ | |
RPCResult::Type::ARR, "", "", | |
@@ -1425,6 +1430,10 @@ static RPCHelpMan gettxspendingprevout() | |
{RPCResult::Type::STR_HEX, "txid", "the transaction id of the checked output"}, | |
{RPCResult::Type::NUM, "vout", "the vout value of the checked output"}, | |
{RPCResult::Type::STR_HEX, "spendingtxid", /*optional=*/true, "the transaction id of the mempool transaction spending this output (omitted if unspent)"}, | |
+ {RPCResult::Type::ARR, "warnings", /* optional */ true, "If spendingtxid isn't found in the mempool, and the mempool_only option isn't set explicitly, this will advise of issues using the txospenderindex.", | |
+ { | |
+ {RPCResult::Type::STR, "", ""}, | |
+ }}, | |
}}, | |
} | |
}, | |
@@ -1440,6 +1449,20 @@ static RPCHelpMan gettxspendingprevout() | |
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, outputs are missing"); | |
} | |
+ std::optional<bool> mempool_only; | |
+ if (!request.params[1].isNull()) { | |
+ const UniValue& options = request.params[1]; | |
+ RPCTypeCheckObj(options, | |
+ { | |
+ {"mempool_only", UniValueType(UniValue::VBOOL)}, | |
+ }, | |
+ /*fAllowNull=*/true, /*fStrict=*/true); | |
+ | |
+ if (options.exists("mempool_only")) { | |
+ mempool_only = options["mempool_only"].get_bool(); | |
+ } | |
+ } | |
+ | |
std::vector<COutPoint> prevouts; | |
prevouts.reserve(output_params.size()); | |
@@ -1461,7 +1484,10 @@ static RPCHelpMan gettxspendingprevout() | |
prevouts.emplace_back(txid, nOutput); | |
} | |
- bool f_txospenderindex_ready = g_txospenderindex ? g_txospenderindex->BlockUntilSyncedToCurrentChain() : false; | |
+ bool f_txospenderindex_ready{false}; | |
+ if (g_txospenderindex && !mempool_only.value_or(false)) { | |
+ f_txospenderindex_ready = g_txospenderindex->BlockUntilSyncedToCurrentChain(); | |
+ } | |
const CTxMemPool& mempool = EnsureAnyMemPool(request.context); | |
LOCK(mempool.cs); | |
@@ -1476,13 +1502,29 @@ static RPCHelpMan gettxspendingprevout() | |
const CTransaction* spendingTx = mempool.GetConflictTx(prevout); | |
if (spendingTx != nullptr) { | |
o.pushKV("spendingtxid", spendingTx->GetHash().ToString()); | |
+ } else if (mempool_only.value_or(false)) { | |
+ // do nothing | |
} else if (g_txospenderindex) { | |
// no spending tx in mempool, query txospender index | |
uint256 spendingtxid; | |
if(g_txospenderindex->FindSpender(prevout, spendingtxid)) { | |
o.pushKV("spendingtxid", spendingtxid.GetHex()); | |
} else if (!f_txospenderindex_ready) { | |
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No spending tx for the provided outpoint. Transactions spenders are still in the process of being indexed "); | |
+ if (mempool_only.has_value()) { // NOTE: value is false here | |
+ throw JSONRPCError(RPC_MISC_ERROR, "No spending tx for the outpoint %s:%s found, and txospenderindex is still being synced."); | |
+ } else { | |
+ UniValue warnings(UniValue::VARR); | |
+ warnings.push_back("txospenderindex is still being synced."); | |
+ o.pushKV("warnings", warnings); | |
+ } | |
+ } | |
+ } else { | |
+ if (mempool_only.has_value()) { // NOTE: value is false here | |
+ throw JSONRPCError(RPC_MISC_ERROR, "No spending tx for the outpoint %s:%s in mempool, and txospenderindex is unavailable."); | |
+ } else { | |
+ UniValue warnings(UniValue::VARR); | |
+ warnings.push_back("txospenderindex is unavailable."); | |
+ o.pushKV("warnings", warnings); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment