Move reused sign and send logic

This commit is contained in:
Eirik0 2019-05-10 12:45:14 -06:00
parent a7a52d2424
commit 0e06801e12
5 changed files with 62 additions and 92 deletions

View File

@ -2,8 +2,11 @@
#include "core_io.h"
#include "init.h"
#include "rpc/protocol.h"
#include "wallet.h"
extern UniValue signrawtransaction(const UniValue& params, bool fHelp);
UniValue SendTransaction(CTransaction& tx, bool testmode) {
UniValue o(UniValue::VOBJ);
// Send the transaction
@ -19,4 +22,37 @@ UniValue SendTransaction(CTransaction& tx, bool testmode) {
o.push_back(Pair("hex", EncodeHexTx(tx)));
}
return o;
}
std::pair<CTransaction, UniValue> SignSendRawTransaction(UniValue obj, bool testmode) {
// Sign the raw transaction
UniValue rawtxnValue = find_value(obj, "rawtxn");
if (rawtxnValue.isNull()) {
throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for raw transaction");
}
std::string rawtxn = rawtxnValue.get_str();
UniValue params = UniValue(UniValue::VARR);
params.push_back(rawtxn);
UniValue signResultValue = signrawtransaction(params, false);
UniValue signResultObject = signResultValue.get_obj();
UniValue completeValue = find_value(signResultObject, "complete");
bool complete = completeValue.get_bool();
if (!complete) {
// TODO: #1366 Maybe get "errors" and print array vErrors into a string
throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Failed to sign transaction");
}
UniValue hexValue = find_value(signResultObject, "hex");
if (hexValue.isNull()) {
throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for signed transaction");
}
std::string signedtxn = hexValue.get_str();
CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION);
CTransaction tx;
stream >> tx;
UniValue sendResult = SendTransaction(tx, testmode);
return std::make_pair(tx, sendResult);
}

View File

@ -8,6 +8,23 @@
#include "primitives/transaction.h"
#include "univalue.h"
/**
* Sends a given transaction.
*
* If testmode is false, commit the transaction to the wallet,
* return {"txid": tx.GetHash().ToString()}
*
* If testmode is true, do not commit the transaction,
* return {"test": 1, "txid": tx.GetHash().ToString(), "hex": EncodeHexTx(tx)}
*/
UniValue SendTransaction(CTransaction& tx, bool testmode);
/**
* Sign and send a raw transaction.
* Raw transaction as hex string should be in object field "rawtxn"
*
* Returns a pair of (the parsed transaction, and the result of sending)
*/
std::pair<CTransaction, UniValue> SignSendRawTransaction(UniValue obj, bool testmode);
#endif /* ASYNCRPCOPERATION_COMMON_H */

View File

@ -720,44 +720,15 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
}
extern UniValue signrawtransaction(const UniValue& params, bool fHelp);
/**
* Sign and send a raw transaction.
* Raw transaction as hex string should be in object field "rawtxn"
*/
void AsyncRPCOperation_mergetoaddress::sign_send_raw_transaction(UniValue obj)
{
// Sign the raw transaction
UniValue rawtxnValue = find_value(obj, "rawtxn");
if (rawtxnValue.isNull()) {
throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for raw transaction");
}
std::string rawtxn = rawtxnValue.get_str();
UniValue params = UniValue(UniValue::VARR);
params.push_back(rawtxn);
UniValue signResultValue = signrawtransaction(params, false);
UniValue signResultObject = signResultValue.get_obj();
UniValue completeValue = find_value(signResultObject, "complete");
bool complete = completeValue.get_bool();
if (!complete) {
// TODO: #1366 Maybe get "errors" and print array vErrors into a string
throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Failed to sign transaction");
}
UniValue hexValue = find_value(signResultObject, "hex");
if (hexValue.isNull()) {
throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for signed transaction");
}
std::string signedtxn = hexValue.get_str();
CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION);
CTransaction tx;
stream >> tx;
tx_ = tx;
UniValue sendResult = SendTransaction(tx_, testmode);
set_result(sendResult);
auto txAndResult = SignSendRawTransaction(obj, testmode);
tx_ = txAndResult.first;
set_result(txAndResult.second);
}

View File

@ -897,36 +897,9 @@ bool AsyncRPCOperation_sendmany::main_impl() {
*/
void AsyncRPCOperation_sendmany::sign_send_raw_transaction(UniValue obj)
{
// Sign the raw transaction
UniValue rawtxnValue = find_value(obj, "rawtxn");
if (rawtxnValue.isNull()) {
throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for raw transaction");
}
std::string rawtxn = rawtxnValue.get_str();
UniValue params = UniValue(UniValue::VARR);
params.push_back(rawtxn);
UniValue signResultValue = signrawtransaction(params, false);
UniValue signResultObject = signResultValue.get_obj();
UniValue completeValue = find_value(signResultObject, "complete");
bool complete = completeValue.get_bool();
if (!complete) {
// TODO: #1366 Maybe get "errors" and print array vErrors into a string
throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Failed to sign transaction");
}
UniValue hexValue = find_value(signResultObject, "hex");
if (hexValue.isNull()) {
throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for signed transaction");
}
std::string signedtxn = hexValue.get_str();
CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION);
CTransaction tx;
stream >> tx;
tx_ = tx;
UniValue sendResult = SendTransaction(tx_, testmode);
set_result(sendResult);
auto txAndResult = SignSendRawTransaction(obj, testmode);
tx_ = txAndResult.first;
set_result(txAndResult.second);
}

View File

@ -278,36 +278,9 @@ bool ShieldToAddress::operator()(const libzcash::InvalidEncoding& no) const {
*/
void AsyncRPCOperation_shieldcoinbase::sign_send_raw_transaction(UniValue obj)
{
// Sign the raw transaction
UniValue rawtxnValue = find_value(obj, "rawtxn");
if (rawtxnValue.isNull()) {
throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for raw transaction");
}
std::string rawtxn = rawtxnValue.get_str();
UniValue params = UniValue(UniValue::VARR);
params.push_back(rawtxn);
UniValue signResultValue = signrawtransaction(params, false);
UniValue signResultObject = signResultValue.get_obj();
UniValue completeValue = find_value(signResultObject, "complete");
bool complete = completeValue.get_bool();
if (!complete) {
// TODO: #1366 Maybe get "errors" and print array vErrors into a string
throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Failed to sign transaction");
}
UniValue hexValue = find_value(signResultObject, "hex");
if (hexValue.isNull()) {
throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for signed transaction");
}
std::string signedtxn = hexValue.get_str();
CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION);
CTransaction tx;
stream >> tx;
tx_ = tx;
UniValue sendResult = SendTransaction(tx_, testmode);
set_result(sendResult);
auto txAndResult = SignSendRawTransaction(obj, testmode);
tx_ = txAndResult.first;
set_result(txAndResult.second);
}