github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/core/committer/txvalidator/txvalidator_test.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 txvalidator
    18  
    19  import (
    20  	"testing"
    21  
    22  	"github.com/golang/protobuf/proto"
    23  	"github.com/hyperledger/fabric/common/configtx/test"
    24  	"github.com/hyperledger/fabric/common/ledger/testutil"
    25  	util2 "github.com/hyperledger/fabric/common/util"
    26  	"github.com/hyperledger/fabric/core/ledger/ledgermgmt"
    27  	"github.com/hyperledger/fabric/core/ledger/util"
    28  	ledgerUtil "github.com/hyperledger/fabric/core/ledger/util"
    29  	mocktxvalidator "github.com/hyperledger/fabric/core/mocks/txvalidator"
    30  	"github.com/hyperledger/fabric/core/mocks/validator"
    31  	"github.com/hyperledger/fabric/msp"
    32  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    33  	msptesttools "github.com/hyperledger/fabric/msp/mgmt/testtools"
    34  	"github.com/hyperledger/fabric/protos/common"
    35  	"github.com/hyperledger/fabric/protos/peer"
    36  	"github.com/hyperledger/fabric/protos/utils"
    37  	"github.com/spf13/viper"
    38  	"github.com/stretchr/testify/assert"
    39  )
    40  
    41  func TestFirstBlockValidation(t *testing.T) {
    42  	viper.Set("peer.fileSystemPath", "/tmp/fabric/txvalidatortest")
    43  	ledgermgmt.InitializeTestEnv()
    44  	defer ledgermgmt.CleanupTestEnv()
    45  
    46  	gb, _ := test.MakeGenesisBlock("TestLedger")
    47  	gbHash := gb.Header.Hash()
    48  	ledger, _ := ledgermgmt.CreateLedger(gb)
    49  	defer ledger.Close()
    50  
    51  	tValidator := &txValidator{&mocktxvalidator.Support{LedgerVal: ledger}, &validator.MockVsccValidator{}}
    52  
    53  	bcInfo, _ := ledger.GetBlockchainInfo()
    54  	testutil.AssertEquals(t, bcInfo, &common.BlockchainInfo{
    55  		Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil})
    56  
    57  	simulator, _ := ledger.NewTxSimulator()
    58  	simulator.SetState("ns1", "key1", []byte("value1"))
    59  	simulator.SetState("ns1", "key2", []byte("value2"))
    60  	simulator.SetState("ns1", "key3", []byte("value3"))
    61  	simulator.Done()
    62  
    63  	simRes, _ := simulator.GetTxSimulationResults()
    64  	block := testutil.ConstructBlock(t, 1, gbHash, [][]byte{simRes}, true)
    65  
    66  	tValidator.Validate(block)
    67  
    68  	txsfltr := util.TxValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
    69  	assert.True(t, txsfltr.IsSetTo(0, peer.TxValidationCode_VALID))
    70  }
    71  
    72  func TestNewTxValidator_DuplicateTransactions(t *testing.T) {
    73  	viper.Set("peer.fileSystemPath", "/tmp/fabric/txvalidatortest")
    74  	ledgermgmt.InitializeTestEnv()
    75  	defer ledgermgmt.CleanupTestEnv()
    76  
    77  	gb, _ := test.MakeGenesisBlock("TestLedger")
    78  	ledger, _ := ledgermgmt.CreateLedger(gb)
    79  
    80  	defer ledger.Close()
    81  
    82  	tValidator := &txValidator{&mocktxvalidator.Support{LedgerVal: ledger}, &validator.MockVsccValidator{}}
    83  
    84  	// Create simple endorsement transaction
    85  	payload := &common.Payload{
    86  		Header: &common.Header{
    87  			ChannelHeader: utils.MarshalOrPanic(&common.ChannelHeader{
    88  				TxId:      "simple_txID", // Fake txID
    89  				Type:      int32(common.HeaderType_ENDORSER_TRANSACTION),
    90  				ChannelId: util2.GetTestChainID(),
    91  			}),
    92  		},
    93  		Data: []byte("test"),
    94  	}
    95  
    96  	payloadBytes, err := proto.Marshal(payload)
    97  
    98  	// Check marshaling didn't fail
    99  	assert.NoError(t, err)
   100  
   101  	// Envelope the payload
   102  	envelope := &common.Envelope{
   103  		Payload: payloadBytes,
   104  	}
   105  
   106  	envelopeBytes, err := proto.Marshal(envelope)
   107  
   108  	// Check marshaling didn't fail
   109  	assert.NoError(t, err)
   110  
   111  	block := &common.Block{
   112  		Data: &common.BlockData{
   113  			// Enconde transactions
   114  			Data: [][]byte{envelopeBytes},
   115  		},
   116  	}
   117  
   118  	block.Header = &common.BlockHeader{
   119  		Number:   0,
   120  		DataHash: block.Data.Hash(),
   121  	}
   122  
   123  	// Initialize metadata
   124  	utils.InitBlockMetadata(block)
   125  	// Commit block to the ledger
   126  	ledger.Commit(block)
   127  
   128  	// Validation should invalidate transaction,
   129  	// because it's already committed
   130  	tValidator.Validate(block)
   131  
   132  	txsfltr := util.TxValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
   133  	assert.True(t, txsfltr.IsInvalid(0))
   134  }
   135  
   136  func createCCUpgradeEnvelope(chainID, chaincodeName, chaincodeVersion string, signer msp.SigningIdentity) (*common.Envelope, error) {
   137  	creator, err := signer.Serialize()
   138  	if err != nil {
   139  		return nil, err
   140  	}
   141  
   142  	spec := &peer.ChaincodeSpec{
   143  		Type: peer.ChaincodeSpec_Type(peer.ChaincodeSpec_Type_value["GOLANG"]),
   144  		ChaincodeId: &peer.ChaincodeID{
   145  			Path:    "github.com/codePath",
   146  			Name:    chaincodeName,
   147  			Version: chaincodeVersion,
   148  		},
   149  	}
   150  
   151  	cds := &peer.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: []byte{}}
   152  	prop, _, err := utils.CreateUpgradeProposalFromCDS(chainID, cds, creator, []byte{}, []byte{}, []byte{})
   153  	if err != nil {
   154  		return nil, err
   155  	}
   156  
   157  	proposalResponse := &peer.ProposalResponse{
   158  		Response: &peer.Response{
   159  			Status: 200, // endorsed successfully
   160  		},
   161  		Endorsement: &peer.Endorsement{},
   162  	}
   163  
   164  	return utils.CreateSignedTx(prop, signer, proposalResponse)
   165  }
   166  
   167  func TestGetTxCCInstance(t *testing.T) {
   168  	// setup the MSP manager so that we can sign/verify
   169  	err := msptesttools.LoadMSPSetupForTesting()
   170  	if err != nil {
   171  		t.Fatalf("Could not initialize msp, err: %s", err)
   172  	}
   173  	signer, err := mspmgmt.GetLocalMSP().GetDefaultSigningIdentity()
   174  	if err != nil {
   175  		t.Fatalf("Could not initialize signer, err: %s", err)
   176  	}
   177  
   178  	chainID := util2.GetTestChainID()
   179  	upgradeCCName := "mycc"
   180  	upgradeCCVersion := "v1"
   181  
   182  	env, err := createCCUpgradeEnvelope(chainID, upgradeCCName, upgradeCCVersion, signer)
   183  	assert.NoError(t, err)
   184  
   185  	// get the payload from the envelope
   186  	payload, err := utils.GetPayload(env)
   187  	assert.NoError(t, err)
   188  
   189  	expectInvokeCCIns := &ChaincodeInstance{
   190  		ChainID:          chainID,
   191  		ChaincodeName:    "lscc",
   192  		ChaincodeVersion: "",
   193  	}
   194  	expectUpgradeCCIns := &ChaincodeInstance{
   195  		ChainID:          chainID,
   196  		ChaincodeName:    upgradeCCName,
   197  		ChaincodeVersion: upgradeCCVersion,
   198  	}
   199  
   200  	tValidator := &txValidator{}
   201  	invokeCCIns, upgradeCCIns, err := tValidator.getTxCCInstance(payload)
   202  	if err != nil {
   203  		t.Fatalf("Get chaincode from tx error: %s", err)
   204  	}
   205  	assert.EqualValues(t, expectInvokeCCIns, invokeCCIns)
   206  	assert.EqualValues(t, expectUpgradeCCIns, upgradeCCIns)
   207  }
   208  
   209  func TestInvalidTXsForUpgradeCC(t *testing.T) {
   210  	txsChaincodeNames := map[int]*ChaincodeInstance{
   211  		0: &ChaincodeInstance{"chain0", "cc0", "v0"}, // invoke cc0/chain0:v0, should not be affected by upgrade tx in other chain
   212  		1: &ChaincodeInstance{"chain1", "cc0", "v0"}, // invoke cc0/chain1:v0, should be invalided by cc1/chain1 upgrade tx
   213  		2: &ChaincodeInstance{"chain1", "lscc", ""},  // upgrade cc0/chain1 to v1, should be invalided by latter cc0/chain1 upgtade tx
   214  		3: &ChaincodeInstance{"chain1", "cc0", "v0"}, // invoke cc0/chain1:v0, should be invalided by cc1/chain1 upgrade tx
   215  		4: &ChaincodeInstance{"chain1", "cc0", "v1"}, // invoke cc0/chain1:v1, should be invalided by cc1/chain1 upgrade tx
   216  		5: &ChaincodeInstance{"chain1", "cc1", "v0"}, // invoke cc1/chain1:v0, should not be affected by other chaincode upgrade tx
   217  		6: &ChaincodeInstance{"chain1", "lscc", ""},  // upgrade cc0/chain1 to v2, should be invalided by latter cc0/chain1 upgtade tx
   218  		7: &ChaincodeInstance{"chain1", "lscc", ""},  // upgrade cc0/chain1 to v3
   219  	}
   220  	upgradedChaincodes := map[int]*ChaincodeInstance{
   221  		2: &ChaincodeInstance{"chain1", "cc0", "v1"},
   222  		6: &ChaincodeInstance{"chain1", "cc0", "v2"},
   223  		7: &ChaincodeInstance{"chain1", "cc0", "v3"},
   224  	}
   225  
   226  	txsfltr := ledgerUtil.NewTxValidationFlags(8)
   227  	txsfltr.SetFlag(0, peer.TxValidationCode_VALID)
   228  	txsfltr.SetFlag(1, peer.TxValidationCode_VALID)
   229  	txsfltr.SetFlag(2, peer.TxValidationCode_VALID)
   230  	txsfltr.SetFlag(3, peer.TxValidationCode_VALID)
   231  	txsfltr.SetFlag(4, peer.TxValidationCode_VALID)
   232  	txsfltr.SetFlag(5, peer.TxValidationCode_VALID)
   233  	txsfltr.SetFlag(6, peer.TxValidationCode_VALID)
   234  	txsfltr.SetFlag(7, peer.TxValidationCode_VALID)
   235  
   236  	expectTxsFltr := ledgerUtil.NewTxValidationFlags(8)
   237  	expectTxsFltr.SetFlag(0, peer.TxValidationCode_VALID)
   238  	expectTxsFltr.SetFlag(1, peer.TxValidationCode_EXPIRED_CHAINCODE)
   239  	expectTxsFltr.SetFlag(2, peer.TxValidationCode_EXPIRED_CHAINCODE)
   240  	expectTxsFltr.SetFlag(3, peer.TxValidationCode_EXPIRED_CHAINCODE)
   241  	expectTxsFltr.SetFlag(4, peer.TxValidationCode_EXPIRED_CHAINCODE)
   242  	expectTxsFltr.SetFlag(5, peer.TxValidationCode_VALID)
   243  	expectTxsFltr.SetFlag(6, peer.TxValidationCode_EXPIRED_CHAINCODE)
   244  	expectTxsFltr.SetFlag(7, peer.TxValidationCode_VALID)
   245  
   246  	tValidator := &txValidator{}
   247  	finalfltr := tValidator.invalidTXsForUpgradeCC(txsChaincodeNames, upgradedChaincodes, txsfltr)
   248  
   249  	assert.EqualValues(t, expectTxsFltr, finalfltr)
   250  }