Section2.3.5 stack
Stack是consensus里一个主要的接口, 包含了consensus.go里定义的除自身和Consenter之外的所有接口.
在pbft内部, 也定义了一个与此对应的接口innerStack, 用于内部使用.
对于Stack里一些方法的介绍在前面各部分已经提到了一部分, 这里综合地描述下Stack的各个部分.
Stack is the set of stack-facing methods available to the consensus plugin
type Stack interface {
NetworkStack
SecurityUtils
Executor
LegacyExecutor
LedgerManager
ReadOnlyLedger
StatePersistor
}Vars
虽然在注释中地提到了在consensus/helper/handler.go中定义的ConsensusHandler也实现了Stack, 但是查找代码会发现, 其实只有consensus/helper/helper.go中定义的Helper实现了Stack. 所以下面只会讨论Helper.
Helper contains the reference to the peer's MessageHandlerCoordinator
type Helper struct {
consenter consensus.Consenter
coordinator peer.MessageHandlerCoordinator
secOn bool
valid bool // Whether we believe the state is up to date
secHelper crypto.Peer
curBatch []*pb.Transaction // TODO, remove after issue 579
curBatchErrs []*pb.TransactionResult // TODO, remove after issue 579
persist.Helper
executor consensus.Executor
}consenter
consenterconsenter成员变量的类型为Consenter, 即consensus里定义的Consenter接口. 注意到, Stack并不包括Consenter.
在Engine的初始化过程中, 会先创建Helper, 然后用Helper作为参数创建obcBatch(即Consenter的实现), 然后再把obcBatch赋给Helper, 整个过程下来, Helper和Consenter两者会互相包含对方作为成员变量.
Helper中仅使用consenter来实现ExecutionConsumer接口. 在ExecutionConsumer已经提到. 这些方法将会在executor中被使用.
coordinator
coordinatorcoordinator类型为peer.MessageHandlerCoordinator, 定义在peer中, 是初始化engine时的唯一参数, 也可以说是和节点联系的途径. engine使用它获得PeerEndpoint(本节点), 然后将它传给Helper用于初始化, 自己并不保存这个变量. Helper会保存该变量, 并用它来实现了NetworkStack里的功能, 包括获取节点信息, 广播, 单播, 另外还包括获取区块链长度.
ConsensusHandler中也保存了该类型变量, 但并未使用.
该变量也会被传给executor, 将在后面提到.
secOn
secOn一个类型为bool的简单变量, 判断是否对消息进行加密(Sign&Verify), 由配置信息决定取值, 且在程序运行时不再改变.
valid
valid类型为bool. 用于标记是否当前状态是否为最新.
Whether we believe the state is up to date
用于实现LedgerManager接口, 在LedgerManager中已经提到了使用情况.
在engine执行func ProcessTransactionMsg()和Helper执行func UpdateState()时会检查valid的取值.
secHelper
secHelper用于实现SecurityUtils接口, 类型为crypto.Peer, 通过调用coordinator.GetSecHelper()生成. 在消息传递前会进行加密, 接收后进行解密.
实际上, 在pbft中并没有直接使用SecurityUtils接口, 而是进行了封装, 但主要还是SecurityUtils接口部分.
curBatch & curBatchErrs
curBatch & curBatchErrs类型分别为[]*pb.Transaction和[]*pb.TransactionResult, 储存Tx和Tx的执行结果, 注释中提到, 这两个变量将被删去.
这两个变量将会在记录产生的Tx, 然后通过func CommitTxBatch()提交.
persist.Helper
persist.HelperHelp继承了persist.Helper, 用于实现StatePersistor接口. 暂不关注.
executor
executor类型为consensus.Executor, 用于实现Executor接口. 通过executor.NewImpl(h, h, mhc)初始化, 这里, h是指Helper自身, mhc则是前面提到的peer.MessageHandlerCoordinator. 这里mhc是作为statetransfer.PartialStack使用的, statetransfer定义在core/peer/statetransfer/statetransfer.go, 用来转换状态, 具体地, 在executor里除了调用外func Start(), func Halt()只是在收到stateUpdateEvent后调用func SyncToTarget()来将区块链更新到目标状态.
前面已经提到过executor的执行模式, 即把所有消息都发送给event.Manager后经event.Manager调用func ProcessEvent()来执行. executor也不具体规定执行动作, 而只是把Helper里的方法(即接口ExecutionConsumer和LegacyExecutor)封装起来, 实际动作是在后面那两个接口里定义的.
func
前面围绕着各个变量已经提到了一部分函数, 除此之外还定义了一些函数用于实现接口.
Executor
Executor针对这个接口, 主要函数是通过executor实现的, 特别的, Executor定义了func Start(), func Halt(), 而这两个函数对于Helper来说是无意义的, 所以, 仅仅为了实现Executor, Helper中定义了两个空函数, 这样做只是为了满足编程语言规范. 另外, executor实际实现了Executor接口, 所以也定义了这两个函数, 在这两个函数中分别启动和停止event.Manager和statetransfer. 而executor本身的启动, 是在func setConsenter()里进行的. (由于Helper的初始化后紧接着就执行了func setConsenter(), 所以也可以理解成Helper初始化时边启动了executor.
ReadOnlyLedger
ReadOnlyLedger这些部分是由Helper和Ledger等交互实现的, 在ReadOnlyLedger里已经提到, 不再重复.
Last updated
Was this helpful?