github.com/MetalBlockchain/metalgo@v1.11.9/vms/propertyfx/fx_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 propertyfx
     5  
     6  import (
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/MetalBlockchain/metalgo/codec/linearcodec"
    13  	"github.com/MetalBlockchain/metalgo/ids"
    14  	"github.com/MetalBlockchain/metalgo/utils/crypto/secp256k1"
    15  	"github.com/MetalBlockchain/metalgo/utils/hashing"
    16  	"github.com/MetalBlockchain/metalgo/utils/logging"
    17  	"github.com/MetalBlockchain/metalgo/vms/secp256k1fx"
    18  )
    19  
    20  var (
    21  	txBytes  = []byte{0, 1, 2, 3, 4, 5}
    22  	sigBytes = [secp256k1.SignatureLen]byte{
    23  		0x0e, 0x33, 0x4e, 0xbc, 0x67, 0xa7, 0x3f, 0xe8,
    24  		0x24, 0x33, 0xac, 0xa3, 0x47, 0x88, 0xa6, 0x3d,
    25  		0x58, 0xe5, 0x8e, 0xf0, 0x3a, 0xd5, 0x84, 0xf1,
    26  		0xbc, 0xa3, 0xb2, 0xd2, 0x5d, 0x51, 0xd6, 0x9b,
    27  		0x0f, 0x28, 0x5d, 0xcd, 0x3f, 0x71, 0x17, 0x0a,
    28  		0xf9, 0xbf, 0x2d, 0xb1, 0x10, 0x26, 0x5c, 0xe9,
    29  		0xdc, 0xc3, 0x9d, 0x7a, 0x01, 0x50, 0x9d, 0xe8,
    30  		0x35, 0xbd, 0xcb, 0x29, 0x3a, 0xd1, 0x49, 0x32,
    31  		0x00,
    32  	}
    33  	addr = [hashing.AddrLen]byte{
    34  		0x01, 0x5c, 0xce, 0x6c, 0x55, 0xd6, 0xb5, 0x09,
    35  		0x84, 0x5c, 0x8c, 0x4e, 0x30, 0xbe, 0xd9, 0x8d,
    36  		0x39, 0x1a, 0xe7, 0xf0,
    37  	}
    38  )
    39  
    40  func TestFxInitialize(t *testing.T) {
    41  	vm := secp256k1fx.TestVM{
    42  		Codec: linearcodec.NewDefault(),
    43  		Log:   logging.NoLog{},
    44  	}
    45  	fx := Fx{}
    46  	require.NoError(t, fx.Initialize(&vm))
    47  }
    48  
    49  func TestFxInitializeInvalid(t *testing.T) {
    50  	fx := Fx{}
    51  	err := fx.Initialize(nil)
    52  	require.ErrorIs(t, err, secp256k1fx.ErrWrongVMType)
    53  }
    54  
    55  func TestFxVerifyMintOperation(t *testing.T) {
    56  	require := require.New(t)
    57  
    58  	vm := secp256k1fx.TestVM{
    59  		Codec: linearcodec.NewDefault(),
    60  		Log:   logging.NoLog{},
    61  	}
    62  	date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
    63  	vm.Clk.Set(date)
    64  
    65  	fx := Fx{}
    66  	require.NoError(fx.Initialize(&vm))
    67  	tx := &secp256k1fx.TestTx{
    68  		UnsignedBytes: txBytes,
    69  	}
    70  	cred := &Credential{Credential: secp256k1fx.Credential{
    71  		Sigs: [][secp256k1.SignatureLen]byte{
    72  			sigBytes,
    73  		},
    74  	}}
    75  	utxo := &MintOutput{OutputOwners: secp256k1fx.OutputOwners{
    76  		Threshold: 1,
    77  		Addrs: []ids.ShortID{
    78  			addr,
    79  		},
    80  	}}
    81  	op := &MintOperation{
    82  		MintInput: secp256k1fx.Input{
    83  			SigIndices: []uint32{0},
    84  		},
    85  		MintOutput: MintOutput{OutputOwners: secp256k1fx.OutputOwners{
    86  			Threshold: 1,
    87  			Addrs: []ids.ShortID{
    88  				addr,
    89  			},
    90  		}},
    91  	}
    92  
    93  	utxos := []interface{}{utxo}
    94  	require.NoError(fx.VerifyOperation(tx, op, cred, utxos))
    95  }
    96  
    97  func TestFxVerifyMintOperationWrongTx(t *testing.T) {
    98  	require := require.New(t)
    99  
   100  	vm := secp256k1fx.TestVM{
   101  		Codec: linearcodec.NewDefault(),
   102  		Log:   logging.NoLog{},
   103  	}
   104  	date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
   105  	vm.Clk.Set(date)
   106  
   107  	fx := Fx{}
   108  	require.NoError(fx.Initialize(&vm))
   109  	cred := &Credential{Credential: secp256k1fx.Credential{
   110  		Sigs: [][secp256k1.SignatureLen]byte{
   111  			sigBytes,
   112  		},
   113  	}}
   114  	utxo := &MintOutput{OutputOwners: secp256k1fx.OutputOwners{
   115  		Threshold: 1,
   116  		Addrs: []ids.ShortID{
   117  			addr,
   118  		},
   119  	}}
   120  	op := &MintOperation{
   121  		MintInput: secp256k1fx.Input{
   122  			SigIndices: []uint32{0},
   123  		},
   124  	}
   125  
   126  	utxos := []interface{}{utxo}
   127  	err := fx.VerifyOperation(nil, op, cred, utxos)
   128  	require.ErrorIs(err, errWrongTxType)
   129  }
   130  
   131  func TestFxVerifyMintOperationWrongNumberUTXOs(t *testing.T) {
   132  	require := require.New(t)
   133  
   134  	vm := secp256k1fx.TestVM{
   135  		Codec: linearcodec.NewDefault(),
   136  		Log:   logging.NoLog{},
   137  	}
   138  	date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
   139  	vm.Clk.Set(date)
   140  
   141  	fx := Fx{}
   142  	require.NoError(fx.Initialize(&vm))
   143  	tx := &secp256k1fx.TestTx{
   144  		UnsignedBytes: txBytes,
   145  	}
   146  	cred := &Credential{Credential: secp256k1fx.Credential{
   147  		Sigs: [][secp256k1.SignatureLen]byte{
   148  			sigBytes,
   149  		},
   150  	}}
   151  	op := &MintOperation{
   152  		MintInput: secp256k1fx.Input{
   153  			SigIndices: []uint32{0},
   154  		},
   155  	}
   156  
   157  	utxos := []interface{}{}
   158  	err := fx.VerifyOperation(tx, op, cred, utxos)
   159  	require.ErrorIs(err, errWrongNumberOfUTXOs)
   160  }
   161  
   162  func TestFxVerifyMintOperationWrongCredential(t *testing.T) {
   163  	require := require.New(t)
   164  
   165  	vm := secp256k1fx.TestVM{
   166  		Codec: linearcodec.NewDefault(),
   167  		Log:   logging.NoLog{},
   168  	}
   169  	date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
   170  	vm.Clk.Set(date)
   171  
   172  	fx := Fx{}
   173  	require.NoError(fx.Initialize(&vm))
   174  	tx := &secp256k1fx.TestTx{
   175  		UnsignedBytes: txBytes,
   176  	}
   177  	utxo := &MintOutput{OutputOwners: secp256k1fx.OutputOwners{
   178  		Threshold: 1,
   179  		Addrs: []ids.ShortID{
   180  			addr,
   181  		},
   182  	}}
   183  	op := &MintOperation{
   184  		MintInput: secp256k1fx.Input{
   185  			SigIndices: []uint32{0},
   186  		},
   187  	}
   188  
   189  	utxos := []interface{}{utxo}
   190  	err := fx.VerifyOperation(tx, op, nil, utxos)
   191  	require.ErrorIs(err, errWrongCredentialType)
   192  }
   193  
   194  func TestFxVerifyMintOperationInvalidUTXO(t *testing.T) {
   195  	require := require.New(t)
   196  
   197  	vm := secp256k1fx.TestVM{
   198  		Codec: linearcodec.NewDefault(),
   199  		Log:   logging.NoLog{},
   200  	}
   201  	date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
   202  	vm.Clk.Set(date)
   203  
   204  	fx := Fx{}
   205  	require.NoError(fx.Initialize(&vm))
   206  	tx := &secp256k1fx.TestTx{
   207  		UnsignedBytes: txBytes,
   208  	}
   209  	cred := &Credential{Credential: secp256k1fx.Credential{
   210  		Sigs: [][secp256k1.SignatureLen]byte{
   211  			sigBytes,
   212  		},
   213  	}}
   214  	op := &MintOperation{
   215  		MintInput: secp256k1fx.Input{
   216  			SigIndices: []uint32{0},
   217  		},
   218  	}
   219  
   220  	utxos := []interface{}{nil}
   221  	err := fx.VerifyOperation(tx, op, cred, utxos)
   222  	require.ErrorIs(err, errWrongUTXOType)
   223  }
   224  
   225  func TestFxVerifyMintOperationFailingVerification(t *testing.T) {
   226  	require := require.New(t)
   227  
   228  	vm := secp256k1fx.TestVM{
   229  		Codec: linearcodec.NewDefault(),
   230  		Log:   logging.NoLog{},
   231  	}
   232  	date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
   233  	vm.Clk.Set(date)
   234  
   235  	fx := Fx{}
   236  	require.NoError(fx.Initialize(&vm))
   237  	tx := &secp256k1fx.TestTx{
   238  		UnsignedBytes: txBytes,
   239  	}
   240  	cred := &Credential{Credential: secp256k1fx.Credential{
   241  		Sigs: [][secp256k1.SignatureLen]byte{
   242  			sigBytes,
   243  		},
   244  	}}
   245  	utxo := &MintOutput{OutputOwners: secp256k1fx.OutputOwners{
   246  		Threshold: 1,
   247  		Addrs: []ids.ShortID{
   248  			addr,
   249  			ids.ShortEmpty,
   250  		},
   251  	}}
   252  	op := &MintOperation{
   253  		MintInput: secp256k1fx.Input{
   254  			SigIndices: []uint32{0},
   255  		},
   256  	}
   257  
   258  	utxos := []interface{}{utxo}
   259  	err := fx.VerifyOperation(tx, op, cred, utxos)
   260  	require.ErrorIs(err, secp256k1fx.ErrAddrsNotSortedUnique)
   261  }
   262  
   263  func TestFxVerifyMintOperationInvalidGroupID(t *testing.T) {
   264  	require := require.New(t)
   265  
   266  	vm := secp256k1fx.TestVM{
   267  		Codec: linearcodec.NewDefault(),
   268  		Log:   logging.NoLog{},
   269  	}
   270  	date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
   271  	vm.Clk.Set(date)
   272  
   273  	fx := Fx{}
   274  	require.NoError(fx.Initialize(&vm))
   275  	tx := &secp256k1fx.TestTx{
   276  		UnsignedBytes: txBytes,
   277  	}
   278  	cred := &Credential{Credential: secp256k1fx.Credential{
   279  		Sigs: [][secp256k1.SignatureLen]byte{
   280  			sigBytes,
   281  		},
   282  	}}
   283  	utxo := &MintOutput{OutputOwners: secp256k1fx.OutputOwners{
   284  		Threshold: 1,
   285  		Addrs: []ids.ShortID{
   286  			addr,
   287  		},
   288  	}}
   289  	op := &MintOperation{
   290  		MintInput: secp256k1fx.Input{
   291  			SigIndices: []uint32{0},
   292  		},
   293  	}
   294  
   295  	utxos := []interface{}{utxo}
   296  	err := fx.VerifyOperation(tx, op, cred, utxos)
   297  	require.ErrorIs(err, errWrongMintOutput)
   298  }
   299  
   300  func TestFxVerifyTransferOperation(t *testing.T) {
   301  	require := require.New(t)
   302  
   303  	vm := secp256k1fx.TestVM{
   304  		Codec: linearcodec.NewDefault(),
   305  		Log:   logging.NoLog{},
   306  	}
   307  	date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
   308  	vm.Clk.Set(date)
   309  
   310  	fx := Fx{}
   311  	require.NoError(fx.Initialize(&vm))
   312  	tx := &secp256k1fx.TestTx{
   313  		UnsignedBytes: txBytes,
   314  	}
   315  	cred := &Credential{Credential: secp256k1fx.Credential{
   316  		Sigs: [][secp256k1.SignatureLen]byte{
   317  			sigBytes,
   318  		},
   319  	}}
   320  	utxo := &OwnedOutput{OutputOwners: secp256k1fx.OutputOwners{
   321  		Threshold: 1,
   322  		Addrs: []ids.ShortID{
   323  			addr,
   324  		},
   325  	}}
   326  	op := &BurnOperation{Input: secp256k1fx.Input{
   327  		SigIndices: []uint32{0},
   328  	}}
   329  
   330  	utxos := []interface{}{utxo}
   331  	require.NoError(fx.VerifyOperation(tx, op, cred, utxos))
   332  }
   333  
   334  func TestFxVerifyTransferOperationWrongUTXO(t *testing.T) {
   335  	require := require.New(t)
   336  
   337  	vm := secp256k1fx.TestVM{
   338  		Codec: linearcodec.NewDefault(),
   339  		Log:   logging.NoLog{},
   340  	}
   341  	date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
   342  	vm.Clk.Set(date)
   343  
   344  	fx := Fx{}
   345  	require.NoError(fx.Initialize(&vm))
   346  	tx := &secp256k1fx.TestTx{
   347  		UnsignedBytes: txBytes,
   348  	}
   349  	cred := &Credential{Credential: secp256k1fx.Credential{
   350  		Sigs: [][secp256k1.SignatureLen]byte{
   351  			sigBytes,
   352  		},
   353  	}}
   354  	op := &BurnOperation{Input: secp256k1fx.Input{
   355  		SigIndices: []uint32{0},
   356  	}}
   357  
   358  	utxos := []interface{}{nil}
   359  	err := fx.VerifyOperation(tx, op, cred, utxos)
   360  	require.ErrorIs(err, errWrongUTXOType)
   361  }
   362  
   363  func TestFxVerifyTransferOperationFailedVerify(t *testing.T) {
   364  	require := require.New(t)
   365  
   366  	vm := secp256k1fx.TestVM{
   367  		Codec: linearcodec.NewDefault(),
   368  		Log:   logging.NoLog{},
   369  	}
   370  	date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
   371  	vm.Clk.Set(date)
   372  
   373  	fx := Fx{}
   374  	require.NoError(fx.Initialize(&vm))
   375  	tx := &secp256k1fx.TestTx{
   376  		UnsignedBytes: txBytes,
   377  	}
   378  	cred := &Credential{Credential: secp256k1fx.Credential{
   379  		Sigs: [][secp256k1.SignatureLen]byte{
   380  			sigBytes,
   381  		},
   382  	}}
   383  	utxo := &OwnedOutput{OutputOwners: secp256k1fx.OutputOwners{
   384  		Threshold: 1,
   385  		Addrs: []ids.ShortID{
   386  			addr,
   387  		},
   388  	}}
   389  	op := &BurnOperation{Input: secp256k1fx.Input{
   390  		SigIndices: []uint32{1, 0},
   391  	}}
   392  
   393  	utxos := []interface{}{utxo}
   394  	err := fx.VerifyOperation(tx, op, cred, utxos)
   395  	require.ErrorIs(err, secp256k1fx.ErrInputIndicesNotSortedUnique)
   396  }
   397  
   398  func TestFxVerifyOperationUnknownOperation(t *testing.T) {
   399  	require := require.New(t)
   400  
   401  	vm := secp256k1fx.TestVM{
   402  		Codec: linearcodec.NewDefault(),
   403  		Log:   logging.NoLog{},
   404  	}
   405  	date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
   406  	vm.Clk.Set(date)
   407  
   408  	fx := Fx{}
   409  	require.NoError(fx.Initialize(&vm))
   410  	tx := &secp256k1fx.TestTx{
   411  		UnsignedBytes: txBytes,
   412  	}
   413  	cred := &Credential{Credential: secp256k1fx.Credential{
   414  		Sigs: [][secp256k1.SignatureLen]byte{
   415  			sigBytes,
   416  		},
   417  	}}
   418  	utxo := &OwnedOutput{OutputOwners: secp256k1fx.OutputOwners{
   419  		Threshold: 1,
   420  		Addrs: []ids.ShortID{
   421  			addr,
   422  		},
   423  	}}
   424  
   425  	utxos := []interface{}{utxo}
   426  	err := fx.VerifyOperation(tx, nil, cred, utxos)
   427  	require.ErrorIs(err, errWrongOperationType)
   428  }
   429  
   430  func TestFxVerifyTransfer(t *testing.T) {
   431  	require := require.New(t)
   432  
   433  	vm := secp256k1fx.TestVM{
   434  		Codec: linearcodec.NewDefault(),
   435  		Log:   logging.NoLog{},
   436  	}
   437  	date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
   438  	vm.Clk.Set(date)
   439  
   440  	fx := Fx{}
   441  	require.NoError(fx.Initialize(&vm))
   442  	err := fx.VerifyTransfer(nil, nil, nil, nil)
   443  	require.ErrorIs(err, errCantTransfer)
   444  }