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 }