github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/protos/utils/commonutils.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 utils 18 19 import ( 20 "fmt" 21 "time" 22 23 cb "github.com/hyperledger/fabric/protos/common" 24 pb "github.com/hyperledger/fabric/protos/peer" 25 26 "errors" 27 28 "github.com/golang/protobuf/proto" 29 "github.com/golang/protobuf/ptypes/timestamp" 30 "github.com/hyperledger/fabric/common/crypto" 31 ) 32 33 // MarshalOrPanic serializes a protobuf message and panics if this operation fails. 34 func MarshalOrPanic(pb proto.Message) []byte { 35 data, err := proto.Marshal(pb) 36 if err != nil { 37 panic(err) 38 } 39 return data 40 } 41 42 // Marshal serializes a protobuf message. 43 func Marshal(pb proto.Message) ([]byte, error) { 44 return proto.Marshal(pb) 45 } 46 47 // CreateNonceOrPanic generates a nonce using the common/crypto package 48 // and panics if this operation fails. 49 func CreateNonceOrPanic() []byte { 50 nonce, err := crypto.GetRandomNonce() 51 if err != nil { 52 panic(fmt.Errorf("Cannot generate random nonce: %s", err)) 53 } 54 return nonce 55 } 56 57 // CreateNonce generates a nonce using the common/crypto package. 58 func CreateNonce() ([]byte, error) { 59 nonce, err := crypto.GetRandomNonce() 60 if err != nil { 61 return nil, fmt.Errorf("Cannot generate random nonce: %s", err) 62 } 63 return nonce, nil 64 } 65 66 // UnmarshalPayloadOrPanic unmarshals bytes to a Payload structure or panics on error 67 func UnmarshalPayloadOrPanic(encoded []byte) *cb.Payload { 68 payload, err := UnmarshalPayload(encoded) 69 if err != nil { 70 panic(fmt.Errorf("Error unmarshaling data to payload: %s", err)) 71 } 72 return payload 73 } 74 75 // UnmarshalPayload unmarshals bytes to a Payload structure 76 func UnmarshalPayload(encoded []byte) (*cb.Payload, error) { 77 payload := &cb.Payload{} 78 err := proto.Unmarshal(encoded, payload) 79 if err != nil { 80 return nil, err 81 } 82 return payload, err 83 } 84 85 // UnmarshalEnvelopeOrPanic unmarshals bytes to an Envelope structure or panics on error 86 func UnmarshalEnvelopeOrPanic(encoded []byte) *cb.Envelope { 87 envelope, err := UnmarshalEnvelope(encoded) 88 if err != nil { 89 panic(fmt.Errorf("Error unmarshaling data to envelope: %s", err)) 90 } 91 return envelope 92 } 93 94 // UnmarshalEnvelope unmarshals bytes to an Envelope structure 95 func UnmarshalEnvelope(encoded []byte) (*cb.Envelope, error) { 96 envelope := &cb.Envelope{} 97 err := proto.Unmarshal(encoded, envelope) 98 if err != nil { 99 return nil, err 100 } 101 return envelope, err 102 } 103 104 // UnmarshalEnvelopeOfType unmarshals an envelope of the specified type, including 105 // the unmarshaling the payload data 106 func UnmarshalEnvelopeOfType(envelope *cb.Envelope, headerType cb.HeaderType, message proto.Message) (*cb.ChannelHeader, error) { 107 payload, err := UnmarshalPayload(envelope.Payload) 108 if err != nil { 109 return nil, err 110 } 111 112 if payload.Header == nil { 113 return nil, fmt.Errorf("Envelope must have a Header") 114 } 115 116 chdr, err := UnmarshalChannelHeader(payload.Header.ChannelHeader) 117 if err != nil { 118 return nil, fmt.Errorf("Invalid ChannelHeader") 119 } 120 121 if chdr.Type != int32(headerType) { 122 return nil, fmt.Errorf("Not a tx of type %v", headerType) 123 } 124 125 if err = proto.Unmarshal(payload.Data, message); err != nil { 126 return nil, fmt.Errorf("Error unmarshaling message for type %v: %s", headerType, err) 127 } 128 129 return chdr, nil 130 } 131 132 // ExtractEnvelopeOrPanic retrieves the requested envelope from a given block and unmarshals it -- it panics if either of these operation fail. 133 func ExtractEnvelopeOrPanic(block *cb.Block, index int) *cb.Envelope { 134 envelope, err := ExtractEnvelope(block, index) 135 if err != nil { 136 panic(err) 137 } 138 return envelope 139 } 140 141 // ExtractEnvelope retrieves the requested envelope from a given block and unmarshals it. 142 func ExtractEnvelope(block *cb.Block, index int) (*cb.Envelope, error) { 143 envelopeCount := len(block.Data.Data) 144 if index < 0 || index >= envelopeCount { 145 return nil, fmt.Errorf("Envelope index out of bounds") 146 } 147 marshaledEnvelope := block.Data.Data[index] 148 envelope, err := GetEnvelopeFromBlock(marshaledEnvelope) 149 if err != nil { 150 return nil, fmt.Errorf("Block data does not carry an envelope at index %d: %s", index, err) 151 } 152 return envelope, nil 153 } 154 155 // ExtractPayloadOrPanic retrieves the payload of a given envelope and unmarshals it -- it panics if either of these operations fail. 156 func ExtractPayloadOrPanic(envelope *cb.Envelope) *cb.Payload { 157 payload, err := ExtractPayload(envelope) 158 if err != nil { 159 panic(err) 160 } 161 return payload 162 } 163 164 // ExtractPayload retrieves the payload of a given envelope and unmarshals it. 165 func ExtractPayload(envelope *cb.Envelope) (*cb.Payload, error) { 166 payload := &cb.Payload{} 167 if err := proto.Unmarshal(envelope.Payload, payload); err != nil { 168 return nil, fmt.Errorf("Envelope does not carry a Payload: %s", err) 169 } 170 return payload, nil 171 } 172 173 // MakeChannelHeader creates a ChannelHeader. 174 func MakeChannelHeader(headerType cb.HeaderType, version int32, chainID string, epoch uint64) *cb.ChannelHeader { 175 return &cb.ChannelHeader{ 176 Type: int32(headerType), 177 Version: version, 178 Timestamp: ×tamp.Timestamp{ 179 Seconds: time.Now().Unix(), 180 Nanos: 0, 181 }, 182 ChannelId: chainID, 183 Epoch: epoch, 184 } 185 } 186 187 // MakeSignatureHeader creates a SignatureHeader. 188 func MakeSignatureHeader(serializedCreatorCertChain []byte, nonce []byte) *cb.SignatureHeader { 189 return &cb.SignatureHeader{ 190 Creator: serializedCreatorCertChain, 191 Nonce: nonce, 192 } 193 } 194 195 func SetTxID(channelHeader *cb.ChannelHeader, signatureHeader *cb.SignatureHeader) error { 196 txid, err := ComputeProposalTxID( 197 signatureHeader.Nonce, 198 signatureHeader.Creator, 199 ) 200 if err != nil { 201 return err 202 } 203 channelHeader.TxId = txid 204 return nil 205 } 206 207 // MakePayloadHeader creates a Payload Header. 208 func MakePayloadHeader(ch *cb.ChannelHeader, sh *cb.SignatureHeader) *cb.Header { 209 return &cb.Header{ 210 ChannelHeader: MarshalOrPanic(ch), 211 SignatureHeader: MarshalOrPanic(sh), 212 } 213 } 214 215 // NewSignatureHeaderOrPanic returns a signature header and panics on error. 216 func NewSignatureHeaderOrPanic(signer crypto.LocalSigner) *cb.SignatureHeader { 217 if signer == nil { 218 panic(errors.New("Invalid signer. Must be different from nil.")) 219 } 220 221 signatureHeader, err := signer.NewSignatureHeader() 222 if err != nil { 223 panic(fmt.Errorf("Failed generating a new SignatureHeader [%s]", err)) 224 } 225 return signatureHeader 226 } 227 228 // SignOrPanic signs a message and panics on error. 229 func SignOrPanic(signer crypto.LocalSigner, msg []byte) []byte { 230 if signer == nil { 231 panic(errors.New("Invalid signer. Must be different from nil.")) 232 } 233 234 sigma, err := signer.Sign(msg) 235 if err != nil { 236 panic(fmt.Errorf("Failed generting signature [%s]", err)) 237 } 238 return sigma 239 } 240 241 // UnmarshalChannelHeader returns a ChannelHeader from bytes 242 func UnmarshalChannelHeader(bytes []byte) (*cb.ChannelHeader, error) { 243 chdr := &cb.ChannelHeader{} 244 err := proto.Unmarshal(bytes, chdr) 245 if err != nil { 246 return nil, fmt.Errorf("UnmarshalChannelHeader failed, err %s", err) 247 } 248 249 return chdr, nil 250 } 251 252 // UnmarshalChaincodeID returns a ChaincodeID from bytes 253 func UnmarshalChaincodeID(bytes []byte) (*pb.ChaincodeID, error) { 254 ccid := &pb.ChaincodeID{} 255 err := proto.Unmarshal(bytes, ccid) 256 if err != nil { 257 return nil, fmt.Errorf("UnmarshalChaincodeID failed, err %s", err) 258 } 259 260 return ccid, nil 261 }