Skip to content

Commit 2ecd3b6

Browse files
committed
rpc: add keypath_only to send
1 parent 9ff4a61 commit 2ecd3b6

32 files changed

+77
-65
lines changed

src/bench/sign_transaction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ static void SignTransactionSingleInput(benchmark::Bench& bench, InputType input_
6565
const CScript& prev_spk = prev_spks[(iter++) % prev_spks.size()];
6666
coins[prevout] = Coin(CTxOut(10000, prev_spk), /*nHeightIn=*/100, /*fCoinBaseIn=*/false);
6767
std::map<int, bilingual_str> input_errors;
68-
bool complete = SignTransaction(tx, &keystore, coins, SIGHASH_ALL, input_errors);
68+
bool complete = SignTransaction(tx, &keystore, coins, SIGHASH_ALL, /*avoid_script_path=*/false, input_errors);
6969
assert(complete);
7070
});
7171
}

src/bitcoin-tx.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
681681
SignatureData sigdata = DataFromTransaction(mergedTx, i, coin.out);
682682
// Only sign SIGHASH_SINGLE if there's a corresponding output:
683683
if (!fHashSingle || (i < mergedTx.vout.size()))
684-
ProduceSignature(keystore, MutableTransactionSignatureCreator(mergedTx, i, amount, nHashType), prevPubKey, sigdata);
684+
ProduceSignature(keystore, MutableTransactionSignatureCreator(mergedTx, i, amount, nHashType), prevPubKey, /*avoid_script_path=*/false, sigdata);
685685

686686
if (amount == MAX_MONEY && !sigdata.scriptWitness.IsNull()) {
687687
throw std::runtime_error(strprintf("Missing amount for CTxOut with scriptPubKey=%s", HexStr(prevPubKey)));

src/interfaces/wallet.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ class Wallet
208208
virtual std::optional<common::PSBTError> fillPSBT(std::optional<int> sighash_type,
209209
bool sign,
210210
bool bip32derivs,
211+
bool avoid_script_path,
211212
size_t* n_signed,
212213
PartiallySignedTransaction& psbtx,
213214
bool& complete) = 0;

src/psbt.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ void UpdatePSBTOutput(const SigningProvider& provider, PartiallySignedTransactio
372372
// Note that ProduceSignature is used to fill in metadata (not actual signatures),
373373
// so provider does not need to provide any private keys (it can be a HidingSigningProvider).
374374
MutableTransactionSignatureCreator creator(tx, /*input_idx=*/0, out.nValue, SIGHASH_ALL);
375-
ProduceSignature(provider, creator, out.scriptPubKey, sigdata);
375+
ProduceSignature(provider, creator, out.scriptPubKey, /*avoid_script_path=*/false, sigdata);
376376

377377
// Put redeem_script, witness_script, key paths, into PSBTOutput.
378378
psbt_out.FromSignatureData(sigdata);
@@ -395,7 +395,7 @@ PrecomputedTransactionData PrecomputePSBTData(const PartiallySignedTransaction&
395395
return txdata;
396396
}
397397

398-
PSBTError SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, const PrecomputedTransactionData* txdata, std::optional<int> sighash, SignatureData* out_sigdata, bool finalize)
398+
PSBTError SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, const PrecomputedTransactionData* txdata, std::optional<int> sighash, SignatureData* out_sigdata, bool avoid_script_path, bool finalize)
399399
{
400400
PSBTInput& input = psbt.inputs.at(index);
401401
const CMutableTransaction& tx = *psbt.tx;
@@ -475,10 +475,10 @@ PSBTError SignPSBTInput(const SigningProvider& provider, PartiallySignedTransact
475475
sigdata.witness = false;
476476
bool sig_complete;
477477
if (txdata == nullptr) {
478-
sig_complete = ProduceSignature(provider, DUMMY_SIGNATURE_CREATOR, utxo.scriptPubKey, sigdata);
478+
sig_complete = ProduceSignature(provider, DUMMY_SIGNATURE_CREATOR, utxo.scriptPubKey, avoid_script_path, sigdata);
479479
} else {
480480
MutableTransactionSignatureCreator creator(tx, index, utxo.nValue, txdata, *sighash);
481-
sig_complete = ProduceSignature(provider, creator, utxo.scriptPubKey, sigdata);
481+
sig_complete = ProduceSignature(provider, creator, utxo.scriptPubKey, avoid_script_path, sigdata);
482482
}
483483
// Verify that a witness signature was produced in case one was required.
484484
if (require_witness_sig && !sigdata.witness) return PSBTError::INCOMPLETE;
@@ -554,7 +554,7 @@ bool FinalizePSBT(PartiallySignedTransaction& psbtx)
554554
const PrecomputedTransactionData txdata = PrecomputePSBTData(psbtx);
555555
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
556556
PSBTInput& input = psbtx.inputs.at(i);
557-
complete &= (SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, &txdata, input.sighash_type, nullptr, true) == PSBTError::OK);
557+
complete &= (SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, &txdata, input.sighash_type, nullptr, /*avoid_script_path=*/false, /*finalize=*/true) == PSBTError::OK);
558558
}
559559

560560
return complete;

src/psbt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1404,7 +1404,7 @@ bool PSBTInputSignedAndVerified(const PartiallySignedTransaction psbt, unsigned
14041404
* txdata should be the output of PrecomputePSBTData (which can be shared across
14051405
* multiple SignPSBTInput calls). If it is nullptr, a dummy signature will be created.
14061406
**/
1407-
[[nodiscard]] PSBTError SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, const PrecomputedTransactionData* txdata, std::optional<int> sighash = std::nullopt, SignatureData* out_sigdata = nullptr, bool finalize = true);
1407+
[[nodiscard]] PSBTError SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, const PrecomputedTransactionData* txdata, std::optional<int> sighash = std::nullopt, SignatureData* out_sigdata = nullptr, bool avoid_script_path = false, bool finalize = true);
14081408

14091409
/** Reduces the size of the PSBT by dropping unnecessary `non_witness_utxos` (i.e. complete previous transactions) from a psbt when all inputs are segwit v1. */
14101410
void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx);

src/qt/psbtoperationsdialog.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ void PSBTOperationsDialog::openWithPSBT(PartiallySignedTransaction psbtx)
5959
bool complete = FinalizePSBT(psbtx); // Make sure all existing signatures are fully combined before checking for completeness.
6060
if (m_wallet_model) {
6161
size_t n_could_sign;
62-
const auto err{m_wallet_model->wallet().fillPSBT(std::nullopt, /*sign=*/false, /*bip32derivs=*/true, &n_could_sign, m_transaction_data, complete)};
62+
const auto err{m_wallet_model->wallet().fillPSBT(std::nullopt, /*sign=*/false, /*bip32derivs=*/true, /*avoid_script_path=*/false, &n_could_sign, m_transaction_data, complete)};
6363
if (err) {
6464
showStatus(tr("Failed to load transaction: %1")
6565
.arg(QString::fromStdString(PSBTErrorString(*err).translated)),
@@ -83,7 +83,7 @@ void PSBTOperationsDialog::signTransaction()
8383

8484
WalletModel::UnlockContext ctx(m_wallet_model->requestUnlock());
8585

86-
const auto err{m_wallet_model->wallet().fillPSBT(std::nullopt, /*sign=*/true, /*bip32derivs=*/true, &n_signed, m_transaction_data, complete)};
86+
const auto err{m_wallet_model->wallet().fillPSBT(std::nullopt, /*sign=*/true, /*bip32derivs=*/true, /*avoid_script_path=*/false, &n_signed, m_transaction_data, complete)};
8787

8888
if (err) {
8989
showStatus(tr("Failed to sign transaction: %1")
@@ -251,7 +251,7 @@ size_t PSBTOperationsDialog::couldSignInputs(const PartiallySignedTransaction &p
251251

252252
size_t n_signed;
253253
bool complete;
254-
const auto err{m_wallet_model->wallet().fillPSBT(std::nullopt, /*sign=*/false, /*bip32derivs=*/false, &n_signed, m_transaction_data, complete)};
254+
const auto err{m_wallet_model->wallet().fillPSBT(std::nullopt, /*sign=*/false, /*bip32derivs=*/false, /*avoid_script_path=*/false, &n_signed, m_transaction_data, complete)};
255255

256256
if (err) {
257257
return 0;

src/qt/sendcoinsdialog.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ void SendCoinsDialog::presentPSBT(PartiallySignedTransaction& psbtx)
450450
bool SendCoinsDialog::signWithExternalSigner(PartiallySignedTransaction& psbtx, CMutableTransaction& mtx, bool& complete) {
451451
std::optional<PSBTError> err;
452452
try {
453-
err = model->wallet().fillPSBT(std::nullopt, /*sign=*/true, /*bip32derivs=*/true, /*n_signed=*/nullptr, psbtx, complete);
453+
err = model->wallet().fillPSBT(std::nullopt, /*sign=*/true, /*bip32derivs=*/true, /*avoid_script_path=*/false, /*n_signed=*/nullptr, psbtx, complete);
454454
} catch (const std::runtime_error& e) {
455455
QMessageBox::critical(nullptr, tr("Sign failed"), e.what());
456456
return false;
@@ -507,7 +507,7 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked)
507507
PartiallySignedTransaction psbtx(mtx);
508508
bool complete = false;
509509
// Fill without signing
510-
const auto err{model->wallet().fillPSBT(std::nullopt, /*sign=*/false, /*bip32derivs=*/true, /*n_signed=*/nullptr, psbtx, complete)};
510+
const auto err{model->wallet().fillPSBT(std::nullopt, /*sign=*/false, /*bip32derivs=*/true, /*avoid_script_path=*/false, /*n_signed=*/nullptr, psbtx, complete)};
511511
assert(!complete);
512512
assert(!err);
513513

@@ -523,7 +523,7 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked)
523523
bool complete = false;
524524
// Always fill without signing first. This prevents an external signer
525525
// from being called prematurely and is not expensive.
526-
const auto err{model->wallet().fillPSBT(std::nullopt, /*sign=*/false, /*bip32derivs=*/true, /*n_signed=*/nullptr, psbtx, complete)};
526+
const auto err{model->wallet().fillPSBT(std::nullopt, /*sign=*/false, /*bip32derivs=*/true, /*avoid_script_path=*/false, /*n_signed=*/nullptr, psbtx, complete)};
527527
assert(!complete);
528528
assert(!err);
529529
send_failure = !signWithExternalSigner(psbtx, mtx, complete);

src/qt/walletmodel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ bool WalletModel::bumpFee(Txid hash, Txid& new_hash)
521521
// "Create Unsigned" clicked
522522
PartiallySignedTransaction psbtx(mtx);
523523
bool complete = false;
524-
const auto err{wallet().fillPSBT(std::nullopt, /*sign=*/false, /*bip32derivs=*/true, nullptr, psbtx, complete)};
524+
const auto err{wallet().fillPSBT(std::nullopt, /*sign=*/false, /*bip32derivs=*/true, /*avoid_script_path=*/false, nullptr, psbtx, complete)};
525525
if (err || complete) {
526526
QMessageBox::critical(nullptr, tr("Fee bump error"), tr("Can't draft transaction."));
527527
return false;

src/rpc/client.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
213213
{ "send", 4, "replaceable"},
214214
{ "send", 4, "solving_data"},
215215
{ "send", 4, "max_tx_weight"},
216+
{ "send", 4, "keypath_only"},
216217
{ "sendall", 0, "recipients" },
217218
{ "sendall", 1, "conf_target" },
218219
{ "sendall", 3, "fee_rate"},

src/rpc/rawtransaction.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ PartiallySignedTransaction ProcessPSBT(const std::string& psbt_string, const std
236236
// We only actually care about those if our signing provider doesn't hide private
237237
// information, as is the case with `descriptorprocesspsbt`
238238
// Only error for mismatching sighash types as it is critical that the sighash to sign with matches the PSBT's
239-
if (SignPSBTInput(provider, psbtx, /*index=*/i, &txdata, sighash_type, /*out_sigdata=*/nullptr, finalize) == common::PSBTError::SIGHASH_MISMATCH) {
239+
if (SignPSBTInput(provider, psbtx, /*index=*/i, &txdata, sighash_type, /*out_sigdata=*/nullptr, /*=avoid_script_path=*/false, finalize) == common::PSBTError::SIGHASH_MISMATCH) {
240240
throw JSONRPCPSBTError(common::PSBTError::SIGHASH_MISMATCH);
241241
}
242242
}
@@ -697,7 +697,7 @@ static RPCHelpMan combinerawtransaction()
697697
sigdata.MergeSignatureData(DataFromTransaction(txv, i, coin.out));
698698
}
699699
}
700-
ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(mergedTx, i, coin.out.nValue, 1), coin.out.scriptPubKey, sigdata);
700+
ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(mergedTx, i, coin.out.nValue, 1), coin.out.scriptPubKey, /*avoid_script_path=*/false, sigdata);
701701

702702
UpdateInput(txin, sigdata);
703703
}

0 commit comments

Comments
 (0)