From e6779b0b6f6d66bc0be8b7aec9a49cef80c82946 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 5 Jan 2021 01:08:19 -0500 Subject: [PATCH] Add a command to get the fees of a deal --- chain/actors/builtin/market/market.go | 17 +++++ cmd/lotus-shed/main.go | 1 + cmd/lotus-shed/market.go | 102 ++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 cmd/lotus-shed/market.go diff --git a/chain/actors/builtin/market/market.go b/chain/actors/builtin/market/market.go index 7381515030d..33729bdf93a 100644 --- a/chain/actors/builtin/market/market.go +++ b/chain/actors/builtin/market/market.go @@ -1,6 +1,7 @@ package market import ( + "github.com/filecoin-project/go-state-types/big" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -153,3 +154,19 @@ func EmptyDealState() *DealState { LastUpdatedEpoch: -1, } } + +// returns the earned fees and pending fees for a given deal +func (deal DealProposal) GetDealFees(height abi.ChainEpoch) (abi.TokenAmount, abi.TokenAmount) { + tf := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(deal.EndEpoch-deal.StartEpoch))) + + ef := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(height-deal.StartEpoch))) + if ef.LessThan(big.Zero()) { + ef = big.Zero() + } + + if ef.GreaterThan(tf) { + ef = tf + } + + return ef, big.Sub(tf, ef) +} diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go index ebe4f014aed..3aa66745957 100644 --- a/cmd/lotus-shed/main.go +++ b/cmd/lotus-shed/main.go @@ -34,6 +34,7 @@ func main() { postFindCmd, proofsCmd, verifRegCmd, + marketCmd, miscCmd, mpoolCmd, genesisVerifyCmd, diff --git a/cmd/lotus-shed/market.go b/cmd/lotus-shed/market.go new file mode 100644 index 00000000000..e2e322784cb --- /dev/null +++ b/cmd/lotus-shed/market.go @@ -0,0 +1,102 @@ +package main + +import ( + "fmt" + + lcli "github.com/filecoin-project/lotus/cli" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" +) + +var marketCmd = &cli.Command{ + Name: "market", + Usage: "Interact with the market actor", + Flags: []cli.Flag{}, + Subcommands: []*cli.Command{ + marketDealFeesCmd, + }, +} + +var marketDealFeesCmd = &cli.Command{ + Name: "get-deal-fees", + Usage: "View the storage fees associated with a particular deal or storage provider", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "provider", + Usage: "provider whose outstanding fees you'd like to calculate", + }, + &cli.IntFlag{ + Name: "dealId", + Usage: "deal whose outstanding fees you'd like to calculate", + }, + }, + Action: func(cctx *cli.Context) error { + api, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + + ctx := lcli.ReqContext(cctx) + + ts, err := lcli.LoadTipSet(ctx, cctx, api) + if err != nil { + return err + } + + ht := ts.Height() + + if cctx.IsSet("provider") { + p, err := address.NewFromString(cctx.String("provider")) + if err != nil { + return fmt.Errorf("failed to parse provider: %w", err) + } + + deals, err := api.StateMarketDeals(ctx, ts.Key()) + if err != nil { + return err + } + + ef := big.Zero() + pf := big.Zero() + count := 0 + + for _, deal := range deals { + if deal.Proposal.Provider == p { + e, p := deal.Proposal.GetDealFees(ht) + ef = big.Add(ef, e) + pf = big.Add(pf, p) + count++ + } + } + + fmt.Println("Total deals: ", count) + fmt.Println("Total earned fees: ", ef) + fmt.Println("Total pending fees: ", pf) + fmt.Println("Total fees: ", big.Add(ef, pf)) + + return nil + } + + if dealid := cctx.Int("dealId"); dealid != 0 { + deal, err := api.StateMarketStorageDeal(ctx, abi.DealID(dealid), ts.Key()) + if err != nil { + return err + } + + ef, pf := deal.Proposal.GetDealFees(ht) + + fmt.Println("Earned fees: ", ef) + fmt.Println("Pending fees: ", pf) + fmt.Println("Total fees: ", big.Add(ef, pf)) + + return nil + } + + return xerrors.New("must provide either --provider or --dealId flag") + }, +}