OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / txscript / opcode_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         "bytes"
9         "fmt"
10         "strconv"
11         "strings"
12         "testing"
13 )
14
15 // TestOpcodeDisabled tests the opcodeDisabled function manually because all
16 // disabled opcodes result in a script execution failure when executed normally,
17 // so the function is not called under normal circumstances.
18 func TestOpcodeDisabled(t *testing.T) {
19         t.Parallel()
20
21         tests := []byte{OP_CAT, OP_SUBSTR, OP_LEFT, OP_RIGHT, OP_INVERT,
22                 OP_AND, OP_OR, OP_2MUL, OP_2DIV, OP_MUL, OP_DIV, OP_MOD,
23                 OP_LSHIFT, OP_RSHIFT,
24         }
25         for _, opcodeVal := range tests {
26                 pop := parsedOpcode{opcode: &opcodeArray[opcodeVal], data: nil}
27                 err := opcodeDisabled(&pop, nil)
28                 if !IsErrorCode(err, ErrDisabledOpcode) {
29                         t.Errorf("opcodeDisabled: unexpected error - got %v, "+
30                                 "want %v", err, ErrDisabledOpcode)
31                         continue
32                 }
33         }
34 }
35
36 // TestOpcodeDisasm tests the print function for all opcodes in both the oneline
37 // and full modes to ensure it provides the expected disassembly.
38 func TestOpcodeDisasm(t *testing.T) {
39         t.Parallel()
40
41         // First, test the oneline disassembly.
42
43         // The expected strings for the data push opcodes are replaced in the
44         // test loops below since they involve repeating bytes.  Also, the
45         // OP_NOP# and OP_UNKNOWN# are replaced below too, since it's easier
46         // than manually listing them here.
47         oneBytes := []byte{0x01}
48         oneStr := "01"
49         expectedStrings := [256]string{0x00: "0", 0x4f: "-1",
50                 0x50: "OP_RESERVED", 0x61: "OP_NOP", 0x62: "OP_VER",
51                 0x63: "OP_IF", 0x64: "OP_NOTIF", 0x65: "OP_VERIF",
52                 0x66: "OP_VERNOTIF", 0x67: "OP_ELSE", 0x68: "OP_ENDIF",
53                 0x69: "OP_VERIFY", 0x6a: "OP_RETURN", 0x6b: "OP_TOALTSTACK",
54                 0x6c: "OP_FROMALTSTACK", 0x6d: "OP_2DROP", 0x6e: "OP_2DUP",
55                 0x6f: "OP_3DUP", 0x70: "OP_2OVER", 0x71: "OP_2ROT",
56                 0x72: "OP_2SWAP", 0x73: "OP_IFDUP", 0x74: "OP_DEPTH",
57                 0x75: "OP_DROP", 0x76: "OP_DUP", 0x77: "OP_NIP",
58                 0x78: "OP_OVER", 0x79: "OP_PICK", 0x7a: "OP_ROLL",
59                 0x7b: "OP_ROT", 0x7c: "OP_SWAP", 0x7d: "OP_TUCK",
60                 0x7e: "OP_CAT", 0x7f: "OP_SUBSTR", 0x80: "OP_LEFT",
61                 0x81: "OP_RIGHT", 0x82: "OP_SIZE", 0x83: "OP_INVERT",
62                 0x84: "OP_AND", 0x85: "OP_OR", 0x86: "OP_XOR",
63                 0x87: "OP_EQUAL", 0x88: "OP_EQUALVERIFY", 0x89: "OP_RESERVED1",
64                 0x8a: "OP_RESERVED2", 0x8b: "OP_1ADD", 0x8c: "OP_1SUB",
65                 0x8d: "OP_2MUL", 0x8e: "OP_2DIV", 0x8f: "OP_NEGATE",
66                 0x90: "OP_ABS", 0x91: "OP_NOT", 0x92: "OP_0NOTEQUAL",
67                 0x93: "OP_ADD", 0x94: "OP_SUB", 0x95: "OP_MUL", 0x96: "OP_DIV",
68                 0x97: "OP_MOD", 0x98: "OP_LSHIFT", 0x99: "OP_RSHIFT",
69                 0x9a: "OP_BOOLAND", 0x9b: "OP_BOOLOR", 0x9c: "OP_NUMEQUAL",
70                 0x9d: "OP_NUMEQUALVERIFY", 0x9e: "OP_NUMNOTEQUAL",
71                 0x9f: "OP_LESSTHAN", 0xa0: "OP_GREATERTHAN",
72                 0xa1: "OP_LESSTHANOREQUAL", 0xa2: "OP_GREATERTHANOREQUAL",
73                 0xa3: "OP_MIN", 0xa4: "OP_MAX", 0xa5: "OP_WITHIN",
74                 0xa6: "OP_RIPEMD160", 0xa7: "OP_SHA1", 0xa8: "OP_SHA256",
75                 0xa9: "OP_HASH160", 0xaa: "OP_HASH256", 0xab: "OP_CODESEPARATOR",
76                 0xac: "OP_CHECKSIG", 0xad: "OP_CHECKSIGVERIFY",
77                 0xae: "OP_CHECKMULTISIG", 0xaf: "OP_CHECKMULTISIGVERIFY",
78                 0xfa: "OP_SMALLINTEGER", 0xfb: "OP_PUBKEYS",
79                 0xfd: "OP_PUBKEYHASH", 0xfe: "OP_PUBKEY",
80                 0xff: "OP_INVALIDOPCODE",
81         }
82         for opcodeVal, expectedStr := range expectedStrings {
83                 var data []byte
84                 switch {
85                 // OP_DATA_1 through OP_DATA_65 display the pushed data.
86                 case opcodeVal >= 0x01 && opcodeVal < 0x4c:
87                         data = bytes.Repeat(oneBytes, opcodeVal)
88                         expectedStr = strings.Repeat(oneStr, opcodeVal)
89
90                 // OP_PUSHDATA1.
91                 case opcodeVal == 0x4c:
92                         data = bytes.Repeat(oneBytes, 1)
93                         expectedStr = strings.Repeat(oneStr, 1)
94
95                 // OP_PUSHDATA2.
96                 case opcodeVal == 0x4d:
97                         data = bytes.Repeat(oneBytes, 2)
98                         expectedStr = strings.Repeat(oneStr, 2)
99
100                 // OP_PUSHDATA4.
101                 case opcodeVal == 0x4e:
102                         data = bytes.Repeat(oneBytes, 3)
103                         expectedStr = strings.Repeat(oneStr, 3)
104
105                 // OP_1 through OP_16 display the numbers themselves.
106                 case opcodeVal >= 0x51 && opcodeVal <= 0x60:
107                         val := byte(opcodeVal - (0x51 - 1))
108                         data = []byte{val}
109                         expectedStr = strconv.Itoa(int(val))
110
111                 // OP_NOP1 through OP_NOP10.
112                 case opcodeVal >= 0xb0 && opcodeVal <= 0xb9:
113                         switch opcodeVal {
114                         case 0xb1:
115                                 // OP_NOP2 is an alias of OP_CHECKLOCKTIMEVERIFY
116                                 expectedStr = "OP_CHECKLOCKTIMEVERIFY"
117                         case 0xb2:
118                                 // OP_NOP3 is an alias of OP_CHECKSEQUENCEVERIFY
119                                 expectedStr = "OP_CHECKSEQUENCEVERIFY"
120                         default:
121                                 val := byte(opcodeVal - (0xb0 - 1))
122                                 expectedStr = "OP_NOP" + strconv.Itoa(int(val))
123                         }
124
125                 // OP_UNKNOWN#.
126                 case opcodeVal >= 0xba && opcodeVal <= 0xf9 || opcodeVal == 0xfc:
127                         expectedStr = "OP_UNKNOWN" + strconv.Itoa(int(opcodeVal))
128                 }
129
130                 pop := parsedOpcode{opcode: &opcodeArray[opcodeVal], data: data}
131                 gotStr := pop.print(true)
132                 if gotStr != expectedStr {
133                         t.Errorf("pop.print (opcode %x): Unexpected disasm "+
134                                 "string - got %v, want %v", opcodeVal, gotStr,
135                                 expectedStr)
136                         continue
137                 }
138         }
139
140         // Now, replace the relevant fields and test the full disassembly.
141         expectedStrings[0x00] = "OP_0"
142         expectedStrings[0x4f] = "OP_1NEGATE"
143         for opcodeVal, expectedStr := range expectedStrings {
144                 var data []byte
145                 switch {
146                 // OP_DATA_1 through OP_DATA_65 display the opcode followed by
147                 // the pushed data.
148                 case opcodeVal >= 0x01 && opcodeVal < 0x4c:
149                         data = bytes.Repeat(oneBytes, opcodeVal)
150                         expectedStr = fmt.Sprintf("OP_DATA_%d 0x%s", opcodeVal,
151                                 strings.Repeat(oneStr, opcodeVal))
152
153                 // OP_PUSHDATA1.
154                 case opcodeVal == 0x4c:
155                         data = bytes.Repeat(oneBytes, 1)
156                         expectedStr = fmt.Sprintf("OP_PUSHDATA1 0x%02x 0x%s",
157                                 len(data), strings.Repeat(oneStr, 1))
158
159                 // OP_PUSHDATA2.
160                 case opcodeVal == 0x4d:
161                         data = bytes.Repeat(oneBytes, 2)
162                         expectedStr = fmt.Sprintf("OP_PUSHDATA2 0x%04x 0x%s",
163                                 len(data), strings.Repeat(oneStr, 2))
164
165                 // OP_PUSHDATA4.
166                 case opcodeVal == 0x4e:
167                         data = bytes.Repeat(oneBytes, 3)
168                         expectedStr = fmt.Sprintf("OP_PUSHDATA4 0x%08x 0x%s",
169                                 len(data), strings.Repeat(oneStr, 3))
170
171                 // OP_1 through OP_16.
172                 case opcodeVal >= 0x51 && opcodeVal <= 0x60:
173                         val := byte(opcodeVal - (0x51 - 1))
174                         data = []byte{val}
175                         expectedStr = "OP_" + strconv.Itoa(int(val))
176
177                 // OP_NOP1 through OP_NOP10.
178                 case opcodeVal >= 0xb0 && opcodeVal <= 0xb9:
179                         switch opcodeVal {
180                         case 0xb1:
181                                 // OP_NOP2 is an alias of OP_CHECKLOCKTIMEVERIFY
182                                 expectedStr = "OP_CHECKLOCKTIMEVERIFY"
183                         case 0xb2:
184                                 // OP_NOP3 is an alias of OP_CHECKSEQUENCEVERIFY
185                                 expectedStr = "OP_CHECKSEQUENCEVERIFY"
186                         default:
187                                 val := byte(opcodeVal - (0xb0 - 1))
188                                 expectedStr = "OP_NOP" + strconv.Itoa(int(val))
189                         }
190
191                 // OP_UNKNOWN#.
192                 case opcodeVal >= 0xba && opcodeVal <= 0xf9 || opcodeVal == 0xfc:
193                         expectedStr = "OP_UNKNOWN" + strconv.Itoa(int(opcodeVal))
194                 }
195
196                 pop := parsedOpcode{opcode: &opcodeArray[opcodeVal], data: data}
197                 gotStr := pop.print(false)
198                 if gotStr != expectedStr {
199                         t.Errorf("pop.print (opcode %x): Unexpected disasm "+
200                                 "string - got %v, want %v", opcodeVal, gotStr,
201                                 expectedStr)
202                         continue
203                 }
204         }
205 }