diff --git a/store/prefix/store_test.go b/store/prefix/store_test.go index 8da075dc90..e15a4b46b4 100644 --- a/store/prefix/store_test.go +++ b/store/prefix/store_test.go @@ -15,7 +15,6 @@ import ( "github.com/cosmos/cosmos-sdk/store/gaskv" "github.com/cosmos/cosmos-sdk/store/iavl" "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" ) // copied from iavl/store_test.go @@ -248,7 +247,7 @@ func mockStoreWithStuff() types.KVStore { store.Set(bz("key2"), bz("value2")) store.Set(bz("key3"), bz("value3")) store.Set(bz("something"), bz("else")) - store.Set(bz("k"), bz(sdk.PrefixValidator)) + store.Set(bz("k"), bz("val")) store.Set(bz("ke"), bz("valu")) store.Set(bz("kee"), bz("valuu")) return store diff --git a/store/snapshots/chunk.go b/store/snapshots/chunk.go index 514acc1f94..271ab74927 100644 --- a/store/snapshots/chunk.go +++ b/store/snapshots/chunk.go @@ -4,7 +4,8 @@ import ( "io" "math" - sdkerrors "cosmossdk.io/errors" + "cosmossdk.io/errors" + snapshottypes "github.com/cosmos/cosmos-sdk/store/snapshots/types" storetypes "github.com/cosmos/cosmos-sdk/store/types" ) @@ -70,7 +71,7 @@ func (w *ChunkWriter) CloseWithError(err error) { // Write implements io.Writer. func (w *ChunkWriter) Write(data []byte) (int, error) { if w.closed { - return 0, sdkerrors.Wrap(storetypes.ErrLogic, "cannot write to closed ChunkWriter") + return 0, errors.Wrap(storetypes.ErrLogic, "cannot write to closed ChunkWriter") } nTotal := 0 for len(data) > 0 { @@ -168,14 +169,14 @@ func DrainChunks(chunks <-chan io.ReadCloser) { // ValidRestoreHeight will check height is valid for snapshot restore or not func ValidRestoreHeight(format uint32, height uint64) error { if format != snapshottypes.CurrentFormat { - return sdkerrors.Wrapf(snapshottypes.ErrUnknownFormat, "format %v", format) + return errors.Wrapf(snapshottypes.ErrUnknownFormat, "format %v", format) } if height == 0 { - return sdkerrors.Wrap(storetypes.ErrLogic, "cannot restore snapshot at height 0") + return errors.Wrap(storetypes.ErrLogic, "cannot restore snapshot at height 0") } if height > uint64(math.MaxInt64) { - return sdkerrors.Wrapf(snapshottypes.ErrInvalidMetadata, + return errors.Wrapf(snapshottypes.ErrInvalidMetadata, "snapshot height %v cannot exceed %v", height, int64(math.MaxInt64)) } diff --git a/store/streaming/constructor_test.go b/store/streaming/constructor_test.go index 0d8c281219..29d097611c 100644 --- a/store/streaming/constructor_test.go +++ b/store/streaming/constructor_test.go @@ -3,6 +3,10 @@ package streaming_test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" + dbm "github.com/tendermint/tm-db" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" codecTypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -11,13 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/store/streaming/file" "github.com/cosmos/cosmos-sdk/store/types" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module/testutil" - - "github.com/tendermint/tendermint/libs/log" - dbm "github.com/tendermint/tm-db" - - "github.com/stretchr/testify/require" ) type fakeOptions struct{} @@ -32,7 +30,7 @@ func (f *fakeOptions) Get(key string) interface{} { var ( mockOptions = new(fakeOptions) - mockKeys = []types.StoreKey{sdk.NewKVStoreKey("mockKey1"), sdk.NewKVStoreKey("mockKey2")} + mockKeys = []types.StoreKey{types.NewKVStoreKey("mockKey1"), types.NewKVStoreKey("mockKey2")} interfaceRegistry = codecTypes.NewInterfaceRegistry() testMarshaller = codec.NewProtoCodec(interfaceRegistry) ) @@ -59,7 +57,7 @@ func TestStreamingServiceConstructor(t *testing.T) { func TestLoadStreamingServices(t *testing.T) { db := dbm.NewMemDB() encCdc := testutil.MakeTestEncodingConfig() - keys := sdk.NewKVStoreKeys("mockKey1", "mockKey2") + keys := types.NewKVStoreKeys("mockKey1", "mockKey2") bApp := baseapp.NewBaseApp("appName", log.NewNopLogger(), db, nil) testCases := map[string]struct { diff --git a/store/streaming/file/service_test.go b/store/streaming/file/service_test.go index 112d8bac49..21ebf508f6 100644 --- a/store/streaming/file/service_test.go +++ b/store/streaming/file/service_test.go @@ -1,6 +1,7 @@ package file import ( + "context" "encoding/binary" "errors" "fmt" @@ -25,7 +26,7 @@ var ( testMarshaller = codec.NewProtoCodec(interfaceRegistry) testStreamingService *StreamingService testListener1, testListener2 types.WriteListener - emptyContext = sdk.Context{} + emptyContext = context.TODO() // test abci message types mockHash = []byte{1, 2, 3, 4, 5, 6, 7, 8, 9} @@ -94,8 +95,8 @@ var ( } // mock store keys - mockStoreKey1 = sdk.NewKVStoreKey("mockStore1") - mockStoreKey2 = sdk.NewKVStoreKey("mockStore2") + mockStoreKey1 = types.NewKVStoreKey("mockStore1") + mockStoreKey2 = types.NewKVStoreKey("mockStore2") // file stuff testPrefix = "testPrefix" diff --git a/store/types/errors.go b/store/types/errors.go index 3aa88e2dd0..bd04e07f3c 100644 --- a/store/types/errors.go +++ b/store/types/errors.go @@ -1,7 +1,7 @@ package types import ( - sdkerrors "cosmossdk.io/errors" + "cosmossdk.io/errors" abci "github.com/tendermint/tendermint/abci/types" ) @@ -9,23 +9,23 @@ const StoreCodespace = "store" var ( // ErrInvalidProof is returned when a proof is invalid - ErrInvalidProof = sdkerrors.Register(StoreCodespace, 2, "invalid proof") + ErrInvalidProof = errors.Register(StoreCodespace, 2, "invalid proof") // ErrTxDecode is returned if we cannot parse a transaction - ErrTxDecode = sdkerrors.Register(StoreCodespace, 3, "tx parse error") + ErrTxDecode = errors.Register(StoreCodespace, 3, "tx parse error") // ErrUnknownRequest to doc - ErrUnknownRequest = sdkerrors.Register(StoreCodespace, 4, "unknown request") + ErrUnknownRequest = errors.Register(StoreCodespace, 4, "unknown request") // ErrLogic defines an internal logic error, e.g. an invariant or assertion // that is violated. It is a programmer error, not a user-facing error. - ErrLogic = sdkerrors.Register(StoreCodespace, 5, "internal logic error") + ErrLogic = errors.Register(StoreCodespace, 5, "internal logic error") // ErrConflict defines a conflict error, e.g. when two goroutines try to access // the same resource and one of them fails. - ErrConflict = sdkerrors.Register(StoreCodespace, 6, "conflict") + ErrConflict = errors.Register(StoreCodespace, 6, "conflict") // ErrInvalidRequest defines an ABCI typed error where the request contains // invalid data. - ErrInvalidRequest = sdkerrors.Register(StoreCodespace, 7, "invalid request") + ErrInvalidRequest = errors.Register(StoreCodespace, 7, "invalid request") ) // ABCI QueryResult @@ -33,7 +33,7 @@ var ( // QueryResult returns a ResponseQuery from an error. It will try to parse ABCI // info from the error. func QueryResult(err error, debug bool) abci.ResponseQuery { - space, code, log := sdkerrors.ABCIInfo(err, debug) + space, code, log := errors.ABCIInfo(err, debug) return abci.ResponseQuery{ Codespace: space, Code: code, diff --git a/store/types/store.go b/store/types/store.go index 3b0a61f06f..4cb7af09e9 100644 --- a/store/types/store.go +++ b/store/types/store.go @@ -364,6 +364,19 @@ func NewKVStoreKey(name string) *KVStoreKey { } } +// NewKVStoreKeys returns a map of new pointers to KVStoreKey's. +// The function will panic if there is a potential conflict in names (see `assertNoPrefix` +// function for more details). +func NewKVStoreKeys(names ...string) map[string]*KVStoreKey { + assertNoCommonPrefix(names) + keys := make(map[string]*KVStoreKey, len(names)) + for _, n := range names { + keys[n] = NewKVStoreKey(n) + } + + return keys +} + func (key *KVStoreKey) Name() string { return key.name } diff --git a/store/types/utils.go b/store/types/utils.go index 7b69dacca3..306fec158d 100644 --- a/store/types/utils.go +++ b/store/types/utils.go @@ -2,6 +2,9 @@ package types import ( "bytes" + "fmt" + "sort" + "strings" "github.com/cosmos/cosmos-sdk/types/kv" ) @@ -105,3 +108,16 @@ func PrefixEndBytes(prefix []byte) []byte { func InclusiveEndBytes(inclusiveBytes []byte) []byte { return append(inclusiveBytes, byte(0x00)) } + +// assertNoCommonPrefix will panic if there are two keys: k1 and k2 in keys, such that +// k1 is a prefix of k2 +func assertNoCommonPrefix(keys []string) { + sorted := make([]string, len(keys)) + copy(sorted, keys) + sort.Strings(sorted) + for i := 1; i < len(sorted); i++ { + if strings.HasPrefix(sorted[i], sorted[i-1]) { + panic(fmt.Sprint("Potential key collision between KVStores:", sorted[i], " - ", sorted[i-1])) + } + } +} diff --git a/store/types/utils_test.go b/store/types/utils_test.go index a13a2d9a5a..7af25af15f 100644 --- a/store/types/utils_test.go +++ b/store/types/utils_test.go @@ -9,17 +9,17 @@ import ( dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/store/rootmulti" - sdk "github.com/cosmos/cosmos-sdk/store/types" + "github.com/cosmos/cosmos-sdk/store/types" ) -func initTestStores(t *testing.T) (sdk.KVStore, sdk.KVStore) { +func initTestStores(t *testing.T) (types.KVStore, types.KVStore) { db := dbm.NewMemDB() ms := rootmulti.NewStore(db, log.NewNopLogger()) - key1 := sdk.NewKVStoreKey("store1") - key2 := sdk.NewKVStoreKey("store2") - require.NotPanics(t, func() { ms.MountStoreWithDB(key1, sdk.StoreTypeIAVL, db) }) - require.NotPanics(t, func() { ms.MountStoreWithDB(key2, sdk.StoreTypeIAVL, db) }) + key1 := types.NewKVStoreKey("store1") + key2 := types.NewKVStoreKey("store2") + require.NotPanics(t, func() { ms.MountStoreWithDB(key1, types.StoreTypeIAVL, db) }) + require.NotPanics(t, func() { ms.MountStoreWithDB(key2, types.StoreTypeIAVL, db) }) require.NoError(t, ms.LoadLatestVersion()) return ms.GetKVStore(key1), ms.GetKVStore(key2) } @@ -32,27 +32,27 @@ func TestDiffKVStores(t *testing.T) { store1.Set(k1, v1) store2.Set(k1, v1) - kvAs, kvBs := sdk.DiffKVStores(store1, store2, nil) + kvAs, kvBs := types.DiffKVStores(store1, store2, nil) require.Equal(t, 0, len(kvAs)) require.Equal(t, len(kvAs), len(kvBs)) // delete k1 from store2, which is now empty store2.Delete(k1) - kvAs, kvBs = sdk.DiffKVStores(store1, store2, nil) + kvAs, kvBs = types.DiffKVStores(store1, store2, nil) require.Equal(t, 1, len(kvAs)) require.Equal(t, len(kvAs), len(kvBs)) // set k1 in store2, different value than what store1 holds for k1 v2 := []byte("v2") store2.Set(k1, v2) - kvAs, kvBs = sdk.DiffKVStores(store1, store2, nil) + kvAs, kvBs = types.DiffKVStores(store1, store2, nil) require.Equal(t, 1, len(kvAs)) require.Equal(t, len(kvAs), len(kvBs)) // add k2 to store2 k2 := []byte("k2") store2.Set(k2, v2) - kvAs, kvBs = sdk.DiffKVStores(store1, store2, nil) + kvAs, kvBs = types.DiffKVStores(store1, store2, nil) require.Equal(t, 2, len(kvAs)) require.Equal(t, len(kvAs), len(kvBs)) @@ -66,7 +66,7 @@ func TestDiffKVStores(t *testing.T) { k1Prefixed := append(prefix, k1...) store1.Set(k1Prefixed, v1) store2.Set(k1Prefixed, v2) - kvAs, kvBs = sdk.DiffKVStores(store1, store2, [][]byte{prefix}) + kvAs, kvBs = types.DiffKVStores(store1, store2, [][]byte{prefix}) require.Equal(t, 0, len(kvAs)) require.Equal(t, len(kvAs), len(kvBs)) } @@ -74,16 +74,16 @@ func TestDiffKVStores(t *testing.T) { func TestPrefixEndBytes(t *testing.T) { t.Parallel() bs1 := []byte{0x23, 0xA5, 0x06} - require.True(t, bytes.Equal([]byte{0x23, 0xA5, 0x07}, sdk.PrefixEndBytes(bs1))) + require.True(t, bytes.Equal([]byte{0x23, 0xA5, 0x07}, types.PrefixEndBytes(bs1))) bs2 := []byte{0x23, 0xA5, 0xFF} - require.True(t, bytes.Equal([]byte{0x23, 0xA6}, sdk.PrefixEndBytes(bs2))) - require.Nil(t, sdk.PrefixEndBytes([]byte{0xFF})) - require.Nil(t, sdk.PrefixEndBytes(nil)) + require.True(t, bytes.Equal([]byte{0x23, 0xA6}, types.PrefixEndBytes(bs2))) + require.Nil(t, types.PrefixEndBytes([]byte{0xFF})) + require.Nil(t, types.PrefixEndBytes(nil)) } func TestInclusiveEndBytes(t *testing.T) { t.Parallel() - require.True(t, bytes.Equal([]byte{0x00}, sdk.InclusiveEndBytes(nil))) + require.True(t, bytes.Equal([]byte{0x00}, types.InclusiveEndBytes(nil))) bs := []byte("test") - require.True(t, bytes.Equal(append(bs, byte(0x00)), sdk.InclusiveEndBytes(bs))) + require.True(t, bytes.Equal(append(bs, byte(0x00)), types.InclusiveEndBytes(bs))) } diff --git a/types/store_test.go b/types/store_test.go index 0588e40b6e..e23d896c7d 100644 --- a/types/store_test.go +++ b/types/store_test.go @@ -39,7 +39,7 @@ func (s *storeTestSuite) TestPrefixEndBytes() { } for _, test := range testCases { - end := sdk.PrefixEndBytes(test.prefix) + end := types.PrefixEndBytes(test.prefix) s.Require().Equal(test.expected, end) } } @@ -120,7 +120,7 @@ func (s *storeTestSuite) initTestStores() (types.KVStore, types.KVStore) { } func (s *storeTestSuite) checkDiffResults(store1, store2 types.KVStore) { - kvAs1, kvBs1 := sdk.DiffKVStores(store1, store2, nil) + kvAs1, kvBs1 := types.DiffKVStores(store1, store2, nil) kvAs2, kvBs2 := types.DiffKVStores(store1, store2, nil) s.Require().Equal(kvAs1, kvAs2) s.Require().Equal(kvBs1, kvBs2)