fix: Format decimals correctly for signmode textual (#15129)
Co-authored-by: Amaury <1293565+amaurym@users.noreply.github.com>
This commit is contained in:
parent
caf94106cb
commit
74ff94fdd5
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
68
x/tx/textual/internal/testdata/decimals.json
vendored
68
x/tx/textual/internal/testdata/decimals.json
vendored
@ -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"]
|
||||
]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user