aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2018-03-27 13:15:10 -0700
committerPieter Wuille <pieter.wuille@gmail.com>2018-04-10 09:29:17 -0700
commit190b8d2dcf2f977b57298cc19be9974bfa83a071 (patch)
treeb245f253c1f0d0486254fc3e4b317a7a5778059c
parent8d651ae32013440b2af1267e87a9d93759a9471f (diff)
Make BaseSignatureCreator a pure interface
-rw-r--r--src/bitcoin-tx.cpp2
-rw-r--r--src/rpc/rawtransaction.cpp2
-rw-r--r--src/script/ismine.cpp2
-rw-r--r--src/script/sign.cpp48
-rw-r--r--src/script/sign.h20
-rw-r--r--src/test/txvalidationcache_tests.cpp4
-rw-r--r--src/wallet/wallet.cpp6
7 files changed, 39 insertions, 45 deletions
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index deb8212a8f..eb41e9a416 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -644,7 +644,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
SignatureData sigdata;
// Only sign SIGHASH_SINGLE if there's a corresponding output:
if (!fHashSingle || (i < mergedTx.vout.size()))
- ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata);
+ ProduceSignature(keystore, MutableTransactionSignatureCreator(&mergedTx, i, amount, nHashType), prevPubKey, sigdata);
// ... and merge in other signatures:
for (const CTransaction& txv : txVariants)
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index f0493de3bd..27edd083ab 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -831,7 +831,7 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival
SignatureData sigdata;
// Only sign SIGHASH_SINGLE if there's a corresponding output:
if (!fHashSingle || (i < mtx.vout.size())) {
- ProduceSignature(MutableTransactionSignatureCreator(keystore, &mtx, i, amount, nHashType), prevPubKey, sigdata);
+ ProduceSignature(*keystore, MutableTransactionSignatureCreator(&mtx, i, amount, nHashType), prevPubKey, sigdata);
}
sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(mtx, i));
diff --git a/src/script/ismine.cpp b/src/script/ismine.cpp
index 05bc5e9bd6..3d24009957 100644
--- a/src/script/ismine.cpp
+++ b/src/script/ismine.cpp
@@ -146,7 +146,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey, bool&
if (keystore.HaveWatchOnly(scriptPubKey)) {
// TODO: This could be optimized some by doing some work after the above solver
SignatureData sigs;
- return ProduceSignature(DummySignatureCreator(&keystore), scriptPubKey, sigs) ? ISMINE_WATCH_SOLVABLE : ISMINE_WATCH_UNSOLVABLE;
+ return ProduceSignature(keystore, DummySignatureCreator(), scriptPubKey, sigs) ? ISMINE_WATCH_SOLVABLE : ISMINE_WATCH_UNSOLVABLE;
}
return ISMINE_NO;
}
diff --git a/src/script/sign.cpp b/src/script/sign.cpp
index 910bb39ce6..18cd542a6f 100644
--- a/src/script/sign.cpp
+++ b/src/script/sign.cpp
@@ -14,12 +14,12 @@
typedef std::vector<unsigned char> valtype;
-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) {}
+TransactionSignatureCreator::TransactionSignatureCreator(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : 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
+bool TransactionSignatureCreator::CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
{
CKey key;
- if (!m_provider->GetKey(address, key))
+ if (!provider.GetKey(address, key))
return false;
// Signing with uncompressed keys is disabled in witness scripts
@@ -33,16 +33,16 @@ bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig,
return true;
}
-static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
+static bool Sign1(const SigningProvider& provider, const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
{
std::vector<unsigned char> vchSig;
- if (!creator.CreateSig(vchSig, address, scriptCode, sigversion))
+ if (!creator.CreateSig(provider, vchSig, address, scriptCode, sigversion))
return false;
ret.push_back(vchSig);
return true;
}
-static bool SignN(const std::vector<valtype>& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
+static bool SignN(const SigningProvider& provider, const std::vector<valtype>& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
{
int nSigned = 0;
int nRequired = multisigdata.front()[0];
@@ -50,7 +50,7 @@ static bool SignN(const std::vector<valtype>& multisigdata, const BaseSignatureC
{
const valtype& pubkey = multisigdata[i];
CKeyID keyID = CPubKey(pubkey).GetID();
- if (Sign1(keyID, creator, scriptCode, ret, sigversion))
+ if (Sign1(provider, keyID, creator, scriptCode, ret, sigversion))
++nSigned;
}
return nSigned==nRequired;
@@ -62,7 +62,7 @@ static bool SignN(const std::vector<valtype>& multisigdata, const BaseSignatureC
* unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script.
* Returns false if scriptPubKey could not be completely satisfied.
*/
-static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey,
+static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey,
std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion)
{
CScript scriptRet;
@@ -82,20 +82,20 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
return false;
case TX_PUBKEY:
keyID = CPubKey(vSolutions[0]).GetID();
- return Sign1(keyID, creator, scriptPubKey, ret, sigversion);
+ return Sign1(provider, keyID, creator, scriptPubKey, ret, sigversion);
case TX_PUBKEYHASH:
keyID = CKeyID(uint160(vSolutions[0]));
- if (!Sign1(keyID, creator, scriptPubKey, ret, sigversion))
+ if (!Sign1(provider, keyID, creator, scriptPubKey, ret, sigversion))
return false;
else
{
CPubKey vch;
- creator.Provider().GetPubKey(keyID, vch);
+ provider.GetPubKey(keyID, vch);
ret.push_back(ToByteVector(vch));
}
return true;
case TX_SCRIPTHASH:
- if (creator.Provider().GetCScript(uint160(vSolutions[0]), scriptRet)) {
+ if (provider.GetCScript(uint160(vSolutions[0]), scriptRet)) {
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
return true;
}
@@ -103,7 +103,7 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
case TX_MULTISIG:
ret.push_back(valtype()); // workaround CHECKMULTISIG bug
- return (SignN(vSolutions, creator, scriptPubKey, ret, sigversion));
+ return (SignN(provider, vSolutions, creator, scriptPubKey, ret, sigversion));
case TX_WITNESS_V0_KEYHASH:
ret.push_back(vSolutions[0]);
@@ -111,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.Provider().GetCScript(h160, scriptRet)) {
+ if (provider.GetCScript(h160, scriptRet)) {
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
return true;
}
@@ -137,11 +137,11 @@ static CScript PushAll(const std::vector<valtype>& values)
return result;
}
-bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata)
+bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata)
{
std::vector<valtype> result;
txnouttype whichType;
- bool solved = SignStep(creator, fromPubKey, result, whichType, SigVersion::BASE);
+ bool solved = SignStep(provider, creator, fromPubKey, result, whichType, SigVersion::BASE);
bool P2SH = false;
CScript subscript;
sigdata.scriptWitness.stack.clear();
@@ -152,7 +152,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
// the final scriptSig is the signatures from that
// and then the serialized subscript:
subscript = CScript(result[0].begin(), result[0].end());
- solved = solved && SignStep(creator, subscript, result, whichType, SigVersion::BASE) && whichType != TX_SCRIPTHASH;
+ solved = solved && SignStep(provider, creator, subscript, result, whichType, SigVersion::BASE) && whichType != TX_SCRIPTHASH;
P2SH = true;
}
@@ -161,7 +161,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
CScript witnessscript;
witnessscript << OP_DUP << OP_HASH160 << ToByteVector(result[0]) << OP_EQUALVERIFY << OP_CHECKSIG;
txnouttype subType;
- solved = solved && SignStep(creator, witnessscript, result, subType, SigVersion::WITNESS_V0);
+ solved = solved && SignStep(provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0);
sigdata.scriptWitness.stack = result;
result.clear();
}
@@ -169,7 +169,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
{
CScript witnessscript(result[0].begin(), result[0].end());
txnouttype subType;
- solved = solved && SignStep(creator, witnessscript, result, subType, SigVersion::WITNESS_V0) && subType != TX_SCRIPTHASH && subType != TX_WITNESS_V0_SCRIPTHASH && subType != TX_WITNESS_V0_KEYHASH;
+ solved = solved && SignStep(provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0) && subType != TX_SCRIPTHASH && subType != TX_WITNESS_V0_SCRIPTHASH && subType != TX_WITNESS_V0_KEYHASH;
result.push_back(std::vector<unsigned char>(witnessscript.begin(), witnessscript.end()));
sigdata.scriptWitness.stack = result;
result.clear();
@@ -210,10 +210,10 @@ bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, C
assert(nIn < txTo.vin.size());
CTransaction txToConst(txTo);
- TransactionSignatureCreator creator(&provider, &txToConst, nIn, amount, nHashType);
+ TransactionSignatureCreator creator(&txToConst, nIn, amount, nHashType);
SignatureData sigdata;
- bool ret = ProduceSignature(creator, fromPubKey, sigdata);
+ bool ret = ProduceSignature(provider, creator, fromPubKey, sigdata);
UpdateTransaction(txTo, nIn, sigdata);
return ret;
}
@@ -410,7 +410,7 @@ const BaseSignatureChecker& DummySignatureCreator::Checker() const
return dummyChecker;
}
-bool DummySignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const
+bool DummySignatureCreator::CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const
{
// Create a dummy signature that is a valid DER-encoding
vchSig.assign(72, '\000');
@@ -432,12 +432,12 @@ bool IsSolvable(const SigningProvider& provider, const CScript& script)
// 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(&provider);
+ static const DummySignatureCreator creator;
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.
static_assert(STANDARD_SCRIPT_VERIFY_FLAGS & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, "IsSolvable requires standard script flags to include WITNESS_PUBKEYTYPE");
- if (ProduceSignature(creator, script, sigs)) {
+ if (ProduceSignature(provider, creator, script, sigs)) {
// VerifyScript check is just defensive, and should never fail.
assert(VerifyScript(sigs.scriptSig, script, &sigs.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker()));
return true;
diff --git a/src/script/sign.h b/src/script/sign.h
index c301f0544f..88d769a84a 100644
--- a/src/script/sign.h
+++ b/src/script/sign.h
@@ -26,19 +26,14 @@ public:
virtual bool GetKey(const CKeyID &address, CKey& key) const =0;
};
-/** Virtual base class for signature creators. */
+/** Interface for signature creators. */
class BaseSignatureCreator {
-protected:
- const SigningProvider* m_provider;
-
public:
- explicit BaseSignatureCreator(const SigningProvider* provider) : m_provider(provider) {}
- const SigningProvider& Provider() const { return *m_provider; }
virtual ~BaseSignatureCreator() {}
virtual const BaseSignatureChecker& Checker() const =0;
/** Create a singular (non-script) signature. */
- virtual bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const =0;
+ virtual bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const =0;
};
/** A signature creator for transactions. */
@@ -50,24 +45,23 @@ class TransactionSignatureCreator : public BaseSignatureCreator {
const TransactionSignatureChecker checker;
public:
- TransactionSignatureCreator(const SigningProvider* provider, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn=SIGHASH_ALL);
+ TransactionSignatureCreator(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn=SIGHASH_ALL);
const BaseSignatureChecker& Checker() const override { return checker; }
- bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override;
+ bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override;
};
class MutableTransactionSignatureCreator : public TransactionSignatureCreator {
CTransaction tx;
public:
- MutableTransactionSignatureCreator(const SigningProvider* provider, const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : TransactionSignatureCreator(provider, &tx, nInIn, amountIn, nHashTypeIn), tx(*txToIn) {}
+ MutableTransactionSignatureCreator(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : TransactionSignatureCreator(&tx, nInIn, amountIn, nHashTypeIn), tx(*txToIn) {}
};
/** A signature creator that just produces 72-byte empty signatures. */
class DummySignatureCreator : public BaseSignatureCreator {
public:
- explicit DummySignatureCreator(const SigningProvider* provider) : BaseSignatureCreator(provider) {}
const BaseSignatureChecker& Checker() const override;
- bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override;
+ bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override;
};
struct SignatureData {
@@ -79,7 +73,7 @@ struct SignatureData {
};
/** Produce a script signature using a generic signature creator. */
-bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& scriptPubKey, SignatureData& sigdata);
+bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey, SignatureData& sigdata);
/** Produce a script signature for a transaction. */
bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType);
diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp
index 7087c26774..a1d86e3afc 100644
--- a/src/test/txvalidationcache_tests.cpp
+++ b/src/test/txvalidationcache_tests.cpp
@@ -314,7 +314,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
// Sign
SignatureData sigdata;
- ProduceSignature(MutableTransactionSignatureCreator(&keystore, &valid_with_witness_tx, 0, 11*CENT, SIGHASH_ALL), spend_tx.vout[1].scriptPubKey, sigdata);
+ ProduceSignature(keystore, MutableTransactionSignatureCreator(&valid_with_witness_tx, 0, 11*CENT, SIGHASH_ALL), spend_tx.vout[1].scriptPubKey, sigdata);
UpdateTransaction(valid_with_witness_tx, 0, sigdata);
// This should be valid under all script flags.
@@ -342,7 +342,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
// Sign
for (int i=0; i<2; ++i) {
SignatureData sigdata;
- ProduceSignature(MutableTransactionSignatureCreator(&keystore, &tx, i, 11*CENT, SIGHASH_ALL), spend_tx.vout[i].scriptPubKey, sigdata);
+ ProduceSignature(keystore, MutableTransactionSignatureCreator(&tx, i, 11*CENT, SIGHASH_ALL), spend_tx.vout[i].scriptPubKey, sigdata);
UpdateTransaction(tx, i, sigdata);
}
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 4308b6d0e8..a3a4e71f02 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -1535,7 +1535,7 @@ bool CWallet::DummySignInput(CTxIn &tx_in, const CTxOut &txout) const
const CScript& scriptPubKey = txout.scriptPubKey;
SignatureData sigdata;
- if (!ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata))
+ if (!ProduceSignature(*this, DummySignatureCreator(), scriptPubKey, sigdata))
{
return false;
} else {
@@ -2579,7 +2579,7 @@ bool CWallet::SignTransaction(CMutableTransaction &tx)
const CScript& scriptPubKey = mi->second.tx->vout[input.prevout.n].scriptPubKey;
const CAmount& amount = mi->second.tx->vout[input.prevout.n].nValue;
SignatureData sigdata;
- if (!ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) {
+ if (!ProduceSignature(*this, TransactionSignatureCreator(&txNewConst, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) {
return false;
}
UpdateTransaction(tx, nIn, sigdata);
@@ -3008,7 +3008,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
const CScript& scriptPubKey = coin.txout.scriptPubKey;
SignatureData sigdata;
- if (!ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.txout.nValue, SIGHASH_ALL), scriptPubKey, sigdata))
+ if (!ProduceSignature(*this, TransactionSignatureCreator(&txNewConst, nIn, coin.txout.nValue, SIGHASH_ALL), scriptPubKey, sigdata))
{
strFailReason = _("Signing transaction failed");
return false;