Browse Source

Merge pull request #5719

9fddced Avoid storing a reference passed to SignatureChecker constructors (Pieter Wuille)
858809a Use separate SignatureChecker for CMutableTransaction (Pieter Wuille)
0.13
Wladimir J. van der Laan 10 years ago
parent
commit
f425050546
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 2
      src/bitcoin-tx.cpp
  2. 2
      src/main.cpp
  3. 2
      src/rpcrawtransaction.cpp
  4. 2
      src/script/bitcoinconsensus.cpp
  5. 6
      src/script/interpreter.cpp
  6. 16
      src/script/interpreter.h
  7. 4
      src/script/sigcache.cpp
  8. 4
      src/script/sigcache.h
  9. 4
      src/script/sign.cpp
  10. 16
      src/test/multisig_tests.cpp
  11. 2
      src/test/script_P2SH_tests.cpp
  12. 28
      src/test/script_tests.cpp
  13. 4
      src/test/transaction_tests.cpp

2
src/bitcoin-tx.cpp

@ -436,7 +436,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
BOOST_FOREACH(const CTransaction& txv, txVariants) { BOOST_FOREACH(const CTransaction& txv, txVariants) {
txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
} }
if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(mergedTx, i))) if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i)))
fComplete = false; fComplete = false;
} }

2
src/main.cpp

@ -1422,7 +1422,7 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
bool CScriptCheck::operator()() { bool CScriptCheck::operator()() {
const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingSignatureChecker(*ptxTo, nIn, cacheStore), &error)) { if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, cacheStore), &error)) {
return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error)); return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
} }
return true; return true;

2
src/rpcrawtransaction.cpp

@ -688,7 +688,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
BOOST_FOREACH(const CMutableTransaction& txv, txVariants) { BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
} }
if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(mergedTx, i))) if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i)))
fComplete = false; fComplete = false;
} }

2
src/script/bitcoinconsensus.cpp

@ -78,7 +78,7 @@ int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned i
// Regardless of the verification result, the tx did not error. // Regardless of the verification result, the tx did not error.
set_error(err, bitcoinconsensus_ERR_OK); set_error(err, bitcoinconsensus_ERR_OK);
return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, SignatureChecker(tx, nIn), NULL); return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, TransactionSignatureChecker(&tx, nIn), NULL);
} catch (const std::exception&) { } catch (const std::exception&) {
return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing
} }

6
src/script/interpreter.cpp

@ -1058,12 +1058,12 @@ uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsig
return ss.GetHash(); return ss.GetHash();
} }
bool SignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const bool TransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
{ {
return pubkey.Verify(sighash, vchSig); return pubkey.Verify(sighash, vchSig);
} }
bool SignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn, const vector<unsigned char>& vchPubKey, const CScript& scriptCode) const bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn, const vector<unsigned char>& vchPubKey, const CScript& scriptCode) const
{ {
CPubKey pubkey(vchPubKey); CPubKey pubkey(vchPubKey);
if (!pubkey.IsValid()) if (!pubkey.IsValid())
@ -1076,7 +1076,7 @@ bool SignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn, const vec
int nHashType = vchSig.back(); int nHashType = vchSig.back();
vchSig.pop_back(); vchSig.pop_back();
uint256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType); uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType);
if (!VerifySignature(vchSig, pubkey, sighash)) if (!VerifySignature(vchSig, pubkey, sighash))
return false; return false;

16
src/script/interpreter.h

@ -7,6 +7,7 @@
#define BITCOIN_SCRIPT_INTERPRETER_H #define BITCOIN_SCRIPT_INTERPRETER_H
#include "script_error.h" #include "script_error.h"
#include "primitives/transaction.h"
#include <vector> #include <vector>
#include <stdint.h> #include <stdint.h>
@ -90,20 +91,29 @@ public:
virtual ~BaseSignatureChecker() {} virtual ~BaseSignatureChecker() {}
}; };
class SignatureChecker : public BaseSignatureChecker class TransactionSignatureChecker : public BaseSignatureChecker
{ {
private: private:
const CTransaction& txTo; const CTransaction* txTo;
unsigned int nIn; unsigned int nIn;
protected: protected:
virtual bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; virtual bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
public: public:
SignatureChecker(const CTransaction& txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {} TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {}
bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const; bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const;
}; };
class MutableTransactionSignatureChecker : public TransactionSignatureChecker
{
private:
const CTransaction txTo;
public:
MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, unsigned int nInIn) : TransactionSignatureChecker(&txTo, nInIn), txTo(*txToIn) {}
};
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL); bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL);
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL); bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL);

4
src/script/sigcache.cpp

@ -74,14 +74,14 @@ public:
} }
bool CachingSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const bool CachingTransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
{ {
static CSignatureCache signatureCache; static CSignatureCache signatureCache;
if (signatureCache.Get(sighash, vchSig, pubkey)) if (signatureCache.Get(sighash, vchSig, pubkey))
return true; return true;
if (!SignatureChecker::VerifySignature(vchSig, pubkey, sighash)) if (!TransactionSignatureChecker::VerifySignature(vchSig, pubkey, sighash))
return false; return false;
if (store) if (store)

4
src/script/sigcache.h

@ -12,13 +12,13 @@
class CPubKey; class CPubKey;
class CachingSignatureChecker : public SignatureChecker class CachingTransactionSignatureChecker : public TransactionSignatureChecker
{ {
private: private:
bool store; bool store;
public: public:
CachingSignatureChecker(const CTransaction& txToIn, unsigned int nInIn, bool storeIn=true) : SignatureChecker(txToIn, nInIn), store(storeIn) {} CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, bool storeIn=true) : TransactionSignatureChecker(txToIn, nInIn), store(storeIn) {}
bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
}; };

4
src/script/sign.cpp

@ -123,7 +123,7 @@ bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutabl
} }
// Test solution // Test solution
return VerifyScript(txin.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(txTo, nIn)); return VerifyScript(txin.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&txTo, nIn));
} }
bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType) bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
@ -174,7 +174,7 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction&
if (sigs.count(pubkey)) if (sigs.count(pubkey))
continue; // Already got a sig for this pubkey continue; // Already got a sig for this pubkey
if (SignatureChecker(txTo, nIn).CheckSig(sig, pubkey, scriptPubKey)) if (TransactionSignatureChecker(&txTo, nIn).CheckSig(sig, pubkey, scriptPubKey))
{ {
sigs[pubkey] = sig; sigs[pubkey] = sig;
break; break;

16
src/test/multisig_tests.cpp

@ -82,20 +82,20 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
keys.assign(1,key[0]); keys.assign(1,key[0]);
keys.push_back(key[1]); keys.push_back(key[1]);
s = sign_multisig(a_and_b, keys, txTo[0], 0); s = sign_multisig(a_and_b, keys, txTo[0], 0);
BOOST_CHECK(VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err)); BOOST_CHECK(VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
keys.assign(1,key[i]); keys.assign(1,key[i]);
s = sign_multisig(a_and_b, keys, txTo[0], 0); s = sign_multisig(a_and_b, keys, txTo[0], 0);
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err), strprintf("a&b 1: %d", i)); BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 1: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
keys.assign(1,key[1]); keys.assign(1,key[1]);
keys.push_back(key[i]); keys.push_back(key[i]);
s = sign_multisig(a_and_b, keys, txTo[0], 0); s = sign_multisig(a_and_b, keys, txTo[0], 0);
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err), strprintf("a&b 2: %d", i)); BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 2: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
} }
@ -106,18 +106,18 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
s = sign_multisig(a_or_b, keys, txTo[1], 0); s = sign_multisig(a_or_b, keys, txTo[1], 0);
if (i == 0 || i == 1) if (i == 0 || i == 1)
{ {
BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err), strprintf("a|b: %d", i)); BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
} }
else else
{ {
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err), strprintf("a|b: %d", i)); BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
} }
} }
s.clear(); s.clear();
s << OP_0 << OP_1; s << OP_0 << OP_1;
BOOST_CHECK(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err)); BOOST_CHECK(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
@ -129,12 +129,12 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
s = sign_multisig(escrow, keys, txTo[2], 0); s = sign_multisig(escrow, keys, txTo[2], 0);
if (i < j && i < 3 && j < 3) if (i < j && i < 3 && j < 3)
{ {
BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, SignatureChecker(txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j)); BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
} }
else else
{ {
BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, SignatureChecker(txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j)); BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
} }
} }

2
src/test/script_P2SH_tests.cpp

@ -43,7 +43,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, Scri
txTo.vin[0].scriptSig = scriptSig; txTo.vin[0].scriptSig = scriptSig;
txTo.vout[0].nValue = 1; txTo.vout[0].nValue = 1;
return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, SignatureChecker(txTo, 0), &err); return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0), &err);
} }

28
src/test/script_tests.cpp

@ -93,7 +93,7 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bo
ScriptError err; ScriptError err;
CMutableTransaction tx = BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)); CMutableTransaction tx = BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey));
CMutableTransaction tx2 = tx; CMutableTransaction tx2 = tx;
BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, SignatureChecker(tx, 0), &err) == expect, message); BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, MutableTransactionSignatureChecker(&tx, 0), &err) == expect, message);
BOOST_CHECK_MESSAGE(expect == (err == SCRIPT_ERR_OK), std::string(ScriptErrorString(err)) + ": " + message); BOOST_CHECK_MESSAGE(expect == (err == SCRIPT_ERR_OK), std::string(ScriptErrorString(err)) + ": " + message);
#if defined(HAVE_CONSENSUS_LIB) #if defined(HAVE_CONSENSUS_LIB)
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
@ -682,18 +682,18 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12)
CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12); CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12);
CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12);
BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err)); BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
txTo12.vout[0].nValue = 2; txTo12.vout[0].nValue = 2;
BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err)); BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12); CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12);
BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err)); BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12); CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12);
BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err)); BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
} }
@ -715,54 +715,54 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
std::vector<CKey> keys; std::vector<CKey> keys;
keys.push_back(key1); keys.push_back(key2); keys.push_back(key1); keys.push_back(key2);
CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear(); keys.clear();
keys.push_back(key1); keys.push_back(key3); keys.push_back(key1); keys.push_back(key3);
CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear(); keys.clear();
keys.push_back(key2); keys.push_back(key3); keys.push_back(key2); keys.push_back(key3);
CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear(); keys.clear();
keys.push_back(key2); keys.push_back(key2); // Can't re-use sig keys.push_back(key2); keys.push_back(key2); // Can't re-use sig
CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear(); keys.clear();
keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order
CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear(); keys.clear();
keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order
CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear(); keys.clear();
keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys
CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23);
BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear(); keys.clear();
keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys
CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23);
BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear(); // Must have signatures keys.clear(); // Must have signatures
CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23);
BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
} }

4
src/test/transaction_tests.cpp

@ -145,7 +145,7 @@ BOOST_AUTO_TEST_CASE(tx_valid)
unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
verify_flags, SignatureChecker(tx, i), &err), verify_flags, TransactionSignatureChecker(&tx, i), &err),
strTest); strTest);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
} }
@ -220,7 +220,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
verify_flags, SignatureChecker(tx, i), &err); verify_flags, TransactionSignatureChecker(&tx, i), &err);
} }
BOOST_CHECK_MESSAGE(!fValid, strTest); BOOST_CHECK_MESSAGE(!fValid, strTest);
BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err));

Loading…
Cancel
Save