LCOV - code coverage report
Current view: top level - src/wallet - external_signer_scriptpubkeyman.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 7 47 14.9 %
Date: 2023-09-26 12:08:55 Functions: 7 12 58.3 %

          Line data    Source code
       1             : // Copyright (c) 2020-2022 The Bitcoin Core developers
       2             : // Distributed under the MIT software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #include <chainparams.h>
       6             : #include <common/args.h>
       7             : #include <common/system.h>
       8             : #include <external_signer.h>
       9             : #include <wallet/external_signer_scriptpubkeyman.h>
      10             : 
      11             : #include <iostream>
      12             : #include <memory>
      13             : #include <stdexcept>
      14             : #include <string>
      15             : #include <utility>
      16             : #include <vector>
      17           2 : 
      18           2 : namespace wallet {
      19           0 : bool ExternalSignerScriptPubKeyMan::SetupDescriptor(std::unique_ptr<Descriptor> desc)
      20             : {
      21           0 :     LOCK(cs_desc_man);
      22           0 :     assert(m_storage.IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
      23           0 :     assert(m_storage.IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER));
      24             : 
      25           0 :     int64_t creation_time = GetTime();
      26             : 
      27           2 :     // Make the descriptor
      28           0 :     WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0);
      29           0 :     m_wallet_descriptor = w_desc;
      30             : 
      31             :     // Store the descriptor
      32           0 :     WalletBatch batch(m_storage.GetDatabase());
      33           0 :     if (!batch.WriteDescriptor(GetID(), m_wallet_descriptor)) {
      34           0 :         throw std::runtime_error(std::string(__func__) + ": writing descriptor failed");
      35             :     }
      36             : 
      37             :     // TopUp
      38           0 :     TopUp();
      39             : 
      40           0 :     m_storage.UnsetBlankWalletFlag(batch);
      41             :     return true;
      42           0 : }
      43             : 
      44           0 : ExternalSigner ExternalSignerScriptPubKeyMan::GetExternalSigner() {
      45           0 :     const std::string command = gArgs.GetArg("-signer", "");
      46           0 :     if (command == "") throw std::runtime_error(std::string(__func__) + ": restart bitcoind with -signer=<cmd>");
      47           0 :     std::vector<ExternalSigner> signers;
      48           0 :     ExternalSigner::Enumerate(command, signers, Params().GetChainTypeString());
      49           0 :     if (signers.empty()) throw std::runtime_error(std::string(__func__) + ": No external signers found");
      50             :     // TODO: add fingerprint argument instead of failing in case of multiple signers.
      51           0 :     if (signers.size() > 1) throw std::runtime_error(std::string(__func__) + ": More than one external signer found. Please connect only one at a time.");
      52           0 :     return signers[0];
      53           0 : }
      54             : 
      55           0 : bool ExternalSignerScriptPubKeyMan::DisplayAddress(const CScript scriptPubKey, const ExternalSigner &signer) const
      56             : {
      57             :     // TODO: avoid the need to infer a descriptor from inside a descriptor wallet
      58           0 :     auto provider = GetSolvingProvider(scriptPubKey);
      59           0 :     auto descriptor = InferDescriptor(scriptPubKey, *provider);
      60             : 
      61           0 :     signer.DisplayAddress(descriptor->ToString());
      62             :     // TODO inspect result
      63             :     return true;
      64           0 : }
      65             : 
      66             : // If sign is true, transaction must previously have been filled
      67           0 : TransactionError ExternalSignerScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type, bool sign, bool bip32derivs, int* n_signed, bool finalize) const
      68             : {
      69           0 :     if (!sign) {
      70           0 :         return DescriptorScriptPubKeyMan::FillPSBT(psbt, txdata, sighash_type, false, bip32derivs, n_signed, finalize);
      71             :     }
      72             : 
      73             :     // Already complete if every input is now signed
      74           2 :     bool complete = true;
      75           0 :     for (const auto& input : psbt.inputs) {
      76             :         // TODO: for multisig wallets, we should only care if all _our_ inputs are signed
      77           0 :         complete &= PSBTInputSigned(input);
      78             :     }
      79           0 :     if (complete) return TransactionError::OK;
      80             : 
      81           0 :     std::string strFailReason;
      82           0 :     if(!GetExternalSigner().SignTransaction(psbt, strFailReason)) {
      83           0 :         tfm::format(std::cerr, "Failed to sign: %s\n", strFailReason);
      84           0 :         return TransactionError::EXTERNAL_SIGNER_FAILED;
      85             :     }
      86           0 :     if (finalize) FinalizePSBT(psbt); // This won't work in a multisig setup
      87           0 :     return TransactionError::OK;
      88           0 : }
      89             : } // namespace wallet

Generated by: LCOV version 1.14