github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric/common/collection/collectionparse.go (about)

     1  package collection
     2  
     3  import (
     4  	"encoding/json"
     5  	"github.com/golang/protobuf/proto"
     6  	"github.com/hellobchain/third_party/hyperledger/fabric/common/policydsl"
     7  	pb "github.com/hyperledger/fabric-protos-go/peer"
     8  	"github.com/pkg/errors"
     9  )
    10  
    11  type endorsementPolicy struct {
    12  	ChannelConfigPolicy string `json:"channelConfigPolicy,omitempty"`
    13  	SignaturePolicy     string `json:"signaturePolicy,omitempty"`
    14  }
    15  type collectionConfigJson struct {
    16  	Name              string             `json:"name"`
    17  	Policy            string             `json:"policy"`
    18  	RequiredPeerCount *int32             `json:"requiredPeerCount"`
    19  	MaxPeerCount      *int32             `json:"maxPeerCount"`
    20  	BlockToLive       uint64             `json:"blockToLive"`
    21  	MemberOnlyRead    bool               `json:"memberOnlyRead"`
    22  	MemberOnlyWrite   bool               `json:"memberOnlyWrite"`
    23  	EndorsementPolicy *endorsementPolicy `json:"endorsementPolicy,omitempty"`
    24  }
    25  
    26  // GetCollectionConfigFromBytes getCollectionConfig retrieves the collection configuration
    27  // from the supplied byte array; the byte array must contain a
    28  // json-formatted array of collectionConfigJson elements
    29  func GetCollectionConfigFromBytes(cconfBytes []byte) (*pb.CollectionConfigPackage, []byte, error) {
    30  	cconf := &[]collectionConfigJson{}
    31  	err := json.Unmarshal(cconfBytes, cconf)
    32  	if err != nil {
    33  		return nil, nil, errors.Wrap(err, "could not parse the collection configuration")
    34  	}
    35  
    36  	ccarray := make([]*pb.CollectionConfig, 0, len(*cconf))
    37  	for _, cconfitem := range *cconf {
    38  		p, err := policydsl.FromString(cconfitem.Policy)
    39  		if err != nil {
    40  			return nil, nil, errors.WithMessagef(err, "invalid policy %s", cconfitem.Policy)
    41  		}
    42  
    43  		cpc := &pb.CollectionPolicyConfig{
    44  			Payload: &pb.CollectionPolicyConfig_SignaturePolicy{
    45  				SignaturePolicy: p,
    46  			},
    47  		}
    48  
    49  		var ep *pb.ApplicationPolicy
    50  		if cconfitem.EndorsementPolicy != nil {
    51  			signaturePolicy := cconfitem.EndorsementPolicy.SignaturePolicy
    52  			channelConfigPolicy := cconfitem.EndorsementPolicy.ChannelConfigPolicy
    53  			ep, err = getApplicationPolicy(signaturePolicy, channelConfigPolicy)
    54  			if err != nil {
    55  				return nil, nil, errors.WithMessagef(err, "invalid endorsement policy [%#v]", cconfitem.EndorsementPolicy)
    56  			}
    57  		}
    58  
    59  		// Set default requiredPeerCount and MaxPeerCount if not specified in json
    60  		requiredPeerCount := int32(0)
    61  		maxPeerCount := int32(1)
    62  		if cconfitem.RequiredPeerCount != nil {
    63  			requiredPeerCount = *cconfitem.RequiredPeerCount
    64  		}
    65  		if cconfitem.MaxPeerCount != nil {
    66  			maxPeerCount = *cconfitem.MaxPeerCount
    67  		}
    68  
    69  		cc := &pb.CollectionConfig{
    70  			Payload: &pb.CollectionConfig_StaticCollectionConfig{
    71  				StaticCollectionConfig: &pb.StaticCollectionConfig{
    72  					Name:              cconfitem.Name,
    73  					MemberOrgsPolicy:  cpc,
    74  					RequiredPeerCount: requiredPeerCount,
    75  					MaximumPeerCount:  maxPeerCount,
    76  					BlockToLive:       cconfitem.BlockToLive,
    77  					MemberOnlyRead:    cconfitem.MemberOnlyRead,
    78  					MemberOnlyWrite:   cconfitem.MemberOnlyWrite,
    79  					EndorsementPolicy: ep,
    80  				},
    81  			},
    82  		}
    83  
    84  		ccarray = append(ccarray, cc)
    85  	}
    86  
    87  	ccp := &pb.CollectionConfigPackage{Config: ccarray}
    88  	ccpBytes, err := proto.Marshal(ccp)
    89  	return ccp, ccpBytes, err
    90  }
    91  
    92  // GetCollectionConfigFromBytesForJava getCollectionConfig retrieves the collection configuration
    93  // from the supplied byte array; the byte array must contain a
    94  // json-formatted array of collectionConfigJson elements
    95  func GetCollectionConfigFromBytesForJava(cconfBytes []byte) (*pb.CollectionConfigPackage, []byte, error) {
    96  	cconf := &[]collectionConfigJson{}
    97  	err := json.Unmarshal(cconfBytes, cconf)
    98  	if err != nil {
    99  		return nil, nil, errors.Wrap(err, "could not parse the collection configuration")
   100  	}
   101  
   102  	ccarray := make([]*pb.CollectionConfig, 0, len(*cconf))
   103  	for _, cconfitem := range *cconf {
   104  		p, err := policydsl.PolicyParseJava(cconfitem.Policy)
   105  		if err != nil {
   106  			return nil, nil, errors.WithMessagef(err, "invalid policy %s", cconfitem.Policy)
   107  		}
   108  
   109  		cpc := &pb.CollectionPolicyConfig{
   110  			Payload: &pb.CollectionPolicyConfig_SignaturePolicy{
   111  				SignaturePolicy: p,
   112  			},
   113  		}
   114  
   115  		var ep *pb.ApplicationPolicy
   116  		if cconfitem.EndorsementPolicy != nil {
   117  			signaturePolicy := cconfitem.EndorsementPolicy.SignaturePolicy
   118  			channelConfigPolicy := cconfitem.EndorsementPolicy.ChannelConfigPolicy
   119  			ep, err = getApplicationPolicy(signaturePolicy, channelConfigPolicy)
   120  			if err != nil {
   121  				return nil, nil, errors.WithMessagef(err, "invalid endorsement policy [%#v]", cconfitem.EndorsementPolicy)
   122  			}
   123  		}
   124  
   125  		// Set default requiredPeerCount and MaxPeerCount if not specified in json
   126  		requiredPeerCount := int32(0)
   127  		maxPeerCount := int32(1)
   128  		if cconfitem.RequiredPeerCount != nil {
   129  			requiredPeerCount = *cconfitem.RequiredPeerCount
   130  		}
   131  		if cconfitem.MaxPeerCount != nil {
   132  			maxPeerCount = *cconfitem.MaxPeerCount
   133  		}
   134  
   135  		cc := &pb.CollectionConfig{
   136  			Payload: &pb.CollectionConfig_StaticCollectionConfig{
   137  				StaticCollectionConfig: &pb.StaticCollectionConfig{
   138  					Name:              cconfitem.Name,
   139  					MemberOrgsPolicy:  cpc,
   140  					RequiredPeerCount: requiredPeerCount,
   141  					MaximumPeerCount:  maxPeerCount,
   142  					BlockToLive:       cconfitem.BlockToLive,
   143  					MemberOnlyRead:    cconfitem.MemberOnlyRead,
   144  					MemberOnlyWrite:   cconfitem.MemberOnlyWrite,
   145  					EndorsementPolicy: ep,
   146  				},
   147  			},
   148  		}
   149  
   150  		ccarray = append(ccarray, cc)
   151  	}
   152  
   153  	ccp := &pb.CollectionConfigPackage{Config: ccarray}
   154  	ccpBytes, err := proto.Marshal(ccp)
   155  	return ccp, ccpBytes, err
   156  }
   157  
   158  // GetCollectionConfigFromBytesForNode getCollectionConfig retrieves the collection configuration
   159  // from the supplied byte array; the byte array must contain a
   160  // json-formatted array of collectionConfigJson elements
   161  func GetCollectionConfigFromBytesForNode(cconfBytes []byte) (*pb.CollectionConfigPackage, []byte, error) {
   162  	cconf := &[]collectionConfigJson{}
   163  	err := json.Unmarshal(cconfBytes, cconf)
   164  	if err != nil {
   165  		return nil, nil, errors.Wrap(err, "could not parse the collection configuration")
   166  	}
   167  
   168  	ccarray := make([]*pb.CollectionConfig, 0, len(*cconf))
   169  	for _, cconfitem := range *cconf {
   170  		p, err := policydsl.PolicyParseNode(cconfitem.Policy)
   171  		if err != nil {
   172  			return nil, nil, errors.WithMessagef(err, "invalid policy %s", cconfitem.Policy)
   173  		}
   174  
   175  		cpc := &pb.CollectionPolicyConfig{
   176  			Payload: &pb.CollectionPolicyConfig_SignaturePolicy{
   177  				SignaturePolicy: p,
   178  			},
   179  		}
   180  
   181  		var ep *pb.ApplicationPolicy
   182  		if cconfitem.EndorsementPolicy != nil {
   183  			signaturePolicy := cconfitem.EndorsementPolicy.SignaturePolicy
   184  			channelConfigPolicy := cconfitem.EndorsementPolicy.ChannelConfigPolicy
   185  			ep, err = getApplicationPolicy(signaturePolicy, channelConfigPolicy)
   186  			if err != nil {
   187  				return nil, nil, errors.WithMessagef(err, "invalid endorsement policy [%#v]", cconfitem.EndorsementPolicy)
   188  			}
   189  		}
   190  
   191  		// Set default requiredPeerCount and MaxPeerCount if not specified in json
   192  		requiredPeerCount := int32(0)
   193  		maxPeerCount := int32(1)
   194  		if cconfitem.RequiredPeerCount != nil {
   195  			requiredPeerCount = *cconfitem.RequiredPeerCount
   196  		}
   197  		if cconfitem.MaxPeerCount != nil {
   198  			maxPeerCount = *cconfitem.MaxPeerCount
   199  		}
   200  
   201  		cc := &pb.CollectionConfig{
   202  			Payload: &pb.CollectionConfig_StaticCollectionConfig{
   203  				StaticCollectionConfig: &pb.StaticCollectionConfig{
   204  					Name:              cconfitem.Name,
   205  					MemberOrgsPolicy:  cpc,
   206  					RequiredPeerCount: requiredPeerCount,
   207  					MaximumPeerCount:  maxPeerCount,
   208  					BlockToLive:       cconfitem.BlockToLive,
   209  					MemberOnlyRead:    cconfitem.MemberOnlyRead,
   210  					MemberOnlyWrite:   cconfitem.MemberOnlyWrite,
   211  					EndorsementPolicy: ep,
   212  				},
   213  			},
   214  		}
   215  
   216  		ccarray = append(ccarray, cc)
   217  	}
   218  
   219  	ccp := &pb.CollectionConfigPackage{Config: ccarray}
   220  	ccpBytes, err := proto.Marshal(ccp)
   221  	return ccp, ccpBytes, err
   222  }
   223  
   224  func getApplicationPolicy(signaturePolicy, channelConfigPolicy string) (*pb.ApplicationPolicy, error) {
   225  	if signaturePolicy == "" && channelConfigPolicy == "" {
   226  		// no policy, no problem
   227  		return nil, nil
   228  	}
   229  
   230  	if signaturePolicy != "" && channelConfigPolicy != "" {
   231  		// mo policies, mo problems
   232  		return nil, errors.New(`cannot specify both "--signature-policy" and "--channel-config-policy"`)
   233  	}
   234  
   235  	var applicationPolicy *pb.ApplicationPolicy
   236  	if signaturePolicy != "" {
   237  		signaturePolicyEnvelope, err := policydsl.FromString(signaturePolicy)
   238  		if err != nil {
   239  			return nil, errors.Errorf("invalid signature policy: %s", signaturePolicy)
   240  		}
   241  
   242  		applicationPolicy = &pb.ApplicationPolicy{
   243  			Type: &pb.ApplicationPolicy_SignaturePolicy{
   244  				SignaturePolicy: signaturePolicyEnvelope,
   245  			},
   246  		}
   247  	}
   248  
   249  	if channelConfigPolicy != "" {
   250  		applicationPolicy = &pb.ApplicationPolicy{
   251  			Type: &pb.ApplicationPolicy_ChannelConfigPolicyReference{
   252  				ChannelConfigPolicyReference: channelConfigPolicy,
   253  			},
   254  		}
   255  	}
   256  
   257  	return applicationPolicy, nil
   258  }