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  }