Changeset View
Changeset View
Standalone View
Standalone View
src/test/script_tests.cpp
Show First 20 Lines • Show All 267 Lines • ▼ Show 20 Lines | |||||
public: | public: | ||||
TestBuilder(const CScript &script_, const std::string &comment_, int flags_, | TestBuilder(const CScript &script_, const std::string &comment_, int flags_, | ||||
bool P2SH = false, CAmount nValue_ = 0) | bool P2SH = false, CAmount nValue_ = 0) | ||||
: script(script_), havePush(false), comment(comment_), flags(flags_), | : script(script_), havePush(false), comment(comment_), flags(flags_), | ||||
scriptError(SCRIPT_ERR_OK), nValue(nValue_) { | scriptError(SCRIPT_ERR_OK), nValue(nValue_) { | ||||
CScript scriptPubKey = script; | CScript scriptPubKey = script; | ||||
if (P2SH) { | if (P2SH) { | ||||
redeemscript = scriptPubKey; | redeemscript = scriptPubKey; | ||||
scriptPubKey = CScript() << OP_HASH160 | scriptPubKey = CScript() | ||||
<< ToByteVector(CScriptID(redeemscript)) | << OP_HASH160 | ||||
<< OP_EQUAL; | << ToByteVector(CScriptID(redeemscript)) << OP_EQUAL; | ||||
} | } | ||||
creditTx = | creditTx = | ||||
MakeTransactionRef(BuildCreditingTransaction(scriptPubKey, nValue)); | MakeTransactionRef(BuildCreditingTransaction(scriptPubKey, nValue)); | ||||
spendTx = BuildSpendingTransaction(CScript(), *creditTx); | spendTx = BuildSpendingTransaction(CScript(), *creditTx); | ||||
} | } | ||||
TestBuilder &ScriptError(ScriptError_t err) { | TestBuilder &ScriptError(ScriptError_t err) { | ||||
scriptError = err; | scriptError = err; | ||||
Show All 20 Lines | public: | ||||
TestBuilder &Push(const CScript &_script) { | TestBuilder &Push(const CScript &_script) { | ||||
DoPush(std::vector<uint8_t>(_script.begin(), _script.end())); | DoPush(std::vector<uint8_t>(_script.begin(), _script.end())); | ||||
return *this; | return *this; | ||||
} | } | ||||
TestBuilder &PushSig(const CKey &key, int nHashType = SIGHASH_ALL, | TestBuilder &PushSig(const CKey &key, int nHashType = SIGHASH_ALL, | ||||
unsigned int lenR = 32, unsigned int lenS = 32, | unsigned int lenR = 32, unsigned int lenS = 32, | ||||
CAmount amount = 0) { | CAmount amount = 0) { | ||||
uint256 hash = SignatureHash(script, spendTx, 0, nHashType, amount); | uint256 hash = | ||||
SignatureHash(script, spendTx, 0, nHashType, amount, CScript()); | |||||
std::vector<uint8_t> vchSig, r, s; | std::vector<uint8_t> vchSig, r, s; | ||||
uint32_t iter = 0; | uint32_t iter = 0; | ||||
do { | do { | ||||
key.Sign(hash, vchSig, iter++); | key.Sign(hash, vchSig, iter++); | ||||
if ((lenS == 33) != (vchSig[5 + vchSig[3]] == 33)) { | if ((lenS == 33) != (vchSig[5 + vchSig[3]] == 33)) { | ||||
NegateSignatureS(vchSig); | NegateSignatureS(vchSig); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 253 Lines • ▼ Show 20 Lines | tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) | ||||
<< OP_CHECKSIG << OP_NOT, | << OP_CHECKSIG << OP_NOT, | ||||
"P2PK NOT with bad sig with too much R padding", | "P2PK NOT with bad sig with too much R padding", | ||||
SCRIPT_VERIFY_DERSIG) | SCRIPT_VERIFY_DERSIG) | ||||
.PushSig(keys.key2, SIGHASH_ALL, 31, 32) | .PushSig(keys.key2, SIGHASH_ALL, 31, 32) | ||||
.EditPush(1, "43021F", "44022000") | .EditPush(1, "43021F", "44022000") | ||||
.DamagePush(10) | .DamagePush(10) | ||||
.ScriptError(SCRIPT_ERR_SIG_DER)); | .ScriptError(SCRIPT_ERR_SIG_DER)); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG | TestBuilder(CScript() | ||||
<< OP_NOT, | << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, | ||||
"P2PK NOT with too much R padding but no DERSIG", 0) | "P2PK NOT with too much R padding but no DERSIG", 0) | ||||
.PushSig(keys.key2, SIGHASH_ALL, 31, 32) | .PushSig(keys.key2, SIGHASH_ALL, 31, 32) | ||||
.EditPush(1, "43021F", "44022000") | .EditPush(1, "43021F", "44022000") | ||||
.ScriptError(SCRIPT_ERR_EVAL_FALSE)); | .ScriptError(SCRIPT_ERR_EVAL_FALSE)); | ||||
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) | tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) | ||||
<< OP_CHECKSIG << OP_NOT, | << OP_CHECKSIG << OP_NOT, | ||||
"P2PK NOT with too much R padding", | "P2PK NOT with too much R padding", | ||||
SCRIPT_VERIFY_DERSIG) | SCRIPT_VERIFY_DERSIG) | ||||
▲ Show 20 Lines • Show All 214 Lines • ▼ Show 20 Lines | tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) | ||||
.ScriptError(SCRIPT_ERR_EVAL_FALSE)); | .ScriptError(SCRIPT_ERR_EVAL_FALSE)); | ||||
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) | tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) | ||||
<< OP_CHECKSIG << OP_NOT, | << OP_CHECKSIG << OP_NOT, | ||||
"P2PK NOT with hybrid pubkey", | "P2PK NOT with hybrid pubkey", | ||||
SCRIPT_VERIFY_STRICTENC) | SCRIPT_VERIFY_STRICTENC) | ||||
.PushSig(keys.key0, SIGHASH_ALL) | .PushSig(keys.key0, SIGHASH_ALL) | ||||
.ScriptError(SCRIPT_ERR_PUBKEYTYPE)); | .ScriptError(SCRIPT_ERR_PUBKEYTYPE)); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG | TestBuilder(CScript() | ||||
<< OP_NOT, | << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, | ||||
"P2PK NOT with invalid hybrid pubkey but no STRICTENC", 0) | "P2PK NOT with invalid hybrid pubkey but no STRICTENC", 0) | ||||
.PushSig(keys.key0, SIGHASH_ALL) | .PushSig(keys.key0, SIGHASH_ALL) | ||||
.DamagePush(10)); | .DamagePush(10)); | ||||
tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) | tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) | ||||
<< OP_CHECKSIG << OP_NOT, | << OP_CHECKSIG << OP_NOT, | ||||
"P2PK NOT with invalid hybrid pubkey", | "P2PK NOT with invalid hybrid pubkey", | ||||
SCRIPT_VERIFY_STRICTENC) | SCRIPT_VERIFY_STRICTENC) | ||||
.PushSig(keys.key0, SIGHASH_ALL) | .PushSig(keys.key0, SIGHASH_ALL) | ||||
Show All 35 Lines | BOOST_AUTO_TEST_CASE(script_build) { | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder( | TestBuilder( | ||||
CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT, | CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT, | ||||
"P2PK NOT with invalid sig and undefined hashtype but no STRICTENC", | "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC", | ||||
0) | 0) | ||||
.PushSig(keys.key1, 5) | .PushSig(keys.key1, 5) | ||||
.DamagePush(10)); | .DamagePush(10)); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG | TestBuilder(CScript() | ||||
<< OP_NOT, | << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT, | ||||
"P2PK NOT with invalid sig and undefined hashtype", | "P2PK NOT with invalid sig and undefined hashtype", | ||||
SCRIPT_VERIFY_STRICTENC) | SCRIPT_VERIFY_STRICTENC) | ||||
.PushSig(keys.key1, 5) | .PushSig(keys.key1, 5) | ||||
.DamagePush(10) | .DamagePush(10) | ||||
.ScriptError(SCRIPT_ERR_SIG_HASHTYPE)); | .ScriptError(SCRIPT_ERR_SIG_HASHTYPE)); | ||||
tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) | tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) | ||||
<< ToByteVector(keys.pubkey1C) | << ToByteVector(keys.pubkey1C) | ||||
▲ Show 20 Lines • Show All 172 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(script_build) { | ||||
std::string strGen; | std::string strGen; | ||||
for (TestBuilder &test : tests) { | for (TestBuilder &test : tests) { | ||||
test.Test(); | test.Test(); | ||||
std::string str = JSONPrettyPrint(test.GetJSON()); | std::string str = JSONPrettyPrint(test.GetJSON()); | ||||
#ifndef UPDATE_JSON_TESTS | #ifndef UPDATE_JSON_TESTS | ||||
if (tests_set.count(str) == 0) { | if (tests_set.count(str) == 0) { | ||||
BOOST_CHECK_MESSAGE(false, "Missing auto script_valid test: " + | BOOST_CHECK_MESSAGE( | ||||
test.GetComment()); | false, "Missing auto script_valid test: " + test.GetComment()); | ||||
} | } | ||||
#endif | #endif | ||||
strGen += str + ",\n"; | strGen += str + ",\n"; | ||||
} | } | ||||
#ifdef UPDATE_JSON_TESTS | #ifdef UPDATE_JSON_TESTS | ||||
FILE *file = fopen("script_tests.json.gen", "w"); | FILE *file = fopen("script_tests.json.gen", "w"); | ||||
fputs(strGen.c_str(), file); | fputs(strGen.c_str(), file); | ||||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | 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(CScript scriptPubKey, std::vector<CKey> keys, | ||||
CTransaction transaction) { | CTransaction transaction) { | ||||
uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL, 0); | uint256 hash = | ||||
SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL, 0, CScript()); | |||||
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) | ||||
// | // | ||||
▲ Show 20 Lines • Show All 254 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(script_combineSigs) { | ||||
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); | ||||
// A couple of partially-signed versions: | // A couple of partially-signed versions: | ||||
std::vector<uint8_t> sig1; | std::vector<uint8_t> sig1; | ||||
uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL, 0); | uint256 hash1 = | ||||
SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL, 0, CScript()); | |||||
BOOST_CHECK(keys[0].Sign(hash1, sig1)); | BOOST_CHECK(keys[0].Sign(hash1, sig1)); | ||||
sig1.push_back(SIGHASH_ALL); | sig1.push_back(SIGHASH_ALL); | ||||
std::vector<uint8_t> sig2; | std::vector<uint8_t> sig2; | ||||
uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE, 0); | uint256 hash2 = | ||||
SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE, 0, CScript()); | |||||
BOOST_CHECK(keys[1].Sign(hash2, sig2)); | BOOST_CHECK(keys[1].Sign(hash2, sig2)); | ||||
sig2.push_back(SIGHASH_NONE); | sig2.push_back(SIGHASH_NONE); | ||||
std::vector<uint8_t> sig3; | std::vector<uint8_t> sig3; | ||||
uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE, 0); | uint256 hash3 = | ||||
SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE, 0, CScript()); | |||||
BOOST_CHECK(keys[2].Sign(hash3, sig3)); | BOOST_CHECK(keys[2].Sign(hash3, sig3)); | ||||
sig3.push_back(SIGHASH_SINGLE); | sig3.push_back(SIGHASH_SINGLE); | ||||
// Not fussy about order (or even existence) of placeholders or signatures: | // Not fussy about order (or even existence) of placeholders or signatures: | ||||
CScript partial1a = CScript() << OP_0 << sig1 << OP_0; | CScript partial1a = CScript() << OP_0 << sig1 << OP_0; | ||||
CScript partial1b = CScript() << OP_0 << OP_0 << sig1; | CScript partial1b = CScript() << OP_0 << OP_0 << sig1; | ||||
CScript partial2a = CScript() << OP_0 << sig2; | CScript partial2a = CScript() << OP_0 << sig2; | ||||
CScript partial2b = CScript() << sig2 << OP_0; | CScript partial2b = CScript() << sig2 << OP_0; | ||||
▲ Show 20 Lines • Show All 325 Lines • Show Last 20 Lines |