OSDN Git Service

Test (#272)
authorGuanghua Guo <1536310027@qq.com>
Thu, 11 Jan 2018 01:31:11 +0000 (09:31 +0800)
committerGitHub <noreply@github.com>
Thu, 11 Jan 2018 01:31:11 +0000 (09:31 +0800)
* Fix rpc server error (#195)

* Add Test RunNode

* Add netinfo rpc test

* rpc integrate test ok

* Add list-key delete-key integrate test

* Add function comment

* Change wallet's sign

* Add util/util.go

* Change integrate/test

15 files changed:
cmd/bytomcli/commands/accesstoken.go
cmd/bytomcli/commands/account.go
cmd/bytomcli/commands/asset.go
cmd/bytomcli/commands/block.go
cmd/bytomcli/commands/bytomcli.go
cmd/bytomcli/commands/key.go
cmd/bytomcli/commands/mining.go
cmd/bytomcli/commands/net.go
cmd/bytomcli/commands/transaction.go
cmd/bytomcli/commands/txfeed.go
cmd/bytomcli/commands/util.go
config/config.go
node/node.go
test/integration/run_test.go
util/util.go [new file with mode: 0644]

index d0a914e..e262196 100755 (executable)
@@ -5,6 +5,8 @@ import (
 
        "github.com/spf13/cobra"
        jww "github.com/spf13/jwalterweatherman"
+
+       "github.com/bytom/util"
 )
 
 var createAccessTokenCmd = &cobra.Command{
@@ -15,8 +17,8 @@ var createAccessTokenCmd = &cobra.Command{
                var token accessToken
                token.ID = args[0]
 
-               data, exitCode := clientCall("/create-access-token", &token)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/create-access-token", &token)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
                printJSON(data)
@@ -28,8 +30,8 @@ var listAccessTokenCmd = &cobra.Command{
        Short: "List the existing access tokens",
        Args:  cobra.NoArgs,
        Run: func(cmd *cobra.Command, args []string) {
-               data, exitCode := clientCall("/list-access-tokens")
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/list-access-tokens")
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -45,7 +47,7 @@ var deleteAccessTokenCmd = &cobra.Command{
                var token accessToken
                token.ID = args[0]
 
-               if _, exitCode := clientCall("/delete-access-token", &token); exitCode != Success {
+               if _, exitCode := util.ClientCall("/delete-access-token", &token); exitCode != util.Success {
                        os.Exit(exitCode)
                }
                jww.FEEDBACK.Println("Successfully delete access token")
@@ -61,7 +63,7 @@ var checkAccessTokenCmd = &cobra.Command{
                token.ID = args[0]
                token.Secret = args[1]
 
-               if _, exitCode := clientCall("/check-access-token", &token); exitCode != Success {
+               if _, exitCode := util.ClientCall("/check-access-token", &token); exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
index 772086a..91b81c8 100755 (executable)
@@ -9,6 +9,7 @@ import (
        jww "github.com/spf13/jwalterweatherman"
 
        "github.com/bytom/crypto/ed25519/chainkd"
+       "github.com/bytom/util"
 )
 
 func init() {
@@ -43,7 +44,7 @@ var createAccountCmd = &cobra.Command{
                        xpub := chainkd.XPub{}
                        if err := xpub.UnmarshalText([]byte(x)); err != nil {
                                jww.ERROR.Println(err)
-                               os.Exit(ErrLocalExe)
+                               os.Exit(util.ErrLocalExe)
                        }
                        ins.RootXPubs = append(ins.RootXPubs, xpub)
                }
@@ -54,15 +55,15 @@ var createAccountCmd = &cobra.Command{
                        tags := strings.Split(accountTags, ":")
                        if len(tags) != 2 {
                                jww.ERROR.Println("Invalid tags")
-                               os.Exit(ErrLocalExe)
+                               os.Exit(util.ErrLocalExe)
                        }
                        ins.Tags = map[string]interface{}{tags[0]: tags[1]}
                }
 
                ins.AccessToken = accountToken
 
-               data, exitCode := clientCall("/create-account", &ins)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/create-account", &ins)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -79,8 +80,8 @@ var listAccountsCmd = &cobra.Command{
                        ID string `json:"id"`
                }{ID: accountID}
 
-               data, exitCode := clientCall("/list-accounts", &filter)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/list-accounts", &filter)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -97,7 +98,7 @@ var deleteAccountCmd = &cobra.Command{
                        AccountInfo string `json:"account_info"`
                }{AccountInfo: args[0]}
 
-               if _, exitCode := clientCall("/delete-account", accountInfo); exitCode != Success {
+               if _, exitCode := util.ClientCall("/delete-account", accountInfo); exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -122,14 +123,14 @@ var updateAccountTagsCmd = &cobra.Command{
                        tags := strings.Split(accountUpdateTags, ":")
                        if len(tags) != 2 {
                                jww.ERROR.Println("Invalid tags")
-                               os.Exit(ErrLocalExe)
+                               os.Exit(util.ErrLocalExe)
                        }
                        updateTag.Tags = map[string]interface{}{tags[0]: tags[1]}
                }
 
                updateTag.AccountInfo = args[0]
 
-               if _, exitCode := clientCall("/update-account-tags", &updateTag); exitCode != Success {
+               if _, exitCode := util.ClientCall("/update-account-tags", &updateTag); exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -147,8 +148,8 @@ var createAccountReceiverCmd = &cobra.Command{
                        ExpiresAt   time.Time `json:"expires_at,omitempty"`
                }{AccountInfo: args[0]}
 
-               data, exitCode := clientCall("/create-account-receiver", &ins)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/create-account-receiver", &ins)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -166,8 +167,8 @@ var createAccountAddressCmd = &cobra.Command{
                        ExpiresAt   time.Time `json:"expires_at,omitempty"`
                }{AccountInfo: args[0]}
 
-               data, exitCode := clientCall("/create-account-address", &ins)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/create-account-address", &ins)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -180,8 +181,8 @@ var listBalancesCmd = &cobra.Command{
        Short: "List the accounts balances",
        Args:  cobra.NoArgs,
        Run: func(cmd *cobra.Command, args []string) {
-               data, exitCode := clientCall("/list-balances")
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/list-balances")
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -198,8 +199,8 @@ var listUnspentOutputsCmd = &cobra.Command{
                        ID string `json:"id"`
                }{ID: outputID}
 
-               data, exitCode := clientCall("/list-unspent-outputs", &filter)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/list-unspent-outputs", &filter)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
index 4eae571..555e06d 100755 (executable)
@@ -8,6 +8,7 @@ import (
        jww "github.com/spf13/jwalterweatherman"
 
        "github.com/bytom/crypto/ed25519/chainkd"
+       "github.com/bytom/util"
 )
 
 func init() {
@@ -42,7 +43,7 @@ var createAssetCmd = &cobra.Command{
                        xpub := chainkd.XPub{}
                        if err := xpub.UnmarshalText([]byte(x)); err != nil {
                                jww.ERROR.Println(err)
-                               os.Exit(ErrLocalExe)
+                               os.Exit(util.ErrLocalExe)
                        }
                        ins.RootXPubs = append(ins.RootXPubs, xpub)
                }
@@ -55,7 +56,7 @@ var createAssetCmd = &cobra.Command{
                        tags := strings.Split(assetTags, ":")
                        if len(tags) != 2 {
                                jww.ERROR.Println("Invalid tags")
-                               os.Exit(ErrLocalExe)
+                               os.Exit(util.ErrLocalExe)
                        }
                        ins.Tags = map[string]interface{}{tags[0]: tags[1]}
                }
@@ -64,13 +65,13 @@ var createAssetCmd = &cobra.Command{
                        definition := strings.Split(assetDefiniton, ":")
                        if len(definition) != 2 {
                                jww.ERROR.Println("Invalid definition")
-                               os.Exit(ErrLocalExe)
+                               os.Exit(util.ErrLocalExe)
                        }
                        ins.Definition = map[string]interface{}{definition[0]: definition[1]}
                }
 
-               data, exitCode := clientCall("/create-asset", &ins)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/create-asset", &ins)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -87,8 +88,8 @@ var listAssetsCmd = &cobra.Command{
                        ID string `json:"id"`
                }{ID: assetID}
 
-               data, exitCode := clientCall("/list-assets", &filter)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/list-assets", &filter)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -113,13 +114,13 @@ var updateAssetTagsCmd = &cobra.Command{
                        tags := strings.Split(assetUpdateTags, ":")
                        if len(tags) != 2 {
                                jww.ERROR.Println("Invalid tags")
-                               os.Exit(ErrLocalExe)
+                               os.Exit(util.ErrLocalExe)
                        }
                        updateTag.Tags = map[string]interface{}{tags[0]: tags[1]}
                }
 
                updateTag.AssetInfo = args[0]
-               if _, exitCode := clientCall("/update-asset-tags", &updateTag); exitCode != Success {
+               if _, exitCode := util.ClientCall("/update-asset-tags", &updateTag); exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
index a9aefb0..a63a795 100755 (executable)
@@ -6,14 +6,7 @@ import (
 
        "github.com/spf13/cobra"
        jww "github.com/spf13/jwalterweatherman"
-
-       "github.com/bytom/blockchain"
-       "github.com/bytom/env"
-)
-
-var (
-       home    = blockchain.HomeDirFromEnvironment()
-       coreURL = env.String("BYTOM_URL", "http://localhost:9888")
+       "github.com/bytom/util"
 )
 
 var blockHashCmd = &cobra.Command{
@@ -21,8 +14,8 @@ var blockHashCmd = &cobra.Command{
        Short: "Get the hash of most recent block",
        Args:  cobra.NoArgs,
        Run: func(cmd *cobra.Command, args []string) {
-               data, exitCode := clientCall("block-hash")
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("block-hash")
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
                printJSON(data)
@@ -34,8 +27,8 @@ var blockHeightCmd = &cobra.Command{
        Short: "Get the number of most recent block",
        Args:  cobra.NoArgs,
        Run: func(cmd *cobra.Command, args []string) {
-               data, exitCode := clientCall("/block-height")
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/block-height")
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
                printJSON(data)
@@ -47,8 +40,8 @@ var getBlockByHashCmd = &cobra.Command{
        Short: "Get a whole block matching the given hash",
        Args:  cobra.ExactArgs(1),
        Run: func(cmd *cobra.Command, args []string) {
-               data, exitCode := clientCall("/get-block-by-hash", args[0])
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/get-block-by-hash", args[0])
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
                printJSON(data)
@@ -60,8 +53,8 @@ var getBlockHeaderByHashCmd = &cobra.Command{
        Short: "Get the header of a block matching the given hash",
        Args:  cobra.ExactArgs(1),
        Run: func(cmd *cobra.Command, args []string) {
-               data, exitCode := clientCall("/get-block-header-by-hash", args[0])
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/get-block-header-by-hash", args[0])
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
                printJSON(data)
@@ -73,8 +66,8 @@ var getBlockTransactionsCountByHashCmd = &cobra.Command{
        Short: "Get the transactions count of a block matching the given hash",
        Args:  cobra.ExactArgs(1),
        Run: func(cmd *cobra.Command, args []string) {
-               data, exitCode := clientCall("/get-block-transactions-count-by-hash", args[0])
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/get-block-transactions-count-by-hash", args[0])
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
                printJSON(data)
@@ -89,11 +82,11 @@ var getBlockByHeightCmd = &cobra.Command{
                height, err := strconv.ParseUint(args[0], 10, 64)
                if err != nil {
                        jww.ERROR.Printf("Invalid height value")
-                       os.Exit(ErrLocalExe)
+                       os.Exit(util.ErrLocalExe)
                }
 
-               data, exitCode := clientCall("/get-block-by-height", height)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/get-block-by-height", height)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -109,11 +102,11 @@ var getBlockTransactionsCountByHeightCmd = &cobra.Command{
                ui64, err := strconv.ParseUint(args[0], 10, 64)
                if err != nil {
                        jww.ERROR.Printf("Invalid height value")
-                       os.Exit(ErrLocalExe)
+                       os.Exit(util.ErrLocalExe)
                }
 
-               data, exitCode := clientCall("/get-block-transactions-count-by-height", ui64)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/get-block-transactions-count-by-height", ui64)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
index 0d7348a..6e7b01c 100644 (file)
@@ -1,35 +1,13 @@
 package commands
 
 import (
-       "context"
        "fmt"
-       "net"
-       "net/http"
        "os"
-       "path/filepath"
        "regexp"
-       "strings"
-       "time"
 
        "github.com/spf13/cobra"
-       jww "github.com/spf13/jwalterweatherman"
 
-       "github.com/bytom/blockchain"
-       "github.com/bytom/blockchain/rpc"
-)
-
-const (
-       // Success indicates the rpc calling is successful.
-       Success = iota
-       // ErrLocalExe indicates error occurs before the rpc calling.
-       ErrLocalExe
-       // ErrConnect indicates error occurs connecting to the bytomd, e.g.,
-       // bytomd can't parse the received arguments.
-       ErrConnect
-       // ErrLocalParse indicates error occurs locally when parsing the response.
-       ErrLocalParse
-       // ErrRemote indicates error occurs in bytomd.
-       ErrRemote
+       "github.com/bytom/util"
 )
 
 // commandError is an error used to signal different error situations in command handling.
@@ -89,7 +67,7 @@ func Execute() {
        AddCommands()
 
        if _, err := BytomcliCmd.ExecuteC(); err != nil {
-               os.Exit(ErrLocalExe)
+               os.Exit(util.ErrLocalExe)
        }
 }
 
@@ -152,65 +130,4 @@ func AddCommands() {
        BytomcliCmd.AddCommand(versionCmd)
 }
 
-func mustRPCClient() *rpc.Client {
-       // TODO(kr): refactor some of this cert-loading logic into bytom/blockchain
-       // and use it from cored as well.
-       // Note that this function, unlike maybeUseTLS in cored,
-       // does not load the cert and key from env vars,
-       // only from the filesystem.
-       certFile := filepath.Join(home, "tls.crt")
-       keyFile := filepath.Join(home, "tls.key")
-       config, err := blockchain.TLSConfig(certFile, keyFile, "")
-       if err == blockchain.ErrNoTLS {
-               return &rpc.Client{BaseURL: *coreURL}
-       } else if err != nil {
-               jww.ERROR.Println("loading TLS cert:", err)
-       }
-
-       t := &http.Transport{
-               DialContext: (&net.Dialer{
-                       Timeout:   30 * time.Second,
-                       KeepAlive: 30 * time.Second,
-                       DualStack: true,
-               }).DialContext,
-               MaxIdleConns:          100,
-               IdleConnTimeout:       90 * time.Second,
-               TLSClientConfig:       config,
-               TLSHandshakeTimeout:   10 * time.Second,
-               ExpectContinueTimeout: 1 * time.Second,
-       }
-
-       url := *coreURL
-       if strings.HasPrefix(url, "http:") {
-               url = "https:" + url[5:]
-       }
-
-       return &rpc.Client{
-               BaseURL: url,
-               Client:  &http.Client{Transport: t},
-       }
-}
-
-func clientCall(path string, req ...interface{}) (interface{}, int) {
-
-       var response = &blockchain.Response{}
-       var request interface{}
-
-       if req != nil {
-               request = req[0]
-       }
 
-       client := mustRPCClient()
-       client.Call(context.Background(), path, request, response)
-
-       switch response.Status {
-       case blockchain.FAIL:
-               jww.ERROR.Println(response.Msg)
-               return nil, ErrRemote
-       case "":
-               jww.ERROR.Println("Unable to connect to the bytomd")
-               return nil, ErrConnect
-       }
-
-       return response.Data, Success
-}
index 0881d44..ca84d63 100644 (file)
@@ -12,6 +12,7 @@ import (
 
        "github.com/bytom/crypto/ed25519/chainkd"
        "github.com/bytom/crypto/sha3pool"
+       "github.com/bytom/util"
 )
 
 var createKeyCmd = &cobra.Command{
@@ -24,8 +25,8 @@ var createKeyCmd = &cobra.Command{
                        Password string `json:"password"`
                }{Alias: args[0], Password: "123456"}
 
-               data, exitCode := clientCall("/create-key", &key)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/create-key", &key)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -41,7 +42,7 @@ var deleteKeyCmd = &cobra.Command{
                xpub := new(chainkd.XPub)
                if err := xpub.UnmarshalText([]byte(args[0])); err != nil {
                        jww.ERROR.Println("delete-key:", err)
-                       os.Exit(ErrLocalExe)
+                       os.Exit(util.ErrLocalExe)
                }
 
                var key = struct {
@@ -49,7 +50,7 @@ var deleteKeyCmd = &cobra.Command{
                        XPub     chainkd.XPub `json:"xpubs"`
                }{XPub: *xpub, Password: "123456"}
 
-               if _, exitCode := clientCall("/delete-key", &key); exitCode != Success {
+               if _, exitCode := util.ClientCall("/delete-key", &key); exitCode != util.Success {
                        os.Exit(exitCode)
                }
                jww.FEEDBACK.Println("Successfully delete key")
@@ -61,8 +62,8 @@ var listKeysCmd = &cobra.Command{
        Short: "List the existing keys",
        Args:  cobra.NoArgs,
        Run: func(cmd *cobra.Command, args []string) {
-               data, exitCode := clientCall("/list-keys")
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/list-keys")
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -90,8 +91,8 @@ var exportPrivateCmd = &cobra.Command{
                key.XPub = *xpub
                key.Password = args[1]
 
-               data, exitCode := clientCall("/export-private-key", &key)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/export-private-key", &key)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -114,11 +115,11 @@ var importPrivateCmd = &cobra.Command{
                privHash, err := base58.Decode(args[1])
                if err != nil {
                        jww.ERROR.Println("wif priv decode error")
-                       os.Exit(ErrLocalExe)
+                       os.Exit(util.ErrLocalExe)
                }
                if len(privHash) != 68 {
                        jww.ERROR.Println("wif priv length error")
-                       os.Exit(ErrLocalExe)
+                       os.Exit(util.ErrLocalExe)
                }
                var hashed [32]byte
 
@@ -126,7 +127,7 @@ var importPrivateCmd = &cobra.Command{
 
                if res := bytes.Compare(hashed[:4], privHash[64:]); res != 0 {
                        jww.ERROR.Println("wif priv hash error")
-                       os.Exit(ErrLocalExe)
+                       os.Exit(util.ErrLocalExe)
                }
 
                var key Key
@@ -135,8 +136,8 @@ var importPrivateCmd = &cobra.Command{
                key.Index, _ = strconv.ParseUint(args[2], 10, 64)
                copy(key.XPrv[:], privHash[:64])
 
-               data, exitCode := clientCall("/import-private-key", &key)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/import-private-key", &key)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
                printJSON(data)
index edc577e..971b924 100644 (file)
@@ -4,6 +4,7 @@ import (
        "os"
 
        "github.com/spf13/cobra"
+       "github.com/bytom/util"
 )
 
 var isMiningCmd = &cobra.Command{
@@ -11,8 +12,8 @@ var isMiningCmd = &cobra.Command{
        Short: "If client is actively mining new blocks",
        Args:  cobra.NoArgs,
        Run: func(cmd *cobra.Command, args []string) {
-               data, exitCode := clientCall("/is-mining")
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/is-mining")
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
                printJSON(data)
index 2733eaf..68967f8 100644 (file)
@@ -5,6 +5,8 @@ import (
 
        "github.com/spf13/cobra"
        jww "github.com/spf13/jwalterweatherman"
+
+       "github.com/bytom/util"
 )
 
 var netInfoCmd = &cobra.Command{
@@ -12,8 +14,8 @@ var netInfoCmd = &cobra.Command{
        Short: "Print the summary of network",
        Args:  cobra.NoArgs,
        Run: func(cmd *cobra.Command, args []string) {
-               data, exitCode := clientCall("/net-info")
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/net-info")
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
                printJSON(data)
@@ -23,8 +25,8 @@ var netListeningCmd = &cobra.Command{
        Use:   "net-listening",
        Short: "If client is actively listening for network connections",
        Run: func(cmd *cobra.Command, args []string) {
-               data, exitCode := clientCall("/net-info")
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/net-info")
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -38,8 +40,8 @@ var peerCountCmd = &cobra.Command{
        Short: "Number of peers currently connected to the client",
        Args:  cobra.NoArgs,
        Run: func(cmd *cobra.Command, args []string) {
-               data, exitCode := clientCall("/net-info")
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/net-info")
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -53,8 +55,8 @@ var netSyncingCmd = &cobra.Command{
        Short: "If the network is still syncing",
        Args:  cobra.NoArgs,
        Run: func(cmd *cobra.Command, args []string) {
-               data, exitCode := clientCall("/net-info")
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/net-info")
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
index 2fbf241..fa38e1b 100644 (file)
@@ -10,6 +10,7 @@ import (
 
        "github.com/bytom/blockchain"
        "github.com/bytom/blockchain/txbuilder"
+       "github.com/bytom/util"
 )
 
 func init() {
@@ -139,17 +140,17 @@ var buildTransactionCmd = &cobra.Command{
                        buildReqStr = fmt.Sprintf(buildControlAddressReqFmt, btmGas, accountInfo, assetInfo, amount, accountInfo, assetInfo, amount, address)
                default:
                        jww.ERROR.Println("Invalid transaction template type")
-                       os.Exit(ErrLocalExe)
+                       os.Exit(util.ErrLocalExe)
                }
 
                var buildReq blockchain.BuildRequest
                if err := json.Unmarshal([]byte(buildReqStr), &buildReq); err != nil {
                        jww.ERROR.Println(err)
-                       os.Exit(ErrLocalExe)
+                       os.Exit(util.ErrLocalExe)
                }
 
-               data, exitCode := clientCall("/build-transaction", &buildReq)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/build-transaction", &buildReq)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -161,13 +162,13 @@ var buildTransactionCmd = &cobra.Command{
                dataMap, ok := data.(map[string]interface{})
                if ok != true {
                        jww.ERROR.Println("invalid type assertion")
-                       os.Exit(ErrLocalParse)
+                       os.Exit(util.ErrLocalParse)
                }
 
                rawTemplate, err := json.Marshal(dataMap)
                if err != nil {
                        jww.ERROR.Println(err)
-                       os.Exit(ErrLocalParse)
+                       os.Exit(util.ErrLocalParse)
                }
 
                jww.FEEDBACK.Printf("Template Type: %s\n%s\n", buildType, string(rawTemplate))
@@ -187,7 +188,7 @@ var signTransactionCmd = &cobra.Command{
                err := json.Unmarshal([]byte(args[0]), &template)
                if err != nil {
                        jww.ERROR.Println(err)
-                       os.Exit(ErrLocalExe)
+                       os.Exit(util.ErrLocalExe)
                }
 
                var req = struct {
@@ -196,8 +197,8 @@ var signTransactionCmd = &cobra.Command{
                }{Auth: "123456", Txs: template}
 
                jww.FEEDBACK.Printf("\n\n")
-               data, exitCode := clientCall("/sign-transaction", &req)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/sign-transaction", &req)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -209,13 +210,13 @@ var signTransactionCmd = &cobra.Command{
                dataMap, ok := data.(map[string]interface{})
                if ok != true {
                        jww.ERROR.Println("invalid type assertion")
-                       os.Exit(ErrLocalParse)
+                       os.Exit(util.ErrLocalParse)
                }
 
                rawSign, err := json.Marshal(dataMap)
                if err != nil {
                        jww.ERROR.Println(err)
-                       os.Exit(ErrLocalParse)
+                       os.Exit(util.ErrLocalParse)
                }
                jww.FEEDBACK.Printf("\nSign Template:\n%s\n", string(rawSign))
        },
@@ -231,12 +232,12 @@ var submitTransactionCmd = &cobra.Command{
                err := json.Unmarshal([]byte(args[0]), &template)
                if err != nil {
                        jww.ERROR.Println(err)
-                       os.Exit(ErrLocalExe)
+                       os.Exit(util.ErrLocalExe)
                }
 
                jww.FEEDBACK.Printf("\n\n")
-               data, exitCode := clientCall("/submit-transaction", &template)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/submit-transaction", &template)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -257,7 +258,7 @@ var signSubTransactionCmd = &cobra.Command{
                err := json.Unmarshal([]byte(args[0]), &template)
                if err != nil {
                        jww.ERROR.Println(err)
-                       os.Exit(ErrLocalExe)
+                       os.Exit(util.ErrLocalExe)
                }
 
                var req = struct {
@@ -266,8 +267,8 @@ var signSubTransactionCmd = &cobra.Command{
                }{Auth: "123456", Txs: template}
 
                jww.FEEDBACK.Printf("\n\n")
-               data, exitCode := clientCall("/sign-submit-transaction", &req)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/sign-submit-transaction", &req)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -285,8 +286,8 @@ var listTransactionsCmd = &cobra.Command{
                        AccountID string `json:"account_id"`
                }{ID: txID, AccountID: account}
 
-               data, exitCode := clientCall("/list-transactions", &filter)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/list-transactions", &filter)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -299,8 +300,8 @@ var gasRateCmd = &cobra.Command{
        Short: "Print the current gas rate",
        Args:  cobra.NoArgs,
        Run: func(cmd *cobra.Command, args []string) {
-               data, exitCode := clientCall("/gas-rate")
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/gas-rate")
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
                printJSON(data)
index dd44150..953315f 100755 (executable)
@@ -5,6 +5,8 @@ import (
 
        "github.com/spf13/cobra"
        jww "github.com/spf13/jwalterweatherman"
+
+       "github.com/bytom/util"
 )
 
 var createTransactionFeedCmd = &cobra.Command{
@@ -16,8 +18,8 @@ var createTransactionFeedCmd = &cobra.Command{
                in.Alias = args[0]
                in.Filter = args[1]
 
-               _, exitCode := clientCall("/create-transaction-feed", &in)
-               if exitCode != Success {
+               _, exitCode := util.ClientCall("/create-transaction-feed", &in)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -30,8 +32,8 @@ var listTransactionFeedsCmd = &cobra.Command{
        Short: "list all of transaction feeds",
        Args:  cobra.NoArgs,
        Run: func(cmd *cobra.Command, args []string) {
-               data, exitCode := clientCall("/list-transaction-feeds")
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/list-transaction-feeds")
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
                printJSONList(data)
@@ -46,8 +48,8 @@ var deleteTransactionFeedCmd = &cobra.Command{
                var in txFeed
                in.Alias = args[0]
 
-               _, exitCode := clientCall("/delete-transaction-feed", &in)
-               if exitCode != Success {
+               _, exitCode := util.ClientCall("/delete-transaction-feed", &in)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
@@ -63,8 +65,8 @@ var getTransactionFeedCmd = &cobra.Command{
                var in txFeed
                in.Alias = args[0]
 
-               data, exitCode := clientCall("/get-transaction-feed", &in)
-               if exitCode != Success {
+               data, exitCode := util.ClientCall("/get-transaction-feed", &in)
+               if exitCode != util.Success {
                        os.Exit(exitCode)
                }
                printJSON(data)
@@ -80,7 +82,7 @@ var updateTransactionFeedCmd = &cobra.Command{
                in.Alias = args[0]
                in.Filter = args[1]
 
-               if _, exitCode := clientCall("/update-transaction-feed", &in); exitCode != Success {
+               if _, exitCode := util.ClientCall("/update-transaction-feed", &in); exitCode != util.Success {
                        os.Exit(exitCode)
                }
                jww.FEEDBACK.Println("Successfully updated transaction feed")
index c882805..f73c399 100644 (file)
@@ -9,6 +9,7 @@ import (
 
        "github.com/bytom/crypto/ed25519/chainkd"
        "github.com/bytom/encoding/json"
+       "github.com/bytom/util"
 )
 
 // accountIns is used for account related request.
@@ -75,13 +76,13 @@ func printJSON(data interface{}) {
        dataMap, ok := data.(map[string]interface{})
        if ok != true {
                jww.ERROR.Println("invalid type assertion")
-               os.Exit(ErrLocalParse)
+               os.Exit(util.ErrLocalParse)
        }
 
        rawData, err := stdjson.MarshalIndent(dataMap, "", "  ")
        if err != nil {
                jww.ERROR.Println(err)
-               os.Exit(ErrLocalParse)
+               os.Exit(util.ErrLocalParse)
        }
 
        jww.FEEDBACK.Println(string(rawData))
@@ -91,7 +92,7 @@ func printJSONList(data interface{}) {
        dataList, ok := data.([]interface{})
        if ok != true {
                jww.ERROR.Println("invalid type assertion")
-               os.Exit(ErrLocalParse)
+               os.Exit(util.ErrLocalParse)
        }
 
        for idx, item := range dataList {
@@ -99,7 +100,7 @@ func printJSONList(data interface{}) {
                rawData, err := stdjson.MarshalIndent(item, "", "  ")
                if err != nil {
                        jww.ERROR.Println(err)
-                       os.Exit(ErrLocalParse)
+                       os.Exit(util.ErrLocalParse)
                }
 
                jww.FEEDBACK.Println(string(rawData))
index cb46748..a1478c9 100644 (file)
@@ -150,7 +150,7 @@ type RPCConfig struct {
 // Default configurable rpc parameters.
 func DefaultRPCConfig() *RPCConfig {
        return &RPCConfig{
-               ListenAddress:     "tcp://0.0.0.0:46657",
+               ListenAddress:     "tcp://0.0.0.0:9888",
                GRPCListenAddress: "",
                Unsafe:            false,
        }
index 1a07ee7..2cf2e45 100755 (executable)
@@ -119,6 +119,7 @@ func rpcInit(h *bc.BlockchainReactor, config *cfg.Config, accessTokens *accessto
                TLSNextProto: map[string]func(*http.Server, *tls.Conn, http.Handler){},
        }
        listenAddr := env.String("LISTEN", config.ApiAddress)
+       log.WithField("api address:", config.ApiAddress).Info("Rpc listen")
        listener, err := net.Listen("tcp", *listenAddr)
        if err != nil {
                cmn.Exit(cmn.Fmt("Failed to register tcp port: %v", err))
index 12c3e49..c1f657c 100644 (file)
@@ -1,10 +1,99 @@
 package integration
 
 import (
-       "os"
+       "fmt"
        "testing"
+       "time"
+       "os"
+
+       cfg "github.com/bytom/config"
+       "github.com/bytom/crypto/ed25519/chainkd"
+       "github.com/bytom/node"
+       "github.com/bytom/util"
 )
 
-func TestMain(m *testing.M) {
-       os.Exit(m.Run())
+// Mock config.
+func mockConfig() *cfg.Config {
+       var config = cfg.DefaultConfig()
+       config.Wallet.Disable = false
+       config.Mining = true
+       config.ApiAddress = "127.0.0.1:9888"
+       return config
+}
+
+// Test net-info call api.
+func testNet() bool {
+       data, exitCode := util.ClientCall("/net-info")
+       if exitCode != util.Success {
+               return false
+       }
+       dataMap, ok := data.(map[string]interface{})
+       if ok && dataMap["listening"].(bool) && dataMap["syncing"].(bool) && dataMap["mining"].(bool) {
+               return true
+       }
+       return false
+}
+
+// Test create-key delete-key list-key api and function.
+func testKey() bool {
+       var key = struct {
+               Alias    string `json:"alias"`
+               Password string `json:"password"`
+       }{Alias: "alice", Password: "123456"}
+
+       data, exitCode := util.ClientCall("/create-key", &key)
+       if exitCode != util.Success {
+               return false
+       }
+       dataMap, ok := data.(map[string]interface{})
+       if (ok && dataMap["alias"].(string) == "alice") == false {
+               return false
+       }
+
+       _, exitCode1 := util.ClientCall("/list-keys")
+       if exitCode1 != util.Success {
+               return false
+       }
+
+       fmt.Println("dataMap", dataMap)
+       xpub := new(chainkd.XPub)
+       if err := xpub.UnmarshalText([]byte(dataMap["xpub"].(string))); err != nil {
+               return false
+       }
+
+       var key1 = struct {
+               Password string
+               XPub     chainkd.XPub `json:"xpubs"`
+       }{XPub: *xpub, Password: "123456"}
+
+       if _, exitCode := util.ClientCall("/delete-key", &key1); exitCode != util.Success {
+               return false
+       }
+
+       return true
+}
+
+// Test node running.
+func TestRunNode(t *testing.T) {
+       // Create & start node
+       config := mockConfig()
+       n := node.NewNodeDefault(config)
+       if _, err := n.Start(); err != nil {
+               t.Fatalf("Failed to start node: %v", err)
+       }
+
+       go func() {
+               time.Sleep(3000 * time.Millisecond)
+               if testNet() && testKey() {
+                       os.RemoveAll("./data")
+                       os.RemoveAll("./keystore")
+                       os.Exit(0)
+               } else {
+                       os.RemoveAll("./data")
+                       os.RemoveAll("./keystore")
+                       os.Exit(1)
+               }
+       }()
+       // Trap signal, run forever.
+       n.RunForever()
 }
diff --git a/util/util.go b/util/util.go
new file mode 100644 (file)
index 0000000..ec9c499
--- /dev/null
@@ -0,0 +1,99 @@
+package util
+
+import (
+       "context"
+       "net"
+       "net/http"
+       "path/filepath"
+       "strings"
+       "time"
+
+       "github.com/bytom/blockchain"
+       "github.com/bytom/blockchain/rpc"
+       "github.com/bytom/env"
+       jww "github.com/spf13/jwalterweatherman"
+)
+
+const (
+       // Success indicates the rpc calling is successful.
+       Success = iota
+       // ErrLocalExe indicates error occurs before the rpc calling.
+       ErrLocalExe
+       // ErrConnect indicates error occurs connecting to the bytomd, e.g.,
+       // bytomd can't parse the received arguments.
+       ErrConnect
+       // ErrLocalParse indicates error occurs locally when parsing the response.
+       ErrLocalParse
+       // ErrRemote indicates error occurs in bytomd.
+       ErrRemote
+)
+
+var (
+       home    = blockchain.HomeDirFromEnvironment()
+       coreURL = env.String("BYTOM_URL", "http://localhost:9888")
+)
+
+// Wraper rpc's client
+func mustRPCClient() *rpc.Client {
+       // TODO(kr): refactor some of this cert-loading logic into bytom/blockchain
+       // and use it from cored as well.
+       // Note that this function, unlike maybeUseTLS in cored,
+       // does not load the cert and key from env vars,
+       // only from the filesystem.
+       certFile := filepath.Join(home, "tls.crt")
+       keyFile := filepath.Join(home, "tls.key")
+       config, err := blockchain.TLSConfig(certFile, keyFile, "")
+       if err == blockchain.ErrNoTLS {
+               return &rpc.Client{BaseURL: *coreURL}
+       } else if err != nil {
+               jww.ERROR.Println("loading TLS cert:", err)
+       }
+
+       t := &http.Transport{
+               DialContext: (&net.Dialer{
+                       Timeout:   30 * time.Second,
+                       KeepAlive: 30 * time.Second,
+                       DualStack: true,
+               }).DialContext,
+               MaxIdleConns:          100,
+               IdleConnTimeout:       90 * time.Second,
+               TLSClientConfig:       config,
+               TLSHandshakeTimeout:   10 * time.Second,
+               ExpectContinueTimeout: 1 * time.Second,
+       }
+
+       url := *coreURL
+       if strings.HasPrefix(url, "http:") {
+               url = "https:" + url[5:]
+       }
+
+       return &rpc.Client{
+               BaseURL: url,
+               Client:  &http.Client{Transport: t},
+       }
+}
+
+// Wrapper rpc call api.
+func ClientCall(path string, req ...interface{}) (interface{}, int) {
+
+       var response = &blockchain.Response{}
+       var request interface{}
+
+       if req != nil {
+               request = req[0]
+       }
+
+       client := mustRPCClient()
+       client.Call(context.Background(), path, request, response)
+
+       switch response.Status {
+       case blockchain.FAIL:
+               jww.ERROR.Println(response.Msg)
+               return nil, ErrRemote
+       case "":
+               jww.ERROR.Println("Unable to connect to the bytomd")
+               return nil, ErrConnect
+       }
+
+       return response.Data, Success
+}