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