You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

717 lines
17 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
8 years ago
9 years ago
7 years ago
7 years ago
9 years ago
9 years ago
lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
7 years ago
7 years ago
7 years ago
9 years ago
9 years ago
9 years ago
9 years ago
lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
9 years ago
  1. package main
  2. import (
  3. "bufio"
  4. "context"
  5. "encoding/hex"
  6. "errors"
  7. "fmt"
  8. "io"
  9. "os"
  10. "strings"
  11. "github.com/spf13/cobra"
  12. "github.com/tendermint/tendermint/libs/log"
  13. tmos "github.com/tendermint/tendermint/libs/os"
  14. abcicli "github.com/tendermint/tendermint/abci/client"
  15. "github.com/tendermint/tendermint/abci/example/code"
  16. "github.com/tendermint/tendermint/abci/example/counter"
  17. "github.com/tendermint/tendermint/abci/example/kvstore"
  18. "github.com/tendermint/tendermint/abci/server"
  19. servertest "github.com/tendermint/tendermint/abci/tests/server"
  20. "github.com/tendermint/tendermint/abci/types"
  21. "github.com/tendermint/tendermint/abci/version"
  22. "github.com/tendermint/tendermint/proto/tendermint/crypto"
  23. )
  24. // client is a global variable so it can be reused by the console
  25. var (
  26. client abcicli.Client
  27. logger log.Logger
  28. ctx = context.Background()
  29. )
  30. // flags
  31. var (
  32. // global
  33. flagAddress string
  34. flagAbci string
  35. flagVerbose bool // for the println output
  36. flagLogLevel string // for the logger
  37. // query
  38. flagPath string
  39. flagHeight int
  40. flagProve bool
  41. // counter
  42. flagSerial bool
  43. // kvstore
  44. flagPersist string
  45. )
  46. var RootCmd = &cobra.Command{
  47. Use: "abci-cli",
  48. Short: "the ABCI CLI tool wraps an ABCI client",
  49. Long: "the ABCI CLI tool wraps an ABCI client and is used for testing ABCI servers",
  50. PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
  51. switch cmd.Use {
  52. case "counter", "kvstore": // for the examples apps, don't pre-run
  53. return nil
  54. case "version": // skip running for version command
  55. return nil
  56. }
  57. if logger == nil {
  58. logger = log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo, false)
  59. }
  60. if client == nil {
  61. var err error
  62. client, err = abcicli.NewClient(flagAddress, flagAbci, false)
  63. if err != nil {
  64. return err
  65. }
  66. client.SetLogger(logger.With("module", "abci-client"))
  67. if err := client.Start(); err != nil {
  68. return err
  69. }
  70. }
  71. return nil
  72. },
  73. }
  74. // Structure for data passed to print response.
  75. type response struct {
  76. // generic abci response
  77. Data []byte
  78. Code uint32
  79. Info string
  80. Log string
  81. Query *queryResponse
  82. }
  83. type queryResponse struct {
  84. Key []byte
  85. Value []byte
  86. Height int64
  87. ProofOps *crypto.ProofOps
  88. }
  89. func Execute() error {
  90. addGlobalFlags()
  91. addCommands()
  92. return RootCmd.Execute()
  93. }
  94. func addGlobalFlags() {
  95. RootCmd.PersistentFlags().StringVarP(&flagAddress,
  96. "address",
  97. "",
  98. "tcp://0.0.0.0:26658",
  99. "address of application socket")
  100. RootCmd.PersistentFlags().StringVarP(&flagAbci, "abci", "", "socket", "either socket or grpc")
  101. RootCmd.PersistentFlags().BoolVarP(&flagVerbose,
  102. "verbose",
  103. "v",
  104. false,
  105. "print the command and results as if it were a console session")
  106. RootCmd.PersistentFlags().StringVarP(&flagLogLevel, "log_level", "", "debug", "set the logger level")
  107. }
  108. func addQueryFlags() {
  109. queryCmd.PersistentFlags().StringVarP(&flagPath, "path", "", "/store", "path to prefix query with")
  110. queryCmd.PersistentFlags().IntVarP(&flagHeight, "height", "", 0, "height to query the blockchain at")
  111. queryCmd.PersistentFlags().BoolVarP(&flagProve,
  112. "prove",
  113. "",
  114. false,
  115. "whether or not to return a merkle proof of the query result")
  116. }
  117. func addCounterFlags() {
  118. counterCmd.PersistentFlags().BoolVarP(&flagSerial, "serial", "", false, "enforce incrementing (serial) transactions")
  119. }
  120. func addKVStoreFlags() {
  121. kvstoreCmd.PersistentFlags().StringVarP(&flagPersist, "persist", "", "", "directory to use for a database")
  122. }
  123. func addCommands() {
  124. RootCmd.AddCommand(batchCmd)
  125. RootCmd.AddCommand(consoleCmd)
  126. RootCmd.AddCommand(echoCmd)
  127. RootCmd.AddCommand(infoCmd)
  128. RootCmd.AddCommand(deliverTxCmd)
  129. RootCmd.AddCommand(checkTxCmd)
  130. RootCmd.AddCommand(commitCmd)
  131. RootCmd.AddCommand(versionCmd)
  132. RootCmd.AddCommand(testCmd)
  133. addQueryFlags()
  134. RootCmd.AddCommand(queryCmd)
  135. // examples
  136. addCounterFlags()
  137. RootCmd.AddCommand(counterCmd)
  138. addKVStoreFlags()
  139. RootCmd.AddCommand(kvstoreCmd)
  140. }
  141. var batchCmd = &cobra.Command{
  142. Use: "batch",
  143. Short: "run a batch of abci commands against an application",
  144. Long: `run a batch of abci commands against an application
  145. This command is run by piping in a file containing a series of commands
  146. you'd like to run:
  147. abci-cli batch < example.file
  148. where example.file looks something like:
  149. check_tx 0x00
  150. check_tx 0xff
  151. deliver_tx 0x00
  152. check_tx 0x00
  153. deliver_tx 0x01
  154. deliver_tx 0x04
  155. info
  156. `,
  157. Args: cobra.ExactArgs(0),
  158. RunE: cmdBatch,
  159. }
  160. var consoleCmd = &cobra.Command{
  161. Use: "console",
  162. Short: "start an interactive ABCI console for multiple commands",
  163. Long: `start an interactive ABCI console for multiple commands
  164. This command opens an interactive console for running any of the other commands
  165. without opening a new connection each time
  166. `,
  167. Args: cobra.ExactArgs(0),
  168. ValidArgs: []string{"echo", "info", "deliver_tx", "check_tx", "commit", "query"},
  169. RunE: cmdConsole,
  170. }
  171. var echoCmd = &cobra.Command{
  172. Use: "echo",
  173. Short: "have the application echo a message",
  174. Long: "have the application echo a message",
  175. Args: cobra.ExactArgs(1),
  176. RunE: cmdEcho,
  177. }
  178. var infoCmd = &cobra.Command{
  179. Use: "info",
  180. Short: "get some info about the application",
  181. Long: "get some info about the application",
  182. Args: cobra.ExactArgs(0),
  183. RunE: cmdInfo,
  184. }
  185. var deliverTxCmd = &cobra.Command{
  186. Use: "deliver_tx",
  187. Short: "deliver a new transaction to the application",
  188. Long: "deliver a new transaction to the application",
  189. Args: cobra.ExactArgs(1),
  190. RunE: cmdDeliverTx,
  191. }
  192. var checkTxCmd = &cobra.Command{
  193. Use: "check_tx",
  194. Short: "validate a transaction",
  195. Long: "validate a transaction",
  196. Args: cobra.ExactArgs(1),
  197. RunE: cmdCheckTx,
  198. }
  199. var commitCmd = &cobra.Command{
  200. Use: "commit",
  201. Short: "commit the application state and return the Merkle root hash",
  202. Long: "commit the application state and return the Merkle root hash",
  203. Args: cobra.ExactArgs(0),
  204. RunE: cmdCommit,
  205. }
  206. var versionCmd = &cobra.Command{
  207. Use: "version",
  208. Short: "print ABCI console version",
  209. Long: "print ABCI console version",
  210. Args: cobra.ExactArgs(0),
  211. RunE: func(cmd *cobra.Command, args []string) error {
  212. fmt.Println(version.Version)
  213. return nil
  214. },
  215. }
  216. var queryCmd = &cobra.Command{
  217. Use: "query",
  218. Short: "query the application state",
  219. Long: "query the application state",
  220. Args: cobra.ExactArgs(1),
  221. RunE: cmdQuery,
  222. }
  223. var counterCmd = &cobra.Command{
  224. Use: "counter",
  225. Short: "ABCI demo example",
  226. Long: "ABCI demo example",
  227. Args: cobra.ExactArgs(0),
  228. RunE: cmdCounter,
  229. }
  230. var kvstoreCmd = &cobra.Command{
  231. Use: "kvstore",
  232. Short: "ABCI demo example",
  233. Long: "ABCI demo example",
  234. Args: cobra.ExactArgs(0),
  235. RunE: cmdKVStore,
  236. }
  237. var testCmd = &cobra.Command{
  238. Use: "test",
  239. Short: "run integration tests",
  240. Long: "run integration tests",
  241. Args: cobra.ExactArgs(0),
  242. RunE: cmdTest,
  243. }
  244. // Generates new Args array based off of previous call args to maintain flag persistence
  245. func persistentArgs(line []byte) []string {
  246. // generate the arguments to run from original os.Args
  247. // to maintain flag arguments
  248. args := os.Args
  249. args = args[:len(args)-1] // remove the previous command argument
  250. if len(line) > 0 { // prevents introduction of extra space leading to argument parse errors
  251. args = append(args, strings.Split(string(line), " ")...)
  252. }
  253. return args
  254. }
  255. //--------------------------------------------------------------------------------
  256. func compose(fs []func() error) error {
  257. if len(fs) == 0 {
  258. return nil
  259. }
  260. err := fs[0]()
  261. if err == nil {
  262. return compose(fs[1:])
  263. }
  264. return err
  265. }
  266. func cmdTest(cmd *cobra.Command, args []string) error {
  267. return compose(
  268. []func() error{
  269. func() error { return servertest.InitChain(client) },
  270. func() error { return servertest.Commit(client, nil) },
  271. func() error { return servertest.DeliverTx(client, []byte("abc"), code.CodeTypeBadNonce, nil) },
  272. func() error { return servertest.Commit(client, nil) },
  273. func() error { return servertest.DeliverTx(client, []byte{0x00}, code.CodeTypeOK, nil) },
  274. func() error { return servertest.Commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 1}) },
  275. func() error { return servertest.DeliverTx(client, []byte{0x00}, code.CodeTypeBadNonce, nil) },
  276. func() error { return servertest.DeliverTx(client, []byte{0x01}, code.CodeTypeOK, nil) },
  277. func() error { return servertest.DeliverTx(client, []byte{0x00, 0x02}, code.CodeTypeOK, nil) },
  278. func() error { return servertest.DeliverTx(client, []byte{0x00, 0x03}, code.CodeTypeOK, nil) },
  279. func() error { return servertest.DeliverTx(client, []byte{0x00, 0x00, 0x04}, code.CodeTypeOK, nil) },
  280. func() error {
  281. return servertest.DeliverTx(client, []byte{0x00, 0x00, 0x06}, code.CodeTypeBadNonce, nil)
  282. },
  283. func() error { return servertest.Commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 5}) },
  284. })
  285. }
  286. func cmdBatch(cmd *cobra.Command, args []string) error {
  287. bufReader := bufio.NewReader(os.Stdin)
  288. LOOP:
  289. for {
  290. line, more, err := bufReader.ReadLine()
  291. switch {
  292. case more:
  293. return errors.New("input line is too long")
  294. case err == io.EOF:
  295. break LOOP
  296. case len(line) == 0:
  297. continue
  298. case err != nil:
  299. return err
  300. }
  301. cmdArgs := persistentArgs(line)
  302. if err := muxOnCommands(cmd, cmdArgs); err != nil {
  303. return err
  304. }
  305. fmt.Println()
  306. }
  307. return nil
  308. }
  309. func cmdConsole(cmd *cobra.Command, args []string) error {
  310. for {
  311. fmt.Printf("> ")
  312. bufReader := bufio.NewReader(os.Stdin)
  313. line, more, err := bufReader.ReadLine()
  314. if more {
  315. return errors.New("input is too long")
  316. } else if err != nil {
  317. return err
  318. }
  319. pArgs := persistentArgs(line)
  320. if err := muxOnCommands(cmd, pArgs); err != nil {
  321. return err
  322. }
  323. }
  324. }
  325. func muxOnCommands(cmd *cobra.Command, pArgs []string) error {
  326. if len(pArgs) < 2 {
  327. return errors.New("expecting persistent args of the form: abci-cli [command] <...>")
  328. }
  329. // TODO: this parsing is fragile
  330. args := []string{}
  331. for i := 0; i < len(pArgs); i++ {
  332. arg := pArgs[i]
  333. // check for flags
  334. if strings.HasPrefix(arg, "-") {
  335. // if it has an equal, we can just skip
  336. if strings.Contains(arg, "=") {
  337. continue
  338. }
  339. // if its a boolean, we can just skip
  340. _, err := cmd.Flags().GetBool(strings.TrimLeft(arg, "-"))
  341. if err == nil {
  342. continue
  343. }
  344. // otherwise, we need to skip the next one too
  345. i++
  346. continue
  347. }
  348. // append the actual arg
  349. args = append(args, arg)
  350. }
  351. var subCommand string
  352. var actualArgs []string
  353. if len(args) > 1 {
  354. subCommand = args[1]
  355. }
  356. if len(args) > 2 {
  357. actualArgs = args[2:]
  358. }
  359. cmd.Use = subCommand // for later print statements ...
  360. switch strings.ToLower(subCommand) {
  361. case "check_tx":
  362. return cmdCheckTx(cmd, actualArgs)
  363. case "commit":
  364. return cmdCommit(cmd, actualArgs)
  365. case "deliver_tx":
  366. return cmdDeliverTx(cmd, actualArgs)
  367. case "echo":
  368. return cmdEcho(cmd, actualArgs)
  369. case "info":
  370. return cmdInfo(cmd, actualArgs)
  371. case "query":
  372. return cmdQuery(cmd, actualArgs)
  373. default:
  374. return cmdUnimplemented(cmd, pArgs)
  375. }
  376. }
  377. func cmdUnimplemented(cmd *cobra.Command, args []string) error {
  378. msg := "unimplemented command"
  379. if len(args) > 0 {
  380. msg += fmt.Sprintf(" args: [%s]", strings.Join(args, " "))
  381. }
  382. printResponse(cmd, args, response{
  383. Code: codeBad,
  384. Log: msg,
  385. })
  386. fmt.Println("Available commands:")
  387. fmt.Printf("%s: %s\n", echoCmd.Use, echoCmd.Short)
  388. fmt.Printf("%s: %s\n", infoCmd.Use, infoCmd.Short)
  389. fmt.Printf("%s: %s\n", checkTxCmd.Use, checkTxCmd.Short)
  390. fmt.Printf("%s: %s\n", deliverTxCmd.Use, deliverTxCmd.Short)
  391. fmt.Printf("%s: %s\n", queryCmd.Use, queryCmd.Short)
  392. fmt.Printf("%s: %s\n", commitCmd.Use, commitCmd.Short)
  393. fmt.Println("Use \"[command] --help\" for more information about a command.")
  394. return nil
  395. }
  396. // Have the application echo a message
  397. func cmdEcho(cmd *cobra.Command, args []string) error {
  398. msg := ""
  399. if len(args) > 0 {
  400. msg = args[0]
  401. }
  402. res, err := client.EchoSync(ctx, msg)
  403. if err != nil {
  404. return err
  405. }
  406. printResponse(cmd, args, response{
  407. Data: []byte(res.Message),
  408. })
  409. return nil
  410. }
  411. // Get some info from the application
  412. func cmdInfo(cmd *cobra.Command, args []string) error {
  413. var version string
  414. if len(args) == 1 {
  415. version = args[0]
  416. }
  417. res, err := client.InfoSync(ctx, types.RequestInfo{Version: version})
  418. if err != nil {
  419. return err
  420. }
  421. printResponse(cmd, args, response{
  422. Data: []byte(res.Data),
  423. })
  424. return nil
  425. }
  426. const codeBad uint32 = 10
  427. // Append a new tx to application
  428. func cmdDeliverTx(cmd *cobra.Command, args []string) error {
  429. if len(args) == 0 {
  430. printResponse(cmd, args, response{
  431. Code: codeBad,
  432. Log: "want the tx",
  433. })
  434. return nil
  435. }
  436. txBytes, err := stringOrHexToBytes(args[0])
  437. if err != nil {
  438. return err
  439. }
  440. res, err := client.DeliverTxSync(ctx, types.RequestDeliverTx{Tx: txBytes})
  441. if err != nil {
  442. return err
  443. }
  444. printResponse(cmd, args, response{
  445. Code: res.Code,
  446. Data: res.Data,
  447. Info: res.Info,
  448. Log: res.Log,
  449. })
  450. return nil
  451. }
  452. // Validate a tx
  453. func cmdCheckTx(cmd *cobra.Command, args []string) error {
  454. if len(args) == 0 {
  455. printResponse(cmd, args, response{
  456. Code: codeBad,
  457. Info: "want the tx",
  458. })
  459. return nil
  460. }
  461. txBytes, err := stringOrHexToBytes(args[0])
  462. if err != nil {
  463. return err
  464. }
  465. res, err := client.CheckTxSync(ctx, types.RequestCheckTx{Tx: txBytes})
  466. if err != nil {
  467. return err
  468. }
  469. printResponse(cmd, args, response{
  470. Code: res.Code,
  471. Data: res.Data,
  472. Info: res.Info,
  473. Log: res.Log,
  474. })
  475. return nil
  476. }
  477. // Get application Merkle root hash
  478. func cmdCommit(cmd *cobra.Command, args []string) error {
  479. res, err := client.CommitSync(ctx)
  480. if err != nil {
  481. return err
  482. }
  483. printResponse(cmd, args, response{
  484. Data: res.Data,
  485. })
  486. return nil
  487. }
  488. // Query application state
  489. func cmdQuery(cmd *cobra.Command, args []string) error {
  490. if len(args) == 0 {
  491. printResponse(cmd, args, response{
  492. Code: codeBad,
  493. Info: "want the query",
  494. Log: "",
  495. })
  496. return nil
  497. }
  498. queryBytes, err := stringOrHexToBytes(args[0])
  499. if err != nil {
  500. return err
  501. }
  502. resQuery, err := client.QuerySync(ctx, types.RequestQuery{
  503. Data: queryBytes,
  504. Path: flagPath,
  505. Height: int64(flagHeight),
  506. Prove: flagProve,
  507. })
  508. if err != nil {
  509. return err
  510. }
  511. printResponse(cmd, args, response{
  512. Code: resQuery.Code,
  513. Info: resQuery.Info,
  514. Log: resQuery.Log,
  515. Query: &queryResponse{
  516. Key: resQuery.Key,
  517. Value: resQuery.Value,
  518. Height: resQuery.Height,
  519. ProofOps: resQuery.ProofOps,
  520. },
  521. })
  522. return nil
  523. }
  524. func cmdCounter(cmd *cobra.Command, args []string) error {
  525. app := counter.NewApplication(flagSerial)
  526. logger := log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo, false)
  527. // Start the listener
  528. srv, err := server.NewServer(flagAddress, flagAbci, app)
  529. if err != nil {
  530. return err
  531. }
  532. srv.SetLogger(logger.With("module", "abci-server"))
  533. if err := srv.Start(); err != nil {
  534. return err
  535. }
  536. // Stop upon receiving SIGTERM or CTRL-C.
  537. tmos.TrapSignal(logger, func() {
  538. // Cleanup
  539. if err := srv.Stop(); err != nil {
  540. logger.Error("Error while stopping server", "err", err)
  541. }
  542. })
  543. // Run forever.
  544. select {}
  545. }
  546. func cmdKVStore(cmd *cobra.Command, args []string) error {
  547. logger := log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo, false)
  548. // Create the application - in memory or persisted to disk
  549. var app types.Application
  550. if flagPersist == "" {
  551. app = kvstore.NewApplication()
  552. } else {
  553. app = kvstore.NewPersistentKVStoreApplication(flagPersist)
  554. app.(*kvstore.PersistentKVStoreApplication).SetLogger(logger.With("module", "kvstore"))
  555. }
  556. // Start the listener
  557. srv, err := server.NewServer(flagAddress, flagAbci, app)
  558. if err != nil {
  559. return err
  560. }
  561. srv.SetLogger(logger.With("module", "abci-server"))
  562. if err := srv.Start(); err != nil {
  563. return err
  564. }
  565. // Stop upon receiving SIGTERM or CTRL-C.
  566. tmos.TrapSignal(logger, func() {
  567. // Cleanup
  568. if err := srv.Stop(); err != nil {
  569. logger.Error("Error while stopping server", "err", err)
  570. }
  571. })
  572. // Run forever.
  573. select {}
  574. }
  575. //--------------------------------------------------------------------------------
  576. func printResponse(cmd *cobra.Command, args []string, rsp response) {
  577. if flagVerbose {
  578. fmt.Println(">", cmd.Use, strings.Join(args, " "))
  579. }
  580. // Always print the status code.
  581. if rsp.Code == types.CodeTypeOK {
  582. fmt.Printf("-> code: OK\n")
  583. } else {
  584. fmt.Printf("-> code: %d\n", rsp.Code)
  585. }
  586. if len(rsp.Data) != 0 {
  587. // Do no print this line when using the commit command
  588. // because the string comes out as gibberish
  589. if cmd.Use != "commit" {
  590. fmt.Printf("-> data: %s\n", rsp.Data)
  591. }
  592. fmt.Printf("-> data.hex: 0x%X\n", rsp.Data)
  593. }
  594. if rsp.Log != "" {
  595. fmt.Printf("-> log: %s\n", rsp.Log)
  596. }
  597. if rsp.Query != nil {
  598. fmt.Printf("-> height: %d\n", rsp.Query.Height)
  599. if rsp.Query.Key != nil {
  600. fmt.Printf("-> key: %s\n", rsp.Query.Key)
  601. fmt.Printf("-> key.hex: %X\n", rsp.Query.Key)
  602. }
  603. if rsp.Query.Value != nil {
  604. fmt.Printf("-> value: %s\n", rsp.Query.Value)
  605. fmt.Printf("-> value.hex: %X\n", rsp.Query.Value)
  606. }
  607. if rsp.Query.ProofOps != nil {
  608. fmt.Printf("-> proof: %#v\n", rsp.Query.ProofOps)
  609. }
  610. }
  611. }
  612. // NOTE: s is interpreted as a string unless prefixed with 0x
  613. func stringOrHexToBytes(s string) ([]byte, error) {
  614. if len(s) > 2 && strings.ToLower(s[:2]) == "0x" {
  615. b, err := hex.DecodeString(s[2:])
  616. if err != nil {
  617. err = fmt.Errorf("error decoding hex argument: %s", err.Error())
  618. return nil, err
  619. }
  620. return b, nil
  621. }
  622. if !strings.HasPrefix(s, "\"") || !strings.HasSuffix(s, "\"") {
  623. err := fmt.Errorf("invalid string arg: \"%s\". Must be quoted or a \"0x\"-prefixed hex string", s)
  624. return nil, err
  625. }
  626. return []byte(s[1 : len(s)-1]), nil
  627. }