Browse Source

Merge pull request #218 from tendermint/release/v0.10.1

Release/v0.10.1
pull/1780/head
Ethan Buchman 6 years ago
committed by GitHub
parent
commit
f3f9f792a5
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 1273 additions and 369 deletions
  1. +13
    -0
      CHANGELOG.md
  2. +6
    -4
      Dockerfile.develop
  3. +213
    -0
      Gopkg.lock
  4. +56
    -0
      Gopkg.toml
  5. +4
    -4
      Makefile
  6. +7
    -8
      README.md
  7. +1
    -2
      client/grpc_client.go
  8. +2
    -2
      client/socket_client.go
  9. +31
    -9
      cmd/abci-cli/abci-cli.go
  10. +1
    -28
      example/dummy/README.md
  11. +0
    -0
      example/dummy/kvstore.go
  12. +0
    -0
      example/dummy/kvstore_test.go
  13. +0
    -0
      example/dummy/persistent_kvstore.go
  14. +4
    -4
      example/example_test.go
  15. +31
    -0
      example/kvstore/README.md
  16. +36
    -0
      example/kvstore/helpers.go
  17. +126
    -0
      example/kvstore/kvstore.go
  18. +310
    -0
      example/kvstore/kvstore_test.go
  19. +205
    -0
      example/kvstore/persistent_kvstore.go
  20. +0
    -120
      glide.lock
  21. +0
    -28
      glide.yaml
  22. +72
    -22
      specification.rst
  23. +2
    -2
      tests/client_server_test.go
  24. +1
    -1
      tests/server/client.go
  25. +1
    -1
      tests/test_cli/test.sh
  26. +3
    -1
      types/messages_test.go
  27. +143
    -128
      types/types.pb.go
  28. +3
    -3
      types/types.proto
  29. +2
    -2
      version/version.go

+ 13
- 0
CHANGELOG.md View File

@ -1,5 +1,18 @@
# Changelog
## 0.10.1 (March 22, 2018)
FEATURES:
- [types] ResponseCheckTx and ResponseDeliverTx are now the same.
- [example] `dummy` is duplicated as `kvstore`.
IMPROVEMENTS:
- glide -> Godep
- remove pkg/errors
- improve specification.rst
## 0.10.0 (February 20, 2018)
BREAKING CHANGES:


+ 6
- 4
Dockerfile.develop View File

@ -6,16 +6,18 @@ WORKDIR /go/src/github.com/tendermint/abci
COPY Makefile /go/src/github.com/tendermint/abci/
# see make protoc for details on ldconfig
RUN make install_protoc && ldconfig
RUN make get_protoc && ldconfig
# killall is used in tests
RUN apt-get update && apt-get install -y \
psmisc \
&& rm -rf /var/lib/apt/lists/*
COPY glide.yaml /go/src/github.com/tendermint/abci/
COPY glide.lock /go/src/github.com/tendermint/abci/
COPY Gopkg.toml /go/src/github.com/tendermint/abci/
COPY Gopkg.lock /go/src/github.com/tendermint/abci/
RUN make get_tools
RUN make get_vendor_deps
# see https://github.com/golang/dep/issues/1312
RUN dep ensure -vendor-only
COPY . /go/src/github.com/tendermint/abci

+ 213
- 0
Gopkg.lock View File

@ -0,0 +1,213 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/davecgh/go-spew"
packages = ["spew"]
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
version = "v1.1.0"
[[projects]]
name = "github.com/go-kit/kit"
packages = [
"log",
"log/level",
"log/term"
]
revision = "4dc7be5d2d12881735283bcab7352178e190fc71"
version = "v0.6.0"
[[projects]]
name = "github.com/go-logfmt/logfmt"
packages = ["."]
revision = "390ab7935ee28ec6b286364bba9b4dd6410cb3d5"
version = "v0.3.0"
[[projects]]
name = "github.com/go-stack/stack"
packages = ["."]
revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc"
version = "v1.7.0"
[[projects]]
name = "github.com/gogo/protobuf"
packages = [
"gogoproto",
"jsonpb",
"proto",
"protoc-gen-gogo/descriptor",
"sortkeys",
"types"
]
revision = "1adfc126b41513cc696b209667c8656ea7aac67c"
version = "v1.0.0"
[[projects]]
name = "github.com/golang/protobuf"
packages = [
"proto",
"ptypes",
"ptypes/any",
"ptypes/duration",
"ptypes/timestamp"
]
revision = "925541529c1fa6821df4e44ce2723319eb2be768"
version = "v1.0.0"
[[projects]]
branch = "master"
name = "github.com/golang/snappy"
packages = ["."]
revision = "553a641470496b2327abcac10b36396bd98e45c9"
[[projects]]
name = "github.com/inconshreveable/mousetrap"
packages = ["."]
revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
version = "v1.0"
[[projects]]
branch = "master"
name = "github.com/jmhodges/levigo"
packages = ["."]
revision = "c42d9e0ca023e2198120196f842701bb4c55d7b9"
[[projects]]
branch = "master"
name = "github.com/kr/logfmt"
packages = ["."]
revision = "b84e30acd515aadc4b783ad4ff83aff3299bdfe0"
[[projects]]
name = "github.com/pkg/errors"
packages = ["."]
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
version = "v0.8.0"
[[projects]]
name = "github.com/pmezard/go-difflib"
packages = ["difflib"]
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
version = "v1.0.0"
[[projects]]
name = "github.com/spf13/cobra"
packages = ["."]
revision = "7b2c5ac9fc04fc5efafb60700713d4fa609b777b"
version = "v0.0.1"
[[projects]]
name = "github.com/spf13/pflag"
packages = ["."]
revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66"
version = "v1.0.0"
[[projects]]
name = "github.com/stretchr/testify"
packages = [
"assert",
"require"
]
revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71"
version = "v1.2.1"
[[projects]]
branch = "master"
name = "github.com/syndtr/goleveldb"
packages = [
"leveldb",
"leveldb/cache",
"leveldb/comparer",
"leveldb/errors",
"leveldb/filter",
"leveldb/iterator",
"leveldb/journal",
"leveldb/memdb",
"leveldb/opt",
"leveldb/storage",
"leveldb/table",
"leveldb/util"
]
revision = "169b1b37be738edb2813dab48c97a549bcf99bb5"
[[projects]]
name = "github.com/tendermint/tmlibs"
packages = [
"common",
"db",
"log"
]
revision = "24da7009c3d8c019b40ba4287495749e3160caca"
version = "v0.7.1"
[[projects]]
branch = "master"
name = "golang.org/x/net"
packages = [
"context",
"http2",
"http2/hpack",
"idna",
"internal/timeseries",
"lex/httplex",
"trace"
]
revision = "6078986fec03a1dcc236c34816c71b0e05018fda"
[[projects]]
name = "golang.org/x/text"
packages = [
"collate",
"collate/build",
"internal/colltab",
"internal/gen",
"internal/tag",
"internal/triegen",
"internal/ucd",
"language",
"secure/bidirule",
"transform",
"unicode/bidi",
"unicode/cldr",
"unicode/norm",
"unicode/rangetable"
]
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
version = "v0.3.0"
[[projects]]
branch = "master"
name = "google.golang.org/genproto"
packages = ["googleapis/rpc/status"]
revision = "f8c8703595236ae70fdf8789ecb656ea0bcdcf46"
[[projects]]
name = "google.golang.org/grpc"
packages = [
".",
"balancer",
"codes",
"connectivity",
"credentials",
"grpclb/grpc_lb_v1/messages",
"grpclog",
"internal",
"keepalive",
"metadata",
"naming",
"peer",
"resolver",
"stats",
"status",
"tap",
"transport"
]
revision = "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e"
version = "v1.7.5"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "e0c31538af2916be2aed38bae72f9040d93aa9a4b86a1839df7a83545a2442f1"
solver-name = "gps-cdcl"
solver-version = 1

+ 56
- 0
Gopkg.toml View File

@ -0,0 +1,56 @@
# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
#
# [prune]
# non-go = false
# go-tests = true
# unused-packages = true
# NOTE if not specified, dep automatically adds `^` to each version,
# meaning it will accept up to the next version for the first non-zero
# element in the version.
#
# So `version = "1.3.2"` means `1.3.2 <= version < 2.0.0`.
# Use `~` for only minor version bumps.
[[constraint]]
name = "github.com/gogo/protobuf"
version = "~1.0.0"
[[constraint]]
name = "github.com/spf13/cobra"
version = "~0.0.1"
[[constraint]]
name = "github.com/stretchr/testify"
version = "~1.2.1"
[[constraint]]
version = "~0.7.1"
name = "github.com/tendermint/tmlibs"
[[constraint]]
name = "google.golang.org/grpc"
version = "~1.7.3"
[prune]
go-tests = true
unused-packages = true

+ 4
- 4
Makefile View File

@ -1,10 +1,10 @@
GOTOOLS = \
github.com/mitchellh/gox \
github.com/Masterminds/glide \
github.com/golang/dep/cmd/dep \
gopkg.in/alecthomas/gometalinter.v2 \
github.com/gogo/protobuf/protoc-gen-gogo \
github.com/gogo/protobuf/gogoproto
GOTOOLS_CHECK = gox glide gometalinter.v2 protoc protoc-gen-gogo
GOTOOLS_CHECK = gox dep gometalinter.v2 protoc protoc-gen-gogo
PACKAGES=$(shell go list ./... | grep -v '/vendor/')
INCLUDE = -I=. -I=${GOPATH}/src -I=${GOPATH}/src/github.com/gogo/protobuf/protobuf
@ -65,8 +65,8 @@ update_tools:
get_vendor_deps:
@rm -rf vendor/
@echo "--> Running glide install"
@glide install
@echo "--> Running dep ensure"
@dep ensure
########################################


+ 7
- 8
README.md View File

@ -90,7 +90,7 @@ See [the documentation](http://tendermint.readthedocs.io/en/master/) for more de
### Examples
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
It also contains the code refered to by the `counter` and `kvstore` apps; these apps come
built into the `abci-cli` binary.
#### Counter
@ -125,21 +125,21 @@ func cmdCounter(cmd *cobra.Command, args []string) error {
and can be found in [this file](cmd/abci-cli/abci-cli.go).
#### Dummy
#### kvstore
The `abci-cli dummy` application, which illustrates a simple key-value Merkle tree
The `abci-cli kvstore` application, which illustrates a simple key-value Merkle tree
```golang
func cmdDummy(cmd *cobra.Command, args []string) error {
func cmdKVStore(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()
app = kvstore.NewKVStoreApplication()
} else {
app = dummy.NewPersistentDummyApplication(flagPersist)
app.(*dummy.PersistentDummyApplication).SetLogger(logger.With("module", "dummy"))
app = kvstore.NewPersistentKVStoreApplication(flagPersist)
app.(*kvstore.PersistentKVStoreApplication).SetLogger(logger.With("module", "kvstore"))
}
// Start the listener
@ -160,4 +160,3 @@ func cmdDummy(cmd *cobra.Command, args []string) error {
return nil
}
```

+ 1
- 2
client/grpc_client.go View File

@ -6,7 +6,6 @@ import (
"sync"
"time"
"github.com/pkg/errors"
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
@ -105,7 +104,7 @@ func (cli *grpcClient) StopForError(err error) {
func (cli *grpcClient) Error() error {
cli.mtx.Lock()
defer cli.mtx.Unlock()
return errors.Wrap(cli.err, "grpc client error")
return cli.err
}
// Set listener for all responses


+ 2
- 2
client/socket_client.go View File

@ -3,13 +3,13 @@ package abcicli
import (
"bufio"
"container/list"
"errors"
"fmt"
"net"
"reflect"
"sync"
"time"
"github.com/pkg/errors"
"github.com/tendermint/abci/types"
cmn "github.com/tendermint/tmlibs/common"
)
@ -111,7 +111,7 @@ func (cli *socketClient) StopForError(err error) {
func (cli *socketClient) Error() error {
cli.mtx.Lock()
defer cli.mtx.Unlock()
return errors.Wrap(cli.err, "socket client error")
return cli.err
}
// Set listener for all responses


+ 31
- 9
cmd/abci-cli/abci-cli.go View File

@ -17,7 +17,7 @@ import (
abcicli "github.com/tendermint/abci/client"
"github.com/tendermint/abci/example/code"
"github.com/tendermint/abci/example/counter"
"github.com/tendermint/abci/example/dummy"
"github.com/tendermint/abci/example/kvstore"
"github.com/tendermint/abci/server"
servertest "github.com/tendermint/abci/tests/server"
"github.com/tendermint/abci/types"
@ -47,7 +47,7 @@ var (
flagAddrC string
flagSerial bool
// dummy
// kvstore
flagAddrD string
flagPersist string
)
@ -59,7 +59,7 @@ var RootCmd = &cobra.Command{
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
switch cmd.Use {
case "counter", "dummy": // for the examples apps, don't pre-run
case "counter", "kvstore", "dummy": // for the examples apps, don't pre-run
return nil
case "version": // skip running for version command
return nil
@ -133,6 +133,12 @@ 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")
}
func addKVStoreFlags() {
kvstoreCmd.PersistentFlags().StringVarP(&flagAddrD, "addr", "", "tcp://0.0.0.0:46658", "listen address")
kvstoreCmd.PersistentFlags().StringVarP(&flagPersist, "persist", "", "", "directory to use for a database")
}
func addCommands() {
RootCmd.AddCommand(batchCmd)
RootCmd.AddCommand(consoleCmd)
@ -150,8 +156,12 @@ func addCommands() {
// examples
addCounterFlags()
RootCmd.AddCommand(counterCmd)
// deprecated, left for backwards compatibility
addDummyFlags()
RootCmd.AddCommand(dummyCmd)
// replaces dummy, see issue #196
addKVStoreFlags()
RootCmd.AddCommand(kvstoreCmd)
}
var batchCmd = &cobra.Command{
@ -285,13 +295,25 @@ var counterCmd = &cobra.Command{
},
}
// deprecated, left for backwards compatibility
var dummyCmd = &cobra.Command{
Use: "dummy",
Use: "dummy",
Deprecated: "use: [abci-cli kvstore] instead",
Short: "ABCI demo example",
Long: "ABCI demo example",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
return cmdKVStore(cmd, args)
},
}
var kvstoreCmd = &cobra.Command{
Use: "kvstore",
Short: "ABCI demo example",
Long: "ABCI demo example",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
return cmdDummy(cmd, args)
return cmdKVStore(cmd, args)
},
}
@ -654,16 +676,16 @@ func cmdCounter(cmd *cobra.Command, args []string) error {
return nil
}
func cmdDummy(cmd *cobra.Command, args []string) error {
func cmdKVStore(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()
app = kvstore.NewKVStoreApplication()
} else {
app = dummy.NewPersistentDummyApplication(flagPersist)
app.(*dummy.PersistentDummyApplication).SetLogger(logger.With("module", "dummy"))
app = kvstore.NewPersistentKVStoreApplication(flagPersist)
app.(*kvstore.PersistentKVStoreApplication).SetLogger(logger.With("module", "kvstore"))
}
// Start the listener


+ 1
- 28
example/dummy/README.md View File

@ -1,31 +1,4 @@
# Dummy
There are two app's here: the DummyApplication and the PersistentDummyApplication.
## DummyApplication
The DummyApplication is a simple merkle key-value store.
Transactions of the form `key=value` are stored as key-value pairs in the tree.
Transactions without an `=` sign set the value to the key.
The app has no replay protection (other than what the mempool provides).
## PersistentDummyApplication
The PersistentDummyApplication wraps the DummyApplication
and provides two additional features:
1) persistence of state across app restarts (using Tendermint's ABCI-Handshake mechanism)
2) validator set changes
The state is persisted in leveldb along with the last block committed,
and the Handshake allows any necessary blocks to be replayed.
Validator set changes are effected using the following transaction format:
```
val:pubkey1/power1,addr2/power2,addr3/power3"
```
where `power1` is the new voting power for the validator with `pubkey1` (possibly a new one).
There is no sybil protection against new validators joining.
Validators can be removed by setting their power to `0`.
DEPRECATED. See KVStore

example/dummy/dummy.go → example/dummy/kvstore.go View File


example/dummy/dummy_test.go → example/dummy/kvstore_test.go View File


example/dummy/persistent_dummy.go → example/dummy/persistent_kvstore.go View File


+ 4
- 4
example/example_test.go View File

@ -16,14 +16,14 @@ import (
abcicli "github.com/tendermint/abci/client"
"github.com/tendermint/abci/example/code"
"github.com/tendermint/abci/example/dummy"
"github.com/tendermint/abci/example/kvstore"
abciserver "github.com/tendermint/abci/server"
"github.com/tendermint/abci/types"
)
func TestDummy(t *testing.T) {
fmt.Println("### Testing Dummy")
testStream(t, dummy.NewDummyApplication())
func TestKVStore(t *testing.T) {
fmt.Println("### Testing KVStore")
testStream(t, kvstore.NewKVStoreApplication())
}
func TestBaseApp(t *testing.T) {


+ 31
- 0
example/kvstore/README.md View File

@ -0,0 +1,31 @@
# KVStore
There are two app's here: the KVStoreApplication and the PersistentKVStoreApplication.
## KVStoreApplication
The KVStoreApplication is a simple merkle key-value store.
Transactions of the form `key=value` are stored as key-value pairs in the tree.
Transactions without an `=` sign set the value to the key.
The app has no replay protection (other than what the mempool provides).
## PersistentKVStoreApplication
The PersistentKVStoreApplication wraps the KVStoreApplication
and provides two additional features:
1) persistence of state across app restarts (using Tendermint's ABCI-Handshake mechanism)
2) validator set changes
The state is persisted in leveldb along with the last block committed,
and the Handshake allows any necessary blocks to be replayed.
Validator set changes are effected using the following transaction format:
```
val:pubkey1/power1,addr2/power2,addr3/power3"
```
where `power1` is the new voting power for the validator with `pubkey1` (possibly a new one).
There is no sybil protection against new validators joining.
Validators can be removed by setting their power to `0`.

+ 36
- 0
example/kvstore/helpers.go View File

@ -0,0 +1,36 @@
package kvstore
import (
"github.com/tendermint/abci/types"
cmn "github.com/tendermint/tmlibs/common"
)
// RandVal creates one random validator, with a key derived
// from the input value
func RandVal(i int) types.Validator {
pubkey := cmn.RandBytes(33)
power := cmn.RandUint16() + 1
return types.Validator{pubkey, int64(power)}
}
// RandVals returns a list of cnt validators for initializing
// the application. Note that the keys are deterministically
// derived from the index in the array, while the power is
// random (Change this if not desired)
func RandVals(cnt int) []types.Validator {
res := make([]types.Validator, cnt)
for i := 0; i < cnt; i++ {
res[i] = RandVal(i)
}
return res
}
// InitKVStore initializes the kvstore app with some data,
// which allows tests to pass and is fine as long as you
// don't make any tx that modify the validator state
func InitKVStore(app *PersistentKVStoreApplication) {
app.InitChain(types.RequestInitChain{
Validators: RandVals(1),
AppStateBytes: []byte("[]"),
})
}

+ 126
- 0
example/kvstore/kvstore.go View File

@ -0,0 +1,126 @@
package kvstore
import (
"bytes"
"encoding/binary"
"encoding/json"
"fmt"
"github.com/tendermint/abci/example/code"
"github.com/tendermint/abci/types"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
)
var (
stateKey = []byte("stateKey")
kvPairPrefixKey = []byte("kvPairKey:")
)
type State struct {
db dbm.DB
Size int64 `json:"size"`
Height int64 `json:"height"`
AppHash []byte `json:"app_hash"`
}
func loadState(db dbm.DB) State {
stateBytes := db.Get(stateKey)
var state State
if len(stateBytes) != 0 {
err := json.Unmarshal(stateBytes, &state)
if err != nil {
panic(err)
}
}
state.db = db
return state
}
func saveState(state State) {
stateBytes, err := json.Marshal(state)
if err != nil {
panic(err)
}
state.db.Set(stateKey, stateBytes)
}
func prefixKey(key []byte) []byte {
return append(kvPairPrefixKey, key...)
}
//---------------------------------------------------
var _ types.Application = (*KVStoreApplication)(nil)
type KVStoreApplication struct {
types.BaseApplication
state State
}
func NewKVStoreApplication() *KVStoreApplication {
state := loadState(dbm.NewMemDB())
return &KVStoreApplication{state: state}
}
func (app *KVStoreApplication) Info(req types.RequestInfo) (resInfo types.ResponseInfo) {
return types.ResponseInfo{Data: fmt.Sprintf("{\"size\":%v}", app.state.Size)}
}
// tx is either "key=value" or just arbitrary bytes
func (app *KVStoreApplication) DeliverTx(tx []byte) types.ResponseDeliverTx {
var key, value []byte
parts := bytes.Split(tx, []byte("="))
if len(parts) == 2 {
key, value = parts[0], parts[1]
} else {
key, value = tx, tx
}
app.state.db.Set(prefixKey(key), value)
app.state.Size += 1
tags := []cmn.KVPair{
{[]byte("app.creator"), []byte("jae")},
{[]byte("app.key"), key},
}
return types.ResponseDeliverTx{Code: code.CodeTypeOK, Tags: tags}
}
func (app *KVStoreApplication) CheckTx(tx []byte) types.ResponseCheckTx {
return types.ResponseCheckTx{Code: code.CodeTypeOK}
}
func (app *KVStoreApplication) Commit() types.ResponseCommit {
// Using a memdb - just return the big endian size of the db
appHash := make([]byte, 8)
binary.PutVarint(appHash, app.state.Size)
app.state.AppHash = appHash
app.state.Height += 1
saveState(app.state)
return types.ResponseCommit{Data: appHash}
}
func (app *KVStoreApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) {
if reqQuery.Prove {
value := app.state.db.Get(prefixKey(reqQuery.Data))
resQuery.Index = -1 // TODO make Proof return index
resQuery.Key = reqQuery.Data
resQuery.Value = value
if value != nil {
resQuery.Log = "exists"
} else {
resQuery.Log = "does not exist"
}
return
} else {
value := app.state.db.Get(prefixKey(reqQuery.Data))
resQuery.Value = value
if value != nil {
resQuery.Log = "exists"
} else {
resQuery.Log = "does not exist"
}
return
}
}

+ 310
- 0
example/kvstore/kvstore_test.go View File

@ -0,0 +1,310 @@
package kvstore
import (
"bytes"
"io/ioutil"
"sort"
"testing"
"github.com/stretchr/testify/require"
cmn "github.com/tendermint/tmlibs/common"
"github.com/tendermint/tmlibs/log"
abcicli "github.com/tendermint/abci/client"
"github.com/tendermint/abci/example/code"
abciserver "github.com/tendermint/abci/server"
"github.com/tendermint/abci/types"
)
func testKVStore(t *testing.T, app types.Application, tx []byte, key, value string) {
ar := app.DeliverTx(tx)
require.False(t, ar.IsErr(), ar)
// repeating tx doesn't raise error
ar = app.DeliverTx(tx)
require.False(t, ar.IsErr(), ar)
// make sure query is fine
resQuery := app.Query(types.RequestQuery{
Path: "/store",
Data: []byte(key),
})
require.Equal(t, code.CodeTypeOK, resQuery.Code)
require.Equal(t, value, string(resQuery.Value))
// make sure proof is fine
resQuery = app.Query(types.RequestQuery{
Path: "/store",
Data: []byte(key),
Prove: true,
})
require.EqualValues(t, code.CodeTypeOK, resQuery.Code)
require.Equal(t, value, string(resQuery.Value))
}
func TestKVStoreKV(t *testing.T) {
kvstore := NewKVStoreApplication()
key := "abc"
value := key
tx := []byte(key)
testKVStore(t, kvstore, tx, key, value)
value = "def"
tx = []byte(key + "=" + value)
testKVStore(t, kvstore, tx, key, value)
}
func TestPersistentKVStoreKV(t *testing.T) {
dir, err := ioutil.TempDir("/tmp", "abci-kvstore-test") // TODO
if err != nil {
t.Fatal(err)
}
kvstore := NewPersistentKVStoreApplication(dir)
key := "abc"
value := key
tx := []byte(key)
testKVStore(t, kvstore, tx, key, value)
value = "def"
tx = []byte(key + "=" + value)
testKVStore(t, kvstore, tx, key, value)
}
func TestPersistentKVStoreInfo(t *testing.T) {
dir, err := ioutil.TempDir("/tmp", "abci-kvstore-test") // TODO
if err != nil {
t.Fatal(err)
}
kvstore := NewPersistentKVStoreApplication(dir)
InitKVStore(kvstore)
height := int64(0)
resInfo := kvstore.Info(types.RequestInfo{})
if resInfo.LastBlockHeight != height {
t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight)
}
// make and apply block
height = int64(1)
hash := []byte("foo")
header := types.Header{
Height: int64(height),
}
kvstore.BeginBlock(types.RequestBeginBlock{hash, header, nil, nil})
kvstore.EndBlock(types.RequestEndBlock{header.Height})
kvstore.Commit()
resInfo = kvstore.Info(types.RequestInfo{})
if resInfo.LastBlockHeight != height {
t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight)
}
}
// add a validator, remove a validator, update a validator
func TestValUpdates(t *testing.T) {
dir, err := ioutil.TempDir("/tmp", "abci-kvstore-test") // TODO
if err != nil {
t.Fatal(err)
}
kvstore := NewPersistentKVStoreApplication(dir)
// init with some validators
total := 10
nInit := 5
vals := RandVals(total)
// iniitalize with the first nInit
kvstore.InitChain(types.RequestInitChain{
Validators: vals[:nInit],
})
vals1, vals2 := vals[:nInit], kvstore.Validators()
valsEqual(t, vals1, vals2)
var v1, v2, v3 types.Validator
// add some validators
v1, v2 = vals[nInit], vals[nInit+1]
diff := []types.Validator{v1, v2}
tx1 := MakeValSetChangeTx(v1.PubKey, v1.Power)
tx2 := MakeValSetChangeTx(v2.PubKey, v2.Power)
makeApplyBlock(t, kvstore, 1, diff, tx1, tx2)
vals1, vals2 = vals[:nInit+2], kvstore.Validators()
valsEqual(t, vals1, vals2)
// remove some validators
v1, v2, v3 = vals[nInit-2], vals[nInit-1], vals[nInit]
v1.Power = 0
v2.Power = 0
v3.Power = 0
diff = []types.Validator{v1, v2, v3}
tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power)
tx2 = MakeValSetChangeTx(v2.PubKey, v2.Power)
tx3 := MakeValSetChangeTx(v3.PubKey, v3.Power)
makeApplyBlock(t, kvstore, 2, diff, tx1, tx2, tx3)
vals1 = append(vals[:nInit-2], vals[nInit+1])
vals2 = kvstore.Validators()
valsEqual(t, vals1, vals2)
// update some validators
v1 = vals[0]
if v1.Power == 5 {
v1.Power = 6
} else {
v1.Power = 5
}
diff = []types.Validator{v1}
tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power)
makeApplyBlock(t, kvstore, 3, diff, tx1)
vals1 = append([]types.Validator{v1}, vals1[1:]...)
vals2 = kvstore.Validators()
valsEqual(t, vals1, vals2)
}
func makeApplyBlock(t *testing.T, kvstore types.Application, heightInt int, diff []types.Validator, txs ...[]byte) {
// make and apply block
height := int64(heightInt)
hash := []byte("foo")
header := types.Header{
Height: height,
}
kvstore.BeginBlock(types.RequestBeginBlock{hash, header, nil, nil})
for _, tx := range txs {
if r := kvstore.DeliverTx(tx); r.IsErr() {
t.Fatal(r)
}
}
resEndBlock := kvstore.EndBlock(types.RequestEndBlock{header.Height})
kvstore.Commit()
valsEqual(t, diff, resEndBlock.ValidatorUpdates)
}
// order doesn't matter
func valsEqual(t *testing.T, vals1, vals2 []types.Validator) {
if len(vals1) != len(vals2) {
t.Fatalf("vals dont match in len. got %d, expected %d", len(vals2), len(vals1))
}
sort.Sort(types.Validators(vals1))
sort.Sort(types.Validators(vals2))
for i, v1 := range vals1 {
v2 := vals2[i]
if !bytes.Equal(v1.PubKey, v2.PubKey) ||
v1.Power != v2.Power {
t.Fatalf("vals dont match at index %d. got %X/%d , expected %X/%d", i, v2.PubKey, v2.Power, v1.PubKey, v1.Power)
}
}
}
func makeSocketClientServer(app types.Application, name string) (abcicli.Client, cmn.Service, error) {
// Start the listener
socket := cmn.Fmt("unix://%s.sock", name)
logger := log.TestingLogger()
server := abciserver.NewSocketServer(socket, app)
server.SetLogger(logger.With("module", "abci-server"))
if err := server.Start(); err != nil {
return nil, nil, err
}
// Connect to the socket
client := abcicli.NewSocketClient(socket, false)
client.SetLogger(logger.With("module", "abci-client"))
if err := client.Start(); err != nil {
server.Stop()
return nil, nil, err
}
return client, server, nil
}
func makeGRPCClientServer(app types.Application, name string) (abcicli.Client, cmn.Service, error) {
// Start the listener
socket := cmn.Fmt("unix://%s.sock", name)
logger := log.TestingLogger()
gapp := types.NewGRPCApplication(app)
server := abciserver.NewGRPCServer(socket, gapp)
server.SetLogger(logger.With("module", "abci-server"))
if err := server.Start(); err != nil {
return nil, nil, err
}
client := abcicli.NewGRPCClient(socket, true)
client.SetLogger(logger.With("module", "abci-client"))
if err := client.Start(); err != nil {
server.Stop()
return nil, nil, err
}
return client, server, nil
}
func TestClientServer(t *testing.T) {
// set up socket app
kvstore := NewKVStoreApplication()
client, server, err := makeSocketClientServer(kvstore, "kvstore-socket")
require.Nil(t, err)
defer server.Stop()
defer client.Stop()
runClientTests(t, client)
// set up grpc app
kvstore = NewKVStoreApplication()
gclient, gserver, err := makeGRPCClientServer(kvstore, "kvstore-grpc")
require.Nil(t, err)
defer gserver.Stop()
defer gclient.Stop()
runClientTests(t, gclient)
}
func runClientTests(t *testing.T, client abcicli.Client) {
// run some tests....
key := "abc"
value := key
tx := []byte(key)
testClient(t, client, tx, key, value)
value = "def"
tx = []byte(key + "=" + value)
testClient(t, client, tx, key, value)
}
func testClient(t *testing.T, app abcicli.Client, tx []byte, key, value string) {
ar, err := app.DeliverTxSync(tx)
require.NoError(t, err)
require.False(t, ar.IsErr(), ar)
// repeating tx doesn't raise error
ar, err = app.DeliverTxSync(tx)
require.NoError(t, err)
require.False(t, ar.IsErr(), ar)
// make sure query is fine
resQuery, err := app.QuerySync(types.RequestQuery{
Path: "/store",
Data: []byte(key),
})
require.Nil(t, err)
require.Equal(t, code.CodeTypeOK, resQuery.Code)
require.Equal(t, value, string(resQuery.Value))
// make sure proof is fine
resQuery, err = app.QuerySync(types.RequestQuery{
Path: "/store",
Data: []byte(key),
Prove: true,
})
require.Nil(t, err)
require.Equal(t, code.CodeTypeOK, resQuery.Code)
require.Equal(t, value, string(resQuery.Value))
}

+ 205
- 0
example/kvstore/persistent_kvstore.go View File

@ -0,0 +1,205 @@
package kvstore
import (
"bytes"
"encoding/hex"
"fmt"
"strconv"
"strings"
"github.com/tendermint/abci/example/code"
"github.com/tendermint/abci/types"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/log"
)
const (
ValidatorSetChangePrefix string = "val:"
)
//-----------------------------------------
var _ types.Application = (*PersistentKVStoreApplication)(nil)
type PersistentKVStoreApplication struct {
app *KVStoreApplication
// validator set
ValUpdates []types.Validator
logger log.Logger
}
func NewPersistentKVStoreApplication(dbDir string) *PersistentKVStoreApplication {
name := "kvstore"
db, err := dbm.NewGoLevelDB(name, dbDir)
if err != nil {
panic(err)
}
state := loadState(db)
return &PersistentKVStoreApplication{
app: &KVStoreApplication{state: state},
logger: log.NewNopLogger(),
}
}
func (app *PersistentKVStoreApplication) SetLogger(l log.Logger) {
app.logger = l
}
func (app *PersistentKVStoreApplication) Info(req types.RequestInfo) types.ResponseInfo {
res := app.app.Info(req)
res.LastBlockHeight = app.app.state.Height
res.LastBlockAppHash = app.app.state.AppHash
return res
}
func (app *PersistentKVStoreApplication) SetOption(req types.RequestSetOption) types.ResponseSetOption {
return app.app.SetOption(req)
}
// tx is either "val:pubkey/power" or "key=value" or just arbitrary bytes
func (app *PersistentKVStoreApplication) DeliverTx(tx []byte) types.ResponseDeliverTx {
// if it starts with "val:", update the validator set
// format is "val:pubkey/power"
if isValidatorTx(tx) {
// update validators in the merkle tree
// and in app.ValUpdates
return app.execValidatorTx(tx)
}
// otherwise, update the key-value store
return app.app.DeliverTx(tx)
}
func (app *PersistentKVStoreApplication) CheckTx(tx []byte) types.ResponseCheckTx {
return app.app.CheckTx(tx)
}
// Commit will panic if InitChain was not called
func (app *PersistentKVStoreApplication) Commit() types.ResponseCommit {
return app.app.Commit()
}
func (app *PersistentKVStoreApplication) Query(reqQuery types.RequestQuery) types.ResponseQuery {
return app.app.Query(reqQuery)
}
// Save the validators in the merkle tree
func (app *PersistentKVStoreApplication) InitChain(req types.RequestInitChain) types.ResponseInitChain {
for _, v := range req.Validators {
r := app.updateValidator(v)
if r.IsErr() {
app.logger.Error("Error updating validators", "r", r)
}
}
return types.ResponseInitChain{}
}
// Track the block hash and header information
func (app *PersistentKVStoreApplication) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock {
// reset valset changes
app.ValUpdates = make([]types.Validator, 0)
return types.ResponseBeginBlock{}
}
// Update the validator set
func (app *PersistentKVStoreApplication) EndBlock(req types.RequestEndBlock) types.ResponseEndBlock {
return types.ResponseEndBlock{ValidatorUpdates: app.ValUpdates}
}
//---------------------------------------------
// update validators
func (app *PersistentKVStoreApplication) Validators() (validators []types.Validator) {
itr := app.app.state.db.Iterator(nil, nil)
for ; itr.Valid(); itr.Next() {
if isValidatorTx(itr.Key()) {
validator := new(types.Validator)
err := types.ReadMessage(bytes.NewBuffer(itr.Value()), validator)
if err != nil {
panic(err)
}
validators = append(validators, *validator)
}
}
return
}
func MakeValSetChangeTx(pubkey []byte, power int64) []byte {
return []byte(cmn.Fmt("val:%X/%d", pubkey, power))
}
func isValidatorTx(tx []byte) bool {
return strings.HasPrefix(string(tx), ValidatorSetChangePrefix)
}
// format is "val:pubkey1/power1,addr2/power2,addr3/power3"tx
func (app *PersistentKVStoreApplication) execValidatorTx(tx []byte) types.ResponseDeliverTx {
tx = tx[len(ValidatorSetChangePrefix):]
//get the pubkey and power
pubKeyAndPower := strings.Split(string(tx), "/")
if len(pubKeyAndPower) != 2 {
return types.ResponseDeliverTx{
Code: code.CodeTypeEncodingError,
Log: fmt.Sprintf("Expected 'pubkey/power'. Got %v", pubKeyAndPower)}
}
pubkeyS, powerS := pubKeyAndPower[0], pubKeyAndPower[1]
// decode the pubkey, ensuring its go-crypto encoded
pubkey, err := hex.DecodeString(pubkeyS)
if err != nil {
return types.ResponseDeliverTx{
Code: code.CodeTypeEncodingError,
Log: fmt.Sprintf("Pubkey (%s) is invalid hex", pubkeyS)}
}
/*_, err = crypto.PubKeyFromBytes(pubkey)
if err != nil {
return types.ResponseDeliverTx{
Code: code.CodeTypeEncodingError,
Log: fmt.Sprintf("Pubkey (%X) is invalid go-crypto encoded", pubkey)}
}*/
// decode the power
power, err := strconv.ParseInt(powerS, 10, 64)
if err != nil {
return types.ResponseDeliverTx{
Code: code.CodeTypeEncodingError,
Log: fmt.Sprintf("Power (%s) is not an int", powerS)}
}
// update
return app.updateValidator(types.Validator{pubkey, power})
}
// add, update, or remove a validator
func (app *PersistentKVStoreApplication) updateValidator(v types.Validator) types.ResponseDeliverTx {
key := []byte("val:" + string(v.PubKey))
if v.Power == 0 {
// remove validator
if !app.app.state.db.Has(key) {
return types.ResponseDeliverTx{
Code: code.CodeTypeUnauthorized,
Log: fmt.Sprintf("Cannot remove non-existent validator %X", key)}
}
app.app.state.db.Delete(key)
} else {
// add or update validator
value := bytes.NewBuffer(make([]byte, 0))
if err := types.WriteMessage(&v, value); err != nil {
return types.ResponseDeliverTx{
Code: code.CodeTypeEncodingError,
Log: fmt.Sprintf("Error encoding validator: %v", err)}
}
app.app.state.db.Set(key, value.Bytes())
}
// we only update the changes array if we successfully updated the tree
app.ValUpdates = append(app.ValUpdates, v)
return types.ResponseDeliverTx{Code: code.CodeTypeOK}
}

+ 0
- 120
glide.lock View File

@ -1,120 +0,0 @@
hash: cff2757779ef879f0c625c42af37fb3e486afd93ab9a91175c2458a719faac66
updated: 2018-02-20T22:02:37.638875125-05:00
imports:
- name: github.com/go-kit/kit
version: 4dc7be5d2d12881735283bcab7352178e190fc71
subpackages:
- log
- log/level
- log/term
- name: github.com/go-logfmt/logfmt
version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5
- name: github.com/go-stack/stack
version: 259ab82a6cad3992b4e21ff5cac294ccb06474bc
- name: github.com/gogo/protobuf
version: 1adfc126b41513cc696b209667c8656ea7aac67c
subpackages:
- gogoproto
- jsonpb
- proto
- protoc-gen-gogo/descriptor
- sortkeys
- types
- name: github.com/golang/protobuf
version: 925541529c1fa6821df4e44ce2723319eb2be768
subpackages:
- proto
- ptypes
- ptypes/any
- ptypes/duration
- ptypes/timestamp
- name: github.com/golang/snappy
version: 553a641470496b2327abcac10b36396bd98e45c9
- name: github.com/inconshreveable/mousetrap
version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
- name: github.com/jmhodges/levigo
version: c42d9e0ca023e2198120196f842701bb4c55d7b9
- name: github.com/kr/logfmt
version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0
- name: github.com/pkg/errors
version: 645ef00459ed84a119197bfb8d8205042c6df63d
- name: github.com/spf13/cobra
version: 7b2c5ac9fc04fc5efafb60700713d4fa609b777b
- name: github.com/spf13/pflag
version: 4c012f6dcd9546820e378d0bdda4d8fc772cdfea
- name: github.com/syndtr/goleveldb
version: 211f780988068502fe874c44dae530528ebd840f
subpackages:
- leveldb
- leveldb/cache
- leveldb/comparer
- leveldb/errors
- leveldb/filter
- leveldb/iterator
- leveldb/journal
- leveldb/memdb
- leveldb/opt
- leveldb/storage
- leveldb/table
- leveldb/util
- name: github.com/tendermint/tmlibs
version: 1b9b5652a199ab0be2e781393fb275b66377309d
subpackages:
- common
- db
- log
- process
- name: golang.org/x/net
version: 2fb46b16b8dda405028c50f7c7f0f9dd1fa6bfb1
subpackages:
- context
- http2
- http2/hpack
- idna
- internal/timeseries
- lex/httplex
- trace
- name: golang.org/x/text
version: e19ae1496984b1c655b8044a65c0300a3c878dd3
subpackages:
- secure/bidirule
- transform
- unicode/bidi
- unicode/norm
- name: google.golang.org/genproto
version: 4eb30f4778eed4c258ba66527a0d4f9ec8a36c45
subpackages:
- googleapis/rpc/status
- name: google.golang.org/grpc
version: 401e0e00e4bb830a10496d64cd95e068c5bf50de
subpackages:
- balancer
- codes
- connectivity
- credentials
- grpclb/grpc_lb_v1/messages
- grpclog
- internal
- keepalive
- metadata
- naming
- peer
- resolver
- stats
- status
- tap
- transport
testImports:
- name: github.com/davecgh/go-spew
version: 346938d642f2ec3594ed81d874461961cd0faa76
subpackages:
- spew
- name: github.com/pmezard/go-difflib
version: 792786c7400a136282c1664665ae0a8db921c6c2
subpackages:
- difflib
- name: github.com/stretchr/testify
version: 12b6f73e6084dad08a7c6e575284b177ecafbc71
subpackages:
- assert
- require

+ 0
- 28
glide.yaml View File

@ -1,28 +0,0 @@
package: github.com/tendermint/abci
import:
- package: github.com/gogo/protobuf
version: ^1.0.0
subpackages:
- proto
- package: github.com/pkg/errors
version: v0.8.0
- package: github.com/spf13/cobra
version: v0.0.1
- package: github.com/tendermint/tmlibs
version: v0.7.0
subpackages:
- common
- db
- log
- process
- package: golang.org/x/net
subpackages:
- context
- package: google.golang.org/grpc
version: v1.7.3
testImport:
- package: github.com/stretchr/testify
version: v1.2.1
subpackages:
- assert
- require

+ 72
- 22
specification.rst View File

@ -8,8 +8,51 @@ 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:
responses. Here, we provide an overview of the messages types and how they
are used by Tendermint. Then we describe each request-response pair as a
function with arguments and return values, and add some notes on usage.
Some messages (``Echo, Info, InitChain, BeginBlock, EndBlock, Commit``), don't
return errors because an error would indicate a critical failure in the
application and there's nothing Tendermint can do. The problem should be
addressed and both Tendermint and the application restarted. All other
messages (``SetOption, Query, CheckTx, DeliverTx``) return an
application-specific response ``Code uint32``, where only ``0`` is reserved for
``OK``.
Some messages (``SetOption, Query, CheckTx, DeliverTx``) return
non-deterministic data in the form of ``Info`` and ``Log``. The ``Log`` is
intended for the literal output from the application's logger, while the
``Info`` is any additional info that should be returned.
The first time a new blockchain is started, Tendermint calls ``InitChain``.
From then on, the Block Execution Sequence that causes the committed state to
be updated is as follows:
``BeginBlock, [DeliverTx], EndBlock, Commit``
where one ``DeliverTx`` is called for each transaction in the block.
Cryptographic commitments to the results of DeliverTx, EndBlock, and
Commit are included in the header of the next block.
Tendermint opens three connections to the application to handle the different message
types:
- ``Consensus Connection - InitChain, BeginBlock, DeliverTx, EndBlock, Commit``
- ``Mempool Connection - CheckTx``
- ``Info Connection - Info, SetOption, Query``
The ``Flush`` message is used on every connection, and the ``Echo`` message
is only used for debugging.
Note that messages may be sent concurrently across all connections -
a typical application will thus maintain a distinct state for each
connection. They may be referred to as the ``DeliverTx state``, the
``CheckTx state``, and the ``Commit state`` respectively.
See below for more details on the message types and how they are used.
Echo
^^^^
@ -55,7 +98,11 @@ Info
- **Usage**:
- Return information about the application state.
- Used to sync the app with Tendermint on crash/restart.
- Used to sync Tendermint with the application during a handshake that
happens on startup.
- Tendermint expects ``LastBlockAppHash`` and ``LastBlockHeight`` to be
updated during ``Commit``, ensuring that ``Commit`` is never called twice
for the same block height.
SetOption
^^^^^^^^^
@ -87,7 +134,7 @@ InitChain
- **Usage**:
- Called once upon genesis
- Called once upon genesis.
Query
^^^^^
@ -161,26 +208,26 @@ CheckTx
- ``Data ([]byte)``: Result bytes, if any.
- ``Log (string)``: The output of the application's logger. May be non-deterministic.
- ``Info (string)``: Additional information. May be non-deterministic.
- ``GasWanted (int64)``: Amount of gas consumed by transaction.
- ``GasWanted (int64)``: Amount of gas request for transaction.
- ``GasUsed (int64)``: Amount of gas consumed by transaction.
- ``Tags ([]cmn.KVPair)``: Key-Value tags for filtering and indexing transactions (eg. by account).
- ``Fee ([]cmn.KI64Pair)``: Fee paid for the transaction.
- ``Fee (cmn.KI64Pair)``: Fee paid for the 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``, to allow for dependent sequences of transactions
in the same block.
proposing. CheckTx should perform stateful but light-weight checks
of the validity of the transaction (like checking signatures and account balances),
but need not execute in full (like running a smart contract).
Tendermint runs CheckTx and DeliverTx concurrently with eachother,
though on distinct ABCI connections - the mempool connection and the consensus
connection, respectively.
The application should maintain a separate state to support CheckTx.
This state can be reset to the latest committed state during ``Commit``,
where Tendermint ensures the mempool is locked and not sending new ``CheckTx``.
After ``Commit``, the mempool will rerun CheckTx on all remaining
transactions, throwing out any that are no longer valid.
DeliverTx
^^^^^^^^^
@ -195,11 +242,13 @@ DeliverTx
- ``Data ([]byte)``: Result bytes, if any.
- ``Log (string)``: The output of the application's logger. May be non-deterministic.
- ``Info (string)``: Additional information. May be non-deterministic.
- ``GasWanted (int64)``: Amount of gas predicted to be consumed by transaction.
- ``GasWanted (int64)``: Amount of gas requested for transaction.
- ``GasUsed (int64)``: Amount of gas consumed by transaction.
- ``Tags ([]cmn.KVPair)``: Key-Value tags for filtering and indexing transactions (eg. by account).
- ``Fee (cmn.KI64Pair)``: Fee paid for the transaction.
- **Usage**:
- Deliver a transaction to be executed in full by the application. If the transaction is valid,
returns CodeType.OK.
@ -222,6 +271,7 @@ EndBlock
- Signals the end of a block.
- Called prior to each Commit, after all transactions.
- Validator set and consensus params are updated with the result.
- Validator pubkeys are expected to be go-wire encoded.
Commit
^^^^^^


+ 2
- 2
tests/client_server_test.go View File

@ -6,14 +6,14 @@ import (
"github.com/stretchr/testify/assert"
abciclient "github.com/tendermint/abci/client"
"github.com/tendermint/abci/example/dummy"
"github.com/tendermint/abci/example/kvstore"
abciserver "github.com/tendermint/abci/server"
)
func TestClientServerNoAddrPrefix(t *testing.T) {
addr := "localhost:46658"
transport := "socket"
app := dummy.NewDummyApplication()
app := kvstore.NewKVStoreApplication()
server, err := abciserver.NewServer(addr, transport, app)
assert.NoError(t, err, "expected no error on NewServer")


+ 1
- 1
tests/server/client.go View File

@ -34,7 +34,7 @@ func SetOption(client abcicli.Client, key, value string) error {
_, err := client.SetOptionSync(types.RequestSetOption{Key: key, Value: value})
if err != nil {
fmt.Println("Failed test: SetOption")
fmt.Printf("error while setting %v=%v: \nerror: %v\n", key, value)
fmt.Printf("error while setting %v=%v: \nerror: %v\n", key, value, err)
return err
}
fmt.Println("Passed test: SetOption")


+ 1
- 1
tests/test_cli/test.sh View File

@ -35,7 +35,7 @@ function testExample() {
rm "${INPUT}".out.new
}
testExample 1 tests/test_cli/ex1.abci abci-cli dummy
testExample 1 tests/test_cli/ex1.abci abci-cli kvstore
testExample 2 tests/test_cli/ex2.abci abci-cli counter
echo ""


+ 3
- 1
types/messages_test.go View File

@ -21,7 +21,9 @@ func TestMarshalJSON(t *testing.T) {
Code: 1,
Data: []byte("hello"),
GasWanted: 43,
Fee: cmn.KI64Pair{[]byte("pho"), 12},
Tags: []cmn.KVPair{
{[]byte("pho"), []byte("bo")},
},
}
b, err = json.Marshal(&r1)
assert.Nil(t, err)


+ 143
- 128
types/types.pb.go View File

@ -1327,14 +1327,14 @@ func (*ResponseBeginBlock) ProtoMessage() {}
func (*ResponseBeginBlock) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{20} }
type ResponseCheckTx struct {
Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
Log string `protobuf:"bytes,3,opt,name=log,proto3" json:"log,omitempty"`
Info string `protobuf:"bytes,4,opt,name=info,proto3" json:"info,omitempty"`
GasWanted int64 `protobuf:"varint,5,opt,name=gas_wanted,json=gasWanted,proto3" json:"gas_wanted,omitempty"`
// int64 gas_used = 6;
Tags []common.KVPair `protobuf:"bytes,7,rep,name=tags" json:"tags,omitempty"`
Fee common.KI64Pair `protobuf:"bytes,8,opt,name=fee" json:"fee"`
Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
Log string `protobuf:"bytes,3,opt,name=log,proto3" json:"log,omitempty"`
Info string `protobuf:"bytes,4,opt,name=info,proto3" json:"info,omitempty"`
GasWanted int64 `protobuf:"varint,5,opt,name=gas_wanted,json=gasWanted,proto3" json:"gas_wanted,omitempty"`
GasUsed int64 `protobuf:"varint,6,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"`
Tags []common.KVPair `protobuf:"bytes,7,rep,name=tags" json:"tags,omitempty"`
Fee *common.KI64Pair `protobuf:"bytes,8,opt,name=fee" json:"fee,omitempty"`
}
func (m *ResponseCheckTx) Reset() { *m = ResponseCheckTx{} }
@ -1377,6 +1377,13 @@ func (m *ResponseCheckTx) GetGasWanted() int64 {
return 0
}
func (m *ResponseCheckTx) GetGasUsed() int64 {
if m != nil {
return m.GasUsed
}
return 0
}
func (m *ResponseCheckTx) GetTags() []common.KVPair {
if m != nil {
return m.Tags
@ -1384,21 +1391,22 @@ func (m *ResponseCheckTx) GetTags() []common.KVPair {
return nil
}
func (m *ResponseCheckTx) GetFee() common.KI64Pair {
func (m *ResponseCheckTx) GetFee() *common.KI64Pair {
if m != nil {
return m.Fee
}
return common.KI64Pair{}
return nil
}
type ResponseDeliverTx struct {
Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
Log string `protobuf:"bytes,3,opt,name=log,proto3" json:"log,omitempty"`
Info string `protobuf:"bytes,4,opt,name=info,proto3" json:"info,omitempty"`
GasWanted int64 `protobuf:"varint,5,opt,name=gas_wanted,json=gasWanted,proto3" json:"gas_wanted,omitempty"`
GasUsed int64 `protobuf:"varint,6,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"`
Tags []common.KVPair `protobuf:"bytes,7,rep,name=tags" json:"tags,omitempty"`
Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
Log string `protobuf:"bytes,3,opt,name=log,proto3" json:"log,omitempty"`
Info string `protobuf:"bytes,4,opt,name=info,proto3" json:"info,omitempty"`
GasWanted int64 `protobuf:"varint,5,opt,name=gas_wanted,json=gasWanted,proto3" json:"gas_wanted,omitempty"`
GasUsed int64 `protobuf:"varint,6,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"`
Tags []common.KVPair `protobuf:"bytes,7,rep,name=tags" json:"tags,omitempty"`
Fee *common.KI64Pair `protobuf:"bytes,8,opt,name=fee" json:"fee,omitempty"`
}
func (m *ResponseDeliverTx) Reset() { *m = ResponseDeliverTx{} }
@ -1455,6 +1463,13 @@ func (m *ResponseDeliverTx) GetTags() []common.KVPair {
return nil
}
func (m *ResponseDeliverTx) GetFee() *common.KI64Pair {
if m != nil {
return m.Fee
}
return nil
}
type ResponseEndBlock struct {
ValidatorUpdates []Validator `protobuf:"bytes,1,rep,name=validator_updates,json=validatorUpdates" json:"validator_updates"`
ConsensusParamUpdates *ConsensusParams `protobuf:"bytes,2,opt,name=consensus_param_updates,json=consensusParamUpdates" json:"consensus_param_updates,omitempty"`
@ -2225,115 +2240,115 @@ var _ABCIApplication_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("types/types.proto", fileDescriptorTypes) }
var fileDescriptorTypes = []byte{
// 1759 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xdd, 0x6e, 0x1b, 0xb9,
0x15, 0xb6, 0xfe, 0x35, 0x47, 0xb6, 0x64, 0xd3, 0x4e, 0xa2, 0x68, 0x51, 0xc4, 0x18, 0x14, 0x59,
0xa5, 0xc9, 0x5a, 0xad, 0xb7, 0x09, 0x92, 0x6c, 0xb1, 0x68, 0x64, 0xa7, 0x91, 0xb0, 0x6d, 0x37,
0x9d, 0x64, 0x53, 0xa0, 0x37, 0x02, 0xa5, 0xa1, 0xa5, 0x41, 0x34, 0x3f, 0x3b, 0xa4, 0xbc, 0x72,
0x9e, 0x61, 0xef, 0x7b, 0xdd, 0xab, 0x3e, 0x41, 0x5f, 0xa1, 0x68, 0xd1, 0x07, 0xe8, 0x9d, 0x2f,
0x16, 0xbd, 0xea, 0x53, 0x14, 0x87, 0xe4, 0xfc, 0x7a, 0x66, 0xb1, 0x68, 0x81, 0xde, 0x48, 0x3c,
0x3c, 0xdf, 0x21, 0x79, 0xc8, 0xc3, 0xef, 0x9c, 0x21, 0x1c, 0x88, 0xab, 0x80, 0xf1, 0x91, 0xfc,
0x3d, 0x09, 0x42, 0x5f, 0xf8, 0xa4, 0x21, 0x85, 0xc1, 0x27, 0x4b, 0x47, 0xac, 0x36, 0xf3, 0x93,
0x85, 0xef, 0x8e, 0x96, 0xfe, 0xd2, 0x1f, 0x49, 0xed, 0x7c, 0x73, 0x21, 0x25, 0x29, 0xc8, 0x96,
0xb2, 0x1a, 0x8c, 0x52, 0x70, 0xc1, 0x3c, 0x9b, 0x85, 0xae, 0xe3, 0x89, 0x91, 0x70, 0xd7, 0xce,
0x9c, 0x8f, 0x16, 0xbe, 0xeb, 0xfa, 0x5e, 0x7a, 0x1a, 0xf3, 0xaf, 0x75, 0x68, 0x59, 0xec, 0xeb,
0x0d, 0xe3, 0x82, 0x0c, 0xa1, 0xce, 0x16, 0x2b, 0xbf, 0x5f, 0x3d, 0xae, 0x0c, 0x3b, 0xa7, 0xe4,
0x44, 0xe1, 0xb4, 0xf6, 0xe5, 0x62, 0xe5, 0x4f, 0x76, 0x2c, 0x89, 0x20, 0x0f, 0xa1, 0x71, 0xb1,
0xde, 0xf0, 0x55, 0xbf, 0x26, 0xa1, 0x87, 0x59, 0xe8, 0xaf, 0x50, 0x35, 0xd9, 0xb1, 0x14, 0x06,
0x87, 0x75, 0xbc, 0x0b, 0xbf, 0x5f, 0x2f, 0x1a, 0x76, 0xea, 0x5d, 0xc8, 0x61, 0x11, 0x41, 0x9e,
0x02, 0x70, 0x26, 0x66, 0x7e, 0x20, 0x1c, 0xdf, 0xeb, 0x37, 0x24, 0xfe, 0x4e, 0x16, 0xff, 0x86,
0x89, 0x2f, 0xa5, 0x7a, 0xb2, 0x63, 0x19, 0x3c, 0x12, 0xd0, 0xd2, 0xf1, 0x1c, 0x31, 0x5b, 0xac,
0xa8, 0xe3, 0xf5, 0x9b, 0x45, 0x96, 0x53, 0xcf, 0x11, 0x67, 0xa8, 0x46, 0x4b, 0x27, 0x12, 0xd0,
0x95, 0xaf, 0x37, 0x2c, 0xbc, 0xea, 0xb7, 0x8a, 0x5c, 0xf9, 0x1d, 0xaa, 0xd0, 0x15, 0x89, 0x21,
0x9f, 0x41, 0x67, 0xce, 0x96, 0x8e, 0x37, 0x9b, 0xaf, 0xfd, 0xc5, 0xfb, 0x7e, 0x5b, 0x9a, 0xf4,
0xb3, 0x26, 0x63, 0x04, 0x8c, 0x51, 0x3f, 0xd9, 0xb1, 0x60, 0x1e, 0x4b, 0xe4, 0x14, 0xda, 0x8b,
0x15, 0x5b, 0xbc, 0x9f, 0x89, 0x6d, 0xdf, 0x90, 0x96, 0xb7, 0xb2, 0x96, 0x67, 0xa8, 0x7d, 0xbb,
0x9d, 0xec, 0x58, 0xad, 0x85, 0x6a, 0xa2, 0x5f, 0x36, 0x5b, 0x3b, 0x97, 0x2c, 0x44, 0xab, 0xc3,
0x22, 0xbf, 0xce, 0x95, 0x5e, 0xda, 0x19, 0x76, 0x24, 0x90, 0xc7, 0x60, 0x30, 0xcf, 0xd6, 0x0b,
0xed, 0x48, 0xc3, 0xdb, 0xb9, 0x13, 0xf5, 0xec, 0x68, 0x99, 0x6d, 0xa6, 0xdb, 0xe4, 0x04, 0x9a,
0x18, 0x25, 0x8e, 0xe8, 0xef, 0x4a, 0x9b, 0xa3, 0xdc, 0x12, 0xa5, 0x6e, 0xb2, 0x63, 0x69, 0xd4,
0xb8, 0x05, 0x8d, 0x4b, 0xba, 0xde, 0x30, 0xf3, 0x63, 0xe8, 0xa4, 0x22, 0x85, 0xf4, 0xa1, 0xe5,
0x32, 0xce, 0xe9, 0x92, 0xf5, 0x2b, 0xc7, 0x95, 0xa1, 0x61, 0x45, 0xa2, 0xd9, 0x85, 0xdd, 0x74,
0x9c, 0xa4, 0x0c, 0x31, 0x16, 0xd0, 0xf0, 0x92, 0x85, 0x1c, 0x03, 0x40, 0x1b, 0x6a, 0xd1, 0x7c,
0x0e, 0xfb, 0xf9, 0x20, 0x20, 0xfb, 0x50, 0x7b, 0xcf, 0xae, 0x34, 0x12, 0x9b, 0xe4, 0x48, 0x2f,
0x48, 0x46, 0xb1, 0x61, 0xe9, 0xd5, 0x85, 0xb1, 0x6d, 0x1c, 0x06, 0xe4, 0x09, 0xc0, 0x25, 0x5d,
0x3b, 0x36, 0x15, 0x7e, 0xc8, 0xfb, 0x95, 0xe3, 0xda, 0xb0, 0x73, 0xba, 0xaf, 0xdd, 0x7d, 0x17,
0x29, 0xc6, 0xf5, 0xbf, 0x5d, 0xdf, 0xdb, 0xb1, 0x52, 0x48, 0x72, 0x1f, 0x7a, 0x34, 0x08, 0x66,
0x5c, 0x50, 0xc1, 0x66, 0xf3, 0x2b, 0xc1, 0xb8, 0x9c, 0x6b, 0xd7, 0xda, 0xa3, 0x41, 0xf0, 0x06,
0x7b, 0xc7, 0xd8, 0x69, 0xda, 0xb1, 0xa3, 0x32, 0x8a, 0x08, 0x81, 0xba, 0x4d, 0x05, 0x95, 0x8b,
0xdd, 0xb5, 0x64, 0x1b, 0xfb, 0x02, 0x2a, 0x56, 0x7a, 0xb1, 0xb2, 0x4d, 0x6e, 0x43, 0x73, 0xc5,
0x9c, 0xe5, 0x4a, 0xc8, 0xdb, 0x55, 0xb3, 0xb4, 0x84, 0x9e, 0x05, 0xa1, 0x7f, 0xc9, 0xe4, 0x45,
0x6a, 0x5b, 0x4a, 0x30, 0xff, 0x51, 0x81, 0x83, 0x1b, 0x91, 0x87, 0xe3, 0xae, 0x28, 0x5f, 0x45,
0x73, 0x61, 0x9b, 0x3c, 0xc4, 0x71, 0xa9, 0xcd, 0x42, 0x7d, 0xc1, 0xf7, 0xb4, 0xaf, 0x13, 0xd9,
0xa9, 0x1d, 0xd5, 0x10, 0xf2, 0x10, 0x0e, 0xe8, 0x9c, 0x33, 0x4f, 0xcc, 0x52, 0x7b, 0x54, 0x3b,
0xae, 0x0d, 0x1b, 0xd6, 0xbe, 0x52, 0xbc, 0x4b, 0x76, 0x64, 0x02, 0x47, 0xf3, 0xab, 0x0f, 0xd4,
0x13, 0x8e, 0xc7, 0xd2, 0xf8, 0xba, 0xdc, 0xd3, 0x9e, 0x9e, 0xe7, 0xe5, 0xa5, 0x63, 0x33, 0x6f,
0xc1, 0xf4, 0x4c, 0x87, 0xb1, 0x49, 0x32, 0x92, 0x79, 0x0c, 0xdd, 0xec, 0x65, 0x20, 0x5d, 0xa8,
0x8a, 0xad, 0xf6, 0xa3, 0x2a, 0xb6, 0xa6, 0x19, 0x9f, 0x64, 0x1c, 0xf8, 0x37, 0x30, 0x0f, 0xa0,
0x97, 0x8b, 0xf1, 0xd4, 0xa6, 0x56, 0xd2, 0x9b, 0x6a, 0xf6, 0x60, 0x2f, 0x13, 0xda, 0xe6, 0xb7,
0x0d, 0x68, 0x5b, 0x8c, 0x07, 0xbe, 0xc7, 0x19, 0x79, 0x0a, 0x06, 0xdb, 0x2e, 0x98, 0xe2, 0xa3,
0x4a, 0xee, 0xb6, 0x2b, 0xcc, 0xcb, 0x48, 0x8f, 0xd7, 0x2f, 0x06, 0x93, 0x07, 0x19, 0x2e, 0x3d,
0xcc, 0x1b, 0xa5, 0xc9, 0xf4, 0x51, 0x96, 0x4c, 0x8f, 0x72, 0xd8, 0x1c, 0x9b, 0x3e, 0xc8, 0xb0,
0x69, 0x7e, 0xe0, 0x0c, 0x9d, 0x3e, 0x2b, 0xa0, 0xd3, 0xfc, 0xf2, 0x4b, 0xf8, 0xf4, 0x59, 0x01,
0x9f, 0xf6, 0x6f, 0xcc, 0x55, 0x48, 0xa8, 0x8f, 0xb2, 0x84, 0x9a, 0x77, 0x27, 0xc7, 0xa8, 0xbf,
0x28, 0x62, 0xd4, 0xbb, 0x39, 0x9b, 0x52, 0x4a, 0xfd, 0xf4, 0x06, 0xa5, 0xde, 0xce, 0x99, 0x16,
0x70, 0xea, 0xb3, 0x0c, 0xa7, 0x42, 0xa1, 0x6f, 0x25, 0xa4, 0xfa, 0xe4, 0x26, 0xa9, 0xde, 0xc9,
0x1f, 0x6d, 0x11, 0xab, 0x8e, 0x72, 0xac, 0x7a, 0x2b, 0xbf, 0xca, 0x52, 0x5a, 0x7d, 0x80, 0xb7,
0x3b, 0x17, 0x69, 0xc8, 0x04, 0x2c, 0x0c, 0xfd, 0x50, 0xf3, 0x9e, 0x12, 0xcc, 0x21, 0xf2, 0x4d,
0x12, 0x5f, 0xdf, 0x43, 0xc1, 0x32, 0xe8, 0x53, 0xd1, 0x65, 0xfe, 0xb1, 0x92, 0xd8, 0x4a, 0x16,
0x4e, 0x73, 0x95, 0xa1, 0xb9, 0x2a, 0xc5, 0xcc, 0xd5, 0x0c, 0x33, 0x93, 0x9f, 0xc0, 0xc1, 0x9a,
0x72, 0xa1, 0xf6, 0x65, 0x96, 0x21, 0xaf, 0x1e, 0x2a, 0xd4, 0x86, 0x28, 0x16, 0xfb, 0x04, 0x0e,
0x53, 0x58, 0x24, 0x52, 0x49, 0x54, 0x75, 0x79, 0x79, 0xf7, 0x63, 0xf4, 0x8b, 0x20, 0x98, 0x50,
0xbe, 0x32, 0x7f, 0x93, 0xf8, 0x9f, 0xb0, 0x3e, 0x81, 0xfa, 0xc2, 0xb7, 0x95, 0x5b, 0x7b, 0x96,
0x6c, 0x63, 0x26, 0x58, 0xfb, 0x4b, 0x39, 0xab, 0x61, 0x61, 0x13, 0x51, 0xf1, 0x4d, 0x31, 0xd4,
0x95, 0x30, 0x0f, 0x93, 0xe1, 0xe2, 0xf0, 0x35, 0xff, 0x52, 0x49, 0xf6, 0x23, 0xa6, 0xea, 0xff,
0x6e, 0x02, 0x3c, 0x1a, 0xc7, 0xb3, 0xd9, 0x56, 0x5e, 0xb7, 0x9a, 0xa5, 0x84, 0x28, 0x4d, 0x35,
0xa5, 0x93, 0xd9, 0x34, 0xd5, 0x92, 0x7d, 0x4a, 0xd0, 0x14, 0xef, 0x5f, 0xc8, 0x7b, 0xb0, 0x6b,
0x29, 0x21, 0xc5, 0x5d, 0x46, 0x86, 0xbb, 0x8e, 0x80, 0xdc, 0xbc, 0x21, 0xe6, 0xbf, 0x2a, 0xc8,
0x7e, 0x99, 0xe8, 0x2f, 0xf4, 0x27, 0x3a, 0xe2, 0x6a, 0x2a, 0x1d, 0xfd, 0x30, 0x1f, 0x7f, 0x04,
0xb0, 0xa4, 0x7c, 0xf6, 0x0d, 0xf5, 0x04, 0xb3, 0xb5, 0xa3, 0xc6, 0x92, 0xf2, 0xdf, 0xcb, 0x0e,
0xf2, 0x1c, 0xea, 0x82, 0x2e, 0x79, 0xbf, 0x25, 0xd9, 0xbf, 0x7b, 0xa2, 0xaa, 0xce, 0x93, 0x2f,
0xde, 0xbd, 0xa6, 0x4e, 0x38, 0xbe, 0x8d, 0xe4, 0xff, 0xef, 0xeb, 0x7b, 0x5d, 0xc4, 0x3c, 0xf2,
0x5d, 0x47, 0x30, 0x37, 0x10, 0x57, 0x96, 0xb4, 0x21, 0x43, 0xa8, 0x5d, 0x30, 0xa6, 0x69, 0x60,
0x3f, 0x36, 0x9d, 0x3e, 0xf9, 0xb9, 0x34, 0x56, 0x99, 0x03, 0x21, 0xe6, 0x3f, 0x2b, 0xc9, 0x51,
0x26, 0x99, 0xe0, 0xff, 0xea, 0xe8, 0x5d, 0x68, 0xa3, 0x7a, 0xc3, 0x99, 0x2d, 0x8f, 0xb6, 0x66,
0xb5, 0x96, 0x94, 0x7f, 0xc5, 0xff, 0xb7, 0x3d, 0x30, 0xff, 0x5c, 0xc1, 0x14, 0x97, 0x65, 0x13,
0x72, 0x06, 0x07, 0x71, 0x62, 0x9d, 0x6d, 0x02, 0x9b, 0x62, 0xd9, 0xf1, 0xfd, 0x35, 0xcb, 0x7e,
0x6c, 0xf0, 0x95, 0xc2, 0x93, 0xdf, 0xc2, 0x9d, 0x05, 0x8e, 0xea, 0xf1, 0x0d, 0x9f, 0x05, 0x34,
0xa4, 0x6e, 0x3c, 0x54, 0x35, 0xc3, 0x9e, 0x67, 0x11, 0xea, 0x35, 0x82, 0xb8, 0x75, 0x6b, 0x91,
0xe9, 0xd0, 0xe3, 0x99, 0x3f, 0xc6, 0x6c, 0x9d, 0x66, 0xb0, 0xa2, 0xbd, 0x36, 0xff, 0x54, 0x81,
0x5e, 0x6e, 0x40, 0x32, 0x02, 0x50, 0x04, 0xc0, 0x9d, 0x0f, 0x4c, 0x67, 0xd6, 0xc8, 0x0f, 0xe9,
0xf0, 0x1b, 0xe7, 0x03, 0xb3, 0x8c, 0x79, 0xd4, 0x24, 0xf7, 0xa1, 0x25, 0xb6, 0x0a, 0x9d, 0xad,
0x5e, 0xde, 0x6e, 0x25, 0xb4, 0x29, 0xe4, 0x3f, 0x79, 0x0c, 0xbb, 0x6a, 0xe0, 0xa5, 0xcf, 0xb9,
0x13, 0xe8, 0x9c, 0x4a, 0xd2, 0x43, 0xbf, 0x92, 0x1a, 0xab, 0x33, 0x4f, 0x04, 0xf3, 0x0f, 0x60,
0xc4, 0xd3, 0x92, 0x8f, 0xc0, 0x70, 0xe9, 0x56, 0x97, 0x76, 0xb8, 0xb6, 0x86, 0xd5, 0x76, 0xe9,
0x56, 0x56, 0x75, 0xe4, 0x0e, 0xb4, 0x50, 0x29, 0xb6, 0x6a, 0xcf, 0x1a, 0x56, 0xd3, 0xa5, 0xdb,
0xb7, 0xdb, 0x58, 0xb1, 0xa4, 0x3c, 0xaa, 0xdb, 0x5c, 0xba, 0x7d, 0x45, 0xb9, 0xf9, 0x39, 0x34,
0xd5, 0x22, 0x7f, 0xd0, 0xc0, 0x68, 0x5f, 0xcd, 0xd8, 0xff, 0x12, 0x3a, 0xa9, 0x75, 0x93, 0x9f,
0xc1, 0x2d, 0xe5, 0x61, 0x40, 0x43, 0x21, 0x77, 0x24, 0x33, 0x20, 0x91, 0xca, 0xd7, 0x34, 0x14,
0x38, 0xa5, 0xaa, 0x44, 0xff, 0x5e, 0x85, 0xa6, 0xaa, 0xf2, 0xc8, 0x7d, 0xcc, 0x98, 0xd4, 0xf1,
0x66, 0x8e, 0xad, 0xc8, 0x7d, 0xdc, 0xf9, 0xee, 0xfa, 0x5e, 0x4b, 0x12, 0xe1, 0xf4, 0x1c, 0x93,
0x24, 0x36, 0xec, 0x14, 0xe7, 0x54, 0x33, 0x45, 0x28, 0x81, 0xba, 0x70, 0x5c, 0xa6, 0x5d, 0x94,
0x6d, 0x5c, 0xb9, 0xb7, 0x71, 0xe5, 0x96, 0xd4, 0xd5, 0x96, 0x78, 0x1b, 0x17, 0xb7, 0xe4, 0x15,
0xec, 0xa5, 0xb8, 0xde, 0xb1, 0x75, 0x0d, 0xd2, 0x4d, 0x9f, 0xc6, 0xf4, 0x7c, 0x7c, 0x88, 0xe1,
0xfa, 0xdd, 0xf5, 0xbd, 0xce, 0xaf, 0x23, 0xf6, 0x9f, 0x9e, 0x5b, 0x9d, 0x38, 0x15, 0x4c, 0x6d,
0x32, 0x04, 0x99, 0x19, 0x66, 0x2a, 0x3b, 0xaa, 0x8c, 0xa1, 0xc8, 0xb4, 0x8b, 0xfd, 0x3a, 0x7d,
0x62, 0x91, 0xfb, 0x11, 0x18, 0x18, 0x74, 0x0a, 0xa2, 0xb8, 0xb5, 0x8d, 0x1d, 0x52, 0xf9, 0x31,
0xf4, 0x92, 0xea, 0x54, 0x41, 0x14, 0xd1, 0x76, 0x93, 0x6e, 0x09, 0xbc, 0x0b, 0xed, 0x38, 0x33,
0x19, 0x12, 0xd1, 0xa2, 0x3a, 0x21, 0x7d, 0x09, 0x2d, 0xbd, 0xc4, 0xc2, 0x22, 0xfb, 0xa7, 0xd0,
0xc0, 0x73, 0x89, 0x2e, 0x54, 0x54, 0xfd, 0xc8, 0xf3, 0x60, 0x22, 0x53, 0x6a, 0x2b, 0xa0, 0xf9,
0x0c, 0xf6, 0x32, 0x5a, 0x4c, 0x02, 0xc2, 0x17, 0x74, 0xad, 0x0f, 0x54, 0x09, 0xf1, 0x64, 0xd5,
0x64, 0x32, 0xf3, 0x39, 0x18, 0xf1, 0xa5, 0xc7, 0x53, 0x08, 0x36, 0xf3, 0x59, 0xf4, 0x39, 0xb4,
0x6b, 0x35, 0x83, 0xcd, 0xfc, 0x0b, 0x95, 0x6a, 0x02, 0xff, 0x1b, 0x5d, 0xf6, 0xd7, 0x2c, 0x25,
0x98, 0x9f, 0x41, 0x3b, 0x2a, 0xc8, 0xcb, 0x4d, 0x4b, 0xa2, 0xe0, 0xf4, 0xdb, 0x06, 0xf4, 0x5e,
0x8c, 0xcf, 0xa6, 0x2f, 0x82, 0x60, 0xed, 0x2c, 0xa8, 0x4c, 0xca, 0x23, 0xa8, 0xcb, 0xb2, 0xa3,
0xe0, 0xdd, 0x60, 0x50, 0x54, 0xff, 0x92, 0x53, 0x68, 0xc8, 0xea, 0x83, 0x14, 0x3d, 0x1f, 0x0c,
0x0a, 0xcb, 0x60, 0x9c, 0x44, 0xd5, 0x27, 0x37, 0x5f, 0x11, 0x06, 0x45, 0xb5, 0x30, 0xf9, 0x1c,
0x8c, 0xa4, 0x6e, 0x28, 0x7b, 0x4b, 0x18, 0x94, 0x56, 0xc5, 0x68, 0x9f, 0x64, 0x97, 0xb2, 0x2f,
0xef, 0x41, 0x69, 0xf9, 0x48, 0x9e, 0x42, 0x2b, 0x4a, 0xc2, 0xc5, 0x5f, 0xfb, 0x83, 0x92, 0x8a,
0x15, 0xb7, 0x47, 0x15, 0x23, 0x45, 0x4f, 0x12, 0x83, 0xc2, 0xb2, 0x9a, 0x3c, 0x86, 0xa6, 0x26,
0xe2, 0xc2, 0xef, 0xf6, 0x41, 0x71, 0xdd, 0x89, 0x4e, 0x26, 0x9f, 0xc5, 0x65, 0xcf, 0x26, 0x83,
0xd2, 0xfa, 0x9f, 0xbc, 0x00, 0x48, 0x7d, 0x7b, 0x96, 0xbe, 0x87, 0x0c, 0xca, 0xeb, 0x7a, 0x82,
0xe1, 0x18, 0x7f, 0xab, 0x15, 0xbf, 0x53, 0x0c, 0xca, 0x4a, 0xed, 0x79, 0x53, 0xbe, 0x65, 0x7d,
0xfa, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x11, 0xd7, 0x9f, 0xcd, 0x47, 0x13, 0x00, 0x00,
// 1756 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x58, 0xcd, 0x6e, 0x1b, 0xc9,
0x11, 0x16, 0xff, 0x39, 0x45, 0x89, 0x94, 0x5a, 0xb2, 0x4d, 0x73, 0x11, 0x58, 0x18, 0x04, 0x5e,
0x39, 0xf6, 0x8a, 0x89, 0x36, 0x36, 0x2c, 0x6f, 0xb0, 0x88, 0x28, 0x39, 0x26, 0xb1, 0x49, 0xd6,
0x19, 0x7b, 0x1d, 0x20, 0x17, 0xa2, 0xc9, 0x69, 0x91, 0x03, 0x73, 0x7e, 0x76, 0xba, 0xa9, 0xa5,
0xfc, 0x0c, 0x7b, 0xcf, 0x39, 0xa7, 0x3c, 0x41, 0x5e, 0x21, 0x48, 0x90, 0x77, 0xd0, 0x61, 0x8f,
0x79, 0x83, 0x20, 0x97, 0xa0, 0xba, 0x7b, 0x7e, 0x35, 0xb3, 0x58, 0xe4, 0xba, 0x17, 0xb2, 0xab,
0xeb, 0xab, 0xee, 0xae, 0xee, 0xea, 0xaf, 0x6a, 0x1a, 0xf6, 0xc4, 0x75, 0xc0, 0xf8, 0x50, 0xfe,
0x1e, 0x07, 0xa1, 0x2f, 0x7c, 0xd2, 0x90, 0xc2, 0xe0, 0x93, 0x85, 0x23, 0x96, 0xeb, 0xd9, 0xf1,
0xdc, 0x77, 0x87, 0x0b, 0x7f, 0xe1, 0x0f, 0xa5, 0x76, 0xb6, 0xbe, 0x94, 0x92, 0x14, 0x64, 0x4b,
0x59, 0x0d, 0x86, 0x29, 0xb8, 0x60, 0x9e, 0xcd, 0x42, 0xd7, 0xf1, 0xc4, 0x50, 0xb8, 0x2b, 0x67,
0xc6, 0x87, 0x73, 0xdf, 0x75, 0x7d, 0x2f, 0x3d, 0x8d, 0xf9, 0xf7, 0x3a, 0xb4, 0x2c, 0xf6, 0xf5,
0x9a, 0x71, 0x41, 0x8e, 0xa0, 0xce, 0xe6, 0x4b, 0xbf, 0x5f, 0x3d, 0xac, 0x1c, 0x75, 0x4e, 0xc8,
0xb1, 0xc2, 0x69, 0xed, 0xcb, 0xf9, 0xd2, 0x1f, 0x6f, 0x59, 0x12, 0x41, 0x1e, 0x43, 0xe3, 0x72,
0xb5, 0xe6, 0xcb, 0x7e, 0x4d, 0x42, 0xf7, 0xb3, 0xd0, 0xdf, 0xa0, 0x6a, 0xbc, 0x65, 0x29, 0x0c,
0x0e, 0xeb, 0x78, 0x97, 0x7e, 0xbf, 0x5e, 0x34, 0xec, 0xc4, 0xbb, 0x94, 0xc3, 0x22, 0x82, 0x3c,
0x07, 0xe0, 0x4c, 0x4c, 0xfd, 0x40, 0x38, 0xbe, 0xd7, 0x6f, 0x48, 0xfc, 0xbd, 0x2c, 0xfe, 0x0d,
0x13, 0x5f, 0x4a, 0xf5, 0x78, 0xcb, 0x32, 0x78, 0x24, 0xa0, 0xa5, 0xe3, 0x39, 0x62, 0x3a, 0x5f,
0x52, 0xc7, 0xeb, 0x37, 0x8b, 0x2c, 0x27, 0x9e, 0x23, 0xce, 0x51, 0x8d, 0x96, 0x4e, 0x24, 0xa0,
0x2b, 0x5f, 0xaf, 0x59, 0x78, 0xdd, 0x6f, 0x15, 0xb9, 0xf2, 0x07, 0x54, 0xa1, 0x2b, 0x12, 0x43,
0x3e, 0x83, 0xce, 0x8c, 0x2d, 0x1c, 0x6f, 0x3a, 0x5b, 0xf9, 0xf3, 0xf7, 0xfd, 0xb6, 0x34, 0xe9,
0x67, 0x4d, 0x46, 0x08, 0x18, 0xa1, 0x7e, 0xbc, 0x65, 0xc1, 0x2c, 0x96, 0xc8, 0x09, 0xb4, 0xe7,
0x4b, 0x36, 0x7f, 0x3f, 0x15, 0x9b, 0xbe, 0x21, 0x2d, 0xef, 0x64, 0x2d, 0xcf, 0x51, 0xfb, 0x76,
0x33, 0xde, 0xb2, 0x5a, 0x73, 0xd5, 0x44, 0xbf, 0x6c, 0xb6, 0x72, 0xae, 0x58, 0x88, 0x56, 0xfb,
0x45, 0x7e, 0x5d, 0x28, 0xbd, 0xb4, 0x33, 0xec, 0x48, 0x20, 0x4f, 0xc1, 0x60, 0x9e, 0xad, 0x17,
0xda, 0x91, 0x86, 0x77, 0x73, 0x27, 0xea, 0xd9, 0xd1, 0x32, 0xdb, 0x4c, 0xb7, 0xc9, 0x31, 0x34,
0x31, 0x4a, 0x1c, 0xd1, 0xdf, 0x96, 0x36, 0x07, 0xb9, 0x25, 0x4a, 0xdd, 0x78, 0xcb, 0xd2, 0xa8,
0x51, 0x0b, 0x1a, 0x57, 0x74, 0xb5, 0x66, 0xe6, 0xc7, 0xd0, 0x49, 0x45, 0x0a, 0xe9, 0x43, 0xcb,
0x65, 0x9c, 0xd3, 0x05, 0xeb, 0x57, 0x0e, 0x2b, 0x47, 0x86, 0x15, 0x89, 0x66, 0x17, 0xb6, 0xd3,
0x71, 0x92, 0x32, 0xc4, 0x58, 0x40, 0xc3, 0x2b, 0x16, 0x72, 0x0c, 0x00, 0x6d, 0xa8, 0x45, 0xf3,
0x05, 0xec, 0xe6, 0x83, 0x80, 0xec, 0x42, 0xed, 0x3d, 0xbb, 0xd6, 0x48, 0x6c, 0x92, 0x03, 0xbd,
0x20, 0x19, 0xc5, 0x86, 0xa5, 0x57, 0x17, 0xc6, 0xb6, 0x71, 0x18, 0x90, 0x67, 0x00, 0x57, 0x74,
0xe5, 0xd8, 0x54, 0xf8, 0x21, 0xef, 0x57, 0x0e, 0x6b, 0x47, 0x9d, 0x93, 0x5d, 0xed, 0xee, 0xbb,
0x48, 0x31, 0xaa, 0xff, 0xe3, 0xe6, 0xc1, 0x96, 0x95, 0x42, 0x92, 0x87, 0xd0, 0xa3, 0x41, 0x30,
0xe5, 0x82, 0x0a, 0x36, 0x9d, 0x5d, 0x0b, 0xc6, 0xe5, 0x5c, 0xdb, 0xd6, 0x0e, 0x0d, 0x82, 0x37,
0xd8, 0x3b, 0xc2, 0x4e, 0xd3, 0x8e, 0x1d, 0x95, 0x51, 0x44, 0x08, 0xd4, 0x6d, 0x2a, 0xa8, 0x5c,
0xec, 0xb6, 0x25, 0xdb, 0xd8, 0x17, 0x50, 0xb1, 0xd4, 0x8b, 0x95, 0x6d, 0x72, 0x17, 0x9a, 0x4b,
0xe6, 0x2c, 0x96, 0x42, 0xde, 0xae, 0x9a, 0xa5, 0x25, 0xf4, 0x2c, 0x08, 0xfd, 0x2b, 0x26, 0x2f,
0x52, 0xdb, 0x52, 0x82, 0xf9, 0xaf, 0x0a, 0xec, 0xdd, 0x8a, 0x3c, 0x1c, 0x77, 0x49, 0xf9, 0x32,
0x9a, 0x0b, 0xdb, 0xe4, 0x31, 0x8e, 0x4b, 0x6d, 0x16, 0xea, 0x0b, 0xbe, 0xa3, 0x7d, 0x1d, 0xcb,
0x4e, 0xed, 0xa8, 0x86, 0x90, 0xc7, 0xb0, 0x47, 0x67, 0x9c, 0x79, 0x62, 0x9a, 0xda, 0xa3, 0xda,
0x61, 0xed, 0xa8, 0x61, 0xed, 0x2a, 0xc5, 0xbb, 0x64, 0x47, 0xc6, 0x70, 0x30, 0xbb, 0xfe, 0x40,
0x3d, 0xe1, 0x78, 0x2c, 0x8d, 0xaf, 0xcb, 0x3d, 0xed, 0xe9, 0x79, 0x5e, 0x5e, 0x39, 0x36, 0xf3,
0xe6, 0x4c, 0xcf, 0xb4, 0x1f, 0x9b, 0x24, 0x23, 0x99, 0x87, 0xd0, 0xcd, 0x5e, 0x06, 0xd2, 0x85,
0xaa, 0xd8, 0x68, 0x3f, 0xaa, 0x62, 0x63, 0x9a, 0xf1, 0x49, 0xc6, 0x81, 0x7f, 0x0b, 0xf3, 0x08,
0x7a, 0xb9, 0x18, 0x4f, 0x6d, 0x6a, 0x25, 0xbd, 0xa9, 0x66, 0x0f, 0x76, 0x32, 0xa1, 0x6d, 0x7e,
0xdb, 0x80, 0xb6, 0xc5, 0x78, 0xe0, 0x7b, 0x9c, 0x91, 0xe7, 0x60, 0xb0, 0xcd, 0x9c, 0x29, 0x3e,
0xaa, 0xe4, 0x6e, 0xbb, 0xc2, 0xbc, 0x8c, 0xf4, 0x78, 0xfd, 0x62, 0x30, 0x79, 0x94, 0xe1, 0xd2,
0xfd, 0xbc, 0x51, 0x9a, 0x4c, 0x9f, 0x64, 0xc9, 0xf4, 0x20, 0x87, 0xcd, 0xb1, 0xe9, 0xa3, 0x0c,
0x9b, 0xe6, 0x07, 0xce, 0xd0, 0xe9, 0x69, 0x01, 0x9d, 0xe6, 0x97, 0x5f, 0xc2, 0xa7, 0xa7, 0x05,
0x7c, 0xda, 0xbf, 0x35, 0x57, 0x21, 0xa1, 0x3e, 0xc9, 0x12, 0x6a, 0xde, 0x9d, 0x1c, 0xa3, 0xfe,
0xaa, 0x88, 0x51, 0xef, 0xe7, 0x6c, 0x4a, 0x29, 0xf5, 0xd3, 0x5b, 0x94, 0x7a, 0x37, 0x67, 0x5a,
0xc0, 0xa9, 0xa7, 0x19, 0x4e, 0x85, 0x42, 0xdf, 0x4a, 0x48, 0xf5, 0xd9, 0x6d, 0x52, 0xbd, 0x97,
0x3f, 0xda, 0x22, 0x56, 0x1d, 0xe6, 0x58, 0xf5, 0x4e, 0x7e, 0x95, 0xa5, 0xb4, 0xfa, 0x08, 0x6f,
0x77, 0x2e, 0xd2, 0x90, 0x09, 0x58, 0x18, 0xfa, 0xa1, 0xe6, 0x3d, 0x25, 0x98, 0x47, 0xc8, 0x37,
0x49, 0x7c, 0x7d, 0x0f, 0x05, 0xcb, 0xa0, 0x4f, 0x45, 0x97, 0xf9, 0xe7, 0x4a, 0x62, 0x2b, 0x59,
0x38, 0xcd, 0x55, 0x86, 0xe6, 0xaa, 0x14, 0x33, 0x57, 0x33, 0xcc, 0x4c, 0x7e, 0x06, 0x7b, 0x2b,
0xca, 0x85, 0xda, 0x97, 0x69, 0x86, 0xbc, 0x7a, 0xa8, 0x50, 0x1b, 0xa2, 0x58, 0xec, 0x13, 0xd8,
0x4f, 0x61, 0x91, 0x48, 0x25, 0x51, 0xd5, 0xe5, 0xe5, 0xdd, 0x8d, 0xd1, 0x67, 0x41, 0x30, 0xa6,
0x7c, 0x69, 0xfe, 0x2e, 0xf1, 0x3f, 0x61, 0x7d, 0x02, 0xf5, 0xb9, 0x6f, 0x2b, 0xb7, 0x76, 0x2c,
0xd9, 0xc6, 0x4c, 0xb0, 0xf2, 0x17, 0x72, 0x56, 0xc3, 0xc2, 0x26, 0xa2, 0xe2, 0x9b, 0x62, 0xa8,
0x2b, 0x61, 0xee, 0x27, 0xc3, 0xc5, 0xe1, 0x6b, 0xfe, 0xad, 0x92, 0xec, 0x47, 0x4c, 0xd5, 0xff,
0xdf, 0x04, 0x78, 0x34, 0x8e, 0x67, 0xb3, 0x8d, 0xbc, 0x6e, 0x35, 0x4b, 0x09, 0x51, 0x9a, 0x6a,
0x4a, 0x27, 0xb3, 0x69, 0xaa, 0x25, 0xfb, 0x94, 0xa0, 0x29, 0xde, 0xbf, 0x94, 0xf7, 0x60, 0xdb,
0x52, 0x42, 0x8a, 0xbb, 0x8c, 0x0c, 0x77, 0x1d, 0x00, 0xb9, 0x7d, 0x43, 0xcc, 0xff, 0x54, 0x90,
0xfd, 0x32, 0xd1, 0x5f, 0xe8, 0x4f, 0x74, 0xc4, 0xd5, 0x54, 0x3a, 0xfa, 0x61, 0x3e, 0xfe, 0x04,
0x60, 0x41, 0xf9, 0xf4, 0x1b, 0xea, 0x09, 0x66, 0x6b, 0x47, 0x8d, 0x05, 0xe5, 0x7f, 0x94, 0x1d,
0xe4, 0x3e, 0xb4, 0x51, 0xbd, 0xe6, 0xcc, 0x96, 0x1e, 0xd7, 0xac, 0xd6, 0x82, 0xf2, 0xaf, 0x38,
0xb3, 0xc9, 0x0b, 0xa8, 0x0b, 0xba, 0xe0, 0xfd, 0x96, 0x4c, 0x0c, 0xdd, 0x63, 0x55, 0x90, 0x1e,
0x7f, 0xf1, 0xee, 0x35, 0x75, 0xc2, 0xd1, 0x5d, 0xcc, 0x0b, 0xff, 0xbe, 0x79, 0xd0, 0x45, 0xcc,
0x13, 0xdf, 0x75, 0x04, 0x73, 0x03, 0x71, 0x6d, 0x49, 0x1b, 0x62, 0x42, 0xed, 0x92, 0x31, 0xcd,
0x10, 0xbb, 0xb1, 0xe9, 0xe4, 0xd9, 0x2f, 0xd1, 0xd8, 0x42, 0xa5, 0xf9, 0xdf, 0x4a, 0x72, 0xbe,
0x49, 0x7a, 0xf8, 0xb1, 0x78, 0xff, 0xd7, 0x0a, 0xe6, 0xc6, 0x2c, 0x0d, 0x91, 0x73, 0xd8, 0x8b,
0x33, 0xf2, 0x74, 0x1d, 0xd8, 0x14, 0xeb, 0x95, 0xef, 0x2f, 0x76, 0x76, 0x63, 0x83, 0xaf, 0x14,
0x9e, 0xfc, 0x1e, 0xee, 0xcd, 0x71, 0x54, 0x8f, 0xaf, 0xf9, 0x34, 0xa0, 0x21, 0x75, 0xe3, 0xa1,
0xaa, 0x19, 0xda, 0x3d, 0x8f, 0x50, 0xaf, 0x11, 0xc4, 0xad, 0x3b, 0xf3, 0x4c, 0x87, 0x1e, 0xcf,
0xfc, 0x29, 0xa6, 0xf9, 0x34, 0xf5, 0x15, 0x9d, 0x87, 0xf9, 0x97, 0x0a, 0xf4, 0x72, 0x03, 0x92,
0x21, 0x80, 0x62, 0x0e, 0xee, 0x7c, 0x60, 0x3a, 0x25, 0x47, 0x7e, 0x48, 0x87, 0xdf, 0x38, 0x1f,
0x98, 0x65, 0xcc, 0xa2, 0x26, 0x79, 0x08, 0x2d, 0xb1, 0x51, 0xe8, 0x6c, 0xd9, 0xf3, 0x76, 0x23,
0xa1, 0x4d, 0x21, 0xff, 0xc9, 0x53, 0xd8, 0x56, 0x03, 0x2f, 0x7c, 0xce, 0x9d, 0x40, 0x27, 0x63,
0x92, 0x1e, 0xfa, 0x95, 0xd4, 0x58, 0x9d, 0x59, 0x22, 0x98, 0x7f, 0x02, 0x23, 0x9e, 0x96, 0x7c,
0x04, 0x86, 0x4b, 0x37, 0xba, 0x26, 0xc4, 0xb5, 0x35, 0xac, 0xb6, 0x4b, 0x37, 0xb2, 0x1c, 0x24,
0xf7, 0xa0, 0x85, 0x4a, 0xb1, 0x51, 0x7b, 0xd6, 0xb0, 0x9a, 0x2e, 0xdd, 0xbc, 0xdd, 0xc4, 0x8a,
0x05, 0xe5, 0x51, 0xc1, 0xe7, 0xd2, 0xcd, 0x2b, 0xca, 0xcd, 0xcf, 0xa1, 0xa9, 0x16, 0xf9, 0x83,
0x06, 0x46, 0xfb, 0x6a, 0xc6, 0xfe, 0xd7, 0xd0, 0x49, 0xad, 0x9b, 0xfc, 0x02, 0xee, 0x28, 0x0f,
0x03, 0x1a, 0x0a, 0xb9, 0x23, 0x99, 0x01, 0x89, 0x54, 0xbe, 0xa6, 0xa1, 0xc0, 0x29, 0x55, 0x09,
0xfb, 0xcf, 0x2a, 0x34, 0x55, 0x79, 0x48, 0x1e, 0x62, 0xaa, 0xa5, 0x8e, 0x37, 0x75, 0x6c, 0x95,
0x15, 0x46, 0x9d, 0xef, 0x6e, 0x1e, 0xb4, 0x24, 0x83, 0x4e, 0x2e, 0x30, 0xbb, 0x62, 0xc3, 0x4e,
0x91, 0x55, 0x35, 0x53, 0xbd, 0x12, 0xa8, 0x0b, 0xc7, 0x65, 0xda, 0x45, 0xd9, 0xc6, 0x95, 0x7b,
0x6b, 0x57, 0x6e, 0x49, 0x5d, 0x6d, 0x89, 0xb7, 0x76, 0x71, 0x4b, 0x5e, 0xc1, 0x4e, 0x2a, 0x49,
0x38, 0xb6, 0x2e, 0x5e, 0xba, 0xe9, 0xd3, 0x98, 0x5c, 0x8c, 0xf6, 0x31, 0x5c, 0xbf, 0xbb, 0x79,
0xd0, 0xf9, 0x6d, 0x94, 0x36, 0x26, 0x17, 0x56, 0x27, 0xce, 0x21, 0x13, 0x9b, 0x1c, 0x81, 0x4c,
0x29, 0x53, 0x95, 0x56, 0x55, 0xaa, 0x51, 0x2c, 0xdc, 0xc5, 0x7e, 0x9d, 0x77, 0xb1, 0x3a, 0xfe,
0x08, 0x0c, 0x0c, 0x3a, 0x05, 0x51, 0xa4, 0xdc, 0xc6, 0x0e, 0xa9, 0xfc, 0x18, 0x7a, 0x49, 0x59,
0xab, 0x20, 0x8a, 0xa1, 0xbb, 0x49, 0xb7, 0x04, 0xde, 0x87, 0x76, 0x9c, 0xd2, 0x0c, 0x89, 0x68,
0x51, 0x9d, 0xc9, 0xbe, 0x84, 0x96, 0x5e, 0x62, 0x61, 0x75, 0xfe, 0x73, 0x68, 0xe0, 0xb9, 0x44,
0x17, 0x2a, 0x2a, 0x9b, 0xe4, 0x79, 0x30, 0x91, 0xa9, 0xd1, 0x15, 0xd0, 0x3c, 0x85, 0x9d, 0x8c,
0x16, 0xb3, 0x87, 0xf0, 0x05, 0x5d, 0xe9, 0x03, 0x55, 0x42, 0x3c, 0x59, 0x35, 0x99, 0xcc, 0x7c,
0x01, 0x46, 0x7c, 0xe9, 0xf1, 0x14, 0x82, 0xf5, 0x6c, 0x1a, 0x7d, 0x47, 0x6d, 0x5b, 0xcd, 0x60,
0x3d, 0xfb, 0x42, 0xe5, 0xa8, 0xc0, 0xff, 0x46, 0x7f, 0x2f, 0xd4, 0x2c, 0x25, 0x98, 0x9f, 0x41,
0x3b, 0xaa, 0xe4, 0xcb, 0x4d, 0x4b, 0xa2, 0xe0, 0xe4, 0xdb, 0x06, 0xf4, 0xce, 0x46, 0xe7, 0x93,
0xb3, 0x20, 0x58, 0x39, 0x73, 0x2a, 0xb3, 0xf9, 0x10, 0xea, 0xb2, 0x5e, 0x29, 0x78, 0x70, 0x18,
0x14, 0x15, 0xce, 0xe4, 0x04, 0x1a, 0xb2, 0x6c, 0x21, 0x45, 0xef, 0x0e, 0x83, 0xc2, 0xfa, 0x19,
0x27, 0x51, 0x85, 0xcd, 0xed, 0xe7, 0x87, 0x41, 0x51, 0x11, 0x4d, 0x3e, 0x07, 0x23, 0x29, 0x38,
0xca, 0x1e, 0x21, 0x06, 0xa5, 0xe5, 0x34, 0xda, 0x27, 0x19, 0xa8, 0xec, 0x93, 0x7d, 0x50, 0x5a,
0x77, 0x92, 0xe7, 0xd0, 0x8a, 0xb2, 0x77, 0xf1, 0x33, 0xc1, 0xa0, 0xa4, 0xd4, 0xc5, 0xed, 0x51,
0x55, 0x4c, 0xd1, 0x5b, 0xc6, 0xa0, 0xb0, 0x1e, 0x27, 0x4f, 0xa1, 0xa9, 0x89, 0xb8, 0xf0, 0x83,
0x7f, 0x50, 0x5c, 0xb0, 0xa2, 0x93, 0xc9, 0xf7, 0x74, 0xd9, 0x7b, 0xcb, 0xa0, 0xf4, 0xc3, 0x81,
0x9c, 0x01, 0xa4, 0x3e, 0x5a, 0x4b, 0x1f, 0x52, 0x06, 0xe5, 0x1f, 0x04, 0x04, 0xc3, 0x31, 0xfe,
0xc8, 0x2b, 0x7e, 0xe0, 0x18, 0x94, 0xd5, 0xe8, 0xb3, 0xa6, 0x7c, 0x04, 0xfb, 0xf4, 0x7f, 0x01,
0x00, 0x00, 0xff, 0xff, 0x78, 0xcf, 0xcd, 0xb3, 0x80, 0x13, 0x00, 0x00,
}

+ 3
- 3
types/types.proto View File

@ -151,9 +151,9 @@ message ResponseCheckTx {
string log = 3; // nondeterministic
string info = 4; // nondeterministic
int64 gas_wanted = 5;
// int64 gas_used = 6;
int64 gas_used = 6;
repeated common.KVPair tags = 7 [(gogoproto.nullable)=false, (gogoproto.jsontag)="tags,omitempty"];
common.KI64Pair fee = 8 [(gogoproto.nullable)=false];
common.KI64Pair fee = 8 [(gogoproto.nullable)=false, (gogoproto.jsontag)="tags,omitempty"];
}
message ResponseDeliverTx {
@ -164,7 +164,7 @@ message ResponseDeliverTx {
int64 gas_wanted = 5;
int64 gas_used = 6;
repeated common.KVPair tags = 7 [(gogoproto.nullable)=false, (gogoproto.jsontag)="tags,omitempty"];
// common.KI64Pair fee = 8;
common.KI64Pair fee = 8 [(gogoproto.nullable)=false, (gogoproto.jsontag)="tags,omitempty"];
}
message ResponseEndBlock {


+ 2
- 2
version/version.go View File

@ -4,6 +4,6 @@ package version
const Maj = "0"
const Min = "10"
const Fix = "0"
const Fix = "1"
const Version = "0.10.0"
const Version = "0.10.1"

Loading…
Cancel
Save