Skip to content

Commit

Permalink
Local retrieval support
Browse files Browse the repository at this point in the history
  • Loading branch information
magik6k committed Mar 30, 2021
1 parent f4a2c8f commit f2ab316
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 127 deletions.
6 changes: 4 additions & 2 deletions api/api_full.go
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ func (o *QueryOffer) Order(client address.Address) RetrievalOrder {
Client: client,

Miner: o.Miner,
MinerPeer: o.MinerPeer,
MinerPeer: &o.MinerPeer,
}
}

Expand All @@ -899,14 +899,16 @@ type RetrievalOrder struct {
Root cid.Cid
Piece *cid.Cid
Size uint64

LocalStore *multistore.StoreID // if specified, get data from local store
// TODO: support offset
Total types.BigInt
UnsealPrice types.BigInt
PaymentInterval uint64
PaymentIntervalIncrease uint64
Client address.Address
Miner address.Address
MinerPeer retrievalmarket.RetrievalPeer
MinerPeer *retrievalmarket.RetrievalPeer
}

type InvocResult struct {
Expand Down
133 changes: 74 additions & 59 deletions cli/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -999,7 +999,7 @@ var clientFindCmd = &cli.Command{
},
}

const DefaultMaxRetrievePrice = 1
const DefaultMaxRetrievePrice = "0.01"

var clientRetrieveCmd = &cli.Command{
Name: "retrieve",
Expand All @@ -1020,12 +1020,15 @@ var clientRetrieveCmd = &cli.Command{
},
&cli.StringFlag{
Name: "maxPrice",
Usage: fmt.Sprintf("maximum price the client is willing to consider (default: %d FIL)", DefaultMaxRetrievePrice),
Usage: fmt.Sprintf("maximum price the client is willing to consider (default: %s FIL)", DefaultMaxRetrievePrice),
},
&cli.StringFlag{
Name: "pieceCid",
Usage: "require data to be retrieved from a specific Piece CID",
},
&cli.BoolFlag{
Name: "allow-local",
},
},
Action: func(cctx *cli.Context) error {
if cctx.NArg() != 2 {
Expand Down Expand Up @@ -1055,18 +1058,6 @@ var clientRetrieveCmd = &cli.Command{
return err
}

// Check if we already have this data locally

/*has, err := api.ClientHasLocal(ctx, file)
if err != nil {
return err
}
if has {
fmt.Println("Success: Already in local storage")
return nil
}*/ // TODO: fix

var pieceCid *cid.Cid
if cctx.String("pieceCid") != "" {
parsed, err := cid.Parse(cctx.String("pieceCid"))
Expand All @@ -1076,69 +1067,93 @@ var clientRetrieveCmd = &cli.Command{
pieceCid = &parsed
}

var offer api.QueryOffer
minerStrAddr := cctx.String("miner")
if minerStrAddr == "" { // Local discovery
offers, err := fapi.ClientFindData(ctx, file, pieceCid)
var order *lapi.RetrievalOrder
if cctx.Bool("allow-local") {
imports, err := fapi.ClientListImports(ctx)
if err != nil {
return err
}

var cleaned []api.QueryOffer
// filter out offers that errored
for _, o := range offers {
if o.Err == "" {
cleaned = append(cleaned, o)
for _, i := range imports {
if i.Root != nil && i.Root.Equals(file) {
order = &lapi.RetrievalOrder{
Root: file,
LocalStore: &i.Key,

Total: big.Zero(),
UnsealPrice: big.Zero(),
}
break
}
}
}

offers = cleaned
if order == nil {
var offer api.QueryOffer
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
}
var cleaned []api.QueryOffer
// filter out offers that errored
for _, o := range offers {
if o.Err == "" {
cleaned = append(cleaned, o)
}
}

// TODO: parse offer strings from `client find`, make this smarter
if len(offers) < 1 {
fmt.Println("Failed to find file")
return nil
}
offer = offers[0]
} else { // Directed retrieval
minerAddr, err := address.NewFromString(minerStrAddr)
if err != nil {
return err
offers = cleaned

// 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
}

// TODO: parse offer strings from `client find`, make this smarter
if len(offers) < 1 {
fmt.Println("Failed to find file")
return nil
}
offer = offers[0]
} else { // Directed retrieval
minerAddr, err := address.NewFromString(minerStrAddr)
if err != nil {
return err
}
offer, err = fapi.ClientMinerQueryOffer(ctx, minerAddr, file, pieceCid)
if err != nil {
return err
}
}
offer, err = fapi.ClientMinerQueryOffer(ctx, minerAddr, file, pieceCid)
if err != nil {
return err
if offer.Err != "" {
return fmt.Errorf("The received offer errored: %s", offer.Err)
}
}
if offer.Err != "" {
return fmt.Errorf("The received offer errored: %s", offer.Err)
}

maxPrice := types.FromFil(DefaultMaxRetrievePrice)
maxPrice := types.MustParseFIL(DefaultMaxRetrievePrice)

if cctx.String("maxPrice") != "" {
maxPriceFil, err := types.ParseFIL(cctx.String("maxPrice"))
if err != nil {
return xerrors.Errorf("parsing maxPrice: %w", err)
if cctx.String("maxPrice") != "" {
maxPrice, err = types.ParseFIL(cctx.String("maxPrice"))
if err != nil {
return xerrors.Errorf("parsing maxPrice: %w", err)
}
}

maxPrice = types.BigInt(maxPriceFil)
}
if offer.MinPrice.GreaterThan(big.Int(maxPrice)) {
return xerrors.Errorf("failed to find offer satisfying maxPrice: %s", maxPrice)
}

if offer.MinPrice.GreaterThan(maxPrice) {
return xerrors.Errorf("failed to find offer satisfying maxPrice: %s", maxPrice)
o := offer.Order(payer)
order = &o
}

ref := &lapi.FileRef{
Path: cctx.Args().Get(1),
IsCAR: cctx.Bool("car"),
}
updates, err := fapi.ClientRetrieveWithEvents(ctx, offer.Order(payer), ref)

updates, err := fapi.ClientRetrieveWithEvents(ctx, *order, ref)
if err != nil {
return xerrors.Errorf("error setting up retrieval: %w", err)
}
Expand Down
Loading

0 comments on commit f2ab316

Please sign in to comment.