github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/bench_test.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2015 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package core 26 27 import ( 28 "crypto/ecdsa" 29 "io/ioutil" 30 "math/big" 31 "os" 32 "testing" 33 34 "github.com/ethereum/go-ethereum/common" 35 "github.com/ethereum/go-ethereum/common/math" 36 "github.com/ethereum/go-ethereum/consensus/ethash" 37 "github.com/ethereum/go-ethereum/core/rawdb" 38 "github.com/ethereum/go-ethereum/core/types" 39 "github.com/ethereum/go-ethereum/core/vm" 40 "github.com/ethereum/go-ethereum/crypto" 41 "github.com/ethereum/go-ethereum/ethdb" 42 "github.com/ethereum/go-ethereum/params" 43 ) 44 45 func BenchmarkInsertChain_empty_memdb(b *testing.B) { 46 benchInsertChain(b, false, nil) 47 } 48 func BenchmarkInsertChain_empty_diskdb(b *testing.B) { 49 benchInsertChain(b, true, nil) 50 } 51 func BenchmarkInsertChain_valueTx_memdb(b *testing.B) { 52 benchInsertChain(b, false, genValueTx(0)) 53 } 54 func BenchmarkInsertChain_valueTx_diskdb(b *testing.B) { 55 benchInsertChain(b, true, genValueTx(0)) 56 } 57 func BenchmarkInsertChain_valueTx_100kB_memdb(b *testing.B) { 58 benchInsertChain(b, false, genValueTx(100*1024)) 59 } 60 func BenchmarkInsertChain_valueTx_100kB_diskdb(b *testing.B) { 61 benchInsertChain(b, true, genValueTx(100*1024)) 62 } 63 func BenchmarkInsertChain_uncles_memdb(b *testing.B) { 64 benchInsertChain(b, false, genUncles) 65 } 66 func BenchmarkInsertChain_uncles_diskdb(b *testing.B) { 67 benchInsertChain(b, true, genUncles) 68 } 69 func BenchmarkInsertChain_ring200_memdb(b *testing.B) { 70 benchInsertChain(b, false, genTxRing(200)) 71 } 72 func BenchmarkInsertChain_ring200_diskdb(b *testing.B) { 73 benchInsertChain(b, true, genTxRing(200)) 74 } 75 func BenchmarkInsertChain_ring1000_memdb(b *testing.B) { 76 benchInsertChain(b, false, genTxRing(1000)) 77 } 78 func BenchmarkInsertChain_ring1000_diskdb(b *testing.B) { 79 benchInsertChain(b, true, genTxRing(1000)) 80 } 81 82 var ( 83 //这是基准使用的Genesis块的内容。 84 benchRootKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 85 benchRootAddr = crypto.PubkeyToAddress(benchRootKey.PublicKey) 86 benchRootFunds = math.BigPow(2, 100) 87 ) 88 89 // 90 //值传输事务,每个事务中有n个字节的额外数据 91 //块。 92 func genValueTx(nbytes int) func(int, *BlockGen) { 93 return func(i int, gen *BlockGen) { 94 toaddr := common.Address{} 95 data := make([]byte, nbytes) 96 gas, _ := IntrinsicGas(data, false, false) 97 tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(benchRootAddr), toaddr, big.NewInt(1), gas, nil, data), types.HomesteadSigner{}, benchRootKey) 98 gen.AddTx(tx) 99 } 100 } 101 102 var ( 103 ringKeys = make([]*ecdsa.PrivateKey, 1000) 104 ringAddrs = make([]common.Address, len(ringKeys)) 105 ) 106 107 func init() { 108 ringKeys[0] = benchRootKey 109 ringAddrs[0] = benchRootAddr 110 for i := 1; i < len(ringKeys); i++ { 111 ringKeys[i], _ = crypto.GenerateKey() 112 ringAddrs[i] = crypto.PubkeyToAddress(ringKeys[i].PublicKey) 113 } 114 } 115 116 //Gentxring返回一个以环形方式发送乙醚的块生成器 117 //在N个帐户中。这是在状态数据库中创建n个条目 118 //并用许多小事务填充块。 119 func genTxRing(naccounts int) func(int, *BlockGen) { 120 from := 0 121 return func(i int, gen *BlockGen) { 122 gas := CalcGasLimit(gen.PrevBlock(i - 1)) 123 for { 124 gas -= params.TxGas 125 if gas < params.TxGas { 126 break 127 } 128 to := (from + 1) % naccounts 129 tx := types.NewTransaction( 130 gen.TxNonce(ringAddrs[from]), 131 ringAddrs[to], 132 benchRootFunds, 133 params.TxGas, 134 nil, 135 nil, 136 ) 137 tx, _ = types.SignTx(tx, types.HomesteadSigner{}, ringKeys[from]) 138 gen.AddTx(tx) 139 from = to 140 } 141 } 142 } 143 144 // 145 func genUncles(i int, gen *BlockGen) { 146 if i >= 6 { 147 b2 := gen.PrevBlock(i - 6).Header() 148 b2.Extra = []byte("foo") 149 gen.AddUncle(b2) 150 b3 := gen.PrevBlock(i - 6).Header() 151 b3.Extra = []byte("bar") 152 gen.AddUncle(b3) 153 } 154 } 155 156 func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) { 157 //在内存或临时目录中创建数据库。 158 var db ethdb.Database 159 if !disk { 160 db = ethdb.NewMemDatabase() 161 } else { 162 dir, err := ioutil.TempDir("", "eth-core-bench") 163 if err != nil { 164 b.Fatalf("cannot create temporary directory: %v", err) 165 } 166 defer os.RemoveAll(dir) 167 db, err = ethdb.NewLDBDatabase(dir, 128, 128) 168 if err != nil { 169 b.Fatalf("cannot create temporary database: %v", err) 170 } 171 defer db.Close() 172 } 173 174 //使用提供的块生成B.N块链 175 //发电机功能。 176 gspec := Genesis{ 177 Config: params.TestChainConfig, 178 Alloc: GenesisAlloc{benchRootAddr: {Balance: benchRootFunds}}, 179 } 180 genesis := gspec.MustCommit(db) 181 chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, b.N, gen) 182 183 //给插入新链条计时。 184 //状态和块存储在同一个数据库中。 185 chainman, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}) 186 defer chainman.Stop() 187 b.ReportAllocs() 188 b.ResetTimer() 189 if i, err := chainman.InsertChain(chain); err != nil { 190 b.Fatalf("insert error (block %d): %v\n", i, err) 191 } 192 } 193 194 func BenchmarkChainRead_header_10k(b *testing.B) { 195 benchReadChain(b, false, 10000) 196 } 197 func BenchmarkChainRead_full_10k(b *testing.B) { 198 benchReadChain(b, true, 10000) 199 } 200 func BenchmarkChainRead_header_100k(b *testing.B) { 201 benchReadChain(b, false, 100000) 202 } 203 func BenchmarkChainRead_full_100k(b *testing.B) { 204 benchReadChain(b, true, 100000) 205 } 206 func BenchmarkChainRead_header_500k(b *testing.B) { 207 benchReadChain(b, false, 500000) 208 } 209 func BenchmarkChainRead_full_500k(b *testing.B) { 210 benchReadChain(b, true, 500000) 211 } 212 func BenchmarkChainWrite_header_10k(b *testing.B) { 213 benchWriteChain(b, false, 10000) 214 } 215 func BenchmarkChainWrite_full_10k(b *testing.B) { 216 benchWriteChain(b, true, 10000) 217 } 218 func BenchmarkChainWrite_header_100k(b *testing.B) { 219 benchWriteChain(b, false, 100000) 220 } 221 func BenchmarkChainWrite_full_100k(b *testing.B) { 222 benchWriteChain(b, true, 100000) 223 } 224 func BenchmarkChainWrite_header_500k(b *testing.B) { 225 benchWriteChain(b, false, 500000) 226 } 227 func BenchmarkChainWrite_full_500k(b *testing.B) { 228 benchWriteChain(b, true, 500000) 229 } 230 231 //makechainforbench写入给定数量的头或空块/收据 232 //进入数据库。 233 func makeChainForBench(db ethdb.Database, full bool, count uint64) { 234 var hash common.Hash 235 for n := uint64(0); n < count; n++ { 236 header := &types.Header{ 237 Coinbase: common.Address{}, 238 Number: big.NewInt(int64(n)), 239 ParentHash: hash, 240 Difficulty: big.NewInt(1), 241 UncleHash: types.EmptyUncleHash, 242 TxHash: types.EmptyRootHash, 243 ReceiptHash: types.EmptyRootHash, 244 } 245 hash = header.Hash() 246 247 rawdb.WriteHeader(db, header) 248 rawdb.WriteCanonicalHash(db, hash, n) 249 rawdb.WriteTd(db, hash, n, big.NewInt(int64(n+1))) 250 251 if full || n == 0 { 252 block := types.NewBlockWithHeader(header) 253 rawdb.WriteBody(db, hash, n, block.Body()) 254 rawdb.WriteReceipts(db, hash, n, nil) 255 } 256 } 257 } 258 259 func benchWriteChain(b *testing.B, full bool, count uint64) { 260 for i := 0; i < b.N; i++ { 261 dir, err := ioutil.TempDir("", "eth-chain-bench") 262 if err != nil { 263 b.Fatalf("cannot create temporary directory: %v", err) 264 } 265 db, err := ethdb.NewLDBDatabase(dir, 128, 1024) 266 if err != nil { 267 b.Fatalf("error opening database at %v: %v", dir, err) 268 } 269 makeChainForBench(db, full, count) 270 db.Close() 271 os.RemoveAll(dir) 272 } 273 } 274 275 func benchReadChain(b *testing.B, full bool, count uint64) { 276 dir, err := ioutil.TempDir("", "eth-chain-bench") 277 if err != nil { 278 b.Fatalf("cannot create temporary directory: %v", err) 279 } 280 defer os.RemoveAll(dir) 281 282 db, err := ethdb.NewLDBDatabase(dir, 128, 1024) 283 if err != nil { 284 b.Fatalf("error opening database at %v: %v", dir, err) 285 } 286 makeChainForBench(db, full, count) 287 db.Close() 288 289 b.ReportAllocs() 290 b.ResetTimer() 291 292 for i := 0; i < b.N; i++ { 293 db, err := ethdb.NewLDBDatabase(dir, 128, 1024) 294 if err != nil { 295 b.Fatalf("error opening database at %v: %v", dir, err) 296 } 297 chain, err := NewBlockChain(db, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}) 298 if err != nil { 299 b.Fatalf("error creating chain: %v", err) 300 } 301 302 for n := uint64(0); n < count; n++ { 303 header := chain.GetHeaderByNumber(n) 304 if full { 305 hash := header.Hash() 306 rawdb.ReadBody(db, hash, n) 307 rawdb.ReadReceipts(db, hash, n) 308 } 309 } 310 chain.Stop() 311 db.Close() 312 } 313 }