From 332941f9b6823a35820b2e4fe9b2c6e025af492a Mon Sep 17 00:00:00 2001 From: Adam Bozanich Date: Tue, 31 Jul 2018 00:30:05 -0700 Subject: [PATCH] pricing: allow micro suffixes, scientific notation --- _docs/deployment.yml | 12 +++--- _docs/sdl.md | 16 ++++++-- _run/kube/deployment.yml | 2 +- _run/multi/deployment.yml | 2 +- denom/denom.go | 30 ++++++++++++-- denom/denom_test.go | 44 +++++++++++++++++++++ sdl/_testdata/profile-svc-name-mismatch.yml | 2 +- sdl/_testdata/simple.yml | 2 +- 8 files changed, 93 insertions(+), 17 deletions(-) create mode 100644 denom/denom_test.go diff --git a/_docs/deployment.yml b/_docs/deployment.yml index e9cf7551a4..366cb9f1ba 100644 --- a/_docs/deployment.yml +++ b/_docs/deployment.yml @@ -74,16 +74,16 @@ profiles: attributes: region: us-west pricing: - web: 0.000010 - db: 0.000050 - db-pool: 0.000030 + web: 10u + db: 50u + db-pool: 30u eastcoast: attributes: region: us-east pricing: - web: 0.000030 - db: 0.000060 - db-pool: 0.000040 + web: 30u + db: 60u + db-pool: 40u deployment: diff --git a/_docs/sdl.md b/_docs/sdl.md index e5257aebb7..cc1c2854bb 100644 --- a/_docs/sdl.md +++ b/_docs/sdl.md @@ -143,12 +143,22 @@ westcoast: attributes: region: us-west pricing: - web: 8 - db: 15 + web: 8u + db: 100u ``` This defines a profile named `westcoast` having required attributes `{region="us-west"}`, and with a max price for -the `web` and `db` [compute profiles](#profilescompute) of 8 and 15 tokens an hour, respectively. +the `web` and `db` [compute profiles](#profilescompute) of 8 and 15 _micro_ (10^-6) tokens per block, respectively. + +Pricing may be expressed in decimal or scientific notation for Akash units, or may be suffixed with `mu`,`µ`, or `u` to represent _micro_ Akash. + +Examples: + +| Value | Micro Akash Tokens | +| --- | --- | +| `1` | 1000000 | +| `1e-4` | 100 | +| `20u` | 20 | ### deployment diff --git a/_run/kube/deployment.yml b/_run/kube/deployment.yml index 338c5ec092..0ccaebf7ce 100644 --- a/_run/kube/deployment.yml +++ b/_run/kube/deployment.yml @@ -24,7 +24,7 @@ profiles: attributes: region: us-west pricing: - web: .002000 + web: 2e-3 deployment: web: diff --git a/_run/multi/deployment.yml b/_run/multi/deployment.yml index 3545886e27..5fae235d8e 100644 --- a/_run/multi/deployment.yml +++ b/_run/multi/deployment.yml @@ -24,7 +24,7 @@ profiles: attributes: region: us-west pricing: - web: .000100 + web: 100u deployment: web: diff --git a/denom/denom.go b/denom/denom.go index 7f30fad1ca..867d618757 100644 --- a/denom/denom.go +++ b/denom/denom.go @@ -1,19 +1,41 @@ package denom import ( + "math/big" "strconv" + "strings" ) const ( - microAkashPerAkash = 1000000 + Mega = 1000000 +) + +var ( + microSuffixes = []string{ + "mu", + "µ", + "u", + } ) // ToBase converts a unit of currency to its equivalent value in base denomination func ToBase(sval string) (uint64, error) { - akash, err := strconv.ParseFloat(sval, 64) + + for _, suffix := range microSuffixes { + if !strings.HasSuffix(sval, suffix) { + continue + } + return strconv.ParseUint(strings.TrimSuffix(sval, suffix), 10, 64) + } + + fval, _, err := big.ParseFloat(sval, 10, 64, big.ToNearestAway) if err != nil { return 0, err } - amount := akash * microAkashPerAkash - return uint64(amount), nil + + mval := new(big.Float). + Mul(fval, new(big.Float).SetUint64(Mega)) + + val, _ := mval.Uint64() + return val, nil } diff --git a/denom/denom_test.go b/denom/denom_test.go new file mode 100644 index 0000000000..e8205f4a41 --- /dev/null +++ b/denom/denom_test.go @@ -0,0 +1,44 @@ +package denom_test + +import ( + "testing" + + "github.com/ovrclk/akash/denom" + "github.com/stretchr/testify/assert" +) + +func TestToBase(t *testing.T) { + + tests := []struct { + sval string + val uint64 + ok bool + }{ + {"1", 1 * denom.Mega, true}, + {"100", 100 * denom.Mega, true}, + {"0.000001", 1, true}, + {"0.000100", 100, true}, + {"1.000001", denom.Mega + 1, true}, + {"0.0000001", 0, true}, + {"1e-6", 1, true}, + {"3e2", 300 * denom.Mega, true}, + + {"100u", 100, true}, + {"35µ", 35, true}, + {"200mu", 200, true}, + + {"0x100", 0, false}, + {"abcd", 0, false}, + {"u", 0, false}, + {"fu", 0, false}, + } + + for _, test := range tests { + val, err := denom.ToBase(test.sval) + if test.ok { + assert.Equal(t, test.val, val, test.sval) + continue + } + assert.Error(t, err, test.sval) + } +} diff --git a/sdl/_testdata/profile-svc-name-mismatch.yml b/sdl/_testdata/profile-svc-name-mismatch.yml index ce48c7960a..4bea660e4b 100644 --- a/sdl/_testdata/profile-svc-name-mismatch.yml +++ b/sdl/_testdata/profile-svc-name-mismatch.yml @@ -21,7 +21,7 @@ profiles: attributes: region: sjc pricing: - web: 0.000025 + web: 25u deployment: webapp: diff --git a/sdl/_testdata/simple.yml b/sdl/_testdata/simple.yml index aa2f6437bd..14ed8bfe99 100644 --- a/sdl/_testdata/simple.yml +++ b/sdl/_testdata/simple.yml @@ -22,7 +22,7 @@ profiles: attributes: region: us-west pricing: - web: 0.005000 + web: 5e-3 deployment: web: