diff options
author | MarcoFalke <falke.marco@gmail.com> | 2022-03-16 12:06:15 +0100 |
---|---|---|
committer | MarcoFalke <falke.marco@gmail.com> | 2022-03-17 08:42:14 +0100 |
commit | fa2d176016683eac82dabfbfc276b8a7b07b7499 (patch) | |
tree | e0911bfe022cd05f7f4be7062d087a95d4d9172e /src/rpc/rawtransaction.cpp | |
parent | bf2c0fb2a26432762bf98e19a98e252b7bdd7d30 (diff) | |
download | bitcoin-fa2d176016683eac82dabfbfc276b8a7b07b7499.tar.xz |
Move txoutproof RPCs to txoutproof.cpp
Diffstat (limited to 'src/rpc/rawtransaction.cpp')
-rw-r--r-- | src/rpc/rawtransaction.cpp | 153 |
1 files changed, 0 insertions, 153 deletions
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 1ef531b293..148734f31a 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -11,7 +11,6 @@ #include <core_io.h> #include <index/txindex.h> #include <key_io.h> -#include <merkleblock.h> #include <node/blockstorage.h> #include <node/coin.h> #include <node/context.h> @@ -268,155 +267,6 @@ static RPCHelpMan getrawtransaction() }; } -static RPCHelpMan gettxoutproof() -{ - return RPCHelpMan{"gettxoutproof", - "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n" - "\nNOTE: By default this function only works sometimes. This is when there is an\n" - "unspent output in the utxo for this transaction. To make it always work,\n" - "you need to maintain a transaction index, using the -txindex command line option or\n" - "specify the block in which the transaction is included manually (by blockhash).\n", - { - {"txids", RPCArg::Type::ARR, RPCArg::Optional::NO, "The txids to filter", - { - {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A transaction hash"}, - }, - }, - {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED_NAMED_ARG, "If specified, looks for txid in the block with this hash"}, - }, - RPCResult{ - RPCResult::Type::STR, "data", "A string that is a serialized, hex-encoded data for the proof." - }, - RPCExamples{""}, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue -{ - std::set<uint256> setTxids; - UniValue txids = request.params[0].get_array(); - if (txids.empty()) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Parameter 'txids' cannot be empty"); - } - for (unsigned int idx = 0; idx < txids.size(); idx++) { - auto ret = setTxids.insert(ParseHashV(txids[idx], "txid")); - if (!ret.second) { - throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated txid: ") + txids[idx].get_str()); - } - } - - const CBlockIndex* pblockindex = nullptr; - uint256 hashBlock; - ChainstateManager& chainman = EnsureAnyChainman(request.context); - if (!request.params[1].isNull()) { - LOCK(cs_main); - hashBlock = ParseHashV(request.params[1], "blockhash"); - pblockindex = chainman.m_blockman.LookupBlockIndex(hashBlock); - if (!pblockindex) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); - } - } else { - LOCK(cs_main); - CChainState& active_chainstate = chainman.ActiveChainstate(); - - // Loop through txids and try to find which block they're in. Exit loop once a block is found. - for (const auto& tx : setTxids) { - const Coin& coin = AccessByTxid(active_chainstate.CoinsTip(), tx); - if (!coin.IsSpent()) { - pblockindex = active_chainstate.m_chain[coin.nHeight]; - break; - } - } - } - - - // Allow txindex to catch up if we need to query it and before we acquire cs_main. - if (g_txindex && !pblockindex) { - g_txindex->BlockUntilSyncedToCurrentChain(); - } - - LOCK(cs_main); - - if (pblockindex == nullptr) { - const CTransactionRef tx = GetTransaction(/* block_index */ nullptr, /* mempool */ nullptr, *setTxids.begin(), Params().GetConsensus(), hashBlock); - if (!tx || hashBlock.IsNull()) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block"); - } - pblockindex = chainman.m_blockman.LookupBlockIndex(hashBlock); - if (!pblockindex) { - throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt"); - } - } - - CBlock block; - if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) { - throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); - } - - unsigned int ntxFound = 0; - for (const auto& tx : block.vtx) { - if (setTxids.count(tx->GetHash())) { - ntxFound++; - } - } - if (ntxFound != setTxids.size()) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Not all transactions found in specified or retrieved block"); - } - - CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS); - CMerkleBlock mb(block, setTxids); - ssMB << mb; - std::string strHex = HexStr(ssMB); - return strHex; -}, - }; -} - -static RPCHelpMan verifytxoutproof() -{ - return RPCHelpMan{"verifytxoutproof", - "\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n" - "and throwing an RPC error if the block is not in our best chain\n", - { - {"proof", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex-encoded proof generated by gettxoutproof"}, - }, - RPCResult{ - RPCResult::Type::ARR, "", "", - { - {RPCResult::Type::STR_HEX, "txid", "The txid(s) which the proof commits to, or empty array if the proof cannot be validated."}, - } - }, - RPCExamples{""}, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue -{ - CDataStream ssMB(ParseHexV(request.params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS); - CMerkleBlock merkleBlock; - ssMB >> merkleBlock; - - UniValue res(UniValue::VARR); - - std::vector<uint256> vMatch; - std::vector<unsigned int> vIndex; - if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot) - return res; - - ChainstateManager& chainman = EnsureAnyChainman(request.context); - LOCK(cs_main); - - const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(merkleBlock.header.GetHash()); - if (!pindex || !chainman.ActiveChain().Contains(pindex) || pindex->nTx == 0) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain"); - } - - // Check if proof is valid, only add results if so - if (pindex->nTx == merkleBlock.txn.GetNumTransactions()) { - for (const uint256& hash : vMatch) { - res.push_back(hash.GetHex()); - } - } - - return res; -}, - }; -} - static RPCHelpMan createrawtransaction() { return RPCHelpMan{"createrawtransaction", @@ -2089,9 +1939,6 @@ static const CRPCCommand commands[] = { "rawtransactions", &utxoupdatepsbt, }, { "rawtransactions", &joinpsbts, }, { "rawtransactions", &analyzepsbt, }, - - { "blockchain", &gettxoutproof, }, - { "blockchain", &verifytxoutproof, }, }; // clang-format on for (const auto& c : commands) { |