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 }