diff --git a/CHANGELOG.md b/CHANGELOG.md index b62e2354..caed7720 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,55 @@ # Changelog +## 0.23.0 + +*August 5th, 2018* + +This release includes breaking upgrades in our P2P encryption, +some ABCI messages, and how we encode time and signatures. + +A few more changes are still coming to the Header, ABCI, +and validator set handling to better support light clients, BFT time, and +upgrades. Most notably, validator set changes will be delayed by one block (see +[#1815][i1815]). + +We also removed `make ensure_deps` in favour of `make get_vendor_deps`. + +BREAKING CHANGES: +- [abci] Changed time format from int64 to google.protobuf.Timestamp +- [abci] Changed Validators to LastCommitInfo in RequestBeginBlock +- [abci] Removed Fee from ResponseDeliverTx and ResponseCheckTx +- [crypto] Switch crypto.Signature from interface to []byte for space efficiency + [#2128](https://github.com/tendermint/tendermint/pull/2128) + - NOTE: this means signatures no longer have the prefix bytes in Amino + binary nor the `type` field in Amino JSON. They're just bytes. +- [p2p] Remove salsa and ripemd primitives, in favor of using chacha as a stream cipher, and hkdf [#2054](https://github.com/tendermint/tendermint/pull/2054) +- [tools] Removed `make ensure_deps` in favor of `make get_vendor_deps` +- [types] CanonicalTime uses nanoseconds instead of clipping to ms + - breaks serialization/signing of all messages with a timestamp + +FEATURES: +- [tools] Added `make check_dep` + - ensures gopkg.lock is synced with gopkg.toml + - ensures no branches are used in the gopkg.toml + +IMPROVEMENTS: +- [blockchain] Improve fast-sync logic + [#1805](https://github.com/tendermint/tendermint/pull/1805) + - tweak params + - only process one block at a time to avoid starving +- [common] bit array functions which take in another parameter are now thread safe +- [crypto] Switch hkdfchachapoly1305 to xchachapoly1305 +- [p2p] begin connecting to peers as soon a seed node provides them to you ([#2093](https://github.com/tendermint/tendermint/issues/2093)) + +BUG FIXES: +- [common] Safely handle cases where atomic write files already exist [#2109](https://github.com/tendermint/tendermint/issues/2109) +- [privval] fix a deadline for accepting new connections in socket private + validator. +- [p2p] Allow startup if a configured seed node's IP can't be resolved ([#1716](https://github.com/tendermint/tendermint/issues/1716)) +- [node] Fully exit when CTRL-C is pressed even if consensus state panics [#2072](https://github.com/tendermint/tendermint/issues/2072) + +[i1815]: https://github.com/tendermint/tendermint/pull/1815 + ## 0.22.8 *July 26th, 2018* diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index daa4931c..776986d9 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -1,37 +1,16 @@ # Pending BREAKING CHANGES: -- [types] CanonicalTime uses nanoseconds instead of clipping to ms - - breaks serialization/signing of all messages with a timestamp - [types] Header ... - [state] Add NextValidatorSet, changes on-disk representation of state - [state] Validator set changes are delayed by one block (!) - [lite] Complete refactor of the package - [rpc] `/commit` returns a `signed_header` field instead of everything being top-level -- [abci] Removed Fee from ResponseDeliverTx and ResponseCheckTx -- [tools] Removed `make ensure_deps` in favor of `make get_vendor_deps` -- [p2p] Remove salsa and ripemd primitives, in favor of using chacha as a stream cipher, and hkdf -- [abci] Changed time format from int64 to google.protobuf.Timestamp -- [abci] Changed Validators to LastCommitInfo in RequestBeginBlock - [abci] Added address of the original proposer of the block to Header. FEATURES: -- [tools] Added `make check_dep` - - ensures gopkg.lock is synced with gopkg.toml - - ensures no branches are used in the gopkg.toml IMPROVEMENTS: -- [blockchain] Improve fast-sync logic - - tweak params - - only process one block at a time to avoid starving -- [crypto] Switch hkdfchachapoly1305 to xchachapoly1305 -- [common] bit array functions which take in another parameter are now thread safe -- [p2p] begin connecting to peers as soon a seed node provides them to you ([#2093](https://github.com/tendermint/tendermint/issues/2093)) BUG FIXES: -- [common] Safely handle cases where atomic write files already exist [#2109](https://github.com/tendermint/tendermint/issues/2109) -- [privval] fix a deadline for accepting new connections in socket private - validator. -- [p2p] Allow startup if a configured seed node's IP can't be resolved ([#1716](https://github.com/tendermint/tendermint/issues/1716)) -- [node] Fully exit when CTRL-C is pressed even if consensus state panics [#2072](https://github.com/tendermint/tendermint/issues/2072) diff --git a/Makefile b/Makefile index c08e583e..d2cec275 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ BUILD_FLAGS = -ldflags "-X github.com/tendermint/tendermint/version.GitCommit=`g all: check build test install -check: check_tools ensure_deps +check: check_tools get_vendor_deps ######################################## diff --git a/abci/example/example_test.go b/abci/example/example_test.go index 7e8bd2e5..8fa3ae02 100644 --- a/abci/example/example_test.go +++ b/abci/example/example_test.go @@ -7,6 +7,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/require" + "google.golang.org/grpc" "golang.org/x/net/context" @@ -43,7 +45,7 @@ func testStream(t *testing.T, app types.Application) { server := abciserver.NewSocketServer("unix://test.sock", app) server.SetLogger(log.TestingLogger().With("module", "abci-server")) if err := server.Start(); err != nil { - t.Fatalf("Error starting socket server: %v", err.Error()) + require.NoError(t, err, "Error starting socket server") } defer server.Stop() diff --git a/consensus/types/round_state_test.go b/consensus/types/round_state_test.go index bcaa6308..0257ea2f 100644 --- a/consensus/types/round_state_test.go +++ b/consensus/types/round_state_test.go @@ -23,7 +23,7 @@ func BenchmarkRoundStateDeepCopy(b *testing.B) { Hash: cmn.RandBytes(20), }, } - sig := ed25519.SignatureEd25519{} + sig := make([]byte, ed25519.SignatureEd25519Size) for i := 0; i < nval; i++ { precommits[i] = &types.Vote{ ValidatorAddress: types.Address(cmn.RandBytes(20)), diff --git a/crypto/README.md b/crypto/README.md index 5fac6733..bb663122 100644 --- a/crypto/README.md +++ b/crypto/README.md @@ -24,9 +24,7 @@ crypto `.Bytes()` uses Amino:binary encoding, but Amino:JSON is also supported. Example Amino:JSON encodings: ed25519.PrivKeyEd25519 - {"type":"954568A3288910","value":"EVkqJO/jIXp3rkASXfh9YnyToYXRXhBr6g9cQVxPFnQBP/5povV4HTjvsy530kybxKHwEi85iU8YL0qQhSYVoQ=="} -crypto.SignatureEd25519 - {"type":"6BF5903DA1DB28","value":"77sQNZOrf7ltExpf7AV1WaYPCHbyRLgjBsoWVzcduuLk+jIGmYk+s5R6Emm29p12HeiNAuhUJgdFGmwkpeGJCA=="} ed25519.PubKeyEd25519 - {"type":"AC26791624DE60","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="} crypto.PrivKeySecp256k1 - {"type":"019E82E1B0F798","value":"zx4Pnh67N+g2V+5vZbQzEyRerX9c4ccNZOVzM9RvJ0Y="} -crypto.SignatureSecp256k1 - {"type":"6D1EA416E1FEE8","value":"MEUCIQCIg5TqS1l7I+MKTrSPIuUN2+4m5tA29dcauqn3NhEJ2wIgICaZ+lgRc5aOTVahU/XoLopXKn8BZcl0bnuYWLvohR8="} crypto.PubKeySecp256k1 - {"type":"F8CCEAEB5AE980","value":"A8lPKJXcNl5VHt1FK8a244K9EJuS4WX1hFBnwisi0IJx"} ``` diff --git a/crypto/crypto.go b/crypto/crypto.go index 4c097b35..09c12ff7 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -6,7 +6,7 @@ import ( type PrivKey interface { Bytes() []byte - Sign(msg []byte) (Signature, error) + Sign(msg []byte) ([]byte, error) PubKey() PubKey Equals(PrivKey) bool } @@ -19,16 +19,10 @@ type Address = cmn.HexBytes type PubKey interface { Address() Address Bytes() []byte - VerifyBytes(msg []byte, sig Signature) bool + VerifyBytes(msg []byte, sig []byte) bool Equals(PubKey) bool } -type Signature interface { - Bytes() []byte - IsZero() bool - Equals(Signature) bool -} - type Symmetric interface { Keygen() []byte Encrypt(plaintext []byte, secret []byte) (ciphertext []byte) diff --git a/crypto/ed25519/ed25519.go b/crypto/ed25519/ed25519.go index 3dd4d2b3..fa7526f3 100644 --- a/crypto/ed25519/ed25519.go +++ b/crypto/ed25519/ed25519.go @@ -11,7 +11,6 @@ import ( amino "github.com/tendermint/go-amino" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/tmhash" - cmn "github.com/tendermint/tendermint/libs/common" ) //------------------------------------- @@ -19,9 +18,11 @@ import ( var _ crypto.PrivKey = PrivKeyEd25519{} const ( - Ed25519PrivKeyAminoRoute = "tendermint/PrivKeyEd25519" - Ed25519PubKeyAminoRoute = "tendermint/PubKeyEd25519" - Ed25519SignatureAminoRoute = "tendermint/SignatureEd25519" + Ed25519PrivKeyAminoRoute = "tendermint/PrivKeyEd25519" + Ed25519PubKeyAminoRoute = "tendermint/PubKeyEd25519" + // Size of an Edwards25519 signature. Namely the size of a compressed + // Edwards25519 point, and a field element. Both of which are 32 bytes. + SignatureEd25519Size = 64 ) var cdc = amino.NewCodec() @@ -34,10 +35,6 @@ func init() { cdc.RegisterInterface((*crypto.PrivKey)(nil), nil) cdc.RegisterConcrete(PrivKeyEd25519{}, Ed25519PrivKeyAminoRoute, nil) - - cdc.RegisterInterface((*crypto.Signature)(nil), nil) - cdc.RegisterConcrete(SignatureEd25519{}, - Ed25519SignatureAminoRoute, nil) } // PrivKeyEd25519 implements crypto.PrivKey. @@ -49,10 +46,10 @@ func (privKey PrivKeyEd25519) Bytes() []byte { } // Sign produces a signature on the provided message. -func (privKey PrivKeyEd25519) Sign(msg []byte) (crypto.Signature, error) { +func (privKey PrivKeyEd25519) Sign(msg []byte) ([]byte, error) { privKeyBytes := [64]byte(privKey) signatureBytes := ed25519.Sign(&privKeyBytes, msg) - return SignatureEd25519(*signatureBytes), nil + return signatureBytes[:], nil } // PubKey gets the corresponding public key from the private key. @@ -159,15 +156,15 @@ func (pubKey PubKeyEd25519) Bytes() []byte { return bz } -func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ crypto.Signature) bool { +func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ []byte) bool { // make sure we use the same algorithm to sign - sig, ok := sig_.(SignatureEd25519) - if !ok { + if len(sig_) != SignatureEd25519Size { return false } + sig := new([SignatureEd25519Size]byte) + copy(sig[:], sig_) pubKeyBytes := [PubKeyEd25519Size]byte(pubKey) - sigBytes := [SignatureEd25519Size]byte(sig) - return ed25519.Verify(&pubKeyBytes, msg, &sigBytes) + return ed25519.Verify(&pubKeyBytes, msg, sig) } // ToCurve25519 takes a public key and returns its representation on @@ -197,40 +194,3 @@ func (pubKey PubKeyEd25519) Equals(other crypto.PubKey) bool { return false } } - -//------------------------------------- - -var _ crypto.Signature = SignatureEd25519{} - -// Size of an Edwards25519 signature. Namely the size of a compressed -// Edwards25519 point, and a field element. Both of which are 32 bytes. -const SignatureEd25519Size = 64 - -// SignatureEd25519 implements crypto.Signature -type SignatureEd25519 [SignatureEd25519Size]byte - -func (sig SignatureEd25519) Bytes() []byte { - bz, err := cdc.MarshalBinaryBare(sig) - if err != nil { - panic(err) - } - return bz -} - -func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 } - -func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", cmn.Fingerprint(sig[:])) } - -func (sig SignatureEd25519) Equals(other crypto.Signature) bool { - if otherEd, ok := other.(SignatureEd25519); ok { - return subtle.ConstantTimeCompare(sig[:], otherEd[:]) == 1 - } else { - return false - } -} - -func SignatureEd25519FromBytes(data []byte) crypto.Signature { - var sig SignatureEd25519 - copy(sig[:], data) - return sig -} diff --git a/crypto/ed25519/ed25519_test.go b/crypto/ed25519/ed25519_test.go index 5c407ccd..50305027 100644 --- a/crypto/ed25519/ed25519_test.go +++ b/crypto/ed25519/ed25519_test.go @@ -23,9 +23,7 @@ func TestSignAndValidateEd25519(t *testing.T) { // Mutate the signature, just one bit. // TODO: Replace this with a much better fuzzer, tendermint/ed25519/issues/10 - sigEd := sig.(ed25519.SignatureEd25519) - sigEd[7] ^= byte(0x01) - sig = sigEd + sig[7] ^= byte(0x01) assert.False(t, pubKey.VerifyBytes(msg, sig)) } diff --git a/crypto/encoding/amino/amino.go b/crypto/encoding/amino/amino.go index 2b5e15b4..fd9a0844 100644 --- a/crypto/encoding/amino/amino.go +++ b/crypto/encoding/amino/amino.go @@ -33,12 +33,6 @@ func RegisterAmino(cdc *amino.Codec) { "tendermint/PrivKeyEd25519", nil) cdc.RegisterConcrete(secp256k1.PrivKeySecp256k1{}, "tendermint/PrivKeySecp256k1", nil) - - cdc.RegisterInterface((*crypto.Signature)(nil), nil) - cdc.RegisterConcrete(ed25519.SignatureEd25519{}, - "tendermint/SignatureEd25519", nil) - cdc.RegisterConcrete(secp256k1.SignatureSecp256k1{}, - "tendermint/SignatureSecp256k1", nil) } func PrivKeyFromBytes(privKeyBytes []byte) (privKey crypto.PrivKey, err error) { @@ -50,8 +44,3 @@ func PubKeyFromBytes(pubKeyBytes []byte) (pubKey crypto.PubKey, err error) { err = cdc.UnmarshalBinaryBare(pubKeyBytes, &pubKey) return } - -func SignatureFromBytes(pubKeyBytes []byte) (pubKey crypto.Signature, err error) { - err = cdc.UnmarshalBinaryBare(pubKeyBytes, &pubKey) - return -} diff --git a/crypto/encoding/amino/encode_test.go b/crypto/encoding/amino/encode_test.go index e0120608..0581ba64 100644 --- a/crypto/encoding/amino/encode_test.go +++ b/crypto/encoding/amino/encode_test.go @@ -15,12 +15,14 @@ type byter interface { Bytes() []byte } -func checkAminoBinary(t *testing.T, src byter, dst interface{}, size int) { +func checkAminoBinary(t *testing.T, src, dst interface{}, size int) { // Marshal to binary bytes. bz, err := cdc.MarshalBinaryBare(src) require.Nil(t, err, "%+v", err) - // Make sure this is compatible with current (Bytes()) encoding. - assert.Equal(t, src.Bytes(), bz, "Amino binary vs Bytes() mismatch") + if byterSrc, ok := src.(byter); ok { + // Make sure this is compatible with current (Bytes()) encoding. + assert.Equal(t, byterSrc.Bytes(), bz, "Amino binary vs Bytes() mismatch") + } // Make sure we have the expected length. if size != -1 { assert.Equal(t, size, len(bz), "Amino binary size mismatch") @@ -53,8 +55,6 @@ func ExamplePrintRegisteredTypes() { //| PubKeySecp256k1 | tendermint/PubKeySecp256k1 | 0xEB5AE987 | 0x21 | | //| PrivKeyEd25519 | tendermint/PrivKeyEd25519 | 0xA3288910 | 0x40 | | //| PrivKeySecp256k1 | tendermint/PrivKeySecp256k1 | 0xE1B0F79B | 0x20 | | - //| SignatureEd25519 | tendermint/SignatureEd25519 | 0x2031EA53 | 0x40 | | - //| SignatureSecp256k1 | tendermint/SignatureSecp256k1 | 0x7FC4A495 | variable | | } func TestKeyEncodings(t *testing.T) { @@ -84,13 +84,11 @@ func TestKeyEncodings(t *testing.T) { assert.EqualValues(t, tc.privKey, priv3, "tc #%d", tcIndex) // Check (de/en)codings of Signatures. - var sig1, sig2, sig3 crypto.Signature + var sig1, sig2 []byte sig1, err := tc.privKey.Sign([]byte("something")) assert.NoError(t, err, "tc #%d", tcIndex) checkAminoBinary(t, sig1, &sig2, -1) // Signature size changes for Secp anyways. assert.EqualValues(t, sig1, sig2, "tc #%d", tcIndex) - checkAminoJSON(t, sig1, &sig3, false) // TODO also check Prefix bytes. - assert.EqualValues(t, sig1, sig3, "tc #%d", tcIndex) // Check (de/en)codings of PubKeys. pubKey := tc.privKey.PubKey() @@ -105,7 +103,7 @@ func TestKeyEncodings(t *testing.T) { func TestNilEncodings(t *testing.T) { // Check nil Signature. - var a, b crypto.Signature + var a, b []byte checkAminoJSON(t, &a, &b, true) assert.EqualValues(t, a, b) diff --git a/crypto/secp256k1/secp256k1.go b/crypto/secp256k1/secp256k1.go index 03d5614a..aee5dafe 100644 --- a/crypto/secp256k1/secp256k1.go +++ b/crypto/secp256k1/secp256k1.go @@ -10,15 +10,13 @@ import ( secp256k1 "github.com/btcsuite/btcd/btcec" amino "github.com/tendermint/go-amino" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/libs/common" "golang.org/x/crypto/ripemd160" ) //------------------------------------- const ( - Secp256k1PrivKeyAminoRoute = "tendermint/PrivKeySecp256k1" - Secp256k1PubKeyAminoRoute = "tendermint/PubKeySecp256k1" - Secp256k1SignatureAminoRoute = "tendermint/SignatureSecp256k1" + Secp256k1PrivKeyAminoRoute = "tendermint/PrivKeySecp256k1" + Secp256k1PubKeyAminoRoute = "tendermint/PubKeySecp256k1" ) var cdc = amino.NewCodec() @@ -31,10 +29,6 @@ func init() { cdc.RegisterInterface((*crypto.PrivKey)(nil), nil) cdc.RegisterConcrete(PrivKeySecp256k1{}, Secp256k1PrivKeyAminoRoute, nil) - - cdc.RegisterInterface((*crypto.Signature)(nil), nil) - cdc.RegisterConcrete(SignatureSecp256k1{}, - Secp256k1SignatureAminoRoute, nil) } //------------------------------------- @@ -50,13 +44,13 @@ func (privKey PrivKeySecp256k1) Bytes() []byte { } // Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg. -func (privKey PrivKeySecp256k1) Sign(msg []byte) (crypto.Signature, error) { +func (privKey PrivKeySecp256k1) Sign(msg []byte) ([]byte, error) { priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) sig, err := priv.Sign(crypto.Sha256(msg)) if err != nil { return nil, err } - return SignatureSecp256k1(sig.Serialize()), nil + return sig.Serialize(), nil } // PubKey performs the point-scalar multiplication from the privKey on the @@ -142,13 +136,7 @@ func (pubKey PubKeySecp256k1) Bytes() []byte { return bz } -func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, interfaceSig crypto.Signature) bool { - // and assert same algorithm to sign and verify - sig, ok := interfaceSig.(SignatureSecp256k1) - if !ok { - return false - } - +func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig []byte) bool { pub, err := secp256k1.ParsePubKey(pubKey[:], secp256k1.S256()) if err != nil { return false @@ -170,38 +158,3 @@ func (pubKey PubKeySecp256k1) Equals(other crypto.PubKey) bool { } return false } - -//------------------------------------- - -var _ crypto.Signature = SignatureSecp256k1{} - -// SignatureSecp256k1 implements crypto.Signature -type SignatureSecp256k1 []byte - -func (sig SignatureSecp256k1) Bytes() []byte { - bz, err := cdc.MarshalBinaryBare(sig) - if err != nil { - panic(err) - } - return bz -} - -func (sig SignatureSecp256k1) IsZero() bool { return len(sig) == 0 } - -func (sig SignatureSecp256k1) String() string { - return fmt.Sprintf("/%X.../", common.Fingerprint(sig[:])) -} - -func (sig SignatureSecp256k1) Equals(other crypto.Signature) bool { - if otherSecp, ok := other.(SignatureSecp256k1); ok { - return subtle.ConstantTimeCompare(sig[:], otherSecp[:]) == 1 - } else { - return false - } -} - -func SignatureSecp256k1FromBytes(data []byte) crypto.Signature { - sig := make(SignatureSecp256k1, len(data)) - copy(sig[:], data) - return sig -} diff --git a/crypto/secp256k1/secpk256k1_test.go b/crypto/secp256k1/secpk256k1_test.go index 46a27b3e..0f0b5adc 100644 --- a/crypto/secp256k1/secpk256k1_test.go +++ b/crypto/secp256k1/secpk256k1_test.go @@ -59,9 +59,7 @@ func TestSignAndValidateSecp256k1(t *testing.T) { assert.True(t, pubKey.VerifyBytes(msg, sig)) // Mutate the signature, just one bit. - sigEd := sig.(secp256k1.SignatureSecp256k1) - sigEd[3] ^= byte(0x01) - sig = sigEd + sig[3] ^= byte(0x01) assert.False(t, pubKey.VerifyBytes(msg, sig)) } diff --git a/node/id.go b/node/id.go index 5100597c..d8e41eca 100644 --- a/node/id.go +++ b/node/id.go @@ -26,7 +26,7 @@ type NodeGreeting struct { type SignedNodeGreeting struct { NodeGreeting - Signature crypto.Signature + Signature []byte } func (pnid *PrivNodeID) SignGreeting() *SignedNodeGreeting { diff --git a/p2p/conn/secret_connection.go b/p2p/conn/secret_connection.go index 1b2b1da5..75199ee6 100644 --- a/p2p/conn/secret_connection.go +++ b/p2p/conn/secret_connection.go @@ -285,7 +285,7 @@ func sort32(foo, bar *[32]byte) (lo, hi *[32]byte) { return } -func signChallenge(challenge *[32]byte, locPrivKey crypto.PrivKey) (signature crypto.Signature) { +func signChallenge(challenge *[32]byte, locPrivKey crypto.PrivKey) (signature []byte) { signature, err := locPrivKey.Sign(challenge[:]) // TODO(ismail): let signChallenge return an error instead if err != nil { @@ -296,10 +296,10 @@ func signChallenge(challenge *[32]byte, locPrivKey crypto.PrivKey) (signature cr type authSigMessage struct { Key crypto.PubKey - Sig crypto.Signature + Sig []byte } -func shareAuthSignature(sc *SecretConnection, pubKey crypto.PubKey, signature crypto.Signature) (recvMsg authSigMessage, err error) { +func shareAuthSignature(sc *SecretConnection, pubKey crypto.PubKey, signature []byte) (recvMsg authSigMessage, err error) { // Send our info and receive theirs in tandem. var trs, _ = cmn.Parallel( diff --git a/p2p/pex/pex_reactor.go b/p2p/pex/pex_reactor.go index 4220dd42..288cb0d1 100644 --- a/p2p/pex/pex_reactor.go +++ b/p2p/pex/pex_reactor.go @@ -504,12 +504,7 @@ func (r *PEXReactor) checkSeeds() (numOnline int, netAddrs []*p2p.NetAddress, er // randomly dial seeds until we connect to one or exhaust them func (r *PEXReactor) dialSeeds() { - lSeeds := len(r.config.Seeds) - if lSeeds == 0 { - return - } - - perm := cmn.RandPerm(lSeeds) + perm := cmn.RandPerm(len(r.seedAddrs)) // perm := r.Switch.rng.Perm(lSeeds) for _, i := range perm { // dial a random seed diff --git a/privval/priv_validator.go b/privval/priv_validator.go index 5b056d8a..a81751a9 100644 --- a/privval/priv_validator.go +++ b/privval/priv_validator.go @@ -38,14 +38,14 @@ func voteToStep(vote *types.Vote) int8 { // to prevent double signing. // NOTE: the directory containing the pv.filePath must already exist. type FilePV struct { - Address types.Address `json:"address"` - PubKey crypto.PubKey `json:"pub_key"` - LastHeight int64 `json:"last_height"` - LastRound int `json:"last_round"` - LastStep int8 `json:"last_step"` - LastSignature crypto.Signature `json:"last_signature,omitempty"` // so we dont lose signatures XXX Why would we lose signatures? - LastSignBytes cmn.HexBytes `json:"last_signbytes,omitempty"` // so we dont lose signatures XXX Why would we lose signatures? - PrivKey crypto.PrivKey `json:"priv_key"` + Address types.Address `json:"address"` + PubKey crypto.PubKey `json:"pub_key"` + LastHeight int64 `json:"last_height"` + LastRound int `json:"last_round"` + LastStep int8 `json:"last_step"` + LastSignature []byte `json:"last_signature,omitempty"` // so we dont lose signatures XXX Why would we lose signatures? + LastSignBytes cmn.HexBytes `json:"last_signbytes,omitempty"` // so we dont lose signatures XXX Why would we lose signatures? + PrivKey crypto.PrivKey `json:"priv_key"` // For persistence. // Overloaded for testing. @@ -138,7 +138,7 @@ func (pv *FilePV) save() { // Reset resets all fields in the FilePV. // NOTE: Unsafe! func (pv *FilePV) Reset() { - var sig crypto.Signature + var sig []byte pv.LastHeight = 0 pv.LastRound = 0 pv.LastStep = 0 @@ -277,7 +277,7 @@ func (pv *FilePV) signProposal(chainID string, proposal *types.Proposal) error { // Persist height/round/step and signature func (pv *FilePV) saveSigned(height int64, round int, step int8, - signBytes []byte, sig crypto.Signature) { + signBytes []byte, sig []byte) { pv.LastHeight = height pv.LastRound = round diff --git a/privval/priv_validator_test.go b/privval/priv_validator_test.go index 127f5c1f..b4f9ddbc 100644 --- a/privval/priv_validator_test.go +++ b/privval/priv_validator_test.go @@ -10,7 +10,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/types" ) @@ -194,7 +193,7 @@ func TestDifferByTimestamp(t *testing.T) { // manipulate the timestamp. should get changed back proposal.Timestamp = proposal.Timestamp.Add(time.Millisecond) - var emptySig crypto.Signature + var emptySig []byte proposal.Signature = emptySig err = privVal.SignProposal("mychainid", proposal) assert.NoError(t, err, "expected no error on signing same proposal") @@ -218,7 +217,7 @@ func TestDifferByTimestamp(t *testing.T) { // manipulate the timestamp. should get changed back vote.Timestamp = vote.Timestamp.Add(time.Millisecond) - var emptySig crypto.Signature + var emptySig []byte vote.Signature = emptySig err = privVal.SignVote("mychainid", vote) assert.NoError(t, err, "expected no error on signing same vote") diff --git a/types/heartbeat.go b/types/heartbeat.go index cebe2864..151f1b0b 100644 --- a/types/heartbeat.go +++ b/types/heartbeat.go @@ -3,7 +3,6 @@ package types import ( "fmt" - "github.com/tendermint/tendermint/crypto" cmn "github.com/tendermint/tendermint/libs/common" ) @@ -13,12 +12,12 @@ import ( // json field tags because we always want the JSON // representation to be in its canonical form. type Heartbeat struct { - ValidatorAddress Address `json:"validator_address"` - ValidatorIndex int `json:"validator_index"` - Height int64 `json:"height"` - Round int `json:"round"` - Sequence int `json:"sequence"` - Signature crypto.Signature `json:"signature"` + ValidatorAddress Address `json:"validator_address"` + ValidatorIndex int `json:"validator_index"` + Height int64 `json:"height"` + Round int `json:"round"` + Sequence int `json:"sequence"` + Signature []byte `json:"signature"` } // SignBytes returns the Heartbeat bytes for signing. @@ -48,5 +47,6 @@ func (heartbeat *Heartbeat) String() string { return fmt.Sprintf("Heartbeat{%v:%X %v/%02d (%v) %v}", heartbeat.ValidatorIndex, cmn.Fingerprint(heartbeat.ValidatorAddress), - heartbeat.Height, heartbeat.Round, heartbeat.Sequence, heartbeat.Signature) + heartbeat.Height, heartbeat.Round, heartbeat.Sequence, + fmt.Sprintf("/%X.../", cmn.Fingerprint(heartbeat.Signature[:]))) } diff --git a/types/heartbeat_test.go b/types/heartbeat_test.go index f55c0bf3..ce9e4923 100644 --- a/types/heartbeat_test.go +++ b/types/heartbeat_test.go @@ -24,13 +24,13 @@ func TestHeartbeatString(t *testing.T) { require.Contains(t, nilHb.String(), "nil", "expecting a string and no panic") hb := &Heartbeat{ValidatorIndex: 1, Height: 11, Round: 2} - require.Equal(t, hb.String(), "Heartbeat{1:000000000000 11/02 (0) }") + require.Equal(t, "Heartbeat{1:000000000000 11/02 (0) /000000000000.../}", hb.String()) var key ed25519.PrivKeyEd25519 sig, err := key.Sign([]byte("Tendermint")) require.NoError(t, err) hb.Signature = sig - require.Equal(t, hb.String(), "Heartbeat{1:000000000000 11/02 (0) /FF41E371B9BF.../}") + require.Equal(t, "Heartbeat{1:000000000000 11/02 (0) /FF41E371B9BF.../}", hb.String()) } func TestHeartbeatWriteSignBytes(t *testing.T) { diff --git a/types/proposal.go b/types/proposal.go index 964ca0ca..325efa85 100644 --- a/types/proposal.go +++ b/types/proposal.go @@ -5,7 +5,7 @@ import ( "fmt" "time" - "github.com/tendermint/tendermint/crypto" + cmn "github.com/tendermint/tendermint/libs/common" ) var ( @@ -19,13 +19,13 @@ var ( // to be considered valid. It may depend on votes from a previous round, // a so-called Proof-of-Lock (POL) round, as noted in the POLRound and POLBlockID. type Proposal struct { - Height int64 `json:"height"` - Round int `json:"round"` - Timestamp time.Time `json:"timestamp"` - BlockPartsHeader PartSetHeader `json:"block_parts_header"` - POLRound int `json:"pol_round"` // -1 if null. - POLBlockID BlockID `json:"pol_block_id"` // zero if null. - Signature crypto.Signature `json:"signature"` + Height int64 `json:"height"` + Round int `json:"round"` + Timestamp time.Time `json:"timestamp"` + BlockPartsHeader PartSetHeader `json:"block_parts_header"` + POLRound int `json:"pol_round"` // -1 if null. + POLBlockID BlockID `json:"pol_block_id"` // zero if null. + Signature []byte `json:"signature"` } // NewProposal returns a new Proposal. @@ -43,9 +43,10 @@ func NewProposal(height int64, round int, blockPartsHeader PartSetHeader, polRou // String returns a string representation of the Proposal. func (p *Proposal) String() string { - return fmt.Sprintf("Proposal{%v/%v %v (%v,%v) %v @ %s}", + return fmt.Sprintf("Proposal{%v/%v %v (%v,%v) %X @ %s}", p.Height, p.Round, p.BlockPartsHeader, p.POLRound, - p.POLBlockID, p.Signature, CanonicalTime(p.Timestamp)) + p.POLBlockID, + cmn.Fingerprint(p.Signature), CanonicalTime(p.Timestamp)) } // SignBytes returns the Proposal bytes for signing diff --git a/types/proposal_test.go b/types/proposal_test.go index 8aef870f..7396fb76 100644 --- a/types/proposal_test.go +++ b/types/proposal_test.go @@ -39,7 +39,7 @@ func TestProposalSignable(t *testing.T) { func TestProposalString(t *testing.T) { str := testProposal.String() - expected := `Proposal{12345/23456 111:626C6F636B70 (-1,:0:000000000000) @ 2018-02-11T07:09:22.765Z}` + expected := `Proposal{12345/23456 111:626C6F636B70 (-1,:0:000000000000) 000000000000 @ 2018-02-11T07:09:22.765Z}` if str != expected { t.Errorf("Got unexpected string for Proposal. Expected:\n%v\nGot:\n%v", expected, str) } diff --git a/types/protobuf_test.go b/types/protobuf_test.go index b1c01290..8c1c39f1 100644 --- a/types/protobuf_test.go +++ b/types/protobuf_test.go @@ -113,7 +113,7 @@ type pubKeyEddie struct{} func (pubKeyEddie) Address() Address { return []byte{} } func (pubKeyEddie) Bytes() []byte { return []byte{} } -func (pubKeyEddie) VerifyBytes(msg []byte, sig crypto.Signature) bool { return false } +func (pubKeyEddie) VerifyBytes(msg []byte, sig []byte) bool { return false } func (pubKeyEddie) Equals(crypto.PubKey) bool { return false } func TestABCIValidatorFromPubKeyAndPower(t *testing.T) { diff --git a/types/vote.go b/types/vote.go index ed4ebd73..9a6180d7 100644 --- a/types/vote.go +++ b/types/vote.go @@ -61,14 +61,14 @@ type Address = cmn.HexBytes // Represents a prevote, precommit, or commit vote from validators for consensus. type Vote struct { - ValidatorAddress Address `json:"validator_address"` - ValidatorIndex int `json:"validator_index"` - Height int64 `json:"height"` - Round int `json:"round"` - Timestamp time.Time `json:"timestamp"` - Type byte `json:"type"` - BlockID BlockID `json:"block_id"` // zero if vote is nil. - Signature crypto.Signature `json:"signature"` + ValidatorAddress Address `json:"validator_address"` + ValidatorIndex int `json:"validator_index"` + Height int64 `json:"height"` + Round int `json:"round"` + Timestamp time.Time `json:"timestamp"` + Type byte `json:"type"` + BlockID BlockID `json:"block_id"` // zero if vote is nil. + Signature []byte `json:"signature"` } func (vote *Vote) SignBytes(chainID string) []byte { @@ -98,10 +98,11 @@ func (vote *Vote) String() string { cmn.PanicSanity("Unknown vote type") } - return fmt.Sprintf("Vote{%v:%X %v/%02d/%v(%v) %X %v @ %s}", + return fmt.Sprintf("Vote{%v:%X %v/%02d/%v(%v) %X %X @ %s}", vote.ValidatorIndex, cmn.Fingerprint(vote.ValidatorAddress), vote.Height, vote.Round, vote.Type, typeString, - cmn.Fingerprint(vote.BlockID.Hash), vote.Signature, + cmn.Fingerprint(vote.BlockID.Hash), + cmn.Fingerprint(vote.Signature), CanonicalTime(vote.Timestamp)) } diff --git a/types/vote_set.go b/types/vote_set.go index 66e89bf6..dbcacbbd 100644 --- a/types/vote_set.go +++ b/types/vote_set.go @@ -179,7 +179,7 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) { // If we already know of this vote, return false. if existing, ok := voteSet.getVote(valIndex, blockKey); ok { - if existing.Signature.Equals(vote.Signature) { + if bytes.Equal(existing.Signature, vote.Signature) { return false, nil // duplicate } return false, errors.Wrapf(ErrVoteNonDeterministicSignature, "Existing vote: %v; New vote: %v", existing, vote) diff --git a/version/version.go b/version/version.go index 85b1f191..04880cfe 100644 --- a/version/version.go +++ b/version/version.go @@ -3,14 +3,14 @@ package version // Version components const ( Maj = "0" - Min = "22" - Fix = "8" + Min = "23" + Fix = "0" ) var ( // Version is the current version of Tendermint // Must be a string because scripts like dist.sh read this file. - Version = "0.22.8" + Version = "0.23.0" // GitCommit is the current HEAD set using ldflags. GitCommit string