OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / txscript / scriptbuilder_test.go
1 // Copyright (c) 2013-2016 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         "bytes"
9         "testing"
10 )
11
12 // TestScriptBuilderAddOp tests that pushing opcodes to a script via the
13 // ScriptBuilder API works as expected.
14 func TestScriptBuilderAddOp(t *testing.T) {
15         t.Parallel()
16
17         tests := []struct {
18                 name     string
19                 opcodes  []byte
20                 expected []byte
21         }{
22                 {
23                         name:     "push OP_0",
24                         opcodes:  []byte{OP_0},
25                         expected: []byte{OP_0},
26                 },
27                 {
28                         name:     "push OP_1 OP_2",
29                         opcodes:  []byte{OP_1, OP_2},
30                         expected: []byte{OP_1, OP_2},
31                 },
32                 {
33                         name:     "push OP_HASH160 OP_EQUAL",
34                         opcodes:  []byte{OP_HASH160, OP_EQUAL},
35                         expected: []byte{OP_HASH160, OP_EQUAL},
36                 },
37         }
38
39         // Run tests and individually add each op via AddOp.
40         builder := NewScriptBuilder()
41         t.Logf("Running %d tests", len(tests))
42         for i, test := range tests {
43                 builder.Reset()
44                 for _, opcode := range test.opcodes {
45                         builder.AddOp(opcode)
46                 }
47                 result, err := builder.Script()
48                 if err != nil {
49                         t.Errorf("ScriptBuilder.AddOp #%d (%s) unexpected "+
50                                 "error: %v", i, test.name, err)
51                         continue
52                 }
53                 if !bytes.Equal(result, test.expected) {
54                         t.Errorf("ScriptBuilder.AddOp #%d (%s) wrong result\n"+
55                                 "got: %x\nwant: %x", i, test.name, result,
56                                 test.expected)
57                         continue
58                 }
59         }
60
61         // Run tests and bulk add ops via AddOps.
62         t.Logf("Running %d tests", len(tests))
63         for i, test := range tests {
64                 builder.Reset()
65                 result, err := builder.AddOps(test.opcodes).Script()
66                 if err != nil {
67                         t.Errorf("ScriptBuilder.AddOps #%d (%s) unexpected "+
68                                 "error: %v", i, test.name, err)
69                         continue
70                 }
71                 if !bytes.Equal(result, test.expected) {
72                         t.Errorf("ScriptBuilder.AddOps #%d (%s) wrong result\n"+
73                                 "got: %x\nwant: %x", i, test.name, result,
74                                 test.expected)
75                         continue
76                 }
77         }
78
79 }
80
81 // TestScriptBuilderAddInt64 tests that pushing signed integers to a script via
82 // the ScriptBuilder API works as expected.
83 func TestScriptBuilderAddInt64(t *testing.T) {
84         t.Parallel()
85
86         tests := []struct {
87                 name     string
88                 val      int64
89                 expected []byte
90         }{
91                 {name: "push -1", val: -1, expected: []byte{OP_1NEGATE}},
92                 {name: "push small int 0", val: 0, expected: []byte{OP_0}},
93                 {name: "push small int 1", val: 1, expected: []byte{OP_1}},
94                 {name: "push small int 2", val: 2, expected: []byte{OP_2}},
95                 {name: "push small int 3", val: 3, expected: []byte{OP_3}},
96                 {name: "push small int 4", val: 4, expected: []byte{OP_4}},
97                 {name: "push small int 5", val: 5, expected: []byte{OP_5}},
98                 {name: "push small int 6", val: 6, expected: []byte{OP_6}},
99                 {name: "push small int 7", val: 7, expected: []byte{OP_7}},
100                 {name: "push small int 8", val: 8, expected: []byte{OP_8}},
101                 {name: "push small int 9", val: 9, expected: []byte{OP_9}},
102                 {name: "push small int 10", val: 10, expected: []byte{OP_10}},
103                 {name: "push small int 11", val: 11, expected: []byte{OP_11}},
104                 {name: "push small int 12", val: 12, expected: []byte{OP_12}},
105                 {name: "push small int 13", val: 13, expected: []byte{OP_13}},
106                 {name: "push small int 14", val: 14, expected: []byte{OP_14}},
107                 {name: "push small int 15", val: 15, expected: []byte{OP_15}},
108                 {name: "push small int 16", val: 16, expected: []byte{OP_16}},
109                 {name: "push 17", val: 17, expected: []byte{OP_DATA_1, 0x11}},
110                 {name: "push 65", val: 65, expected: []byte{OP_DATA_1, 0x41}},
111                 {name: "push 127", val: 127, expected: []byte{OP_DATA_1, 0x7f}},
112                 {name: "push 128", val: 128, expected: []byte{OP_DATA_2, 0x80, 0}},
113                 {name: "push 255", val: 255, expected: []byte{OP_DATA_2, 0xff, 0}},
114                 {name: "push 256", val: 256, expected: []byte{OP_DATA_2, 0, 0x01}},
115                 {name: "push 32767", val: 32767, expected: []byte{OP_DATA_2, 0xff, 0x7f}},
116                 {name: "push 32768", val: 32768, expected: []byte{OP_DATA_3, 0, 0x80, 0}},
117                 {name: "push -2", val: -2, expected: []byte{OP_DATA_1, 0x82}},
118                 {name: "push -3", val: -3, expected: []byte{OP_DATA_1, 0x83}},
119                 {name: "push -4", val: -4, expected: []byte{OP_DATA_1, 0x84}},
120                 {name: "push -5", val: -5, expected: []byte{OP_DATA_1, 0x85}},
121                 {name: "push -17", val: -17, expected: []byte{OP_DATA_1, 0x91}},
122                 {name: "push -65", val: -65, expected: []byte{OP_DATA_1, 0xc1}},
123                 {name: "push -127", val: -127, expected: []byte{OP_DATA_1, 0xff}},
124                 {name: "push -128", val: -128, expected: []byte{OP_DATA_2, 0x80, 0x80}},
125                 {name: "push -255", val: -255, expected: []byte{OP_DATA_2, 0xff, 0x80}},
126                 {name: "push -256", val: -256, expected: []byte{OP_DATA_2, 0x00, 0x81}},
127                 {name: "push -32767", val: -32767, expected: []byte{OP_DATA_2, 0xff, 0xff}},
128                 {name: "push -32768", val: -32768, expected: []byte{OP_DATA_3, 0x00, 0x80, 0x80}},
129         }
130
131         builder := NewScriptBuilder()
132         t.Logf("Running %d tests", len(tests))
133         for i, test := range tests {
134                 builder.Reset().AddInt64(test.val)
135                 result, err := builder.Script()
136                 if err != nil {
137                         t.Errorf("ScriptBuilder.AddInt64 #%d (%s) unexpected "+
138                                 "error: %v", i, test.name, err)
139                         continue
140                 }
141                 if !bytes.Equal(result, test.expected) {
142                         t.Errorf("ScriptBuilder.AddInt64 #%d (%s) wrong result\n"+
143                                 "got: %x\nwant: %x", i, test.name, result,
144                                 test.expected)
145                         continue
146                 }
147         }
148 }
149
150 // TestScriptBuilderAddData tests that pushing data to a script via the
151 // ScriptBuilder API works as expected and conforms to BIP0062.
152 func TestScriptBuilderAddData(t *testing.T) {
153         t.Parallel()
154
155         tests := []struct {
156                 name     string
157                 data     []byte
158                 expected []byte
159                 useFull  bool // use AddFullData instead of AddData.
160         }{
161                 // BIP0062: Pushing an empty byte sequence must use OP_0.
162                 {name: "push empty byte sequence", data: nil, expected: []byte{OP_0}},
163                 {name: "push 1 byte 0x00", data: []byte{0x00}, expected: []byte{OP_0}},
164
165                 // BIP0062: Pushing a 1-byte sequence of byte 0x01 through 0x10 must use OP_n.
166                 {name: "push 1 byte 0x01", data: []byte{0x01}, expected: []byte{OP_1}},
167                 {name: "push 1 byte 0x02", data: []byte{0x02}, expected: []byte{OP_2}},
168                 {name: "push 1 byte 0x03", data: []byte{0x03}, expected: []byte{OP_3}},
169                 {name: "push 1 byte 0x04", data: []byte{0x04}, expected: []byte{OP_4}},
170                 {name: "push 1 byte 0x05", data: []byte{0x05}, expected: []byte{OP_5}},
171                 {name: "push 1 byte 0x06", data: []byte{0x06}, expected: []byte{OP_6}},
172                 {name: "push 1 byte 0x07", data: []byte{0x07}, expected: []byte{OP_7}},
173                 {name: "push 1 byte 0x08", data: []byte{0x08}, expected: []byte{OP_8}},
174                 {name: "push 1 byte 0x09", data: []byte{0x09}, expected: []byte{OP_9}},
175                 {name: "push 1 byte 0x0a", data: []byte{0x0a}, expected: []byte{OP_10}},
176                 {name: "push 1 byte 0x0b", data: []byte{0x0b}, expected: []byte{OP_11}},
177                 {name: "push 1 byte 0x0c", data: []byte{0x0c}, expected: []byte{OP_12}},
178                 {name: "push 1 byte 0x0d", data: []byte{0x0d}, expected: []byte{OP_13}},
179                 {name: "push 1 byte 0x0e", data: []byte{0x0e}, expected: []byte{OP_14}},
180                 {name: "push 1 byte 0x0f", data: []byte{0x0f}, expected: []byte{OP_15}},
181                 {name: "push 1 byte 0x10", data: []byte{0x10}, expected: []byte{OP_16}},
182
183                 // BIP0062: Pushing the byte 0x81 must use OP_1NEGATE.
184                 {name: "push 1 byte 0x81", data: []byte{0x81}, expected: []byte{OP_1NEGATE}},
185
186                 // BIP0062: Pushing any other byte sequence up to 75 bytes must
187                 // use the normal data push (opcode byte n, with n the number of
188                 // bytes, followed n bytes of data being pushed).
189                 {name: "push 1 byte 0x11", data: []byte{0x11}, expected: []byte{OP_DATA_1, 0x11}},
190                 {name: "push 1 byte 0x80", data: []byte{0x80}, expected: []byte{OP_DATA_1, 0x80}},
191                 {name: "push 1 byte 0x82", data: []byte{0x82}, expected: []byte{OP_DATA_1, 0x82}},
192                 {name: "push 1 byte 0xff", data: []byte{0xff}, expected: []byte{OP_DATA_1, 0xff}},
193                 {
194                         name:     "push data len 17",
195                         data:     bytes.Repeat([]byte{0x49}, 17),
196                         expected: append([]byte{OP_DATA_17}, bytes.Repeat([]byte{0x49}, 17)...),
197                 },
198                 {
199                         name:     "push data len 75",
200                         data:     bytes.Repeat([]byte{0x49}, 75),
201                         expected: append([]byte{OP_DATA_75}, bytes.Repeat([]byte{0x49}, 75)...),
202                 },
203
204                 // BIP0062: Pushing 76 to 255 bytes must use OP_PUSHDATA1.
205                 {
206                         name:     "push data len 76",
207                         data:     bytes.Repeat([]byte{0x49}, 76),
208                         expected: append([]byte{OP_PUSHDATA1, 76}, bytes.Repeat([]byte{0x49}, 76)...),
209                 },
210                 {
211                         name:     "push data len 255",
212                         data:     bytes.Repeat([]byte{0x49}, 255),
213                         expected: append([]byte{OP_PUSHDATA1, 255}, bytes.Repeat([]byte{0x49}, 255)...),
214                 },
215
216                 // BIP0062: Pushing 256 to 520 bytes must use OP_PUSHDATA2.
217                 {
218                         name:     "push data len 256",
219                         data:     bytes.Repeat([]byte{0x49}, 256),
220                         expected: append([]byte{OP_PUSHDATA2, 0, 1}, bytes.Repeat([]byte{0x49}, 256)...),
221                 },
222                 {
223                         name:     "push data len 520",
224                         data:     bytes.Repeat([]byte{0x49}, 520),
225                         expected: append([]byte{OP_PUSHDATA2, 0x08, 0x02}, bytes.Repeat([]byte{0x49}, 520)...),
226                 },
227
228                 // BIP0062: OP_PUSHDATA4 can never be used, as pushes over 520
229                 // bytes are not allowed, and those below can be done using
230                 // other operators.
231                 {
232                         name:     "push data len 521",
233                         data:     bytes.Repeat([]byte{0x49}, 521),
234                         expected: nil,
235                 },
236                 {
237                         name:     "push data len 32767 (canonical)",
238                         data:     bytes.Repeat([]byte{0x49}, 32767),
239                         expected: nil,
240                 },
241                 {
242                         name:     "push data len 65536 (canonical)",
243                         data:     bytes.Repeat([]byte{0x49}, 65536),
244                         expected: nil,
245                 },
246
247                 // Additional tests for the PushFullData function that
248                 // intentionally allows data pushes to exceed the limit for
249                 // regression testing purposes.
250
251                 // 3-byte data push via OP_PUSHDATA_2.
252                 {
253                         name:     "push data len 32767 (non-canonical)",
254                         data:     bytes.Repeat([]byte{0x49}, 32767),
255                         expected: append([]byte{OP_PUSHDATA2, 255, 127}, bytes.Repeat([]byte{0x49}, 32767)...),
256                         useFull:  true,
257                 },
258
259                 // 5-byte data push via OP_PUSHDATA_4.
260                 {
261                         name:     "push data len 65536 (non-canonical)",
262                         data:     bytes.Repeat([]byte{0x49}, 65536),
263                         expected: append([]byte{OP_PUSHDATA4, 0, 0, 1, 0}, bytes.Repeat([]byte{0x49}, 65536)...),
264                         useFull:  true,
265                 },
266         }
267
268         builder := NewScriptBuilder()
269         t.Logf("Running %d tests", len(tests))
270         for i, test := range tests {
271                 if !test.useFull {
272                         builder.Reset().AddData(test.data)
273                 } else {
274                         builder.Reset().AddFullData(test.data)
275                 }
276                 result, _ := builder.Script()
277                 if !bytes.Equal(result, test.expected) {
278                         t.Errorf("ScriptBuilder.AddData #%d (%s) wrong result\n"+
279                                 "got: %x\nwant: %x", i, test.name, result,
280                                 test.expected)
281                         continue
282                 }
283         }
284 }
285
286 // TestExceedMaxScriptSize ensures that all of the functions that can be used
287 // to add data to a script don't allow the script to exceed the max allowed
288 // size.
289 func TestExceedMaxScriptSize(t *testing.T) {
290         t.Parallel()
291
292         // Start off by constructing a max size script.
293         builder := NewScriptBuilder()
294         builder.Reset().AddFullData(make([]byte, MaxScriptSize-3))
295         origScript, err := builder.Script()
296         if err != nil {
297                 t.Fatalf("Unexpected error for max size script: %v", err)
298         }
299
300         // Ensure adding data that would exceed the maximum size of the script
301         // does not add the data.
302         script, err := builder.AddData([]byte{0x00}).Script()
303         if _, ok := err.(ErrScriptNotCanonical); !ok || err == nil {
304                 t.Fatalf("ScriptBuilder.AddData allowed exceeding max script "+
305                         "size: %v", len(script))
306         }
307         if !bytes.Equal(script, origScript) {
308                 t.Fatalf("ScriptBuilder.AddData unexpected modified script - "+
309                         "got len %d, want len %d", len(script), len(origScript))
310         }
311
312         // Ensure adding an opcode that would exceed the maximum size of the
313         // script does not add the data.
314         builder.Reset().AddFullData(make([]byte, MaxScriptSize-3))
315         script, err = builder.AddOp(OP_0).Script()
316         if _, ok := err.(ErrScriptNotCanonical); !ok || err == nil {
317                 t.Fatalf("ScriptBuilder.AddOp unexpected modified script - "+
318                         "got len %d, want len %d", len(script), len(origScript))
319         }
320         if !bytes.Equal(script, origScript) {
321                 t.Fatalf("ScriptBuilder.AddOp unexpected modified script - "+
322                         "got len %d, want len %d", len(script), len(origScript))
323         }
324
325         // Ensure adding an integer that would exceed the maximum size of the
326         // script does not add the data.
327         builder.Reset().AddFullData(make([]byte, MaxScriptSize-3))
328         script, err = builder.AddInt64(0).Script()
329         if _, ok := err.(ErrScriptNotCanonical); !ok || err == nil {
330                 t.Fatalf("ScriptBuilder.AddInt64 unexpected modified script - "+
331                         "got len %d, want len %d", len(script), len(origScript))
332         }
333         if !bytes.Equal(script, origScript) {
334                 t.Fatalf("ScriptBuilder.AddInt64 unexpected modified script - "+
335                         "got len %d, want len %d", len(script), len(origScript))
336         }
337 }
338
339 // TestErroredScript ensures that all of the functions that can be used to add
340 // data to a script don't modify the script once an error has happened.
341 func TestErroredScript(t *testing.T) {
342         t.Parallel()
343
344         // Start off by constructing a near max size script that has enough
345         // space left to add each data type without an error and force an
346         // initial error condition.
347         builder := NewScriptBuilder()
348         builder.Reset().AddFullData(make([]byte, MaxScriptSize-8))
349         origScript, err := builder.Script()
350         if err != nil {
351                 t.Fatalf("ScriptBuilder.AddFullData unexpected error: %v", err)
352         }
353         script, err := builder.AddData([]byte{0x00, 0x00, 0x00, 0x00, 0x00}).Script()
354         if _, ok := err.(ErrScriptNotCanonical); !ok || err == nil {
355                 t.Fatalf("ScriptBuilder.AddData allowed exceeding max script "+
356                         "size: %v", len(script))
357         }
358         if !bytes.Equal(script, origScript) {
359                 t.Fatalf("ScriptBuilder.AddData unexpected modified script - "+
360                         "got len %d, want len %d", len(script), len(origScript))
361         }
362
363         // Ensure adding data, even using the non-canonical path, to a script
364         // that has errored doesn't succeed.
365         script, err = builder.AddFullData([]byte{0x00}).Script()
366         if _, ok := err.(ErrScriptNotCanonical); !ok || err == nil {
367                 t.Fatal("ScriptBuilder.AddFullData succeeded on errored script")
368         }
369         if !bytes.Equal(script, origScript) {
370                 t.Fatalf("ScriptBuilder.AddFullData unexpected modified "+
371                         "script - got len %d, want len %d", len(script),
372                         len(origScript))
373         }
374
375         // Ensure adding data to a script that has errored doesn't succeed.
376         script, err = builder.AddData([]byte{0x00}).Script()
377         if _, ok := err.(ErrScriptNotCanonical); !ok || err == nil {
378                 t.Fatal("ScriptBuilder.AddData succeeded on errored script")
379         }
380         if !bytes.Equal(script, origScript) {
381                 t.Fatalf("ScriptBuilder.AddData unexpected modified "+
382                         "script - got len %d, want len %d", len(script),
383                         len(origScript))
384         }
385
386         // Ensure adding an opcode to a script that has errored doesn't succeed.
387         script, err = builder.AddOp(OP_0).Script()
388         if _, ok := err.(ErrScriptNotCanonical); !ok || err == nil {
389                 t.Fatal("ScriptBuilder.AddOp succeeded on errored script")
390         }
391         if !bytes.Equal(script, origScript) {
392                 t.Fatalf("ScriptBuilder.AddOp unexpected modified script - "+
393                         "got len %d, want len %d", len(script), len(origScript))
394         }
395
396         // Ensure adding an integer to a script that has errored doesn't
397         // succeed.
398         script, err = builder.AddInt64(0).Script()
399         if _, ok := err.(ErrScriptNotCanonical); !ok || err == nil {
400                 t.Fatal("ScriptBuilder.AddInt64 succeeded on errored script")
401         }
402         if !bytes.Equal(script, origScript) {
403                 t.Fatalf("ScriptBuilder.AddInt64 unexpected modified script - "+
404                         "got len %d, want len %d", len(script), len(origScript))
405         }
406
407         // Ensure the error has a message set.
408         if err.Error() == "" {
409                 t.Fatal("ErrScriptNotCanonical.Error does not have any text")
410         }
411 }