From 1014f8c84bb10300f43f246642d69f46bd8954fd Mon Sep 17 00:00:00 2001 From: Marko Date: Fri, 28 Jun 2019 17:32:15 +0200 Subject: [PATCH 01/34] docs: update to contributing.md (#3760) * Update to contributing.md - Add in section for Draft PR, instead of WIP - Add make lint as part of the commit process. Signed-off-by: Marko Baricevic * mistake * minor word change --- CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 77a625504..ef992fee6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,7 +13,9 @@ to write a more detailed design document in the form of an Architectural Decision Record (ie. see [here](./docs/architecture/)) before submitting code changes. -Please make sure to use `gofmt` before every commit - the easiest way to do this is have your editor run it for you upon saving a file. +Please open a [Draft PR](https://github.blog/2019-02-14-introducing-draft-pull-requests/), even if your contribution is incomplete, this inidicates to the community you're working on something and allows them to provide comments early in the development process. When the code is complete it can be marked as ready-for-review. + +Please make sure to use `gofmt` before every commit - the easiest way to do this is have your editor run it for you upon saving a file. Additionally please ensure that your code is lint compliant by running `make lint` ## Forking From b2afc6590858c0804bdca478a76ea9d36f0181c6 Mon Sep 17 00:00:00 2001 From: Peng Zhong <172531+nylira@users.noreply.github.com> Date: Sat, 29 Jun 2019 03:06:44 -0400 Subject: [PATCH 02/34] docs: add readme image (#3763) --- README.md | 1 + docs/tendermint-core-image.jpg | Bin 0 -> 125536 bytes 2 files changed, 1 insertion(+) create mode 100755 docs/tendermint-core-image.jpg diff --git a/README.md b/README.md index ec7b28cc0..994ca63b2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Tendermint +![banner](docs/tendermint-core-image.jpg) [Byzantine-Fault Tolerant](https://en.wikipedia.org/wiki/Byzantine_fault_tolerance) [State Machines](https://en.wikipedia.org/wiki/State_machine_replication). diff --git a/docs/tendermint-core-image.jpg b/docs/tendermint-core-image.jpg new file mode 100755 index 0000000000000000000000000000000000000000..75832e602dbb36010e1812de3e5dd0c5969a47f9 GIT binary patch literal 125536 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%0Dx$6!G)u1{;V=V=17T`y9g)& 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 Date: Sun, 30 Jun 2019 11:46:31 +0400 Subject: [PATCH 03/34] docs: remove confusing statement from contributing.md (#3764) --- CONTRIBUTING.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ef992fee6..832156bda 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,8 +41,6 @@ To pull in updates from the origin repo, run * `git fetch upstream` * `git rebase upstream/master` (or whatever branch you want) -Please don't make Pull Requests to `master`. - ## Dependencies We use [go modules](https://github.com/golang/go/wiki/Modules) to manage dependencies. From d4cf2040877aea2e863265a56fe1d91e93bf021a Mon Sep 17 00:00:00 2001 From: Marko Date: Sun, 30 Jun 2019 09:56:24 +0200 Subject: [PATCH 04/34] libs: remove commented and unneeded code (#3757) - libs/errors: commented out errors.go - libs/common: unused colors.go - libs/db: unused debugDB Signed-off-by: Marko Baricevic --- CHANGELOG_PENDING.md | 2 + libs/common/colors.go | 95 ---------------- libs/db/db_test.go | 3 +- libs/db/debug_db.go | 257 ------------------------------------------ libs/errors/errors.go | 21 ---- 5 files changed, 3 insertions(+), 375 deletions(-) delete mode 100644 libs/common/colors.go delete mode 100644 libs/db/debug_db.go delete mode 100644 libs/errors/errors.go diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 45d1c7899..d57446a10 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -14,6 +14,8 @@ program](https://hackerone.com/tendermint). * Apps * Go API + - [libs] Remove unused `db/debugDB` and `common/colors.go` & `errors/errors.go` files (@marbar3778) + * Blockchain Protocol diff --git a/libs/common/colors.go b/libs/common/colors.go deleted file mode 100644 index 89dda2c97..000000000 --- a/libs/common/colors.go +++ /dev/null @@ -1,95 +0,0 @@ -package common - -import ( - "fmt" - "strings" -) - -const ( - ANSIReset = "\x1b[0m" - ANSIBright = "\x1b[1m" - ANSIDim = "\x1b[2m" - ANSIUnderscore = "\x1b[4m" - ANSIBlink = "\x1b[5m" - ANSIReverse = "\x1b[7m" - ANSIHidden = "\x1b[8m" - - ANSIFgBlack = "\x1b[30m" - ANSIFgRed = "\x1b[31m" - ANSIFgGreen = "\x1b[32m" - ANSIFgYellow = "\x1b[33m" - ANSIFgBlue = "\x1b[34m" - ANSIFgMagenta = "\x1b[35m" - ANSIFgCyan = "\x1b[36m" - ANSIFgWhite = "\x1b[37m" - - ANSIBgBlack = "\x1b[40m" - ANSIBgRed = "\x1b[41m" - ANSIBgGreen = "\x1b[42m" - ANSIBgYellow = "\x1b[43m" - ANSIBgBlue = "\x1b[44m" - ANSIBgMagenta = "\x1b[45m" - ANSIBgCyan = "\x1b[46m" - ANSIBgWhite = "\x1b[47m" -) - -// color the string s with color 'color' -// unless s is already colored -func treat(s string, color string) string { - if len(s) > 2 && s[:2] == "\x1b[" { - return s - } - return color + s + ANSIReset -} - -func treatAll(color string, args ...interface{}) string { - parts := make([]string, 0, len(args)) - for _, arg := range args { - parts = append(parts, treat(fmt.Sprintf("%v", arg), color)) - } - return strings.Join(parts, "") -} - -func Black(args ...interface{}) string { - return treatAll(ANSIFgBlack, args...) -} - -func Red(args ...interface{}) string { - return treatAll(ANSIFgRed, args...) -} - -func Green(args ...interface{}) string { - return treatAll(ANSIFgGreen, args...) -} - -func Yellow(args ...interface{}) string { - return treatAll(ANSIFgYellow, args...) -} - -func Blue(args ...interface{}) string { - return treatAll(ANSIFgBlue, args...) -} - -func Magenta(args ...interface{}) string { - return treatAll(ANSIFgMagenta, args...) -} - -func Cyan(args ...interface{}) string { - return treatAll(ANSIFgCyan, args...) -} - -func White(args ...interface{}) string { - return treatAll(ANSIFgWhite, args...) -} - -func ColoredBytes(data []byte, textColor, bytesColor func(...interface{}) string) string { - s := "" - for _, b := range data { - if 0x21 <= b && b < 0x7F { - s += textColor(string(b)) - } else { - s += bytesColor(fmt.Sprintf("%02X", b)) - } - } - return s -} diff --git a/libs/db/db_test.go b/libs/db/db_test.go index 7cb721b26..22b781f95 100644 --- a/libs/db/db_test.go +++ b/libs/db/db_test.go @@ -182,8 +182,7 @@ func TestDBBatchWrite(t *testing.T) { for i, tc := range testCases { mdb := newMockDB() - ddb := NewDebugDB(t.Name(), mdb) - batch := ddb.NewBatch() + batch := mdb.NewBatch() tc.modify(batch) diff --git a/libs/db/debug_db.go b/libs/db/debug_db.go deleted file mode 100644 index 658cd0555..000000000 --- a/libs/db/debug_db.go +++ /dev/null @@ -1,257 +0,0 @@ -package db - -import ( - "fmt" - "sync" - - cmn "github.com/tendermint/tendermint/libs/common" -) - -//---------------------------------------- -// debugDB - -type debugDB struct { - label string - db DB -} - -// For printing all operationgs to the console for debugging. -func NewDebugDB(label string, db DB) debugDB { - return debugDB{ - label: label, - db: db, - } -} - -// Implements atomicSetDeleter. -func (ddb debugDB) Mutex() *sync.Mutex { return nil } - -// Implements DB. -func (ddb debugDB) Get(key []byte) (value []byte) { - defer func() { - fmt.Printf("%v.Get(%v) %v\n", ddb.label, - cmn.ColoredBytes(key, cmn.Cyan, cmn.Blue), - cmn.ColoredBytes(value, cmn.Green, cmn.Blue)) - }() - value = ddb.db.Get(key) - return -} - -// Implements DB. -func (ddb debugDB) Has(key []byte) (has bool) { - defer func() { - fmt.Printf("%v.Has(%v) %v\n", ddb.label, - cmn.ColoredBytes(key, cmn.Cyan, cmn.Blue), has) - }() - return ddb.db.Has(key) -} - -// Implements DB. -func (ddb debugDB) Set(key []byte, value []byte) { - fmt.Printf("%v.Set(%v, %v)\n", ddb.label, - cmn.ColoredBytes(key, cmn.Yellow, cmn.Blue), - cmn.ColoredBytes(value, cmn.Green, cmn.Blue)) - ddb.db.Set(key, value) -} - -// Implements DB. -func (ddb debugDB) SetSync(key []byte, value []byte) { - fmt.Printf("%v.SetSync(%v, %v)\n", ddb.label, - cmn.ColoredBytes(key, cmn.Yellow, cmn.Blue), - cmn.ColoredBytes(value, cmn.Green, cmn.Blue)) - ddb.db.SetSync(key, value) -} - -// Implements atomicSetDeleter. -func (ddb debugDB) SetNoLock(key []byte, value []byte) { - fmt.Printf("%v.SetNoLock(%v, %v)\n", ddb.label, - cmn.ColoredBytes(key, cmn.Yellow, cmn.Blue), - cmn.ColoredBytes(value, cmn.Green, cmn.Blue)) - ddb.db.(atomicSetDeleter).SetNoLock(key, value) -} - -// Implements atomicSetDeleter. -func (ddb debugDB) SetNoLockSync(key []byte, value []byte) { - fmt.Printf("%v.SetNoLockSync(%v, %v)\n", ddb.label, - cmn.ColoredBytes(key, cmn.Yellow, cmn.Blue), - cmn.ColoredBytes(value, cmn.Green, cmn.Blue)) - ddb.db.(atomicSetDeleter).SetNoLockSync(key, value) -} - -// Implements DB. -func (ddb debugDB) Delete(key []byte) { - fmt.Printf("%v.Delete(%v)\n", ddb.label, - cmn.ColoredBytes(key, cmn.Red, cmn.Yellow)) - ddb.db.Delete(key) -} - -// Implements DB. -func (ddb debugDB) DeleteSync(key []byte) { - fmt.Printf("%v.DeleteSync(%v)\n", ddb.label, - cmn.ColoredBytes(key, cmn.Red, cmn.Yellow)) - ddb.db.DeleteSync(key) -} - -// Implements atomicSetDeleter. -func (ddb debugDB) DeleteNoLock(key []byte) { - fmt.Printf("%v.DeleteNoLock(%v)\n", ddb.label, - cmn.ColoredBytes(key, cmn.Red, cmn.Yellow)) - ddb.db.(atomicSetDeleter).DeleteNoLock(key) -} - -// Implements atomicSetDeleter. -func (ddb debugDB) DeleteNoLockSync(key []byte) { - fmt.Printf("%v.DeleteNoLockSync(%v)\n", ddb.label, - cmn.ColoredBytes(key, cmn.Red, cmn.Yellow)) - ddb.db.(atomicSetDeleter).DeleteNoLockSync(key) -} - -// Implements DB. -func (ddb debugDB) Iterator(start, end []byte) Iterator { - fmt.Printf("%v.Iterator(%v, %v)\n", ddb.label, - cmn.ColoredBytes(start, cmn.Cyan, cmn.Blue), - cmn.ColoredBytes(end, cmn.Cyan, cmn.Blue)) - return NewDebugIterator(ddb.label, ddb.db.Iterator(start, end)) -} - -// Implements DB. -func (ddb debugDB) ReverseIterator(start, end []byte) Iterator { - fmt.Printf("%v.ReverseIterator(%v, %v)\n", ddb.label, - cmn.ColoredBytes(start, cmn.Cyan, cmn.Blue), - cmn.ColoredBytes(end, cmn.Cyan, cmn.Blue)) - return NewDebugIterator(ddb.label, ddb.db.ReverseIterator(start, end)) -} - -// Implements DB. -// Panics if the underlying db is not an -// atomicSetDeleter. -func (ddb debugDB) NewBatch() Batch { - fmt.Printf("%v.NewBatch()\n", ddb.label) - return NewDebugBatch(ddb.label, ddb.db.NewBatch()) -} - -// Implements DB. -func (ddb debugDB) Close() { - fmt.Printf("%v.Close()\n", ddb.label) - ddb.db.Close() -} - -// Implements DB. -func (ddb debugDB) Print() { - ddb.db.Print() -} - -// Implements DB. -func (ddb debugDB) Stats() map[string]string { - return ddb.db.Stats() -} - -//---------------------------------------- -// debugIterator - -type debugIterator struct { - label string - itr Iterator -} - -// For printing all operationgs to the console for debugging. -func NewDebugIterator(label string, itr Iterator) debugIterator { - return debugIterator{ - label: label, - itr: itr, - } -} - -// Implements Iterator. -func (ditr debugIterator) Domain() (start []byte, end []byte) { - defer func() { - fmt.Printf("%v.itr.Domain() (%X,%X)\n", ditr.label, start, end) - }() - start, end = ditr.itr.Domain() - return -} - -// Implements Iterator. -func (ditr debugIterator) Valid() (ok bool) { - defer func() { - fmt.Printf("%v.itr.Valid() %v\n", ditr.label, ok) - }() - ok = ditr.itr.Valid() - return -} - -// Implements Iterator. -func (ditr debugIterator) Next() { - fmt.Printf("%v.itr.Next()\n", ditr.label) - ditr.itr.Next() -} - -// Implements Iterator. -func (ditr debugIterator) Key() (key []byte) { - key = ditr.itr.Key() - fmt.Printf("%v.itr.Key() %v\n", ditr.label, - cmn.ColoredBytes(key, cmn.Cyan, cmn.Blue)) - return -} - -// Implements Iterator. -func (ditr debugIterator) Value() (value []byte) { - value = ditr.itr.Value() - fmt.Printf("%v.itr.Value() %v\n", ditr.label, - cmn.ColoredBytes(value, cmn.Green, cmn.Blue)) - return -} - -// Implements Iterator. -func (ditr debugIterator) Close() { - fmt.Printf("%v.itr.Close()\n", ditr.label) - ditr.itr.Close() -} - -//---------------------------------------- -// debugBatch - -type debugBatch struct { - label string - bch Batch -} - -// For printing all operationgs to the console for debugging. -func NewDebugBatch(label string, bch Batch) debugBatch { - return debugBatch{ - label: label, - bch: bch, - } -} - -// Implements Batch. -func (dbch debugBatch) Set(key, value []byte) { - fmt.Printf("%v.batch.Set(%v, %v)\n", dbch.label, - cmn.ColoredBytes(key, cmn.Yellow, cmn.Blue), - cmn.ColoredBytes(value, cmn.Green, cmn.Blue)) - dbch.bch.Set(key, value) -} - -// Implements Batch. -func (dbch debugBatch) Delete(key []byte) { - fmt.Printf("%v.batch.Delete(%v)\n", dbch.label, - cmn.ColoredBytes(key, cmn.Red, cmn.Yellow)) - dbch.bch.Delete(key) -} - -// Implements Batch. -func (dbch debugBatch) Write() { - fmt.Printf("%v.batch.Write()\n", dbch.label) - dbch.bch.Write() -} - -// Implements Batch. -func (dbch debugBatch) WriteSync() { - fmt.Printf("%v.batch.WriteSync()\n", dbch.label) - dbch.bch.WriteSync() -} - -// Implements Batch. -func (dbch debugBatch) Close() { - dbch.bch.Close() -} diff --git a/libs/errors/errors.go b/libs/errors/errors.go deleted file mode 100644 index a03382780..000000000 --- a/libs/errors/errors.go +++ /dev/null @@ -1,21 +0,0 @@ -// Package errors contains errors that are thrown across packages. -package errors - -// // ErrPermissionsChanged occurs if the file permission have changed since the file was created. -// type ErrPermissionsChanged struct { -// name string -// got, want os.FileMode -// } - -// func NewErrPermissionsChanged(name string, got, want os.FileMode) *ErrPermissionsChanged { -// return &ErrPermissionsChanged{name: name, got: got, want: want} -// } - -// func (e ErrPermissionsChanged) Error() string { -// return fmt.Sprintf( -// "file: [%v]\nexpected file permissions: %v, got: %v", -// e.name, -// e.want, -// e.got, -// ) -// } From d9481e3648450cb99e15c6a070c1fb69aa0c255b Mon Sep 17 00:00:00 2001 From: Ivan Kushmantsev Date: Mon, 1 Jul 2019 12:48:54 +0400 Subject: [PATCH 05/34] config: make possible to set absolute paths for TLS cert and key (#3765) --- CHANGELOG_PENDING.md | 1 + config/config.go | 18 ++++++++++++++---- config/config_test.go | 16 ++++++++++++++++ config/toml.go | 6 ++++-- docs/tendermint-core/configuration.md | 6 ++++-- 5 files changed, 39 insertions(+), 8 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index d57446a10..d81e815f3 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -24,5 +24,6 @@ program](https://hackerone.com/tendermint). ### FEATURES: ### IMPROVEMENTS: + - [rpc] \#3700 Make possible to set absolute paths for TLS cert and key (@climber73) ### BUG FIXES: diff --git a/config/config.go b/config/config.go index aa25cff6b..32e37f3e1 100644 --- a/config/config.go +++ b/config/config.go @@ -351,7 +351,8 @@ type RPCConfig struct { // See https://github.com/tendermint/tendermint/issues/3435 TimeoutBroadcastTxCommit time.Duration `mapstructure:"timeout_broadcast_tx_commit"` - // The name of a file containing certificate that is used to create the HTTPS server. + // The path to a file containing certificate that is used to create the HTTPS server. + // Migth be either absolute path or path related to tendermint's config directory. // // If the certificate is signed by a certificate authority, // the certFile should be the concatenation of the server's certificate, any intermediates, @@ -360,7 +361,8 @@ type RPCConfig struct { // NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. TLSCertFile string `mapstructure:"tls_cert_file"` - // The name of a file containing matching private key that is used to create the HTTPS server. + // The path to a file containing matching private key that is used to create the HTTPS server. + // Migth be either absolute path or path related to tendermint's config directory. // // NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. TLSKeyFile string `mapstructure:"tls_key_file"` @@ -424,11 +426,19 @@ func (cfg *RPCConfig) IsCorsEnabled() bool { } func (cfg RPCConfig) KeyFile() string { - return rootify(filepath.Join(defaultConfigDir, cfg.TLSKeyFile), cfg.RootDir) + path := cfg.TLSKeyFile + if filepath.IsAbs(path) { + return path + } + return rootify(filepath.Join(defaultConfigDir, path), cfg.RootDir) } func (cfg RPCConfig) CertFile() string { - return rootify(filepath.Join(defaultConfigDir, cfg.TLSCertFile), cfg.RootDir) + path := cfg.TLSCertFile + if filepath.IsAbs(path) { + return path + } + return rootify(filepath.Join(defaultConfigDir, path), cfg.RootDir) } func (cfg RPCConfig) IsTLSEnabled() bool { diff --git a/config/config_test.go b/config/config_test.go index afdbed181..6f9e3783e 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -36,3 +36,19 @@ func TestConfigValidateBasic(t *testing.T) { cfg.Consensus.TimeoutPropose = -10 * time.Second assert.Error(t, cfg.ValidateBasic()) } + +func TestTLSConfiguration(t *testing.T) { + assert := assert.New(t) + cfg := DefaultConfig() + cfg.SetRoot("/home/user") + + cfg.RPC.TLSCertFile = "file.crt" + assert.Equal("/home/user/config/file.crt", cfg.RPC.CertFile()) + cfg.RPC.TLSKeyFile = "file.key" + assert.Equal("/home/user/config/file.key", cfg.RPC.KeyFile()) + + cfg.RPC.TLSCertFile = "/abs/path/to/file.crt" + assert.Equal("/abs/path/to/file.crt", cfg.RPC.CertFile()) + cfg.RPC.TLSKeyFile = "/abs/path/to/file.key" + assert.Equal("/abs/path/to/file.key", cfg.RPC.KeyFile()) +} diff --git a/config/toml.go b/config/toml.go index b1541c05a..09117a0fb 100644 --- a/config/toml.go +++ b/config/toml.go @@ -192,14 +192,16 @@ max_subscriptions_per_client = {{ .RPC.MaxSubscriptionsPerClient }} # See https://github.com/tendermint/tendermint/issues/3435 timeout_broadcast_tx_commit = "{{ .RPC.TimeoutBroadcastTxCommit }}" -# The name of a file containing certificate that is used to create the HTTPS server. +# The path to a file containing certificate that is used to create the HTTPS server. +# Migth be either absolute path or path related to tendermint's config directory. # If the certificate is signed by a certificate authority, # the certFile should be the concatenation of the server's certificate, any intermediates, # and the CA's certificate. # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. tls_cert_file = "{{ .RPC.TLSCertFile }}" -# The name of a file containing matching private key that is used to create the HTTPS server. +# The path to a file containing matching private key that is used to create the HTTPS server. +# Migth be either absolute path or path related to tendermint's config directory. # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. tls_key_file = "{{ .RPC.TLSKeyFile }}" diff --git a/docs/tendermint-core/configuration.md b/docs/tendermint-core/configuration.md index f24e76d6d..df05f7c5d 100644 --- a/docs/tendermint-core/configuration.md +++ b/docs/tendermint-core/configuration.md @@ -138,14 +138,16 @@ max_subscriptions_per_client = 5 # See https://github.com/tendermint/tendermint/issues/3435 timeout_broadcast_tx_commit = "10s" -# The name of a file containing certificate that is used to create the HTTPS server. +# The path to a file containing certificate that is used to create the HTTPS server. +# Migth be either absolute path or path related to tendermint's config directory. # If the certificate is signed by a certificate authority, # the certFile should be the concatenation of the server's certificate, any intermediates, # and the CA's certificate. # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. tls_cert_file = "" -# The name of a file containing matching private key that is used to create the HTTPS server. +# The path to a file containing matching private key that is used to create the HTTPS server. +# Migth be either absolute path or path related to tendermint's config directory. # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. tls_key_file = "" From 62f97a69e97262b5feb57b1c2498f0c1e0e297b3 Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Tue, 2 Jul 2019 10:14:53 -0400 Subject: [PATCH 06/34] abci: Refactor CheckTx to notify of recheck (#3744) As per #2127, this refactors the RequestCheckTx ProtoBuf struct to allow for a flag indicating whether a query is a recheck or not (and allows for possible future, more nuanced states). In order to pass this extended information through to the ABCI app, the proxy.AppConnMempool (and, for consistency, the proxy.AppConnConsensus) interface seems to need to be refactored along with abcicli.Client. And, as per this comment, I've made the following modification to the protobuf definition for the RequestCheckTx structure: enum CheckTxType { New = 0; Recheck = 1; } message RequestCheckTx { bytes tx = 1; CheckTxType type = 2; } * Refactor ABCI CheckTx to notify of recheck As per #2127, this refactors the `RequestCheckTx` ProtoBuf struct to allow for: 1. a flag indicating whether a query is a recheck or not (and allows for possible future, more nuanced states) 2. an `additional_data` bytes array to provide information for those more nuanced states. In order to pass this extended information through to the ABCI app, the `proxy.AppConnMempool` (and, for consistency, the `proxy.AppConnConsensus`) interface seems to need to be refactored. Commits: * Fix linting issue * Add CHANGELOG_PENDING entry * Remove extraneous explicit initialization * Update ABCI spec doc to include new CheckTx params * Rename method param for consistency * Rename CheckTxType enum values and remove additional_data param --- CHANGELOG_PENDING.md | 6 +- abci/client/client.go | 8 +- abci/client/grpc_client.go | 16 +- abci/client/local_client.go | 20 +- abci/client/socket_client.go | 16 +- abci/cmd/abci-cli/abci-cli.go | 4 +- abci/example/example_test.go | 2 +- abci/example/kvstore/kvstore_test.go | 4 +- abci/tests/server/client.go | 4 +- abci/tests/test_app/app.go | 2 +- abci/types/messages.go | 8 +- abci/types/types.pb.go | 452 +++++++++++++++------------ abci/types/types.proto | 6 + consensus/replay_test.go | 2 +- docs/spec/abci/abci.md | 6 + mempool/clist_mempool.go | 7 +- mempool/clist_mempool_test.go | 4 +- proxy/app_conn.go | 12 +- state/execution.go | 2 +- 19 files changed, 333 insertions(+), 248 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index d81e815f3..9c94c55e7 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -14,9 +14,13 @@ program](https://hackerone.com/tendermint). * Apps * Go API + - [abci] \#2127 ABCI / mempool: Add a "Recheck Tx" indicator. Breaks the ABCI + client interface (`abcicli.Client`) to allow for supplying the ABCI + `types.RequestCheckTx` and `types.RequestDeliverTx` structs, and lets the + mempool indicate to the ABCI app whether a CheckTx request is a recheck or + not. - [libs] Remove unused `db/debugDB` and `common/colors.go` & `errors/errors.go` files (@marbar3778) - * Blockchain Protocol * P2P Protocol diff --git a/abci/client/client.go b/abci/client/client.go index e1eea5d4e..5f5ad7860 100644 --- a/abci/client/client.go +++ b/abci/client/client.go @@ -28,8 +28,8 @@ type Client interface { EchoAsync(msg string) *ReqRes InfoAsync(types.RequestInfo) *ReqRes SetOptionAsync(types.RequestSetOption) *ReqRes - DeliverTxAsync(tx []byte) *ReqRes - CheckTxAsync(tx []byte) *ReqRes + DeliverTxAsync(types.RequestDeliverTx) *ReqRes + CheckTxAsync(types.RequestCheckTx) *ReqRes QueryAsync(types.RequestQuery) *ReqRes CommitAsync() *ReqRes InitChainAsync(types.RequestInitChain) *ReqRes @@ -40,8 +40,8 @@ type Client interface { EchoSync(msg string) (*types.ResponseEcho, error) InfoSync(types.RequestInfo) (*types.ResponseInfo, error) SetOptionSync(types.RequestSetOption) (*types.ResponseSetOption, error) - DeliverTxSync(tx []byte) (*types.ResponseDeliverTx, error) - CheckTxSync(tx []byte) (*types.ResponseCheckTx, error) + DeliverTxSync(types.RequestDeliverTx) (*types.ResponseDeliverTx, error) + CheckTxSync(types.RequestCheckTx) (*types.ResponseCheckTx, error) QuerySync(types.RequestQuery) (*types.ResponseQuery, error) CommitSync() (*types.ResponseCommit, error) InitChainSync(types.RequestInitChain) (*types.ResponseInitChain, error) diff --git a/abci/client/grpc_client.go b/abci/client/grpc_client.go index d04f42b66..23d790550 100644 --- a/abci/client/grpc_client.go +++ b/abci/client/grpc_client.go @@ -159,8 +159,8 @@ func (cli *grpcClient) SetOptionAsync(params types.RequestSetOption) *ReqRes { return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_SetOption{SetOption: res}}) } -func (cli *grpcClient) DeliverTxAsync(tx []byte) *ReqRes { - req := types.ToRequestDeliverTx(tx) +func (cli *grpcClient) DeliverTxAsync(params types.RequestDeliverTx) *ReqRes { + req := types.ToRequestDeliverTx(params) res, err := cli.client.DeliverTx(context.Background(), req.GetDeliverTx(), grpc.FailFast(true)) if err != nil { cli.StopForError(err) @@ -168,8 +168,8 @@ func (cli *grpcClient) DeliverTxAsync(tx []byte) *ReqRes { return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_DeliverTx{DeliverTx: res}}) } -func (cli *grpcClient) CheckTxAsync(tx []byte) *ReqRes { - req := types.ToRequestCheckTx(tx) +func (cli *grpcClient) CheckTxAsync(params types.RequestCheckTx) *ReqRes { + req := types.ToRequestCheckTx(params) res, err := cli.client.CheckTx(context.Background(), req.GetCheckTx(), grpc.FailFast(true)) if err != nil { cli.StopForError(err) @@ -265,13 +265,13 @@ func (cli *grpcClient) SetOptionSync(req types.RequestSetOption) (*types.Respons return reqres.Response.GetSetOption(), cli.Error() } -func (cli *grpcClient) DeliverTxSync(tx []byte) (*types.ResponseDeliverTx, error) { - reqres := cli.DeliverTxAsync(tx) +func (cli *grpcClient) DeliverTxSync(params types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { + reqres := cli.DeliverTxAsync(params) return reqres.Response.GetDeliverTx(), cli.Error() } -func (cli *grpcClient) CheckTxSync(tx []byte) (*types.ResponseCheckTx, error) { - reqres := cli.CheckTxAsync(tx) +func (cli *grpcClient) CheckTxSync(params types.RequestCheckTx) (*types.ResponseCheckTx, error) { + reqres := cli.CheckTxAsync(params) return reqres.Response.GetCheckTx(), cli.Error() } diff --git a/abci/client/local_client.go b/abci/client/local_client.go index 4a3e6a5ee..bb009173a 100644 --- a/abci/client/local_client.go +++ b/abci/client/local_client.go @@ -81,24 +81,24 @@ func (app *localClient) SetOptionAsync(req types.RequestSetOption) *ReqRes { ) } -func (app *localClient) DeliverTxAsync(tx []byte) *ReqRes { +func (app *localClient) DeliverTxAsync(params types.RequestDeliverTx) *ReqRes { app.mtx.Lock() defer app.mtx.Unlock() - res := app.Application.DeliverTx(types.RequestDeliverTx{Tx: tx}) + res := app.Application.DeliverTx(params) return app.callback( - types.ToRequestDeliverTx(tx), + types.ToRequestDeliverTx(params), types.ToResponseDeliverTx(res), ) } -func (app *localClient) CheckTxAsync(tx []byte) *ReqRes { +func (app *localClient) CheckTxAsync(req types.RequestCheckTx) *ReqRes { app.mtx.Lock() defer app.mtx.Unlock() - res := app.Application.CheckTx(types.RequestCheckTx{Tx: tx}) + res := app.Application.CheckTx(req) return app.callback( - types.ToRequestCheckTx(tx), + types.ToRequestCheckTx(req), types.ToResponseCheckTx(res), ) } @@ -184,19 +184,19 @@ func (app *localClient) SetOptionSync(req types.RequestSetOption) (*types.Respon return &res, nil } -func (app *localClient) DeliverTxSync(tx []byte) (*types.ResponseDeliverTx, error) { +func (app *localClient) DeliverTxSync(req types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { app.mtx.Lock() defer app.mtx.Unlock() - res := app.Application.DeliverTx(types.RequestDeliverTx{Tx: tx}) + res := app.Application.DeliverTx(req) return &res, nil } -func (app *localClient) CheckTxSync(tx []byte) (*types.ResponseCheckTx, error) { +func (app *localClient) CheckTxSync(req types.RequestCheckTx) (*types.ResponseCheckTx, error) { app.mtx.Lock() defer app.mtx.Unlock() - res := app.Application.CheckTx(types.RequestCheckTx{Tx: tx}) + res := app.Application.CheckTx(req) return &res, nil } diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index 3b401bd3c..16e39bf35 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -243,12 +243,12 @@ func (cli *socketClient) SetOptionAsync(req types.RequestSetOption) *ReqRes { return cli.queueRequest(types.ToRequestSetOption(req)) } -func (cli *socketClient) DeliverTxAsync(tx []byte) *ReqRes { - return cli.queueRequest(types.ToRequestDeliverTx(tx)) +func (cli *socketClient) DeliverTxAsync(req types.RequestDeliverTx) *ReqRes { + return cli.queueRequest(types.ToRequestDeliverTx(req)) } -func (cli *socketClient) CheckTxAsync(tx []byte) *ReqRes { - return cli.queueRequest(types.ToRequestCheckTx(tx)) +func (cli *socketClient) CheckTxAsync(req types.RequestCheckTx) *ReqRes { + return cli.queueRequest(types.ToRequestCheckTx(req)) } func (cli *socketClient) QueryAsync(req types.RequestQuery) *ReqRes { @@ -300,14 +300,14 @@ func (cli *socketClient) SetOptionSync(req types.RequestSetOption) (*types.Respo return reqres.Response.GetSetOption(), cli.Error() } -func (cli *socketClient) DeliverTxSync(tx []byte) (*types.ResponseDeliverTx, error) { - reqres := cli.queueRequest(types.ToRequestDeliverTx(tx)) +func (cli *socketClient) DeliverTxSync(req types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { + reqres := cli.queueRequest(types.ToRequestDeliverTx(req)) cli.FlushSync() return reqres.Response.GetDeliverTx(), cli.Error() } -func (cli *socketClient) CheckTxSync(tx []byte) (*types.ResponseCheckTx, error) { - reqres := cli.queueRequest(types.ToRequestCheckTx(tx)) +func (cli *socketClient) CheckTxSync(req types.RequestCheckTx) (*types.ResponseCheckTx, error) { + reqres := cli.queueRequest(types.ToRequestCheckTx(req)) cli.FlushSync() return reqres.Response.GetCheckTx(), cli.Error() } diff --git a/abci/cmd/abci-cli/abci-cli.go b/abci/cmd/abci-cli/abci-cli.go index 7e55569cb..cd0a6fd1f 100644 --- a/abci/cmd/abci-cli/abci-cli.go +++ b/abci/cmd/abci-cli/abci-cli.go @@ -546,7 +546,7 @@ func cmdDeliverTx(cmd *cobra.Command, args []string) error { if err != nil { return err } - res, err := client.DeliverTxSync(txBytes) + res, err := client.DeliverTxSync(types.RequestDeliverTx{Tx: txBytes}) if err != nil { return err } @@ -572,7 +572,7 @@ func cmdCheckTx(cmd *cobra.Command, args []string) error { if err != nil { return err } - res, err := client.CheckTxSync(txBytes) + res, err := client.CheckTxSync(types.RequestCheckTx{Tx: txBytes}) if err != nil { return err } diff --git a/abci/example/example_test.go b/abci/example/example_test.go index 677a2a481..6282f3a44 100644 --- a/abci/example/example_test.go +++ b/abci/example/example_test.go @@ -87,7 +87,7 @@ func testStream(t *testing.T, app types.Application) { // Write requests for counter := 0; counter < numDeliverTxs; counter++ { // Send request - reqRes := client.DeliverTxAsync([]byte("test")) + reqRes := client.DeliverTxAsync(types.RequestDeliverTx{Tx: []byte("test")}) _ = reqRes // check err ? diff --git a/abci/example/kvstore/kvstore_test.go b/abci/example/kvstore/kvstore_test.go index 074baa49f..1649d3e84 100644 --- a/abci/example/kvstore/kvstore_test.go +++ b/abci/example/kvstore/kvstore_test.go @@ -283,11 +283,11 @@ func runClientTests(t *testing.T, client abcicli.Client) { } func testClient(t *testing.T, app abcicli.Client, tx []byte, key, value string) { - ar, err := app.DeliverTxSync(tx) + ar, err := app.DeliverTxSync(types.RequestDeliverTx{Tx: tx}) require.NoError(t, err) require.False(t, ar.IsErr(), ar) // repeating tx doesn't raise error - ar, err = app.DeliverTxSync(tx) + ar, err = app.DeliverTxSync(types.RequestDeliverTx{Tx: tx}) require.NoError(t, err) require.False(t, ar.IsErr(), ar) diff --git a/abci/tests/server/client.go b/abci/tests/server/client.go index 5daa1e6af..58a413a4e 100644 --- a/abci/tests/server/client.go +++ b/abci/tests/server/client.go @@ -58,7 +58,7 @@ func Commit(client abcicli.Client, hashExp []byte) error { } func DeliverTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) error { - res, _ := client.DeliverTxSync(txBytes) + res, _ := client.DeliverTxSync(types.RequestDeliverTx{Tx: txBytes}) code, data, log := res.Code, res.Data, res.Log if code != codeExp { fmt.Println("Failed test: DeliverTx") @@ -77,7 +77,7 @@ func DeliverTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp [] } func CheckTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) error { - res, _ := client.CheckTxSync(txBytes) + res, _ := client.CheckTxSync(types.RequestCheckTx{Tx: txBytes}) code, data, log := res.Code, res.Data, res.Log if code != codeExp { fmt.Println("Failed test: CheckTx") diff --git a/abci/tests/test_app/app.go b/abci/tests/test_app/app.go index 25ed2f582..9c32fcc7d 100644 --- a/abci/tests/test_app/app.go +++ b/abci/tests/test_app/app.go @@ -43,7 +43,7 @@ func commit(client abcicli.Client, hashExp []byte) { } func deliverTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) { - res, err := client.DeliverTxSync(txBytes) + res, err := client.DeliverTxSync(types.RequestDeliverTx{Tx: txBytes}) if err != nil { panicf("client error: %v", err) } diff --git a/abci/types/messages.go b/abci/types/messages.go index cb64a15d6..ad18727a8 100644 --- a/abci/types/messages.go +++ b/abci/types/messages.go @@ -93,15 +93,15 @@ func ToRequestSetOption(req RequestSetOption) *Request { } } -func ToRequestDeliverTx(tx []byte) *Request { +func ToRequestDeliverTx(req RequestDeliverTx) *Request { return &Request{ - Value: &Request_DeliverTx{&RequestDeliverTx{Tx: tx}}, + Value: &Request_DeliverTx{&req}, } } -func ToRequestCheckTx(tx []byte) *Request { +func ToRequestCheckTx(req RequestCheckTx) *Request { return &Request{ - Value: &Request_CheckTx{&RequestCheckTx{Tx: tx}}, + Value: &Request_CheckTx{&req}, } } diff --git a/abci/types/types.pb.go b/abci/types/types.pb.go index a7455b523..926d528ad 100644 --- a/abci/types/types.pb.go +++ b/abci/types/types.pb.go @@ -38,6 +38,29 @@ var _ = time.Kitchen // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package +type CheckTxType int32 + +const ( + CheckTxType_New CheckTxType = 0 + CheckTxType_Recheck CheckTxType = 1 +) + +var CheckTxType_name = map[int32]string{ + 0: "New", + 1: "Recheck", +} +var CheckTxType_value = map[string]int32{ + "New": 0, + "Recheck": 1, +} + +func (x CheckTxType) String() string { + return proto.EnumName(CheckTxType_name, int32(x)) +} +func (CheckTxType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_types_30d8160a6576aafe, []int{0} +} + type Request struct { // Types that are valid to be assigned to Value: // *Request_Echo @@ -61,7 +84,7 @@ func (m *Request) Reset() { *m = Request{} } func (m *Request) String() string { return proto.CompactTextString(m) } func (*Request) ProtoMessage() {} func (*Request) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{0} + return fileDescriptor_types_30d8160a6576aafe, []int{0} } func (m *Request) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -483,7 +506,7 @@ func (m *RequestEcho) Reset() { *m = RequestEcho{} } func (m *RequestEcho) String() string { return proto.CompactTextString(m) } func (*RequestEcho) ProtoMessage() {} func (*RequestEcho) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{1} + return fileDescriptor_types_30d8160a6576aafe, []int{1} } func (m *RequestEcho) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -529,7 +552,7 @@ func (m *RequestFlush) Reset() { *m = RequestFlush{} } func (m *RequestFlush) String() string { return proto.CompactTextString(m) } func (*RequestFlush) ProtoMessage() {} func (*RequestFlush) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{2} + return fileDescriptor_types_30d8160a6576aafe, []int{2} } func (m *RequestFlush) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -571,7 +594,7 @@ func (m *RequestInfo) Reset() { *m = RequestInfo{} } func (m *RequestInfo) String() string { return proto.CompactTextString(m) } func (*RequestInfo) ProtoMessage() {} func (*RequestInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{3} + return fileDescriptor_types_30d8160a6576aafe, []int{3} } func (m *RequestInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -634,7 +657,7 @@ func (m *RequestSetOption) Reset() { *m = RequestSetOption{} } func (m *RequestSetOption) String() string { return proto.CompactTextString(m) } func (*RequestSetOption) ProtoMessage() {} func (*RequestSetOption) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{4} + return fileDescriptor_types_30d8160a6576aafe, []int{4} } func (m *RequestSetOption) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -692,7 +715,7 @@ func (m *RequestInitChain) Reset() { *m = RequestInitChain{} } func (m *RequestInitChain) String() string { return proto.CompactTextString(m) } func (*RequestInitChain) ProtoMessage() {} func (*RequestInitChain) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{5} + return fileDescriptor_types_30d8160a6576aafe, []int{5} } func (m *RequestInitChain) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -770,7 +793,7 @@ func (m *RequestQuery) Reset() { *m = RequestQuery{} } func (m *RequestQuery) String() string { return proto.CompactTextString(m) } func (*RequestQuery) ProtoMessage() {} func (*RequestQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{6} + return fileDescriptor_types_30d8160a6576aafe, []int{6} } func (m *RequestQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -841,7 +864,7 @@ func (m *RequestBeginBlock) Reset() { *m = RequestBeginBlock{} } func (m *RequestBeginBlock) String() string { return proto.CompactTextString(m) } func (*RequestBeginBlock) ProtoMessage() {} func (*RequestBeginBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{7} + return fileDescriptor_types_30d8160a6576aafe, []int{7} } func (m *RequestBeginBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -899,17 +922,18 @@ func (m *RequestBeginBlock) GetByzantineValidators() []Evidence { } type RequestCheckTx struct { - Tx []byte `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Tx []byte `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"` + Type CheckTxType `protobuf:"varint,2,opt,name=type,proto3,enum=types.CheckTxType" json:"type,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *RequestCheckTx) Reset() { *m = RequestCheckTx{} } func (m *RequestCheckTx) String() string { return proto.CompactTextString(m) } func (*RequestCheckTx) ProtoMessage() {} func (*RequestCheckTx) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{8} + return fileDescriptor_types_30d8160a6576aafe, []int{8} } func (m *RequestCheckTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -945,6 +969,13 @@ func (m *RequestCheckTx) GetTx() []byte { return nil } +func (m *RequestCheckTx) GetType() CheckTxType { + if m != nil { + return m.Type + } + return CheckTxType_New +} + type RequestDeliverTx struct { Tx []byte `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -956,7 +987,7 @@ func (m *RequestDeliverTx) Reset() { *m = RequestDeliverTx{} } func (m *RequestDeliverTx) String() string { return proto.CompactTextString(m) } func (*RequestDeliverTx) ProtoMessage() {} func (*RequestDeliverTx) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{9} + return fileDescriptor_types_30d8160a6576aafe, []int{9} } func (m *RequestDeliverTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1003,7 +1034,7 @@ func (m *RequestEndBlock) Reset() { *m = RequestEndBlock{} } func (m *RequestEndBlock) String() string { return proto.CompactTextString(m) } func (*RequestEndBlock) ProtoMessage() {} func (*RequestEndBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{10} + return fileDescriptor_types_30d8160a6576aafe, []int{10} } func (m *RequestEndBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1049,7 +1080,7 @@ func (m *RequestCommit) Reset() { *m = RequestCommit{} } func (m *RequestCommit) String() string { return proto.CompactTextString(m) } func (*RequestCommit) ProtoMessage() {} func (*RequestCommit) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{11} + return fileDescriptor_types_30d8160a6576aafe, []int{11} } func (m *RequestCommit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1102,7 +1133,7 @@ func (m *Response) Reset() { *m = Response{} } func (m *Response) String() string { return proto.CompactTextString(m) } func (*Response) ProtoMessage() {} func (*Response) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{12} + return fileDescriptor_types_30d8160a6576aafe, []int{12} } func (m *Response) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1555,7 +1586,7 @@ func (m *ResponseException) Reset() { *m = ResponseException{} } func (m *ResponseException) String() string { return proto.CompactTextString(m) } func (*ResponseException) ProtoMessage() {} func (*ResponseException) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{13} + return fileDescriptor_types_30d8160a6576aafe, []int{13} } func (m *ResponseException) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1602,7 +1633,7 @@ func (m *ResponseEcho) Reset() { *m = ResponseEcho{} } func (m *ResponseEcho) String() string { return proto.CompactTextString(m) } func (*ResponseEcho) ProtoMessage() {} func (*ResponseEcho) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{14} + return fileDescriptor_types_30d8160a6576aafe, []int{14} } func (m *ResponseEcho) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1648,7 +1679,7 @@ func (m *ResponseFlush) Reset() { *m = ResponseFlush{} } func (m *ResponseFlush) String() string { return proto.CompactTextString(m) } func (*ResponseFlush) ProtoMessage() {} func (*ResponseFlush) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{15} + return fileDescriptor_types_30d8160a6576aafe, []int{15} } func (m *ResponseFlush) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1692,7 +1723,7 @@ func (m *ResponseInfo) Reset() { *m = ResponseInfo{} } func (m *ResponseInfo) String() string { return proto.CompactTextString(m) } func (*ResponseInfo) ProtoMessage() {} func (*ResponseInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{16} + return fileDescriptor_types_30d8160a6576aafe, []int{16} } func (m *ResponseInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1771,7 +1802,7 @@ func (m *ResponseSetOption) Reset() { *m = ResponseSetOption{} } func (m *ResponseSetOption) String() string { return proto.CompactTextString(m) } func (*ResponseSetOption) ProtoMessage() {} func (*ResponseSetOption) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{17} + return fileDescriptor_types_30d8160a6576aafe, []int{17} } func (m *ResponseSetOption) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1833,7 +1864,7 @@ func (m *ResponseInitChain) Reset() { *m = ResponseInitChain{} } func (m *ResponseInitChain) String() string { return proto.CompactTextString(m) } func (*ResponseInitChain) ProtoMessage() {} func (*ResponseInitChain) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{18} + return fileDescriptor_types_30d8160a6576aafe, []int{18} } func (m *ResponseInitChain) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1896,7 +1927,7 @@ func (m *ResponseQuery) Reset() { *m = ResponseQuery{} } func (m *ResponseQuery) String() string { return proto.CompactTextString(m) } func (*ResponseQuery) ProtoMessage() {} func (*ResponseQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{19} + return fileDescriptor_types_30d8160a6576aafe, []int{19} } func (m *ResponseQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1999,7 +2030,7 @@ func (m *ResponseBeginBlock) Reset() { *m = ResponseBeginBlock{} } func (m *ResponseBeginBlock) String() string { return proto.CompactTextString(m) } func (*ResponseBeginBlock) ProtoMessage() {} func (*ResponseBeginBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{20} + return fileDescriptor_types_30d8160a6576aafe, []int{20} } func (m *ResponseBeginBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2053,7 +2084,7 @@ func (m *ResponseCheckTx) Reset() { *m = ResponseCheckTx{} } func (m *ResponseCheckTx) String() string { return proto.CompactTextString(m) } func (*ResponseCheckTx) ProtoMessage() {} func (*ResponseCheckTx) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{21} + return fileDescriptor_types_30d8160a6576aafe, []int{21} } func (m *ResponseCheckTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2156,7 +2187,7 @@ func (m *ResponseDeliverTx) Reset() { *m = ResponseDeliverTx{} } func (m *ResponseDeliverTx) String() string { return proto.CompactTextString(m) } func (*ResponseDeliverTx) ProtoMessage() {} func (*ResponseDeliverTx) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{22} + return fileDescriptor_types_30d8160a6576aafe, []int{22} } func (m *ResponseDeliverTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2254,7 +2285,7 @@ func (m *ResponseEndBlock) Reset() { *m = ResponseEndBlock{} } func (m *ResponseEndBlock) String() string { return proto.CompactTextString(m) } func (*ResponseEndBlock) ProtoMessage() {} func (*ResponseEndBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{23} + return fileDescriptor_types_30d8160a6576aafe, []int{23} } func (m *ResponseEndBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2316,7 +2347,7 @@ func (m *ResponseCommit) Reset() { *m = ResponseCommit{} } func (m *ResponseCommit) String() string { return proto.CompactTextString(m) } func (*ResponseCommit) ProtoMessage() {} func (*ResponseCommit) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{24} + return fileDescriptor_types_30d8160a6576aafe, []int{24} } func (m *ResponseCommit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2367,7 +2398,7 @@ func (m *ConsensusParams) Reset() { *m = ConsensusParams{} } func (m *ConsensusParams) String() string { return proto.CompactTextString(m) } func (*ConsensusParams) ProtoMessage() {} func (*ConsensusParams) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{25} + return fileDescriptor_types_30d8160a6576aafe, []int{25} } func (m *ConsensusParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2417,7 +2448,7 @@ func (m *ConsensusParams) GetValidator() *ValidatorParams { return nil } -// BlockParams contains limits on the block size and timestamp. +// BlockParams contains limits on the block size. type BlockParams struct { // Note: must be greater than 0 MaxBytes int64 `protobuf:"varint,1,opt,name=max_bytes,json=maxBytes,proto3" json:"max_bytes,omitempty"` @@ -2432,7 +2463,7 @@ func (m *BlockParams) Reset() { *m = BlockParams{} } func (m *BlockParams) String() string { return proto.CompactTextString(m) } func (*BlockParams) ProtoMessage() {} func (*BlockParams) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{26} + return fileDescriptor_types_30d8160a6576aafe, []int{26} } func (m *BlockParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2488,7 +2519,7 @@ func (m *EvidenceParams) Reset() { *m = EvidenceParams{} } func (m *EvidenceParams) String() string { return proto.CompactTextString(m) } func (*EvidenceParams) ProtoMessage() {} func (*EvidenceParams) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{27} + return fileDescriptor_types_30d8160a6576aafe, []int{27} } func (m *EvidenceParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2536,7 +2567,7 @@ func (m *ValidatorParams) Reset() { *m = ValidatorParams{} } func (m *ValidatorParams) String() string { return proto.CompactTextString(m) } func (*ValidatorParams) ProtoMessage() {} func (*ValidatorParams) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{28} + return fileDescriptor_types_30d8160a6576aafe, []int{28} } func (m *ValidatorParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2584,7 +2615,7 @@ func (m *LastCommitInfo) Reset() { *m = LastCommitInfo{} } func (m *LastCommitInfo) String() string { return proto.CompactTextString(m) } func (*LastCommitInfo) ProtoMessage() {} func (*LastCommitInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{29} + return fileDescriptor_types_30d8160a6576aafe, []int{29} } func (m *LastCommitInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2639,7 +2670,7 @@ func (m *Event) Reset() { *m = Event{} } func (m *Event) String() string { return proto.CompactTextString(m) } func (*Event) ProtoMessage() {} func (*Event) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{30} + return fileDescriptor_types_30d8160a6576aafe, []int{30} } func (m *Event) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2713,7 +2744,7 @@ func (m *Header) Reset() { *m = Header{} } func (m *Header) String() string { return proto.CompactTextString(m) } func (*Header) ProtoMessage() {} func (*Header) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{31} + return fileDescriptor_types_30d8160a6576aafe, []int{31} } func (m *Header) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2866,7 +2897,7 @@ func (m *Version) Reset() { *m = Version{} } func (m *Version) String() string { return proto.CompactTextString(m) } func (*Version) ProtoMessage() {} func (*Version) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{32} + return fileDescriptor_types_30d8160a6576aafe, []int{32} } func (m *Version) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2921,7 +2952,7 @@ func (m *BlockID) Reset() { *m = BlockID{} } func (m *BlockID) String() string { return proto.CompactTextString(m) } func (*BlockID) ProtoMessage() {} func (*BlockID) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{33} + return fileDescriptor_types_30d8160a6576aafe, []int{33} } func (m *BlockID) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2976,7 +3007,7 @@ func (m *PartSetHeader) Reset() { *m = PartSetHeader{} } func (m *PartSetHeader) String() string { return proto.CompactTextString(m) } func (*PartSetHeader) ProtoMessage() {} func (*PartSetHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{34} + return fileDescriptor_types_30d8160a6576aafe, []int{34} } func (m *PartSetHeader) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3033,7 +3064,7 @@ func (m *Validator) Reset() { *m = Validator{} } func (m *Validator) String() string { return proto.CompactTextString(m) } func (*Validator) ProtoMessage() {} func (*Validator) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{35} + return fileDescriptor_types_30d8160a6576aafe, []int{35} } func (m *Validator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3089,7 +3120,7 @@ func (m *ValidatorUpdate) Reset() { *m = ValidatorUpdate{} } func (m *ValidatorUpdate) String() string { return proto.CompactTextString(m) } func (*ValidatorUpdate) ProtoMessage() {} func (*ValidatorUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{36} + return fileDescriptor_types_30d8160a6576aafe, []int{36} } func (m *ValidatorUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3145,7 +3176,7 @@ func (m *VoteInfo) Reset() { *m = VoteInfo{} } func (m *VoteInfo) String() string { return proto.CompactTextString(m) } func (*VoteInfo) ProtoMessage() {} func (*VoteInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{37} + return fileDescriptor_types_30d8160a6576aafe, []int{37} } func (m *VoteInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3200,7 +3231,7 @@ func (m *PubKey) Reset() { *m = PubKey{} } func (m *PubKey) String() string { return proto.CompactTextString(m) } func (*PubKey) ProtoMessage() {} func (*PubKey) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{38} + return fileDescriptor_types_30d8160a6576aafe, []int{38} } func (m *PubKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3258,7 +3289,7 @@ func (m *Evidence) Reset() { *m = Evidence{} } func (m *Evidence) String() string { return proto.CompactTextString(m) } func (*Evidence) ProtoMessage() {} func (*Evidence) Descriptor() ([]byte, []int) { - return fileDescriptor_types_62f0c59aeb977f78, []int{39} + return fileDescriptor_types_30d8160a6576aafe, []int{39} } func (m *Evidence) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3403,6 +3434,8 @@ func init() { golang_proto.RegisterType((*PubKey)(nil), "types.PubKey") proto.RegisterType((*Evidence)(nil), "types.Evidence") golang_proto.RegisterType((*Evidence)(nil), "types.Evidence") + proto.RegisterEnum("types.CheckTxType", CheckTxType_name, CheckTxType_value) + golang_proto.RegisterEnum("types.CheckTxType", CheckTxType_name, CheckTxType_value) } func (this *Request) Equal(that interface{}) bool { if that == nil { @@ -3958,6 +3991,9 @@ func (this *RequestCheckTx) Equal(that interface{}) bool { if !bytes.Equal(this.Tx, that1.Tx) { return false } + if this.Type != that1.Type { + return false + } if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { return false } @@ -6211,6 +6247,11 @@ func (m *RequestCheckTx) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintTypes(dAtA, i, uint64(len(m.Tx))) i += copy(dAtA[i:], m.Tx) } + if m.Type != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.Type)) + } if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -7872,8 +7913,9 @@ func NewPopulatedRequestCheckTx(r randyTypes, easy bool) *RequestCheckTx { for i := 0; i < v11; i++ { this.Tx[i] = byte(r.Intn(256)) } + this.Type = CheckTxType([]int32{0, 1}[r.Intn(2)]) if !easy && r.Intn(10) != 0 { - this.XXX_unrecognized = randUnrecognizedTypes(r, 2) + this.XXX_unrecognized = randUnrecognizedTypes(r, 3) } return this } @@ -8906,6 +8948,9 @@ func (m *RequestCheckTx) Size() (n int) { if l > 0 { n += 1 + l + sovTypes(uint64(l)) } + if m.Type != 0 { + n += 1 + sovTypes(uint64(m.Type)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -11127,6 +11172,25 @@ func (m *RequestCheckTx) Unmarshal(dAtA []byte) error { m.Tx = []byte{} } iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + m.Type = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Type |= (CheckTxType(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -15638,152 +15702,154 @@ var ( ErrIntOverflowTypes = fmt.Errorf("proto: integer overflow") ) -func init() { proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_62f0c59aeb977f78) } +func init() { proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_30d8160a6576aafe) } func init() { - golang_proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_62f0c59aeb977f78) -} - -var fileDescriptor_types_62f0c59aeb977f78 = []byte{ - // 2241 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x58, 0x4b, 0x73, 0x1c, 0x49, - 0xf1, 0x57, 0xcf, 0xbb, 0x73, 0x34, 0x0f, 0x97, 0x65, 0x7b, 0x3c, 0x7f, 0xff, 0x25, 0x47, 0x1b, - 0x76, 0x25, 0xd6, 0x3b, 0xda, 0xd5, 0x62, 0x42, 0xc6, 0xcb, 0x46, 0x68, 0x6c, 0x83, 0x14, 0x6b, - 0x40, 0xb4, 0x6d, 0x71, 0x21, 0xa2, 0xa3, 0x66, 0xba, 0x3c, 0xd3, 0xe1, 0x99, 0xee, 0xde, 0xee, - 0x9a, 0xd9, 0x11, 0x47, 0xce, 0x7b, 0xd8, 0x03, 0x1f, 0x81, 0x03, 0x1f, 0x61, 0x8f, 0x9c, 0x88, - 0x3d, 0x72, 0xe0, 0x6c, 0x40, 0x04, 0x17, 0x22, 0x38, 0x03, 0x37, 0xa2, 0xb2, 0xaa, 0x9f, 0xea, - 0x31, 0xbb, 0x86, 0x1b, 0x17, 0xa9, 0xab, 0xf2, 0x97, 0xf5, 0xc8, 0xc9, 0xcc, 0x5f, 0x66, 0xc1, - 0x75, 0x3a, 0x1a, 0x3b, 0xfb, 0xfc, 0xdc, 0x67, 0xa1, 0xfc, 0x3b, 0xf0, 0x03, 0x8f, 0x7b, 0xa4, - 0x8a, 0x83, 0xfe, 0xbb, 0x13, 0x87, 0x4f, 0x17, 0xa3, 0xc1, 0xd8, 0x9b, 0xef, 0x4f, 0xbc, 0x89, - 0xb7, 0x8f, 0xd2, 0xd1, 0xe2, 0x05, 0x8e, 0x70, 0x80, 0x5f, 0x52, 0xab, 0xff, 0x20, 0x05, 0xe7, - 0xcc, 0xb5, 0x59, 0x30, 0x77, 0x5c, 0x9e, 0xfe, 0x1c, 0x07, 0xe7, 0x3e, 0xf7, 0xf6, 0xe7, 0x2c, - 0x78, 0x39, 0x63, 0xea, 0x9f, 0x52, 0x3e, 0xfc, 0xb7, 0xca, 0x33, 0x67, 0x14, 0xee, 0x8f, 0xbd, - 0xf9, 0xdc, 0x73, 0xd3, 0x87, 0xed, 0xef, 0x4c, 0x3c, 0x6f, 0x32, 0x63, 0xc9, 0xe1, 0xb8, 0x33, - 0x67, 0x21, 0xa7, 0x73, 0x5f, 0x02, 0x8c, 0xdf, 0x56, 0xa0, 0x6e, 0xb2, 0x4f, 0x16, 0x2c, 0xe4, - 0x64, 0x17, 0x2a, 0x6c, 0x3c, 0xf5, 0x7a, 0xa5, 0xdb, 0xda, 0x6e, 0xf3, 0x80, 0x0c, 0xe4, 0x42, - 0x4a, 0xfa, 0x78, 0x3c, 0xf5, 0x8e, 0x37, 0x4c, 0x44, 0x90, 0x77, 0xa0, 0xfa, 0x62, 0xb6, 0x08, - 0xa7, 0xbd, 0x32, 0x42, 0xaf, 0x66, 0xa1, 0xdf, 0x17, 0xa2, 0xe3, 0x0d, 0x53, 0x62, 0xc4, 0xb2, - 0x8e, 0xfb, 0xc2, 0xeb, 0x55, 0x8a, 0x96, 0x3d, 0x71, 0x5f, 0xe0, 0xb2, 0x02, 0x41, 0x0e, 0x01, - 0x42, 0xc6, 0x2d, 0xcf, 0xe7, 0x8e, 0xe7, 0xf6, 0xaa, 0x88, 0xbf, 0x91, 0xc5, 0x3f, 0x65, 0xfc, - 0xc7, 0x28, 0x3e, 0xde, 0x30, 0xf5, 0x30, 0x1a, 0x08, 0x4d, 0xc7, 0x75, 0xb8, 0x35, 0x9e, 0x52, - 0xc7, 0xed, 0xd5, 0x8a, 0x34, 0x4f, 0x5c, 0x87, 0x3f, 0x14, 0x62, 0xa1, 0xe9, 0x44, 0x03, 0x71, - 0x95, 0x4f, 0x16, 0x2c, 0x38, 0xef, 0xd5, 0x8b, 0xae, 0xf2, 0x13, 0x21, 0x12, 0x57, 0x41, 0x0c, - 0x79, 0x00, 0xcd, 0x11, 0x9b, 0x38, 0xae, 0x35, 0x9a, 0x79, 0xe3, 0x97, 0xbd, 0x06, 0xaa, 0xf4, - 0xb2, 0x2a, 0x43, 0x01, 0x18, 0x0a, 0xf9, 0xf1, 0x86, 0x09, 0xa3, 0x78, 0x44, 0x0e, 0xa0, 0x31, - 0x9e, 0xb2, 0xf1, 0x4b, 0x8b, 0xaf, 0x7a, 0x3a, 0x6a, 0x5e, 0xcb, 0x6a, 0x3e, 0x14, 0xd2, 0x67, - 0xab, 0xe3, 0x0d, 0xb3, 0x3e, 0x96, 0x9f, 0xe4, 0x1e, 0xe8, 0xcc, 0xb5, 0xd5, 0x76, 0x4d, 0x54, - 0xba, 0x9e, 0xfb, 0x5d, 0x5c, 0x3b, 0xda, 0xac, 0xc1, 0xd4, 0x37, 0x19, 0x40, 0x4d, 0x38, 0x83, - 0xc3, 0x7b, 0x9b, 0xa8, 0xb3, 0x95, 0xdb, 0x08, 0x65, 0xc7, 0x1b, 0xa6, 0x42, 0x09, 0xf3, 0xd9, - 0x6c, 0xe6, 0x2c, 0x59, 0x20, 0x0e, 0x77, 0xb5, 0xc8, 0x7c, 0x8f, 0xa4, 0x1c, 0x8f, 0xa7, 0xdb, - 0xd1, 0x60, 0x58, 0x87, 0xea, 0x92, 0xce, 0x16, 0xcc, 0x78, 0x1b, 0x9a, 0x29, 0x4f, 0x21, 0x3d, - 0xa8, 0xcf, 0x59, 0x18, 0xd2, 0x09, 0xeb, 0x69, 0xb7, 0xb5, 0x5d, 0xdd, 0x8c, 0x86, 0x46, 0x1b, - 0x36, 0xd3, 0x7e, 0x62, 0xcc, 0x63, 0x45, 0xe1, 0x0b, 0x42, 0x71, 0xc9, 0x82, 0x50, 0x38, 0x80, - 0x52, 0x54, 0x43, 0x72, 0x07, 0x5a, 0x68, 0x07, 0x2b, 0x92, 0x0b, 0x3f, 0xad, 0x98, 0x9b, 0x38, - 0x79, 0xa6, 0x40, 0x3b, 0xd0, 0xf4, 0x0f, 0xfc, 0x18, 0x52, 0x46, 0x08, 0xf8, 0x07, 0xbe, 0x02, - 0x18, 0xdf, 0x85, 0x6e, 0xde, 0x95, 0x48, 0x17, 0xca, 0x2f, 0xd9, 0xb9, 0xda, 0x4f, 0x7c, 0x92, - 0x2d, 0x75, 0x2d, 0xdc, 0x43, 0x37, 0xd5, 0x1d, 0x3f, 0x2f, 0xc5, 0xca, 0xb1, 0x37, 0x91, 0x43, - 0xa8, 0x88, 0xa0, 0x42, 0xed, 0xe6, 0x41, 0x7f, 0x20, 0x23, 0x6e, 0x10, 0x45, 0xdc, 0xe0, 0x59, - 0x14, 0x71, 0xc3, 0xc6, 0x97, 0xaf, 0x76, 0x36, 0x3e, 0xff, 0xc3, 0x8e, 0x66, 0xa2, 0x06, 0xb9, - 0x29, 0x1c, 0x82, 0x3a, 0xae, 0xe5, 0xd8, 0x6a, 0x9f, 0x3a, 0x8e, 0x4f, 0x6c, 0x72, 0x04, 0xdd, - 0xb1, 0xe7, 0x86, 0xcc, 0x0d, 0x17, 0xa1, 0xe5, 0xd3, 0x80, 0xce, 0x43, 0x15, 0x6b, 0xd1, 0xcf, - 0xff, 0x30, 0x12, 0x9f, 0xa2, 0xd4, 0xec, 0x8c, 0xb3, 0x13, 0xe4, 0x43, 0x80, 0x25, 0x9d, 0x39, - 0x36, 0xe5, 0x5e, 0x10, 0xf6, 0x2a, 0xb7, 0xcb, 0x29, 0xe5, 0xb3, 0x48, 0xf0, 0xdc, 0xb7, 0x29, - 0x67, 0xc3, 0x8a, 0x38, 0x99, 0x99, 0xc2, 0x93, 0xb7, 0xa0, 0x43, 0x7d, 0xdf, 0x0a, 0x39, 0xe5, - 0xcc, 0x1a, 0x9d, 0x73, 0x16, 0x62, 0x3c, 0x6e, 0x9a, 0x2d, 0xea, 0xfb, 0x4f, 0xc5, 0xec, 0x50, - 0x4c, 0x1a, 0x76, 0xfc, 0x6b, 0x62, 0xa8, 0x10, 0x02, 0x15, 0x9b, 0x72, 0x8a, 0xd6, 0xd8, 0x34, - 0xf1, 0x5b, 0xcc, 0xf9, 0x94, 0x4f, 0xd5, 0x1d, 0xf1, 0x9b, 0x5c, 0x87, 0xda, 0x94, 0x39, 0x93, - 0x29, 0xc7, 0x6b, 0x95, 0x4d, 0x35, 0x12, 0x86, 0xf7, 0x03, 0x6f, 0xc9, 0x30, 0x5b, 0x34, 0x4c, - 0x39, 0x30, 0xfe, 0xa2, 0xc1, 0x95, 0x4b, 0xe1, 0x25, 0xd6, 0x9d, 0xd2, 0x70, 0x1a, 0xed, 0x25, - 0xbe, 0xc9, 0x3b, 0x62, 0x5d, 0x6a, 0xb3, 0x40, 0x65, 0xb1, 0x96, 0xba, 0xf1, 0x31, 0x4e, 0xaa, - 0x8b, 0x2a, 0x08, 0x79, 0x0c, 0xdd, 0x19, 0x0d, 0xb9, 0x25, 0xa3, 0xc0, 0xc2, 0x2c, 0x55, 0xce, - 0x44, 0xe6, 0x13, 0x1a, 0x45, 0x8b, 0x70, 0x4e, 0xa5, 0xde, 0x9e, 0x65, 0x66, 0xc9, 0x31, 0x6c, - 0x8d, 0xce, 0x7f, 0x4e, 0x5d, 0xee, 0xb8, 0xcc, 0xba, 0x64, 0xf3, 0x8e, 0x5a, 0xea, 0xf1, 0xd2, - 0xb1, 0x99, 0x3b, 0x8e, 0x8c, 0x7d, 0x35, 0x56, 0x89, 0x7f, 0x8c, 0xd0, 0xb8, 0x0d, 0xed, 0x6c, - 0x2e, 0x20, 0x6d, 0x28, 0xf1, 0x95, 0xba, 0x61, 0x89, 0xaf, 0x0c, 0x23, 0xf6, 0xc0, 0x38, 0x20, - 0x2f, 0x61, 0xf6, 0xa0, 0x93, 0x4b, 0x0e, 0x29, 0x73, 0x6b, 0x69, 0x73, 0x1b, 0x1d, 0x68, 0x65, - 0x72, 0x82, 0xf1, 0x59, 0x15, 0x1a, 0x26, 0x0b, 0x7d, 0xe1, 0x4c, 0xe4, 0x10, 0x74, 0xb6, 0x1a, - 0x33, 0x99, 0x8e, 0xb5, 0x5c, 0xb2, 0x93, 0x98, 0xc7, 0x91, 0x5c, 0xa4, 0x85, 0x18, 0x4c, 0xf6, - 0x32, 0x54, 0x72, 0x35, 0xaf, 0x94, 0xe6, 0x92, 0xbb, 0x59, 0x2e, 0xd9, 0xca, 0x61, 0x73, 0x64, - 0xb2, 0x97, 0x21, 0x93, 0xfc, 0xc2, 0x19, 0x36, 0xb9, 0x5f, 0xc0, 0x26, 0xf9, 0xe3, 0xaf, 0xa1, - 0x93, 0xfb, 0x05, 0x74, 0xd2, 0xbb, 0xb4, 0x57, 0x21, 0x9f, 0xdc, 0xcd, 0xf2, 0x49, 0xfe, 0x3a, - 0x39, 0x42, 0xf9, 0xb0, 0x88, 0x50, 0x6e, 0xe6, 0x74, 0xd6, 0x32, 0xca, 0x07, 0x97, 0x18, 0xe5, - 0x7a, 0x4e, 0xb5, 0x80, 0x52, 0xee, 0x67, 0x72, 0x3d, 0x14, 0xde, 0xad, 0x38, 0xd9, 0x93, 0xef, - 0x5c, 0x66, 0xa3, 0x1b, 0xf9, 0x9f, 0xb6, 0x88, 0x8e, 0xf6, 0x73, 0x74, 0x74, 0x2d, 0x7f, 0xca, - 0x1c, 0x1f, 0x25, 0xac, 0xb2, 0x27, 0xe2, 0x3e, 0xe7, 0x69, 0x22, 0x47, 0xb0, 0x20, 0xf0, 0x02, - 0x95, 0xb0, 0xe5, 0xc0, 0xd8, 0x15, 0x99, 0x28, 0xf1, 0xaf, 0xd7, 0x30, 0x10, 0x3a, 0x7d, 0xca, - 0xbb, 0x8c, 0x2f, 0xb4, 0x44, 0x17, 0x23, 0x3a, 0x9d, 0xc5, 0x74, 0x95, 0xc5, 0x52, 0xc4, 0x54, - 0xca, 0x12, 0xd3, 0x0e, 0x34, 0x45, 0xae, 0xcc, 0x71, 0x0e, 0xf5, 0x23, 0xce, 0x21, 0xdf, 0x82, - 0x2b, 0x98, 0x67, 0x24, 0x7d, 0xa9, 0x40, 0xac, 0x60, 0x20, 0x76, 0x84, 0x40, 0x5a, 0x4c, 0x26, - 0xc0, 0x77, 0xe1, 0x6a, 0x0a, 0x2b, 0xd6, 0xc5, 0x1c, 0x27, 0x93, 0x6f, 0x37, 0x46, 0x1f, 0xf9, - 0xfe, 0x31, 0x0d, 0xa7, 0xc6, 0x0f, 0x13, 0x03, 0x25, 0x7c, 0x46, 0xa0, 0x32, 0xf6, 0x6c, 0x79, - 0xef, 0x96, 0x89, 0xdf, 0x82, 0xe3, 0x66, 0xde, 0x04, 0x0f, 0xa7, 0x9b, 0xe2, 0x53, 0xa0, 0xe2, - 0x50, 0xd2, 0x65, 0xcc, 0x18, 0xbf, 0xd4, 0x92, 0xf5, 0x12, 0x8a, 0x2b, 0x62, 0x23, 0xed, 0x3f, - 0x61, 0xa3, 0xd2, 0xd7, 0x63, 0x23, 0xe3, 0x42, 0x4b, 0x7e, 0xb2, 0x98, 0x67, 0xde, 0xec, 0x8a, - 0xc2, 0x7b, 0x1c, 0xd7, 0x66, 0x2b, 0x34, 0x69, 0xd9, 0x94, 0x83, 0xa8, 0x04, 0xa8, 0xa1, 0x99, - 0xb3, 0x25, 0x40, 0x1d, 0xe7, 0xe4, 0x80, 0xdc, 0x41, 0x7e, 0xf2, 0x5e, 0xa8, 0x50, 0x6d, 0x0d, - 0x54, 0xa1, 0x7e, 0x2a, 0x26, 0x4d, 0x29, 0x4b, 0x65, 0x5b, 0x3d, 0x43, 0x6e, 0xb7, 0x40, 0x17, - 0x07, 0x0d, 0x7d, 0x3a, 0x66, 0x18, 0x79, 0xba, 0x99, 0x4c, 0x18, 0xcf, 0x80, 0x5c, 0x8e, 0x78, - 0xf2, 0x11, 0xd4, 0xd8, 0x92, 0xb9, 0x5c, 0x58, 0x5c, 0x18, 0x6d, 0x33, 0xa6, 0x13, 0xe6, 0xf2, - 0x61, 0x4f, 0x98, 0xea, 0xaf, 0xaf, 0x76, 0xba, 0x12, 0x73, 0xd7, 0x9b, 0x3b, 0x9c, 0xcd, 0x7d, - 0x7e, 0x6e, 0x2a, 0x2d, 0xe3, 0xef, 0x9a, 0x60, 0x83, 0x4c, 0x36, 0x28, 0x34, 0x5e, 0xe4, 0xf2, - 0xa5, 0x14, 0x71, 0x7f, 0x35, 0x83, 0xfe, 0x3f, 0xc0, 0x84, 0x86, 0xd6, 0xa7, 0xd4, 0xe5, 0xcc, - 0x56, 0x56, 0xd5, 0x27, 0x34, 0xfc, 0x29, 0x4e, 0x88, 0x2a, 0x47, 0x88, 0x17, 0x21, 0xb3, 0xd1, - 0xbc, 0x65, 0xb3, 0x3e, 0xa1, 0xe1, 0xf3, 0x90, 0xd9, 0xa9, 0xbb, 0xd5, 0xdf, 0xe4, 0x6e, 0x59, - 0x7b, 0x36, 0xf2, 0xf6, 0xfc, 0x67, 0xca, 0x97, 0x13, 0xb2, 0xfc, 0xdf, 0xb8, 0xfb, 0xdf, 0x34, - 0x51, 0x27, 0x64, 0x53, 0x32, 0x39, 0x81, 0x2b, 0x71, 0x4c, 0x59, 0x0b, 0x8c, 0xb5, 0xc8, 0xab, - 0x5e, 0x1f, 0x8a, 0xdd, 0x65, 0x76, 0x3a, 0x24, 0x3f, 0x82, 0x1b, 0xb9, 0x8c, 0x10, 0x2f, 0x58, - 0x7a, 0x6d, 0x62, 0xb8, 0x96, 0x4d, 0x0c, 0xd1, 0x7a, 0x89, 0x35, 0xca, 0x6f, 0xe4, 0xe5, 0xdf, - 0x10, 0x85, 0x53, 0x9a, 0x4c, 0x8a, 0x7e, 0x53, 0xe3, 0x57, 0x1a, 0x74, 0x72, 0x07, 0x22, 0xbb, - 0x50, 0x95, 0x7c, 0xa6, 0x65, 0xda, 0x53, 0xb4, 0x98, 0x3a, 0xb3, 0x04, 0x90, 0xf7, 0xa1, 0xc1, - 0x54, 0x0d, 0xa7, 0x2e, 0x79, 0x2d, 0x57, 0xda, 0x29, 0x7c, 0x0c, 0x23, 0xdf, 0x06, 0x3d, 0x36, - 0x5d, 0xae, 0x7e, 0x8f, 0x2d, 0xad, 0x94, 0x12, 0xa0, 0xf1, 0x10, 0x9a, 0xa9, 0xed, 0xc9, 0xff, - 0x81, 0x3e, 0xa7, 0x2b, 0x55, 0x84, 0xcb, 0xf2, 0xad, 0x31, 0xa7, 0x2b, 0xac, 0xbf, 0xc9, 0x0d, - 0xa8, 0x0b, 0xe1, 0x84, 0x4a, 0xc3, 0x97, 0xcd, 0xda, 0x9c, 0xae, 0x7e, 0x40, 0x43, 0x63, 0x0f, - 0xda, 0xd9, 0x63, 0x45, 0xd0, 0x88, 0x10, 0x25, 0xf4, 0x68, 0xc2, 0x8c, 0x7b, 0xd0, 0xc9, 0x9d, - 0x86, 0x18, 0xd0, 0xf2, 0x17, 0x23, 0xeb, 0x25, 0x3b, 0xb7, 0xf0, 0xb8, 0xe8, 0x26, 0xba, 0xd9, - 0xf4, 0x17, 0xa3, 0x8f, 0xd9, 0xf9, 0x33, 0x31, 0x65, 0x3c, 0x85, 0x76, 0xb6, 0x3c, 0x16, 0x29, - 0x33, 0xf0, 0x16, 0xae, 0x8d, 0xeb, 0x57, 0x4d, 0x39, 0x10, 0x1d, 0xf6, 0xd2, 0x93, 0x9e, 0x91, - 0xae, 0x87, 0xcf, 0x3c, 0xce, 0x52, 0x45, 0xb5, 0xc4, 0x18, 0x0e, 0x54, 0xf1, 0x37, 0x17, 0xbf, - 0x9f, 0xc0, 0x45, 0x14, 0x2c, 0xbe, 0xc9, 0x13, 0x00, 0xca, 0x79, 0xe0, 0x8c, 0x16, 0xc9, 0x72, - 0xed, 0x81, 0x7c, 0xf6, 0x18, 0x7c, 0x7c, 0x76, 0x4a, 0x9d, 0x60, 0x78, 0x4b, 0xf9, 0xca, 0x56, - 0x82, 0x4c, 0xf9, 0x4b, 0x4a, 0xdf, 0xf8, 0x45, 0x15, 0x6a, 0xb2, 0x2d, 0x20, 0x83, 0x6c, 0xd3, - 0x29, 0x56, 0x55, 0x87, 0x94, 0xb3, 0xea, 0x8c, 0x31, 0xe3, 0xbf, 0x95, 0xef, 0xdc, 0x86, 0xcd, - 0x8b, 0x57, 0x3b, 0x75, 0x64, 0xcb, 0x93, 0x47, 0x49, 0x1b, 0xb7, 0xae, 0xcb, 0x89, 0x7a, 0xc6, - 0xca, 0xd7, 0xee, 0x19, 0x6f, 0x40, 0xdd, 0x5d, 0xcc, 0x2d, 0xbe, 0x0a, 0x55, 0xb6, 0xa9, 0xb9, - 0x8b, 0xf9, 0xb3, 0x15, 0x7a, 0x09, 0xf7, 0x38, 0x9d, 0xa1, 0x48, 0xe6, 0x9a, 0x06, 0x4e, 0x08, - 0xe1, 0x21, 0xb4, 0x52, 0x45, 0x85, 0x63, 0xab, 0xe2, 0xb4, 0x9d, 0x76, 0xf6, 0x93, 0x47, 0xea, - 0x96, 0xcd, 0xb8, 0xc8, 0x38, 0xb1, 0xc9, 0x6e, 0xb6, 0x45, 0xc2, 0x5a, 0xa4, 0x81, 0x21, 0x95, - 0xea, 0x82, 0x44, 0x25, 0x22, 0x0e, 0x20, 0x82, 0x4c, 0x42, 0x74, 0x84, 0x34, 0xc4, 0x04, 0x0a, - 0xdf, 0x86, 0x4e, 0x42, 0xe7, 0x12, 0x02, 0x72, 0x95, 0x64, 0x1a, 0x81, 0xef, 0xc1, 0x96, 0xcb, - 0x56, 0xdc, 0xca, 0xa3, 0x9b, 0x88, 0x26, 0x42, 0x76, 0x96, 0xd5, 0xf8, 0x26, 0xb4, 0x93, 0x54, - 0x84, 0xd8, 0x4d, 0xd9, 0xa8, 0xc6, 0xb3, 0x08, 0xbb, 0x09, 0x8d, 0xb8, 0x98, 0x6a, 0x21, 0xa0, - 0x4e, 0x65, 0x0d, 0x15, 0x97, 0x67, 0x01, 0x0b, 0x17, 0x33, 0xae, 0x16, 0x69, 0x23, 0x06, 0xcb, - 0x33, 0x53, 0xce, 0x23, 0xf6, 0x0e, 0xb4, 0xa2, 0xe8, 0x96, 0xb8, 0x0e, 0xe2, 0x36, 0xa3, 0x49, - 0x04, 0xed, 0x41, 0xd7, 0x0f, 0x3c, 0xdf, 0x0b, 0x59, 0x60, 0x51, 0xdb, 0x0e, 0x58, 0x18, 0xf6, - 0xba, 0x72, 0xbd, 0x68, 0xfe, 0x48, 0x4e, 0x1b, 0xef, 0x43, 0x3d, 0xaa, 0x12, 0xb7, 0xa0, 0x3a, - 0x8c, 0x33, 0x51, 0xc5, 0x94, 0x03, 0xc1, 0x43, 0x47, 0xbe, 0xaf, 0xde, 0x3a, 0xc4, 0xa7, 0xf1, - 0x33, 0xa8, 0xab, 0x1f, 0xac, 0xb0, 0x03, 0xfe, 0x1e, 0x6c, 0xfa, 0x34, 0x10, 0xd7, 0x48, 0xf7, - 0xc1, 0x51, 0x1f, 0x72, 0x4a, 0x03, 0xfe, 0x94, 0xf1, 0x4c, 0x3b, 0xdc, 0x44, 0xbc, 0x9c, 0x32, - 0xee, 0x43, 0x2b, 0x83, 0x11, 0xc7, 0x42, 0x3f, 0x8a, 0x82, 0x1a, 0x07, 0xf1, 0xce, 0xa5, 0x64, - 0x67, 0xe3, 0x01, 0xe8, 0xf1, 0x6f, 0x23, 0xca, 0xe5, 0xe8, 0xea, 0x9a, 0x32, 0xb7, 0x1c, 0x62, - 0x8b, 0xef, 0x7d, 0xca, 0x02, 0x15, 0x13, 0x72, 0x60, 0x3c, 0x4f, 0x25, 0x21, 0xc9, 0x0a, 0xe4, - 0x2e, 0xd4, 0x55, 0x12, 0x52, 0x51, 0x19, 0x35, 0xf3, 0xa7, 0x98, 0x85, 0xa2, 0x66, 0x5e, 0xe6, - 0xa4, 0x64, 0xd9, 0x52, 0x7a, 0xd9, 0x19, 0x34, 0xa2, 0x44, 0x93, 0xcd, 0xc6, 0x72, 0xc5, 0x6e, - 0x3e, 0x1b, 0xab, 0x45, 0x13, 0xa0, 0xf0, 0x8e, 0xd0, 0x99, 0xb8, 0xcc, 0xb6, 0x92, 0x10, 0xc2, - 0x3d, 0x1a, 0x66, 0x47, 0x0a, 0x9e, 0x44, 0xf1, 0x62, 0xbc, 0x07, 0x35, 0x79, 0xb6, 0xc2, 0xf4, - 0x55, 0x44, 0x49, 0xbf, 0xd7, 0xa0, 0x11, 0xe5, 0xe9, 0x42, 0xa5, 0xcc, 0xa1, 0x4b, 0x5f, 0xf5, - 0xd0, 0xff, 0xfd, 0xc4, 0x73, 0x17, 0x88, 0xcc, 0x2f, 0x4b, 0x8f, 0x3b, 0xee, 0xc4, 0x92, 0xb6, - 0x96, 0x39, 0xa8, 0x8b, 0x92, 0x33, 0x14, 0x9c, 0x8a, 0xf9, 0x83, 0xcf, 0xaa, 0xd0, 0x39, 0x1a, - 0x3e, 0x3c, 0x39, 0xf2, 0xfd, 0x99, 0x33, 0xa6, 0xd8, 0x95, 0xec, 0x43, 0x05, 0x1b, 0xb3, 0x82, - 0x87, 0xe5, 0x7e, 0xd1, 0x0b, 0x01, 0x39, 0x80, 0x2a, 0xf6, 0x67, 0xa4, 0xe8, 0x7d, 0xb9, 0x5f, - 0xf8, 0x50, 0x20, 0x36, 0x91, 0x1d, 0xdc, 0xe5, 0x67, 0xe6, 0x7e, 0xd1, 0x6b, 0x01, 0xf9, 0x08, - 0xf4, 0xa4, 0x71, 0x5a, 0xf7, 0xd8, 0xdc, 0x5f, 0xfb, 0x6e, 0x20, 0xf4, 0x93, 0xe2, 0x72, 0xdd, - 0x9b, 0x69, 0x7f, 0x6d, 0x83, 0x4d, 0x0e, 0xa1, 0x1e, 0x95, 0xe5, 0xc5, 0xcf, 0xc1, 0xfd, 0x35, - 0x3d, 0xbd, 0x30, 0x8f, 0xec, 0x85, 0x8a, 0xde, 0xac, 0xfb, 0x85, 0x0f, 0x0f, 0xe4, 0x1e, 0xd4, - 0x54, 0x7d, 0x54, 0xf8, 0x24, 0xdc, 0x2f, 0xee, 0xcc, 0xc5, 0x25, 0x93, 0x6e, 0x70, 0xdd, 0xbb, - 0x7a, 0x7f, 0xed, 0x0b, 0x09, 0x39, 0x02, 0x48, 0xb5, 0x34, 0x6b, 0x1f, 0xcc, 0xfb, 0xeb, 0x5f, - 0x3e, 0xc8, 0x03, 0x68, 0x24, 0xaf, 0x59, 0xc5, 0x4f, 0xe0, 0xfd, 0x75, 0x8f, 0x11, 0xc3, 0x5b, - 0xff, 0xf8, 0xd3, 0xb6, 0xf6, 0xeb, 0x8b, 0x6d, 0xed, 0x8b, 0x8b, 0x6d, 0xed, 0xcb, 0x8b, 0x6d, - 0xed, 0x77, 0x17, 0xdb, 0xda, 0x1f, 0x2f, 0xb6, 0xb5, 0xdf, 0xfc, 0x79, 0x5b, 0x1b, 0xd5, 0xd0, - 0xfd, 0x3f, 0xf8, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3e, 0x33, 0xc0, 0x3b, 0xf2, 0x19, 0x00, - 0x00, + golang_proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_30d8160a6576aafe) +} + +var fileDescriptor_types_30d8160a6576aafe = []byte{ + // 2282 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x58, 0xcd, 0x73, 0x1c, 0x47, + 0x15, 0xd7, 0xec, 0xf7, 0xbc, 0xd5, 0x7e, 0xb8, 0x2d, 0xdb, 0xeb, 0xc5, 0x48, 0xae, 0x31, 0x38, + 0x52, 0xe2, 0xac, 0x12, 0x05, 0x53, 0x32, 0x0e, 0xa9, 0xd2, 0xda, 0x06, 0xa9, 0x62, 0x82, 0x18, + 0xdb, 0xe2, 0x42, 0xd5, 0x54, 0xef, 0x4e, 0x7b, 0x77, 0xca, 0xbb, 0x33, 0x93, 0x99, 0x5e, 0x79, + 0xc5, 0x91, 0x73, 0x0e, 0x39, 0xf0, 0x27, 0x70, 0xe0, 0x4f, 0xc8, 0x91, 0x13, 0x95, 0x23, 0x07, + 0xce, 0x06, 0x44, 0x71, 0xa1, 0x8a, 0x33, 0x70, 0xa3, 0xfa, 0x75, 0xcf, 0xa7, 0x66, 0x4d, 0x62, + 0xb8, 0xe5, 0xb2, 0x3b, 0xdd, 0xef, 0xf7, 0x7a, 0xba, 0xdf, 0xbc, 0xf7, 0x7e, 0xef, 0x35, 0x5c, + 0xa5, 0xa3, 0xb1, 0xb3, 0xcb, 0xcf, 0x7c, 0x16, 0xca, 0xdf, 0x81, 0x1f, 0x78, 0xdc, 0x23, 0x55, + 0x1c, 0xf4, 0xdf, 0x9d, 0x38, 0x7c, 0xba, 0x18, 0x0d, 0xc6, 0xde, 0x7c, 0x77, 0xe2, 0x4d, 0xbc, + 0x5d, 0x94, 0x8e, 0x16, 0xcf, 0x71, 0x84, 0x03, 0x7c, 0x92, 0x5a, 0xfd, 0xfb, 0x29, 0x38, 0x67, + 0xae, 0xcd, 0x82, 0xb9, 0xe3, 0xf2, 0xf4, 0xe3, 0x38, 0x38, 0xf3, 0xb9, 0xb7, 0x3b, 0x67, 0xc1, + 0x8b, 0x19, 0x53, 0x7f, 0x4a, 0x79, 0xff, 0xbf, 0x2a, 0xcf, 0x9c, 0x51, 0xb8, 0x3b, 0xf6, 0xe6, + 0x73, 0xcf, 0x4d, 0x6f, 0xb6, 0xbf, 0x35, 0xf1, 0xbc, 0xc9, 0x8c, 0x25, 0x9b, 0xe3, 0xce, 0x9c, + 0x85, 0x9c, 0xce, 0x7d, 0x09, 0x30, 0x7e, 0x5f, 0x81, 0xba, 0xc9, 0x3e, 0x5d, 0xb0, 0x90, 0x93, + 0x6d, 0xa8, 0xb0, 0xf1, 0xd4, 0xeb, 0x95, 0x6e, 0x6a, 0xdb, 0xcd, 0x3d, 0x32, 0x90, 0x0b, 0x29, + 0xe9, 0xa3, 0xf1, 0xd4, 0x3b, 0x5c, 0x33, 0x11, 0x41, 0xde, 0x81, 0xea, 0xf3, 0xd9, 0x22, 0x9c, + 0xf6, 0xca, 0x08, 0xbd, 0x9c, 0x85, 0xfe, 0x48, 0x88, 0x0e, 0xd7, 0x4c, 0x89, 0x11, 0xcb, 0x3a, + 0xee, 0x73, 0xaf, 0x57, 0x29, 0x5a, 0xf6, 0xc8, 0x7d, 0x8e, 0xcb, 0x0a, 0x04, 0xd9, 0x07, 0x08, + 0x19, 0xb7, 0x3c, 0x9f, 0x3b, 0x9e, 0xdb, 0xab, 0x22, 0xfe, 0x5a, 0x16, 0xff, 0x84, 0xf1, 0x9f, + 0xa2, 0xf8, 0x70, 0xcd, 0xd4, 0xc3, 0x68, 0x20, 0x34, 0x1d, 0xd7, 0xe1, 0xd6, 0x78, 0x4a, 0x1d, + 0xb7, 0x57, 0x2b, 0xd2, 0x3c, 0x72, 0x1d, 0xfe, 0x40, 0x88, 0x85, 0xa6, 0x13, 0x0d, 0xc4, 0x51, + 0x3e, 0x5d, 0xb0, 0xe0, 0xac, 0x57, 0x2f, 0x3a, 0xca, 0xcf, 0x84, 0x48, 0x1c, 0x05, 0x31, 0xe4, + 0x3e, 0x34, 0x47, 0x6c, 0xe2, 0xb8, 0xd6, 0x68, 0xe6, 0x8d, 0x5f, 0xf4, 0x1a, 0xa8, 0xd2, 0xcb, + 0xaa, 0x0c, 0x05, 0x60, 0x28, 0xe4, 0x87, 0x6b, 0x26, 0x8c, 0xe2, 0x11, 0xd9, 0x83, 0xc6, 0x78, + 0xca, 0xc6, 0x2f, 0x2c, 0xbe, 0xec, 0xe9, 0xa8, 0x79, 0x25, 0xab, 0xf9, 0x40, 0x48, 0x9f, 0x2e, + 0x0f, 0xd7, 0xcc, 0xfa, 0x58, 0x3e, 0x92, 0xbb, 0xa0, 0x33, 0xd7, 0x56, 0xaf, 0x6b, 0xa2, 0xd2, + 0xd5, 0xdc, 0x77, 0x71, 0xed, 0xe8, 0x65, 0x0d, 0xa6, 0x9e, 0xc9, 0x00, 0x6a, 0xc2, 0x19, 0x1c, + 0xde, 0x5b, 0x47, 0x9d, 0x8d, 0xdc, 0x8b, 0x50, 0x76, 0xb8, 0x66, 0x2a, 0x94, 0x30, 0x9f, 0xcd, + 0x66, 0xce, 0x29, 0x0b, 0xc4, 0xe6, 0x2e, 0x17, 0x99, 0xef, 0xa1, 0x94, 0xe3, 0xf6, 0x74, 0x3b, + 0x1a, 0x0c, 0xeb, 0x50, 0x3d, 0xa5, 0xb3, 0x05, 0x33, 0xde, 0x82, 0x66, 0xca, 0x53, 0x48, 0x0f, + 0xea, 0x73, 0x16, 0x86, 0x74, 0xc2, 0x7a, 0xda, 0x4d, 0x6d, 0x5b, 0x37, 0xa3, 0xa1, 0xd1, 0x86, + 0xf5, 0xb4, 0x9f, 0x18, 0xf3, 0x58, 0x51, 0xf8, 0x82, 0x50, 0x3c, 0x65, 0x41, 0x28, 0x1c, 0x40, + 0x29, 0xaa, 0x21, 0xb9, 0x05, 0x2d, 0xb4, 0x83, 0x15, 0xc9, 0x85, 0x9f, 0x56, 0xcc, 0x75, 0x9c, + 0x3c, 0x51, 0xa0, 0x2d, 0x68, 0xfa, 0x7b, 0x7e, 0x0c, 0x29, 0x23, 0x04, 0xfc, 0x3d, 0x5f, 0x01, + 0x8c, 0x1f, 0x40, 0x37, 0xef, 0x4a, 0xa4, 0x0b, 0xe5, 0x17, 0xec, 0x4c, 0xbd, 0x4f, 0x3c, 0x92, + 0x0d, 0x75, 0x2c, 0x7c, 0x87, 0x6e, 0xaa, 0x33, 0x7e, 0x5e, 0x8a, 0x95, 0x63, 0x6f, 0x22, 0xfb, + 0x50, 0x11, 0x41, 0x85, 0xda, 0xcd, 0xbd, 0xfe, 0x40, 0x46, 0xdc, 0x20, 0x8a, 0xb8, 0xc1, 0xd3, + 0x28, 0xe2, 0x86, 0x8d, 0x2f, 0x5f, 0x6d, 0xad, 0x7d, 0xfe, 0xa7, 0x2d, 0xcd, 0x44, 0x0d, 0x72, + 0x5d, 0x38, 0x04, 0x75, 0x5c, 0xcb, 0xb1, 0xd5, 0x7b, 0xea, 0x38, 0x3e, 0xb2, 0xc9, 0x01, 0x74, + 0xc7, 0x9e, 0x1b, 0x32, 0x37, 0x5c, 0x84, 0x96, 0x4f, 0x03, 0x3a, 0x0f, 0x55, 0xac, 0x45, 0x9f, + 0xff, 0x41, 0x24, 0x3e, 0x46, 0xa9, 0xd9, 0x19, 0x67, 0x27, 0xc8, 0x87, 0x00, 0xa7, 0x74, 0xe6, + 0xd8, 0x94, 0x7b, 0x41, 0xd8, 0xab, 0xdc, 0x2c, 0xa7, 0x94, 0x4f, 0x22, 0xc1, 0x33, 0xdf, 0xa6, + 0x9c, 0x0d, 0x2b, 0x62, 0x67, 0x66, 0x0a, 0x4f, 0x6e, 0x43, 0x87, 0xfa, 0xbe, 0x15, 0x72, 0xca, + 0x99, 0x35, 0x3a, 0xe3, 0x2c, 0xc4, 0x78, 0x5c, 0x37, 0x5b, 0xd4, 0xf7, 0x9f, 0x88, 0xd9, 0xa1, + 0x98, 0x34, 0xec, 0xf8, 0x6b, 0x62, 0xa8, 0x10, 0x02, 0x15, 0x9b, 0x72, 0x8a, 0xd6, 0x58, 0x37, + 0xf1, 0x59, 0xcc, 0xf9, 0x94, 0x4f, 0xd5, 0x19, 0xf1, 0x99, 0x5c, 0x85, 0xda, 0x94, 0x39, 0x93, + 0x29, 0xc7, 0x63, 0x95, 0x4d, 0x35, 0x12, 0x86, 0xf7, 0x03, 0xef, 0x94, 0x61, 0xb6, 0x68, 0x98, + 0x72, 0x60, 0xfc, 0x4d, 0x83, 0x4b, 0x17, 0xc2, 0x4b, 0xac, 0x3b, 0xa5, 0xe1, 0x34, 0x7a, 0x97, + 0x78, 0x26, 0xef, 0x88, 0x75, 0xa9, 0xcd, 0x02, 0x95, 0xc5, 0x5a, 0xea, 0xc4, 0x87, 0x38, 0xa9, + 0x0e, 0xaa, 0x20, 0xe4, 0x11, 0x74, 0x67, 0x34, 0xe4, 0x96, 0x8c, 0x02, 0x0b, 0xb3, 0x54, 0x39, + 0x13, 0x99, 0x8f, 0x69, 0x14, 0x2d, 0xc2, 0x39, 0x95, 0x7a, 0x7b, 0x96, 0x99, 0x25, 0x87, 0xb0, + 0x31, 0x3a, 0xfb, 0x25, 0x75, 0xb9, 0xe3, 0x32, 0xeb, 0x82, 0xcd, 0x3b, 0x6a, 0xa9, 0x47, 0xa7, + 0x8e, 0xcd, 0xdc, 0x71, 0x64, 0xec, 0xcb, 0xb1, 0x4a, 0xfc, 0x31, 0x42, 0xe3, 0x10, 0xda, 0xd9, + 0x5c, 0x40, 0xda, 0x50, 0xe2, 0x4b, 0x75, 0xc2, 0x12, 0x5f, 0x92, 0xdb, 0x50, 0x11, 0xcb, 0xe1, + 0xe9, 0xda, 0x71, 0x32, 0x55, 0xe8, 0xa7, 0x67, 0x3e, 0x33, 0x51, 0x6e, 0x18, 0xb1, 0xa7, 0xc6, + 0x81, 0x9b, 0x5f, 0xcb, 0xd8, 0x81, 0x4e, 0x2e, 0x89, 0xa4, 0x3e, 0x8b, 0x96, 0xfe, 0x2c, 0x46, + 0x07, 0x5a, 0x99, 0xdc, 0x61, 0x7c, 0x56, 0x85, 0x86, 0xc9, 0x42, 0x5f, 0x38, 0x1d, 0xd9, 0x07, + 0x9d, 0x2d, 0xc7, 0x4c, 0xa6, 0x6d, 0x2d, 0x97, 0x14, 0x25, 0xe6, 0x51, 0x24, 0x17, 0xe9, 0x23, + 0x06, 0x93, 0x9d, 0x0c, 0xe5, 0x5c, 0xce, 0x2b, 0xa5, 0x39, 0xe7, 0x4e, 0x96, 0x73, 0x36, 0x72, + 0xd8, 0x1c, 0xe9, 0xec, 0x64, 0x48, 0x27, 0xbf, 0x70, 0x86, 0x75, 0xee, 0x15, 0xb0, 0x4e, 0x7e, + 0xfb, 0x2b, 0x68, 0xe7, 0x5e, 0x01, 0xed, 0xf4, 0x2e, 0xbc, 0xab, 0x90, 0x77, 0xee, 0x64, 0x79, + 0x27, 0x7f, 0x9c, 0x1c, 0xf1, 0x7c, 0x58, 0x44, 0x3c, 0xd7, 0x73, 0x3a, 0x2b, 0x99, 0xe7, 0x83, + 0x0b, 0xcc, 0x73, 0x35, 0xa7, 0x5a, 0x40, 0x3d, 0xf7, 0x32, 0x9c, 0x00, 0x85, 0x67, 0x2b, 0x26, + 0x05, 0xf2, 0xfd, 0x8b, 0xac, 0x75, 0x2d, 0xff, 0x69, 0x8b, 0x68, 0x6b, 0x37, 0x47, 0x5b, 0x57, + 0xf2, 0xbb, 0xcc, 0xf1, 0x56, 0xc2, 0x3e, 0x3b, 0x22, 0x3f, 0xe4, 0x3c, 0x4d, 0xe4, 0x12, 0x16, + 0x04, 0x5e, 0xa0, 0x12, 0xbb, 0x1c, 0x18, 0xdb, 0x22, 0x63, 0x25, 0xfe, 0xf5, 0x1a, 0xa6, 0x42, + 0xa7, 0x4f, 0x79, 0x97, 0xf1, 0x85, 0x96, 0xe8, 0x62, 0xe4, 0xa7, 0xb3, 0x9d, 0xae, 0xb2, 0x5d, + 0x8a, 0xc0, 0x4a, 0x59, 0x02, 0xdb, 0x82, 0xa6, 0xc8, 0xa9, 0x39, 0x6e, 0xa2, 0x7e, 0xc4, 0x4d, + 0xe4, 0x6d, 0xb8, 0x84, 0xf9, 0x48, 0xd2, 0x9c, 0x0a, 0xc4, 0x0a, 0x06, 0x62, 0x47, 0x08, 0xa4, + 0xc5, 0x64, 0xa2, 0x7c, 0x17, 0x2e, 0xa7, 0xb0, 0x62, 0x5d, 0xcc, 0x85, 0x32, 0x49, 0x77, 0x63, + 0xf4, 0x81, 0xef, 0x1f, 0xd2, 0x70, 0x6a, 0xfc, 0x24, 0x31, 0x50, 0xc2, 0x7b, 0x04, 0x2a, 0x63, + 0xcf, 0x96, 0xe7, 0x6e, 0x99, 0xf8, 0x2c, 0xb8, 0x70, 0xe6, 0x4d, 0x70, 0x73, 0xba, 0x29, 0x1e, + 0x05, 0x2a, 0x0e, 0x25, 0x5d, 0xc6, 0x8c, 0xf1, 0x6b, 0x2d, 0x59, 0x2f, 0xa1, 0xc2, 0x22, 0xd6, + 0xd2, 0xfe, 0x17, 0xd6, 0x2a, 0x7d, 0x3d, 0xd6, 0x32, 0xce, 0xb5, 0xe4, 0x93, 0xc5, 0x7c, 0xf4, + 0x66, 0x47, 0x14, 0xde, 0xe3, 0xb8, 0x36, 0x5b, 0xa2, 0x49, 0xcb, 0xa6, 0x1c, 0x44, 0xa5, 0x42, + 0x0d, 0xcd, 0x9c, 0x2d, 0x15, 0xea, 0x38, 0x27, 0x07, 0xe4, 0x16, 0xf2, 0x98, 0xf7, 0x5c, 0x85, + 0x6a, 0x6b, 0xa0, 0x0a, 0xfa, 0x63, 0x31, 0x69, 0x4a, 0x59, 0x2a, 0xdb, 0xea, 0x19, 0x12, 0xbc, + 0x01, 0xba, 0xd8, 0x68, 0xe8, 0xd3, 0x31, 0xc3, 0xc8, 0xd3, 0xcd, 0x64, 0xc2, 0x78, 0x0a, 0xe4, + 0x62, 0xc4, 0x93, 0x8f, 0xa0, 0xc6, 0x4e, 0x99, 0xcb, 0x85, 0xc5, 0x85, 0xd1, 0xd6, 0x63, 0xda, + 0x61, 0x2e, 0x1f, 0xf6, 0x84, 0xa9, 0xfe, 0xfe, 0x6a, 0xab, 0x2b, 0x31, 0x77, 0xbc, 0xb9, 0xc3, + 0xd9, 0xdc, 0xe7, 0x67, 0xa6, 0xd2, 0x32, 0xfe, 0xa9, 0x09, 0x36, 0xc8, 0x64, 0x83, 0x42, 0xe3, + 0x45, 0x2e, 0x5f, 0x4a, 0x11, 0xfc, 0x57, 0x33, 0xe8, 0xb7, 0x01, 0x26, 0x34, 0xb4, 0x5e, 0x52, + 0x97, 0x33, 0x5b, 0x59, 0x55, 0x9f, 0xd0, 0xf0, 0xe7, 0x38, 0x21, 0xaa, 0x21, 0x21, 0x5e, 0x84, + 0xcc, 0x46, 0xf3, 0x96, 0xcd, 0xfa, 0x84, 0x86, 0xcf, 0x42, 0x66, 0xa7, 0xce, 0x56, 0x7f, 0x93, + 0xb3, 0x65, 0xed, 0xd9, 0xc8, 0xdb, 0xf3, 0xdf, 0x29, 0x5f, 0x4e, 0xc8, 0xf2, 0x9b, 0x71, 0xf6, + 0x7f, 0x68, 0xa2, 0x4e, 0xc8, 0xa6, 0x64, 0x72, 0x04, 0x97, 0xe2, 0x98, 0xb2, 0x16, 0x18, 0x6b, + 0x91, 0x57, 0xbd, 0x3e, 0x14, 0xbb, 0xa7, 0xd9, 0xe9, 0x90, 0x7c, 0x02, 0xd7, 0x72, 0x19, 0x21, + 0x5e, 0xb0, 0xf4, 0xda, 0xc4, 0x70, 0x25, 0x9b, 0x18, 0xa2, 0xf5, 0x12, 0x6b, 0x94, 0xdf, 0xc8, + 0xcb, 0xbf, 0x23, 0x0a, 0xac, 0x34, 0x99, 0x14, 0x7d, 0x53, 0xe3, 0x37, 0x1a, 0x74, 0x72, 0x1b, + 0x22, 0xdb, 0x50, 0x95, 0x7c, 0xa6, 0x65, 0xda, 0x58, 0xb4, 0x98, 0xda, 0xb3, 0x04, 0x90, 0xf7, + 0xa1, 0xc1, 0x54, 0xad, 0xa7, 0x0e, 0x79, 0x25, 0x57, 0x02, 0x2a, 0x7c, 0x0c, 0x23, 0xdf, 0x03, + 0x3d, 0x36, 0x5d, 0xae, 0xce, 0x8f, 0x2d, 0xad, 0x94, 0x12, 0xa0, 0xf1, 0x00, 0x9a, 0xa9, 0xd7, + 0x93, 0x6f, 0x81, 0x3e, 0xa7, 0x4b, 0x55, 0xac, 0xcb, 0xf2, 0xad, 0x31, 0xa7, 0x4b, 0xac, 0xd3, + 0xc9, 0x35, 0xa8, 0x0b, 0xe1, 0x84, 0x4a, 0xc3, 0x97, 0xcd, 0xda, 0x9c, 0x2e, 0x7f, 0x4c, 0x43, + 0x63, 0x07, 0xda, 0xd9, 0x6d, 0x45, 0xd0, 0x88, 0x10, 0x25, 0xf4, 0x60, 0xc2, 0x8c, 0xbb, 0xd0, + 0xc9, 0xed, 0x86, 0x18, 0xd0, 0xf2, 0x17, 0x23, 0xeb, 0x05, 0x3b, 0xb3, 0x70, 0xbb, 0xe8, 0x26, + 0xba, 0xd9, 0xf4, 0x17, 0xa3, 0x8f, 0xd9, 0x99, 0xa8, 0x47, 0x43, 0xe3, 0x09, 0xb4, 0xb3, 0x65, + 0xb4, 0x48, 0x99, 0x81, 0xb7, 0x70, 0x6d, 0x5c, 0xbf, 0x6a, 0xca, 0x81, 0xe8, 0xc4, 0x4f, 0x3d, + 0xe9, 0x19, 0xe9, 0xba, 0xf9, 0xc4, 0xe3, 0x2c, 0x55, 0x7c, 0x4b, 0x8c, 0xe1, 0x40, 0x15, 0xbf, + 0xb9, 0xf8, 0x7e, 0x58, 0x10, 0x2b, 0x0a, 0x16, 0xcf, 0xe4, 0x31, 0x00, 0xe5, 0x3c, 0x70, 0x46, + 0x8b, 0x64, 0xb9, 0xf6, 0x40, 0x5e, 0x8f, 0x0c, 0x3e, 0x3e, 0x39, 0xa6, 0x4e, 0x30, 0xbc, 0xa1, + 0x7c, 0x65, 0x23, 0x41, 0xa6, 0xfc, 0x25, 0xa5, 0x6f, 0xfc, 0xaa, 0x0a, 0x35, 0xd9, 0x3e, 0x90, + 0x41, 0xb6, 0x39, 0x15, 0xab, 0xaa, 0x4d, 0xca, 0x59, 0xb5, 0xc7, 0x98, 0xf1, 0x6f, 0xe7, 0x3b, + 0xbc, 0x61, 0xf3, 0xfc, 0xd5, 0x56, 0x1d, 0xd9, 0xf2, 0xe8, 0x61, 0xd2, 0xee, 0xad, 0xea, 0x86, + 0xa2, 0xde, 0xb2, 0xf2, 0xb5, 0x7b, 0xcb, 0x6b, 0x50, 0x77, 0x17, 0x73, 0x8b, 0x2f, 0x43, 0x95, + 0x6d, 0x6a, 0xee, 0x62, 0xfe, 0x74, 0x89, 0x5e, 0xc2, 0x3d, 0x4e, 0x67, 0x28, 0x92, 0xb9, 0xa6, + 0x81, 0x13, 0x42, 0xb8, 0x0f, 0xad, 0x54, 0x51, 0xe1, 0xd8, 0xaa, 0x38, 0x6d, 0xa7, 0x9d, 0xfd, + 0xe8, 0xa1, 0x3a, 0x65, 0x33, 0x2e, 0x32, 0x8e, 0x6c, 0xb2, 0x9d, 0x6d, 0xa5, 0xb0, 0x16, 0x69, + 0x60, 0x48, 0xa5, 0xba, 0x25, 0x51, 0x89, 0x88, 0x0d, 0x88, 0x20, 0x93, 0x10, 0x1d, 0x21, 0x0d, + 0x31, 0x81, 0xc2, 0xb7, 0xa0, 0x93, 0xd0, 0xb9, 0x84, 0x80, 0x5c, 0x25, 0x99, 0x46, 0xe0, 0x7b, + 0xb0, 0xe1, 0xb2, 0x25, 0xb7, 0xf2, 0xe8, 0x26, 0xa2, 0x89, 0x90, 0x9d, 0x64, 0x35, 0xbe, 0x0b, + 0xed, 0x24, 0x15, 0x21, 0x76, 0x5d, 0x36, 0xb4, 0xf1, 0x2c, 0xc2, 0xae, 0x43, 0x23, 0x2e, 0xa6, + 0x5a, 0x08, 0xa8, 0x53, 0x59, 0x43, 0xc5, 0xe5, 0x59, 0xc0, 0xc2, 0xc5, 0x8c, 0xab, 0x45, 0xda, + 0x88, 0xc1, 0xf2, 0xcc, 0x94, 0xf3, 0x88, 0xbd, 0x05, 0xad, 0x28, 0xba, 0x25, 0xae, 0x83, 0xb8, + 0xf5, 0x68, 0x12, 0x41, 0x3b, 0xd0, 0xf5, 0x03, 0xcf, 0xf7, 0x42, 0x16, 0x58, 0xd4, 0xb6, 0x03, + 0x16, 0x86, 0xbd, 0xae, 0x5c, 0x2f, 0x9a, 0x3f, 0x90, 0xd3, 0xc6, 0xfb, 0x50, 0x8f, 0xaa, 0xc4, + 0x0d, 0xa8, 0x0e, 0xe3, 0x4c, 0x54, 0x31, 0xe5, 0x40, 0xf0, 0xd0, 0x81, 0xef, 0xab, 0x3b, 0x11, + 0xf1, 0x68, 0xfc, 0x02, 0xea, 0xea, 0x83, 0x15, 0x76, 0xca, 0x3f, 0x84, 0x75, 0x9f, 0x06, 0xe2, + 0x18, 0xe9, 0x7e, 0x39, 0xea, 0x43, 0x8e, 0x69, 0xc0, 0x9f, 0x30, 0x9e, 0x69, 0x9b, 0x9b, 0x88, + 0x97, 0x53, 0xc6, 0x3d, 0x68, 0x65, 0x30, 0x62, 0x5b, 0xe8, 0x47, 0x51, 0x50, 0xe3, 0x20, 0x7e, + 0x73, 0x29, 0x79, 0xb3, 0x71, 0x1f, 0xf4, 0xf8, 0xdb, 0x88, 0x72, 0x39, 0x3a, 0xba, 0xa6, 0xcc, + 0x2d, 0x87, 0x78, 0x15, 0xe0, 0xbd, 0x64, 0x81, 0x8a, 0x09, 0x39, 0x30, 0x9e, 0xa5, 0x92, 0x90, + 0x64, 0x05, 0x72, 0x07, 0xea, 0x2a, 0x09, 0xa9, 0xa8, 0x8c, 0x9a, 0xfe, 0x63, 0xcc, 0x42, 0x51, + 0xd3, 0x2f, 0x73, 0x52, 0xb2, 0x6c, 0x29, 0xbd, 0xec, 0x0c, 0x1a, 0x51, 0xa2, 0xc9, 0x66, 0x63, + 0xb9, 0x62, 0x37, 0x9f, 0x8d, 0xd5, 0xa2, 0x09, 0x50, 0x78, 0x47, 0xe8, 0x4c, 0x5c, 0x66, 0x5b, + 0x49, 0x08, 0xe1, 0x3b, 0x1a, 0x66, 0x47, 0x0a, 0x1e, 0x47, 0xf1, 0x62, 0xbc, 0x07, 0x35, 0xb9, + 0xb7, 0xc2, 0xf4, 0x55, 0x44, 0x49, 0x7f, 0xd4, 0xa0, 0x11, 0xe5, 0xe9, 0x42, 0xa5, 0xcc, 0xa6, + 0x4b, 0x5f, 0x75, 0xd3, 0xff, 0xff, 0xc4, 0x73, 0x07, 0x88, 0xcc, 0x2f, 0xa7, 0x1e, 0x77, 0xdc, + 0x89, 0x25, 0x6d, 0x2d, 0x73, 0x50, 0x17, 0x25, 0x27, 0x28, 0x38, 0x16, 0xf3, 0x6f, 0xdf, 0x82, + 0x66, 0xea, 0xee, 0x82, 0xd4, 0xa1, 0xfc, 0x09, 0x7b, 0xd9, 0x5d, 0x23, 0x4d, 0xa8, 0x9b, 0x0c, + 0x3b, 0xd1, 0xae, 0xb6, 0xf7, 0x59, 0x15, 0x3a, 0x07, 0xc3, 0x07, 0x47, 0x07, 0xbe, 0x3f, 0x73, + 0xc6, 0x14, 0x5b, 0x97, 0x5d, 0xa8, 0x60, 0xf7, 0x56, 0x70, 0x4b, 0xdd, 0x2f, 0xba, 0x46, 0x20, + 0x7b, 0x50, 0xc5, 0x26, 0x8e, 0x14, 0x5d, 0x56, 0xf7, 0x0b, 0x6f, 0x13, 0xc4, 0x4b, 0x64, 0x9b, + 0x77, 0xf1, 0xce, 0xba, 0x5f, 0x74, 0xa5, 0x40, 0x3e, 0x02, 0x3d, 0xe9, 0xae, 0x56, 0xdd, 0x5c, + 0xf7, 0x57, 0x5e, 0x2e, 0x08, 0xfd, 0xa4, 0x02, 0x5d, 0x75, 0x01, 0xdb, 0x5f, 0xd9, 0x85, 0x93, + 0x7d, 0xa8, 0x47, 0xb5, 0x7b, 0xf1, 0xdd, 0x72, 0x7f, 0x45, 0xe3, 0x2f, 0xcc, 0x23, 0x1b, 0xa6, + 0xa2, 0x0b, 0xf0, 0x7e, 0xe1, 0xed, 0x04, 0xb9, 0x0b, 0x35, 0x55, 0x44, 0x15, 0xde, 0x2f, 0xf7, + 0x8b, 0xdb, 0x77, 0x71, 0xc8, 0xa4, 0x65, 0x5c, 0x75, 0x49, 0xdf, 0x5f, 0x79, 0x8d, 0x42, 0x0e, + 0x00, 0x52, 0x7d, 0xcf, 0xca, 0xdb, 0xf7, 0xfe, 0xea, 0xeb, 0x11, 0x72, 0x1f, 0x1a, 0xc9, 0x95, + 0x57, 0xf1, 0x7d, 0x7a, 0x7f, 0xd5, 0x8d, 0xc5, 0xf0, 0xc6, 0xbf, 0xfe, 0xb2, 0xa9, 0xfd, 0xf6, + 0x7c, 0x53, 0xfb, 0xe2, 0x7c, 0x53, 0xfb, 0xf2, 0x7c, 0x53, 0xfb, 0xc3, 0xf9, 0xa6, 0xf6, 0xe7, + 0xf3, 0x4d, 0xed, 0x77, 0x7f, 0xdd, 0xd4, 0x46, 0x35, 0x8c, 0x91, 0x0f, 0xfe, 0x13, 0x00, 0x00, + 0xff, 0xff, 0x92, 0xed, 0x9f, 0xca, 0x3f, 0x1a, 0x00, 0x00, } diff --git a/abci/types/types.proto b/abci/types/types.proto index 8a2da5b47..8f9dda832 100644 --- a/abci/types/types.proto +++ b/abci/types/types.proto @@ -81,8 +81,14 @@ message RequestBeginBlock { repeated Evidence byzantine_validators = 4 [(gogoproto.nullable)=false]; } +enum CheckTxType { + New = 0; + Recheck = 1; +} + message RequestCheckTx { bytes tx = 1; + CheckTxType type = 2; } message RequestDeliverTx { diff --git a/consensus/replay_test.go b/consensus/replay_test.go index 724dd056b..bbb5b6678 100644 --- a/consensus/replay_test.go +++ b/consensus/replay_test.go @@ -565,7 +565,7 @@ func TestMockProxyApp(t *testing.T) { mock.SetResponseCallback(proxyCb) someTx := []byte("tx") - mock.DeliverTxAsync(someTx) + mock.DeliverTxAsync(abci.RequestDeliverTx{Tx: someTx}) }) assert.True(t, validTxs == 1) assert.True(t, invalidTxs == 0) diff --git a/docs/spec/abci/abci.md b/docs/spec/abci/abci.md index b7b2e09fe..abab7f548 100644 --- a/docs/spec/abci/abci.md +++ b/docs/spec/abci/abci.md @@ -296,6 +296,12 @@ Commit are included in the header of the next block. - **Request**: - `Tx ([]byte)`: The request transaction bytes + - `Type (CheckTxType)`: What type of `CheckTx` request is this? At present, + there are two possible values: `CheckTx_Unchecked` (the default, which says + that a full check is required), and `CheckTx_Checked` (when the mempool is + initiating a normal recheck of a transaction). + - `AdditionalData ([]byte)`: Reserved for future use. See + [here](https://github.com/tendermint/tendermint/issues/2127#issuecomment-456661420). - **Response**: - `Code (uint32)`: Response code - `Data ([]byte)`: Result bytes, if any. diff --git a/mempool/clist_mempool.go b/mempool/clist_mempool.go index 0d1f3c5b1..4042e9b4b 100644 --- a/mempool/clist_mempool.go +++ b/mempool/clist_mempool.go @@ -279,7 +279,7 @@ func (mem *CListMempool) CheckTxWithInfo(tx types.Tx, cb func(*abci.Response), t return err } - reqRes := mem.proxyAppConn.CheckTxAsync(tx) + reqRes := mem.proxyAppConn.CheckTxAsync(abci.RequestCheckTx{Tx: tx}) reqRes.SetCallback(mem.reqResCb(tx, txInfo.SenderID, cb)) return nil @@ -591,7 +591,10 @@ func (mem *CListMempool) recheckTxs() { // NOTE: globalCb may be called concurrently. for e := mem.txs.Front(); e != nil; e = e.Next() { memTx := e.Value.(*mempoolTx) - mem.proxyAppConn.CheckTxAsync(memTx.tx) + mem.proxyAppConn.CheckTxAsync(abci.RequestCheckTx{ + Tx: memTx.tx, + Type: abci.CheckTxType_Recheck, + }) } mem.proxyAppConn.FlushAsync() diff --git a/mempool/clist_mempool_test.go b/mempool/clist_mempool_test.go index db6e800b8..90d0ed1ae 100644 --- a/mempool/clist_mempool_test.go +++ b/mempool/clist_mempool_test.go @@ -314,7 +314,7 @@ func TestSerialReap(t *testing.T) { for i := start; i < end; i++ { txBytes := make([]byte, 8) binary.BigEndian.PutUint64(txBytes, uint64(i)) - res, err := appConnCon.DeliverTxSync(txBytes) + res, err := appConnCon.DeliverTxSync(abci.RequestDeliverTx{Tx: txBytes}) if err != nil { t.Errorf("Client error committing tx: %v", err) } @@ -522,7 +522,7 @@ func TestMempoolTxsBytes(t *testing.T) { err = appConnCon.Start() require.Nil(t, err) defer appConnCon.Stop() - res, err := appConnCon.DeliverTxSync(txBytes) + res, err := appConnCon.DeliverTxSync(abci.RequestDeliverTx{Tx: txBytes}) require.NoError(t, err) require.EqualValues(t, 0, res.Code) res2, err := appConnCon.CommitSync() diff --git a/proxy/app_conn.go b/proxy/app_conn.go index 2f792671e..1698ab52f 100644 --- a/proxy/app_conn.go +++ b/proxy/app_conn.go @@ -15,7 +15,7 @@ type AppConnConsensus interface { InitChainSync(types.RequestInitChain) (*types.ResponseInitChain, error) BeginBlockSync(types.RequestBeginBlock) (*types.ResponseBeginBlock, error) - DeliverTxAsync(tx []byte) *abcicli.ReqRes + DeliverTxAsync(types.RequestDeliverTx) *abcicli.ReqRes EndBlockSync(types.RequestEndBlock) (*types.ResponseEndBlock, error) CommitSync() (*types.ResponseCommit, error) } @@ -24,7 +24,7 @@ type AppConnMempool interface { SetResponseCallback(abcicli.Callback) Error() error - CheckTxAsync(tx []byte) *abcicli.ReqRes + CheckTxAsync(types.RequestCheckTx) *abcicli.ReqRes FlushAsync() *abcicli.ReqRes FlushSync() error @@ -69,8 +69,8 @@ func (app *appConnConsensus) BeginBlockSync(req types.RequestBeginBlock) (*types return app.appConn.BeginBlockSync(req) } -func (app *appConnConsensus) DeliverTxAsync(tx []byte) *abcicli.ReqRes { - return app.appConn.DeliverTxAsync(tx) +func (app *appConnConsensus) DeliverTxAsync(req types.RequestDeliverTx) *abcicli.ReqRes { + return app.appConn.DeliverTxAsync(req) } func (app *appConnConsensus) EndBlockSync(req types.RequestEndBlock) (*types.ResponseEndBlock, error) { @@ -110,8 +110,8 @@ func (app *appConnMempool) FlushSync() error { return app.appConn.FlushSync() } -func (app *appConnMempool) CheckTxAsync(tx []byte) *abcicli.ReqRes { - return app.appConn.CheckTxAsync(tx) +func (app *appConnMempool) CheckTxAsync(req types.RequestCheckTx) *abcicli.ReqRes { + return app.appConn.CheckTxAsync(req) } //------------------------------------------------ diff --git a/state/execution.go b/state/execution.go index 7e49a9ad8..fd75b2959 100644 --- a/state/execution.go +++ b/state/execution.go @@ -284,7 +284,7 @@ func execBlockOnProxyApp( // Run txs of block. for _, tx := range block.Txs { - proxyAppConn.DeliverTxAsync(tx) + proxyAppConn.DeliverTxAsync(abci.RequestDeliverTx{Tx: tx}) if err := proxyAppConn.Error(); err != nil { return nil, err } From d0414768195807044fa8614b07f4e0035fd5f9e1 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Tue, 2 Jul 2019 21:19:58 +0400 Subject: [PATCH 07/34] p2p: dial addrs which came from seed instead of calling ensurePeers (#3762) Calling ensurePeers outside of ensurePeersRoutine can lead to nodes disconnecting from us due to "sent next PEX request too soon" error. Solution is to just dial addrs we got from src instead of calling ensurePeers. Refs #2093 Fixes #3338 --- CHANGELOG_PENDING.md | 2 ++ p2p/pex/pex_reactor.go | 29 ++++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 9c94c55e7..fa81d9bbb 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -31,3 +31,5 @@ program](https://hackerone.com/tendermint). - [rpc] \#3700 Make possible to set absolute paths for TLS cert and key (@climber73) ### BUG FIXES: +- [p2p] \#3338 Prevent "sent next PEX request too soon" errors by not calling + ensurePeers outside of ensurePeersRoutine diff --git a/p2p/pex/pex_reactor.go b/p2p/pex/pex_reactor.go index e77fa8eaa..20862d323 100644 --- a/p2p/pex/pex_reactor.go +++ b/p2p/pex/pex_reactor.go @@ -340,6 +340,15 @@ func (r *PEXReactor) ReceiveAddrs(addrs []*p2p.NetAddress, src Peer) error { if err != nil { return err } + + srcIsSeed := false + for _, seedAddr := range r.seedAddrs { + if seedAddr.Equals(srcAddr) { + srcIsSeed = true + break + } + } + for _, netAddr := range addrs { // Validate netAddr. Disconnect from a peer if it sends us invalid data. if netAddr == nil { @@ -365,13 +374,23 @@ func (r *PEXReactor) ReceiveAddrs(addrs []*p2p.NetAddress, src Peer) error { } // If this address came from a seed node, try to connect to it without - // waiting. - for _, seedAddr := range r.seedAddrs { - if seedAddr.Equals(srcAddr) { - r.ensurePeers() - } + // waiting (#2093) + if srcIsSeed { + r.Logger.Info("Will dial address, which came from seed", "addr", netAddr, "seed", srcAddr) + go func(addr *p2p.NetAddress) { + err := r.dialPeer(addr) + if err != nil { + switch err.(type) { + case errMaxAttemptsToDial, errTooEarlyToDial: + r.Logger.Debug(err.Error(), "addr", addr) + default: + r.Logger.Error(err.Error(), "addr", addr) + } + } + }(netAddr) } } + return nil } From e645442c9be7694a09fccfde206ff715ee462824 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Tue, 2 Jul 2019 22:01:29 +0400 Subject: [PATCH 08/34] abci: minor cleanups in the socket client (#3758) Follow up from #3512 Specifically: cli.conn.Close() need not be under the mutex (#3512 (comment)) call the reqRes callback after the resCb so they always happen in the same order (#3512) Fixes #3513 --- abci/client/socket_client.go | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index 16e39bf35..7b1e4cd8d 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -55,10 +55,6 @@ func NewSocketClient(addr string, mustConnect bool) *socketClient { } func (cli *socketClient) OnStart() error { - if err := cli.BaseService.OnStart(); err != nil { - return err - } - var err error var conn net.Conn RETRY_LOOP: @@ -82,15 +78,12 @@ RETRY_LOOP: } func (cli *socketClient) OnStop() { - cli.BaseService.OnStop() - - cli.mtx.Lock() - defer cli.mtx.Unlock() if cli.conn != nil { - // does this really need a mutex? cli.conn.Close() } + cli.mtx.Lock() + defer cli.mtx.Unlock() cli.flushQueue() } @@ -209,19 +202,18 @@ func (cli *socketClient) didRecvResponse(res *types.Response) error { reqres.Done() // Release waiters cli.reqSent.Remove(next) // Pop first item from linked list + // Notify client listener if set (global callback). + if cli.resCb != nil { + cli.resCb(reqres.Request, res) + } + // Notify reqRes listener if set (request specific callback). // NOTE: it is possible this callback isn't set on the reqres object. // at this point, in which case it will be called after, when it is set. - // TODO: should we move this after the resCb call so the order is always consistent? if cb := reqres.GetCallback(); cb != nil { cb(res) } - // Notify client listener if set (global callback). - if cli.resCb != nil { - cli.resCb(reqres.Request, res) - } - return nil } From f76684a05c9e179f8b5fcb528d90b74a1956b4b9 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Wed, 3 Jul 2019 17:17:59 +0400 Subject: [PATCH 09/34] node: allow registration of custom reactors while creating node (#3771) * change invocation of NewNode across * custom reactor name are prefixed with CUSTOM_ * upgate changelog pending * improve comments * node: refactor NewNode to use functional options --- CHANGELOG_PENDING.md | 4 ++++ node/node.go | 25 ++++++++++++++++++++++++- node/node_test.go | 34 +++++++++++++++++++++++++++++++++- p2p/mock/reactor.go | 23 +++++++++++++++++++++++ 4 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 p2p/mock/reactor.go diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index fa81d9bbb..5a747650e 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -26,6 +26,10 @@ program](https://hackerone.com/tendermint). * P2P Protocol ### FEATURES: +- [node] Refactor `NewNode` to use functional options to make it more flexible + and extensible in the future. +- [node] [\#3730](https://github.com/tendermint/tendermint/pull/3730) Add `CustomReactors` option to `NewNode` allowing caller to pass + custom reactors to run inside Tendermint node (@ParthDesai) ### IMPROVEMENTS: - [rpc] \#3700 Make possible to set absolute paths for TLS cert and key (@climber73) diff --git a/node/node.go b/node/node.go index c992e2424..9beb0669f 100644 --- a/node/node.go +++ b/node/node.go @@ -47,6 +47,10 @@ import ( "github.com/tendermint/tendermint/version" ) +// CustomReactorNamePrefix is a prefix for all custom reactors to prevent +// clashes with built-in reactors. +const CustomReactorNamePrefix = "CUSTOM_" + //------------------------------------------------------------------------------ // DBContext specifies config information for loading a new DB. @@ -136,6 +140,18 @@ func DefaultMetricsProvider(config *cfg.InstrumentationConfig) MetricsProvider { } } +// Option sets a parameter for the node. +type Option func(*Node) + +// CustomReactors allows you to add custom reactors to the node's Switch. +func CustomReactors(reactors map[string]p2p.Reactor) Option { + return func(n *Node) { + for name, reactor := range reactors { + n.sw.AddReactor(CustomReactorNamePrefix+name, reactor) + } + } +} + //------------------------------------------------------------------------------ // Node is the highest level interface to a full Tendermint node. @@ -433,6 +449,7 @@ func createSwitch(config *cfg.Config, sw.AddReactor("BLOCKCHAIN", bcReactor) sw.AddReactor("CONSENSUS", consensusReactor) sw.AddReactor("EVIDENCE", evidenceReactor) + sw.SetNodeInfo(nodeInfo) sw.SetNodeKey(nodeKey) @@ -495,7 +512,8 @@ func NewNode(config *cfg.Config, genesisDocProvider GenesisDocProvider, dbProvider DBProvider, metricsProvider MetricsProvider, - logger log.Logger) (*Node, error) { + logger log.Logger, + options ...Option) (*Node, error) { blockStore, stateDB, err := initDBs(config, dbProvider) if err != nil { @@ -661,6 +679,11 @@ func NewNode(config *cfg.Config, eventBus: eventBus, } node.BaseService = *cmn.NewBaseService(logger, "Node", node) + + for _, option := range options { + option(node) + } + return node, nil } diff --git a/node/node_test.go b/node/node_test.go index ce4e82c2d..841a04686 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -21,6 +21,7 @@ import ( "github.com/tendermint/tendermint/libs/log" mempl "github.com/tendermint/tendermint/mempool" "github.com/tendermint/tendermint/p2p" + p2pmock "github.com/tendermint/tendermint/p2p/mock" "github.com/tendermint/tendermint/privval" "github.com/tendermint/tendermint/proxy" sm "github.com/tendermint/tendermint/state" @@ -100,7 +101,10 @@ func TestNodeDelayedStart(t *testing.T) { n.GenesisDoc().GenesisTime = now.Add(2 * time.Second) require.NoError(t, err) - n.Start() + err = n.Start() + require.NoError(t, err) + defer n.Stop() + startTime := tmtime.Now() assert.Equal(t, true, startTime.After(n.GenesisDoc().GenesisTime)) } @@ -279,6 +283,34 @@ func TestCreateProposalBlock(t *testing.T) { assert.NoError(t, err) } +func TestNodeNewNodeCustomReactors(t *testing.T) { + config := cfg.ResetTestRoot("node_new_node_custom_reactors_test") + defer os.RemoveAll(config.RootDir) + + cr := p2pmock.NewReactor() + + nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) + require.NoError(t, err) + + n, err := NewNode(config, + privval.LoadOrGenFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile()), + nodeKey, + proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()), + DefaultGenesisDocProviderFunc(config), + DefaultDBProvider, + DefaultMetricsProvider(config.Instrumentation), + log.TestingLogger(), + CustomReactors(map[string]p2p.Reactor{"FOO": cr}), + ) + require.NoError(t, err) + + err = n.Start() + require.NoError(t, err) + defer n.Stop() + + assert.True(t, cr.IsRunning()) +} + func state(nVals int, height int64) (sm.State, dbm.DB) { vals := make([]types.GenesisValidator, nVals) for i := 0; i < nVals; i++ { diff --git a/p2p/mock/reactor.go b/p2p/mock/reactor.go new file mode 100644 index 000000000..cfce12bd1 --- /dev/null +++ b/p2p/mock/reactor.go @@ -0,0 +1,23 @@ +package mock + +import ( + "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/p2p" + "github.com/tendermint/tendermint/p2p/conn" +) + +type Reactor struct { + p2p.BaseReactor +} + +func NewReactor() *Reactor { + r := &Reactor{} + r.BaseReactor = *p2p.NewBaseReactor("Reactor", r) + r.SetLogger(log.TestingLogger()) + return r +} + +func (r *Reactor) GetChannels() []*conn.ChannelDescriptor { return []*conn.ChannelDescriptor{} } +func (r *Reactor) AddPeer(peer p2p.Peer) {} +func (r *Reactor) RemovePeer(peer p2p.Peer, reason interface{}) {} +func (r *Reactor) Receive(chID byte, peer p2p.Peer, msgBytes []byte) {} From 94e0176ac24090d8048c1fa71b51e84ad8e77701 Mon Sep 17 00:00:00 2001 From: Jay Namsayin <31609693+jim380@users.noreply.github.com> Date: Thu, 4 Jul 2019 00:26:13 -0700 Subject: [PATCH 10/34] behaviour: return correct reason in MessageOutOfOrder (#3772) --- CHANGELOG_PENDING.md | 2 ++ behaviour/peer_behaviour.go | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 5a747650e..9c4c8b684 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -37,3 +37,5 @@ program](https://hackerone.com/tendermint). ### BUG FIXES: - [p2p] \#3338 Prevent "sent next PEX request too soon" errors by not calling ensurePeers outside of ensurePeersRoutine +- [behaviour] Return correct reason in MessageOutOfOrder (@jim380) + diff --git a/behaviour/peer_behaviour.go b/behaviour/peer_behaviour.go index 36630f46b..f7cfd00f0 100644 --- a/behaviour/peer_behaviour.go +++ b/behaviour/peer_behaviour.go @@ -27,7 +27,7 @@ type messageOutOfOrder struct { // MessageOutOfOrder returns a messagOutOfOrder PeerBehaviour. func MessageOutOfOrder(peerID p2p.ID, explanation string) PeerBehaviour { - return PeerBehaviour{peerID: peerID, reason: badMessage{explanation}} + return PeerBehaviour{peerID: peerID, reason: messageOutOfOrder{explanation}} } type consensusVote struct { From 1d5fcc22814389abfc3f461d94ca3afe3307fbfa Mon Sep 17 00:00:00 2001 From: Sean Braithwaite Date: Mon, 8 Jul 2019 19:45:52 +0200 Subject: [PATCH 11/34] adr: [43] blockchain riri-org (#3753) * [adr] First draft on adr-042 * fix diagram urls * Update docs/architecture/adr-042-blockchain-riri-org.md Co-Authored-By: Marko * Update docs/architecture/adr-042-blockchain-riri-org.md Co-Authored-By: Marko * Update docs/architecture/adr-042-blockchain-riri-org.md Co-Authored-By: Marko * add go syntax highlight * more highlighting * consistency fixes * Add references * new adr number * Fixes based on feedback * aditional state info * Add details on getSchedule * replace spaces with tabs * fixes based on feedback * add clarity around r.msgs * clarify block processing * fix off by one error * additional details on ioRoutine * Update docs/architecture/adr-043-blockchain-riri-org.md Co-Authored-By: Anca Zamfir --- .../adr-043-blockchain-riri-org.md | 391 ++++++++++++++++++ .../img/blockchain-reactor-v1.png | Bin 0 -> 124042 bytes .../img/blockchain-reactor-v2.png | Bin 0 -> 120617 bytes 3 files changed, 391 insertions(+) create mode 100644 docs/architecture/adr-043-blockchain-riri-org.md create mode 100644 docs/architecture/img/blockchain-reactor-v1.png create mode 100644 docs/architecture/img/blockchain-reactor-v2.png diff --git a/docs/architecture/adr-043-blockchain-riri-org.md b/docs/architecture/adr-043-blockchain-riri-org.md new file mode 100644 index 000000000..3cdf6e31e --- /dev/null +++ b/docs/architecture/adr-043-blockchain-riri-org.md @@ -0,0 +1,391 @@ +# ADR 043: Blockhchain Reactor Riri-Org + +## Changelog +* 18-06-2019: Initial draft +* 08-07-2019: Reviewed + +## Context + +The blockchain reactor is responsible for two high level processes:sending/receiving blocks from peers and FastSync-ing blocks to catch upnode who is far behind. The goal of [ADR-40](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-040-blockchain-reactor-refactor.md) was to refactor these two processes by separating business logic currently wrapped up in go-channels into pure `handle*` functions. While the ADR specified what the final form of the reactor might look like it lacked guidance on intermediary steps to get there. +The following diagram illustrates the state of the [blockchain-reorg](https://github.com/tendermint/tendermint/pull/35610) reactor which will be referred to as `v1`. + +![v1 Blockchain Reactor Architecture +Diagram](https://github.com/tendermint/tendermint/blob/f9e556481654a24aeb689bdadaf5eab3ccd66829/docs/architecture/img/blockchain-reactor-v1.png) + +While `v1` of the blockchain reactor has shown significant improvements in terms of simplifying the concurrency model, the current PR has run into few roadblocks. + +* The current PR large and difficult to review. +* Block gossiping and fast sync processes are highly coupled to the shared `Pool` data structure. +* Peer communication is spread over multiple components creating complex dependency graph which must be mocked out during testing. +* Timeouts modeled as stateful tickers introduce non-determinism in tests + +This ADR is meant to specify the missing components and control necessary to achieve [ADR-40](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-040-blockchain-reactor-refactor.md). + +## Decision + +Partition the responsibilities of the blockchain reactor into a set of components which communicate exclusively with events. Events will contain timestamps allowing each component to track time as internal state. The internal state will be mutated by a set of `handle*` which will produce event(s). The integration between components will happen in the reactor and reactor tests will then become integration tests between components. This design will be known as `v2`. + +![v2 Blockchain Reactor Architecture +Diagram](https://github.com/tendermint/tendermint/blob/f9e556481654a24aeb689bdadaf5eab3ccd66829/docs/architecture/img/blockchain-reactor-v2.png) + +### Reactor changes in detail + +The reactor will include a demultiplexing routine which will send each message to each sub routine for independent processing. Each sub routine will then select the messages it's interested in and call the handle specific function specified in [ADR-40](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-040-blockchain-reactor-refactor.md). The demuxRoutine acts as "pacemaker" setting the time in which events are expected to be handled. + + +```go +func demuxRoutine(msgs, scheduleMsgs, processorMsgs, ioMsgs) { + timer := time.NewTicker(interval) + for { + select { + case <-timer.C: + now := evTimeCheck{time.Now()} + schedulerMsgs <- now + processorMsgs <- now + ioMsgs <- now + case msg:= <- msgs: + msg.time = time.Now() + // These channels should produce backpressure before + // being full to avoid starving each other + schedulerMsgs <- msg + processorMsgs <- msg + ioMesgs <- msg + if msg == stop { + break; + } + } + } +} + +func processRoutine(input chan Message, output chan Message) { + processor := NewProcessor(..) + for { + msg := <- input + switch msg := msg.(type) { + case bcBlockRequestMessage: + output <- processor.handleBlockRequest(msg)) + ... + case stop: + processor.stop() + break; + } +} + +func scheduleRoutine(input chan Message, output chan Message) { + schelduer = NewScheduler(...) + for { + msg := <-msgs + switch msg := input.(type) { + case bcBlockResponseMessage: + output <- scheduler.handleBlockResponse(msg) + ... + case stop: + schedule.stop() + break; + } + } +} +``` + +## Lifecycle management + +A set of routines for individual processes allow processes to run in parallel with clear lifecycle management. `Start`, `Stop`, and `AddPeer` hooks currently present in the reactor will delegate to the sub-routines allowing them to manage internal state independent without further coupling to the reactor. + +```go +func (r *BlockChainReactor) Start() { + r.msgs := make(chan Message, maxInFlight) + schedulerMsgs := make(chan Message) + processorMsgs := make(chan Message) + ioMsgs := make(chan Message) + + go processorRoutine(processorMsgs, r.msgs) + go scheduleRoutine(schedulerMsgs, r.msgs) + go ioRoutine(ioMsgs, r.msgs) + ... +} + +func (bcR *BlockchainReactor) Receive(...) { + ... + r.msgs <- msg + ... +} + +func (r *BlockchainReactor) Stop() { + ... + r.msgs <- stop + ... +} + +... +func (r *BlockchainReactor) Stop() { + ... + r.msgs <- stop + ... +} +... + +func (r *BlockchainReactor) AddPeer(peer p2p.Peer) { + ... + r.msgs <- bcAddPeerEv{peer.ID} + ... +} + +``` + +## IO handling +An io handling routine within the reactor will isolate peer communication. Message going through the ioRoutine will usually be one way, using `p2p` APIs. In the case in which the `p2p` API such as `trySend` return errors, the ioRoutine can funnel those message back to the demuxRoutine for distribution to the other routines. For instance errors from the ioRoutine can be consumed by the scheduler to inform better peer selection implementations. + +```go +func (r *BlockchainReacor) ioRoutine(ioMesgs chan Message, outMsgs chan Message) { + ... + for { + msg := <-ioMsgs + switch msg := msg.(type) { + case scBlockRequestMessage: + queued := r.sendBlockRequestToPeer(...) + if queued { + outMsgs <- ioSendQueued{...} + } + case scStatusRequestMessage + r.sendStatusRequestToPeer(...) + case bcPeerError + r.Swtich.StopPeerForError(msg.src) + ... + ... + case bcFinished + break; + } + } +} + +``` +### Processor Internals + +The processor is responsible for ordering, verifying and executing blocks. The Processor will maintain an internal cursor `height` refering to the last processed block. As a set of blocks arrive unordered, the Processor will check if it has `height+1` necessary to process the next block. The processor also maintains the map `blockPeers` of peers to height, to keep track of which peer provided the block at `height`. `blockPeers` can be used in`handleRemovePeer(...)` to reschedule all unprocessed blocks provided by a peer who has errored. + +```go +type Processor struct { + height int64 // the height cursor + state ... + blocks [height]*Block // keep a set of blocks in memory until they are processed + blockPeers [height]PeerID // keep track of which heights came from which peerID + lastTouch timestamp +} + +func (proc *Processor) handleBlockResponse(peerID, block) { + if block.height <= height || block[block.height] { + } else if blocks[block.height] { + return errDuplicateBlock{} + } else { + blocks[block.height] = block + } + + if blocks[height] && blocks[height+1] { + ... = state.Validators.VerifyCommit(...) + ... = store.SaveBlock(...) + state, err = blockExec.ApplyBlock(...) + ... + if err == nil { + delete blocks[height] + height++ + lastTouch = msg.time + return pcBlockProcessed{height-1} + } else { + ... // Delete all unprocessed block from the peer + return pcBlockProcessError{peerID, height} + } + } +} + +func (proc *Processor) handleRemovePeer(peerID) { + events = [] + // Delete all unprocessed blocks from peerID + for i = height; i < len(blocks); i++ { + if blockPeers[i] == peerID { + events = append(events, pcBlockReschedule{height}) + + delete block[height] + } + } + return events +} + +func handleTimeCheckEv(time) { + if time - lastTouch > timeout { + // Timeout the processor + ... + } +} +``` + +## Schedule + +The Schedule maintains the internal state used for scheduling blockRequestMessages based on some scheduling algorithm. The schedule needs to maintain state on: + +* The state `blockState` of every block seem up to height of maxHeight +* The set of peers and their peer state `peerState` +* which peers have which blocks +* which blocks have been requested from which peers + +```go +type blockState int + +const ( + blockStateNew = iota + blockStatePending, + blockStateReceived, + blockStateProcessed +) + +type schedule { + // a list of blocks in which blockState + blockStates map[height]blockState + + // a map of which blocks are available from which peers + blockPeers map[height]map[p2p.ID]scPeer + + // a map of peerID to schedule specific peer struct `scPeer` + peers map[p2p.ID]scPeer + + // a map of heights to the peer we are waiting for a response from + pending map[height]scPeer + + targetPending int // the number of blocks we want in blockStatePending + targetReceived int // the number of blocks we want in blockStateReceived + + peerTimeout int + peerMinSpeed int +} + +func (sc *schedule) numBlockInState(state blockState) uint32 { + num := 0 + for i := sc.minHeight(); i <= sc.maxHeight(); i++ { + if sc.blockState[i] == state { + num++ + } + } + return num +} + + +func (sc *schedule) popSchedule(maxRequest int) []scBlockRequestMessage { + // We only want to schedule requests such that we have less than sc.targetPending and sc.targetReceived + // This ensures we don't saturate the network or flood the processor with unprocessed blocks + todo := min(sc.targetPending - sc.numBlockInState(blockStatePending), sc.numBlockInState(blockStateReceived)) + events := []scBlockRequestMessage{} + for i := sc.minHeight(); i < sc.maxMaxHeight(); i++ { + if todo == 0 { + break + } + if blockStates[i] == blockStateNew { + peer = sc.selectPeer(blockPeers[i]) + sc.blockStates[i] = blockStatePending + sc.pending[i] = peer + events = append(events, scBlockRequestMessage{peerID: peer.peerID, height: i}) + todo-- + } + } + return events +} +... + +type scPeer struct { + peerID p2p.ID + numOustandingRequest int + lastTouched time.Time + monitor flow.Monitor +} + +``` + +# Scheduler +The scheduler is configured to maintain a target `n` of in flight +messages and will use feedback from `_blockResponseMessage`, +`_statusResponseMessage` and `_peerError` produce an optimal assignment +of scBlockRequestMessage at each `timeCheckEv`. + +``` + +func handleStatusResponse(peerID, height, time) { + schedule.touchPeer(peerID, time) + schedule.setPeerHeight(peerID, height) +} + +func handleBlockResponseMessage(peerID, height, block, time) { + schedule.touchPeer(peerID, time) + schedule.markReceived(peerID, height, size(block)) +} + +func handleNoBlockResponseMessage(peerID, height, time) { + schedule.touchPeer(peerID, time) + // reschedule that block, punish peer... + ... +} + +func handlePeerError(peerID) { + // Remove the peer, reschedule the requests + ... +} + +func handleTimeCheckEv(time) { + // clean peer list + + events = [] + for peerID := range schedule.peersNotTouchedSince(time) { + pending = schedule.pendingFrom(peerID) + schedule.setPeerState(peerID, timedout) + schedule.resetBlocks(pending) + events = append(events, peerTimeout{peerID}) + } + + events = append(events, schedule.popSchedule()) + + return events +} +``` + +## Peer +The Peer Stores per peer state based on messages received by the scheduler. + +```go +type Peer struct { + lastTouched timestamp + lastDownloaded timestamp + pending map[height]struct{} + height height // max height for the peer + state { + pending, // we know the peer but not the height + active, // we know the height + timeout // the peer has timed out + } +} +``` + +## Status + +Work in progress + +## Consequences + +### Positive + +* Test become deterministic +* Simulation becomes a-termporal: no need wait for a wall-time timeout +* Peer Selection can be independently tested/simulated +* Develop a general approach to refactoring reactors + +### Negative + +### Neutral + +### Implementation Path + +* Implement the scheduler, test the scheduler, review the rescheduler +* Implement the processor, test the processor, review the processor +* Implement the demuxer, write integration test, review integration tests + +## References + + +* [ADR-40](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-040-blockchain-reactor-refactor.md): The original blockchain reactor re-org proposal +* [Blockchain re-org](https://github.com/tendermint/tendermint/pull/3561): The current blockchain reactor re-org implementation (v1) diff --git a/docs/architecture/img/blockchain-reactor-v1.png b/docs/architecture/img/blockchain-reactor-v1.png new file mode 100644 index 0000000000000000000000000000000000000000..70debcd66988635a180efbf0fde3635458c59597 GIT binary patch literal 124042 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 literal 0 HcmV?d00001 diff --git a/docs/architecture/img/blockchain-reactor-v2.png b/docs/architecture/img/blockchain-reactor-v2.png new file mode 100644 index 0000000000000000000000000000000000000000..086bf71bd88d47e02fc4f47b563ebe365695836a GIT binary patch literal 120617 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

Ah*9Vo97=Fg^|9GhFQ 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 literal 0 HcmV?d00001 From f2ada0a604b4c0763bda2f64fac53d506d3beca7 Mon Sep 17 00:00:00 2001 From: Marko Date: Mon, 8 Jul 2019 19:54:24 +0200 Subject: [PATCH 12/34] docs: quick link fixes throughout docs and repo (#3776) * Quick link fixes throughout docs and repo - used markdown link tester to find broken links Signed-off-by: Marko Baricevic * minor change remove slash * pr comments * minor fix * remove docker.develop * remove master tag --- DOCKER/Dockerfile.develop | 34 --------------- DOCKER/README.md | 21 ++++----- docs/DOCS_README.md | 10 ++--- docs/app-dev/abci-cli.md | 6 +-- docs/app-dev/app-development.md | 4 +- docs/architecture/adr-018-ABCI-Validators.md | 9 ++-- docs/introduction/install.md | 4 +- docs/introduction/introduction.md | 4 +- docs/introduction/what-is-tendermint.md | 4 +- docs/networks/docker-compose.md | 6 +-- docs/networks/terraform-and-ansible.md | 2 +- docs/spec/abci/README.md | 4 +- docs/spec/abci/abci.md | 45 ++++++++++---------- docs/spec/abci/client-server.md | 11 +++-- docs/spec/blockchain/encoding.md | 26 +++++------ docs/spec/consensus/consensus.md | 2 +- docs/spec/reactors/mempool/reactor.md | 2 +- docs/spec/software/wal.md | 2 +- docs/tendermint-core/configuration.md | 5 +-- docs/tendermint-core/how-to-read-logs.md | 2 +- docs/tendermint-core/rpc.md | 2 +- 21 files changed, 80 insertions(+), 125 deletions(-) delete mode 100644 DOCKER/Dockerfile.develop diff --git a/DOCKER/Dockerfile.develop b/DOCKER/Dockerfile.develop deleted file mode 100644 index 943b21291..000000000 --- a/DOCKER/Dockerfile.develop +++ /dev/null @@ -1,34 +0,0 @@ -FROM alpine:3.7 - -ENV DATA_ROOT /tendermint -ENV TMHOME $DATA_ROOT - -RUN addgroup tmuser && \ - adduser -S -G tmuser tmuser - -RUN mkdir -p $DATA_ROOT && \ - chown -R tmuser:tmuser $DATA_ROOT - -RUN apk add --no-cache bash curl jq - -ENV GOPATH /go -ENV PATH "$PATH:/go/bin" -RUN mkdir -p /go/src/github.com/tendermint/tendermint && \ - apk add --no-cache go build-base git && \ - cd /go/src/github.com/tendermint/tendermint && \ - git clone https://github.com/tendermint/tendermint . && \ - git checkout develop && \ - make get_tools && \ - make install && \ - cd - && \ - rm -rf /go/src/github.com/tendermint/tendermint && \ - apk del go build-base git - -VOLUME $DATA_ROOT - -EXPOSE 26656 -EXPOSE 26657 - -ENTRYPOINT ["tendermint"] - -CMD ["node", "--moniker=`hostname`", "--proxy_app=kvstore"] diff --git a/DOCKER/README.md b/DOCKER/README.md index 43edce0fc..57e631aaa 100644 --- a/DOCKER/README.md +++ b/DOCKER/README.md @@ -12,28 +12,25 @@ - `0.9.1`, `0.9`, [(Dockerfile)](https://github.com/tendermint/tendermint/blob/809e0e8c5933604ba8b2d096803ada7c5ec4dfd3/DOCKER/Dockerfile) - `0.9.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/d474baeeea6c22b289e7402449572f7c89ee21da/DOCKER/Dockerfile) - `0.8.0`, `0.8` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/bf64dd21fdb193e54d8addaaaa2ecf7ac371de8c/DOCKER/Dockerfile) -- `develop` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/master/DOCKER/Dockerfile.develop) - -`develop` tag points to the [develop](https://github.com/tendermint/tendermint/tree/develop) branch. ## Quick reference -* **Where to get help:** - https://cosmos.network/community +- **Where to get help:** + [cosmos.network/ecosystem](https://cosmos.network/ecosystem) -* **Where to file issues:** - https://github.com/tendermint/tendermint/issues +- **Where to file issues:** + [Tendermint Issues](https://github.com/tendermint/tendermint/issues) -* **Supported Docker versions:** +- **Supported Docker versions:** [the latest release](https://github.com/moby/moby/releases) (down to 1.6 on a best-effort basis) ## Tendermint Tendermint Core is Byzantine Fault Tolerant (BFT) middleware that takes a state transition machine, written in any programming language, and securely replicates it on many machines. -For more background, see the [introduction](https://tendermint.readthedocs.io/en/master/introduction.html). +For more background, see the [the docs](https://tendermint.com/docs/introduction/#quick-start). -To get started developing applications, see the [application developers guide](https://tendermint.readthedocs.io/en/master/getting-started.html). +To get started developing applications, see the [application developers guide](https://tendermint.com/docs/introduction/quick-start.html). ## How to use this image @@ -48,7 +45,7 @@ docker run -it --rm -v "/tmp:/tendermint" tendermint/tendermint node --proxy_app ## Local cluster -To run a 4-node network, see the `Makefile` in the root of [the repo](https://github.com/tendermint/tendermint/master/Makefile) and run: +To run a 4-node network, see the `Makefile` in the root of [the repo](https://github.com/tendermint/tendermint/blob/master/Makefile) and run: ``` make build-linux @@ -60,7 +57,7 @@ Note that this will build and use a different image than the ones provided here. ## License -- Tendermint's license is [Apache 2.0](https://github.com/tendermint/tendermint/master/LICENSE). +- Tendermint's license is [Apache 2.0](https://github.com/tendermint/tendermint/blob/master/LICENSE). ## Contributing diff --git a/docs/DOCS_README.md b/docs/DOCS_README.md index 49c2030a2..5b743cfa9 100644 --- a/docs/DOCS_README.md +++ b/docs/DOCS_README.md @@ -6,14 +6,12 @@ The documentation for Tendermint Core is hosted at: - https://tendermint-staging.interblock.io/docs/ built from the files in this (`/docs`) directory for -[master](https://github.com/tendermint/tendermint/tree/master/docs) -and [develop](https://github.com/tendermint/tendermint/tree/develop/docs), -respectively. +[master](https://github.com/tendermint/tendermint/tree/master/docs) respectively. ## How It Works There is a CircleCI job listening for changes in the `/docs` directory, on both -the `master` and `develop` branches. Any updates to files in this directory +the `master` branch. Any updates to files in this directory on those branches will automatically trigger a website deployment. Under the hood, the private website repository has a `make build-docs` target consumed by a CircleCI job in that repo. @@ -35,7 +33,7 @@ of the sidebar. **NOTE:** Strongly consider the existing links - both within this directory and to the website docs - when moving or deleting files. -Links to directories *MUST* end in a `/`. +Links to directories _MUST_ end in a `/`. Relative links should be used nearly everywhere, having discovered and weighed the following: @@ -101,4 +99,4 @@ We are using [Algolia](https://www.algolia.com) to power full-text search. This ## Consistency Because the build processes are identical (as is the information contained herein), this file should be kept in sync as -much as possible with its [counterpart in the Cosmos SDK repo](https://github.com/cosmos/cosmos-sdk/blob/develop/docs/DOCS_README.md). +much as possible with its [counterpart in the Cosmos SDK repo](https://github.com/cosmos/cosmos-sdk/blob/master/docs/DOCS_README.md). diff --git a/docs/app-dev/abci-cli.md b/docs/app-dev/abci-cli.md index 7e9db91b9..4b21a4b2d 100644 --- a/docs/app-dev/abci-cli.md +++ b/docs/app-dev/abci-cli.md @@ -62,7 +62,7 @@ as `abci-cli` above. The kvstore just stores transactions in a merkle tree. Its code can be found -[here](https://github.com/tendermint/tendermint/blob/develop/abci/cmd/abci-cli/abci-cli.go) +[here](https://github.com/tendermint/tendermint/blob/master/abci/cmd/abci-cli/abci-cli.go) and looks like: ``` @@ -137,7 +137,7 @@ response. The server may be generic for a particular language, and we provide a [reference implementation in -Golang](https://github.com/tendermint/tendermint/tree/develop/abci/server). See the +Golang](https://github.com/tendermint/tendermint/tree/master/abci/server). See the [list of other ABCI implementations](./ecosystem.md) for servers in other languages. @@ -324,7 +324,7 @@ But the ultimate flexibility comes from being able to write the application easily in any language. We have implemented the counter in a number of languages [see the -example directory](https://github.com/tendermint/tendermint/tree/develop/abci/example). +example directory](https://github.com/tendermint/tendermint/tree/master/abci/example). To run the Node.js version, fist download & install [the Javascript ABCI server](https://github.com/tendermint/js-abci): diff --git a/docs/app-dev/app-development.md b/docs/app-dev/app-development.md index c9983beaa..ba21d3a37 100644 --- a/docs/app-dev/app-development.md +++ b/docs/app-dev/app-development.md @@ -48,9 +48,9 @@ open ABCI connection with the application, which hosts an ABCI server. Shown are the request and response types sent on each connection. Most of the examples below are from [kvstore -application](https://github.com/tendermint/tendermint/blob/develop/abci/example/kvstore/kvstore.go), +application](https://github.com/tendermint/tendermint/blob/master/abci/example/kvstore/kvstore.go), which is a part of the abci repo. [persistent_kvstore -application](https://github.com/tendermint/tendermint/blob/develop/abci/example/kvstore/persistent_kvstore.go) +application](https://github.com/tendermint/tendermint/blob/master/abci/example/kvstore/persistent_kvstore.go) is used to show `BeginBlock`, `EndBlock` and `InitChain` example implementations. diff --git a/docs/architecture/adr-018-ABCI-Validators.md b/docs/architecture/adr-018-ABCI-Validators.md index b632da855..f40efca15 100644 --- a/docs/architecture/adr-018-ABCI-Validators.md +++ b/docs/architecture/adr-018-ABCI-Validators.md @@ -2,10 +2,7 @@ ## Changelog -016-08-2018: Follow up from review: - - Revert changes to commit round - - Remind about justification for removing pubkey - - Update pros/cons +016-08-2018: Follow up from review: - Revert changes to commit round - Remind about justification for removing pubkey - Update pros/cons 05-08-2018: Initial draft ## Context @@ -35,11 +32,11 @@ message ValidatorUpdate { } ``` -As noted in ADR-009[https://github.com/tendermint/tendermint/blob/develop/docs/architecture/adr-009-ABCI-design.md], +As noted in ADR-009[https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-009-ABCI-design.md], the `Validator` does not contain a pubkey because quantum public keys are quite large and it would be wasteful to send them all over ABCI with every block. Thus, applications that want to take advantage of the information in BeginBlock -are *required* to store pubkeys in state (or use much less efficient lazy means +are _required_ to store pubkeys in state (or use much less efficient lazy means of verifying BeginBlock data). ### RequestBeginBlock diff --git a/docs/introduction/install.md b/docs/introduction/install.md index 00e04fa0b..0a013bed1 100644 --- a/docs/introduction/install.md +++ b/docs/introduction/install.md @@ -1,9 +1,9 @@ # Install Tendermint The fastest and easiest way to install the `tendermint` binary -is to run [this script](https://github.com/tendermint/tendermint/blob/develop/scripts/install/install_tendermint_ubuntu.sh) on +is to run [this script](https://github.com/tendermint/tendermint/blob/master/scripts/install/install_tendermint_ubuntu.sh) on a fresh Ubuntu instance, -or [this script](https://github.com/tendermint/tendermint/blob/develop/scripts/install/install_tendermint_bsd.sh) +or [this script](https://github.com/tendermint/tendermint/blob/master/scripts/install/install_tendermint_bsd.sh) on a fresh FreeBSD instance. Read the comments / instructions carefully (i.e., reset your terminal after running the script, make sure you are okay with the network connections being made). diff --git a/docs/introduction/introduction.md b/docs/introduction/introduction.md index f80a159ca..4f435bbf5 100644 --- a/docs/introduction/introduction.md +++ b/docs/introduction/introduction.md @@ -122,7 +122,7 @@ consensus engine, and provides a particular application state. ## ABCI Overview The [Application BlockChain Interface -(ABCI)](https://github.com/tendermint/tendermint/tree/develop/abci) +(ABCI)](https://github.com/tendermint/tendermint/tree/master/abci) allows for Byzantine Fault Tolerant replication of applications written in any programming language. @@ -190,7 +190,7 @@ core to the application. The application replies with corresponding response messages. The messages are specified here: [ABCI Message -Types](https://github.com/tendermint/tendermint/blob/develop/abci/README.md#message-types). +Types](https://github.com/tendermint/tendermint/blob/master/abci/README.md#message-types). The **DeliverTx** message is the work horse of the application. Each transaction in the blockchain is delivered with this message. The diff --git a/docs/introduction/what-is-tendermint.md b/docs/introduction/what-is-tendermint.md index a35dd9ec1..0371afc63 100644 --- a/docs/introduction/what-is-tendermint.md +++ b/docs/introduction/what-is-tendermint.md @@ -116,7 +116,7 @@ consensus engine, and provides a particular application state. ## ABCI Overview The [Application BlockChain Interface -(ABCI)](https://github.com/tendermint/tendermint/tree/develop/abci) +(ABCI)](https://github.com/tendermint/tendermint/tree/master/abci) allows for Byzantine Fault Tolerant replication of applications written in any programming language. @@ -184,7 +184,7 @@ core to the application. The application replies with corresponding response messages. The messages are specified here: [ABCI Message -Types](https://github.com/tendermint/tendermint/blob/develop/abci/README.md#message-types). +Types](https://github.com/tendermint/tendermint/blob/master/abci/README.md#message-types). The **DeliverTx** message is the work horse of the application. Each transaction in the blockchain is delivered with this message. The diff --git a/docs/networks/docker-compose.md b/docs/networks/docker-compose.md index 8db49af5e..37b53fafe 100644 --- a/docs/networks/docker-compose.md +++ b/docs/networks/docker-compose.md @@ -78,9 +78,9 @@ cd $GOPATH/src/github.com/tendermint/tendermint rm -rf ./build/node* ``` -## Configuring abci containers +## Configuring abci containers -To use your own abci applications with 4-node setup edit the [docker-compose.yaml](https://github.com/tendermint/tendermint/blob/develop/docker-compose.yml) file and add image to your abci application. +To use your own abci applications with 4-node setup edit the [docker-compose.yaml](https://github.com/tendermint/tendermint/blob/master/docker-compose.yml) file and add image to your abci application. ``` abci0: @@ -129,7 +129,7 @@ To use your own abci applications with 4-node setup edit the [docker-compose.yam ``` -Override the [command](https://github.com/tendermint/tendermint/blob/master/networks/local/localnode/Dockerfile#L12) in each node to connect to it's abci. +Override the [command](https://github.com/tendermint/tendermint/blob/master/networks/local/localnode/Dockerfile#L12) in each node to connect to it's abci. ``` node0: diff --git a/docs/networks/terraform-and-ansible.md b/docs/networks/terraform-and-ansible.md index 122591be0..3ef6056a0 100644 --- a/docs/networks/terraform-and-ansible.md +++ b/docs/networks/terraform-and-ansible.md @@ -8,7 +8,7 @@ testnets on those servers. ## Install NOTE: see the [integration bash -script](https://github.com/tendermint/tendermint/blob/develop/networks/remote/integration.sh) +script](https://github.com/tendermint/tendermint/blob/master/networks/remote/integration.sh) that can be run on a fresh DO droplet and will automatically spin up a 4 node testnet. The script more or less does everything described below. diff --git a/docs/spec/abci/README.md b/docs/spec/abci/README.md index bb1c38b6e..56d5e8aaf 100644 --- a/docs/spec/abci/README.md +++ b/docs/spec/abci/README.md @@ -2,11 +2,11 @@ ABCI is the interface between Tendermint (a state-machine replication engine) and your application (the actual state machine). It consists of a set of -*methods*, where each method has a corresponding `Request` and `Response` +_methods_, where each method has a corresponding `Request` and `Response` message type. Tendermint calls the ABCI methods on the ABCI application by sending the `Request*` messages and receiving the `Response*` messages in return. -All message types are defined in a [protobuf file](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto). +All message types are defined in a [protobuf file](https://github.com/tendermint/tendermint/blob/master/abci/types/types.proto). This allows Tendermint to run applications written in any programming language. This specification is split as follows: diff --git a/docs/spec/abci/abci.md b/docs/spec/abci/abci.md index abab7f548..31ac85abd 100644 --- a/docs/spec/abci/abci.md +++ b/docs/spec/abci/abci.md @@ -3,9 +3,9 @@ ## Overview The ABCI message types are defined in a [protobuf -file](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto). +file](https://github.com/tendermint/tendermint/blob/master/abci/types/types.proto). -ABCI methods are split across 3 separate ABCI *connections*: +ABCI methods are split across 3 separate ABCI _connections_: - `Consensus Connection`: `InitChain, BeginBlock, DeliverTx, EndBlock, Commit` - `Mempool Connection`: `CheckTx` @@ -85,7 +85,7 @@ Example: cmn.KVPair{Key: []byte("amount"), Value: []byte("...")}, cmn.KVPair{Key: []byte("reason"), Value: []byte("...")}, }, - }, + }, // ... }, } @@ -115,19 +115,19 @@ non-determinism must be fixed and the nodes restarted. Sources of non-determinism in applications may include: - Hardware failures - - Cosmic rays, overheating, etc. + - Cosmic rays, overheating, etc. - Node-dependent state - - Random numbers - - Time + - Random numbers + - Time - Underspecification - - Library version changes - - Race conditions - - Floating point numbers - - JSON serialization - - Iterating through hash-tables/maps/dictionaries + - Library version changes + - Race conditions + - Floating point numbers + - JSON serialization + - Iterating through hash-tables/maps/dictionaries - External Sources - - Filesystem - - Network calls (eg. some external REST API service) + - Filesystem + - Network calls (eg. some external REST API service) See [#56](https://github.com/tendermint/abci/issues/56) for original discussion. @@ -240,9 +240,9 @@ Commit are included in the header of the next block. - `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. + underlying store. The key SHOULD be specified in the Data field. - Apps SHOULD allow queries over specific types like - '/accounts/...' or '/votes/...' + '/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 @@ -269,7 +269,7 @@ Commit are included in the header of the next block. - Query for data from the application at current or past height. - Optionally return Merkle proof. - Merkle proof includes self-describing `type` field to support many types - of Merkle trees and encoding formats. + of Merkle trees and encoding formats. ### BeginBlock @@ -486,7 +486,7 @@ Commit are included in the header of the next block. - `Votes ([]VoteInfo)`: List of validators addresses in the last validator set with their voting power and whether or not they signed a vote. -### ConsensusParams +### ConsensusParams - **Fields**: - `Block (BlockParams)`: Parameters limiting the size of a block and time between consecutive blocks. @@ -500,17 +500,17 @@ Commit are included in the header of the next block. - `MaxBytes (int64)`: Max size of a block, in bytes. - `MaxGas (int64)`: Max sum of `GasWanted` in a proposed block. - NOTE: blocks that violate this may be committed if there are Byzantine proposers. - It's the application's responsibility to handle this when processing a - block! + It's the application's responsibility to handle this when processing a + block! ### EvidenceParams - **Fields**: - `MaxAge (int64)`: Max age of evidence, in blocks. Evidence older than this is considered stale and ignored. - - This should correspond with an app's "unbonding period" or other - similar mechanism for handling Nothing-At-Stake attacks. - - NOTE: this should change to time (instead of blocks)! + - This should correspond with an app's "unbonding period" or other + similar mechanism for handling Nothing-At-Stake attacks. + - NOTE: this should change to time (instead of blocks)! ### ValidatorParams @@ -532,4 +532,3 @@ Commit are included in the header of the next block. - `Type (string)`: Type of Merkle proof and how it's encoded. - `Key ([]byte)`: Key in the Merkle tree that this proof is for. - `Data ([]byte)`: Encoded Merkle proof for the key. - diff --git a/docs/spec/abci/client-server.md b/docs/spec/abci/client-server.md index 5ac7b3eb4..94485f0d9 100644 --- a/docs/spec/abci/client-server.md +++ b/docs/spec/abci/client-server.md @@ -9,7 +9,7 @@ Applications](./apps.md). ## Message Protocol The message protocol consists of pairs of requests and responses defined in the -[protobuf file](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto). +[protobuf file](https://github.com/tendermint/tendermint/blob/master/abci/types/types.proto). Some messages have no fields, while others may include byte-arrays, strings, integers, or custom protobuf types. @@ -33,9 +33,9 @@ The latter two can be tested using the `abci-cli` by setting the `--abci` flag appropriately (ie. to `socket` or `grpc`). See examples, in various stages of maintenance, in -[Go](https://github.com/tendermint/tendermint/tree/develop/abci/server), +[Go](https://github.com/tendermint/tendermint/tree/master/abci/server), [JavaScript](https://github.com/tendermint/js-abci), -[Python](https://github.com/tendermint/tendermint/tree/develop/abci/example/python3/abci), +[Python](https://github.com/tendermint/tendermint/tree/master/abci/example/python3/abci), [C++](https://github.com/mdyring/cpp-tmsp), and [Java](https://github.com/jTendermint/jabci). @@ -44,14 +44,13 @@ See examples, in various stages of maintenance, in The simplest implementation uses function calls within Golang. This means ABCI applications written in Golang can be compiled with TendermintCore and run as a single binary. - ### GRPC If GRPC is available in your language, this is the easiest approach, though it will have significant performance overhead. To get started with GRPC, copy in the [protobuf -file](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto) +file](https://github.com/tendermint/tendermint/blob/master/abci/types/types.proto) and compile it using the GRPC plugin for your language. For instance, for golang, the command is `protoc --go_out=plugins=grpc:. types.proto`. See the [grpc documentation for more details](http://www.grpc.io/docs/). @@ -107,4 +106,4 @@ received or a block is committed. It is unlikely that you will need to implement a client. For details of our client, see -[here](https://github.com/tendermint/tendermint/tree/develop/abci/client). +[here](https://github.com/tendermint/tendermint/tree/master/abci/client). diff --git a/docs/spec/blockchain/encoding.md b/docs/spec/blockchain/encoding.md index 14d0e786b..170e91605 100644 --- a/docs/spec/blockchain/encoding.md +++ b/docs/spec/blockchain/encoding.md @@ -59,20 +59,20 @@ familiar with amino encoding. You can simply use below table and concatenate Prefix || Length (of raw bytes) || raw bytes ( while || stands for byte concatenation here). -| Type | Name | Prefix | Length | Notes | -| ------------------ | ----------------------------- | ---------- | -------- | ----- | -| PubKeyEd25519 | tendermint/PubKeyEd25519 | 0x1624DE64 | 0x20 | | -| PubKeySecp256k1 | tendermint/PubKeySecp256k1 | 0xEB5AE987 | 0x21 | | -| PrivKeyEd25519 | tendermint/PrivKeyEd25519 | 0xA3288910 | 0x40 | | -| PrivKeySecp256k1 | tendermint/PrivKeySecp256k1 | 0xE1B0F79B | 0x20 | | -| PubKeyMultisigThreshold | tendermint/PubKeyMultisigThreshold | 0x22C1F7E2 | variable | | +| Type | Name | Prefix | Length | Notes | +| ----------------------- | ---------------------------------- | ---------- | -------- | ----- | +| PubKeyEd25519 | tendermint/PubKeyEd25519 | 0x1624DE64 | 0x20 | | +| PubKeySecp256k1 | tendermint/PubKeySecp256k1 | 0xEB5AE987 | 0x21 | | +| PrivKeyEd25519 | tendermint/PrivKeyEd25519 | 0xA3288910 | 0x40 | | +| PrivKeySecp256k1 | tendermint/PrivKeySecp256k1 | 0xE1B0F79B | 0x20 | | +| PubKeyMultisigThreshold | tendermint/PubKeyMultisigThreshold | 0x22C1F7E2 | variable | | ### Example For example, the 33-byte (or 0x21-byte in hex) Secp256k1 pubkey - `020BD40F225A57ED383B440CF073BC5539D0341F5767D2BF2D78406D00475A2EE9` - would be encoded as - `EB5AE98721020BD40F225A57ED383B440CF073BC5539D0341F5767D2BF2D78406D00475A2EE9` +`020BD40F225A57ED383B440CF073BC5539D0341F5767D2BF2D78406D00475A2EE9` +would be encoded as +`EB5AE98721020BD40F225A57ED383B440CF073BC5539D0341F5767D2BF2D78406D00475A2EE9` ### Key Types @@ -170,11 +170,11 @@ We use the RFC 6962 specification of a merkle tree, with sha256 as the hash func Merkle trees are used throughout Tendermint to compute a cryptographic digest of a data structure. The differences between RFC 6962 and the simplest form a merkle tree are that: -1) leaf nodes and inner nodes have different hashes. +1. leaf nodes and inner nodes have different hashes. This is for "second pre-image resistance", to prevent the proof to an inner node being valid as the proof of a leaf. The leaf nodes are `SHA256(0x00 || leaf_data)`, and inner nodes are `SHA256(0x01 || left_hash || right_hash)`. -2) When the number of items isn't a power of two, the left half of the tree is as big as it could be. +2. When the number of items isn't a power of two, the left half of the tree is as big as it could be. (The largest power of two less than the number of items) This allows new leaves to be added with less recomputation. For example: @@ -290,7 +290,7 @@ func computeHashFromAunts(index, total int, leafHash []byte, innerHashes [][]byt ### IAVL+ Tree -Because Tendermint only uses a Simple Merkle Tree, application developers are expect to use their own Merkle tree in their applications. For example, the IAVL+ Tree - an immutable self-balancing binary tree for persisting application state is used by the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk/blob/develop/docs/sdk/core/multistore.md) +Because Tendermint only uses a Simple Merkle Tree, application developers are expect to use their own Merkle tree in their applications. For example, the IAVL+ Tree - an immutable self-balancing binary tree for persisting application state is used by the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk/blob/master/docs/clients/lite/specification.md) ## JSON diff --git a/docs/spec/consensus/consensus.md b/docs/spec/consensus/consensus.md index acd07397a..ec6659c96 100644 --- a/docs/spec/consensus/consensus.md +++ b/docs/spec/consensus/consensus.md @@ -120,7 +120,7 @@ A proposal is signed and published by the designated proposer at each round. The proposer is chosen by a deterministic and non-choking round robin selection algorithm that selects proposers in proportion to their voting power (see -[implementation](https://github.com/tendermint/tendermint/blob/develop/types/validator_set.go)). +[implementation](https://github.com/tendermint/tendermint/blob/master/types/validator_set.go)). A proposal at `(H,R)` is composed of a block and an optional latest `PoLC-Round < R` which is included iff the proposer knows of one. This diff --git a/docs/spec/reactors/mempool/reactor.md b/docs/spec/reactors/mempool/reactor.md index d349fc7cc..7e9a2d8fe 100644 --- a/docs/spec/reactors/mempool/reactor.md +++ b/docs/spec/reactors/mempool/reactor.md @@ -7,7 +7,7 @@ See [this issue](https://github.com/tendermint/tendermint/issues/1503) Mempool maintains a cache of the last 10000 transactions to prevent replaying old transactions (plus transactions coming from other validators, who are continually exchanging transactions). Read [Replay -Protection](../../../../app-development.md#replay-protection) +Protection](../../../app-dev/app-development.md#replay-protection) for details. Sending incorrectly encoded data or data exceeding `maxMsgSize` will result diff --git a/docs/spec/software/wal.md b/docs/spec/software/wal.md index 1f5d712c5..889ce4868 100644 --- a/docs/spec/software/wal.md +++ b/docs/spec/software/wal.md @@ -28,5 +28,5 @@ WAL. Then it will go to precommit, and that time it will work because the private validator contains the `LastSignBytes` and then we’ll replay the precommit from the WAL. -Make sure to read about [WAL corruption](../../../tendermint-core/running-in-production.md#wal-corruption) +Make sure to read about [WAL corruption](../../tendermint-core/running-in-production.md#wal-corruption) and recovery strategies. diff --git a/docs/tendermint-core/configuration.md b/docs/tendermint-core/configuration.md index df05f7c5d..b9f784596 100644 --- a/docs/tendermint-core/configuration.md +++ b/docs/tendermint-core/configuration.md @@ -315,8 +315,7 @@ namespace = "tendermint" If `create_empty_blocks` is set to `true` in your config, blocks will be created ~ every second (with default consensus parameters). You can regulate -the delay between blocks by changing the `timeout_commit`. E.g. `timeout_commit -= "10s"` should result in ~ 10 second blocks. +the delay between blocks by changing the `timeout_commit`. E.g. `timeout_commit = "10s"` should result in ~ 10 second blocks. **create_empty_blocks = false** @@ -342,7 +341,7 @@ Tendermint will only create blocks if there are transactions, or after waiting ## Consensus timeouts explained There's a variety of information about timeouts in [Running in -production](./running-in-production.html) +production](./running-in-production.md) You can also find more detailed technical explanation in the spec: [The latest gossip on BFT consensus](https://arxiv.org/abs/1807.04938). diff --git a/docs/tendermint-core/how-to-read-logs.md b/docs/tendermint-core/how-to-read-logs.md index 54c2c8a32..e852298b8 100644 --- a/docs/tendermint-core/how-to-read-logs.md +++ b/docs/tendermint-core/how-to-read-logs.md @@ -115,7 +115,7 @@ little overview what they do. - `abci-client` As mentioned in [Application Development Guide](../app-dev/app-development.md), Tendermint acts as an ABCI client with respect to the application and maintains 3 connections: mempool, consensus and query. The code used by Tendermint Core can - be found [here](https://github.com/tendermint/tendermint/tree/develop/abci/client). + be found [here](https://github.com/tendermint/tendermint/tree/master/abci/client). - `blockchain` Provides storage, pool (a group of peers), and reactor for both storing and exchanging blocks between peers. - `consensus` The heart of Tendermint core, which is the diff --git a/docs/tendermint-core/rpc.md b/docs/tendermint-core/rpc.md index 4ea5ab0d9..1b8e24426 100644 --- a/docs/tendermint-core/rpc.md +++ b/docs/tendermint-core/rpc.md @@ -4,4 +4,4 @@ The RPC documentation is hosted here: - [https://tendermint.com/rpc/](https://tendermint.com/rpc/) -To update the documentation, edit the relevant `godoc` comments in the [rpc/core directory](https://github.com/tendermint/tendermint/tree/develop/rpc/core). +To update the documentation, edit the relevant `godoc` comments in the [rpc/core directory](https://github.com/tendermint/tendermint/tree/master/rpc/core). From ddee2d641f864d62212bc3ab318f5ff7b64d9aa3 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Wed, 10 Jul 2019 09:48:31 +0100 Subject: [PATCH 13/34] infrastructure for reproducible builds (#3770) * Add deterministic buildsystem * Update CircleCI config * Enable build on all branches for testing purposes * Revert "Enable build on all branches for testing purposes" This reverts commit bf5cf66da94bf9c23787b42995b0409492805f03. * Remove develop from branch filters * Remove dangling reference to develop * Upload binaries too * Build for stable branches too --- .circleci/config.yml | 35 ++- scripts/gitian-build.sh | 201 ++++++++++++++++++ scripts/gitian-descriptors/gitian-darwin.yml | 111 ++++++++++ scripts/gitian-descriptors/gitian-linux.yml | 110 ++++++++++ scripts/gitian-descriptors/gitian-windows.yml | 111 ++++++++++ scripts/gitian-keys/README.md | 29 +++ scripts/gitian-keys/keys.txt | 1 + 7 files changed, 597 insertions(+), 1 deletion(-) create mode 100755 scripts/gitian-build.sh create mode 100644 scripts/gitian-descriptors/gitian-darwin.yml create mode 100644 scripts/gitian-descriptors/gitian-linux.yml create mode 100644 scripts/gitian-descriptors/gitian-windows.yml create mode 100644 scripts/gitian-keys/README.md create mode 100644 scripts/gitian-keys/keys.txt diff --git a/.circleci/config.yml b/.circleci/config.yml index 5836b4546..539dd7ee4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -331,6 +331,34 @@ jobs: docker push "tendermint/tendermint" docker logout + reproducible_builds: + <<: *defaults + steps: + - attach_workspace: + at: /tmp/workspace + - checkout + - setup_remote_docker: + docker_layer_caching: true + - run: + name: Build tendermint + no_output_timeout: 20m + command: | + sudo apt-get install -y ruby + bash -x ./scripts/gitian-build.sh all + for os in darwin linux windows; do + cp gitian-build-${os}/result/tendermint-${os}-res.yml . + cp gitian-build-${os}/build/out/tendermint-*.tar.gz . + rm -rf gitian-build-${os}/ + done + - store_artifacts: + path: /go/src/github.com/tendermint/tendermint/tendermint-darwin-res.yml + - store_artifacts: + path: /go/src/github.com/tendermint/tendermint/tendermint-linux-res.yml + - store_artifacts: + path: /go/src/github.com/tendermint/tendermint/tendermint-windows-res.yml + - store_artifacts: + path: /go/src/github.com/tendermint/tendermint/tendermint-*.tar.gz + workflows: version: 2 test-suite: @@ -340,7 +368,6 @@ workflows: branches: only: - master - - develop - setup_dependencies - test_abci_apps: requires: @@ -364,6 +391,12 @@ workflows: - upload_coverage: requires: - test_cover + - reproducible_builds: + filters: + branches: + only: + - master + - /v[0-9]+\.[0-9]+/ release: jobs: - prepare_build diff --git a/scripts/gitian-build.sh b/scripts/gitian-build.sh new file mode 100755 index 000000000..a7a6acec3 --- /dev/null +++ b/scripts/gitian-build.sh @@ -0,0 +1,201 @@ +#!/bin/bash + +# symbol prefixes: +# g_ -> global +# l_ - local variable +# f_ -> function + +set -euo pipefail + +GITIAN_CACHE_DIRNAME='.gitian-builder-cache' +GO_DEBIAN_RELEASE='1.12.5-1' +GO_TARBALL="golang-debian-${GO_DEBIAN_RELEASE}.tar.gz" +GO_TARBALL_URL="https://salsa.debian.org/go-team/compiler/golang/-/archive/debian/${GO_DEBIAN_RELEASE}/${GO_TARBALL}" + +# Defaults + +DEFAULT_SIGN_COMMAND='gpg --detach-sign' +DEFAULT_TENDERMINT_SIGS=${TENDERMINT_SIGS:-'tendermint.sigs'} +DEFAULT_GITIAN_REPO='https://github.com/devrandom/gitian-builder' +DEFAULT_GBUILD_FLAGS='' +DEFAULT_SIGS_REPO='https://github.com/tendermint/tendermint.sigs' + +# Overrides + +SIGN_COMMAND=${SIGN_COMMAND:-${DEFAULT_SIGN_COMMAND}} +GITIAN_REPO=${GITIAN_REPO:-${DEFAULT_GITIAN_REPO}} +GBUILD_FLAGS=${GBUILD_FLAGS:-${DEFAULT_GBUILD_FLAGS}} + +# Globals + +g_workdir='' +g_gitian_cache='' +g_cached_gitian='' +g_cached_go_tarball='' +g_sign_identity='' +g_sigs_dir='' +g_flag_commit='' + + +f_help() { + cat >&2 <&2 + mkdir "${l_builddir}/inputs/" + cp -v "${g_cached_go_tarball}" "${l_builddir}/inputs/" + done +} + +f_build() { + local l_descriptor + + l_descriptor=$1 + + bin/gbuild --commit tendermint="$g_commit" ${GBUILD_FLAGS} "$l_descriptor" + libexec/stop-target || f_echo_stderr "warning: couldn't stop target" +} + +f_sign_verify() { + local l_descriptor + + l_descriptor=$1 + + bin/gsign -p "${SIGN_COMMAND}" -s "${g_sign_identity}" --destination="${g_sigs_dir}" --release=${g_release} ${l_descriptor} + bin/gverify --destination="${g_sigs_dir}" --release="${g_release}" ${l_descriptor} +} + +f_commit_sig() { + local l_release_name + + l_release_name=$1 + + pushd "${g_sigs_dir}" + git add . || echo "git add failed" >&2 + git commit -m "Add ${l_release_name} reproducible build" || echo "git commit failed" >&2 + popd +} + +f_prep_docker_image() { + pushd $1 + bin/make-base-vm --docker --suite bionic --arch amd64 + popd +} + +f_ensure_cache() { + g_gitian_cache="${g_workdir}/${GITIAN_CACHE_DIRNAME}" + [ -d "${g_gitian_cache}" ] || mkdir "${g_gitian_cache}" + + g_cached_go_tarball="${g_gitian_cache}/${GO_TARBALL}" + if [ ! -f "${g_cached_go_tarball}" ]; then + f_echo_stderr "${g_cached_go_tarball}: cache miss, caching..." + curl -L "${GO_TARBALL_URL}" --output "${g_cached_go_tarball}" + fi + + g_cached_gitian="${g_gitian_cache}/gitian-builder" + if [ ! -d "${g_cached_gitian}" ]; then + f_echo_stderr "${g_cached_gitian}: cache miss, caching..." + git clone ${GITIAN_REPO} "${g_cached_gitian}" + fi +} + +f_demangle_platforms() { + case "${1}" in + all) + printf '%s' 'darwin linux windows' ;; + linux|darwin|windows) + printf '%s' "${1}" ;; + *) + echo "invalid platform -- ${1}" + exit 1 + esac +} + +f_echo_stderr() { + echo $@ >&2 +} + + +while getopts ":cs:h" opt; do + case "${opt}" in + h) f_help ; exit 0 ;; + c) g_flag_commit=y ;; + s) g_sign_identity="${OPTARG}" ;; + esac +done + +shift "$((OPTIND-1))" + +g_platforms=$(f_demangle_platforms "${1}") +g_workdir="$(pwd)" +g_commit="$(git rev-parse HEAD)" +g_sigs_dir=${TENDERMINT_SIGS:-"${g_workdir}/${DEFAULT_TENDERMINT_SIGS}"} + +f_ensure_cache + +f_prep_docker_image "${g_cached_gitian}" + +f_prep_build "${g_platforms}" + +export USE_DOCKER=1 +for g_os in ${g_platforms}; do + g_release="$(git describe --tags --abbrev=9 | sed 's/^v//')-${g_os}" + g_descriptor="${g_workdir}/scripts/gitian-descriptors/gitian-${g_os}.yml" + [ -f ${g_descriptor} ] + g_builddir="$(f_builddir ${g_os})" + + pushd "${g_builddir}" + f_build "${g_descriptor}" + if [ -n "${g_sign_identity}" ]; then + f_sign_verify "${g_descriptor}" + fi + popd + + if [ -n "${g_sign_identity}" -a -n "${g_flag_commit}" ]; then + [ -d "${g_sigs_dir}/.git/" ] && f_commit_sig ${g_release} || f_echo_stderr "couldn't commit, ${g_sigs_dir} is not a git clone" + fi +done + +exit 0 diff --git a/scripts/gitian-descriptors/gitian-darwin.yml b/scripts/gitian-descriptors/gitian-darwin.yml new file mode 100644 index 000000000..03ba1f1a4 --- /dev/null +++ b/scripts/gitian-descriptors/gitian-darwin.yml @@ -0,0 +1,111 @@ +--- +name: "tendermint-darwin" +enable_cache: true +distro: "ubuntu" +suites: +- "bionic" +architectures: +- "amd64" +packages: +- "bsdmainutils" +- "build-essential" +- "ca-certificates" +- "curl" +- "debhelper" +- "dpkg-dev" +- "devscripts" +- "fakeroot" +- "git" +- "golang-any" +- "xxd" +- "quilt" +remotes: +- "url": "https://github.com/tendermint/tendermint.git" + "dir": "tendermint" +files: +- "golang-debian-1.12.5-1.tar.gz" +script: | + set -e -o pipefail + + GO_SRC_RELEASE=golang-debian-1.12.5-1 + GO_SRC_TARBALL="${GO_SRC_RELEASE}.tar.gz" + # Compile go and configure the environment + export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" + export BUILD_DIR=`pwd` + tar xf "${GO_SRC_TARBALL}" + rm -f "${GO_SRC_TARBALL}" + [ -d "${GO_SRC_RELEASE}/" ] + mv "${GO_SRC_RELEASE}/" go/ + pushd go/ + QUILT_PATCHES=debian/patches quilt push -a + fakeroot debian/rules build RUN_TESTS=false GOCACHE=/tmp/go-cache + popd + + export GOOS=darwin + export GOROOT=${BUILD_DIR}/go + export GOPATH=${BUILD_DIR}/gopath + mkdir -p ${GOPATH}/bin + + export PATH_orig=${PATH} + export PATH=$GOPATH/bin:$GOROOT/bin:$PATH + + export ARCHS='386 amd64' + export GO111MODULE=on + + # Make release tarball + pushd tendermint + VERSION=$(git describe --tags | sed 's/^v//') + COMMIT=$(git rev-parse --short=8 HEAD) + DISTNAME=tendermint-${VERSION} + git archive --format tar.gz --prefix ${DISTNAME}/ -o ${DISTNAME}.tar.gz HEAD + SOURCEDIST=`pwd`/`echo tendermint-*.tar.gz` + popd + + # Correct tar file order + mkdir -p temp + pushd temp + tar xf $SOURCEDIST + rm $SOURCEDIST + find tendermint-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > $SOURCEDIST + popd + + # Prepare GOPATH and install deps + distsrc=${GOPATH}/src/github.com/tendermint/tendermint + mkdir -p ${distsrc} + pushd ${distsrc} + tar --strip-components=1 -xf $SOURCEDIST + go mod download + popd + + # Configure LDFLAGS for reproducible builds + LDFLAGS="-extldflags=-static -buildid=${VERSION} -s -w \ + -X github.com/tendermint/tendermint/version.GitCommit=${COMMIT}" + + # Extract release tarball and build + for arch in ${ARCHS}; do + INSTALLPATH=`pwd`/installed/${DISTNAME}-${arch} + mkdir -p ${INSTALLPATH} + + # Build tendermint binary + pushd ${distsrc} + GOARCH=${arch} GOROOT_FINAL=${GOROOT} go build -a \ + -gcflags=all=-trimpath=${GOPATH} \ + -asmflags=all=-trimpath=${GOPATH} \ + -mod=readonly -tags "tendermint" \ + -ldflags="${LDFLAGS}" \ + -o ${INSTALLPATH}/tendermint ./cmd/tendermint/ + + popd # ${distsrc} + + pushd ${INSTALLPATH} + find -type f | sort | tar \ + --no-recursion --mode='u+rw,go+r-w,a+X' \ + --numeric-owner --sort=name \ + --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-darwin-${arch}.tar.gz + popd # installed + done + + rm -rf ${distsrc} + + mkdir -p $OUTDIR/src + mv $SOURCEDIST $OUTDIR/src diff --git a/scripts/gitian-descriptors/gitian-linux.yml b/scripts/gitian-descriptors/gitian-linux.yml new file mode 100644 index 000000000..f1c31c40e --- /dev/null +++ b/scripts/gitian-descriptors/gitian-linux.yml @@ -0,0 +1,110 @@ +--- +name: "tendermint-linux" +enable_cache: true +distro: "ubuntu" +suites: +- "bionic" +architectures: +- "amd64" +packages: +- "bsdmainutils" +- "build-essential" +- "ca-certificates" +- "curl" +- "debhelper" +- "dpkg-dev" +- "devscripts" +- "fakeroot" +- "git" +- "golang-any" +- "xxd" +- "quilt" +remotes: +- "url": "https://github.com/tendermint/tendermint.git" + "dir": "tendermint" +files: +- "golang-debian-1.12.5-1.tar.gz" +script: | + set -e -o pipefail + + GO_SRC_RELEASE=golang-debian-1.12.5-1 + GO_SRC_TARBALL="${GO_SRC_RELEASE}.tar.gz" + # Compile go and configure the environment + export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" + export BUILD_DIR=`pwd` + tar xf "${GO_SRC_TARBALL}" + rm -f "${GO_SRC_TARBALL}" + [ -d "${GO_SRC_RELEASE}/" ] + mv "${GO_SRC_RELEASE}/" go/ + pushd go/ + QUILT_PATCHES=debian/patches quilt push -a + fakeroot debian/rules build RUN_TESTS=false GOCACHE=/tmp/go-cache + popd + + export GOROOT=${BUILD_DIR}/go + export GOPATH=${BUILD_DIR}/gopath + mkdir -p ${GOPATH}/bin + + export PATH_orig=${PATH} + export PATH=$GOPATH/bin:$GOROOT/bin:$PATH + + export ARCHS='386 amd64 arm arm64' + export GO111MODULE=on + + # Make release tarball + pushd tendermint + VERSION=$(git describe --tags | sed 's/^v//') + COMMIT=$(git rev-parse --short=8 HEAD) + DISTNAME=tendermint-${VERSION} + git archive --format tar.gz --prefix ${DISTNAME}/ -o ${DISTNAME}.tar.gz HEAD + SOURCEDIST=`pwd`/`echo tendermint-*.tar.gz` + popd + + # Correct tar file order + mkdir -p temp + pushd temp + tar xf $SOURCEDIST + rm $SOURCEDIST + find tendermint-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > $SOURCEDIST + popd + + # Prepare GOPATH and install deps + distsrc=${GOPATH}/src/github.com/tendermint/tendermint + mkdir -p ${distsrc} + pushd ${distsrc} + tar --strip-components=1 -xf $SOURCEDIST + go mod download + popd + + # Configure LDFLAGS for reproducible builds + LDFLAGS="-extldflags=-static -buildid=${VERSION} -s -w \ + -X github.com/tendermint/tendermint/version.GitCommit=${COMMIT}" + + # Extract release tarball and build + for arch in ${ARCHS}; do + INSTALLPATH=`pwd`/installed/${DISTNAME}-${arch} + mkdir -p ${INSTALLPATH} + + # Build tendermint binary + pushd ${distsrc} + GOARCH=${arch} GOROOT_FINAL=${GOROOT} go build -a \ + -gcflags=all=-trimpath=${GOPATH} \ + -asmflags=all=-trimpath=${GOPATH} \ + -mod=readonly -tags "tendermint" \ + -ldflags="${LDFLAGS}" \ + -o ${INSTALLPATH}/tendermint ./cmd/tendermint/ + + popd # ${distsrc} + + pushd ${INSTALLPATH} + find -type f | sort | tar \ + --no-recursion --mode='u+rw,go+r-w,a+X' \ + --numeric-owner --sort=name \ + --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-linux-${arch}.tar.gz + popd # installed + done + + rm -rf ${distsrc} + + mkdir -p $OUTDIR/src + mv $SOURCEDIST $OUTDIR/src diff --git a/scripts/gitian-descriptors/gitian-windows.yml b/scripts/gitian-descriptors/gitian-windows.yml new file mode 100644 index 000000000..80b2e60d3 --- /dev/null +++ b/scripts/gitian-descriptors/gitian-windows.yml @@ -0,0 +1,111 @@ +--- +name: "tendermint-windows" +enable_cache: true +distro: "ubuntu" +suites: +- "bionic" +architectures: +- "amd64" +packages: +- "bsdmainutils" +- "build-essential" +- "ca-certificates" +- "curl" +- "debhelper" +- "dpkg-dev" +- "devscripts" +- "fakeroot" +- "git" +- "golang-any" +- "xxd" +- "quilt" +remotes: +- "url": "https://github.com/tendermint/tendermint.git" + "dir": "tendermint" +files: +- "golang-debian-1.12.5-1.tar.gz" +script: | + set -e -o pipefail + + GO_SRC_RELEASE=golang-debian-1.12.5-1 + GO_SRC_TARBALL="${GO_SRC_RELEASE}.tar.gz" + # Compile go and configure the environment + export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" + export BUILD_DIR=`pwd` + tar xf "${GO_SRC_TARBALL}" + rm -f "${GO_SRC_TARBALL}" + [ -d "${GO_SRC_RELEASE}/" ] + mv "${GO_SRC_RELEASE}/" go/ + pushd go/ + QUILT_PATCHES=debian/patches quilt push -a + fakeroot debian/rules build RUN_TESTS=false GOCACHE=/tmp/go-cache + popd + + export GOOS=windows + export GOROOT=${BUILD_DIR}/go + export GOPATH=${BUILD_DIR}/gopath + mkdir -p ${GOPATH}/bin + + export PATH_orig=${PATH} + export PATH=$GOPATH/bin:$GOROOT/bin:$PATH + + export ARCHS='386 amd64' + export GO111MODULE=on + + # Make release tarball + pushd tendermint + VERSION=$(git describe --tags | sed 's/^v//') + COMMIT=$(git rev-parse --short=8 HEAD) + DISTNAME=tendermint-${VERSION} + git archive --format tar.gz --prefix ${DISTNAME}/ -o ${DISTNAME}.tar.gz HEAD + SOURCEDIST=`pwd`/`echo tendermint-*.tar.gz` + popd + + # Correct tar file order + mkdir -p temp + pushd temp + tar xf $SOURCEDIST + rm $SOURCEDIST + find tendermint-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > $SOURCEDIST + popd + + # Prepare GOPATH and install deps + distsrc=${GOPATH}/src/github.com/tendermint/tendermint + mkdir -p ${distsrc} + pushd ${distsrc} + tar --strip-components=1 -xf $SOURCEDIST + go mod download + popd + + # Configure LDFLAGS for reproducible builds + LDFLAGS="-extldflags=-static -buildid=${VERSION} -s -w \ + -X github.com/tendermint/tendermint/version.GitCommit=${COMMIT}" + + # Extract release tarball and build + for arch in ${ARCHS}; do + INSTALLPATH=`pwd`/installed/${DISTNAME}-${arch} + mkdir -p ${INSTALLPATH} + + # Build tendermint binary + pushd ${distsrc} + GOARCH=${arch} GOROOT_FINAL=${GOROOT} go build -a \ + -gcflags=all=-trimpath=${GOPATH} \ + -asmflags=all=-trimpath=${GOPATH} \ + -mod=readonly -tags "tendermint" \ + -ldflags="${LDFLAGS}" \ + -o ${INSTALLPATH}/tendermint.exe ./cmd/tendermint/ + + popd # ${distsrc} + + pushd ${INSTALLPATH} + find -type f | sort | tar \ + --no-recursion --mode='u+rw,go+r-w,a+X' \ + --numeric-owner --sort=name \ + --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-windows-${arch}.tar.gz + popd # installed + done + + rm -rf ${distsrc} + + mkdir -p $OUTDIR/src + mv $SOURCEDIST $OUTDIR/src diff --git a/scripts/gitian-keys/README.md b/scripts/gitian-keys/README.md new file mode 100644 index 000000000..f4ad711a9 --- /dev/null +++ b/scripts/gitian-keys/README.md @@ -0,0 +1,29 @@ +## PGP keys of Gitian builders and Tendermint Developers + +The file `keys.txt` contains fingerprints of the public keys of Gitian builders +and active developers. + +The associated keys are mainly used to sign git commits or the build results +of Gitian builds. + +The most recent version of each pgp key can be found on most PGP key servers. + +Fetch the latest version from the key server to see if any key was revoked in +the meantime. +To fetch the latest version of all pgp keys in your gpg homedir, + +```sh +gpg --refresh-keys +``` + +To fetch keys of Gitian builders and active core developers, feed the list of +fingerprints of the primary keys into gpg: + +```sh +while read fingerprint keyholder_name; \ +do gpg --keyserver hkp://subset.pool.sks-keyservers.net \ +--recv-keys ${fingerprint}; done < ./keys.txt +``` + +Add your key to the list if you are a Tendermint core developer or you have +provided Gitian signatures for two major or minor releases of Tendermint. diff --git a/scripts/gitian-keys/keys.txt b/scripts/gitian-keys/keys.txt new file mode 100644 index 000000000..91330ae0b --- /dev/null +++ b/scripts/gitian-keys/keys.txt @@ -0,0 +1 @@ +04160004A8276E40BB9890FBE8A48AE5311D765A Alessio Treglia From fc1eb46587644452e3e0ba495679a7f1d37f85b3 Mon Sep 17 00:00:00 2001 From: Marko Date: Wed, 10 Jul 2019 11:06:03 +0200 Subject: [PATCH 14/34] libs/common: remove heap.go (#3780) * Remove file heap.go - cmn.Heap is not being used in cosmos-sdk, iavl nor tendermint repo. Signed-off-by: Marko Baricevic * changelog entry * Update CHANGELOG_PENDING.md closes #2432 --- CHANGELOG_PENDING.md | 22 ++++---- libs/common/heap.go | 125 ------------------------------------------- 2 files changed, 13 insertions(+), 134 deletions(-) delete mode 100644 libs/common/heap.go diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 9c4c8b684..cda247cb0 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -1,6 +1,6 @@ ## v0.32.1 -** +\*\* Special thanks to external contributors on this release: @@ -9,33 +9,37 @@ program](https://hackerone.com/tendermint). ### BREAKING CHANGES: -* CLI/RPC/Config +- CLI/RPC/Config -* Apps +- Apps + +- Go API -* Go API - [abci] \#2127 ABCI / mempool: Add a "Recheck Tx" indicator. Breaks the ABCI client interface (`abcicli.Client`) to allow for supplying the ABCI `types.RequestCheckTx` and `types.RequestDeliverTx` structs, and lets the mempool indicate to the ABCI app whether a CheckTx request is a recheck or not. - [libs] Remove unused `db/debugDB` and `common/colors.go` & `errors/errors.go` files (@marbar3778) + - [libs] \#2432 Remove unused `common/heap.go` file (@marbar3778) -* Blockchain Protocol +- Blockchain Protocol -* P2P Protocol +- P2P Protocol ### FEATURES: + - [node] Refactor `NewNode` to use functional options to make it more flexible and extensible in the future. -- [node] [\#3730](https://github.com/tendermint/tendermint/pull/3730) Add `CustomReactors` option to `NewNode` allowing caller to pass +- [node][\#3730](https://github.com/tendermint/tendermint/pull/3730) Add `CustomReactors` option to `NewNode` allowing caller to pass custom reactors to run inside Tendermint node (@ParthDesai) ### IMPROVEMENTS: - - [rpc] \#3700 Make possible to set absolute paths for TLS cert and key (@climber73) + +- [rpc] \#3700 Make possible to set absolute paths for TLS cert and key (@climber73) ### BUG FIXES: + - [p2p] \#3338 Prevent "sent next PEX request too soon" errors by not calling ensurePeers outside of ensurePeersRoutine - [behaviour] Return correct reason in MessageOutOfOrder (@jim380) - diff --git a/libs/common/heap.go b/libs/common/heap.go deleted file mode 100644 index b3bcb9db8..000000000 --- a/libs/common/heap.go +++ /dev/null @@ -1,125 +0,0 @@ -package common - -import ( - "bytes" - "container/heap" -) - -/* - Example usage: - - ``` - h := NewHeap() - - h.Push("msg1", 1) - h.Push("msg3", 3) - h.Push("msg2", 2) - - fmt.Println(h.Pop()) // msg1 - fmt.Println(h.Pop()) // msg2 - fmt.Println(h.Pop()) // msg3 - ``` -*/ -type Heap struct { - pq priorityQueue -} - -func NewHeap() *Heap { - return &Heap{pq: make([]*pqItem, 0)} -} - -func (h *Heap) Len() int64 { - return int64(len(h.pq)) -} - -func (h *Heap) Push(value interface{}, priority int) { - heap.Push(&h.pq, &pqItem{value: value, priority: cmpInt(priority)}) -} - -func (h *Heap) PushBytes(value interface{}, priority []byte) { - heap.Push(&h.pq, &pqItem{value: value, priority: cmpBytes(priority)}) -} - -func (h *Heap) PushComparable(value interface{}, priority Comparable) { - heap.Push(&h.pq, &pqItem{value: value, priority: priority}) -} - -func (h *Heap) Peek() interface{} { - if len(h.pq) == 0 { - return nil - } - return h.pq[0].value -} - -func (h *Heap) Update(value interface{}, priority Comparable) { - h.pq.Update(h.pq[0], value, priority) -} - -func (h *Heap) Pop() interface{} { - item := heap.Pop(&h.pq).(*pqItem) - return item.value -} - -//----------------------------------------------------------------------------- -// From: http://golang.org/pkg/container/heap/#example__priorityQueue - -type pqItem struct { - value interface{} - priority Comparable - index int -} - -type priorityQueue []*pqItem - -func (pq priorityQueue) Len() int { return len(pq) } - -func (pq priorityQueue) Less(i, j int) bool { - return pq[i].priority.Less(pq[j].priority) -} - -func (pq priorityQueue) Swap(i, j int) { - pq[i], pq[j] = pq[j], pq[i] - pq[i].index = i - pq[j].index = j -} - -func (pq *priorityQueue) Push(x interface{}) { - n := len(*pq) - item := x.(*pqItem) - item.index = n - *pq = append(*pq, item) -} - -func (pq *priorityQueue) Pop() interface{} { - old := *pq - n := len(old) - item := old[n-1] - item.index = -1 // for safety - *pq = old[0 : n-1] - return item -} - -func (pq *priorityQueue) Update(item *pqItem, value interface{}, priority Comparable) { - item.value = value - item.priority = priority - heap.Fix(pq, item.index) -} - -//-------------------------------------------------------------------------------- -// Comparable - -type Comparable interface { - Less(o interface{}) bool -} - -type cmpInt int - -func (i cmpInt) Less(o interface{}) bool { - return int(i) < int(o.(cmpInt)) -} - -type cmpBytes []byte - -func (bz cmpBytes) Less(o interface{}) bool { - return bytes.Compare([]byte(bz), []byte(o.(cmpBytes))) < 0 -} From d70871f41b8b4279b4a18505e3b2d49c3962be3e Mon Sep 17 00:00:00 2001 From: Ashley Vega <48948661+ashleyvega@users.noreply.github.com> Date: Wed, 10 Jul 2019 10:27:17 +0100 Subject: [PATCH 15/34] testnet: add consensus_params to testnet config generation (#3781) Also, document time_iota_ms. Closes #3723 Commits: * config: Add ConsensusParams when generating testnet config (#3723) * docs: Add explanation of time_iota_ms (#3723) * Update changelog_pending (#3723) --- CHANGELOG_PENDING.md | 1 + cmd/tendermint/commands/testnet.go | 7 ++++--- docs/tendermint-core/using-tendermint.md | 10 ++++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index cda247cb0..01b1bfabf 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -43,3 +43,4 @@ program](https://hackerone.com/tendermint). - [p2p] \#3338 Prevent "sent next PEX request too soon" errors by not calling ensurePeers outside of ensurePeersRoutine - [behaviour] Return correct reason in MessageOutOfOrder (@jim380) +- [config] \#3723 Add consensus_params to testnet config generation; document time_iota_ms (@ashleyvega) diff --git a/cmd/tendermint/commands/testnet.go b/cmd/tendermint/commands/testnet.go index f1dd6f16e..5e2dc1a3a 100644 --- a/cmd/tendermint/commands/testnet.go +++ b/cmd/tendermint/commands/testnet.go @@ -161,9 +161,10 @@ func testnetFiles(cmd *cobra.Command, args []string) error { // Generate genesis doc from generated validators genDoc := &types.GenesisDoc{ - GenesisTime: tmtime.Now(), - ChainID: "chain-" + cmn.RandStr(6), - Validators: genVals, + ChainID: "chain-" + cmn.RandStr(6), + ConsensusParams: types.DefaultConsensusParams(), + GenesisTime: tmtime.Now(), + Validators: genVals, } // Write genesis file. diff --git a/docs/tendermint-core/using-tendermint.md b/docs/tendermint-core/using-tendermint.md index 05d481b2c..8c2fa1e03 100644 --- a/docs/tendermint-core/using-tendermint.md +++ b/docs/tendermint-core/using-tendermint.md @@ -43,6 +43,11 @@ definition](https://github.com/tendermint/tendermint/blob/master/types/genesis.g - `chain_id`: ID of the blockchain. This must be unique for every blockchain. If your testnet blockchains do not have unique chain IDs, you will have a bad time. The ChainID must be less than 50 symbols. +- `consensus_params` + - `block` + - `time_iota_ms`: Minimum time increment between consecutive blocks (in + milliseconds). If the block header timestamp is ahead of the system clock, + decrease this value. - `validators`: List of initial validators. Note this may be overridden entirely by the application, and may be left empty to make explicit that the application will initialize the validator set with ResponseInitChain. @@ -63,9 +68,10 @@ definition](https://github.com/tendermint/tendermint/blob/master/types/genesis.g "genesis_time": "2018-11-13T18:11:50.277637Z", "chain_id": "test-chain-s4ui7D", "consensus_params": { - "block_size": { + "block": { "max_bytes": "22020096", - "max_gas": "-1" + "max_gas": "-1", + "time_iota_ms": "1000" }, "evidence": { "max_age": "100000" From f05c2a95586cdad1940e3ee2869b213a4bdd3bde Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Wed, 10 Jul 2019 13:36:48 +0400 Subject: [PATCH 16/34] p2p: extract ID validation into a separate func (#3754) * p2p: extract ID validation into a separate func - NewNetAddress panics if ID is invalid - NetAddress#Valid returns an error - remove ErrAddrBookInvalidAddrNoID Fixes #2722 * p2p: remove repetitive check in ReceiveAddrs * fix netaddress test --- p2p/netaddress.go | 58 +++++++++++++++++++++++++++--------------- p2p/netaddress_test.go | 15 ++++++++--- p2p/pex/addrbook.go | 8 ++---- p2p/pex/errors.go | 13 +++------- p2p/pex/pex_reactor.go | 16 +----------- 5 files changed, 56 insertions(+), 54 deletions(-) diff --git a/p2p/netaddress.go b/p2p/netaddress.go index d11504525..f39a60543 100644 --- a/p2p/netaddress.go +++ b/p2p/netaddress.go @@ -13,7 +13,7 @@ import ( "strings" "time" - "errors" + "github.com/pkg/errors" ) // NetAddress defines information about a peer on the network @@ -40,7 +40,7 @@ func IDAddressString(id ID, protocolHostPort string) string { // NewNetAddress returns a new NetAddress using the provided TCP // address. When testing, other net.Addr (except TCP) will result in // using 0.0.0.0:0. When normal run, other net.Addr (except TCP) will -// panic. +// panic. Panics if ID is invalid. // TODO: socks proxies? func NewNetAddress(id ID, addr net.Addr) *NetAddress { tcpAddr, ok := addr.(*net.TCPAddr) @@ -53,6 +53,11 @@ func NewNetAddress(id ID, addr net.Addr) *NetAddress { return netAddr } } + + if err := validateID(id); err != nil { + panic(fmt.Sprintf("Invalid ID %v: %v (addr: %v)", id, err, addr)) + } + ip := tcpAddr.IP port := uint16(tcpAddr.Port) na := NewNetAddressIPPort(ip, port) @@ -72,18 +77,11 @@ func NewNetAddressString(addr string) (*NetAddress, error) { } // get ID - idStr := spl[0] - idBytes, err := hex.DecodeString(idStr) - if err != nil { + if err := validateID(ID(spl[0])); err != nil { return nil, ErrNetAddressInvalid{addrWithoutProtocol, err} } - if len(idBytes) != IDByteLength { - return nil, ErrNetAddressInvalid{ - addrWithoutProtocol, - fmt.Errorf("invalid hex length - got %d, expected %d", len(idBytes), IDByteLength)} - } var id ID - id, addrWithoutProtocol = ID(idStr), spl[1] + id, addrWithoutProtocol = ID(spl[0]), spl[1] // get host and port host, portStr, err := net.SplitHostPort(addrWithoutProtocol) @@ -207,22 +205,28 @@ func (na *NetAddress) DialTimeout(timeout time.Duration) (net.Conn, error) { // Routable returns true if the address is routable. func (na *NetAddress) Routable() bool { + if err := na.Valid(); err != nil { + return false + } // TODO(oga) bitcoind doesn't include RFC3849 here, but should we? - return na.Valid() && !(na.RFC1918() || na.RFC3927() || na.RFC4862() || + return !(na.RFC1918() || na.RFC3927() || na.RFC4862() || na.RFC4193() || na.RFC4843() || na.Local()) } // For IPv4 these are either a 0 or all bits set address. For IPv6 a zero // address or one that matches the RFC3849 documentation address format. -func (na *NetAddress) Valid() bool { - if string(na.ID) != "" { - data, err := hex.DecodeString(string(na.ID)) - if err != nil || len(data) != IDByteLength { - return false - } +func (na *NetAddress) Valid() error { + if err := validateID(na.ID); err != nil { + return errors.Wrap(err, "invalid ID") } - return na.IP != nil && !(na.IP.IsUnspecified() || na.RFC3849() || - na.IP.Equal(net.IPv4bcast)) + + if na.IP == nil { + return errors.New("no IP") + } + if na.IP.IsUnspecified() || na.RFC3849() || na.IP.Equal(net.IPv4bcast) { + return errors.New("invalid IP") + } + return nil } // HasID returns true if the address has an ID. @@ -329,3 +333,17 @@ func removeProtocolIfDefined(addr string) string { return addr } + +func validateID(id ID) error { + if len(id) == 0 { + return errors.New("no ID") + } + idBytes, err := hex.DecodeString(string(id)) + if err != nil { + return err + } + if len(idBytes) != IDByteLength { + return fmt.Errorf("invalid hex length - got %d, expected %d", len(idBytes), IDByteLength) + } + return nil +} diff --git a/p2p/netaddress_test.go b/p2p/netaddress_test.go index 7afcab131..e7d82cd77 100644 --- a/p2p/netaddress_test.go +++ b/p2p/netaddress_test.go @@ -11,9 +11,13 @@ import ( func TestNewNetAddress(t *testing.T) { tcpAddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:8080") require.Nil(t, err) - addr := NewNetAddress("", tcpAddr) - assert.Equal(t, "127.0.0.1:8080", addr.String()) + assert.Panics(t, func() { + NewNetAddress("", tcpAddr) + }) + + addr := NewNetAddress("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", tcpAddr) + assert.Equal(t, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", addr.String()) assert.NotPanics(t, func() { NewNetAddress("", &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8000}) @@ -106,7 +110,12 @@ func TestNetAddressProperties(t *testing.T) { addr, err := NewNetAddressString(tc.addr) require.Nil(t, err) - assert.Equal(t, tc.valid, addr.Valid()) + err = addr.Valid() + if tc.valid { + assert.NoError(t, err) + } else { + assert.Error(t, err) + } assert.Equal(t, tc.local, addr.Local()) assert.Equal(t, tc.routable, addr.Routable()) } diff --git a/p2p/pex/addrbook.go b/p2p/pex/addrbook.go index 85dd05248..cfe2569ba 100644 --- a/p2p/pex/addrbook.go +++ b/p2p/pex/addrbook.go @@ -586,8 +586,8 @@ func (a *addrBook) addAddress(addr, src *p2p.NetAddress) error { return ErrAddrBookNilAddr{addr, src} } - if !addr.HasID() { - return ErrAddrBookInvalidAddrNoID{addr} + if err := addr.Valid(); err != nil { + return ErrAddrBookInvalidAddr{Addr: addr, AddrErr: err} } if _, ok := a.privateIDs[addr.ID]; ok { @@ -607,10 +607,6 @@ func (a *addrBook) addAddress(addr, src *p2p.NetAddress) error { return ErrAddrBookNonRoutable{addr} } - if !addr.Valid() { - return ErrAddrBookInvalidAddr{addr} - } - ka := a.addrLookup[addr.ID] if ka != nil { // If its already old and the addr is the same, ignore it. diff --git a/p2p/pex/errors.go b/p2p/pex/errors.go index 543056af5..911389a9e 100644 --- a/p2p/pex/errors.go +++ b/p2p/pex/errors.go @@ -56,17 +56,10 @@ func (err ErrAddrBookNilAddr) Error() string { } type ErrAddrBookInvalidAddr struct { - Addr *p2p.NetAddress + Addr *p2p.NetAddress + AddrErr error } func (err ErrAddrBookInvalidAddr) Error() string { - return fmt.Sprintf("Cannot add invalid address %v", err.Addr) -} - -type ErrAddrBookInvalidAddrNoID struct { - Addr *p2p.NetAddress -} - -func (err ErrAddrBookInvalidAddrNoID) Error() string { - return fmt.Sprintf("Cannot add address with no ID %v", err.Addr) + return fmt.Sprintf("Cannot add invalid address %v: %v", err.Addr, err.AddrErr) } diff --git a/p2p/pex/pex_reactor.go b/p2p/pex/pex_reactor.go index 20862d323..557e7ca75 100644 --- a/p2p/pex/pex_reactor.go +++ b/p2p/pex/pex_reactor.go @@ -350,22 +350,8 @@ func (r *PEXReactor) ReceiveAddrs(addrs []*p2p.NetAddress, src Peer) error { } for _, netAddr := range addrs { - // Validate netAddr. Disconnect from a peer if it sends us invalid data. - if netAddr == nil { - return errors.New("nil address in pexAddrsMessage") - } - // TODO: extract validating logic from NewNetAddressString - // and put it in netAddr#Valid (#2722) - na, err := p2p.NewNetAddressString(netAddr.String()) - if err != nil { - return fmt.Errorf("%s address in pexAddrsMessage is invalid: %v", - netAddr.String(), - err, - ) - } - // NOTE: we check netAddr validity and routability in book#AddAddress. - err = r.book.AddAddress(na, srcAddr) + err = r.book.AddAddress(netAddr, srcAddr) if err != nil { r.logErrAddrBook(err) // XXX: should we be strict about incoming data and disconnect from a From e9c9c558d7a347b37c9ac6ca770107f84ad24696 Mon Sep 17 00:00:00 2001 From: Marko Date: Wed, 10 Jul 2019 16:40:21 +0200 Subject: [PATCH 17/34] libs/common: remove unused functions (#3784) - The removed functions are not used in Iavl, Cosmos-sdk and tendermint repos - Code-hygenie `whoop whoop` Signed-off-by: Marko Baricevic --- CHANGELOG_PENDING.md | 1 + libs/common/date.go | 43 ----------------------- libs/common/date_test.go | 46 ------------------------- libs/common/io.go | 74 ---------------------------------------- libs/common/os.go | 61 --------------------------------- libs/common/os_test.go | 46 ------------------------- 6 files changed, 1 insertion(+), 270 deletions(-) delete mode 100644 libs/common/date.go delete mode 100644 libs/common/date_test.go delete mode 100644 libs/common/io.go delete mode 100644 libs/common/os_test.go diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 01b1bfabf..d387f9ecb 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -22,6 +22,7 @@ program](https://hackerone.com/tendermint). not. - [libs] Remove unused `db/debugDB` and `common/colors.go` & `errors/errors.go` files (@marbar3778) - [libs] \#2432 Remove unused `common/heap.go` file (@marbar3778) + - [libs] Remove unused `date.go`, `io.go`. Remove `GoPath()`, `Prompt()` and `IsDirEmpty()` functions from `os.go` (@marbar3778) - Blockchain Protocol diff --git a/libs/common/date.go b/libs/common/date.go deleted file mode 100644 index e017a4b41..000000000 --- a/libs/common/date.go +++ /dev/null @@ -1,43 +0,0 @@ -package common - -import ( - "strings" - "time" - - "github.com/pkg/errors" -) - -// TimeLayout helps to parse a date string of the format YYYY-MM-DD -// Intended to be used with the following function: -// time.Parse(TimeLayout, date) -var TimeLayout = "2006-01-02" //this represents YYYY-MM-DD - -// ParseDateRange parses a date range string of the format start:end -// where the start and end date are of the format YYYY-MM-DD. -// The parsed dates are time.Time and will return the zero time for -// unbounded dates, ex: -// unbounded start: :2000-12-31 -// unbounded end: 2000-12-31: -func ParseDateRange(dateRange string) (startDate, endDate time.Time, err error) { - dates := strings.Split(dateRange, ":") - if len(dates) != 2 { - err = errors.New("bad date range, must be in format date:date") - return - } - parseDate := func(date string) (out time.Time, err error) { - if len(date) == 0 { - return - } - out, err = time.Parse(TimeLayout, date) - return - } - startDate, err = parseDate(dates[0]) - if err != nil { - return - } - endDate, err = parseDate(dates[1]) - if err != nil { - return - } - return -} diff --git a/libs/common/date_test.go b/libs/common/date_test.go deleted file mode 100644 index 2c0632477..000000000 --- a/libs/common/date_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package common - -import ( - "testing" - "time" - - "github.com/stretchr/testify/assert" -) - -var ( - date = time.Date(2015, time.Month(12), 31, 0, 0, 0, 0, time.UTC) - date2 = time.Date(2016, time.Month(12), 31, 0, 0, 0, 0, time.UTC) - zero time.Time -) - -func TestParseDateRange(t *testing.T) { - assert := assert.New(t) - - var testDates = []struct { - dateStr string - start time.Time - end time.Time - errNil bool - }{ - {"2015-12-31:2016-12-31", date, date2, true}, - {"2015-12-31:", date, zero, true}, - {":2016-12-31", zero, date2, true}, - {"2016-12-31", zero, zero, false}, - {"2016-31-12:", zero, zero, false}, - {":2016-31-12", zero, zero, false}, - } - - for _, test := range testDates { - start, end, err := ParseDateRange(test.dateStr) - if test.errNil { - assert.Nil(err) - testPtr := func(want, have time.Time) { - assert.True(have.Equal(want)) - } - testPtr(test.start, start) - testPtr(test.end, end) - } else { - assert.NotNil(err) - } - } -} diff --git a/libs/common/io.go b/libs/common/io.go deleted file mode 100644 index fa0443e09..000000000 --- a/libs/common/io.go +++ /dev/null @@ -1,74 +0,0 @@ -package common - -import ( - "bytes" - "errors" - "io" -) - -type PrefixedReader struct { - Prefix []byte - reader io.Reader -} - -func NewPrefixedReader(prefix []byte, reader io.Reader) *PrefixedReader { - return &PrefixedReader{prefix, reader} -} - -func (pr *PrefixedReader) Read(p []byte) (n int, err error) { - if len(pr.Prefix) > 0 { - read := copy(p, pr.Prefix) - pr.Prefix = pr.Prefix[read:] - return read, nil - } - return pr.reader.Read(p) -} - -// NOTE: Not goroutine safe -type BufferCloser struct { - bytes.Buffer - Closed bool -} - -func NewBufferCloser(buf []byte) *BufferCloser { - return &BufferCloser{ - *bytes.NewBuffer(buf), - false, - } -} - -func (bc *BufferCloser) Close() error { - if bc.Closed { - return errors.New("BufferCloser already closed") - } - bc.Closed = true - return nil -} - -func (bc *BufferCloser) Write(p []byte) (n int, err error) { - if bc.Closed { - return 0, errors.New("Cannot write to closed BufferCloser") - } - return bc.Buffer.Write(p) -} - -func (bc *BufferCloser) WriteByte(c byte) error { - if bc.Closed { - return errors.New("Cannot write to closed BufferCloser") - } - return bc.Buffer.WriteByte(c) -} - -func (bc *BufferCloser) WriteRune(r rune) (n int, err error) { - if bc.Closed { - return 0, errors.New("Cannot write to closed BufferCloser") - } - return bc.Buffer.WriteRune(r) -} - -func (bc *BufferCloser) WriteString(s string) (n int, err error) { - if bc.Closed { - return 0, errors.New("Cannot write to closed BufferCloser") - } - return bc.Buffer.WriteString(s) -} diff --git a/libs/common/os.go b/libs/common/os.go index 7c3fad7ee..0e35524cf 100644 --- a/libs/common/os.go +++ b/libs/common/os.go @@ -1,39 +1,13 @@ package common import ( - "bufio" "fmt" - "io" "io/ioutil" "os" - "os/exec" "os/signal" - "strings" "syscall" ) -var gopath string - -// GoPath returns GOPATH env variable value. If it is not set, this function -// will try to call `go env GOPATH` subcommand. -func GoPath() string { - if gopath != "" { - return gopath - } - - path := os.Getenv("GOPATH") - if len(path) == 0 { - goCmd := exec.Command("go", "env", "GOPATH") - out, err := goCmd.Output() - if err != nil { - panic(fmt.Sprintf("failed to determine gopath: %v", err)) - } - path = string(out) - } - gopath = path - return path -} - type logger interface { Info(msg string, keyvals ...interface{}) } @@ -78,25 +52,6 @@ func EnsureDir(dir string, mode os.FileMode) error { return nil } -func IsDirEmpty(name string) (bool, error) { - f, err := os.Open(name) - if err != nil { - if os.IsNotExist(err) { - return true, err - } - // Otherwise perhaps a permission - // error or some other error. - return false, err - } - defer f.Close() - - _, err = f.Readdirnames(1) // Or f.Readdir(1) - if err == io.EOF { - return true, nil - } - return false, err // Either not empty or error, suits both cases -} - func FileExists(filePath string) bool { _, err := os.Stat(filePath) return !os.IsNotExist(err) @@ -125,19 +80,3 @@ func MustWriteFile(filePath string, contents []byte, mode os.FileMode) { Exit(fmt.Sprintf("MustWriteFile failed: %v", err)) } } - -//-------------------------------------------------------------------------------- - -func Prompt(prompt string, defaultValue string) (string, error) { - fmt.Print(prompt) - reader := bufio.NewReader(os.Stdin) - line, err := reader.ReadString('\n') - if err != nil { - return defaultValue, err - } - line = strings.TrimSpace(line) - if line == "" { - return defaultValue, nil - } - return line, nil -} diff --git a/libs/common/os_test.go b/libs/common/os_test.go deleted file mode 100644 index e8a23ebd6..000000000 --- a/libs/common/os_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package common - -import ( - "os" - "testing" -) - -func TestOSGoPath(t *testing.T) { - // restore original gopath upon exit - path := os.Getenv("GOPATH") - defer func() { - _ = os.Setenv("GOPATH", path) - }() - - err := os.Setenv("GOPATH", "~/testgopath") - if err != nil { - t.Fatal(err) - } - path = GoPath() - if path != "~/testgopath" { - t.Fatalf("should get GOPATH env var value, got %v", path) - } - os.Unsetenv("GOPATH") - - path = GoPath() - if path != "~/testgopath" { - t.Fatalf("subsequent calls should return the same value, got %v", path) - } -} - -func TestOSGoPathWithoutEnvVar(t *testing.T) { - // restore original gopath upon exit - path := os.Getenv("GOPATH") - defer func() { - _ = os.Setenv("GOPATH", path) - }() - - os.Unsetenv("GOPATH") - // reset cache - gopath = "" - - path = GoPath() - if path == "" || path == "~/testgopath" { - t.Fatalf("should get nonempty result of calling go env GOPATH, got %v", path) - } -} From ac232caef364f216504b66050ddbae5a4e79f62e Mon Sep 17 00:00:00 2001 From: Marko Baricevic Date: Thu, 11 Jul 2019 18:34:21 +0200 Subject: [PATCH 18/34] Release branch for v0.32.1 Signed-off-by: Marko Baricevic --- CHANGELOG.md | 79 +++++++++++++++++++++++++++++++++++--------- CHANGELOG_PENDING.md | 27 +-------------- version/version.go | 2 +- 3 files changed, 66 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76f547a05..c27538ab5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,54 @@ # Changelog +## v0.32.1 + +*July 12, 2019* + +Special thanks to external contributors on this release: + +Friendly reminder, we have a [bug bounty +program](https://hackerone.com/tendermint). + +### BREAKING CHANGES: + +- CLI/RPC/Config + +- Apps + +- Go API + + - [abci] [\#2127](https://github.com/tendermint/tendermint/issues/2127) ABCI / mempool: Add a "Recheck Tx" indicator. Breaks the ABCI + client interface (`abcicli.Client`) to allow for supplying the ABCI + `types.RequestCheckTx` and `types.RequestDeliverTx` structs, and lets the + mempool indicate to the ABCI app whether a CheckTx request is a recheck or + not. + - [libs] Remove unused `db/debugDB` and `common/colors.go` & `errors/errors.go` files (@marbar3778) + - [libs] [\#2432](https://github.com/tendermint/tendermint/issues/2432) Remove unused `common/heap.go` file (@marbar3778) + - [libs] Remove unused `date.go`, `io.go`. Remove `GoPath()`, `Prompt()` and `IsDirEmpty()` functions from `os.go` (@marbar3778) + +- Blockchain Protocol + +- P2P Protocol + +### FEATURES: + +- [node] Refactor `NewNode` to use functional options to make it more flexible + and extensible in the future. +- [node][\#3730](https://github.com/tendermint/tendermint/pull/3730) Add `CustomReactors` option to `NewNode` allowing caller to pass + custom reactors to run inside Tendermint node (@ParthDesai) + +### IMPROVEMENTS: + +- [rpc] [\#3700](https://github.com/tendermint/tendermint/issues/3700) Make possible to set absolute paths for TLS cert and key (@climber73) + +### BUG FIXES: + +- [p2p] [\#3338](https://github.com/tendermint/tendermint/issues/3338) Prevent "sent next PEX request too soon" errors by not calling + ensurePeers outside of ensurePeersRoutine +- [behaviour] Return correct reason in MessageOutOfOrder (@jim380) +- [config] [\#3723](https://github.com/tendermint/tendermint/issues/3723) Add consensus_params to testnet config generation; document time_iota_ms (@ashleyvega) + + ## v0.32.0 *June 25, 2019* @@ -21,29 +70,29 @@ program](https://hackerone.com/tendermint). ### BREAKING CHANGES: * CLI/RPC/Config - - [cli] \#3613 Switch from golang/dep to Go Modules to resolve dependencies: + - [cli] [\#3613](https://github.com/tendermint/tendermint/issues/3613) Switch from golang/dep to Go Modules to resolve dependencies: It is recommended to switch to Go Modules if your project has tendermint as a dependency. Read more on Modules here: https://github.com/golang/go/wiki/Modules - [config] [\#3632](https://github.com/tendermint/tendermint/pull/3632) Removed `leveldb` as generic option for `db_backend`. Must be `goleveldb` or `cleveldb`. - - [rpc] \#3616 Fix field names for `/block_results` response (eg. `results.DeliverTx` + - [rpc] [\#3616](https://github.com/tendermint/tendermint/issues/3616) Fix field names for `/block_results` response (eg. `results.DeliverTx` -> `results.deliver_tx`). See docs for details. - - [rpc] \#3724 RPC now binds to `127.0.0.1` by default instead of `0.0.0.0` + - [rpc] [\#3724](https://github.com/tendermint/tendermint/issues/3724) RPC now binds to `127.0.0.1` by default instead of `0.0.0.0` * Apps - - [abci] \#1859 `ResponseCheckTx`, `ResponseDeliverTx`, `ResponseBeginBlock`, + - [abci] [\#1859](https://github.com/tendermint/tendermint/issues/1859) `ResponseCheckTx`, `ResponseDeliverTx`, `ResponseBeginBlock`, and `ResponseEndBlock` now include `Events` instead of `Tags`. Each `Event` contains a `type` and a list of `attributes` (list of key-value pairs) allowing for inclusion of multiple distinct events in each response. * Go API - - [abci] \#3193 Use RequestDeliverTx and RequestCheckTx in the ABCI + - [abci] [\#3193](https://github.com/tendermint/tendermint/issues/3193) Use RequestDeliverTx and RequestCheckTx in the ABCI Application interface - [libs/db] [\#3632](https://github.com/tendermint/tendermint/pull/3632) Removed deprecated `LevelDBBackend` const If you have `db_backend` set to `leveldb` in your config file, please change it to `goleveldb` or `cleveldb`. - - [p2p] \#3521 Remove NewNetAddressStringWithOptionalID + - [p2p] [\#3521](https://github.com/tendermint/tendermint/issues/3521) Remove NewNetAddressStringWithOptionalID * Blockchain Protocol @@ -52,16 +101,16 @@ program](https://hackerone.com/tendermint). ### FEATURES: ### IMPROVEMENTS: -- [abci/examples] \#3659 Change validator update tx format in the `persistent_kvstore` to use base64 for pubkeys instead of hex (@needkane) -- [consensus] \#3656 Exit if SwitchToConsensus fails -- [p2p] \#3666 Add per channel telemetry to improve reactor observability +- [abci/examples] [\#3659](https://github.com/tendermint/tendermint/issues/3659) Change validator update tx format in the `persistent_kvstore` to use base64 for pubkeys instead of hex (@needkane) +- [consensus] [\#3656](https://github.com/tendermint/tendermint/issues/3656) Exit if SwitchToConsensus fails +- [p2p] [\#3666](https://github.com/tendermint/tendermint/issues/3666) Add per channel telemetry to improve reactor observability - [rpc] [\#3686](https://github.com/tendermint/tendermint/pull/3686) `HTTPClient#Call` returns wrapped errors, so a caller could use `errors.Cause` to retrieve an error code. (@wooparadog) ### BUG FIXES: -- [libs/db] \#3717 Fixed the BoltDB backend's Batch.Delete implementation (@Yawning) -- [libs/db] \#3718 Fixed the BoltDB backend's Get and Iterator implementation (@Yawning) -- [node] \#3716 Fix a bug where `nil` is recorded as node's address -- [node] \#3741 Fix profiler blocking the entire node +- [libs/db] [\#3717](https://github.com/tendermint/tendermint/issues/3717) Fixed the BoltDB backend's Batch.Delete implementation (@Yawning) +- [libs/db] [\#3718](https://github.com/tendermint/tendermint/issues/3718) Fixed the BoltDB backend's Get and Iterator implementation (@Yawning) +- [node] [\#3716](https://github.com/tendermint/tendermint/issues/3716) Fix a bug where `nil` is recorded as node's address +- [node] [\#3741](https://github.com/tendermint/tendermint/issues/3741) Fix profiler blocking the entire node ## v0.31.7 @@ -72,11 +121,11 @@ The regression caused the invalid committed txs to be proposed in blocks over an over again. ### BUG FIXES: -- [mempool] \#3699 Remove all committed txs from the mempool. +- [mempool] [\#3699](https://github.com/tendermint/tendermint/issues/3699) Remove all committed txs from the mempool. This reverts the change from v0.31.6 where we only remove valid txs from the mempool. Note this means malicious proposals can cause txs to be dropped from the mempools of other nodes by including them in blocks before they are valid. - See \#3322. + See [\#3322](https://github.com/tendermint/tendermint/issues/3322). ## v0.31.6 diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index d387f9ecb..fd5c4b27e 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -1,4 +1,4 @@ -## v0.32.1 +## v0.32.2 \*\* @@ -15,33 +15,8 @@ program](https://hackerone.com/tendermint). - Go API - - [abci] \#2127 ABCI / mempool: Add a "Recheck Tx" indicator. Breaks the ABCI - client interface (`abcicli.Client`) to allow for supplying the ABCI - `types.RequestCheckTx` and `types.RequestDeliverTx` structs, and lets the - mempool indicate to the ABCI app whether a CheckTx request is a recheck or - not. - - [libs] Remove unused `db/debugDB` and `common/colors.go` & `errors/errors.go` files (@marbar3778) - - [libs] \#2432 Remove unused `common/heap.go` file (@marbar3778) - - [libs] Remove unused `date.go`, `io.go`. Remove `GoPath()`, `Prompt()` and `IsDirEmpty()` functions from `os.go` (@marbar3778) - -- Blockchain Protocol - -- P2P Protocol - ### FEATURES: -- [node] Refactor `NewNode` to use functional options to make it more flexible - and extensible in the future. -- [node][\#3730](https://github.com/tendermint/tendermint/pull/3730) Add `CustomReactors` option to `NewNode` allowing caller to pass - custom reactors to run inside Tendermint node (@ParthDesai) - ### IMPROVEMENTS: -- [rpc] \#3700 Make possible to set absolute paths for TLS cert and key (@climber73) - ### BUG FIXES: - -- [p2p] \#3338 Prevent "sent next PEX request too soon" errors by not calling - ensurePeers outside of ensurePeersRoutine -- [behaviour] Return correct reason in MessageOutOfOrder (@jim380) -- [config] \#3723 Add consensus_params to testnet config generation; document time_iota_ms (@ashleyvega) diff --git a/version/version.go b/version/version.go index 2d1c41fd5..c5d221551 100644 --- a/version/version.go +++ b/version/version.go @@ -20,7 +20,7 @@ const ( // Must be a string because scripts like dist.sh read this file. // XXX: Don't change the name of this variable or you will break // automation :) - TMCoreSemVer = "0.32.0" + TMCoreSemVer = "0.32.1" // ABCISemVer is the semantic version of the ABCI library ABCISemVer = "0.16.0" From 0f076e5fbef444c18107add3020dda09aea2984f Mon Sep 17 00:00:00 2001 From: Marko Baricevic Date: Thu, 11 Jul 2019 18:37:46 +0200 Subject: [PATCH 19/34] add links to changelog --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c27538ab5..a11b66dea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,13 @@ *July 12, 2019* -Special thanks to external contributors on this release: +Special thanks to external contributors on this release: +@ParthDesai, @climber73, @jim380, @ashleyvega + +This release contains breaking changes to our build and release processes, ABCI namely: +- Add a "Recheck Tx" indicator +- Removal of `db/debugDB`, `common/colors.go`, `errors/errors.go`, `common/heap.go`, `date.go`, `io.go` and + `GoPath()`, `Prompt()` and `IsDirEmpty()` functions from `os.go` Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermint). From e8926867d8edab5fb208dc6ecb4f25daef0911ab Mon Sep 17 00:00:00 2001 From: Marko Baricevic Date: Thu, 11 Jul 2019 21:22:14 +0200 Subject: [PATCH 20/34] wording change --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a11b66dea..9d7203d7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ Special thanks to external contributors on this release: @ParthDesai, @climber73, @jim380, @ashleyvega -This release contains breaking changes to our build and release processes, ABCI namely: +This release contains breaking changes to our libs folder and ABCI namely: - Add a "Recheck Tx" indicator - Removal of `db/debugDB`, `common/colors.go`, `errors/errors.go`, `common/heap.go`, `date.go`, `io.go` and `GoPath()`, `Prompt()` and `IsDirEmpty()` functions from `os.go` From 378a0e51bfbc11f8c9891a0fc18a2ff43536f51b Mon Sep 17 00:00:00 2001 From: Andy Nogueira <45477427+andynog@users.noreply.github.com> Date: Thu, 11 Jul 2019 15:31:42 -0400 Subject: [PATCH 21/34] docs: replace priv_validator.json with priv_validator_key.json (#3786) --- docs/tendermint-core/using-tendermint.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/tendermint-core/using-tendermint.md b/docs/tendermint-core/using-tendermint.md index 8c2fa1e03..abf382501 100644 --- a/docs/tendermint-core/using-tendermint.md +++ b/docs/tendermint-core/using-tendermint.md @@ -20,7 +20,7 @@ Initialize the root directory by running: tendermint init ``` -This will create a new private key (`priv_validator.json`), and a +This will create a new private key (`priv_validator_key.json`), and a genesis file (`genesis.json`) containing the associated public key, in `$TMHOME/config`. This is all that's necessary to run a local testnet with one validator. @@ -314,7 +314,7 @@ write-ahead-log](../tendermint-core/running-in-production.md#mempool-wal) ## Tendermint Networks When `tendermint init` is run, both a `genesis.json` and -`priv_validator.json` are created in `~/.tendermint/config`. The +`priv_validator_key.json` are created in `~/.tendermint/config`. The `genesis.json` might look like: ``` @@ -335,7 +335,7 @@ When `tendermint init` is run, both a `genesis.json` and } ``` -And the `priv_validator.json`: +And the `priv_validator_key.json`: ``` { @@ -354,20 +354,20 @@ And the `priv_validator.json`: } ``` -The `priv_validator.json` actually contains a private key, and should +The `priv_validator_key.json` actually contains a private key, and should thus be kept absolutely secret; for now we work with the plain text. Note the `last_` fields, which are used to prevent us from signing conflicting messages. Note also that the `pub_key` (the public key) in the -`priv_validator.json` is also present in the `genesis.json`. +`priv_validator_key.json` is also present in the `genesis.json`. The genesis file contains the list of public keys which may participate in the consensus, and their corresponding voting power. Greater than 2/3 of the voting power must be active (i.e. the corresponding private keys must be producing signatures) for the consensus to make progress. In our case, the genesis file contains the public key of our -`priv_validator.json`, so a Tendermint node started with the default +`priv_validator_key.json`, so a Tendermint node started with the default root directory will be able to make progress. Voting power uses an int64 but must be positive, thus the range is: 0 through 9223372036854775807. Because of how the current proposer selection algorithm works, we do not @@ -453,16 +453,16 @@ not connected to the other peer. The easiest way to add new validators is to do it in the `genesis.json`, before starting the network. For instance, we could make a new -`priv_validator.json`, and copy it's `pub_key` into the above genesis. +`priv_validator_key.json`, and copy it's `pub_key` into the above genesis. -We can generate a new `priv_validator.json` with the command: +We can generate a new `priv_validator_key.json` with the command: ``` tendermint gen_validator ``` Now we can update our genesis file. For instance, if the new -`priv_validator.json` looks like: +`priv_validator_key.json` looks like: ``` { @@ -510,7 +510,7 @@ then the new `genesis.json` will be: ``` Update the `genesis.json` in `~/.tendermint/config`. Copy the genesis -file and the new `priv_validator.json` to the `~/.tendermint/config` on +file and the new `priv_validator_key.json` to the `~/.tendermint/config` on a new machine. Now run `tendermint node` on both machines, and use either From 823d916a11ae413e2b1bca0e838ab5c5ff4beeaa Mon Sep 17 00:00:00 2001 From: Marko Date: Fri, 12 Jul 2019 11:06:27 +0200 Subject: [PATCH 22/34] Apply suggestions from code review Comment from PR Co-Authored-By: Ethan Buchman --- CHANGELOG.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d7203d7d..788bb8049 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,8 @@ Special thanks to external contributors on this release: @ParthDesai, @climber73, @jim380, @ashleyvega This release contains breaking changes to our libs folder and ABCI namely: -- Add a "Recheck Tx" indicator -- Removal of `db/debugDB`, `common/colors.go`, `errors/errors.go`, `common/heap.go`, `date.go`, `io.go` and +- CheckTx requests include a `CheckTxType` enum that can be set to `Recheck` to indicate to the application that this transaction was already checked/validated and certain expensive operations (like checking signatures) can be skipped +- Removed various functions from `libs` pkgs `GoPath()`, `Prompt()` and `IsDirEmpty()` functions from `os.go` Friendly reminder, we have a [bug bounty @@ -38,8 +38,7 @@ program](https://hackerone.com/tendermint). ### FEATURES: -- [node] Refactor `NewNode` to use functional options to make it more flexible - and extensible in the future. +- [node] Add variadic argument to `NewNode` to support functional options, allowing the Node to be more easily customized. - [node][\#3730](https://github.com/tendermint/tendermint/pull/3730) Add `CustomReactors` option to `NewNode` allowing caller to pass custom reactors to run inside Tendermint node (@ParthDesai) From 0787b793473102c4d96ec0d16d0f78666ec8a308 Mon Sep 17 00:00:00 2001 From: Marko Baricevic Date: Fri, 12 Jul 2019 11:17:20 +0200 Subject: [PATCH 23/34] add link bump abci Version --- CHANGELOG.md | 10 +--------- version/version.go | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 788bb8049..1ea8024f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,10 +17,6 @@ program](https://hackerone.com/tendermint). ### BREAKING CHANGES: -- CLI/RPC/Config - -- Apps - - Go API - [abci] [\#2127](https://github.com/tendermint/tendermint/issues/2127) ABCI / mempool: Add a "Recheck Tx" indicator. Breaks the ABCI @@ -32,10 +28,6 @@ program](https://hackerone.com/tendermint). - [libs] [\#2432](https://github.com/tendermint/tendermint/issues/2432) Remove unused `common/heap.go` file (@marbar3778) - [libs] Remove unused `date.go`, `io.go`. Remove `GoPath()`, `Prompt()` and `IsDirEmpty()` functions from `os.go` (@marbar3778) -- Blockchain Protocol - -- P2P Protocol - ### FEATURES: - [node] Add variadic argument to `NewNode` to support functional options, allowing the Node to be more easily customized. @@ -50,7 +42,7 @@ program](https://hackerone.com/tendermint). - [p2p] [\#3338](https://github.com/tendermint/tendermint/issues/3338) Prevent "sent next PEX request too soon" errors by not calling ensurePeers outside of ensurePeersRoutine -- [behaviour] Return correct reason in MessageOutOfOrder (@jim380) +- [behaviour] [\3772](https://github.com/tendermint/tendermint/pull/3772) Return correct reason in MessageOutOfOrder (@jim380) - [config] [\#3723](https://github.com/tendermint/tendermint/issues/3723) Add consensus_params to testnet config generation; document time_iota_ms (@ashleyvega) diff --git a/version/version.go b/version/version.go index c5d221551..91b0ab410 100644 --- a/version/version.go +++ b/version/version.go @@ -23,7 +23,7 @@ const ( TMCoreSemVer = "0.32.1" // ABCISemVer is the semantic version of the ABCI library - ABCISemVer = "0.16.0" + ABCISemVer = "0.16.1" ABCIVersion = ABCISemVer ) From eddb433d7c082efbeaf8974413a36641519ee895 Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Fri, 12 Jul 2019 09:43:03 -0400 Subject: [PATCH 24/34] abci: Fix documentation regarding CheckTx type update (#3789) * Update ABCI docs to reflect latest changes on PR #3744 * Add note about new Type parameter for CheckTx --- docs/spec/abci/abci.md | 6 ++---- docs/spec/abci/apps.md | 5 ++++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/spec/abci/abci.md b/docs/spec/abci/abci.md index 31ac85abd..275c4dcd8 100644 --- a/docs/spec/abci/abci.md +++ b/docs/spec/abci/abci.md @@ -297,11 +297,9 @@ Commit are included in the header of the next block. - **Request**: - `Tx ([]byte)`: The request transaction bytes - `Type (CheckTxType)`: What type of `CheckTx` request is this? At present, - there are two possible values: `CheckTx_Unchecked` (the default, which says - that a full check is required), and `CheckTx_Checked` (when the mempool is + there are two possible values: `CheckTx_New` (the default, which says + that a full check is required), and `CheckTx_Recheck` (when the mempool is initiating a normal recheck of a transaction). - - `AdditionalData ([]byte)`: Reserved for future use. See - [here](https://github.com/tendermint/tendermint/issues/2127#issuecomment-456661420). - **Response**: - `Code (uint32)`: Response code - `Data ([]byte)`: Result bytes, if any. diff --git a/docs/spec/abci/apps.md b/docs/spec/abci/apps.md index 908ad3eaf..5d4a678d4 100644 --- a/docs/spec/abci/apps.md +++ b/docs/spec/abci/apps.md @@ -65,7 +65,10 @@ begin. After `Commit`, CheckTx is run again on all transactions that remain in the node's local mempool after filtering those included in the block. To prevent the mempool from rechecking all transactions every time a block is committed, set -the configuration option `mempool.recheck=false`. +the configuration option `mempool.recheck=false`. As of Tendermint v0.32.1, +an additional `Type` parameter is made available to the CheckTx function that +indicates whether an incoming transaction is new (`CheckTxType_New`), or a +recheck (`CheckTxType_Recheck`). Finally, the mempool will unlock and new transactions can be processed through CheckTx again. From 1b69c6b56b7dc7941534f2e1f1b12156011f9077 Mon Sep 17 00:00:00 2001 From: Marko Baricevic Date: Fri, 12 Jul 2019 15:59:53 +0200 Subject: [PATCH 25/34] include doc change for abci/app --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ea8024f3..24eec219d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,7 @@ program](https://hackerone.com/tendermint). client interface (`abcicli.Client`) to allow for supplying the ABCI `types.RequestCheckTx` and `types.RequestDeliverTx` structs, and lets the mempool indicate to the ABCI app whether a CheckTx request is a recheck or - not. + not. see [docs](https://github.com/tendermint/tendermint/blob/eddb433d7c082efbeaf8974413a36641519ee895/docs/spec/abci/apps.md#mempool-connection) - [libs] Remove unused `db/debugDB` and `common/colors.go` & `errors/errors.go` files (@marbar3778) - [libs] [\#2432](https://github.com/tendermint/tendermint/issues/2432) Remove unused `common/heap.go` file (@marbar3778) - [libs] Remove unused `date.go`, `io.go`. Remove `GoPath()`, `Prompt()` and `IsDirEmpty()` functions from `os.go` (@marbar3778) From e7ac73177e036a09af2547321d1c9e98130e5349 Mon Sep 17 00:00:00 2001 From: Aditya Date: Fri, 12 Jul 2019 17:29:36 +0000 Subject: [PATCH 26/34] upgrade go.mod (#3793) upgrade levelDB to latest master --- go.mod | 3 +-- go.sum | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index f4a4c6dda..948cf9887 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,6 @@ require ( github.com/gogo/protobuf v1.2.1 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect github.com/golang/protobuf v1.3.0 - github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect github.com/google/gofuzz v1.0.0 // indirect github.com/gorilla/websocket v1.2.0 github.com/hashicorp/hcl v1.0.0 // indirect @@ -41,7 +40,7 @@ require ( github.com/spf13/pflag v1.0.3 // indirect github.com/spf13/viper v1.0.0 github.com/stretchr/testify v1.2.2 - github.com/syndtr/goleveldb v0.0.0-20181012014443-6b91fda63f2e + github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965 github.com/tendermint/go-amino v0.14.1 go.etcd.io/bbolt v1.3.3 // indirect golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 diff --git a/go.sum b/go.sum index 2a349d300..14091bbc0 100644 --- a/go.sum +++ b/go.sum @@ -39,6 +39,8 @@ github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ= @@ -103,6 +105,9 @@ github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/syndtr/goleveldb v0.0.0-20181012014443-6b91fda63f2e h1:91EeXI4y4ShkyzkMqZ7QP/ZTIqwXp3RuDu5WFzxcFAs= github.com/syndtr/goleveldb v0.0.0-20181012014443-6b91fda63f2e/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= +github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= +github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965 h1:1oFLiOyVl+W7bnBzGhf7BbIv9loSFQcieWWYIjLqcAw= +github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= github.com/tendermint/go-amino v0.14.1 h1:o2WudxNfdLNBwMyl2dqOJxiro5rfrEaU0Ugs6offJMk= github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= From 6d96cf4f055492e34e803c30d834bdfc714ce17d Mon Sep 17 00:00:00 2001 From: Karoly Albert Szabo Date: Sat, 13 Jul 2019 07:57:43 +0200 Subject: [PATCH 27/34] tm-monitor: update build-docker Makefile target (#3790) - build docker needs go111module on - switch to golang:1.12 to have git available Signed-off-by: Karoly Albert Szabo --- tools/tm-monitor/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/tm-monitor/Makefile b/tools/tm-monitor/Makefile index 901b0a14d..a71eb2642 100644 --- a/tools/tm-monitor/Makefile +++ b/tools/tm-monitor/Makefile @@ -36,7 +36,7 @@ dist: build-all build-docker: rm -f ./tm-monitor - docker run -it --rm -v "$(PWD)/../../:/go/src/github.com/tendermint/tendermint" -w "/go/src/github.com/tendermint/tendermint/tools/tm-monitor" -e "CGO_ENABLED=0" golang:alpine go build -ldflags "-s -w" -o tm-monitor + docker run -it --rm -v "$(PWD)/../../:/go/src/github.com/tendermint/tendermint" -w "/go/src/github.com/tendermint/tendermint/tools/tm-monitor" -e "GO111MODULE=on" -e "CGO_ENABLED=0" golang:1.12 go build -ldflags "-s -w" -o tm-monitor docker build -t "tendermint/monitor" . clean: From 78e634dd5c5a193ff56a8ed724e23fd2e0c973d8 Mon Sep 17 00:00:00 2001 From: Karoly Albert Szabo Date: Sat, 13 Jul 2019 08:09:28 +0200 Subject: [PATCH 28/34] tm-monitor: add Context to RPC handlers (#3792) * Fix rpc handle for tm-monitor Signed-off-by: Karoly Albert Szabo * go imports file Signed-off-by: Karoly Albert Szabo * go imports file Signed-off-by: Karoly Albert Szabo * fix RPCUnmonitor too Signed-off-by: Karoly Albert Szabo --- tools/tm-monitor/rpc.go | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/tools/tm-monitor/rpc.go b/tools/tm-monitor/rpc.go index 4412e6e0b..42cc23075 100644 --- a/tools/tm-monitor/rpc.go +++ b/tools/tm-monitor/rpc.go @@ -5,9 +5,11 @@ import ( "net" "net/http" + rpctypes "github.com/tendermint/tendermint/rpc/lib/types" + "github.com/tendermint/tendermint/libs/log" rpc "github.com/tendermint/tendermint/rpc/lib/server" - monitor "github.com/tendermint/tendermint/tools/tm-monitor/monitor" + "github.com/tendermint/tendermint/tools/tm-monitor/monitor" ) func startRPC(listenAddr string, m *monitor.Monitor, logger log.Logger) net.Listener { @@ -41,33 +43,33 @@ func routes(m *monitor.Monitor) map[string]*rpc.RPCFunc { } // RPCStatus returns common statistics for the network and statistics per node. -func RPCStatus(m *monitor.Monitor) interface{} { - return func() (networkAndNodes, error) { +func RPCStatus(m *monitor.Monitor) func(*rpctypes.Context) (networkAndNodes, error) { + return func(_ *rpctypes.Context) (networkAndNodes, error) { return networkAndNodes{m.Network, m.Nodes}, nil } } // RPCNetworkStatus returns common statistics for the network. -func RPCNetworkStatus(m *monitor.Monitor) interface{} { - return func() (*monitor.Network, error) { +func RPCNetworkStatus(m *monitor.Monitor) func(*rpctypes.Context) (*monitor.Network, error) { + return func(_ *rpctypes.Context) (*monitor.Network, error) { return m.Network, nil } } // RPCNodeStatus returns statistics for the given node. -func RPCNodeStatus(m *monitor.Monitor) interface{} { - return func(name string) (*monitor.Node, error) { +func RPCNodeStatus(m *monitor.Monitor) func(*rpctypes.Context, string) (*monitor.Node, error) { + return func(_ *rpctypes.Context, name string) (*monitor.Node, error) { if i, n := m.NodeByName(name); i != -1 { return n, nil } - return nil, errors.New("Cannot find node with that name") + return nil, errors.New("cannot find node with that name") } } // RPCMonitor allows to dynamically add a endpoint to under the monitor. Safe // to call multiple times. -func RPCMonitor(m *monitor.Monitor) interface{} { - return func(endpoint string) (*monitor.Node, error) { +func RPCMonitor(m *monitor.Monitor) func(*rpctypes.Context, string) (*monitor.Node, error) { + return func(_ *rpctypes.Context, endpoint string) (*monitor.Node, error) { i, n := m.NodeByName(endpoint) if i == -1 { n = monitor.NewNode(endpoint) @@ -80,13 +82,13 @@ func RPCMonitor(m *monitor.Monitor) interface{} { } // RPCUnmonitor removes the given endpoint from under the monitor. -func RPCUnmonitor(m *monitor.Monitor) interface{} { - return func(endpoint string) (bool, error) { +func RPCUnmonitor(m *monitor.Monitor) func(*rpctypes.Context, string) (bool, error) { + return func(_ *rpctypes.Context, endpoint string) (bool, error) { if i, n := m.NodeByName(endpoint); i != -1 { m.Unmonitor(n) return true, nil } - return false, errors.New("Cannot find node with that name") + return false, errors.New("cannot find node with that name") } } From 7a86e49312b8975fd0ce187c5232ebae2eefec6c Mon Sep 17 00:00:00 2001 From: Marko Baricevic Date: Sat, 13 Jul 2019 13:39:11 +0200 Subject: [PATCH 29/34] moved abci change to features as it doesnt break the abci --- CHANGELOG.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24eec219d..930e6e4a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,11 +19,6 @@ program](https://hackerone.com/tendermint). - Go API - - [abci] [\#2127](https://github.com/tendermint/tendermint/issues/2127) ABCI / mempool: Add a "Recheck Tx" indicator. Breaks the ABCI - client interface (`abcicli.Client`) to allow for supplying the ABCI - `types.RequestCheckTx` and `types.RequestDeliverTx` structs, and lets the - mempool indicate to the ABCI app whether a CheckTx request is a recheck or - not. see [docs](https://github.com/tendermint/tendermint/blob/eddb433d7c082efbeaf8974413a36641519ee895/docs/spec/abci/apps.md#mempool-connection) - [libs] Remove unused `db/debugDB` and `common/colors.go` & `errors/errors.go` files (@marbar3778) - [libs] [\#2432](https://github.com/tendermint/tendermint/issues/2432) Remove unused `common/heap.go` file (@marbar3778) - [libs] Remove unused `date.go`, `io.go`. Remove `GoPath()`, `Prompt()` and `IsDirEmpty()` functions from `os.go` (@marbar3778) @@ -33,6 +28,11 @@ program](https://hackerone.com/tendermint). - [node] Add variadic argument to `NewNode` to support functional options, allowing the Node to be more easily customized. - [node][\#3730](https://github.com/tendermint/tendermint/pull/3730) Add `CustomReactors` option to `NewNode` allowing caller to pass custom reactors to run inside Tendermint node (@ParthDesai) +- [abci] [\#2127](https://github.com/tendermint/tendermint/issues/2127) ABCI / mempool: Add a "Recheck Tx" indicator. Breaks the ABCI + client interface (`abcicli.Client`) to allow for supplying the ABCI + `types.RequestCheckTx` and `types.RequestDeliverTx` structs, and lets the + mempool indicate to the ABCI app whether a CheckTx request is a recheck or + not. see [docs](https://github.com/tendermint/tendermint/blob/eddb433d7c082efbeaf8974413a36641519ee895/docs/spec/abci/apps.md#mempool-connection) ### IMPROVEMENTS: From 5d1459b5847d65069b776be3b4ba5e81bc933dcc Mon Sep 17 00:00:00 2001 From: Marko Date: Sun, 14 Jul 2019 15:50:33 +0200 Subject: [PATCH 30/34] libs/fail: clean up `fail.go` (#3785) * Clean up `fail.go` - Clean up fail.go - Remove unneeded Func `FailRand()` closes #2729 Signed-off-by: Marko Baricevic * add in commented lines --- CHANGELOG_PENDING.md | 1 + libs/fail/fail.go | 47 +++++++------------------------------------- 2 files changed, 8 insertions(+), 40 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index d387f9ecb..5131a38ab 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -23,6 +23,7 @@ program](https://hackerone.com/tendermint). - [libs] Remove unused `db/debugDB` and `common/colors.go` & `errors/errors.go` files (@marbar3778) - [libs] \#2432 Remove unused `common/heap.go` file (@marbar3778) - [libs] Remove unused `date.go`, `io.go`. Remove `GoPath()`, `Prompt()` and `IsDirEmpty()` functions from `os.go` (@marbar3778) + - [libs] Remove unused `FailRand()` func and minor clean up to `fail.go`(@marbar3778) - Blockchain Protocol diff --git a/libs/fail/fail.go b/libs/fail/fail.go index d7912af5c..0c9220622 100644 --- a/libs/fail/fail.go +++ b/libs/fail/fail.go @@ -2,36 +2,30 @@ package fail import ( "fmt" - "math/rand" "os" "strconv" ) -var callIndexToFail int - -func init() { +func envSet() int { callIndexToFailS := os.Getenv("FAIL_TEST_INDEX") if callIndexToFailS == "" { - callIndexToFail = -1 + return -1 } else { var err error - callIndexToFail, err = strconv.Atoi(callIndexToFailS) + callIndexToFail, err := strconv.Atoi(callIndexToFailS) if err != nil { - callIndexToFail = -1 + return -1 } + return callIndexToFail } } // Fail when FAIL_TEST_INDEX == callIndex -var ( - callIndex int //indexes Fail calls - - callRandIndex int // indexes a run of FailRand calls - callRandIndexToFail = -1 // the callRandIndex to fail on in FailRand -) +var callIndex int //indexes Fail calls func Fail() { + callIndexToFail := envSet() if callIndexToFail < 0 { return } @@ -43,33 +37,6 @@ func Fail() { callIndex += 1 } -// FailRand should be called n successive times. -// It will fail on a random one of those calls -// n must be greater than 0 -func FailRand(n int) { - if callIndexToFail < 0 { - return - } - - if callRandIndexToFail < 0 { - // first call in the loop, pick a random index to fail at - callRandIndexToFail = rand.Intn(n) - callRandIndex = 0 - } - - if callIndex == callIndexToFail { - if callRandIndex == callRandIndexToFail { - Exit() - } - } - - callRandIndex += 1 - - if callRandIndex == n { - callIndex += 1 - } -} - func Exit() { fmt.Printf("*** fail-test %d ***\n", callIndex) os.Exit(1) From e0b9298134aba2297f9d17367ab9364b28c3fe18 Mon Sep 17 00:00:00 2001 From: Marko Date: Sun, 14 Jul 2019 16:02:48 +0200 Subject: [PATCH 31/34] libs: minor cleanup (#3794) * more minor cleanup of libs Remove unused `version.go`, `assert.go` and `libs/circle.yml` * Update types/vote_set_test.go Co-Authored-By: Anton Kaliaev * spelling change --- CHANGELOG_PENDING.md | 1 + libs/circle.yml | 21 --------------------- libs/test/assert.go | 14 -------------- libs/version/version.go | 3 --- types/vote_set_test.go | 5 +++-- types/vote_test.go | 1 + 6 files changed, 5 insertions(+), 40 deletions(-) delete mode 100644 libs/circle.yml delete mode 100644 libs/test/assert.go delete mode 100644 libs/version/version.go diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 5131a38ab..0120b03ce 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -23,6 +23,7 @@ program](https://hackerone.com/tendermint). - [libs] Remove unused `db/debugDB` and `common/colors.go` & `errors/errors.go` files (@marbar3778) - [libs] \#2432 Remove unused `common/heap.go` file (@marbar3778) - [libs] Remove unused `date.go`, `io.go`. Remove `GoPath()`, `Prompt()` and `IsDirEmpty()` functions from `os.go` (@marbar3778) + - [libs] Remove unused `version.go`, `assert.go` and `libs/circle.yml` - [libs] Remove unused `FailRand()` func and minor clean up to `fail.go`(@marbar3778) - Blockchain Protocol diff --git a/libs/circle.yml b/libs/circle.yml deleted file mode 100644 index 2b7d1266c..000000000 --- a/libs/circle.yml +++ /dev/null @@ -1,21 +0,0 @@ -machine: - environment: - GOPATH: "${HOME}/.go_workspace" - PROJECT_PARENT_PATH: "$GOPATH/src/github.com/$CIRCLE_PROJECT_USERNAME" - PROJECT_PATH: $GOPATH/src/github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME - hosts: - localhost: 127.0.0.1 - -dependencies: - override: - - mkdir -p "$PROJECT_PARENT_PATH" - - ln -sf "$HOME/$CIRCLE_PROJECT_REPONAME/" "$PROJECT_PATH" - post: - - go version - -test: - override: - - cd $PROJECT_PATH && make get_tools && bash ./test.sh - post: - - cd "$PROJECT_PATH" && bash <(curl -s https://codecov.io/bash) -f coverage.txt - - cd "$PROJECT_PATH" && mv coverage.txt "${CIRCLE_ARTIFACTS}" diff --git a/libs/test/assert.go b/libs/test/assert.go deleted file mode 100644 index a6ffed0ce..000000000 --- a/libs/test/assert.go +++ /dev/null @@ -1,14 +0,0 @@ -package test - -import ( - "testing" -) - -func AssertPanics(t *testing.T, msg string, f func()) { - defer func() { - if err := recover(); err == nil { - t.Errorf("Should have panic'd, but didn't: %v", msg) - } - }() - f() -} diff --git a/libs/version/version.go b/libs/version/version.go deleted file mode 100644 index 6e73a937d..000000000 --- a/libs/version/version.go +++ /dev/null @@ -1,3 +0,0 @@ -package version - -const Version = "0.9.0" diff --git a/types/vote_set_test.go b/types/vote_set_test.go index 59205efc6..2e217e940 100644 --- a/types/vote_set_test.go +++ b/types/vote_set_test.go @@ -4,9 +4,10 @@ import ( "bytes" "testing" + "github.com/stretchr/testify/assert" + "github.com/tendermint/tendermint/crypto" cmn "github.com/tendermint/tendermint/libs/common" - tst "github.com/tendermint/tendermint/libs/test" tmtime "github.com/tendermint/tendermint/types/time" ) @@ -490,7 +491,7 @@ func TestMakeCommit(t *testing.T) { } // MakeCommit should fail. - tst.AssertPanics(t, "Doesn't have +2/3 majority", func() { voteSet.MakeCommit() }) + assert.Panics(t, func() { voteSet.MakeCommit() }, "Doesn't have +2/3 majority") // 7th voted for some other block. { diff --git a/types/vote_test.go b/types/vote_test.go index af8a9625b..b6eb1f586 100644 --- a/types/vote_test.go +++ b/types/vote_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + amino "github.com/tendermint/go-amino" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" From 86f70893969f8399ccc8a7326544696e6040d856 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Mon, 15 Jul 2019 19:31:35 +0400 Subject: [PATCH 32/34] add a changelog entry (#3802) Refs https://github.com/tendermint/tendermint/pull/3758#issuecomment-510738955 --- CHANGELOG_PENDING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 0120b03ce..89eccbc6e 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -40,6 +40,7 @@ program](https://hackerone.com/tendermint). ### IMPROVEMENTS: - [rpc] \#3700 Make possible to set absolute paths for TLS cert and key (@climber73) +- [abci] [\#3513](https://github.com/tendermint/tendermint/issues/3513) Call the reqRes callback after the resCb so they always happen in the same order ### BUG FIXES: From 245e1c9ef7608fcc3364ea958627da97ea0351a1 Mon Sep 17 00:00:00 2001 From: Marko Date: Mon, 15 Jul 2019 17:31:50 +0200 Subject: [PATCH 33/34] pr comments (#3803) * pr comments * abci changelog change --- CHANGELOG.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9d11f58f..74ca9cd31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,15 +2,14 @@ ## v0.32.1 -*July 12, 2019* +*July 15, 2019* Special thanks to external contributors on this release: @ParthDesai, @climber73, @jim380, @ashleyvega -This release contains breaking changes to our libs folder and ABCI namely: +This release contains a minor enhancement to the ABCI and some breaking changes to our libs folder, namely: - CheckTx requests include a `CheckTxType` enum that can be set to `Recheck` to indicate to the application that this transaction was already checked/validated and certain expensive operations (like checking signatures) can be skipped - Removed various functions from `libs` pkgs - `GoPath()`, `Prompt()` and `IsDirEmpty()` functions from `os.go` Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermint). @@ -19,6 +18,7 @@ program](https://hackerone.com/tendermint). - Go API + - [abci] [\#2127](https://github.com/tendermint/tendermint/issues/2127) The CheckTx and DeliverTx methods in the ABCI `Application` interface now take structs as arguments (RequestCheckTx and RequestDeliverTx, respectively), instead of just the raw tx bytes. This allows more information to be passed to these methods, for instance, indicating whether a tx has already been checked. - [libs] Remove unused `db/debugDB` and `common/colors.go` & `errors/errors.go` files (@marbar3778) - [libs] [\#2432](https://github.com/tendermint/tendermint/issues/2432) Remove unused `common/heap.go` file (@marbar3778) - [libs] Remove unused `date.go`, `io.go`. Remove `GoPath()`, `Prompt()` and `IsDirEmpty()` functions from `os.go` (@marbar3778) @@ -29,11 +29,7 @@ program](https://hackerone.com/tendermint). - [node] Add variadic argument to `NewNode` to support functional options, allowing the Node to be more easily customized. - [node][\#3730](https://github.com/tendermint/tendermint/pull/3730) Add `CustomReactors` option to `NewNode` allowing caller to pass custom reactors to run inside Tendermint node (@ParthDesai) -- [abci] [\#2127](https://github.com/tendermint/tendermint/issues/2127) ABCI / mempool: Add a "Recheck Tx" indicator. Breaks the ABCI - client interface (`abcicli.Client`) to allow for supplying the ABCI - `types.RequestCheckTx` and `types.RequestDeliverTx` structs, and lets the - mempool indicate to the ABCI app whether a CheckTx request is a recheck or - not. see [docs](https://github.com/tendermint/tendermint/blob/eddb433d7c082efbeaf8974413a36641519ee895/docs/spec/abci/apps.md#mempool-connection) +- [abci] [\#2127](https://github.com/tendermint/tendermint/issues/2127)RequestCheckTx has a new field, `CheckTxType`, which can take values of `CheckTxType_New` and `CheckTxType_Recheck`, indicating whether this is a new tx being checked for the first time or whether this tx is being rechecked after a block commit. This allows applications to skip certain expensive operations, like signature checking, if they've already been done once. see [docs](https://github.com/tendermint/tendermint/blob/eddb433d7c082efbeaf8974413a36641519ee895/docs/spec/abci/apps.md#mempool-connection) ### IMPROVEMENTS: From 0c9a284f8df898a80e4c26052f961b3158e72507 Mon Sep 17 00:00:00 2001 From: Marko Date: Mon, 15 Jul 2019 17:42:08 +0200 Subject: [PATCH 34/34] Marko/update release1 (#3806) * pr comments * remove empty space --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74ca9cd31..cf2879c75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ program](https://hackerone.com/tendermint). ### IMPROVEMENTS: - [rpc] [\#3700](https://github.com/tendermint/tendermint/issues/3700) Make possible to set absolute paths for TLS cert and key (@climber73) +- [abci] [\#3513](https://github.com/tendermint/tendermint/issues/3513) Call the reqRes callback after the resCb so they always happen in the same order ### BUG FIXES: