github.com/ava-labs/avalanchego@v1.11.11/vms/components/avax/utxo_id_test.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package avax
     5  
     6  import (
     7  	"math"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/ava-labs/avalanchego/codec"
    13  	"github.com/ava-labs/avalanchego/codec/linearcodec"
    14  	"github.com/ava-labs/avalanchego/ids"
    15  )
    16  
    17  func TestUTXOIDVerifyNil(t *testing.T) {
    18  	utxoID := (*UTXOID)(nil)
    19  	err := utxoID.Verify()
    20  	require.ErrorIs(t, err, errNilUTXOID)
    21  }
    22  
    23  func TestUTXOID(t *testing.T) {
    24  	require := require.New(t)
    25  
    26  	c := linearcodec.NewDefault()
    27  	manager := codec.NewDefaultManager()
    28  	require.NoError(manager.RegisterCodec(codecVersion, c))
    29  
    30  	utxoID := UTXOID{
    31  		TxID: ids.ID{
    32  			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    33  			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    34  			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    35  			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
    36  		},
    37  		OutputIndex: 0x20212223,
    38  	}
    39  
    40  	require.NoError(utxoID.Verify())
    41  
    42  	bytes, err := manager.Marshal(codecVersion, &utxoID)
    43  	require.NoError(err)
    44  
    45  	newUTXOID := UTXOID{}
    46  	_, err = manager.Unmarshal(bytes, &newUTXOID)
    47  	require.NoError(err)
    48  
    49  	require.NoError(newUTXOID.Verify())
    50  	require.Equal(utxoID.InputID(), newUTXOID.InputID())
    51  }
    52  
    53  func TestUTXOIDCompare(t *testing.T) {
    54  	type test struct {
    55  		name     string
    56  		id1      UTXOID
    57  		id2      UTXOID
    58  		expected int
    59  	}
    60  	tests := []*test{
    61  		{
    62  			name:     "same",
    63  			id1:      UTXOID{},
    64  			id2:      UTXOID{},
    65  			expected: 0,
    66  		},
    67  		{
    68  			name: "id smaller",
    69  			id1:  UTXOID{},
    70  			id2: UTXOID{
    71  				TxID: ids.ID{1},
    72  			},
    73  			expected: -1,
    74  		},
    75  		{
    76  			name: "index smaller",
    77  			id1:  UTXOID{},
    78  			id2: UTXOID{
    79  				OutputIndex: 1,
    80  			},
    81  			expected: -1,
    82  		},
    83  	}
    84  	for _, tt := range tests {
    85  		t.Run(tt.name, func(t *testing.T) {
    86  			require := require.New(t)
    87  
    88  			require.Equal(tt.expected, tt.id1.Compare(&tt.id2))
    89  			require.Equal(-tt.expected, tt.id2.Compare(&tt.id1))
    90  		})
    91  	}
    92  }
    93  
    94  func TestUTXOIDFromString(t *testing.T) {
    95  	tests := []struct {
    96  		description string
    97  		utxoID      *UTXOID
    98  		expectedStr string
    99  		parseErr    error
   100  	}{
   101  		{
   102  			description: "empty utxoID",
   103  			utxoID:      &UTXOID{},
   104  			expectedStr: "11111111111111111111111111111111LpoYY:0",
   105  			parseErr:    nil,
   106  		},
   107  		{
   108  			description: "a random utxoID",
   109  			utxoID: &UTXOID{
   110  				TxID:        ids.Empty.Prefix(2022),
   111  				OutputIndex: 2022,
   112  			},
   113  			expectedStr: "PkHybKBmFvBkfumRvJZToECJp4oCiziLu95p86rU1THx1WAqa:2022",
   114  			parseErr:    nil,
   115  		},
   116  		{
   117  			description: "max output index utxoID",
   118  			utxoID: &UTXOID{
   119  				TxID:        ids.Empty.Prefix(1789),
   120  				OutputIndex: math.MaxUint32,
   121  			},
   122  			expectedStr: "Y3sXNphGY121uVzj37rA8ooUAHrfuDZahzLrTq6UauAZTEqoX:4294967295",
   123  			parseErr:    nil,
   124  		},
   125  		{
   126  			description: "not enough tokens",
   127  			utxoID:      &UTXOID{},
   128  			expectedStr: "11111111111111111111111111111111LpoYY",
   129  			parseErr:    errMalformedUTXOIDString,
   130  		},
   131  		{
   132  			description: "not enough tokens",
   133  			utxoID:      &UTXOID{},
   134  			expectedStr: "11111111111111111111111111111111LpoYY:10:10",
   135  			parseErr:    errMalformedUTXOIDString,
   136  		},
   137  		{
   138  			description: "missing TxID",
   139  			utxoID:      &UTXOID{},
   140  			expectedStr: ":2022",
   141  			parseErr:    errFailedDecodingUTXOIDTxID,
   142  		},
   143  		{
   144  			description: "non TxID",
   145  			utxoID:      &UTXOID{},
   146  			expectedStr: "11:NOT_AN_INDEX",
   147  			parseErr:    errFailedDecodingUTXOIDTxID,
   148  		},
   149  		{
   150  			description: "missing index",
   151  			utxoID:      &UTXOID{},
   152  			expectedStr: "11111111111111111111111111111111LpoYY:",
   153  			parseErr:    errFailedDecodingUTXOIDIndex,
   154  		},
   155  		{
   156  			description: "non index",
   157  			utxoID:      &UTXOID{},
   158  			expectedStr: "11111111111111111111111111111111LpoYY:NOT_AN_INDEX",
   159  			parseErr:    errFailedDecodingUTXOIDIndex,
   160  		},
   161  		{
   162  			description: "negative index",
   163  			utxoID:      &UTXOID{},
   164  			expectedStr: "11111111111111111111111111111111LpoYY:-1",
   165  			parseErr:    errFailedDecodingUTXOIDIndex,
   166  		},
   167  		{
   168  			description: "index too large",
   169  			utxoID:      &UTXOID{},
   170  			expectedStr: "11111111111111111111111111111111LpoYY:4294967296",
   171  			parseErr:    errFailedDecodingUTXOIDIndex,
   172  		},
   173  	}
   174  
   175  	for _, test := range tests {
   176  		t.Run(test.description, func(t *testing.T) {
   177  			require := require.New(t)
   178  
   179  			retrievedUTXOID, err := UTXOIDFromString(test.expectedStr)
   180  			require.ErrorIs(err, test.parseErr)
   181  			if test.parseErr != nil {
   182  				return
   183  			}
   184  			require.Equal(test.utxoID.InputID(), retrievedUTXOID.InputID())
   185  			require.Equal(test.utxoID, retrievedUTXOID)
   186  			require.Equal(test.utxoID.String(), retrievedUTXOID.String())
   187  		})
   188  	}
   189  }