github.com/ethereum/go-ethereum@v1.16.1/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" 25 "math/big" 26 "reflect" 27 "strings" 28 "testing" 29 "time" 30 ) 31 32 func TestBytesConversion(t *testing.T) { 33 bytes := []byte{5} 34 hash := BytesToHash(bytes) 35 36 var exp Hash 37 exp[31] = 5 38 39 if hash != exp { 40 t.Errorf("expected %x got %x", exp, hash) 41 } 42 } 43 44 func TestIsHexAddress(t *testing.T) { 45 tests := []struct { 46 str string 47 exp bool 48 }{ 49 {"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true}, 50 {"5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true}, 51 {"0X5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true}, 52 {"0XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", true}, 53 {"0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", true}, 54 {"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed1", false}, 55 {"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beae", false}, 56 {"5aaeb6053f3e94c9b9a09f33669435e7ef1beaed11", false}, 57 {"0xxaaeb6053f3e94c9b9a09f33669435e7ef1beaed", false}, 58 } 59 60 for _, test := range tests { 61 if result := IsHexAddress(test.str); result != test.exp { 62 t.Errorf("IsHexAddress(%s) == %v; expected %v", 63 test.str, result, test.exp) 64 } 65 } 66 } 67 68 func TestHashJsonValidation(t *testing.T) { 69 var tests = []struct { 70 Prefix string 71 Size int 72 Error string 73 }{ 74 {"", 62, "json: cannot unmarshal hex string without 0x prefix into Go value of type common.Hash"}, 75 {"0x", 66, "hex string has length 66, want 64 for common.Hash"}, 76 {"0x", 63, "json: cannot unmarshal hex string of odd length into Go value of type common.Hash"}, 77 {"0x", 0, "hex string has length 0, want 64 for common.Hash"}, 78 {"0x", 64, ""}, 79 {"0X", 64, ""}, 80 } 81 for _, test := range tests { 82 input := `"` + test.Prefix + strings.Repeat("0", test.Size) + `"` 83 var v Hash 84 err := json.Unmarshal([]byte(input), &v) 85 if err == nil { 86 if test.Error != "" { 87 t.Errorf("%s: error mismatch: have nil, want %q", input, test.Error) 88 } 89 } else { 90 if err.Error() != test.Error { 91 t.Errorf("%s: error mismatch: have %q, want %q", input, err, test.Error) 92 } 93 } 94 } 95 } 96 97 func TestAddressUnmarshalJSON(t *testing.T) { 98 var tests = []struct { 99 Input string 100 ShouldErr bool 101 Output *big.Int 102 }{ 103 {"", true, nil}, 104 {`""`, true, nil}, 105 {`"0x"`, true, nil}, 106 {`"0x00"`, true, nil}, 107 {`"0xG000000000000000000000000000000000000000"`, true, nil}, 108 {`"0x0000000000000000000000000000000000000000"`, false, big.NewInt(0)}, 109 {`"0x0000000000000000000000000000000000000010"`, false, big.NewInt(16)}, 110 } 111 for i, test := range tests { 112 var v Address 113 err := json.Unmarshal([]byte(test.Input), &v) 114 if err != nil && !test.ShouldErr { 115 t.Errorf("test #%d: unexpected error: %v", i, err) 116 } 117 if err == nil { 118 if test.ShouldErr { 119 t.Errorf("test #%d: expected error, got none", i) 120 } 121 if got := new(big.Int).SetBytes(v.Bytes()); got.Cmp(test.Output) != 0 { 122 t.Errorf("test #%d: address mismatch: have %v, want %v", i, got, test.Output) 123 } 124 } 125 } 126 } 127 128 func TestAddressHexChecksum(t *testing.T) { 129 var tests = []struct { 130 Input string 131 Output string 132 }{ 133 // Test cases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md#specification 134 {"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"}, 135 {"0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359", "0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359"}, 136 {"0xdbf03b407c01e7cd3cbea99509d93f8dddc8c6fb", "0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB"}, 137 {"0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", "0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb"}, 138 // Ensure that non-standard length input values are handled correctly 139 {"0xa", "0x000000000000000000000000000000000000000A"}, 140 {"0x0a", "0x000000000000000000000000000000000000000A"}, 141 {"0x00a", "0x000000000000000000000000000000000000000A"}, 142 {"0x000000000000000000000000000000000000000a", "0x000000000000000000000000000000000000000A"}, 143 } 144 for i, test := range tests { 145 output := HexToAddress(test.Input).Hex() 146 if output != test.Output { 147 t.Errorf("test #%d: failed to match when it should (%s != %s)", i, output, test.Output) 148 } 149 } 150 } 151 152 func BenchmarkAddressHex(b *testing.B) { 153 testAddr := HexToAddress("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed") 154 for n := 0; n < b.N; n++ { 155 testAddr.Hex() 156 } 157 } 158 159 // Test checks if the customized json marshaller of MixedcaseAddress object 160 // is invoked correctly. In golang the struct pointer will inherit the 161 // non-pointer receiver methods, the reverse is not true. In the case of 162 // MixedcaseAddress, it must define the MarshalJSON method in the object 163 // but not the pointer level, so that this customized marshalled can be used 164 // for both MixedcaseAddress object and pointer. 165 func TestMixedcaseAddressMarshal(t *testing.T) { 166 var ( 167 output string 168 input = "0xae967917c465db8578ca9024c205720b1a3651A9" 169 ) 170 addr, err := NewMixedcaseAddressFromString(input) 171 if err != nil { 172 t.Fatal(err) 173 } 174 blob, err := json.Marshal(*addr) 175 if err != nil { 176 t.Fatal(err) 177 } 178 json.Unmarshal(blob, &output) 179 if output != input { 180 t.Fatal("Failed to marshal/unmarshal MixedcaseAddress object") 181 } 182 } 183 184 func TestMixedcaseAccount_Address(t *testing.T) { 185 // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md 186 // Note: 0X{checksum_addr} is not valid according to spec above 187 188 var res []struct { 189 A MixedcaseAddress 190 Valid bool 191 } 192 if err := json.Unmarshal([]byte(`[ 193 {"A" : "0xae967917c465db8578ca9024c205720b1a3651A9", "Valid": false}, 194 {"A" : "0xAe967917c465db8578ca9024c205720b1a3651A9", "Valid": true}, 195 {"A" : "0XAe967917c465db8578ca9024c205720b1a3651A9", "Valid": false}, 196 {"A" : "0x1111111111111111111112222222222223333323", "Valid": true} 197 ]`), &res); err != nil { 198 t.Fatal(err) 199 } 200 201 for _, r := range res { 202 if got := r.A.ValidChecksum(); got != r.Valid { 203 t.Errorf("Expected checksum %v, got checksum %v, input %v", r.Valid, got, r.A.String()) 204 } 205 } 206 207 // These should throw exceptions: 208 var r2 []MixedcaseAddress 209 for _, r := range []string{ 210 `["0x11111111111111111111122222222222233333"]`, // Too short 211 `["0x111111111111111111111222222222222333332"]`, // Too short 212 `["0x11111111111111111111122222222222233333234"]`, // Too long 213 `["0x111111111111111111111222222222222333332344"]`, // Too long 214 `["1111111111111111111112222222222223333323"]`, // Missing 0x 215 `["x1111111111111111111112222222222223333323"]`, // Missing 0 216 `["0xG111111111111111111112222222222223333323"]`, //Non-hex 217 } { 218 if err := json.Unmarshal([]byte(r), &r2); err == nil { 219 t.Errorf("Expected failure, input %v", r) 220 } 221 } 222 } 223 224 func TestHash_Scan(t *testing.T) { 225 type args struct { 226 src interface{} 227 } 228 tests := []struct { 229 name string 230 args args 231 wantErr bool 232 }{ 233 { 234 name: "working scan", 235 args: args{src: []byte{ 236 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 237 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 238 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 239 0x10, 0x00, 240 }}, 241 wantErr: false, 242 }, 243 { 244 name: "non working scan", 245 args: args{src: int64(1234567890)}, 246 wantErr: true, 247 }, 248 { 249 name: "invalid length scan", 250 args: args{src: []byte{ 251 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 252 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 253 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 254 }}, 255 wantErr: true, 256 }, 257 } 258 for _, tt := range tests { 259 t.Run(tt.name, func(t *testing.T) { 260 h := &Hash{} 261 if err := h.Scan(tt.args.src); (err != nil) != tt.wantErr { 262 t.Errorf("Hash.Scan() error = %v, wantErr %v", err, tt.wantErr) 263 } 264 265 if !tt.wantErr { 266 for i := range h { 267 if h[i] != tt.args.src.([]byte)[i] { 268 t.Errorf( 269 "Hash.Scan() didn't scan the %d src correctly (have %X, want %X)", 270 i, h[i], tt.args.src.([]byte)[i], 271 ) 272 } 273 } 274 } 275 }) 276 } 277 } 278 279 func TestHash_Value(t *testing.T) { 280 b := []byte{ 281 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 282 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 283 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 284 0x10, 0x00, 285 } 286 var usedH Hash 287 usedH.SetBytes(b) 288 tests := []struct { 289 name string 290 h Hash 291 want driver.Value 292 wantErr bool 293 }{ 294 { 295 name: "Working value", 296 h: usedH, 297 want: b, 298 wantErr: false, 299 }, 300 } 301 for _, tt := range tests { 302 t.Run(tt.name, func(t *testing.T) { 303 got, err := tt.h.Value() 304 if (err != nil) != tt.wantErr { 305 t.Errorf("Hash.Value() error = %v, wantErr %v", err, tt.wantErr) 306 return 307 } 308 if !reflect.DeepEqual(got, tt.want) { 309 t.Errorf("Hash.Value() = %v, want %v", got, tt.want) 310 } 311 }) 312 } 313 } 314 315 func TestAddress_Scan(t *testing.T) { 316 type args struct { 317 src interface{} 318 } 319 tests := []struct { 320 name string 321 args args 322 wantErr bool 323 }{ 324 { 325 name: "working scan", 326 args: args{src: []byte{ 327 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 328 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 329 }}, 330 wantErr: false, 331 }, 332 { 333 name: "non working scan", 334 args: args{src: int64(1234567890)}, 335 wantErr: true, 336 }, 337 { 338 name: "invalid length scan", 339 args: args{src: []byte{ 340 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 341 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 342 }}, 343 wantErr: true, 344 }, 345 } 346 for _, tt := range tests { 347 t.Run(tt.name, func(t *testing.T) { 348 a := &Address{} 349 if err := a.Scan(tt.args.src); (err != nil) != tt.wantErr { 350 t.Errorf("Address.Scan() error = %v, wantErr %v", err, tt.wantErr) 351 } 352 353 if !tt.wantErr { 354 for i := range a { 355 if a[i] != tt.args.src.([]byte)[i] { 356 t.Errorf( 357 "Address.Scan() didn't scan the %d src correctly (have %X, want %X)", 358 i, a[i], tt.args.src.([]byte)[i], 359 ) 360 } 361 } 362 } 363 }) 364 } 365 } 366 367 func TestAddress_Value(t *testing.T) { 368 b := []byte{ 369 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 370 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 371 } 372 var usedA Address 373 usedA.SetBytes(b) 374 tests := []struct { 375 name string 376 a Address 377 want driver.Value 378 wantErr bool 379 }{ 380 { 381 name: "Working value", 382 a: usedA, 383 want: b, 384 wantErr: false, 385 }, 386 } 387 for _, tt := range tests { 388 t.Run(tt.name, func(t *testing.T) { 389 got, err := tt.a.Value() 390 if (err != nil) != tt.wantErr { 391 t.Errorf("Address.Value() error = %v, wantErr %v", err, tt.wantErr) 392 return 393 } 394 if !reflect.DeepEqual(got, tt.want) { 395 t.Errorf("Address.Value() = %v, want %v", got, tt.want) 396 } 397 }) 398 } 399 } 400 401 func TestAddress_Format(t *testing.T) { 402 b := []byte{ 403 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 404 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 405 } 406 var addr Address 407 addr.SetBytes(b) 408 409 tests := []struct { 410 name string 411 out string 412 want string 413 }{ 414 { 415 name: "println", 416 out: fmt.Sprintln(addr), 417 want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15\n", 418 }, 419 { 420 name: "print", 421 out: fmt.Sprint(addr), 422 want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15", 423 }, 424 { 425 name: "printf-s", 426 out: func() string { 427 buf := new(bytes.Buffer) 428 fmt.Fprintf(buf, "%s", addr) 429 return buf.String() 430 }(), 431 want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15", 432 }, 433 { 434 name: "printf-q", 435 out: fmt.Sprintf("%q", addr), 436 want: `"0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15"`, 437 }, 438 { 439 name: "printf-x", 440 out: fmt.Sprintf("%x", addr), 441 want: "b26f2b342aab24bcf63ea218c6a9274d30ab9a15", 442 }, 443 { 444 name: "printf-X", 445 out: fmt.Sprintf("%X", addr), 446 want: "B26F2B342AAB24BCF63EA218C6A9274D30AB9A15", 447 }, 448 { 449 name: "printf-#x", 450 out: fmt.Sprintf("%#x", addr), 451 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15", 452 }, 453 { 454 name: "printf-v", 455 out: fmt.Sprintf("%v", addr), 456 want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15", 457 }, 458 // The original default formatter for byte slice 459 { 460 name: "printf-d", 461 out: fmt.Sprintf("%d", addr), 462 want: "[178 111 43 52 42 171 36 188 246 62 162 24 198 169 39 77 48 171 154 21]", 463 }, 464 // Invalid format char. 465 { 466 name: "printf-t", 467 out: fmt.Sprintf("%t", addr), 468 want: "%!t(address=b26f2b342aab24bcf63ea218c6a9274d30ab9a15)", 469 }, 470 } 471 for _, tt := range tests { 472 t.Run(tt.name, func(t *testing.T) { 473 if tt.out != tt.want { 474 t.Errorf("%s does not render as expected:\n got %s\nwant %s", tt.name, tt.out, tt.want) 475 } 476 }) 477 } 478 } 479 480 func TestHash_Format(t *testing.T) { 481 var hash Hash 482 hash.SetBytes([]byte{ 483 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 484 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 485 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 486 0x10, 0x00, 487 }) 488 489 tests := []struct { 490 name string 491 out string 492 want string 493 }{ 494 { 495 name: "println", 496 out: fmt.Sprintln(hash), 497 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000\n", 498 }, 499 { 500 name: "print", 501 out: fmt.Sprint(hash), 502 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", 503 }, 504 { 505 name: "printf-s", 506 out: func() string { 507 buf := new(bytes.Buffer) 508 fmt.Fprintf(buf, "%s", hash) 509 return buf.String() 510 }(), 511 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", 512 }, 513 { 514 name: "printf-q", 515 out: fmt.Sprintf("%q", hash), 516 want: `"0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000"`, 517 }, 518 { 519 name: "printf-x", 520 out: fmt.Sprintf("%x", hash), 521 want: "b26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", 522 }, 523 { 524 name: "printf-X", 525 out: fmt.Sprintf("%X", hash), 526 want: "B26F2B342AAB24BCF63EA218C6A9274D30AB9A15A218C6A9274D30AB9A151000", 527 }, 528 { 529 name: "printf-#x", 530 out: fmt.Sprintf("%#x", hash), 531 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", 532 }, 533 { 534 name: "printf-#X", 535 out: fmt.Sprintf("%#X", hash), 536 want: "0XB26F2B342AAB24BCF63EA218C6A9274D30AB9A15A218C6A9274D30AB9A151000", 537 }, 538 { 539 name: "printf-v", 540 out: fmt.Sprintf("%v", hash), 541 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", 542 }, 543 // The original default formatter for byte slice 544 { 545 name: "printf-d", 546 out: fmt.Sprintf("%d", hash), 547 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]", 548 }, 549 // Invalid format char. 550 { 551 name: "printf-t", 552 out: fmt.Sprintf("%t", hash), 553 want: "%!t(hash=b26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000)", 554 }, 555 } 556 for _, tt := range tests { 557 t.Run(tt.name, func(t *testing.T) { 558 if tt.out != tt.want { 559 t.Errorf("%s does not render as expected:\n got %s\nwant %s", tt.name, tt.out, tt.want) 560 } 561 }) 562 } 563 } 564 565 func TestAddressEIP55(t *testing.T) { 566 addr := HexToAddress("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed") 567 addrEIP55 := AddressEIP55(addr) 568 569 if addr.Hex() != addrEIP55.String() { 570 t.Fatal("AddressEIP55 should match original address hex") 571 } 572 573 blob, err := addrEIP55.MarshalJSON() 574 if err != nil { 575 t.Fatal("Failed to marshal AddressEIP55", err) 576 } 577 if strings.Trim(string(blob), "\"") != addr.Hex() { 578 t.Fatal("Address with checksum is expected") 579 } 580 var dec Address 581 if err := json.Unmarshal(blob, &dec); err != nil { 582 t.Fatal("Failed to unmarshal AddressEIP55", err) 583 } 584 if addr != dec { 585 t.Fatal("Unexpected address after unmarshal") 586 } 587 } 588 589 func BenchmarkPrettyDuration(b *testing.B) { 590 var x = PrettyDuration(time.Duration(int64(1203123912312))) 591 b.Logf("Pre %s", time.Duration(x).String()) 592 var a string 593 b.ResetTimer() 594 for i := 0; i < b.N; i++ { 595 a = x.String() 596 } 597 b.Logf("Post %s", a) 598 } 599 600 func TestDecimalUnmarshalJSON(t *testing.T) { 601 // These should error 602 for _, tc := range []string{``, `"`, `""`, `"-1"`} { 603 if err := new(Decimal).UnmarshalJSON([]byte(tc)); err == nil { 604 t.Errorf("input %s should cause error", tc) 605 } 606 } 607 // These should succeed 608 for _, tc := range []struct { 609 input string 610 want uint64 611 }{ 612 {`"0"`, 0}, 613 {`"9223372036854775807"`, math.MaxInt64}, 614 {`"18446744073709551615"`, math.MaxUint64}, 615 } { 616 have := new(Decimal) 617 if err := have.UnmarshalJSON([]byte(tc.input)); err != nil { 618 t.Errorf("input %q triggered error: %v", tc.input, err) 619 } 620 if uint64(*have) != tc.want { 621 t.Errorf("input %q, have %d want %d", tc.input, *have, tc.want) 622 } 623 } 624 }