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