Skip to content

Commit

Permalink
[FAB-2429] Skip invalid trans in history db
Browse files Browse the repository at this point in the history
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 <enyeart@us.ibm.com>
  • Loading branch information
denyeart committed Mar 1, 2017
1 parent a0d032b commit 40e061c
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/rwset"
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/version"
"github.com/hyperledger/fabric/core/ledger/ledgerconfig"
"github.com/hyperledger/fabric/core/ledger/util"
"github.com/hyperledger/fabric/protos/common"
putils "github.com/hyperledger/fabric/protos/utils"
logging "github.com/op/go-logging"
Expand Down Expand Up @@ -92,10 +93,26 @@ func (historyDB *historyDB) Commit(block *common.Block) error {
logger.Debugf("Channel [%s]: Updating history database for blockNo [%v] with [%d] transactions",
historyDB.dbName, blockNo, len(block.Data.Data))

//TODO add check for invalid trans in bit array
// Get the invalidation byte array for the block
txsFilter := util.TxValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
// Initialize txsFilter if it does not yet exist (e.g. during testing, for genesis block, etc)
if len(txsFilter) == 0 {
txsFilter = util.NewTxValidationFlags(len(block.Data.Data))
block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txsFilter
}

// write each tran's write set to history db
for _, envBytes := range block.Data.Data {
tranNo++

// If the tran is marked as invalid, skip it
// Note, tranNo starts at 1 for height, while tranIndex starts at 0 for invalid array
if txsFilter.IsInvalid(int(tranNo) - 1) {
logger.Debugf("Channel [%s]: Skipping history write for invalid transaction number %d",
historyDB.dbName, tranNo)
continue
}

env, err := putils.GetEnvelopeFromBlock(envBytes)
if err != nil {
return err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import (
configtxtest "github.com/hyperledger/fabric/common/configtx/test"
"github.com/hyperledger/fabric/common/ledger/testutil"
"github.com/hyperledger/fabric/core/ledger"
"github.com/hyperledger/fabric/core/ledger/util"
"github.com/hyperledger/fabric/protos/common"
"github.com/hyperledger/fabric/protos/peer"
"github.com/spf13/viper"
)

Expand Down Expand Up @@ -124,6 +127,45 @@ func TestHistory(t *testing.T) {
testutil.AssertEquals(t, count, 3)
}

func TestHistoryForInvalidTran(t *testing.T) {

env := NewTestHistoryEnv(t)
defer env.cleanup()
provider := env.testBlockStorageEnv.provider
store1, err := provider.OpenBlockStore("ledger1")
testutil.AssertNoError(t, err, "Error upon provider.OpenBlockStore()")
defer store1.Shutdown()

//block1
simulator, _ := env.txmgr.NewTxSimulator()
value1 := []byte("value1")
simulator.SetState("ns1", "key7", value1)
simulator.Done()
simRes, _ := simulator.GetTxSimulationResults()
bg := testutil.NewBlockGenerator(t)
block1 := bg.NextBlock([][]byte{simRes}, false)

//for this invalid tran test, set the transaction to invalid
txsFilter := util.TxValidationFlags(block1.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
txsFilter.SetFlag(0, peer.TxValidationCode_INVALID_OTHER_REASON)
block1.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txsFilter

err = store1.AddBlock(block1)
testutil.AssertNoError(t, err, "")
err = env.testHistoryDB.Commit(block1)
testutil.AssertNoError(t, err, "")

qhistory, err := env.testHistoryDB.NewHistoryQueryExecutor(store1)
testutil.AssertNoError(t, err, "Error upon NewHistoryQueryExecutor")

itr, err2 := qhistory.GetHistoryForKey("ns1", "key7")
testutil.AssertNoError(t, err2, "Error upon GetHistoryForKey()")

// test that there are no history values, since the tran was marked as invalid
kmod, _ := itr.Next()
testutil.AssertNil(t, kmod)
}

//TestSavepoint tests that save points get written after each block and get returned via GetBlockNumfromSavepoint
func TestHistoryDisabled(t *testing.T) {

Expand Down

0 comments on commit 40e061c

Please sign in to comment.