diff --git a/types/mempool/sender_nonce.go b/types/mempool/sender_nonce.go index c491387193..928d6319bd 100644 --- a/types/mempool/sender_nonce.go +++ b/types/mempool/sender_nonce.go @@ -37,7 +37,7 @@ type SenderNonceMempool struct { existingTx map[txKey]bool } -type SenderNonceOptions func(mp *SenderNonceMempool) +type SenderNonceOptions func(*SenderNonceMempool) type txKey struct { address string diff --git a/x/tx/textual/dec.go b/x/tx/textual/dec.go index 7639b60838..396d7ac6da 100644 --- a/x/tx/textual/dec.go +++ b/x/tx/textual/dec.go @@ -3,6 +3,7 @@ package textual import ( "context" "fmt" + "math/big" "strings" "google.golang.org/protobuf/reflect/protoreflect" @@ -21,7 +22,22 @@ type decValueRenderer struct{} var _ ValueRenderer = decValueRenderer{} func (vr decValueRenderer) Format(_ context.Context, v protoreflect.Value) ([]Screen, error) { - formatted, err := math.FormatDec(v.String()) + decStr := v.String() + + // If the decimal doesn't contain a point, we assume it's a value formatted using the legacy + // `sdk.Dec`. So we try to parse it as an integer and then convert it to a + // decimal. + if !strings.Contains(decStr, ".") { + parsedInt, ok := new(big.Int).SetString(decStr, 10) + if !ok { + return nil, fmt.Errorf("invalid decimal: %s", decStr) + } + + // We assume the decimal has 18 digits of precision. + decStr = math.LegacyNewDecFromBigIntWithPrec(parsedInt, math.LegacyPrecision).String() + } + + formatted, err := math.FormatDec(decStr) if err != nil { return nil, err } diff --git a/x/tx/textual/dec_test.go b/x/tx/textual/dec_test.go index 1bf3657520..3f76c71c32 100644 --- a/x/tx/textual/dec_test.go +++ b/x/tx/textual/dec_test.go @@ -1,13 +1,17 @@ package textual_test import ( + "context" "encoding/json" + "math/big" "os" + "strings" "testing" "github.com/stretchr/testify/require" "google.golang.org/protobuf/reflect/protoreflect" + "cosmossdk.io/math" "cosmossdk.io/x/tx/textual" ) @@ -27,7 +31,36 @@ func TestDecJsonTestcases(t *testing.T) { r, err := textual.GetFieldValueRenderer(fieldDescriptorFromName("SDKDEC")) require.NoError(t, err) - checkNumberTest(t, r, protoreflect.ValueOf(tc[0]), tc[1]) + checkDecTest(t, r, protoreflect.ValueOf(tc[0]), tc[1]) }) } } + +func checkDecTest(t *testing.T, r textual.ValueRenderer, pv protoreflect.Value, expected string) { + screens, err := r.Format(context.Background(), pv) + require.NoError(t, err) + require.Len(t, screens, 1) + require.Zero(t, screens[0].Indent) + require.False(t, screens[0].Expert) + + require.Equal(t, expected, screens[0].Content) + + // Round trip. + value, err := r.Parse(context.Background(), screens) + require.NoError(t, err) + + v1, err := math.LegacyNewDecFromStr(value.String()) + require.NoError(t, err) + + decStr := pv.String() + if !strings.Contains(decStr, ".") { + n, ok := new(big.Int).SetString(decStr, 10) + require.True(t, ok) + decStr = math.LegacyNewDecFromBigIntWithPrec(n, 18).String() + } + + v, err := math.LegacyNewDecFromStr(decStr) + require.NoError(t, err) + + require.Truef(t, v.Equal(v1), "%s != %s", v, v1) +} diff --git a/x/tx/textual/int_test.go b/x/tx/textual/int_test.go index 7b305221d7..5d9680b8c9 100644 --- a/x/tx/textual/int_test.go +++ b/x/tx/textual/int_test.go @@ -63,8 +63,8 @@ func checkNumberTest(t *testing.T, r textual.ValueRenderer, pv protoreflect.Valu screens, err := r.Format(context.Background(), pv) require.NoError(t, err) require.Len(t, screens, 1) - require.Equal(t, 0, screens[0].Indent) - require.Equal(t, false, screens[0].Expert) + require.Zero(t, screens[0].Indent) + require.False(t, screens[0].Expert) require.Equal(t, expected, screens[0].Content) @@ -78,5 +78,5 @@ func checkNumberTest(t *testing.T, r textual.ValueRenderer, pv protoreflect.Valu v1, err := math.LegacyNewDecFromStr(value.String()) require.NoError(t, err) - require.True(t, v.Equal(v1)) + require.Truef(t, v.Equal(v1), "%s != %s", v, v1) } diff --git a/x/tx/textual/internal/testdata/decimals.json b/x/tx/textual/internal/testdata/decimals.json index 3564b597d9..e3685316e7 100644 --- a/x/tx/textual/internal/testdata/decimals.json +++ b/x/tx/textual/internal/testdata/decimals.json @@ -1,9 +1,9 @@ [ - ["0", "0"], - ["1", "1"], - ["12", "12"], - ["123", "123"], - ["1234", "1'234"], + ["0.0", "0"], + ["1.0", "1"], + ["12.0", "12"], + ["123.0", "123"], + ["1234.0", "1'234"], ["0.1", "0.1"], ["0.01", "0.01"], ["0.001", "0.001"], @@ -41,7 +41,59 @@ ["0.000000000000000010", "0.00000000000000001"], ["0.000000000000000001", "0.000000000000000001"], ["-10.0", "-10"], - ["-10000", "-10'000"], - ["-9999", "-9'999"], - ["-999999999999", "-999'999'999'999"] + ["-10000.0", "-10'000"], + ["-9999.0", "-9'999"], + ["-999999999999.0", "-999'999'999'999"], + ["1000000000000000000000000", "1'000'000"], + ["1000000000000000000000000", "1'000'000"], + ["100000000000000000000000", "100'000"], + ["10000000000000000000000", "10'000"], + ["1000000000000000000000", "1'000"], + ["100000000000000000000", "100"], + ["10000000000000000000", "10"], + ["1000000000000000000", "1"], + ["100000000000000000", "0.1"], + ["10000000000000000", "0.01"], + ["1000000000000000", "0.001"], + ["100000000000000", "0.0001"], + ["10000000000000", "0.00001"], + ["1000000000000", "0.000001"], + ["100000000000", "0.0000001"], + ["10000000000", "0.00000001"], + ["1000000000", "0.000000001"], + ["100000000", "0.0000000001"], + ["10000000", "0.00000000001"], + ["1000000", "0.000000000001"], + ["100000", "0.0000000000001"], + ["10000", "0.00000000000001"], + ["1000", "0.000000000000001"], + ["100", "0.0000000000000001"], + ["10", "0.00000000000000001"], + ["1", "0.000000000000000001"], + ["-1000000000000000000000000", "-1'000'000"], + ["-1000000000000000000000000", "-1'000'000"], + ["-100000000000000000000000", "-100'000"], + ["-10000000000000000000000", "-10'000"], + ["-1000000000000000000000", "-1'000"], + ["-100000000000000000000", "-100"], + ["-10000000000000000000", "-10"], + ["-1000000000000000000", "-1"], + ["-100000000000000000", "-0.1"], + ["-10000000000000000", "-0.01"], + ["-1000000000000000", "-0.001"], + ["-100000000000000", "-0.0001"], + ["-10000000000000", "-0.00001"], + ["-1000000000000", "-0.000001"], + ["-100000000000", "-0.0000001"], + ["-10000000000", "-0.00000001"], + ["-1000000000", "-0.000000001"], + ["-100000000", "-0.0000000001"], + ["-10000000", "-0.00000000001"], + ["-1000000", "-0.000000000001"], + ["-100000", "-0.0000000000001"], + ["-10000", "-0.00000000000001"], + ["-1000", "-0.000000000000001"], + ["-100", "-0.0000000000000001"], + ["-10", "-0.00000000000000001"], + ["-1", "-0.000000000000000001"] ]