Skip to content

Commit 7c484f6

Browse files
committed
[FAB-4842] Improve logging for invalid txs
See the JIRA for more details, but this change adds the channel and transaction id to the warning message for invalid transactions. Change-Id: Ie07a1c29d03097e366466bf4657d1dae8a3948d8 Signed-off-by: Gari Singh <gari.r.singh@gmail.com>
1 parent 03d1479 commit 7c484f6

File tree

2 files changed

+121
-13
lines changed

2 files changed

+121
-13
lines changed

core/ledger/kvledger/txmgmt/validator/valimpl/helper.go

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func validatePvtdata(tx *valinternal.Transaction, pvtdata *ledger.TxPvtData) err
7777
hashInPubdata := tx.RetrieveHash(nsPvtdata.Namespace, collPvtdata.CollectionName)
7878
if !bytes.Equal(collPvtdataHash, hashInPubdata) {
7979
return &validator.ErrPvtdataHashMissmatch{
80-
Msg: fmt.Sprintf(`Hash of pvt data for collection [%s:%s] does not match with the corresponding hash in the public data.
80+
Msg: fmt.Sprintf(`Hash of pvt data for collection [%s:%s] does not match with the corresponding hash in the public data.
8181
public hash = [%#v], pvt data hash = [%#v]`, nsPvtdata.Namespace, collPvtdata.CollectionName, hashInPubdata, collPvtdataHash),
8282
}
8383
}
@@ -98,24 +98,27 @@ func preprocessProtoBlock(txmgr txmgr.TxMgr, block *common.Block) (*valinternal.
9898
block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txsFilter
9999
}
100100
for txIndex, envBytes := range block.Data.Data {
101+
var env *common.Envelope
102+
var chdr *common.ChannelHeader
103+
var payload *common.Payload
104+
var err error
105+
if env, err = utils.GetEnvelopeFromBlock(envBytes); err == nil {
106+
if payload, err = utils.GetPayload(env); err == nil {
107+
chdr, err = utils.UnmarshalChannelHeader(payload.Header.ChannelHeader)
108+
}
109+
}
101110
if txsFilter.IsInvalid(txIndex) {
102-
// Skiping invalid transaction
103-
logger.Warningf("Block [%d] Transaction index [%d] marked as invalid by committer. Reason code [%d]",
104-
block.Header.Number, txIndex, txsFilter.Flag(txIndex))
111+
// Skipping invalid transaction
112+
logger.Warningf("Channel [%s]: Block [%d] Transaction index [%d] TxId [%s]"+
113+
" marked as invalid by committer. Reason code [%s]",
114+
chdr.GetChannelId(), block.Header.Number, txIndex, chdr.GetTxId(),
115+
txsFilter.Flag(txIndex).String())
105116
continue
106117
}
107-
env, err := utils.GetEnvelopeFromBlock(envBytes)
108-
if err != nil {
109-
return nil, err
110-
}
111-
payload, err := utils.GetPayload(env)
112-
if err != nil {
113-
return nil, err
114-
}
115-
chdr, err := utils.UnmarshalChannelHeader(payload.Header.ChannelHeader)
116118
if err != nil {
117119
return nil, err
118120
}
121+
119122
var txRWSet *rwsetutil.TxRwSet
120123
txType := common.HeaderType(chdr.Type)
121124
logger.Debugf("txType=%s", txType)
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package valimpl
8+
9+
import (
10+
"fmt"
11+
"testing"
12+
13+
"github.com/hyperledger/fabric/common/ledger/testutil"
14+
"github.com/hyperledger/fabric/common/util"
15+
lutils "github.com/hyperledger/fabric/core/ledger/util"
16+
"github.com/hyperledger/fabric/protos/common"
17+
"github.com/hyperledger/fabric/protos/peer"
18+
putils "github.com/hyperledger/fabric/protos/utils"
19+
"github.com/op/go-logging"
20+
"github.com/stretchr/testify/assert"
21+
)
22+
23+
func TestPreprocessProtoBlock(t *testing.T) {
24+
25+
// good block
26+
//_, gb := testutil.NewBlockGenerator(t, "testLedger", false)
27+
gb := testutil.ConstructTestBlock(t, 10, 1, 1)
28+
_, err := preprocessProtoBlock(nil, gb)
29+
assert.NoError(t, err)
30+
// bad envelope
31+
gb = testutil.ConstructTestBlock(t, 11, 1, 1)
32+
gb.Data = &common.BlockData{Data: [][]byte{[]byte{123}}}
33+
gb.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] =
34+
lutils.NewTxValidationFlags(len(gb.Data.Data))
35+
_, err = preprocessProtoBlock(nil, gb)
36+
assert.Error(t, err)
37+
t.Log(err)
38+
// bad payload
39+
gb = testutil.ConstructTestBlock(t, 12, 1, 1)
40+
envBytes, _ := putils.GetBytesEnvelope(&common.Envelope{Payload: []byte{123}})
41+
gb.Data = &common.BlockData{Data: [][]byte{envBytes}}
42+
_, err = preprocessProtoBlock(nil, gb)
43+
assert.Error(t, err)
44+
t.Log(err)
45+
// bad channel header
46+
gb = testutil.ConstructTestBlock(t, 13, 1, 1)
47+
payloadBytes, _ := putils.GetBytesPayload(&common.Payload{
48+
Header: &common.Header{ChannelHeader: []byte{123}},
49+
})
50+
envBytes, _ = putils.GetBytesEnvelope(&common.Envelope{Payload: payloadBytes})
51+
gb.Data = &common.BlockData{Data: [][]byte{envBytes}}
52+
_, err = preprocessProtoBlock(nil, gb)
53+
assert.Error(t, err)
54+
t.Log(err)
55+
56+
// bad channel header with invalid filter set
57+
gb = testutil.ConstructTestBlock(t, 14, 1, 1)
58+
payloadBytes, _ = putils.GetBytesPayload(&common.Payload{
59+
Header: &common.Header{ChannelHeader: []byte{123}},
60+
})
61+
envBytes, _ = putils.GetBytesEnvelope(&common.Envelope{Payload: payloadBytes})
62+
gb.Data = &common.BlockData{Data: [][]byte{envBytes}}
63+
flags := lutils.NewTxValidationFlags(len(gb.Data.Data))
64+
flags.SetFlag(0, peer.TxValidationCode_BAD_CHANNEL_HEADER)
65+
gb.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = flags
66+
_, err = preprocessProtoBlock(nil, gb)
67+
assert.NoError(t, err) // invalid filter should take precendence
68+
69+
// new block
70+
var blockNum uint64 = 15
71+
txid := "testtxid1234"
72+
gb = testutil.ConstructBlockWithTxid(t, blockNum, []byte{123},
73+
[][]byte{[]byte{123}}, []string{txid}, false)
74+
flags = lutils.NewTxValidationFlags(len(gb.Data.Data))
75+
flags.SetFlag(0, peer.TxValidationCode_BAD_HEADER_EXTENSION)
76+
gb.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = flags
77+
// set logging backend for test
78+
backend := logging.NewMemoryBackend(1)
79+
logging.SetBackend(backend)
80+
_, err = preprocessProtoBlock(nil, gb)
81+
assert.NoError(t, err)
82+
expected := fmt.Sprintf("Channel [%s]: Block [%d] Transaction index [%d] TxId [%s]"+
83+
" marked as invalid by committer. Reason code [%s]",
84+
util.GetTestChainID(), blockNum, 0, txid, peer.TxValidationCode_BAD_HEADER_EXTENSION.String())
85+
t.Log(expected)
86+
assert.Equal(t, expected, memoryRecordN(backend, 0).Message())
87+
//assert.Equal(t, message, MemoryRecordN(backend, i).Message())
88+
t.Log(memoryRecordN(backend, 0).Message())
89+
90+
}
91+
92+
// from go-logging memory_test.go
93+
func memoryRecordN(b *logging.MemoryBackend, n int) *logging.Record {
94+
node := b.Head()
95+
for i := 0; i < n; i++ {
96+
if node == nil {
97+
break
98+
}
99+
node = node.Next()
100+
}
101+
if node == nil {
102+
return nil
103+
}
104+
return node.Record
105+
}

0 commit comments

Comments
 (0)