Michael.W谈hyperledger Fabric第20期-详细带读Fabric的源码5-orderer节点的solo排序

Michael.W谈hyperledger Fabric第20期-详细带读Fabric的源码5-orderer节点的solo排序


solo模式的源代码文件在orderer/solo/consensus.go中:

	func (ch *chain) main() {
		// 之前讲过Fabric对区块的分割有两个影响条件: 1、区块中的交易数量大于等于我们设定的最大交易数量;2、在交易数量尚未达到设定的最大交易数量时,区块等待的最大时间间隔 
	  	// 创建一个定时器(无缓冲的通道)。用于计算区块等待的最大时间间隔
		var timer <-chan time.Time
	  for {
	    	// for select,用于时刻监听数据通道
			select {
	      	// 监听用于接受交易的通道(交易的类型为*cb.Envelope)
			case msg := <-ch.sendChan:
				// 将获取到的交易进行切割,Ordered方法上面刚刚讲过
				batches, committers, ok, _ := ch.support.BlockCutter().Ordered(msg)
	      if ok && len(batches) == 0 && timer == nil {
	        // 如果得到的是一个空的交易(即这段时间内orderer节点没有获取到任何从客户端提交的交易信息)并且定时器还没有被初始化
	        		// 初始化定时器,其定时时间为Orderer接口的实例化对象中设定的超时时间
					timer = time.After(ch.support.SharedConfig().BatchTimeout())
					continue
				}
				// 如果确实接收到了客户端提交来的交易数据,遍历这些收到的交易数据
				for i, batch := range batches {
	        		// 创建一个新的区块
					block := ch.support.CreateNextBlock(batch)
	        		// 将交易数据和对应的committers写入账本中,完成一个数据持久化的过程
					ch.support.WriteBlock(block, committers[i], nil)
				}
	      		// 如果收到了有效的交易数据,定时器需要置空(重新计时)
				if len(batches) > 0 {
					timer = nil
				}
			case <-timer:
	      		// 如果定时器被触发(定时时间到)
	      		// 置空定时器
				timer = nil
				// 对reciever中先存有的待处理交易数据进行一次切割。Cut方法上面也刚刚讲过:返回待处理队列中的数据,并清空待处理队列状态
				batch, committers := ch.support.BlockCutter().Cut()
				if len(batch) == 0 {
	        		// 如果超时了,同时orderer节点在这期间没有获得客户端传来的任何交易数据
					logger.Warningf("Batch timer expired with no pending requests, this might indicate a bug")
					continue
				}    
	       		// 如果超时了,同时orderer节点在这期间获得了客户端传来的交易数据
				logger.Debugf("Batch timer expired, creating block")
	      		// 创建一个新的区块
				block := ch.support.CreateNextBlock(batch)
	      		// 将交易数据和对应的committers写入账本中,完成一个数据持久化的过程
				ch.support.WriteBlock(block, committers, nil)
			case <-ch.exitChan:
	      		// 如果收到了一个退出信号
				logger.Debugf("Exiting")
	      		// 退出整个监听
				return
			}
		}
	}
	type chain struct {
		support  multichain.ConsenterSupport
	  	// 获得客户端传来的消息通道
		sendChan chan *cb.Envelope
	  	// 退出信号
		exitChan chan struct{}
	}

ps:
本人热爱图灵,热爱中本聪,热爱V神,热爱一切被梨花照过的姑娘。
以下是我个人的公众号,如果有技术问题可以关注我的公众号来跟我交流。
同时我也会在这个公众号上每周更新我的原创文章,喜欢的小伙伴或者老伙计可以支持一下!
如果需要转发,麻烦注明作者。十分感谢!
后现代泼痞浪漫主义奠基人
公众号名称:后现代泼痞浪漫主义奠基人

你可能感兴趣的:(Fabric,Fabric)