Fabric 1.0原始碼分析(30) Orderer #BroadcastServer(Broadcast服務端)
# Fabric 1.0原始碼筆記 之 Orderer #BroadcastServer(Broadcast服務端)
## 1、BroadcastServer概述
BroadcastServer相關程式碼在protos/orderer、orderer目錄下。
protos/orderer/ab.pb.go,AtomicBroadcastServer介面定義。
orderer/server.go,go,AtomicBroadcastServer介面實現。
## 2、AtomicBroadcastServer介面定義
### 2.1、AtomicBroadcastServer介面定義
```go
type AtomicBroadcastServer interface {
Broadcast(AtomicBroadcast_BroadcastServer) error
Deliver(AtomicBroadcast_DeliverServer) error
}
//程式碼在protos/orderer/ab.pb.go
···
### 2.2、gRPC相關實現
```go
var _AtomicBroadcast_serviceDesc = grpc.ServiceDesc{
ServiceName: "orderer.AtomicBroadcast",
HandlerType: (*AtomicBroadcastServer)(nil),
Methods: []grpc.MethodDesc{},
Streams: []grpc.StreamDesc{
{
StreamName: "Broadcast",
Handler: _AtomicBroadcast_Broadcast_Handler,
ServerStreams: true,
ClientStreams: true,
},
{
StreamName: "Deliver",
Handler: _AtomicBroadcast_Deliver_Handler,
ServerStreams: true,
ClientStreams: true,
},
},
Metadata: "orderer/ab.proto",
}
func RegisterAtomicBroadcastServer(s *grpc.Server, srv AtomicBroadcastServer) {
s.RegisterService(&_AtomicBroadcast_serviceDesc, srv)
}
func _AtomicBroadcast_Broadcast_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(AtomicBroadcastServer).Broadcast(&atomicBroadcastBroadcastServer{stream})
}
func _AtomicBroadcast_Deliver_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(AtomicBroadcastServer).Deliver(&atomicBroadcastDeliverServer{stream})
}
//程式碼在protos/orderer/ab.pb.go
```
## 3、AtomicBroadcastServer介面實現
### 3.1、server結構體
server結構體:
```go
type server struct {
bh broadcast.Handler
dh deliver.Handler
}
type broadcastSupport struct {
multichain.Manager
broadcast.ConfigUpdateProcessor
}
//程式碼在orderer/server.go
```
broadcast.Handler:
```go
type Handler interface {
Handle(srv ab.AtomicBroadcast_BroadcastServer) error
}
type handlerImpl struct {
sm SupportManager
}
func NewHandlerImpl(sm SupportManager) Handler {
return &handlerImpl{
sm: sm,
}
}
type SupportManager interface {
ConfigUpdateProcessor
GetChain(chainID string) (Support, bool)
}
type ConfigUpdateProcessor interface { //處理通道配置更新
Process(envConfigUpdate *cb.Envelope) (*cb.Envelope, error)
}
//程式碼在orderer/common/broadcast/broadcast.go
```
deliver.Handler:
```go
type Handler interface {
Handle(srv ab.AtomicBroadcast_DeliverServer) error
}
type deliverServer struct {
sm SupportManager
}
type SupportManager interface {
GetChain(chainID string) (Support, bool)
}
//程式碼在orderer/common/deliver/deliver.go
```
### 3.2、server結構體相關方法
```go
//構建server結構體
func NewServer(ml multichain.Manager, signer crypto.LocalSigner) ab.AtomicBroadcastServer
//s.bh.Handle(srv)
func (s *server) Broadcast(srv ab.AtomicBroadcast_BroadcastServer) error
//s.dh.Handle(srv)
func (s *server) Deliver(srv ab.AtomicBroadcast_DeliverServer) error
//程式碼在orderer/server.go
```
func NewServer(ml multichain.Manager, signer crypto.LocalSigner) ab.AtomicBroadcastServer程式碼如下:
```go
func NewServer(ml multichain.Manager, signer crypto.LocalSigner) ab.AtomicBroadcastServer {
s := &server{
dh: deliver.NewHandlerImpl(deliverSupport{Manager: ml}),
bh: broadcast.NewHandlerImpl(broadcastSupport{
Manager: ml,
ConfigUpdateProcessor: configupdate.New(ml.SystemChannelID(), configUpdateSupport{Manager: ml}, signer),
}),
}
return s
}
//程式碼在orderer/server.go
```
### 3.3、Broadcast服務端Broadcast處理流程
Broadcast服務端Broadcast處理流程,即broadcast.handlerImpl.Handle方法。
#### 3.3.1、接收Envelope訊息,並獲取Payload和ChannelHeader
```go
msg, err := srv.Recv() //接收Envelope訊息
payload, err := utils.UnmarshalPayload(msg.Payload) //反序列化獲取Payload
chdr, err := utils.UnmarshalChannelHeader(payload.Header.ChannelHeader) //反序列化獲取ChannelHeader
//程式碼在orderer/common/broadcast/broadcast.go
```
#### 3.3.2、如果訊息型別為channel配置或更新,則使用multichain.Manager處理訊息
```
if chdr.Type == int32(cb.HeaderType_CONFIG_UPDATE) { //如果是channel配置或更新
msg, err = bh.sm.Process(msg) //configupdate.Processor.Process方法
}
//程式碼在orderer/common/broadcast/broadcast.go
```
msg, err = bh.sm.Process(msg)程式碼如下:
```go
func (p *Processor) Process(envConfigUpdate *cb.Envelope) (*cb.Envelope, error) {
channelID, err := channelID(envConfigUpdate) //獲取ChannelHeader.ChannelId
//multichain.Manager.GetChain方法,獲取chainSupport,以及chain是否存在
support, ok := p.manager.GetChain(channelID)
if ok {
//已存在的channel配置,調取multichain.Manager.ProposeConfigUpdate方法
return p.existingChannelConfig(envConfigUpdate, channelID, support)
}
//新channel配置,調取multichain.Manager.NewChannelConfig方法
return p.newChannelConfig(channelID, envConfigUpdate)
}
//程式碼在orderer/configupdate/configupdate.go
```
#### 3.3.3、其他訊息型別或channel訊息處理後,接受訊息並加入排序
```go
support, ok := bh.sm.GetChain(chdr.ChannelId) //獲取chainSupport
_, filterErr := support.Filters().Apply(msg) //filter.RuleSet.Apply方法
//調取Chain.Enqueue方法,接受訊息,加入排序
support.Enqueue(msg)
//程式碼在orderer/common/broadcast/broadcast.go
```
#### 3.3.4、向客戶端傳送響應資訊
```go
err = srv.Send(&ab.BroadcastResponse{Status: cb.Status_SUCCESS})
//程式碼在orderer/common/broadcast/broadcast.go
```
### 3.4、Broadcast服務端Deliver處理流程
Broadcast服務端Deliver處理流程,即deliver.deliverServer.Handle方法。
```go
func (ds *deliverServer) Handle(srv ab.AtomicBroadcast_DeliverServer) error {
for {
//接收客戶端查詢請求
envelope, err := srv.Recv()
payload, err := utils.UnmarshalPayload(envelope.Payload)
chdr, err := utils.UnmarshalChannelHeader(payload.Header.ChannelHeader)
chain, ok := ds.sm.GetChain(chdr.ChannelId)
erroredChan := chain.Errored()
select {
case <-erroredChan:
return sendStatusReply(srv, cb.Status_SERVICE_UNAVAILABLE)
default:
}
lastConfigSequence := chain.Sequence()
sf := sigfilter.New(policies.ChannelReaders, chain.PolicyManager())
result, _ := sf.Apply(envelope)
seekInfo := &ab.SeekInfo{}
err = proto.Unmarshal(payload.Data, seekInfo)
cursor, number := chain.Reader().Iterator(seekInfo.Start)
var stopNum uint64
switch stop := seekInfo.Stop.Type.(type) {
case *ab.SeekPosition_Oldest:
stopNum = number
case *ab.SeekPosition_Newest:
stopNum = chain.Reader().Height() - 1
case *ab.SeekPosition_Specified:
stopNum = stop.Specified.Number
if stopNum < number {
return sendStatusReply(srv, cb.Status_BAD_REQUEST)
}
}
for {
if seekInfo.Behavior == ab.SeekInfo_BLOCK_UNTIL_READY {
select {
case <-erroredChan:
return sendStatusReply(srv, cb.Status_SERVICE_UNAVAILABLE)
case <-cursor.ReadyChan():
}
} else {
select {
case <-cursor.ReadyChan():
default:
return sendStatusReply(srv, cb.Status_NOT_FOUND)
}
}
currentConfigSequence := chain.Sequence()
if currentConfigSequence > lastConfigSequence {
lastConfigSequence = currentConfigSequence
sf := sigfilter.New(policies.ChannelReaders, chain.PolicyManager())
result, _ := sf.Apply(envelope)
}
block, status := cursor.Next()
err := sendBlockReply(srv, block)
if stopNum == block.Header.Number {
break
}
}
err := sendStatusReply(srv, cb.Status_SUCCESS)
}
}
```
網址:http://www.qukuailianxueyuan.io/
欲領取造幣技術與全套虛擬機器資料
區塊鏈技術交流QQ群:756146052 備註:CSDN
尹成學院微信:備註:CSDN
網址:http://www.qukuailianxueyuan.io/
欲領取造幣技術與全套虛擬機器資料
區塊鏈技術交流QQ群:756146052 備註:CSDN
尹成學院微信:備註:CSDN
相關文章
- Fabric 1.0原始碼分析(25) Orderer原始碼
- Fabric 1.0原始碼分析(26)Orderer #ledger(Orderer Ledger)原始碼
- Fabric 1.0原始碼分析(38) Peer #BroadcastClient(Broadcast客戶端)原始碼ASTclient客戶端
- Fabric 1.0原始碼分析(28) Orderer #localconfig(Orderer配置檔案定義)原始碼
- Fabric 1.0原始碼分析(35)Peer #EndorserServer(Endorser服務端)原始碼Server服務端
- Fabric 1.0原始碼分析(29) Orderer #multichain(多鏈支援包)原始碼AI
- Fabric 1.0原始碼分析(13)events(事件服務)原始碼事件
- Fabric 1.0原始碼分析(27) Orderer #configupdate(處理通道配置更新)原始碼
- Fabric 1.0原始碼分析(16)gossip(流言演算法) #GossipServer(Gossip服務端)原始碼Go演算法Server服務端
- Fabric 1.0原始碼分析(31) Peer原始碼
- Fabric 1.0原始碼分析(36) Peer #EndorserClient(Endorser客戶端)原始碼client客戶端
- Fabric 1.0原始碼分析(37) Peer #DeliverClient(Deliver客戶端)原始碼client客戶端
- Fabric 1.0原始碼分析(1)BCCSP(區塊鏈加密服務提供者)原始碼區塊鏈加密
- Fabric 1.0原始碼分析(24)MSP(成員關係服務提供者)原始碼
- Fabric 1.0原始碼分析(3)Chaincode(鏈碼)原始碼AI
- Fabric 1.0原始碼分析(40) Proposal(提案)原始碼
- 區塊鏈教程Fabric1.0原始碼分析流言演算法Gossip服務端二-兄弟連區塊鏈原始碼演算法Go服務端
- Fabric 1.0原始碼分析(14) flogging(Fabric日誌系統)原始碼
- Fabric 1.0原始碼分析(18) Ledger(賬本)原始碼
- Fabric 1.0原始碼分析(43) Tx(Transaction 交易)原始碼
- Fabric 1.0原始碼分析(47)Fabric 1.0.4 go程式碼量統計原始碼Go
- Broadcast原始碼分析AST原始碼
- Fabric 1.0原始碼分析(42)scc(系統鏈碼)原始碼
- Fabric 1.0原始碼分析(39) policy(背書策略)原始碼
- Fabric 1.0原始碼分析(45)gRPC(Fabric中註冊的gRPC Service)原始碼RPC
- 區塊鏈教程Fabric1.0原始碼分析流言演算法Gossip服務端一兄弟連區塊鏈教程區塊鏈原始碼演算法Go服務端
- Fabric 1.0原始碼分析(10)consenter(共識外掛)原始碼
- Fabric 1.0原始碼分析(15)gossip(流言演算法)原始碼Go演算法
- Fabric 1.0原始碼分析(23)LevelDB(KV資料庫)原始碼資料庫
- Fabric 1.0原始碼分析(44)Tx #RWSet(讀寫集)原始碼
- Fabric 1.0原始碼分析(17)gossip(流言演算法) #deliverclient(deliver客戶端)原始碼Go演算法client客戶端
- Fabric 1.0原始碼分析(5)Chaincode(鏈碼)體系總結原始碼AI
- Fabric 1.0原始碼分析(6)configtx(配置交易) #ChannelConfig(通道配置)原始碼
- Fabric 1.0原始碼分析(20) Ledger #idStore(ledgerID資料庫)原始碼資料庫
- Fabric 1.0原始碼分析(41)putils(protos/utils工具包)原始碼
- Fabric 1.0原始碼分析(2) blockfile(區塊檔案儲存)原始碼BloC
- Fabric 1.0原始碼分析(7)configtx(配置交易) #configtxgen(生成通道配置)原始碼
- Fabric 1.0原始碼分析(9)configtx(配置交易)體系介紹原始碼