feat(simulation): Implement store decoder implementation from collections schema (#16074)
Co-authored-by: unknown unknown <unknown@unknown>
This commit is contained in:
co-authored by
unknown unknown
parent
908677e648
commit
69642f6176
@@ -0,0 +1,52 @@
|
||||
package simulation
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"cosmossdk.io/collections"
|
||||
collcodec "cosmossdk.io/collections/codec"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/kv"
|
||||
)
|
||||
|
||||
func NewStoreDecoderFuncFromCollectionsSchema(schema collections.Schema) func(kvA, kvB kv.Pair) string {
|
||||
colls := schema.ListCollections()
|
||||
prefixes := make([][]byte, len(colls))
|
||||
valueCodecs := make([]collcodec.UntypedValueCodec, len(colls))
|
||||
for i, coll := range colls {
|
||||
prefixes[i] = coll.GetPrefix()
|
||||
valueCodecs[i] = coll.ValueCodec()
|
||||
}
|
||||
|
||||
return func(kvA, kvB kv.Pair) string {
|
||||
for i, prefix := range prefixes {
|
||||
if bytes.HasPrefix(kvA.Key, prefix) {
|
||||
if !bytes.HasPrefix(kvB.Key, prefix) {
|
||||
panic(fmt.Sprintf("prefix mismatch, keyA has prefix %x (%s), but keyB does not %x (%s)", prefix, prefix, kvB.Key, kvB.Key))
|
||||
}
|
||||
vc := valueCodecs[i]
|
||||
// unmarshal kvA.Value to the corresponding type
|
||||
vA, err := vc.Decode(kvA.Value)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// unmarshal kvB.Value to the corresponding type
|
||||
vB, err := vc.Decode(kvB.Value)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
vAString, err := vc.Stringify(vA)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
vBString, err := vc.Stringify(vB)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return vAString + "\n" + vBString
|
||||
}
|
||||
}
|
||||
panic(fmt.Errorf("unexpected key %X (%s)", kvA.Key, kvA.Key))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package simulation
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"cosmossdk.io/collections"
|
||||
"cosmossdk.io/collections/colltest"
|
||||
"github.com/cosmos/cosmos-sdk/types/kv"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNewStoreDecoderFuncFromCollectionsSchema(t *testing.T) {
|
||||
store, _ := colltest.MockStore()
|
||||
sb := collections.NewSchemaBuilder(store)
|
||||
|
||||
prefixM1 := collections.NewPrefix("map_1")
|
||||
prefixM2 := collections.NewPrefix("map_2")
|
||||
|
||||
m1 := collections.NewMap(sb, prefixM1, "map_1", collections.StringKey, collections.StringValue)
|
||||
m2 := collections.NewMap(sb, prefixM2, "map_2", collections.Int32Key, collections.Int32Value)
|
||||
|
||||
schema, err := sb.Build()
|
||||
require.NoError(t, err)
|
||||
|
||||
// create a new store decoder function from the schema
|
||||
dec := NewStoreDecoderFuncFromCollectionsSchema(schema)
|
||||
|
||||
key1M1, err := collections.EncodeKeyWithPrefix(prefixM1, m1.KeyCodec(), "key_1")
|
||||
require.NoError(t, err)
|
||||
key2M1, err := collections.EncodeKeyWithPrefix(prefixM1, m1.KeyCodec(), "key_2")
|
||||
require.NoError(t, err)
|
||||
key1M2, err := collections.EncodeKeyWithPrefix(prefixM2, m2.KeyCodec(), int32(1))
|
||||
require.NoError(t, err)
|
||||
key2M2, err := collections.EncodeKeyWithPrefix(prefixM2, m2.KeyCodec(), int32(2))
|
||||
require.NoError(t, err)
|
||||
|
||||
storeDec1 := dec(kv.Pair{
|
||||
Key: key1M1,
|
||||
Value: []byte("value_1"),
|
||||
}, kv.Pair{
|
||||
Key: key2M1,
|
||||
Value: []byte("value_2"),
|
||||
})
|
||||
require.Equal(t, "value_1\nvalue_2", storeDec1)
|
||||
|
||||
storeDec2 := dec(kv.Pair{
|
||||
Key: key1M2,
|
||||
Value: []byte{0, 0, 0, 1},
|
||||
}, kv.Pair{
|
||||
Key: key2M2,
|
||||
Value: []byte{0, 0, 0, 2},
|
||||
})
|
||||
|
||||
require.Equal(t, "-2147483647\n-2147483646", storeDec2)
|
||||
|
||||
// test key conflict
|
||||
|
||||
require.Panics(t, func() {
|
||||
dec(
|
||||
kv.Pair{Key: append(prefixM1.Bytes(), 0x1)},
|
||||
kv.Pair{Key: append(prefixM2.Bytes(), 0x1)},
|
||||
)
|
||||
}, "must panic when keys do not have the same prefix")
|
||||
|
||||
require.Panics(t, func() {
|
||||
dec(
|
||||
kv.Pair{Key: []byte("unknown_1")},
|
||||
kv.Pair{Key: []byte("unknown_2")},
|
||||
)
|
||||
}, "must panic on unknown prefixes")
|
||||
}
|
||||
@@ -172,6 +172,6 @@ func (ms multiSource) Int63() (r int64) {
|
||||
return r
|
||||
}
|
||||
|
||||
func (ms multiSource) Seed(seed int64) {
|
||||
func (ms multiSource) Seed(_ int64) {
|
||||
panic("multiSource Seed should not be called")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user