From 471b7b2f16dc97e57e1b7d317291bb1345c5e1d3 Mon Sep 17 00:00:00 2001 From: coderofstuff <114628839+coderofstuff@users.noreply.github.com> Date: Fri, 22 Sep 2023 08:45:26 -0600 Subject: [PATCH] Fix off by small amounts in sent amount kaspa Floating point math causes inconsistencies when converting kas to sompi. Use a method that parses the amount as a string, the converts it to sompi then parse back to uint64 --- cmd/kaspawallet/send.go | 16 ++++++++++++++-- cmd/kaspawallet/send_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 cmd/kaspawallet/send_test.go diff --git a/cmd/kaspawallet/send.go b/cmd/kaspawallet/send.go index 3e20c2b97..71d6fdb24 100644 --- a/cmd/kaspawallet/send.go +++ b/cmd/kaspawallet/send.go @@ -4,13 +4,13 @@ import ( "context" "fmt" "os" + "strconv" "strings" "github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/client" "github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb" "github.com/kaspanet/kaspad/cmd/kaspawallet/keys" "github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet" - "github.com/kaspanet/kaspad/domain/consensus/utils/constants" "github.com/pkg/errors" ) @@ -35,7 +35,7 @@ func send(conf *sendConfig) error { var sendAmountSompi uint64 if !conf.IsSendAll { - sendAmountSompi = uint64(conf.SendAmount * constants.SompiPerKaspa) + sendAmountSompi = kasToSompi(conf.SendAmount) } createUnsignedTransactionsResponse, err := @@ -99,3 +99,15 @@ func send(conf *sendConfig) error { return nil } + +/** + */ +func kasToSompi(amount float64) uint64 { + amountInStr := fmt.Sprintf("%.8f", amount) + + parts := strings.Split(amountInStr, ".") + + convertedAmount, _ := strconv.ParseUint(strings.Join(parts, ""), 10, 64) + + return convertedAmount +} diff --git a/cmd/kaspawallet/send_test.go b/cmd/kaspawallet/send_test.go new file mode 100644 index 000000000..dcd04b4e0 --- /dev/null +++ b/cmd/kaspawallet/send_test.go @@ -0,0 +1,25 @@ +package main + +import "testing" + +func TestKasToSompi(t *testing.T) { + type testVector struct { + originalAmount float64 + convertedAmount uint64 + } + + testVectors := []testVector{ + {originalAmount: 0, convertedAmount: 0}, + {originalAmount: 1, convertedAmount: 100000000}, + {originalAmount: 33184.1489732, convertedAmount: 3318414897320}, + {originalAmount: 21.35808032, convertedAmount: 2135808032}, + {originalAmount: 184467440737.09551615, convertedAmount: 18446744073709551615}, + } + + for _, currentTestVector := range testVectors { + if kasToSompi(currentTestVector.originalAmount) != currentTestVector.convertedAmount { + t.Fail() + t.Logf("Expected %.8f, to convert to %d. Got: %d", currentTestVector.originalAmount, currentTestVector.convertedAmount, kasToSompi(currentTestVector.originalAmount)) + } + } +}