github.com/true-sqn/fabric@v2.1.1+incompatible/core/ledger/kvledger/tests/util.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package tests
     8  
     9  import (
    10  	"testing"
    11  
    12  	"github.com/golang/protobuf/proto"
    13  	"github.com/hyperledger/fabric-protos-go/common"
    14  	"github.com/hyperledger/fabric-protos-go/ledger/rwset"
    15  	"github.com/hyperledger/fabric-protos-go/msp"
    16  	protopeer "github.com/hyperledger/fabric-protos-go/peer"
    17  	configtxtest "github.com/hyperledger/fabric/common/configtx/test"
    18  	"github.com/hyperledger/fabric/common/crypto"
    19  	"github.com/hyperledger/fabric/common/flogging"
    20  	"github.com/hyperledger/fabric/common/metrics/disabled"
    21  	"github.com/hyperledger/fabric/common/policydsl"
    22  	"github.com/hyperledger/fabric/core/ledger/kvledger/tests/fakes"
    23  	lutils "github.com/hyperledger/fabric/core/ledger/util"
    24  	"github.com/hyperledger/fabric/core/ledger/util/couchdb"
    25  	"github.com/hyperledger/fabric/protoutil"
    26  	"github.com/stretchr/testify/require"
    27  )
    28  
    29  var logger = flogging.MustGetLogger("test2")
    30  
    31  // collConf helps writing tests with less verbose code by specifying coll configuration
    32  // in a simple struct in place of 'peer.CollectionConfigPackage'. (the test heplers' apis
    33  // use 'collConf' as parameters and return values and transform back and forth to/from proto
    34  // message internally (using func 'convertToCollConfigProtoBytes' and 'convertFromCollConfigProto')
    35  type collConf struct {
    36  	name    string
    37  	btl     uint64
    38  	members []string
    39  }
    40  
    41  type txAndPvtdata struct {
    42  	Txid     string
    43  	Envelope *common.Envelope
    44  	Pvtws    *rwset.TxPvtReadWriteSet
    45  }
    46  
    47  //go:generate counterfeiter -o fakes/signer.go --fake-name Signer . signer
    48  
    49  type signer interface {
    50  	Sign(msg []byte) ([]byte, error)
    51  	Serialize() ([]byte, error)
    52  }
    53  
    54  func convertToCollConfigProtoBytes(collConfs []*collConf) ([]byte, error) {
    55  	var protoConfArray []*protopeer.CollectionConfig
    56  	for _, c := range collConfs {
    57  		protoConf := &protopeer.CollectionConfig{
    58  			Payload: &protopeer.CollectionConfig_StaticCollectionConfig{
    59  				StaticCollectionConfig: &protopeer.StaticCollectionConfig{
    60  					Name:             c.name,
    61  					BlockToLive:      c.btl,
    62  					MemberOrgsPolicy: convertToMemberOrgsPolicy(c.members),
    63  				},
    64  			},
    65  		}
    66  		protoConfArray = append(protoConfArray, protoConf)
    67  	}
    68  	return proto.Marshal(&protopeer.CollectionConfigPackage{Config: protoConfArray})
    69  }
    70  
    71  func convertToMemberOrgsPolicy(members []string) *protopeer.CollectionPolicyConfig {
    72  	var data [][]byte
    73  	for _, member := range members {
    74  		data = append(data, []byte(member))
    75  	}
    76  	return &protopeer.CollectionPolicyConfig{
    77  		Payload: &protopeer.CollectionPolicyConfig_SignaturePolicy{
    78  			SignaturePolicy: policydsl.Envelope(policydsl.Or(policydsl.SignedBy(0), policydsl.SignedBy(1)), data),
    79  		},
    80  	}
    81  }
    82  
    83  func convertFromMemberOrgsPolicy(policy *protopeer.CollectionPolicyConfig) []string {
    84  	if policy.GetSignaturePolicy() == nil {
    85  		return nil
    86  	}
    87  	ids := policy.GetSignaturePolicy().Identities
    88  	var members []string
    89  	for _, id := range ids {
    90  		role := &msp.MSPRole{}
    91  		err := proto.Unmarshal(id.Principal, role)
    92  		if err == nil {
    93  			// This is for sample ledger generated by fabric (e.g., integration test),
    94  			// where id.Principal was properly marshalled during sample ledger generation.
    95  			members = append(members, role.MspIdentifier)
    96  		} else {
    97  			// This is for sample ledger generated by sampleDataHelper.populateLedger,
    98  			// where id.Principal was a []byte cast from a string (not a marshalled msp.MSPRole)
    99  			members = append(members, string(id.Principal))
   100  		}
   101  	}
   102  	return members
   103  }
   104  
   105  func convertFromCollConfigProto(collConfPkg *protopeer.CollectionConfigPackage) []*collConf {
   106  	var collConfs []*collConf
   107  	protoConfArray := collConfPkg.Config
   108  	for _, protoConf := range protoConfArray {
   109  		p := protoConf.GetStaticCollectionConfig()
   110  		collConfs = append(collConfs,
   111  			&collConf{
   112  				name:    p.Name,
   113  				btl:     p.BlockToLive,
   114  				members: convertFromMemberOrgsPolicy(p.MemberOrgsPolicy),
   115  			},
   116  		)
   117  	}
   118  	return collConfs
   119  }
   120  
   121  func constructTransaction(txid string, simulationResults []byte) (*common.Envelope, error) {
   122  	channelid := "dummyChannel"
   123  	ccid := &protopeer.ChaincodeID{
   124  		Name:    "dummyCC",
   125  		Version: "dummyVer",
   126  	}
   127  	txenv, _, err := constructUnsignedTxEnv(
   128  		channelid,
   129  		ccid,
   130  		&protopeer.Response{Status: 200},
   131  		simulationResults,
   132  		txid,
   133  		nil,
   134  		nil,
   135  		common.HeaderType_ENDORSER_TRANSACTION,
   136  	)
   137  	return txenv, err
   138  }
   139  
   140  // constructUnsignedTxEnv creates a Transaction envelope from given inputs
   141  func constructUnsignedTxEnv(
   142  	channelID string,
   143  	ccid *protopeer.ChaincodeID,
   144  	response *protopeer.Response,
   145  	simulationResults []byte,
   146  	txid string,
   147  	events []byte,
   148  	visibility []byte,
   149  	headerType common.HeaderType,
   150  ) (*common.Envelope, string, error) {
   151  
   152  	sigID := &fakes.Signer{}
   153  	sigID.SerializeReturns([]byte("signer"), nil)
   154  	sigID.SignReturns([]byte("signature"), nil)
   155  
   156  	ss, err := sigID.Serialize()
   157  	if err != nil {
   158  		return nil, "", err
   159  	}
   160  
   161  	var prop *protopeer.Proposal
   162  	if txid == "" {
   163  		// if txid is not set, then we need to generate one while creating the proposal message
   164  		prop, txid, err = protoutil.CreateChaincodeProposal(
   165  			headerType,
   166  			channelID,
   167  			&protopeer.ChaincodeInvocationSpec{
   168  				ChaincodeSpec: &protopeer.ChaincodeSpec{
   169  					ChaincodeId: ccid,
   170  				},
   171  			},
   172  			ss,
   173  		)
   174  
   175  	} else {
   176  		// if txid is set, we should not generate a txid instead reuse the given txid
   177  		nonce, err := crypto.GetRandomNonce()
   178  		if err != nil {
   179  			return nil, "", err
   180  		}
   181  		prop, txid, err = protoutil.CreateChaincodeProposalWithTxIDNonceAndTransient(
   182  			txid,
   183  			headerType,
   184  			channelID,
   185  			&protopeer.ChaincodeInvocationSpec{
   186  				ChaincodeSpec: &protopeer.ChaincodeSpec{
   187  					ChaincodeId: ccid,
   188  				},
   189  			},
   190  			nonce,
   191  			ss,
   192  			nil,
   193  		)
   194  	}
   195  	if err != nil {
   196  		return nil, "", err
   197  	}
   198  
   199  	presp, err := protoutil.CreateProposalResponse(
   200  		prop.Header,
   201  		prop.Payload,
   202  		response,
   203  		simulationResults,
   204  		nil,
   205  		ccid,
   206  		sigID,
   207  	)
   208  	if err != nil {
   209  		return nil, "", err
   210  	}
   211  
   212  	env, err := protoutil.CreateSignedTx(prop, sigID, presp)
   213  	if err != nil {
   214  		return nil, "", err
   215  	}
   216  	return env, txid, nil
   217  }
   218  
   219  func constructTestGenesisBlock(channelid string) (*common.Block, error) {
   220  	blk, err := configtxtest.MakeGenesisBlock(channelid)
   221  	if err != nil {
   222  		return nil, err
   223  	}
   224  	setBlockFlagsToValid(blk)
   225  	return blk, nil
   226  }
   227  
   228  func setBlockFlagsToValid(block *common.Block) {
   229  	protoutil.InitBlockMetadata(block)
   230  	block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] =
   231  		lutils.NewTxValidationFlagsSetValue(len(block.Data.Data), protopeer.TxValidationCode_VALID)
   232  }
   233  
   234  func dropCouchDBs(t *testing.T, couchdbConfig *couchdb.Config) {
   235  	couchInstance, err := couchdb.CreateCouchInstance(couchdbConfig, &disabled.Provider{})
   236  	require.NoError(t, err)
   237  	dbNames, err := couchInstance.RetrieveApplicationDBNames()
   238  	require.NoError(t, err)
   239  	for _, dbName := range dbNames {
   240  		db := &couchdb.CouchDatabase{
   241  			CouchInstance: couchInstance,
   242  			DBName:        dbName,
   243  		}
   244  		response, err := db.DropDatabase()
   245  		require.NoError(t, err)
   246  		require.True(t, response.Ok)
   247  	}
   248  }