Skip to content

Commit

Permalink
fix cost math; clean up naming
Browse files Browse the repository at this point in the history
  • Loading branch information
jmank88 committed Apr 30, 2019
1 parent b5bb611 commit 48f6b37
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 21 deletions.
33 changes: 16 additions & 17 deletions cmd/gofs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ func main() {
Usage: "Pin a CID",
Flags: []cli.Flag{
cli.Uint64Flag{
Name: "duration, d",
Usage: "Storage duration in hours.",
Name: "gbh",
Usage: "Storage to purchase in GigaByteHours.",
},
cli.StringFlag{
Name: "private-key, pk",
Expand All @@ -93,9 +93,9 @@ func main() {
if cid == "" {
return errors.New("missing CID")
}
dur := c.Uint64("duration")
if dur == 0 {
return fmt.Errorf("duration missing or invalid")
gbh := c.Uint64("gbh")
if gbh == 0 {
return fmt.Errorf("gbh missing or invalid")
}
contract, err := parseAddress(contract)
if err != nil {
Expand All @@ -106,7 +106,7 @@ func main() {
if err != nil {
return fmt.Errorf("invalid private key %q: %v", pkStr, err)
}
return Pin(ctx, rpc, contract, pk, cid, dur)
return Pin(ctx, rpc, contract, pk, cid, gbh)
},
},
{
Expand Down Expand Up @@ -141,18 +141,18 @@ func main() {
return fmt.Errorf("duration missing or invalid")
}
sizeStr := c.String("size")
size, err := units.ParseBase2Bytes(sizeStr)
bytes, err := units.ParseBase2Bytes(sizeStr)
if err != nil {
return fmt.Errorf("invalid size %q: %v", sizeStr, err)
}
if size == 0 {
if bytes == 0 {
return fmt.Errorf("size must be greater than 0")
}
contract, err := parseAddress(contract)
if err != nil {
return fmt.Errorf("invalid contract: %v", err)
}
return Cost(ctx, rpc, contract, int64(size), dur)
return Cost(ctx, rpc, contract, int64(bytes), dur)
},
},
{
Expand Down Expand Up @@ -270,16 +270,16 @@ func parseAddress(addr string) (common.Address, error) {
return common.HexToAddress(addr), nil
}

func Pin(ctx context.Context, rpcURL string, contract common.Address, pk *ecdsa.PrivateKey, ci string, dur uint64) error {
h, r, err := gofs.Pin(ctx, rpcURL, contract, pk, ci, dur)
func Pin(ctx context.Context, rpcURL string, contract common.Address, pk *ecdsa.PrivateKey, ci string, gbh uint64) error {
h, r, err := gofs.Pin(ctx, rpcURL, contract, pk, ci, gbh)
if err != nil {
return fmt.Errorf("failed to pin: %v", err)
}
switch r.Status {
case types.ReceiptStatusFailed:
return fmt.Errorf("tx %s failed", h.Hex())
case types.ReceiptStatusSuccessful:
fmt.Printf("Purchased %d GigaByteHours of storage for %s.\n", dur, ci)
fmt.Printf("Purchased %d GigaByteHours of storage for %s.\n", gbh, ci)
fmt.Printf("https://testnet-explorer.gochain.io/tx/%s\n", h.Hex())
return nil
default:
Expand All @@ -299,13 +299,13 @@ func Add(ctx context.Context, apiURL, path string) error {
return nil
}

func Cost(ctx context.Context, rpcURL string, contract common.Address, size, hrs int64) error {
_, cost, err := gofs.Cost(ctx, rpcURL, contract, size, hrs)
func Cost(ctx context.Context, rpcURL string, contract common.Address, bytes, hrs int64) error {
_, cost, err := gofs.Cost(ctx, rpcURL, contract, bytes, hrs)
if err != nil {
return err
}

fmt.Println(costStr(size, hrs, cost))
fmt.Println(costStr(bytes, hrs, cost))

return nil
}
Expand Down Expand Up @@ -362,8 +362,7 @@ func Rate(ctx context.Context, rpcURL string, contract common.Address) error {
{bytes: 10 * units.GiB, hrs: 24 * 7 * 52},
{bytes: units.Tebibyte, hrs: 24 * 7 * 52},
} {
gbh := big.NewInt(int64(vals.bytes) * vals.hrs)
cost := new(big.Int).Mul(gbh, rate)
cost := gofs.ComputeCost(rate, int64(vals.bytes), vals.hrs)

fmt.Println("\t", costStr(int64(vals.bytes), vals.hrs, cost))
}
Expand Down
16 changes: 12 additions & 4 deletions gofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"strings"
"time"

"github.com/alecthomas/units"
"github.com/gochain-io/gochain/v3"
"github.com/gochain-io/gochain/v3/accounts/abi"
"github.com/gochain-io/gochain/v3/accounts/abi/bind"
Expand Down Expand Up @@ -48,6 +49,14 @@ func Rate(ctx context.Context, rpcURL string, contract common.Address) (*big.Int
return p.Rate(&bind.CallOpts{Context: ctx})
}

func ComputeCost(rate *big.Int, bytes, hrs int64) *big.Int {
gbh := big.NewRat(bytes*hrs, int64(units.GiB))
rat := new(big.Rat).Mul(gbh, new(big.Rat).SetInt(rate))
// This is gross but there doesn't appear to be a way to go from big.Rat to big.Int directly, and we need the Rat precision.
c, _ := new(big.Int).SetString(rat.FloatString(0), 10)
return c
}

// Cost calculates the storage cost at the current rate.
func Cost(ctx context.Context, rpcURL string, contract common.Address, bytes, hrs int64) (rate *big.Int, cost *big.Int, err error) {
gc, err := goclient.Dial(rpcURL)
Expand All @@ -62,8 +71,7 @@ func Cost(ctx context.Context, rpcURL string, contract common.Address, bytes, hr
if err != nil {
return
}
gbhs := bytes * hrs
cost = new(big.Int).Mul(rate, big.NewInt(int64(gbhs)))
cost = ComputeCost(rate, bytes, hrs)
return
}

Expand All @@ -87,7 +95,7 @@ func AddFile(ctx context.Context, apiURL, path string) (AddResponse, error) {
return NewClient(apiURL).Add(ctx, f)
}

func Pin(ctx context.Context, rpcURL string, contract common.Address, pk *ecdsa.PrivateKey, ci string, dur uint64) (common.Hash, *types.Receipt, error) {
func Pin(ctx context.Context, rpcURL string, contract common.Address, pk *ecdsa.PrivateKey, ci string, gbh uint64) (common.Hash, *types.Receipt, error) {
cid, err := cid.Parse(ci)
if err != nil {
return common.Hash{}, nil, fmt.Errorf("invalid cid %q: %v", ci, err)
Expand All @@ -107,7 +115,7 @@ func Pin(ctx context.Context, rpcURL string, contract common.Address, pk *ecdsa.
if err != nil {
return common.Hash{}, nil, err
}
cost := new(big.Int).Mul(rate, big.NewInt(int64(dur)))
cost := new(big.Int).Mul(rate, big.NewInt(int64(gbh)))
opts := &bind.TransactOpts{
Context: ctx,
From: crypto.PubkeyToAddress(pk.PublicKey),
Expand Down

0 comments on commit 48f6b37

Please sign in to comment.