refactor(x/group)!: remove MustAccAddressFromBech32 (#20082)

This commit is contained in:
Julián Toledano 2024-04-18 13:01:21 +02:00 committed by GitHub
parent c6b8d7d146
commit 90a0114992
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 147 additions and 99 deletions

View File

@ -1,11 +1,14 @@
package testdata
import "cosmossdk.io/errors"
import (
"cosmossdk.io/core/address"
"cosmossdk.io/errors"
)
var ErrTest = errors.Register("table_testdata", 2, "test")
func (g TableModel) PrimaryKeyFields() []interface{} {
return []interface{}{g.Id}
func (g TableModel) PrimaryKeyFields(_ address.Codec) ([]interface{}, error) {
return []interface{}{g.Id}, nil
}
func (g TableModel) ValidateBasic() error {

View File

@ -32,6 +32,9 @@ Ref: https://keepachangelog.com/en/1.0.0/
### API Breaking Changes
* [#20082](https://github.com/cosmos/cosmos-sdk/pull/20082) Removes the use of `MustAccAddressFromBech32`:
* `PrimaryKeyFields` function from interface `PrimaryKeyed` now takes an address codec as argument.
* `PrimaryKey`, `NewAutoUInt64Table` and `NewPrimaryKeyTable` now take an address codec as argument.
* [#19916](https://github.com/cosmos/cosmos-sdk/pull/19916) Removes the use of Address String methods:
* `NewMsgCreateGroupPolicy` now takes a string as argument instead of an `AccAddress`.
* `NewMsgUpdateGroupPolicyDecisionPolicy` now takes strings as argument instead of `AccAddress`.

View File

@ -3,6 +3,7 @@ package orm
import (
"github.com/cosmos/gogoproto/proto"
"cosmossdk.io/core/address"
storetypes "cosmossdk.io/core/store"
"cosmossdk.io/errors"
@ -21,8 +22,8 @@ type AutoUInt64Table struct {
}
// NewAutoUInt64Table creates a new AutoUInt64Table.
func NewAutoUInt64Table(prefixData [2]byte, prefixSeq byte, model proto.Message, cdc codec.Codec) (*AutoUInt64Table, error) {
table, err := newTable(prefixData, model, cdc)
func NewAutoUInt64Table(prefixData [2]byte, prefixSeq byte, model proto.Message, cdc codec.Codec, addressCodec address.Codec) (*AutoUInt64Table, error) {
table, err := newTable(prefixData, model, cdc, addressCodec)
if err != nil {
return nil, err
}

View File

@ -13,6 +13,7 @@ import (
"cosmossdk.io/x/group/errors"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
@ -23,7 +24,7 @@ func TestAutoUInt64PrefixScan(t *testing.T) {
interfaceRegistry := types.NewInterfaceRegistry()
cdc := codec.NewProtoCodec(interfaceRegistry)
tb, err := NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc)
tb, err := NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc, address.NewBech32Codec("cosmos"))
require.NoError(t, err)
key := storetypes.NewKVStoreKey("test")

View File

@ -2,6 +2,7 @@ package orm
import (
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
)
@ -27,8 +28,9 @@ var (
func NewTestKeeper(cdc codec.Codec) TestKeeper {
k := TestKeeper{}
var err error
ac := address.NewBech32Codec("cosmos")
k.autoUInt64Table, err = NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc)
k.autoUInt64Table, err = NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc, ac)
if err != nil {
panic(err.Error())
}
@ -39,7 +41,7 @@ func NewTestKeeper(cdc codec.Codec) TestKeeper {
panic(err.Error())
}
k.primaryKeyTable, err = NewPrimaryKeyTable(PrimaryKeyTablePrefix, &testdata.TableModel{}, cdc)
k.primaryKeyTable, err = NewPrimaryKeyTable(PrimaryKeyTablePrefix, &testdata.TableModel{}, cdc, ac)
if err != nil {
panic(err.Error())
}

View File

@ -8,6 +8,7 @@ import (
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
@ -18,7 +19,7 @@ func TestImportExportTableData(t *testing.T) {
interfaceRegistry := types.NewInterfaceRegistry()
cdc := codec.NewProtoCodec(interfaceRegistry)
table, err := NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc)
table, err := NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc, address.NewBech32Codec("cosmos"))
require.NoError(t, err)
key := storetypes.NewKVStoreKey("test")

View File

@ -12,6 +12,7 @@ import (
"cosmossdk.io/x/group/errors"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
@ -33,7 +34,7 @@ func TestNewIndex(t *testing.T) {
interfaceRegistry := types.NewInterfaceRegistry()
cdc := codec.NewProtoCodec(interfaceRegistry)
myTable, err := NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc)
myTable, err := NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc, address.NewBech32Codec("cosmos"))
require.NoError(t, err)
indexer := func(val interface{}) ([]interface{}, error) {
return []interface{}{val.(*testdata.TableModel).Metadata}, nil
@ -91,7 +92,7 @@ func TestIndexPrefixScan(t *testing.T) {
interfaceRegistry := types.NewInterfaceRegistry()
cdc := codec.NewProtoCodec(interfaceRegistry)
tb, err := NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc)
tb, err := NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc, address.NewBech32Codec("cosmos"))
require.NoError(t, err)
idx, err := NewIndex(tb, AutoUInt64TableModelByMetadataPrefix, func(val interface{}) ([]interface{}, error) {
i := []interface{}{val.(*testdata.TableModel).Metadata}
@ -297,8 +298,8 @@ func TestIndexPrefixScan(t *testing.T) {
func TestUniqueIndex(t *testing.T) {
interfaceRegistry := types.NewInterfaceRegistry()
cdc := codec.NewProtoCodec(interfaceRegistry)
myTable, err := NewPrimaryKeyTable(PrimaryKeyTablePrefix, &testdata.TableModel{}, cdc)
ac := address.NewBech32Codec("cosmos")
myTable, err := NewPrimaryKeyTable(PrimaryKeyTablePrefix, &testdata.TableModel{}, cdc, ac)
require.NoError(t, err)
uniqueIdx, err := NewUniqueIndex(myTable, 0x10, func(val interface{}) (interface{}, error) {
return []byte{val.(*testdata.TableModel).Metadata[0]}, nil
@ -330,7 +331,7 @@ func TestUniqueIndex(t *testing.T) {
var loaded testdata.TableModel
rowID, err := it.LoadNext(&loaded)
require.NoError(t, err)
require.Equal(t, RowID(PrimaryKey(&m)), rowID)
require.Equal(t, RowID(PrimaryKey(&m, ac)), rowID)
require.Equal(t, m, loaded)
// GetPaginated
@ -357,7 +358,7 @@ func TestUniqueIndex(t *testing.T) {
require.Error(t, err)
} else {
require.NoError(t, err)
require.Equal(t, RowID(PrimaryKey(&m)), rowID)
require.Equal(t, RowID(PrimaryKey(&m, ac)), rowID)
require.Equal(t, m, loaded)
}
})
@ -368,7 +369,7 @@ func TestUniqueIndex(t *testing.T) {
require.NoError(t, err)
rowID, err = it.LoadNext(&loaded)
require.NoError(t, err)
require.Equal(t, RowID(PrimaryKey(&m)), rowID)
require.Equal(t, RowID(PrimaryKey(&m, ac)), rowID)
require.Equal(t, m, loaded)
// PrefixScan no match
@ -382,7 +383,7 @@ func TestUniqueIndex(t *testing.T) {
require.NoError(t, err)
rowID, err = it.LoadNext(&loaded)
require.NoError(t, err)
require.Equal(t, RowID(PrimaryKey(&m)), rowID)
require.Equal(t, RowID(PrimaryKey(&m, ac)), rowID)
require.Equal(t, m, loaded)
// ReversePrefixScan no match

View File

@ -12,6 +12,7 @@ import (
"cosmossdk.io/x/group/errors"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
@ -204,7 +205,7 @@ func TestPaginate(t *testing.T) {
interfaceRegistry := types.NewInterfaceRegistry()
cdc := codec.NewProtoCodec(interfaceRegistry)
tb, err := NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc)
tb, err := NewAutoUInt64Table(AutoUInt64TablePrefix, AutoUInt64TableSeqPrefix, &testdata.TableModel{}, cdc, address.NewBech32Codec("cosmos"))
require.NoError(t, err)
idx, err := NewIndex(tb, AutoUInt64TableModelByMetadataPrefix, func(val interface{}) ([]interface{}, error) {
return []interface{}{val.(*testdata.TableModel).Metadata}, nil

View File

@ -14,6 +14,7 @@ import (
"cosmossdk.io/x/group/errors"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
@ -122,7 +123,7 @@ func TestKeeperEndToEndWithPrimaryKeyTable(t *testing.T) {
err := k.primaryKeyTable.Create(store, &tm)
require.NoError(t, err)
// then we should find it by primary key
primaryKey := PrimaryKey(&tm)
primaryKey := PrimaryKey(&tm, address.NewBech32Codec("cosmos"))
exists := k.primaryKeyTable.Has(store, primaryKey)
require.True(t, exists)
@ -192,6 +193,7 @@ func TestKeeperEndToEndWithPrimaryKeyTable(t *testing.T) {
func TestGasCostsPrimaryKeyTable(t *testing.T) {
interfaceRegistry := types.NewInterfaceRegistry()
cdc := codec.NewProtoCodec(interfaceRegistry)
ac := address.NewBech32Codec("cosmos")
key := storetypes.NewKVStoreKey("test")
testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test"))
@ -216,7 +218,7 @@ func TestGasCostsPrimaryKeyTable(t *testing.T) {
// get by primary key
testCtx.Ctx = testCtx.Ctx.WithGasMeter(storetypes.NewInfiniteGasMeter())
var loaded testdata.TableModel
err = k.primaryKeyTable.GetOne(store, PrimaryKey(&tm), &loaded)
err = k.primaryKeyTable.GetOne(store, PrimaryKey(&tm, ac), &loaded)
require.NoError(t, err)
t.Logf("gas consumed on get by primary key: %d", testCtx.Ctx.GasMeter().GasConsumed())
@ -260,7 +262,7 @@ func TestGasCostsPrimaryKeyTable(t *testing.T) {
Number: 123,
Metadata: []byte("metadata"),
}
err = k.primaryKeyTable.GetOne(store, PrimaryKey(&tm), &loaded)
err = k.primaryKeyTable.GetOne(store, PrimaryKey(&tm, ac), &loaded)
require.NoError(t, err)
t.Logf("%d: gas consumed on get by primary key: %d", i, testCtx.Ctx.GasMeter().GasConsumed())
}
@ -391,7 +393,7 @@ func TestExportImportStatePrimaryKeyTable(t *testing.T) {
keys, err := ReadAll(it, &loaded)
require.NoError(t, err)
for i := range keys {
assert.Equal(t, PrimaryKey(&testRecords[i]), keys[i].Bytes())
assert.Equal(t, PrimaryKey(&testRecords[i], address.NewBech32Codec("cosmos")), keys[i].Bytes())
}
assert.Equal(t, testRecords, loaded)
@ -411,7 +413,7 @@ func assertIndex(t *testing.T, store corestore.KVStore, index Index, v testdata.
var loaded []testdata.TableModel
keys, err := ReadAll(it, &loaded)
require.NoError(t, err)
assert.Equal(t, []RowID{PrimaryKey(&v)}, keys)
assert.Equal(t, []RowID{PrimaryKey(&v, address.NewBech32Codec("cosmos"))}, keys)
assert.Equal(t, []testdata.TableModel{v}, loaded)
}

View File

@ -3,6 +3,7 @@ package orm
import (
"github.com/cosmos/gogoproto/proto"
"cosmossdk.io/core/address"
storetypes "cosmossdk.io/core/store"
"github.com/cosmos/cosmos-sdk/codec"
@ -20,8 +21,8 @@ type PrimaryKeyTable struct {
}
// NewPrimaryKeyTable creates a new PrimaryKeyTable.
func NewPrimaryKeyTable(prefixData [2]byte, model PrimaryKeyed, cdc codec.Codec) (*PrimaryKeyTable, error) {
table, err := newTable(prefixData, model, cdc)
func NewPrimaryKeyTable(prefixData [2]byte, model PrimaryKeyed, cdc codec.Codec, addressCodec address.Codec) (*PrimaryKeyTable, error) {
table, err := newTable(prefixData, model, cdc, addressCodec)
if err != nil {
return nil, err
}
@ -42,7 +43,7 @@ type PrimaryKeyed interface {
//
// IMPORTANT: []byte parts are encoded with a single byte length prefix,
// so cannot be longer than 255 bytes.
PrimaryKeyFields() []interface{}
PrimaryKeyFields(address.Codec) ([]interface{}, error)
proto.Message
}
@ -50,8 +51,11 @@ type PrimaryKeyed interface {
// The primary key has to be unique within it's domain so that not two with same
// value can exist in the same table. This means PrimaryKeyFields() has to
// return a unique value for each object.
func PrimaryKey(obj PrimaryKeyed) []byte {
fields := obj.PrimaryKeyFields()
func PrimaryKey(obj PrimaryKeyed, addressCodec address.Codec) []byte {
fields, err := obj.PrimaryKeyFields(addressCodec)
if err != nil {
panic(err)
}
key, err := buildKeyFromParts(fields)
if err != nil {
panic(err)
@ -65,7 +69,7 @@ func PrimaryKey(obj PrimaryKeyed) []byte {
// Create iterates through the registered callbacks that may add secondary
// index keys.
func (a PrimaryKeyTable) Create(store storetypes.KVStore, obj PrimaryKeyed) error {
rowID := PrimaryKey(obj)
rowID := PrimaryKey(obj, a.ac)
return a.table.Create(store, rowID, obj)
}
@ -77,7 +81,7 @@ func (a PrimaryKeyTable) Create(store storetypes.KVStore, obj PrimaryKeyed) erro
// Update iterates through the registered callbacks that may add or remove
// secondary index keys.
func (a PrimaryKeyTable) Update(store storetypes.KVStore, newValue PrimaryKeyed) error {
return a.table.Update(store, PrimaryKey(newValue), newValue)
return a.table.Update(store, PrimaryKey(newValue, a.ac), newValue)
}
// Set persists the given object under the rowID key. It does not check if the
@ -86,7 +90,7 @@ func (a PrimaryKeyTable) Update(store storetypes.KVStore, newValue PrimaryKeyed)
// Set iterates through the registered callbacks that may add secondary index
// keys.
func (a PrimaryKeyTable) Set(store storetypes.KVStore, newValue PrimaryKeyed) error {
return a.table.Set(store, PrimaryKey(newValue), newValue)
return a.table.Set(store, PrimaryKey(newValue, a.ac), newValue)
}
// Delete removes the object. It expects the primary key to exists already and
@ -96,7 +100,7 @@ func (a PrimaryKeyTable) Set(store storetypes.KVStore, newValue PrimaryKeyed) er
// Delete iterates through the registered callbacks that remove secondary index
// keys.
func (a PrimaryKeyTable) Delete(store storetypes.KVStore, obj PrimaryKeyed) error {
return a.table.Delete(store, PrimaryKey(obj))
return a.table.Delete(store, PrimaryKey(obj, a.ac))
}
// Has checks if a key exists. Always returns false on nil or empty key.
@ -109,7 +113,7 @@ func (a PrimaryKeyTable) Contains(store storetypes.KVStore, obj PrimaryKeyed) bo
if err := assertCorrectType(a.table.model, obj); err != nil {
return false
}
return a.table.Has(store, PrimaryKey(obj))
return a.table.Has(store, PrimaryKey(obj, a.ac))
}
// GetOne loads the object persisted for the given primary Key into the dest parameter.

View File

@ -9,6 +9,7 @@ import (
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
@ -17,6 +18,7 @@ import (
func TestPrimaryKeyTable(t *testing.T) {
rapid.Check(t, func(rt *rapid.T) {
ac := address.NewBech32Codec("cosmos")
// Init creates a new instance of the state machine model by building the real
// table and making the empty model map
// Create context
@ -31,6 +33,7 @@ func TestPrimaryKeyTable(t *testing.T) {
[2]byte{0x1},
&testdata.TableModel{},
cdc,
ac,
)
require.NoError(t, err)
@ -42,7 +45,7 @@ func TestPrimaryKeyTable(t *testing.T) {
// an error if it already exists.
"Create": func(t *rapid.T) {
g := genTableModel.Draw(t, "g")
pk := string(PrimaryKey(g))
pk := string(PrimaryKey(g, ac))
t.Logf("pk: %v", pk)
t.Logf("state: %v", state)
@ -68,7 +71,7 @@ func TestPrimaryKeyTable(t *testing.T) {
// Perform the real Update
err := table.Update(store, tm)
if state[string(PrimaryKey(tm))] == nil {
if state[string(PrimaryKey(tm, ac))] == nil {
// If there's no value in the model, we expect an error
require.Error(t, err)
} else {
@ -76,7 +79,7 @@ func TestPrimaryKeyTable(t *testing.T) {
require.NoError(t, err)
// Update the model with the new value
state[string(PrimaryKey(tm))] = tm
state[string(PrimaryKey(tm, ac))] = tm
}
},
@ -84,7 +87,7 @@ func TestPrimaryKeyTable(t *testing.T) {
// whether it exists or not.
"Set": func(t *rapid.T) {
g := genTableModel.Draw(t, "g")
pk := string(PrimaryKey(g))
pk := string(PrimaryKey(g, ac))
err := table.Set(store, g)
@ -101,7 +104,7 @@ func TestPrimaryKeyTable(t *testing.T) {
// Perform the real Delete
err := table.Delete(store, tm)
if state[string(PrimaryKey(tm))] == nil {
if state[string(PrimaryKey(tm, ac))] == nil {
// If there's no value in the model, we expect an error
require.Error(t, err)
} else {
@ -109,14 +112,14 @@ func TestPrimaryKeyTable(t *testing.T) {
require.NoError(t, err)
// Delete the value from the model
delete(state, string(PrimaryKey(tm)))
delete(state, string(PrimaryKey(tm, ac)))
}
},
// Has is one of the model commands. It checks whether a key already exists in
// the table.
"Has": func(t *rapid.T) {
pk := PrimaryKey(generateTableModel(state).Draw(t, "g"))
pk := PrimaryKey(generateTableModel(state).Draw(t, "g"), ac)
realHas := table.Has(store, pk)
modelHas := state[string(pk)] != nil
@ -127,7 +130,7 @@ func TestPrimaryKeyTable(t *testing.T) {
// GetOne is one of the model commands. It fetches an object from the table by
// its primary key and returns an error if that primary key isn't in the table.
"GetOne": func(t *rapid.T) {
pk := PrimaryKey(generateTableModel(state).Draw(t, "tm"))
pk := PrimaryKey(generateTableModel(state).Draw(t, "tm"), ac)
var tm testdata.TableModel

View File

@ -12,6 +12,7 @@ import (
"cosmossdk.io/x/group/errors"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
@ -21,8 +22,9 @@ import (
func TestPrimaryKeyTablePrefixScan(t *testing.T) {
interfaceRegistry := types.NewInterfaceRegistry()
cdc := codec.NewProtoCodec(interfaceRegistry)
ac := address.NewBech32Codec("cosmos")
tb, err := NewPrimaryKeyTable(PrimaryKeyTablePrefix, &testdata.TableModel{}, cdc)
tb, err := NewPrimaryKeyTable(PrimaryKeyTablePrefix, &testdata.TableModel{}, cdc, ac)
require.NoError(t, err)
key := storetypes.NewKVStoreKey("test")
@ -62,49 +64,49 @@ func TestPrimaryKeyTablePrefixScan(t *testing.T) {
end: EncodeSequence(2), // == PrimaryKey(&t2)
method: tb.PrefixScan,
expResult: []testdata.TableModel{t1},
expRowIDs: []RowID{PrimaryKey(&t1)},
expRowIDs: []RowID{PrimaryKey(&t1, ac)},
},
"one result by 1st byte": {
start: []byte{0},
end: EncodeSequence(2), // == PrimaryKey(&t2)
method: tb.PrefixScan,
expResult: []testdata.TableModel{t1},
expRowIDs: []RowID{PrimaryKey(&t1)},
expRowIDs: []RowID{PrimaryKey(&t1, ac)},
},
"open end query": {
start: EncodeSequence(3),
end: nil,
method: tb.PrefixScan,
expResult: []testdata.TableModel{t3},
expRowIDs: []RowID{PrimaryKey(&t3)},
expRowIDs: []RowID{PrimaryKey(&t3, ac)},
},
"open end query with all": {
start: EncodeSequence(1),
end: nil,
method: tb.PrefixScan,
expResult: []testdata.TableModel{t1, t2, t3},
expRowIDs: []RowID{PrimaryKey(&t1), PrimaryKey(&t2), PrimaryKey(&t3)},
expRowIDs: []RowID{PrimaryKey(&t1, ac), PrimaryKey(&t2, ac), PrimaryKey(&t3, ac)},
},
"open start query": {
start: nil,
end: EncodeSequence(3),
method: tb.PrefixScan,
expResult: []testdata.TableModel{t1, t2},
expRowIDs: []RowID{PrimaryKey(&t1), PrimaryKey(&t2)},
expRowIDs: []RowID{PrimaryKey(&t1, ac), PrimaryKey(&t2, ac)},
},
"open start and end query": {
start: nil,
end: nil,
method: tb.PrefixScan,
expResult: []testdata.TableModel{t1, t2, t3},
expRowIDs: []RowID{PrimaryKey(&t1), PrimaryKey(&t2), PrimaryKey(&t3)},
expRowIDs: []RowID{PrimaryKey(&t1, ac), PrimaryKey(&t2, ac), PrimaryKey(&t3, ac)},
},
"all matching 1st byte": {
start: []byte{0},
end: nil,
method: tb.PrefixScan,
expResult: []testdata.TableModel{t1, t2, t3},
expRowIDs: []RowID{PrimaryKey(&t1), PrimaryKey(&t2), PrimaryKey(&t3)},
expRowIDs: []RowID{PrimaryKey(&t1, ac), PrimaryKey(&t2, ac), PrimaryKey(&t3, ac)},
},
"non matching 1st byte": {
start: []byte{1},
@ -129,49 +131,49 @@ func TestPrimaryKeyTablePrefixScan(t *testing.T) {
end: EncodeSequence(2), // == PrimaryKey(&t2)
method: tb.ReversePrefixScan,
expResult: []testdata.TableModel{t1},
expRowIDs: []RowID{PrimaryKey(&t1)},
expRowIDs: []RowID{PrimaryKey(&t1, ac)},
},
"reverse: one result by 1st byte": {
start: []byte{0},
end: EncodeSequence(2), // == PrimaryKey(&t2)
method: tb.ReversePrefixScan,
expResult: []testdata.TableModel{t1},
expRowIDs: []RowID{PrimaryKey(&t1)},
expRowIDs: []RowID{PrimaryKey(&t1, ac)},
},
"reverse: open end query": {
start: EncodeSequence(3),
end: nil,
method: tb.ReversePrefixScan,
expResult: []testdata.TableModel{t3},
expRowIDs: []RowID{PrimaryKey(&t3)},
expRowIDs: []RowID{PrimaryKey(&t3, ac)},
},
"reverse: open end query with all": {
start: EncodeSequence(1),
end: nil,
method: tb.ReversePrefixScan,
expResult: []testdata.TableModel{t3, t2, t1},
expRowIDs: []RowID{PrimaryKey(&t3), PrimaryKey(&t2), PrimaryKey(&t1)},
expRowIDs: []RowID{PrimaryKey(&t3, ac), PrimaryKey(&t2, ac), PrimaryKey(&t1, ac)},
},
"reverse: open start query": {
start: nil,
end: EncodeSequence(3),
method: tb.ReversePrefixScan,
expResult: []testdata.TableModel{t2, t1},
expRowIDs: []RowID{PrimaryKey(&t2), PrimaryKey(&t1)},
expRowIDs: []RowID{PrimaryKey(&t2, ac), PrimaryKey(&t1, ac)},
},
"reverse: open start and end query": {
start: nil,
end: nil,
method: tb.ReversePrefixScan,
expResult: []testdata.TableModel{t3, t2, t1},
expRowIDs: []RowID{PrimaryKey(&t3), PrimaryKey(&t2), PrimaryKey(&t1)},
expRowIDs: []RowID{PrimaryKey(&t3, ac), PrimaryKey(&t2, ac), PrimaryKey(&t1, ac)},
},
"reverse: all matching 1st byte": {
start: []byte{0},
end: nil,
method: tb.ReversePrefixScan,
expResult: []testdata.TableModel{t3, t2, t1},
expRowIDs: []RowID{PrimaryKey(&t3), PrimaryKey(&t2), PrimaryKey(&t1)},
expRowIDs: []RowID{PrimaryKey(&t3, ac), PrimaryKey(&t2, ac), PrimaryKey(&t1, ac)},
},
"reverse: non matching prefix": {
start: []byte{1},
@ -216,7 +218,7 @@ func TestContains(t *testing.T) {
testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test"))
store := runtime.NewKVStoreService(key).OpenKVStore(testCtx.Ctx)
tb, err := NewPrimaryKeyTable(PrimaryKeyTablePrefix, &testdata.TableModel{}, cdc)
tb, err := NewPrimaryKeyTable(PrimaryKeyTablePrefix, &testdata.TableModel{}, cdc, address.NewBech32Codec("cosmos"))
require.NoError(t, err)
obj := testdata.TableModel{

View File

@ -6,6 +6,7 @@ import (
"github.com/cosmos/gogoproto/proto"
"cosmossdk.io/core/address"
storetypes "cosmossdk.io/core/store"
errorsmod "cosmossdk.io/errors"
"cosmossdk.io/store/types"
@ -37,10 +38,11 @@ type table struct {
afterSet []AfterSetInterceptor
afterDelete []AfterDeleteInterceptor
cdc codec.Codec
ac address.Codec
}
// newTable creates a new table
func newTable(prefix [2]byte, model proto.Message, cdc codec.Codec) (*table, error) {
func newTable(prefix [2]byte, model proto.Message, cdc codec.Codec, addressCodec address.Codec) (*table, error) {
if model == nil {
return nil, errors.ErrORMInvalidArgument.Wrap("Model must not be nil")
}
@ -52,6 +54,7 @@ func newTable(prefix [2]byte, model proto.Message, cdc codec.Codec) (*table, err
prefix: prefix,
model: tp,
cdc: cdc,
ac: addressCodec,
}, nil
}
@ -299,7 +302,7 @@ func (a table) Import(store storetypes.KVStore, data interface{}, _ uint64) erro
if !ok {
return errorsmod.Wrapf(errors.ErrORMInvalidArgument, "unsupported type :%s", reflect.TypeOf(data).Elem().Elem())
}
err := a.Create(store, PrimaryKey(obj), obj)
err := a.Create(store, PrimaryKey(obj, a.ac), obj)
if err != nil {
return err
}

View File

@ -13,6 +13,7 @@ import (
"cosmossdk.io/x/group/errors"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
@ -45,7 +46,7 @@ func TestNewTable(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
table, err := newTable([2]byte{0x1}, tc.model, cdc)
table, err := newTable([2]byte{0x1}, tc.model, cdc, address.NewBech32Codec("cosmos"))
if tc.expectErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expectedErr)
@ -105,7 +106,7 @@ func TestCreate(t *testing.T) {
store := runtime.NewKVStoreService(key).OpenKVStore(testCtx.Ctx)
anyPrefix := [2]byte{0x10}
myTable, err := newTable(anyPrefix, &testdata.TableModel{}, cdc)
myTable, err := newTable(anyPrefix, &testdata.TableModel{}, cdc, address.NewBech32Codec("cosmos"))
require.NoError(t, err)
err = myTable.Create(store, spec.rowID, spec.src)
@ -163,7 +164,7 @@ func TestUpdate(t *testing.T) {
store := runtime.NewKVStoreService(key).OpenKVStore(testCtx.Ctx)
anyPrefix := [2]byte{0x10}
myTable, err := newTable(anyPrefix, &testdata.TableModel{}, cdc)
myTable, err := newTable(anyPrefix, &testdata.TableModel{}, cdc, address.NewBech32Codec("cosmos"))
require.NoError(t, err)
initValue := testdata.TableModel{
@ -213,7 +214,7 @@ func TestDelete(t *testing.T) {
store := runtime.NewKVStoreService(key).OpenKVStore(testCtx.Ctx)
anyPrefix := [2]byte{0x10}
myTable, err := newTable(anyPrefix, &testdata.TableModel{}, cdc)
myTable, err := newTable(anyPrefix, &testdata.TableModel{}, cdc, address.NewBech32Codec("cosmos"))
require.NoError(t, err)
initValue := testdata.TableModel{

View File

@ -54,7 +54,7 @@ func (k Keeper) GroupPolicyInfo(ctx context.Context, request *group.QueryGroupPo
// getGroupPolicyInfo gets the group policy info of the given account address.
func (k Keeper) getGroupPolicyInfo(ctx context.Context, accountAddress string) (group.GroupPolicyInfo, error) {
var obj group.GroupPolicyInfo
return obj, k.groupPolicyTable.GetOne(k.KVStoreService.OpenKVStore(ctx), orm.PrimaryKey(&group.GroupPolicyInfo{Address: accountAddress}), &obj)
return obj, k.groupPolicyTable.GetOne(k.KVStoreService.OpenKVStore(ctx), orm.PrimaryKey(&group.GroupPolicyInfo{Address: accountAddress}, k.accKeeper.AddressCodec()), &obj)
}
// GroupMembers queries all members of a group.
@ -311,7 +311,7 @@ func (k Keeper) GroupsByMember(ctx context.Context, request *group.QueryGroupsBy
// getVote gets the vote info for the given proposal id and voter address.
func (k Keeper) getVote(ctx context.Context, proposalID uint64, voter string) (group.Vote, error) {
var v group.Vote
return v, k.voteTable.GetOne(k.KVStoreService.OpenKVStore(ctx), orm.PrimaryKey(&group.Vote{ProposalId: proposalID, Voter: voter}), &v)
return v, k.voteTable.GetOne(k.KVStoreService.OpenKVStore(ctx), orm.PrimaryKey(&group.Vote{ProposalId: proposalID, Voter: voter}, k.accKeeper.AddressCodec()), &v)
}
// getVotesByProposal returns an iterator for the given proposal id and page request.

View File

@ -56,11 +56,11 @@ func (s *invariantTestSuite) TestGroupTotalWeightInvariant() {
addressCodec := codectestutil.CodecOptions{}.GetAddressCodec()
// Group Table
groupTable, err := orm.NewAutoUInt64Table([2]byte{keeper.GroupTablePrefix}, keeper.GroupTableSeqPrefix, &group.GroupInfo{}, cdc)
groupTable, err := orm.NewAutoUInt64Table([2]byte{keeper.GroupTablePrefix}, keeper.GroupTableSeqPrefix, &group.GroupInfo{}, cdc, addressCodec)
s.Require().NoError(err)
// Group Member Table
groupMemberTable, err := orm.NewPrimaryKeyTable([2]byte{keeper.GroupMemberTablePrefix}, &group.GroupMember{}, cdc)
groupMemberTable, err := orm.NewPrimaryKeyTable([2]byte{keeper.GroupMemberTablePrefix}, &group.GroupMember{}, cdc, addressCodec)
s.Require().NoError(err)
groupMemberByGroupIndex, err := orm.NewIndex(groupMemberTable, keeper.GroupMemberByGroupIndexPrefix, func(val interface{}) ([]interface{}, error) {

View File

@ -113,7 +113,7 @@ func NewKeeper(env appmodule.Environment, cdc codec.Codec, accKeeper group.Accou
}
k.config = config
groupTable, err := orm.NewAutoUInt64Table([2]byte{GroupTablePrefix}, GroupTableSeqPrefix, &group.GroupInfo{}, cdc)
groupTable, err := orm.NewAutoUInt64Table([2]byte{GroupTablePrefix}, GroupTableSeqPrefix, &group.GroupInfo{}, cdc, k.accKeeper.AddressCodec())
if err != nil {
panic(err.Error())
}
@ -130,7 +130,7 @@ func NewKeeper(env appmodule.Environment, cdc codec.Codec, accKeeper group.Accou
k.groupTable = *groupTable
// Group Member Table
groupMemberTable, err := orm.NewPrimaryKeyTable([2]byte{GroupMemberTablePrefix}, &group.GroupMember{}, cdc)
groupMemberTable, err := orm.NewPrimaryKeyTable([2]byte{GroupMemberTablePrefix}, &group.GroupMember{}, cdc, k.accKeeper.AddressCodec())
if err != nil {
panic(err.Error())
}
@ -156,7 +156,7 @@ func NewKeeper(env appmodule.Environment, cdc codec.Codec, accKeeper group.Accou
// Group Policy Table
k.groupPolicySeq = orm.NewSequence(GroupPolicyTableSeqPrefix)
groupPolicyTable, err := orm.NewPrimaryKeyTable([2]byte{GroupPolicyTablePrefix}, &group.GroupPolicyInfo{}, cdc)
groupPolicyTable, err := orm.NewPrimaryKeyTable([2]byte{GroupPolicyTablePrefix}, &group.GroupPolicyInfo{}, cdc, k.accKeeper.AddressCodec())
if err != nil {
panic(err.Error())
}
@ -180,7 +180,7 @@ func NewKeeper(env appmodule.Environment, cdc codec.Codec, accKeeper group.Accou
k.groupPolicyTable = *groupPolicyTable
// Proposal Table
proposalTable, err := orm.NewAutoUInt64Table([2]byte{ProposalTablePrefix}, ProposalTableSeqPrefix, &group.Proposal{}, cdc)
proposalTable, err := orm.NewAutoUInt64Table([2]byte{ProposalTablePrefix}, ProposalTableSeqPrefix, &group.Proposal{}, cdc, k.accKeeper.AddressCodec())
if err != nil {
panic(err.Error())
}
@ -205,7 +205,7 @@ func NewKeeper(env appmodule.Environment, cdc codec.Codec, accKeeper group.Accou
k.proposalTable = *proposalTable
// Vote Table
voteTable, err := orm.NewPrimaryKeyTable([2]byte{VoteTablePrefix}, &group.Vote{}, cdc)
voteTable, err := orm.NewPrimaryKeyTable([2]byte{VoteTablePrefix}, &group.Vote{}, cdc, k.accKeeper.AddressCodec())
if err != nil {
panic(err.Error())
}

View File

@ -134,7 +134,7 @@ func (k Keeper) UpdateGroupMembers(ctx context.Context, msg *group.MsgUpdateGrou
// Checking if the group member is already part of the group
var found bool
var prevGroupMember group.GroupMember
switch err := k.groupMemberTable.GetOne(kvStore, orm.PrimaryKey(&groupMember), &prevGroupMember); {
switch err := k.groupMemberTable.GetOne(kvStore, orm.PrimaryKey(&groupMember, k.accKeeper.AddressCodec()), &prevGroupMember); {
case err == nil:
found = true
case sdkerrors.ErrNotFound.Is(err):
@ -578,7 +578,7 @@ func (k Keeper) SubmitProposal(ctx context.Context, msg *group.MsgSubmitProposal
// Only members of the group can submit a new proposal.
for _, proposer := range msg.Proposers {
if !k.groupMemberTable.Has(kvStore, orm.PrimaryKey(&group.GroupMember{GroupId: groupInfo.Id, Member: &group.Member{Address: proposer}})) {
if !k.groupMemberTable.Has(kvStore, orm.PrimaryKey(&group.GroupMember{GroupId: groupInfo.Id, Member: &group.Member{Address: proposer}}, k.accKeeper.AddressCodec())) {
return nil, errorsmod.Wrapf(errors.ErrUnauthorized, "not in group: %s", proposer)
}
}
@ -748,7 +748,7 @@ func (k Keeper) Vote(ctx context.Context, msg *group.MsgVote) (*group.MsgVoteRes
// Count and store votes.
voter := group.GroupMember{GroupId: groupInfo.Id, Member: &group.Member{Address: msg.Voter}}
if err := k.groupMemberTable.GetOne(kvStore, orm.PrimaryKey(&voter), &voter); err != nil {
if err := k.groupMemberTable.GetOne(kvStore, orm.PrimaryKey(&voter, k.accKeeper.AddressCodec()), &voter); err != nil {
return nil, errorsmod.Wrapf(err, "voter address: %s", msg.Voter)
}
newVote := group.Vote{
@ -981,7 +981,7 @@ func (k Keeper) getGroupMember(ctx context.Context, member *group.GroupMember) (
kvStore := k.KVStoreService.OpenKVStore(ctx)
var groupMember group.GroupMember
switch err := k.groupMemberTable.GetOne(kvStore,
orm.PrimaryKey(member), &groupMember); {
orm.PrimaryKey(member, k.accKeeper.AddressCodec()), &groupMember); {
case err == nil:
break
case sdkerrors.ErrNotFound.Is(err):

View File

@ -47,7 +47,7 @@ func (k Keeper) Tally(ctx context.Context, p group.Proposal, groupID uint64) (gr
err := k.groupMemberTable.GetOne(kvStore, orm.PrimaryKey(&group.GroupMember{
GroupId: groupID,
Member: &group.Member{Address: vote.Voter},
}), &member)
}, k.accKeeper.AddressCodec()), &member)
switch {
case sdkerrors.ErrNotFound.Is(err):

View File

@ -31,12 +31,20 @@ import (
var (
policies = []sdk.AccAddress{policyAddr1, policyAddr2, policyAddr3}
policyAddr1 = sdk.MustAccAddressFromBech32("cosmos1q32tjg5qm3n9fj8wjgpd7gl98prefntrckjkyvh8tntp7q33zj0s5tkjrk")
policyAddr2 = sdk.MustAccAddressFromBech32("cosmos1afk9zr2hn2jsac63h4hm60vl9z3e5u69gndzf7c99cqge3vzwjzsfwkgpd")
policyAddr3 = sdk.MustAccAddressFromBech32("cosmos1dlszg2sst9r69my4f84l3mj66zxcf3umcgujys30t84srg95dgvsmn3jeu")
policyAddr1 = mustAccAddressFromBech32("cosmos1q32tjg5qm3n9fj8wjgpd7gl98prefntrckjkyvh8tntp7q33zj0s5tkjrk")
policyAddr2 = mustAccAddressFromBech32("cosmos1afk9zr2hn2jsac63h4hm60vl9z3e5u69gndzf7c99cqge3vzwjzsfwkgpd")
policyAddr3 = mustAccAddressFromBech32("cosmos1dlszg2sst9r69my4f84l3mj66zxcf3umcgujys30t84srg95dgvsmn3jeu")
authorityAddr = sdk.AccAddress("authority")
)
func mustAccAddressFromBech32(address string) sdk.AccAddress {
addr, err := addresscodec.NewBech32Codec("cosmos").StringToBytes(address)
if err != nil {
panic(err)
}
return addr
}
func TestMigrate(t *testing.T) {
cdc := moduletestutil.MakeTestEncodingConfig(codectestutil.CodecOptions{}, auth.AppModule{}, groupmodule.AppModule{}).Codec
storeKey := storetypes.NewKVStoreKey(v2.ModuleName)
@ -62,7 +70,7 @@ func TestMigrate(t *testing.T) {
}
func createGroupPolicies(ctx sdk.Context, storeService corestore.KVStoreService, cdc codec.Codec, policies []sdk.AccAddress, addressCodec address.Codec) (orm.PrimaryKeyTable, orm.Sequence, error) {
groupPolicyTable, err := orm.NewPrimaryKeyTable([2]byte{groupkeeper.GroupPolicyTablePrefix}, &group.GroupPolicyInfo{}, cdc)
groupPolicyTable, err := orm.NewPrimaryKeyTable([2]byte{groupkeeper.GroupPolicyTablePrefix}, &group.GroupPolicyInfo{}, cdc, addressCodec)
if err != nil {
panic(err.Error())
}

View File

@ -12,6 +12,7 @@ import (
"cosmossdk.io/x/group/module"
"cosmossdk.io/x/group/simulation"
"github.com/cosmos/cosmos-sdk/codec/address"
codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
"github.com/cosmos/cosmos-sdk/types/kv"
@ -22,6 +23,7 @@ func TestDecodeStore(t *testing.T) {
encodingConfig := moduletestutil.MakeTestEncodingConfig(codectestutil.CodecOptions{}, module.AppModule{})
cdc := encodingConfig.Codec
dec := simulation.NewDecodeStore(cdc)
ac := address.NewBech32Codec("cosmos")
g := group.GroupInfo{Id: 1}
groupBz, err := cdc.Marshal(&g)
@ -53,11 +55,11 @@ func TestDecodeStore(t *testing.T) {
kvPairs := kv.Pairs{
Pairs: []kv.Pair{
{Key: append([]byte{keeper.GroupTablePrefix}, orm.PrimaryKey(&g)...), Value: groupBz},
{Key: append([]byte{keeper.GroupMemberTablePrefix}, orm.PrimaryKey(&member)...), Value: memberBz},
{Key: append([]byte{keeper.GroupPolicyTablePrefix}, orm.PrimaryKey(&acc)...), Value: accBz},
{Key: append([]byte{keeper.ProposalTablePrefix}, orm.PrimaryKey(&proposal)...), Value: proposalBz},
{Key: append([]byte{keeper.VoteTablePrefix}, orm.PrimaryKey(&vote)...), Value: voteBz},
{Key: append([]byte{keeper.GroupTablePrefix}, orm.PrimaryKey(&g, ac)...), Value: groupBz},
{Key: append([]byte{keeper.GroupMemberTablePrefix}, orm.PrimaryKey(&member, ac)...), Value: memberBz},
{Key: append([]byte{keeper.GroupPolicyTablePrefix}, orm.PrimaryKey(&acc, ac)...), Value: accBz},
{Key: append([]byte{keeper.ProposalTablePrefix}, orm.PrimaryKey(&proposal, ac)...), Value: proposalBz},
{Key: append([]byte{keeper.VoteTablePrefix}, orm.PrimaryKey(&vote, ac)...), Value: voteBz},
{Key: []byte{0x99}, Value: []byte{0x99}},
},
}

View File

@ -6,6 +6,7 @@ import (
proto "github.com/cosmos/gogoproto/proto"
"cosmossdk.io/core/address"
errorsmod "cosmossdk.io/errors"
"cosmossdk.io/x/group/errors"
"cosmossdk.io/x/group/internal/math"
@ -290,8 +291,8 @@ func (g GroupPolicyInfo) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error
return unpacker.UnpackAny(g.DecisionPolicy, &decisionPolicy)
}
func (g GroupInfo) PrimaryKeyFields() []interface{} {
return []interface{}{g.Id}
func (g GroupInfo) PrimaryKeyFields(_ address.Codec) ([]interface{}, error) {
return []interface{}{g.Id}, nil
}
// ValidateBasic does basic validation on group info.
@ -314,14 +315,17 @@ func (g GroupInfo) ValidateBasic() error {
return nil
}
func (g GroupPolicyInfo) PrimaryKeyFields() []interface{} {
addr := sdk.MustAccAddressFromBech32(g.Address)
func (g GroupPolicyInfo) PrimaryKeyFields(addressCodec address.Codec) ([]interface{}, error) {
addr, err := addressCodec.StringToBytes(g.Address)
if err != nil {
return nil, err
}
return []interface{}{addr.Bytes()}
return []interface{}{addr}, nil
}
func (g Proposal) PrimaryKeyFields() []interface{} {
return []interface{}{g.Id}
func (g Proposal) PrimaryKeyFields(_ address.Codec) ([]interface{}, error) {
return []interface{}{g.Id}, nil
}
// ValidateBasic does basic validation on group policy info.
@ -352,10 +356,13 @@ func (g GroupPolicyInfo) ValidateBasic() error {
return nil
}
func (g GroupMember) PrimaryKeyFields() []interface{} {
addr := sdk.MustAccAddressFromBech32(g.Member.Address)
func (g GroupMember) PrimaryKeyFields(addressCodec address.Codec) ([]interface{}, error) {
addr, err := addressCodec.StringToBytes(g.Member.Address)
if err != nil {
return nil, err
}
return []interface{}{g.GroupId, addr.Bytes()}
return []interface{}{g.GroupId, addr}, nil
}
// ValidateBasic does basic validation on group member.
@ -421,10 +428,13 @@ func (g Proposal) ValidateBasic() error {
return nil
}
func (v Vote) PrimaryKeyFields() []interface{} {
addr := sdk.MustAccAddressFromBech32(v.Voter)
func (v Vote) PrimaryKeyFields(addressCodec address.Codec) ([]interface{}, error) {
addr, err := addressCodec.StringToBytes(v.Voter)
if err != nil {
return nil, err
}
return []interface{}{v.ProposalId, addr.Bytes()}
return []interface{}{v.ProposalId, addr}, nil
}
var _ orm.Validateable = Vote{}