diff --git a/api/api_full.go b/api/api_full.go index cbd23564616..4c0eb4e0524 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -293,7 +293,7 @@ type FullNode interface { // ClientGetDealInfo returns the latest information about a given deal. ClientGetDealInfo(context.Context, cid.Cid) (*DealInfo, error) // ClientListDeals returns information about the deals made by the local client. - ClientListDeals(ctx context.Context) ([]DealInfo, error) + ClientListDeals(ctx context.Context, filter storagemarket.ListDealsPageParams) ([]DealInfo, error) // ClientGetDealUpdates returns the status of updated deals ClientGetDealUpdates(ctx context.Context) (<-chan DealInfo, error) // ClientGetDealStatus returns status given a code diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 56ead4b1072..e9295796d9b 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -167,7 +167,7 @@ type FullNodeStruct struct { ClientStartDeal func(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) `perm:"admin"` ClientGetDealInfo func(context.Context, cid.Cid) (*api.DealInfo, error) `perm:"read"` ClientGetDealStatus func(context.Context, uint64) (string, error) `perm:"read"` - ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"` + ClientListDeals func(ctx context.Context, filter storagemarket.ListDealsPageParams) ([]api.DealInfo, error) `perm:"write"` ClientGetDealUpdates func(ctx context.Context) (<-chan api.DealInfo, error) `perm:"read"` ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error `perm:"admin"` ClientRetrieveWithEvents func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) (<-chan marketevents.RetrievalEvent, error) `perm:"admin"` @@ -622,8 +622,8 @@ func (c *FullNodeStruct) ClientGetDealStatus(ctx context.Context, statusCode uin return c.Internal.ClientGetDealStatus(ctx, statusCode) } -func (c *FullNodeStruct) ClientListDeals(ctx context.Context) ([]api.DealInfo, error) { - return c.Internal.ClientListDeals(ctx) +func (c *FullNodeStruct) ClientListDeals(ctx context.Context, filter storagemarket.ListDealsPageParams) ([]api.DealInfo, error) { + return c.Internal.ClientListDeals(ctx, filter) } func (c *FullNodeStruct) ClientGetDealUpdates(ctx context.Context) (<-chan api.DealInfo, error) { diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index 8fd646d9abe..99aa82b9bab 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -610,18 +610,18 @@ func (mr *MockFullNodeMockRecorder) ClientListDataTransfers(arg0 interface{}) *g } // ClientListDeals mocks base method -func (m *MockFullNode) ClientListDeals(arg0 context.Context) ([]api.DealInfo, error) { +func (m *MockFullNode) ClientListDeals(arg0 context.Context, arg1 storagemarket.ListDealsPageParams) ([]api.DealInfo, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ClientListDeals", arg0) + ret := m.ctrl.Call(m, "ClientListDeals", arg0, arg1) ret0, _ := ret[0].([]api.DealInfo) ret1, _ := ret[1].(error) return ret0, ret1 } // ClientListDeals indicates an expected call of ClientListDeals -func (mr *MockFullNodeMockRecorder) ClientListDeals(arg0 interface{}) *gomock.Call { +func (mr *MockFullNodeMockRecorder) ClientListDeals(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListDeals", reflect.TypeOf((*MockFullNode)(nil).ClientListDeals), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListDeals", reflect.TypeOf((*MockFullNode)(nil).ClientListDeals), arg0, arg1) } // ClientListImports mocks base method diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index bd38746b0f8..6887141a828 100644 Binary files a/build/openrpc/full.json.gz and b/build/openrpc/full.json.gz differ diff --git a/cli/client.go b/cli/client.go index 98f4b022927..b225ccee1c1 100644 --- a/cli/client.go +++ b/cli/client.go @@ -1130,7 +1130,7 @@ var clientDealStatsCmd = &cli.Command{ defer closer() ctx := ReqContext(cctx) - localDeals, err := api.ClientListDeals(ctx) + localDeals, err := api.ClientListDeals(ctx, storagemarket.ListDealsPageParams{}) if err != nil { return err } @@ -1473,8 +1473,9 @@ var clientQueryAskCmd = &cli.Command{ } var clientListDeals = &cli.Command{ - Name: "list-deals", - Usage: "List storage market deals", + Name: "list-deals", + Usage: "List storage market deals", + UsageText: "also supports pagination, please see supported options for more details", Flags: []cli.Flag{ &cli.BoolFlag{ Name: "verbose", @@ -1486,14 +1487,35 @@ var clientListDeals = &cli.Command{ Usage: "use color in display output", Value: true, }, - &cli.BoolFlag{ - Name: "show-failed", - Usage: "show failed/failing deals", - }, &cli.BoolFlag{ Name: "watch", Usage: "watch deal updates in real-time, rather than a one time list", }, + &cli.BoolFlag{ + Name: "hide-failed", + Usage: "hide failed/failing deals", + }, + &cli.TimestampFlag{ + Name: "creation-time-offset", + Layout: time.RFC3339, + Usage: "only show deals with a creation time greater than this value", + DefaultText: "no-op", + }, + &cli.IntFlag{ + Name: "limit", + Usage: "number of deals to show in the deal list page", + Value: 50, + }, + &cli.Int64Flag{ + Name: "min-start-epoch", + Usage: "minimum start epoch of the deals to include in the deal list page", + DefaultText: "no-op", + }, + &cli.Int64Flag{ + Name: "max-end-epoch", + Usage: "maximum end epoch of the deals to include in the deal list page", + DefaultText: "no-op", + }, }, Action: func(cctx *cli.Context) error { api, closer, err := GetFullNodeAPI(cctx) @@ -1506,9 +1528,27 @@ var clientListDeals = &cli.Command{ verbose := cctx.Bool("verbose") color := cctx.Bool("color") watch := cctx.Bool("watch") - showFailed := cctx.Bool("show-failed") - localDeals, err := api.ClientListDeals(ctx) + ctOffset := cctx.Timestamp("creation-time-offset") + nDeals := cctx.Int("limit") + minStart := cctx.Int64("min-start-epoch") + maxEnd := cctx.Int64("max-end-epoch") + hideFailed := cctx.Bool("hide-failed") + + var timeOffset time.Time + if ctOffset != nil { + timeOffset = *ctOffset + } + + filter := storagemarket.ListDealsPageParams{ + CreationTimePageOffset: timeOffset, + DealsPerPage: nDeals, + MinStartEpoch: abi.ChainEpoch(minStart), + MaxEndEpoch: abi.ChainEpoch(maxEnd), + HideDealsInErrorState: hideFailed, + } + + localDeals, err := api.ClientListDeals(ctx, filter) if err != nil { return err } @@ -1523,7 +1563,7 @@ var clientListDeals = &cli.Command{ tm.Clear() tm.MoveCursor(1, 1) - err = outputStorageDeals(ctx, tm.Screen, api, localDeals, verbose, color, showFailed) + err = outputStorageDeals(ctx, tm.Screen, api, localDeals, verbose, color) if err != nil { return err } @@ -1549,7 +1589,7 @@ var clientListDeals = &cli.Command{ } } - return outputStorageDeals(ctx, cctx.App.Writer, api, localDeals, verbose, color, showFailed) + return outputStorageDeals(ctx, cctx.App.Writer, api, localDeals, verbose, color) }, } @@ -1572,7 +1612,7 @@ func dealFromDealInfo(ctx context.Context, full api.FullNode, head *types.TipSet } } -func outputStorageDeals(ctx context.Context, out io.Writer, full lapi.FullNode, localDeals []lapi.DealInfo, verbose bool, color bool, showFailed bool) error { +func outputStorageDeals(ctx context.Context, out io.Writer, full lapi.FullNode, localDeals []lapi.DealInfo, verbose bool, color bool) error { sort.Slice(localDeals, func(i, j int) bool { return localDeals[i].CreationTime.Before(localDeals[j].CreationTime) }) @@ -1584,9 +1624,7 @@ func outputStorageDeals(ctx context.Context, out io.Writer, full lapi.FullNode, var deals []deal for _, localDeal := range localDeals { - if showFailed || localDeal.State != storagemarket.StorageDealError { - deals = append(deals, dealFromDealInfo(ctx, full, head, localDeal)) - } + deals = append(deals, dealFromDealInfo(ctx, full, head, localDeal)) } if verbose { @@ -1620,7 +1658,7 @@ func outputStorageDeals(ctx context.Context, out io.Writer, full lapi.FullNode, //} } fmt.Fprintf(w, "%s\t%s\t%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d\t%s\t%s\t%v\t%s\n", - d.LocalDeal.CreationTime.Format(time.Stamp), + d.LocalDeal.CreationTime.Format(time.RFC3339), d.LocalDeal.ProposalCid, d.LocalDeal.DealID, d.LocalDeal.Provider, diff --git a/documentation/en/api-methods.md b/documentation/en/api-methods.md index 4dc0303d220..4ac285cdbf2 100644 --- a/documentation/en/api-methods.md +++ b/documentation/en/api-methods.md @@ -1213,7 +1213,18 @@ ClientListDeals returns information about the deals made by the local client. Perms: write -Inputs: `null` +Inputs: +```json +[ + { + "CreationTimePageOffset": "0001-01-01T00:00:00Z", + "DealsPerPage": 123, + "MinStartEpoch": 10101, + "MaxEndEpoch": 10101, + "HideDealsInErrorState": true + } +] +``` Response: `null` diff --git a/go.mod b/go.mod index f1bcab06132..90d2de88c4b 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 github.com/filecoin-project/go-data-transfer v1.4.0 github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a - github.com/filecoin-project/go-fil-markets v1.2.3 + github.com/filecoin-project/go-fil-markets v1.0.8-0.20210325080341-82f614c26d93 github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 diff --git a/go.sum b/go.sum index 93c6bb2d992..090151eaead 100644 --- a/go.sum +++ b/go.sum @@ -273,8 +273,8 @@ github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a h1:hyJ+pUm/4U4RdEZBlg6k8Ma4rDiuvqyGpoICXAxwsTg= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= -github.com/filecoin-project/go-fil-markets v1.2.3 h1:JDbGKQf60tB00TFKG/nofSyHyIEbqowZqoLOfda7yTs= -github.com/filecoin-project/go-fil-markets v1.2.3/go.mod h1:p5BIKl6sEoeOCKFa3/nfy66Q95rifEkJyGQgaNjPsno= +github.com/filecoin-project/go-fil-markets v1.0.8-0.20210325080341-82f614c26d93 h1:narSwEt79rz2G3KCDwOirr1sGPQ1wA1gLKxX1I/qW0w= +github.com/filecoin-project/go-fil-markets v1.0.8-0.20210325080341-82f614c26d93/go.mod h1:p5BIKl6sEoeOCKFa3/nfy66Q95rifEkJyGQgaNjPsno= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= diff --git a/node/impl/client/client.go b/node/impl/client/client.go index ac526ac6030..7d5c295a9d6 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -190,8 +190,8 @@ func (a *API) ClientStartDeal(ctx context.Context, params *api.StartDealParams) return &result.ProposalCid, nil } -func (a *API) ClientListDeals(ctx context.Context) ([]api.DealInfo, error) { - deals, err := a.SMDealClient.ListLocalDeals(ctx) +func (a *API) ClientListDeals(ctx context.Context, filter storagemarket.ListDealsPageParams) ([]api.DealInfo, error) { + deals, err := a.SMDealClient.ListLocalDeals(ctx, filter) if err != nil { return nil, err }