complete implementation

This commit is contained in:
Juan Leni
2019-04-03 14:15:50 +02:00
parent fb31eefe50
commit defade8c6c
4 changed files with 87 additions and 56 deletions
+1
View File
@@ -214,6 +214,7 @@ type BrokenSignerDialerEndpoint struct {
*SignerDialerEndpoint
}
// nolint
func (ss *BrokenSignerDialerEndpoint) writeMessage(msg RemoteSignerMsg) (err error) {
_, err = cdc.MarshalBinaryLengthPrefixedWriter(ss.conn, PubKeyResponse{})
return
+23 -38
View File
@@ -7,7 +7,6 @@ import (
"sync"
"time"
"github.com/tendermint/tendermint/crypto"
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/types"
@@ -32,11 +31,8 @@ func SignerServiceEndpointConnRetries(retries int) SignerServiceEndpointOption {
}
// TODO(jleni): Create a common type for a signerEndpoint (common for both listener/dialer)
// getConnection
// AcceptNewConnection
// read
// write
// close
// SignerDialerEndpoint dials using its dialer and responds to any
// signature requests using its privVal.
@@ -95,17 +91,34 @@ func (ss *SignerDialerEndpoint) OnStart() error {
// OnStop implements cmn.Service.
func (ss *SignerDialerEndpoint) OnStop() {
// Trigger a stop and wait
ss.Logger.Debug("SignerDialerEndpoint: OnStop calling Close")
_ = ss.Close()
}
// IsConnected indicates if there is an active connection
func (ss *SignerDialerEndpoint) IsConnected() bool {
ss.mtx.Lock()
defer ss.mtx.Unlock()
return ss.isConnected()
}
// Close closes the underlying net.Conn.
func (ss *SignerDialerEndpoint) Close() error {
ss.mtx.Lock()
defer ss.mtx.Unlock()
close(ss.stopCh)
<-ss.stoppedCh
ss.Logger.Debug("SignerDialerEndpoint: Close")
if ss.conn != nil {
if err := ss.conn.Close(); err != nil {
ss.Logger.Error("OnStop", "err", cmn.ErrorWrap(err, "closing listener failed"))
ss.Logger.Debug("Reset conn")
ss.conn = nil
}
}
return nil
}
func (ss *SignerDialerEndpoint) serviceLoop() {
@@ -209,7 +222,7 @@ func (ss *SignerDialerEndpoint) handleRequest() {
return
}
res, err := handleMessage(req, ss.chainID, ss.privVal)
res, err := HandleValidatorRequest(req, ss.chainID, ss.privVal)
if err != nil {
// only log the error; we'll reply with an error in res
@@ -223,35 +236,7 @@ func (ss *SignerDialerEndpoint) handleRequest() {
}
}
func handleMessage(req RemoteSignerMsg, chainID string, privVal types.PrivValidator) (RemoteSignerMsg, error) {
var res RemoteSignerMsg
var err error
switch r := req.(type) {
case *PubKeyRequest:
var p crypto.PubKey
p = privVal.GetPubKey()
res = &PubKeyResponse{p, nil}
case *SignVoteRequest:
err = privVal.SignVote(chainID, r.Vote)
if err != nil {
res = &SignedVoteResponse{nil, &RemoteSignerError{0, err.Error()}}
} else {
res = &SignedVoteResponse{r.Vote, nil}
}
case *SignProposalRequest:
err = privVal.SignProposal(chainID, r.Proposal)
if err != nil {
res = &SignedProposalResponse{nil, &RemoteSignerError{0, err.Error()}}
} else {
res = &SignedProposalResponse{r.Proposal, nil}
}
default:
err = fmt.Errorf("unknown msg: %v", r)
}
return res, err
// IsConnected indicates if there is an active connection
func (ve *SignerDialerEndpoint) isConnected() bool {
return ve.IsRunning() && ve.conn != nil
}
+22 -18
View File
@@ -42,7 +42,7 @@ func NewSignerListenerEndpoint(logger log.Logger, listener net.Listener) *Signer
func (ve *SignerListenerEndpoint) OnStart() error {
ve.Logger.Debug("SignerListenerEndpoint: OnStart")
err := ve.AcceptNewConnection()
err := ve.acceptNewConnection()
if err != nil {
ve.Logger.Error("OnStart", "err", err)
return err
@@ -67,8 +67,11 @@ func (ve *SignerListenerEndpoint) IsConnected() bool {
// WaitForConnection waits maxWait for a connection or returns a timeout error
func (ve *SignerListenerEndpoint) WaitForConnection(maxWait time.Duration) error {
// TODO(jleni): complete this
return nil
ve.mtx.Lock()
defer ve.mtx.Unlock()
// TODO(jleni): Pass maxwait through
return ve.ensureConnection()
}
// Close closes the underlying net.Conn.
@@ -96,18 +99,14 @@ func (ve *SignerListenerEndpoint) SendRequest(request RemoteSignerMsg) (RemoteSi
defer ve.mtx.Unlock()
ve.Logger.Debug("SignerListenerEndpoint: Send request", "connected", ve.isConnected())
if !ve.isConnected() {
ve.Logger.Info("SignerListenerEndpoint: Reconnecting")
err := ve.AcceptNewConnection()
if err != nil {
return nil, cmn.ErrorWrap(ErrListenerNoConnection, "could not reconnect")
}
err := ve.ensureConnection()
if err != nil {
return nil, err
}
ve.Logger.Debug("Send request. Write")
err := ve.writeMessage(request)
err = ve.writeMessage(request)
if err != nil {
return nil, err
}
@@ -125,8 +124,17 @@ func (ve *SignerListenerEndpoint) SendRequest(request RemoteSignerMsg) (RemoteSi
// IsConnected indicates if there is an active connection
func (ve *SignerListenerEndpoint) isConnected() bool {
// return ve.IsRunning() && ve.conn != nil
return ve.conn != nil
return ve.IsRunning() && ve.conn != nil
}
func (ve *SignerListenerEndpoint) ensureConnection() error {
if !ve.isConnected() {
err := ve.acceptNewConnection()
if err != nil {
return cmn.ErrorWrap(ErrListenerNoConnection, "could not reconnect")
}
}
return nil
}
// dropConnection closes the current connection but does not touch the listening socket
@@ -193,11 +201,7 @@ func (ve *SignerListenerEndpoint) writeMessage(msg RemoteSignerMsg) (err error)
return
}
// AcceptNewConnection waits to accept a new connection.
func (ve *SignerListenerEndpoint) AcceptNewConnection() error {
ve.mtx.Lock()
defer ve.mtx.Unlock()
func (ve *SignerListenerEndpoint) acceptNewConnection() error {
ve.Logger.Debug("SignerListenerEndpoint: AcceptNewConnection")
if !ve.IsRunning() || ve.listener == nil {
+41
View File
@@ -0,0 +1,41 @@
package privval
import (
"fmt"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/types"
)
func HandleValidatorRequest(req RemoteSignerMsg, chainID string, privVal types.PrivValidator) (RemoteSignerMsg, error) {
var res RemoteSignerMsg
var err error
switch r := req.(type) {
case *PubKeyRequest:
var p crypto.PubKey
p = privVal.GetPubKey()
res = &PubKeyResponse{p, nil}
case *SignVoteRequest:
err = privVal.SignVote(chainID, r.Vote)
if err != nil {
res = &SignedVoteResponse{nil, &RemoteSignerError{0, err.Error()}}
} else {
res = &SignedVoteResponse{r.Vote, nil}
}
case *SignProposalRequest:
err = privVal.SignProposal(chainID, r.Proposal)
if err != nil {
res = &SignedProposalResponse{nil, &RemoteSignerError{0, err.Error()}}
} else {
res = &SignedProposalResponse{r.Proposal, nil}
}
default:
err = fmt.Errorf("unknown msg: %v", r)
}
return res, err
}