github.com/MetalBlockchain/subnet-evm@v0.4.9/warp/handlers/signature_request.go (about)

     1  // (c) 2023, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package handlers
     5  
     6  import (
     7  	"context"
     8  	"time"
     9  
    10  	"github.com/MetalBlockchain/metalgo/codec"
    11  	"github.com/MetalBlockchain/metalgo/ids"
    12  	"github.com/MetalBlockchain/subnet-evm/plugin/evm/message"
    13  	"github.com/MetalBlockchain/subnet-evm/warp"
    14  	"github.com/MetalBlockchain/subnet-evm/warp/handlers/stats"
    15  	"github.com/ethereum/go-ethereum/log"
    16  )
    17  
    18  // SignatureRequestHandler is a peer.RequestHandler for message.SignatureRequest
    19  // serving requested BLS signature data
    20  type SignatureRequestHandler interface {
    21  	OnSignatureRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, signatureRequest message.SignatureRequest) ([]byte, error)
    22  }
    23  
    24  // signatureRequestHandler implements the SignatureRequestHandler interface
    25  type signatureRequestHandler struct {
    26  	backend warp.WarpBackend
    27  	codec   codec.Manager
    28  	stats   stats.SignatureRequestHandlerStats
    29  }
    30  
    31  func NewSignatureRequestHandler(backend warp.WarpBackend, codec codec.Manager, stats stats.SignatureRequestHandlerStats) SignatureRequestHandler {
    32  	return &signatureRequestHandler{
    33  		backend: backend,
    34  		codec:   codec,
    35  		stats:   stats,
    36  	}
    37  }
    38  
    39  // OnSignatureRequest handles message.SignatureRequest, and retrieves a warp signature for the requested message ID.
    40  // Never returns an error
    41  // Expects returned errors to be treated as FATAL
    42  // Returns empty response if signature is not found
    43  // Assumes ctx is active
    44  func (s *signatureRequestHandler) OnSignatureRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, signatureRequest message.SignatureRequest) ([]byte, error) {
    45  	startTime := time.Now()
    46  	s.stats.IncSignatureRequest()
    47  
    48  	// Always report signature request time
    49  	defer func() {
    50  		s.stats.UpdateSignatureRequestTime(time.Since(startTime))
    51  	}()
    52  
    53  	signature, err := s.backend.GetSignature(ctx, signatureRequest.MessageID)
    54  	if err != nil {
    55  		log.Debug("Unknown warp signature requested", "messageID", signatureRequest.MessageID)
    56  		s.stats.IncSignatureMiss()
    57  		return nil, nil
    58  	}
    59  
    60  	s.stats.IncSignatureHit()
    61  	response := message.SignatureResponse{Signature: signature}
    62  	responseBytes, err := s.codec.Marshal(message.Version, &response)
    63  	if err != nil {
    64  		log.Warn("could not marshal SignatureResponse, dropping request", "nodeID", nodeID, "requestID", requestID, "err", err)
    65  		return nil, nil
    66  	}
    67  
    68  	return responseBytes, nil
    69  }
    70  
    71  type NoopSignatureRequestHandler struct{}
    72  
    73  func (s *NoopSignatureRequestHandler) OnSignatureRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, signatureRequest message.SignatureRequest) ([]byte, error) {
    74  	return nil, nil
    75  }