scriptnum_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. // Copyright (c) 2015-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. "bytes"
  7. "encoding/hex"
  8. "testing"
  9. "github.com/pkt-cash/pktd/btcutil/er"
  10. "github.com/pkt-cash/pktd/txscript/scriptnum"
  11. "github.com/pkt-cash/pktd/txscript/txscripterr"
  12. )
  13. // hexToBytes converts the passed hex string into bytes and will panic if there
  14. // is an error. This is only provided for the hard-coded constants so errors in
  15. // the source code can be detected. It will only (and must only) be called with
  16. // hard-coded values.
  17. func hexToBytes(s string) []byte {
  18. b, err := hex.DecodeString(s)
  19. if err != nil {
  20. panic("invalid hex in source file: " + s)
  21. }
  22. return b
  23. }
  24. // TestScriptNumBytes ensures that converting from integral script numbers to
  25. // byte representations works as expected.
  26. func TestScriptNumBytes(t *testing.T) {
  27. tests := []struct {
  28. num scriptnum.ScriptNum
  29. serialized []byte
  30. }{
  31. {0, nil},
  32. {1, hexToBytes("01")},
  33. {-1, hexToBytes("81")},
  34. {127, hexToBytes("7f")},
  35. {-127, hexToBytes("ff")},
  36. {128, hexToBytes("8000")},
  37. {-128, hexToBytes("8080")},
  38. {129, hexToBytes("8100")},
  39. {-129, hexToBytes("8180")},
  40. {256, hexToBytes("0001")},
  41. {-256, hexToBytes("0081")},
  42. {32767, hexToBytes("ff7f")},
  43. {-32767, hexToBytes("ffff")},
  44. {32768, hexToBytes("008000")},
  45. {-32768, hexToBytes("008080")},
  46. {65535, hexToBytes("ffff00")},
  47. {-65535, hexToBytes("ffff80")},
  48. {524288, hexToBytes("000008")},
  49. {-524288, hexToBytes("000088")},
  50. {7340032, hexToBytes("000070")},
  51. {-7340032, hexToBytes("0000f0")},
  52. {8388608, hexToBytes("00008000")},
  53. {-8388608, hexToBytes("00008080")},
  54. {2147483647, hexToBytes("ffffff7f")},
  55. {-2147483647, hexToBytes("ffffffff")},
  56. // Values that are out of range for data that is interpreted as
  57. // numbers, but are allowed as the result of numeric operations.
  58. {2147483648, hexToBytes("0000008000")},
  59. {-2147483648, hexToBytes("0000008080")},
  60. {2415919104, hexToBytes("0000009000")},
  61. {-2415919104, hexToBytes("0000009080")},
  62. {4294967295, hexToBytes("ffffffff00")},
  63. {-4294967295, hexToBytes("ffffffff80")},
  64. {4294967296, hexToBytes("0000000001")},
  65. {-4294967296, hexToBytes("0000000081")},
  66. {281474976710655, hexToBytes("ffffffffffff00")},
  67. {-281474976710655, hexToBytes("ffffffffffff80")},
  68. {72057594037927935, hexToBytes("ffffffffffffff00")},
  69. {-72057594037927935, hexToBytes("ffffffffffffff80")},
  70. {9223372036854775807, hexToBytes("ffffffffffffff7f")},
  71. {-9223372036854775807, hexToBytes("ffffffffffffffff")},
  72. }
  73. for _, test := range tests {
  74. gotBytes := test.num.Bytes()
  75. if !bytes.Equal(gotBytes, test.serialized) {
  76. t.Errorf("Bytes: did not get expected bytes for %d - "+
  77. "got %x, want %x", test.num, gotBytes,
  78. test.serialized)
  79. continue
  80. }
  81. }
  82. }
  83. // TestMakeScriptNum ensures that converting from byte representations to
  84. // integral script numbers works as expected.
  85. func TestMakeScriptNum(t *testing.T) {
  86. // Errors used in the tests below defined here for convenience and to
  87. // keep the horizontal test size shorter.
  88. errNumTooBig := txscripterr.ScriptError(txscripterr.ErrNumberTooBig, "")
  89. errMinimalData := txscripterr.ScriptError(txscripterr.ErrMinimalData, "")
  90. tests := []struct {
  91. serialized []byte
  92. num scriptnum.ScriptNum
  93. numLen int
  94. minimalEncoding bool
  95. err er.R
  96. }{
  97. // Minimal encoding must reject negative 0.
  98. {hexToBytes("80"), 0, scriptnum.DefaultScriptNumLen, true, errMinimalData},
  99. // Minimally encoded valid values with minimal encoding flag.
  100. // Should not error and return expected integral number.
  101. {nil, 0, scriptnum.DefaultScriptNumLen, true, nil},
  102. {hexToBytes("01"), 1, scriptnum.DefaultScriptNumLen, true, nil},
  103. {hexToBytes("81"), -1, scriptnum.DefaultScriptNumLen, true, nil},
  104. {hexToBytes("7f"), 127, scriptnum.DefaultScriptNumLen, true, nil},
  105. {hexToBytes("ff"), -127, scriptnum.DefaultScriptNumLen, true, nil},
  106. {hexToBytes("8000"), 128, scriptnum.DefaultScriptNumLen, true, nil},
  107. {hexToBytes("8080"), -128, scriptnum.DefaultScriptNumLen, true, nil},
  108. {hexToBytes("8100"), 129, scriptnum.DefaultScriptNumLen, true, nil},
  109. {hexToBytes("8180"), -129, scriptnum.DefaultScriptNumLen, true, nil},
  110. {hexToBytes("0001"), 256, scriptnum.DefaultScriptNumLen, true, nil},
  111. {hexToBytes("0081"), -256, scriptnum.DefaultScriptNumLen, true, nil},
  112. {hexToBytes("ff7f"), 32767, scriptnum.DefaultScriptNumLen, true, nil},
  113. {hexToBytes("ffff"), -32767, scriptnum.DefaultScriptNumLen, true, nil},
  114. {hexToBytes("008000"), 32768, scriptnum.DefaultScriptNumLen, true, nil},
  115. {hexToBytes("008080"), -32768, scriptnum.DefaultScriptNumLen, true, nil},
  116. {hexToBytes("ffff00"), 65535, scriptnum.DefaultScriptNumLen, true, nil},
  117. {hexToBytes("ffff80"), -65535, scriptnum.DefaultScriptNumLen, true, nil},
  118. {hexToBytes("000008"), 524288, scriptnum.DefaultScriptNumLen, true, nil},
  119. {hexToBytes("000088"), -524288, scriptnum.DefaultScriptNumLen, true, nil},
  120. {hexToBytes("000070"), 7340032, scriptnum.DefaultScriptNumLen, true, nil},
  121. {hexToBytes("0000f0"), -7340032, scriptnum.DefaultScriptNumLen, true, nil},
  122. {hexToBytes("00008000"), 8388608, scriptnum.DefaultScriptNumLen, true, nil},
  123. {hexToBytes("00008080"), -8388608, scriptnum.DefaultScriptNumLen, true, nil},
  124. {hexToBytes("ffffff7f"), 2147483647, scriptnum.DefaultScriptNumLen, true, nil},
  125. {hexToBytes("ffffffff"), -2147483647, scriptnum.DefaultScriptNumLen, true, nil},
  126. {hexToBytes("ffffffff7f"), 549755813887, 5, true, nil},
  127. {hexToBytes("ffffffffff"), -549755813887, 5, true, nil},
  128. {hexToBytes("ffffffffffffff7f"), 9223372036854775807, 8, true, nil},
  129. {hexToBytes("ffffffffffffffff"), -9223372036854775807, 8, true, nil},
  130. {hexToBytes("ffffffffffffffff7f"), -1, 9, true, nil},
  131. {hexToBytes("ffffffffffffffffff"), 1, 9, true, nil},
  132. {hexToBytes("ffffffffffffffffff7f"), -1, 10, true, nil},
  133. {hexToBytes("ffffffffffffffffffff"), 1, 10, true, nil},
  134. // Minimally encoded values that are out of range for data that
  135. // is interpreted as script numbers with the minimal encoding
  136. // flag set. Should error and return 0.
  137. {hexToBytes("0000008000"), 0, scriptnum.DefaultScriptNumLen, true, errNumTooBig},
  138. {hexToBytes("0000008080"), 0, scriptnum.DefaultScriptNumLen, true, errNumTooBig},
  139. {hexToBytes("0000009000"), 0, scriptnum.DefaultScriptNumLen, true, errNumTooBig},
  140. {hexToBytes("0000009080"), 0, scriptnum.DefaultScriptNumLen, true, errNumTooBig},
  141. {hexToBytes("ffffffff00"), 0, scriptnum.DefaultScriptNumLen, true, errNumTooBig},
  142. {hexToBytes("ffffffff80"), 0, scriptnum.DefaultScriptNumLen, true, errNumTooBig},
  143. {hexToBytes("0000000001"), 0, scriptnum.DefaultScriptNumLen, true, errNumTooBig},
  144. {hexToBytes("0000000081"), 0, scriptnum.DefaultScriptNumLen, true, errNumTooBig},
  145. {hexToBytes("ffffffffffff00"), 0, scriptnum.DefaultScriptNumLen, true, errNumTooBig},
  146. {hexToBytes("ffffffffffff80"), 0, scriptnum.DefaultScriptNumLen, true, errNumTooBig},
  147. {hexToBytes("ffffffffffffff00"), 0, scriptnum.DefaultScriptNumLen, true, errNumTooBig},
  148. {hexToBytes("ffffffffffffff80"), 0, scriptnum.DefaultScriptNumLen, true, errNumTooBig},
  149. {hexToBytes("ffffffffffffff7f"), 0, scriptnum.DefaultScriptNumLen, true, errNumTooBig},
  150. {hexToBytes("ffffffffffffffff"), 0, scriptnum.DefaultScriptNumLen, true, errNumTooBig},
  151. // Non-minimally encoded, but otherwise valid values with
  152. // minimal encoding flag. Should error and return 0.
  153. {hexToBytes("00"), 0, scriptnum.DefaultScriptNumLen, true, errMinimalData}, // 0
  154. {hexToBytes("0100"), 0, scriptnum.DefaultScriptNumLen, true, errMinimalData}, // 1
  155. {hexToBytes("7f00"), 0, scriptnum.DefaultScriptNumLen, true, errMinimalData}, // 127
  156. {hexToBytes("800000"), 0, scriptnum.DefaultScriptNumLen, true, errMinimalData}, // 128
  157. {hexToBytes("810000"), 0, scriptnum.DefaultScriptNumLen, true, errMinimalData}, // 129
  158. {hexToBytes("000100"), 0, scriptnum.DefaultScriptNumLen, true, errMinimalData}, // 256
  159. {hexToBytes("ff7f00"), 0, scriptnum.DefaultScriptNumLen, true, errMinimalData}, // 32767
  160. {hexToBytes("00800000"), 0, scriptnum.DefaultScriptNumLen, true, errMinimalData}, // 32768
  161. {hexToBytes("ffff0000"), 0, scriptnum.DefaultScriptNumLen, true, errMinimalData}, // 65535
  162. {hexToBytes("00000800"), 0, scriptnum.DefaultScriptNumLen, true, errMinimalData}, // 524288
  163. {hexToBytes("00007000"), 0, scriptnum.DefaultScriptNumLen, true, errMinimalData}, // 7340032
  164. {hexToBytes("0009000100"), 0, 5, true, errMinimalData}, // 16779520
  165. // Non-minimally encoded, but otherwise valid values without
  166. // minimal encoding flag. Should not error and return expected
  167. // integral number.
  168. {hexToBytes("00"), 0, scriptnum.DefaultScriptNumLen, false, nil},
  169. {hexToBytes("0100"), 1, scriptnum.DefaultScriptNumLen, false, nil},
  170. {hexToBytes("7f00"), 127, scriptnum.DefaultScriptNumLen, false, nil},
  171. {hexToBytes("800000"), 128, scriptnum.DefaultScriptNumLen, false, nil},
  172. {hexToBytes("810000"), 129, scriptnum.DefaultScriptNumLen, false, nil},
  173. {hexToBytes("000100"), 256, scriptnum.DefaultScriptNumLen, false, nil},
  174. {hexToBytes("ff7f00"), 32767, scriptnum.DefaultScriptNumLen, false, nil},
  175. {hexToBytes("00800000"), 32768, scriptnum.DefaultScriptNumLen, false, nil},
  176. {hexToBytes("ffff0000"), 65535, scriptnum.DefaultScriptNumLen, false, nil},
  177. {hexToBytes("00000800"), 524288, scriptnum.DefaultScriptNumLen, false, nil},
  178. {hexToBytes("00007000"), 7340032, scriptnum.DefaultScriptNumLen, false, nil},
  179. {hexToBytes("0009000100"), 16779520, 5, false, nil},
  180. }
  181. for _, test := range tests {
  182. // Ensure the error code is of the expected type and the error
  183. // code matches the value specified in the test instance.
  184. gotNum, err := scriptnum.MakeScriptNum(test.serialized, test.minimalEncoding,
  185. test.numLen)
  186. if e := tstCheckScriptError(err, test.err); e != nil {
  187. t.Errorf("makeScriptNum(%#x): %v", test.serialized, e)
  188. continue
  189. }
  190. if gotNum != test.num {
  191. t.Errorf("makeScriptNum(%#x): did not get expected "+
  192. "number - got %d, want %d", test.serialized,
  193. gotNum, test.num)
  194. continue
  195. }
  196. }
  197. }
  198. // TestScriptNumInt32 ensures that the Int32 function on script number behaves
  199. // as expected.
  200. func TestScriptNumInt32(t *testing.T) {
  201. tests := []struct {
  202. in scriptnum.ScriptNum
  203. want int32
  204. }{
  205. // Values inside the valid int32 range are just the values
  206. // themselves cast to an int32.
  207. {0, 0},
  208. {1, 1},
  209. {-1, -1},
  210. {127, 127},
  211. {-127, -127},
  212. {128, 128},
  213. {-128, -128},
  214. {129, 129},
  215. {-129, -129},
  216. {256, 256},
  217. {-256, -256},
  218. {32767, 32767},
  219. {-32767, -32767},
  220. {32768, 32768},
  221. {-32768, -32768},
  222. {65535, 65535},
  223. {-65535, -65535},
  224. {524288, 524288},
  225. {-524288, -524288},
  226. {7340032, 7340032},
  227. {-7340032, -7340032},
  228. {8388608, 8388608},
  229. {-8388608, -8388608},
  230. {2147483647, 2147483647},
  231. {-2147483647, -2147483647},
  232. {-2147483648, -2147483648},
  233. // Values outside of the valid int32 range are limited to int32.
  234. {2147483648, 2147483647},
  235. {-2147483649, -2147483648},
  236. {1152921504606846975, 2147483647},
  237. {-1152921504606846975, -2147483648},
  238. {2305843009213693951, 2147483647},
  239. {-2305843009213693951, -2147483648},
  240. {4611686018427387903, 2147483647},
  241. {-4611686018427387903, -2147483648},
  242. {9223372036854775807, 2147483647},
  243. {-9223372036854775808, -2147483648},
  244. }
  245. for _, test := range tests {
  246. got := test.in.Int32()
  247. if got != test.want {
  248. t.Errorf("Int32: did not get expected value for %d - "+
  249. "got %d, want %d", test.in, got, test.want)
  250. continue
  251. }
  252. }
  253. }