github.com/calmw/ethereum@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  )
    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  // Test checks if the customized json marshaller of MixedcaseAddress object
   158  // is invoked correctly. In golang the struct pointer will inherit the
   159  // non-pointer receiver methods, the reverse is not true. In the case of
   160  // MixedcaseAddress, it must define the MarshalJSON method in the object
   161  // but not the pointer level, so that this customized marshalled can be used
   162  // for both MixedcaseAddress object and pointer.
   163  func TestMixedcaseAddressMarshal(t *testing.T) {
   164  	var (
   165  		output string
   166  		input  = "0xae967917c465db8578ca9024c205720b1a3651A9"
   167  	)
   168  	addr, err := NewMixedcaseAddressFromString(input)
   169  	if err != nil {
   170  		t.Fatal(err)
   171  	}
   172  	blob, err := json.Marshal(*addr)
   173  	if err != nil {
   174  		t.Fatal(err)
   175  	}
   176  	json.Unmarshal(blob, &output)
   177  	if output != input {
   178  		t.Fatal("Failed to marshal/unmarshal MixedcaseAddress object")
   179  	}
   180  }
   181  
   182  func TestMixedcaseAccount_Address(t *testing.T) {
   183  	// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md
   184  	// Note: 0X{checksum_addr} is not valid according to spec above
   185  
   186  	var res []struct {
   187  		A     MixedcaseAddress
   188  		Valid bool
   189  	}
   190  	if err := json.Unmarshal([]byte(`[
   191  		{"A" : "0xae967917c465db8578ca9024c205720b1a3651A9", "Valid": false},
   192  		{"A" : "0xAe967917c465db8578ca9024c205720b1a3651A9", "Valid": true},
   193  		{"A" : "0XAe967917c465db8578ca9024c205720b1a3651A9", "Valid": false},
   194  		{"A" : "0x1111111111111111111112222222222223333323", "Valid": true}
   195  		]`), &res); err != nil {
   196  		t.Fatal(err)
   197  	}
   198  
   199  	for _, r := range res {
   200  		if got := r.A.ValidChecksum(); got != r.Valid {
   201  			t.Errorf("Expected checksum %v, got checksum %v, input %v", r.Valid, got, r.A.String())
   202  		}
   203  	}
   204  
   205  	// These should throw exceptions:
   206  	var r2 []MixedcaseAddress
   207  	for _, r := range []string{
   208  		`["0x11111111111111111111122222222222233333"]`,     // Too short
   209  		`["0x111111111111111111111222222222222333332"]`,    // Too short
   210  		`["0x11111111111111111111122222222222233333234"]`,  // Too long
   211  		`["0x111111111111111111111222222222222333332344"]`, // Too long
   212  		`["1111111111111111111112222222222223333323"]`,     // Missing 0x
   213  		`["x1111111111111111111112222222222223333323"]`,    // Missing 0
   214  		`["0xG111111111111111111112222222222223333323"]`,   //Non-hex
   215  	} {
   216  		if err := json.Unmarshal([]byte(r), &r2); err == nil {
   217  			t.Errorf("Expected failure, input %v", r)
   218  		}
   219  	}
   220  }
   221  
   222  func TestHash_Scan(t *testing.T) {
   223  	type args struct {
   224  		src interface{}
   225  	}
   226  	tests := []struct {
   227  		name    string
   228  		args    args
   229  		wantErr bool
   230  	}{
   231  		{
   232  			name: "working scan",
   233  			args: args{src: []byte{
   234  				0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   235  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   236  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   237  				0x10, 0x00,
   238  			}},
   239  			wantErr: false,
   240  		},
   241  		{
   242  			name:    "non working scan",
   243  			args:    args{src: int64(1234567890)},
   244  			wantErr: true,
   245  		},
   246  		{
   247  			name: "invalid length scan",
   248  			args: args{src: []byte{
   249  				0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   250  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   251  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   252  			}},
   253  			wantErr: true,
   254  		},
   255  	}
   256  	for _, tt := range tests {
   257  		t.Run(tt.name, func(t *testing.T) {
   258  			h := &Hash{}
   259  			if err := h.Scan(tt.args.src); (err != nil) != tt.wantErr {
   260  				t.Errorf("Hash.Scan() error = %v, wantErr %v", err, tt.wantErr)
   261  			}
   262  
   263  			if !tt.wantErr {
   264  				for i := range h {
   265  					if h[i] != tt.args.src.([]byte)[i] {
   266  						t.Errorf(
   267  							"Hash.Scan() didn't scan the %d src correctly (have %X, want %X)",
   268  							i, h[i], tt.args.src.([]byte)[i],
   269  						)
   270  					}
   271  				}
   272  			}
   273  		})
   274  	}
   275  }
   276  
   277  func TestHash_Value(t *testing.T) {
   278  	b := []byte{
   279  		0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   280  		0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   281  		0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   282  		0x10, 0x00,
   283  	}
   284  	var usedH Hash
   285  	usedH.SetBytes(b)
   286  	tests := []struct {
   287  		name    string
   288  		h       Hash
   289  		want    driver.Value
   290  		wantErr bool
   291  	}{
   292  		{
   293  			name:    "Working value",
   294  			h:       usedH,
   295  			want:    b,
   296  			wantErr: false,
   297  		},
   298  	}
   299  	for _, tt := range tests {
   300  		t.Run(tt.name, func(t *testing.T) {
   301  			got, err := tt.h.Value()
   302  			if (err != nil) != tt.wantErr {
   303  				t.Errorf("Hash.Value() error = %v, wantErr %v", err, tt.wantErr)
   304  				return
   305  			}
   306  			if !reflect.DeepEqual(got, tt.want) {
   307  				t.Errorf("Hash.Value() = %v, want %v", got, tt.want)
   308  			}
   309  		})
   310  	}
   311  }
   312  
   313  func TestAddress_Scan(t *testing.T) {
   314  	type args struct {
   315  		src interface{}
   316  	}
   317  	tests := []struct {
   318  		name    string
   319  		args    args
   320  		wantErr bool
   321  	}{
   322  		{
   323  			name: "working scan",
   324  			args: args{src: []byte{
   325  				0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   326  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   327  			}},
   328  			wantErr: false,
   329  		},
   330  		{
   331  			name:    "non working scan",
   332  			args:    args{src: int64(1234567890)},
   333  			wantErr: true,
   334  		},
   335  		{
   336  			name: "invalid length scan",
   337  			args: args{src: []byte{
   338  				0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   339  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a,
   340  			}},
   341  			wantErr: true,
   342  		},
   343  	}
   344  	for _, tt := range tests {
   345  		t.Run(tt.name, func(t *testing.T) {
   346  			a := &Address{}
   347  			if err := a.Scan(tt.args.src); (err != nil) != tt.wantErr {
   348  				t.Errorf("Address.Scan() error = %v, wantErr %v", err, tt.wantErr)
   349  			}
   350  
   351  			if !tt.wantErr {
   352  				for i := range a {
   353  					if a[i] != tt.args.src.([]byte)[i] {
   354  						t.Errorf(
   355  							"Address.Scan() didn't scan the %d src correctly (have %X, want %X)",
   356  							i, a[i], tt.args.src.([]byte)[i],
   357  						)
   358  					}
   359  				}
   360  			}
   361  		})
   362  	}
   363  }
   364  
   365  func TestAddress_Value(t *testing.T) {
   366  	b := []byte{
   367  		0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   368  		0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   369  	}
   370  	var usedA Address
   371  	usedA.SetBytes(b)
   372  	tests := []struct {
   373  		name    string
   374  		a       Address
   375  		want    driver.Value
   376  		wantErr bool
   377  	}{
   378  		{
   379  			name:    "Working value",
   380  			a:       usedA,
   381  			want:    b,
   382  			wantErr: false,
   383  		},
   384  	}
   385  	for _, tt := range tests {
   386  		t.Run(tt.name, func(t *testing.T) {
   387  			got, err := tt.a.Value()
   388  			if (err != nil) != tt.wantErr {
   389  				t.Errorf("Address.Value() error = %v, wantErr %v", err, tt.wantErr)
   390  				return
   391  			}
   392  			if !reflect.DeepEqual(got, tt.want) {
   393  				t.Errorf("Address.Value() = %v, want %v", got, tt.want)
   394  			}
   395  		})
   396  	}
   397  }
   398  
   399  func TestAddress_Format(t *testing.T) {
   400  	b := []byte{
   401  		0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   402  		0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   403  	}
   404  	var addr Address
   405  	addr.SetBytes(b)
   406  
   407  	tests := []struct {
   408  		name string
   409  		out  string
   410  		want string
   411  	}{
   412  		{
   413  			name: "println",
   414  			out:  fmt.Sprintln(addr),
   415  			want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15\n",
   416  		},
   417  		{
   418  			name: "print",
   419  			out:  fmt.Sprint(addr),
   420  			want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15",
   421  		},
   422  		{
   423  			name: "printf-s",
   424  			out: func() string {
   425  				buf := new(bytes.Buffer)
   426  				fmt.Fprintf(buf, "%s", addr)
   427  				return buf.String()
   428  			}(),
   429  			want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15",
   430  		},
   431  		{
   432  			name: "printf-q",
   433  			out:  fmt.Sprintf("%q", addr),
   434  			want: `"0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15"`,
   435  		},
   436  		{
   437  			name: "printf-x",
   438  			out:  fmt.Sprintf("%x", addr),
   439  			want: "b26f2b342aab24bcf63ea218c6a9274d30ab9a15",
   440  		},
   441  		{
   442  			name: "printf-X",
   443  			out:  fmt.Sprintf("%X", addr),
   444  			want: "B26F2B342AAB24BCF63EA218C6A9274D30AB9A15",
   445  		},
   446  		{
   447  			name: "printf-#x",
   448  			out:  fmt.Sprintf("%#x", addr),
   449  			want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15",
   450  		},
   451  		{
   452  			name: "printf-v",
   453  			out:  fmt.Sprintf("%v", addr),
   454  			want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15",
   455  		},
   456  		// The original default formatter for byte slice
   457  		{
   458  			name: "printf-d",
   459  			out:  fmt.Sprintf("%d", addr),
   460  			want: "[178 111 43 52 42 171 36 188 246 62 162 24 198 169 39 77 48 171 154 21]",
   461  		},
   462  		// Invalid format char.
   463  		{
   464  			name: "printf-t",
   465  			out:  fmt.Sprintf("%t", addr),
   466  			want: "%!t(address=b26f2b342aab24bcf63ea218c6a9274d30ab9a15)",
   467  		},
   468  	}
   469  	for _, tt := range tests {
   470  		t.Run(tt.name, func(t *testing.T) {
   471  			if tt.out != tt.want {
   472  				t.Errorf("%s does not render as expected:\n got %s\nwant %s", tt.name, tt.out, tt.want)
   473  			}
   474  		})
   475  	}
   476  }
   477  
   478  func TestHash_Format(t *testing.T) {
   479  	var hash Hash
   480  	hash.SetBytes([]byte{
   481  		0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   482  		0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   483  		0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   484  		0x10, 0x00,
   485  	})
   486  
   487  	tests := []struct {
   488  		name string
   489  		out  string
   490  		want string
   491  	}{
   492  		{
   493  			name: "println",
   494  			out:  fmt.Sprintln(hash),
   495  			want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000\n",
   496  		},
   497  		{
   498  			name: "print",
   499  			out:  fmt.Sprint(hash),
   500  			want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000",
   501  		},
   502  		{
   503  			name: "printf-s",
   504  			out: func() string {
   505  				buf := new(bytes.Buffer)
   506  				fmt.Fprintf(buf, "%s", hash)
   507  				return buf.String()
   508  			}(),
   509  			want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000",
   510  		},
   511  		{
   512  			name: "printf-q",
   513  			out:  fmt.Sprintf("%q", hash),
   514  			want: `"0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000"`,
   515  		},
   516  		{
   517  			name: "printf-x",
   518  			out:  fmt.Sprintf("%x", hash),
   519  			want: "b26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000",
   520  		},
   521  		{
   522  			name: "printf-X",
   523  			out:  fmt.Sprintf("%X", hash),
   524  			want: "B26F2B342AAB24BCF63EA218C6A9274D30AB9A15A218C6A9274D30AB9A151000",
   525  		},
   526  		{
   527  			name: "printf-#x",
   528  			out:  fmt.Sprintf("%#x", hash),
   529  			want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000",
   530  		},
   531  		{
   532  			name: "printf-#X",
   533  			out:  fmt.Sprintf("%#X", hash),
   534  			want: "0XB26F2B342AAB24BCF63EA218C6A9274D30AB9A15A218C6A9274D30AB9A151000",
   535  		},
   536  		{
   537  			name: "printf-v",
   538  			out:  fmt.Sprintf("%v", hash),
   539  			want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000",
   540  		},
   541  		// The original default formatter for byte slice
   542  		{
   543  			name: "printf-d",
   544  			out:  fmt.Sprintf("%d", hash),
   545  			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]",
   546  		},
   547  		// Invalid format char.
   548  		{
   549  			name: "printf-t",
   550  			out:  fmt.Sprintf("%t", hash),
   551  			want: "%!t(hash=b26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000)",
   552  		},
   553  	}
   554  	for _, tt := range tests {
   555  		t.Run(tt.name, func(t *testing.T) {
   556  			if tt.out != tt.want {
   557  				t.Errorf("%s does not render as expected:\n got %s\nwant %s", tt.name, tt.out, tt.want)
   558  			}
   559  		})
   560  	}
   561  }