Extract FinishTransaction from send()

The final step of send either produces a PSBT or the final transaction.
We extract these steps to a new helper function `FinishTransaction()` to
reuse them in `sendall`.
24.x
Murch 3 years ago
parent 6d2208a3f6
commit 902793c777
No known key found for this signature in database
GPG Key ID: 7BA035CA5B901713

@ -74,6 +74,50 @@ static void InterpretFeeEstimationInstructions(const UniValue& conf_target, cons
} }
} }
static UniValue FinishTransaction(const std::shared_ptr<CWallet> pwallet, const UniValue& options, const CMutableTransaction& rawTx)
{
// Make a blank psbt
PartiallySignedTransaction psbtx(rawTx);
// First fill transaction with our data without signing,
// so external signers are not asked sign more than once.
bool complete;
pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, false, true);
const TransactionError err{pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, true, false)};
if (err != TransactionError::OK) {
throw JSONRPCTransactionError(err);
}
CMutableTransaction mtx;
complete = FinalizeAndExtractPSBT(psbtx, mtx);
UniValue result(UniValue::VOBJ);
const bool psbt_opt_in{options.exists("psbt") && options["psbt"].get_bool()};
bool add_to_wallet{options.exists("add_to_wallet") ? options["add_to_wallet"].get_bool() : true};
if (psbt_opt_in || !complete || !add_to_wallet) {
// Serialize the PSBT
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << psbtx;
result.pushKV("psbt", EncodeBase64(ssTx.str()));
}
if (complete) {
std::string hex{EncodeHexTx(CTransaction(mtx))};
CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
result.pushKV("txid", tx->GetHash().GetHex());
if (add_to_wallet && !psbt_opt_in) {
pwallet->CommitTransaction(tx, {}, {} /* orderForm */);
} else {
result.pushKV("hex", hex);
}
}
result.pushKV("complete", complete);
return result;
}
static void PreventOutdatedOptions(const UniValue& options) static void PreventOutdatedOptions(const UniValue& options)
{ {
if (options.exists("feeRate")) { if (options.exists("feeRate")) {
@ -1174,14 +1218,10 @@ RPCHelpMan send()
InterpretFeeEstimationInstructions(/*conf_target=*/request.params[1], /*estimate_mode=*/request.params[2], /*fee_rate=*/request.params[3], options); InterpretFeeEstimationInstructions(/*conf_target=*/request.params[1], /*estimate_mode=*/request.params[2], /*fee_rate=*/request.params[3], options);
PreventOutdatedOptions(options); PreventOutdatedOptions(options);
const bool psbt_opt_in = options.exists("psbt") && options["psbt"].get_bool();
CAmount fee; CAmount fee;
int change_position; int change_position;
bool rbf = pwallet->m_signal_rbf; bool rbf = options.exists("replaceable") ? options["replaceable"].get_bool() : pwallet->m_signal_rbf;
if (options.exists("replaceable")) {
rbf = options["replaceable"].get_bool();
}
CMutableTransaction rawTx = ConstructTransaction(options["inputs"], request.params[0], options["locktime"], rbf); CMutableTransaction rawTx = ConstructTransaction(options["inputs"], request.params[0], options["locktime"], rbf);
CCoinControl coin_control; CCoinControl coin_control;
// Automatically select coins, unless at least one is manually selected. Can // Automatically select coins, unless at least one is manually selected. Can
@ -1190,49 +1230,7 @@ RPCHelpMan send()
SetOptionsInputWeights(options["inputs"], options); SetOptionsInputWeights(options["inputs"], options);
FundTransaction(*pwallet, rawTx, fee, change_position, options, coin_control, /* override_min_fee */ false); FundTransaction(*pwallet, rawTx, fee, change_position, options, coin_control, /* override_min_fee */ false);
bool add_to_wallet = true; return FinishTransaction(pwallet, options, rawTx);
if (options.exists("add_to_wallet")) {
add_to_wallet = options["add_to_wallet"].get_bool();
}
// Make a blank psbt
PartiallySignedTransaction psbtx(rawTx);
// First fill transaction with our data without signing,
// so external signers are not asked sign more than once.
bool complete;
pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, false, true);
const TransactionError err = pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, true, false);
if (err != TransactionError::OK) {
throw JSONRPCTransactionError(err);
}
CMutableTransaction mtx;
complete = FinalizeAndExtractPSBT(psbtx, mtx);
UniValue result(UniValue::VOBJ);
if (psbt_opt_in || !complete || !add_to_wallet) {
// Serialize the PSBT
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << psbtx;
result.pushKV("psbt", EncodeBase64(ssTx.str()));
}
if (complete) {
std::string err_string;
std::string hex = EncodeHexTx(CTransaction(mtx));
CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
result.pushKV("txid", tx->GetHash().GetHex());
if (add_to_wallet && !psbt_opt_in) {
pwallet->CommitTransaction(tx, {}, {} /* orderForm */);
} else {
result.pushKV("hex", hex);
}
}
result.pushKV("complete", complete);
return result;
} }
}; };
} }

Loading…
Cancel
Save