@ -18,9 +18,9 @@ import (
)
)
const (
const (
c onnDeadlineSeconds = 3
dialRetryIntervalSeconds = 1
dialRetryMax = 10
defaultC onnDeadlineSeconds = 3
defaultD ialRetryIntervalSeconds = 1
defaultD ialRetryMax = 10
)
)
// Socket errors.
// Socket errors.
@ -29,70 +29,89 @@ var (
)
)
var (
var (
connDeadline = time . Second * c onnDeadlineSeconds
connDeadline = time . Second * defaultC onnDeadlineSeconds
)
)
//-----------------------------------------------------------------
// SocketClientOption sets an optional parameter on the SocketClient.
type SocketClientOption func ( * socketClient )
var _ types . PrivValidator2 = ( * PrivValidatorSocketClient ) ( nil )
// SocketClientTimeout sets the timeout for connecting to the external socket
// address.
func SocketClientTimeout ( timeout time . Duration ) SocketClientOption {
return func ( sc * socketClient ) { sc . connectTimeout = timeout }
}
// PrivValidatorSocketClient implements PrivValidator.
// It uses a socket to request signatures.
type PrivValidatorSocketClient struct {
// socketClient implements PrivValidator, it uses a socket to request signatures
// from an external proces s.
type s ocketClient struct {
cmn . BaseService
cmn . BaseService
conn net . Conn
conn net . Conn
privKey * crypto . PrivKeyEd25519
privKey * crypto . PrivKeyEd25519
ID types . ValidatorID
SocketAddress string
addr string
connectTimeout time . Duration
}
}
// NewPrivValidatorSocketClient returns an instance of
// PrivValidatorSocketClient.
func NewPrivValidatorSocketClient (
// Check that socketClient implements PrivValidator2.
var _ types . PrivValidator2 = ( * socketClient ) ( nil )
// NewsocketClient returns an instance of socketClient.
func NewSocketClient (
logger log . Logger ,
logger log . Logger ,
socketAddr string ,
socketAddr string ,
privKey * crypto . PrivKeyEd25519 ,
privKey * crypto . PrivKeyEd25519 ,
) * PrivValidatorSocketClient {
pvsc := & PrivValidatorSocketClient {
SocketAddress : socketAddr ,
privKey : privKey ,
) * socketClient {
sc := & socketClient {
addr : socketAddr ,
connectTimeout : time . Second * defaultConnDeadlineSeconds ,
privKey : privKey ,
}
}
pv sc. BaseService = * cmn . NewBaseService ( logger , "privValidatorS ocketClient" , pv sc)
sc . BaseService = * cmn . NewBaseService ( logger , "privValidators ocketClient" , sc )
return pv sc
return sc
}
}
// OnStart implements cmn.Service.
// OnStart implements cmn.Service.
func ( pv sc * PrivValidatorS ocketClient) OnStart ( ) error {
if err := pv sc. BaseService . OnStart ( ) ; err != nil {
func ( sc * s ocketClient) OnStart ( ) error {
if err := sc . BaseService . OnStart ( ) ; err != nil {
return err
return err
}
}
conn , err := pv sc. connect ( )
conn , err := sc . connect ( )
if err != nil {
if err != nil {
return err
return err
}
}
pv sc. conn = conn
sc . conn = conn
return nil
return nil
}
}
// OnStop implements cmn.Service.
// OnStop implements cmn.Service.
func ( pv sc * PrivValidatorS ocketClient) OnStop ( ) {
pv sc. BaseService . OnStop ( )
func ( sc * s ocketClient) OnStop ( ) {
sc . BaseService . OnStop ( )
if pv sc. conn != nil {
pv sc. conn . Close ( )
if sc . conn != nil {
sc . conn . Close ( )
}
}
}
}
// GetAddress implements PrivValidator.
// TODO(xla): Remove when PrivValidator2 replaced PrivValidator.
func ( sc * socketClient ) GetAddress ( ) types . Address {
addr , err := sc . Address ( )
if err != nil {
panic ( err )
}
return addr
}
// Address is an alias for PubKey().Address().
// Address is an alias for PubKey().Address().
func ( pvsc * PrivValidatorSocketClient ) Address ( ) ( cmn . HexBytes , error ) {
p , err := pvsc . PubKey ( )
func ( sc * s ocketClient) Address ( ) ( cmn . HexBytes , error ) {
p , err := sc . PubKey ( )
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
@ -100,14 +119,25 @@ func (pvsc *PrivValidatorSocketClient) Address() (cmn.HexBytes, error) {
return p . Address ( ) , nil
return p . Address ( ) , nil
}
}
// PubKey implements PrivValidator.
func ( pvsc * PrivValidatorSocketClient ) PubKey ( ) ( crypto . PubKey , error ) {
err := writeMsg ( pvsc . conn , & PubKeyMsg { } )
// GetPubKey implements PrivValidator.
// TODO(xla): Remove when PrivValidator2 replaced PrivValidator.
func ( sc * socketClient ) GetPubKey ( ) crypto . PubKey {
pubKey , err := sc . PubKey ( )
if err != nil {
panic ( err )
}
return pubKey
}
// PubKey implements PrivValidator2.
func ( sc * socketClient ) PubKey ( ) ( crypto . PubKey , error ) {
err := writeMsg ( sc . conn , & PubKeyMsg { } )
if err != nil {
if err != nil {
return crypto . PubKey { } , err
return crypto . PubKey { } , err
}
}
res , err := readMsg ( pvsc . conn )
res , err := readMsg ( sc . conn )
if err != nil {
if err != nil {
return crypto . PubKey { } , err
return crypto . PubKey { } , err
}
}
@ -115,14 +145,14 @@ func (pvsc *PrivValidatorSocketClient) PubKey() (crypto.PubKey, error) {
return res . ( * PubKeyMsg ) . PubKey , nil
return res . ( * PubKeyMsg ) . PubKey , nil
}
}
// SignVote implements PrivValidator.
func ( pv sc * PrivValidatorS ocketClient) SignVote ( chainID string , vote * types . Vote ) error {
err := writeMsg ( pv sc. conn , & SignVoteMsg { Vote : vote } )
// SignVote implements PrivValidator2 .
func ( sc * s ocketClient) SignVote ( chainID string , vote * types . Vote ) error {
err := writeMsg ( sc . conn , & SignVoteMsg { Vote : vote } )
if err != nil {
if err != nil {
return err
return err
}
}
res , err := readMsg ( pv sc. conn )
res , err := readMsg ( sc . conn )
if err != nil {
if err != nil {
return err
return err
}
}
@ -132,14 +162,14 @@ func (pvsc *PrivValidatorSocketClient) SignVote(chainID string, vote *types.Vote
return nil
return nil
}
}
// SignProposal implements PrivValidator.
func ( pv sc * PrivValidatorS ocketClient) SignProposal ( chainID string , proposal * types . Proposal ) error {
err := writeMsg ( pv sc. conn , & SignProposalMsg { Proposal : proposal } )
// SignProposal implements PrivValidator2 .
func ( sc * s ocketClient) SignProposal ( chainID string , proposal * types . Proposal ) error {
err := writeMsg ( sc . conn , & SignProposalMsg { Proposal : proposal } )
if err != nil {
if err != nil {
return err
return err
}
}
res , err := readMsg ( pv sc. conn )
res , err := readMsg ( sc . conn )
if err != nil {
if err != nil {
return err
return err
}
}
@ -149,14 +179,14 @@ func (pvsc *PrivValidatorSocketClient) SignProposal(chainID string, proposal *ty
return nil
return nil
}
}
// SignHeartbeat implements PrivValidator.
func ( pv sc * PrivValidatorS ocketClient) SignHeartbeat ( chainID string , heartbeat * types . Heartbeat ) error {
err := writeMsg ( pv sc. conn , & SignHeartbeatMsg { Heartbeat : heartbeat } )
// SignHeartbeat implements PrivValidator2 .
func ( sc * s ocketClient) SignHeartbeat ( chainID string , heartbeat * types . Heartbeat ) error {
err := writeMsg ( sc . conn , & SignHeartbeatMsg { Heartbeat : heartbeat } )
if err != nil {
if err != nil {
return err
return err
}
}
res , err := readMsg ( pv sc. conn )
res , err := readMsg ( sc . conn )
if err != nil {
if err != nil {
return err
return err
}
}
@ -166,22 +196,22 @@ func (pvsc *PrivValidatorSocketClient) SignHeartbeat(chainID string, heartbeat *
return nil
return nil
}
}
func ( pv sc * PrivValidatorS ocketClient) connect ( ) ( net . Conn , error ) {
retries := dialRetryMax
func ( sc * s ocketClient) connect ( ) ( net . Conn , error ) {
retries := defaultD ialRetryMax
RETRY_LOOP :
RETRY_LOOP :
for retries > 0 {
for retries > 0 {
if retries != dialRetryMax {
time . Sleep ( time . Second * dialRetryIntervalSeconds )
if retries != defaultD ialRetryMax {
time . Sleep ( sc . connectTimeout )
}
}
retries --
retries --
conn , err := cmn . Connect ( pv sc. SocketAddress )
conn , err := cmn . Connect ( sc . addr )
if err != nil {
if err != nil {
pv sc. Logger . Error (
"pv sc connect" ,
"addr" , pv sc. SocketAddress ,
sc . Logger . Error (
"sc connect" ,
"addr" , sc . addr ,
"err" , errors . Wrap ( err , "connection failed" ) ,
"err" , errors . Wrap ( err , "connection failed" ) ,
)
)
@ -189,18 +219,18 @@ RETRY_LOOP:
}
}
if err := conn . SetDeadline ( time . Now ( ) . Add ( connDeadline ) ) ; err != nil {
if err := conn . SetDeadline ( time . Now ( ) . Add ( connDeadline ) ) ; err != nil {
pv sc. Logger . Error (
"pv sc connect" ,
sc . Logger . Error (
"sc connect" ,
"err" , errors . Wrap ( err , "setting connection timeout failed" ) ,
"err" , errors . Wrap ( err , "setting connection timeout failed" ) ,
)
)
continue
continue
}
}
if pv sc. privKey != nil {
conn , err = p2pconn . MakeSecretConnection ( conn , pv sc. privKey . Wrap ( ) )
if sc . privKey != nil {
conn , err = p2pconn . MakeSecretConnection ( conn , sc . privKey . Wrap ( ) )
if err != nil {
if err != nil {
pv sc. Logger . Error (
"pv sc connect" ,
sc . Logger . Error (
"sc connect" ,
"err" , errors . Wrap ( err , "encrypting connection failed" ) ,
"err" , errors . Wrap ( err , "encrypting connection failed" ) ,
)
)