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

发布于:2021-09-22 00:30:29



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神,热爱一切被梨花照过的姑娘。
以下是我个人的公众号,如果有技术问题可以关注我的公众号来跟我交流。
同时我也会在这个公众号上每周更新我的原创文章,喜欢的小伙伴或者老伙计可以支持一下!
如果需要转发,麻烦注明作者。十分感谢!

公众号名称:后现代泼痞浪漫主义奠基人

相关推荐

最新更新

猜你喜欢