diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0dc591d1..9a990a86 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,14 +1,18 @@
# Changelog
-## 0.9.0 (TBD)
+## 0.9.0 (December 28, 2017)
BREAKING CHANGES:
+ - [types] Id -> ID
- [types] ResponseEndBlock: renamed Diffs field to ValidatorUpdates
- [types] changed protobuf field indices for Request and Response oneof types
FEATURES:
- [types] ResponseEndBlock: added ConsensusParamUpdates
+BUG FIXES:
+ - [cmd] fix console and batch commands to use a single persistent connection
+
## 0.8.0 (December 6, 2017)
BREAKING CHANGES:
diff --git a/README.md b/README.md
index 902e3a08..5089f5da 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,20 @@ The two guides to focus on are the `Application Development Guide` and `Using AB
Previously, the ABCI was referred to as TMSP.
-The community has provided a number of addtional implementations, see the `Tendermint Ecosystem` in [the documentation](http://tendermint.readthedocs.io/en/master/).
+The community has provided a number of addtional implementations, see the [Tendermint Ecosystem](https://tendermint.com/ecosystem)
+
+## Specification
+
+See the [spec file](specification.rst) for more information.
+
+## Install
+
+```
+go get github.com/tendermint/abci
+cd $GOPATH/src/github.com/tendermint/abci
+make get_vendor_deps
+make install
+```
## Implementation
@@ -24,19 +37,21 @@ We provide three implementations of the ABCI in Go:
- GRPC
Note the GRPC version is maintained primarily to simplify onboarding and prototyping and is not receiving the same
-attention to security and performance as the others.
+attention to security and performance as the others
### In Process
The simplest implementation just uses function calls within Go.
This means ABCI applications written in Golang can be compiled with TendermintCore and run as a single binary.
+See the [examples](#examples) below for more information.
+
### Socket (TSP)
ABCI is best implemented as a streaming protocol.
The socket implementation provides for asynchronous, ordered message passing over unix or tcp.
Messages are serialized using Protobuf3 and length-prefixed.
-Protobuf3 doesn't have an official length-prefix standard, so we use our own. The first byte represents the length of the big-endian encoded length.
+Protobuf3 doesn't have an official length-prefix standard, so we use our own. The first byte represents the length of the big-endian encoded length.
For example, if the Protobuf3 encoded ABCI message is `0xDEADBEEF` (4 bytes), the length-prefixed message is `0x0104DEADBEEF`. If the Protobuf3 encoded ABCI message is 65535 bytes long, the length-prefixed message would be like `0x02FFFF...`.
@@ -48,36 +63,85 @@ the ordered, asynchronous socket protocol. The implementation has also not recei
Note the length-prefixing used in the socket implementation does not apply for GRPC.
-## Tools
+## Usage
The `abci-cli` tool wraps an ABCI client and can be used for probing/testing an ABCI server.
For instance, `abci-cli test` will run a test sequence against a listening server running the Counter application (see below).
It can also be used to run some example applications.
See [the documentation](http://tendermint.readthedocs.io/en/master/) for more details.
-### Example Apps
+### Examples
-Multiple example apps are included:
-- the `abci-cli counter` application, which illustrates nonce checking in txs
-- the `abci-cli dummy` application, which illustrates a simple key-value Merkle tree
-- the `abci-cli dummy --persistent` application, which augments the dummy with persistence and validator set changes
+Check out the variety of example applications in the [example directory](example/).
+It also contains the code refered to by the `counter` and `dummy` apps; these apps come
+built into the `abci-cli` binary.
-### Install
+#### Counter
-```
-go get github.com/tendermint/abci
-cd $GOPATH/src/github.com/tendermint/abci
-make get_vendor_deps
-make install
+The `abci-cli counter` application illustrates nonce checking in transactions. It's code looks like:
+
+```golang
+func cmdCounter(cmd *cobra.Command, args []string) error {
+
+ app := counter.NewCounterApplication(flagSerial)
+
+ logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
+
+ // Start the listener
+ srv, err := server.NewServer(flagAddrC, flagAbci, app)
+ if err != nil {
+ return err
+ }
+ srv.SetLogger(logger.With("module", "abci-server"))
+ if err := srv.Start(); err != nil {
+ return err
+ }
+
+ // Wait forever
+ cmn.TrapSignal(func() {
+ // Cleanup
+ srv.Stop()
+ })
+ return nil
+}
```
-## Specification
+and can be found in [this file](cmd/abci-cli/abci-cli.go).
-The [primary specification](https://github.com/tendermint/abci/blob/master/types/types.proto) is made using Protocol Buffers.
-To build it, run
+#### Dummy
-```
-make protoc
+The `abci-cli dummy` application, which illustrates a simple key-value Merkle tree
+
+```golang
+func cmdDummy(cmd *cobra.Command, args []string) error {
+ logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
+
+ // Create the application - in memory or persisted to disk
+ var app types.Application
+ if flagPersist == "" {
+ app = dummy.NewDummyApplication()
+ } else {
+ app = dummy.NewPersistentDummyApplication(flagPersist)
+ app.(*dummy.PersistentDummyApplication).SetLogger(logger.With("module", "dummy"))
+ }
+
+ // Start the listener
+ srv, err := server.NewServer(flagAddrD, flagAbci, app)
+ if err != nil {
+ return err
+ }
+ srv.SetLogger(logger.With("module", "abci-server"))
+ if err := srv.Start(); err != nil {
+ return err
+ }
+
+ // Wait forever
+ cmn.TrapSignal(func() {
+ // Cleanup
+ srv.Stop()
+ })
+ return nil
+}
```
See `protoc --help` and [the Protocol Buffers site](https://developers.google.com/protocol-buffers/) for details on compiling for other languages.
@@ -200,3 +264,5 @@ Here, we describe the requests and responses as function arguments and return va
* `Log (string)`: Debug or error message
* __Usage__:
Return a Merkle root hash of the application state.
+and can be found in [this file](cmd/abci-cli/abci-cli.go).
+
diff --git a/circle.yml b/circle.yml
index 2f52ce9f..8e737339 100644
--- a/circle.yml
+++ b/circle.yml
@@ -15,7 +15,7 @@ checkout:
test:
override:
- - cd $REPO && make get_tools check build test_integrations
+ - cd $REPO && make get_tools check get_vendor_deps install test_integrations
post:
- cd "$REPO" && bash <(curl -s https://codecov.io/bash) -f coverage.txt
- cd "$REPO" && mv coverage.txt "${CIRCLE_ARTIFACTS}"
diff --git a/cmd/abci-cli/abci-cli.go b/cmd/abci-cli/abci-cli.go
index 0b8102ee..7d257f27 100644
--- a/cmd/abci-cli/abci-cli.go
+++ b/cmd/abci-cli/abci-cli.go
@@ -54,8 +54,8 @@ var (
var RootCmd = &cobra.Command{
Use: "abci-cli",
- Short: "",
- Long: "",
+ Short: "the ABCI CLI tool wraps an ABCI client",
+ Long: "the ABCI CLI tool wraps an ABCI client and is used for testing ABCI servers",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
switch cmd.Use {
@@ -112,26 +112,26 @@ func Execute() error {
}
func addGlobalFlags() {
- RootCmd.PersistentFlags().StringVarP(&flagAddress, "address", "", "tcp://0.0.0.0:46658", "Address of application socket")
- RootCmd.PersistentFlags().StringVarP(&flagAbci, "abci", "", "socket", "Either socket or grpc")
- RootCmd.PersistentFlags().BoolVarP(&flagVerbose, "verbose", "v", false, "Print the command and results as if it were a console session")
- RootCmd.PersistentFlags().StringVarP(&flagLogLevel, "log_level", "", "debug", "Set the logger level")
+ RootCmd.PersistentFlags().StringVarP(&flagAddress, "address", "", "tcp://0.0.0.0:46658", "address of application socket")
+ RootCmd.PersistentFlags().StringVarP(&flagAbci, "abci", "", "socket", "either socket or grpc")
+ RootCmd.PersistentFlags().BoolVarP(&flagVerbose, "verbose", "v", false, "print the command and results as if it were a console session")
+ RootCmd.PersistentFlags().StringVarP(&flagLogLevel, "log_level", "", "debug", "set the logger level")
}
func addQueryFlags() {
- queryCmd.PersistentFlags().StringVarP(&flagPath, "path", "", "/store", "Path to prefix query with")
- queryCmd.PersistentFlags().IntVarP(&flagHeight, "height", "", 0, "Height to query the blockchain at")
- queryCmd.PersistentFlags().BoolVarP(&flagProve, "prove", "", false, "Whether or not to return a merkle proof of the query result")
+ queryCmd.PersistentFlags().StringVarP(&flagPath, "path", "", "/store", "path to prefix query with")
+ queryCmd.PersistentFlags().IntVarP(&flagHeight, "height", "", 0, "height to query the blockchain at")
+ queryCmd.PersistentFlags().BoolVarP(&flagProve, "prove", "", false, "whether or not to return a merkle proof of the query result")
}
func addCounterFlags() {
- counterCmd.PersistentFlags().StringVarP(&flagAddrC, "addr", "", "tcp://0.0.0.0:46658", "Listen address")
- counterCmd.PersistentFlags().BoolVarP(&flagSerial, "serial", "", false, "Enforce incrementing (serial) transactions")
+ counterCmd.PersistentFlags().StringVarP(&flagAddrC, "addr", "", "tcp://0.0.0.0:46658", "listen address")
+ counterCmd.PersistentFlags().BoolVarP(&flagSerial, "serial", "", false, "enforce incrementing (serial) transactions")
}
func addDummyFlags() {
- dummyCmd.PersistentFlags().StringVarP(&flagAddrD, "addr", "", "tcp://0.0.0.0:46658", "Listen address")
- dummyCmd.PersistentFlags().StringVarP(&flagPersist, "persist", "", "", "Directory to use for a database")
+ dummyCmd.PersistentFlags().StringVarP(&flagAddrD, "addr", "", "tcp://0.0.0.0:46658", "listen address")
+ dummyCmd.PersistentFlags().StringVarP(&flagPersist, "persist", "", "", "directory to use for a database")
}
func addCommands() {
RootCmd.AddCommand(batchCmd)
@@ -156,18 +156,39 @@ func addCommands() {
var batchCmd = &cobra.Command{
Use: "batch",
- Short: "Run a batch of abci commands against an application",
- Long: "",
- Args: cobra.ExactArgs(0),
+ Short: "run a batch of abci commands against an application",
+ Long: `run a batch of abci commands against an application
+
+This command is run by piping in a file containing a series of commands
+you'd like to run:
+
+ abci-cli batch < example.file
+
+where example.file looks something like:
+
+ set_option serial on
+ check_tx 0x00
+ check_tx 0xff
+ deliver_tx 0x00
+ check_tx 0x00
+ deliver_tx 0x01
+ deliver_tx 0x04
+ info
+`,
+ Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
return cmdBatch(cmd, args)
},
}
var consoleCmd = &cobra.Command{
- Use: "console",
- Short: "Start an interactive abci console for multiple commands",
- Long: "",
+ Use: "console",
+ Short: "start an interactive ABCI console for multiple commands",
+ Long: `start an interactive ABCI console for multiple commands
+
+This command opens an interactive console for running any of the other commands
+without opening a new connection each time
+`,
Args: cobra.ExactArgs(0),
ValidArgs: []string{"echo", "info", "set_option", "deliver_tx", "check_tx", "commit", "query"},
RunE: func(cmd *cobra.Command, args []string) error {
@@ -177,8 +198,8 @@ var consoleCmd = &cobra.Command{
var echoCmd = &cobra.Command{
Use: "echo",
- Short: "Have the application echo a message",
- Long: "",
+ Short: "have the application echo a message",
+ Long: "have the application echo a message",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return cmdEcho(cmd, args)
@@ -186,8 +207,8 @@ var echoCmd = &cobra.Command{
}
var infoCmd = &cobra.Command{
Use: "info",
- Short: "Get some info about the application",
- Long: "",
+ Short: "get some info about the application",
+ Long: "get some info about the application",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
return cmdInfo(cmd, args)
@@ -195,8 +216,8 @@ var infoCmd = &cobra.Command{
}
var setOptionCmd = &cobra.Command{
Use: "set_option",
- Short: "Set an option on the application",
- Long: "",
+ Short: "set an option on the application",
+ Long: "set an option on the application",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
return cmdSetOption(cmd, args)
@@ -205,8 +226,8 @@ var setOptionCmd = &cobra.Command{
var deliverTxCmd = &cobra.Command{
Use: "deliver_tx",
- Short: "Deliver a new transaction to the application",
- Long: "",
+ Short: "deliver a new transaction to the application",
+ Long: "deliver a new transaction to the application",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return cmdDeliverTx(cmd, args)
@@ -215,8 +236,8 @@ var deliverTxCmd = &cobra.Command{
var checkTxCmd = &cobra.Command{
Use: "check_tx",
- Short: "Validate a transaction",
- Long: "",
+ Short: "validate a transaction",
+ Long: "validate a transaction",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return cmdCheckTx(cmd, args)
@@ -225,8 +246,8 @@ var checkTxCmd = &cobra.Command{
var commitCmd = &cobra.Command{
Use: "commit",
- Short: "Commit the application state and return the Merkle root hash",
- Long: "",
+ Short: "commit the application state and return the Merkle root hash",
+ Long: "commit the application state and return the Merkle root hash",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
return cmdCommit(cmd, args)
@@ -235,8 +256,8 @@ var commitCmd = &cobra.Command{
var versionCmd = &cobra.Command{
Use: "version",
- Short: "Print abci console version",
- Long: "",
+ Short: "print ABCI console version",
+ Long: "print ABCI console version",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println(version.Version)
@@ -246,8 +267,8 @@ var versionCmd = &cobra.Command{
var queryCmd = &cobra.Command{
Use: "query",
- Short: "Query the application state",
- Long: "",
+ Short: "query the application state",
+ Long: "query the application state",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return cmdQuery(cmd, args)
@@ -257,7 +278,7 @@ var queryCmd = &cobra.Command{
var counterCmd = &cobra.Command{
Use: "counter",
Short: "ABCI demo example",
- Long: "",
+ Long: "ABCI demo example",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
return cmdCounter(cmd, args)
@@ -267,7 +288,7 @@ var counterCmd = &cobra.Command{
var dummyCmd = &cobra.Command{
Use: "dummy",
Short: "ABCI demo example",
- Long: "",
+ Long: "ABCI demo example",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
return cmdDummy(cmd, args)
@@ -276,8 +297,8 @@ var dummyCmd = &cobra.Command{
var testCmd = &cobra.Command{
Use: "test",
- Short: "Run integration tests",
- Long: "",
+ Short: "run integration tests",
+ Long: "run integration tests",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
return cmdTest(cmd, args)
@@ -300,49 +321,39 @@ func persistentArgs(line []byte) []string {
//--------------------------------------------------------------------------------
-func or(err1 error, err2 error) error {
- if err1 == nil {
- return err2
+func compose(fs []func() error) error {
+ if len(fs) == 0 {
+ return nil
} else {
- return err1
+ err := fs[0]()
+ if err == nil {
+ return compose(fs[1:])
+ } else {
+ return err
+ }
}
}
func cmdTest(cmd *cobra.Command, args []string) error {
- fmt.Println("Running tests")
-
- err := servertest.InitChain(client)
- fmt.Println("")
- err = or(err, servertest.SetOption(client, "serial", "on"))
- fmt.Println("")
- err = or(err, servertest.Commit(client, nil))
- fmt.Println("")
- err = or(err, servertest.DeliverTx(client, []byte("abc"), code.CodeTypeBadNonce, nil))
- fmt.Println("")
- err = or(err, servertest.Commit(client, nil))
- fmt.Println("")
- err = or(err, servertest.DeliverTx(client, []byte{0x00}, code.CodeTypeOK, nil))
- fmt.Println("")
- err = or(err, servertest.Commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 1}))
- fmt.Println("")
- err = or(err, servertest.DeliverTx(client, []byte{0x00}, code.CodeTypeBadNonce, nil))
- fmt.Println("")
- err = or(err, servertest.DeliverTx(client, []byte{0x01}, code.CodeTypeOK, nil))
- fmt.Println("")
- err = or(err, servertest.DeliverTx(client, []byte{0x00, 0x02}, code.CodeTypeOK, nil))
- fmt.Println("")
- err = or(err, servertest.DeliverTx(client, []byte{0x00, 0x03}, code.CodeTypeOK, nil))
- fmt.Println("")
- err = or(err, servertest.DeliverTx(client, []byte{0x00, 0x00, 0x04}, code.CodeTypeOK, nil))
- fmt.Println("")
- err = or(err, servertest.DeliverTx(client, []byte{0x00, 0x00, 0x06}, code.CodeTypeBadNonce, nil))
- fmt.Println("")
- err = or(err, servertest.Commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 5}))
-
- if err != nil {
- return errors.New("Some checks didn't pass, please inspect stdout to see the exact failures.")
- }
- return nil
+ return compose(
+ []func() error{
+ func() error { return servertest.InitChain(client) },
+ func() error { return servertest.SetOption(client, "serial", "on") },
+ func() error { return servertest.Commit(client, nil) },
+ func() error { return servertest.DeliverTx(client, []byte("abc"), code.CodeTypeBadNonce, nil) },
+ func() error { return servertest.Commit(client, nil) },
+ func() error { return servertest.DeliverTx(client, []byte{0x00}, code.CodeTypeOK, nil) },
+ func() error { return servertest.Commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 1}) },
+ func() error { return servertest.DeliverTx(client, []byte{0x00}, code.CodeTypeBadNonce, nil) },
+ func() error { return servertest.DeliverTx(client, []byte{0x01}, code.CodeTypeOK, nil) },
+ func() error { return servertest.DeliverTx(client, []byte{0x00, 0x02}, code.CodeTypeOK, nil) },
+ func() error { return servertest.DeliverTx(client, []byte{0x00, 0x03}, code.CodeTypeOK, nil) },
+ func() error { return servertest.DeliverTx(client, []byte{0x00, 0x00, 0x04}, code.CodeTypeOK, nil) },
+ func() error {
+ return servertest.DeliverTx(client, []byte{0x00, 0x00, 0x06}, code.CodeTypeBadNonce, nil)
+ },
+ func() error { return servertest.Commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 5}) },
+ })
}
func cmdBatch(cmd *cobra.Command, args []string) error {
diff --git a/specification.rst b/specification.rst
new file mode 100644
index 00000000..282178ce
--- /dev/null
+++ b/specification.rst
@@ -0,0 +1,221 @@
+Specification
+=============
+
+The `primary
+specification `__
+is made using Protocol Buffers. To build it, run
+
+::
+
+ make protoc
+
+See ``protoc --help`` and `the Protocol Buffers
+site `__ for details on
+compiling for other languages. Note we also include a
+`GRPC `__ service definition.
+
+For the specification as an interface in Go, see the
+`types/application.go
+file `__.
+
+Message Types
+~~~~~~~~~~~~~
+
+ABCI requests/responses are defined as simple Protobuf messages in `this
+schema
+file `__.
+TendermintCore sends the requests, and the ABCI application sends the
+responses. Here, we describe the requests and responses as function
+arguments and return values, and make some notes about usage:
+
+Echo
+^^^^
+
+- **Arguments**:
+
+ - ``Message (string)``: A string to echo back
+
+- **Returns**:
+
+ - ``Message (string)``: The input string
+
+- **Usage**:
+
+ - Echo a string to test an abci client/server implementation
+
+Flush
+^^^^^
+
+- **Usage**:
+
+ - Signals that messages queued on the client should be flushed to
+ the server. It is called periodically by the client implementation
+ to ensure asynchronous requests are actually sent, and is called
+ immediately to make a synchronous request, which returns when the
+ Flush response comes back.
+
+Info
+^^^^
+
+- **Returns**:
+
+ - ``Data (string)``: Some arbitrary information
+ - ``Version (Version)``: Version information
+ - ``LastBlockHeight (int64)``: Latest block for which the app has
+ called Commit
+ - ``LastBlockAppHash ([]byte)``: Latest result of Commit
+
+- **Usage**: Return information about the application state. Used to
+ sync the app with Tendermint on crash/restart.
+
+SetOption
+^^^^^^^^^
+
+- **Arguments**:
+
+ - ``Key (string)``: Key to set
+ - ``Value (string)``: Value to set for key
+
+- **Returns**:
+
+ - ``Code (uint32)``: Response code
+ - ``Log (string)``: Debug or error message
+
+- **Usage**: Set application options. E.g. Key="mode", Value="mempool"
+ for a mempool connection, or Key="mode", Value="consensus" for a
+ consensus connection. Other options are application specific.
+
+InitChain
+^^^^^^^^^
+
+- **Arguments**:
+
+ - ``Validators ([]Validator)``: Initial genesis validators
+
+- **Usage**: Called once upon genesis
+
+Query
+^^^^^
+
+- **Arguments**:
+
+ - ``Data ([]byte)``: Raw query bytes. Can be used with or in lieu of
+ Path.
+ - ``Path (string)``: Path of request, like an HTTP GET path. Can be
+ used with or in liue of Data.
+ - Apps MUST interpret '/store' as a query by key on the underlying
+ store. The key SHOULD be specified in the Data field.
+ - Apps SHOULD allow queries over specific types like '/accounts/...'
+ or '/votes/...'
+ - ``Height (int64)``: The block height for which you want the query
+ (default=0 returns data for the latest committed block). Note that
+ this is the height of the block containing the application's
+ Merkle root hash, which represents the state as it was after
+ committing the block at Height-1
+ - ``Prove (bool)``: Return Merkle proof with response if possible
+
+- **Returns**:
+
+ - ``Code (uint32)``: Response code
+ - ``Key ([]byte)``: The key of the matching data
+ - ``Value ([]byte)``: The value of the matching data
+ - ``Proof ([]byte)``: Proof for the data, if requested
+ - ``Height (int64)``: The block height from which data was derived.
+ Note that this is the height of the block containing the
+ application's Merkle root hash, which represents the state as it
+ was after committing the block at Height-1
+ - ``Log (string)``: Debug or error message
+
+BeginBlock
+^^^^^^^^^^
+
+- **Arguments**:
+
+ - ``Hash ([]byte)``: The block's hash. This can be derived from the
+ block header.
+ - ``Header (struct{})``: The block header
+ - ``AbsentValidators ([]int32)``: List of indices of validators not
+ included in the LastCommit
+ - ``ByzantineValidators ([]Evidence)``: List of evidence of
+ validators that acted maliciously
+
+- **Usage**: Signals the beginning of a new block. Called prior to any
+ DeliverTxs. The header is expected to at least contain the Height.
+ The ``AbsentValidators`` and ``ByzantineValidators`` can be used to
+ determine rewards and punishments for the validators.
+
+CheckTx
+^^^^^^^
+
+- **Arguments**:
+
+ - ``Data ([]byte)``: The request transaction bytes
+
+- **Returns**:
+
+ - ``Code (uint32)``: Response code
+ - ``Data ([]byte)``: Result bytes, if any
+ - ``Log (string)``: Debug or error message
+ - ``Gas (int64)``: Amount of gas consumed by transaction
+ - ``Fee (int64)``: Fee paid by transaction
+
+- **Usage**: Validate a mempool transaction, prior to broadcasting or
+ proposing. This message should not mutate the main state, but
+ application developers may want to keep a separate CheckTx state that
+ gets reset upon Commit.
+
+ CheckTx can happen interspersed with DeliverTx, but they happen on
+ different ABCI connections - CheckTx from the mempool connection, and
+ DeliverTx from the consensus connection. During Commit, the mempool
+ is locked, so you can reset the mempool state to the latest state
+ after running all those DeliverTxs, and then the mempool will re-run
+ whatever txs it has against that latest mempool state.
+
+ Transactions are first run through CheckTx before broadcast to peers
+ in the mempool layer. You can make CheckTx semi-stateful and clear
+ the state upon ``Commit`` or ``BeginBlock``, to allow for dependent
+ sequences of transactions in the same block.
+
+DeliverTx
+^^^^^^^^^
+
+- **Arguments**:
+
+ - ``Data ([]byte)``: The request transaction bytes
+
+- **Returns**:
+
+ - ``Code (uint32)``: Response code
+ - ``Data ([]byte)``: Result bytes, if any
+ - ``Log (string)``: Debug or error message
+ - ``Tags ([]*KVPair)``: Optional tags for indexing
+
+- **Usage**: Append and run a transaction. If the transaction is valid,
+ returns CodeType.OK
+
+EndBlock
+^^^^^^^^
+
+- **Arguments**:
+
+ - ``Height (int64)``: The block height that ended
+
+- **Returns**:
+
+ - ``ValidatorUpdates ([]Validator)``: Changes to validator set (set
+ voting power to 0 to remove)
+ - ``ConsensusParamUpdates (ConsensusParams)``: Changes to
+ consensus-critical time/size parameters
+
+- **Usage**: Signals the end of a block. Called prior to each Commit
+ after all transactions. Validator set is updated with the result.
+
+Commit
+^^^^^^
+
+- **Returns**:
+
+ - ``Data ([]byte)``: The Merkle root hash
+ - ``Log (string)``: Debug or error message
+
+- **Usage**: Return a Merkle root hash of the application state.
diff --git a/tests/test_cli/test.sh b/tests/test_cli/test.sh
index ed00b9d7..dcf2dcc8 100755
--- a/tests/test_cli/test.sh
+++ b/tests/test_cli/test.sh
@@ -20,8 +20,8 @@ function testExample() {
abci-cli --log_level=error --verbose batch < "$INPUT" > "${INPUT}.out.new"
killall "$3"
- pre=$(shasum < "${INPUT}.out")
- post=$(shasum < "${INPUT}.out.new")
+ pre=$(sha256sum < "${INPUT}.out")
+ post=$(sha256sum < "${INPUT}.out.new")
if [[ "$pre" != "$post" ]]; then
echo "You broke the tutorial"
diff --git a/version/version.go b/version/version.go
index c0699526..982a8886 100644
--- a/version/version.go
+++ b/version/version.go
@@ -3,7 +3,7 @@ package version
// NOTE: we should probably be versioning the ABCI and the abci-cli separately
const Maj = "0"
-const Min = "8"
+const Min = "9"
const Fix = "0"
-const Version = "0.8.0"
+const Version = "0.9.0"