Repository: trustwallet/blockatlas
Pull request #1110 (2020-05-19 20:00:23)

Fix DecimalToSatoshis for 0 input.
DecimalToSatoshis has a bug: for input "0", it trims the single 0 to "", and returns as a valid response.  Results in unparseable normalized TX in case of Solana, KIN, Cosmos.  See #1106 . 

Also solve a minor sporadic unit test, #1111 .

codecov[bot]: # [Codecov](https://codecov.io/gh/trustwallet/blockatlas/pull/1110?src=pr&el=h1) Report
> Merging [#1110](https://codecov.io/gh/trustwallet/blockatlas/pull/1110?src=pr&el=desc) into [master](https://codecov.io/gh/trustwallet/blockatlas/commit/7495506f457ca99737e94fa365a529443ff58128&el=desc) will **increase** coverage by `0%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/trustwallet/blockatlas/pull/1110/graphs/tree.svg?width=650&height=150&src=pr&token=jnrjoEQAqv)](https://codecov.io/gh/trustwallet/blockatlas/pull/1110?src=pr&el=tree)

```diff
@@          Coverage Diff           @@
##           master   #1110   +/-   ##
======================================
  Coverage      38%     38%           
======================================
  Files         156     156           
  Lines        5387    5388    +1     
======================================
+ Hits         2064    2067    +3     
+ Misses       3189    3188    -1     
+ Partials      134     133    -1     
```


| [Impacted Files](https://codecov.io/gh/trustwallet/blockatlas/pull/1110?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pkg/numbers/decimal.go](https://codecov.io/gh/trustwallet/blockatlas/pull/1110/diff?src=pr&el=tree#diff-cGtnL251bWJlcnMvZGVjaW1hbC5nbw==) | `89% <100%> (+4%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/trustwallet/blockatlas/pull/1110?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/trustwallet/blockatlas/pull/1110?src=pr&el=footer). Last update [7495506...c458570](https://codecov.io/gh/trustwallet/blockatlas/pull/1110?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/pkg/numbers/decimal.go b/pkg/numbers/decimal.go
index 667470a..72e40ef 100644
--- a/pkg/numbers/decimal.go
+++ b/pkg/numbers/decimal.go
@@ -11,8 +11,16 @@ import (
 // "12.345" => "12345"
 // "0.0230" => "230"
 func DecimalToSatoshis(dec string) (string, error) {
-	out := strings.Replace(dec, ".", "", 1)
-	out = strings.TrimLeft(out, "0")
+	out := strings.TrimLeft(dec, " ")
+	out = strings.TrimRight(out, " ")
+	out = strings.Replace(out, ".", "", 1)
+	// trim left 0's but keep last
+	if l := len(out); l >= 2 {
+		out = strings.TrimLeft(out[:l-1], "0") + out[l-1:l]
+	}
+	if len(out) == 0 {
+		return "", errors.E("Invalid empty input", errors.Params{"dec": dec, "dec_trimmed": out})
+	}
 	for _, c := range out {
 		if !unicode.IsNumber(c) {
 			return "", errors.E("not a number", errors.Params{"dec": dec, "c": c})
diff --git a/platform/cosmos/transaction.go b/platform/cosmos/transaction.go
index 5a08c1f..3de7d5f 100644
--- a/platform/cosmos/transaction.go
+++ b/platform/cosmos/transaction.go
@@ -146,9 +146,13 @@ func (p *Platform) fillTransfer(tx *blockatlas.Tx, transfer MessageValueTransfer
 }
 
 func (p *Platform) fillDelegate(tx *blockatlas.Tx, delegate MessageValueDelegate, events Events, msgType TxType) {
-	value, err := numbers.DecimalToSatoshis(delegate.Amount.Quantity)
-	if err != nil {
-		return
+	value := ""
+	if len(delegate.Amount.Quantity) > 0 {
+		var err error
+		value, err = numbers.DecimalToSatoshis(delegate.Amount.Quantity)
+		if err != nil {
+			return
+		}
 	}
 	tx.From = delegate.DelegatorAddr
 	tx.To = delegate.ValidatorAddr


Test patch:
diff --git a/pkg/numbers/amount_test.go b/pkg/numbers/amount_test.go
index 5b95462..8db856b 100644
--- a/pkg/numbers/amount_test.go
+++ b/pkg/numbers/amount_test.go
@@ -33,7 +33,7 @@ func Test_addAmount(t *testing.T) {
 	}
 }
 
-func Test_decimalToSatoshis(t *testing.T) {
+func Test_ToSatoshi(t *testing.T) {
 	tests := []struct {
 		name   string
 		amount string
@@ -47,7 +47,7 @@ func Test_decimalToSatoshis(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			if got := ToSatoshi(tt.amount); got != tt.want {
-				t.Errorf("decimalToSatoshis() = %v, want %v", got, tt.want)
+				t.Errorf("ToSatoshi() = %v, want %v", got, tt.want)
 			}
 		})
 	}
diff --git a/pkg/numbers/decimal_test.go b/pkg/numbers/decimal_test.go
index 2cfcc29..89c3c37 100644
--- a/pkg/numbers/decimal_test.go
+++ b/pkg/numbers/decimal_test.go
@@ -9,14 +9,35 @@ func TestDecimalToSatoshis(t *testing.T) {
 			t.Error(err)
 		}
 		if expected != actual {
-			t.Errorf("expected: %s, got %s", expected, actual)
+			t.Errorf("expected %s, got %s, input %s", expected, actual, input)
+		}
+	}
+
+	assertSatError := func(input string) {
+		actual, err := DecimalToSatoshis(input)
+		if err == nil {
+			t.Errorf("Expected error but no error: got %s, input %s", actual, input)
 		}
 	}
 
 	assertSatEquals("10", "1.0")
 	assertSatEquals("1", "0.1")
 	assertSatEquals("13602", "136.02")
+	assertSatEquals("13602", "0136.02")
 	assertSatEquals("1500000", "0.01500000")
+	assertSatEquals("0", "0")
+	assertSatEquals("2030", "0.002030")
+	assertSatEquals("101010", "0101010")
+	assertSatEquals("11001100", "0011001100")
+	assertSatEquals("376", " 376")
+	assertSatEquals("376", "376 ")
+	
+	assertSatError("12NotNumber34")
+	assertSatError("12,34")
+	assertSatError("")
+	assertSatError(" ")
+	assertSatError("37 6")
+	assertSatError("37,6")
 }
 
 func TestDecimalExp(t *testing.T) {
diff --git a/platform/nimiq/transaction_test.go b/platform/nimiq/transaction_test.go
index 8c0a5f0..f936434 100644
--- a/platform/nimiq/transaction_test.go
+++ b/platform/nimiq/transaction_test.go
@@ -6,6 +6,7 @@ import (
 	"github.com/trustwallet/blockatlas/coin"
 	"github.com/trustwallet/blockatlas/pkg/blockatlas"
 	"io/ioutil"
+	"math"
 	"path/filepath"
 	"runtime"
 	"sort"
@@ -68,7 +69,7 @@ var (
 		From:  "NQ74 SJ0Q 49T1 4XQL KABH 1RUC 8DPT 9F0U 9P0B",
 		To:    "NQ97 18BJ 33YV QGHQ BV2K 56V4 12CH J8TD S9S3",
 		Fee:   "300",
-		Date:  time.Now().Unix(),
+		Date:  666666, // special placholder value
 		Block: 0,
 		Meta: blockatlas.Transfer{
 			Value:    "100000",
@@ -79,6 +80,7 @@ var (
 )
 
 func TestNormalizeTx1(t *testing.T) {
+	now := time.Now().Unix()
 	tests := []struct {
 		name  string
 		srcTx string
@@ -96,6 +98,10 @@ func TestNormalizeTx1(t *testing.T) {
 				return
 			}
 			got := NormalizeTx(&srcTx)
+			// special handling for current date, if around now, replace with special value
+			if math.Abs(float64(got.Date - now)) < 30 {
+				got.Date = 666666
+			}
 			assert.Equal(t, tt.want, got)
 		})
 	}