Skip to content

Commit 940e682

Browse files
authoredJul 22, 2020
privval: if remote signer errors, don't retry (#5140)
Closes #5112

File tree

4 files changed

+26
-27
lines changed

4 files changed

+26
-27
lines changed
 

‎privval/errors.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
)
77

8+
// EndpointTimeoutError occurs when endpoint times out.
89
type EndpointTimeoutError struct{}
910

1011
// Implement the net.Error interface.
@@ -14,15 +15,15 @@ func (e EndpointTimeoutError) Temporary() bool { return true }
1415

1516
// Socket errors.
1617
var (
17-
ErrUnexpectedResponse = errors.New("received unexpected response")
18-
ErrNoConnection = errors.New("endpoint is not connected")
1918
ErrConnectionTimeout = EndpointTimeoutError{}
20-
21-
ErrReadTimeout = errors.New("endpoint read timed out")
22-
ErrWriteTimeout = errors.New("endpoint write timed out")
19+
ErrNoConnection = errors.New("endpoint is not connected")
20+
ErrReadTimeout = errors.New("endpoint read timed out")
21+
ErrUnexpectedResponse = errors.New("empty response")
22+
ErrWriteTimeout = errors.New("endpoint write timed out")
2323
)
2424

25-
// RemoteSignerError allows (remote) validators to include meaningful error descriptions in their reply.
25+
// RemoteSignerError allows (remote) validators to include meaningful error
26+
// descriptions in their reply.
2627
type RemoteSignerError struct {
2728
// TODO(ismail): create an enum of known errors
2829
Code int

‎privval/retry_signer_client.go

+12
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ func (sc *RetrySignerClient) GetPubKey() (crypto.PubKey, error) {
5454
if err == nil {
5555
return pk, nil
5656
}
57+
// If remote signer errors, we don't retry.
58+
if _, ok := err.(*RemoteSignerError); ok {
59+
return nil, err
60+
}
5761
time.Sleep(sc.timeout)
5862
}
5963
return nil, fmt.Errorf("exhausted all attempts to get pubkey: %w", err)
@@ -66,6 +70,10 @@ func (sc *RetrySignerClient) SignVote(chainID string, vote *tmproto.Vote) error
6670
if err == nil {
6771
return nil
6872
}
73+
// If remote signer errors, we don't retry.
74+
if _, ok := err.(*RemoteSignerError); ok {
75+
return err
76+
}
6977
time.Sleep(sc.timeout)
7078
}
7179
return fmt.Errorf("exhausted all attempts to sign vote: %w", err)
@@ -78,6 +86,10 @@ func (sc *RetrySignerClient) SignProposal(chainID string, proposal *tmproto.Prop
7886
if err == nil {
7987
return nil
8088
}
89+
// If remote signer errors, we don't retry.
90+
if _, ok := err.(*RemoteSignerError); ok {
91+
return err
92+
}
8193
time.Sleep(sc.timeout)
8294
}
8395
return fmt.Errorf("exhausted all attempts to sign proposal: %w", err)

‎privval/signer_client.go

+6-20
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package privval
22

33
import (
4-
"errors"
54
"fmt"
65
"time"
76

@@ -53,15 +52,13 @@ func (sc *SignerClient) WaitForConnection(maxWait time.Duration) error {
5352
// Ping sends a ping request to the remote signer
5453
func (sc *SignerClient) Ping() error {
5554
response, err := sc.endpoint.SendRequest(mustWrapMsg(&privvalproto.PingRequest{}))
56-
5755
if err != nil {
5856
sc.endpoint.Logger.Error("SignerClient::Ping", "err", err)
5957
return nil
6058
}
6159

6260
pb := response.GetPingResponse()
6361
if pb == nil {
64-
sc.endpoint.Logger.Error("SignerClient::Ping", "err", "response != PingResponse")
6562
return err
6663
}
6764

@@ -73,22 +70,18 @@ func (sc *SignerClient) Ping() error {
7370
func (sc *SignerClient) GetPubKey() (crypto.PubKey, error) {
7471
response, err := sc.endpoint.SendRequest(mustWrapMsg(&privvalproto.PubKeyRequest{}))
7572
if err != nil {
76-
sc.endpoint.Logger.Error("SignerClient::GetPubKey", "err", err)
7773
return nil, fmt.Errorf("send: %w", err)
7874
}
7975

80-
pubKeyResp := response.GetPubKeyResponse()
81-
if pubKeyResp == nil {
82-
sc.endpoint.Logger.Error("SignerClient::GetPubKey", "err", "response != PubKeyResponse")
83-
return nil, fmt.Errorf("unexpected response type %T", response)
76+
resp := response.GetPubKeyResponse()
77+
if resp == nil {
78+
return nil, ErrUnexpectedResponse
8479
}
85-
86-
if pubKeyResp.Error != nil {
87-
sc.endpoint.Logger.Error("failed to get private validator's public key", "err", pubKeyResp.Error)
88-
return nil, fmt.Errorf("remote error: %w", errors.New(pubKeyResp.Error.Description))
80+
if resp.Error != nil {
81+
return nil, &RemoteSignerError{Code: int(resp.Error.Code), Description: resp.Error.Description}
8982
}
9083

91-
pk, err := cryptoenc.PubKeyFromProto(*pubKeyResp.PubKey)
84+
pk, err := cryptoenc.PubKeyFromProto(*resp.PubKey)
9285
if err != nil {
9386
return nil, err
9487
}
@@ -98,19 +91,15 @@ func (sc *SignerClient) GetPubKey() (crypto.PubKey, error) {
9891

9992
// SignVote requests a remote signer to sign a vote
10093
func (sc *SignerClient) SignVote(chainID string, vote *tmproto.Vote) error {
101-
10294
response, err := sc.endpoint.SendRequest(mustWrapMsg(&privvalproto.SignVoteRequest{Vote: vote}))
10395
if err != nil {
104-
sc.endpoint.Logger.Error("SignerClient::SignVote", "err", err)
10596
return err
10697
}
10798

10899
resp := response.GetSignedVoteResponse()
109100
if resp == nil {
110-
sc.endpoint.Logger.Error("SignerClient::GetPubKey", "err", "response != SignedVoteResponse")
111101
return ErrUnexpectedResponse
112102
}
113-
114103
if resp.Error != nil {
115104
return &RemoteSignerError{Code: int(resp.Error.Code), Description: resp.Error.Description}
116105
}
@@ -122,16 +111,13 @@ func (sc *SignerClient) SignVote(chainID string, vote *tmproto.Vote) error {
122111

123112
// SignProposal requests a remote signer to sign a proposal
124113
func (sc *SignerClient) SignProposal(chainID string, proposal *tmproto.Proposal) error {
125-
126114
response, err := sc.endpoint.SendRequest(mustWrapMsg(&privvalproto.SignProposalRequest{Proposal: *proposal}))
127115
if err != nil {
128-
sc.endpoint.Logger.Error("SignerClient::SignProposal", "err", err)
129116
return err
130117
}
131118

132119
resp := response.GetSignedProposalResponse()
133120
if resp == nil {
134-
sc.endpoint.Logger.Error("SignerClient::SignProposal", "err", "response != SignedProposalResponse")
135121
return ErrUnexpectedResponse
136122
}
137123
if resp.Error != nil {

‎privval/signer_client_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,6 @@ func TestSignerUnexpectedResponse(t *testing.T) {
433433
want := &types.Vote{Timestamp: ts, Type: tmproto.PrecommitType}
434434

435435
e := tc.signerClient.SignVote(tc.chainID, want.ToProto())
436-
assert.EqualError(t, e, "received unexpected response")
436+
assert.EqualError(t, e, "empty response")
437437
}
438438
}

0 commit comments

Comments
 (0)
Please sign in to comment.