github.com/ethxdao/go-ethereum@v0.0.0-20221218102228-5ae34a9cc189/common/types_test.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package common 18 19 import ( 20 "bytes" 21 "database/sql/driver" 22 "encoding/json" 23 "fmt" 24 "math/big" 25 "reflect" 26 "strings" 27 "testing" 28 ) 29 30 func TestBytesConversion(t *testing.T) { 31 bytes := []byte{5} 32 hash := BytesToHash(bytes) 33 34 var exp Hash 35 exp[31] = 5 36 37 if hash != exp { 38 t.Errorf("expected %x got %x", exp, hash) 39 } 40 } 41 42 func TestIsHexAddress(t *testing.T) { 43 tests := []struct { 44 str string 45 exp bool 46 }{ 47 {"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true}, 48 {"5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true}, 49 {"0X5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true}, 50 {"0XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", true}, 51 {"0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", true}, 52 {"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed1", false}, 53 {"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beae", false}, 54 {"5aaeb6053f3e94c9b9a09f33669435e7ef1beaed11", false}, 55 {"0xxaaeb6053f3e94c9b9a09f33669435e7ef1beaed", false}, 56 } 57 58 for _, test := range tests { 59 if result := IsHexAddress(test.str); result != test.exp { 60 t.Errorf("IsHexAddress(%s) == %v; expected %v", 61 test.str, result, test.exp) 62 } 63 } 64 } 65 66 func TestHashJsonValidation(t *testing.T) { 67 var tests = []struct { 68 Prefix string 69 Size int 70 Error string 71 }{ 72 {"", 62, "json: cannot unmarshal hex string without 0x prefix into Go value of type common.Hash"}, 73 {"0x", 66, "hex string has length 66, want 64 for common.Hash"}, 74 {"0x", 63, "json: cannot unmarshal hex string of odd length into Go value of type common.Hash"}, 75 {"0x", 0, "hex string has length 0, want 64 for common.Hash"}, 76 {"0x", 64, ""}, 77 {"0X", 64, ""}, 78 } 79 for _, test := range tests { 80 input := `"` + test.Prefix + strings.Repeat("0", test.Size) + `"` 81 var v Hash 82 err := json.Unmarshal([]byte(input), &v) 83 if err == nil { 84 if test.Error != "" { 85 t.Errorf("%s: error mismatch: have nil, want %q", input, test.Error) 86 } 87 } else { 88 if err.Error() != test.Error { 89 t.Errorf("%s: error mismatch: have %q, want %q", input, err, test.Error) 90 } 91 } 92 } 93 } 94 95 func TestAddressUnmarshalJSON(t *testing.T) { 96 var tests = []struct { 97 Input string 98 ShouldErr bool 99 Output *big.Int 100 }{ 101 {"", true, nil}, 102 {`""`, true, nil}, 103 {`"0x"`, true, nil}, 104 {`"0x00"`, true, nil}, 105 {`"0xG000000000000000000000000000000000000000"`, true, nil}, 106 {`"0x0000000000000000000000000000000000000000"`, false, big.NewInt(0)}, 107 {`"0x0000000000000000000000000000000000000010"`, false, big.NewInt(16)}, 108 } 109 for i, test := range tests { 110 var v Address 111 err := json.Unmarshal([]byte(test.Input), &v) 112 if err != nil && !test.ShouldErr { 113 t.Errorf("test #%d: unexpected error: %v", i, err) 114 } 115 if err == nil { 116 if test.ShouldErr { 117 t.Errorf("test #%d: expected error, got none", i) 118 } 119 if got := new(big.Int).SetBytes(v.Bytes()); got.Cmp(test.Output) != 0 { 120 t.Errorf("test #%d: address mismatch: have %v, want %v", i, got, test.Output) 121 } 122 } 123 } 124 } 125 126 func TestAddressHexChecksum(t *testing.T) { 127 var tests = []struct { 128 Input string 129 Output string 130 }{ 131 // Test cases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md#specification 132 {"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"}, 133 {"0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359", "0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359"}, 134 {"0xdbf03b407c01e7cd3cbea99509d93f8dddc8c6fb", "0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB"}, 135 {"0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", "0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb"}, 136 // Ensure that non-standard length input values are handled correctly 137 {"0xa", "0x000000000000000000000000000000000000000A"}, 138 {"0x0a", "0x000000000000000000000000000000000000000A"}, 139 {"0x00a", "0x000000000000000000000000000000000000000A"}, 140 {"0x000000000000000000000000000000000000000a", "0x000000000000000000000000000000000000000A"}, 141 } 142 for i, test := range tests { 143 output := HexToAddress(test.Input).Hex() 144 if output != test.Output { 145 t.Errorf("test #%d: failed to match when it should (%s != %s)", i, output, test.Output) 146 } 147 } 148 } 149 150 func BenchmarkAddressHex(b *testing.B) { 151 testAddr := HexToAddress("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed") 152 for n := 0; n < b.N; n++ { 153 testAddr.Hex() 154 } 155 } 156 157 func TestMixedcaseAccount_Address(t *testing.T) { 158 // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md 159 // Note: 0X{checksum_addr} is not valid according to spec above 160 161 var res []struct { 162 A MixedcaseAddress 163 Valid bool 164 } 165 if err := json.Unmarshal([]byte(`[ 166 {"A" : "0xae967917c465db8578ca9024c205720b1a3651A9", "Valid": false}, 167 {"A" : "0xAe967917c465db8578ca9024c205720b1a3651A9", "Valid": true}, 168 {"A" : "0XAe967917c465db8578ca9024c205720b1a3651A9", "Valid": false}, 169 {"A" : "0x1111111111111111111112222222222223333323", "Valid": true} 170 ]`), &res); err != nil { 171 t.Fatal(err) 172 } 173 174 for _, r := range res { 175 if got := r.A.ValidChecksum(); got != r.Valid { 176 t.Errorf("Expected checksum %v, got checksum %v, input %v", r.Valid, got, r.A.String()) 177 } 178 } 179 180 //These should throw exceptions: 181 var r2 []MixedcaseAddress 182 for _, r := range []string{ 183 `["0x11111111111111111111122222222222233333"]`, // Too short 184 `["0x111111111111111111111222222222222333332"]`, // Too short 185 `["0x11111111111111111111122222222222233333234"]`, // Too long 186 `["0x111111111111111111111222222222222333332344"]`, // Too long 187 `["1111111111111111111112222222222223333323"]`, // Missing 0x 188 `["x1111111111111111111112222222222223333323"]`, // Missing 0 189 `["0xG111111111111111111112222222222223333323"]`, //Non-hex 190 } { 191 if err := json.Unmarshal([]byte(r), &r2); err == nil { 192 t.Errorf("Expected failure, input %v", r) 193 } 194 } 195 } 196 197 func TestHash_Scan(t *testing.T) { 198 type args struct { 199 src interface{} 200 } 201 tests := []struct { 202 name string 203 args args 204 wantErr bool 205 }{ 206 { 207 name: "working scan", 208 args: args{src: []byte{ 209 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 210 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 211 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 212 0x10, 0x00, 213 }}, 214 wantErr: false, 215 }, 216 { 217 name: "non working scan", 218 args: args{src: int64(1234567890)}, 219 wantErr: true, 220 }, 221 { 222 name: "invalid length scan", 223 args: args{src: []byte{ 224 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 225 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 226 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 227 }}, 228 wantErr: true, 229 }, 230 } 231 for _, tt := range tests { 232 t.Run(tt.name, func(t *testing.T) { 233 h := &Hash{} 234 if err := h.Scan(tt.args.src); (err != nil) != tt.wantErr { 235 t.Errorf("Hash.Scan() error = %v, wantErr %v", err, tt.wantErr) 236 } 237 238 if !tt.wantErr { 239 for i := range h { 240 if h[i] != tt.args.src.([]byte)[i] { 241 t.Errorf( 242 "Hash.Scan() didn't scan the %d src correctly (have %X, want %X)", 243 i, h[i], tt.args.src.([]byte)[i], 244 ) 245 } 246 } 247 } 248 }) 249 } 250 } 251 252 func TestHash_Value(t *testing.T) { 253 b := []byte{ 254 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 255 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 256 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 257 0x10, 0x00, 258 } 259 var usedH Hash 260 usedH.SetBytes(b) 261 tests := []struct { 262 name string 263 h Hash 264 want driver.Value 265 wantErr bool 266 }{ 267 { 268 name: "Working value", 269 h: usedH, 270 want: b, 271 wantErr: false, 272 }, 273 } 274 for _, tt := range tests { 275 t.Run(tt.name, func(t *testing.T) { 276 got, err := tt.h.Value() 277 if (err != nil) != tt.wantErr { 278 t.Errorf("Hash.Value() error = %v, wantErr %v", err, tt.wantErr) 279 return 280 } 281 if !reflect.DeepEqual(got, tt.want) { 282 t.Errorf("Hash.Value() = %v, want %v", got, tt.want) 283 } 284 }) 285 } 286 } 287 288 func TestAddress_Scan(t *testing.T) { 289 type args struct { 290 src interface{} 291 } 292 tests := []struct { 293 name string 294 args args 295 wantErr bool 296 }{ 297 { 298 name: "working scan", 299 args: args{src: []byte{ 300 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 301 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 302 }}, 303 wantErr: false, 304 }, 305 { 306 name: "non working scan", 307 args: args{src: int64(1234567890)}, 308 wantErr: true, 309 }, 310 { 311 name: "invalid length scan", 312 args: args{src: []byte{ 313 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 314 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 315 }}, 316 wantErr: true, 317 }, 318 } 319 for _, tt := range tests { 320 t.Run(tt.name, func(t *testing.T) { 321 a := &Address{} 322 if err := a.Scan(tt.args.src); (err != nil) != tt.wantErr { 323 t.Errorf("Address.Scan() error = %v, wantErr %v", err, tt.wantErr) 324 } 325 326 if !tt.wantErr { 327 for i := range a { 328 if a[i] != tt.args.src.([]byte)[i] { 329 t.Errorf( 330 "Address.Scan() didn't scan the %d src correctly (have %X, want %X)", 331 i, a[i], tt.args.src.([]byte)[i], 332 ) 333 } 334 } 335 } 336 }) 337 } 338 } 339 340 func TestAddress_Value(t *testing.T) { 341 b := []byte{ 342 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 343 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 344 } 345 var usedA Address 346 usedA.SetBytes(b) 347 tests := []struct { 348 name string 349 a Address 350 want driver.Value 351 wantErr bool 352 }{ 353 { 354 name: "Working value", 355 a: usedA, 356 want: b, 357 wantErr: false, 358 }, 359 } 360 for _, tt := range tests { 361 t.Run(tt.name, func(t *testing.T) { 362 got, err := tt.a.Value() 363 if (err != nil) != tt.wantErr { 364 t.Errorf("Address.Value() error = %v, wantErr %v", err, tt.wantErr) 365 return 366 } 367 if !reflect.DeepEqual(got, tt.want) { 368 t.Errorf("Address.Value() = %v, want %v", got, tt.want) 369 } 370 }) 371 } 372 } 373 374 func TestAddress_Format(t *testing.T) { 375 b := []byte{ 376 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 377 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 378 } 379 var addr Address 380 addr.SetBytes(b) 381 382 tests := []struct { 383 name string 384 out string 385 want string 386 }{ 387 { 388 name: "println", 389 out: fmt.Sprintln(addr), 390 want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15\n", 391 }, 392 { 393 name: "print", 394 out: fmt.Sprint(addr), 395 want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15", 396 }, 397 { 398 name: "printf-s", 399 out: func() string { 400 buf := new(bytes.Buffer) 401 fmt.Fprintf(buf, "%s", addr) 402 return buf.String() 403 }(), 404 want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15", 405 }, 406 { 407 name: "printf-q", 408 out: fmt.Sprintf("%q", addr), 409 want: `"0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15"`, 410 }, 411 { 412 name: "printf-x", 413 out: fmt.Sprintf("%x", addr), 414 want: "b26f2b342aab24bcf63ea218c6a9274d30ab9a15", 415 }, 416 { 417 name: "printf-X", 418 out: fmt.Sprintf("%X", addr), 419 want: "B26F2B342AAB24BCF63EA218C6A9274D30AB9A15", 420 }, 421 { 422 name: "printf-#x", 423 out: fmt.Sprintf("%#x", addr), 424 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15", 425 }, 426 { 427 name: "printf-v", 428 out: fmt.Sprintf("%v", addr), 429 want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15", 430 }, 431 // The original default formatter for byte slice 432 { 433 name: "printf-d", 434 out: fmt.Sprintf("%d", addr), 435 want: "[178 111 43 52 42 171 36 188 246 62 162 24 198 169 39 77 48 171 154 21]", 436 }, 437 // Invalid format char. 438 { 439 name: "printf-t", 440 out: fmt.Sprintf("%t", addr), 441 want: "%!t(address=b26f2b342aab24bcf63ea218c6a9274d30ab9a15)", 442 }, 443 } 444 for _, tt := range tests { 445 t.Run(tt.name, func(t *testing.T) { 446 if tt.out != tt.want { 447 t.Errorf("%s does not render as expected:\n got %s\nwant %s", tt.name, tt.out, tt.want) 448 } 449 }) 450 } 451 } 452 453 func TestHash_Format(t *testing.T) { 454 var hash Hash 455 hash.SetBytes([]byte{ 456 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 457 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 458 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 459 0x10, 0x00, 460 }) 461 462 tests := []struct { 463 name string 464 out string 465 want string 466 }{ 467 { 468 name: "println", 469 out: fmt.Sprintln(hash), 470 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000\n", 471 }, 472 { 473 name: "print", 474 out: fmt.Sprint(hash), 475 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", 476 }, 477 { 478 name: "printf-s", 479 out: func() string { 480 buf := new(bytes.Buffer) 481 fmt.Fprintf(buf, "%s", hash) 482 return buf.String() 483 }(), 484 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", 485 }, 486 { 487 name: "printf-q", 488 out: fmt.Sprintf("%q", hash), 489 want: `"0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000"`, 490 }, 491 { 492 name: "printf-x", 493 out: fmt.Sprintf("%x", hash), 494 want: "b26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", 495 }, 496 { 497 name: "printf-X", 498 out: fmt.Sprintf("%X", hash), 499 want: "B26F2B342AAB24BCF63EA218C6A9274D30AB9A15A218C6A9274D30AB9A151000", 500 }, 501 { 502 name: "printf-#x", 503 out: fmt.Sprintf("%#x", hash), 504 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", 505 }, 506 { 507 name: "printf-#X", 508 out: fmt.Sprintf("%#X", hash), 509 want: "0XB26F2B342AAB24BCF63EA218C6A9274D30AB9A15A218C6A9274D30AB9A151000", 510 }, 511 { 512 name: "printf-v", 513 out: fmt.Sprintf("%v", hash), 514 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", 515 }, 516 // The original default formatter for byte slice 517 { 518 name: "printf-d", 519 out: fmt.Sprintf("%d", hash), 520 want: "[178 111 43 52 42 171 36 188 246 62 162 24 198 169 39 77 48 171 154 21 162 24 198 169 39 77 48 171 154 21 16 0]", 521 }, 522 // Invalid format char. 523 { 524 name: "printf-t", 525 out: fmt.Sprintf("%t", hash), 526 want: "%!t(hash=b26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000)", 527 }, 528 } 529 for _, tt := range tests { 530 t.Run(tt.name, func(t *testing.T) { 531 if tt.out != tt.want { 532 t.Errorf("%s does not render as expected:\n got %s\nwant %s", tt.name, tt.out, tt.want) 533 } 534 }) 535 } 536 }