Skip to content

Commit 544542f

Browse files
committed
Add segwit support to script_tests
1 parent e967241 commit 544542f

File tree

4 files changed

+59
-48
lines changed

4 files changed

+59
-48
lines changed

src/test/data/script_invalid.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
[
2-
["Format is: [scriptSig, scriptPubKey, flags, ... comments]"],
2+
["Format is: [[scriptWitness1, ...]?, scriptSig, scriptPubKey, flags, ... comments]"],
33
["It is evaluated as if there was a crediting coinbase transaction with two 0"],
44
["pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,"],
55
["followed by a spending transaction which spends this output as only input (and"],
6-
["correct prevout hash), using the given scriptSig. All nLockTimes are 0, all"],
7-
["nSequences are max."],
6+
["correct prevout hash), using the given scriptSig and witness stack. All nLockTimes"],
7+
["are 0, all nSequences are max."],
88

99
["", "DEPTH", "P2SH,STRICTENC", "Test the test: we should have an empty stack after scriptSig evaluation"],
1010
[" ", "DEPTH", "P2SH,STRICTENC", "and multiple spaces should not change that."],
@@ -532,6 +532,10 @@
532532
["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "Zero-length S is incorrectly encoded for DERSIG"],
533533
["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Negative S is incorrectly encoded for DERSIG"],
534534

535+
["Basic segwit tests"],
536+
[["00"], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "WITNESS", "Invalid witness script"],
537+
[["51"], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "WITNESS", "Witness script hash mismatch"],
538+
535539
["Automatically generated test cases"],
536540
[
537541
"0x47 0x304402200a5c6163f07b8c3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001",

src/test/data/script_valid.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
[
2-
["Format is: [scriptSig, scriptPubKey, flags, ... comments]"],
2+
["Format is: [[scriptWitness1, ...]?, scriptSig, scriptPubKey, flags, ... comments]"],
33
["It is evaluated as if there was a crediting coinbase transaction with two 0"],
44
["pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,"],
55
["followed by a spending transaction which spends this output as only input (and"],
6-
["correct prevout hash), using the given scriptSig. All nLockTimes are 0, all"],
7-
["nSequences are max."],
6+
["correct prevout hash), using the given scriptSig and witness stack. All nLockTimes"],
7+
["are 0, all nSequences are max."],
88

99
["", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "Test the test: we should have an empty stack after scriptSig evaluation"],
1010
[" ", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "and multiple spaces should not change that."],
@@ -701,6 +701,10 @@
701701
["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "Zero-length S is correctly encoded for DERSIG"],
702702
["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Negative S is correctly encoded"],
703703

704+
["Basic segwit tests"],
705+
[["00"], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "", "Invalid witness script without WITNESS"],
706+
[["51"], "", "0 0x206e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", "", "Witness script hash mismatch without WITNESS"],
707+
704708
["Automatically generated test cases"],
705709
[
706710
"0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001",

src/test/script_tests.cpp

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,15 @@ CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey)
7070
return txCredit;
7171
}
7272

73-
CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMutableTransaction& txCredit)
73+
CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScriptWitness& scriptWitness, const CMutableTransaction& txCredit)
7474
{
7575
CMutableTransaction txSpend;
7676
txSpend.nVersion = 1;
7777
txSpend.nLockTime = 0;
7878
txSpend.vin.resize(1);
7979
txSpend.vout.resize(1);
80+
txSpend.wit.vtxinwit.resize(1);
81+
txSpend.wit.vtxinwit[0].scriptWitness = scriptWitness;
8082
txSpend.vin[0].prevout.hash = txCredit.GetHash();
8183
txSpend.vin[0].prevout.n = 0;
8284
txSpend.vin[0].scriptSig = scriptSig;
@@ -87,20 +89,20 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMu
8789
return txSpend;
8890
}
8991

90-
void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bool expect, const std::string& message)
92+
void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScriptWitness& scriptWitness, int flags, bool expect, const std::string& message)
9193
{
9294
if (flags & SCRIPT_VERIFY_CLEANSTACK) {
9395
flags |= SCRIPT_VERIFY_P2SH;
9496
flags |= SCRIPT_VERIFY_WITNESS;
9597
}
9698
ScriptError err;
9799
CMutableTransaction txCredit = BuildCreditingTransaction(scriptPubKey);
98-
CMutableTransaction tx = BuildSpendingTransaction(scriptSig, txCredit);
100+
CMutableTransaction tx = BuildSpendingTransaction(scriptSig, scriptWitness, txCredit);
99101
CMutableTransaction tx2 = tx;
100-
BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, txCredit.vout[0].scriptPubKey, NULL, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue), &err) == expect, message);
102+
BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, txCredit.vout[0].scriptPubKey, &scriptWitness, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue), &err) == expect, message);
101103
BOOST_CHECK_MESSAGE(expect == (err == SCRIPT_ERR_OK), std::string(ScriptErrorString(err)) + ": " + message);
102104
#if defined(HAVE_CONSENSUS_LIB)
103-
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
105+
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_WITNESS);
104106
stream << tx2;
105107
if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) {
106108
BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(begin_ptr(scriptPubKey), scriptPubKey.size(), txCredit.vout[0].nValue, (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect, message);
@@ -221,7 +223,7 @@ class TestBuilder
221223
} else {
222224
creditTx = BuildCreditingTransaction(redeemScript);
223225
}
224-
spendTx = BuildSpendingTransaction(CScript(), creditTx);
226+
spendTx = BuildSpendingTransaction(CScript(), CScriptWitness(), creditTx);
225227
}
226228

227229
TestBuilder& Add(const CScript& script)
@@ -298,7 +300,7 @@ class TestBuilder
298300
{
299301
TestBuilder copy = *this; // Make a copy so we can rollback the push.
300302
DoPush();
301-
DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, flags, expect, comment);
303+
DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, CScriptWitness(), flags, expect, comment);
302304
*this = copy;
303305
return *this;
304306
}
@@ -637,32 +639,45 @@ BOOST_AUTO_TEST_CASE(script_build)
637639
#endif
638640
}
639641

642+
static void RunJSONTest(const UniValue& test, bool expect)
643+
{
644+
string strTest = test.write();
645+
CScriptWitness witness;
646+
unsigned int pos = 0;
647+
if (test.size() > 0 && test[pos].isArray()) {
648+
for (unsigned int i = 0; i < test[pos].size(); i++) {
649+
witness.stack.push_back(ParseHex(test[pos][i].get_str()));
650+
}
651+
pos++;
652+
}
653+
if (test.size() < 3 + pos) // Allow size > 3; extra stuff ignored (useful for comments)
654+
{
655+
if (test.size() != 1) {
656+
BOOST_ERROR("Bad test: " << strTest);
657+
}
658+
return;
659+
}
660+
string scriptSigString = test[pos++].get_str();
661+
CScript scriptSig = ParseScript(scriptSigString);
662+
string scriptPubKeyString = test[pos++].get_str();
663+
CScript scriptPubKey = ParseScript(scriptPubKeyString);
664+
unsigned int scriptflags = ParseScriptFlags(test[pos++].get_str());
665+
666+
DoTest(scriptPubKey, scriptSig, witness, scriptflags, expect, strTest);
667+
}
668+
640669
BOOST_AUTO_TEST_CASE(script_valid)
641670
{
642671
// Read tests from test/data/script_valid.json
643672
// Format is an array of arrays
644-
// Inner arrays are [ "scriptSig", "scriptPubKey", "flags" ]
673+
// Inner arrays are [ ["wit1", "wit2", ...]?, "scriptSig", "scriptPubKey", "flags" ]
645674
// ... where scriptSig and scriptPubKey are stringified
646675
// scripts.
647676
UniValue tests = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid)));
648677

649678
for (unsigned int idx = 0; idx < tests.size(); idx++) {
650679
UniValue test = tests[idx];
651-
string strTest = test.write();
652-
if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments)
653-
{
654-
if (test.size() != 1) {
655-
BOOST_ERROR("Bad test: " << strTest);
656-
}
657-
continue;
658-
}
659-
string scriptSigString = test[0].get_str();
660-
CScript scriptSig = ParseScript(scriptSigString);
661-
string scriptPubKeyString = test[1].get_str();
662-
CScript scriptPubKey = ParseScript(scriptPubKeyString);
663-
unsigned int scriptflags = ParseScriptFlags(test[2].get_str());
664-
665-
DoTest(scriptPubKey, scriptSig, scriptflags, true, strTest);
680+
RunJSONTest(test, true);
666681
}
667682
}
668683

@@ -673,21 +688,7 @@ BOOST_AUTO_TEST_CASE(script_invalid)
673688

674689
for (unsigned int idx = 0; idx < tests.size(); idx++) {
675690
UniValue test = tests[idx];
676-
string strTest = test.write();
677-
if (test.size() < 3) // Allow size > 2; extra stuff ignored (useful for comments)
678-
{
679-
if (test.size() != 1) {
680-
BOOST_ERROR("Bad test: " << strTest);
681-
}
682-
continue;
683-
}
684-
string scriptSigString = test[0].get_str();
685-
CScript scriptSig = ParseScript(scriptSigString);
686-
string scriptPubKeyString = test[1].get_str();
687-
CScript scriptPubKey = ParseScript(scriptPubKeyString);
688-
unsigned int scriptflags = ParseScriptFlags(test[2].get_str());
689-
690-
DoTest(scriptPubKey, scriptSig, scriptflags, false, strTest);
691+
RunJSONTest(test, false);
691692
}
692693
}
693694

@@ -765,7 +766,7 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12)
765766
scriptPubKey12 << OP_1 << ToByteVector(key1.GetPubKey()) << ToByteVector(key2.GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
766767

767768
CMutableTransaction txFrom12 = BuildCreditingTransaction(scriptPubKey12);
768-
CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12);
769+
CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom12);
769770

770771
CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12);
771772
BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, NULL, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), &err));
@@ -796,7 +797,7 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
796797
scriptPubKey23 << OP_2 << ToByteVector(key1.GetPubKey()) << ToByteVector(key2.GetPubKey()) << ToByteVector(key3.GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
797798

798799
CMutableTransaction txFrom23 = BuildCreditingTransaction(scriptPubKey23);
799-
CMutableTransaction txTo23 = BuildSpendingTransaction(CScript(), txFrom23);
800+
CMutableTransaction txTo23 = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom23);
800801

801802
std::vector<CKey> keys;
802803
keys.push_back(key1); keys.push_back(key2);
@@ -869,7 +870,7 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
869870
}
870871

871872
CMutableTransaction txFrom = BuildCreditingTransaction(GetScriptForDestination(keys[0].GetPubKey().GetID()));
872-
CMutableTransaction txTo = BuildSpendingTransaction(CScript(), txFrom);
873+
CMutableTransaction txTo = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom);
873874
CScript& scriptPubKey = txFrom.vout[0].scriptPubKey;
874875
CScript& scriptSig = txTo.vin[0].scriptSig;
875876

src/test/transaction_tests.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of
5050
(string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
5151
(string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK)
5252
(string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)
53-
(string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY);
53+
(string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)
54+
(string("WITNESS"), (unsigned int)SCRIPT_VERIFY_WITNESS)
55+
(string("DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM);
5456

5557
unsigned int ParseScriptFlags(string strFlags)
5658
{

0 commit comments

Comments
 (0)