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 }