From 1c288abc5892e96c4751b12310b3bc461f8b871f Mon Sep 17 00:00:00 2001 From: Florian Ruen Date: Wed, 5 Jul 2023 18:06:57 +0200 Subject: [PATCH] feat: update from main boost repo --- .qodo/history.sqlite | Bin 0 -> 20480 bytes .vscode/settings.json | 14 + cmd/boost/deal_cidgravity_cmd.go | 500 +++++++++++++++++++++++++++++++ cmd/boost/deal_cmd.go | 31 +- cmd/boost/main.go | 1 + cmd/util.go | 30 ++ go.mod | 2 +- go.sum | 2 + go.work.sum | 1 + 9 files changed, 574 insertions(+), 7 deletions(-) create mode 100644 .qodo/history.sqlite create mode 100644 .vscode/settings.json create mode 100644 cmd/boost/deal_cidgravity_cmd.go 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= 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 17ab2c971..adf97ba0a 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) } @@ -333,22 +333,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 { diff --git a/go.mod b/go.mod index f2cd0975e..c530e59f0 100644 --- a/go.mod +++ b/go.mod @@ -31,7 +31,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-jsonrpc v0.8.0 + 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 github.com/filecoin-project/go-state-types v0.17.0 diff --git a/go.sum b/go.sum index 9d3fb75f9..6db8d5c56 100644 --- a/go.sum +++ b/go.sum @@ -361,6 +361,8 @@ github.com/filecoin-project/go-fil-commcid v0.2.0 h1:B+5UX8XGgdg/XsdUpST4pEBviKk github.com/filecoin-project/go-fil-commcid v0.2.0/go.mod h1:8yigf3JDIil+/WpqR5zoKyP0jBPCOGtEqq/K1CcMy9Q= github.com/filecoin-project/go-fil-commp-hashhash v0.2.0 h1:HYIUugzjq78YvV3vC6rL95+SfC/aSTVSnZSZiDV5pCk= github.com/filecoin-project/go-fil-commp-hashhash v0.2.0/go.mod h1:VH3fAFOru4yyWar4626IoS5+VGE8SfZiBODJLUigEo4= +github.com/filecoin-project/go-fil-markets v1.28.3 h1:2cFu7tLZYrfNz4LnxjgERaVD7k5+Wwp0H76mnnTGPBk= +github.com/filecoin-project/go-fil-markets v1.28.3/go.mod h1:eryxo/oVgIxaR5g5CNr9PlvZOi+u/bak0IsPL/PT1hk= 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/go.work.sum b/go.work.sum index 4a04259d7..1f0c37d97 100644 --- a/go.work.sum +++ b/go.work.sum @@ -6048,6 +6048,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=