1 // Copyright (c) 2012-2020 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <consensus/tx_verify.h>
6 #include <key.h>
7 #include <policy/policy.h>
8 #include <policy/settings.h>
9 #include <script/script.h>
10 #include <script/script_error.h>
11 #include <script/sign.h>
12 #include <script/signingprovider.h>
13 #include <test/util/setup_common.h>
14 #include <validation.h>
15 
16 #include <vector>
17 
18 #include <boost/test/unit_test.hpp>
19 
20 // Helpers:
21 static std::vector<unsigned char>
Serialize(const CScript & s)22 Serialize(const CScript& s)
23 {
24     std::vector<unsigned char> sSerialized(s.begin(), s.end());
25     return sSerialized;
26 }
27 
28 static bool
Verify(const CScript & scriptSig,const CScript & scriptPubKey,bool fStrict,ScriptError & err)29 Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, ScriptError& err)
30 {
31     // Create dummy to/from transactions:
32     CMutableTransaction txFrom;
33     txFrom.vout.resize(1);
34     txFrom.vout[0].scriptPubKey = scriptPubKey;
35 
36     CMutableTransaction txTo;
37     txTo.vin.resize(1);
38     txTo.vout.resize(1);
39     txTo.vin[0].prevout.n = 0;
40     txTo.vin[0].prevout.hash = txFrom.GetHash();
41     txTo.vin[0].scriptSig = scriptSig;
42     txTo.vout[0].nValue = 1;
43 
44     return VerifyScript(scriptSig, scriptPubKey, nullptr, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0, txFrom.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err);
45 }
46 
47 
BOOST_FIXTURE_TEST_SUITE(script_p2sh_tests,BasicTestingSetup)48 BOOST_FIXTURE_TEST_SUITE(script_p2sh_tests, BasicTestingSetup)
49 
50 BOOST_AUTO_TEST_CASE(sign)
51 {
52     LOCK(cs_main);
53     // Pay-to-script-hash looks like this:
54     // scriptSig:    <sig> <sig...> <serialized_script>
55     // scriptPubKey: HASH160 <hash> EQUAL
56 
57     // Test SignSignature() (and therefore the version of Solver() that signs transactions)
58     FillableSigningProvider keystore;
59     CKey key[4];
60     for (int i = 0; i < 4; i++)
61     {
62         key[i].MakeNewKey(true);
63         BOOST_CHECK(keystore.AddKey(key[i]));
64     }
65 
66     // 8 Scripts: checking all combinations of
67     // different keys, straight/P2SH, pubkey/pubkeyhash
68     CScript standardScripts[4];
69     standardScripts[0] << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG;
70     standardScripts[1] = GetScriptForDestination(PKHash(key[1].GetPubKey()));
71     standardScripts[2] << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG;
72     standardScripts[3] = GetScriptForDestination(PKHash(key[2].GetPubKey()));
73     CScript evalScripts[4];
74     for (int i = 0; i < 4; i++)
75     {
76         BOOST_CHECK(keystore.AddCScript(standardScripts[i]));
77         evalScripts[i] = GetScriptForDestination(ScriptHash(standardScripts[i]));
78     }
79 
80     CMutableTransaction txFrom;  // Funding transaction:
81     std::string reason;
82     txFrom.vout.resize(8);
83     for (int i = 0; i < 4; i++)
84     {
85         txFrom.vout[i].scriptPubKey = evalScripts[i];
86         txFrom.vout[i].nValue = COIN;
87         txFrom.vout[i+4].scriptPubKey = standardScripts[i];
88         txFrom.vout[i+4].nValue = COIN;
89     }
90     BOOST_CHECK(IsStandardTx(CTransaction(txFrom), reason));
91 
92     CMutableTransaction txTo[8]; // Spending transactions
93     for (int i = 0; i < 8; i++)
94     {
95         txTo[i].vin.resize(1);
96         txTo[i].vout.resize(1);
97         txTo[i].vin[0].prevout.n = i;
98         txTo[i].vin[0].prevout.hash = txFrom.GetHash();
99         txTo[i].vout[0].nValue = 1;
100     }
101     for (int i = 0; i < 8; i++)
102     {
103         BOOST_CHECK_MESSAGE(SignSignature(keystore, CTransaction(txFrom), txTo[i], 0, SIGHASH_ALL), strprintf("SignSignature %d", i));
104     }
105     // All of the above should be OK, and the txTos have valid signatures
106     // Check to make sure signature verification fails if we use the wrong ScriptSig:
107     for (int i = 0; i < 8; i++) {
108         PrecomputedTransactionData txdata(txTo[i]);
109         for (int j = 0; j < 8; j++)
110         {
111             CScript sigSave = txTo[i].vin[0].scriptSig;
112             txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig;
113             bool sigOK = CScriptCheck(txFrom.vout[txTo[i].vin[0].prevout.n], CTransaction(txTo[i]), 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, false, &txdata)();
114             if (i == j)
115                 BOOST_CHECK_MESSAGE(sigOK, strprintf("VerifySignature %d %d", i, j));
116             else
117                 BOOST_CHECK_MESSAGE(!sigOK, strprintf("VerifySignature %d %d", i, j));
118             txTo[i].vin[0].scriptSig = sigSave;
119         }
120     }
121 }
122 
BOOST_AUTO_TEST_CASE(norecurse)123 BOOST_AUTO_TEST_CASE(norecurse)
124 {
125     ScriptError err;
126     // Make sure only the outer pay-to-script-hash does the
127     // extra-validation thing:
128     CScript invalidAsScript;
129     invalidAsScript << OP_INVALIDOPCODE << OP_INVALIDOPCODE;
130 
131     CScript p2sh = GetScriptForDestination(ScriptHash(invalidAsScript));
132 
133     CScript scriptSig;
134     scriptSig << Serialize(invalidAsScript);
135 
136     // Should not verify, because it will try to execute OP_INVALIDOPCODE
137     BOOST_CHECK(!Verify(scriptSig, p2sh, true, err));
138     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_BAD_OPCODE, ScriptErrorString(err));
139 
140     // Try to recur, and verification should succeed because
141     // the inner HASH160 <> EQUAL should only check the hash:
142     CScript p2sh2 = GetScriptForDestination(ScriptHash(p2sh));
143     CScript scriptSig2;
144     scriptSig2 << Serialize(invalidAsScript) << Serialize(p2sh);
145 
146     BOOST_CHECK(Verify(scriptSig2, p2sh2, true, err));
147     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
148 }
149 
BOOST_AUTO_TEST_CASE(set)150 BOOST_AUTO_TEST_CASE(set)
151 {
152     LOCK(cs_main);
153     // Test the CScript::Set* methods
154     FillableSigningProvider keystore;
155     CKey key[4];
156     std::vector<CPubKey> keys;
157     for (int i = 0; i < 4; i++)
158     {
159         key[i].MakeNewKey(true);
160         BOOST_CHECK(keystore.AddKey(key[i]));
161         keys.push_back(key[i].GetPubKey());
162     }
163 
164     CScript inner[4];
165     inner[0] = GetScriptForDestination(PKHash(key[0].GetPubKey()));
166     inner[1] = GetScriptForMultisig(2, std::vector<CPubKey>(keys.begin(), keys.begin()+2));
167     inner[2] = GetScriptForMultisig(1, std::vector<CPubKey>(keys.begin(), keys.begin()+2));
168     inner[3] = GetScriptForMultisig(2, std::vector<CPubKey>(keys.begin(), keys.begin()+3));
169 
170     CScript outer[4];
171     for (int i = 0; i < 4; i++)
172     {
173         outer[i] = GetScriptForDestination(ScriptHash(inner[i]));
174         BOOST_CHECK(keystore.AddCScript(inner[i]));
175     }
176 
177     CMutableTransaction txFrom;  // Funding transaction:
178     std::string reason;
179     txFrom.vout.resize(4);
180     for (int i = 0; i < 4; i++)
181     {
182         txFrom.vout[i].scriptPubKey = outer[i];
183         txFrom.vout[i].nValue = CENT;
184     }
185     BOOST_CHECK(IsStandardTx(CTransaction(txFrom), reason));
186 
187     CMutableTransaction txTo[4]; // Spending transactions
188     for (int i = 0; i < 4; i++)
189     {
190         txTo[i].vin.resize(1);
191         txTo[i].vout.resize(1);
192         txTo[i].vin[0].prevout.n = i;
193         txTo[i].vin[0].prevout.hash = txFrom.GetHash();
194         txTo[i].vout[0].nValue = 1*CENT;
195         txTo[i].vout[0].scriptPubKey = inner[i];
196     }
197     for (int i = 0; i < 4; i++)
198     {
199         BOOST_CHECK_MESSAGE(SignSignature(keystore, CTransaction(txFrom), txTo[i], 0, SIGHASH_ALL), strprintf("SignSignature %d", i));
200         BOOST_CHECK_MESSAGE(IsStandardTx(CTransaction(txTo[i]), reason), strprintf("txTo[%d].IsStandard", i));
201     }
202 }
203 
BOOST_AUTO_TEST_CASE(is)204 BOOST_AUTO_TEST_CASE(is)
205 {
206     // Test CScript::IsPayToScriptHash()
207     uint160 dummy;
208     CScript p2sh;
209     p2sh << OP_HASH160 << ToByteVector(dummy) << OP_EQUAL;
210     BOOST_CHECK(p2sh.IsPayToScriptHash());
211 
212     std::vector<unsigned char> direct = {OP_HASH160, 20};
213     direct.insert(direct.end(), 20, 0);
214     direct.push_back(OP_EQUAL);
215     BOOST_CHECK(CScript(direct.begin(), direct.end()).IsPayToScriptHash());
216 
217     // Not considered pay-to-script-hash if using one of the OP_PUSHDATA opcodes:
218     std::vector<unsigned char> pushdata1 = {OP_HASH160, OP_PUSHDATA1, 20};
219     pushdata1.insert(pushdata1.end(), 20, 0);
220     pushdata1.push_back(OP_EQUAL);
221     BOOST_CHECK(!CScript(pushdata1.begin(), pushdata1.end()).IsPayToScriptHash());
222     std::vector<unsigned char> pushdata2 = {OP_HASH160, OP_PUSHDATA2, 20, 0};
223     pushdata2.insert(pushdata2.end(), 20, 0);
224     pushdata2.push_back(OP_EQUAL);
225     BOOST_CHECK(!CScript(pushdata2.begin(), pushdata2.end()).IsPayToScriptHash());
226     std::vector<unsigned char> pushdata4 = {OP_HASH160, OP_PUSHDATA4, 20, 0, 0, 0};
227     pushdata4.insert(pushdata4.end(), 20, 0);
228     pushdata4.push_back(OP_EQUAL);
229     BOOST_CHECK(!CScript(pushdata4.begin(), pushdata4.end()).IsPayToScriptHash());
230 
231     CScript not_p2sh;
232     BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
233 
234     not_p2sh.clear(); not_p2sh << OP_HASH160 << ToByteVector(dummy) << ToByteVector(dummy) << OP_EQUAL;
235     BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
236 
237     not_p2sh.clear(); not_p2sh << OP_NOP << ToByteVector(dummy) << OP_EQUAL;
238     BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
239 
240     not_p2sh.clear(); not_p2sh << OP_HASH160 << ToByteVector(dummy) << OP_CHECKSIG;
241     BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
242 }
243 
BOOST_AUTO_TEST_CASE(switchover)244 BOOST_AUTO_TEST_CASE(switchover)
245 {
246     // Test switch over code
247     CScript notValid;
248     ScriptError err;
249     notValid << OP_11 << OP_12 << OP_EQUALVERIFY;
250     CScript scriptSig;
251     scriptSig << Serialize(notValid);
252 
253     CScript fund = GetScriptForDestination(ScriptHash(notValid));
254 
255 
256     // Validation should succeed under old rules (hash is correct):
257     BOOST_CHECK(Verify(scriptSig, fund, false, err));
258     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
259     // Fail under new:
260     BOOST_CHECK(!Verify(scriptSig, fund, true, err));
261     BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EQUALVERIFY, ScriptErrorString(err));
262 }
263 
BOOST_AUTO_TEST_CASE(AreInputsStandard)264 BOOST_AUTO_TEST_CASE(AreInputsStandard)
265 {
266     LOCK(cs_main);
267     CCoinsView coinsDummy;
268     CCoinsViewCache coins(&coinsDummy);
269     FillableSigningProvider keystore;
270     CKey key[6];
271     std::vector<CPubKey> keys;
272     for (int i = 0; i < 6; i++)
273     {
274         key[i].MakeNewKey(true);
275         BOOST_CHECK(keystore.AddKey(key[i]));
276     }
277     for (int i = 0; i < 3; i++)
278         keys.push_back(key[i].GetPubKey());
279 
280     CMutableTransaction txFrom;
281     txFrom.vout.resize(7);
282 
283     // First three are standard:
284     CScript pay1 = GetScriptForDestination(PKHash(key[0].GetPubKey()));
285     BOOST_CHECK(keystore.AddCScript(pay1));
286     CScript pay1of3 = GetScriptForMultisig(1, keys);
287 
288     txFrom.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(pay1)); // P2SH (OP_CHECKSIG)
289     txFrom.vout[0].nValue = 1000;
290     txFrom.vout[1].scriptPubKey = pay1; // ordinary OP_CHECKSIG
291     txFrom.vout[1].nValue = 2000;
292     txFrom.vout[2].scriptPubKey = pay1of3; // ordinary OP_CHECKMULTISIG
293     txFrom.vout[2].nValue = 3000;
294 
295     // vout[3] is complicated 1-of-3 AND 2-of-3
296     // ... that is OK if wrapped in P2SH:
297     CScript oneAndTwo;
298     oneAndTwo << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey());
299     oneAndTwo << OP_3 << OP_CHECKMULTISIGVERIFY;
300     oneAndTwo << OP_2 << ToByteVector(key[3].GetPubKey()) << ToByteVector(key[4].GetPubKey()) << ToByteVector(key[5].GetPubKey());
301     oneAndTwo << OP_3 << OP_CHECKMULTISIG;
302     BOOST_CHECK(keystore.AddCScript(oneAndTwo));
303     txFrom.vout[3].scriptPubKey = GetScriptForDestination(ScriptHash(oneAndTwo));
304     txFrom.vout[3].nValue = 4000;
305 
306     // vout[4] is max sigops:
307     CScript fifteenSigops; fifteenSigops << OP_1;
308     for (unsigned i = 0; i < MAX_P2SH_SIGOPS; i++)
309         fifteenSigops << ToByteVector(key[i%3].GetPubKey());
310     fifteenSigops << OP_15 << OP_CHECKMULTISIG;
311     BOOST_CHECK(keystore.AddCScript(fifteenSigops));
312     txFrom.vout[4].scriptPubKey = GetScriptForDestination(ScriptHash(fifteenSigops));
313     txFrom.vout[4].nValue = 5000;
314 
315     // vout[5/6] are non-standard because they exceed MAX_P2SH_SIGOPS
316     CScript sixteenSigops; sixteenSigops << OP_16 << OP_CHECKMULTISIG;
317     BOOST_CHECK(keystore.AddCScript(sixteenSigops));
318     txFrom.vout[5].scriptPubKey = GetScriptForDestination(ScriptHash(sixteenSigops));
319     txFrom.vout[5].nValue = 5000;
320     CScript twentySigops; twentySigops << OP_CHECKMULTISIG;
321     BOOST_CHECK(keystore.AddCScript(twentySigops));
322     txFrom.vout[6].scriptPubKey = GetScriptForDestination(ScriptHash(twentySigops));
323     txFrom.vout[6].nValue = 6000;
324 
325     AddCoins(coins, CTransaction(txFrom), 0);
326 
327     CMutableTransaction txTo;
328     txTo.vout.resize(1);
329     txTo.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key[1].GetPubKey()));
330 
331     txTo.vin.resize(5);
332     for (int i = 0; i < 5; i++)
333     {
334         txTo.vin[i].prevout.n = i;
335         txTo.vin[i].prevout.hash = txFrom.GetHash();
336     }
337     BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL));
338     BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 1, SIGHASH_ALL));
339     BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 2, SIGHASH_ALL));
340     // SignSignature doesn't know how to sign these. We're
341     // not testing validating signatures, so just create
342     // dummy signatures that DO include the correct P2SH scripts:
343     txTo.vin[3].scriptSig << OP_11 << OP_11 << std::vector<unsigned char>(oneAndTwo.begin(), oneAndTwo.end());
344     txTo.vin[4].scriptSig << std::vector<unsigned char>(fifteenSigops.begin(), fifteenSigops.end());
345 
346     BOOST_CHECK(::AreInputsStandard(CTransaction(txTo), coins, false));
347     // 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4]
348     BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(txTo), coins), 22U);
349 
350     CMutableTransaction txToNonStd1;
351     txToNonStd1.vout.resize(1);
352     txToNonStd1.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key[1].GetPubKey()));
353     txToNonStd1.vout[0].nValue = 1000;
354     txToNonStd1.vin.resize(1);
355     txToNonStd1.vin[0].prevout.n = 5;
356     txToNonStd1.vin[0].prevout.hash = txFrom.GetHash();
357     txToNonStd1.vin[0].scriptSig << std::vector<unsigned char>(sixteenSigops.begin(), sixteenSigops.end());
358 
359     BOOST_CHECK(!::AreInputsStandard(CTransaction(txToNonStd1), coins, false));
360     BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(txToNonStd1), coins), 16U);
361 
362     CMutableTransaction txToNonStd2;
363     txToNonStd2.vout.resize(1);
364     txToNonStd2.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key[1].GetPubKey()));
365     txToNonStd2.vout[0].nValue = 1000;
366     txToNonStd2.vin.resize(1);
367     txToNonStd2.vin[0].prevout.n = 6;
368     txToNonStd2.vin[0].prevout.hash = txFrom.GetHash();
369     txToNonStd2.vin[0].scriptSig << std::vector<unsigned char>(twentySigops.begin(), twentySigops.end());
370 
371     BOOST_CHECK(!::AreInputsStandard(CTransaction(txToNonStd2), coins, false));
372     BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(txToNonStd2), coins), 20U);
373 }
374 
375 BOOST_AUTO_TEST_SUITE_END()
376