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.

354 lines
9.1 KiB

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