github.com/ava-labs/avalanchego@v1.11.11/vms/secp256k1fx/keychain_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 secp256k1fx
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/ava-labs/avalanchego/ids"
    12  	"github.com/ava-labs/avalanchego/utils/crypto/secp256k1"
    13  	"github.com/ava-labs/avalanchego/utils/formatting"
    14  )
    15  
    16  var (
    17  	keys = []string{
    18  		"0xb1ed77ad48555d49f03a7465f0685a7d86bfd5f3a3ccf1be01971ea8dec5471c",
    19  		"0x51a5e21237263396a5dfce60496d0ca3829d23fd33c38e6d13ae53b4810df9ca",
    20  		"0x8c2bae69b0e1f6f3a5e784504ee93279226f997c5a6771b9bd6b881a8fee1e9d",
    21  	}
    22  	addrs = []string{
    23  		"B6D4v1VtPYLbiUvYXtW4Px8oE9imC2vGW",
    24  		"P5wdRuZeaDt28eHMP5S3w9ZdoBfo7wuzF",
    25  		"Q4MzFZZDPHRPAHFeDs3NiyyaZDvxHKivf",
    26  	}
    27  )
    28  
    29  func TestNewKeychain(t *testing.T) {
    30  	require.NotNil(t, NewKeychain())
    31  }
    32  
    33  func TestKeychainGetUnknownAddr(t *testing.T) {
    34  	require := require.New(t)
    35  	kc := NewKeychain()
    36  
    37  	addr, _ := ids.ShortFromString(addrs[0])
    38  	_, exists := kc.Get(addr)
    39  	require.False(exists)
    40  }
    41  
    42  func TestKeychainAdd(t *testing.T) {
    43  	require := require.New(t)
    44  	kc := NewKeychain()
    45  
    46  	skBytes, err := formatting.Decode(formatting.HexNC, keys[0])
    47  	require.NoError(err)
    48  
    49  	sk, err := secp256k1.ToPrivateKey(skBytes)
    50  	require.NoError(err)
    51  	kc.Add(sk)
    52  
    53  	addr, _ := ids.ShortFromString(addrs[0])
    54  	rsk, exists := kc.Get(addr)
    55  	require.True(exists)
    56  	require.IsType(&secp256k1.PrivateKey{}, rsk)
    57  	rsksecp := rsk.(*secp256k1.PrivateKey)
    58  	require.Equal(sk.Bytes(), rsksecp.Bytes())
    59  
    60  	addrs := kc.Addresses()
    61  	require.Equal(1, addrs.Len())
    62  	require.True(addrs.Contains(addr))
    63  }
    64  
    65  func TestKeychainNew(t *testing.T) {
    66  	require := require.New(t)
    67  	kc := NewKeychain()
    68  
    69  	require.Zero(kc.Addresses().Len())
    70  
    71  	sk, err := kc.New()
    72  	require.NoError(err)
    73  
    74  	addr := sk.PublicKey().Address()
    75  
    76  	addrs := kc.Addresses()
    77  	require.Equal(1, addrs.Len())
    78  	require.True(addrs.Contains(addr))
    79  }
    80  
    81  func TestKeychainMatch(t *testing.T) {
    82  	require := require.New(t)
    83  	kc := NewKeychain()
    84  
    85  	sks := []*secp256k1.PrivateKey{}
    86  	for _, keyStr := range keys {
    87  		skBytes, err := formatting.Decode(formatting.HexNC, keyStr)
    88  		require.NoError(err)
    89  
    90  		sk, err := secp256k1.ToPrivateKey(skBytes)
    91  		require.NoError(err)
    92  		sks = append(sks, sk)
    93  	}
    94  
    95  	kc.Add(sks[0])
    96  
    97  	owners := OutputOwners{
    98  		Threshold: 1,
    99  		Addrs: []ids.ShortID{
   100  			sks[1].PublicKey().Address(),
   101  			sks[2].PublicKey().Address(),
   102  		},
   103  	}
   104  	require.NoError(owners.Verify())
   105  
   106  	_, _, ok := kc.Match(&owners, 0)
   107  	require.False(ok)
   108  
   109  	kc.Add(sks[1])
   110  
   111  	indices, keys, ok := kc.Match(&owners, 1)
   112  	require.True(ok)
   113  	require.Equal([]uint32{0}, indices)
   114  	require.Len(keys, 1)
   115  	require.Equal(sks[1].PublicKey().Address(), keys[0].PublicKey().Address())
   116  
   117  	kc.Add(sks[2])
   118  
   119  	indices, keys, ok = kc.Match(&owners, 1)
   120  	require.True(ok)
   121  	require.Equal([]uint32{0}, indices)
   122  	require.Len(keys, 1)
   123  	require.Equal(sks[1].PublicKey().Address(), keys[0].PublicKey().Address())
   124  }
   125  
   126  func TestKeychainSpendMint(t *testing.T) {
   127  	require := require.New(t)
   128  	kc := NewKeychain()
   129  
   130  	sks := []*secp256k1.PrivateKey{}
   131  	for _, keyStr := range keys {
   132  		skBytes, err := formatting.Decode(formatting.HexNC, keyStr)
   133  		require.NoError(err)
   134  
   135  		sk, err := secp256k1.ToPrivateKey(skBytes)
   136  		require.NoError(err)
   137  		sks = append(sks, sk)
   138  	}
   139  
   140  	mint := MintOutput{OutputOwners: OutputOwners{
   141  		Threshold: 2,
   142  		Addrs: []ids.ShortID{
   143  			sks[1].PublicKey().Address(),
   144  			sks[2].PublicKey().Address(),
   145  		},
   146  	}}
   147  	require.NoError(mint.Verify())
   148  
   149  	_, _, err := kc.Spend(&mint, 0)
   150  	require.ErrorIs(err, errCantSpend)
   151  
   152  	kc.Add(sks[0])
   153  	kc.Add(sks[1])
   154  	kc.Add(sks[2])
   155  
   156  	vinput, keys, err := kc.Spend(&mint, 0)
   157  	require.NoError(err)
   158  
   159  	require.IsType(&Input{}, vinput)
   160  	input := vinput.(*Input)
   161  	require.NoError(input.Verify())
   162  	require.Equal([]uint32{0, 1}, input.SigIndices)
   163  	require.Len(keys, 2)
   164  	require.Equal(sks[1].PublicKey().Address(), keys[0].PublicKey().Address())
   165  	require.Equal(sks[2].PublicKey().Address(), keys[1].PublicKey().Address())
   166  }
   167  
   168  func TestKeychainSpendTransfer(t *testing.T) {
   169  	require := require.New(t)
   170  	kc := NewKeychain()
   171  
   172  	sks := []*secp256k1.PrivateKey{}
   173  	for _, keyStr := range keys {
   174  		skBytes, err := formatting.Decode(formatting.HexNC, keyStr)
   175  		require.NoError(err)
   176  
   177  		sk, err := secp256k1.ToPrivateKey(skBytes)
   178  		require.NoError(err)
   179  		sks = append(sks, sk)
   180  	}
   181  
   182  	transfer := TransferOutput{
   183  		Amt: 12345,
   184  		OutputOwners: OutputOwners{
   185  			Locktime:  54321,
   186  			Threshold: 2,
   187  			Addrs: []ids.ShortID{
   188  				sks[1].PublicKey().Address(),
   189  				sks[2].PublicKey().Address(),
   190  			},
   191  		},
   192  	}
   193  	require.NoError(transfer.Verify())
   194  
   195  	_, _, err := kc.Spend(&transfer, 54321)
   196  	require.ErrorIs(err, errCantSpend)
   197  
   198  	kc.Add(sks[0])
   199  	kc.Add(sks[1])
   200  	kc.Add(sks[2])
   201  
   202  	_, _, err = kc.Spend(&transfer, 4321)
   203  	require.ErrorIs(err, errCantSpend)
   204  
   205  	vinput, keys, err := kc.Spend(&transfer, 54321)
   206  	require.NoError(err)
   207  
   208  	require.IsType(&TransferInput{}, vinput)
   209  	input := vinput.(*TransferInput)
   210  	require.NoError(input.Verify())
   211  	require.Equal(uint64(12345), input.Amount())
   212  	require.Equal([]uint32{0, 1}, input.SigIndices)
   213  	require.Len(keys, 2)
   214  	require.Equal(sks[1].PublicKey().Address(), keys[0].PublicKey().Address())
   215  	require.Equal(sks[2].PublicKey().Address(), keys[1].PublicKey().Address())
   216  }
   217  
   218  func TestKeychainString(t *testing.T) {
   219  	require := require.New(t)
   220  	kc := NewKeychain()
   221  
   222  	skBytes, err := formatting.Decode(formatting.HexNC, keys[0])
   223  	require.NoError(err)
   224  
   225  	sk, err := secp256k1.ToPrivateKey(skBytes)
   226  	require.NoError(err)
   227  	kc.Add(sk)
   228  
   229  	expected := "Key[0]: Key: 0xb1ed77ad48555d49f03a7465f0685a7d86bfd5f3a3ccf1be01971ea8dec5471c Address: B6D4v1VtPYLbiUvYXtW4Px8oE9imC2vGW"
   230  	require.Equal(expected, kc.String())
   231  }
   232  
   233  func TestKeychainPrefixedString(t *testing.T) {
   234  	require := require.New(t)
   235  	kc := NewKeychain()
   236  
   237  	skBytes, err := formatting.Decode(formatting.HexNC, keys[0])
   238  	require.NoError(err)
   239  
   240  	sk, err := secp256k1.ToPrivateKey(skBytes)
   241  	require.NoError(err)
   242  	kc.Add(sk)
   243  
   244  	expected := "xDKey[0]: Key: 0xb1ed77ad48555d49f03a7465f0685a7d86bfd5f3a3ccf1be01971ea8dec5471c Address: B6D4v1VtPYLbiUvYXtW4Px8oE9imC2vGW"
   245  	require.Equal(expected, kc.PrefixedString("xD"))
   246  }