Skip to content

Commit 7105f8b

Browse files
committed
recon: commit only validTx's pvtData in pvtStore
Currently, gossip constructs pvtData only for validTx as per VSCC. Hence, we are not storing all pvtData of a block. In the ledger, currently, we are storing pvtData of invalidTx (i.e., failed MVCC checks) too. To be consistent, this CR can stores the pvtData of only validTx (as per MVCC check). FAB-11805 #done Change-Id: Ic4b228cade0456bc1ddc4ab80595e9e82d7aaa25 Signed-off-by: senthil <cendhu@gmail.com>
1 parent 8c96636 commit 7105f8b

File tree

3 files changed

+71
-22
lines changed

3 files changed

+71
-22
lines changed

common/ledger/testutil/test_helper.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func (bg *BlockGenerator) NextBlock(simulationResults [][]byte) *common.Block {
4444
return block
4545
}
4646

47-
// NextBlock constructs next block in sequence that includes a number of transactions - one per simulationResults
47+
// NextBlockWithTxid constructs next block in sequence that includes a number of transactions - one per simulationResults
4848
func (bg *BlockGenerator) NextBlockWithTxid(simulationResults [][]byte, txids []string) *common.Block {
4949
// Length of simulationResults should be same as the length of txids.
5050
if len(simulationResults) != len(txids) {
@@ -68,8 +68,11 @@ func (bg *BlockGenerator) NextTestBlock(numTx int, txSize int) *common.Block {
6868
// NextTestBlocks constructs 'numBlocks' number of blocks for testing
6969
func (bg *BlockGenerator) NextTestBlocks(numBlocks int) []*common.Block {
7070
blocks := []*common.Block{}
71+
numTx := 10
7172
for i := 0; i < numBlocks; i++ {
72-
blocks = append(blocks, bg.NextTestBlock(10, 100))
73+
block := bg.NextTestBlock(numTx, 100)
74+
block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = lutils.NewTxValidationFlagsSetValue(numTx, pb.TxValidationCode_VALID)
75+
blocks = append(blocks, block)
7376
}
7477
return blocks
7578
}

core/ledger/ledgerstorage/store.go

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/hyperledger/fabric/core/ledger/ledgerconfig"
1717
"github.com/hyperledger/fabric/core/ledger/pvtdatapolicy"
1818
"github.com/hyperledger/fabric/core/ledger/pvtdatastorage"
19+
lutil "github.com/hyperledger/fabric/core/ledger/util"
1920
"github.com/hyperledger/fabric/protos/common"
2021
"github.com/pkg/errors"
2122
)
@@ -88,8 +89,6 @@ func (s *Store) Init(btlPolicy pvtdatapolicy.BTLPolicy) {
8889
// CommitWithPvtData commits the block and the corresponding pvt data in an atomic operation
8990
func (s *Store) CommitWithPvtData(blockAndPvtdata *ledger.BlockAndPvtData) error {
9091
blockNum := blockAndPvtdata.Block.Header.Number
91-
missingPvtData := blockAndPvtdata.MissingPvtData
92-
9392
s.rwlock.Lock()
9493
defer s.rwlock.Unlock()
9594

@@ -103,11 +102,10 @@ func (s *Store) CommitWithPvtData(blockAndPvtdata *ledger.BlockAndPvtData) error
103102
// when re-processing blocks (rejoin the channel or re-fetching last few block),
104103
// skip the pvt data commit to the pvtdata blockstore
105104
logger.Debugf("Writing block [%d] to pvt block store", blockNum)
106-
var pvtdata []*ledger.TxPvtData
107-
for _, v := range blockAndPvtdata.PvtData {
108-
pvtdata = append(pvtdata, v)
109-
}
110-
if err := s.pvtdataStore.Prepare(blockAndPvtdata.Block.Header.Number, pvtdata, missingPvtData); err != nil {
105+
// as the ledger has already validated all txs in this block, we need to
106+
// use the validated info to commit only the pvtData of valid tx
107+
validTxPvtData, validTxMissingPvtData := constructValidTxPvtDataAndMissingData(blockAndPvtdata)
108+
if err := s.pvtdataStore.Prepare(blockAndPvtdata.Block.Header.Number, validTxPvtData, validTxMissingPvtData); err != nil {
111109
return err
112110
}
113111
writtenToPvtStore = true
@@ -126,6 +124,35 @@ func (s *Store) CommitWithPvtData(blockAndPvtdata *ledger.BlockAndPvtData) error
126124
return nil
127125
}
128126

127+
func constructValidTxPvtDataAndMissingData(blockAndPvtData *ledger.BlockAndPvtData) ([]*ledger.TxPvtData,
128+
ledger.TxMissingPvtDataMap) {
129+
130+
var validTxPvtData []*ledger.TxPvtData
131+
validTxMissingPvtData := make(ledger.TxMissingPvtDataMap)
132+
133+
txsFilter := lutil.TxValidationFlags(blockAndPvtData.Block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
134+
numTxs := uint64(len(blockAndPvtData.Block.Data.Data))
135+
136+
// for all valid tx, construct pvtdata and missing pvtdata list
137+
for txNum := uint64(0); txNum < numTxs; txNum++ {
138+
if txsFilter.IsInvalid(int(txNum)) {
139+
continue
140+
}
141+
142+
if pvtdata, ok := blockAndPvtData.PvtData[txNum]; ok {
143+
validTxPvtData = append(validTxPvtData, pvtdata)
144+
}
145+
146+
if missingPvtData, ok := blockAndPvtData.MissingPvtData[txNum]; ok {
147+
for _, missing := range missingPvtData {
148+
validTxMissingPvtData.Add(txNum, missing.Namespace,
149+
missing.Collection, missing.IsEligible)
150+
}
151+
}
152+
}
153+
return validTxPvtData, validTxMissingPvtData
154+
}
155+
129156
// CommitPvtDataOfOldBlocks commits the pvtData of old blocks
130157
func (s *Store) CommitPvtDataOfOldBlocks(blocksPvtData map[uint64][]*ledger.TxPvtData) error {
131158
err := s.pvtdataStore.CommitPvtDataOfOldBlocks(blocksPvtData)

core/ledger/ledgerstorage/store_test.go

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ import (
2020
"github.com/hyperledger/fabric/core/ledger/pvtdatapolicy"
2121
btltestutil "github.com/hyperledger/fabric/core/ledger/pvtdatapolicy/testutil"
2222
"github.com/hyperledger/fabric/core/ledger/pvtdatastorage"
23+
lutil "github.com/hyperledger/fabric/core/ledger/util"
24+
"github.com/hyperledger/fabric/protos/common"
2325
"github.com/hyperledger/fabric/protos/ledger/rwset"
26+
pb "github.com/hyperledger/fabric/protos/peer"
2427
"github.com/spf13/viper"
2528
"github.com/stretchr/testify/assert"
2629
)
@@ -56,7 +59,9 @@ func TestStore(t *testing.T) {
5659
assert.NoError(t, err)
5760
assert.Nil(t, pvtdata)
5861

59-
// block 2 has pvt data for tx 3 and 5 only
62+
// block 2 has pvt data for tx 3, 5 and 6. However, tx 6
63+
// is marked as invalid in the block and hence should not
64+
// have been stored
6065
pvtdata, err = store.GetPvtDataByNum(2, nil)
6166
assert.NoError(t, err)
6267
assert.Equal(t, 2, len(pvtdata))
@@ -72,20 +77,10 @@ func TestStore(t *testing.T) {
7277

7378
blockAndPvtdata, err := store.GetPvtDataAndBlockByNum(2, nil)
7479
assert.NoError(t, err)
75-
assert.Equal(t, len(sampleData[2].MissingPvtData), len(blockAndPvtdata.MissingPvtData))
76-
for txNum := range blockAndPvtdata.MissingPvtData {
77-
assert.ElementsMatch(t, sampleData[2].MissingPvtData[txNum],
78-
blockAndPvtdata.MissingPvtData)
79-
}
8080
assert.True(t, proto.Equal(sampleData[2].Block, blockAndPvtdata.Block))
8181

8282
blockAndPvtdata, err = store.GetPvtDataAndBlockByNum(3, nil)
8383
assert.NoError(t, err)
84-
assert.Equal(t, len(sampleData[2].MissingPvtData), len(blockAndPvtdata.MissingPvtData))
85-
for txNum := range blockAndPvtdata.MissingPvtData {
86-
assert.ElementsMatch(t, sampleData[2].MissingPvtData[txNum],
87-
blockAndPvtdata.MissingPvtData)
88-
}
8984
assert.True(t, proto.Equal(sampleData[3].Block, blockAndPvtdata.Block))
9085

9186
// pvt data retrieval for block 3 with filter should return filtered pvtdata
@@ -101,6 +96,15 @@ func TestStore(t *testing.T) {
10196
assert.Equal(t, 1, len(blockAndPvtdata.PvtData[6].WriteSet.NsPvtRwset))
10297
// any other transaction entry should be nil
10398
assert.Nil(t, blockAndPvtdata.PvtData[2])
99+
100+
// test missing data retrieval in the presence of invalid tx. Block 5 had
101+
// missing data (for tx4 and tx5). However, tx5 was marked as invalid tx.
102+
// Hence, only tx4's missing data should be returned
103+
expectedMissingDataInfo := make(ledger.MissingPvtDataInfo)
104+
expectedMissingDataInfo.Add(5, 4, "ns-4", "coll-4")
105+
missingDataInfo, err := store.GetMissingPvtDataInfoForMostRecentBlocks(1)
106+
assert.NoError(t, err)
107+
assert.Equal(t, expectedMissingDataInfo, missingDataInfo)
104108
}
105109

106110
func TestStoreWithExistingBlockchain(t *testing.T) {
@@ -326,10 +330,25 @@ func sampleDataWithPvtdataForSelectiveTx(t *testing.T) []*ledger.BlockAndPvtData
326330
for i := 0; i < 10; i++ {
327331
blockAndpvtdata = append(blockAndpvtdata, &ledger.BlockAndPvtData{Block: blocks[i]})
328332
}
329-
// txNum 3, 5 in block 2 has pvtdata
330-
blockAndpvtdata[2].PvtData = samplePvtData(t, []uint64{3, 5})
333+
334+
// txNum 3, 5, 6 in block 2 has pvtdata but txNum 6 is invalid
335+
blockAndpvtdata[2].PvtData = samplePvtData(t, []uint64{3, 5, 6})
336+
txFilter := lutil.TxValidationFlags(blockAndpvtdata[2].Block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
337+
txFilter.SetFlag(6, pb.TxValidationCode_INVALID_WRITESET)
338+
blockAndpvtdata[2].Block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txFilter
339+
331340
// txNum 4, 6 in block 3 has pvtdata
332341
blockAndpvtdata[3].PvtData = samplePvtData(t, []uint64{4, 6})
342+
343+
// txNum 4, 5 in block 5 has missing pvt data but txNum 5 is invalid
344+
missingData := make(ledger.TxMissingPvtDataMap)
345+
missingData.Add(4, "ns-4", "coll-4", true)
346+
missingData.Add(5, "ns-5", "coll-5", true)
347+
blockAndpvtdata[5].MissingPvtData = missingData
348+
txFilter = lutil.TxValidationFlags(blockAndpvtdata[5].Block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
349+
txFilter.SetFlag(5, pb.TxValidationCode_INVALID_WRITESET)
350+
blockAndpvtdata[5].Block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txFilter
351+
333352
return blockAndpvtdata
334353
}
335354

0 commit comments

Comments
 (0)