From 057a3f49912a1deac3fc277bcd0b011ab37f405c Mon Sep 17 00:00:00 2001 From: Leeren Date: Fri, 13 Sep 2024 01:48:25 +0800 Subject: [PATCH 1/7] chore(release): begin story v0.10.1 unstable release (#116) --- lib/buildinfo/buildinfo.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/buildinfo/buildinfo.go b/lib/buildinfo/buildinfo.go index a7c3808b..011b1ce0 100644 --- a/lib/buildinfo/buildinfo.go +++ b/lib/buildinfo/buildinfo.go @@ -13,10 +13,10 @@ import ( ) const ( - VersionMajor = 0 // Major version component of the current release - VersionMinor = 10 // Minor version component of the current release - VersionPatch = 0 // Patch version component of the current release - VersionMeta = "stable" // Version metadata to append to the version string + VersionMajor = 0 // Major version component of the current release + VersionMinor = 10 // Minor version component of the current release + VersionPatch = 1 // Patch version component of the current release + VersionMeta = "unstable" // Version metadata to append to the version string ) // Version returns the version of the whole story-monorepo and all binaries built from this git commit. From 89b90f72db3ff6e3c00f47a4769c7d1ce9e03fde Mon Sep 17 00:00:00 2001 From: Jongwon Park Date: Sun, 29 Sep 2024 12:06:26 -0500 Subject: [PATCH 2/7] feat(x/evmstaking): max unbond withdrawal --- client/x/evmstaking/keeper/abci.go | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/client/x/evmstaking/keeper/abci.go b/client/x/evmstaking/keeper/abci.go index da647b45..d7b98e88 100644 --- a/client/x/evmstaking/keeper/abci.go +++ b/client/x/evmstaking/keeper/abci.go @@ -90,17 +90,18 @@ func (k *Keeper) EndBlock(ctx context.Context) (abci.ValidatorUpdates, error) { } for _, entry := range unbondedEntries { - log.Debug(ctx, "Adding undelegation to withdrawal queue", - "delegator", entry.delegatorAddress, - "validator", entry.validatorAddress, - "amount", entry.amount.String()) - delegatorAddr, err := k.authKeeper.AddressCodec().StringToBytes(entry.delegatorAddress) if err != nil { return nil, errors.Wrap(err, "delegator address from bech32") } + + maxAmount := k.bankKeeper.GetBalance(ctx, delegatorAddr, sdk.DefaultBondDenom).Amount + if entry.amount.LT(maxAmount) { + maxAmount = entry.amount + } + // Burn tokens from the delegator - _, coins := IPTokenToBondCoin(entry.amount.BigInt()) + _, coins := IPTokenToBondCoin(maxAmount.BigInt()) err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, delegatorAddr, types.ModuleName, coins) if err != nil { return nil, errors.Wrap(err, "send coins from account to module") @@ -110,6 +111,16 @@ func (k *Keeper) EndBlock(ctx context.Context) (abci.ValidatorUpdates, error) { return nil, errors.Wrap(err, "burn coins") } + log.Debug(ctx, "Adding undelegation to withdrawal queue", + "delegator", entry.delegatorAddress, + "validator", entry.validatorAddress, + "max_amount", maxAmount.String()) + if entry.amount.LT(maxAmount) { + log.Debug(ctx, "Undelegation amount is less than max amount", + "original_amount", entry.amount.String(), + "max_amount", maxAmount.String()) + } + // This should not produce error, as all delegations are done via the evmstaking module via EL. // However, we should gracefully handle in case Get fails. delEvmAddr, err := k.DelegatorMap.Get(ctx, entry.delegatorAddress) @@ -123,7 +134,7 @@ func (k *Keeper) EndBlock(ctx context.Context) (abci.ValidatorUpdates, error) { entry.delegatorAddress, entry.validatorAddress, delEvmAddr, - entry.amount.Uint64(), + maxAmount.Uint64(), )) if err != nil { return nil, err From 58fc5ed47e96c40a35f146354df8977235dd59fa Mon Sep 17 00:00:00 2001 From: Jongwon Park Date: Sun, 29 Sep 2024 12:17:22 -0500 Subject: [PATCH 3/7] chore(x/evmstaking): bump log level --- client/x/evmstaking/keeper/abci.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/x/evmstaking/keeper/abci.go b/client/x/evmstaking/keeper/abci.go index d7b98e88..3d0d623b 100644 --- a/client/x/evmstaking/keeper/abci.go +++ b/client/x/evmstaking/keeper/abci.go @@ -116,7 +116,10 @@ func (k *Keeper) EndBlock(ctx context.Context) (abci.ValidatorUpdates, error) { "validator", entry.validatorAddress, "max_amount", maxAmount.String()) if entry.amount.LT(maxAmount) { - log.Debug(ctx, "Undelegation amount is less than max amount", + log.Warn(ctx, "Undelegation amount is less than max amount", + errors.New("undelegation amount is less than max amount"), + "delegator", entry.delegatorAddress, + "validator", entry.validatorAddress, "original_amount", entry.amount.String(), "max_amount", maxAmount.String()) } From dfdd687bd5274843b63b9e6ad053add4d69034dd Mon Sep 17 00:00:00 2001 From: Jongwon Park Date: Sun, 29 Sep 2024 12:27:53 -0500 Subject: [PATCH 4/7] feat(x/evmstaking): spendable coin max amount with tests --- client/x/evmstaking/keeper/abci.go | 7 +-- client/x/evmstaking/keeper/abci_test.go | 6 +++ .../testutil/expected_keepers_mocks.go | 52 +++++++------------ client/x/evmstaking/types/expected_keepers.go | 1 + 4 files changed, 29 insertions(+), 37 deletions(-) diff --git a/client/x/evmstaking/keeper/abci.go b/client/x/evmstaking/keeper/abci.go index 3d0d623b..6fbe818a 100644 --- a/client/x/evmstaking/keeper/abci.go +++ b/client/x/evmstaking/keeper/abci.go @@ -95,8 +95,9 @@ func (k *Keeper) EndBlock(ctx context.Context) (abci.ValidatorUpdates, error) { return nil, errors.Wrap(err, "delegator address from bech32") } - maxAmount := k.bankKeeper.GetBalance(ctx, delegatorAddr, sdk.DefaultBondDenom).Amount - if entry.amount.LT(maxAmount) { + maxAmount := k.bankKeeper.SpendableCoin(ctx, delegatorAddr, sdk.DefaultBondDenom).Amount + maxBounded := entry.amount.LT(maxAmount) + if maxBounded { maxAmount = entry.amount } @@ -115,7 +116,7 @@ func (k *Keeper) EndBlock(ctx context.Context) (abci.ValidatorUpdates, error) { "delegator", entry.delegatorAddress, "validator", entry.validatorAddress, "max_amount", maxAmount.String()) - if entry.amount.LT(maxAmount) { + if maxBounded { log.Warn(ctx, "Undelegation amount is less than max amount", errors.New("undelegation amount is less than max amount"), "delegator", entry.delegatorAddress, diff --git a/client/x/evmstaking/keeper/abci_test.go b/client/x/evmstaking/keeper/abci_test.go index ccf26b94..d300159f 100644 --- a/client/x/evmstaking/keeper/abci_test.go +++ b/client/x/evmstaking/keeper/abci_test.go @@ -5,6 +5,8 @@ import ( "testing" "time" + sdkmath "cosmossdk.io/math" + abcitypes "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" dtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" @@ -363,6 +365,7 @@ func compareValUpdates(t *testing.T, expected, actual abcitypes.ValidatorUpdates // setupMaturedUnbonding creates matured unbondings for testing. func (s *TestSuite) setupMatureUnbondingDelegation(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt string, duration time.Duration) { + require := s.Require() pastHeader := ctx.BlockHeader() pastHeader.Time = pastHeader.Time.Add(-duration).Add(-time.Minute) pastCtx := ctx.WithBlockHeader(pastHeader) @@ -372,6 +375,9 @@ func (s *TestSuite) setupMatureUnbondingDelegation(ctx sdk.Context, delAddr sdk. // Mock staking.EndBlocker s.BankKeeper.EXPECT().UndelegateCoinsFromModuleToAccount(gomock.Any(), stypes.NotBondedPoolName, delAddr, gomock.Any()).Return(nil) // Mock evmstaking.EndBlocker + amtInt, ok := sdkmath.NewIntFromString(amt) + require.True(ok) + s.BankKeeper.EXPECT().SpendableCoin(gomock.Any(), delAddr, sdk.DefaultBondDenom).Return(sdk.NewCoin(sdk.DefaultBondDenom, amtInt)) s.BankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), delAddr, types.ModuleName, gomock.Any()).Return(nil) s.BankKeeper.EXPECT().BurnCoins(gomock.Any(), types.ModuleName, gomock.Any()).Return(nil) } diff --git a/client/x/evmstaking/testutil/expected_keepers_mocks.go b/client/x/evmstaking/testutil/expected_keepers_mocks.go index ab85d653..c2360617 100644 --- a/client/x/evmstaking/testutil/expected_keepers_mocks.go +++ b/client/x/evmstaking/testutil/expected_keepers_mocks.go @@ -155,15 +155,15 @@ func (mr *MockAccountKeeperMockRecorder) SetAccount(ctx, acc any) *gomock.Call { } // SetModuleAccount mocks base method. -func (m *MockAccountKeeper) SetModuleAccount(arg0 context.Context, arg1 types0.ModuleAccountI) { +func (m *MockAccountKeeper) SetModuleAccount(ctx context.Context, modAcc types0.ModuleAccountI) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetModuleAccount", arg0, arg1) + m.ctrl.Call(m, "SetModuleAccount", ctx, modAcc) } // SetModuleAccount indicates an expected call of SetModuleAccount. -func (mr *MockAccountKeeperMockRecorder) SetModuleAccount(arg0, arg1 any) *gomock.Call { +func (mr *MockAccountKeeperMockRecorder) SetModuleAccount(ctx, modAcc any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetModuleAccount", reflect.TypeOf((*MockAccountKeeper)(nil).SetModuleAccount), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetModuleAccount", reflect.TypeOf((*MockAccountKeeper)(nil).SetModuleAccount), ctx, modAcc) } // MockBankKeeper is a mock of BankKeeper interface. @@ -329,6 +329,20 @@ func (mr *MockBankKeeperMockRecorder) SendCoinsFromModuleToModule(ctx, senderPoo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCoinsFromModuleToModule", reflect.TypeOf((*MockBankKeeper)(nil).SendCoinsFromModuleToModule), ctx, senderPool, recipientPool, amt) } +// SpendableCoin mocks base method. +func (m *MockBankKeeper) SpendableCoin(ctx context.Context, addr types0.AccAddress, denom string) types0.Coin { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SpendableCoin", ctx, addr, denom) + ret0, _ := ret[0].(types0.Coin) + return ret0 +} + +// SpendableCoin indicates an expected call of SpendableCoin. +func (mr *MockBankKeeperMockRecorder) SpendableCoin(ctx, addr, denom any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpendableCoin", reflect.TypeOf((*MockBankKeeper)(nil).SpendableCoin), ctx, addr, denom) +} + // SpendableCoins mocks base method. func (m *MockBankKeeper) SpendableCoins(ctx context.Context, addr types0.AccAddress) types0.Coins { m.ctrl.T.Helper() @@ -395,21 +409,6 @@ func (mr *MockStakingKeeperMockRecorder) BondDenom(ctx any) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BondDenom", reflect.TypeOf((*MockStakingKeeper)(nil).BondDenom), ctx) } -// CompleteRedelegation mocks base method. -func (m *MockStakingKeeper) CompleteRedelegation(ctx context.Context, delAddr types0.AccAddress, valSrcAddr, valDstAddr types0.ValAddress) (types0.Coins, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CompleteRedelegation", ctx, delAddr, valSrcAddr, valDstAddr) - ret0, _ := ret[0].(types0.Coins) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CompleteRedelegation indicates an expected call of CompleteRedelegation. -func (mr *MockStakingKeeperMockRecorder) CompleteRedelegation(ctx, delAddr, valSrcAddr, valDstAddr any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CompleteRedelegation", reflect.TypeOf((*MockStakingKeeper)(nil).CompleteRedelegation), ctx, delAddr, valSrcAddr, valDstAddr) -} - // DeleteUnbondingIndex mocks base method. func (m *MockStakingKeeper) DeleteUnbondingIndex(ctx context.Context, id uint64) error { m.ctrl.T.Helper() @@ -424,21 +423,6 @@ func (mr *MockStakingKeeperMockRecorder) DeleteUnbondingIndex(ctx, id any) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUnbondingIndex", reflect.TypeOf((*MockStakingKeeper)(nil).DeleteUnbondingIndex), ctx, id) } -// DequeueAllMatureRedelegationQueue mocks base method. -func (m *MockStakingKeeper) DequeueAllMatureRedelegationQueue(ctx context.Context, currTime time.Time) ([]types2.DVVTriplet, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DequeueAllMatureRedelegationQueue", ctx, currTime) - ret0, _ := ret[0].([]types2.DVVTriplet) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// DequeueAllMatureRedelegationQueue indicates an expected call of DequeueAllMatureRedelegationQueue. -func (mr *MockStakingKeeperMockRecorder) DequeueAllMatureRedelegationQueue(ctx, currTime any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DequeueAllMatureRedelegationQueue", reflect.TypeOf((*MockStakingKeeper)(nil).DequeueAllMatureRedelegationQueue), ctx, currTime) -} - // EndBlocker mocks base method. func (m *MockStakingKeeper) EndBlocker(ctx context.Context) ([]types.ValidatorUpdate, error) { m.ctrl.T.Helper() diff --git a/client/x/evmstaking/types/expected_keepers.go b/client/x/evmstaking/types/expected_keepers.go index e4f5e20d..d3317890 100644 --- a/client/x/evmstaking/types/expected_keepers.go +++ b/client/x/evmstaking/types/expected_keepers.go @@ -40,6 +40,7 @@ type BankKeeper interface { GetAllBalances(ctx context.Context, addr sdk.AccAddress) sdk.Coins LockedCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins SpendableCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins + SpendableCoin(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin GetSupply(ctx context.Context, denom string) sdk.Coin SendCoinsFromModuleToModule(ctx context.Context, senderPool, recipientPool string, amt sdk.Coins) error } From d6e96b27dc40afbfc62665016676d15161685190 Mon Sep 17 00:00:00 2001 From: Jongwon Park Date: Sun, 29 Sep 2024 12:31:00 -0500 Subject: [PATCH 5/7] feat(x/evmstaking): pass zero amount --- client/x/evmstaking/keeper/abci.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/client/x/evmstaking/keeper/abci.go b/client/x/evmstaking/keeper/abci.go index 6fbe818a..142ad7cb 100644 --- a/client/x/evmstaking/keeper/abci.go +++ b/client/x/evmstaking/keeper/abci.go @@ -96,6 +96,16 @@ func (k *Keeper) EndBlock(ctx context.Context) (abci.ValidatorUpdates, error) { } maxAmount := k.bankKeeper.SpendableCoin(ctx, delegatorAddr, sdk.DefaultBondDenom).Amount + if maxAmount.IsZero() { + log.Warn(ctx, "No spendable coins for undelegation", + errors.New("no spendable coins for undelegation"), + "delegator", entry.delegatorAddress, + "validator", entry.validatorAddress, + "original_amount", entry.amount.String()) + + continue + } + maxBounded := entry.amount.LT(maxAmount) if maxBounded { maxAmount = entry.amount From 60a879f1087600a15cb46abadfcbcc5f6d487942 Mon Sep 17 00:00:00 2001 From: Jongwon Park Date: Sun, 29 Sep 2024 12:41:57 -0500 Subject: [PATCH 6/7] chore(x/evmstaking): move logs --- client/x/evmstaking/keeper/abci.go | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/client/x/evmstaking/keeper/abci.go b/client/x/evmstaking/keeper/abci.go index 142ad7cb..bbe4a64c 100644 --- a/client/x/evmstaking/keeper/abci.go +++ b/client/x/evmstaking/keeper/abci.go @@ -106,11 +106,21 @@ func (k *Keeper) EndBlock(ctx context.Context) (abci.ValidatorUpdates, error) { continue } - maxBounded := entry.amount.LT(maxAmount) - if maxBounded { + if entry.amount.LT(maxAmount) { maxAmount = entry.amount + log.Warn(ctx, "Undelegation amount is less than max amount", + errors.New("undelegation amount is less than max amount"), + "delegator", entry.delegatorAddress, + "validator", entry.validatorAddress, + "original_amount", entry.amount.String(), + "max_amount", maxAmount.String()) } + log.Debug(ctx, "Adding undelegation to withdrawal queue", + "delegator", entry.delegatorAddress, + "validator", entry.validatorAddress, + "max_amount", maxAmount.String()) + // Burn tokens from the delegator _, coins := IPTokenToBondCoin(maxAmount.BigInt()) err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, delegatorAddr, types.ModuleName, coins) @@ -122,19 +132,6 @@ func (k *Keeper) EndBlock(ctx context.Context) (abci.ValidatorUpdates, error) { return nil, errors.Wrap(err, "burn coins") } - log.Debug(ctx, "Adding undelegation to withdrawal queue", - "delegator", entry.delegatorAddress, - "validator", entry.validatorAddress, - "max_amount", maxAmount.String()) - if maxBounded { - log.Warn(ctx, "Undelegation amount is less than max amount", - errors.New("undelegation amount is less than max amount"), - "delegator", entry.delegatorAddress, - "validator", entry.validatorAddress, - "original_amount", entry.amount.String(), - "max_amount", maxAmount.String()) - } - // This should not produce error, as all delegations are done via the evmstaking module via EL. // However, we should gracefully handle in case Get fails. delEvmAddr, err := k.DelegatorMap.Get(ctx, entry.delegatorAddress) From 5328fa62b9be8b4970d51bde3c7a5501e23d3f8b Mon Sep 17 00:00:00 2001 From: Leeren Chang Date: Sun, 29 Sep 2024 14:02:06 -0700 Subject: [PATCH 7/7] chore(release): finalize client 0.10.1 stable release --- lib/buildinfo/buildinfo.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/buildinfo/buildinfo.go b/lib/buildinfo/buildinfo.go index 011b1ce0..4bf5301e 100644 --- a/lib/buildinfo/buildinfo.go +++ b/lib/buildinfo/buildinfo.go @@ -13,10 +13,10 @@ import ( ) const ( - VersionMajor = 0 // Major version component of the current release - VersionMinor = 10 // Minor version component of the current release - VersionPatch = 1 // Patch version component of the current release - VersionMeta = "unstable" // Version metadata to append to the version string + VersionMajor = 0 // Major version component of the current release + VersionMinor = 10 // Minor version component of the current release + VersionPatch = 1 // Patch version component of the current release + VersionMeta = "stable" // Version metadata to append to the version string ) // Version returns the version of the whole story-monorepo and all binaries built from this git commit.