Skip to content

Commit 13e784d

Browse files
committed
Fix cosmos#7640: tally calculation precision error
Solution: - change `(a / b) * c` to `a * b / c`
1 parent bd6c16b commit 13e784d

File tree

3 files changed

+18
-7
lines changed

3 files changed

+18
-7
lines changed

CHANGELOG.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
4040

4141
* (x/staking) [\#7499](https://github.com/cosmos/cosmos-sdk/pull/7499) `BondStatus` is now a protobuf `enum` instead of an `int32`, and JSON serialized using its protobuf name, so expect names like `BOND_STATUS_UNBONDING` as opposed to `Unbonding`.
4242
* (x/evidence) [\#7538](https://github.com/cosmos/cosmos-sdk/pull/7538) The ABCI's `Result.Data` field of `MsgSubmitEvidence` does not contain the raw evidence's hash, but the encoded `MsgSubmitEvidenceResponse` struct.
43-
* (x/upgrade) [#7697](https://github.com/cosmos/cosmos-sdk/pull/7697) Rename flag name "--time" to "--upgrade-time", "--info" to "--upgrade-info", to keep it consistent with help message.
43+
* (x/upgrade) [#7697](https://github.com/cosmos/cosmos-sdk/pull/7697) Rename flag name "--time" to "--upgrade-time", "--info" to "--upgrade-info", to keep it consistent with help message.
4444

4545
### API Breaking
4646

@@ -63,6 +63,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
6363

6464
* (kvstore) [\#7415](https://github.com/cosmos/cosmos-sdk/pull/7415) Allow new stores to be registered during on-chain upgrades.
6565
* (client) [\#7699](https://github.com/cosmos/cosmos-sdk/pull/7699) Fix panic in context when setting invalid nodeURI. `WithNodeURI` does not set the `Client` in the context.
66+
* (x/gov) [#7641](https://github.com/cosmos/cosmos-sdk/pull/7641) Fix tally calculation precision error.
6667

6768

6869
## [v0.40.0-rc0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.40.0-rc0) - 2020-10-13
@@ -653,6 +654,7 @@ generalized genesis accounts through the `GenesisAccount` interface.
653654
* (sdk) [\#4758](https://github.com/cosmos/cosmos-sdk/issues/4758) update `x/genaccounts` to match module spec
654655
* (simulation) [\#4824](https://github.com/cosmos/cosmos-sdk/issues/4824) `PrintAllInvariants` flag will print all failed invariants
655656
* (simulation) [\#4490](https://github.com/cosmos/cosmos-sdk/issues/4490) add `InitialBlockHeight` flag to resume a simulation from a given block
657+
656658
* Support exporting the simulation stats to a given JSON file
657659
* (simulation) [\#4847](https://github.com/cosmos/cosmos-sdk/issues/4847), [\#4838](https://github.com/cosmos/cosmos-sdk/pull/4838) and [\#4869](https://github.com/cosmos/cosmos-sdk/pull/4869) `SimApp` and simulation refactors:
658660
* Implement `SimulationManager` for executing modules' simulation functionalities in a modularized way
@@ -966,6 +968,7 @@ that error is that the account doesn't exist.
966968
* (simulation) PrintAllInvariants flag will print all failed invariants
967969
* (simulation) Add `InitialBlockHeight` flag to resume a simulation from a given block
968970
* (simulation) [\#4670](https://github.com/cosmos/cosmos-sdk/issues/4670) Update simulation statistics to JSON format
971+
969972
- Support exporting the simulation stats to a given JSON file
970973
* [\#4775](https://github.com/cosmos/cosmos-sdk/issues/4775) Refactor CI config
971974
* Upgrade IAVL to v0.12.4
@@ -1571,8 +1574,9 @@ BREAKING CHANGES
15711574
FEATURES
15721575

15731576
* Gaia REST API
1574-
* [\#2358](https://github.com/cosmos/cosmos-sdk/issues/2358) Add distribution module REST interface
1575-
1577+
1578+
* [\#2358](https://github.com/cosmos/cosmos-sdk/issues/2358) Add distribution module REST interface
1579+
15761580
* Gaia CLI (`gaiacli`)
15771581
* [\#3429](https://github.com/cosmos/cosmos-sdk/issues/3429) Support querying
15781582
for all delegator distribution rewards.

types/decimal_test.go

+8
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,14 @@ func (s *decimalTestSuite) TestDecEncoding() {
478478
}
479479
}
480480

481+
// Showcase that different orders of operations causes different results.
482+
func (s *decimalTestSuite) TestOperationOrders() {
483+
n1 := sdk.NewDec(10)
484+
n2 := sdk.NewDec(1000000010)
485+
s.Require().Equal(n1.Mul(n2).Quo(n2), sdk.NewDec(10))
486+
s.Require().NotEqual(n1.Mul(n2).Quo(n2), n1.Quo(n2).Mul(n2))
487+
}
488+
481489
func BenchmarkMarshalTo(b *testing.B) {
482490
bis := []struct {
483491
in sdk.Dec

x/gov/keeper/tally.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal types.Proposal) (passes boo
5757
val.DelegatorDeductions = val.DelegatorDeductions.Add(delegation.GetShares())
5858
currValidators[valAddrStr] = val
5959

60-
delegatorShare := delegation.GetShares().Quo(val.DelegatorShares)
61-
votingPower := delegatorShare.MulInt(val.BondedTokens)
60+
// delegation shares * bonded / total shares
61+
votingPower := delegation.GetShares().MulInt(val.BondedTokens).Quo(val.DelegatorShares)
6262

6363
results[vote.Option] = results[vote.Option].Add(votingPower)
6464
totalVotingPower = totalVotingPower.Add(votingPower)
@@ -78,8 +78,7 @@ func (keeper Keeper) Tally(ctx sdk.Context, proposal types.Proposal) (passes boo
7878
}
7979

8080
sharesAfterDeductions := val.DelegatorShares.Sub(val.DelegatorDeductions)
81-
fractionAfterDeductions := sharesAfterDeductions.Quo(val.DelegatorShares)
82-
votingPower := fractionAfterDeductions.MulInt(val.BondedTokens)
81+
votingPower := sharesAfterDeductions.MulInt(val.BondedTokens).Quo(val.DelegatorShares)
8382

8483
results[val.Vote] = results[val.Vote].Add(votingPower)
8584
totalVotingPower = totalVotingPower.Add(votingPower)

0 commit comments

Comments
 (0)