Skip to content

Commit

Permalink
Fix history panic on config blocks
Browse files Browse the repository at this point in the history
Getting a panic error when committer receives a config block
and attempts to write the tran to history db.
Fixed by only writing to history db for endorsement transactions.

Change-Id: I32d5e414199d85355eeae84f3e1ae680fe0811f0
Signed-off-by: denyeart <enyeart@us.ibm.com>
  • Loading branch information
denyeart committed Jan 27, 2017
1 parent 0920c5e commit cb46696
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
"github.com/hyperledger/fabric/core/ledger/ledgerconfig"
"github.com/hyperledger/fabric/core/ledger/util/leveldbhelper"
"github.com/hyperledger/fabric/protos/common"
"github.com/hyperledger/fabric/protos/utils"
putils "github.com/hyperledger/fabric/protos/utils"
logging "github.com/op/go-logging"
)

Expand Down Expand Up @@ -97,41 +97,57 @@ func (historyDB *historyDB) Commit(block *common.Block) error {
//TODO add check for invalid trans in bit array
for _, envBytes := range block.Data.Data {
tranNo++
logger.Debugf("Updating history for tranNo: %v", tranNo)

// extract actions from the envelope message
respPayload, err := utils.GetActionFromEnvelope(envBytes)
env, err := putils.GetEnvelopeFromBlock(envBytes)
if err != nil {
return err
}

//preparation for extracting RWSet from transaction
txRWSet := &rwset.TxReadWriteSet{}

// Get the Result from the Action and then Unmarshal
// it into a TxReadWriteSet using custom unmarshalling
if err = txRWSet.Unmarshal(respPayload.Results); err != nil {
payload, err := putils.GetPayload(env)
if err != nil {
return err
}

// for each transaction, loop through the namespaces and writesets
// and add a history record for each write
for _, nsRWSet := range txRWSet.NsRWs {
ns := nsRWSet.NameSpace
if common.HeaderType(payload.Header.ChainHeader.Type) == common.HeaderType_ENDORSER_TRANSACTION {

for _, kvWrite := range nsRWSet.Writes {
writeKey := kvWrite.Key
logger.Debugf("Updating history for tranNo: %d", tranNo)
// extract actions from the envelope message
respPayload, err := putils.GetActionFromEnvelope(envBytes)
if err != nil {
return err
}

logger.Debugf("Writing history record for: ns=%s, key=%s, blockNo=%d tranNo=%d",
ns, writeKey, blockNo, tranNo)
//preparation for extracting RWSet from transaction
txRWSet := &rwset.TxReadWriteSet{}

// Get the Result from the Action and then Unmarshal
// it into a TxReadWriteSet using custom unmarshalling
if err = txRWSet.Unmarshal(respPayload.Results); err != nil {
return err
}
// for each transaction, loop through the namespaces and writesets
// and add a history record for each write
for _, nsRWSet := range txRWSet.NsRWs {
ns := nsRWSet.NameSpace

//composite key for history records is in the form ns~key~blockNo~tranNo
compositeHistoryKey := historydb.ConstructCompositeHistoryKey(ns, writeKey, blockNo, tranNo)
for _, kvWrite := range nsRWSet.Writes {
writeKey := kvWrite.Key

// No value is required, write an empty byte array (emptyValue) since Put() of nil is not allowed
dbBatch.Put(compositeHistoryKey, emptyValue)
logger.Debugf("Writing history record for: ns=%s, key=%s, blockNo=%d tranNo=%d",
ns, writeKey, blockNo, tranNo)

//composite key for history records is in the form ns~key~blockNo~tranNo
compositeHistoryKey := historydb.ConstructCompositeHistoryKey(ns, writeKey, blockNo, tranNo)

// No value is required, write an empty byte array (emptyValue) since Put() of nil is not allowed
dbBatch.Put(compositeHistoryKey, emptyValue)
}
}

} else {
logger.Debugf("Skipping transaction %d since it is not an endorsement transaction\n", tranNo)
}

}

// add savepoint for recovery purpose
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"os"
"testing"

configtxtest "github.com/hyperledger/fabric/common/configtx/test"
"github.com/hyperledger/fabric/core/ledger"
"github.com/hyperledger/fabric/core/ledger/testutil"
"github.com/spf13/viper"
Expand Down Expand Up @@ -125,3 +126,17 @@ func TestHistoryDisabled(t *testing.T) {
_, err2 := qhistory.GetHistoryForKey("ns1", "key7")
testutil.AssertError(t, err2, "Error should have been returned for GetHistoryForKey() when history disabled")
}

//TestGenesisBlockNoError tests that Genesis blocks are ignored by history processing
// since we only persist history of chaincode key writes
func TestGenesisBlockNoError(t *testing.T) {

env := NewTestHistoryEnv(t)
defer env.cleanup()

block, err := configtxtest.MakeGenesisBlock("test_chainid")
testutil.AssertNoError(t, err, "")

err = env.TestHistoryDB.Commit(block)
testutil.AssertNoError(t, err, "")
}

0 comments on commit cb46696

Please sign in to comment.