diff --git a/Gopkg.lock b/Gopkg.lock index 1037c1d4..5efb7254 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -3,63 +3,49 @@ [[projects]] branch = "master" - digest = "1:d6afaeed1502aa28e80a4ed0981d570ad91b2579193404256ce672ed0a609e0d" name = "github.com/beorn7/perks" packages = ["quantile"] - pruneopts = "UT" revision = "3a771d992973f24aa725d07868b467d1ddfceafb" [[projects]] branch = "master" - digest = "1:6aabc1566d6351115d561d038da82a4c19b46c3b6e17f4a0a2fa60260663dc79" name = "github.com/btcsuite/btcd" packages = ["btcec"] pruneopts = "UT" revision = "f673a4b563b57b9a95832545c878669a7fa801d9" [[projects]] - digest = "1:df684ed7fed3fb406ec421424aaf5fc9c63ccc2f428b25b842da78e634482e4b" name = "github.com/btcsuite/btcutil" packages = [ "base58", - "bech32", + "bech32" ] - pruneopts = "UT" revision = "d4cc87b860166d00d6b5b9e0d3b3d71d6088d4d4" [[projects]] - digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39" name = "github.com/davecgh/go-spew" packages = ["spew"] - pruneopts = "UT" revision = "346938d642f2ec3594ed81d874461961cd0faa76" version = "v1.1.0" [[projects]] - digest = "1:c7644c73a3d23741fdba8a99b1464e021a224b7e205be497271a8003a15ca41b" name = "github.com/ebuchman/fail-test" packages = ["."] - pruneopts = "UT" revision = "95f809107225be108efcf10a3509e4ea6ceef3c4" [[projects]] - digest = "1:544229a3ca0fb2dd5ebc2896d3d2ff7ce096d9751635301e44e37e761349ee70" name = "github.com/fortytw2/leaktest" packages = ["."] - pruneopts = "UT" revision = "a5ef70473c97b71626b9abeda80ee92ba2a7de9e" version = "v1.2.0" [[projects]] - digest = "1:abeb38ade3f32a92943e5be54f55ed6d6e3b6602761d74b4aab4c9dd45c18abd" name = "github.com/fsnotify/fsnotify" packages = ["."] - pruneopts = "UT" revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9" version = "v1.4.7" [[projects]] - digest = "1:fa30c0652956e159cdb97dcb2ef8b8db63ed668c02a5c3a40961c8f0641252fe" name = "github.com/go-kit/kit" packages = [ "log", @@ -68,30 +54,24 @@ "metrics", "metrics/discard", "metrics/internal/lv", - "metrics/prometheus", + "metrics/prometheus" ] - pruneopts = "UT" revision = "4dc7be5d2d12881735283bcab7352178e190fc71" version = "v0.6.0" [[projects]] - digest = "1:31a18dae27a29aa074515e43a443abfd2ba6deb6d69309d8d7ce789c45f34659" name = "github.com/go-logfmt/logfmt" packages = ["."] - pruneopts = "UT" revision = "390ab7935ee28ec6b286364bba9b4dd6410cb3d5" version = "v0.3.0" [[projects]] - digest = "1:c4a2528ccbcabf90f9f3c464a5fc9e302d592861bbfd0b7135a7de8a943d0406" name = "github.com/go-stack/stack" packages = ["."] - pruneopts = "UT" revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc" version = "v1.7.0" [[projects]] - digest = "1:212285efb97b9ec2e20550d81f0446cb7897e57cbdfd7301b1363ab113d8be45" name = "github.com/gogo/protobuf" packages = [ "gogoproto", @@ -99,45 +79,37 @@ "proto", "protoc-gen-gogo/descriptor", "sortkeys", - "types", + "types" ] - pruneopts = "UT" revision = "7d68e886eac4f7e34d0d82241a6273d6c304c5cf" version = "v1.1.0" [[projects]] - digest = "1:cb22af0ed7c72d495d8be1106233ee553898950f15fd3f5404406d44c2e86888" name = "github.com/golang/protobuf" packages = [ "proto", "ptypes", "ptypes/any", "ptypes/duration", - "ptypes/timestamp", + "ptypes/timestamp" ] - pruneopts = "UT" revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265" version = "v1.1.0" [[projects]] branch = "master" - digest = "1:4a0c6bb4805508a6287675fac876be2ac1182539ca8a32468d8128882e9d5009" name = "github.com/golang/snappy" packages = ["."] - pruneopts = "UT" revision = "2e65f85255dbc3072edf28d6b5b8efc472979f5a" [[projects]] - digest = "1:43dd08a10854b2056e615d1b1d22ac94559d822e1f8b6fcc92c1a1057e85188e" name = "github.com/gorilla/websocket" packages = ["."] - pruneopts = "UT" revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b" version = "v1.2.0" [[projects]] branch = "master" - digest = "1:8951fe6e358876736d8fa1f3992624fdbb2dec6bc49401c1381d1ef8abbb544f" name = "github.com/hashicorp/hcl" packages = [ ".", @@ -148,48 +120,37 @@ "hcl/token", "json/parser", "json/scanner", - "json/token", + "json/token" ] - pruneopts = "UT" revision = "ef8a98b0bbce4a65b5aa4c368430a80ddc533168" [[projects]] - digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be" name = "github.com/inconshreveable/mousetrap" packages = ["."] - pruneopts = "UT" revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" version = "v1.0" [[projects]] branch = "master" - digest = "1:39b27d1381a30421f9813967a5866fba35dc1d4df43a6eefe3b7a5444cb07214" name = "github.com/jmhodges/levigo" packages = ["."] - pruneopts = "UT" revision = "c42d9e0ca023e2198120196f842701bb4c55d7b9" [[projects]] branch = "master" - digest = "1:a64e323dc06b73892e5bb5d040ced475c4645d456038333883f58934abbf6f72" name = "github.com/kr/logfmt" packages = ["."] - pruneopts = "UT" revision = "b84e30acd515aadc4b783ad4ff83aff3299bdfe0" [[projects]] - digest = "1:c568d7727aa262c32bdf8a3f7db83614f7af0ed661474b24588de635c20024c7" name = "github.com/magiconair/properties" packages = ["."] - pruneopts = "UT" revision = "c2353362d570a7bfa228149c62842019201cfb71" version = "v1.8.0" [[projects]] - digest = "1:ff5ebae34cfbf047d505ee150de27e60570e8c394b3b8fdbb720ff6ac71985fc" name = "github.com/matttproud/golang_protobuf_extensions" packages = ["pbutil"] - pruneopts = "UT" revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c" version = "v1.0.1" @@ -202,37 +163,29 @@ revision = "f15292f7a699fcc1a38a80977f80a046874ba8ac" [[projects]] - digest = "1:95741de3af260a92cc5c7f3f3061e85273f5a81b5db20d4bd68da74bd521675e" name = "github.com/pelletier/go-toml" packages = ["."] - pruneopts = "UT" revision = "c01d1270ff3e442a8a57cddc1c92dc1138598194" version = "v1.2.0" [[projects]] - digest = "1:40e195917a951a8bf867cd05de2a46aaf1806c50cf92eebf4c16f78cd196f747" name = "github.com/pkg/errors" packages = ["."] - pruneopts = "UT" revision = "645ef00459ed84a119197bfb8d8205042c6df63d" version = "v0.8.0" [[projects]] - digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" name = "github.com/pmezard/go-difflib" packages = ["difflib"] - pruneopts = "UT" revision = "792786c7400a136282c1664665ae0a8db921c6c2" version = "v1.0.0" [[projects]] - digest = "1:98225904b7abff96c052b669b25788f18225a36673fba022fb93514bb9a2a64e" name = "github.com/prometheus/client_golang" packages = [ "prometheus", - "prometheus/promhttp", + "prometheus/promhttp" ] - pruneopts = "UT" revision = "ae27198cdd90bf12cd134ad79d1366a6cf49f632" [[projects]] @@ -245,101 +198,80 @@ [[projects]] branch = "master" - digest = "1:4d291d51042ed9de40eef61a3c1b56e969d6e0f8aa5fd3da5e958ec66bee68e4" name = "github.com/prometheus/common" packages = [ "expfmt", "internal/bitbucket.org/ww/goautoneg", - "model", + "model" ] - pruneopts = "UT" revision = "7600349dcfe1abd18d72d3a1770870d9800a7801" [[projects]] branch = "master" - digest = "1:55d7449d6987dabf272b4e81b2f9c449f05b17415c939b68d1e82f57e3374b7f" name = "github.com/prometheus/procfs" packages = [ ".", "internal/util", "nfs", - "xfs", + "xfs" ] - pruneopts = "UT" revision = "ae68e2d4c00fed4943b5f6698d504a5fe083da8a" [[projects]] - digest = "1:c4556a44e350b50a490544d9b06e9fba9c286c21d6c0e47f54f3a9214597298c" name = "github.com/rcrowley/go-metrics" packages = ["."] - pruneopts = "UT" revision = "e2704e165165ec55d062f5919b4b29494e9fa790" [[projects]] - digest = "1:37ace7f35375adec11634126944bdc45a673415e2fcc07382d03b75ec76ea94c" name = "github.com/spf13/afero" packages = [ ".", - "mem", + "mem" ] - pruneopts = "UT" revision = "787d034dfe70e44075ccc060d346146ef53270ad" version = "v1.1.1" [[projects]] - digest = "1:516e71bed754268937f57d4ecb190e01958452336fa73dbac880894164e91c1f" name = "github.com/spf13/cast" packages = ["."] - pruneopts = "UT" revision = "8965335b8c7107321228e3e3702cab9832751bac" version = "v1.2.0" [[projects]] - digest = "1:627ab2f549a6a55c44f46fa24a4307f4d0da81bfc7934ed0473bf38b24051d26" name = "github.com/spf13/cobra" packages = ["."] - pruneopts = "UT" revision = "7b2c5ac9fc04fc5efafb60700713d4fa609b777b" version = "v0.0.1" [[projects]] branch = "master" - digest = "1:080e5f630945ad754f4b920e60b4d3095ba0237ebf88dc462eb28002932e3805" name = "github.com/spf13/jwalterweatherman" packages = ["."] - pruneopts = "UT" revision = "7c0cea34c8ece3fbeb2b27ab9b59511d360fb394" [[projects]] - digest = "1:9424f440bba8f7508b69414634aef3b2b3a877e522d8a4624692412805407bb7" name = "github.com/spf13/pflag" packages = ["."] - pruneopts = "UT" revision = "583c0c0531f06d5278b7d917446061adc344b5cd" version = "v1.0.1" [[projects]] - digest = "1:f8e1a678a2571e265f4bf91a3e5e32aa6b1474a55cb0ea849750cc177b664d96" name = "github.com/spf13/viper" packages = ["."] - pruneopts = "UT" revision = "25b30aa063fc18e48662b86996252eabdcf2f0c7" version = "v1.0.0" [[projects]] - digest = "1:73697231b93fb74a73ebd8384b68b9a60c57ea6b13c56d2425414566a72c8e6d" name = "github.com/stretchr/testify" packages = [ "assert", - "require", + "require" ] - pruneopts = "UT" revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" version = "v1.2.1" [[projects]] branch = "master" - digest = "1:922191411ad8f61bcd8018ac127589bb489712c1d1a0ab2497aca4b16de417d2" name = "github.com/syndtr/goleveldb" packages = [ "leveldb", @@ -353,34 +285,28 @@ "leveldb/opt", "leveldb/storage", "leveldb/table", - "leveldb/util", + "leveldb/util" ] - pruneopts = "UT" revision = "c4c61651e9e37fa117f53c5a906d3b63090d8445" [[projects]] branch = "master" - digest = "1:203b409c21115233a576f99e8f13d8e07ad82b25500491f7e1cca12588fb3232" name = "github.com/tendermint/ed25519" packages = [ ".", "edwards25519", - "extra25519", + "extra25519" ] - pruneopts = "UT" revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057" [[projects]] - digest = "1:e9113641c839c21d8eaeb2c907c7276af1eddeed988df8322168c56b7e06e0e1" name = "github.com/tendermint/go-amino" packages = ["."] - pruneopts = "UT" revision = "2106ca61d91029c931fd54968c2bb02dc96b1412" version = "0.10.1" [[projects]] branch = "master" - digest = "1:df132ec33d5acb4a1ab58d637f1bc3557be49456ca59b9198f5c1e7fa32e0d31" name = "golang.org/x/crypto" packages = [ "bcrypt", @@ -396,13 +322,11 @@ "openpgp/errors", "poly1305", "ripemd160", - "salsa20/salsa", + "salsa20/salsa" ] - pruneopts = "UT" - revision = "a49355c7e3f8fe157a85be2f77e6e269a0f89602" + revision = "a2144134853fc9a27a7b1e3eb4f19f1a76df13c9" [[projects]] - digest = "1:04dda8391c3e2397daf254ac68003f30141c069b228d06baec8324a5f81dc1e9" name = "golang.org/x/net" packages = [ "context", @@ -412,24 +336,21 @@ "idna", "internal/timeseries", "netutil", - "trace", + "trace" ] - pruneopts = "UT" revision = "292b43bbf7cb8d35ddf40f8d5100ef3837cced3f" [[projects]] branch = "master" - digest = "1:0470500d9a2c5c653f89fc369cdf2fece01996432d42ef87e03ebc3e5b5f8717" name = "golang.org/x/sys" packages = [ "cpu", - "unix", + "unix" ] pruneopts = "UT" revision = "ac767d655b305d4e9612f5f6e33120b9176c4ad4" [[projects]] - digest = "1:7509ba4347d1f8de6ae9be8818b0cd1abc3deeffe28aeaf4be6d4b6b5178d9ca" name = "golang.org/x/text" packages = [ "collate", @@ -445,21 +366,17 @@ "unicode/bidi", "unicode/cldr", "unicode/norm", - "unicode/rangetable", + "unicode/rangetable" ] - pruneopts = "UT" revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" version = "v0.3.0" [[projects]] - digest = "1:cd018653a358d4b743a9d3bee89e825521f2ab2f2ec0770164bf7632d8d73ab7" name = "google.golang.org/genproto" packages = ["googleapis/rpc/status"] - pruneopts = "UT" revision = "7fd901a49ba6a7f87732eb344f6e3c5b19d1b200" [[projects]] - digest = "1:4d7b5d9746840266938cdb21a40f8eba7137d9153c4ed404d6bb2a450d06f690" name = "google.golang.org/grpc" packages = [ ".", @@ -471,9 +388,11 @@ "credentials", "encoding", "encoding/proto", - "grpclb/grpc_lb_v1/messages", "grpclog", "internal", + "internal/backoff", + "internal/channelz", + "internal/grpcrand", "keepalive", "metadata", "naming", @@ -484,68 +403,20 @@ "stats", "status", "tap", - "transport", + "transport" ] - pruneopts = "UT" - revision = "d11072e7ca9811b1100b80ca0269ac831f06d024" - version = "v1.11.3" + revision = "168a6198bcb0ef175f7dacec0b8691fc141dc9b8" + version = "v1.13.0" [[projects]] - digest = "1:342378ac4dcb378a5448dd723f0784ae519383532f5e70ade24132c4c8693202" name = "gopkg.in/yaml.v2" packages = ["."] - pruneopts = "UT" revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" version = "v2.2.1" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - input-imports = [ - "github.com/btcsuite/btcd/btcec", - "github.com/btcsuite/btcutil/base58", - "github.com/btcsuite/btcutil/bech32", - "github.com/ebuchman/fail-test", - "github.com/fortytw2/leaktest", - "github.com/go-kit/kit/log", - "github.com/go-kit/kit/log/level", - "github.com/go-kit/kit/log/term", - "github.com/go-kit/kit/metrics", - "github.com/go-kit/kit/metrics/discard", - "github.com/go-kit/kit/metrics/prometheus", - "github.com/go-logfmt/logfmt", - "github.com/gogo/protobuf/gogoproto", - "github.com/gogo/protobuf/jsonpb", - "github.com/gogo/protobuf/proto", - "github.com/golang/protobuf/proto", - "github.com/gorilla/websocket", - "github.com/jmhodges/levigo", - "github.com/pkg/errors", - "github.com/prometheus/client_golang/prometheus", - "github.com/prometheus/client_golang/prometheus/promhttp", - "github.com/rcrowley/go-metrics", - "github.com/spf13/cobra", - "github.com/spf13/viper", - "github.com/stretchr/testify/assert", - "github.com/stretchr/testify/require", - "github.com/syndtr/goleveldb/leveldb", - "github.com/syndtr/goleveldb/leveldb/errors", - "github.com/syndtr/goleveldb/leveldb/iterator", - "github.com/syndtr/goleveldb/leveldb/opt", - "github.com/tendermint/ed25519", - "github.com/tendermint/ed25519/extra25519", - "github.com/tendermint/go-amino", - "golang.org/x/crypto/bcrypt", - "golang.org/x/crypto/chacha20poly1305", - "golang.org/x/crypto/hkdf", - "golang.org/x/crypto/nacl/box", - "golang.org/x/crypto/nacl/secretbox", - "golang.org/x/crypto/openpgp/armor", - "golang.org/x/crypto/ripemd160", - "golang.org/x/net/context", - "golang.org/x/net/netutil", - "google.golang.org/grpc", - "google.golang.org/grpc/credentials", - ] + inputs-digest = "9beb2d27dc19e3f9e2c7f416f312f7129f5441b1b53def42503fc6f7d3a54b16" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 19fa6894..f53c5bb9 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -31,11 +31,11 @@ [[constraint]] name = "github.com/go-kit/kit" - version = "=0.6.0" + version = "=0.7.0" [[constraint]] name = "github.com/gogo/protobuf" - version = "=1.1.0" + version = "=1.1.1" [[constraint]] name = "github.com/golang/protobuf" @@ -51,23 +51,23 @@ [[constraint]] name = "github.com/spf13/cobra" - version = "=0.0.1" + version = "=0.0.3" [[constraint]] name = "github.com/spf13/viper" - version = "=1.0.0" + version = "=1.0.2" [[constraint]] name = "github.com/stretchr/testify" - version = "=1.2.1" + version = "=1.2.2" [[constraint]] name = "github.com/tendermint/go-amino" - version = "=0.10.1" + version = "=v0.11.1" [[constraint]] name = "google.golang.org/grpc" - version = "=1.11.3" + version = "=1.13.0" [[constraint]] name = "github.com/fortytw2/leaktest" diff --git a/Makefile b/Makefile index 5770f6a1..50e626cd 100644 --- a/Makefile +++ b/Makefile @@ -308,4 +308,4 @@ build-slate: # To avoid unintended conflicts with file names, always add to .PHONY # unless there is a reason not to. # https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html -.PHONY: check build build_race build_abci dist install install_abci check_tools get_tools update_tools get_vendor_deps draw_deps get_protoc protoc_abci protoc_libs gen_certs clean_certs grpc_dbserver test_cover test_apps test_persistence test_p2p test test_race test_integrations test_release test100 vagrant_test fmt build-linux localnet-start localnet-stop build-docker build-docker-localnode sentry-start sentry-config sentry-stop build-slate +.PHONY: check build build_race build_abci dist install install_abci check_tools get_tools update_tools get_vendor_deps draw_deps get_protoc protoc_abci protoc_libs gen_certs clean_certs grpc_dbserver test_cover test_apps test_persistence test_p2p test test_race test_integrations test_release test100 vagrant_test fmt build-linux localnet-start localnet-stop build-docker build-docker-localnode sentry-start sentry-config sentry-stop build-slate protoc_grpc protoc_all diff --git a/blockchain/pool_test.go b/blockchain/pool_test.go index dcb046db..01187bcf 100644 --- a/blockchain/pool_test.go +++ b/blockchain/pool_test.go @@ -79,7 +79,7 @@ func TestBasic(t *testing.T) { } // Request desired, pretend like we got the block immediately. go func() { - block := &types.Block{Header: &types.Header{Height: request.Height}} + block := &types.Block{Header: types.Header{Height: request.Height}} pool.AddBlock(request.PeerID, block, 123) t.Logf("Added block from peer %v (height: %v)", request.PeerID, request.Height) }() diff --git a/blockchain/store_test.go b/blockchain/store_test.go index 888040bd..c8165400 100644 --- a/blockchain/store_test.go +++ b/blockchain/store_test.go @@ -126,7 +126,7 @@ func TestBlockStoreSaveLoadBlock(t *testing.T) { eraseSeenCommitInDB bool }{ { - block: newBlock(&header1, commitAtH10), + block: newBlock(header1, commitAtH10), parts: validPartSet, seenCommit: seenCommit1, }, @@ -137,19 +137,19 @@ func TestBlockStoreSaveLoadBlock(t *testing.T) { }, { - block: newBlock(&header2, commitAtH10), + block: newBlock(header2, commitAtH10), parts: uncontiguousPartSet, wantPanic: "only save contiguous blocks", // and incomplete and uncontiguous parts }, { - block: newBlock(&header1, commitAtH10), + block: newBlock(header1, commitAtH10), parts: incompletePartSet, wantPanic: "only save complete block", // incomplete parts }, { - block: newBlock(&header1, commitAtH10), + block: newBlock(header1, commitAtH10), parts: validPartSet, seenCommit: seenCommit1, corruptCommitInDB: true, // Corrupt the DB's commit entry @@ -157,7 +157,7 @@ func TestBlockStoreSaveLoadBlock(t *testing.T) { }, { - block: newBlock(&header1, commitAtH10), + block: newBlock(header1, commitAtH10), parts: validPartSet, seenCommit: seenCommit1, wantPanic: "unmarshal to types.BlockMeta failed", @@ -165,7 +165,7 @@ func TestBlockStoreSaveLoadBlock(t *testing.T) { }, { - block: newBlock(&header1, commitAtH10), + block: newBlock(header1, commitAtH10), parts: validPartSet, seenCommit: seenCommit1, @@ -174,7 +174,7 @@ func TestBlockStoreSaveLoadBlock(t *testing.T) { }, { - block: newBlock(&header1, commitAtH10), + block: newBlock(header1, commitAtH10), parts: validPartSet, seenCommit: seenCommit1, @@ -183,7 +183,7 @@ func TestBlockStoreSaveLoadBlock(t *testing.T) { }, { - block: newBlock(&header1, commitAtH10), + block: newBlock(header1, commitAtH10), parts: validPartSet, seenCommit: seenCommit1, @@ -375,7 +375,7 @@ func doFn(fn func() (interface{}, error)) (res interface{}, err error, panicErr return res, err, panicErr } -func newBlock(hdr *types.Header, lastCommit *types.Commit) *types.Block { +func newBlock(hdr types.Header, lastCommit *types.Commit) *types.Block { return &types.Block{ Header: hdr, LastCommit: lastCommit, diff --git a/consensus/state.go b/consensus/state.go index e4b360e0..f7dd52bb 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -81,7 +81,7 @@ type ConsensusState struct { evpool sm.EvidencePool // internal state - mtx sync.Mutex + mtx sync.RWMutex cstypes.RoundState state sm.State // State until height-1. @@ -192,15 +192,15 @@ func (cs *ConsensusState) String() string { // GetState returns a copy of the chain state. func (cs *ConsensusState) GetState() sm.State { - cs.mtx.Lock() - defer cs.mtx.Unlock() + cs.mtx.RLock() + defer cs.mtx.RUnlock() return cs.state.Copy() } // GetRoundState returns a shallow copy of the internal consensus state. func (cs *ConsensusState) GetRoundState() *cstypes.RoundState { - cs.mtx.Lock() - defer cs.mtx.Unlock() + cs.mtx.RLock() + defer cs.mtx.RUnlock() rs := cs.RoundState // copy return &rs @@ -208,24 +208,24 @@ func (cs *ConsensusState) GetRoundState() *cstypes.RoundState { // GetRoundStateJSON returns a json of RoundState, marshalled using go-amino. func (cs *ConsensusState) GetRoundStateJSON() ([]byte, error) { - cs.mtx.Lock() - defer cs.mtx.Unlock() + cs.mtx.RLock() + defer cs.mtx.RUnlock() return cdc.MarshalJSON(cs.RoundState) } // GetRoundStateSimpleJSON returns a json of RoundStateSimple, marshalled using go-amino. func (cs *ConsensusState) GetRoundStateSimpleJSON() ([]byte, error) { - cs.mtx.Lock() - defer cs.mtx.Unlock() + cs.mtx.RLock() + defer cs.mtx.RUnlock() return cdc.MarshalJSON(cs.RoundState.RoundStateSimple()) } // GetValidators returns a copy of the current validators. func (cs *ConsensusState) GetValidators() (int64, []*types.Validator) { - cs.mtx.Lock() - defer cs.mtx.Unlock() + cs.mtx.RLock() + defer cs.mtx.RUnlock() return cs.state.LastBlockHeight, cs.state.Validators.Copy().Validators } @@ -245,8 +245,8 @@ func (cs *ConsensusState) SetTimeoutTicker(timeoutTicker TimeoutTicker) { // LoadCommit loads the commit for a given height. func (cs *ConsensusState) LoadCommit(height int64) *types.Commit { - cs.mtx.Lock() - defer cs.mtx.Unlock() + cs.mtx.RLock() + defer cs.mtx.RUnlock() if height == cs.blockStore.Height() { return cs.blockStore.LoadSeenCommit(height) } diff --git a/consensus/types/round_state_test.go b/consensus/types/round_state_test.go index 73f4a34d..bcaa6308 100644 --- a/consensus/types/round_state_test.go +++ b/consensus/types/round_state_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/tendermint/go-amino" + amino "github.com/tendermint/go-amino" "github.com/tendermint/tendermint/crypto/ed25519" cmn "github.com/tendermint/tendermint/libs/common" "github.com/tendermint/tendermint/types" @@ -38,7 +38,7 @@ func BenchmarkRoundStateDeepCopy(b *testing.B) { } // Random block block := &types.Block{ - Header: &types.Header{ + Header: types.Header{ ChainID: cmn.RandStr(12), Time: time.Now(), LastBlockID: blockID, @@ -50,7 +50,7 @@ func BenchmarkRoundStateDeepCopy(b *testing.B) { LastResultsHash: cmn.RandBytes(20), EvidenceHash: cmn.RandBytes(20), }, - Data: &types.Data{ + Data: types.Data{ Txs: txs, }, Evidence: types.EvidenceData{}, diff --git a/lite/proxy/block.go b/lite/proxy/block.go index 4cff9ee6..00b8c87f 100644 --- a/lite/proxy/block.go +++ b/lite/proxy/block.go @@ -15,14 +15,14 @@ func ValidateBlockMeta(meta *types.BlockMeta, check lite.Commit) error { return errors.New("expecting a non-nil BlockMeta") } // TODO: check the BlockID?? - return ValidateHeader(meta.Header, check) + return ValidateHeader(&meta.Header, check) } func ValidateBlock(meta *types.Block, check lite.Commit) error { if meta == nil { return errors.New("expecting a non-nil Block") } - err := ValidateHeader(meta.Header, check) + err := ValidateHeader(&meta.Header, check) if err != nil { return err } diff --git a/lite/proxy/validate_test.go b/lite/proxy/validate_test.go index 782a6aab..47c0ff6d 100644 --- a/lite/proxy/validate_test.go +++ b/lite/proxy/validate_test.go @@ -18,7 +18,7 @@ var ( testTime2 = time.Date(2017, 1, 2, 1, 1, 1, 1, time.UTC) ) -var hdrHeight11 = &types.Header{ +var hdrHeight11 = types.Header{ Height: 11, Time: testTime1, ValidatorsHash: []byte("Tendermint"), @@ -34,21 +34,18 @@ func TestValidateBlock(t *testing.T) { block: nil, wantErr: "non-nil Block", }, { - block: &types.Block{}, wantErr: "nil Header", - }, - { - block: &types.Block{Header: new(types.Header)}, + block: &types.Block{}, }, // Start Header.Height mismatch test { - block: &types.Block{Header: &types.Header{Height: 10}}, + block: &types.Block{Header: types.Header{Height: 10}}, commit: lite.Commit{Header: &types.Header{Height: 11}}, wantErr: "don't match - 10 vs 11", }, { - block: &types.Block{Header: &types.Header{Height: 11}}, + block: &types.Block{Header: types.Header{Height: 11}}, commit: lite.Commit{Header: &types.Header{Height: 11}}, }, // End Header.Height mismatch test @@ -62,15 +59,15 @@ func TestValidateBlock(t *testing.T) { { block: &types.Block{Header: hdrHeight11}, - commit: lite.Commit{Header: hdrHeight11}, + commit: lite.Commit{Header: &hdrHeight11}, }, // End Header.Hash mismatch test // Start Header.Data hash mismatch test { block: &types.Block{ - Header: &types.Header{Height: 11}, - Data: &types.Data{Txs: []types.Tx{[]byte("0xDE"), []byte("AD")}}, + Header: types.Header{Height: 11}, + Data: types.Data{Txs: []types.Tx{[]byte("0xDE"), []byte("AD")}}, }, commit: lite.Commit{ Header: &types.Header{Height: 11}, @@ -80,8 +77,8 @@ func TestValidateBlock(t *testing.T) { }, { block: &types.Block{ - Header: &types.Header{Height: 11, DataHash: deadBeefHash}, - Data: &types.Data{Txs: deadBeefTxs}, + Header: types.Header{Height: 11, DataHash: deadBeefHash}, + Data: types.Data{Txs: deadBeefTxs}, }, commit: lite.Commit{ Header: &types.Header{Height: 11}, @@ -116,21 +113,18 @@ func TestValidateBlockMeta(t *testing.T) { meta: nil, wantErr: "non-nil BlockMeta", }, { - meta: &types.BlockMeta{}, wantErr: "non-nil Header", - }, - { - meta: &types.BlockMeta{Header: new(types.Header)}, + meta: &types.BlockMeta{}, }, // Start Header.Height mismatch test { - meta: &types.BlockMeta{Header: &types.Header{Height: 10}}, + meta: &types.BlockMeta{Header: types.Header{Height: 10}}, commit: lite.Commit{Header: &types.Header{Height: 11}}, wantErr: "don't match - 10 vs 11", }, { - meta: &types.BlockMeta{Header: &types.Header{Height: 11}}, + meta: &types.BlockMeta{Header: types.Header{Height: 11}}, commit: lite.Commit{Header: &types.Header{Height: 11}}, }, // End Header.Height mismatch test @@ -144,12 +138,12 @@ func TestValidateBlockMeta(t *testing.T) { { meta: &types.BlockMeta{Header: hdrHeight11}, - commit: lite.Commit{Header: hdrHeight11}, + commit: lite.Commit{Header: &hdrHeight11}, }, { meta: &types.BlockMeta{ - Header: &types.Header{ + Header: types.Header{ Height: 11, ValidatorsHash: []byte("lite-test"), // TODO: should be able to use empty time after Amino upgrade @@ -164,7 +158,7 @@ func TestValidateBlockMeta(t *testing.T) { { meta: &types.BlockMeta{ - Header: &types.Header{ + Header: types.Header{ Height: 11, DataHash: deadBeefHash, ValidatorsHash: []byte("Tendermint"), Time: testTime1, @@ -183,7 +177,7 @@ func TestValidateBlockMeta(t *testing.T) { { meta: &types.BlockMeta{ - Header: &types.Header{ + Header: types.Header{ Height: 11, DataHash: deadBeefHash, ValidatorsHash: []byte("Tendermint"), Time: testTime2, diff --git a/rpc/core/blocks.go b/rpc/core/blocks.go index 0e887315..5815b60e 100644 --- a/rpc/core/blocks.go +++ b/rpc/core/blocks.go @@ -3,10 +3,10 @@ package core import ( "fmt" + cmn "github.com/tendermint/tendermint/libs/common" ctypes "github.com/tendermint/tendermint/rpc/core/types" sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tendermint/libs/common" ) // Get block headers for minHeight <= height <= maxHeight. @@ -288,12 +288,12 @@ func Commit(heightPtr *int64) (*ctypes.ResultCommit, error) { // use a non-canonical commit if height == storeHeight { commit := blockStore.LoadSeenCommit(height) - return ctypes.NewResultCommit(header, commit, false), nil + return ctypes.NewResultCommit(&header, commit, false), nil } // Return the canonical commit (comes from the block at height+1) commit := blockStore.LoadBlockCommit(height) - return ctypes.NewResultCommit(header, commit, true), nil + return ctypes.NewResultCommit(&header, commit, true), nil } // BlockResults gets ABCIResults at a given height. diff --git a/rpc/core/status.go b/rpc/core/status.go index 63e62b2c..739e67b8 100644 --- a/rpc/core/status.go +++ b/rpc/core/status.go @@ -4,10 +4,10 @@ import ( "bytes" "time" + cmn "github.com/tendermint/tendermint/libs/common" ctypes "github.com/tendermint/tendermint/rpc/core/types" sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tendermint/libs/common" ) // Get Tendermint status including node info, pubkey, latest block @@ -104,8 +104,17 @@ func Status() (*ctypes.ResultStatus, error) { return result, nil } +const consensusTimeout = time.Second + func validatorAtHeight(h int64) *types.Validator { - lastBlockHeight, vals := consensusState.GetValidators() + lastBlockHeight, vals := getValidatorsWithTimeout( + consensusState, + consensusTimeout, + ) + + if lastBlockHeight == -1 { + return nil + } privValAddress := pubKey.Address() @@ -131,3 +140,32 @@ func validatorAtHeight(h int64) *types.Validator { return nil } + +type validatorRetriever interface { + GetValidators() (int64, []*types.Validator) +} + +// NOTE: Consensus might halt, but we still need to process RPC requests (at +// least for endpoints whole output does not depend on consensus state). +func getValidatorsWithTimeout( + vr validatorRetriever, + t time.Duration, +) (int64, []*types.Validator) { + resultCh := make(chan struct { + lastBlockHeight int64 + vals []*types.Validator + }) + go func() { + h, v := vr.GetValidators() + resultCh <- struct { + lastBlockHeight int64 + vals []*types.Validator + }{h, v} + }() + select { + case res := <-resultCh: + return res.lastBlockHeight, res.vals + case <-time.After(t): + return -1, []*types.Validator{} + } +} diff --git a/rpc/core/status_test.go b/rpc/core/status_test.go new file mode 100644 index 00000000..e44ffed0 --- /dev/null +++ b/rpc/core/status_test.go @@ -0,0 +1,39 @@ +package core + +import ( + "testing" + "time" + + "github.com/tendermint/tendermint/types" +) + +func TestGetValidatorsWithTimeout(t *testing.T) { + height, vs := getValidatorsWithTimeout( + testValidatorReceiver{}, + time.Millisecond, + ) + + if height != -1 { + t.Errorf("expected negative height") + } + + if len(vs) != 0 { + t.Errorf("expected no validators") + } +} + +type testValidatorReceiver struct{} + +func (tr testValidatorReceiver) GetValidators() (int64, []*types.Validator) { + vs := []*types.Validator{} + + for i := 0; i < 3; i++ { + v, _ := types.RandValidator(true, 10) + + vs = append(vs, v) + } + + time.Sleep(time.Millisecond) + + return 10, vs +} diff --git a/state/execution.go b/state/execution.go index 601abec9..f38f5e0b 100644 --- a/state/execution.go +++ b/state/execution.go @@ -86,7 +86,7 @@ func (blockExec *BlockExecutor) ApplyBlock(state State, blockID types.BlockID, b fail.Fail() // XXX // update the state with the block and responses - state, err = updateState(state, blockID, block.Header, abciResponses) + state, err = updateState(state, blockID, &block.Header, abciResponses) if err != nil { return state, fmt.Errorf("Commit failed for application: %v", err) } @@ -189,7 +189,7 @@ func execBlockOnProxyApp(logger log.Logger, proxyAppConn proxy.AppConnConsensus, // Begin block _, err := proxyAppConn.BeginBlockSync(abci.RequestBeginBlock{ Hash: block.Hash(), - Header: types.TM2PB.Header(block.Header), + Header: types.TM2PB.Header(&block.Header), Validators: signVals, ByzantineValidators: byzVals, }) diff --git a/state/state_test.go b/state/state_test.go index b70ab021..fa50693c 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -220,7 +220,7 @@ func TestOneValidatorChangesSaveLoad(t *testing.T) { power++ } header, blockID, responses := makeHeaderPartsResponsesValPowerChange(state, i, power) - state, err = updateState(state, blockID, header, responses) + state, err = updateState(state, blockID, &header, responses) assert.Nil(t, err) nextHeight := state.LastBlockHeight + 1 saveValidatorsInfo(stateDB, nextHeight, state.LastHeightValidatorsChanged, state.Validators) @@ -265,7 +265,7 @@ func TestManyValidatorChangesSaveLoad(t *testing.T) { // swap the first validator with a new one ^^^ (validator set size stays the same) header, blockID, responses := makeHeaderPartsResponsesValPubKeyChange(state, height, pubkey) var err error - state, err = updateState(state, blockID, header, responses) + state, err = updateState(state, blockID, &header, responses) require.Nil(t, err) nextHeight := state.LastBlockHeight + 1 saveValidatorsInfo(stateDB, nextHeight, state.LastHeightValidatorsChanged, state.Validators) @@ -322,7 +322,7 @@ func TestConsensusParamsChangesSaveLoad(t *testing.T) { cp = params[changeIndex] } header, blockID, responses := makeHeaderPartsResponsesParams(state, i, cp) - state, err = updateState(state, blockID, header, responses) + state, err = updateState(state, blockID, &header, responses) require.Nil(t, err) nextHeight := state.LastBlockHeight + 1 @@ -421,7 +421,7 @@ func TestApplyUpdates(t *testing.T) { } func makeHeaderPartsResponsesValPubKeyChange(state State, height int64, - pubkey crypto.PubKey) (*types.Header, types.BlockID, *ABCIResponses) { + pubkey crypto.PubKey) (types.Header, types.BlockID, *ABCIResponses) { block := makeBlock(state, height) abciResponses := &ABCIResponses{ @@ -443,7 +443,7 @@ func makeHeaderPartsResponsesValPubKeyChange(state State, height int64, } func makeHeaderPartsResponsesValPowerChange(state State, height int64, - power int64) (*types.Header, types.BlockID, *ABCIResponses) { + power int64) (types.Header, types.BlockID, *ABCIResponses) { block := makeBlock(state, height) abciResponses := &ABCIResponses{ @@ -464,7 +464,7 @@ func makeHeaderPartsResponsesValPowerChange(state State, height int64, } func makeHeaderPartsResponsesParams(state State, height int64, - params types.ConsensusParams) (*types.Header, types.BlockID, *ABCIResponses) { + params types.ConsensusParams) (types.Header, types.BlockID, *ABCIResponses) { block := makeBlock(state, height) abciResponses := &ABCIResponses{ @@ -477,14 +477,3 @@ type paramsChangeTestCase struct { height int64 params types.ConsensusParams } - -func makeHeaderPartsResults(state State, height int64, - results []*abci.ResponseDeliverTx) (*types.Header, types.BlockID, *ABCIResponses) { - - block := makeBlock(state, height) - abciResponses := &ABCIResponses{ - DeliverTx: results, - EndBlock: &abci.ResponseEndBlock{}, - } - return block.Header, types.BlockID{block.Hash(), types.PartSetHeader{}}, abciResponses -} diff --git a/tools/tm-monitor/monitor/node.go b/tools/tm-monitor/monitor/node.go index 7dc6d747..b9987020 100644 --- a/tools/tm-monitor/monitor/node.go +++ b/tools/tm-monitor/monitor/node.go @@ -134,7 +134,7 @@ func newBlockCallback(n *Node) em.EventCallbackFunc { n.logger.Info("new block", "height", block.Height, "numTxs", block.NumTxs) if n.blockCh != nil { - n.blockCh <- *block + n.blockCh <- block } } } diff --git a/tools/tm-monitor/monitor/node_test.go b/tools/tm-monitor/monitor/node_test.go index 449abcc9..1925a8b7 100644 --- a/tools/tm-monitor/monitor/node_test.go +++ b/tools/tm-monitor/monitor/node_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/tendermint/go-amino" + amino "github.com/tendermint/go-amino" "github.com/tendermint/tendermint/crypto/ed25519" ctypes "github.com/tendermint/tendermint/rpc/core/types" em "github.com/tendermint/tendermint/tools/tm-monitor/eventmeter" @@ -33,11 +33,11 @@ func TestNodeNewBlockReceived(t *testing.T) { defer n.Stop() n.SendBlocksTo(blockCh) - blockHeader := &tmtypes.Header{Height: 5} + blockHeader := tmtypes.Header{Height: 5} emMock.Call("eventCallback", &em.EventMetric{}, tmtypes.EventDataNewBlockHeader{blockHeader}) assert.Equal(t, int64(5), n.Height) - assert.Equal(t, *blockHeader, <-blockCh) + assert.Equal(t, blockHeader, <-blockCh) } func TestNodeNewBlockLatencyReceived(t *testing.T) { diff --git a/types/block.go b/types/block.go index e23fd71d..48857076 100644 --- a/types/block.go +++ b/types/block.go @@ -17,8 +17,8 @@ import ( // TODO: add Version byte type Block struct { mtx sync.Mutex - *Header `json:"header"` - *Data `json:"data"` + Header `json:"header"` + Data `json:"data"` Evidence EvidenceData `json:"evidence"` LastCommit *Commit `json:"last_commit"` } @@ -27,15 +27,15 @@ type Block struct { // It populates the same set of fields validated by ValidateBasic func MakeBlock(height int64, txs []Tx, commit *Commit) *Block { block := &Block{ - Header: &Header{ + Header: Header{ Height: height, Time: time.Now(), NumTxs: int64(len(txs)), }, - LastCommit: commit, - Data: &Data{ + Data: Data{ Txs: txs, }, + LastCommit: commit, } block.fillHeader() return block @@ -43,6 +43,9 @@ func MakeBlock(height int64, txs []Tx, commit *Commit) *Block { // AddEvidence appends the given evidence to the block func (b *Block) AddEvidence(evidence []Evidence) { + if b == nil { + return + } b.Evidence.Evidence = append(b.Evidence.Evidence, evidence...) } @@ -98,7 +101,7 @@ func (b *Block) Hash() cmn.HexBytes { b.mtx.Lock() defer b.mtx.Unlock() - if b == nil || b.Header == nil || b.Data == nil || b.LastCommit == nil { + if b == nil || b.LastCommit == nil { return nil } b.fillHeader() diff --git a/types/block_meta.go b/types/block_meta.go index 6dd502e4..d8926af0 100644 --- a/types/block_meta.go +++ b/types/block_meta.go @@ -3,7 +3,7 @@ package types // BlockMeta contains meta information about a block - namely, it's ID and Header. type BlockMeta struct { BlockID BlockID `json:"block_id"` // the block hash and partsethash - Header *Header `json:"header"` // The block's Header + Header Header `json:"header"` // The block's Header } // NewBlockMeta returns a new BlockMeta from the block and its blockParts. diff --git a/types/events.go b/types/events.go index 891c6a90..c26fecb7 100644 --- a/types/events.go +++ b/types/events.go @@ -64,7 +64,7 @@ type EventDataNewBlock struct { // light weight event for benchmarking type EventDataNewBlockHeader struct { - Header *Header `json:"header"` + Header Header `json:"header"` } // All txs fire EventDataTx diff --git a/types/proto3/block.pb.go b/types/proto3/block.pb.go new file mode 100644 index 00000000..805828f8 --- /dev/null +++ b/types/proto3/block.pb.go @@ -0,0 +1,261 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: block.proto + +/* +Package proto3 is a generated protocol buffer package. + +It is generated from these files: + block.proto + +It has these top-level messages: + PartSetHeader + BlockID + Header + Timestamp +*/ +package proto3 + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type PartSetHeader struct { + Total int32 `protobuf:"zigzag32,1,opt,name=Total" json:"Total,omitempty"` + Hash []byte `protobuf:"bytes,2,opt,name=Hash,proto3" json:"Hash,omitempty"` +} + +func (m *PartSetHeader) Reset() { *m = PartSetHeader{} } +func (m *PartSetHeader) String() string { return proto.CompactTextString(m) } +func (*PartSetHeader) ProtoMessage() {} +func (*PartSetHeader) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *PartSetHeader) GetTotal() int32 { + if m != nil { + return m.Total + } + return 0 +} + +func (m *PartSetHeader) GetHash() []byte { + if m != nil { + return m.Hash + } + return nil +} + +type BlockID struct { + Hash []byte `protobuf:"bytes,1,opt,name=Hash,proto3" json:"Hash,omitempty"` + PartsHeader *PartSetHeader `protobuf:"bytes,2,opt,name=PartsHeader" json:"PartsHeader,omitempty"` +} + +func (m *BlockID) Reset() { *m = BlockID{} } +func (m *BlockID) String() string { return proto.CompactTextString(m) } +func (*BlockID) ProtoMessage() {} +func (*BlockID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *BlockID) GetHash() []byte { + if m != nil { + return m.Hash + } + return nil +} + +func (m *BlockID) GetPartsHeader() *PartSetHeader { + if m != nil { + return m.PartsHeader + } + return nil +} + +type Header struct { + // basic block info + ChainID string `protobuf:"bytes,1,opt,name=ChainID" json:"ChainID,omitempty"` + Height int64 `protobuf:"zigzag64,2,opt,name=Height" json:"Height,omitempty"` + Time *Timestamp `protobuf:"bytes,3,opt,name=Time" json:"Time,omitempty"` + NumTxs int64 `protobuf:"zigzag64,4,opt,name=NumTxs" json:"NumTxs,omitempty"` + // prev block info + LastBlockID *BlockID `protobuf:"bytes,5,opt,name=LastBlockID" json:"LastBlockID,omitempty"` + TotalTxs int64 `protobuf:"zigzag64,6,opt,name=TotalTxs" json:"TotalTxs,omitempty"` + // hashes of block data + LastCommitHash []byte `protobuf:"bytes,7,opt,name=LastCommitHash,proto3" json:"LastCommitHash,omitempty"` + DataHash []byte `protobuf:"bytes,8,opt,name=DataHash,proto3" json:"DataHash,omitempty"` + // hashes from the app output from the prev block + ValidatorsHash []byte `protobuf:"bytes,9,opt,name=ValidatorsHash,proto3" json:"ValidatorsHash,omitempty"` + ConsensusHash []byte `protobuf:"bytes,10,opt,name=ConsensusHash,proto3" json:"ConsensusHash,omitempty"` + AppHash []byte `protobuf:"bytes,11,opt,name=AppHash,proto3" json:"AppHash,omitempty"` + LastResultsHash []byte `protobuf:"bytes,12,opt,name=LastResultsHash,proto3" json:"LastResultsHash,omitempty"` + // consensus info + EvidenceHash []byte `protobuf:"bytes,13,opt,name=EvidenceHash,proto3" json:"EvidenceHash,omitempty"` +} + +func (m *Header) Reset() { *m = Header{} } +func (m *Header) String() string { return proto.CompactTextString(m) } +func (*Header) ProtoMessage() {} +func (*Header) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *Header) GetChainID() string { + if m != nil { + return m.ChainID + } + return "" +} + +func (m *Header) GetHeight() int64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *Header) GetTime() *Timestamp { + if m != nil { + return m.Time + } + return nil +} + +func (m *Header) GetNumTxs() int64 { + if m != nil { + return m.NumTxs + } + return 0 +} + +func (m *Header) GetLastBlockID() *BlockID { + if m != nil { + return m.LastBlockID + } + return nil +} + +func (m *Header) GetTotalTxs() int64 { + if m != nil { + return m.TotalTxs + } + return 0 +} + +func (m *Header) GetLastCommitHash() []byte { + if m != nil { + return m.LastCommitHash + } + return nil +} + +func (m *Header) GetDataHash() []byte { + if m != nil { + return m.DataHash + } + return nil +} + +func (m *Header) GetValidatorsHash() []byte { + if m != nil { + return m.ValidatorsHash + } + return nil +} + +func (m *Header) GetConsensusHash() []byte { + if m != nil { + return m.ConsensusHash + } + return nil +} + +func (m *Header) GetAppHash() []byte { + if m != nil { + return m.AppHash + } + return nil +} + +func (m *Header) GetLastResultsHash() []byte { + if m != nil { + return m.LastResultsHash + } + return nil +} + +func (m *Header) GetEvidenceHash() []byte { + if m != nil { + return m.EvidenceHash + } + return nil +} + +// Timestamp wraps how amino encodes time. Note that this is different from the protobuf well-known type +// protobuf/timestamp.proto in the sense that there seconds and nanos are varint encoded. See: +// https://github.com/google/protobuf/blob/d2980062c859649523d5fd51d6b55ab310e47482/src/google/protobuf/timestamp.proto#L123-L135 +// Also nanos do not get skipped if they are zero in amino. +type Timestamp struct { + Seconds int64 `protobuf:"fixed64,1,opt,name=seconds" json:"seconds,omitempty"` + Nanos int32 `protobuf:"fixed32,2,opt,name=nanos" json:"nanos,omitempty"` +} + +func (m *Timestamp) Reset() { *m = Timestamp{} } +func (m *Timestamp) String() string { return proto.CompactTextString(m) } +func (*Timestamp) ProtoMessage() {} +func (*Timestamp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + +func (m *Timestamp) GetSeconds() int64 { + if m != nil { + return m.Seconds + } + return 0 +} + +func (m *Timestamp) GetNanos() int32 { + if m != nil { + return m.Nanos + } + return 0 +} + +func init() { + proto.RegisterType((*PartSetHeader)(nil), "proto3.PartSetHeader") + proto.RegisterType((*BlockID)(nil), "proto3.BlockID") + proto.RegisterType((*Header)(nil), "proto3.Header") + proto.RegisterType((*Timestamp)(nil), "proto3.Timestamp") +} + +func init() { proto.RegisterFile("block.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 372 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x92, 0x4f, 0x6b, 0xe3, 0x30, + 0x10, 0xc5, 0xf1, 0xe6, 0xff, 0x38, 0xd9, 0x6c, 0x86, 0xdd, 0xc5, 0xf4, 0x14, 0x4c, 0x5b, 0x72, + 0x0a, 0xb4, 0x39, 0x94, 0xd2, 0x53, 0x9b, 0x14, 0x12, 0x28, 0xa5, 0xa8, 0x21, 0x77, 0x25, 0x16, + 0x8d, 0xa9, 0x2d, 0x19, 0x4b, 0x29, 0xfd, 0x7c, 0xfd, 0x64, 0x45, 0x23, 0xdb, 0x8d, 0x73, 0x4a, + 0xde, 0x9b, 0x37, 0xbf, 0x91, 0x47, 0x02, 0x7f, 0x9b, 0xa8, 0xdd, 0xfb, 0x34, 0xcb, 0x95, 0x51, + 0xd8, 0xa6, 0x9f, 0x59, 0x78, 0x0b, 0x83, 0x17, 0x9e, 0x9b, 0x57, 0x61, 0x96, 0x82, 0x47, 0x22, + 0xc7, 0xbf, 0xd0, 0x5a, 0x2b, 0xc3, 0x93, 0xc0, 0x1b, 0x7b, 0x93, 0x11, 0x73, 0x02, 0x11, 0x9a, + 0x4b, 0xae, 0xf7, 0xc1, 0xaf, 0xb1, 0x37, 0xe9, 0x33, 0xfa, 0x1f, 0x6e, 0xa0, 0xf3, 0x60, 0x89, + 0xab, 0x45, 0x55, 0xf6, 0x7e, 0xca, 0x78, 0x03, 0xbe, 0x25, 0x6b, 0xc7, 0xa5, 0x4e, 0xff, 0xfa, + 0x9f, 0x1b, 0x3f, 0x9b, 0xd6, 0x86, 0xb2, 0xe3, 0x64, 0xf8, 0xd5, 0x80, 0x76, 0x71, 0x98, 0x00, + 0x3a, 0xf3, 0x3d, 0x8f, 0xe5, 0x6a, 0x41, 0xe8, 0x1e, 0x2b, 0x25, 0xfe, 0xb7, 0x99, 0xf8, 0x6d, + 0x6f, 0x08, 0x8c, 0xac, 0x50, 0x78, 0x01, 0xcd, 0x75, 0x9c, 0x8a, 0xa0, 0x41, 0xe3, 0x46, 0xe5, + 0x38, 0xeb, 0x69, 0xc3, 0xd3, 0x8c, 0x51, 0xd9, 0xb6, 0x3f, 0x1f, 0xd2, 0xf5, 0xa7, 0x0e, 0x9a, + 0xae, 0xdd, 0x29, 0xbc, 0x02, 0xff, 0x89, 0x6b, 0x53, 0x7c, 0x57, 0xd0, 0x22, 0xca, 0xb0, 0xa4, + 0x14, 0x36, 0x3b, 0xce, 0xe0, 0x19, 0x74, 0x69, 0x47, 0x16, 0xd6, 0x26, 0x58, 0xa5, 0xf1, 0x12, + 0x7e, 0xdb, 0xe8, 0x5c, 0xa5, 0x69, 0x6c, 0x68, 0x43, 0x1d, 0xda, 0xd0, 0x89, 0x6b, 0x19, 0x0b, + 0x6e, 0x38, 0x25, 0xba, 0x94, 0xa8, 0xb4, 0x65, 0x6c, 0x78, 0x12, 0x47, 0xdc, 0xa8, 0x5c, 0x53, + 0xa2, 0xe7, 0x18, 0x75, 0x17, 0xcf, 0x61, 0x30, 0x57, 0x52, 0x0b, 0xa9, 0x0f, 0x2e, 0x06, 0x14, + 0xab, 0x9b, 0x76, 0xa3, 0xf7, 0x59, 0x46, 0x75, 0x9f, 0xea, 0xa5, 0xc4, 0x09, 0x0c, 0xed, 0xa9, + 0x98, 0xd0, 0x87, 0xc4, 0x38, 0x42, 0x9f, 0x12, 0xa7, 0x36, 0x86, 0xd0, 0x7f, 0xfc, 0x88, 0x23, + 0x21, 0x77, 0x82, 0x62, 0x03, 0x8a, 0xd5, 0xbc, 0xf0, 0x0e, 0x7a, 0xd5, 0xce, 0xed, 0x50, 0x2d, + 0x76, 0x4a, 0x46, 0x9a, 0xae, 0xf1, 0x0f, 0x2b, 0xa5, 0x7d, 0x6d, 0x92, 0x4b, 0xa5, 0xe9, 0x16, + 0x87, 0xcc, 0x89, 0x6d, 0xf1, 0x38, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x6b, 0x74, 0x2f, 0xbd, + 0xb2, 0x02, 0x00, 0x00, +} diff --git a/types/proto3/block.proto b/types/proto3/block.proto new file mode 100644 index 00000000..bc3cf874 --- /dev/null +++ b/types/proto3/block.proto @@ -0,0 +1,48 @@ +syntax = "proto3"; + +package proto3; + + +message PartSetHeader { + sint32 Total = 1; + bytes Hash = 2; +} + +message BlockID { + bytes Hash = 1; + PartSetHeader PartsHeader = 2; +} + +message Header { + // basic block info + string ChainID = 1; + sint64 Height = 2; + Timestamp Time = 3; + sint64 NumTxs = 4; + + // prev block info + BlockID LastBlockID = 5; + sint64 TotalTxs = 6; + + // hashes of block data + bytes LastCommitHash = 7; // commit from validators from the last block + bytes DataHash = 8; // transactions + + // hashes from the app output from the prev block + bytes ValidatorsHash = 9; // validators for the current block + bytes ConsensusHash = 10; // consensus params for current block + bytes AppHash = 11; // state after txs from the previous block + bytes LastResultsHash = 12; // root hash of all results from the txs from the previous block + + // consensus info + bytes EvidenceHash = 13; // evidence included in the block +} + +// Timestamp wraps how amino encodes time. Note that this is different from the protobuf well-known type +// protobuf/timestamp.proto in the sense that there seconds and nanos are varint encoded. See: +// https://github.com/google/protobuf/blob/d2980062c859649523d5fd51d6b55ab310e47482/src/google/protobuf/timestamp.proto#L123-L135 +// Also nanos do not get skipped if they are zero in amino. +message Timestamp { + sfixed64 seconds = 1; + sfixed32 nanos = 2; +} diff --git a/types/proto3_test.go b/types/proto3_test.go new file mode 100644 index 00000000..19a624a6 --- /dev/null +++ b/types/proto3_test.go @@ -0,0 +1,115 @@ +package types + +import ( + "testing" + "time" + + "github.com/golang/protobuf/proto" + "github.com/stretchr/testify/assert" + + "github.com/tendermint/tendermint/types/proto3" +) + +func TestProto3Compatibility(t *testing.T) { + tm, err := time.Parse("Mon Jan 2 15:04:05 -0700 MST 2006", "Mon Jan 2 15:04:05 -0700 MST 2006") + assert.NoError(t, err) + // add some nanos, otherwise protobuf will skip over this while amino (still) won't! + tm = tm.Add(50000 * time.Nanosecond) + seconds := tm.Unix() + nanos := int32(tm.Nanosecond()) + t.Log("seconds", seconds) + t.Log("nanos", nanos) + + pbHeader := proto3.Header{ + ChainID: "cosmos", + Height: 150, + Time: &proto3.Timestamp{Seconds: seconds, Nanos: nanos}, + NumTxs: 7, + LastBlockID: &proto3.BlockID{ + Hash: []byte("some serious hashing"), + PartsHeader: &proto3.PartSetHeader{ + Total: 8, + Hash: []byte("some more serious hashing"), + }, + }, + TotalTxs: 100, + LastCommitHash: []byte("commit hash"), + DataHash: []byte("data hash"), + ValidatorsHash: []byte("validators hash"), + } + aminoHeader := Header{ + ChainID: "cosmos", + Height: 150, + Time: tm, + NumTxs: 7, + LastBlockID: BlockID{ + Hash: []byte("some serious hashing"), + PartsHeader: PartSetHeader{ + Total: 8, + Hash: []byte("some more serious hashing"), + }, + }, + TotalTxs: 100, + LastCommitHash: []byte("commit hash"), + DataHash: []byte("data hash"), + ValidatorsHash: []byte("validators hash"), + } + ab, err := cdc.MarshalBinaryBare(aminoHeader) + assert.NoError(t, err, "unexpected error") + + pb, err := proto.Marshal(&pbHeader) + assert.NoError(t, err, "unexpected error") + // This works: + assert.Equal(t, ab, pb, "encoding doesn't match") + + emptyLastBlockPb := proto3.Header{ + ChainID: "cosmos", + Height: 150, + Time: &proto3.Timestamp{Seconds: seconds, Nanos: nanos}, + NumTxs: 7, + // This is not fully skipped in amino (yet) although it is empty: + LastBlockID: &proto3.BlockID{ + PartsHeader: &proto3.PartSetHeader{ + }, + }, + TotalTxs: 100, + LastCommitHash: []byte("commit hash"), + DataHash: []byte("data hash"), + ValidatorsHash: []byte("validators hash"), + } + emptyLastBlockAm := Header{ + ChainID: "cosmos", + Height: 150, + Time: tm, + NumTxs: 7, + TotalTxs: 100, + LastCommitHash: []byte("commit hash"), + DataHash: []byte("data hash"), + ValidatorsHash: []byte("validators hash"), + } + + ab, err = cdc.MarshalBinaryBare(emptyLastBlockAm) + assert.NoError(t, err, "unexpected error") + + pb, err = proto.Marshal(&emptyLastBlockPb) + assert.NoError(t, err, "unexpected error") + // This works: + assert.Equal(t, ab, pb, "encoding doesn't match") + + pb, err = proto.Marshal(&proto3.Header{}) + assert.NoError(t, err, "unexpected error") + t.Log(pb) + + // While in protobuf Header{} encodes to an empty byte slice it does not in amino: + ab, err = cdc.MarshalBinaryBare(Header{}) + assert.NoError(t, err, "unexpected error") + t.Log(ab) + + pb, err = proto.Marshal(&proto3.Timestamp{}) + assert.NoError(t, err, "unexpected error") + t.Log(pb) + + ab, err = cdc.MarshalBinaryBare(time.Time{}) + assert.NoError(t, err, "unexpected error") + t.Log(ab) +}