github.com/klaytn/klaytn@v1.12.1/crypto/create_address_test.go (about) 1 // Copyright 2019 The klaytn Authors 2 // This file is part of the klaytn library. 3 // 4 // The klaytn 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 klaytn 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 klaytn library. If not, see <http://www.gnu.org/licenses/>. 16 17 package crypto 18 19 import ( 20 "encoding/binary" 21 "fmt" 22 "math/rand" 23 "reflect" 24 "runtime" 25 "strings" 26 "testing" 27 28 "github.com/klaytn/klaytn/common" 29 "github.com/klaytn/klaytn/rlp" 30 ) 31 32 // BenchmarkCreateAddress measures performance of two address generation methods: 33 // createAddressUsingCode: hash(address, nonce, code) 34 // createAddressUsingCodeHash: hash(address, nonce, codeHash) 35 // 36 // This benchmark is created to measure performance difference of hashing twice with shorter data 37 // and hashing once with long data. 38 func BenchmarkCreateAddress(b *testing.B) { 39 addr := common.HexToAddress("333c3310824b7c685133f2bedb2ca4b8b4df633d") 40 nonce := uint64(1023) 41 42 fns := []func(addr common.Address, nonce uint64, code []byte) common.Address{ 43 createAddressUsingCode, 44 createAddressUsingCodeHash, 45 } 46 47 const MaxCodeSize uint = 10 * 1024 48 49 for codeSize := uint(0); codeSize <= MaxCodeSize; codeSize += 640 { 50 code := randCode(codeSize) 51 52 for _, f := range fns { 53 fname := getFunctionName(f) 54 fname = fname[strings.LastIndex(fname, ".")+1:] 55 56 benchName := fmt.Sprintf("%s/%d", fname, codeSize) 57 58 b.Run(benchName, func(b *testing.B) { 59 for i := 0; i < b.N; i++ { 60 _ = f(addr, nonce, code) 61 } 62 }) 63 } 64 } 65 } 66 67 func randCode(codeSize uint) []byte { 68 code := make([]byte, 0, codeSize) 69 rand.Seed(0) 70 r := rand.Uint64() 71 b := make([]byte, 8) 72 binary.LittleEndian.PutUint64(b, r) 73 code = append(code, b...) 74 75 return code 76 } 77 78 func createAddressUsingCodeHash(addr common.Address, nonce uint64, code []byte) common.Address { 79 codeHash := Keccak256Hash(code) 80 81 data, _ := rlp.EncodeToBytes(struct { 82 Addr common.Address 83 nonce uint64 84 codeHash common.Hash 85 }{addr, nonce, codeHash}) 86 87 return common.BytesToAddress(Keccak256(data)[12:]) 88 } 89 90 func createAddressUsingCode(addr common.Address, nonce uint64, code []byte) common.Address { 91 data, _ := rlp.EncodeToBytes(struct { 92 Addr common.Address 93 nonce uint64 94 codeHash []byte 95 }{addr, nonce, code}) 96 97 return common.BytesToAddress(Keccak256(data)[12:]) 98 } 99 100 func getFunctionName(i interface{}) string { 101 return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() 102 }