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.

328 lines
9.6 KiB

6 years ago
6 years ago
  1. # Using ABCI-CLI
  2. To facilitate testing and debugging of ABCI servers and simple apps, we
  3. built a CLI, the `abci-cli`, for sending ABCI messages from the command
  4. line.
  5. ## Install
  6. Make sure you [have Go installed](https://golang.org/doc/install).
  7. Next, install the `abci-cli` tool and example applications:
  8. go get github.com/tendermint/tendermint
  9. to get vendored dependencies:
  10. cd $GOPATH/src/github.com/tendermint/tendermint
  11. make get_tools
  12. make get_vendor_deps
  13. make install_abci
  14. Now run `abci-cli` to see the list of commands:
  15. Usage:
  16. abci-cli [command]
  17. Available Commands:
  18. batch Run a batch of abci commands against an application
  19. check_tx Validate a tx
  20. commit Commit the application state and return the Merkle root hash
  21. console Start an interactive abci console for multiple commands
  22. counter ABCI demo example
  23. deliver_tx Deliver a new tx to the application
  24. kvstore ABCI demo example
  25. echo Have the application echo a message
  26. help Help about any command
  27. info Get some info about the application
  28. query Query the application state
  29. set_option Set an options on the application
  30. Flags:
  31. --abci string socket or grpc (default "socket")
  32. --address string address of application socket (default "tcp://127.0.0.1:26658")
  33. -h, --help help for abci-cli
  34. -v, --verbose print the command and results as if it were a console session
  35. Use "abci-cli [command] --help" for more information about a command.
  36. ## KVStore - First Example
  37. The `abci-cli` tool lets us send ABCI messages to our application, to
  38. help build and debug them.
  39. The most important messages are `deliver_tx`, `check_tx`, and `commit`,
  40. but there are others for convenience, configuration, and information
  41. purposes.
  42. We'll start a kvstore application, which was installed at the same time
  43. as `abci-cli` above. The kvstore just stores transactions in a merkle
  44. tree.
  45. Its code can be found
  46. [here](https://github.com/tendermint/tendermint/blob/develop/abci/cmd/abci-cli/abci-cli.go)
  47. and looks like:
  48. func cmdKVStore(cmd *cobra.Command, args []string) error {
  49. logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
  50. // Create the application - in memory or persisted to disk
  51. var app types.Application
  52. if flagPersist == "" {
  53. app = kvstore.NewKVStoreApplication()
  54. } else {
  55. app = kvstore.NewPersistentKVStoreApplication(flagPersist)
  56. app.(*kvstore.PersistentKVStoreApplication).SetLogger(logger.With("module", "kvstore"))
  57. }
  58. // Start the listener
  59. srv, err := server.NewServer(flagAddrD, flagAbci, app)
  60. if err != nil {
  61. return err
  62. }
  63. srv.SetLogger(logger.With("module", "abci-server"))
  64. if err := srv.Start(); err != nil {
  65. return err
  66. }
  67. // Wait forever
  68. cmn.TrapSignal(func() {
  69. // Cleanup
  70. srv.Stop()
  71. })
  72. return nil
  73. }
  74. Start by running:
  75. abci-cli kvstore
  76. And in another terminal, run
  77. abci-cli echo hello
  78. abci-cli info
  79. You'll see something like:
  80. -> data: hello
  81. -> data.hex: 68656C6C6F
  82. and:
  83. -> data: {"size":0}
  84. -> data.hex: 7B2273697A65223A307D
  85. An ABCI application must provide two things:
  86. - a socket server
  87. - a handler for ABCI messages
  88. When we run the `abci-cli` tool we open a new connection to the
  89. application's socket server, send the given ABCI message, and wait for a
  90. response.
  91. The server may be generic for a particular language, and we provide a
  92. [reference implementation in
  93. Golang](https://github.com/tendermint/tendermint/tree/develop/abci/server). See the
  94. [list of other ABCI implementations](./ecosystem.html) for servers in
  95. other languages.
  96. The handler is specific to the application, and may be arbitrary, so
  97. long as it is deterministic and conforms to the ABCI interface
  98. specification.
  99. So when we run `abci-cli info`, we open a new connection to the ABCI
  100. server, which calls the `Info()` method on the application, which tells
  101. us the number of transactions in our Merkle tree.
  102. Now, since every command opens a new connection, we provide the
  103. `abci-cli console` and `abci-cli batch` commands, to allow multiple ABCI
  104. messages to be sent over a single connection.
  105. Running `abci-cli console` should drop you in an interactive console for
  106. speaking ABCI messages to your application.
  107. Try running these commands:
  108. > echo hello
  109. -> code: OK
  110. -> data: hello
  111. -> data.hex: 0x68656C6C6F
  112. > info
  113. -> code: OK
  114. -> data: {"size":0}
  115. -> data.hex: 0x7B2273697A65223A307D
  116. > commit
  117. -> code: OK
  118. -> data.hex: 0x0000000000000000
  119. > deliver_tx "abc"
  120. -> code: OK
  121. > info
  122. -> code: OK
  123. -> data: {"size":1}
  124. -> data.hex: 0x7B2273697A65223A317D
  125. > commit
  126. -> code: OK
  127. -> data.hex: 0x0200000000000000
  128. > query "abc"
  129. -> code: OK
  130. -> log: exists
  131. -> height: 0
  132. -> value: abc
  133. -> value.hex: 616263
  134. > deliver_tx "def=xyz"
  135. -> code: OK
  136. > commit
  137. -> code: OK
  138. -> data.hex: 0x0400000000000000
  139. > query "def"
  140. -> code: OK
  141. -> log: exists
  142. -> height: 0
  143. -> value: xyz
  144. -> value.hex: 78797A
  145. Note that if we do `deliver_tx "abc"` it will store `(abc, abc)`, but if
  146. we do `deliver_tx "abc=efg"` it will store `(abc, efg)`.
  147. Similarly, you could put the commands in a file and run
  148. `abci-cli --verbose batch < myfile`.
  149. ## Counter - Another Example
  150. Now that we've got the hang of it, let's try another application, the
  151. "counter" app.
  152. Like the kvstore app, its code can be found
  153. [here](https://github.com/tendermint/tendermint/blob/master/abci/cmd/abci-cli/abci-cli.go)
  154. and looks like:
  155. func cmdCounter(cmd *cobra.Command, args []string) error {
  156. app := counter.NewCounterApplication(flagSerial)
  157. logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
  158. // Start the listener
  159. srv, err := server.NewServer(flagAddrC, flagAbci, app)
  160. if err != nil {
  161. return err
  162. }
  163. srv.SetLogger(logger.With("module", "abci-server"))
  164. if err := srv.Start(); err != nil {
  165. return err
  166. }
  167. // Wait forever
  168. cmn.TrapSignal(func() {
  169. // Cleanup
  170. srv.Stop()
  171. })
  172. return nil
  173. }
  174. The counter app doesn't use a Merkle tree, it just counts how many times
  175. we've sent a transaction, asked for a hash, or committed the state. The
  176. result of `commit` is just the number of transactions sent.
  177. This application has two modes: `serial=off` and `serial=on`.
  178. When `serial=on`, transactions must be a big-endian encoded incrementing
  179. integer, starting at 0.
  180. If `serial=off`, there are no restrictions on transactions.
  181. We can toggle the value of `serial` using the `set_option` ABCI message.
  182. When `serial=on`, some transactions are invalid. In a live blockchain,
  183. transactions collect in memory before they are committed into blocks. To
  184. avoid wasting resources on invalid transactions, ABCI provides the
  185. `check_tx` message, which application developers can use to accept or
  186. reject transactions, before they are stored in memory or gossipped to
  187. other peers.
  188. In this instance of the counter app, `check_tx` only allows transactions
  189. whose integer is greater than the last committed one.
  190. Let's kill the console and the kvstore application, and start the
  191. counter app:
  192. abci-cli counter
  193. In another window, start the `abci-cli console`:
  194. > set_option serial on
  195. -> code: OK
  196. -> log: OK (SetOption doesn't return anything.)
  197. > check_tx 0x00
  198. -> code: OK
  199. > check_tx 0xff
  200. -> code: OK
  201. > deliver_tx 0x00
  202. -> code: OK
  203. > check_tx 0x00
  204. -> code: BadNonce
  205. -> log: Invalid nonce. Expected >= 1, got 0
  206. > deliver_tx 0x01
  207. -> code: OK
  208. > deliver_tx 0x04
  209. -> code: BadNonce
  210. -> log: Invalid nonce. Expected 2, got 4
  211. > info
  212. -> code: OK
  213. -> data: {"hashes":0,"txs":2}
  214. -> data.hex: 0x7B22686173686573223A302C22747873223A327D
  215. This is a very simple application, but between `counter` and `kvstore`,
  216. its easy to see how you can build out arbitrary application states on
  217. top of the ABCI. [Hyperledger's
  218. Burrow](https://github.com/hyperledger/burrow) also runs atop ABCI,
  219. bringing with it Ethereum-like accounts, the Ethereum virtual-machine,
  220. Monax's permissioning scheme, and native contracts extensions.
  221. But the ultimate flexibility comes from being able to write the
  222. application easily in any language.
  223. We have implemented the counter in a number of languages [see the
  224. example directory](https://github.com/tendermint/tendermint/tree/develop/abci/example).
  225. To run the Node JS version, `cd` to `example/js` and run
  226. node app.js
  227. (you'll have to kill the other counter application process). In another
  228. window, run the console and those previous ABCI commands. You should get
  229. the same results as for the Go version.
  230. ## Bounties
  231. Want to write the counter app in your favorite language?! We'd be happy
  232. to add you to our [ecosystem](https://tendermint.com/ecosystem)! We're
  233. also offering [bounties](https://hackerone.com/tendermint/) for
  234. implementations in new languages!
  235. The `abci-cli` is designed strictly for testing and debugging. In a real
  236. deployment, the role of sending messages is taken by Tendermint, which
  237. connects to the app using three separate connections, each with its own
  238. pattern of messages.
  239. For more information, see the [application developers
  240. guide](./app-development.md). For examples of running an ABCI app with
  241. Tendermint, see the [getting started guide](./getting-started.md).
  242. Next is the ABCI specification.