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