Merge pull request #7312 from filecoin-project/nonsense/crossref-datatransfer-storagedeal
add `lotus-miner storage-deals list --format=json` with transfers
This commit is contained in:
		
						commit
						0e7e665e6d
					
				| @ -3,6 +3,7 @@ package main | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"context" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| @ -28,6 +29,7 @@ import ( | ||||
| 	"github.com/filecoin-project/go-fil-markets/storagemarket" | ||||
| 	"github.com/filecoin-project/go-state-types/abi" | ||||
| 
 | ||||
| 	"github.com/filecoin-project/lotus/api" | ||||
| 	"github.com/filecoin-project/lotus/build" | ||||
| 	"github.com/filecoin-project/lotus/chain/types" | ||||
| 	lcli "github.com/filecoin-project/lotus/cli" | ||||
| @ -386,6 +388,11 @@ var dealsListCmd = &cli.Command{ | ||||
| 	Name:  "list", | ||||
| 	Usage: "List all deals for this miner", | ||||
| 	Flags: []cli.Flag{ | ||||
| 		&cli.StringFlag{ | ||||
| 			Name:  "format", | ||||
| 			Usage: "output format of data, supported: table, json", | ||||
| 			Value: "table", | ||||
| 		}, | ||||
| 		&cli.BoolFlag{ | ||||
| 			Name:    "verbose", | ||||
| 			Aliases: []string{"v"}, | ||||
| @ -396,63 +403,74 @@ var dealsListCmd = &cli.Command{ | ||||
| 		}, | ||||
| 	}, | ||||
| 	Action: func(cctx *cli.Context) error { | ||||
| 		api, closer, err := lcli.GetMarketsAPI(cctx) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		switch cctx.String("format") { | ||||
| 		case "table": | ||||
| 			return listDealsWithTable(cctx) | ||||
| 		case "json": | ||||
| 			return listDealsWithJSON(cctx) | ||||
| 		} | ||||
| 		defer closer() | ||||
| 
 | ||||
| 		ctx := lcli.DaemonContext(cctx) | ||||
| 		return fmt.Errorf("unknown format: %s; use `table` or `json`", cctx.String("format")) | ||||
| 	}, | ||||
| } | ||||
| 
 | ||||
| 		deals, err := api.MarketListIncompleteDeals(ctx) | ||||
| func listDealsWithTable(cctx *cli.Context) error { | ||||
| 	api, closer, err := lcli.GetMarketsAPI(cctx) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer closer() | ||||
| 
 | ||||
| 	ctx := lcli.DaemonContext(cctx) | ||||
| 
 | ||||
| 	deals, err := api.MarketListIncompleteDeals(ctx) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	verbose := cctx.Bool("verbose") | ||||
| 	watch := cctx.Bool("watch") | ||||
| 
 | ||||
| 	if watch { | ||||
| 		updates, err := api.MarketGetDealUpdates(ctx) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		verbose := cctx.Bool("verbose") | ||||
| 		watch := cctx.Bool("watch") | ||||
| 		for { | ||||
| 			tm.Clear() | ||||
| 			tm.MoveCursor(1, 1) | ||||
| 
 | ||||
| 		if watch { | ||||
| 			updates, err := api.MarketGetDealUpdates(ctx) | ||||
| 			err = outputStorageDealsTable(tm.Output, deals, verbose) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 
 | ||||
| 			for { | ||||
| 				tm.Clear() | ||||
| 				tm.MoveCursor(1, 1) | ||||
| 			tm.Flush() | ||||
| 
 | ||||
| 				err = outputStorageDeals(tm.Output, deals, verbose) | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 			select { | ||||
| 			case <-ctx.Done(): | ||||
| 				return nil | ||||
| 			case updated := <-updates: | ||||
| 				var found bool | ||||
| 				for i, existing := range deals { | ||||
| 					if existing.ProposalCid.Equals(updated.ProposalCid) { | ||||
| 						deals[i] = updated | ||||
| 						found = true | ||||
| 						break | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				tm.Flush() | ||||
| 
 | ||||
| 				select { | ||||
| 				case <-ctx.Done(): | ||||
| 					return nil | ||||
| 				case updated := <-updates: | ||||
| 					var found bool | ||||
| 					for i, existing := range deals { | ||||
| 						if existing.ProposalCid.Equals(updated.ProposalCid) { | ||||
| 							deals[i] = updated | ||||
| 							found = true | ||||
| 							break | ||||
| 						} | ||||
| 					} | ||||
| 					if !found { | ||||
| 						deals = append(deals, updated) | ||||
| 					} | ||||
| 				if !found { | ||||
| 					deals = append(deals, updated) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 		return outputStorageDeals(os.Stdout, deals, verbose) | ||||
| 	}, | ||||
| 	return outputStorageDealsTable(os.Stdout, deals, verbose) | ||||
| } | ||||
| 
 | ||||
| func outputStorageDeals(out io.Writer, deals []storagemarket.MinerDeal, verbose bool) error { | ||||
| func outputStorageDealsTable(out io.Writer, deals []storagemarket.MinerDeal, verbose bool) error { | ||||
| 	sort.Slice(deals, func(i, j int) bool { | ||||
| 		return deals[i].CreationTime.Time().Before(deals[j].CreationTime.Time()) | ||||
| 	}) | ||||
| @ -891,3 +909,76 @@ var dealsPendingPublish = &cli.Command{ | ||||
| 		return nil | ||||
| 	}, | ||||
| } | ||||
| 
 | ||||
| func listDealsWithJSON(cctx *cli.Context) error { | ||||
| 	node, closer, err := lcli.GetMarketsAPI(cctx) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer closer() | ||||
| 
 | ||||
| 	ctx := lcli.DaemonContext(cctx) | ||||
| 
 | ||||
| 	deals, err := node.MarketListIncompleteDeals(ctx) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	channels, err := node.MarketListDataTransfers(ctx) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	sort.Slice(deals, func(i, j int) bool { | ||||
| 		return deals[i].CreationTime.Time().Before(deals[j].CreationTime.Time()) | ||||
| 	}) | ||||
| 
 | ||||
| 	channelsByTransferID := map[datatransfer.TransferID]api.DataTransferChannel{} | ||||
| 	for _, c := range channels { | ||||
| 		channelsByTransferID[c.TransferID] = c | ||||
| 	} | ||||
| 
 | ||||
| 	w := json.NewEncoder(os.Stdout) | ||||
| 
 | ||||
| 	for _, deal := range deals { | ||||
| 		val := struct { | ||||
| 			DateTime        string                   `json:"datetime"` | ||||
| 			VerifiedDeal    bool                     `json:"verified-deal"` | ||||
| 			ProposalCID     string                   `json:"proposal-cid"` | ||||
| 			DealID          abi.DealID               `json:"deal-id"` | ||||
| 			DealStatus      string                   `json:"deal-status"` | ||||
| 			Client          string                   `json:"client"` | ||||
| 			PieceSize       string                   `json:"piece-size"` | ||||
| 			Price           types.FIL                `json:"price"` | ||||
| 			DurationEpochs  abi.ChainEpoch           `json:"duration-epochs"` | ||||
| 			TransferID      *datatransfer.TransferID `json:"transfer-id,omitempty"` | ||||
| 			TransferStatus  string                   `json:"transfer-status,omitempty"` | ||||
| 			TransferredData string                   `json:"transferred-data,omitempty"` | ||||
| 		}{} | ||||
| 
 | ||||
| 		val.DateTime = deal.CreationTime.Time().Format(time.RFC3339) | ||||
| 		val.VerifiedDeal = deal.Proposal.VerifiedDeal | ||||
| 		val.ProposalCID = deal.ProposalCid.String() | ||||
| 		val.DealID = deal.DealID | ||||
| 		val.DealStatus = storagemarket.DealStates[deal.State] | ||||
| 		val.Client = deal.Proposal.Client.String() | ||||
| 		val.PieceSize = units.BytesSize(float64(deal.Proposal.PieceSize)) | ||||
| 		val.Price = types.FIL(types.BigMul(deal.Proposal.StoragePricePerEpoch, types.NewInt(uint64(deal.Proposal.Duration())))) | ||||
| 		val.DurationEpochs = deal.Proposal.Duration() | ||||
| 
 | ||||
| 		if deal.TransferChannelId != nil { | ||||
| 			if c, ok := channelsByTransferID[deal.TransferChannelId.ID]; ok { | ||||
| 				val.TransferID = &c.TransferID | ||||
| 				val.TransferStatus = datatransfer.Statuses[c.Status] | ||||
| 				val.TransferredData = units.BytesSize(float64(c.Transferred)) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		err := w.Encode(val) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -658,9 +658,10 @@ USAGE: | ||||
|    lotus-miner storage-deals list [command options] [arguments...] | ||||
| 
 | ||||
| OPTIONS: | ||||
|    --verbose, -v  (default: false) | ||||
|    --watch        watch deal updates in real-time, rather than a one time list (default: false) | ||||
|    --help, -h     show help (default: false) | ||||
|    --format value  output format of data, supported: table, json (default: "table") | ||||
|    --verbose, -v   (default: false) | ||||
|    --watch         watch deal updates in real-time, rather than a one time list (default: false) | ||||
|    --help, -h      show help (default: false) | ||||
|     | ||||
| ``` | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user