Skip to content

Commit 22e2fc9

Browse files
committed
[FAB-3269] properly honor endorsement policies
This change set introduces proper validation of transactions: the write set of every transaction is validated according to the endorsement policy that was defined for the corresponding chaincode. Change-Id: Ie1cd22e1ad348d4fc1a2f8895f759955a461f416 Signed-off-by: Alessandro Sorniotti <[email protected]>
1 parent 8f7bfc3 commit 22e2fc9

18 files changed

+800
-351
lines changed

common/mocks/scc/sccprovider.go

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
Copyright IBM Corp. 2017 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 scc
18+
19+
import (
20+
lm "github.com/hyperledger/fabric/common/mocks/ledger"
21+
"github.com/hyperledger/fabric/core/common/sysccprovider"
22+
"github.com/hyperledger/fabric/core/ledger"
23+
)
24+
25+
type MocksccProviderFactory struct {
26+
Qe *lm.MockQueryExecutor
27+
}
28+
29+
func (c *MocksccProviderFactory) NewSystemChaincodeProvider() sysccprovider.SystemChaincodeProvider {
30+
return &mocksccProviderImpl{Qe: c.Qe}
31+
}
32+
33+
type mocksccProviderImpl struct {
34+
Qe *lm.MockQueryExecutor
35+
}
36+
37+
func (c *mocksccProviderImpl) IsSysCC(name string) bool {
38+
return (name == "lscc") || (name == "escc") || (name == "vscc") || (name == "notext")
39+
}
40+
41+
func (c *mocksccProviderImpl) IsSysCCAndNotInvokableCC2CC(name string) bool {
42+
return (name == "escc") || (name == "vscc")
43+
}
44+
45+
func (c *mocksccProviderImpl) IsSysCCAndNotInvokableExternal(name string) bool {
46+
return (name == "escc") || (name == "vscc") || (name == "notext")
47+
}
48+
49+
func (c *mocksccProviderImpl) GetQueryExecutorForLedger(cid string) (ledger.QueryExecutor, error) {
50+
return c.Qe, nil
51+
}

core/committer/txvalidator/txvalidator_test.go

+33-44
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"github.com/hyperledger/fabric/common/configtx/test"
2424
"github.com/hyperledger/fabric/common/ledger/testutil"
2525
util2 "github.com/hyperledger/fabric/common/util"
26-
"github.com/hyperledger/fabric/core/common/sysccprovider"
2726
"github.com/hyperledger/fabric/core/ledger/ledgermgmt"
2827
"github.com/hyperledger/fabric/core/ledger/util"
2928
ledgerUtil "github.com/hyperledger/fabric/core/ledger/util"
@@ -49,12 +48,6 @@ func TestBlockValidation(t *testing.T) {
4948
ledger, _ := ledgermgmt.CreateLedger(gb)
5049
defer ledger.Close()
5150

52-
chaincodeIns := &sysccprovider.ChaincodeInstance{
53-
ChaincodeName: "foo",
54-
ChaincodeVersion: "v1",
55-
ChainID: util2.GetTestChainID(),
56-
}
57-
5851
simulator, _ := ledger.NewTxSimulator()
5952
simulator.SetState("ns1", "key1", []byte("value1"))
6053
simulator.SetState("ns1", "key2", []byte("value2"))
@@ -63,15 +56,12 @@ func TestBlockValidation(t *testing.T) {
6356

6457
simRes, _ := simulator.GetTxSimulationResults()
6558

66-
prespPaylBytes, err := testutil.ConstructBytesProposalResponsePayload("v1", simRes)
59+
_, err := testutil.ConstructBytesProposalResponsePayload("v1", simRes)
6760
if err != nil {
6861
t.Fatalf("Could not construct ProposalResponsePayload bytes, err: %s", err)
6962
}
7063

71-
mockVsccValidator := &validator.MockVsccValidator{
72-
CIns: chaincodeIns,
73-
RespPayl: prespPaylBytes,
74-
}
64+
mockVsccValidator := &validator.MockVsccValidator{}
7565
tValidator := &txValidator{&mocktxvalidator.Support{LedgerVal: ledger}, mockVsccValidator}
7666

7767
bcInfo, _ := ledger.GetBlockchainInfo()
@@ -85,27 +75,26 @@ func TestBlockValidation(t *testing.T) {
8575
txsfltr := util.TxValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
8676
assert.True(t, txsfltr.IsSetTo(0, peer.TxValidationCode_VALID))
8777

88-
// upgrade chaincode version
89-
upgradeChaincodeIns := &sysccprovider.ChaincodeInstance{
90-
ChaincodeName: "foo",
91-
ChaincodeVersion: "v2", // new version
92-
ChainID: util2.GetTestChainID(),
93-
}
78+
/*
9479
95-
newMockVsccValidator := &validator.MockVsccValidator{
96-
CIns: upgradeChaincodeIns,
97-
RespPayl: prespPaylBytes,
98-
}
99-
newTxValidator := &txValidator{&mocktxvalidator.Support{LedgerVal: ledger}, newMockVsccValidator}
80+
a better way of testing this without all of the mocking was
81+
implemented in validator_test.go
82+
83+
newMockVsccValidator := &validator.MockVsccValidator{
84+
CIns: upgradeChaincodeIns,
85+
RespPayl: prespPaylBytes,
86+
}
87+
newTxValidator := &txValidator{&mocktxvalidator.Support{LedgerVal: ledger}, newMockVsccValidator}
10088
101-
// generate new block
102-
newBlock := testutil.ConstructBlock(t, 2, block.Header.Hash(), [][]byte{simRes}, true) // contains one tx with chaincode version v1
89+
// generate new block
90+
newBlock := testutil.ConstructBlock(t, 2, block.Header.Hash(), [][]byte{simRes}, true) // contains one tx with chaincode version v1
10391
104-
newTxValidator.Validate(newBlock)
92+
newTxValidator.Validate(newBlock)
10593
106-
// tx should be invalided because of chaincode upgrade
107-
txsfltr = util.TxValidationFlags(newBlock.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
108-
assert.True(t, txsfltr.IsSetTo(0, peer.TxValidationCode_EXPIRED_CHAINCODE))
94+
// tx should be invalided because of chaincode upgrade
95+
txsfltr = util.TxValidationFlags(newBlock.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
96+
assert.True(t, txsfltr.IsSetTo(0, peer.TxValidationCode_EXPIRED_CHAINCODE))
97+
*/
10998
}
11099

111100
func TestNewTxValidator_DuplicateTransactions(t *testing.T) {
@@ -225,12 +214,12 @@ func TestGetTxCCInstance(t *testing.T) {
225214
payload, err := utils.GetPayload(env)
226215
assert.NoError(t, err)
227216

228-
expectInvokeCCIns := &sysccprovider.ChaincodeInstance{
217+
expectInvokeCCIns := &ChaincodeInstance{
229218
ChainID: chainID,
230219
ChaincodeName: "lscc",
231220
ChaincodeVersion: "",
232221
}
233-
expectUpgradeCCIns := &sysccprovider.ChaincodeInstance{
222+
expectUpgradeCCIns := &ChaincodeInstance{
234223
ChainID: chainID,
235224
ChaincodeName: upgradeCCName,
236225
ChaincodeVersion: upgradeCCVersion,
@@ -246,20 +235,20 @@ func TestGetTxCCInstance(t *testing.T) {
246235
}
247236

248237
func TestInvalidTXsForUpgradeCC(t *testing.T) {
249-
txsChaincodeNames := map[int]*sysccprovider.ChaincodeInstance{
250-
0: &sysccprovider.ChaincodeInstance{"chain0", "cc0", "v0"}, // invoke cc0/chain0:v0, should not be affected by upgrade tx in other chain
251-
1: &sysccprovider.ChaincodeInstance{"chain1", "cc0", "v0"}, // invoke cc0/chain1:v0, should be invalided by cc1/chain1 upgrade tx
252-
2: &sysccprovider.ChaincodeInstance{"chain1", "lscc", ""}, // upgrade cc0/chain1 to v1, should be invalided by latter cc0/chain1 upgtade tx
253-
3: &sysccprovider.ChaincodeInstance{"chain1", "cc0", "v0"}, // invoke cc0/chain1:v0, should be invalided by cc1/chain1 upgrade tx
254-
4: &sysccprovider.ChaincodeInstance{"chain1", "cc0", "v1"}, // invoke cc0/chain1:v1, should be invalided by cc1/chain1 upgrade tx
255-
5: &sysccprovider.ChaincodeInstance{"chain1", "cc1", "v0"}, // invoke cc1/chain1:v0, should not be affected by other chaincode upgrade tx
256-
6: &sysccprovider.ChaincodeInstance{"chain1", "lscc", ""}, // upgrade cc0/chain1 to v2, should be invalided by latter cc0/chain1 upgtade tx
257-
7: &sysccprovider.ChaincodeInstance{"chain1", "lscc", ""}, // upgrade cc0/chain1 to v3
238+
txsChaincodeNames := map[int]*ChaincodeInstance{
239+
0: &ChaincodeInstance{"chain0", "cc0", "v0"}, // invoke cc0/chain0:v0, should not be affected by upgrade tx in other chain
240+
1: &ChaincodeInstance{"chain1", "cc0", "v0"}, // invoke cc0/chain1:v0, should be invalided by cc1/chain1 upgrade tx
241+
2: &ChaincodeInstance{"chain1", "lscc", ""}, // upgrade cc0/chain1 to v1, should be invalided by latter cc0/chain1 upgtade tx
242+
3: &ChaincodeInstance{"chain1", "cc0", "v0"}, // invoke cc0/chain1:v0, should be invalided by cc1/chain1 upgrade tx
243+
4: &ChaincodeInstance{"chain1", "cc0", "v1"}, // invoke cc0/chain1:v1, should be invalided by cc1/chain1 upgrade tx
244+
5: &ChaincodeInstance{"chain1", "cc1", "v0"}, // invoke cc1/chain1:v0, should not be affected by other chaincode upgrade tx
245+
6: &ChaincodeInstance{"chain1", "lscc", ""}, // upgrade cc0/chain1 to v2, should be invalided by latter cc0/chain1 upgtade tx
246+
7: &ChaincodeInstance{"chain1", "lscc", ""}, // upgrade cc0/chain1 to v3
258247
}
259-
upgradedChaincodes := map[int]*sysccprovider.ChaincodeInstance{
260-
2: &sysccprovider.ChaincodeInstance{"chain1", "cc0", "v1"},
261-
6: &sysccprovider.ChaincodeInstance{"chain1", "cc0", "v2"},
262-
7: &sysccprovider.ChaincodeInstance{"chain1", "cc0", "v3"},
248+
upgradedChaincodes := map[int]*ChaincodeInstance{
249+
2: &ChaincodeInstance{"chain1", "cc0", "v1"},
250+
6: &ChaincodeInstance{"chain1", "cc0", "v2"},
251+
7: &ChaincodeInstance{"chain1", "cc0", "v3"},
263252
}
264253

265254
txsfltr := ledgerUtil.NewTxValidationFlags(8)

0 commit comments

Comments
 (0)