Skip to content

Commit 97a5e62

Browse files
committed
Fix for nil pointer error during phantom validation
https://jira.hyperledger.org/browse/FAB-2618 - Added a nil check - Added a test case for this situation Change-Id: I245c68b7c1e732bd1dd694e57438232a0f4e750c Signed-off-by: manish <[email protected]>
1 parent 01cc491 commit 97a5e62

File tree

2 files changed

+44
-20
lines changed

2 files changed

+44
-20
lines changed

core/ledger/kvledger/txmgmt/validator/statebasedval/combined_iterator.go

+12-3
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@ limitations under the License.
1616

1717
package statebasedval
1818

19-
import "github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/statedb"
20-
import "strings"
19+
import (
20+
"strings"
21+
22+
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/statedb"
23+
)
2124

2225
// combinedIterator implements the interface statedb.ResultsIterator.
2326
// Internally, it maintains two iterators
@@ -131,15 +134,21 @@ func (itr *combinedIterator) serveEndKeyIfNeeded() (statedb.QueryResult, error)
131134
var vv *statedb.VersionedValue
132135
var err error
133136
vv = itr.updates.Get(itr.ns, itr.endKey)
137+
logger.Debugf("endKey value from updates:%s", vv)
134138
if vv == nil {
135139
if vv, err = itr.db.GetState(itr.ns, itr.endKey); err != nil {
136140
return nil, err
137141
}
142+
logger.Debugf("endKey value from stateDB:%s", vv)
143+
}
144+
itr.endKeyServed = true
145+
if vv == nil {
146+
return nil, nil
138147
}
139148
vkv := &statedb.VersionedKV{
140149
CompositeKey: statedb.CompositeKey{Namespace: itr.ns, Key: itr.endKey},
141150
VersionedValue: statedb.VersionedValue{Value: vv.Value, Version: vv.Version}}
142-
itr.endKeyServed = true
151+
143152
if isDelete(vkv) {
144153
return nil, nil
145154
}

core/ledger/kvledger/txmgmt/validator/statebasedval/combined_iterator_test.go

+32-17
Original file line numberDiff line numberDiff line change
@@ -50,55 +50,70 @@ func TestCombinedIterator(t *testing.T) {
5050
// prepare batch2 (empty)
5151
batch2 := statedb.NewUpdateBatch()
5252

53-
// Test db + batch1 updates
53+
// Test db + batch1 updates (exclude endKey)
5454
itr1, _ := newCombinedIterator(db, batch1, "ns", "key2", "key8", false)
5555
defer itr1.Close()
56-
checkItrResults(t, itr1, []*statedb.VersionedKV{
56+
checkItrResults(t, "ExcludeEndKey", itr1, []*statedb.VersionedKV{
5757
constructVersionedKV("ns", "key3", []byte("value3"), version.NewHeight(1, 1)),
5858
constructVersionedKV("ns", "key4", []byte("value4"), version.NewHeight(1, 1)),
5959
constructVersionedKV("ns", "key6", []byte("value6_new"), version.NewHeight(1, 1)),
6060
constructVersionedKV("ns", "key7", []byte("value7"), version.NewHeight(1, 1)),
6161
})
6262

63+
// Test db + batch1 updates (include endKey)
6364
itr1WithEndKey, _ := newCombinedIterator(db, batch1, "ns", "key2", "key8", true)
6465
defer itr1WithEndKey.Close()
65-
checkItrResults(t, itr1WithEndKey, []*statedb.VersionedKV{
66+
checkItrResults(t, "IncludeEndKey", itr1WithEndKey, []*statedb.VersionedKV{
6667
constructVersionedKV("ns", "key3", []byte("value3"), version.NewHeight(1, 1)),
6768
constructVersionedKV("ns", "key4", []byte("value4"), version.NewHeight(1, 1)),
6869
constructVersionedKV("ns", "key6", []byte("value6_new"), version.NewHeight(1, 1)),
6970
constructVersionedKV("ns", "key7", []byte("value7"), version.NewHeight(1, 1)),
7071
constructVersionedKV("ns", "key8", []byte("value8"), version.NewHeight(1, 1)),
7172
})
7273

73-
// Test db + batch2 updates
74-
itr2, _ := newCombinedIterator(db, batch2, "ns", "key2", "key8", false)
75-
defer itr2.Close()
76-
checkItrResults(t, itr2, []*statedb.VersionedKV{
74+
// Test db + batch1 updates (include endKey) for extra range
75+
itr1WithEndKeyExtraRange, _ := newCombinedIterator(db, batch1, "ns", "key0", "key9", true)
76+
defer itr1WithEndKeyExtraRange.Close()
77+
checkItrResults(t, "IncludeEndKey_ExtraRange", itr1WithEndKeyExtraRange, []*statedb.VersionedKV{
78+
constructVersionedKV("ns", "key1", []byte("value1"), version.NewHeight(1, 1)),
79+
constructVersionedKV("ns", "key3", []byte("value3"), version.NewHeight(1, 1)),
7780
constructVersionedKV("ns", "key4", []byte("value4"), version.NewHeight(1, 1)),
78-
constructVersionedKV("ns", "key6", []byte("value6"), version.NewHeight(1, 1)),
81+
constructVersionedKV("ns", "key6", []byte("value6_new"), version.NewHeight(1, 1)),
82+
constructVersionedKV("ns", "key7", []byte("value7"), version.NewHeight(1, 1)),
83+
constructVersionedKV("ns", "key8", []byte("value8"), version.NewHeight(1, 1)),
7984
})
8085

8186
// Test db + batch1 updates with full range query
8287
itr3, _ := newCombinedIterator(db, batch1, "ns", "", "", false)
8388
defer itr3.Close()
84-
checkItrResults(t, itr3, []*statedb.VersionedKV{
89+
checkItrResults(t, "ExcludeEndKey_FullRange", itr3, []*statedb.VersionedKV{
8590
constructVersionedKV("ns", "key1", []byte("value1"), version.NewHeight(1, 1)),
8691
constructVersionedKV("ns", "key3", []byte("value3"), version.NewHeight(1, 1)),
8792
constructVersionedKV("ns", "key4", []byte("value4"), version.NewHeight(1, 1)),
8893
constructVersionedKV("ns", "key6", []byte("value6_new"), version.NewHeight(1, 1)),
8994
constructVersionedKV("ns", "key7", []byte("value7"), version.NewHeight(1, 1)),
9095
constructVersionedKV("ns", "key8", []byte("value8"), version.NewHeight(1, 1)),
9196
})
97+
98+
// Test db + batch2 updates
99+
itr2, _ := newCombinedIterator(db, batch2, "ns", "key2", "key8", false)
100+
defer itr2.Close()
101+
checkItrResults(t, "ExcludeEndKey_EmptyUpdates", itr2, []*statedb.VersionedKV{
102+
constructVersionedKV("ns", "key4", []byte("value4"), version.NewHeight(1, 1)),
103+
constructVersionedKV("ns", "key6", []byte("value6"), version.NewHeight(1, 1)),
104+
})
92105
}
93106

94-
func checkItrResults(t *testing.T, itr statedb.ResultsIterator, expectedResults []*statedb.VersionedKV) {
95-
for i := 0; i < len(expectedResults); i++ {
96-
res, _ := itr.Next()
97-
testutil.AssertEquals(t, res, expectedResults[i])
98-
}
99-
lastRes, err := itr.Next()
100-
testutil.AssertNoError(t, err, "")
101-
testutil.AssertNil(t, lastRes)
107+
func checkItrResults(t *testing.T, testName string, itr statedb.ResultsIterator, expectedResults []*statedb.VersionedKV) {
108+
t.Run(testName, func(t *testing.T) {
109+
for i := 0; i < len(expectedResults); i++ {
110+
res, _ := itr.Next()
111+
testutil.AssertEquals(t, res, expectedResults[i])
112+
}
113+
lastRes, err := itr.Next()
114+
testutil.AssertNoError(t, err, "")
115+
testutil.AssertNil(t, lastRes)
116+
})
102117
}
103118

104119
func constructVersionedKV(ns string, key string, value []byte, version *version.Height) *statedb.VersionedKV {

0 commit comments

Comments
 (0)