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