github.com/klaytn/klaytn@v1.12.1/common/types_test.go (about)

     1  // Modifications Copyright 2018 The klaytn Authors
     2  // Copyright 2015 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  // This file is derived from common/types_test.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package common
    22  
    23  import (
    24  	"encoding/json"
    25  	"fmt"
    26  	"math/big"
    27  	"strings"
    28  	"testing"
    29  
    30  	"github.com/klaytn/klaytn/common/hexutil"
    31  	"github.com/stretchr/testify/assert"
    32  )
    33  
    34  // Make sure Hash and ExtHash both implement similar interfaces
    35  type hashLike interface {
    36  	Bytes() []byte
    37  	Hex() string
    38  
    39  	String() string
    40  	TerminalString() string
    41  	Format(s fmt.State, c rune)
    42  	MarshalText() ([]byte, error)
    43  
    44  	getShardIndex(shardMask int) int
    45  }
    46  
    47  type hashPtrLike interface {
    48  	SetBytes(b []byte)
    49  	UnmarshalText(input []byte) error
    50  	UnmarshalJSON(input []byte) error
    51  }
    52  
    53  var (
    54  	_ hashLike    = Hash{}
    55  	_ hashLike    = ExtHash{}
    56  	_ hashPtrLike = &Hash{}
    57  	_ hashPtrLike = &ExtHash{}
    58  )
    59  
    60  func TestBytesConversion(t *testing.T) {
    61  	bytes := []byte{5}
    62  	hash := BytesToHash(bytes)
    63  
    64  	var exp Hash
    65  	exp[31] = 5
    66  
    67  	if hash != exp {
    68  		t.Errorf("expected %x got %x", exp, hash)
    69  	}
    70  }
    71  
    72  func TestExtHash(t *testing.T) {
    73  	var (
    74  		sHash     = "0x1122334411223344112233441122334411223344112233441122334411223344"
    75  		nCounter  = uint64(0xccccddddeeee01)
    76  		sCounter  = "0xccccddddeeee01"
    77  		sExtHash  = "0x1122334411223344112233441122334411223344112233441122334411223344ccccddddeeee01"
    78  		sExtHash2 = "0x1122334411223344112233441122334411223344112233441122334411223344ccccddddeeee02"
    79  		sExtZero  = "0x112233441122334411223344112233441122334411223344112233441122334400000000000000"
    80  		sEmpty    = "0x000000000000000000000000000000000000000000000000000000000000000000000000000000"
    81  		bHash     = hexutil.MustDecode(sHash)
    82  		bCounter  = hexutil.MustDecode(sCounter)
    83  		bExtHash  = hexutil.MustDecode(sExtHash)
    84  	)
    85  
    86  	h := BytesToHash(bHash)
    87  	counter := BytesToExtHashCounter(bCounter)
    88  	eh := h.extend(counter)
    89  
    90  	// ExtHash methods
    91  	assert.Equal(t, bExtHash, eh.Bytes())
    92  	assert.Equal(t, sExtHash, eh.Hex())
    93  	assert.Equal(t, counter, eh.Counter())
    94  
    95  	assert.Equal(t, sEmpty, BytesToExtHash(nil).Hex())
    96  	assert.Equal(t, sExtZero, BytesToExtHash(bHash).Hex())
    97  	assert.Equal(t, sExtHash, BytesToExtHash(bExtHash).Hex())
    98  	assert.Equal(t, sCounter, BytesToExtHashCounter(bCounter).Hex())
    99  
   100  	assert.Equal(t, sExtHash, HexToExtHash(sExtHash).Hex())
   101  	assert.Equal(t, sExtZero, HexToExtHash(sHash).Hex())
   102  
   103  	// Hash <-> ExtHash
   104  	assert.Equal(t, h, eh.Unextend())
   105  	assert.Equal(t, sExtZero, h.ExtendZero().Hex())
   106  	ResetExtHashCounterForTest(nCounter - 1)
   107  	assert.Equal(t, sExtHash, h.Extend().Hex())
   108  	assert.Equal(t, sExtHash2, h.Extend().Hex())
   109  
   110  	// Predicates
   111  	assert.False(t, eh.IsZeroExtended())
   112  	assert.True(t, h.ExtendZero().IsZeroExtended())
   113  
   114  	assert.False(t, EmptyExtHash(eh))
   115  	assert.True(t, EmptyExtHash(Hash{}.ExtendZero()))
   116  	assert.True(t, EmptyExtHash(ExtHash{}))
   117  }
   118  
   119  func TestIsHexAddress(t *testing.T) {
   120  	tests := []struct {
   121  		str string
   122  		exp bool
   123  	}{
   124  		{"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true},
   125  		{"5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true},
   126  		{"0X5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true},
   127  		{"0XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", true},
   128  		{"0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", true},
   129  		{"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed1", false},
   130  		{"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beae", false},
   131  		{"5aaeb6053f3e94c9b9a09f33669435e7ef1beaed11", false},
   132  		{"0xxaaeb6053f3e94c9b9a09f33669435e7ef1beaed", false},
   133  	}
   134  
   135  	for _, test := range tests {
   136  		if result := IsHexAddress(test.str); result != test.exp {
   137  			t.Errorf("IsHexAddress(%s) == %v; expected %v",
   138  				test.str, result, test.exp)
   139  		}
   140  	}
   141  }
   142  
   143  func TestHashJsonValidation(t *testing.T) {
   144  	tests := []struct {
   145  		Prefix string
   146  		Size   int
   147  		Error  string
   148  	}{
   149  		{"", 62, "json: cannot unmarshal hex string without 0x prefix into Go value of type common.Hash"},
   150  		{"0x", 66, "hex string has length 66, want 64 for common.Hash"},
   151  		{"0x", 63, "json: cannot unmarshal hex string of odd length into Go value of type common.Hash"},
   152  		{"0x", 0, "hex string has length 0, want 64 for common.Hash"},
   153  		{"0x", 64, ""},
   154  		{"0X", 64, ""},
   155  	}
   156  	for _, test := range tests {
   157  		input := `"` + test.Prefix + strings.Repeat("0", test.Size) + `"`
   158  		var v Hash
   159  		err := json.Unmarshal([]byte(input), &v)
   160  		if err == nil {
   161  			if test.Error != "" {
   162  				t.Errorf("%s: error mismatch: have nil, want %q", input, test.Error)
   163  			}
   164  		} else {
   165  			if err.Error() != test.Error {
   166  				t.Errorf("%s: error mismatch: have %q, want %q", input, err, test.Error)
   167  			}
   168  		}
   169  	}
   170  }
   171  
   172  func TestAddressUnmarshalJSON(t *testing.T) {
   173  	tests := []struct {
   174  		Input     string
   175  		ShouldErr bool
   176  		Output    *big.Int
   177  	}{
   178  		{"", true, nil},
   179  		{`""`, true, nil},
   180  		{`"0x"`, true, nil},
   181  		{`"0x00"`, true, nil},
   182  		{`"0xG000000000000000000000000000000000000000"`, true, nil},
   183  		{`"0x0000000000000000000000000000000000000000"`, false, big.NewInt(0)},
   184  		{`"0x0000000000000000000000000000000000000010"`, false, big.NewInt(16)},
   185  	}
   186  	for i, test := range tests {
   187  		var v Address
   188  		err := json.Unmarshal([]byte(test.Input), &v)
   189  		if err != nil && !test.ShouldErr {
   190  			t.Errorf("test #%d: unexpected error: %v", i, err)
   191  		}
   192  		if err == nil {
   193  			if test.ShouldErr {
   194  				t.Errorf("test #%d: expected error, got none", i)
   195  			}
   196  			if got := new(big.Int).SetBytes(v.Bytes()); got.Cmp(test.Output) != 0 {
   197  				t.Errorf("test #%d: address mismatch: have %v, want %v", i, got, test.Output)
   198  			}
   199  		}
   200  	}
   201  }
   202  
   203  func TestAddressHexChecksum(t *testing.T) {
   204  	tests := []struct {
   205  		Input  string
   206  		Output string
   207  	}{
   208  		// Test cases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md#specification
   209  		{"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"},
   210  		{"0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359", "0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359"},
   211  		{"0xdbf03b407c01e7cd3cbea99509d93f8dddc8c6fb", "0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB"},
   212  		{"0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", "0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb"},
   213  		// Ensure that non-standard length input values are handled correctly
   214  		{"0xa", "0x000000000000000000000000000000000000000A"},
   215  		{"0x0a", "0x000000000000000000000000000000000000000A"},
   216  		{"0x00a", "0x000000000000000000000000000000000000000A"},
   217  		{"0x000000000000000000000000000000000000000a", "0x000000000000000000000000000000000000000A"},
   218  	}
   219  	for i, test := range tests {
   220  		output := HexToAddress(test.Input).Hex()
   221  		if output != test.Output {
   222  			t.Errorf("test #%d: failed to match when it should (%s != %s)", i, output, test.Output)
   223  		}
   224  	}
   225  }
   226  
   227  func BenchmarkAddressHex(b *testing.B) {
   228  	testAddr := HexToAddress("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed")
   229  	for n := 0; n < b.N; n++ {
   230  		testAddr.Hex()
   231  	}
   232  }
   233  
   234  // TODO-Klaytn-FailedTest Klaytn doesn't have MixedcaseAddress type
   235  /*
   236  func TestMixedcaseAccount_Address(t *testing.T) {
   237  
   238  	// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md
   239  	// Note: 0X{checksum_addr} is not valid according to spec above
   240  
   241  	var res []struct {
   242  		A     MixedcaseAddress
   243  		Valid bool
   244  	}
   245  	if err := json.Unmarshal([]byte(`[
   246  		{"A" : "0xae967917c465db8578ca9024c205720b1a3651A9", "Valid": false},
   247  		{"A" : "0xAe967917c465db8578ca9024c205720b1a3651A9", "Valid": true},
   248  		{"A" : "0XAe967917c465db8578ca9024c205720b1a3651A9", "Valid": false},
   249  		{"A" : "0x1111111111111111111112222222222223333323", "Valid": true}
   250  		]`), &res); err != nil {
   251  		t.Fatal(err)
   252  	}
   253  
   254  	for _, r := range res {
   255  		if got := r.A.ValidChecksum(); got != r.Valid {
   256  			t.Errorf("Expected checksum %v, got checksum %v, input %v", r.Valid, got, r.A.String())
   257  		}
   258  	}
   259  
   260  	//These should throw exceptions:
   261  	var r2 []MixedcaseAddress
   262  	for _, r := range []string{
   263  		`["0x11111111111111111111122222222222233333"]`,     // Too short
   264  		`["0x111111111111111111111222222222222333332"]`,    // Too short
   265  		`["0x11111111111111111111122222222222233333234"]`,  // Too long
   266  		`["0x111111111111111111111222222222222333332344"]`, // Too long
   267  		`["1111111111111111111112222222222223333323"]`,     // Missing 0x
   268  		`["x1111111111111111111112222222222223333323"]`,    // Missing 0
   269  		`["0xG111111111111111111112222222222223333323"]`,   //Non-hex
   270  	} {
   271  		if err := json.Unmarshal([]byte(r), &r2); err == nil {
   272  			t.Errorf("Expected failure, input %v", r)
   273  		}
   274  
   275  	}
   276  
   277  }
   278  */