github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/core/tx_cacher.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 12:09:34</date>
    10  //</624342618599329792>
    11  
    12  
    13  package core
    14  
    15  import (
    16  	"runtime"
    17  
    18  	"github.com/ethereum/go-ethereum/core/types"
    19  )
    20  
    21  //sender cacher是一个并发事务发送方恢复器和缓存器。
    22  var senderCacher = newTxSenderCacher(runtime.NumCPU())
    23  
    24  //txsendercacherRequest是一个用于恢复事务发送方的请求,
    25  //特定的签名方案并将其缓存到事务本身中。
    26  //
    27  //inc字段定义每次恢复后要跳过的事务数,
    28  //它用于向不同的线程提供相同的基础输入数组,但
    29  //确保他们快速处理早期事务。
    30  type txSenderCacherRequest struct {
    31  	signer types.Signer
    32  	txs    []*types.Transaction
    33  	inc    int
    34  }
    35  
    36  //txsendercacher是用于并发ecrecover事务的辅助结构
    37  //来自后台线程上数字签名的发件人。
    38  type txSenderCacher struct {
    39  	threads int
    40  	tasks   chan *txSenderCacherRequest
    41  }
    42  
    43  //newtxsendercacher创建一个新的事务发送方后台缓存并启动
    44  //gomaxprocs在构建时允许的处理goroutine的数量。
    45  func newTxSenderCacher(threads int) *txSenderCacher {
    46  	cacher := &txSenderCacher{
    47  		tasks:   make(chan *txSenderCacherRequest, threads),
    48  		threads: threads,
    49  	}
    50  	for i := 0; i < threads; i++ {
    51  		go cacher.cache()
    52  	}
    53  	return cacher
    54  }
    55  
    56  //缓存是一个无限循环,缓存来自各种形式的事务发送者
    57  //数据结构。
    58  func (cacher *txSenderCacher) cache() {
    59  	for task := range cacher.tasks {
    60  		for i := 0; i < len(task.txs); i += task.inc {
    61  			types.Sender(task.signer, task.txs[i])
    62  		}
    63  	}
    64  }
    65  
    66  //recover从一批事务中恢复发送方并缓存它们
    67  //回到相同的数据结构中。没有进行验证,也没有
    68  //对无效签名的任何反应。这取决于以后调用代码。
    69  func (cacher *txSenderCacher) recover(signer types.Signer, txs []*types.Transaction) {
    70  //如果没有什么可恢复的,中止
    71  	if len(txs) == 0 {
    72  		return
    73  	}
    74  //确保我们拥有有意义的任务规模并计划恢复
    75  	tasks := cacher.threads
    76  	if len(txs) < tasks*4 {
    77  		tasks = (len(txs) + 3) / 4
    78  	}
    79  	for i := 0; i < tasks; i++ {
    80  		cacher.tasks <- &txSenderCacherRequest{
    81  			signer: signer,
    82  			txs:    txs[i:],
    83  			inc:    tasks,
    84  		}
    85  	}
    86  }
    87  
    88  //恢复器块从批处理中恢复发件人并缓存它们。
    89  //回到相同的数据结构中。没有进行验证,也没有
    90  //对无效签名的任何反应。这取决于以后调用代码。
    91  func (cacher *txSenderCacher) recoverFromBlocks(signer types.Signer, blocks []*types.Block) {
    92  	count := 0
    93  	for _, block := range blocks {
    94  		count += len(block.Transactions())
    95  	}
    96  	txs := make([]*types.Transaction, 0, count)
    97  	for _, block := range blocks {
    98  		txs = append(txs, block.Transactions()...)
    99  	}
   100  	cacher.recover(signer, txs)
   101  }
   102