github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/protos/utils/blockutils.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  
    22  	"github.com/golang/protobuf/proto"
    23  	cb "github.com/hyperledger/fabric/protos/common"
    24  )
    25  
    26  // GetChainIDFromBlockBytes returns chain ID given byte array which represents the block
    27  func GetChainIDFromBlockBytes(bytes []byte) (string, error) {
    28  	block, err := GetBlockFromBlockBytes(bytes)
    29  	if err != nil {
    30  		return "", err
    31  	}
    32  
    33  	return GetChainIDFromBlock(block)
    34  }
    35  
    36  // GetChainIDFromBlock returns chain ID in the block
    37  func GetChainIDFromBlock(block *cb.Block) (string, error) {
    38  	if block == nil || block.Data == nil || block.Data.Data == nil || len(block.Data.Data) == 0 {
    39  		return "", fmt.Errorf("failed to retrieve channel id - block is empty")
    40  	}
    41  	var err error
    42  	envelope := &cb.Envelope{}
    43  	if err = proto.Unmarshal(block.Data.Data[0], envelope); err != nil {
    44  		return "", fmt.Errorf("error reconstructing envelope(%s)", err)
    45  	}
    46  	payload := &cb.Payload{}
    47  	if err = proto.Unmarshal(envelope.Payload, payload); err != nil {
    48  		return "", fmt.Errorf("error reconstructing payload(%s)", err)
    49  	}
    50  
    51  	if payload.Header == nil {
    52  		return "", fmt.Errorf("failed to retrieve channel id - payload header is empty")
    53  	}
    54  	chdr, err := UnmarshalChannelHeader(payload.Header.ChannelHeader)
    55  	if err != nil {
    56  		return "", err
    57  	}
    58  
    59  	return chdr.ChannelId, nil
    60  }
    61  
    62  // GetMetadataFromBlock retrieves metadata at the specified index.
    63  func GetMetadataFromBlock(block *cb.Block, index cb.BlockMetadataIndex) (*cb.Metadata, error) {
    64  	md := &cb.Metadata{}
    65  	err := proto.Unmarshal(block.Metadata.Metadata[index], md)
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  	return md, nil
    70  }
    71  
    72  // GetMetadataFromBlockOrPanic retrieves metadata at the specified index, or panics on error.
    73  func GetMetadataFromBlockOrPanic(block *cb.Block, index cb.BlockMetadataIndex) *cb.Metadata {
    74  	md, err := GetMetadataFromBlock(block, index)
    75  	if err != nil {
    76  		panic(err)
    77  	}
    78  	return md
    79  }
    80  
    81  // GetLastConfigIndexFromBlock retrieves the index of the last config block as encoded in the block metadata
    82  func GetLastConfigIndexFromBlock(block *cb.Block) (uint64, error) {
    83  	md, err := GetMetadataFromBlock(block, cb.BlockMetadataIndex_LAST_CONFIG)
    84  	if err != nil {
    85  		return 0, err
    86  	}
    87  	lc := &cb.LastConfig{}
    88  	err = proto.Unmarshal(md.Value, lc)
    89  	if err != nil {
    90  		return 0, err
    91  	}
    92  	return lc.Index, nil
    93  }
    94  
    95  // GetLastConfigIndexFromBlockOrPanic retrieves the index of the last config block as encoded in the block metadata, or panics on error.
    96  func GetLastConfigIndexFromBlockOrPanic(block *cb.Block) uint64 {
    97  	index, err := GetLastConfigIndexFromBlock(block)
    98  	if err != nil {
    99  		panic(err)
   100  	}
   101  	return index
   102  }
   103  
   104  // GetBlockFromBlockBytes marshals the bytes into Block
   105  func GetBlockFromBlockBytes(blockBytes []byte) (*cb.Block, error) {
   106  	block := &cb.Block{}
   107  	err := proto.Unmarshal(blockBytes, block)
   108  	return block, err
   109  }
   110  
   111  // CopyBlockMetadata copies metadata from one block into another
   112  func CopyBlockMetadata(src *cb.Block, dst *cb.Block) {
   113  	dst.Metadata = src.Metadata
   114  	// Once copied initialize with rest of the
   115  	// required metadata positions.
   116  	InitBlockMetadata(dst)
   117  }
   118  
   119  // InitBlockMetadata copies metadata from one block into another
   120  func InitBlockMetadata(block *cb.Block) {
   121  	if block.Metadata == nil {
   122  		block.Metadata = &cb.BlockMetadata{Metadata: [][]byte{[]byte{}, []byte{}, []byte{}}}
   123  	} else if len(block.Metadata.Metadata) < int(cb.BlockMetadataIndex_TRANSACTIONS_FILTER+1) {
   124  		for i := int(len(block.Metadata.Metadata)); i <= int(cb.BlockMetadataIndex_TRANSACTIONS_FILTER); i++ {
   125  			block.Metadata.Metadata = append(block.Metadata.Metadata, []byte{})
   126  		}
   127  	}
   128  }