github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/blockchain_insert.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:34</date> 10 //</624450077649276928> 11 12 13 package core 14 15 import ( 16 "time" 17 18 "github.com/ethereum/go-ethereum/common" 19 "github.com/ethereum/go-ethereum/common/mclock" 20 "github.com/ethereum/go-ethereum/core/types" 21 "github.com/ethereum/go-ethereum/log" 22 ) 23 24 //插件在块插入时跟踪和报告。 25 type insertStats struct { 26 queued, processed, ignored int 27 usedGas uint64 28 lastIndex int 29 startTime mclock.AbsTime 30 } 31 32 //statsreportlimit是导入和导出期间的时间限制,在此之后我们 33 //总是打印出进度。这避免了用户想知道发生了什么。 34 const statsReportLimit = 8 * time.Second 35 36 //如果处理了一些块,则报告将打印统计信息 37 //或者自上一条消息以来已经过了几秒钟。 38 func (st *insertStats) report(chain []*types.Block, index int, cache common.StorageSize) { 39 //获取批的计时 40 var ( 41 now = mclock.Now() 42 elapsed = time.Duration(now) - time.Duration(st.startTime) 43 ) 44 //如果我们在到达的批或报告周期的最后一个块,请记录 45 if index == len(chain)-1 || elapsed >= statsReportLimit { 46 //计算此段中的事务数 47 var txs int 48 for _, block := range chain[st.lastIndex : index+1] { 49 txs += len(block.Transactions()) 50 } 51 end := chain[index] 52 53 //组装日志上下文并将其发送到记录器 54 context := []interface{}{ 55 "blocks", st.processed, "txs", txs, "mgas", float64(st.usedGas) / 1000000, 56 "elapsed", common.PrettyDuration(elapsed), "mgasps", float64(st.usedGas) * 1000 / float64(elapsed), 57 "number", end.Number(), "hash", end.Hash(), 58 } 59 if timestamp := time.Unix(end.Time().Int64(), 0); time.Since(timestamp) > time.Minute { 60 context = append(context, []interface{}{"age", common.PrettyAge(timestamp)}...) 61 } 62 context = append(context, []interface{}{"cache", cache}...) 63 64 if st.queued > 0 { 65 context = append(context, []interface{}{"queued", st.queued}...) 66 } 67 if st.ignored > 0 { 68 context = append(context, []interface{}{"ignored", st.ignored}...) 69 } 70 log.Info("Imported new chain segment", context...) 71 72 //将报告的统计数据转发到下一节 73 *st = insertStats{startTime: now, lastIndex: index + 1} 74 } 75 } 76 77 //插入器是在链导入过程中提供帮助的助手。 78 type insertIterator struct { 79 chain types.Blocks 80 results <-chan error 81 index int 82 validator Validator 83 } 84 85 //newinsertiator基于给定的块创建一个新的迭代器,它是 86 //假定为连续链。 87 func newInsertIterator(chain types.Blocks, results <-chan error, validator Validator) *insertIterator { 88 return &insertIterator{ 89 chain: chain, 90 results: results, 91 index: -1, 92 validator: validator, 93 } 94 } 95 96 //next返回迭代器中的下一个块,以及任何可能的验证 97 //该块出错。当结束时,它将返回(零,零)。 98 func (it *insertIterator) next() (*types.Block, error) { 99 if it.index+1 >= len(it.chain) { 100 it.index = len(it.chain) 101 return nil, nil 102 } 103 it.index++ 104 if err := <-it.results; err != nil { 105 return it.chain[it.index], err 106 } 107 return it.chain[it.index], it.validator.ValidateBody(it.chain[it.index]) 108 } 109 110 //current返回正在处理的当前块。 111 func (it *insertIterator) current() *types.Block { 112 if it.index < 0 || it.index+1 >= len(it.chain) { 113 return nil 114 } 115 return it.chain[it.index] 116 } 117 118 //previous返回正在处理的前一个块,或者为nil 119 func (it *insertIterator) previous() *types.Block { 120 if it.index < 1 { 121 return nil 122 } 123 return it.chain[it.index-1] 124 } 125 126 //首先返回IT中的第一个块。 127 func (it *insertIterator) first() *types.Block { 128 return it.chain[0] 129 } 130 131 //remaining返回剩余块的数目。 132 func (it *insertIterator) remaining() int { 133 return len(it.chain) - it.index 134 } 135 136 //processed返回已处理的块数。 137 func (it *insertIterator) processed() int { 138 return it.index + 1 139 } 140