Skip to content

Commit

Permalink
unit change from GigaByteHours to ByteHours (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
jmank88 committed Jul 29, 2019
1 parent 48f6b37 commit 7201755
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 81 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ VERSION:

COMMANDS:
pin Pin a CID
rate Get the current storage rate in wei per GigaByteHour.
cost Get the current storage cost in wei for the given size and duration.
rate Get the current storage rate in atto GO per ByteHour.
cost Get the current storage cost in atto GO for the given size and duration.
add Add and pin a file.
status Get the current storage status for a CID.
receipts Query for receipts.
Expand Down
35 changes: 20 additions & 15 deletions cmd/gofs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func init() {
}
}

//TODO doc flags more
func main() {
// Interrupt cancellation.
ctx, cancelFn := context.WithCancel(context.Background())
Expand Down Expand Up @@ -79,8 +80,8 @@ func main() {
Usage: "Pin a CID",
Flags: []cli.Flag{
cli.Uint64Flag{
Name: "gbh",
Usage: "Storage to purchase in GigaByteHours.",
Name: "bh",
Usage: "Storage to purchase in ByteHours.",
},
cli.StringFlag{
Name: "private-key, pk",
Expand All @@ -93,9 +94,10 @@ func main() {
if cid == "" {
return errors.New("missing CID")
}
gbh := c.Uint64("gbh")
if gbh == 0 {
return fmt.Errorf("gbh missing or invalid")
//TODO or accept amount in go/wei
bh := c.Uint64("bh")
if bh == 0 {
return fmt.Errorf("bh missing or invalid")
}
contract, err := parseAddress(contract)
if err != nil {
Expand All @@ -106,12 +108,12 @@ func main() {
if err != nil {
return fmt.Errorf("invalid private key %q: %v", pkStr, err)
}
return Pin(ctx, rpc, contract, pk, cid, gbh)
return Pin(ctx, rpc, contract, pk, cid, bh)
},
},
{
Name: "rate",
Usage: "Get the current storage rate in wei per GigaByteHour.",
Usage: "Get the current storage rate in atto GO per ByteHour.",
Action: func(c *cli.Context) error {
contract, err := parseAddress(contract)
if err != nil {
Expand All @@ -122,7 +124,7 @@ func main() {
},
{
Name: "cost",
Usage: "Get the current storage cost in wei for the given size and duration.",
Usage: "Get the current storage cost in atto GO for the given size and duration.",
Flags: []cli.Flag{
cli.Uint64Flag{
Name: "duration, d",
Expand All @@ -136,6 +138,7 @@ func main() {
},
},
Action: func(c *cli.Context) error {
//TODO accept go duration
dur := c.Int64("duration")
if dur == 0 {
return fmt.Errorf("duration missing or invalid")
Expand All @@ -152,6 +155,7 @@ func main() {
if err != nil {
return fmt.Errorf("invalid contract: %v", err)
}
//TODO print BHs too
return Cost(ctx, rpc, contract, int64(bytes), dur)
},
},
Expand Down Expand Up @@ -270,16 +274,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, gbh uint64) error {
h, r, err := gofs.Pin(ctx, rpcURL, contract, pk, ci, gbh)
func Pin(ctx context.Context, rpcURL string, contract common.Address, pk *ecdsa.PrivateKey, ci string, bh uint64) error {
h, r, err := gofs.Pin(ctx, rpcURL, contract, pk, ci, bh)
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", gbh, ci)
fmt.Printf("Purchased %d ByteHours of storage for %s.\n", bh, ci)
fmt.Printf("https://testnet-explorer.gochain.io/tx/%s\n", h.Hex())
return nil
default:
Expand Down Expand Up @@ -346,7 +350,7 @@ func Rate(ctx context.Context, rpcURL string, contract common.Address) error {
return err
}
//TODO friendlier units?
fmt.Printf("Current storage rate: %d wei per GBHour.\n\n", rate)
fmt.Printf("Current storage rate: %d atto GO per ByteHour.\n\n", rate)

fmt.Println("Cost:")
for _, vals := range []struct {
Expand All @@ -362,7 +366,8 @@ 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},
} {
cost := gofs.ComputeCost(rate, int64(vals.bytes), vals.hrs)
bh := new(big.Int).Mul(big.NewInt(int64(vals.bytes)), big.NewInt(vals.hrs))
cost := bh.Mul(bh, rate)

fmt.Println("\t", costStr(int64(vals.bytes), vals.hrs, cost))
}
Expand Down Expand Up @@ -393,7 +398,7 @@ func Receipts(ctx context.Context, rpcURL string, contract common.Address, f gof
return err
}
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
fmt.Fprintln(w, "Block\tTx\tLog\tRemoved\tCID\tGBH\tUser\t")
fmt.Fprintln(w, "Block\tTx\tLog\tRemoved\tCID\tBH\tUser\t")
for _, r := range receipts {
fmt.Fprintf(w,
"%d\t%d\t%d\t%t\t%s\t%s\t%s\t\n",
Expand All @@ -402,7 +407,7 @@ func Receipts(ctx context.Context, rpcURL string, contract common.Address, f gof
r.LogNum,
r.Removed,
r.CID.String(),
r.GBH,
r.BH,
r.User.Hex(),
)
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/GOFSPinner.abi
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
},
{
"indexed": false,
"name": "gbh",
"name": "bh",
"type": "uint256"
}
],
Expand Down
2 changes: 1 addition & 1 deletion contracts/GOFSPinner.bin
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0x608060405234801561001057600080fd5b506040516020806104d38339810180604052602081101561003057600080fd5b505160008054600160a060020a03191633179055600155436002556104798061005a6000396000f3fe60806040526004361061005b577c010000000000000000000000000000000000000000000000000000000060003504632c4e722e811461006057806334fcf437146100875780637d1962f8146100c5578063f905c15a1461016b575b600080fd5b34801561006c57600080fd5b50610075610180565b60408051918252519081900360200190f35b34801561009357600080fd5b506100b1600480360360208110156100aa57600080fd5b5035610186565b604080519115158252519081900360200190f35b6100b1600480360360208110156100db57600080fd5b8101906020810181356401000000008111156100f657600080fd5b82018360208201111561010857600080fd5b8035906020019184600183028401116401000000008311171561012a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610200945050505050565b34801561017757600080fd5b50610075610425565b60015481565b6000805473ffffffffffffffffffffffffffffffffffffffff1633146101f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061042c6022913960400191505060405180910390fd5b60019190915590565b600081600081518110151561021157fe5b90602001015160f860020a900460f860020a027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916601260f860020a021480156102a4575081600181518110151561026557fe5b90602001015160f860020a900460f860020a027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916602060f860020a02145b1561031057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f56657273696f6e203020434944206e6f7420616c6c6f7765642e000000000000604482015290519081900360640190fd5b60015434101561038157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f43616e6e6f7420707572636861736520302073746f726167652e000000000000604482015290519081900360640190fd5b60006001543481151561039057fe5b049050826040518082805190602001908083835b602083106103c35780518252601f1990920191602091820191016103a4565b51815160209384036101000a60001901801990921691161790526040805192909401829003822087835293519395503394507f7c80eb99758dfe3e8aef5df583c1c9bab5369cf46b930b802f130edcfeac90ca9391829003019150a350919050565b6002548156fe4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6e2ea165627a7a7230582066a562655974347c7be5c07036895dbda69fb0afe99bdcb6d150fa1322d3610c0029
0x608060405234801561001057600080fd5b506040516020806104d38339810180604052602081101561003057600080fd5b505160008054600160a060020a03191633179055600155436002556104798061005a6000396000f3fe60806040526004361061005b577c010000000000000000000000000000000000000000000000000000000060003504632c4e722e811461006057806334fcf437146100875780637d1962f8146100c5578063f905c15a1461016b575b600080fd5b34801561006c57600080fd5b50610075610180565b60408051918252519081900360200190f35b34801561009357600080fd5b506100b1600480360360208110156100aa57600080fd5b5035610186565b604080519115158252519081900360200190f35b6100b1600480360360208110156100db57600080fd5b8101906020810181356401000000008111156100f657600080fd5b82018360208201111561010857600080fd5b8035906020019184600183028401116401000000008311171561012a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610200945050505050565b34801561017757600080fd5b50610075610425565b60015481565b6000805473ffffffffffffffffffffffffffffffffffffffff1633146101f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061042c6022913960400191505060405180910390fd5b60019190915590565b600081600081518110151561021157fe5b90602001015160f860020a900460f860020a027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916601260f860020a021480156102a4575081600181518110151561026557fe5b90602001015160f860020a900460f860020a027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916602060f860020a02145b1561031057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f56657273696f6e203020434944206e6f7420616c6c6f7765642e000000000000604482015290519081900360640190fd5b60015434101561038157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f43616e6e6f7420707572636861736520302073746f726167652e000000000000604482015290519081900360640190fd5b60006001543481151561039057fe5b049050826040518082805190602001908083835b602083106103c35780518252601f1990920191602091820191016103a4565b51815160209384036101000a60001901801990921691161790526040805192909401829003822087835293519395503294507f7c80eb99758dfe3e8aef5df583c1c9bab5369cf46b930b802f130edcfeac90ca9391829003019150a350919050565b6002548156fe4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6e2ea165627a7a72305820bb2c3f7751bc46bc00512d7519dbc05e7254b6d967157a88321965422de35a400029
2 changes: 1 addition & 1 deletion contracts/Pinner.abi
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
},
{
"indexed": false,
"name": "gbh",
"name": "bh",
"type": "uint256"
}
],
Expand Down
2 changes: 1 addition & 1 deletion contracts/owned.bin
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0x6080604052348015600f57600080fd5b5060008054600160a060020a03191633179055603580602f6000396000f3fe6080604052600080fdfea165627a7a7230582098afa05ed8e3ff8058a574fc21b8e95b17963ede9b523afa7131a098db58c42f0029
0x6080604052348015600f57600080fd5b5060008054600160a060020a03191633179055603580602f6000396000f3fe6080604052600080fdfea165627a7a7230582090498b51bcf1bfe3b5f8126eaa5c90a2aaa64bb6abae8e91d5c678b97504cecf0029
13 changes: 8 additions & 5 deletions contracts/pinner.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pragma solidity ^0.5.3;

interface Pinner {
// Returns the current rate in wei per GigaByteHour.
// Returns the current rate in atto GO per ByteHour.
function rate() external view returns (uint);

// Returns the number of the block when this contract was deployed.
Expand All @@ -10,7 +10,7 @@ interface Pinner {
// Pin a CID. Value must be greater than 0. CID must not be version 0.
function pin(bytes calldata cid) external payable returns (bool);

event Pinned(address indexed user, bytes indexed cid, uint gbh);
event Pinned(address indexed user, bytes indexed cid, uint bh);
}

contract owned {
Expand All @@ -35,7 +35,7 @@ contract owned {

//TODO killable, and then refund full amount when dead?
contract GOFSPinner is Pinner, owned {
// Rate in wei per GigaByteHour.
// Rate in atto GO per ByteHour.
uint public rate;
uint public deployed;

Expand All @@ -58,7 +58,10 @@ contract GOFSPinner is Pinner, owned {
msg.value >= rate,
"Cannot purchase 0 storage."
);
uint gbh = msg.value/rate;
emit Pinned(msg.sender, cid, gbh);
uint bh = msg.value/rate;
//TODO tx.origin for forwarded proxy contract calls. They also must forward the payment as well...
emit Pinned(tx.origin, cid, bh);
}

//TODO withdraw?
}
21 changes: 7 additions & 14 deletions gofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ 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 All @@ -37,6 +36,7 @@ func init() {
pinMethod = pinnerABI.Methods["pin"]
}

// Rate returns the storage cost rate in atto GO per ByteHour.
func Rate(ctx context.Context, rpcURL string, contract common.Address) (*big.Int, error) {
gc, err := goclient.Dial(rpcURL)
if err != nil {
Expand All @@ -49,14 +49,6 @@ 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 @@ -71,7 +63,8 @@ func Cost(ctx context.Context, rpcURL string, contract common.Address, bytes, hr
if err != nil {
return
}
cost = ComputeCost(rate, bytes, hrs)
bh := new(big.Int).Mul(big.NewInt(bytes), big.NewInt(hrs))
cost = bh.Mul(bh, rate)
return
}

Expand All @@ -95,7 +88,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, gbh uint64) (common.Hash, *types.Receipt, error) {
func Pin(ctx context.Context, rpcURL string, contract common.Address, pk *ecdsa.PrivateKey, ci string, bh 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 @@ -115,7 +108,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(gbh)))
cost := new(big.Int).Mul(rate, big.NewInt(int64(bh)))
opts := &bind.TransactOpts{
Context: ctx,
From: crypto.PubkeyToAddress(pk.PublicKey),
Expand Down Expand Up @@ -180,7 +173,7 @@ func UnpackPinInputs(data []byte) (pi PinInputs, err error) {
type Receipt struct {
User common.Address
CID cid.Cid
GBH *big.Int
BH *big.Int
Tx *types.Transaction
BlNum uint64
TxNum uint
Expand Down Expand Up @@ -255,7 +248,7 @@ func Receipts(ctx context.Context, rpcURL string, contract common.Address, filte
receipts = append(receipts, Receipt{
User: from,
CID: ci,
GBH: event.Gbh,
BH: event.Bh,
Tx: tx,
BlNum: l.BlockNumber,
TxNum: l.TxIndex,
Expand Down
37 changes: 0 additions & 37 deletions gofs_test.go

This file was deleted.

8 changes: 4 additions & 4 deletions pinner.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7201755

Please sign in to comment.