From 9b486c200143a2cb3ab2105d060b0f4f39695a48 Mon Sep 17 00:00:00 2001 From: Florian Ruen Date: Wed, 5 Jul 2023 18:06:57 +0200 Subject: [PATCH 1/4] feat: update from main boost repo feat: apply cidgravity changes --- cmd/boost/deal_cidgravity_cmd.go | 500 +++++++++++++++++++++++++++++++ cmd/boost/deal_cmd.go | 31 +- cmd/boost/main.go | 1 + cmd/util.go | 30 ++ 4 files changed, 556 insertions(+), 6 deletions(-) create mode 100644 cmd/boost/deal_cidgravity_cmd.go diff --git a/cmd/boost/deal_cidgravity_cmd.go b/cmd/boost/deal_cidgravity_cmd.go new file mode 100644 index 000000000..19224267d --- /dev/null +++ b/cmd/boost/deal_cidgravity_cmd.go @@ -0,0 +1,500 @@ +package main + +import ( + "strings" + + bcli "github.com/filecoin-project/boost/cli" + clinode "github.com/filecoin-project/boost/cli/node" + "github.com/filecoin-project/boost/cmd" + "github.com/filecoin-project/boost/storagemarket/types" + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-fil-markets/storagemarket/network" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + chain_types "github.com/filecoin-project/lotus/chain/types" + lcli "github.com/filecoin-project/lotus/cli" + "github.com/google/uuid" + "github.com/ipfs/go-cid" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" + "github.com/multiformats/go-multiaddr" + "github.com/urfave/cli/v2" +) + +var dealCIDgravityFlags = []cli.Flag{ + &cli.StringFlag{ + Name: "label", + Usage: "label to be specified in the proposal (default: root CID)", + Value: "", + }, + &cli.StringFlag{ + Name: "provider", + Usage: "storage provider on-chain address", + Required: true, + }, + &cli.StringFlag{ + Name: "commp", + Usage: "commp of the CAR file", + Required: true, + }, + &cli.Uint64Flag{ + Name: "piece-size", + Usage: "size of the CAR file as a padded piece", + Required: true, + }, + &cli.Uint64Flag{ + Name: "car-size", + Usage: "size of the CAR file", + Required: true, + }, + &cli.StringFlag{ + Name: "payload-cid", + Usage: "root CID of the CAR file", + Required: true, + }, + &cli.IntFlag{ + Name: "start-epoch", + Usage: "start epoch by when the deal should be proved by provider on-chain", + DefaultText: "current chain head + 2 days", + }, + &cli.IntFlag{ + Name: "duration", + Usage: "duration of the deal in epochs", + Value: 518400, // default is 2880 * 180 == 180 days + }, + &cli.IntFlag{ + Name: "provider-collateral", + Usage: "deal collateral that storage miner must put in escrow; if empty, the min collateral for the given piece size will be used", + }, + &cli.Int64Flag{ + Name: "storage-price", + Usage: "storage price in attoFIL per epoch per GiB", + Value: 1, + }, + &cli.BoolFlag{ + Name: "verified", + Usage: "whether the deal funds should come from verified client data-cap", + Value: true, + }, +} + +type CheckStatus string + +const ( + Available CheckStatus = "available" + Unavailable CheckStatus = "unavailable" + InternalError CheckStatus = "internal_error" + Unknown CheckStatus = "unknown" +) + +type dealCidGravityResponse struct { + Status CheckStatus `json:"status"` + Reason string `json:"reason"` + Message string `json:"message"` + + Multiaddresses []multiaddr.Multiaddr `json:"multiaddresses"` + PeerId peer.ID `json:"peerId"` + + GetAskPricePerGib string `json:"getAskPricePerGib"` + GetAskVerifiedPricePerGib string `json:"getAskVerifiedPricePerGib"` + GetAskMinPieceSize string `json:"getAskMinPieceSize"` + GetAskMaxPieceSize string `json:"getAskMaxPieceSize"` + GetAskSectorSize string `json:"getAskSectorSize"` + + DealProtocolsSupported protocol.ID `json:"dealProtocolsSupported"` +} + +var dealCidGravityCmd = &cli.Command{ + Name: "cidgravity-deal", + Usage: "Make an Keep Alive deal with Boost using CIDgravity proposal format (offline deal)", + Flags: dealCIDgravityFlags, + Before: before, + Action: func(cctx *cli.Context) error { + return dealCidGravityCmdAction(cctx) + }, +} + +func dealCidGravityCmdAction(cctx *cli.Context) error { + ctx := bcli.ReqContext(cctx) + + n, err := clinode.Setup(cctx.String(cmd.FlagRepo.Name)) + if err != nil { + return cmd.PrintJson(dealCidGravityResponse{ + Status: InternalError, + Reason: "ERR_API_GATEWAY", + Message: err.Error(), + }) + } + + api, closer, err := lcli.GetGatewayAPI(cctx) + if err != nil { + return cmd.PrintJson(dealCidGravityResponse{ + Status: InternalError, + Reason: "ERR_API_GATEWAY", + Message: err.Error(), + }) + } + defer closer() + + walletAddr, err := n.GetProvidedOrDefaultWallet(ctx, cctx.String("wallet")) + if err != nil { + return cmd.PrintJson(dealCidGravityResponse{ + Status: InternalError, + Reason: "ERR_INVALID_WALLET", + Message: err.Error(), + }) + } + + log.Debugw("selected wallet", "wallet", walletAddr) + + maddr, err := address.NewFromString(cctx.String("provider")) + if err != nil { + return cmd.PrintJson(dealCidGravityResponse{ + Status: InternalError, + Reason: "ERR_INVALID_PROVIDER", + Message: err.Error(), + }) + } + + addrInfo, sectorSize, reason, err := cmd.GetAddrInfoCid(ctx, api, maddr) + if err != nil { + return cmd.PrintJson(dealCidGravityResponse{ + Status: Unavailable, + Reason: reason, + Message: err.Error(), + Multiaddresses: []multiaddr.Multiaddr{}, + }) + } + + log.Debugw("found storage provider", "id", addrInfo.ID, "multiaddrs", addrInfo.Addrs, "addr", maddr) + + if err := n.Host.Connect(ctx, *addrInfo); err != nil { + return cmd.PrintJson(dealCidGravityResponse{ + Status: Unavailable, + Reason: "ERR_CONNECT_MINER_PEER_ID", + Message: err.Error(), + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + }) + } + + x, err := n.Host.Peerstore().FirstSupportedProtocol(addrInfo.ID, DealProtocolv120) + if err != nil { + return cmd.PrintJson(dealCidGravityResponse{ + Status: Unavailable, + Reason: "ERR_DEAL_PROTOCOL_UNSUPPORTED", + Message: err.Error(), + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + }) + } + + if len(x) == 0 { + return cmd.PrintJson(dealCidGravityResponse{ + Status: Unavailable, + Reason: "ERR_NO_MATCHING_DEAL_PROTOCOL_SUPPORTED", + Message: "boost client cannot make a deal with storage provider because it does not support protocol version 1.2", + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + }) + } + + dealUuid := uuid.New() + + commP := cctx.String("commp") + pieceCid, err := cid.Parse(commP) + if err != nil { + return cmd.PrintJson(dealCidGravityResponse{ + Status: InternalError, + Reason: "ERR_INVALID_PARAM_COMMP", + Message: "unable to parse commP : " + err.Error(), + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + }) + } + + pieceSize := cctx.Uint64("piece-size") + if pieceSize == 0 { + return cmd.PrintJson(dealCidGravityResponse{ + Status: InternalError, + Reason: "ERR_INVALID_PARAM_PIECE_SIZE", + Message: "must provide piece-size parameter for CAR url", + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + }) + } + + payloadCidStr := cctx.String("payload-cid") + rootCid, err := cid.Parse(payloadCidStr) + if err != nil { + return cmd.PrintJson(dealCidGravityResponse{ + Status: InternalError, + Reason: "ERR_INVALID_PARAM_PAYLOAD_CID", + Message: "unable to parse payload cid : " + err.Error(), + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + }) + } + + carFileSize := cctx.Uint64("car-size") + if carFileSize == 0 { + return cmd.PrintJson(dealCidGravityResponse{ + Status: InternalError, + Reason: "ERR_INVALID_PARAM_CAR_SIZE", + Message: "size of car file cannot be 0", + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + }) + } + + transfer := types.Transfer{ + Size: carFileSize, + } + + var providerCollateral abi.TokenAmount + if cctx.IsSet("provider-collateral") { + providerCollateral = abi.NewTokenAmount(cctx.Int64("provider-collateral")) + } else { + bounds, err := api.StateDealProviderCollateralBounds(ctx, abi.PaddedPieceSize(pieceSize), cctx.Bool("verified"), chain_types.EmptyTSK) + if err != nil { + return cmd.PrintJson(dealCidGravityResponse{ + Status: InternalError, + Reason: "ERR_API_GATEWAY_CANNOT_RETRIEVE_MINIMUM_COLLATERAL", + Message: "node error getting collateral bounds : " + err.Error(), + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + }) + } + + providerCollateral = big.Div(big.Mul(bounds.Min, big.NewInt(6)), big.NewInt(5)) // add 20% + } + + var startEpoch abi.ChainEpoch + if cctx.IsSet("start-epoch") { + startEpoch = abi.ChainEpoch(cctx.Int("start-epoch")) + } else { + tipset, err := api.ChainHead(ctx) + if err != nil { + return cmd.PrintJson(dealCidGravityResponse{ + Status: InternalError, + Reason: "ERR_API_GATEWAY_CANNOT_RETRIEVE_CURRENT_CHAIN_HEAD", + Message: "unable to get chain head : " + err.Error(), + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + }) + } + + head := tipset.Height() + + log.Debugw("current block height", "number", head) + + startEpoch = head + abi.ChainEpoch(5760) // head + 2 days + } + + // Create a deal proposal to storage provider using deal protocol v1.2.0 format + label := cctx.String("label") + + // Send a get ask request for the final check + log.Debugw("about to send a get ask request to", "address", maddr.String()) + + streamGetAsk, err := n.Host.NewStream(ctx, addrInfo.ID, AskProtocolID) + + if err != nil { + return cmd.PrintJson(dealCidGravityResponse{ + Status: Unavailable, + Reason: "ERR_GET_ASK", + Message: "failed to open stream to address : " + err.Error(), + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + }) + } + + defer streamGetAsk.Close() + var resp network.AskResponse + + askRequest := network.AskRequest{ + Miner: maddr, + } + + if err := doRpc(ctx, streamGetAsk, &askRequest, &resp); err != nil { + return cmd.PrintJson(dealCidGravityResponse{ + Status: Unavailable, + Reason: "ERR_GET_ASK", + Message: "error while send get ask request rpc: " + err.Error(), + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + }) + } + + ask := resp.Ask.Ask + + log.Debugw("found get ask information", + "Price per GiB", chain_types.FIL(ask.Price), + "Verified Price per GiB", chain_types.FIL(ask.VerifiedPrice), + "Min Piece size", chain_types.SizeStr(chain_types.NewInt(uint64(ask.MaxPieceSize))), + "Max Piece size", chain_types.SizeStr(chain_types.NewInt(uint64(ask.MinPieceSize))), + "Sector size", sectorSize.ShortString()) + + // To work with CIDgravity, every price must be 0 + if !ask.Price.Equals(abi.NewTokenAmount(0)) || !ask.VerifiedPrice.Equals(abi.NewTokenAmount(0)) { + return cmd.PrintJson(dealCidGravityResponse{ + Status: Unavailable, + Reason: "ERR_GET_ASK_PRICES_NOT_SET_TO_ZERO", + Message: "get-ask price has to be set to 0", + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + GetAskPricePerGib: chain_types.FIL(ask.Price).String(), + GetAskVerifiedPricePerGib: chain_types.FIL(ask.VerifiedPrice).String(), + GetAskMinPieceSize: chain_types.SizeStr(chain_types.NewInt(uint64(ask.MinPieceSize))), + GetAskMaxPieceSize: chain_types.SizeStr(chain_types.NewInt(uint64(ask.MaxPieceSize))), + GetAskSectorSize: sectorSize.ShortString(), + }) + } + + // To work with CIDgravity, the min size must be set to 256B and max size must be set to {sectorSize} + if ask.MinPieceSize != 256 || ask.MaxPieceSize != abi.PaddedPieceSize(*sectorSize) { + return cmd.PrintJson(dealCidGravityResponse{ + Status: Unavailable, + Reason: "ERR_GET_ASK_SIZES_NOT_PROPERLY_SET", + Message: "get-ask accepting size must be min=256B and max=" + sectorSize.ShortString(), + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + GetAskPricePerGib: chain_types.FIL(ask.Price).String(), + GetAskVerifiedPricePerGib: chain_types.FIL(ask.VerifiedPrice).String(), + GetAskMinPieceSize: chain_types.SizeStr(chain_types.NewInt(uint64(ask.MinPieceSize))), + GetAskMaxPieceSize: chain_types.SizeStr(chain_types.NewInt(uint64(ask.MaxPieceSize))), + GetAskSectorSize: sectorSize.ShortString(), + }) + } + + // Build the proposal + dealProposal, err := dealProposal(ctx, label, n, walletAddr, rootCid, abi.PaddedPieceSize(pieceSize), pieceCid, maddr, startEpoch, cctx.Int("duration"), cctx.Bool("verified"), providerCollateral, abi.NewTokenAmount(cctx.Int64("storage-price"))) + if err != nil { + return cmd.PrintJson(dealCidGravityResponse{ + Status: InternalError, + Reason: "ERR_SEND_PROPOSAL", + Message: "unable to create a deal proposal : " + err.Error(), + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + GetAskPricePerGib: chain_types.FIL(ask.Price).String(), + GetAskVerifiedPricePerGib: chain_types.FIL(ask.VerifiedPrice).String(), + GetAskMinPieceSize: chain_types.SizeStr(chain_types.NewInt(uint64(ask.MinPieceSize))), + GetAskMaxPieceSize: chain_types.SizeStr(chain_types.NewInt(uint64(ask.MaxPieceSize))), + GetAskSectorSize: sectorSize.ShortString(), + }) + } + + // Generate the final proposal + dealParams := types.DealParams{ + DealUUID: dealUuid, + ClientDealProposal: *dealProposal, + DealDataRoot: rootCid, + IsOffline: true, + Transfer: transfer, + RemoveUnsealedCopy: true, + SkipIPNIAnnounce: false, + } + + log.Debugw("about to submit deal proposal", "uuid", dealUuid.String()) + + streamSendProposal, err := n.Host.NewStream(ctx, addrInfo.ID, DealProtocolv120) + + if err != nil { + return cmd.PrintJson(dealCidGravityResponse{ + Status: Unavailable, + Reason: "ERR_SEND_PROPOSAL", + Message: "failed to open stream to peer : " + err.Error(), + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + GetAskPricePerGib: chain_types.FIL(ask.Price).String(), + GetAskVerifiedPricePerGib: chain_types.FIL(ask.VerifiedPrice).String(), + GetAskMinPieceSize: chain_types.SizeStr(chain_types.NewInt(uint64(ask.MinPieceSize))), + GetAskMaxPieceSize: chain_types.SizeStr(chain_types.NewInt(uint64(ask.MaxPieceSize))), + GetAskSectorSize: sectorSize.ShortString(), + }) + } + + defer streamSendProposal.Close() + + var respDealResponse types.DealResponse + if err := doRpc(ctx, streamSendProposal, &dealParams, &respDealResponse); err != nil { + return cmd.PrintJson(dealCidGravityResponse{ + Status: Unavailable, + Reason: "ERR_SEND_PROPOSAL", + Message: "error while send proposal rpc : " + err.Error(), + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + GetAskPricePerGib: chain_types.FIL(ask.Price).String(), + GetAskVerifiedPricePerGib: chain_types.FIL(ask.VerifiedPrice).String(), + GetAskMinPieceSize: chain_types.SizeStr(chain_types.NewInt(uint64(ask.MinPieceSize))), + GetAskMaxPieceSize: chain_types.SizeStr(chain_types.NewInt(uint64(ask.MaxPieceSize))), + GetAskSectorSize: sectorSize.ShortString(), + }) + } + + // For CIDgravity miner-status-check the proposal will be rejected every time + if !respDealResponse.Accepted { + + // So if the message contains the return code from miner-status-check service, we shouldn't consider as error + if strings.Contains(respDealResponse.Message, "CIDgravity miner status check successful") { + return cmd.PrintJson(dealCidGravityResponse{ + Status: Available, + Reason: "DIAGNOSIS_SUCCESS", + Message: "deal proposal successfully sent and received", + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + GetAskPricePerGib: chain_types.FIL(ask.Price).String(), + GetAskVerifiedPricePerGib: chain_types.FIL(ask.VerifiedPrice).String(), + GetAskMinPieceSize: chain_types.SizeStr(chain_types.NewInt(uint64(ask.MinPieceSize))), + GetAskMaxPieceSize: chain_types.SizeStr(chain_types.NewInt(uint64(ask.MaxPieceSize))), + GetAskSectorSize: sectorSize.ShortString(), + }) + } + + // Otherwise, return ERR_CIDGRAVITY_CONNECTOR_MISCONFIGURED + return cmd.PrintJson(dealCidGravityResponse{ + Status: Unavailable, + Reason: "ERR_CIDGRAVITY_CONNECTOR_MISCONFIGURED", + Message: respDealResponse.Message, + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + GetAskPricePerGib: chain_types.FIL(ask.Price).String(), + GetAskVerifiedPricePerGib: chain_types.FIL(ask.VerifiedPrice).String(), + GetAskMinPieceSize: chain_types.SizeStr(chain_types.NewInt(uint64(ask.MinPieceSize))), + GetAskMaxPieceSize: chain_types.SizeStr(chain_types.NewInt(uint64(ask.MaxPieceSize))), + GetAskSectorSize: sectorSize.ShortString(), + }) + } + + // In our case, this block will never be reached (because all proposals will be rejected) + return cmd.PrintJson(dealCidGravityResponse{ + Status: Unknown, + Reason: "SENT", + Message: "this case should normally never happend : unknown", + Multiaddresses: addrInfo.Addrs, + PeerId: addrInfo.ID, + DealProtocolsSupported: x, + GetAskPricePerGib: chain_types.FIL(ask.Price).String(), + GetAskVerifiedPricePerGib: chain_types.FIL(ask.VerifiedPrice).String(), + GetAskMinPieceSize: chain_types.SizeStr(chain_types.NewInt(uint64(ask.MinPieceSize))), + GetAskMaxPieceSize: chain_types.SizeStr(chain_types.NewInt(uint64(ask.MaxPieceSize))), + GetAskSectorSize: sectorSize.ShortString(), + }) +} diff --git a/cmd/boost/deal_cmd.go b/cmd/boost/deal_cmd.go index a11d5a555..9686b448c 100644 --- a/cmd/boost/deal_cmd.go +++ b/cmd/boost/deal_cmd.go @@ -261,7 +261,7 @@ func dealCmdAction(cctx *cli.Context, isOnline bool) error { } // Create a deal proposal to storage provider using deal protocol v1.2.0 format - dealProposal, err := dealProposal(ctx, n, walletAddr, rootCid, abi.PaddedPieceSize(pieceSize), pieceCid, maddr, startEpoch, cctx.Int("duration"), cctx.Bool("verified"), providerCollateral, abi.NewTokenAmount(cctx.Int64("storage-price"))) + dealProposal, err := dealProposal(ctx, "", n, walletAddr, rootCid, abi.PaddedPieceSize(pieceSize), pieceCid, maddr, startEpoch, cctx.Int("duration"), cctx.Bool("verified"), providerCollateral, abi.NewTokenAmount(cctx.Int64("storage-price"))) if err != nil { return fmt.Errorf("failed to create a deal proposal: %w", err) } @@ -331,22 +331,41 @@ func dealCmdAction(cctx *cli.Context, isOnline bool) error { return nil } -func dealProposal(ctx context.Context, n *clinode.Node, clientAddr address.Address, rootCid cid.Cid, pieceSize abi.PaddedPieceSize, pieceCid cid.Cid, minerAddr address.Address, startEpoch abi.ChainEpoch, duration int, verified bool, providerCollateral abi.TokenAmount, storagePrice abi.TokenAmount) (*market.ClientDealProposal, error) { +func dealProposal(ctx context.Context, label string, n *clinode.Node, clientAddr address.Address, rootCid cid.Cid, pieceSize abi.PaddedPieceSize, pieceCid cid.Cid, minerAddr address.Address, startEpoch abi.ChainEpoch, duration int, verified bool, providerCollateral abi.TokenAmount, storagePrice abi.TokenAmount) (*market.ClientDealProposal, error) { endEpoch := startEpoch + abi.ChainEpoch(duration) // deal proposal expects total storage price for deal per epoch, therefore we // multiply pieceSize * storagePrice (which is set per epoch per GiB) and divide by 2^30 storagePricePerEpochForDeal := big.Div(big.Mul(big.NewInt(int64(pieceSize)), storagePrice), big.NewInt(int64(1<<30))) - l, err := market.NewLabelFromString(rootCid.String()) - if err != nil { - return nil, err + // If param --label is empty, use root CID + // If not, put the value in Label field (format use for CIDgravity keep-alive service) + var labelForProposal market.DealLabel + + if label != "" { + customLabel, err := market.NewLabelFromString(label) + + if err != nil { + return nil, err + } + + labelForProposal = customLabel + + } else { + l, err := market.NewLabelFromString(rootCid.String()) + + if err != nil { + return nil, err + } + + labelForProposal = l } + proposal := market.DealProposal{ PieceCID: pieceCid, PieceSize: pieceSize, VerifiedDeal: verified, Client: clientAddr, Provider: minerAddr, - Label: l, + Label: labelForProposal, StartEpoch: startEpoch, EndEpoch: endEpoch, StoragePricePerEpoch: storagePricePerEpochForDeal, diff --git a/cmd/boost/main.go b/cmd/boost/main.go index 2fdc45d29..d5efc4310 100644 --- a/cmd/boost/main.go +++ b/cmd/boost/main.go @@ -35,6 +35,7 @@ func main() { Commands: []*cli.Command{ initCmd, dealCmd, + dealCidGravityCmd, dealStatusCmd, retrieveCmd, offlineDealCmd, diff --git a/cmd/util.go b/cmd/util.go index ef6a2835b..7ddc36452 100644 --- a/cmd/util.go +++ b/cmd/util.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" "github.com/libp2p/go-libp2p/core/peer" @@ -39,6 +40,35 @@ func GetAddrInfo(ctx context.Context, api api.Gateway, maddr address.Address) (* }, nil } +func GetAddrInfoCid(ctx context.Context, api api.Gateway, maddr address.Address) (*peer.AddrInfo, *abi.SectorSize, string, error) { + minfo, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK) + if err != nil { + return nil, nil, "", err + } + if minfo.PeerId == nil { + return nil, nil, "ERR_NO_PEER_ID_SET_ON_CHAIN", fmt.Errorf("storage provider %s has no peer ID set on-chain", maddr) + } + + var maddrs []multiaddr.Multiaddr + + if len(minfo.Multiaddrs) == 0 { + return nil, nil, "ERR_NO_MULTI_ADDRESS_SET_ON_CHAIN", fmt.Errorf("storage provider %s has no multiaddrs set on-chain", maddr) + } + + for _, mma := range minfo.Multiaddrs { + ma, err := multiaddr.NewMultiaddrBytes(mma) + if err != nil { + return nil, nil, "ERR_INVALID_MULTI_ADDRESS_IN_MINER_INFO", fmt.Errorf("storage provider %s had invalid multiaddrs in their info: %w", maddr, err) + } + maddrs = append(maddrs, ma) + } + + return &peer.AddrInfo{ + ID: *minfo.PeerId, + Addrs: maddrs, + }, &minfo.SectorSize, "", nil +} + func PrintJson(obj interface{}) error { resJson, err := json.MarshalIndent(obj, "", " ") if err != nil { From 86c3a3830fcb4deb9ef990a0017b2d1224b7f5ca Mon Sep 17 00:00:00 2001 From: Florian RUEN Date: Thu, 25 Jul 2024 18:38:40 +0200 Subject: [PATCH 2/4] feat: upgrade to lotus v1.28.1 --- .qodo/history.sqlite | Bin 0 -> 20480 bytes .vscode/settings.json | 14 ++++++++++++++ extern/filecoin-ffi | 2 +- go.sum | 2 ++ 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 .qodo/history.sqlite create mode 100644 .vscode/settings.json diff --git a/.qodo/history.sqlite b/.qodo/history.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..61be47a3f6ad6a412e984272b883c61e47d38ea8 GIT binary patch literal 20480 zcmeI%J#W)M7zc1Wbz2lEZMQ58w?s)KgoGFn8^*aHt9Du(SE38nHNK=L`33AtRf(-I z@hSKwd@V-q5+}7mMe4v3{VmzK=k9#*^Ly;U^7OqYBq#H{NSP!rjT6H(jW>iChS5^{ zzS=jNj;&3ge$86@p=Qf?e)GL^{L8R9mT~ms_-DsD;tx$mKLj8E0SG_<0uX=z1Rwx` z|1EI$aqqC(@0;JgNOqO**)@|<%FB{1c-aUnC!lsnNoc?IC}|9lL7R~3BzHtY`XMCe zf$Q7BB{`*+&(x^AE;x&;LESM^vE;EW$w;jlx;`Z%I<_yokT@4XKqq0OJEx)TpX>QW zp77PmI>-yL5ShQe%-W)99^X%jnPl5D^hn~dE1qn-W_g;jEZ)Y;k{53FX(_iovQOIt*{;`2O=Jlvx&;Wql(F~r;a_M?cr Date: Sat, 22 Feb 2025 19:11:54 +0100 Subject: [PATCH 3/4] fix: update get ask requirements --- cmd/boost/deal_cidgravity_cmd.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/boost/deal_cidgravity_cmd.go b/cmd/boost/deal_cidgravity_cmd.go index 19224267d..ccaa7b002 100644 --- a/cmd/boost/deal_cidgravity_cmd.go +++ b/cmd/boost/deal_cidgravity_cmd.go @@ -362,12 +362,12 @@ func dealCidGravityCmdAction(cctx *cli.Context) error { }) } - // To work with CIDgravity, the min size must be set to 256B and max size must be set to {sectorSize} - if ask.MinPieceSize != 256 || ask.MaxPieceSize != abi.PaddedPieceSize(*sectorSize) { + // To work with CIDgravity, the min size must be set >= 256B and max size must be set to {sectorSize} + if ask.MinPieceSize > 256 || ask.MaxPieceSize != abi.PaddedPieceSize(*sectorSize) { return cmd.PrintJson(dealCidGravityResponse{ Status: Unavailable, Reason: "ERR_GET_ASK_SIZES_NOT_PROPERLY_SET", - Message: "get-ask accepting size must be min=256B and max=" + sectorSize.ShortString(), + Message: "get-ask accepting size must be min<=256B and max=" + sectorSize.ShortString(), Multiaddresses: addrInfo.Addrs, PeerId: addrInfo.ID, DealProtocolsSupported: x, From 7eddde116754054c482ce5919dbdddc467181fd0 Mon Sep 17 00:00:00 2001 From: Florian RUEN Date: Thu, 10 Apr 2025 20:49:05 +0200 Subject: [PATCH 4/4] feat: rebase --- go.mod | 1 + go.work.sum | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 997edf975..e5f3519a5 100644 --- a/go.mod +++ b/go.mod @@ -30,6 +30,7 @@ require ( github.com/filecoin-project/go-ds-versioning v0.1.2 github.com/filecoin-project/go-fil-commcid v0.2.0 github.com/filecoin-project/go-fil-commp-hashhash v0.2.0 + github.com/filecoin-project/go-fil-markets v1.28.3 github.com/filecoin-project/go-jsonrpc v0.7.0 github.com/filecoin-project/go-padreader v0.0.1 github.com/filecoin-project/go-paramfetch v0.0.4 diff --git a/go.work.sum b/go.work.sum index 94ac09e04..5f9a0d711 100644 --- a/go.work.sum +++ b/go.work.sum @@ -2608,8 +2608,6 @@ github.com/filecoin-project/kubo-api-client v0.0.1/go.mod h1:c36PPMIVOkKfHDwDG5U github.com/filecoin-project/lotus v1.25.0-rc1/go.mod h1:L4HPpbCl0dvIVLW/anT1iBu1/CURDYN9n4ULKkDZ5ps= github.com/filecoin-project/lotus v1.25.3-0.20240228124156-fc6229abf7f4 h1:ccee29n37fR0ymXBL3rSPSY+56AuLXBuIeMFcZmVy0g= github.com/filecoin-project/lotus v1.25.3-0.20240228124156-fc6229abf7f4/go.mod h1:m2HZtRLwJKm2WVBFzYitQqq4Jqb2wcxzR1qWHNVUHuY= -github.com/filecoin-project/lotus v1.32.2 h1:UQsJgLeZVKE7dPc171va7LlIBYN5XTSqrCs8hooGcik= -github.com/filecoin-project/lotus v1.32.2/go.mod h1:eNfZ0eXGMckDBFQmL1/MJk/0UgxVKHy74z40uMrGlg4= github.com/filecoin-project/specs-storage v0.4.1 h1:yvLEaLZj8f+uByhNC4mFOtCUyL2wQku+NGBp6hjTe9M= github.com/filecoin-project/storetheindex v0.4.17 h1:w0dVc954TGPukoVbidlYvn9Xt+wVhk5vBvrqeJiRo8I= github.com/filecoin-project/test-vectors/schema v0.0.7 h1:hhrcxLnQR2Oe6fjk63hZXG1fWQGyxgCVXOOlAlR/D9A= @@ -3475,6 +3473,7 @@ github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8t github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6 h1:KAZ1BW2TCmT6PRihDPpocIy1QTtsAsrx6TneU/4+CMg= github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada h1:3L+neHp83cTjegPdCiOxVOJtRIy7/8RldvMTsyPYH10= github.com/koalacxr/quantile v0.0.1 h1:wAW+SQ286Erny9wOjVww96t8ws+x5Zj6AKHDULUK+o0= @@ -4774,7 +4773,6 @@ go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= @@ -5451,6 +5449,7 @@ google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:+Rvu7ElI google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= google.golang.org/genproto v0.0.0-20240205150955-31a09d347014/go.mod h1:xEgQu1e4stdSSsxPDK8Azkrk/ECl5HvdPf6nbZrTS5M= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=