https://github.com/tendermint/tendermint
Raw File
Tip revision: 31e61d937ce329a2f1940169ee2ad247aa60bc87 authored by William Banfield on 28 January 2022, 22:41:02 UTC
update validate/complete logic for consensus params
Tip revision: 31e61d9
signer_dialer_endpoint.go
package privval

import (
	"context"
	"time"

	"github.com/tendermint/tendermint/libs/log"
	"github.com/tendermint/tendermint/libs/service"
)

const (
	defaultMaxDialRetries        = 10
	defaultRetryWaitMilliseconds = 100
)

// SignerServiceEndpointOption sets an optional parameter on the SignerDialerEndpoint.
type SignerServiceEndpointOption func(*SignerDialerEndpoint)

// SignerDialerEndpointTimeoutReadWrite sets the read and write timeout for
// connections from client processes.
func SignerDialerEndpointTimeoutReadWrite(timeout time.Duration) SignerServiceEndpointOption {
	return func(ss *SignerDialerEndpoint) { ss.timeoutReadWrite = timeout }
}

// SignerDialerEndpointConnRetries sets the amount of attempted retries to
// acceptNewConnection.
func SignerDialerEndpointConnRetries(retries int) SignerServiceEndpointOption {
	return func(ss *SignerDialerEndpoint) { ss.maxConnRetries = retries }
}

// SignerDialerEndpointRetryWaitInterval sets the retry wait interval to a
// custom value.
func SignerDialerEndpointRetryWaitInterval(interval time.Duration) SignerServiceEndpointOption {
	return func(ss *SignerDialerEndpoint) { ss.retryWait = interval }
}

// SignerDialerEndpoint dials using its dialer and responds to any signature
// requests using its privVal.
type SignerDialerEndpoint struct {
	signerEndpoint

	dialer SocketDialer

	retryWait      time.Duration
	maxConnRetries int
}

// NewSignerDialerEndpoint returns a SignerDialerEndpoint that will dial using the given
// dialer and respond to any signature requests over the connection
// using the given privVal.
func NewSignerDialerEndpoint(
	logger log.Logger,
	dialer SocketDialer,
	options ...SignerServiceEndpointOption,
) *SignerDialerEndpoint {

	sd := &SignerDialerEndpoint{
		dialer:         dialer,
		retryWait:      defaultRetryWaitMilliseconds * time.Millisecond,
		maxConnRetries: defaultMaxDialRetries,
	}
	sd.signerEndpoint.logger = logger

	sd.BaseService = *service.NewBaseService(logger, "SignerDialerEndpoint", sd)
	sd.signerEndpoint.timeoutReadWrite = defaultTimeoutReadWriteSeconds * time.Second

	for _, optionFunc := range options {
		optionFunc(sd)
	}

	return sd
}

func (sd *SignerDialerEndpoint) OnStart(context.Context) error { return nil }
func (sd *SignerDialerEndpoint) OnStop()                       {}

func (sd *SignerDialerEndpoint) ensureConnection(ctx context.Context) error {
	if sd.IsConnected() {
		return nil
	}

	timer := time.NewTimer(0)
	defer timer.Stop()
	retries := 0
	for retries < sd.maxConnRetries {
		if err := ctx.Err(); err != nil {
			return err
		}
		conn, err := sd.dialer()

		if err != nil {
			retries++
			sd.logger.Debug("SignerDialer: Reconnection failed", "retries", retries, "max", sd.maxConnRetries, "err", err)

			// Wait between retries
			timer.Reset(sd.retryWait)
			select {
			case <-ctx.Done():
				return ctx.Err()
			case <-timer.C:
			}
		} else {
			sd.SetConnection(conn)
			sd.logger.Debug("SignerDialer: Connection Ready")
			return nil
		}
	}

	sd.logger.Debug("SignerDialer: Max retries exceeded", "retries", retries, "max", sd.maxConnRetries)

	return ErrNoConnection
}
back to top