mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-24 03:31:21 +00:00
Merge branch 'develop' into sdk2
This commit is contained in:
commit
c38ac88d69
@ -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:
|
||||
|
104
README.md
104
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,13 +37,15 @@ 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.
|
||||
@ -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__:<br/>
|
||||
Return a Merkle root hash of the application state.
|
||||
and can be found in [this file](cmd/abci-cli/abci-cli.go).
|
||||
|
||||
|
@ -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}"
|
||||
|
@ -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,8 +156,25 @@ func addCommands() {
|
||||
|
||||
var batchCmd = &cobra.Command{
|
||||
Use: "batch",
|
||||
Short: "Run a batch of abci commands against an application",
|
||||
Long: "",
|
||||
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)
|
||||
@ -166,8 +183,12 @@ var batchCmd = &cobra.Command{
|
||||
|
||||
var consoleCmd = &cobra.Command{
|
||||
Use: "console",
|
||||
Short: "Start an interactive abci console for multiple commands",
|
||||
Long: "",
|
||||
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 {
|
||||
|
221
specification.rst
Normal file
221
specification.rst
Normal file
@ -0,0 +1,221 @@
|
||||
Specification
|
||||
=============
|
||||
|
||||
The `primary
|
||||
specification <https://github.com/tendermint/abci/blob/master/types/types.proto>`__
|
||||
is made using Protocol Buffers. To build it, run
|
||||
|
||||
::
|
||||
|
||||
make protoc
|
||||
|
||||
See ``protoc --help`` and `the Protocol Buffers
|
||||
site <https://developers.google.com/protocol-buffers/>`__ for details on
|
||||
compiling for other languages. Note we also include a
|
||||
`GRPC <http://www.grpc.io/docs>`__ service definition.
|
||||
|
||||
For the specification as an interface in Go, see the
|
||||
`types/application.go
|
||||
file <https://github.com/tendermint/abci/blob/master/types/application.go>`__.
|
||||
|
||||
Message Types
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
ABCI requests/responses are defined as simple Protobuf messages in `this
|
||||
schema
|
||||
file <https://github.com/tendermint/abci/blob/master/types/types.proto>`__.
|
||||
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.
|
@ -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"
|
||||
|
@ -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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user