Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/rawtransaction.cpp
Show First 20 Lines • Show All 721 Lines • ▼ Show 20 Lines | static void TxInErrorToJSON(const CTxIn &txin, UniValue &vErrorsRet, | ||||
entry.push_back(Pair("sequence", uint64_t(txin.nSequence))); | entry.push_back(Pair("sequence", uint64_t(txin.nSequence))); | ||||
entry.push_back(Pair("error", strMessage)); | entry.push_back(Pair("error", strMessage)); | ||||
vErrorsRet.push_back(entry); | vErrorsRet.push_back(entry); | ||||
} | } | ||||
UniValue combinerawtransaction(const Config &config, | UniValue combinerawtransaction(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 1) | if (request.fHelp || request.params.size() != 1) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
"combinerawtransaction [\"hexstring\",...]\n" | "combinerawtransaction [\"hexstring\",...]\n" | ||||
"\nCombine multiple partially signed transactions into one " | "\nCombine multiple partially signed transactions into one " | ||||
"transaction.\n" | "transaction.\n" | ||||
"The combined transaction may be another partially signed " | "The combined transaction may be another partially signed " | ||||
"transaction or a \n" | "transaction or a \n" | ||||
"fully signed transaction." | "fully signed transaction." | ||||
"\nArguments:\n" | "\nArguments:\n" | ||||
"1. \"txs\" (string) A json array of hex strings of " | "1. \"txs\" (string) A json array of hex strings of " | ||||
"partially signed transactions\n" | "partially signed transactions\n" | ||||
" [\n" | " [\n" | ||||
" \"hexstring\" (string) A transaction hash\n" | " \"hexstring\" (string) A transaction hash\n" | ||||
" ,...\n" | " ,...\n" | ||||
" ]\n" | " ]\n" | ||||
"\nResult:\n" | "\nResult:\n" | ||||
"\"hex\" : \"value\", (string) The hex-encoded raw " | "\"hex\" : \"value\", (string) The hex-encoded raw " | ||||
"transaction with signature(s)\n" | "transaction with signature(s)\n" | ||||
"\nExamples:\n" + | "\nExamples:\n" + | ||||
HelpExampleCli("combinerawtransaction", | HelpExampleCli("combinerawtransaction", | ||||
"[\"myhex1\", \"myhex2\", \"myhex3\"]")); | "[\"myhex1\", \"myhex2\", \"myhex3\"]")); | ||||
} | |||||
UniValue txs = request.params[0].get_array(); | UniValue txs = request.params[0].get_array(); | ||||
std::vector<CMutableTransaction> txVariants(txs.size()); | std::vector<CMutableTransaction> txVariants(txs.size()); | ||||
for (unsigned int idx = 0; idx < txs.size(); idx++) { | for (unsigned int idx = 0; idx < txs.size(); idx++) { | ||||
if (!DecodeHexTx(txVariants[idx], txs[idx].get_str())) { | if (!DecodeHexTx(txVariants[idx], txs[idx].get_str())) { | ||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, | ||||
strprintf("TX decode failed for tx %d", idx)); | strprintf("TX decode failed for tx %d", idx)); | ||||
Show All 11 Lines | UniValue combinerawtransaction(const Config &config, | ||||
// Fetch previous transactions (inputs): | // Fetch previous transactions (inputs): | ||||
CCoinsView viewDummy; | CCoinsView viewDummy; | ||||
CCoinsViewCache view(&viewDummy); | CCoinsViewCache view(&viewDummy); | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
LOCK(mempool.cs); | LOCK(mempool.cs); | ||||
CCoinsViewCache &viewChain = *pcoinsTip; | CCoinsViewCache &viewChain = *pcoinsTip; | ||||
CCoinsViewMemPool viewMempool(&viewChain, mempool); | CCoinsViewMemPool viewMempool(&viewChain, mempool); | ||||
view.SetBackend( | // temporarily switch cache backend to db+mempool view | ||||
viewMempool); // temporarily switch cache backend to db+mempool view | view.SetBackend(viewMempool); | ||||
for (const CTxIn &txin : mergedTx.vin) { | for (const CTxIn &txin : mergedTx.vin) { | ||||
view.AccessCoin(txin.prevout); // Load entries from viewChain into | // Load entries from viewChain into view; can fail. | ||||
// view; can fail. | view.AccessCoin(txin.prevout); | ||||
} | } | ||||
view.SetBackend( | // switch back to avoid locking mempool for too long | ||||
viewDummy); // switch back to avoid locking mempool for too long | view.SetBackend(viewDummy); | ||||
} | } | ||||
// Use CTransaction for the constant parts of the | // Use CTransaction for the constant parts of the | ||||
// transaction to avoid rehashing. | // transaction to avoid rehashing. | ||||
const CTransaction txConst(mergedTx); | const CTransaction txConst(mergedTx); | ||||
// Sign what we can: | // Sign what we can: | ||||
for (unsigned int i = 0; i < mergedTx.vin.size(); i++) { | for (unsigned int i = 0; i < mergedTx.vin.size(); i++) { | ||||
CTxIn &txin = mergedTx.vin[i]; | CTxIn &txin = mergedTx.vin[i]; | ||||
▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | |||||
#else | #else | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
#endif | #endif | ||||
RPCTypeCheck( | RPCTypeCheck( | ||||
request.params, | request.params, | ||||
{UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true); | {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true); | ||||
CMutableTransaction mtx; | CMutableTransaction mtx; | ||||
if (!DecodeHexTx(mtx, request.params[0].get_str())) | if (!DecodeHexTx(mtx, request.params[0].get_str())) { | ||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); | ||||
} | |||||
// Fetch previous transactions (inputs): | // Fetch previous transactions (inputs): | ||||
CCoinsView viewDummy; | CCoinsView viewDummy; | ||||
CCoinsViewCache view(&viewDummy); | CCoinsViewCache view(&viewDummy); | ||||
{ | { | ||||
LOCK(mempool.cs); | LOCK(mempool.cs); | ||||
CCoinsViewCache &viewChain = *pcoinsTip; | CCoinsViewCache &viewChain = *pcoinsTip; | ||||
CCoinsViewMemPool viewMempool(&viewChain, mempool); | CCoinsViewMemPool viewMempool(&viewChain, mempool); | ||||
▲ Show 20 Lines • Show All 336 Lines • Show Last 20 Lines |