x/auth genesis protobuf migration (#6880)

* Add auth genesis.proto and related changes

* Add UnpackInterfaces method to auth GenesisState

* Remove unrelevant test case

* Update proto/cosmos/auth/genesis.proto

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>

* Add test for auth types ConvertAccountsAny

* Apply naming suggestions

* Update x/auth/types/genesis_test.go

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
Marie 2020-07-29 18:00:15 +02:00 committed by GitHub
parent 9592f34cde
commit bc7e943158
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 574 additions and 41 deletions

View File

@ -0,0 +1,17 @@
syntax = "proto3";
package cosmos.auth;
import "google/protobuf/any.proto";
import "gogoproto/gogo.proto";
import "cosmos/auth/auth.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types";
// GenesisState - all auth state that must be provided at genesis
message GenesisState {
Params params = 1 [
(gogoproto.casttype) = "Params",
(gogoproto.nullable) = false
];
repeated google.protobuf.Any accounts = 2;
}

View File

@ -120,14 +120,25 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
authGenState := authtypes.GetGenesisStateFromAppState(cdc, appState)
if authGenState.Accounts.Contains(addr) {
accs, err := authtypes.UnpackAccounts(authGenState.Accounts)
if err != nil {
return fmt.Errorf("failed to get accounts from any: %w", err)
}
if accs.Contains(addr) {
return fmt.Errorf("cannot add account at existing address %s", addr)
}
// Add the new account to the set of genesis accounts and sanitize the
// accounts afterwards.
authGenState.Accounts = append(authGenState.Accounts, genAccount)
authGenState.Accounts = authtypes.SanitizeGenesisAccounts(authGenState.Accounts)
accs = append(accs, genAccount)
accs = authtypes.SanitizeGenesisAccounts(accs)
genAccs, err := authtypes.PackAccounts(accs)
if err != nil {
return fmt.Errorf("failed to convert accounts into any's: %w", err)
}
authGenState.Accounts = genAccs
authGenStateBz, err := cdc.MarshalJSON(authGenState)
if err != nil {

View File

@ -264,7 +264,12 @@ func initGenFiles(
var authGenState authtypes.GenesisState
cdc.MustUnmarshalJSON(appGenState[authtypes.ModuleName], &authGenState)
authGenState.Accounts = genAccounts
accounts, err := authtypes.PackAccounts(genAccounts)
if err != nil {
return err
}
authGenState.Accounts = accounts
appGenState[authtypes.ModuleName] = cdc.MustMarshalJSON(authGenState)
// set the balances in the genesis state

View File

@ -154,8 +154,13 @@ func AppStateFromGenesisFileFn(r io.Reader, cdc *codec.Codec, genesisFile string
privKey := secp256k1.GenPrivKeySecp256k1(privkeySeed)
a, ok := acc.GetCachedValue().(authtypes.AccountI)
if !ok {
panic("expected account")
}
// create simulator accounts
simAcc := simtypes.Account{PrivKey: privKey, PubKey: privKey.PubKey(), Address: acc.GetAddress()}
simAcc := simtypes.Account{PrivKey: privKey, PubKey: privKey.PubKey(), Address: a.GetAddress()}
newAccs[i] = simAcc
}

View File

@ -136,7 +136,12 @@ func initGenFiles(cfg Config, genAccounts []authtypes.GenesisAccount, genBalance
var authGenState authtypes.GenesisState
cfg.Codec.MustUnmarshalJSON(cfg.GenesisState[authtypes.ModuleName], &authGenState)
authGenState.Accounts = genAccounts
accounts, err := authtypes.PackAccounts(genAccounts)
if err != nil {
return err
}
authGenState.Accounts = accounts
cfg.GenesisState[authtypes.ModuleName] = cfg.Codec.MustMarshalJSON(authGenState)
// set the balances in the genesis state

View File

@ -12,9 +12,14 @@ import (
// a genesis port script to the new fee collector account
func InitGenesis(ctx sdk.Context, ak keeper.AccountKeeper, data types.GenesisState) {
ak.SetParams(ctx, data.Params)
data.Accounts = types.SanitizeGenesisAccounts(data.Accounts)
for _, a := range data.Accounts {
accounts, err := types.UnpackAccounts(data.Accounts)
if err != nil {
panic(err)
}
accounts = types.SanitizeGenesisAccounts(accounts)
for _, a := range accounts {
acc := ak.NewAccount(ctx, a)
ak.SetAccount(ctx, acc)
}

View File

@ -45,28 +45,11 @@ func TestRandomizedGenState(t *testing.T) {
require.Equal(t, uint64(0x1ff), authGenesis.Params.GetSigVerifyCostSecp256k1())
require.Equal(t, uint64(9), authGenesis.Params.GetTxSigLimit())
require.Equal(t, uint64(5), authGenesis.Params.GetTxSizeCostPerByte())
require.Len(t, authGenesis.Accounts, 3)
require.Equal(t, "cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", authGenesis.Accounts[2].GetAddress().String())
require.Equal(t, uint64(0), authGenesis.Accounts[2].GetAccountNumber())
require.Equal(t, uint64(0), authGenesis.Accounts[2].GetSequence())
}
// TestRandomizedGenState tests abnormal scenarios of applying RandomizedGenState.
func TestRandomizedGenState1(t *testing.T) {
cdc := codec.New()
s := rand.NewSource(1)
r := rand.New(s)
simState := module.SimulationState{
AppParams: make(simtypes.AppParams),
Cdc: cdc,
Rand: r,
NumBonded: 3,
Accounts: simtypes.RandomAccounts(r, 3),
InitialStake: 1000,
GenState: make(map[string]json.RawMessage),
}
require.Panicsf(t, func() { simulation.RandomizedGenState(&simState) }, "Unregistered interface types.GenesisAccount")
genAccounts, err := types.UnpackAccounts(authGenesis.Accounts)
require.NoError(t, err)
require.Len(t, genAccounts, 3)
require.Equal(t, "cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", genAccounts[2].GetAddress().String())
require.Equal(t, uint64(0), genAccounts[2].GetAccountNumber())
require.Equal(t, uint64(0), genAccounts[2].GetSequence())
}

View File

@ -6,22 +6,36 @@ import (
"sort"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
proto "github.com/gogo/protobuf/proto"
)
// GenesisState - all auth state that must be provided at genesis
type GenesisState struct {
Params Params `json:"params" yaml:"params"`
Accounts GenesisAccounts `json:"accounts" yaml:"accounts"`
}
var _ types.UnpackInterfacesMessage = GenesisState{}
// NewGenesisState - Create a new genesis state
func NewGenesisState(params Params, accounts GenesisAccounts) GenesisState {
genAccounts, err := PackAccounts(accounts)
if err != nil {
panic(err)
}
return GenesisState{
Params: params,
Accounts: accounts,
Accounts: genAccounts,
}
}
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (g GenesisState) UnpackInterfaces(unpacker types.AnyUnpacker) error {
for _, any := range g.Accounts {
var account GenesisAccount
err := unpacker.UnpackAny(any, &account)
if err != nil {
return err
}
}
return nil
}
// DefaultGenesisState - Return a default genesis state
func DefaultGenesisState() GenesisState {
return NewGenesisState(DefaultParams(), GenesisAccounts{})
@ -46,7 +60,12 @@ func ValidateGenesis(data GenesisState) error {
return err
}
return ValidateGenAccounts(data.Accounts)
genAccs, err := UnpackAccounts(data.Accounts)
if err != nil {
return err
}
return ValidateGenAccounts(genAccs)
}
// SanitizeGenesisAccounts sorts accounts and coin sets.
@ -89,8 +108,44 @@ func (GenesisAccountIterator) IterateGenesisAccounts(
cdc codec.Marshaler, appGenesis map[string]json.RawMessage, cb func(AccountI) (stop bool),
) {
for _, genAcc := range GetGenesisStateFromAppState(cdc, appGenesis).Accounts {
if cb(genAcc) {
acc, ok := genAcc.GetCachedValue().(AccountI)
if !ok {
panic("expected account")
}
if cb(acc) {
break
}
}
}
// PackAccounts converts GenesisAccounts to Any slice
func PackAccounts(accounts GenesisAccounts) ([]*types.Any, error) {
accountsAny := make([]*types.Any, len(accounts))
for i, acc := range accounts {
msg, ok := acc.(proto.Message)
if !ok {
return nil, fmt.Errorf("cannot proto marshal %T", acc)
}
any, err := types.NewAnyWithValue(msg)
if err != nil {
return nil, err
}
accountsAny[i] = any
}
return accountsAny, nil
}
// UnpackAccounts converts Any slice to GenesisAccounts
func UnpackAccounts(accountsAny []*types.Any) (GenesisAccounts, error) {
accounts := make(GenesisAccounts, len(accountsAny))
for i, any := range accountsAny {
acc, ok := any.GetCachedValue().(GenesisAccount)
if !ok {
return nil, fmt.Errorf("expected genesis account")
}
accounts[i] = acc
}
return accounts, nil
}

390
x/auth/types/genesis.pb.go Normal file
View File

@ -0,0 +1,390 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cosmos/auth/genesis.proto
package types
import (
fmt "fmt"
types "github.com/cosmos/cosmos-sdk/codec/types"
_ "github.com/gogo/protobuf/gogoproto"
proto "github.com/gogo/protobuf/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// GenesisState - all auth state that must be provided at genesis
type GenesisState struct {
Params Params `protobuf:"bytes,1,opt,name=params,proto3,casttype=Params" json:"params"`
Accounts []*types.Any `protobuf:"bytes,2,rep,name=accounts,proto3" json:"accounts,omitempty"`
}
func (m *GenesisState) Reset() { *m = GenesisState{} }
func (m *GenesisState) String() string { return proto.CompactTextString(m) }
func (*GenesisState) ProtoMessage() {}
func (*GenesisState) Descriptor() ([]byte, []int) {
return fileDescriptor_eb73f4d82d582a1f, []int{0}
}
func (m *GenesisState) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *GenesisState) XXX_Merge(src proto.Message) {
xxx_messageInfo_GenesisState.Merge(m, src)
}
func (m *GenesisState) XXX_Size() int {
return m.Size()
}
func (m *GenesisState) XXX_DiscardUnknown() {
xxx_messageInfo_GenesisState.DiscardUnknown(m)
}
var xxx_messageInfo_GenesisState proto.InternalMessageInfo
func (m *GenesisState) GetParams() Params {
if m != nil {
return m.Params
}
return Params{}
}
func (m *GenesisState) GetAccounts() []*types.Any {
if m != nil {
return m.Accounts
}
return nil
}
func init() {
proto.RegisterType((*GenesisState)(nil), "cosmos.auth.GenesisState")
}
func init() { proto.RegisterFile("cosmos/auth/genesis.proto", fileDescriptor_eb73f4d82d582a1f) }
var fileDescriptor_eb73f4d82d582a1f = []byte{
// 246 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4c, 0xce, 0x2f, 0xce,
0xcd, 0x2f, 0xd6, 0x4f, 0x2c, 0x2d, 0xc9, 0xd0, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6,
0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x86, 0x48, 0xe9, 0x81, 0xa4, 0xa4, 0x24, 0xd3, 0xf3,
0xf3, 0xd3, 0x73, 0x52, 0xf5, 0xc1, 0x52, 0x49, 0xa5, 0x69, 0xfa, 0x89, 0x79, 0x95, 0x10, 0x75,
0x52, 0x22, 0xe9, 0xf9, 0xe9, 0xf9, 0x60, 0xa6, 0x3e, 0x88, 0x05, 0x15, 0x15, 0x43, 0x36, 0x18,
0x44, 0x40, 0xc4, 0x95, 0x6a, 0xb9, 0x78, 0xdc, 0x21, 0xd6, 0x04, 0x97, 0x24, 0x96, 0xa4, 0x0a,
0x59, 0x73, 0xb1, 0x15, 0x24, 0x16, 0x25, 0xe6, 0x16, 0x4b, 0x30, 0x2a, 0x30, 0x6a, 0x70, 0x1b,
0x09, 0xeb, 0x21, 0x59, 0xab, 0x17, 0x00, 0x96, 0x72, 0xe2, 0x3b, 0x71, 0x4f, 0x9e, 0xe1, 0xd7,
0x3d, 0x79, 0x36, 0x08, 0x3f, 0x08, 0xaa, 0x45, 0xc8, 0x80, 0x8b, 0x23, 0x31, 0x39, 0x39, 0xbf,
0x34, 0xaf, 0xa4, 0x58, 0x82, 0x49, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x44, 0x0f, 0xe2, 0x50, 0x3d,
0x98, 0x43, 0xf5, 0x1c, 0xf3, 0x2a, 0x83, 0xe0, 0xaa, 0x9c, 0x9c, 0x4f, 0x3c, 0x92, 0x63, 0xbc,
0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63,
0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, 0x33, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f,
0x57, 0x1f, 0xea, 0x76, 0x08, 0xa5, 0x5b, 0x9c, 0x92, 0xad, 0x5f, 0x01, 0xf1, 0x48, 0x49, 0x65,
0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x70, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x47, 0xda,
0x47, 0x7b, 0x3d, 0x01, 0x00, 0x00,
}
func (m *GenesisState) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Accounts) > 0 {
for iNdEx := len(m.Accounts) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Accounts[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
}
{
size, err := m.Params.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int {
offset -= sovGenesis(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *GenesisState) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = m.Params.Size()
n += 1 + l + sovGenesis(uint64(l))
if len(m.Accounts) > 0 {
for _, e := range m.Accounts {
l = e.Size()
n += 1 + l + sovGenesis(uint64(l))
}
}
return n
}
func sovGenesis(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozGenesis(x uint64) (n int) {
return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *GenesisState) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: GenesisState: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Accounts", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Accounts = append(m.Accounts, &types.Any{})
if err := m.Accounts[len(m.Accounts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipGenesis(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthGenesis
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupGenesis
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthGenesis
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group")
)

View File

@ -4,9 +4,11 @@ import (
"encoding/json"
"testing"
proto "github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/ed25519"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/types"
)
@ -55,7 +57,9 @@ func TestGenesisAccountIterator(t *testing.T) {
genAccounts := types.GenesisAccounts{acc1, acc2}
authGenState := types.DefaultGenesisState()
authGenState.Accounts = genAccounts
accounts, err := types.PackAccounts(genAccounts)
require.NoError(t, err)
authGenState.Accounts = accounts
appGenesis := make(map[string]json.RawMessage)
authGenStateBz, err := appCodec.MarshalJSON(authGenState)
@ -75,3 +79,56 @@ func TestGenesisAccountIterator(t *testing.T) {
require.Equal(t, addresses[0], acc1.GetAddress())
require.Equal(t, addresses[1], acc2.GetAddress())
}
func TestPackAccountsAny(t *testing.T) {
var (
accounts []*codectypes.Any
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"expected genesis account",
func() {
accounts = []*codectypes.Any{&codectypes.Any{}}
},
false,
},
{
"success",
func() {
genAccounts := types.GenesisAccounts{&types.BaseAccount{}}
accounts = make([]*codectypes.Any, len(genAccounts))
for i, a := range genAccounts {
msg, ok := a.(proto.Message)
require.Equal(t, ok, true)
any, err := codectypes.NewAnyWithValue(msg)
require.NoError(t, err)
accounts[i] = any
}
},
true,
},
}
for _, tc := range testCases {
t.Run(tc.msg, func(t *testing.T) {
tc.malleate()
res, err := types.UnpackAccounts(accounts)
if tc.expPass {
require.NoError(t, err)
require.NotNil(t, res)
require.Equal(t, len(res), len(accounts))
} else {
require.Error(t, err)
require.Nil(t, res)
}
})
}
}