Just these days to have a need to help customers magic change fabric-v0.6, put some hyperchain advanced characteristics of the past, take this opportunity to read before the source in the comb.
The following is the fabric Consensus module source analysis and carding, the code is based on Fabric-v0.6-preview as an example, in 1.0 and subsequent versions are removed PBFT parts, with a better sbft, this part is still in development. directory Structure
You can see the consensus module directory below.
Consensus
├──controller
├──executor
├──helper
│
└──persist
├──noops ├──pbft └──util
└──events
The directory meaning is as follows controller is used to control fabric Select what kind of consensus algorithm, default is Noops. Executor encapsulates the processing of transactions in message queues. Helper provides interface invocation and data persistence interfaces externally. Noops provides a demo of how to write a fabric consensus algorithm. The concrete implementation of PBFT PBFT algorithm. Util implements a peer node to the consensus algorithm of a message channel, and a message queue. Process Overview
Fabric networks interact through a eventloop and consensus algorithm, all of which are propelled by event sniffing in the event loop.
The overall process is shown in the following figure.
Consensus module Interface
Fabric/consensus/consensus.go a method call to provide a consensus module externally.
The core of which is that each algorithm must implement the interface is Consenter.
Type Executionconsumer Interface {
executed (tag interface{})
committed (tag interface{}, Target *PB. Blockchaininfo)
rolledback (Tag interface{})
stateupdated (Tag interface{}, Target *PB. Blockchaininfo)
}
type Consenter interface {
recvmsg (msg *pb. Message, Senderhandle *PB. Peerid) Error
Executionconsumer
}
The concrete implementation of the interface is fabric/consensus/pbft/external.go.
Because the operation of the transaction is asynchronous, it is necessary to manually implement the Executed,committed,rolledback,stateupdated method to monitor the completion of the corresponding action.
The Recvmsg method is used to receive messages from unused peer nodes. Initialize consensus module
The consensus algorithm engine is initialized when the peer is started, and the specific functions initialized are shown below.
Consensus/helper/engine.go
func getengine (coord peer. Messagehandlercoordinator) (peer. Engine, error) {
var err error
Engineonce.do (func () {
Engine = new (Engineimpl)
engine.helper = Newhelper (coord)
Engine.consenter = controller. Newconsenter (Engine.helper)
engine.helper.setConsenter (engine.consenter)
engine.peerendpoint, err = coord . Getpeerendpoint ()
engine.consensusfan = util. Newmessagefan () Go
func () {
logger. Debug (' Starting up message thread for Consenter ') for
msg: = Range Engine.consensusFan.GetOutChannel () {
ENGINE.CONSENTER.RECVMSG (Msg. MSG, MSG. Sender)
}
()}
) return
engine, err
}
The role of Getengine is to initialize the consensus module, while starting a goroutine waiting for the message to enter.
The specific engine.consenter is chosen in the Consensus/controller/controller.go.
Consensus/controller/controller.go
func newconsenter (stack consensus. Stack) consensus. Consenter {
Plugin: = Strings. ToLower (Viper. GetString ("Peer.validator.consensus.plugin"))
If plugin = = "PBFT" {
logger. Infof ("Creating consensus plugin%s", plugin) return
pbft. Getplugin (Stack)
}
logger. Info ("Creating default consensus plugin (noops)") return
Noops. Getnoops (Stack)
}
The default choice is Noops, and if you need to add your own written consensus module, you need to add your own judgment here. Noops just demonstrates how to write a fabric consensus module, not in a production environment.
If PBFT is selected, Consensus/pbft/pbft.go is invoked for initialization.
The Newobcbatch is invoked for PBFT algorithm initialization when the PBFT batch mode is started. PBFT only batch a pattern.
Consensus/pbft/batch.go
func newobcbatch (id uint64, config *viper. Viper, stack consensus. Stack) *obcbatch {
var err error
...
Op.manager = events. Newmanagerimpl ()
op.manager.SetReceiver (OP)
ETF: = events. Newtimerfactoryimpl (op.manager)
op.pbft = newpbftcore (id, config, op, etf)
Op.manager.Start ()
Blockchaininfoblob: = stack. Getblockchaininfoblob ()
Op.externalEventReceiver.manager = Op.manager
...
Return op
}
Newobcbatch mainly did these tasks to initialize the EventLoop message queue. The receiver of the message is set up to handle the corresponding message. Creates a timer that listens for message timeouts. Initializes the PBFT algorithm. Start Message Queuing, continuously monitor the arrival of events and distribute them to recipient processing. Message Processing
The consensus message for fabric is injected through eventloop to the corresponding processing function.
Consensus/util/events/events.go