github.com/klaytn/klaytn@v1.12.1/common/types.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.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package common
    22  
    23  import (
    24  	"bytes"
    25  	"encoding/binary"
    26  	"encoding/hex"
    27  	"fmt"
    28  	"math/big"
    29  	"math/rand"
    30  	"reflect"
    31  	"sync/atomic"
    32  	"time"
    33  
    34  	"github.com/klaytn/klaytn/common/hexutil"
    35  	"github.com/klaytn/klaytn/crypto/sha3"
    36  )
    37  
    38  const (
    39  	HashLength           = 32
    40  	ExtHashCounterLength = 7
    41  	ExtHashLength        = HashLength + ExtHashCounterLength
    42  	AddressLength        = 20
    43  	SignatureLength      = 65
    44  )
    45  
    46  var (
    47  	hashT    = reflect.TypeOf(Hash{})
    48  	extHashT = reflect.TypeOf(ExtHash{})
    49  	addressT = reflect.TypeOf(Address{})
    50  )
    51  
    52  var (
    53  	lastPrecompiledContractAddressHex = hexutil.MustDecode("0x00000000000000000000000000000000000003FF")
    54  
    55  	// extHashLastCounter is the counter used to generate the counter for the ExtHash.
    56  	// It starts off the most significant 7 bytes of the timestamp in nanoseconds at program startup.
    57  	// It increments every time a new ExtHash counter is generated.
    58  	//                      [b1 b2 b3 b4 b5 b6 b7 b8] = UnixNano()
    59  	// extHashLastCounter = [00 b1 b2 b3 b4 b5 b6 b7]
    60  	// nextCounter        =    [b1 b2 b3 b4 b5 b6 b7]
    61  	extHashLastCounter = uint64(0)
    62  	// extHashZeroCounter signifies the trie node referred by the ExtHash is actually
    63  	// identified by the regular 32-byte Hash.
    64  	extHashZeroCounter = ExtHashCounter{0, 0, 0, 0, 0, 0, 0}
    65  )
    66  
    67  func init() {
    68  	extHashLastCounter = uint64(time.Now().UnixNano() >> 8)
    69  	if extHashLastCounter == 0 {
    70  		panic("Failed to retrieve current timestamp for ExtHashCounter")
    71  	}
    72  }
    73  
    74  // Hash represents the 32 byte Keccak256 hash of arbitrary data.
    75  type Hash [HashLength]byte
    76  
    77  // BytesToHash sets b to hash.
    78  // If b is larger than len(h), b will be cropped from the left.
    79  func BytesToHash(b []byte) Hash {
    80  	var h Hash
    81  	h.SetBytes(b)
    82  	return h
    83  }
    84  
    85  // BigToHash sets byte representation of b to hash.
    86  // If b is larger than len(h), b will be cropped from the left.
    87  func BigToHash(b *big.Int) Hash { return BytesToHash(b.Bytes()) }
    88  
    89  // HexToHash sets byte representation of s to hash.
    90  // If b is larger than len(h), b will be cropped from the left.
    91  func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) }
    92  
    93  // Bytes gets the byte representation of the underlying hash.
    94  func (h Hash) Bytes() []byte { return h[:] }
    95  
    96  // Big converts a hash to a big integer.
    97  func (h Hash) Big() *big.Int { return new(big.Int).SetBytes(h[:]) }
    98  
    99  // Hex converts a hash to a hex string.
   100  func (h Hash) Hex() string { return hexutil.Encode(h[:]) }
   101  
   102  // TerminalString implements log.TerminalStringer, formatting a string for console
   103  // output during logging.
   104  func (h Hash) TerminalString() string {
   105  	return fmt.Sprintf("%x…%x", h[:3], h[29:])
   106  }
   107  
   108  // String implements the stringer interface and is used also by the logger when
   109  // doing full logging into a file.
   110  func (h Hash) String() string {
   111  	return h.Hex()
   112  }
   113  
   114  // Format implements fmt.Formatter, forcing the byte slice to be formatted as is,
   115  // without going through the stringer interface used for logging.
   116  func (h Hash) Format(s fmt.State, c rune) {
   117  	fmt.Fprintf(s, "%"+string(c), h[:])
   118  }
   119  
   120  // UnmarshalText parses a hash in hex syntax.
   121  func (h *Hash) UnmarshalText(input []byte) error {
   122  	return hexutil.UnmarshalFixedText("Hash", input, h[:])
   123  }
   124  
   125  // UnmarshalJSON parses a hash in hex syntax.
   126  func (h *Hash) UnmarshalJSON(input []byte) error {
   127  	return hexutil.UnmarshalFixedJSON(hashT, input, h[:])
   128  }
   129  
   130  // MarshalText returns the hex representation of h.
   131  func (h Hash) MarshalText() ([]byte, error) {
   132  	return hexutil.Bytes(h[:]).MarshalText()
   133  }
   134  
   135  // SetBytes sets the hash to the value of b.
   136  // If b is larger than len(h), b will be cropped from the left.
   137  func (h *Hash) SetBytes(b []byte) {
   138  	if len(b) > len(h) {
   139  		b = b[len(b)-HashLength:]
   140  	}
   141  
   142  	copy(h[HashLength-len(b):], b)
   143  }
   144  
   145  // Generate implements testing/quick.Generator.
   146  func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value {
   147  	m := rand.Intn(len(h))
   148  	for i := len(h) - 1; i > m; i-- {
   149  		h[i] = byte(rand.Uint32())
   150  	}
   151  	return reflect.ValueOf(h)
   152  }
   153  
   154  // getShardIndex returns the index of the shard.
   155  // The address is arranged in the front or back of the array according to the initialization method.
   156  // And the opposite is zero. In any case, to calculate the various shard index values,
   157  // add both values and shift to calculate the shard index.
   158  func (h Hash) getShardIndex(shardMask int) int {
   159  	data1 := int(h[HashLength-1]) + int(h[0])
   160  	data2 := int(h[HashLength-2]) + int(h[1])
   161  	return ((data2 << 8) + data1) & shardMask
   162  }
   163  
   164  func EmptyHash(h Hash) bool {
   165  	return h == Hash{}
   166  }
   167  
   168  // UnprefixedHash allows marshaling a Hash without 0x prefix.
   169  type UnprefixedHash Hash
   170  
   171  // UnmarshalText decodes the hash from hex. The 0x prefix is optional.
   172  func (h *UnprefixedHash) UnmarshalText(input []byte) error {
   173  	return hexutil.UnmarshalFixedUnprefixedText("UnprefixedHash", input, h[:])
   174  }
   175  
   176  // MarshalText encodes the hash as hex.
   177  func (h UnprefixedHash) MarshalText() ([]byte, error) {
   178  	return []byte(hex.EncodeToString(h[:])), nil
   179  }
   180  
   181  /////////// ExtHash
   182  
   183  type (
   184  	// ExtHash is an extended hash composed of a 32 byte Hash and a 7 byte Counter.
   185  	// ExtHash is used as the reference of Merkle Patricia Trie nodes to enable
   186  	// the KIP-111 live state database pruning. The Hash component shall represent
   187  	// the merkle hash of the node and the Counter component shall differentiate
   188  	// nodes with the same merkle hash.
   189  	ExtHash        [ExtHashLength]byte
   190  	ExtHashCounter [ExtHashCounterLength]byte
   191  )
   192  
   193  // BytesToExtHash converts the byte array b to ExtHash.
   194  // If len(b) is 0 or 32, then b is interpreted as a Hash and zero-extended.
   195  // If len(b) is 39, then b is interpreted as an ExtHash.
   196  // Otherwise, this function panics.
   197  func BytesToExtHash(b []byte) (eh ExtHash) {
   198  	if len(b) == 0 || len(b) == HashLength {
   199  		return BytesToHash(b).ExtendZero()
   200  	} else if len(b) == ExtHashLength {
   201  		eh.SetBytes(b)
   202  		return eh
   203  	} else {
   204  		logger.Crit("Invalid ExtHash bytes", "data", hexutil.Encode(b))
   205  		return ExtHash{}
   206  	}
   207  }
   208  
   209  func BytesToExtHashCounter(b []byte) (counter ExtHashCounter) {
   210  	if len(b) == ExtHashCounterLength {
   211  		copy(counter[:], b)
   212  		return counter
   213  	} else {
   214  		logger.Crit("Invalid ExtHashCounter bytes", "data", hexutil.Encode(b))
   215  		return ExtHashCounter{}
   216  	}
   217  }
   218  
   219  func HexToExtHash(s string) ExtHash { return BytesToExtHash(FromHex(s)) }
   220  
   221  func HexToExtHashCounter(s string) ExtHashCounter { return BytesToExtHashCounter(FromHex(s)) }
   222  
   223  func (n ExtHashCounter) Bytes() []byte { return n[:] }
   224  
   225  func (n ExtHashCounter) Hex() string { return hexutil.Encode(n[:]) }
   226  
   227  func (eh ExtHash) Bytes() []byte { return eh[:] }
   228  
   229  func (eh ExtHash) Hex() string { return hexutil.Encode(eh[:]) }
   230  
   231  func (eh ExtHash) String() string { return eh.Hex() }
   232  
   233  func (eh ExtHash) TerminalString() string {
   234  	return fmt.Sprintf("%x…%x", eh[:3], eh[29:])
   235  }
   236  
   237  func (eh ExtHash) Format(s fmt.State, c rune) {
   238  	fmt.Fprintf(s, "%"+string(c), eh[:])
   239  }
   240  
   241  func (eh *ExtHash) UnmarshalText(input []byte) error {
   242  	return hexutil.UnmarshalFixedText("ExtHash", input, eh[:])
   243  }
   244  
   245  func (eh *ExtHash) UnmarshalJSON(input []byte) error {
   246  	return hexutil.UnmarshalFixedJSON(extHashT, input, eh[:])
   247  }
   248  
   249  func (eh ExtHash) MarshalText() ([]byte, error) {
   250  	return hexutil.Bytes(eh[:]).MarshalText()
   251  }
   252  
   253  // SetBytes sets the ExtHash to the value of b.
   254  // If b is larger than ExtHashLength, b will be cropped from the left.
   255  // If b is smaller than ExtHashLength, b will be right aligned.
   256  func (eh *ExtHash) SetBytes(b []byte) {
   257  	if len(b) > ExtHashLength {
   258  		b = b[len(b)-ExtHashLength:]
   259  	}
   260  
   261  	copy(eh[ExtHashLength-len(b):], b)
   262  }
   263  
   264  func (eh ExtHash) getShardIndex(shardMask int) int {
   265  	return eh.Unextend().getShardIndex(shardMask)
   266  }
   267  
   268  func EmptyExtHash(eh ExtHash) bool {
   269  	return EmptyHash(eh.Unextend())
   270  }
   271  
   272  // Unextend returns the 32 byte Hash component of an ExtHash
   273  func (eh ExtHash) Unextend() (h Hash) {
   274  	copy(h[:], eh[:HashLength])
   275  	return h
   276  }
   277  
   278  // Counter returns the 7 byte counter component of an ExtHash
   279  func (eh ExtHash) Counter() (counter ExtHashCounter) {
   280  	copy(counter[:], eh[HashLength:])
   281  	return counter
   282  }
   283  
   284  // IsZeroExtended returns true if the counter component of an ExtHash is zero.
   285  // A zero counter signifies that the ExtHash is actually a Hash.
   286  func (eh ExtHash) IsZeroExtended() bool {
   287  	return bytes.Equal(eh.Counter().Bytes(), extHashZeroCounter[:])
   288  }
   289  
   290  // ResetExtHashCounterForTest sets the extHashCounter for deterministic testing
   291  func ResetExtHashCounterForTest(counter uint64) {
   292  	atomic.StoreUint64(&extHashLastCounter, counter)
   293  }
   294  
   295  func nextExtHashCounter() ExtHashCounter {
   296  	num := atomic.AddUint64(&extHashLastCounter, 1)
   297  	bin := make([]byte, 8)
   298  	binary.BigEndian.PutUint64(bin, num)
   299  	return BytesToExtHashCounter(bin[1:8])
   300  }
   301  
   302  // extend converts Hash to ExtHash by attaching a given counter
   303  func (h Hash) extend(counter ExtHashCounter) (eh ExtHash) {
   304  	copy(eh[:HashLength], h[:HashLength])
   305  	copy(eh[HashLength:], counter[:])
   306  	return eh
   307  }
   308  
   309  // Extend converts Hash to ExtHash by attaching an auto-generated counter
   310  // Auto-generated counters must be different every time
   311  func (h Hash) Extend() ExtHash {
   312  	counter := nextExtHashCounter()
   313  	eh := h.extend(counter)
   314  	// logger.Trace("extend hash", "exthash", eh.Hex())
   315  	return eh
   316  }
   317  
   318  // ExtendZero converts Hash to ExtHash by attaching the zero counter.
   319  // A zero counter is attached to a 32-byte Hash of Trie nodes,
   320  // later to be unextended back to a Hash.
   321  func (h Hash) ExtendZero() ExtHash {
   322  	return h.extend(extHashZeroCounter)
   323  }
   324  
   325  /////////// Address
   326  
   327  // Address represents the 20 byte address of a Klaytn account.
   328  type Address [AddressLength]byte
   329  
   330  func EmptyAddress(a Address) bool {
   331  	return a == Address{}
   332  }
   333  
   334  // BytesToAddress returns Address with value b.
   335  // If b is larger than len(h), b will be cropped from the left.
   336  func BytesToAddress(b []byte) Address {
   337  	var a Address
   338  	a.SetBytes(b)
   339  	return a
   340  }
   341  func StringToAddress(s string) Address { return BytesToAddress([]byte(s)) }
   342  
   343  // BigToAddress returns Address with byte values of b.
   344  // If b is larger than len(h), b will be cropped from the left.
   345  func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) }
   346  
   347  // HexToAddress returns Address with byte values of s.
   348  // If s is larger than len(h), s will be cropped from the left.
   349  func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) }
   350  
   351  // IsPrecompiledContractAddress returns true if the input address is in the range of precompiled contract addresses.
   352  func IsPrecompiledContractAddress(addr Address) bool {
   353  	if bytes.Compare(addr.Bytes(), lastPrecompiledContractAddressHex) > 0 || addr == (Address{}) {
   354  		return false
   355  	}
   356  	return true
   357  }
   358  
   359  // IsHexAddress verifies whether a string can represent a valid hex-encoded
   360  // Klaytn address or not.
   361  func IsHexAddress(s string) bool {
   362  	if hasHexPrefix(s) {
   363  		s = s[2:]
   364  	}
   365  	return len(s) == 2*AddressLength && isHex(s)
   366  }
   367  
   368  // Bytes gets the string representation of the underlying address.
   369  func (a Address) Bytes() []byte { return a[:] }
   370  
   371  // Hash converts an address to a hash by left-padding it with zeros.
   372  func (a Address) Hash() Hash { return BytesToHash(a[:]) }
   373  
   374  // Hex returns an EIP55-compliant hex string representation of the address.
   375  func (a Address) Hex() string {
   376  	unchecksummed := hex.EncodeToString(a[:])
   377  	sha := sha3.NewKeccak256()
   378  	sha.Write([]byte(unchecksummed))
   379  	hash := sha.Sum(nil)
   380  
   381  	result := []byte(unchecksummed)
   382  	for i := 0; i < len(result); i++ {
   383  		hashByte := hash[i/2]
   384  		if i%2 == 0 {
   385  			hashByte = hashByte >> 4
   386  		} else {
   387  			hashByte &= 0xf
   388  		}
   389  		if result[i] > '9' && hashByte > 7 {
   390  			result[i] -= 32
   391  		}
   392  	}
   393  	return "0x" + string(result)
   394  }
   395  
   396  // String implements fmt.Stringer.
   397  func (a Address) String() string {
   398  	return a.Hex()
   399  }
   400  
   401  // Format implements fmt.Formatter, forcing the byte slice to be formatted as is,
   402  // without going through the stringer interface used for logging.
   403  func (a Address) Format(s fmt.State, c rune) {
   404  	fmt.Fprintf(s, "%"+string(c), a[:])
   405  }
   406  
   407  // SetBytes sets the address to the value of b.
   408  // If b is larger than len(a) it will panic.
   409  func (a *Address) SetBytes(b []byte) {
   410  	if len(b) > len(a) {
   411  		b = b[len(b)-AddressLength:]
   412  	}
   413  	copy(a[AddressLength-len(b):], b)
   414  }
   415  
   416  // SetBytesFromFront sets the address to the value of b.
   417  // If len(b) is larger, take AddressLength bytes from front.
   418  func (a *Address) SetBytesFromFront(b []byte) {
   419  	if len(b) > AddressLength {
   420  		b = b[:AddressLength]
   421  	}
   422  	copy(a[:], b)
   423  }
   424  
   425  // MarshalText returns the hex representation of a.
   426  func (a Address) MarshalText() ([]byte, error) {
   427  	return hexutil.Bytes(a[:]).MarshalText()
   428  }
   429  
   430  // UnmarshalText parses a hash in hex syntax.
   431  func (a *Address) UnmarshalText(input []byte) error {
   432  	return hexutil.UnmarshalFixedText("Address", input, a[:])
   433  }
   434  
   435  // UnmarshalJSON parses a hash in hex syntax.
   436  func (a *Address) UnmarshalJSON(input []byte) error {
   437  	return hexutil.UnmarshalFixedJSON(addressT, input, a[:])
   438  }
   439  
   440  // getShardIndex returns the index of the shard.
   441  // The address is arranged in the front or back of the array according to the initialization method.
   442  // And the opposite is zero. In any case, to calculate the various shard index values,
   443  // add both values and shift to calculate the shard index.
   444  func (a Address) getShardIndex(shardMask int) int {
   445  	data1 := int(a[AddressLength-1]) + int(a[0])
   446  	data2 := int(a[AddressLength-2]) + int(a[1])
   447  	return ((data2 << 8) + data1) & shardMask
   448  }
   449  
   450  // UnprefixedAddress allows marshaling an Address without 0x prefix.
   451  type UnprefixedAddress Address
   452  
   453  // UnmarshalText decodes the address from hex. The 0x prefix is optional.
   454  func (a *UnprefixedAddress) UnmarshalText(input []byte) error {
   455  	return hexutil.UnmarshalFixedUnprefixedText("UnprefixedAddress", input, a[:])
   456  }
   457  
   458  // MarshalText encodes the address as hex.
   459  func (a UnprefixedAddress) MarshalText() ([]byte, error) {
   460  	return []byte(hex.EncodeToString(a[:])), nil
   461  }
   462  
   463  type ConnType int
   464  
   465  const ConnTypeUndefined ConnType = -1
   466  
   467  const (
   468  	CONSENSUSNODE ConnType = iota
   469  	ENDPOINTNODE
   470  	PROXYNODE
   471  	BOOTNODE
   472  	UNKNOWNNODE // For error case
   473  )
   474  
   475  func (ct ConnType) Valid() bool {
   476  	if int(ct) > 255 {
   477  		return false
   478  	}
   479  	return true
   480  }
   481  
   482  func (ct ConnType) String() string {
   483  	s := fmt.Sprintf("%d", int(ct))
   484  	return s
   485  }