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