mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-12-14 22:58:13 +01:00
Introduce interface for signing providers
CKeyStore is a rich interface that provides many features, including knowledge of scripts and pubkeys for solving, private keys for signing, in addition to watch-only keys and scripts, and distinguishing lack of keys from them just being encrypted. The signing logic in script/sign does not actually need most of these features. Here we introduce a simpler interface (SigningProvider) which *only* provides keys and scripts. This is actually sufficient for signing. In addtion, we swap the dependency between keystore and script/sign (keystore now depends on script/script with CKeyStore deriving from SigningProvider, rather than CKeyStore being the interface that signing relies on).
This commit is contained in:
@@ -6,7 +6,6 @@
|
||||
#include <script/sign.h>
|
||||
|
||||
#include <key.h>
|
||||
#include <keystore.h>
|
||||
#include <policy/policy.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/standard.h>
|
||||
@@ -15,12 +14,12 @@
|
||||
|
||||
typedef std::vector<unsigned char> valtype;
|
||||
|
||||
TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
|
||||
TransactionSignatureCreator::TransactionSignatureCreator(const SigningProvider* provider, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : BaseSignatureCreator(provider), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
|
||||
|
||||
bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
|
||||
{
|
||||
CKey key;
|
||||
if (!keystore->GetKey(address, key))
|
||||
if (!m_provider->GetKey(address, key))
|
||||
return false;
|
||||
|
||||
// Signing with uncompressed keys is disabled in witness scripts
|
||||
@@ -91,12 +90,12 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
|
||||
else
|
||||
{
|
||||
CPubKey vch;
|
||||
creator.KeyStore().GetPubKey(keyID, vch);
|
||||
creator.Provider().GetPubKey(keyID, vch);
|
||||
ret.push_back(ToByteVector(vch));
|
||||
}
|
||||
return true;
|
||||
case TX_SCRIPTHASH:
|
||||
if (creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptRet)) {
|
||||
if (creator.Provider().GetCScript(uint160(vSolutions[0]), scriptRet)) {
|
||||
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
|
||||
return true;
|
||||
}
|
||||
@@ -112,7 +111,7 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
|
||||
|
||||
case TX_WITNESS_V0_SCRIPTHASH:
|
||||
CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(h160.begin());
|
||||
if (creator.KeyStore().GetCScript(h160, scriptRet)) {
|
||||
if (creator.Provider().GetCScript(h160, scriptRet)) {
|
||||
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
|
||||
return true;
|
||||
}
|
||||
@@ -206,12 +205,12 @@ void UpdateTransaction(CMutableTransaction& tx, unsigned int nIn, const Signatur
|
||||
UpdateInput(tx.vin[nIn], data);
|
||||
}
|
||||
|
||||
bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType)
|
||||
bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType)
|
||||
{
|
||||
assert(nIn < txTo.vin.size());
|
||||
|
||||
CTransaction txToConst(txTo);
|
||||
TransactionSignatureCreator creator(&keystore, &txToConst, nIn, amount, nHashType);
|
||||
TransactionSignatureCreator creator(&provider, &txToConst, nIn, amount, nHashType);
|
||||
|
||||
SignatureData sigdata;
|
||||
bool ret = ProduceSignature(creator, fromPubKey, sigdata);
|
||||
@@ -219,14 +218,14 @@ bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutabl
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
|
||||
bool SignSignature(const SigningProvider &provider, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
|
||||
{
|
||||
assert(nIn < txTo.vin.size());
|
||||
CTxIn& txin = txTo.vin[nIn];
|
||||
assert(txin.prevout.n < txFrom.vout.size());
|
||||
const CTxOut& txout = txFrom.vout[txin.prevout.n];
|
||||
|
||||
return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType);
|
||||
return SignSignature(provider, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType);
|
||||
}
|
||||
|
||||
static std::vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
|
||||
@@ -427,13 +426,13 @@ bool DummySignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsSolvable(const CKeyStore& store, const CScript& script)
|
||||
bool IsSolvable(const SigningProvider& provider, const CScript& script)
|
||||
{
|
||||
// This check is to make sure that the script we created can actually be solved for and signed by us
|
||||
// if we were to have the private keys. This is just to make sure that the script is valid and that,
|
||||
// if found in a transaction, we would still accept and relay that transaction. In particular,
|
||||
// it will reject witness outputs that require signing with an uncompressed public key.
|
||||
DummySignatureCreator creator(&store);
|
||||
DummySignatureCreator creator(&provider);
|
||||
SignatureData sigs;
|
||||
// Make sure that STANDARD_SCRIPT_VERIFY_FLAGS includes SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, the most
|
||||
// important property this function is designed to test for.
|
||||
|
||||
Reference in New Issue
Block a user