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 }