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