github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/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.Data == nil || block.Data.Data == nil || len(block.Data.Data) == 0 {
    39  		return "", fmt.Errorf("Failed to find chain ID because the 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  	chdr, err := UnmarshalChannelHeader(payload.Header.ChannelHeader)
    52  	if err != nil {
    53  		return "", err
    54  	}
    55  
    56  	return chdr.ChannelId, nil
    57  }
    58  
    59  // GetMetadataFromBlock retrieves metadata at the specified index.
    60  func GetMetadataFromBlock(block *cb.Block, index cb.BlockMetadataIndex) (*cb.Metadata, error) {
    61  	md := &cb.Metadata{}
    62  	err := proto.Unmarshal(block.Metadata.Metadata[index], md)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  	return md, nil
    67  }
    68  
    69  // GetMetadataFromBlockOrPanic retrieves metadata at the specified index, or panics on error.
    70  func GetMetadataFromBlockOrPanic(block *cb.Block, index cb.BlockMetadataIndex) *cb.Metadata {
    71  	md, err := GetMetadataFromBlock(block, index)
    72  	if err != nil {
    73  		panic(err)
    74  	}
    75  	return md
    76  }
    77  
    78  // GetLastConfigIndexFromBlock retrieves the index of the last config block as encoded in the block metadata
    79  func GetLastConfigIndexFromBlock(block *cb.Block) (uint64, error) {
    80  	md, err := GetMetadataFromBlock(block, cb.BlockMetadataIndex_LAST_CONFIG)
    81  	if err != nil {
    82  		return 0, err
    83  	}
    84  	lc := &cb.LastConfig{}
    85  	err = proto.Unmarshal(md.Value, lc)
    86  	if err != nil {
    87  		return 0, err
    88  	}
    89  	return lc.Index, nil
    90  }
    91  
    92  // GetLastConfigIndexFromBlockOrPanic retrieves the index of the last config block as encoded in the block metadata, or panics on error.
    93  func GetLastConfigIndexFromBlockOrPanic(block *cb.Block) uint64 {
    94  	index, err := GetLastConfigIndexFromBlock(block)
    95  	if err != nil {
    96  		panic(err)
    97  	}
    98  	return index
    99  }
   100  
   101  // GetBlockFromBlockBytes marshals the bytes into Block
   102  func GetBlockFromBlockBytes(blockBytes []byte) (*cb.Block, error) {
   103  	block := &cb.Block{}
   104  	err := proto.Unmarshal(blockBytes, block)
   105  	return block, err
   106  }
   107  
   108  // CopyBlockMetadata copies metadata from one block into another
   109  func CopyBlockMetadata(src *cb.Block, dst *cb.Block) {
   110  	dst.Metadata = src.Metadata
   111  	// Once copied initialize with rest of the
   112  	// required metadata positions.
   113  	InitBlockMetadata(dst)
   114  }
   115  
   116  // InitBlockMetadata copies metadata from one block into another
   117  func InitBlockMetadata(block *cb.Block) {
   118  	if block.Metadata == nil {
   119  		block.Metadata = &cb.BlockMetadata{Metadata: [][]byte{[]byte{}, []byte{}, []byte{}}}
   120  	} else if len(block.Metadata.Metadata) < int(cb.BlockMetadataIndex_TRANSACTIONS_FILTER+1) {
   121  		for i := int(len(block.Metadata.Metadata)); i <= int(cb.BlockMetadataIndex_TRANSACTIONS_FILTER); i++ {
   122  			block.Metadata.Metadata = append(block.Metadata.Metadata, []byte{})
   123  		}
   124  	}
   125  }