Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: (v0.45.x) regression in return value of WithdrawDelegationRewards when rewards are zero #13588

Conversation

nddeluca
Copy link

@nddeluca nddeluca commented Oct 18, 2022

Description

Related to #13340 and also noticed by Terra terra-money@996da0f

In v0.45.9, the WithdrawDelegationRewards returns a invalid coins when delegation rewards are zero. While this isn't state breaking, it does break state for modules depending on valid coins being returned without a zero value.

Technically an api breaking change from v0.45.9.

Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • included the correct type prefix in the PR title
  • added ! to the type prefix if API or client breaking change
  • targeted the correct branch (see PR Targeting)
  • provided a link to the relevant issue or specification
  • followed the guidelines for building modules
  • included the necessary unit and integration tests
  • added a changelog entry to CHANGELOG.md
  • included comments for documenting Go code
  • updated the relevant documentation or specification
  • reviewed "Files changed" and left comments if necessary
  • confirmed all CI checks have passed

Reviewers Checklist

All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.

I have...

  • confirmed the correct type prefix in the PR title
  • confirmed ! in the type prefix if API or client breaking change
  • confirmed all author checklist items have been addressed
  • reviewed state machine logic
  • reviewed API design and naming
  • reviewed documentation is accurate
  • reviewed tests and test coverage
  • manually tested (if applicable)

@github-actions github-actions bot added the C:x/distribution distribution module related label Oct 18, 2022
@nddeluca nddeluca force-pushed the nd-0.45.x-revert-withdraw-delegation-api-change branch from 9bd0082 to 44c0873 Compare October 18, 2022 17:48
@alexanderbez
Copy link
Contributor

I think we should do this on 0.46 too.

@nddeluca
Copy link
Author

Would it be better to fix on main and backport for 0.46.x and 0.45.x?

Copy link
Contributor

@alexanderbez alexanderbez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So to be clear with the PR that introduced this improvement, finalRewards is always valid due to the denom being present under all circumstances.

Now with this PR, you allow the denom to be empty and thus an invalid coin. Is this what you intend?

x/distribution/keeper/delegation.go Outdated Show resolved Hide resolved
@alexanderbez
Copy link
Contributor

Ahhh, ok to summarize:

  1. v0.45.x did NOT have the if rewards.IsZero() { // ... } check so this PR reverts to the original behavior. Thank you 🙏
  2. As of v0.46.2 it DOES have the if rewards.IsZero() { // ... } check, so we need to keep it there.

@nddeluca
Copy link
Author

nddeluca commented Oct 18, 2022

Correct, really what this PR solves is:

// On v0.45.8 with zero rewards we have:
amount, _ := app.DistrKeeper.WithdrawDelegationRewards(ctx, sdk.AccAddress(valAddrs[0]), valAddrs[0])
amount.IsValid() == true

// 0n v0.45.9 with zero rewards with have:
amount, _ := app.DistrKeeper.WithdrawDelegationRewards(ctx, sdk.AccAddress(valAddrs[0]), valAddrs[0])
amount.IsValid() == false

which breaks API expectations of downstream modules expecting IsValid() to return true in all cases. This can cause a panic if IsZero or IsValid isn't checked under that assumption, and the amount is passed to other coin/module methods.

For v0.46.0, v0.46.1, v0.46.2 it looks like IsValid() always returns false when rewards are zero, so the same breaking change doesn't occur. Though imo, maybe it is a little unexpected for a WithdrawDelegationRewards to return a non-valid coins value? I'm not sure if that behavior is desired?

That is, is it best practice to ensure no zero coins are included in coins such that len(coins) == 0 when coins.IsZero() == true? I guess based on the constructor sdk.NewCoins(...) removing zero coins maybe it should be? Or should modules generally always check for valid coins after method calls to modules?

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
@alexanderbez
Copy link
Contributor

I don't see how IsValid() is true in either case?

Assume actual rewards are zero. Then prior to my PR, you'd have {denom: "", amount: 0}, which is invalid. With your reversion, it's somehow valid?

In 0.46, you always have `{denom: "", amount: 0}, which is technically also not valid -- never will be since it's a zero amount.

@nddeluca
Copy link
Author

nddeluca commented Oct 19, 2022

This passes on v0.45.8, and the goal of this PR is to pass the same assertions.

amount, err := app.DistrKeeper.WithdrawDelegationRewards(ctx, sdk.AccAddress(valAddrs[0]), valAddrs[0])
require.NoError(t, err)
require.True(t, amount.IsZero())

require.Equal(t, "", amount.String()) // "0stake" on v0.45.9
require.Equal(t, len(amount), 0) // 1 on v0.45.9
require.True(t, amount.IsValid()) // False on v0.45.9

I believe the DecCoin#TruncateDecimal call at

finalRewards, remainder := rewards.TruncateDecimal()
drops the zero value and results in a sdk.Coins(nil) value for finalRewards, which is returned directly in v0.45.8.

Maybe that wasn't intended before or the change in v0.45.9 is outside the scope of what is considered a breaking change?

@alexanderbez
Copy link
Contributor

alexanderbez commented Oct 19, 2022

I agree that we should fix the event regression, but I want to note that all versions <= 0.45.8 are NOT valid. I.e. amount.String() == "" is not valid, it should be 0<denom>. So my approval stands for 0.45.x, just pointing this out :)

@nddeluca
Copy link
Author

Thank you @alexanderbez, completely agree -- this should only target v0.45.x

@alexanderbez alexanderbez merged commit 1596edf into cosmos:release/v0.45.x Oct 20, 2022
SpicyLemon added a commit to provenance-io/cosmos-sdk that referenced this pull request Oct 24, 2022
* fix: move ics23 to correct folder (cosmos#13549)

* fix: fix liveness tests cosmos#13551

* feat: add `GenSignedMockTx` (cosmos#13557)

* fix: fix `make proto-gen` (cosmos#13564)

* fix: fix `make proto-gen`

* add changelog

* feat: [REDO] gRPC query for operator and chain configuration (backport cosmos#13485) (cosmos#13589)

* chore: bump tendermint to `0.34.22` (cosmos#13585)

* fix: (v0.45.x) regression in return value of WithdrawDelegationRewards when rewards are zero (cosmos#13588)

* fix(server): v0.45.x Populate the PruningKeepEvery config entry in GetConfig. (cosmos#13610)

* Populate the PruningKeepEvery config entry in GetConfig.

* Update changlog.

* feat(cli): add module-account cli cmd and grpc get api (backport cosmos#13612) (cosmos#13617)

* feat(cli): add module-account cli cmd and grpc get api (cosmos#13612)

(cherry picked from commit ddf5cf0)

# Conflicts:
#	CHANGELOG.md
#	api/cosmos/auth/v1beta1/query.pulsar.go
#	api/cosmos/auth/v1beta1/query_grpc.pb.go
#	proto/cosmos/auth/v1beta1/query.proto
#	tests/e2e/auth/suite.go
#	x/auth/client/cli/query.go
#	x/auth/keeper/grpc_query.go
#	x/auth/keeper/grpc_query_test.go
#	x/auth/types/query.pb.go
#	x/auth/types/query.pb.gw.go

* update changelog

* fix conflicts

Co-authored-by: Sai Kumar <17549398+gsk967@users.noreply.github.com>
Co-authored-by: Julien Robert <julien@rbrt.fr>

* chore: prepare 0.45.10 changelog (cosmos#13624)

* chore: prepare 0.45.10 changelog

* default release notes

* period

* Add missing changelog section for v0.45.9-pio-1.

* Remove the old release notes.

* Remove accidentally duplicated section for v0.45.4.

* Add new v0.45.10-pio-1 section to the changelog and update the release notes to reflect our stuff.

* Include a 'nothing' under unreleased.

* Add links to changlog entries.

Co-authored-by: Aaron Craelius <aaron@regen.network>
Co-authored-by: Dev Ojha <ValarDragon@users.noreply.github.com>
Co-authored-by: Julien Robert <julien@rbrt.fr>
Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: Sai Kumar <17549398+gsk967@users.noreply.github.com>
jaybxyz pushed a commit to cosmosquad-labs/cosmos-sdk that referenced this pull request Nov 1, 2022
nnkken pushed a commit to likecoin/cosmos-sdk that referenced this pull request Nov 16, 2022
JeancarloBarrios pushed a commit to agoric-labs/cosmos-sdk that referenced this pull request Sep 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C:x/distribution distribution module related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants