diff --git a/cli/client.go b/cli/client.go index 8c2ad7eb8..f80ed99ec 100644 --- a/cli/client.go +++ b/cli/client.go @@ -485,6 +485,8 @@ var clientFindCmd = &cli.Command{ }, } +const DefaultMaxRetrievePrice = 1 + var clientRetrieveCmd = &cli.Command{ Name: "retrieve", Usage: "retrieve data from network", @@ -502,6 +504,10 @@ var clientRetrieveCmd = &cli.Command{ Name: "miner", Usage: "miner address for retrieval, if not present it'll use local discovery", }, + &cli.StringFlag{ + Name: "maxPrice", + Usage: fmt.Sprintf("maximum price the client is willing to consider (default: %d FIL)", DefaultMaxRetrievePrice), + }, &cli.StringFlag{ Name: "pieceCid", Usage: "require data to be retrieved from a specific Piece CID", @@ -560,6 +566,11 @@ var clientRetrieveCmd = &cli.Command{ minerStrAddr := cctx.String("miner") if minerStrAddr == "" { // Local discovery offers, err := fapi.ClientFindData(ctx, file, pieceCid) + + // sort by price low to high + sort.Slice(offers, func(i, j int) bool { + return offers[i].MinPrice.LessThan(offers[j].MinPrice) + }) if err != nil { return err } @@ -584,6 +595,21 @@ var clientRetrieveCmd = &cli.Command{ return fmt.Errorf("The received offer errored: %s", offer.Err) } + maxPrice := types.FromFil(DefaultMaxRetrievePrice) + + if cctx.String("maxPrice") != "" { + maxPriceFil, err := types.ParseFIL(cctx.String("maxPrice")) + if err != nil { + return xerrors.Errorf("parsing maxPrice: %w", err) + } + + maxPrice = types.BigInt(maxPriceFil) + } + + if offer.MinPrice.GreaterThan(maxPrice) { + return xerrors.Errorf("failed to find offer satisfying maxPrice: %s", maxPrice) + } + ref := &lapi.FileRef{ Path: cctx.Args().Get(1), IsCAR: cctx.Bool("car"),