From b7d72a6fd94d5d47e3833663bbfe2797bf713a2d Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Mon, 1 Apr 2019 23:23:03 +0000 Subject: [PATCH] [wallet] add cli -p profile to wallet wallet supports configuration file Signed-off-by: Leo Chen --- cmd/client/wallet/main.go | 113 ++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 59 deletions(-) diff --git a/cmd/client/wallet/main.go b/cmd/client/wallet/main.go index f66dd058d..e23bd04fa 100644 --- a/cmd/client/wallet/main.go +++ b/cmd/client/wallet/main.go @@ -53,7 +53,9 @@ type AccountState struct { } const ( - rpcRetry = 3 + rpcRetry = 3 + defaultConfigFile = ".hmy/wallet.ini" + defaultProfile = "default" ) var ( @@ -77,32 +79,7 @@ var ( ) var ( - // list of bootnodes - addrStrings = []string{"/ip4/100.26.90.187/tcp/9876/p2p/QmZJJx6AdaoEkGLrYG4JeLCKeCKDjnFz2wfHNHxAqFSGA9", "/ip4/54.213.43.194/tcp/9876/p2p/QmQayinFSgMMw5cSpDUiD9pQ2WeP6WNmGxpZ6ou3mdVFJX"} - - // list of rpc servers - rpcServers = []p2p.Peer{ - p2p.Peer{ - IP: "18.236.187.250", - Port: "14555", - }, - p2p.Peer{ - IP: "54.186.236.223", - Port: "14555", - }, - p2p.Peer{ - IP: "18.213.246.142", - Port: "14555", - }, - p2p.Peer{ - IP: "75.101.226.226", - Port: "14555", - }, - p2p.Peer{ - IP: "34.221.85.140", - Port: "14555", - }, - } + walletProfile *utils.WalletProfile ) // setupLog setup log for verbose output @@ -122,7 +99,10 @@ func main() { // os.Arg[1] will be the subcommand if len(os.Args) < 2 { fmt.Println("Usage:") - fmt.Println(" wallet ") + fmt.Println(" wallet -p profile ") + fmt.Println(" -p profile - Specify the profile of the wallet, either testnet/devnet or others configured. Default is: testnet") + fmt.Println(" The profile is in file:", defaultConfigFile) + fmt.Println() fmt.Println("Actions:") fmt.Println(" 1. new - Generates a new account and store the private key locally") fmt.Println(" 2. list - Lists all accounts in local keystore") @@ -133,7 +113,7 @@ func main() { fmt.Println(" --address - The address to check balance for") fmt.Println(" 6. getFreeToken - Gets free token on each shard") fmt.Println(" --address - The free token receiver account's address") - fmt.Println(" 7. transfer") + fmt.Println(" 7. transfer - Transfer token from one account to another") fmt.Println(" --from - The sender account's address or index in the local keystore") fmt.Println(" --to - The receiver account's address") fmt.Println(" --amount - The amount of token to transfer") @@ -149,22 +129,22 @@ ARG: case "--verbose": setupLog() os.Args = os.Args[:len(os.Args)-1] - case "--devnet": - // the multiaddress of bootnodes for devnet - addrStrings = []string{"/ip4/100.26.90.187/tcp/9871/p2p/Qmdfjtk6hPoyrH1zVD9PEH4zfWLo38dP2mDvvKXfh3tnEv", "/ip4/54.213.43.194/tcp/9871/p2p/QmRVbTpEYup8dSaURZfF6ByrMTSKa4UyUzJhSjahFzRqNj"} - os.Args = os.Args[:len(os.Args)-1] default: break ARG } } - if len(os.Getenv("RpcNodes")) > 0 { - rpcServers = utils.StringsToPeers(os.Getenv("RpcNodes")) + var profile string + if os.Args[1] == "-p" { + profile = os.Args[2] + os.Args = os.Args[2:] + } else { + profile = defaultProfile } - if len(rpcServers) == 0 { - fmt.Println("Error: please set environment variable RpcNodes") - fmt.Println("Example: export RpcNodes=127.0.0.1:8000,192.168.0.1:9999") - os.Exit(0) + if len(os.Args) == 1 { + fmt.Println("Missing action") + flag.PrintDefaults() + os.Exit(1) } // Switch on the subcommand @@ -180,10 +160,13 @@ ARG: case "import": processImportCommnad() case "balances": + readProfile(profile) processBalancesCommand() case "getFreeToken": + readProfile(profile) processGetFreeToken() case "transfer": + readProfile(profile) processTransferCommand() default: fmt.Printf("Unknown action: %s\n", os.Args[1]) @@ -192,9 +175,19 @@ ARG: } } +func readProfile(profile string) { + fmt.Printf("Using %s profile for wallet\n", profile) + var err error + walletProfile, err = utils.ReadWalletProfile(defaultConfigFile, profile) + if err != nil { + fmt.Printf("Read wallet profile error: %v\nExiting ...\n", err) + os.Exit(2) + } +} + // createWalletNode creates wallet server node. func createWalletNode() *node.Node { - bootNodeAddrs, err := utils.StringsToAddrs(addrStrings) + bootNodeAddrs, err := utils.StringsToAddrs(walletProfile.Bootnodes) if err != nil { panic(err) } @@ -427,29 +420,30 @@ func convertBalanceIntoReadableFormat(balance *big.Int) string { } // FetchBalance fetches account balance of specified address from the Harmony network -// TODO: (chao) add support for non beacon chain shards func FetchBalance(address common.Address) map[uint32]AccountState { result := make(map[uint32]AccountState) balance := big.NewInt(0) - result[0] = AccountState{balance, 0} - - for retry := 0; retry < rpcRetry; retry++ { - server := rpcServers[rand.Intn(len(rpcServers))] - client, err := clientService.NewClient(server.IP, server.Port) - if err != nil { - continue - } + for i := 0; i < walletProfile.Shards; i++ { + result[uint32(i)] = AccountState{balance, 0} + + for retry := 0; retry < rpcRetry; retry++ { + server := walletProfile.RPCServer[i][rand.Intn(len(walletProfile.RPCServer[i]))] + client, err := clientService.NewClient(server.IP, server.Port) + if err != nil { + continue + } - log.Debug("FetchBalance", "server", server) - response, err := client.GetBalance(address) - if err != nil { - log.Info("failed to get balance, retrying ...") - continue + log.Debug("FetchBalance", "server", server) + response, err := client.GetBalance(address) + if err != nil { + log.Info("failed to get balance, retrying ...") + continue + } + log.Debug("FetchBalance", "response", response) + balance.SetBytes(response.Balance) + result[uint32(i)] = AccountState{balance, response.Nonce} + break } - log.Debug("FetchBalance", "response", response) - balance.SetBytes(response.Balance) - result[0] = AccountState{balance, response.Nonce} - break } return result } @@ -457,7 +451,8 @@ func FetchBalance(address common.Address) map[uint32]AccountState { // GetFreeToken requests for token test token on each shard func GetFreeToken(address common.Address) { for retry := 0; retry < rpcRetry; retry++ { - server := rpcServers[0] + // use the 1st server from shard 0 (beacon chain) to make the getFreeToken call + server := walletProfile.RPCServer[0][0] client, err := clientService.NewClient(server.IP, server.Port) if err != nil { continue