Skip to content
This repository has been archived by the owner on Nov 2, 2018. It is now read-only.

Commit

Permalink
Merge pull request #777 from bitspill/hostconfig
Browse files Browse the repository at this point in the history
Add support for convenient sizes "100GB", "100GiB", etc
  • Loading branch information
lukechampine committed Sep 11, 2015
2 parents eb8c96a + f170c51 commit d287aa7
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 34 deletions.
6 changes: 3 additions & 3 deletions Makefile
Expand Up @@ -63,9 +63,9 @@ clean:
# 'test-long' runs more thorough tests which should not last more than a few
# minutes.
pkgs = ./api ./compatibility ./crypto ./encoding ./modules ./modules/consensus \
./modules/explorer ./modules/gateway ./modules/host ./modules/hostdb \
./modules/miner ./modules/renter ./modules/transactionpool \
./modules/wallet ./persist ./siae ./types
./modules/explorer ./modules/gateway ./modules/host ./modules/hostdb \
./modules/miner ./modules/renter ./modules/transactionpool \
./modules/wallet ./persist ./siac ./siae ./types
test: clean fmt REBUILD
go test -short -tags='debug testing' -timeout=10s $(pkgs)
test-v: clean fmt REBUILD
Expand Down
8 changes: 8 additions & 0 deletions siac/hostcmd.go
Expand Up @@ -62,6 +62,14 @@ func hostconfigcmd(param, value string) {
p.Mul(p, big.NewRat(1e24/1e9, 4320))
value = new(big.Int).Div(p.Num(), p.Denom()).String()
}
// parse sizes of form 10GB, 10TB, 1TiB etc
if param == "totalstorage" || param == "minfilesize" || param == "maxfilesize" {
var err error // must be pre-declared because value is
value, err = parseSize(value)
if err != nil {
fmt.Println("could not parse " + param)
}
}
err := post("/host/configure", param+"="+value)
if err != nil {
fmt.Println("Could not update host settings:", err)
Expand Down
77 changes: 77 additions & 0 deletions siac/parse.go
@@ -0,0 +1,77 @@
package main

import (
"errors"
"fmt"
"math/big"
"strings"
)

var errUnableToParseSize = errors.New("unable to parse size")

// parseSize converts strings of form 10GB to a size in bytes. Fractional sizes
// are truncated at the byte size. If parsing fails an error is returned.
func parseSize(strSize string) (string, error) {
units := []struct {
suffix string
multiplier int64
}{
{"kb", 1e3},
{"mb", 1e6},
{"gb", 1e9},
{"tb", 1e12},
{"kib", 1 << 10},
{"mib", 1 << 20},
{"gib", 1 << 30},
{"tib", 1 << 40},
{"b", 1}, // must be after others else it'll match on them all
{"", 1}, // no suffix is still a valid suffix
}

strSize = strings.ToLower(strSize)
for _, unit := range units {
if strings.HasSuffix(strSize, unit.suffix) {
r, ok := new(big.Rat).SetString(strings.TrimSuffix(strSize, unit.suffix))
if !ok {
return "", errUnableToParseSize
}
r.Mul(r, new(big.Rat).SetInt(big.NewInt(unit.multiplier)))
if !r.IsInt() {
f, _ := r.Float64()
return fmt.Sprintf("%d", int64(f)), nil
}
return r.RatString(), nil
}
}

return "", errUnableToParseSize
}

// coinUnits converts a siacoin amount to base units.
func coinUnits(amount string) (string, error) {
units := []string{"pS", "nS", "uS", "mS", "SC", "KS", "MS", "GS", "TS"}
for i, unit := range units {
if strings.HasSuffix(amount, unit) {
// scan into big.Rat
r, ok := new(big.Rat).SetString(strings.TrimSuffix(amount, unit))
if !ok {
return "", errors.New("malformed amount")
}
// convert units
exp := 24 + 3*(int64(i)-4)
mag := new(big.Int).Exp(big.NewInt(10), big.NewInt(exp), nil)
r.Mul(r, new(big.Rat).SetInt(mag))
// r must be an integer at this point
if !r.IsInt() {
return "", errors.New("non-integer number of hastings")
}
return r.RatString(), nil
}
}
// check for hastings separately
if strings.HasSuffix(amount, "H") {
return strings.TrimSuffix(amount, "H"), nil
}

return "", errors.New("amount is missing units; run 'wallet --help' for a list of units")
}
41 changes: 41 additions & 0 deletions siac/parse_test.go
@@ -0,0 +1,41 @@
package main

import (
"fmt"
"testing"
)

func TestParseSize(t *testing.T) {
tests := []struct {
in, out string
err error
}{
{"1b", "1", nil},
{"1KB", "1000", nil},
{"1MB", "1000000", nil},
{"1GB", "1000000000", nil},
{"1TB", "1000000000000", nil},
{"1KiB", "1024", nil},
{"1MiB", "1048576", nil},
{"1GiB", "1073741824", nil},
{"1TiB", "1099511627776", nil},
{"", "", errUnableToParseSize},
{"123", "123", nil},
{"123TB", "123000000000000", nil},
{"123GiB", "132070244352", nil},
{"123BiB", "", errUnableToParseSize},
{"GB", "", errUnableToParseSize},
{"123G", "", errUnableToParseSize},
{"123B99", "", errUnableToParseSize},
{"12A3456", "", errUnableToParseSize},
{"1.23KB", "1230", nil},
{"1.234KB", "1234", nil},
{"1.2345KB", "1234", nil},
}
for _, test := range tests {
res, err := parseSize(test.in)
if res != test.out || err != test.err {
t.Error(fmt.Sprintf("parseSize(%v): expected %v %v, got %v %v", test.in, test.out, test.err, res, err))
}
}
}
31 changes: 0 additions & 31 deletions siac/walletcmd.go
@@ -1,10 +1,8 @@
package main

import (
"errors"
"fmt"
"math/big"
"strings"

"github.com/bgentry/speakeasy"
"github.com/spf13/cobra"
Expand All @@ -13,35 +11,6 @@ import (
"github.com/NebulousLabs/Sia/types"
)

// coinUnits converts a siacoin amount to base units.
func coinUnits(amount string) (string, error) {
units := []string{"pS", "nS", "uS", "mS", "SC", "KS", "MS", "GS", "TS"}
for i, unit := range units {
if strings.HasSuffix(amount, unit) {
// scan into big.Rat
r, ok := new(big.Rat).SetString(strings.TrimSuffix(amount, unit))
if !ok {
return "", errors.New("malformed amount")
}
// convert units
exp := 24 + 3*(int64(i)-4)
mag := new(big.Int).Exp(big.NewInt(10), big.NewInt(exp), nil)
r.Mul(r, new(big.Rat).SetInt(mag))
// r must be an integer at this point
if !r.IsInt() {
return "", errors.New("non-integer number of hastings")
}
return r.RatString(), nil
}
}
// check for hastings separately
if strings.HasSuffix(amount, "H") {
return strings.TrimSuffix(amount, "H"), nil
}

return "", errors.New("amount is missing units; run 'wallet --help' for a list of units")
}

var (
walletCmd = &cobra.Command{
Use: "wallet",
Expand Down

0 comments on commit d287aa7

Please sign in to comment.