Changeset View
Changeset View
Standalone View
Standalone View
src/test/script_tests.cpp
Show First 20 Lines • Show All 2,544 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(script_PushData) { | ||||
std::vector<std::vector<uint8_t>> pushdata4Stack; | std::vector<std::vector<uint8_t>> pushdata4Stack; | ||||
BOOST_CHECK(EvalScript( | BOOST_CHECK(EvalScript( | ||||
pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), | pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), | ||||
SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); | SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); | ||||
BOOST_CHECK(pushdata4Stack == directStack); | BOOST_CHECK(pushdata4Stack == directStack); | ||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); | BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); | ||||
} | } | ||||
CScript sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, | CScript sign_multisig(const CScript &scriptPubKey, | ||||
CTransaction transaction) { | const std::vector<CKey> &keys, | ||||
const CTransaction &transaction) { | |||||
uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SigHashType(), | uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SigHashType(), | ||||
Amount::zero()); | Amount::zero()); | ||||
CScript result; | CScript result; | ||||
// | // | ||||
// NOTE: CHECKMULTISIG has an unfortunate bug; it requires one extra item on | // NOTE: CHECKMULTISIG has an unfortunate bug; it requires one extra item on | ||||
// the stack, before the signatures. Putting OP_0 on the stack is the | // the stack, before the signatures. Putting OP_0 on the stack is the | ||||
// workaround; fixing the bug would mean splitting the block chain (old | // workaround; fixing the bug would mean splitting the block chain (old | ||||
// clients would not accept new CHECKMULTISIG transactions, and vice-versa) | // clients would not accept new CHECKMULTISIG transactions, and vice-versa) | ||||
// | // | ||||
result << OP_0; | result << OP_0; | ||||
for (const CKey &key : keys) { | for (const CKey &key : keys) { | ||||
std::vector<uint8_t> vchSig; | std::vector<uint8_t> vchSig; | ||||
BOOST_CHECK(key.SignECDSA(hash, vchSig)); | BOOST_CHECK(key.SignECDSA(hash, vchSig)); | ||||
vchSig.push_back(uint8_t(SIGHASH_ALL)); | vchSig.push_back(uint8_t(SIGHASH_ALL)); | ||||
result << vchSig; | result << vchSig; | ||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
CScript sign_multisig(CScript scriptPubKey, const CKey &key, | CScript sign_multisig(const CScript &scriptPubKey, const CKey &key, | ||||
CTransaction transaction) { | const CTransaction &transaction) { | ||||
std::vector<CKey> keys; | std::vector<CKey> keys; | ||||
keys.push_back(key); | keys.push_back(key); | ||||
return sign_multisig(scriptPubKey, keys, transaction); | return sign_multisig(scriptPubKey, keys, transaction); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) { | BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) { | ||||
ScriptError err; | ScriptError err; | ||||
CKey key1, key2, key3; | CKey key1, key2, key3; | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | scriptPubKey23 << OP_2 << ToByteVector(key1.GetPubKey()) | ||||
<< ToByteVector(key3.GetPubKey()) << OP_3 | << ToByteVector(key3.GetPubKey()) << OP_3 | ||||
<< OP_CHECKMULTISIG; | << OP_CHECKMULTISIG; | ||||
CMutableTransaction txFrom23 = | CMutableTransaction txFrom23 = | ||||
BuildCreditingTransaction(scriptPubKey23, Amount::zero()); | BuildCreditingTransaction(scriptPubKey23, Amount::zero()); | ||||
CMutableTransaction mutableTxTo23 = | CMutableTransaction mutableTxTo23 = | ||||
BuildSpendingTransaction(CScript(), txFrom23); | BuildSpendingTransaction(CScript(), txFrom23); | ||||
// after it has been set up, mutableTxTo23 does not change in this test, | // after it has been set up, mutableTxTo23 does not change in this test, so | ||||
// so we can convert it to readonly transaction and use | // we can convert it to readonly transaction and use | ||||
// TransactionSignatureChecker | // TransactionSignatureChecker instead of MutableTransactionSignatureChecker | ||||
// instead of MutableTransactionSignatureChecker | |||||
const CTransaction txTo23(mutableTxTo23); | const CTransaction txTo23(mutableTxTo23); | ||||
std::vector<CKey> keys; | std::vector<CKey> keys; | ||||
keys.push_back(key1); | keys.push_back(key1); | ||||
keys.push_back(key2); | keys.push_back(key2); | ||||
CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); | CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); | ||||
BOOST_CHECK(VerifyScript( | BOOST_CHECK(VerifyScript( | ||||
goodsig1, scriptPubKey23, gFlags, | goodsig1, scriptPubKey23, gFlags, | ||||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(script_combineSigs) { | ||||
} | } | ||||
CMutableTransaction txFrom = BuildCreditingTransaction( | CMutableTransaction txFrom = BuildCreditingTransaction( | ||||
GetScriptForDestination(keys[0].GetPubKey().GetID()), Amount::zero()); | GetScriptForDestination(keys[0].GetPubKey().GetID()), Amount::zero()); | ||||
CMutableTransaction txTo = BuildSpendingTransaction(CScript(), txFrom); | CMutableTransaction txTo = BuildSpendingTransaction(CScript(), txFrom); | ||||
CScript &scriptPubKey = txFrom.vout[0].scriptPubKey; | CScript &scriptPubKey = txFrom.vout[0].scriptPubKey; | ||||
CScript &scriptSig = txTo.vin[0].scriptSig; | CScript &scriptSig = txTo.vin[0].scriptSig; | ||||
// Although it looks like CMutableTransaction is not modified after it’s | |||||
// been set up (it is not passed as parameter to any non-const function), | |||||
// it is actually modified when new value is assigned to scriptPubKey, | |||||
// which points to mutableTxFrom.vout[0].scriptPubKey. Therefore we can | |||||
// not use single instance of CTransaction in this test. | |||||
// CTransaction creates a copy of CMutableTransaction and is not modified | |||||
// when scriptPubKey is assigned to. | |||||
SignatureData empty; | SignatureData empty; | ||||
SignatureData combined = CombineSignatures( | SignatureData combined = CombineSignatures( | ||||
scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | ||||
empty, empty); | empty, empty); | ||||
BOOST_CHECK(combined.scriptSig.empty()); | BOOST_CHECK(combined.scriptSig.empty()); | ||||
// Single signature case: | // Single signature case: | ||||
SignSignature(keystore, CTransaction(txFrom), txTo, 0, | SignSignature(keystore, CTransaction(txFrom), txTo, 0, SigHashType()); | ||||
SigHashType()); // changes scriptSig | |||||
combined = CombineSignatures( | combined = CombineSignatures( | ||||
scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | ||||
SignatureData(scriptSig), empty); | SignatureData(scriptSig), empty); | ||||
BOOST_CHECK(combined.scriptSig == scriptSig); | BOOST_CHECK(combined.scriptSig == scriptSig); | ||||
combined = CombineSignatures( | combined = CombineSignatures( | ||||
scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | ||||
empty, SignatureData(scriptSig)); | empty, SignatureData(scriptSig)); | ||||
BOOST_CHECK(combined.scriptSig == scriptSig); | BOOST_CHECK(combined.scriptSig == scriptSig); | ||||
▲ Show 20 Lines • Show All 444 Lines • Show Last 20 Lines |