Skip to content

Fix iterators with existant start, nil end #12661

@ValarDragon

Description

@ValarDragon

Summary

Both of the following iterators fail:

func (suite *TestSuite) TestIterator() {
	key := suite.App.GetKVStoreKey()[types.StoreKey]
	store := suite.Ctx.KVStore(key)

	store.Set([]byte("AB"), []byte{1})

	iter := store.Iterator([]byte("AA"), nil)
	suite.Require().True(iter.Valid())
	iter.Close()

	iter = store.Iterator([]byte("A"), nil)
	suite.Require().True(iter.Valid())
	iter.Close()
}

They should work. The root cause is that there is a check in the CacheKvStore, that unsafe converts []byte to a string, and then compares the string representations.

The typecast of a nil []byte, will always return as less than a correctly formed string. Thus you get start > end and the CacheKVStore iterator returns a no-op.

This is a bug in the SDK, that we have to fix at the caller level, by making nil 0xff. (This took forever in debugging to figure out)

(Just flagging here, the entire CacheKVStore should likely be rewritten due to the massive number of issues and complexity it has with iterators right now. Will try to make a larger issue about this later)

Proposal

Fix the implementation here https://github.com/cosmos/cosmos-sdk/blob/main/store/cachekv/store.go#L283-L287 by making more explicit handling of this nil end time case.


For Admin Use

  • Not duplicate issue
  • Appropriate labels applied
  • Appropriate contributors tagged
  • Contributor assigned/self-assigned

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions