github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/evmcore/bench_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 evmcore 18 19 import ( 20 "crypto/ecdsa" 21 "io/ioutil" 22 "math/big" 23 "os" 24 "testing" 25 26 "github.com/unicornultrafoundation/go-u2u/common" 27 "github.com/unicornultrafoundation/go-u2u/common/math" 28 "github.com/unicornultrafoundation/go-u2u/core/rawdb" 29 "github.com/unicornultrafoundation/go-u2u/core/state" 30 "github.com/unicornultrafoundation/go-u2u/core/types" 31 "github.com/unicornultrafoundation/go-u2u/crypto" 32 "github.com/unicornultrafoundation/go-u2u/ethdb" 33 "github.com/unicornultrafoundation/go-u2u/params" 34 ) 35 36 func BenchmarkInsertChain_empty_memdb(b *testing.B) { 37 benchInsertChain(b, false, nil) 38 } 39 func BenchmarkInsertChain_empty_diskdb(b *testing.B) { 40 benchInsertChain(b, true, nil) 41 } 42 func BenchmarkInsertChain_valueTx_memdb(b *testing.B) { 43 benchInsertChain(b, false, genValueTx(0)) 44 } 45 func BenchmarkInsertChain_valueTx_diskdb(b *testing.B) { 46 benchInsertChain(b, true, genValueTx(0)) 47 } 48 func BenchmarkInsertChain_valueTx_100kB_memdb(b *testing.B) { 49 benchInsertChain(b, false, genValueTx(100*1024)) 50 } 51 func BenchmarkInsertChain_valueTx_100kB_diskdb(b *testing.B) { 52 benchInsertChain(b, true, genValueTx(100*1024)) 53 } 54 func BenchmarkInsertChain_ring200_memdb(b *testing.B) { 55 benchInsertChain(b, false, genTxRing(200)) 56 } 57 func BenchmarkInsertChain_ring200_diskdb(b *testing.B) { 58 benchInsertChain(b, true, genTxRing(200)) 59 } 60 func BenchmarkInsertChain_ring1000_memdb(b *testing.B) { 61 benchInsertChain(b, false, genTxRing(1000)) 62 } 63 func BenchmarkInsertChain_ring1000_diskdb(b *testing.B) { 64 benchInsertChain(b, true, genTxRing(1000)) 65 } 66 67 var ( 68 // This is the content of the genesis block used by the benchmarks. 69 benchRootKey = FakeKey(1) 70 benchRootAddr = crypto.PubkeyToAddress(benchRootKey.PublicKey) 71 benchRootFunds = math.BigPow(2, 100) 72 ) 73 74 // genValueTx returns a block generator that includes a single 75 // value-transfer transaction with n bytes of extra data in each 76 // block. 77 func genValueTx(nbytes int) func(int, *BlockGen) { 78 return func(i int, gen *BlockGen) { 79 toaddr := common.Address{} 80 data := make([]byte, nbytes) 81 gas, _ := IntrinsicGas(data, types.AccessList{}, false) 82 tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(benchRootAddr), toaddr, big.NewInt(1), gas, nil, data), types.HomesteadSigner{}, benchRootKey) 83 gen.AddTx(tx) 84 } 85 } 86 87 var ( 88 ringKeys = make([]*ecdsa.PrivateKey, 1000) 89 ringAddrs = make([]common.Address, len(ringKeys)) 90 ) 91 92 func init() { 93 ringKeys[0] = benchRootKey 94 ringAddrs[0] = benchRootAddr 95 for i := 1; i < len(ringKeys); i++ { 96 ringKeys[i], _ = crypto.GenerateKey() 97 ringAddrs[i] = crypto.PubkeyToAddress(ringKeys[i].PublicKey) 98 } 99 } 100 101 // genTxRing returns a block generator that sends ether in a ring 102 // among n accounts. This is creates n entries in the state database 103 // and fills the blocks with many small transactions. 104 func genTxRing(naccounts int) func(int, *BlockGen) { 105 from := 0 106 return func(i int, gen *BlockGen) { 107 block := gen.PrevBlock(i - 1) 108 gas := block.GasLimit 109 for { 110 gas -= params.TxGas 111 if gas < params.TxGas { 112 break 113 } 114 to := (from + 1) % naccounts 115 tx := types.NewTransaction( 116 gen.TxNonce(ringAddrs[from]), 117 ringAddrs[to], 118 benchRootFunds, 119 params.TxGas, 120 nil, 121 nil, 122 ) 123 tx, _ = types.SignTx(tx, types.HomesteadSigner{}, ringKeys[from]) 124 gen.AddTx(tx) 125 from = to 126 } 127 } 128 } 129 130 func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) { 131 // Create the database in memory or in a temporary directory. 132 var db ethdb.Database 133 if !disk { 134 db = rawdb.NewMemoryDatabase() 135 } else { 136 dir, err := ioutil.TempDir("", "eth-core-bench") 137 if err != nil { 138 b.Fatalf("cannot create temporary directory: %v", err) 139 } 140 defer os.RemoveAll(dir) 141 db, err = rawdb.NewLevelDBDatabase(dir, 128, 128, "", false) 142 if err != nil { 143 b.Fatalf("cannot create temporary database: %v", err) 144 } 145 defer db.Close() 146 } 147 148 // Generate a chain of b.N blocks using the supplied block 149 // generator function. 150 // state 151 statedb, err := state.New(common.Hash{}, state.NewDatabase(db), nil) 152 if err != nil { 153 b.Fatalf("cannot create statedb: %v", err) 154 } 155 genesisBlock := MustApplyFakeGenesis(statedb, FakeGenesisTime, map[common.Address]*big.Int{ 156 benchRootAddr: benchRootFunds, 157 }) 158 genesisBlock.GasLimit = 1000000 159 160 // Time the insertion of the new chain. 161 // State and blocks are stored in the same DB. 162 b.ReportAllocs() 163 b.ResetTimer() 164 165 _, _, _ = GenerateChain(nil, genesisBlock, db, b.N, gen) 166 }