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 }