aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet.cpp
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2020-02-10 19:50:56 -0500
committerAndrew Chow <achow101-github@achow101.com>2020-03-09 11:16:17 -0400
commit3d70dd99f9f74eef70b19ff6f6f850adc0d5ef8f (patch)
tree4a4f77dfab8fa0209237a259293ccc545c2f5037 /src/wallet/wallet.cpp
parenta4af324d15c1ee43c2abd11a304ae18c7ee82eb0 (diff)
downloadbitcoin-3d70dd99f9f74eef70b19ff6f6f850adc0d5ef8f.tar.xz
Move FillPSBT to be a member of CWallet
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r--src/wallet/wallet.cpp72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index a120354580..099a79ed64 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -2477,6 +2477,78 @@ bool CWallet::SignTransaction(CMutableTransaction& tx, const std::map<COutPoint,
return false;
}
+TransactionError CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bool& complete, int sighash_type, bool sign, bool bip32derivs) const
+{
+ LOCK(cs_wallet);
+ // Get all of the previous transactions
+ complete = true;
+ for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
+ const CTxIn& txin = psbtx.tx->vin[i];
+ PSBTInput& input = psbtx.inputs.at(i);
+
+ if (PSBTInputSigned(input)) {
+ continue;
+ }
+
+ // Verify input looks sane. This will check that we have at most one uxto, witness or non-witness.
+ if (!input.IsSane()) {
+ return TransactionError::INVALID_PSBT;
+ }
+
+ // If we have no utxo, grab it from the wallet.
+ if (!input.non_witness_utxo && input.witness_utxo.IsNull()) {
+ const uint256& txhash = txin.prevout.hash;
+ const auto it = mapWallet.find(txhash);
+ if (it != mapWallet.end()) {
+ const CWalletTx& wtx = it->second;
+ // We only need the non_witness_utxo, which is a superset of the witness_utxo.
+ // The signing code will switch to the smaller witness_utxo if this is ok.
+ input.non_witness_utxo = wtx.tx;
+ }
+ }
+
+ // Get the Sighash type
+ if (sign && input.sighash_type > 0 && input.sighash_type != sighash_type) {
+ return TransactionError::SIGHASH_MISMATCH;
+ }
+
+ // Get the scriptPubKey to know which SigningProvider to use
+ CScript script;
+ if (!input.witness_utxo.IsNull()) {
+ script = input.witness_utxo.scriptPubKey;
+ } else if (input.non_witness_utxo) {
+ if (txin.prevout.n >= input.non_witness_utxo->vout.size()) {
+ return TransactionError::MISSING_INPUTS;
+ }
+ script = input.non_witness_utxo->vout[txin.prevout.n].scriptPubKey;
+ } else {
+ // There's no UTXO so we can just skip this now
+ complete = false;
+ continue;
+ }
+ SignatureData sigdata;
+ input.FillSignatureData(sigdata);
+ std::unique_ptr<SigningProvider> provider = GetSigningProvider(script, sigdata);
+ if (!provider) {
+ complete = false;
+ continue;
+ }
+
+ complete &= SignPSBTInput(HidingSigningProvider(provider.get(), !sign, !bip32derivs), psbtx, i, sighash_type);
+ }
+
+ // Fill in the bip32 keypaths and redeemscripts for the outputs so that hardware wallets can identify change
+ for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) {
+ const CTxOut& out = psbtx.tx->vout.at(i);
+ std::unique_ptr<SigningProvider> provider = GetSigningProvider(out.scriptPubKey);
+ if (provider) {
+ UpdatePSBTOutput(HidingSigningProvider(provider.get(), true, !bip32derivs), psbtx, i);
+ }
+ }
+
+ return TransactionError::OK;
+}
+
bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, CCoinControl coinControl)
{
std::vector<CRecipient> vecSend;