Commit 949a4736 authored by David Vorick's avatar David Vorick

add Uint64() method to types.Currency

A future commit makes use of this function call. An error is returned if
there is an overflow. Though a panic could have been called, it is
believed that this method will be used heavily on currencies that could
potentially be manipulated by untrusted input. Rather than require that
all untrusted input be handled to check for currency-overflow causing
problems, and error is returned by the currency type.
parent 1f0440a4
......@@ -159,6 +159,18 @@ func (x Currency) Sub(y Currency) (c Currency) {
return
}
// Uint64 converts a Currency to a uint64. An error is returned because this
// function is sometimes called on values that can be determined by users -
// rather than have all user-facing points do input checking, the input
// checking should happen at the base type. This minimizes the chances of a
// rogue user causing a build.Critical to be triggered.
func (c Currency) Uint64() (u uint64, err error) {
if c.Cmp(NewCurrency64(math.MaxUint64)) > 0 {
return 0, ErrUint64Overflow
}
return uint64(c.Big().Int64()), nil
}
// MarshalJSON implements the json.Marshaler interface.
func (c Currency) MarshalJSON() ([]byte, error) {
// Must enclosed the value in quotes; otherwise JS will convert it to a
......
......@@ -3,6 +3,7 @@ package types
import (
"bytes"
"fmt"
"math"
"math/big"
"testing"
......@@ -298,3 +299,30 @@ func TestNegativeNewCurrency(t *testing.T) {
negBig := big.NewInt(-1)
_ = NewCurrency(negBig)
}
// TestCurrencyUint64 tests that a currency is correctly converted to a uint64.
func TestCurrencyUint64(t *testing.T) {
// Try a set of valid values.
attempts := []uint64{0, 1, 2, 3, 4, 25e3, math.MaxUint64}
for _, attempt := range attempts {
c := NewCurrency64(attempt)
result, err := c.Uint64()
if err != nil {
t.Error(err)
}
if attempt != result {
t.Error("uint64 conversion failed")
}
}
// Try an overflow.
c := NewCurrency64(math.MaxUint64)
c = c.Mul(NewCurrency64(2))
result, err := c.Uint64()
if err != ErrUint64Overflow {
t.Error(err)
}
if result != 0 {
t.Error("result is not being zeroed in the event of an error")
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment