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: &timestamp.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  }