github.com/MetalBlockchain/metalgo@v1.11.9/vms/avm/txs/operation_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 txs 5 6 import ( 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 11 "github.com/MetalBlockchain/metalgo/codec" 12 "github.com/MetalBlockchain/metalgo/codec/linearcodec" 13 "github.com/MetalBlockchain/metalgo/ids" 14 "github.com/MetalBlockchain/metalgo/snow" 15 "github.com/MetalBlockchain/metalgo/vms/components/avax" 16 "github.com/MetalBlockchain/metalgo/vms/components/verify" 17 ) 18 19 type testOperable struct { 20 avax.TestTransferable `serialize:"true"` 21 22 Outputs []verify.State `serialize:"true"` 23 } 24 25 func (*testOperable) InitCtx(*snow.Context) {} 26 27 func (o *testOperable) Outs() []verify.State { 28 return o.Outputs 29 } 30 31 func TestOperationVerifyNil(t *testing.T) { 32 op := (*Operation)(nil) 33 err := op.Verify() 34 require.ErrorIs(t, err, ErrNilOperation) 35 } 36 37 func TestOperationVerifyEmpty(t *testing.T) { 38 op := &Operation{ 39 Asset: avax.Asset{ID: ids.Empty}, 40 } 41 err := op.Verify() 42 require.ErrorIs(t, err, ErrNilFxOperation) 43 } 44 45 func TestOperationVerifyUTXOIDsNotSorted(t *testing.T) { 46 op := &Operation{ 47 Asset: avax.Asset{ID: ids.Empty}, 48 UTXOIDs: []*avax.UTXOID{ 49 { 50 TxID: ids.Empty, 51 OutputIndex: 1, 52 }, 53 { 54 TxID: ids.Empty, 55 OutputIndex: 0, 56 }, 57 }, 58 Op: &testOperable{}, 59 } 60 err := op.Verify() 61 require.ErrorIs(t, err, ErrNotSortedAndUniqueUTXOIDs) 62 } 63 64 func TestOperationVerify(t *testing.T) { 65 assetID := ids.GenerateTestID() 66 op := &Operation{ 67 Asset: avax.Asset{ID: assetID}, 68 UTXOIDs: []*avax.UTXOID{ 69 { 70 TxID: assetID, 71 OutputIndex: 1, 72 }, 73 }, 74 Op: &testOperable{}, 75 } 76 require.NoError(t, op.Verify()) 77 } 78 79 func TestOperationSorting(t *testing.T) { 80 require := require.New(t) 81 82 c := linearcodec.NewDefault() 83 require.NoError(c.RegisterType(&testOperable{})) 84 85 m := codec.NewDefaultManager() 86 require.NoError(m.RegisterCodec(CodecVersion, c)) 87 88 ops := []*Operation{ 89 { 90 Asset: avax.Asset{ID: ids.Empty}, 91 UTXOIDs: []*avax.UTXOID{ 92 { 93 TxID: ids.Empty, 94 OutputIndex: 1, 95 }, 96 }, 97 Op: &testOperable{}, 98 }, 99 { 100 Asset: avax.Asset{ID: ids.Empty}, 101 UTXOIDs: []*avax.UTXOID{ 102 { 103 TxID: ids.Empty, 104 OutputIndex: 0, 105 }, 106 }, 107 Op: &testOperable{}, 108 }, 109 } 110 require.False(IsSortedAndUniqueOperations(ops, m)) 111 SortOperations(ops, m) 112 require.True(IsSortedAndUniqueOperations(ops, m)) 113 ops = append(ops, &Operation{ 114 Asset: avax.Asset{ID: ids.Empty}, 115 UTXOIDs: []*avax.UTXOID{ 116 { 117 TxID: ids.Empty, 118 OutputIndex: 1, 119 }, 120 }, 121 Op: &testOperable{}, 122 }) 123 require.False(IsSortedAndUniqueOperations(ops, m)) 124 } 125 126 func TestOperationTxNotState(t *testing.T) { 127 intf := interface{}(&OperationTx{}) 128 _, ok := intf.(verify.State) 129 require.False(t, ok) 130 }