github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/bft/privval/signer_server.go (about)

     1  package privval
     2  
     3  import (
     4  	"errors"
     5  	"io"
     6  	"sync"
     7  
     8  	"github.com/gnolang/gno/tm2/pkg/bft/types"
     9  	"github.com/gnolang/gno/tm2/pkg/service"
    10  )
    11  
    12  // ValidationRequestHandlerFunc handles different remoteSigner requests
    13  type ValidationRequestHandlerFunc func(
    14  	privVal types.PrivValidator,
    15  	requestMessage SignerMessage,
    16  	chainID string) (SignerMessage, error)
    17  
    18  type SignerServer struct {
    19  	service.BaseService
    20  
    21  	endpoint *SignerDialerEndpoint
    22  	chainID  string
    23  	privVal  types.PrivValidator
    24  
    25  	handlerMtx               sync.Mutex
    26  	validationRequestHandler ValidationRequestHandlerFunc
    27  }
    28  
    29  func NewSignerServer(endpoint *SignerDialerEndpoint, chainID string, privVal types.PrivValidator) *SignerServer {
    30  	ss := &SignerServer{
    31  		endpoint:                 endpoint,
    32  		chainID:                  chainID,
    33  		privVal:                  privVal,
    34  		validationRequestHandler: DefaultValidationRequestHandler,
    35  	}
    36  
    37  	ss.BaseService = *service.NewBaseService(endpoint.Logger, "SignerServer", ss)
    38  
    39  	return ss
    40  }
    41  
    42  // OnStart implements service.Service.
    43  func (ss *SignerServer) OnStart() error {
    44  	go ss.serviceLoop()
    45  	return nil
    46  }
    47  
    48  // OnStop implements service.Service.
    49  func (ss *SignerServer) OnStop() {
    50  	ss.endpoint.Logger.Debug("SignerServer: OnStop calling Close")
    51  	_ = ss.endpoint.Close()
    52  }
    53  
    54  // SetRequestHandler override the default function that is used to service requests
    55  func (ss *SignerServer) SetRequestHandler(validationRequestHandler ValidationRequestHandlerFunc) {
    56  	ss.handlerMtx.Lock()
    57  	defer ss.handlerMtx.Unlock()
    58  	ss.validationRequestHandler = validationRequestHandler
    59  }
    60  
    61  func (ss *SignerServer) servicePendingRequest() {
    62  	if !ss.IsRunning() {
    63  		return // Ignore error from closing.
    64  	}
    65  
    66  	req, err := ss.endpoint.ReadMessage()
    67  	if err != nil {
    68  		if !errors.Is(err, io.EOF) {
    69  			ss.Logger.Error("SignerServer: HandleMessage", "err", err)
    70  		}
    71  		return
    72  	}
    73  
    74  	var res SignerMessage
    75  	{
    76  		// limit the scope of the lock
    77  		ss.handlerMtx.Lock()
    78  		defer ss.handlerMtx.Unlock()
    79  		res, err = ss.validationRequestHandler(ss.privVal, req, ss.chainID)
    80  		if err != nil {
    81  			// only log the error; we'll reply with an error in res
    82  			ss.Logger.Error("SignerServer: handleMessage", "err", err)
    83  		}
    84  	}
    85  
    86  	if res != nil {
    87  		err = ss.endpoint.WriteMessage(res)
    88  		if err != nil {
    89  			ss.Logger.Error("SignerServer: writeMessage", "err", err)
    90  		}
    91  	}
    92  }
    93  
    94  func (ss *SignerServer) serviceLoop() {
    95  	for {
    96  		select {
    97  		default:
    98  			err := ss.endpoint.ensureConnection()
    99  			if err != nil {
   100  				return
   101  			}
   102  			ss.servicePendingRequest()
   103  
   104  		case <-ss.Quit():
   105  			return
   106  		}
   107  	}
   108  }