github.com/sykesm/fabric@v1.1.0-preview.0.20200129034918-2aa12b1a0181/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  }