You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

106 lines
2.7 KiB

package privval
import (
"context"
"io"
"sync"
"github.com/tendermint/tendermint/libs/service"
privvalproto "github.com/tendermint/tendermint/proto/tendermint/privval"
"github.com/tendermint/tendermint/types"
)
// ValidationRequestHandlerFunc handles different remoteSigner requests
type ValidationRequestHandlerFunc func(
ctx context.Context,
privVal types.PrivValidator,
requestMessage privvalproto.Message,
chainID string) (privvalproto.Message, error)
type SignerServer struct {
service.BaseService
endpoint *SignerDialerEndpoint
chainID string
privVal types.PrivValidator
handlerMtx sync.Mutex
validationRequestHandler ValidationRequestHandlerFunc
}
func NewSignerServer(endpoint *SignerDialerEndpoint, chainID string, privVal types.PrivValidator) *SignerServer {
ss := &SignerServer{
endpoint: endpoint,
chainID: chainID,
privVal: privVal,
validationRequestHandler: DefaultValidationRequestHandler,
}
ss.BaseService = *service.NewBaseService(endpoint.logger, "SignerServer", ss)
return ss
}
// OnStart implements service.Service.
func (ss *SignerServer) OnStart(ctx context.Context) error {
go ss.serviceLoop(ctx)
return nil
}
// OnStop implements service.Service.
func (ss *SignerServer) OnStop() {
ss.endpoint.logger.Debug("SignerServer: OnStop calling Close")
_ = ss.endpoint.Close()
}
// SetRequestHandler override the default function that is used to service requests
func (ss *SignerServer) SetRequestHandler(validationRequestHandler ValidationRequestHandlerFunc) {
ss.handlerMtx.Lock()
defer ss.handlerMtx.Unlock()
ss.validationRequestHandler = validationRequestHandler
}
func (ss *SignerServer) servicePendingRequest(ctx context.Context) {
if !ss.IsRunning() {
return // Ignore error from closing.
}
req, err := ss.endpoint.ReadMessage()
if err != nil {
if err != io.EOF {
ss.endpoint.logger.Error("SignerServer: HandleMessage", "err", err)
}
return
}
var res privvalproto.Message
{
// limit the scope of the lock
ss.handlerMtx.Lock()
defer ss.handlerMtx.Unlock()
res, err = ss.validationRequestHandler(ctx, ss.privVal, req, ss.chainID) // todo
if err != nil {
// only log the error; we'll reply with an error in res
ss.endpoint.logger.Error("SignerServer: handleMessage", "err", err)
}
}
err = ss.endpoint.WriteMessage(res)
if err != nil {
ss.endpoint.logger.Error("SignerServer: writeMessage", "err", err)
}
}
func (ss *SignerServer) serviceLoop(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
default:
if err := ss.endpoint.ensureConnection(ctx); err != nil {
return
}
ss.servicePendingRequest(ctx)
}
}
}