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.

745 lines
18 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/merkle"
  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 *merkle.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(setOptionCmd)
  131. RootCmd.AddCommand(deliverTxCmd)
  132. RootCmd.AddCommand(checkTxCmd)
  133. RootCmd.AddCommand(commitCmd)
  134. RootCmd.AddCommand(versionCmd)
  135. RootCmd.AddCommand(testCmd)
  136. addQueryFlags()
  137. RootCmd.AddCommand(queryCmd)
  138. // examples
  139. addCounterFlags()
  140. RootCmd.AddCommand(counterCmd)
  141. addKVStoreFlags()
  142. RootCmd.AddCommand(kvstoreCmd)
  143. }
  144. var batchCmd = &cobra.Command{
  145. Use: "batch",
  146. Short: "run a batch of abci commands against an application",
  147. Long: `run a batch of abci commands against an application
  148. This command is run by piping in a file containing a series of commands
  149. you'd like to run:
  150. abci-cli batch < example.file
  151. where example.file looks something like:
  152. set_option serial on
  153. check_tx 0x00
  154. check_tx 0xff
  155. deliver_tx 0x00
  156. check_tx 0x00
  157. deliver_tx 0x01
  158. deliver_tx 0x04
  159. info
  160. `,
  161. Args: cobra.ExactArgs(0),
  162. RunE: cmdBatch,
  163. }
  164. var consoleCmd = &cobra.Command{
  165. Use: "console",
  166. Short: "start an interactive ABCI console for multiple commands",
  167. Long: `start an interactive ABCI console for multiple commands
  168. This command opens an interactive console for running any of the other commands
  169. without opening a new connection each time
  170. `,
  171. Args: cobra.ExactArgs(0),
  172. ValidArgs: []string{"echo", "info", "set_option", "deliver_tx", "check_tx", "commit", "query"},
  173. RunE: cmdConsole,
  174. }
  175. var echoCmd = &cobra.Command{
  176. Use: "echo",
  177. Short: "have the application echo a message",
  178. Long: "have the application echo a message",
  179. Args: cobra.ExactArgs(1),
  180. RunE: cmdEcho,
  181. }
  182. var infoCmd = &cobra.Command{
  183. Use: "info",
  184. Short: "get some info about the application",
  185. Long: "get some info about the application",
  186. Args: cobra.ExactArgs(0),
  187. RunE: cmdInfo,
  188. }
  189. var setOptionCmd = &cobra.Command{
  190. Use: "set_option",
  191. Short: "set an option on the application",
  192. Long: "set an option on the application",
  193. Args: cobra.ExactArgs(2),
  194. RunE: cmdSetOption,
  195. }
  196. var deliverTxCmd = &cobra.Command{
  197. Use: "deliver_tx",
  198. Short: "deliver a new transaction to the application",
  199. Long: "deliver a new transaction to the application",
  200. Args: cobra.ExactArgs(1),
  201. RunE: cmdDeliverTx,
  202. }
  203. var checkTxCmd = &cobra.Command{
  204. Use: "check_tx",
  205. Short: "validate a transaction",
  206. Long: "validate a transaction",
  207. Args: cobra.ExactArgs(1),
  208. RunE: cmdCheckTx,
  209. }
  210. var commitCmd = &cobra.Command{
  211. Use: "commit",
  212. Short: "commit the application state and return the Merkle root hash",
  213. Long: "commit the application state and return the Merkle root hash",
  214. Args: cobra.ExactArgs(0),
  215. RunE: cmdCommit,
  216. }
  217. var versionCmd = &cobra.Command{
  218. Use: "version",
  219. Short: "print ABCI console version",
  220. Long: "print ABCI console version",
  221. Args: cobra.ExactArgs(0),
  222. RunE: func(cmd *cobra.Command, args []string) error {
  223. fmt.Println(version.Version)
  224. return nil
  225. },
  226. }
  227. var queryCmd = &cobra.Command{
  228. Use: "query",
  229. Short: "query the application state",
  230. Long: "query the application state",
  231. Args: cobra.ExactArgs(1),
  232. RunE: cmdQuery,
  233. }
  234. var counterCmd = &cobra.Command{
  235. Use: "counter",
  236. Short: "ABCI demo example",
  237. Long: "ABCI demo example",
  238. Args: cobra.ExactArgs(0),
  239. RunE: cmdCounter,
  240. }
  241. var kvstoreCmd = &cobra.Command{
  242. Use: "kvstore",
  243. Short: "ABCI demo example",
  244. Long: "ABCI demo example",
  245. Args: cobra.ExactArgs(0),
  246. RunE: cmdKVStore,
  247. }
  248. var testCmd = &cobra.Command{
  249. Use: "test",
  250. Short: "run integration tests",
  251. Long: "run integration tests",
  252. Args: cobra.ExactArgs(0),
  253. RunE: cmdTest,
  254. }
  255. // Generates new Args array based off of previous call args to maintain flag persistence
  256. func persistentArgs(line []byte) []string {
  257. // generate the arguments to run from original os.Args
  258. // to maintain flag arguments
  259. args := os.Args
  260. args = args[:len(args)-1] // remove the previous command argument
  261. if len(line) > 0 { // prevents introduction of extra space leading to argument parse errors
  262. args = append(args, strings.Split(string(line), " ")...)
  263. }
  264. return args
  265. }
  266. //--------------------------------------------------------------------------------
  267. func compose(fs []func() error) error {
  268. if len(fs) == 0 {
  269. return nil
  270. }
  271. err := fs[0]()
  272. if err == nil {
  273. return compose(fs[1:])
  274. }
  275. return err
  276. }
  277. func cmdTest(cmd *cobra.Command, args []string) error {
  278. return compose(
  279. []func() error{
  280. func() error { return servertest.InitChain(client) },
  281. func() error { return servertest.SetOption(client, "serial", "on") },
  282. func() error { return servertest.Commit(client, nil) },
  283. func() error { return servertest.DeliverTx(client, []byte("abc"), code.CodeTypeBadNonce, nil) },
  284. func() error { return servertest.Commit(client, nil) },
  285. func() error { return servertest.DeliverTx(client, []byte{0x00}, code.CodeTypeOK, nil) },
  286. func() error { return servertest.Commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 1}) },
  287. func() error { return servertest.DeliverTx(client, []byte{0x00}, code.CodeTypeBadNonce, nil) },
  288. func() error { return servertest.DeliverTx(client, []byte{0x01}, code.CodeTypeOK, nil) },
  289. func() error { return servertest.DeliverTx(client, []byte{0x00, 0x02}, code.CodeTypeOK, nil) },
  290. func() error { return servertest.DeliverTx(client, []byte{0x00, 0x03}, code.CodeTypeOK, nil) },
  291. func() error { return servertest.DeliverTx(client, []byte{0x00, 0x00, 0x04}, code.CodeTypeOK, nil) },
  292. func() error {
  293. return servertest.DeliverTx(client, []byte{0x00, 0x00, 0x06}, code.CodeTypeBadNonce, nil)
  294. },
  295. func() error { return servertest.Commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 5}) },
  296. })
  297. }
  298. func cmdBatch(cmd *cobra.Command, args []string) error {
  299. bufReader := bufio.NewReader(os.Stdin)
  300. LOOP:
  301. for {
  302. line, more, err := bufReader.ReadLine()
  303. switch {
  304. case more:
  305. return errors.New("input line is too long")
  306. case err == io.EOF:
  307. break LOOP
  308. case len(line) == 0:
  309. continue
  310. case err != nil:
  311. return err
  312. }
  313. cmdArgs := persistentArgs(line)
  314. if err := muxOnCommands(cmd, cmdArgs); err != nil {
  315. return err
  316. }
  317. fmt.Println()
  318. }
  319. return nil
  320. }
  321. func cmdConsole(cmd *cobra.Command, args []string) error {
  322. for {
  323. fmt.Printf("> ")
  324. bufReader := bufio.NewReader(os.Stdin)
  325. line, more, err := bufReader.ReadLine()
  326. if more {
  327. return errors.New("input is too long")
  328. } else if err != nil {
  329. return err
  330. }
  331. pArgs := persistentArgs(line)
  332. if err := muxOnCommands(cmd, pArgs); err != nil {
  333. return err
  334. }
  335. }
  336. }
  337. func muxOnCommands(cmd *cobra.Command, pArgs []string) error {
  338. if len(pArgs) < 2 {
  339. return errors.New("expecting persistent args of the form: abci-cli [command] <...>")
  340. }
  341. // TODO: this parsing is fragile
  342. args := []string{}
  343. for i := 0; i < len(pArgs); i++ {
  344. arg := pArgs[i]
  345. // check for flags
  346. if strings.HasPrefix(arg, "-") {
  347. // if it has an equal, we can just skip
  348. if strings.Contains(arg, "=") {
  349. continue
  350. }
  351. // if its a boolean, we can just skip
  352. _, err := cmd.Flags().GetBool(strings.TrimLeft(arg, "-"))
  353. if err == nil {
  354. continue
  355. }
  356. // otherwise, we need to skip the next one too
  357. i++
  358. continue
  359. }
  360. // append the actual arg
  361. args = append(args, arg)
  362. }
  363. var subCommand string
  364. var actualArgs []string
  365. if len(args) > 1 {
  366. subCommand = args[1]
  367. }
  368. if len(args) > 2 {
  369. actualArgs = args[2:]
  370. }
  371. cmd.Use = subCommand // for later print statements ...
  372. switch strings.ToLower(subCommand) {
  373. case "check_tx":
  374. return cmdCheckTx(cmd, actualArgs)
  375. case "commit":
  376. return cmdCommit(cmd, actualArgs)
  377. case "deliver_tx":
  378. return cmdDeliverTx(cmd, actualArgs)
  379. case "echo":
  380. return cmdEcho(cmd, actualArgs)
  381. case "info":
  382. return cmdInfo(cmd, actualArgs)
  383. case "query":
  384. return cmdQuery(cmd, actualArgs)
  385. case "set_option":
  386. return cmdSetOption(cmd, actualArgs)
  387. default:
  388. return cmdUnimplemented(cmd, pArgs)
  389. }
  390. }
  391. func cmdUnimplemented(cmd *cobra.Command, args []string) error {
  392. msg := "unimplemented command"
  393. if len(args) > 0 {
  394. msg += fmt.Sprintf(" args: [%s]", strings.Join(args, " "))
  395. }
  396. printResponse(cmd, args, response{
  397. Code: codeBad,
  398. Log: msg,
  399. })
  400. fmt.Println("Available commands:")
  401. fmt.Printf("%s: %s\n", echoCmd.Use, echoCmd.Short)
  402. fmt.Printf("%s: %s\n", infoCmd.Use, infoCmd.Short)
  403. fmt.Printf("%s: %s\n", checkTxCmd.Use, checkTxCmd.Short)
  404. fmt.Printf("%s: %s\n", deliverTxCmd.Use, deliverTxCmd.Short)
  405. fmt.Printf("%s: %s\n", queryCmd.Use, queryCmd.Short)
  406. fmt.Printf("%s: %s\n", commitCmd.Use, commitCmd.Short)
  407. fmt.Printf("%s: %s\n", setOptionCmd.Use, setOptionCmd.Short)
  408. fmt.Println("Use \"[command] --help\" for more information about a command.")
  409. return nil
  410. }
  411. // Have the application echo a message
  412. func cmdEcho(cmd *cobra.Command, args []string) error {
  413. msg := ""
  414. if len(args) > 0 {
  415. msg = args[0]
  416. }
  417. res, err := client.EchoSync(msg)
  418. if err != nil {
  419. return err
  420. }
  421. printResponse(cmd, args, response{
  422. Data: []byte(res.Message),
  423. })
  424. return nil
  425. }
  426. // Get some info from the application
  427. func cmdInfo(cmd *cobra.Command, args []string) error {
  428. var version string
  429. if len(args) == 1 {
  430. version = args[0]
  431. }
  432. res, err := client.InfoSync(types.RequestInfo{Version: version})
  433. if err != nil {
  434. return err
  435. }
  436. printResponse(cmd, args, response{
  437. Data: []byte(res.Data),
  438. })
  439. return nil
  440. }
  441. const codeBad uint32 = 10
  442. // Set an option on the application
  443. func cmdSetOption(cmd *cobra.Command, args []string) error {
  444. if len(args) < 2 {
  445. printResponse(cmd, args, response{
  446. Code: codeBad,
  447. Log: "want at least arguments of the form: <key> <value>",
  448. })
  449. return nil
  450. }
  451. key, val := args[0], args[1]
  452. _, err := client.SetOptionSync(types.RequestSetOption{Key: key, Value: val})
  453. if err != nil {
  454. return err
  455. }
  456. printResponse(cmd, args, response{Log: "OK (SetOption doesn't return anything.)"}) // NOTE: Nothing to show...
  457. return nil
  458. }
  459. // Append a new tx to application
  460. func cmdDeliverTx(cmd *cobra.Command, args []string) error {
  461. if len(args) == 0 {
  462. printResponse(cmd, args, response{
  463. Code: codeBad,
  464. Log: "want the tx",
  465. })
  466. return nil
  467. }
  468. txBytes, err := stringOrHexToBytes(args[0])
  469. if err != nil {
  470. return err
  471. }
  472. res, err := client.DeliverTxSync(types.RequestDeliverTx{Tx: txBytes})
  473. if err != nil {
  474. return err
  475. }
  476. printResponse(cmd, args, response{
  477. Code: res.Code,
  478. Data: res.Data,
  479. Info: res.Info,
  480. Log: res.Log,
  481. })
  482. return nil
  483. }
  484. // Validate a tx
  485. func cmdCheckTx(cmd *cobra.Command, args []string) error {
  486. if len(args) == 0 {
  487. printResponse(cmd, args, response{
  488. Code: codeBad,
  489. Info: "want the tx",
  490. })
  491. return nil
  492. }
  493. txBytes, err := stringOrHexToBytes(args[0])
  494. if err != nil {
  495. return err
  496. }
  497. res, err := client.CheckTxSync(types.RequestCheckTx{Tx: txBytes})
  498. if err != nil {
  499. return err
  500. }
  501. printResponse(cmd, args, response{
  502. Code: res.Code,
  503. Data: res.Data,
  504. Info: res.Info,
  505. Log: res.Log,
  506. })
  507. return nil
  508. }
  509. // Get application Merkle root hash
  510. func cmdCommit(cmd *cobra.Command, args []string) error {
  511. res, err := client.CommitSync()
  512. if err != nil {
  513. return err
  514. }
  515. printResponse(cmd, args, response{
  516. Data: res.Data,
  517. })
  518. return nil
  519. }
  520. // Query application state
  521. func cmdQuery(cmd *cobra.Command, args []string) error {
  522. if len(args) == 0 {
  523. printResponse(cmd, args, response{
  524. Code: codeBad,
  525. Info: "want the query",
  526. Log: "",
  527. })
  528. return nil
  529. }
  530. queryBytes, err := stringOrHexToBytes(args[0])
  531. if err != nil {
  532. return err
  533. }
  534. resQuery, err := client.QuerySync(types.RequestQuery{
  535. Data: queryBytes,
  536. Path: flagPath,
  537. Height: int64(flagHeight),
  538. Prove: flagProve,
  539. })
  540. if err != nil {
  541. return err
  542. }
  543. printResponse(cmd, args, response{
  544. Code: resQuery.Code,
  545. Info: resQuery.Info,
  546. Log: resQuery.Log,
  547. Query: &queryResponse{
  548. Key: resQuery.Key,
  549. Value: resQuery.Value,
  550. Height: resQuery.Height,
  551. ProofOps: resQuery.ProofOps,
  552. },
  553. })
  554. return nil
  555. }
  556. func cmdCounter(cmd *cobra.Command, args []string) error {
  557. app := counter.NewApplication(flagSerial)
  558. logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
  559. // Start the listener
  560. srv, err := server.NewServer(flagAddress, flagAbci, app)
  561. if err != nil {
  562. return err
  563. }
  564. srv.SetLogger(logger.With("module", "abci-server"))
  565. if err := srv.Start(); err != nil {
  566. return err
  567. }
  568. // Stop upon receiving SIGTERM or CTRL-C.
  569. tmos.TrapSignal(logger, func() {
  570. // Cleanup
  571. srv.Stop()
  572. })
  573. // Run forever.
  574. select {}
  575. }
  576. func cmdKVStore(cmd *cobra.Command, args []string) error {
  577. logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
  578. // Create the application - in memory or persisted to disk
  579. var app types.Application
  580. if flagPersist == "" {
  581. app = kvstore.NewApplication()
  582. } else {
  583. app = kvstore.NewPersistentKVStoreApplication(flagPersist)
  584. app.(*kvstore.PersistentKVStoreApplication).SetLogger(logger.With("module", "kvstore"))
  585. }
  586. // Start the listener
  587. srv, err := server.NewServer(flagAddress, flagAbci, app)
  588. if err != nil {
  589. return err
  590. }
  591. srv.SetLogger(logger.With("module", "abci-server"))
  592. if err := srv.Start(); err != nil {
  593. return err
  594. }
  595. // Stop upon receiving SIGTERM or CTRL-C.
  596. tmos.TrapSignal(logger, func() {
  597. // Cleanup
  598. srv.Stop()
  599. })
  600. // Run forever.
  601. select {}
  602. }
  603. //--------------------------------------------------------------------------------
  604. func printResponse(cmd *cobra.Command, args []string, rsp response) {
  605. if flagVerbose {
  606. fmt.Println(">", cmd.Use, strings.Join(args, " "))
  607. }
  608. // Always print the status code.
  609. if rsp.Code == types.CodeTypeOK {
  610. fmt.Printf("-> code: OK\n")
  611. } else {
  612. fmt.Printf("-> code: %d\n", rsp.Code)
  613. }
  614. if len(rsp.Data) != 0 {
  615. // Do no print this line when using the commit command
  616. // because the string comes out as gibberish
  617. if cmd.Use != "commit" {
  618. fmt.Printf("-> data: %s\n", rsp.Data)
  619. }
  620. fmt.Printf("-> data.hex: 0x%X\n", rsp.Data)
  621. }
  622. if rsp.Log != "" {
  623. fmt.Printf("-> log: %s\n", rsp.Log)
  624. }
  625. if rsp.Query != nil {
  626. fmt.Printf("-> height: %d\n", rsp.Query.Height)
  627. if rsp.Query.Key != nil {
  628. fmt.Printf("-> key: %s\n", rsp.Query.Key)
  629. fmt.Printf("-> key.hex: %X\n", rsp.Query.Key)
  630. }
  631. if rsp.Query.Value != nil {
  632. fmt.Printf("-> value: %s\n", rsp.Query.Value)
  633. fmt.Printf("-> value.hex: %X\n", rsp.Query.Value)
  634. }
  635. if rsp.Query.ProofOps != nil {
  636. fmt.Printf("-> proof: %#v\n", rsp.Query.ProofOps)
  637. }
  638. }
  639. }
  640. // NOTE: s is interpreted as a string unless prefixed with 0x
  641. func stringOrHexToBytes(s string) ([]byte, error) {
  642. if len(s) > 2 && strings.ToLower(s[:2]) == "0x" {
  643. b, err := hex.DecodeString(s[2:])
  644. if err != nil {
  645. err = fmt.Errorf("error decoding hex argument: %s", err.Error())
  646. return nil, err
  647. }
  648. return b, nil
  649. }
  650. if !strings.HasPrefix(s, "\"") || !strings.HasSuffix(s, "\"") {
  651. err := fmt.Errorf("invalid string arg: \"%s\". Must be quoted or a \"0x\"-prefixed hex string", s)
  652. return nil, err
  653. }
  654. return []byte(s[1 : len(s)-1]), nil
  655. }