Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var ListCmd = &cli.Command{ Name: "list", Usage: "List all deals", Flags: []cli.Flag{ &cli.StringSliceFlag{ Name: "preparation", Usage: "Filter deals by preparation id or name", }, &cli.StringSliceFlag{ Name: "source", Usage: "Filter deals by source storage id or name", }, &cli.UintSliceFlag{ Name: "schedule", Usage: "Filter deals by schedule", }, &cli.StringSliceFlag{ Name: "provider", Usage: "Filter deals by provider", }, &cli.StringSliceFlag{ Name: "state", Usage: "Filter deals by state: proposed, published, active, expired, proposal_expired, slashed", }, &cli.StringSliceFlag{ Name: "deal-type", Usage: "Filter deals by type: market, pdp, ddo", }, }, Action: func(c *cli.Context) error { db, closer, err := database.OpenFromCLI(c) if err != nil { return errors.WithStack(err) } defer closer.Close() deals, err := deal.Default.ListHandler(c.Context, db, deal.ListDealRequest{ Preparations: c.StringSlice("preparation"), Sources: c.StringSlice("source"), Schedules: underscore.Map(c.IntSlice("schedules"), func(i int) uint32 { return uint32(i) }), Providers: c.StringSlice("provider"), States: underscore.Map(c.StringSlice("state"), func(s string) model.DealState { return model.DealState(s) }), DealTypes: underscore.Map(c.StringSlice("deal-type"), func(s string) model.DealType { return model.DealType(s) }), }) if err != nil { return errors.WithStack(err) } cliutil.Print(c, deals) return nil }, }
View Source
var SendManualCmd = &cli.Command{ Name: "send-manual", Usage: "Send a manual deal proposal to boost or legacy market", Description: `Send a manual deal proposal to boost or legacy market Example: singularity deal send-manual --client f01234 --provider f05678 --piece-cid bagaxxxx --piece-size 32GiB Notes: * The client address must have been imported to the wallet using 'singularity wallet import' * The deal proposal will not be saved in the database however will eventually be tracked if the deal tracker is running * There is a quick address verification using GLIF API which can be made faster by setting LOTUS_API and LOTUS_TOKEN to your own lotus node`, Flags: []cli.Flag{ &cli.BoolFlag{ Name: "save", Usage: "Whether to save the deal proposal to the database for tracking purpose", }, &cli.StringFlag{ Name: "client", Category: "Deal Proposal", Usage: "Client address to send deal from", Required: true, }, &cli.StringFlag{ Name: "provider", Category: "Deal Proposal", Usage: "Storage Provider ID to send deal to", Required: true, }, &cli.StringFlag{ Name: "piece-cid", Category: "Deal Proposal", Usage: "Piece CID of the deal", Required: true, }, &cli.StringFlag{ Name: "piece-size", Category: "Deal Proposal", Usage: "Piece Size of the deal", Value: "32GiB", Required: true, }, &cli.StringSliceFlag{ Name: "http-header", Category: "Boost Only", Usage: "http headers to be passed with the request (i.e. key=value)", }, &cli.StringFlag{ Name: "http-url", Category: "Boost Only", Usage: "URL or URL template with PIECE_CID placeholder for boost to fetch the CAR file, e.g. http://127.0.0.1/piece/{PIECE_CID}.car", Aliases: []string{"url-template"}, Value: "", }, &cli.Uint64Flag{ Name: "file-size", Category: "Boost Only", Usage: "File size in bytes for boost to fetch the CAR file", Value: 0, }, &cli.Float64Flag{ Name: "price-per-gb-epoch", Category: "Deal Proposal", Usage: "Price in FIL per GiB per epoch", Value: 0, }, &cli.Float64Flag{ Name: "price-per-gb", Category: "Deal Proposal", Usage: "Price in FIL per GiB", Value: 0, }, &cli.Float64Flag{ Name: "price-per-deal", Category: "Deal Proposal", Usage: "Price in FIL per deal", Value: 0, }, &cli.StringFlag{ Name: "root-cid", Category: "Deal Proposal", Usage: "Root CID that is required as part of the deal proposal, if empty, will be set to empty CID", Value: "bafkqaaa", DefaultText: "Empty CID", }, &cli.BoolFlag{ Name: "verified", Category: "Deal Proposal", Usage: "Whether to propose deals as verified", Value: true, }, &cli.BoolFlag{ Name: "ipni", Category: "Boost Only", Usage: "Whether to announce the deal to IPNI", Value: true, }, &cli.BoolFlag{ Name: "keep-unsealed", Category: "Deal Proposal", Usage: "Whether to keep unsealed copy", Value: true, }, &cli.StringFlag{ Name: "start-delay", Category: "Deal Proposal", Aliases: []string{"s"}, Usage: "Deal start delay in epoch or in duration format, i.e. 1000, 72h", Value: "72h", DefaultText: "72h[3 days]", }, &cli.StringFlag{ Name: "duration", Category: "Deal Proposal", Aliases: []string{"d"}, Usage: "Duration in epoch or in duration format, i.e. 1500000, 2400h", Value: "12840h", DefaultText: "12840h[535 days]", }, &cli.DurationFlag{ Name: "timeout", Usage: "Timeout for the deal proposal", Value: time.Minute, DefaultText: "1m", }, }, Action: func(c *cli.Context) error { lotusAPI := c.String("lotus-api") lotusToken := c.String("lotus-token") err := epochutil.Initialize(c.Context, lotusAPI, lotusToken) if err != nil { return errors.WithStack(err) } proposal := deal.Proposal{ HTTPHeaders: c.StringSlice("http-header"), URLTemplate: c.String("url-template"), PricePerGBEpoch: c.Float64("price-per-gb-epoch"), PricePerGB: c.Float64("price-per-gb"), PricePerDeal: c.Float64("price-per-deal"), RootCID: c.String("root-cid"), Verified: c.Bool("verified"), IPNI: c.Bool("ipni"), KeepUnsealed: c.Bool("keep-unsealed"), StartDelay: c.String("start-delay"), Duration: c.String("duration"), ClientAddress: c.String("client"), ProviderID: c.String("provider"), PieceCID: c.String("piece-cid"), PieceSize: c.String("piece-size"), FileSize: c.Uint64("file-size"), } timeout := c.Duration("timeout") db, closer, err := database.OpenFromCLI(c) if err != nil { return errors.WithStack(err) } defer closer.Close() ctx, cancel := context.WithTimeout(c.Context, timeout) defer cancel() h, err := util.InitHost(nil) if err != nil { return errors.Wrap(err, "failed to init host") } defer h.Close() ks, err := keystore.NewLocalKeyStore(wallet.GetKeystoreDir()) if err != nil { return errors.Wrap(err, "failed to init keystore") } lotusClient := util.NewLotusClient(c.String("lotus-api"), c.String("lotus-token")) dealMaker := replication.NewDealMaker(lotusClient, h, 10*timeout, timeout) dealModel, err := deal.Default.SendManualHandler(ctx, db, ks, lotusClient, dealMaker, proposal) if err != nil { return errors.WithStack(err) } if c.Bool("save") { db = db.WithContext(ctx) err = database.DoRetry(ctx, func() error { return db.Create(dealModel).Error }) if err != nil { return errors.WithStack(err) } } cliutil.Print(c, dealModel) return nil }, }
View Source
var SendManualPDPCmd = &cli.Command{ Name: "send-manual-pdp", Usage: "Send a manual PDP deal via the FWSS-pull flow", Description: `Push a single piece to an SP via Curio's /pdp/piece/pull, then trigger the SP's on-chain commit (createDataSet+addPieces if no assembling set yet, or addPieces into the existing one). Useful for e2e/diagnostic testing of the FWSS pull path. Example: singularity deal send-manual-pdp --client f1xxx --provider t410fxxx --piece-cid bagaxxxx --piece-size 1048576 --eth-rpc http://localhost:5700/rpc/v1 --source-url-base https://static.example.org`, Flags: []cli.Flag{ &cli.StringFlag{ Name: "client", Usage: "Client wallet address (must be imported)", Required: true, }, &cli.StringFlag{ Name: "provider", Usage: "Storage provider f4/t4 address", Required: true, }, &cli.StringFlag{ Name: "piece-cid", Usage: "Piece CID (commp v1)", Required: true, }, &cli.Int64Flag{ Name: "piece-size", Usage: "Padded piece size in bytes", Required: true, }, &cli.Int64Flag{ Name: "payload-size", Usage: "Real CAR file size in bytes (the data the SP will fetch). The CommPv2 piece CID encodes this size; SP zero-fills locally up to PieceSize when computing CommP.", Required: true, }, &cli.StringFlag{ Name: "eth-rpc", Usage: "FEVM JSON-RPC endpoint", EnvVars: []string{"ETH_RPC_URL"}, Required: true, }, &cli.StringFlag{ Name: "source-url-base", Usage: "HTTPS base where Curio fetches the piece (sourceUrl = <base>/piece/<pieceCidV2>)", EnvVars: []string{"PDP_SOURCE_URL_BASE"}, Required: true, }, &cli.StringFlag{ Name: "record-keeper", Usage: "FWSS contract address. Defaults to network FWSS from go-synapse.", EnvVars: []string{"PDP_RECORD_KEEPER"}, }, &cli.DurationFlag{ Name: "pull-timeout", Usage: "How long to wait for Curio to finish each phase", Value: 5 * time.Minute, }, }, Action: func(c *cli.Context) error { db, closer, err := database.OpenFromCLI(c) if err != nil { return errors.WithStack(err) } defer closer.Close() pdp, err := dealpusher.NewOnChainPDP(c.Context, dealpusher.OnChainPDPConfig{ DB: db, RPCURL: c.String("eth-rpc"), SourceURLBase: c.String("source-url-base"), RecordKeeper: c.String("record-keeper"), }) if err != nil { return errors.WithStack(err) } defer pdp.Close() var walletObj model.Wallet err = db.WithContext(c.Context).Where("address = ?", c.String("client")).First(&walletObj).Error if errors.Is(err, gorm.ErrRecordNotFound) { return fmt.Errorf("wallet %s not found -- import it first with 'singularity wallet import'", c.String("client")) } if err != nil { return errors.WithStack(err) } ks, err := keystore.NewLocalKeyStore(wallet.GetKeystoreDir()) if err != nil { return errors.Wrap(err, "failed to init keystore") } evmSigner, err := keystore.EVMSigner(ks, walletObj) if err != nil { return errors.WithStack(err) } pieceCID, err := cid.Parse(c.String("piece-cid")) if err != nil { return errors.Wrap(err, "invalid piece CID") } pieceSize := c.Int64("piece-size") payloadSize := c.Int64("payload-size") cfg := dealpusher.PDPSchedulingConfig{ BatchSize: 1, MaxPiecesPerProofSet: 1024, PullTimeout: c.Duration("pull-timeout"), } fmt.Println("pushing piece to SP via /pdp/piece/pull + on-chain commit...") result, err := pdp.PullPiecesToFWSS( c.Context, evmSigner, c.String("provider"), []dealpusher.PDPPieceInput{{PieceCID: pieceCID, PieceSize: pieceSize, PayloadSize: payloadSize}}, cfg, ) if err != nil { return errors.Wrap(err, "FWSS pull push failed") } fmt.Printf("data set ID: %d\n", result.DataSetID) dataSetIDCopy := result.DataSetID dealModel := &model.Deal{ State: model.DealProposed, DealType: model.DealTypePDP, Provider: c.String("provider"), PieceCID: model.CID(pieceCID), PieceSize: pieceSize, StartEpoch: dealpusher.PDPDealEpochSentinel, EndEpoch: dealpusher.PDPDealEpochSentinel, WalletID: &walletObj.ID, ProofSetID: &dataSetIDCopy, } if err := db.WithContext(c.Context).Create(dealModel).Error; err != nil { return errors.Wrap(err, "failed to save deal") } cliutil.Print(c, dealModel) return nil }, }
Functions ¶
This section is empty.
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.