OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / txscript / engine_test.go
1 // Copyright (c) 2013-2017 The btcsuite developers
2 // Use of this source code is governed by an ISC
3 // license that can be found in the LICENSE file.
4
5 package txscript
6
7 import (
8         "testing"
9
10         "github.com/btcsuite/btcd/chaincfg/chainhash"
11         "github.com/btcsuite/btcd/wire"
12 )
13
14 // TestBadPC sets the pc to a deliberately bad result then confirms that Step()
15 // and Disasm fail correctly.
16 func TestBadPC(t *testing.T) {
17         t.Parallel()
18
19         tests := []struct {
20                 script, off int
21         }{
22                 {script: 2, off: 0},
23                 {script: 0, off: 2},
24         }
25
26         // tx with almost empty scripts.
27         tx := &wire.MsgTx{
28                 Version: 1,
29                 TxIn: []*wire.TxIn{
30                         {
31                                 PreviousOutPoint: wire.OutPoint{
32                                         Hash: chainhash.Hash([32]byte{
33                                                 0xc9, 0x97, 0xa5, 0xe5,
34                                                 0x6e, 0x10, 0x41, 0x02,
35                                                 0xfa, 0x20, 0x9c, 0x6a,
36                                                 0x85, 0x2d, 0xd9, 0x06,
37                                                 0x60, 0xa2, 0x0b, 0x2d,
38                                                 0x9c, 0x35, 0x24, 0x23,
39                                                 0xed, 0xce, 0x25, 0x85,
40                                                 0x7f, 0xcd, 0x37, 0x04,
41                                         }),
42                                         Index: 0,
43                                 },
44                                 SignatureScript: mustParseShortForm("NOP"),
45                                 Sequence:        4294967295,
46                         },
47                 },
48                 TxOut: []*wire.TxOut{{
49                         Value:    1000000000,
50                         PkScript: nil,
51                 }},
52                 LockTime: 0,
53         }
54         pkScript := mustParseShortForm("NOP")
55
56         for _, test := range tests {
57                 vm, err := NewEngine(pkScript, tx, 0, 0, nil, nil, -1)
58                 if err != nil {
59                         t.Errorf("Failed to create script: %v", err)
60                 }
61
62                 // set to after all scripts
63                 vm.scriptIdx = test.script
64                 vm.scriptOff = test.off
65
66                 _, err = vm.Step()
67                 if err == nil {
68                         t.Errorf("Step with invalid pc (%v) succeeds!", test)
69                         continue
70                 }
71
72                 _, err = vm.DisasmPC()
73                 if err == nil {
74                         t.Errorf("DisasmPC with invalid pc (%v) succeeds!",
75                                 test)
76                 }
77         }
78 }
79
80 // TestCheckErrorCondition tests the execute early test in CheckErrorCondition()
81 // since most code paths are tested elsewhere.
82 func TestCheckErrorCondition(t *testing.T) {
83         t.Parallel()
84
85         // tx with almost empty scripts.
86         tx := &wire.MsgTx{
87                 Version: 1,
88                 TxIn: []*wire.TxIn{{
89                         PreviousOutPoint: wire.OutPoint{
90                                 Hash: chainhash.Hash([32]byte{
91                                         0xc9, 0x97, 0xa5, 0xe5,
92                                         0x6e, 0x10, 0x41, 0x02,
93                                         0xfa, 0x20, 0x9c, 0x6a,
94                                         0x85, 0x2d, 0xd9, 0x06,
95                                         0x60, 0xa2, 0x0b, 0x2d,
96                                         0x9c, 0x35, 0x24, 0x23,
97                                         0xed, 0xce, 0x25, 0x85,
98                                         0x7f, 0xcd, 0x37, 0x04,
99                                 }),
100                                 Index: 0,
101                         },
102                         SignatureScript: nil,
103                         Sequence:        4294967295,
104                 }},
105                 TxOut: []*wire.TxOut{{
106                         Value:    1000000000,
107                         PkScript: nil,
108                 }},
109                 LockTime: 0,
110         }
111         pkScript := mustParseShortForm("NOP NOP NOP NOP NOP NOP NOP NOP NOP" +
112                 " NOP TRUE")
113
114         vm, err := NewEngine(pkScript, tx, 0, 0, nil, nil, 0)
115         if err != nil {
116                 t.Errorf("failed to create script: %v", err)
117         }
118
119         for i := 0; i < len(pkScript)-1; i++ {
120                 done, err := vm.Step()
121                 if err != nil {
122                         t.Fatalf("failed to step %dth time: %v", i, err)
123                 }
124                 if done {
125                         t.Fatalf("finshed early on %dth time", i)
126                 }
127
128                 err = vm.CheckErrorCondition(false)
129                 if !IsErrorCode(err, ErrScriptUnfinished) {
130                         t.Fatalf("got unexepected error %v on %dth iteration",
131                                 err, i)
132                 }
133         }
134         done, err := vm.Step()
135         if err != nil {
136                 t.Fatalf("final step failed %v", err)
137         }
138         if !done {
139                 t.Fatalf("final step isn't done!")
140         }
141
142         err = vm.CheckErrorCondition(false)
143         if err != nil {
144                 t.Errorf("unexpected error %v on final check", err)
145         }
146 }
147
148 // TestInvalidFlagCombinations ensures the script engine returns the expected
149 // error when disallowed flag combinations are specified.
150 func TestInvalidFlagCombinations(t *testing.T) {
151         t.Parallel()
152
153         tests := []ScriptFlags{
154                 ScriptVerifyCleanStack,
155         }
156
157         // tx with almost empty scripts.
158         tx := &wire.MsgTx{
159                 Version: 1,
160                 TxIn: []*wire.TxIn{
161                         {
162                                 PreviousOutPoint: wire.OutPoint{
163                                         Hash: chainhash.Hash([32]byte{
164                                                 0xc9, 0x97, 0xa5, 0xe5,
165                                                 0x6e, 0x10, 0x41, 0x02,
166                                                 0xfa, 0x20, 0x9c, 0x6a,
167                                                 0x85, 0x2d, 0xd9, 0x06,
168                                                 0x60, 0xa2, 0x0b, 0x2d,
169                                                 0x9c, 0x35, 0x24, 0x23,
170                                                 0xed, 0xce, 0x25, 0x85,
171                                                 0x7f, 0xcd, 0x37, 0x04,
172                                         }),
173                                         Index: 0,
174                                 },
175                                 SignatureScript: []uint8{OP_NOP},
176                                 Sequence:        4294967295,
177                         },
178                 },
179                 TxOut: []*wire.TxOut{
180                         {
181                                 Value:    1000000000,
182                                 PkScript: nil,
183                         },
184                 },
185                 LockTime: 0,
186         }
187         pkScript := []byte{OP_NOP}
188
189         for i, test := range tests {
190                 _, err := NewEngine(pkScript, tx, 0, test, nil, nil, -1)
191                 if !IsErrorCode(err, ErrInvalidFlags) {
192                         t.Fatalf("TestInvalidFlagCombinations #%d unexpected "+
193                                 "error: %v", i, err)
194                 }
195         }
196 }
197
198 // TestCheckPubKeyEncoding ensures the internal checkPubKeyEncoding function
199 // works as expected.
200 func TestCheckPubKeyEncoding(t *testing.T) {
201         t.Parallel()
202
203         tests := []struct {
204                 name    string
205                 key     []byte
206                 isValid bool
207         }{
208                 {
209                         name: "uncompressed ok",
210                         key: hexToBytes("0411db93e1dcdb8a016b49840f8c53bc1eb68" +
211                                 "a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf" +
212                                 "9744464f82e160bfa9b8b64f9d4c03f999b8643f656b" +
213                                 "412a3"),
214                         isValid: true,
215                 },
216                 {
217                         name: "compressed ok",
218                         key: hexToBytes("02ce0b14fb842b1ba549fdd675c98075f12e9" +
219                                 "c510f8ef52bd021a9a1f4809d3b4d"),
220                         isValid: true,
221                 },
222                 {
223                         name: "compressed ok",
224                         key: hexToBytes("032689c7c2dab13309fb143e0e8fe39634252" +
225                                 "1887e976690b6b47f5b2a4b7d448e"),
226                         isValid: true,
227                 },
228                 {
229                         name: "hybrid",
230                         key: hexToBytes("0679be667ef9dcbbac55a06295ce870b07029" +
231                                 "bfcdb2dce28d959f2815b16f81798483ada7726a3c46" +
232                                 "55da4fbfc0e1108a8fd17b448a68554199c47d08ffb1" +
233                                 "0d4b8"),
234                         isValid: false,
235                 },
236                 {
237                         name:    "empty",
238                         key:     nil,
239                         isValid: false,
240                 },
241         }
242
243         vm := Engine{flags: ScriptVerifyStrictEncoding}
244         for _, test := range tests {
245                 err := vm.checkPubKeyEncoding(test.key)
246                 if err != nil && test.isValid {
247                         t.Errorf("checkSignatureEncoding test '%s' failed "+
248                                 "when it should have succeeded: %v", test.name,
249                                 err)
250                 } else if err == nil && !test.isValid {
251                         t.Errorf("checkSignatureEncooding test '%s' succeeded "+
252                                 "when it should have failed", test.name)
253                 }
254         }
255
256 }
257
258 // TestCheckSignatureEncoding ensures the internal checkSignatureEncoding
259 // function works as expected.
260 func TestCheckSignatureEncoding(t *testing.T) {
261         t.Parallel()
262
263         tests := []struct {
264                 name    string
265                 sig     []byte
266                 isValid bool
267         }{
268                 {
269                         name: "valid signature",
270                         sig: hexToBytes("304402204e45e16932b8af514961a1d3a1a25" +
271                                 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
272                                 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
273                                 "82221a8768d1d09"),
274                         isValid: true,
275                 },
276                 {
277                         name:    "empty.",
278                         sig:     nil,
279                         isValid: false,
280                 },
281                 {
282                         name: "bad magic",
283                         sig: hexToBytes("314402204e45e16932b8af514961a1d3a1a25" +
284                                 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
285                                 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
286                                 "82221a8768d1d09"),
287                         isValid: false,
288                 },
289                 {
290                         name: "bad 1st int marker magic",
291                         sig: hexToBytes("304403204e45e16932b8af514961a1d3a1a25" +
292                                 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
293                                 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
294                                 "82221a8768d1d09"),
295                         isValid: false,
296                 },
297                 {
298                         name: "bad 2nd int marker",
299                         sig: hexToBytes("304402204e45e16932b8af514961a1d3a1a25" +
300                                 "fdf3f4f7732e9d624c6c61548ab5fb8cd41032018152" +
301                                 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
302                                 "82221a8768d1d09"),
303                         isValid: false,
304                 },
305                 {
306                         name: "short len",
307                         sig: hexToBytes("304302204e45e16932b8af514961a1d3a1a25" +
308                                 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
309                                 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
310                                 "82221a8768d1d09"),
311                         isValid: false,
312                 },
313                 {
314                         name: "long len",
315                         sig: hexToBytes("304502204e45e16932b8af514961a1d3a1a25" +
316                                 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
317                                 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
318                                 "82221a8768d1d09"),
319                         isValid: false,
320                 },
321                 {
322                         name: "long X",
323                         sig: hexToBytes("304402424e45e16932b8af514961a1d3a1a25" +
324                                 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
325                                 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
326                                 "82221a8768d1d09"),
327                         isValid: false,
328                 },
329                 {
330                         name: "long Y",
331                         sig: hexToBytes("304402204e45e16932b8af514961a1d3a1a25" +
332                                 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022118152" +
333                                 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
334                                 "82221a8768d1d09"),
335                         isValid: false,
336                 },
337                 {
338                         name: "short Y",
339                         sig: hexToBytes("304402204e45e16932b8af514961a1d3a1a25" +
340                                 "fdf3f4f7732e9d624c6c61548ab5fb8cd41021918152" +
341                                 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
342                                 "82221a8768d1d09"),
343                         isValid: false,
344                 },
345                 {
346                         name: "trailing crap",
347                         sig: hexToBytes("304402204e45e16932b8af514961a1d3a1a25" +
348                                 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
349                                 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
350                                 "82221a8768d1d0901"),
351                         isValid: false,
352                 },
353                 {
354                         name: "X == N ",
355                         sig: hexToBytes("30440220fffffffffffffffffffffffffffff" +
356                                 "ffebaaedce6af48a03bbfd25e8cd0364141022018152" +
357                                 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
358                                 "82221a8768d1d09"),
359                         isValid: false,
360                 },
361                 {
362                         name: "X == N ",
363                         sig: hexToBytes("30440220fffffffffffffffffffffffffffff" +
364                                 "ffebaaedce6af48a03bbfd25e8cd0364142022018152" +
365                                 "2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
366                                 "82221a8768d1d09"),
367                         isValid: false,
368                 },
369                 {
370                         name: "Y == N",
371                         sig: hexToBytes("304402204e45e16932b8af514961a1d3a1a25" +
372                                 "fdf3f4f7732e9d624c6c61548ab5fb8cd410220fffff" +
373                                 "ffffffffffffffffffffffffffebaaedce6af48a03bb" +
374                                 "fd25e8cd0364141"),
375                         isValid: false,
376                 },
377                 {
378                         name: "Y > N",
379                         sig: hexToBytes("304402204e45e16932b8af514961a1d3a1a25" +
380                                 "fdf3f4f7732e9d624c6c61548ab5fb8cd410220fffff" +
381                                 "ffffffffffffffffffffffffffebaaedce6af48a03bb" +
382                                 "fd25e8cd0364142"),
383                         isValid: false,
384                 },
385                 {
386                         name: "0 len X",
387                         sig: hexToBytes("302402000220181522ec8eca07de4860a4acd" +
388                                 "d12909d831cc56cbbac4622082221a8768d1d09"),
389                         isValid: false,
390                 },
391                 {
392                         name: "0 len Y",
393                         sig: hexToBytes("302402204e45e16932b8af514961a1d3a1a25" +
394                                 "fdf3f4f7732e9d624c6c61548ab5fb8cd410200"),
395                         isValid: false,
396                 },
397                 {
398                         name: "extra R padding",
399                         sig: hexToBytes("30450221004e45e16932b8af514961a1d3a1a" +
400                                 "25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181" +
401                                 "522ec8eca07de4860a4acdd12909d831cc56cbbac462" +
402                                 "2082221a8768d1d09"),
403                         isValid: false,
404                 },
405                 {
406                         name: "extra S padding",
407                         sig: hexToBytes("304502204e45e16932b8af514961a1d3a1a25" +
408                                 "fdf3f4f7732e9d624c6c61548ab5fb8cd41022100181" +
409                                 "522ec8eca07de4860a4acdd12909d831cc56cbbac462" +
410                                 "2082221a8768d1d09"),
411                         isValid: false,
412                 },
413         }
414
415         vm := Engine{flags: ScriptVerifyStrictEncoding}
416         for _, test := range tests {
417                 err := vm.checkSignatureEncoding(test.sig)
418                 if err != nil && test.isValid {
419                         t.Errorf("checkSignatureEncoding test '%s' failed "+
420                                 "when it should have succeeded: %v", test.name,
421                                 err)
422                 } else if err == nil && !test.isValid {
423                         t.Errorf("checkSignatureEncooding test '%s' succeeded "+
424                                 "when it should have failed", test.name)
425                 }
426         }
427 }