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  }