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