feat: cli: lotus client list-asks --protocols

This commit is contained in:
Łukasz Magiera 2022-04-11 19:49:52 +02:00
parent 66f88773c0
commit 6bef1aeb82
9 changed files with 79 additions and 26 deletions

View File

@ -360,7 +360,7 @@ type FullNode interface {
// ClientGetRetrievalUpdates returns status of updated retrieval deals // ClientGetRetrievalUpdates returns status of updated retrieval deals
ClientGetRetrievalUpdates(ctx context.Context) (<-chan RetrievalInfo, error) //perm:write ClientGetRetrievalUpdates(ctx context.Context) (<-chan RetrievalInfo, error) //perm:write
// ClientQueryAsk returns a signed StorageAsk from the specified miner. // ClientQueryAsk returns a signed StorageAsk from the specified miner.
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) //perm:read ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*StorageAsk, error) //perm:read
// ClientCalcCommP calculates the CommP and data size of the specified CID // ClientCalcCommP calculates the CommP and data size of the specified CID
ClientDealPieceCID(ctx context.Context, root cid.Cid) (DataCIDSize, error) //perm:read ClientDealPieceCID(ctx context.Context, root cid.Cid) (DataCIDSize, error) //perm:read
// ClientCalcCommP calculates the CommP for a specified file // ClientCalcCommP calculates the CommP for a specified file
@ -728,6 +728,12 @@ type FullNode interface {
CreateBackup(ctx context.Context, fpath string) error //perm:admin CreateBackup(ctx context.Context, fpath string) error //perm:admin
} }
type StorageAsk struct {
Response *storagemarket.StorageAsk
DealProtocols []string
}
type FileRef struct { type FileRef struct {
Path string Path string
IsCAR bool IsCAR bool

View File

@ -14,7 +14,6 @@ import (
bitfield "github.com/filecoin-project/go-bitfield" bitfield "github.com/filecoin-project/go-bitfield"
datatransfer "github.com/filecoin-project/go-data-transfer" datatransfer "github.com/filecoin-project/go-data-transfer"
retrievalmarket "github.com/filecoin-project/go-fil-markets/retrievalmarket" retrievalmarket "github.com/filecoin-project/go-fil-markets/retrievalmarket"
storagemarket "github.com/filecoin-project/go-fil-markets/storagemarket"
auth "github.com/filecoin-project/go-jsonrpc/auth" auth "github.com/filecoin-project/go-jsonrpc/auth"
abi "github.com/filecoin-project/go-state-types/abi" abi "github.com/filecoin-project/go-state-types/abi"
big "github.com/filecoin-project/go-state-types/big" big "github.com/filecoin-project/go-state-types/big"
@ -746,10 +745,10 @@ func (mr *MockFullNodeMockRecorder) ClientMinerQueryOffer(arg0, arg1, arg2, arg3
} }
// ClientQueryAsk mocks base method. // ClientQueryAsk mocks base method.
func (m *MockFullNode) ClientQueryAsk(arg0 context.Context, arg1 peer.ID, arg2 address.Address) (*storagemarket.StorageAsk, error) { func (m *MockFullNode) ClientQueryAsk(arg0 context.Context, arg1 peer.ID, arg2 address.Address) (*api.StorageAsk, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ClientQueryAsk", arg0, arg1, arg2) ret := m.ctrl.Call(m, "ClientQueryAsk", arg0, arg1, arg2)
ret0, _ := ret[0].(*storagemarket.StorageAsk) ret0, _ := ret[0].(*api.StorageAsk)
ret1, _ := ret[1].(error) ret1, _ := ret[1].(error)
return ret0, ret1 return ret0, ret1
} }

View File

@ -190,7 +190,7 @@ type FullNodeStruct struct {
ClientMinerQueryOffer func(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (QueryOffer, error) `perm:"read"` ClientMinerQueryOffer func(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (QueryOffer, error) `perm:"read"`
ClientQueryAsk func(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) `perm:"read"` ClientQueryAsk func(p0 context.Context, p1 peer.ID, p2 address.Address) (*StorageAsk, error) `perm:"read"`
ClientRemoveImport func(p0 context.Context, p1 imports.ID) error `perm:"admin"` ClientRemoveImport func(p0 context.Context, p1 imports.ID) error `perm:"admin"`
@ -1571,14 +1571,14 @@ func (s *FullNodeStub) ClientMinerQueryOffer(p0 context.Context, p1 address.Addr
return *new(QueryOffer), ErrNotSupported return *new(QueryOffer), ErrNotSupported
} }
func (s *FullNodeStruct) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) { func (s *FullNodeStruct) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*StorageAsk, error) {
if s.Internal.ClientQueryAsk == nil { if s.Internal.ClientQueryAsk == nil {
return nil, ErrNotSupported return nil, ErrNotSupported
} }
return s.Internal.ClientQueryAsk(p0, p1, p2) return s.Internal.ClientQueryAsk(p0, p1, p2)
} }
func (s *FullNodeStub) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) { func (s *FullNodeStub) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*StorageAsk, error) {
return nil, ErrNotSupported return nil, ErrNotSupported
} }

View File

@ -3,6 +3,9 @@ package v0api
import ( import (
"context" "context"
"github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/retrievalmarket"
"github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/crypto"
@ -341,4 +344,12 @@ func (w *WrapperV1Full) PaychGet(ctx context.Context, from, to address.Address,
return w.FullNode.PaychFund(ctx, from, to, amt) return w.FullNode.PaychFund(ctx, from, to, amt)
} }
func (w *WrapperV1Full) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) {
a, err := w.FullNode.ClientQueryAsk(ctx, p, miner)
if err != nil {
return nil, err
}
return a.Response, nil
}
var _ FullNode = &WrapperV1Full{} var _ FullNode = &WrapperV1Full{}

Binary file not shown.

View File

@ -515,7 +515,7 @@ The minimum value is 518400 (6 months).`,
} }
func interactiveDeal(cctx *cli.Context) error { func interactiveDeal(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx) api, closer, err := GetFullNodeAPIV1(cctx)
if err != nil { if err != nil {
return err return err
} }
@ -873,7 +873,7 @@ uiLoop:
continue uiLoop continue uiLoop
} }
ask = append(ask, *a) ask = append(ask, *a.Response)
} }
// TODO: run more validation // TODO: run more validation
@ -1403,9 +1403,13 @@ var clientListAsksCmd = &cli.Command{
Value: "text", Value: "text",
Usage: "Either 'text' or 'csv'", Usage: "Either 'text' or 'csv'",
}, },
&cli.BoolFlag{
Name: "protocols",
Usage: "Output supported deal protocols",
},
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx) api, closer, err := GetFullNodeAPIV1(cctx)
if err != nil { if err != nil {
return err return err
} }
@ -1422,21 +1426,27 @@ var clientListAsksCmd = &cli.Command{
return asks[i].Ping < asks[j].Ping return asks[i].Ping < asks[j].Ping
}) })
} }
pfmt := "%s: min:%s max:%s price:%s/GiB/Epoch verifiedPrice:%s/GiB/Epoch ping:%s\n" pfmt := "%s: min:%s max:%s price:%s/GiB/Epoch verifiedPrice:%s/GiB/Epoch ping:%s protos:%s\n"
if cctx.String("output-format") == "csv" { if cctx.String("output-format") == "csv" {
fmt.Printf("Miner,Min,Max,Price,VerifiedPrice,Ping\n") fmt.Printf("Miner,Min,Max,Price,VerifiedPrice,Ping,Protocols")
pfmt = "%s,%s,%s,%s,%s,%s\n" pfmt = "%s,%s,%s,%s,%s,%s,%s\n"
} }
for _, a := range asks { for _, a := range asks {
ask := a.Ask ask := a.Ask
protos := ""
if cctx.Bool("protocols") {
protos = "[" + strings.Join(a.DealProtocols, ",") + "]"
}
fmt.Printf(pfmt, ask.Miner, fmt.Printf(pfmt, ask.Miner,
types.SizeStr(types.NewInt(uint64(ask.MinPieceSize))), types.SizeStr(types.NewInt(uint64(ask.MinPieceSize))),
types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize))), types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize))),
types.FIL(ask.Price), types.FIL(ask.Price),
types.FIL(ask.VerifiedPrice), types.FIL(ask.VerifiedPrice),
a.Ping, a.Ping,
protos,
) )
} }
@ -1445,11 +1455,13 @@ var clientListAsksCmd = &cli.Command{
} }
type QueriedAsk struct { type QueriedAsk struct {
Ask *storagemarket.StorageAsk Ask *storagemarket.StorageAsk
DealProtocols []string
Ping time.Duration Ping time.Duration
} }
func GetAsks(ctx context.Context, api v0api.FullNode) ([]QueriedAsk, error) { func GetAsks(ctx context.Context, api lapi.FullNode) ([]QueriedAsk, error) {
isTTY := true isTTY := true
if fileInfo, _ := os.Stdout.Stat(); (fileInfo.Mode() & os.ModeCharDevice) == 0 { if fileInfo, _ := os.Stdout.Stat(); (fileInfo.Mode() & os.ModeCharDevice) == 0 {
isTTY = false isTTY = false
@ -1560,7 +1572,9 @@ loop:
atomic.AddInt64(&got, 1) atomic.AddInt64(&got, 1)
lk.Lock() lk.Lock()
asks = append(asks, QueriedAsk{ asks = append(asks, QueriedAsk{
Ask: ask, Ask: ask.Response,
DealProtocols: ask.DealProtocols,
Ping: pingDuration, Ping: pingDuration,
}) })
lk.Unlock() lk.Unlock()

View File

@ -1897,14 +1897,19 @@ Inputs:
Response: Response:
```json ```json
{ {
"Price": "0", "Response": {
"VerifiedPrice": "0", "Price": "0",
"MinPieceSize": 1032, "VerifiedPrice": "0",
"MaxPieceSize": 1032, "MinPieceSize": 1032,
"Miner": "f01234", "MaxPieceSize": 1032,
"Timestamp": 10101, "Miner": "f01234",
"Expiry": 10101, "Timestamp": 10101,
"SeqNo": 42 "Expiry": 10101,
"SeqNo": 42
},
"DealProtocols": [
"string value"
]
} }
``` ```

View File

@ -794,6 +794,7 @@ CATEGORY:
OPTIONS: OPTIONS:
--by-ping sort by ping (default: false) --by-ping sort by ping (default: false)
--output-format value Either 'text' or 'csv' (default: "text") --output-format value Either 'text' or 'csv' (default: "text")
--protocols Output supported deal protocols (default: false)
--help, -h show help (default: false) --help, -h show help (default: false)
``` ```

View File

@ -1247,7 +1247,9 @@ func (a *API) newRetrievalInfo(ctx context.Context, v rm.ClientDealState) api.Re
return a.newRetrievalInfoWithTransfer(transferCh, v) return a.newRetrievalInfoWithTransfer(transferCh, v)
} }
func (a *API) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) { const dealProtoPrefix = "/fil/storage/mk/"
func (a *API) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*api.StorageAsk, error) {
mi, err := a.StateMinerInfo(ctx, miner, types.EmptyTSK) mi, err := a.StateMinerInfo(ctx, miner, types.EmptyTSK)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed getting miner info: %w", err) return nil, xerrors.Errorf("failed getting miner info: %w", err)
@ -1258,7 +1260,22 @@ func (a *API) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Addre
if err != nil { if err != nil {
return nil, err return nil, err
} }
return ask, nil res := &api.StorageAsk{
Response: ask,
}
ps, err := a.Host.Peerstore().GetProtocols(p)
if err != nil {
return nil, err
}
for _, s := range ps {
if strings.HasPrefix(s, dealProtoPrefix) {
res.DealProtocols = append(res.DealProtocols, s)
}
}
sort.Strings(res.DealProtocols)
return res, nil
} }
func (a *API) ClientCalcCommP(ctx context.Context, inpath string) (*api.CommPRet, error) { func (a *API) ClientCalcCommP(ctx context.Context, inpath string) (*api.CommPRet, error) {