mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-18 13:17:55 +02:00
Merge dcf2ccbfde into merged_master (Bitcoin PR #18115)
I really like this PR, but it wound up being pretty nontrivial to merge. The crux is that it pulls PSBT signing logic into scriptpubkey manager, which is where it belongs, but for us this means reasoning about pegins inside script/sign.cpp. However, sign.cpp is part of libbitcoin_common, which does not include anything for reasoning about PoW or RPC (lol) or anything heavy about that. This means that some pegin validation had to remain split between the wallet/rpc layer and sign.cpp. I added a new file script/pegins.cpp which has the (one) method we actually need in sign.cpp. Aside from that, this diff is very large but is mostly just moving our code changes to wallet/psbtwallet.* into wallet/wallet.* where those functions now live. As far as review, it's probably not worthwhile to spend too much too much time on this since it's going to be change again in #16528 and others. The test coverage is pretty extensive.
This commit is contained in:
commit
5b9f316537
27 changed files with 716 additions and 502 deletions
|
|
@ -5,6 +5,7 @@
|
|||
#include <key_io.h>
|
||||
#include <outputtype.h>
|
||||
#include <script/descriptor.h>
|
||||
#include <script/sign.h>
|
||||
#include <util/bip32.h>
|
||||
#include <util/strencodings.h>
|
||||
#include <util/translation.h>
|
||||
|
|
@ -484,7 +485,7 @@ int64_t LegacyScriptPubKeyMan::GetTimeFirstKey() const
|
|||
return nTimeFirstKey;
|
||||
}
|
||||
|
||||
std::unique_ptr<SigningProvider> LegacyScriptPubKeyMan::GetSigningProvider(const CScript& script) const
|
||||
std::unique_ptr<SigningProvider> LegacyScriptPubKeyMan::GetSolvingProvider(const CScript& script) const
|
||||
{
|
||||
return MakeUnique<LegacySigningProvider>(*this);
|
||||
}
|
||||
|
|
@ -512,6 +513,67 @@ bool LegacyScriptPubKeyMan::CanProvide(const CScript& script, SignatureData& sig
|
|||
}
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, std::string>& input_errors) const
|
||||
{
|
||||
return ::SignTransaction(tx, this, coins, sighash, input_errors);
|
||||
}
|
||||
|
||||
SigningResult LegacyScriptPubKeyMan::SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const
|
||||
{
|
||||
CKeyID key_id(pkhash);
|
||||
CKey key;
|
||||
if (!GetKey(key_id, key)) {
|
||||
return SigningResult::PRIVATE_KEY_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (MessageSign(key, message, str_sig)) {
|
||||
return SigningResult::OK;
|
||||
}
|
||||
return SigningResult::SIGNING_FAILED;
|
||||
}
|
||||
|
||||
TransactionError LegacyScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psbtx, int sighash_type, bool sign, bool bip32derivs) const
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// Get the Sighash type
|
||||
if (sign && input.sighash_type > 0 && input.sighash_type != sighash_type) {
|
||||
return TransactionError::SIGHASH_MISMATCH;
|
||||
}
|
||||
|
||||
// Check non_witness_utxo has specified prevout
|
||||
if (input.non_witness_utxo) {
|
||||
if (txin.prevout.n >= input.non_witness_utxo->vout.size()) {
|
||||
return TransactionError::MISSING_INPUTS;
|
||||
}
|
||||
} else if (input.witness_utxo.IsNull()) {
|
||||
// There's no UTXO so we can just skip this now
|
||||
continue;
|
||||
}
|
||||
SignatureData sigdata;
|
||||
input.FillSignatureData(sigdata);
|
||||
SignPSBTInput(HidingSigningProvider(this, !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) {
|
||||
UpdatePSBTOutput(HidingSigningProvider(this, true, !bip32derivs), psbtx, i);
|
||||
}
|
||||
|
||||
return TransactionError::OK;
|
||||
}
|
||||
|
||||
const CKeyMetadata* LegacyScriptPubKeyMan::GetMetadata(const CTxDestination& dest) const
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue