github.com/MetalBlockchain/subnet-evm@v0.4.9/warp/handlers/signature_request_test.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  	"testing"
     9  	"time"
    10  
    11  	"github.com/MetalBlockchain/metalgo/database/memdb"
    12  	"github.com/MetalBlockchain/metalgo/ids"
    13  	"github.com/MetalBlockchain/metalgo/snow"
    14  	"github.com/MetalBlockchain/metalgo/utils/crypto/bls"
    15  	"github.com/MetalBlockchain/metalgo/utils/hashing"
    16  	"github.com/MetalBlockchain/metalgo/vms/platformvm/teleporter"
    17  	"github.com/MetalBlockchain/subnet-evm/plugin/evm/message"
    18  	"github.com/MetalBlockchain/subnet-evm/warp"
    19  	"github.com/MetalBlockchain/subnet-evm/warp/handlers/stats"
    20  	"github.com/stretchr/testify/require"
    21  )
    22  
    23  func TestSignatureHandler(t *testing.T) {
    24  	database := memdb.New()
    25  	snowCtx := snow.DefaultContextTest()
    26  	blsSecretKey, err := bls.NewSecretKey()
    27  	require.NoError(t, err)
    28  
    29  	snowCtx.TeleporterSigner = teleporter.NewSigner(blsSecretKey, snowCtx.ChainID)
    30  	warpBackend := warp.NewWarpBackend(snowCtx, database, 100)
    31  
    32  	msg, err := teleporter.NewUnsignedMessage(snowCtx.ChainID, snowCtx.CChainID, []byte("test"))
    33  	require.NoError(t, err)
    34  
    35  	messageID := hashing.ComputeHash256Array(msg.Bytes())
    36  	require.NoError(t, warpBackend.AddMessage(context.Background(), msg))
    37  	signature, err := warpBackend.GetSignature(context.Background(), messageID)
    38  	require.NoError(t, err)
    39  	unknownMessageID := ids.GenerateTestID()
    40  
    41  	mockHandlerStats := &stats.MockSignatureRequestHandlerStats{}
    42  	signatureRequestHandler := NewSignatureRequestHandler(warpBackend, message.Codec, mockHandlerStats)
    43  
    44  	tests := map[string]struct {
    45  		setup       func() (request message.SignatureRequest, expectedResponse []byte)
    46  		verifyStats func(t *testing.T, stats *stats.MockSignatureRequestHandlerStats)
    47  	}{
    48  		"normal": {
    49  			setup: func() (request message.SignatureRequest, expectedResponse []byte) {
    50  				return message.SignatureRequest{
    51  					MessageID: messageID,
    52  				}, signature[:]
    53  			},
    54  			verifyStats: func(t *testing.T, stats *stats.MockSignatureRequestHandlerStats) {
    55  				require.EqualValues(t, 1, mockHandlerStats.SignatureRequestCount)
    56  				require.EqualValues(t, 1, mockHandlerStats.SignatureRequestHit)
    57  				require.EqualValues(t, 0, mockHandlerStats.SignatureRequestMiss)
    58  				require.Greater(t, mockHandlerStats.SignatureRequestDuration, time.Duration(0))
    59  			},
    60  		},
    61  		"unknown": {
    62  			setup: func() (request message.SignatureRequest, expectedResponse []byte) {
    63  				return message.SignatureRequest{
    64  					MessageID: unknownMessageID,
    65  				}, nil
    66  			},
    67  			verifyStats: func(t *testing.T, stats *stats.MockSignatureRequestHandlerStats) {
    68  				require.EqualValues(t, 1, mockHandlerStats.SignatureRequestCount)
    69  				require.EqualValues(t, 1, mockHandlerStats.SignatureRequestMiss)
    70  				require.EqualValues(t, 0, mockHandlerStats.SignatureRequestHit)
    71  				require.Greater(t, mockHandlerStats.SignatureRequestDuration, time.Duration(0))
    72  			},
    73  		},
    74  	}
    75  
    76  	for name, test := range tests {
    77  		// Reset stats before each test
    78  		mockHandlerStats.Reset()
    79  
    80  		t.Run(name, func(t *testing.T) {
    81  			request, expectedResponse := test.setup()
    82  			responseBytes, err := signatureRequestHandler.OnSignatureRequest(context.Background(), ids.GenerateTestNodeID(), 1, request)
    83  			require.NoError(t, err)
    84  
    85  			// If the expected response is empty, assert that the handler returns an empty response and return early.
    86  			if len(expectedResponse) == 0 {
    87  				test.verifyStats(t, mockHandlerStats)
    88  				require.Len(t, responseBytes, 0, "expected response to be empty")
    89  				return
    90  			}
    91  			var response message.SignatureResponse
    92  			_, err = message.Codec.Unmarshal(responseBytes, &response)
    93  			require.NoError(t, err, "error unmarshalling SignatureResponse")
    94  
    95  			require.Equal(t, expectedResponse, response.Signature[:])
    96  			test.verifyStats(t, mockHandlerStats)
    97  		})
    98  	}
    99  }