diff --git a/x/fswap/keeper/keys.go b/x/fswap/keeper/keys.go index 04e36660f8..e9a4652926 100644 --- a/x/fswap/keeper/keys.go +++ b/x/fswap/keeper/keys.go @@ -8,12 +8,29 @@ var ( // swapKey key(prefix + fromDenom + toDenom) func swapKey(fromDenom, toDenom string) []byte { - key := append(swapPrefix, fromDenom...) - return append(key, toDenom...) + denoms := combineDenoms(fromDenom, toDenom) + return append(swapPrefix, denoms...) } -// swappedKey key(prefix + fromDenom + toDenom) +// swappedKey key(prefix + (lengthPrefixed+)fromDenom + (lengthPrefixed+)toDenom) func swappedKey(fromDenom, toDenom string) []byte { - key := append(swappedKeyPrefix, fromDenom...) - return append(key, toDenom...) + denoms := combineDenoms(fromDenom, toDenom) + return append(swappedKeyPrefix, denoms...) +} + +func combineDenoms(fromDenom, toDenom string) []byte { + lengthPrefixedFromDenom := lengthPrefix([]byte(fromDenom)) + lengthPrefixedToDenom := lengthPrefix([]byte(toDenom)) + return append(lengthPrefixedFromDenom, lengthPrefixedToDenom...) +} + +// lengthPrefix prefixes the address bytes with its length, this is used +// for example for variable-length components in store keys. +func lengthPrefix(bz []byte) []byte { + bzLen := len(bz) + if bzLen == 0 { + return bz + } + + return append([]byte{byte(bzLen)}, bz...) } diff --git a/x/fswap/keeper/keys_test.go b/x/fswap/keeper/keys_test.go new file mode 100644 index 0000000000..9e814e418c --- /dev/null +++ b/x/fswap/keeper/keys_test.go @@ -0,0 +1,53 @@ +package keeper + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestSwapKey(t *testing.T) { + tests := []struct { + name string + fromDenom string + toDenom string + expectedKey []byte + }{ + { + name: "swapKey", + fromDenom: "cony", + toDenom: "peb", + expectedKey: []byte{0x1, 0x4, 0x63, 0x6f, 0x6e, 0x79, 0x3, 0x70, 0x65, 0x62}, + //expectedKey: append(swapPrefix, append(append([]byte{byte(len("cony"))}, []byte("cony")...), append([]byte{byte(len("peb"))}, []byte("peb")...)...)...), + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + actualKey := swapKey(tc.fromDenom, tc.toDenom) + require.Equal(t, tc.expectedKey, actualKey) + }) + } +} + +func TestSwappedKey(t *testing.T) { + tests := []struct { + name string + fromDenom string + toDenom string + expectedKey []byte + }{ + { + name: "swappedKey", + fromDenom: "cony", + toDenom: "peb", + expectedKey: []byte{0x3, 0x4, 0x63, 0x6f, 0x6e, 0x79, 0x3, 0x70, 0x65, 0x62}, + //expectedKey: append(swappedKeyPrefix, append(append([]byte{byte(len("cony"))}, []byte("cony")...), append([]byte{byte(len("peb"))}, []byte("peb")...)...)...), + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + actualKey := swappedKey(tc.fromDenom, tc.toDenom) + require.Equal(t, tc.expectedKey, actualKey) + }) + } +}