diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a2e67d83..603b0b639 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Changelog ## v0.3 -* The voter to be elected has been changed so that it can be determined in the n-1 block +* The voter to be elected has been changed so that it can be determined in the n-1 block from the one determined by the n-2 block. * A BLS signature library was added. The ability to use the BLS signature library will be added in the next version. * When distributing rewards in Cosmos-SDK, some ABCIs have been modified to distribute the voting power of elected voters. @@ -14,14 +14,12 @@ from the one determined by the n-2 block. - P2P Protocol - [abci] [\#100](https://github.com/line/tendermint/pull/100) Add `voters_hash` field, which is needed for verification of a block header - - [abci] [\#102](https://github.com/line/tendermint/pull/102) Add voting power in `VoterInfo` of abci + - [abci] [\#102](https://github.com/line/tendermint/pull/102) Add voting power in `VoterInfo` of abci ### FEATURES: - [BLS] [\#81](https://github.com/line/tendermint/issues/81) Modify to generate at the same time as Ed25519 key generation - [lite] [\#100](https://github.com/line/tendermint/pull/100) Lite calls `Genesis()` rpc when it starts up - - ## v0.2 * Changed from the consensus way which the entire validator agrees to a part of the validators is elected as a voter to consensus. The selected validator is called `voter` diff --git a/CHANGELOG_OF_TENDERMINT.md b/CHANGELOG_OF_TENDERMINT.md index c588224be..79064f90f 100644 --- a/CHANGELOG_OF_TENDERMINT.md +++ b/CHANGELOG_OF_TENDERMINT.md @@ -1,5 +1,14 @@ # Changelog +## v0.33.7 + +*August 4, 2020* + +### BUG FIXES: + +- [go] Build release binary using Go 1.14.4, to avoid halt caused by Go 1.14.1 (https://github.com/golang/go/issues/38223) +- [privval] [\#5140](https://github.com/tendermint/tendermint/pull/5140) `RemoteSignerError` from remote signers are no longer retried (@melekes) + ## v0.33.6 *July 2, 2020* @@ -10,12 +19,12 @@ This security release fixes: Tendermint 0.33.0 and above allow block proposers to include signatures for the wrong block. This may happen naturally if you start a network, have it run for -some time and restart it **without changing the chainID**. (It is a -[misconfiguration](https://docs.tendermint.com/master/tendermint-core/using-tendermint.html) -to reuse chainIDs.) Correct block proposers will accidentally include signatures -for the wrong block if they see these signatures, and then commits won't validate, -making all proposed blocks invalid. A malicious validator (even with a minimal -amount of stake) can use this vulnerability to completely halt the network. +some time and restart it **without changing the chainID**. (It is a +[misconfiguration](https://docs.tendermint.com/master/tendermint-core/using-tendermint.html) +to reuse chainIDs.) Correct block proposers will accidentally include signatures +for the wrong block if they see these signatures, and then commits won't validate, +making all proposed blocks invalid. A malicious validator (even with a minimal +amount of stake) can use this vulnerability to completely halt the network. Tendermint 0.33.6 checks all the signatures are for the block with +2/3 majority before creating a commit. @@ -33,7 +42,7 @@ lot of invalid data. _This was already true of blocks, since they could include invalid txs filled with garbage, but in that case the application knew that they are invalid and could punish the proposer. But since applications didn't--and don't-- -verify commit signatures directly (they trust Tendermint to do that), +verify commit signatures directly (they trust Tendermint to do that), they won't be able to detect it._ This can impact incentivization logic in the application that depends on the @@ -45,7 +54,7 @@ their signatures. There may be other tricks that can be played because of this. Tendermint 0.33.6 verifies all the signatures during block execution. -_Please note that the light client does not check nil votes and exits as soon +_Please note that the light client does not check nil votes and exits as soon as 2/3+ of the signatures are checked._ **All clients are recommended to upgrade.** diff --git a/privval/errors.go b/privval/errors.go index 9f151f11d..297d5dca2 100644 --- a/privval/errors.go +++ b/privval/errors.go @@ -1,9 +1,11 @@ package privval import ( + "errors" "fmt" ) +// EndpointTimeoutError occurs when endpoint times out. type EndpointTimeoutError struct{} // Implement the net.Error interface. @@ -13,15 +15,15 @@ func (e EndpointTimeoutError) Temporary() bool { return true } // Socket errors. var ( - ErrUnexpectedResponse = fmt.Errorf("received unexpected response") - ErrNoConnection = fmt.Errorf("endpoint is not connected") ErrConnectionTimeout = EndpointTimeoutError{} - - ErrReadTimeout = fmt.Errorf("endpoint read timed out") - ErrWriteTimeout = fmt.Errorf("endpoint write timed out") + ErrNoConnection = errors.New("endpoint is not connected") + ErrReadTimeout = errors.New("endpoint read timed out") + ErrUnexpectedResponse = errors.New("empty response") + ErrWriteTimeout = errors.New("endpoint write timed out") ) -// RemoteSignerError allows (remote) validators to include meaningful error descriptions in their reply. +// RemoteSignerError allows (remote) validators to include meaningful error +// descriptions in their reply. type RemoteSignerError struct { // TODO(ismail): create an enum of known errors Code int diff --git a/privval/retry_signer_client.go b/privval/retry_signer_client.go index 8347b14f5..2ddef2a07 100644 --- a/privval/retry_signer_client.go +++ b/privval/retry_signer_client.go @@ -53,6 +53,10 @@ func (sc *RetrySignerClient) GetPubKey() (crypto.PubKey, error) { if err == nil { return pk, nil } + // If remote signer errors, we don't retry. + if _, ok := err.(*RemoteSignerError); ok { + return nil, err + } time.Sleep(sc.timeout) } return nil, fmt.Errorf("exhausted all attempts to get pubkey: %w", err) @@ -65,6 +69,10 @@ func (sc *RetrySignerClient) SignVote(chainID string, vote *types.Vote) error { if err == nil { return nil } + // If remote signer errors, we don't retry. + if _, ok := err.(*RemoteSignerError); ok { + return err + } time.Sleep(sc.timeout) } return fmt.Errorf("exhausted all attempts to sign vote: %w", err) @@ -77,6 +85,10 @@ func (sc *RetrySignerClient) SignProposal(chainID string, proposal *types.Propos if err == nil { return nil } + // If remote signer errors, we don't retry. + if _, ok := err.(*RemoteSignerError); ok { + return err + } time.Sleep(sc.timeout) } return fmt.Errorf("exhausted all attempts to sign proposal: %w", err) diff --git a/privval/signer_client.go b/privval/signer_client.go index 1db6b4623..34f221526 100644 --- a/privval/signer_client.go +++ b/privval/signer_client.go @@ -1,7 +1,6 @@ package privval import ( - "fmt" "time" "github.com/pkg/errors" @@ -51,7 +50,6 @@ func (sc *SignerClient) WaitForConnection(maxWait time.Duration) error { // Ping sends a ping request to the remote signer func (sc *SignerClient) Ping() error { response, err := sc.endpoint.SendRequest(&PingRequest{}) - if err != nil { sc.endpoint.Logger.Error("SignerClient::Ping", "err", err) return nil @@ -59,8 +57,7 @@ func (sc *SignerClient) Ping() error { _, ok := response.(*PingResponse) if !ok { - sc.endpoint.Logger.Error("SignerClient::Ping", "err", "response != PingResponse") - return err + return ErrUnexpectedResponse } return nil @@ -71,19 +68,16 @@ func (sc *SignerClient) Ping() error { func (sc *SignerClient) GetPubKey() (crypto.PubKey, error) { response, err := sc.endpoint.SendRequest(&PubKeyRequest{}) if err != nil { - sc.endpoint.Logger.Error("SignerClient::GetPubKey", "err", err) - return nil, errors.Wrap(err, "send") + return nil, err } pubKeyResp, ok := response.(*PubKeyResponse) if !ok { - sc.endpoint.Logger.Error("SignerClient::GetPubKey", "err", "response != PubKeyResponse") - return nil, errors.Errorf("unexpected response type %T", response) + return nil, ErrUnexpectedResponse } if pubKeyResp.Error != nil { - sc.endpoint.Logger.Error("failed to get private validator's public key", "err", pubKeyResp.Error) - return nil, fmt.Errorf("remote error: %w", pubKeyResp.Error) + return nil, pubKeyResp.Error } return pubKeyResp.PubKey, nil @@ -93,16 +87,13 @@ func (sc *SignerClient) GetPubKey() (crypto.PubKey, error) { func (sc *SignerClient) SignVote(chainID string, vote *types.Vote) error { response, err := sc.endpoint.SendRequest(&SignVoteRequest{Vote: vote}) if err != nil { - sc.endpoint.Logger.Error("SignerClient::SignVote", "err", err) return err } resp, ok := response.(*SignedVoteResponse) if !ok { - sc.endpoint.Logger.Error("SignerClient::GetPubKey", "err", "response != SignedVoteResponse") return ErrUnexpectedResponse } - if resp.Error != nil { return resp.Error } @@ -115,13 +106,11 @@ func (sc *SignerClient) SignVote(chainID string, vote *types.Vote) error { func (sc *SignerClient) SignProposal(chainID string, proposal *types.Proposal) error { response, err := sc.endpoint.SendRequest(&SignProposalRequest{Proposal: proposal}) if err != nil { - sc.endpoint.Logger.Error("SignerClient::SignProposal", "err", err) return err } resp, ok := response.(*SignedProposalResponse) if !ok { - sc.endpoint.Logger.Error("SignerClient::SignProposal", "err", "response != SignedProposalResponse") return ErrUnexpectedResponse } if resp.Error != nil { diff --git a/privval/signer_client_test.go b/privval/signer_client_test.go index 74c9d43a3..ebc7ac2cf 100644 --- a/privval/signer_client_test.go +++ b/privval/signer_client_test.go @@ -271,6 +271,6 @@ func TestSignerUnexpectedResponse(t *testing.T) { want := &types.Vote{Timestamp: ts, Type: types.PrecommitType} e := tc.signerClient.SignVote(tc.chainID, want) - assert.EqualError(t, e, "received unexpected response") + assert.EqualError(t, e, "empty response") } } diff --git a/version/version.go b/version/version.go index 1559e6dff..df3262f07 100644 --- a/version/version.go +++ b/version/version.go @@ -21,7 +21,7 @@ const ( // XXX: Don't change the name of this variable or you will break // automation :) - TMCoreSemVer = "0.33.6" + TMCoreSemVer = "0.33.7" // LINECoreSemVer is the current version of LINE Tendermint Core. LINECoreSemVer = "0.3"