engine_test.go 11 KB

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