本文主要分析fabric共识模块的流程,方便自己添加新的共识模块。
主要涉及的函数和调用流程如下图所示:
一般来讲,如果要添加新的共识算法,主要实现这个接口:
type Chain interface {
// NOTE: The kafka consenter has not been updated to perform the revalidation
// checks conditionally. For now, Order/Configure are essentially Enqueue as before.
// This does not cause data inconsistency, but it wastes cycles and will be required
// to properly support the ConfigUpdate concept once introduced
// Once this is done, the MsgClassification logic in msgprocessor should return error
// for non ConfigUpdate/Normal msg types
// Order accepts a message which has been processed at a given configSeq.
// If the configSeq advances, it is the responsibility of the consenter
// to revalidate and potentially discard the message
// The consenter may return an error, indicating the message was not accepted
Order(env *cb.Envelope, configSeq uint64) error
// Configure accepts a message which reconfigures the channel and will
// trigger an update to the configSeq if committed. The configuration must have
// been triggered by a ConfigUpdate message. If the config sequence advances,
// it is the responsibility of the consenter to recompute the resulting config,
// discarding the message if the reconfiguration is no longer valid.
// The consenter may return an error, indicating the message was not accepted
Configure(config *cb.Envelope, configSeq uint64) error
// WaitReady blocks waiting for consenter to be ready for accepting new messages.
// This is useful when consenter needs to temporarily block ingress messages so
// that in-flight messages can be consumed. It could return error if consenter is
// in erroneous states. If this blocking behavior is not desired, consenter could
// simply return nil.
WaitReady() error
// Errored returns a channel which will close when an error has occurred.
// This is especially useful for the Deliver client, who must terminate waiting
// clients when the consenter is not up to date.
Errored() <-chan struct{}
// Start should allocate whatever resources are needed for staying up to date with the chain.
// Typically, this involves creating a thread which reads from the ordering source, passes those
// messages to a block cutter, and writes the resulting blocks to the ledger.
Start()
// Halt frees the resources which were allocated for this Chain.
Halt()
}
例如要添加raft共识算法: 一般来讲order接口把peer发送过来的envelope送到raft的proposeC 这个channel里,经过raft共识后,从commitC 这个channel里取出共识后的entry,然后再chain.start()里把消息进行Cut(),然后生成block并写入ledger.