github.com/Hnampk/fabric@v2.1.1+incompatible/gossip/util/privdata.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package util 8 9 import ( 10 "encoding/hex" 11 "fmt" 12 13 "github.com/golang/protobuf/proto" 14 "github.com/hyperledger/fabric-protos-go/gossip" 15 "github.com/hyperledger/fabric-protos-go/ledger/rwset" 16 "github.com/hyperledger/fabric-protos-go/peer" 17 "github.com/hyperledger/fabric/common/util" 18 "github.com/hyperledger/fabric/core/ledger" 19 "github.com/pkg/errors" 20 ) 21 22 // PvtDataCollections data type to encapsulate collections 23 // of private data 24 type PvtDataCollections []*ledger.TxPvtData 25 26 // Marshal encodes private collection into bytes array 27 func (pvt *PvtDataCollections) Marshal() ([][]byte, error) { 28 pvtDataBytes := make([][]byte, 0) 29 for index, each := range *pvt { 30 if each == nil { 31 errMsg := fmt.Sprintf("Mallformed private data payload, rwset index %d is nil", index) 32 return nil, errors.New(errMsg) 33 } 34 pvtBytes, err := proto.Marshal(each.WriteSet) 35 if err != nil { 36 errMsg := fmt.Sprintf("Could not marshal private rwset index %d, due to %s", index, err) 37 return nil, errors.New(errMsg) 38 } 39 // Compose gossip protobuf message with private rwset + index of transaction in the block 40 txSeqInBlock := each.SeqInBlock 41 pvtDataPayload := &gossip.PvtDataPayload{TxSeqInBlock: txSeqInBlock, Payload: pvtBytes} 42 payloadBytes, err := proto.Marshal(pvtDataPayload) 43 if err != nil { 44 errMsg := fmt.Sprintf("Could not marshal private payload with transaction index %d, due to %s", txSeqInBlock, err) 45 return nil, errors.New(errMsg) 46 } 47 48 pvtDataBytes = append(pvtDataBytes, payloadBytes) 49 } 50 return pvtDataBytes, nil 51 } 52 53 // Unmarshal read and unmarshal collection of private data 54 // from given bytes array 55 func (pvt *PvtDataCollections) Unmarshal(data [][]byte) error { 56 for _, each := range data { 57 payload := &gossip.PvtDataPayload{} 58 if err := proto.Unmarshal(each, payload); err != nil { 59 return err 60 } 61 pvtRWSet := &rwset.TxPvtReadWriteSet{} 62 if err := proto.Unmarshal(payload.Payload, pvtRWSet); err != nil { 63 return err 64 } 65 *pvt = append(*pvt, &ledger.TxPvtData{ 66 SeqInBlock: payload.TxSeqInBlock, 67 WriteSet: pvtRWSet, 68 }) 69 } 70 71 return nil 72 } 73 74 // PrivateRWSets creates an aggregated slice of RWSets 75 func PrivateRWSets(rwsets ...PrivateRWSet) [][]byte { 76 var res [][]byte 77 for _, rws := range rwsets { 78 res = append(res, []byte(rws)) 79 } 80 return res 81 } 82 83 // PrivateRWSet contains the bytes of CollectionPvtReadWriteSet 84 type PrivateRWSet []byte 85 86 // Digest returns a deterministic and collision-free representation of the PrivateRWSet 87 func (rws PrivateRWSet) Digest() string { 88 return hex.EncodeToString(util.ComputeSHA256(rws)) 89 } 90 91 // PrivateRWSetWithConfig encapsulates private read-write set 92 // among with relevant to collections config information 93 type PrivateRWSetWithConfig struct { 94 RWSet []PrivateRWSet 95 CollectionConfig *peer.CollectionConfig 96 }