Skip to content

Commit 902793c

Browse files
committed
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`.
1 parent 6d2208a commit 902793c

File tree

1 file changed

+46
-48
lines changed

1 file changed

+46
-48
lines changed

src/wallet/rpc/spend.cpp

Lines changed: 46 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,50 @@ static void InterpretFeeEstimationInstructions(const UniValue& conf_target, cons
7474
}
7575
}
7676

77+
static UniValue FinishTransaction(const std::shared_ptr<CWallet> pwallet, const UniValue& options, const CMutableTransaction& rawTx)
78+
{
79+
80+
// Make a blank psbt
81+
PartiallySignedTransaction psbtx(rawTx);
82+
83+
// First fill transaction with our data without signing,
84+
// so external signers are not asked sign more than once.
85+
bool complete;
86+
pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, false, true);
87+
const TransactionError err{pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, true, false)};
88+
if (err != TransactionError::OK) {
89+
throw JSONRPCTransactionError(err);
90+
}
91+
92+
CMutableTransaction mtx;
93+
complete = FinalizeAndExtractPSBT(psbtx, mtx);
94+
95+
UniValue result(UniValue::VOBJ);
96+
97+
const bool psbt_opt_in{options.exists("psbt") && options["psbt"].get_bool()};
98+
bool add_to_wallet{options.exists("add_to_wallet") ? options["add_to_wallet"].get_bool() : true};
99+
if (psbt_opt_in || !complete || !add_to_wallet) {
100+
// Serialize the PSBT
101+
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
102+
ssTx << psbtx;
103+
result.pushKV("psbt", EncodeBase64(ssTx.str()));
104+
}
105+
106+
if (complete) {
107+
std::string hex{EncodeHexTx(CTransaction(mtx))};
108+
CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
109+
result.pushKV("txid", tx->GetHash().GetHex());
110+
if (add_to_wallet && !psbt_opt_in) {
111+
pwallet->CommitTransaction(tx, {}, {} /* orderForm */);
112+
} else {
113+
result.pushKV("hex", hex);
114+
}
115+
}
116+
result.pushKV("complete", complete);
117+
118+
return result;
119+
}
120+
77121
static void PreventOutdatedOptions(const UniValue& options)
78122
{
79123
if (options.exists("feeRate")) {
@@ -1174,14 +1218,10 @@ RPCHelpMan send()
11741218
InterpretFeeEstimationInstructions(/*conf_target=*/request.params[1], /*estimate_mode=*/request.params[2], /*fee_rate=*/request.params[3], options);
11751219
PreventOutdatedOptions(options);
11761220

1177-
const bool psbt_opt_in = options.exists("psbt") && options["psbt"].get_bool();
11781221

11791222
CAmount fee;
11801223
int change_position;
1181-
bool rbf = pwallet->m_signal_rbf;
1182-
if (options.exists("replaceable")) {
1183-
rbf = options["replaceable"].get_bool();
1184-
}
1224+
bool rbf = options.exists("replaceable") ? options["replaceable"].get_bool() : pwallet->m_signal_rbf;
11851225
CMutableTransaction rawTx = ConstructTransaction(options["inputs"], request.params[0], options["locktime"], rbf);
11861226
CCoinControl coin_control;
11871227
// Automatically select coins, unless at least one is manually selected. Can
@@ -1190,49 +1230,7 @@ RPCHelpMan send()
11901230
SetOptionsInputWeights(options["inputs"], options);
11911231
FundTransaction(*pwallet, rawTx, fee, change_position, options, coin_control, /* override_min_fee */ false);
11921232

1193-
bool add_to_wallet = true;
1194-
if (options.exists("add_to_wallet")) {
1195-
add_to_wallet = options["add_to_wallet"].get_bool();
1196-
}
1197-
1198-
// Make a blank psbt
1199-
PartiallySignedTransaction psbtx(rawTx);
1200-
1201-
// First fill transaction with our data without signing,
1202-
// so external signers are not asked sign more than once.
1203-
bool complete;
1204-
pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, false, true);
1205-
const TransactionError err = pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, true, false);
1206-
if (err != TransactionError::OK) {
1207-
throw JSONRPCTransactionError(err);
1208-
}
1209-
1210-
CMutableTransaction mtx;
1211-
complete = FinalizeAndExtractPSBT(psbtx, mtx);
1212-
1213-
UniValue result(UniValue::VOBJ);
1214-
1215-
if (psbt_opt_in || !complete || !add_to_wallet) {
1216-
// Serialize the PSBT
1217-
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
1218-
ssTx << psbtx;
1219-
result.pushKV("psbt", EncodeBase64(ssTx.str()));
1220-
}
1221-
1222-
if (complete) {
1223-
std::string err_string;
1224-
std::string hex = EncodeHexTx(CTransaction(mtx));
1225-
CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
1226-
result.pushKV("txid", tx->GetHash().GetHex());
1227-
if (add_to_wallet && !psbt_opt_in) {
1228-
pwallet->CommitTransaction(tx, {}, {} /* orderForm */);
1229-
} else {
1230-
result.pushKV("hex", hex);
1231-
}
1232-
}
1233-
result.pushKV("complete", complete);
1234-
1235-
return result;
1233+
return FinishTransaction(pwallet, options, rawTx);
12361234
}
12371235
};
12381236
}

0 commit comments

Comments
 (0)