Skip to content

Commit 40e061c

Browse files
committed
[FAB-2429] Skip invalid trans in history db
Invalid trans should not be written to history database. This will prevent writes from invalid trans from showing up in GetHistoryForKey() results. Change-Id: I8508094d697febf213098712185b3d6e9aaf9f29 Signed-off-by: denyeart <[email protected]>
1 parent a0d032b commit 40e061c

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

core/ledger/kvledger/history/historydb/historyleveldb/historyleveldb.go

+18-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/rwset"
2525
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/version"
2626
"github.com/hyperledger/fabric/core/ledger/ledgerconfig"
27+
"github.com/hyperledger/fabric/core/ledger/util"
2728
"github.com/hyperledger/fabric/protos/common"
2829
putils "github.com/hyperledger/fabric/protos/utils"
2930
logging "github.com/op/go-logging"
@@ -92,10 +93,26 @@ func (historyDB *historyDB) Commit(block *common.Block) error {
9293
logger.Debugf("Channel [%s]: Updating history database for blockNo [%v] with [%d] transactions",
9394
historyDB.dbName, blockNo, len(block.Data.Data))
9495

95-
//TODO add check for invalid trans in bit array
96+
// Get the invalidation byte array for the block
97+
txsFilter := util.TxValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
98+
// Initialize txsFilter if it does not yet exist (e.g. during testing, for genesis block, etc)
99+
if len(txsFilter) == 0 {
100+
txsFilter = util.NewTxValidationFlags(len(block.Data.Data))
101+
block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txsFilter
102+
}
103+
104+
// write each tran's write set to history db
96105
for _, envBytes := range block.Data.Data {
97106
tranNo++
98107

108+
// If the tran is marked as invalid, skip it
109+
// Note, tranNo starts at 1 for height, while tranIndex starts at 0 for invalid array
110+
if txsFilter.IsInvalid(int(tranNo) - 1) {
111+
logger.Debugf("Channel [%s]: Skipping history write for invalid transaction number %d",
112+
historyDB.dbName, tranNo)
113+
continue
114+
}
115+
99116
env, err := putils.GetEnvelopeFromBlock(envBytes)
100117
if err != nil {
101118
return err

core/ledger/kvledger/history/historydb/historyleveldb/historyleveldb_test.go

+42
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ import (
2424
configtxtest "github.com/hyperledger/fabric/common/configtx/test"
2525
"github.com/hyperledger/fabric/common/ledger/testutil"
2626
"github.com/hyperledger/fabric/core/ledger"
27+
"github.com/hyperledger/fabric/core/ledger/util"
28+
"github.com/hyperledger/fabric/protos/common"
29+
"github.com/hyperledger/fabric/protos/peer"
2730
"github.com/spf13/viper"
2831
)
2932

@@ -124,6 +127,45 @@ func TestHistory(t *testing.T) {
124127
testutil.AssertEquals(t, count, 3)
125128
}
126129

130+
func TestHistoryForInvalidTran(t *testing.T) {
131+
132+
env := NewTestHistoryEnv(t)
133+
defer env.cleanup()
134+
provider := env.testBlockStorageEnv.provider
135+
store1, err := provider.OpenBlockStore("ledger1")
136+
testutil.AssertNoError(t, err, "Error upon provider.OpenBlockStore()")
137+
defer store1.Shutdown()
138+
139+
//block1
140+
simulator, _ := env.txmgr.NewTxSimulator()
141+
value1 := []byte("value1")
142+
simulator.SetState("ns1", "key7", value1)
143+
simulator.Done()
144+
simRes, _ := simulator.GetTxSimulationResults()
145+
bg := testutil.NewBlockGenerator(t)
146+
block1 := bg.NextBlock([][]byte{simRes}, false)
147+
148+
//for this invalid tran test, set the transaction to invalid
149+
txsFilter := util.TxValidationFlags(block1.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
150+
txsFilter.SetFlag(0, peer.TxValidationCode_INVALID_OTHER_REASON)
151+
block1.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txsFilter
152+
153+
err = store1.AddBlock(block1)
154+
testutil.AssertNoError(t, err, "")
155+
err = env.testHistoryDB.Commit(block1)
156+
testutil.AssertNoError(t, err, "")
157+
158+
qhistory, err := env.testHistoryDB.NewHistoryQueryExecutor(store1)
159+
testutil.AssertNoError(t, err, "Error upon NewHistoryQueryExecutor")
160+
161+
itr, err2 := qhistory.GetHistoryForKey("ns1", "key7")
162+
testutil.AssertNoError(t, err2, "Error upon GetHistoryForKey()")
163+
164+
// test that there are no history values, since the tran was marked as invalid
165+
kmod, _ := itr.Next()
166+
testutil.AssertNil(t, kmod)
167+
}
168+
127169
//TestSavepoint tests that save points get written after each block and get returned via GetBlockNumfromSavepoint
128170
func TestHistoryDisabled(t *testing.T) {
129171

0 commit comments

Comments
 (0)