Summary
FABIRC Source Resolution 6 Describes how the peer node creates and registers the GRPC service, and the next few articles will detail the various services registered by peer. This article describes the Chaincodesupport service, Chaincodesupport Service provides support for Chaincode operations for each peer. Registerchaincodesupport (Peerserver.server ()) is located in/fabric/peer/node/start. The serve function in the go file registers the Chaincodesupport service for Peerserver.
Chaincodesupport's service prototypes and generated go definitions are in/fabric/protos/peer/under Chaincode_shim.proto and Chaincode_shim.pb.go, and the core implementation code is in/fabric In/core/chaincode/chaincode_support.go. The main definition is an RPC Register (stream chaincodemessage) returns (Stream chaincodemessage) {} service. This service implements the exchange of Chaincodemessage type stream data between client and server side. The Grpc Flow service interface for service-side flow data exchange is like the Chaincodesupport_registerserver in/fabric/protos/peer/chaincode_shim.pb.go, in/fabric/core/ In Container/ccintf/ccintf.go, there is a flow interface Chaincodestream for the interior of the container.
The Chaincodesupport service is a global single instance that is defined in Chaincode_support.go, var thechaincodesupport *chaincodesupport. The Chaincodesupport object itself stores a series of configuration values, and the task of receiving and processing client Chaincodemessage type messages is actually entrusted to a handler object.
The generated send and receive data type type
chaincodemessage struct {type chaincodemessage_type
Timestamp *google_protobuf1 . Timestamp
Payload []byte
txid string
Proposal
*signedproposal chaincodeevent * Chaincodeevent
}
//proto Chaincodesupport Services prototype service
Chaincodesupport {
rpc Register (stream Chaincodemessage) returns (Stream chaincodemessage) {}
}
//Generated service-side flow interface
type Chaincodesupport_ RegisterServer Interface {
Send (*chaincodemessage) error
Recv () (*chaincodemessage, error)
Grpc. Clientstream
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 1 2 3-4-5 6 7 8 9 10 11 12 13 14 15 16-17
FSM
The
FSM is the abbreviation for the finite state machine, which is a third-party library used by the Chaincodesupport service and can be downloaded in GITHUB.COM/LOOPLAB/FSM. An FSM considers the transformation of a thing from state A to State B as an event, and can set the timing function that is invoked automatically when entering/leaving a state. Each State event, state, and timing function is represented by a string keyword. Here is a brief introduction to usage:
Create a state machine//three parameters: 1. Default state 2. Define State Event 3. Function FSM that is called when state transitions are defined: = FSM. NEWFSM ("green", FSM). The name of the events{//status event the start state of the event SRC the end state of the event DST//That is: State event warn (Warning event) indicates the state of things from state green to state yellow {Na
Me: "Warn", src: []string{"Green"}, Dst: "Yellow"}, {Name: "Panic", src: []string{"Yellow"}, DST: "Red"}, {Name: "calm", SRC: []string{"Red"}, Dst: "Yellow"},},//state event Call function, here called the timing function. The keyword is separated by ' _ ', and the format is: "Invocation time _ Event or state"//before means that the function, such as "Before_warn", is called before the event or state occurs, which means that the function is called before the Warn//state event occurs.
"Before_yellow" represents the call///function before entering the yellow state. And so on, after means in ... After that, enter indicates the entry ...
At the time, leave said at the time of departure ...//. Fsm. callbacks{the State event function defined within the//FSM, the keyword specifies xxx_event and xxx_state//representing the status of the any or state event "Before_event": Func (E *FSM.E Vent) {FMT. Println ("Before_event")}, "Leave_state": Func (E *fsm. Event) {fmt. Println ("Leave_state")},///According to the State event function defined by the custom State or event "Before_yellow": Func (E *fsm. Event) {fmt. PrIntln ("Before_yellow")}, "Before_warn": Func (E *fsm. Event) {fmt. Println ("Before_warn")},},)//print the current status, the output is the default state green FMT. PRINTLN (FSM.
Current ())//triggers the Warn State event, the status will shift from green to yellow//and trigger "Before_warn", "Before_yellow", "Before_event", "leave_state" functions Fsm. Event ("warn")//print the current state, the output status is yellow FMT. PRINTLN (FSM. Current ())
The 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 The 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 A. 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39-40
Structure Overview:
In any project, the service is centered on what can be provided, and the operation of the Chaincodesupport service (a function that can be called externally) has launch,register,execute,handlechaincodestream,stop. Register
The register function that traces the Chaincodesupport object mount, and ultimately calls the Handlechaincodestream function in/fabric/core/chaincode/handler.go. In the Handlechaincodestream function:
Handler: = Newchaincodesupporthandler (Chaincodesupport, stream)
Handler.processstream ()
1 2 1 2
A handler is created and the handler Processstream function is invoked to process the stream data sent by the client. Both of these functions are implemented in the same file. The two parameters passed in by the Newchaincodesupporthandler function are noteworthy, one is Chaincodesupport, the other is stream. The former is the Chaincodesupport object of the Register service, which is assigned to the Hanlder object member Chaincodesupport, In order for the handler object to handle the service of the Chaincodesupport object when receiving data, the Grpc flow interface of the Register service, which is assigned to the handler object member Chatstream, So that handler can receive data from the client. The following article will also mention this point. Handler
Newchaincodesupporthandler creates and initializes a handler member that has the following initialization:
* Chatstream-grpc Flow Service Interface, is passed in the Register function.
* Chaincodesupport-chaincodesupport itself.
* Nextstate-Status channel.
* FSM-state machine, the reference to the text.
* Policychecker-Policy checker, which will be detailed in the corresponding topic article. Processstream
Processstream with recv logo, | ERRC | Msgavil | Nextstate | Keepalivetimer | Four channels, select three cooperate with each other, forming the reception control of the client message. Then call Handlemessage, Serialsend, and Serialsendasync to process the received message. ERRC-Error channel Msgavil-chaincodemessage Channel Nextstate-contains chaincodemessage channel KeepAliveTime-Heartbeat channel
The process is as follows:
Handlemessage
The way handlemessage processes chaincodemessage data is entirely driven by the state machine FSM in handler. In Newchaincodesupporthandler there is a large section of code that initializes its state machine:
V.FSM = FSM. NEWFSM (CREATEDSTATE,FSM. EVENTS{...},FSM. callbacks{...})
1 1
Status events registered by the state machine FSM are:
//register is defined as Pb.chaincodemessage_register in Fabric/protos/peer/chaincode_shim.pb.go
. String () corresponding to the
//register event represented from state createdstate to state Establishedstate, next.
REGISTER SRC: []string{createdstate}, dst:establishedstate
READY
put_state
del_state
Invoke_chai
COMPLETED
Get_state
get_state_b
get_query_r
get_history
query_state
ERROR
RESPONSE
Init
TRANSACTION
RESPONSE
init
TRANSACTION
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4-5--6 7---8 9--10 11 12 13 14 15 16-17 18 19 20
The state machine FSM is involved in the event state:
Define
createdstate = "created"
establishedstate = "In the form of constants" in/fabric/core/chaincode/handler.go Established "
readystate =" Ready "
endstate =" End "
1 2 3 4 5 1 2 3 4 5
The timing function invoked by the state machine FSM State event is:
//calls Beforeregisterevent before the Register event occurs. "Before_register": Beforeregisterevent "before_completed": Beforecompletedevent "After_get_state" : Aftergetstate "After_get_state_by_range": Aftergetstatebyrange "After_get_query_result": AfterGetQueryResul T "After_get_history_for_key": Aftergethistoryforkey "After_query_state_next": Afterquerystatenext "after_QUERY_ State_close ": Afterquerystateclose" after_put_state ": Enterbusystate" after_del_state ": enterBusy
State "After_invoke_chaincode": enterbusystate//Indicates that enterestablishedstate is invoked when entering the established status.