@ -10,11 +10,22 @@ import (
"github.com/tendermint/tendermint/libs/service"
)
// SignerValidatorEndpointOption sets an optional parameter on the SocketVal.
type SignerValidatorEndpointOption func ( * SignerListenerEndpoint )
// SignerListenerEndpointOption sets an optional parameter on the SignerListenerEndpoint.
type SignerListenerEndpointOption func ( * SignerListenerEndpoint )
// SignerListenerEndpointTimeoutReadWrite sets the read and write timeout for
// connections from external signing processes.
//
// Default: 5s
func SignerListenerEndpointTimeoutReadWrite ( timeout time . Duration ) SignerListenerEndpointOption {
return func ( sl * SignerListenerEndpoint ) { sl . signerEndpoint . timeoutReadWrite = timeout }
}
// SignerListenerEndpoint listens for an external process to dial in
// and keeps the connection alive by dropping and reconnecting
// SignerListenerEndpoint listens for an external process to dial in and keeps
// the connection alive by dropping and reconnecting.
//
// The process will send pings every ~3s (read/write timeout * 2/3) to keep the
// connection alive.
type SignerListenerEndpoint struct {
signerEndpoint
@ -24,6 +35,7 @@ type SignerListenerEndpoint struct {
timeoutAccept time . Duration
pingTimer * time . Ticker
pingInterval time . Duration
instanceMtx sync . Mutex // Ensures instance public methods access, i.e. SendRequest
}
@ -32,15 +44,21 @@ type SignerListenerEndpoint struct {
func NewSignerListenerEndpoint (
logger log . Logger ,
listener net . Listener ,
options ... SignerListenerEndpointOption ,
) * SignerListenerEndpoint {
sc := & SignerListenerEndpoint {
sl := & SignerListenerEndpoint {
listener : listener ,
timeoutAccept : defaultTimeoutAcceptSeconds * time . Second ,
}
sc . BaseService = * service . NewBaseService ( logger , "SignerListenerEndpoint" , sc )
sc . signerEndpoint . timeoutReadWrite = defaultTimeoutReadWriteSeconds * time . Second
return sc
sl . BaseService = * service . NewBaseService ( logger , "SignerListenerEndpoint" , sl )
sl . signerEndpoint . timeoutReadWrite = defaultTimeoutReadWriteSeconds * time . Second
for _ , optionFunc := range options {
optionFunc ( sl )
}
return sl
}
// OnStart implements service.Service.
@ -48,7 +66,9 @@ func (sl *SignerListenerEndpoint) OnStart() error {
sl . connectRequestCh = make ( chan struct { } )
sl . connectionAvailableCh = make ( chan net . Conn )
sl . pingTimer = time . NewTicker ( defaultPingPeriodMilliseconds * time . Millisecond )
// NOTE: ping timeout must be less than read/write timeout
sl . pingInterval = time . Duration ( sl . signerEndpoint . timeoutReadWrite . Milliseconds ( ) * 2 / 3 ) * time . Millisecond
sl . pingTimer = time . NewTicker ( sl . pingInterval )
go sl . serviceLoop ( )
go sl . pingLoop ( )
@ -116,6 +136,7 @@ func (sl *SignerListenerEndpoint) ensureConnection(maxWait time.Duration) error
}
// block until connected or timeout
sl . Logger . Info ( "SignerListener: Blocking for connection" )
sl . triggerConnect ( )
err := sl . WaitConnection ( sl . connectionAvailableCh , maxWait )
if err != nil {