From 87a8d5841ee1f19ca7cbe5b5df2f441bebab921c Mon Sep 17 00:00:00 2001 From: Supanat Potiwarakorn Date: Wed, 8 Feb 2023 11:42:04 +0700 Subject: [PATCH] Add param to allow non lock owner to force unlock --- go.mod | 2 +- proto/osmosis/lockup/params.proto | 3 ++ x/lockup/keeper/grpc_query_test.go | 4 +- x/lockup/keeper/msg_server.go | 31 ++++++++--- x/lockup/keeper/msg_server_test.go | 77 +++++++++++++++++---------- x/lockup/types/params.go | 15 ++++-- x/lockup/types/params.pb.go | 84 +++++++++++++++++++++++++----- 7 files changed, 162 insertions(+), 54 deletions(-) diff --git a/go.mod b/go.mod index 8f84ead28ee..8cc72b62a2e 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/CosmWasm/wasmd v0.30.0 github.com/cosmos/cosmos-proto v1.0.0-alpha8 - github.com/cosmos/cosmos-sdk v0.46.8 + github.com/cosmos/cosmos-sdk v0.46.9 github.com/cosmos/go-bip39 v1.0.0 github.com/cosmos/ibc-go/v4 v4.3.0 github.com/gogo/protobuf v1.3.3 diff --git a/proto/osmosis/lockup/params.proto b/proto/osmosis/lockup/params.proto index 0a8f0125e4d..dddb5dda69b 100644 --- a/proto/osmosis/lockup/params.proto +++ b/proto/osmosis/lockup/params.proto @@ -8,4 +8,7 @@ option go_package = "github.com/osmosis-labs/osmosis/v14/x/lockup/types"; message Params { repeated string force_unlock_allowed_addresses = 1 [ (gogoproto.moretags) = "yaml:\"force_unlock_allowed_address\"" ]; + repeated string non_owner_force_unlock_allowed_addresses = 2 + [ (gogoproto.moretags) = + "yaml:\"non_owner_force_unlock_allowed_addresses\"" ]; } diff --git a/x/lockup/keeper/grpc_query_test.go b/x/lockup/keeper/grpc_query_test.go index 050fb327b1b..a7168027f77 100644 --- a/x/lockup/keeper/grpc_query_test.go +++ b/x/lockup/keeper/grpc_query_test.go @@ -521,10 +521,12 @@ func (suite *KeeperTestSuite) TestParams() { res, err := suite.querier.Params(sdk.WrapSDKContext(suite.Ctx), &types.QueryParamsRequest{}) suite.Require().NoError(err) suite.Require().Equal([]string(nil), res.Params.ForceUnlockAllowedAddresses) + suite.Require().Equal([]string(nil), res.Params.NonOwnerForceUnlockAllowedAddresses) // Set new params & query - suite.App.LockupKeeper.SetParams(suite.Ctx, types.NewParams([]string{suite.TestAccs[0].String()})) + suite.App.LockupKeeper.SetParams(suite.Ctx, types.NewParams([]string{suite.TestAccs[0].String()}, []string{suite.TestAccs[1].String()})) res, err = suite.querier.Params(sdk.WrapSDKContext(suite.Ctx), &types.QueryParamsRequest{}) suite.Require().NoError(err) suite.Require().Equal([]string{suite.TestAccs[0].String()}, res.Params.ForceUnlockAllowedAddresses) + suite.Require().Equal([]string{suite.TestAccs[1].String()}, res.Params.NonOwnerForceUnlockAllowedAddresses) } diff --git a/x/lockup/keeper/msg_server.go b/x/lockup/keeper/msg_server.go index b4596465271..3659082add3 100644 --- a/x/lockup/keeper/msg_server.go +++ b/x/lockup/keeper/msg_server.go @@ -187,22 +187,37 @@ func (server msgServer) ForceUnlock(goCtx context.Context, msg *types.MsgForceUn return &types.MsgForceUnlockResponse{Success: false}, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error()) } - // check if message sender matches lock owner - if lock.Owner != msg.Owner { - return &types.MsgForceUnlockResponse{Success: false}, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "Sender (%s) does not match lock owner (%s)", msg.Owner, lock.Owner) + params := server.keeper.GetParams(ctx) + nonOwnerForceUnlockAllowedAddresses := params.NonOwnerForceUnlockAllowedAddresses + nonOwnerForceUnlockAuthorized := false + + for _, addr := range nonOwnerForceUnlockAllowedAddresses { + if addr == msg.Owner { + nonOwnerForceUnlockAuthorized = true + } + } + + // if non owner force unlock is not authorized, check if message sender matches lock owner + if !nonOwnerForceUnlockAuthorized { + if lock.Owner != msg.Owner { + return &types.MsgForceUnlockResponse{Success: false}, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "Sender (%s) does not match lock owner (%s)", msg.Owner, lock.Owner) + } } + // inherit non owner force unlock authorization as starting point for the next check + // since the address is allowed for non owner force unlock, it is also allowed for owner force unlock + forceUnlockAuthorized := nonOwnerForceUnlockAuthorized + // check for chain parameter that the address is allowed to force unlock - forceUnlockAllowedAddresses := server.keeper.GetParams(ctx).ForceUnlockAllowedAddresses - found := false - for _, addr := range forceUnlockAllowedAddresses { + forceUnlockAllowedAddresseses := params.ForceUnlockAllowedAddresses + for _, addr := range forceUnlockAllowedAddresseses { // defense in depth, double checking the message owner and lock owner are both the same and is one of the allowed force unlock addresses if addr == lock.Owner && addr == msg.Owner { - found = true + forceUnlockAuthorized = true break } } - if !found { + if !forceUnlockAuthorized { return &types.MsgForceUnlockResponse{Success: false}, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "Sender (%s) not allowed to force unlock", lock.Owner) } diff --git a/x/lockup/keeper/msg_server_test.go b/x/lockup/keeper/msg_server_test.go index 3e7104ec33c..1f6f7e22f45 100644 --- a/x/lockup/keeper/msg_server_test.go +++ b/x/lockup/keeper/msg_server_test.go @@ -332,30 +332,33 @@ func (suite *KeeperTestSuite) TestMsgEditLockup() { } func (suite *KeeperTestSuite) TestMsgForceUnlock() { - addr1 := sdk.AccAddress([]byte("addr1---------------")) - addr2 := sdk.AccAddress([]byte("addr2---------------")) + unlocker := sdk.AccAddress([]byte("addr1---------------")) + nonUnlocker := sdk.AccAddress([]byte("addr2---------------")) defaultPoolID, defaultLockID := uint64(1), uint64(1) defaultLockAmount := sdk.NewInt(1000000000) tests := []struct { - name string - forceUnlockAllowedAddress types.Params - postLockSetup func() - forceUnlockAmount sdk.Int - expectPass bool + name string + lockupParams types.Params + poolOwner sdk.AccAddress + postLockSetup func() + forceUnlockAmount sdk.Int + expectPass bool }{ { "happy path", - types.Params{ForceUnlockAllowedAddresses: []string{addr1.String()}}, + types.Params{ForceUnlockAllowedAddresses: []string{unlocker.String()}}, + unlocker, func() {}, defaultLockAmount, true, }, { "force unlock superfluid delegated lock", - types.Params{ForceUnlockAllowedAddresses: []string{addr1.String()}}, + types.Params{ForceUnlockAllowedAddresses: []string{unlocker.String()}}, + unlocker, func() { - err := suite.SuperfluidDelegateToDefaultVal(addr1, defaultPoolID, defaultLockID) + err := suite.SuperfluidDelegateToDefaultVal(unlocker, defaultPoolID, defaultLockID) suite.Require().NoError(err) }, defaultLockAmount, @@ -363,12 +366,13 @@ func (suite *KeeperTestSuite) TestMsgForceUnlock() { }, { "superfluid undelegating lock", - types.Params{ForceUnlockAllowedAddresses: []string{addr1.String()}}, + types.Params{ForceUnlockAllowedAddresses: []string{unlocker.String()}}, + unlocker, func() { - err := suite.SuperfluidDelegateToDefaultVal(addr1, defaultPoolID, defaultLockID) + err := suite.SuperfluidDelegateToDefaultVal(unlocker, defaultPoolID, defaultLockID) suite.Require().NoError(err) - err = suite.App.SuperfluidKeeper.SuperfluidUndelegate(suite.Ctx, addr1.String(), defaultLockID) + err = suite.App.SuperfluidKeeper.SuperfluidUndelegate(suite.Ctx, unlocker.String(), defaultLockID) suite.Require().NoError(err) }, defaultLockAmount, @@ -376,7 +380,8 @@ func (suite *KeeperTestSuite) TestMsgForceUnlock() { }, { "partial unlock", - types.Params{ForceUnlockAllowedAddresses: []string{addr1.String()}}, + types.Params{ForceUnlockAllowedAddresses: []string{unlocker.String()}}, + unlocker, func() {}, // try force unlocking half of locked amount defaultLockAmount.Quo(sdk.NewInt(2)), @@ -384,22 +389,41 @@ func (suite *KeeperTestSuite) TestMsgForceUnlock() { }, { "force unlock more than what we have locked", - types.Params{ForceUnlockAllowedAddresses: []string{addr1.String()}}, + types.Params{ForceUnlockAllowedAddresses: []string{unlocker.String()}}, + unlocker, func() {}, // try force more than the locked amount defaultLockAmount.Add(sdk.NewInt(1)), false, }, { - "params with different address", - types.Params{ForceUnlockAllowedAddresses: []string{addr2.String()}}, + "param with multiple addresses ", + types.Params{ForceUnlockAllowedAddresses: []string{unlocker.String(), nonUnlocker.String()}}, + unlocker, + func() {}, + defaultLockAmount, + true, + }, + { + "force unlock lock that is not owned by the unlocker", + types.Params{ForceUnlockAllowedAddresses: []string{unlocker.String()}}, + nonUnlocker, func() {}, defaultLockAmount, false, }, { - "param with multiple addresses ", - types.Params{ForceUnlockAllowedAddresses: []string{addr1.String(), addr2.String()}}, + "force unlock lock that is not owned by the unlocker but are allowed by the params", + types.Params{NonOwnerForceUnlockAllowedAddresses: []string{unlocker.String()}}, + nonUnlocker, + func() {}, + defaultLockAmount, + true, + }, + { + "force unlock lock that is owned by the unlocker while msg owner is only allowed in NonOwnerForceUnlockAllowedAddresses", + types.Params{NonOwnerForceUnlockAllowedAddresses: []string{unlocker.String()}}, + unlocker, func() {}, defaultLockAmount, true, @@ -409,7 +433,7 @@ func (suite *KeeperTestSuite) TestMsgForceUnlock() { for _, test := range tests { // set up test suite.SetupTest() - suite.App.LockupKeeper.SetParams(suite.Ctx, test.forceUnlockAllowedAddress) + suite.App.LockupKeeper.SetParams(suite.Ctx, test.lockupParams) // prepare pool for superfluid staking cases poolId := suite.PrepareBalancerPoolWithCoins(sdk.NewCoin("stake", sdk.NewInt(1000000000000)), sdk.NewCoin("foo", sdk.NewInt(5000))) @@ -420,30 +444,29 @@ func (suite *KeeperTestSuite) TestMsgForceUnlock() { poolDenom := gammtypes.GetPoolShareDenom(poolId) coinsToLock := sdk.Coins{sdk.NewCoin(poolDenom, defaultLockAmount)} - suite.FundAcc(addr1, coinsToLock) + suite.FundAcc(test.poolOwner, coinsToLock) unbondingDuration := suite.App.StakingKeeper.GetParams(suite.Ctx).UnbondingTime - resp, err := msgServer.LockTokens(c, types.NewMsgLockTokens(addr1, unbondingDuration, coinsToLock)) + resp, err := msgServer.LockTokens(c, types.NewMsgLockTokens(test.poolOwner, unbondingDuration, coinsToLock)) suite.Require().NoError(err) // setup env after lock tokens test.postLockSetup() // test force unlock - _, err = msgServer.ForceUnlock(c, types.NewMsgForceUnlock(addr1, resp.ID, sdk.Coins{sdk.NewCoin(poolDenom, test.forceUnlockAmount)})) + _, err = msgServer.ForceUnlock(c, types.NewMsgForceUnlock(unlocker, resp.ID, sdk.Coins{sdk.NewCoin(poolDenom, test.forceUnlockAmount)})) if test.expectPass { - suite.Require().NoError(err) + suite.Require().NoError(err, "test: %s", test.name) // check that we have successfully force unlocked - balanceAfterForceUnlock := suite.App.BankKeeper.GetBalance(suite.Ctx, addr1, poolDenom) + balanceAfterForceUnlock := suite.App.BankKeeper.GetBalance(suite.Ctx, test.poolOwner, poolDenom) suite.Require().Equal(test.forceUnlockAmount, balanceAfterForceUnlock.Amount) } else { suite.Require().Error(err) // check that we have successfully force unlocked - balanceAfterForceUnlock := suite.App.BankKeeper.GetBalance(suite.Ctx, addr1, poolDenom) + balanceAfterForceUnlock := suite.App.BankKeeper.GetBalance(suite.Ctx, test.poolOwner, poolDenom) suite.Require().NotEqual(test.forceUnlockAmount, balanceAfterForceUnlock.Amount) - return } } } diff --git a/x/lockup/types/params.go b/x/lockup/types/params.go index 18ac9b3290f..61b876beb36 100644 --- a/x/lockup/types/params.go +++ b/x/lockup/types/params.go @@ -9,7 +9,8 @@ import ( // Parameter store keys. var ( - KeyForceUnlockAllowedAddresses = []byte("ForceUnlockAllowedAddresses") + KeyForceUnlockAllowedAddresses = []byte("ForceUnlockAllowedAddresses") + KeyNonOwnerForceUnlockAllowedAddresses = []byte("NonOwnerForceUnlockAllowedAddresses") _ paramtypes.ParamSet = &Params{} ) @@ -19,16 +20,18 @@ func ParamKeyTable() paramtypes.KeyTable { return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) } -func NewParams(forceUnlockAllowedAddresses []string) Params { +func NewParams(forceUnlockAllowedAddresses, nonOwnerForceUnlockAllowedAddresses []string) Params { return Params{ - ForceUnlockAllowedAddresses: forceUnlockAllowedAddresses, + ForceUnlockAllowedAddresses: forceUnlockAllowedAddresses, + NonOwnerForceUnlockAllowedAddresses: nonOwnerForceUnlockAllowedAddresses, } } // DefaultParams returns default lockup module parameters. func DefaultParams() Params { return Params{ - ForceUnlockAllowedAddresses: []string{}, + ForceUnlockAllowedAddresses: []string{}, + NonOwnerForceUnlockAllowedAddresses: []string{}, } } @@ -37,6 +40,9 @@ func (p Params) Validate() error { if err := validateAddresses(p.ForceUnlockAllowedAddresses); err != nil { return err } + if err := validateAddresses(p.NonOwnerForceUnlockAllowedAddresses); err != nil { + return err + } return nil } @@ -44,6 +50,7 @@ func (p Params) Validate() error { func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{ paramtypes.NewParamSetPair(KeyForceUnlockAllowedAddresses, &p.ForceUnlockAllowedAddresses, validateAddresses), + paramtypes.NewParamSetPair(KeyNonOwnerForceUnlockAllowedAddresses, &p.NonOwnerForceUnlockAllowedAddresses, validateAddresses), } } diff --git a/x/lockup/types/params.pb.go b/x/lockup/types/params.pb.go index 1a0499cf537..350feace192 100644 --- a/x/lockup/types/params.pb.go +++ b/x/lockup/types/params.pb.go @@ -24,7 +24,8 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type Params struct { - ForceUnlockAllowedAddresses []string `protobuf:"bytes,1,rep,name=force_unlock_allowed_addresses,json=forceUnlockAllowedAddresses,proto3" json:"force_unlock_allowed_addresses,omitempty" yaml:"force_unlock_allowed_address"` + ForceUnlockAllowedAddresses []string `protobuf:"bytes,1,rep,name=force_unlock_allowed_addresses,json=forceUnlockAllowedAddresses,proto3" json:"force_unlock_allowed_addresses,omitempty" yaml:"force_unlock_allowed_address"` + NonOwnerForceUnlockAllowedAddresses []string `protobuf:"bytes,2,rep,name=non_owner_force_unlock_allowed_addresses,json=nonOwnerForceUnlockAllowedAddresses,proto3" json:"non_owner_force_unlock_allowed_addresses,omitempty" yaml:"non_owner_force_unlock_allowed_addresses"` } func (m *Params) Reset() { *m = Params{} } @@ -67,6 +68,13 @@ func (m *Params) GetForceUnlockAllowedAddresses() []string { return nil } +func (m *Params) GetNonOwnerForceUnlockAllowedAddresses() []string { + if m != nil { + return m.NonOwnerForceUnlockAllowedAddresses + } + return nil +} + func init() { proto.RegisterType((*Params)(nil), "osmosis.lockup.Params") } @@ -74,21 +82,24 @@ func init() { func init() { proto.RegisterFile("osmosis/lockup/params.proto", fileDescriptor_4595e58f5e17053c) } var fileDescriptor_4595e58f5e17053c = []byte{ - // 214 bytes of a gzipped FileDescriptorProto + // 258 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0xce, 0x2c, 0xd6, 0xcf, 0xc9, 0x4f, 0xce, 0x2e, 0x2d, 0xd0, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x83, 0x4a, 0xea, 0x41, 0x24, 0xa5, 0x44, - 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0x52, 0xfa, 0x20, 0x16, 0x44, 0x95, 0x52, 0x19, 0x17, 0x5b, 0x00, - 0x58, 0x97, 0x50, 0x0e, 0x97, 0x5c, 0x5a, 0x7e, 0x51, 0x72, 0x6a, 0x7c, 0x69, 0x1e, 0x48, 0x47, - 0x7c, 0x62, 0x4e, 0x4e, 0x7e, 0x79, 0x6a, 0x4a, 0x7c, 0x62, 0x4a, 0x4a, 0x51, 0x6a, 0x71, 0x71, - 0x6a, 0xb1, 0x04, 0xa3, 0x02, 0xb3, 0x06, 0xa7, 0x93, 0xfa, 0xa7, 0x7b, 0xf2, 0xca, 0x95, 0x89, - 0xb9, 0x39, 0x56, 0x4a, 0xf8, 0xd4, 0x2b, 0x05, 0x49, 0x83, 0xa5, 0x43, 0xc1, 0xb2, 0x8e, 0x10, - 0x49, 0x47, 0x98, 0x59, 0x4e, 0x3e, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, - 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, - 0x65, 0x94, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x0f, 0xf5, 0x82, 0x6e, - 0x4e, 0x62, 0x52, 0x31, 0x8c, 0xa3, 0x5f, 0x66, 0x68, 0xa2, 0x5f, 0x01, 0xf3, 0x72, 0x49, 0x65, - 0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x33, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2b, 0xbe, - 0x16, 0xd8, 0x11, 0x01, 0x00, 0x00, + 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0x52, 0xfa, 0x20, 0x16, 0x44, 0x95, 0x52, 0x33, 0x13, 0x17, 0x5b, + 0x00, 0x58, 0x9b, 0x50, 0x0e, 0x97, 0x5c, 0x5a, 0x7e, 0x51, 0x72, 0x6a, 0x7c, 0x69, 0x1e, 0x48, + 0x4b, 0x7c, 0x62, 0x4e, 0x4e, 0x7e, 0x79, 0x6a, 0x4a, 0x7c, 0x62, 0x4a, 0x4a, 0x51, 0x6a, 0x71, + 0x71, 0x6a, 0xb1, 0x04, 0xa3, 0x02, 0xb3, 0x06, 0xa7, 0x93, 0xfa, 0xa7, 0x7b, 0xf2, 0xca, 0x95, + 0x89, 0xb9, 0x39, 0x56, 0x4a, 0xf8, 0xd4, 0x2b, 0x05, 0x49, 0x83, 0xa5, 0x43, 0xc1, 0xb2, 0x8e, + 0x10, 0x49, 0x47, 0x98, 0x59, 0x42, 0x5d, 0x8c, 0x5c, 0x1a, 0x79, 0xf9, 0x79, 0xf1, 0xf9, 0xe5, + 0x79, 0xa9, 0x45, 0xf1, 0x04, 0x2c, 0x66, 0x02, 0x5b, 0x6c, 0xfc, 0xe9, 0x9e, 0xbc, 0x3e, 0xc4, + 0x62, 0x62, 0x75, 0x2a, 0x05, 0x29, 0xe7, 0xe5, 0xe7, 0xf9, 0x83, 0x54, 0xba, 0xe1, 0x76, 0x8c, + 0x93, 0xcf, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, + 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x19, 0xa5, 0x67, 0x96, + 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x43, 0x03, 0x54, 0x37, 0x27, 0x31, 0xa9, 0x18, + 0xc6, 0xd1, 0x2f, 0x33, 0x34, 0xd1, 0xaf, 0x80, 0x45, 0x40, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, + 0x1b, 0x38, 0x68, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe3, 0xb8, 0x2f, 0xe0, 0x9f, 0x01, + 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -111,6 +122,15 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.NonOwnerForceUnlockAllowedAddresses) > 0 { + for iNdEx := len(m.NonOwnerForceUnlockAllowedAddresses) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.NonOwnerForceUnlockAllowedAddresses[iNdEx]) + copy(dAtA[i:], m.NonOwnerForceUnlockAllowedAddresses[iNdEx]) + i = encodeVarintParams(dAtA, i, uint64(len(m.NonOwnerForceUnlockAllowedAddresses[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } if len(m.ForceUnlockAllowedAddresses) > 0 { for iNdEx := len(m.ForceUnlockAllowedAddresses) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.ForceUnlockAllowedAddresses[iNdEx]) @@ -146,6 +166,12 @@ func (m *Params) Size() (n int) { n += 1 + l + sovParams(uint64(l)) } } + if len(m.NonOwnerForceUnlockAllowedAddresses) > 0 { + for _, s := range m.NonOwnerForceUnlockAllowedAddresses { + l = len(s) + n += 1 + l + sovParams(uint64(l)) + } + } return n } @@ -216,6 +242,38 @@ func (m *Params) Unmarshal(dAtA []byte) error { } m.ForceUnlockAllowedAddresses = append(m.ForceUnlockAllowedAddresses, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NonOwnerForceUnlockAllowedAddresses", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NonOwnerForceUnlockAllowedAddresses = append(m.NonOwnerForceUnlockAllowedAddresses, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:])