diff --git a/math/CHANGELOG.md b/math/CHANGELOG.md index 43e36e120b..3d97302b88 100644 --- a/math/CHANGELOG.md +++ b/math/CHANGELOG.md @@ -34,6 +34,12 @@ Ref: https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.j # Changelog +## [Unreleased] + +### Bug Fixes + +* [#15506](https://github.com/cosmos/cosmos-sdk/issues/16605) fix: Dec marshal shouldn't have side effects + ## [math/v1.0.0-rc.0](https://github.com/cosmos/cosmos-sdk/releases/tag/math/v1.0.0-rc.0) - 2023-03-13 ### Features @@ -43,6 +49,7 @@ Ref: https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.j ### Bug Fixes * [#14922](https://github.com/cosmos/cosmos-sdk/issues/14922) check for negative precision +* [#15506](https://github.com/cosmos/cosmos-sdk/issues/16605) fix: Dec marshal shouldn't have side effects ### Testing diff --git a/math/dec.go b/math/dec.go index 844b3039af..8875dfdd70 100644 --- a/math/dec.go +++ b/math/dec.go @@ -799,19 +799,21 @@ func (d LegacyDec) MarshalYAML() (interface{}, error) { // Marshal implements the gogo proto custom type interface. func (d LegacyDec) Marshal() ([]byte, error) { - if d.i == nil { - d.i = new(big.Int) + i := d.i + if i == nil { + i = new(big.Int) } - return d.i.MarshalText() + return i.MarshalText() } // MarshalTo implements the gogo proto custom type interface. func (d *LegacyDec) MarshalTo(data []byte) (n int, err error) { - if d.i == nil { - d.i = new(big.Int) + i := d.i + if i == nil { + i = new(big.Int) } - if d.i.Cmp(zeroInt) == 0 { + if i.Cmp(zeroInt) == 0 { copy(data, []byte{0x30}) return 1, nil } diff --git a/tests/integration/aminojson/aminojson_test.go b/tests/integration/aminojson/aminojson_test.go index ad8168a0fe..0a2abe15f3 100644 --- a/tests/integration/aminojson/aminojson_test.go +++ b/tests/integration/aminojson/aminojson_test.go @@ -665,6 +665,26 @@ func TestSendAuthorization(t *testing.T) { require.Equal(t, string(legacyAminoJson), string(aminoJson)) } +func TestDecimalMutation(t *testing.T) { + encCfg := testutil.MakeTestEncodingConfig(staking.AppModuleBasic{}) + rates := &stakingtypes.CommissionRates{} + rateBz, _ := encCfg.Amino.MarshalJSON(rates) + require.Equal(t, `{"rate":"0","max_rate":"0","max_change_rate":"0"}`, string(rateBz)) + _, err := gogoproto.Marshal(rates) + require.NoError(t, err) + rateBz, _ = encCfg.Amino.MarshalJSON(rates) + + // these assertions show behavior prior to the merge of https://github.com/cosmos/cosmos-sdk/pull/15506 + // and should be updated to reflect the new behavior once a release of math is made and updated in ./tests/go.mod + require.NotEqual(t, `{"rate":"0","max_rate":"0","max_change_rate":"0"}`, string(rateBz)) + require.Equal(t, + `{"rate":"0.000000000000000000","max_rate":"0.000000000000000000","max_change_rate":"0.000000000000000000"}`, + string(rateBz)) + + // new behavior + //require.Equal(t, `{"rate":"0","max_rate":"0","max_change_rate":"0"}`, string(rateBz)) +} + func postFixPulsarMessage(msg proto.Message) { switch m := msg.(type) { case *authapi.ModuleAccount: