Skip to content

Commit bde7c9f

Browse files
committed
Implement SignTransaction in DescriptorScriptPubKeyMan
1 parent d50c8dd commit bde7c9f

File tree

2 files changed

+22
-30
lines changed

2 files changed

+22
-30
lines changed

src/wallet/scriptpubkeyman.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1943,7 +1943,16 @@ bool DescriptorScriptPubKeyMan::CanProvide(const CScript& script, SignatureData&
19431943

19441944
bool DescriptorScriptPubKeyMan::SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, std::string>& input_errors) const
19451945
{
1946-
return false;
1946+
std::unique_ptr<FlatSigningProvider> keys = MakeUnique<FlatSigningProvider>();
1947+
for (const auto& coin_pair : coins) {
1948+
std::unique_ptr<FlatSigningProvider> coin_keys = GetSigningProvider(coin_pair.second.out.scriptPubKey, true);
1949+
if (!coin_keys) {
1950+
continue;
1951+
}
1952+
*keys = Merge(*keys, *coin_keys);
1953+
}
1954+
1955+
return ::SignTransaction(tx, keys.get(), coins, sighash, input_errors);
19471956
}
19481957

19491958
SigningResult DescriptorScriptPubKeyMan::SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const

src/wallet/wallet.cpp

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,11 +2428,17 @@ bool CWallet::SignTransaction(CMutableTransaction& tx) const
24282428

24292429
bool CWallet::SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, std::string>& input_errors) const
24302430
{
2431-
// Sign the tx with ScriptPubKeyMans
2432-
// Because each ScriptPubKeyMan can sign more than one input, we need to keep track of each ScriptPubKeyMan that has signed this transaction.
2433-
// Each iteration, we may sign more txins than the txin that is specified in that iteration.
2434-
// We assume that each input is signed by only one ScriptPubKeyMan.
2435-
std::set<uint256> visited_spk_mans;
2431+
// Try to sign with all ScriptPubKeyMans
2432+
for (ScriptPubKeyMan* spk_man : GetAllScriptPubKeyMans()) {
2433+
// spk_man->SignTransaction will return true if the transaction is complete,
2434+
// so we can exit early and return true if that happens
2435+
if (spk_man->SignTransaction(tx, coins, sighash, input_errors)) {
2436+
return true;
2437+
}
2438+
}
2439+
2440+
// At this point, one input was not fully signed otherwise we would have exited already
2441+
// Find that input and figure out what went wrong.
24362442
for (unsigned int i = 0; i < tx.vin.size(); i++) {
24372443
// Get the prevout
24382444
CTxIn& txin = tx.vin[i];
@@ -2444,33 +2450,10 @@ bool CWallet::SignTransaction(CMutableTransaction& tx, const std::map<COutPoint,
24442450

24452451
// Check if this input is complete
24462452
SignatureData sigdata = DataFromTransaction(tx, i, coin->second.out);
2447-
if (sigdata.complete) {
2448-
continue;
2449-
}
2450-
2451-
// Input needs to be signed, find the right ScriptPubKeyMan
2452-
std::set<ScriptPubKeyMan*> spk_mans = GetScriptPubKeyMans(coin->second.out.scriptPubKey, sigdata);
2453-
if (spk_mans.size() == 0) {
2453+
if (!sigdata.complete) {
24542454
input_errors[i] = "Unable to sign input, missing keys";
24552455
continue;
24562456
}
2457-
2458-
for (auto& spk_man : spk_mans) {
2459-
// If we've already been signed by this spk_man, skip it
2460-
if (visited_spk_mans.count(spk_man->GetID()) > 0) {
2461-
continue;
2462-
}
2463-
2464-
// Sign the tx.
2465-
// spk_man->SignTransaction will return true if the transaction is complete,
2466-
// so we can exit early and return true if that happens.
2467-
if (spk_man->SignTransaction(tx, coins, sighash, input_errors)) {
2468-
return true;
2469-
}
2470-
2471-
// Add this spk_man to visited_spk_mans so we can skip it later
2472-
visited_spk_mans.insert(spk_man->GetID());
2473-
}
24742457
}
24752458
return false;
24762459
}

0 commit comments

Comments
 (0)