cli

package
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 20, 2022 License: Apache-2.0, MIT Imports: 23 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var CIDNetCMD = &cli.Command{
	Name:        "cidnet",
	Usage:       "access cid network functions",
	Description: "This command outputs a list of cid network functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		CIDNetSearchOfferCMD,
		CIDNetQueryOfferCMD,
		PieceCMD,
		CServingCMD,
	},
}

CID network command.

View Source
var CIDNetQueryOfferCMD = &cli.Command{
	Name:        "query",
	Usage:       "query piece offer from given peer",
	Description: "Query a given peer for a piece offer with given currency",
	ArgsUsage:   "[cid, currency id, peer addr]",
	Action: func(c *cli.Context) error {

		id, err := cid.Parse(c.Args().Get(0))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse cid: %v", err.Error()))
		}
		currencyID, err := strconv.ParseUint(c.Args().Get(1), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		peerAddr := c.Args().Get(2)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		offer, err := client.COfferProtoQueryOffer(c.Context, byte(currencyID), peerAddr, id)
		if err != nil {
			return err
		}
		fmt.Printf("Piece offer:\n")
		offerData, err := offer.Encode()
		if err != nil {
			fmt.Printf("\tFail to encode: %v\n", err.Error())
			return err
		}
		fmt.Printf("\tsize %v\n", offer.Size)
		fmt.Printf("\tprice per byte %v\n", offer.PPB)
		fmt.Printf("\tsender %v\n", offer.RecipientAddr)
		fmt.Printf("\tlinked miner %v (Type %v)\n", offer.LinkedMinerAddr, offer.LinkedMinerKeyType)
		fmt.Printf("\texpiration %v\n", offer.Expiration)
		fmt.Printf("\tinactivity %v\n", offer.Inactivity)
		fmt.Printf("\toffer data: %v\n", base64.StdEncoding.EncodeToString(offerData))
		return nil
	},
}
View Source
var CIDNetSearchOfferCMD = &cli.Command{
	Name:        "search",
	Usage:       "search piece offer",
	Description: "Search the cid network for a piece offer with given currency",
	ArgsUsage:   "[cid, currency id, max]",
	Action: func(c *cli.Context) error {

		id, err := cid.Parse(c.Args().Get(0))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse cid: %v", err.Error()))
		}
		currencyID, err := strconv.ParseUint(c.Args().Get(1), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		max, err := strconv.ParseUint(c.Args().Get(2), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse max: %v", err.Error()))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		offerChan := client.COfferProtoFindOffersAsync(c.Context, byte(currencyID), id, int(max))
		i := 0
		for offer := range offerChan {
			fmt.Printf("Piece offer %v:\n", i)
			offerData, err := offer.Encode()
			if err != nil {
				fmt.Printf("\tFail to encode: %v\n", err.Error())
				continue
			}
			fmt.Printf("\tsize %v\n", offer.Size)
			fmt.Printf("\tprice per byte %v\n", offer.PPB)
			fmt.Printf("\tsender %v\n", offer.RecipientAddr)
			fmt.Printf("\tlinked miner %v (Type %v)\n", offer.LinkedMinerAddr, offer.LinkedMinerKeyType)
			fmt.Printf("\texpiration %v\n", offer.Expiration)
			fmt.Printf("\tinactivity %v\n", offer.Inactivity)
			fmt.Printf("\toffer data: %v\n", base64.StdEncoding.EncodeToString(offerData))
			i++
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var CServingCMD = &cli.Command{
	Name:        "serving",
	Usage:       "Access serving functions",
	Description: "This command outputs a list of piece serving functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		CServingServeCMD,
		CServingListCMD,
		CServingInspectCMD,
		CServingStopCMD,
		CServingSetMinerProofCMD,
		CServingGetMinerProofCMD,
	},
}

CID serving command.

View Source
var CServingGetMinerProofCMD = &cli.Command{
	Name:        "get-miner-proof",
	Usage:       "get the miner proof for served piece",
	Description: "Get the miner proof for served piece for given currency id",
	ArgsUsage:   "[currency id]",
	Action: func(c *cli.Context) error {

		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		res, err := client.MPSGetMinerProof(c.Context, byte(currencyID))
		if err != nil {
			return err
		}
		if !res.Exists {
			fmt.Println("Not set")
		} else {
			fmt.Printf("Linked miner: %v (Type %v), Proof: %v\n", res.MinerAddr, res.MinerKeyType, base64.StdEncoding.EncodeToString(res.Proof))
		}
		return nil
	},
}
View Source
var CServingInspectCMD = &cli.Command{
	Name:        "inspect",
	Usage:       "inspect a served piece",
	Description: "Inspect the details of a given piece",
	ArgsUsage:   "[cid, currency id]",
	Action: func(c *cli.Context) error {

		id, err := cid.Parse(c.Args().Get(0))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse cid: %v", err.Error()))
		}
		currencyID, err := strconv.ParseUint(c.Args().Get(1), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		res, err := client.CServMgrInspect(c.Context, id, byte(currencyID))
		if err != nil {
			return err
		}
		if res.Served {
			fmt.Printf("Piece %v (Currency %v):\n", id.String(), currencyID)
			fmt.Printf("\tPrice per byte: %v\n", res.PPB)
		} else {
			fmt.Printf("Piece %v does not exist\n", id.String())
		}
		return nil
	},
}
View Source
var CServingListCMD = &cli.Command{
	Name:        "list",
	Aliases:     []string{"ls"},
	Usage:       "list served pieces",
	Description: "List pieces that are currently being served",
	ArgsUsage:   " ",
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "long",
			Aliases: []string{"l"},
			Usage:   "display details",
		},
	},
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		idChan := client.CServMgrListPieceIDs(c.Context)
		for id := range idChan {
			curChan := client.CServMgrListCurrencyIDs(c.Context, id)
			for currencyID := range curChan {
				if c.IsSet("long") {
					res, err := client.CServMgrInspect(c.Context, id, byte(currencyID))
					if err != nil {
						return err
					}
					if res.Served {
						fmt.Printf("Piece %v (Currency %v): PPB %v\n", id.String(), currencyID, res.PPB)
					}
				} else {
					fmt.Printf("Piece %v (Currency %v)\n", id.String(), currencyID)
				}
			}
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var CServingServeCMD = &cli.Command{
	Name:        "serve",
	Usage:       "serve piece to network",
	Description: "Start serving a piece with given price",
	ArgsUsage:   "[cid, currency id, ppb]",
	Action: func(c *cli.Context) error {

		id, err := cid.Parse(c.Args().Get(0))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse cid: %v", err.Error()))
		}
		currencyID, err := strconv.ParseUint(c.Args().Get(1), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		ppb, ok := big.NewInt(0).SetString(c.Args().Get(2), 10)
		if !ok {
			return usageError(c, fmt.Errorf("fail to parse ppb"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.CServMgrServe(c.Context, id, byte(currencyID), ppb)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var CServingSetMinerProofCMD = &cli.Command{
	Name:        "set-miner-proof",
	Usage:       "set the miner proof for served piece",
	Description: "Set the miner proof for served piece for given currency id",
	ArgsUsage:   "[currency id, miner key type, miner address, base64 proof]",
	Action: func(c *cli.Context) error {

		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		keyType, err := strconv.ParseUint(c.Args().Get(1), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse key type: %v", err.Error()))
		}
		minerAddr := c.Args().Get(2)
		if minerAddr == "" {
			return usageError(c, fmt.Errorf("received empty miner addr"))
		}
		proof, err := base64.StdEncoding.DecodeString(c.Args().Get(3))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse proof: %v", err.Error()))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.MPSUpsertMinerProof(c.Context, byte(currencyID), byte(keyType), minerAddr, proof)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var CServingStopCMD = &cli.Command{
	Name:        "stop",
	Usage:       "stop a served piece",
	Description: "Stop serving a given piece and currency id pair",
	ArgsUsage:   "[cid, currency id]",
	Action: func(c *cli.Context) error {

		id, err := cid.Parse(c.Args().Get(0))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse cid: %v", err.Error()))
		}
		currencyID, err := strconv.ParseUint(c.Args().Get(1), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.CServMgrStop(c.Context, id, byte(currencyID))
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var DaemonCMD = &cli.Command{
	Name:        "daemon",
	Usage:       "start daemon",
	Description: "This command starts a running FCR daemon",
	ArgsUsage:   " ",
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:    "config",
			Aliases: []string{"c"},
			Value:   "",
			Usage:   "specify config file",
		},
	},
	Action: func(c *cli.Context) error {
		return daemon.Daemon(c.Context, c.String("config"))
	},
}

Daemon command.

View Source
var FastRetrieveCMD = &cli.Command{
	Name:        "fast-retrieve",
	Usage:       "fast retrieve a piece",
	Description: "Fast retrieve a piece from network using pre-set strategy",
	ArgsUsage:   "[cid, outpath, currency id, max amount]",
	Action: func(c *cli.Context) error {
		id, err := cid.Parse(c.Args().Get(0))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse cid: %v", err.Error()))
		}
		outPath := c.Args().Get(1)
		if outPath == "" {
			return usageError(c, fmt.Errorf("empty outpath received"))
		}
		outPathAbs, err := filepath.Abs(outPath)
		if err != nil {
			return fmt.Errorf("error getting path: %v", err.Error())
		}
		currencyID, err := strconv.ParseUint(c.Args().Get(2), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		max, ok := big.NewInt(0).SetString(c.Args().Get(3), 10)
		if !ok {
			return usageError(c, fmt.Errorf("fail to parse max"))
		}
		if max.Cmp(big.NewInt(0)) <= 0 {
			return usageError(c, fmt.Errorf("max amount must be positive, got %v", max))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()

		fmt.Println("Try to retrieve from cache...")
		found, err := client.RetMgrRetrieveFromCache(c.Context, id, outPathAbs)
		if err != nil {
			if !strings.Contains(err.Error(), "failed to fetch all nodes") {
				return err
			}
		}
		if found {
			fmt.Println("Retrieved from cache")
			return nil
		}

		fmt.Println("Try to retrieve using direct payment...")
		peerChan := client.ActiveOutListPeers(c.Context, byte(currencyID))
		peers := make(map[string]bool)
		for peer := range peerChan {
			peers[peer] = true
			offer, err := client.COfferProtoQueryOffer(c.Context, byte(currencyID), peer, id)
			if err != nil {
				fmt.Printf("Fail to query piece offer from %v-%v: %v\n", currencyID, peer, err.Error())
				continue
			}

			offerData, err := offer.Encode()
			if err != nil {
				fmt.Printf("Fail to encode offer: %v\n", err.Error())
				continue
			}
			required := big.NewInt(0).Mul(offer.PPB, big.NewInt(int64(offer.Size)))
			if required.Cmp(max) > 0 {
				continue
			}
			if required.Cmp(big.NewInt(0)) > 0 {

				res, err := client.PayMgrReserveForSelf(c.Context, offer.CurrencyID, offer.RecipientAddr, required, offer.Expiration, offer.Inactivity)
				if err != nil {
					fmt.Printf("Fail to reserve for %v-%v: %v\n", currencyID, peer, err.Error())
					continue
				}
				fmt.Printf("Start direct retrieval using piece offer %v and reservation %v-%v\n", base64.StdEncoding.EncodeToString(offerData), res.ResCh, res.ResID)
				resChan := client.RetMgrRetrieve(c.Context, offer, nil, res.ResCh, res.ResID, outPathAbs)
				for res := range resChan {
					if res.Err != "" {
						err = fmt.Errorf(res.Err)
						break
					}
					fmt.Printf("\r%v\t\t", res.Progress)
				}
				if err == nil {
					fmt.Printf("\nRetrieved from %v-%v with direct payment %v\n", currencyID, peer, required)
					return nil
				}
			} else {

				fmt.Printf("Start direct free retrieval using piece offer of %v\n", base64.StdEncoding.EncodeToString(offerData))
				resChan := client.RetMgrRetrieve(c.Context, offer, nil, "0", 0, outPathAbs)
				for res := range resChan {
					if res.Err != "" {
						err = fmt.Errorf(res.Err)
						break
					}
					fmt.Printf("\r%v\t\t", res.Progress)
				}
				if err == nil {
					fmt.Printf("\nRetrieved from %v-%v with free payment\n", currencyID, offer.RecipientAddr)
					return nil
				}
			}
		}

		fmt.Println("Try to retrieve using proxy payment...")
		offerChan := client.COfferProtoFindOffersAsync(c.Context, byte(currencyID), id, 0)
		for offer := range offerChan {

			if peers[offer.RecipientAddr] {
				continue
			}
			offerData, err := offer.Encode()
			if err != nil {
				fmt.Printf("Fail to encode offer: %v\n", err.Error())
				continue
			}
			if offer.PPB.Cmp(big.NewInt(0)) > 0 {

				required := big.NewInt(0).Mul(offer.PPB, big.NewInt(int64(offer.Size)))
				if required.Cmp(max) > 0 {
					continue
				}

				routeChan := client.RouteStoreListRoutesTo(c.Context, offer.CurrencyID, offer.RecipientAddr)
				for route := range routeChan {
					payOffer, err := client.POfferProtoQueryOffer(c.Context, offer.CurrencyID, route, required)
					if err != nil {
						fmt.Printf("Fail to query pay offer: %v\n", err.Error())
						continue
					}
					payOfferData, err := payOffer.Encode()
					if err != nil {
						fmt.Printf("Fail to encode pay offer: %v\n", err.Error())
						continue
					}
					if payOffer.PPP.Cmp(big.NewInt(0)) > 0 {

						temp := big.NewInt(0).Sub(required, big.NewInt(1))
						temp = big.NewInt(0).Div(temp, payOffer.Period)
						temp = big.NewInt(0).Add(temp, big.NewInt(1))
						temp = big.NewInt(0).Mul(temp, payOffer.PPP)
						total := big.NewInt(0).Add(temp, required)
						if total.Cmp(max) > 0 {
							continue
						}
					}

					res, err := client.PayMgrReserveForSelfWithOffer(c.Context, payOffer)
					if err != nil {
						fmt.Printf("Fail to reserve: %v", err.Error())
						continue
					}
					fmt.Printf("Start retrieval using piece offer %v, reservation %v-%v and payment offer %v\n", base64.StdEncoding.EncodeToString(offerData), res.ResCh, res.ResID, base64.StdEncoding.EncodeToString(payOfferData))
					resChan := client.RetMgrRetrieve(c.Context, offer, &payOffer, res.ResCh, res.ResID, outPathAbs)
					for res := range resChan {
						if res.Err != "" {
							err = fmt.Errorf(res.Err)
							break
						}
						fmt.Printf("\r%v\t\t", res.Progress)
					}
					if err == nil {
						fmt.Printf("\nRetrieved from %v-%v with proxy payment %v from %v\n", currencyID, offer.RecipientAddr, required, payOffer.SrcAddr)
						return nil
					}
				}
			} else {

				fmt.Printf("Start free retrieval using piece offer of %v\n", base64.StdEncoding.EncodeToString(offerData))
				resChan := client.RetMgrRetrieve(c.Context, offer, nil, "0", 0, outPathAbs)
				for res := range resChan {
					if res.Err != "" {
						err = fmt.Errorf(res.Err)
						break
					}
					fmt.Printf("\r%v\t\t", res.Progress)
				}
				if err == nil {
					fmt.Printf("\nRetrieved from %v-%v with free payment\n", currencyID, offer.RecipientAddr)
					return nil
				}
			}
		}
		return fmt.Errorf("fail to fast retrieve %v with max %v-%v, recommend using old offer to retry instead of using another fast-retrieve", id, currencyID, max)
	},
}
View Source
var PServingInspectCMD = &cli.Command{
	Name:        "inspect",
	Usage:       "inspect a served paych",
	Description: "Inspect the details of a given paych",
	ArgsUsage:   "[currency id, peer addr, paych addr]",
	Action: func(c *cli.Context) error {
		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		chAddr := c.Args().Get(2)
		if chAddr == "" {
			return usageError(c, fmt.Errorf("received empty paych addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		res, err := client.PservMgrInspect(c.Context, byte(currencyID), peerAddr, chAddr)
		if err != nil {
			return err
		}
		if res.Served {
			fmt.Printf("Paych %v (to %v, currency %v):\n", chAddr, peerAddr, currencyID)
			fmt.Printf("\tPPP %v\n", res.PPP)
			fmt.Printf("\tPeriod %v\n", res.Period)
		} else {
			fmt.Printf("Paych %v-%v-%v does not exist\n", currencyID, peerAddr, chAddr)
		}
		return nil
	},
}
View Source
var PServingListCMD = &cli.Command{
	Name:        "list",
	Aliases:     []string{"ls"},
	Usage:       "list served paychs",
	Description: "List paychs that are currently being served",
	ArgsUsage:   " ",
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "long",
			Aliases: []string{"l"},
			Usage:   "display details",
		},
	},
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		curChan := client.PservMgrListCurrencyIDs(c.Context)
		for currencyID := range curChan {
			peerChan := client.PservMgrListRecipients(c.Context, currencyID)
			for peer := range peerChan {
				paychChan := client.PservMgrListServings(c.Context, currencyID, peer)
				for paych := range paychChan {
					if c.IsSet("long") {
						res, err := client.PservMgrInspect(c.Context, currencyID, peer, paych)
						if err != nil {
							return err
						}
						if res.Served {
							fmt.Printf("Paych %v (to %v, currency %v): PPP %v, Period %v\n", paych, peer, currencyID, res.PPP, res.Period)
						}
					} else {
						fmt.Printf("Paych %v (to %v, currency %v)\n", paych, peer, currencyID)
					}
				}
			}
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var PServingServeCMD = &cli.Command{
	Name:        "serve",
	Usage:       "serve paych to network",
	Description: "Start serving a paych with given price",
	ArgsUsage:   "[currency id, peer addr, paych addr, ppp, period]",
	Action: func(c *cli.Context) error {
		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		chAddr := c.Args().Get(2)
		if chAddr == "" {
			return usageError(c, fmt.Errorf("received empty paych addr"))
		}
		ppp, ok := big.NewInt(0).SetString(c.Args().Get(3), 10)
		if !ok {
			return usageError(c, fmt.Errorf("fail to parse ppp"))
		}
		period, ok := big.NewInt(0).SetString(c.Args().Get(4), 10)
		if !ok {
			return usageError(c, fmt.Errorf("fail to parse period"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.PservMgrServe(c.Context, byte(currencyID), peerAddr, chAddr, ppp, period)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var PayNetCMD = &cli.Command{
	Name:        "paynet",
	Usage:       "access payment network functions",
	Description: "This command outputs a list of payment network functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		PayNetQueryOfferCMD,
		PayNetReserveCMD,
		PaychCMD,
		PservingCMD,
		PayNetPolicyCMD,
	},
}

Payment network command.

View Source
var PayNetPolicyCMD = &cli.Command{
	Name:        "policy",
	Usage:       "access policy functions",
	Description: "This command outputs a list of policy functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		SettleCMD,
		RenewCMD,
		ReserveCMD,
	},
}

Payment network policy command.

View Source
var PayNetQueryOfferCMD = &cli.Command{
	Name:        "query",
	Usage:       "query pay offer for given piece offer",
	Description: "Query network for a pay offer based on given piece offer",
	ArgsUsage:   "[piece offer]",
	Action: func(c *cli.Context) error {
		offerData, err := base64.StdEncoding.DecodeString(c.Args().Get(0))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse offer data"))
		}
		offer := fcroffer.PieceOffer{}
		err = offer.Decode(offerData)
		if err != nil {
			return err
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()

		subCtx, cancel := context.WithCancel(c.Context)
		defer cancel()
		paychChan := client.ActiveOutListPaychsByPeer(subCtx, offer.CurrencyID, offer.RecipientAddr)
		exists := false
		for range paychChan {
			exists = true
			cancel()
		}
		if exists {
			return fmt.Errorf("exists active out channel to %v with currency %v, no need to query offer", offer.RecipientAddr, offer.CurrencyID)
		}
		required := big.NewInt(0).Mul(offer.PPB, big.NewInt(int64(offer.Size)))
		routeChan := client.RouteStoreListRoutesTo(c.Context, offer.CurrencyID, offer.RecipientAddr)
		i := 0
		for route := range routeChan {
			payOffer, err := client.POfferProtoQueryOffer(c.Context, offer.CurrencyID, route, required)
			if err != nil {
				fmt.Printf("Fail to query for route %v: %v\n", route, err.Error())
				continue
			}
			fmt.Printf("Pay offer %v:\n", i)
			payOfferData, err := payOffer.Encode()
			if err != nil {
				fmt.Printf("\tFail to encode: %v\n", err.Error())
				continue
			}
			fmt.Printf("\tamount %v\n", payOffer.Amt)
			fmt.Printf("\tprice per period %v\n", payOffer.PPP)
			fmt.Printf("\tperiod %v\n", payOffer.Period)
			fmt.Printf("\texpiration %v\n", payOffer.Expiration)
			fmt.Printf("\tinactivity %v\n", payOffer.Inactivity)
			fmt.Printf("\toffer data %v\n", base64.StdEncoding.EncodeToString(payOfferData))
			i++
		}
		return nil
	},
}
View Source
var PayNetReserveCMD = &cli.Command{
	Name:        "reserve",
	Usage:       "reserve payment for given offer",
	Description: "Reserve channel balance for given piece offer or pay offer",
	ArgsUsage:   "[piece offer/pay offer]",
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "payoffer",
			Aliases: []string{"po"},
			Usage:   "indicate whether pay offer is supplied",
		},
	},
	Action: func(c *cli.Context) error {
		offerData, err := base64.StdEncoding.DecodeString(c.Args().Get(0))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse offer data"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		if c.IsSet("payoffer") {
			offer := fcroffer.PayOffer{}
			err = offer.Decode(offerData)
			if err != nil {
				return err
			}
			res, err := client.PayMgrReserveForSelfWithOffer(c.Context, offer)
			if err != nil {
				return err
			}
			fmt.Printf("Reservation: %v-%v\n", res.ResCh, res.ResID)
		} else {
			offer := fcroffer.PieceOffer{}
			err = offer.Decode(offerData)
			if err != nil {
				return err
			}
			required := big.NewInt(0).Mul(offer.PPB, big.NewInt(int64(offer.Size)))
			res, err := client.PayMgrReserveForSelf(c.Context, offer.CurrencyID, offer.RecipientAddr, required, offer.Expiration, offer.Inactivity)
			if err != nil {
				return err
			}
			fmt.Printf("Reservation: %v-%v\n", res.ResCh, res.ResID)
		}
		return nil
	},
}
View Source
var PaychActiveInCMD = &cli.Command{
	Name:        "active-in",
	Usage:       "access active in paych functions",
	Description: "This command outputs a list of active in paych functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		PaychActiveInGetCMD,
		PaychActiveInListCMD,
	},
}
View Source
var PaychActiveInGetCMD = &cli.Command{
	Name:        "get",
	Usage:       "get paych state",
	Description: "Get the state of a given paych",
	ArgsUsage:   "[currency id, peer addr, paych addr]",
	Action: func(c *cli.Context) error {

		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		paychAddr := c.Args().Get(2)
		if paychAddr == "" {
			return usageError(c, fmt.Errorf("received empty paych addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		state, err := client.ActiveInRead(c.Context, byte(currencyID), peerAddr, paychAddr)
		if err != nil {
			return err
		}
		res, err := client.PaychMonitorCheck(c.Context, false, state.CurrencyID, state.ChAddr)
		if err != nil {
			return err
		}
		fmt.Printf("Channel: %v (Currency %v):\n", paychAddr, currencyID)
		fmt.Printf("\tBalance: %v\n", state.Balance)
		fmt.Printf("\tRedeemed: %v\n", state.Redeemed)
		fmt.Printf("\tNonce: %v\n", state.Nonce)
		fmt.Printf("\tVoucher: %v\n", state.Voucher)
		fmt.Printf("\tSettlement: %v\n", res.Settlement)
		fmt.Printf("\tLast updated: %v\n", res.Updated)
		return nil
	},
}
View Source
var PaychActiveInListCMD = &cli.Command{
	Name:        "list",
	Aliases:     []string{"ls"},
	Usage:       "list all paychs",
	Description: "List all payment channels stored",
	ArgsUsage:   " ",
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "long",
			Aliases: []string{"l"},
			Usage:   "display details",
		},
	},
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		curChan := client.ActiveInListCurrencyIDs(c.Context)
		for currencyID := range curChan {
			fmt.Printf("Currency %v\n", currencyID)
			peerChan := client.ActiveInListPeers(c.Context, currencyID)
			for peer := range peerChan {
				fmt.Printf("\tPeer %v\n", peer)
				paychChan := client.ActiveInListPaychsByPeer(c.Context, currencyID, peer)
				for paych := range paychChan {
					if c.IsSet("long") {
						state, err := client.ActiveInRead(c.Context, currencyID, peer, paych)
						if err != nil {
							return err
						}
						res, err := client.PaychMonitorCheck(c.Context, false, currencyID, state.ChAddr)
						if err != nil {
							return err
						}
						fmt.Printf("\t\t%v:\n", paych)
						fmt.Printf("\t\t\tBalance %v, Redeemed %v, Nonce %v, Voucher: %v, Settlement %v, Last updated %v\n", state.Balance, state.Redeemed, state.Nonce, state.Voucher, res.Settlement, res.Updated)
					} else {
						fmt.Printf("\t\t%v\n", paych)
					}
				}
			}
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var PaychActiveOutBearNetworkLossCMD = &cli.Command{
	Name:        "bear",
	Usage:       "bear the network loss",
	Description: "Bear network loss and continue the use of active out paych",
	ArgsUsage:   "[currency id, peer addr, paych addr]",
	Action: func(c *cli.Context) error {

		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		paychAddr := c.Args().Get(2)
		if paychAddr == "" {
			return usageError(c, fmt.Errorf("received empty paych addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()

		state, err := client.ActiveOutRead(c.Context, byte(currencyID), peerAddr, paychAddr)
		if err != nil {
			return err
		}
		if state.NetworkLossVoucher == "" {
			return fmt.Errorf("No network loss found")
		}
		err = client.PayMgrBearNetworkLoss(c.Context, state.CurrencyID, peerAddr, paychAddr)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var PaychActiveOutCMD = &cli.Command{
	Name:        "active-out",
	Usage:       "access active out paych functions",
	Description: "This command outputs a list of active out paych functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		PaychActiveOutGetCMD,
		PaychActiveOutListCMD,
		PaychActiveOutBearNetworkLossCMD,
	},
}
View Source
var PaychActiveOutGetCMD = &cli.Command{
	Name:        "get",
	Usage:       "get paych state",
	Description: "Get the state of a given paych",
	ArgsUsage:   "[currency id, peer addr, paych addr]",
	Action: func(c *cli.Context) error {

		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		paychAddr := c.Args().Get(2)
		if paychAddr == "" {
			return usageError(c, fmt.Errorf("received empty paych addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		state, err := client.ActiveOutRead(c.Context, byte(currencyID), peerAddr, paychAddr)
		if err != nil {
			return err
		}
		res, err := client.PaychMonitorCheck(c.Context, true, state.CurrencyID, state.ChAddr)
		if err != nil {
			return err
		}
		loss := big.NewInt(0)
		if state.NetworkLossVoucher != "" {
			res, err := client.TransactorVerifyVoucher(state.CurrencyID, state.NetworkLossVoucher)
			if err != nil {
				return err
			}
			loss = big.NewInt(0).Sub(res.Redeemed, state.Redeemed)
		}
		fmt.Printf("Channel: %v (Currency %v):\n", paychAddr, currencyID)
		fmt.Printf("\tBalance: %v\n", state.Balance)
		fmt.Printf("\tRedeemed: %v\n", state.Redeemed)
		fmt.Printf("\tNonce: %v\n", state.Nonce)
		fmt.Printf("\tVoucher: %v\n", state.Voucher)
		fmt.Printf("\tNetwork loss voucher: %v (%v)\n", state.NetworkLossVoucher, loss)
		fmt.Printf("\tSettlement: %v\n", res.Settlement)
		fmt.Printf("\tLast updated: %v\n", res.Updated)
		return nil
	},
}
View Source
var PaychActiveOutListCMD = &cli.Command{
	Name:        "list",
	Aliases:     []string{"ls"},
	Usage:       "list all paychs",
	Description: "List all payment channels stored",
	ArgsUsage:   " ",
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "long",
			Aliases: []string{"l"},
			Usage:   "display details",
		},
	},
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		curChan := client.ActiveOutListCurrencyIDs(c.Context)
		for currencyID := range curChan {
			fmt.Printf("Currency %v\n", currencyID)
			peerChan := client.ActiveOutListPeers(c.Context, currencyID)
			for peer := range peerChan {
				fmt.Printf("\tPeer %v\n", peer)
				paychChan := client.ActiveOutListPaychsByPeer(c.Context, currencyID, peer)
				for paych := range paychChan {
					if c.IsSet("long") {
						state, err := client.ActiveOutRead(c.Context, currencyID, peer, paych)
						if err != nil {
							return err
						}
						res, err := client.PaychMonitorCheck(c.Context, true, currencyID, state.ChAddr)
						if err != nil {
							return err
						}

						loss := big.NewInt(0)
						if state.NetworkLossVoucher != "" {
							res, err := client.TransactorVerifyVoucher(currencyID, state.NetworkLossVoucher)
							if err != nil {
								return err
							}
							loss = big.NewInt(0).Sub(res.Redeemed, state.Redeemed)
						}
						fmt.Printf("\t\t%v:\n", paych)
						fmt.Printf("\t\t\tBalance %v, Redeemed %v, Nonce %v, Voucher %v, Network loss voucher %v (%v), Settlement %v, Last updated %v\n", state.Balance, state.Redeemed, state.Nonce, state.Voucher, state.NetworkLossVoucher, loss, res.Settlement, res.Updated)
					} else {
						fmt.Printf("\t\t%v\n", paych)
					}
				}
			}
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var PaychCMD = &cli.Command{
	Name:        "paych",
	Usage:       "access paych functions",
	Description: "This command outputs a list of paych functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		PaychQueryOfferCMD,
		PaychCreateCMD,
		PaychRenewCMD,
		PaychTopupCMD,
		PaychUpdateCMD,
		PaychSettleCMD,
		PaychCollectCMD,
		PaychActiveOutCMD,
		PaychActiveInCMD,
		PaychInactiveOutCMD,
		PaychInactiveInCMD,
	},
}

Paych command.

View Source
var PaychCollectCMD = &cli.Command{
	Name:        "collect",
	Usage:       "collect a settled paych",
	Description: "Collect a settled payment channel",
	ArgsUsage:   "[currency id, peer addr, paych addr]",
	Action: func(c *cli.Context) error {
		currency, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		currencyID := byte(currency)
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		chAddr := c.Args().Get(2)
		if chAddr == "" {
			return usageError(c, fmt.Errorf("received empty paych addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()

		inbound := false
		_, err = client.InactiveOutRead(c.Context, currencyID, peerAddr, chAddr)
		if err != nil {
			_, err = client.InactiveInRead(c.Context, currencyID, peerAddr, chAddr)
			if err != nil {
				return err
			}
			inbound = true
		}
		fmt.Println("Collect payment channel...")
		err = client.TransactorCollect(c.Context, currencyID, chAddr)
		if err != nil {
			return err
		}
		if inbound {
			client.InactiveInRemove(currencyID, peerAddr, chAddr)
		} else {
			client.InactiveOutRemove(currencyID, peerAddr, chAddr)
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var PaychCreateCMD = &cli.Command{
	Name:        "create",
	Usage:       "create a payment channel",
	Description: "create a payment channel for given paych offer",
	ArgsUsage:   "[paych offer, amt]",
	Action: func(c *cli.Context) error {
		offerData, err := base64.StdEncoding.DecodeString(c.Args().Get(0))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse offer data"))
		}
		amt, ok := big.NewInt(0).SetString(c.Args().Get(1), 10)
		if !ok {
			return usageError(c, fmt.Errorf("fail to parse amount"))
		}
		if amt.Cmp(big.NewInt(0)) <= 0 {
			return fmt.Errorf("expect positive amount, got %v", amt)
		}
		offer := fcroffer.PaychOffer{}
		err = offer.Decode(offerData)
		if err != nil {
			return err
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()

		fmt.Println("Create payment channel...")
		chAddr, err := client.TransactorCreate(c.Context, offer.CurrencyID, offer.ToAddr, amt)
		if err != nil {
			return err
		}
		fmt.Println(chAddr)
		fmt.Println("Add payment channel...")
		err = client.PaychProtoAdd(c.Context, chAddr, offer)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var PaychInactiveInCMD = &cli.Command{
	Name:        "inactive-in",
	Usage:       "access active in paych functions",
	Description: "This command outputs a list of inactive in paych functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		PaychInactiveInGetCMD,
		PaychInactiveInListCMD,
	},
}
View Source
var PaychInactiveInGetCMD = &cli.Command{
	Name:        "get",
	Usage:       "get paych state",
	Description: "Get the state of a given paych",
	ArgsUsage:   "[currency id, peer addr, paych addr]",
	Action: func(c *cli.Context) error {

		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		paychAddr := c.Args().Get(2)
		if paychAddr == "" {
			return usageError(c, fmt.Errorf("received empty paych addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		state, err := client.InactiveInRead(c.Context, byte(currencyID), peerAddr, paychAddr)
		if err != nil {
			return err
		}
		res, err := client.TransactorCheck(c.Context, state.CurrencyID, paychAddr)
		if err != nil {
			return err
		}
		fmt.Printf("Channel: %v (Currency %v):\n", paychAddr, currencyID)
		fmt.Printf("\tBalance: %v\n", state.Balance)
		fmt.Printf("\tRedeemed: %v\n", state.Redeemed)
		fmt.Printf("\tNonce: %v\n", state.Nonce)
		fmt.Printf("\tVoucher: %v\n", state.Voucher)
		fmt.Printf("\tSettling at: %v\n", res.SettlingAt)
		fmt.Printf("\tCurrent height: %v\n", res.CurrentHeight)
		return nil
	},
}
View Source
var PaychInactiveInListCMD = &cli.Command{
	Name:        "list",
	Aliases:     []string{"ls"},
	Usage:       "list all paychs",
	Description: "List all payment channels stored",
	ArgsUsage:   " ",
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "long",
			Aliases: []string{"l"},
			Usage:   "display details",
		},
	},
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		curChan := client.InactiveInListCurrencyIDs(c.Context)
		for currencyID := range curChan {
			fmt.Printf("Currency %v\n", currencyID)
			peerChan := client.InactiveInListPeers(c.Context, currencyID)
			for peer := range peerChan {
				fmt.Printf("\tPeer %v\n", peer)
				paychChan := client.InactiveInListPaychsByPeer(c.Context, currencyID, peer)
				for paych := range paychChan {
					if c.IsSet("long") {
						state, err := client.ActiveInRead(c.Context, currencyID, peer, paych)
						if err != nil {
							return err
						}
						res, err := client.TransactorCheck(c.Context, currencyID, paych)
						if err != nil {
							return err
						}
						fmt.Printf("\t\t%v:\n", paych)
						fmt.Printf("\t\t\tBalance %v, Redeemed %v, Nonce %v, Voucher %v, Settling at %v, Height checked %v", state.Balance, state.Redeemed, state.Nonce, state.Voucher, res.SettlingAt, res.CurrentHeight)
					} else {
						fmt.Printf("\t\t%v\n", paych)
					}
				}
			}
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var PaychInactiveOutCMD = &cli.Command{
	Name:        "inactive-out",
	Usage:       "access inactive out paych functions",
	Description: "This command outputs a list of inactive out paych functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		PaychInactiveOutGetCMD,
		PaychInactiveOutListCMD,
	},
}
View Source
var PaychInactiveOutGetCMD = &cli.Command{
	Name:        "get",
	Usage:       "get paych state",
	Description: "Get the state of a given paych",
	ArgsUsage:   "[currency id, peer addr, paych addr]",
	Action: func(c *cli.Context) error {

		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		paychAddr := c.Args().Get(2)
		if paychAddr == "" {
			return usageError(c, fmt.Errorf("received empty paych addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		state, err := client.InactiveOutRead(c.Context, byte(currencyID), peerAddr, paychAddr)
		if err != nil {
			return err
		}
		res, err := client.TransactorCheck(c.Context, state.CurrencyID, paychAddr)
		if err != nil {
			return err
		}
		loss := big.NewInt(0)
		if state.NetworkLossVoucher != "" {
			res, err := client.TransactorVerifyVoucher(state.CurrencyID, state.NetworkLossVoucher)
			if err != nil {
				return err
			}
			loss = big.NewInt(0).Sub(res.Redeemed, state.Redeemed)
		}
		fmt.Printf("Channel: %v (Currency %v):\n", paychAddr, currencyID)
		fmt.Printf("\tBalance: %v\n", state.Balance)
		fmt.Printf("\tRedeemed: %v\n", state.Redeemed)
		fmt.Printf("\tNonce: %v\n", state.Nonce)
		fmt.Printf("\tVoucher: %v\n", state.Voucher)
		fmt.Printf("\tNetwork loss voucher: %v (%v)\n", state.NetworkLossVoucher, loss)
		fmt.Printf("\tSettling at: %v\n", res.SettlingAt)
		fmt.Printf("\tCurrent height: %v\n", res.CurrentHeight)
		return nil
	},
}
View Source
var PaychInactiveOutListCMD = &cli.Command{
	Name:        "list",
	Aliases:     []string{"ls"},
	Usage:       "list all paychs",
	Description: "List all payment channels stored",
	ArgsUsage:   " ",
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "long",
			Aliases: []string{"l"},
			Usage:   "display details",
		},
	},
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		curChan := client.InactiveOutListCurrencyIDs(c.Context)
		for currencyID := range curChan {
			fmt.Printf("Currency %v\n", currencyID)
			peerChan := client.InactiveOutListPeers(c.Context, currencyID)
			for peer := range peerChan {
				fmt.Printf("\tPeer %v\n", peer)
				paychChan := client.InactiveOutListPaychsByPeer(c.Context, currencyID, peer)
				for paych := range paychChan {
					if c.IsSet("long") {
						state, err := client.InactiveOutRead(c.Context, currencyID, peer, paych)
						if err != nil {
							return err
						}
						res, err := client.TransactorCheck(c.Context, currencyID, paych)
						if err != nil {
							return err
						}
						loss := big.NewInt(0)
						if state.NetworkLossVoucher != "" {
							res, err := client.TransactorVerifyVoucher(currencyID, state.NetworkLossVoucher)
							if err != nil {
								return err
							}
							loss = big.NewInt(0).Sub(res.Redeemed, state.Redeemed)
						}
						fmt.Printf("\t\t%v:\n", paych)
						fmt.Printf("\t\t\tBalance %v, Redeemed %v, Nonce %v, Voucher, %v, Network loss voucher %v (%v), Settling at %v, Height checked %v", state.Balance, state.Redeemed, state.Nonce, state.Voucher, state.NetworkLossVoucher, loss, res.SettlingAt, res.CurrentHeight)
					} else {
						fmt.Printf("\t\t%v\n", paych)
					}
				}
			}
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var PaychQueryOfferCMD = &cli.Command{
	Name:        "query",
	Usage:       "query for paych offer",
	Description: "Query given peer the minimum settlement time for a new payment channel",
	ArgsUsage:   "[currency id, peer addr]",
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:    "cidoffer",
			Aliases: []string{"co"},
			Usage:   "override arguments and query from cidoffer",
		},
	},
	Action: func(c *cli.Context) error {
		var currencyID byte
		var peerAddr string
		if c.IsSet("cidoffer") {
			offerData, err := base64.StdEncoding.DecodeString(c.String("cidoffer"))
			if err != nil {
				return err
			}
			offer := fcroffer.PieceOffer{}
			err = offer.Decode(offerData)
			if err != nil {
				return err
			}
			currencyID = offer.CurrencyID
			peerAddr = offer.RecipientAddr
		} else {
			currency, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
			if err != nil {
				return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
			}
			currencyID = byte(currency)
			peerAddr = c.Args().Get(1)
			if peerAddr == "" {
				return usageError(c, fmt.Errorf("received empty peer addr"))
			}
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		paychOffer, err := client.PaychProtoQueryAdd(c.Context, currencyID, peerAddr)
		if err != nil {
			return err
		}
		fmt.Printf("Paych offer:\n")
		offerData, err := paychOffer.Encode()
		if err != nil {
			fmt.Printf("\tFail to encode: %v\n", err.Error())
			return err
		}
		fmt.Printf("\tcurrency %v\n", paychOffer.CurrencyID)
		fmt.Printf("\trecipient %v\n", paychOffer.ToAddr)
		fmt.Printf("\tsettlement %v\n", paychOffer.Settlement)
		fmt.Printf("\texpiration %v\n", paychOffer.Expiration)
		fmt.Printf("\toffer data: %v\n", base64.StdEncoding.EncodeToString(offerData))
		return nil
	},
}
View Source
var PaychRenewCMD = &cli.Command{
	Name:        "renew",
	Usage:       "renew an active out paych",
	Description: "Attempt to renew a outbound payment channel that is currently active",
	ArgsUsage:   "[currency id, peer addr, paych addr]",
	Action: func(c *cli.Context) error {
		currency, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		currencyID := byte(currency)
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		chAddr := c.Args().Get(2)
		if chAddr == "" {
			return usageError(c, fmt.Errorf("received empty paych addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		_, err = client.ActiveOutRead(c.Context, currencyID, peerAddr, chAddr)
		if err != nil {
			return err
		}
		err = client.PaychProtoRenew(c.Context, currencyID, peerAddr, chAddr)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var PaychSettleCMD = &cli.Command{
	Name:        "settle",
	Usage:       "settle an inactive paych",
	Description: "Settle an inactive payment channel",
	ArgsUsage:   "[currency id, peer addr, paych addr]",
	Action: func(c *cli.Context) error {
		currency, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		currencyID := byte(currency)
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		chAddr := c.Args().Get(2)
		if chAddr == "" {
			return usageError(c, fmt.Errorf("received empty paych addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()

		_, err = client.InactiveOutRead(c.Context, currencyID, peerAddr, chAddr)
		if err != nil {
			_, err = client.InactiveInRead(c.Context, currencyID, peerAddr, chAddr)
			if err != nil {
				return err
			}
		}
		fmt.Println("Settle payment channel...")
		err = client.TransactorSettle(c.Context, currencyID, chAddr)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var PaychTopupCMD = &cli.Command{
	Name:        "topup",
	Usage:       "topup an active out paych",
	Description: "Topup a outbound payment channel that is currently active",
	ArgsUsage:   "[currency id, peer addr, paych addr, amt]",
	Action: func(c *cli.Context) error {
		currency, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		currencyID := byte(currency)
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		chAddr := c.Args().Get(2)
		if chAddr == "" {
			return usageError(c, fmt.Errorf("received empty paych addr"))
		}
		amt, ok := big.NewInt(0).SetString(c.Args().Get(3), 10)
		if !ok {
			return usageError(c, fmt.Errorf("fail to parse amount"))
		}
		if amt.Cmp(big.NewInt(0)) <= 0 {
			return fmt.Errorf("expect positive amount, got %v", amt)
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		_, err = client.ActiveOutRead(c.Context, currencyID, peerAddr, chAddr)
		if err != nil {
			return err
		}
		fmt.Println("Topup payment channel...")
		err = client.TransactorTopup(c.Context, currencyID, chAddr, amt)
		if err != nil {
			return err
		}
		fmt.Println("Updating payment manager channel balance...")
		err = client.PayMgrUpdateOutboundChannelBalance(c.Context, currencyID, peerAddr, chAddr)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var PaychUpdateCMD = &cli.Command{
	Name:        "update",
	Usage:       "update a paych",
	Description: "Update the state of a payment channel",
	ArgsUsage:   "[currency id, peer addr, paych addr]",
	Action: func(c *cli.Context) error {
		currency, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		currencyID := byte(currency)
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		chAddr := c.Args().Get(2)
		if chAddr == "" {
			return usageError(c, fmt.Errorf("received empty paych addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		var state paychstate.State

		state, err = client.ActiveOutRead(c.Context, currencyID, peerAddr, chAddr)
		if err != nil {
			state, err = client.ActiveInRead(c.Context, currencyID, peerAddr, chAddr)
			if err != nil {
				state, err = client.InactiveOutRead(c.Context, currencyID, peerAddr, chAddr)
				if err != nil {
					state, err = client.InactiveInRead(c.Context, currencyID, peerAddr, chAddr)
					if err != nil {
						return err
					}
				}
			}
		}
		if state.Voucher == "" {
			return fmt.Errorf("voucher stored is empty, cannot update")
		}
		fmt.Println("Update payment channel...")
		err = client.TransactorUpdate(c.Context, currencyID, chAddr, state.Voucher)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var PeerAddCMD = &cli.Command{
	Name:        "add",
	Usage:       "add a peer",
	Description: "Add a new peer or update the peer network address",
	ArgsUsage:   "[currency id, peer addr, p2p addr]",
	Action: func(c *cli.Context) error {
		currency, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		currencyID := byte(currency)
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		p2pAddrs := strings.Split(c.Args().Get(2), "/p2p/")
		if len(p2pAddrs) != 2 {
			return usageError(c, fmt.Errorf("fail to parse p2p addr, should contain net addr and peer id"))
		}
		maddr, err := multiaddr.NewMultiaddr(p2pAddrs[0])
		if err != nil {
			return fmt.Errorf("error parsing multiaddr: %v", err.Error())
		}
		pid, err := peer.Decode(p2pAddrs[1])
		if err != nil {
			return fmt.Errorf("error parsing peer id: %v", err.Error())
		}
		pi := peer.AddrInfo{Addrs: []multiaddr.Multiaddr{maddr}, ID: pid}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.PeerMgrAddPeer(c.Context, currencyID, peerAddr, pi)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var PeerBlockCMD = &cli.Command{
	Name:        "block",
	Usage:       "block peer",
	Description: "Block a peer based on given currency id and peer address",
	ArgsUsage:   "[currency id, peer addr]",
	Action: func(c *cli.Context) error {
		currency, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		currencyID := byte(currency)
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.PeerMgrBlockPeer(c.Context, currencyID, peerAddr)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var PeerCMD = &cli.Command{
	Name:        "peer",
	Usage:       "access peer functions",
	Description: "This command outputs a list of peer functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		PeerAddCMD,
		PeerListCMD,
		PeerInspectCMD,
		PeerRemoveCMD,
		PeerBlockCMD,
		PeerUnblockCMD,
		PeerListHistoryCMD,
		PeerRemoveRecordCMD,
		PeerRemoveSetRecIDCMD,
	},
}

Peer manager command.

View Source
var PeerInspectCMD = &cli.Command{
	Name:        "inspect",
	Usage:       "inspect peer details",
	Description: "Inspect the details of a peer",
	ArgsUsage:   "[currency id, peer addr]",
	Action: func(c *cli.Context) error {
		currency, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		currencyID := byte(currency)
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		fmt.Printf("Peer %v (Currency %v):\n", peerAddr, currency)
		exists, err := client.PeerMgrHasPeer(c.Context, currencyID, peerAddr)
		if err != nil {
			return err
		}
		if !exists {
			fmt.Printf("\tDoes not exist\n")
			return nil
		}

		pi, err := client.PeerMgrPeerAddr(c.Context, currencyID, peerAddr)
		if err != nil {
			return err
		}
		res := make([]string, 0)
		for _, maddr := range pi.Addrs {
			if manet.IsPrivateAddr(maddr) {

				res = append(res, maddr.String()+"/p2p/"+pi.ID.String())
			} else {
				res = append([]string{maddr.String() + "/p2p/" + pi.ID.String()}, res...)
			}
		}
		fmt.Printf("\tNetwork Addrs: %v\n", res)
		blocked, err := client.PeerMgrIsBlocked(c.Context, currencyID, peerAddr)
		if err != nil {
			return err
		}
		fmt.Printf("\tBlocked: %v\n", blocked)
		fmt.Printf("\tRecent history:\n")

		i := 0
		recChan := client.PeerMgrListHistory(c.Context, currencyID, peerAddr)
		for rec := range recChan {
			if i == 10 {
				break
			}
			i++
			fmt.Printf("\t\t%v: %v - %v\n", rec.RecID, rec.Record.CreatedAt, rec.Record.Description)
		}
		return nil
	},
}
View Source
var PeerListCMD = &cli.Command{
	Name:        "list",
	Aliases:     []string{"ls"},
	Usage:       "list peers",
	Description: "List all peers stored in the peer manager",
	ArgsUsage:   " ",
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "long",
			Aliases: []string{"l"},
			Usage:   "display details",
		},
	},
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		curChan := client.PeerMgrListCurrencyIDs(c.Context)
		for currencyID := range curChan {
			fmt.Printf("Currency %v\n", currencyID)
			peerChan := client.PeerMgrListPeers(c.Context, currencyID)
			for peer := range peerChan {
				if c.IsSet("long") {
					fmt.Printf("\t%v:\n", peer)

					pi, err := client.PeerMgrPeerAddr(c.Context, currencyID, peer)
					if err != nil {
						return err
					}
					res := make([]string, 0)
					for _, maddr := range pi.Addrs {
						if manet.IsPrivateAddr(maddr) {

							res = append(res, maddr.String()+"/p2p/"+pi.ID.String())
						} else {
							res = append([]string{maddr.String() + "/p2p/" + pi.ID.String()}, res...)
						}
					}
					fmt.Printf("\t\tNetwork Addrs: %v\n", res)

					blocked, err := client.PeerMgrIsBlocked(c.Context, currencyID, peer)
					if err != nil {
						return err
					}
					fmt.Printf("\t\tBlocked: %v\n", blocked)
					fmt.Printf("\t\tRecent history:\n")

					i := 0
					recChan := client.PeerMgrListHistory(c.Context, currencyID, peer)
					for rec := range recChan {
						if i == 10 {
							break
						}
						i++
						fmt.Printf("\t\t\t%v: %v - %v\n", rec.RecID, rec.Record.CreatedAt, rec.Record.Description)
					}
				} else {
					fmt.Printf("\t%v\n", peer)
				}
			}
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var PeerListHistoryCMD = &cli.Command{
	Name:        "list-history",
	Usage:       "list history of given peer",
	Description: "List the history of a given peer based on given currency id and peer address",
	ArgsUsage:   "[currency id, peer addr]",
	Action: func(c *cli.Context) error {
		currency, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		currencyID := byte(currency)
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		recChan := client.PeerMgrListHistory(c.Context, currencyID, peerAddr)
		for rec := range recChan {
			fmt.Printf("%v: %v - %v\n", rec.RecID, rec.Record.CreatedAt, rec.Record.Description)
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var PeerRemoveCMD = &cli.Command{
	Name:        "remove",
	Usage:       "remove peer and history",
	Description: "Remove a peer and all history recorded",
	ArgsUsage:   "[currency id, peer addr]",
	Action: func(c *cli.Context) error {
		currency, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		currencyID := byte(currency)
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.PeerMgrRemovePeer(c.Context, currencyID, peerAddr)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var PeerRemoveRecordCMD = &cli.Command{
	Name:        "remove-record",
	Usage:       "remove the record of a peer",
	Description: "Remove a record of a peer based on record id",
	ArgsUsage:   "[currency id, peer addr, record id]",
	Action: func(c *cli.Context) error {
		currency, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		currencyID := byte(currency)
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		recID, ok := big.NewInt(0).SetString(c.Args().Get(2), 10)
		if !ok {
			return usageError(c, fmt.Errorf("fail to parse record id"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.PeerMgrRemoveRecord(c.Context, currencyID, peerAddr, recID)
		if err != nil {
			return err
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var PeerRemoveSetRecIDCMD = &cli.Command{
	Name:        "set-recid",
	Usage:       "set the record id of a peer",
	Description: "Set a record id of a peer to be the given record id",
	ArgsUsage:   "[currency id, peer addr, record id]",
	Action: func(c *cli.Context) error {
		currency, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		currencyID := byte(currency)
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		recID, ok := big.NewInt(0).SetString(c.Args().Get(2), 10)
		if !ok {
			return usageError(c, fmt.Errorf("fail to parse record id"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.PeerMgrSetRecID(c.Context, currencyID, peerAddr, recID)
		if err != nil {
			return err
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var PeerUnblockCMD = &cli.Command{
	Name:        "unblock",
	Usage:       "unblock peer",
	Description: "Unblock a peer based on given currency id and peer address",
	ArgsUsage:   "[currency id, peer addr]",
	Action: func(c *cli.Context) error {
		currency, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		currencyID := byte(currency)
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.PeerMgrUnblockPeer(c.Context, currencyID, peerAddr)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var PieceCMD = &cli.Command{
	Name:        "piece",
	Usage:       "access piece manager functions",
	Description: "This command outputs a list of piece manager functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		PieceImportCMD,
		PieceImportCarCMD,
		PieceImportSectorCMD,
		PieceListCMD,
		PieceInspectCMD,
		PieceRemoveCMD,
	},
}

Piece command.

View Source
var PieceImportCMD = &cli.Command{
	Name:        "import",
	Usage:       "import a file",
	Description: "Import a file into the piece manager",
	ArgsUsage:   "[filename]",
	Action: func(c *cli.Context) error {

		filename := c.Args().Get(0)
		if filename == "" {
			return usageError(c, fmt.Errorf("received empty filename"))
		}
		filenameAbs, err := filepath.Abs(filename)
		if err != nil {
			return fmt.Errorf("fail to get abs path: %v", err.Error())
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		id, err := client.PieceMgrImport(c.Context, filenameAbs)
		if err != nil {
			return err
		}
		fmt.Printf("Imported: %v\n", id.String())
		return nil
	},
}
View Source
var PieceImportCarCMD = &cli.Command{
	Name:        "import-car",
	Usage:       "import a .car file",
	Description: "Import a .car file into the piece manager",
	ArgsUsage:   "[filename]",
	Action: func(c *cli.Context) error {

		filename := c.Args().Get(0)
		if filename == "" {
			return usageError(c, fmt.Errorf("received empty filename"))
		}
		filenameAbs, err := filepath.Abs(filename)
		if err != nil {
			return fmt.Errorf("fail to get abs path: %v", err.Error())
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		id, err := client.PieceMgrImportCar(c.Context, filenameAbs)
		if err != nil {
			return err
		}
		fmt.Printf("Imported: %v\n", id.String())
		return nil
	},
}
View Source
var PieceImportSectorCMD = &cli.Command{
	Name:        "import-sector",
	Usage:       "import a lotus unsealed sector",
	Description: "Import a lotus unsealed sector into the piece manager",
	ArgsUsage:   "[filename, copy]",
	Action: func(c *cli.Context) error {

		filename := c.Args().Get(0)
		if filename == "" {
			return usageError(c, fmt.Errorf("received empty filename"))
		}
		copy, err := strconv.ParseBool(c.Args().Get(1))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse copy: %v", err.Error()))
		}
		filenameAbs, err := filepath.Abs(filename)
		if err != nil {
			return fmt.Errorf("fail to get abs path: %v", err.Error())
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		ids, err := client.PieceMgrImportSector(c.Context, filenameAbs, copy)
		if err != nil {
			return err
		}
		fmt.Println("Imported:")
		for _, id := range ids {
			fmt.Printf("\t%v\n", id.String())
		}
		return nil
	},
}
View Source
var PieceInspectCMD = &cli.Command{
	Name:        "inspect",
	Usage:       "inspect given piece",
	Description: "Inspect the details of a given piece",
	ArgsUsage:   "[cid]",
	Action: func(c *cli.Context) error {
		id, err := cid.Parse(c.Args().Get(0))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse cid: %v", err.Error()))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		res, err := client.PieceMgrInspect(c.Context, id)
		if err != nil {
			return err
		}
		if res.Exists {
			fmt.Printf("Piece %v:\n", id.String())
			fmt.Printf("\tpath - %v\n", res.Path)
			fmt.Printf("\tindex - %v\n", res.Index)
			fmt.Printf("\tsize - %v\n", res.Size)
			fmt.Printf("\tcopy - %v\n", res.Copy)
		} else {
			fmt.Printf("Piece %v does not exist\n", id.String())
		}
		return nil
	},
}
View Source
var PieceListCMD = &cli.Command{
	Name:        "list",
	Aliases:     []string{"ls"},
	Usage:       "list all pieces",
	Description: "List all pieces imported to this piece manager",
	ArgsUsage:   " ",
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "long",
			Aliases: []string{"l"},
			Usage:   "display details",
		},
	},
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		idChan := client.PieceMgrListImported(c.Context)
		for id := range idChan {
			if c.IsSet("long") {
				res, err := client.PieceMgrInspect(c.Context, id)
				if err != nil {
					return err
				}
				if res.Exists {
					fmt.Printf("%v: path(%v), index(%v), size(%v), copy (%v)\n", id.String(), res.Path, res.Index, res.Size, res.Copy)
				}
			} else {
				fmt.Println(id.String())
			}
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var PieceRemoveCMD = &cli.Command{
	Name:        "remove",
	Usage:       "remove given piece",
	Description: "Remove the given piece from the piece manager",
	ArgsUsage:   "[cid]",
	Action: func(c *cli.Context) error {
		id, err := cid.Parse(c.Args().Get(0))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse cid: %v", err.Error()))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.PieceMgrRemove(c.Context, id)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var PservingCMD = &cli.Command{
	Name:        "serving",
	Usage:       "Access serving functions",
	Description: "This command outputs a list of paych serving functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		PServingServeCMD,
		PServingListCMD,
		PServingInspectCMD,
		PservingStopCMD,
	},
}

Paych serving command.

View Source
var PservingStopCMD = &cli.Command{
	Name:        "stop",
	Usage:       "stop a served paych",
	Description: "Stop serving a given paych",
	ArgsUsage:   "[currency id, peer addr, paych addr]",
	Action: func(c *cli.Context) error {
		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		chAddr := c.Args().Get(2)
		if chAddr == "" {
			return usageError(c, fmt.Errorf("received empty paych addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.PservMgrStop(c.Context, byte(currencyID), peerAddr, chAddr)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var RenewCMD = &cli.Command{
	Name:        "renew",
	Usage:       "access renew policy functions",
	Description: "This command outputs a list of renew policy functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		RenewSetCMD,
		RenewGetCMD,
		RenewRemoveCMD,
		RenewListCMD,
	},
}
View Source
var RenewGetCMD = &cli.Command{
	Name:        "get",
	Usage:       "get renew policy",
	Description: "This command gets the renew policy",
	ArgsUsage:   fmt.Sprintf("[currency id, peer addr (or %v)] or [currency id, peer addr, paych addr]", renewmgr.DefaultPolicyID),
	Action: func(c *cli.Context) error {
		var duration time.Duration
		if c.Args().Len() == 2 {
			currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
			if err != nil {
				return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
			}
			peerAddr := c.Args().Get(1)
			if peerAddr == "" {
				return usageError(c, fmt.Errorf("received empty peer addr"))
			}
			client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
			if err != nil {
				return err
			}
			defer closer()
			if peerAddr == renewmgr.DefaultPolicyID {
				duration, err = client.RenewMgrGetDefaultPolicy(c.Context, byte(currencyID))
			} else {
				duration, err = client.RenewMgrGetSenderPolicy(c.Context, byte(currencyID), peerAddr)
			}
			if err != nil {
				return err
			}
		} else {
			currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
			if err != nil {
				return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
			}
			peerAddr := c.Args().Get(1)
			if peerAddr == "" {
				return usageError(c, fmt.Errorf("received empty peer addr"))
			}
			paychAddr := c.Args().Get(2)
			if paychAddr == "" {
				return usageError(c, fmt.Errorf("received empty paych addr"))
			}
			client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
			if err != nil {
				return err
			}
			defer closer()
			duration, err = client.RenewMgrGetPaychPolicy(c.Context, byte(currencyID), peerAddr, paychAddr)
			if err != nil {
				return err
			}
		}
		fmt.Println(duration)
		return nil
	},
}
View Source
var RenewListCMD = &cli.Command{
	Name:        "list",
	Aliases:     []string{"ls"},
	Usage:       "list all policies",
	Description: "List all existing and active policies for renew",
	ArgsUsage:   " ",
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "long",
			Aliases: []string{"l"},
			Usage:   "display details",
		},
	},
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		curChan := client.RenewMgrListCurrencyIDs(c.Context)
		for currencyID := range curChan {
			fmt.Printf("Currency %v:\n", currencyID)
			peerChan := client.RenewMgrListSenders(c.Context, currencyID)
			for peer := range peerChan {
				if peer == renewmgr.DefaultPolicyID {
					if c.IsSet("long") {
						policy, err := client.RenewMgrGetDefaultPolicy(c.Context, currencyID)
						if err != nil {
							return err
						}
						fmt.Printf("\t%v: %v\n", peer, policy)
					} else {
						fmt.Printf("\t%v\n", peer)
					}
				} else {
					fmt.Printf("\tPeer %v:\n", peer)
					paychChan := client.RenewMgrListPaychs(c.Context, currencyID, peer)
					for paych := range paychChan {
						if c.IsSet("long") {
							var policy time.Duration
							if paych == renewmgr.DefaultPolicyID {
								policy, err = client.RenewMgrGetSenderPolicy(c.Context, currencyID, peer)
								if err != nil {
									return err
								}
							} else {
								policy, err = client.RenewMgrGetPaychPolicy(c.Context, currencyID, peer, paych)
								if err != nil {
									return err
								}
							}
							fmt.Printf("\t\t%v: %v\n", paych, policy)
						} else {
							fmt.Printf("\t\t%v\n", paych)
						}
					}
				}
			}
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var RenewRemoveCMD = &cli.Command{
	Name:        "remove",
	Usage:       "remove renew policy",
	Description: "This command removes the renew policy",
	ArgsUsage:   fmt.Sprintf("[currency id, peer addr (or %v)] or [currency id, peer addr, paych addr]", renewmgr.DefaultPolicyID),
	Action: func(c *cli.Context) error {
		if c.Args().Len() == 2 {
			currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
			if err != nil {
				return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
			}
			peerAddr := c.Args().Get(1)
			if peerAddr == "" {
				return usageError(c, fmt.Errorf("received empty peer addr"))
			}
			client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
			if err != nil {
				return err
			}
			defer closer()
			if peerAddr == renewmgr.DefaultPolicyID {
				err = client.RenewMgrRemoveDefaultPolicy(c.Context, byte(currencyID))
			} else {
				err = client.RenewMgrRemoveSenderPolicy(c.Context, byte(currencyID), peerAddr)
			}
			if err != nil {
				return err
			}
		} else {
			currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
			if err != nil {
				return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
			}
			peerAddr := c.Args().Get(1)
			if peerAddr == "" {
				return usageError(c, fmt.Errorf("received empty peer addr"))
			}
			paychAddr := c.Args().Get(2)
			if paychAddr == "" {
				return usageError(c, fmt.Errorf("received empty paych addr"))
			}
			client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
			if err != nil {
				return err
			}
			defer closer()
			err = client.RenewMgrRemovePaychPolicy(c.Context, byte(currencyID), peerAddr, paychAddr)
			if err != nil {
				return err
			}
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var RenewSetCMD = &cli.Command{
	Name:        "set",
	Usage:       "set renew policy",
	Description: "This command sets the renew policy",
	ArgsUsage:   fmt.Sprintf("[currency id, peer addr (or %v), duration] or [currency id, peer addr, paych addr, duration]", renewmgr.DefaultPolicyID),
	Action: func(c *cli.Context) error {
		if c.Args().Len() == 3 {
			currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
			if err != nil {
				return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
			}
			peerAddr := c.Args().Get(1)
			if peerAddr == "" {
				return usageError(c, fmt.Errorf("received empty peer addr"))
			}
			duration, err := time.ParseDuration(c.Args().Get(2))
			if err != nil {
				return usageError(c, fmt.Errorf("fail to parse duration: %v", err.Error()))
			}
			client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
			if err != nil {
				return err
			}
			defer closer()
			if peerAddr == renewmgr.DefaultPolicyID {
				err = client.RenewMgrSetDefaultPolicy(c.Context, byte(currencyID), duration)
			} else {
				err = client.RenewMgrSetSenderPolicy(c.Context, byte(currencyID), peerAddr, duration)
			}
			if err != nil {
				return err
			}
		} else if c.Args().Len() == 4 {
			currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
			if err != nil {
				return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
			}
			peerAddr := c.Args().Get(1)
			if peerAddr == "" {
				return usageError(c, fmt.Errorf("received empty peer addr"))
			}
			paychAddr := c.Args().Get(2)
			if paychAddr == "" {
				return usageError(c, fmt.Errorf("received empty paych addr"))
			}
			duration, err := time.ParseDuration(c.Args().Get(3))
			if err != nil {
				return usageError(c, fmt.Errorf("fail to parse duration: %v", err.Error()))
			}
			client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
			if err != nil {
				return err
			}
			defer closer()
			err = client.RenewMgrSetPaychPolicy(c.Context, byte(currencyID), peerAddr, paychAddr, duration)
			if err != nil {
				return err
			}
		} else {
			return usageError(c, fmt.Errorf("incorrect number of arguments, expect 3 or 4, got %v", c.Args().Len()))
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var ReserveCMD = &cli.Command{
	Name:        "reserve",
	Usage:       "access reservation policy functions",
	Description: "This command outputs a list of reservation policy functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		ReserveSetCMD,
		ReserveGetCMD,
		ReserveRemoveCMD,
		ReserveListCMD,
	},
}
View Source
var ReserveGetCMD = &cli.Command{
	Name:        "get",
	Usage:       "get reservation policy",
	Description: "This command gets the reservation policy",
	ArgsUsage:   fmt.Sprintf("[currency id, paych addr (or %v)] or [currency id, paych addr, peer addr]", reservmgr.DefaultPolicyID),
	Action: func(c *cli.Context) error {
		var res api.ReservMgrPolicyRes
		if c.Args().Len() == 2 {
			currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
			if err != nil {
				return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
			}
			paychAddr := c.Args().Get(1)
			if paychAddr == "" {
				return usageError(c, fmt.Errorf("received empty paych addr"))
			}
			client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
			if err != nil {
				return err
			}
			defer closer()
			if paychAddr == reservmgr.DefaultPolicyID {
				res, err = client.ReservMgrGetDefaultPolicy(c.Context, byte(currencyID))
			} else {
				res, err = client.ReservMgrGetPaychPolicy(c.Context, byte(currencyID), paychAddr)
			}
			if err != nil {
				return nil
			}
		} else {
			currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
			if err != nil {
				return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
			}
			paychAddr := c.Args().Get(1)
			if paychAddr == "" {
				return usageError(c, fmt.Errorf("received empty paych addr"))
			}
			peerAddr := c.Args().Get(2)
			if peerAddr == "" {
				return usageError(c, fmt.Errorf("received empty peer addr"))
			}
			client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
			if err != nil {
				return err
			}
			defer closer()
			res, err = client.ReservMgrGetPeerPolicy(c.Context, byte(currencyID), paychAddr, peerAddr)
			if err != nil {
				return err
			}
		}
		if res.Unlimited {
			fmt.Println("Unlimited")
		} else {
			fmt.Println(res.Max)
		}
		return nil
	},
}
View Source
var ReserveListCMD = &cli.Command{
	Name:        "list",
	Aliases:     []string{"ls"},
	Usage:       "list all policies",
	Description: "List all existing and active policies for reserve",
	ArgsUsage:   " ",
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "long",
			Aliases: []string{"l"},
			Usage:   "display details",
		},
	},
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		curChan := client.ReservMgrListCurrencyIDs(c.Context)
		for currencyID := range curChan {
			fmt.Printf("Currency %v:\n", currencyID)
			paychChan := client.ReservMgrListPaychs(c.Context, currencyID)
			for paych := range paychChan {
				if paych == reservmgr.DefaultPolicyID {
					if c.IsSet("long") {
						policy, err := client.ReservMgrGetDefaultPolicy(c.Context, currencyID)
						if err != nil {
							return err
						}
						if policy.Unlimited {
							fmt.Printf("\t%v: Unlimited\n", paych)
						} else {
							fmt.Printf("\t%v: %v\n", paych, policy.Max)
						}
					}
				} else {
					fmt.Printf("\tPaych: %v:\n", paych)
					peerChan := client.ReservMgrListPeers(c.Context, currencyID, paych)
					for peer := range peerChan {
						if c.IsSet("long") {
							var policy api.ReservMgrPolicyRes
							if peer == reservmgr.DefaultPolicyID {
								policy, err = client.ReservMgrGetPaychPolicy(c.Context, currencyID, paych)
								if err != nil {
									return err
								}
							} else {
								policy, err = client.ReservMgrGetPeerPolicy(c.Context, currencyID, paych, peer)
								if err != nil {
									return err
								}
							}
							if policy.Unlimited {
								fmt.Printf("\t\t%v: Unlimited\n", peer)
							} else {
								fmt.Printf("\t\t%v: %v\n", peer, policy.Max)
							}
						} else {
							fmt.Printf("\t\t%v\n", peer)
						}
					}
				}
			}
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var ReserveRemoveCMD = &cli.Command{
	Name:        "remove",
	Usage:       "remove reservation policy",
	Description: "This command removes the reservation policy",
	ArgsUsage:   fmt.Sprintf("[currency id, paych addr (or %v)] or [currency id, paych addr, peer addr]", reservmgr.DefaultPolicyID),
	Action: func(c *cli.Context) error {
		if c.Args().Len() == 2 {
			currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
			if err != nil {
				return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
			}
			paychAddr := c.Args().Get(1)
			if paychAddr == "" {
				return usageError(c, fmt.Errorf("received empty paych addr"))
			}
			client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
			if err != nil {
				return err
			}
			defer closer()
			if paychAddr == reservmgr.DefaultPolicyID {
				err = client.ReservMgrRemoveDefaultPolicy(c.Context, byte(currencyID))
			} else {
				err = client.ReservMgrRemovePaychPolicy(c.Context, byte(currencyID), paychAddr)
			}
			if err != nil {
				return nil
			}
		} else {
			currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
			if err != nil {
				return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
			}
			paychAddr := c.Args().Get(1)
			if paychAddr == "" {
				return usageError(c, fmt.Errorf("received empty paych addr"))
			}
			peerAddr := c.Args().Get(2)
			if peerAddr == "" {
				return usageError(c, fmt.Errorf("received empty peer addr"))
			}
			client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
			if err != nil {
				return err
			}
			defer closer()
			err = client.ReservMgrRemovePeerPolicy(c.Context, byte(currencyID), paychAddr, peerAddr)
			if err != nil {
				return err
			}
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var ReserveSetCMD = &cli.Command{
	Name:        "set",
	Usage:       "set reservation policy",
	Description: "This command sets the reservation policy",
	ArgsUsage:   fmt.Sprintf("[currency id, paych addr (or %v), max (-1 if unlimited)] or [currency id, paych addr, peer addr, max (-1 if unlimited)]", reservmgr.DefaultPolicyID),
	Action: func(c *cli.Context) error {
		if c.Args().Len() == 3 {
			currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
			if err != nil {
				return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
			}
			paychAddr := c.Args().Get(1)
			if paychAddr == "" {
				return usageError(c, fmt.Errorf("received empty paych addr"))
			}
			max, ok := big.NewInt(0).SetString(c.Args().Get(2), 10)
			if !ok {
				return usageError(c, fmt.Errorf("fail to parse max %v", c.Args().Get(2)))
			}
			client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
			if err != nil {
				return err
			}
			defer closer()
			if paychAddr == reservmgr.DefaultPolicyID {
				if max.Cmp(big.NewInt(0)) < 0 {
					err = client.ReservMgrSetDefaultPolicy(c.Context, byte(currencyID), true, nil)
				} else {
					err = client.ReservMgrSetDefaultPolicy(c.Context, byte(currencyID), false, max)
				}
			} else {
				if max.Cmp(big.NewInt(0)) < 0 {
					err = client.ReservMgrSetPaychPolicy(c.Context, byte(currencyID), paychAddr, true, nil)
				} else {
					err = client.ReservMgrSetPaychPolicy(c.Context, byte(currencyID), paychAddr, false, max)
				}
			}
			if err != nil {
				return err
			}
		} else if c.Args().Len() == 4 {
			currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
			if err != nil {
				return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
			}
			paychAddr := c.Args().Get(1)
			if paychAddr == "" {
				return usageError(c, fmt.Errorf("received empty paych addr"))
			}
			peerAddr := c.Args().Get(2)
			if peerAddr == "" {
				return usageError(c, fmt.Errorf("received empty peer addr"))
			}
			max, ok := big.NewInt(0).SetString(c.Args().Get(3), 10)
			if !ok {
				return usageError(c, fmt.Errorf("fail to parse max %v", c.Args().Get(2)))
			}
			client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
			if err != nil {
				return err
			}
			defer closer()
			if max.Cmp(big.NewInt(0)) < 0 {
				err = client.ReservMgrSetPeerPolicy(c.Context, byte(currencyID), paychAddr, peerAddr, true, nil)
			} else {
				err = client.ReservMgrSetPeerPolicy(c.Context, byte(currencyID), paychAddr, peerAddr, false, max)
			}
			if err != nil {
				return err
			}
		} else {
			return usageError(c, fmt.Errorf("incorrect number of arguments, expect 3 or 4, got %v", c.Args().Len()))
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var RetrieveCMD = &cli.Command{
	Name:        "retrieve",
	Usage:       "retrieve a piece",
	Description: "Retrieve a piece based on given piece offer and paych reservation",
	ArgsUsage:   "[piece offer, reservation (0-0 if free), outpath, pay offer (optional)]",
	Action: func(c *cli.Context) error {
		offerData, err := base64.StdEncoding.DecodeString(c.Args().Get(0))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse piece offer data"))
		}
		reservation := strings.Split(c.Args().Get(1), "-")
		if len(reservation) != 2 {
			return usageError(c, fmt.Errorf("fail to parse reservation, should be resCh-resId"))
		}
		resCh := reservation[0]
		resID, err := strconv.ParseUint(reservation[1], 10, 64)
		if err != nil {
			return err
		}
		outPath := c.Args().Get(2)
		if outPath == "" {
			return usageError(c, fmt.Errorf("empty outpath received"))
		}
		outPathAbs, err := filepath.Abs(outPath)
		if err != nil {
			return fmt.Errorf("error getting path: %v", err.Error())
		}
		pieceOffer := fcroffer.PieceOffer{}
		err = pieceOffer.Decode(offerData)
		if err != nil {
			return err
		}
		var payOffer *fcroffer.PayOffer
		if c.Args().Len() > 3 {
			offerData, err := base64.StdEncoding.DecodeString(c.Args().Get(3))
			if err != nil {
				return err
			}
			offer := fcroffer.PayOffer{}
			err = offer.Decode(offerData)
			if err != nil {
				return err
			}
			payOffer = &offer
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		fmt.Println("Start retrieval...")
		resChan := client.RetMgrRetrieve(c.Context, pieceOffer, payOffer, resCh, resID, outPathAbs)
		for res := range resChan {
			if res.Err != "" {
				return fmt.Errorf(res.Err)
			}
			fmt.Printf("\r%v\t\t", res.Progress)
		}
		fmt.Println("\nSucceed")
		return nil
	},
}

Retrieve command.

View Source
var RetrieveCacheCMD = &cli.Command{
	Name:        "cache-retrieve",
	Usage:       "retrieve a piece from cache",
	Description: "Retrieve a piece based on given cid from cache",
	ArgsUsage:   "[cid, outpath]",
	Action: func(c *cli.Context) error {
		id, err := cid.Parse(c.Args().Get(0))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse cid: %v", err.Error()))
		}
		outPath := c.Args().Get(1)
		if outPath == "" {
			return usageError(c, fmt.Errorf("empty outpath received"))
		}
		outPathAbs, err := filepath.Abs(outPath)
		if err != nil {
			return fmt.Errorf("error getting path: %v", err.Error())
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		found, err := client.RetMgrRetrieveFromCache(c.Context, id, outPathAbs)
		if err != nil {
			return err
		}
		if found {
			fmt.Println("Succeed")
		} else {
			fmt.Println("Piece not found in cache")
		}
		return nil
	},
}
View Source
var SettleCMD = &cli.Command{
	Name:        "settle",
	Usage:       "access settlement policy functions",
	Description: "This command outputs a list of settlement policy functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		SettleSetCMD,
		SettleGetCMD,
		SettleRemoveCMD,
		SettleListCMD,
	},
}
View Source
var SettleGetCMD = &cli.Command{
	Name:        "get",
	Usage:       "get settlement policy",
	Description: "This command gets the settlement policy",
	ArgsUsage:   fmt.Sprintf("[currency id, peer addr (or %v)]", settlemgr.DefaultPolicyID),
	Action: func(c *cli.Context) error {
		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		var duration time.Duration
		if peerAddr == settlemgr.DefaultPolicyID {
			duration, err = client.SettleMgrGetDefaultPolicy(c.Context, byte(currencyID))
		} else {
			duration, err = client.SettleMgrGetSenderPolicy(c.Context, byte(currencyID), peerAddr)
		}
		if err != nil {
			return err
		}
		fmt.Println(duration)
		return nil
	},
}
View Source
var SettleListCMD = &cli.Command{
	Name:        "list",
	Aliases:     []string{"ls"},
	Usage:       "list all policies",
	Description: "List all existing and active policies for settlement",
	ArgsUsage:   " ",
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "long",
			Aliases: []string{"l"},
			Usage:   "display details",
		},
	},
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		curChan := client.SettleMgrListCurrencyIDs(c.Context)
		for currencyID := range curChan {
			fmt.Printf("Currency %v:\n", currencyID)
			peerChan := client.SettleMgrListSenders(c.Context, currencyID)
			for peer := range peerChan {
				if c.IsSet("long") {
					var policy time.Duration
					if peer == settlemgr.DefaultPolicyID {
						policy, err = client.SettleMgrGetDefaultPolicy(c.Context, currencyID)
					} else {
						policy, err = client.SettleMgrGetSenderPolicy(c.Context, currencyID, peer)
					}
					if err != nil {
						return err
					}
					fmt.Printf("\t%v: %v\n", peer, policy)
				} else {
					fmt.Printf("\t%v\n", peer)
				}
			}
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var SettleRemoveCMD = &cli.Command{
	Name:        "remove",
	Usage:       "remove settlement policy",
	Description: "This command removes the settlement policy",
	ArgsUsage:   fmt.Sprintf("[currency id, peer addr (or %v)]", settlemgr.DefaultPolicyID),
	Action: func(c *cli.Context) error {
		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		if peerAddr == settlemgr.DefaultPolicyID {
			err = client.SettleMgrRemoveDefaultPolicy(c.Context, byte(currencyID))
		} else {
			err = client.SettleMgrRemoveSenderPolicy(c.Context, byte(currencyID), peerAddr)
		}
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var SettleSetCMD = &cli.Command{
	Name:        "set",
	Usage:       "set settlement policy",
	Description: "This command sets the settlement policy",
	ArgsUsage:   fmt.Sprintf("[currency id, peer addr (or %v), duration]", settlemgr.DefaultPolicyID),
	Action: func(c *cli.Context) error {
		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		peerAddr := c.Args().Get(1)
		if peerAddr == "" {
			return usageError(c, fmt.Errorf("received empty peer addr"))
		}
		duration, err := time.ParseDuration(c.Args().Get(2))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse duration: %v", err.Error()))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		if peerAddr == settlemgr.DefaultPolicyID {
			err = client.SettleMgrSetDefaultPolicy(c.Context, byte(currencyID), duration)
		} else {
			err = client.SettleMgrSetSenderPolicy(c.Context, byte(currencyID), peerAddr, duration)
		}
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var SystemAddrCMD = &cli.Command{
	Name:        "addr",
	Usage:       "get the node network address",
	Description: "Get the network address of this node",
	ArgsUsage:   " ",
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		pi, err := client.NetAddr(c.Context)
		if err != nil {
			return err
		}
		res := make([]string, 0)
		for _, maddr := range pi.Addrs {
			if manet.IsPrivateAddr(maddr) {

				res = append(res, maddr.String()+"/p2p/"+pi.ID.String())
			} else {
				res = append([]string{maddr.String() + "/p2p/" + pi.ID.String()}, res...)
			}
		}
		fmt.Println(res)
		return nil
	},
}
View Source
var SystemCMD = &cli.Command{
	Name:        "system",
	Usage:       "access system functions",
	Description: "This command outputs a list of system functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		SystemAddrCMD,
		SystemConnectCMD,
		SystemPublishCMD,
		SystemCacheSizeCMD,
		SystemCachePruneCMD,
		SystemCleanCMD,
		SystemGCCMD,
	},
}

System command.

View Source
var SystemCachePruneCMD = &cli.Command{
	Name:        "cache-prune",
	Usage:       "prune the retrieval cache",
	Description: "Prune the current retrieval cache size",
	ArgsUsage:   " ",
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.RetMgrCleanRetrievalCache(c.Context)
		if err != nil {
			return err
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var SystemCacheSizeCMD = &cli.Command{
	Name:        "cache-size",
	Usage:       "get the retrieval cache size",
	Description: "Get the current retrieval cache size",
	ArgsUsage:   " ",
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		size, err := client.RetMgrGetRetrievalCacheSize(c.Context)
		if err != nil {
			return err
		}
		fmt.Println(size)
		return nil
	},
}
View Source
var SystemCleanCMD = &cli.Command{
	Name:        "clean",
	Usage:       "run retrieval cleanning",
	Description: "Run cleaning process to clean stuck retrieval process",
	ArgsUsage:   " ",
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.RetMgrCleanIncomingProcesses(c.Context)
		if err != nil {
			return err
		}
		err = client.RetMgrCleanOutgoingProcesses(c.Context)
		if err != nil {
			return err
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var SystemConnectCMD = &cli.Command{
	Name:        "connect",
	Usage:       "connect to peer network address",
	Description: "Attempt to connect to given peer network address",
	ArgsUsage:   "[p2p addr]",
	Action: func(c *cli.Context) error {
		p2pAddrs := strings.Split(c.Args().Get(0), "/p2p/")
		if len(p2pAddrs) != 2 {
			return usageError(c, fmt.Errorf("fail to parse p2p addr, should contain net addr and peer id"))
		}
		maddr, err := multiaddr.NewMultiaddr(p2pAddrs[0])
		if err != nil {
			return fmt.Errorf("error parsing multiaddr: %v", err.Error())
		}
		pid, err := peer.Decode(p2pAddrs[1])
		if err != nil {
			return fmt.Errorf("error parsing peer id: %v", err.Error())
		}
		pi := peer.AddrInfo{Addrs: []multiaddr.Multiaddr{maddr}, ID: pid}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.NetConnect(c.Context, pi)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var SystemGCCMD = &cli.Command{
	Name:        "gc",
	Usage:       "run garbage collection",
	Description: "Force to run garbage collection",
	ArgsUsage:   " ",
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.GC()
		if err != nil {
			return err
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var SystemPublishCMD = &cli.Command{
	Name:        "publish",
	Usage:       "force publish addr to network",
	Description: "Force the node to publish presence to the network",
	ArgsUsage:   " ",
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.AddrProtoPublish(c.Context)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var WalletCMD = &cli.Command{
	Name:        "wallet",
	Usage:       "access wallet functions",
	Description: "This command outputs a list of wallet functions",
	ArgsUsage:   " ",
	Subcommands: []*cli.Command{
		WalletGenerateCMD,
		WalletSetKeyCMD,
		WalletGetAddrCMD,
		WalletList,
		WalletRetireKey,
		WalletStopRetire,
	},
}

Wallet command.

View Source
var WalletGenerateCMD = &cli.Command{
	Name:        "generate",
	Usage:       "generate a private key",
	Description: "Generate a private key for given currency id",
	ArgsUsage:   "[currency id]",
	Hidden:      true,
	Action: func(c *cli.Context) error {

		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		if byte(currencyID) == crypto.FIL {
			prv, err := crypto2.GenerateKey()
			if err != nil {
				return err
			}
			fmt.Println(base64.StdEncoding.EncodeToString(prv))
			return nil
		}
		return fmt.Errorf("Unsupported currency id %v", currencyID)
	},
}
View Source
var WalletGetAddrCMD = &cli.Command{
	Name:        "get",
	Usage:       "get the wallet address",
	Description: "Get the address of the stored key for given currency id",
	ArgsUsage:   "[currency id]",
	Action: func(c *cli.Context) error {

		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		res, err := client.SignerGetAddr(c.Context, byte(currencyID))
		if err != nil {
			return err
		}
		bal, err := client.TransactorGetBalance(c.Context, byte(currencyID), res.Addr)
		if err != nil {
			return err
		}
		fmt.Printf("%v (Type %v): %v\n", res.Addr, res.KeyType, bal)
		return nil
	},
}
View Source
var WalletList = &cli.Command{
	Name:        "list",
	Aliases:     []string{"ls"},
	Usage:       "list all addresses",
	Description: "List the address of stored key for all configured currency ids",
	ArgsUsage:   " ",
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "long",
			Aliases: []string{"l"},
			Usage:   "display details",
		},
	},
	Action: func(c *cli.Context) error {
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		curChan := client.SignerListCurrencyIDs(c.Context)
		for currencyID := range curChan {
			if c.IsSet("long") {
				res, err := client.SignerGetAddr(c.Context, byte(currencyID))
				if err != nil {
					return err
				}
				bal, err := client.TransactorGetBalance(c.Context, byte(currencyID), res.Addr)
				if err != nil {
					return err
				}
				fmt.Printf("Currency %v: %v (Type %v) with balance %v\n", currencyID, res.Addr, res.KeyType, bal)
			} else {
				fmt.Printf("Currency %v\n", currencyID)
			}
		}
		fmt.Println("Done")
		return nil
	},
}
View Source
var WalletRetireKey = &cli.Command{
	Name:        "retire",
	Usage:       "retire key",
	Description: "Retire a key for given currency id",
	ArgsUsage:   "[currency id]",
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:  "confirm",
			Value: false,
			Usage: "confirm by setting true",
		},
		&cli.DurationFlag{
			Name:   "timeout",
			Value:  time.Hour,
			Usage:  "specify the timeout",
			Hidden: true,
		},
	},
	Hidden: true,
	Action: func(c *cli.Context) error {

		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		if !c.IsSet("confirm") {
			return fmt.Errorf("you must pass confirm flag to confirm this")
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		errStr := <-client.SignerRetireKey(c.Context, byte(currencyID), c.Duration("timeout"))
		if errStr != "" {
			return fmt.Errorf(errStr)
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var WalletSetKeyCMD = &cli.Command{
	Name:        "set",
	Usage:       "set the wallet key",
	Description: "Set a private key for given currency id",
	ArgsUsage:   "[currency id, key type, base64 key]",
	Action: func(c *cli.Context) error {

		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		keyType, err := strconv.ParseUint(c.Args().Get(1), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse key type: %v", err.Error()))
		}
		key, err := base64.StdEncoding.DecodeString(c.Args().Get(2))
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse key: %v", err.Error()))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.SignerSetKey(c.Context, byte(currencyID), byte(keyType), key)
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}
View Source
var WalletStopRetire = &cli.Command{
	Name:        "stop-retire",
	Usage:       "stop retiring a key",
	Description: "Stop retiring a key for given currency id",
	ArgsUsage:   "[currency id]",
	Hidden:      true,
	Action: func(c *cli.Context) error {

		currencyID, err := strconv.ParseUint(c.Args().Get(0), 10, 8)
		if err != nil {
			return usageError(c, fmt.Errorf("fail to parse currency id: %v", err.Error()))
		}
		client, closer, err := api.NewClient(c.Context, c.Int("port"), c.Path("auth"))
		if err != nil {
			return err
		}
		defer closer()
		err = client.SignerStopRetire(c.Context, byte(currencyID))
		if err != nil {
			return err
		}
		fmt.Println("Succeed")
		return nil
	},
}

Functions

func NewCLI

func NewCLI() *cli.App

NewCLI creates a CLI app.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL