github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/orderer/common/deliver/deliver.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package deliver 18 19 import ( 20 "github.com/hyperledger/fabric/common/policies" 21 "github.com/hyperledger/fabric/orderer/common/filter" 22 "github.com/hyperledger/fabric/orderer/common/sigfilter" 23 "github.com/hyperledger/fabric/orderer/ledger" 24 cb "github.com/hyperledger/fabric/protos/common" 25 ab "github.com/hyperledger/fabric/protos/orderer" 26 "github.com/op/go-logging" 27 28 "github.com/golang/protobuf/proto" 29 "github.com/hyperledger/fabric/protos/utils" 30 ) 31 32 var logger = logging.MustGetLogger("orderer/common/deliver") 33 34 // Handler defines an interface which handles Deliver requests 35 type Handler interface { 36 Handle(srv ab.AtomicBroadcast_DeliverServer) error 37 } 38 39 // SupportManager provides a way for the Handler to look up the Support for a chain 40 type SupportManager interface { 41 GetChain(chainID string) (Support, bool) 42 } 43 44 // Support provides the backing resources needed to support deliver on a chain 45 type Support interface { 46 // PolicyManager returns the current policy manager as specified by the chain configuration 47 PolicyManager() policies.Manager 48 49 // Reader returns the chain Reader for the chain 50 Reader() ledger.Reader 51 } 52 53 type deliverServer struct { 54 sm SupportManager 55 } 56 57 // NewHandlerImpl creates an implementation of the Handler interface 58 func NewHandlerImpl(sm SupportManager) Handler { 59 return &deliverServer{ 60 sm: sm, 61 } 62 } 63 64 func (ds *deliverServer) Handle(srv ab.AtomicBroadcast_DeliverServer) error { 65 logger.Debugf("Starting new deliver loop") 66 for { 67 logger.Debugf("Attempting to read seek info message") 68 envelope, err := srv.Recv() 69 if err != nil { 70 if logger.IsEnabledFor(logging.WARNING) { 71 logger.Warningf("Error reading from stream: %s", err) 72 } 73 return err 74 } 75 payload := &cb.Payload{} 76 if err = proto.Unmarshal(envelope.Payload, payload); err != nil { 77 if logger.IsEnabledFor(logging.WARNING) { 78 logger.Warningf("Received an envelope with no payload: %s", err) 79 } 80 return sendStatusReply(srv, cb.Status_BAD_REQUEST) 81 } 82 83 if payload.Header == nil { 84 if logger.IsEnabledFor(logging.WARNING) { 85 logger.Warningf("Malformed envelope received with bad header") 86 } 87 return sendStatusReply(srv, cb.Status_BAD_REQUEST) 88 } 89 90 chdr, err := utils.UnmarshalChannelHeader(payload.Header.ChannelHeader) 91 if err != nil { 92 logger.Error(err) 93 return err 94 } 95 96 chain, ok := ds.sm.GetChain(chdr.ChannelId) 97 if !ok { 98 // Note, we log this at DEBUG because SDKs will poll waiting for channels to be created 99 // So we would expect our log to be somewhat flooded with these 100 if logger.IsEnabledFor(logging.DEBUG) { 101 logger.Debugf("Client request for channel %s not found", chdr.ChannelId) 102 } 103 return sendStatusReply(srv, cb.Status_NOT_FOUND) 104 } 105 106 sf := sigfilter.New(policies.ChannelReaders, chain.PolicyManager()) 107 result, _ := sf.Apply(envelope) 108 if result != filter.Forward { 109 if logger.IsEnabledFor(logging.WARNING) { 110 logger.Warningf("Received unauthorized deliver request for channel %s", chdr.ChannelId) 111 } 112 return sendStatusReply(srv, cb.Status_FORBIDDEN) 113 } 114 115 seekInfo := &ab.SeekInfo{} 116 if err = proto.Unmarshal(payload.Data, seekInfo); err != nil { 117 if logger.IsEnabledFor(logging.WARNING) { 118 logger.Warningf("Received a signed deliver request with malformed seekInfo payload: %s", err) 119 } 120 return sendStatusReply(srv, cb.Status_BAD_REQUEST) 121 } 122 123 if seekInfo.Start == nil || seekInfo.Stop == nil { 124 if logger.IsEnabledFor(logging.WARNING) { 125 logger.Warningf("Received seekInfo message with missing start or stop %v, %v", seekInfo.Start, seekInfo.Stop) 126 } 127 return sendStatusReply(srv, cb.Status_BAD_REQUEST) 128 } 129 130 if logger.IsEnabledFor(logging.DEBUG) { 131 logger.Debugf("Received seekInfo (%p) %v for chain %s", seekInfo, seekInfo, chdr.ChannelId) 132 } 133 134 cursor, number := chain.Reader().Iterator(seekInfo.Start) 135 var stopNum uint64 136 switch stop := seekInfo.Stop.Type.(type) { 137 case *ab.SeekPosition_Oldest: 138 stopNum = number 139 case *ab.SeekPosition_Newest: 140 stopNum = chain.Reader().Height() - 1 141 case *ab.SeekPosition_Specified: 142 stopNum = stop.Specified.Number 143 } 144 145 for { 146 if seekInfo.Behavior == ab.SeekInfo_BLOCK_UNTIL_READY { 147 <-cursor.ReadyChan() 148 } else { 149 select { 150 case <-cursor.ReadyChan(): 151 default: 152 return sendStatusReply(srv, cb.Status_NOT_FOUND) 153 } 154 } 155 156 block, status := cursor.Next() 157 if status != cb.Status_SUCCESS { 158 logger.Errorf("Error reading from channel, cause was: %v", status) 159 return sendStatusReply(srv, status) 160 } 161 162 if logger.IsEnabledFor(logging.DEBUG) { 163 logger.Debugf("Delivering block for (%p) channel: %s", seekInfo, chdr.ChannelId) 164 } 165 if err := sendBlockReply(srv, block); err != nil { 166 return err 167 } 168 169 if stopNum == block.Header.Number { 170 break 171 } 172 } 173 174 if err := sendStatusReply(srv, cb.Status_SUCCESS); err != nil { 175 return err 176 } 177 if logger.IsEnabledFor(logging.DEBUG) { 178 logger.Debugf("Done delivering for (%p), waiting for new SeekInfo", seekInfo) 179 } 180 } 181 } 182 183 func sendStatusReply(srv ab.AtomicBroadcast_DeliverServer, status cb.Status) error { 184 return srv.Send(&ab.DeliverResponse{ 185 Type: &ab.DeliverResponse_Status{Status: status}, 186 }) 187 188 } 189 190 func sendBlockReply(srv ab.AtomicBroadcast_DeliverServer, block *cb.Block) error { 191 return srv.Send(&ab.DeliverResponse{ 192 Type: &ab.DeliverResponse_Block{Block: block}, 193 }) 194 }