github.com/MetalBlockchain/metalgo@v1.11.9/vms/secp256k1fx/transfer_output_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/MetalBlockchain/metalgo/codec" 12 "github.com/MetalBlockchain/metalgo/codec/linearcodec" 13 "github.com/MetalBlockchain/metalgo/ids" 14 "github.com/MetalBlockchain/metalgo/vms/components/verify" 15 ) 16 17 func TestOutputAmount(t *testing.T) { 18 require := require.New(t) 19 out := TransferOutput{ 20 Amt: 1, 21 OutputOwners: OutputOwners{ 22 Locktime: 1, 23 Threshold: 1, 24 Addrs: []ids.ShortID{ 25 ids.ShortEmpty, 26 }, 27 }, 28 } 29 require.Equal(uint64(1), out.Amount()) 30 } 31 32 func TestOutputVerify(t *testing.T) { 33 require := require.New(t) 34 out := TransferOutput{ 35 Amt: 1, 36 OutputOwners: OutputOwners{ 37 Locktime: 1, 38 Threshold: 1, 39 Addrs: []ids.ShortID{ 40 ids.ShortEmpty, 41 }, 42 }, 43 } 44 require.NoError(out.Verify()) 45 } 46 47 func TestOutputVerifyNil(t *testing.T) { 48 require := require.New(t) 49 out := (*TransferOutput)(nil) 50 err := out.Verify() 51 require.ErrorIs(err, ErrNilOutput) 52 } 53 54 func TestOutputVerifyNoValue(t *testing.T) { 55 require := require.New(t) 56 out := TransferOutput{ 57 Amt: 0, 58 OutputOwners: OutputOwners{ 59 Locktime: 1, 60 Threshold: 1, 61 Addrs: []ids.ShortID{ 62 ids.ShortEmpty, 63 }, 64 }, 65 } 66 err := out.Verify() 67 require.ErrorIs(err, ErrNoValueOutput) 68 } 69 70 func TestOutputVerifyUnspendable(t *testing.T) { 71 require := require.New(t) 72 out := TransferOutput{ 73 Amt: 1, 74 OutputOwners: OutputOwners{ 75 Locktime: 1, 76 Threshold: 2, 77 Addrs: []ids.ShortID{ 78 ids.ShortEmpty, 79 }, 80 }, 81 } 82 err := out.Verify() 83 require.ErrorIs(err, ErrOutputUnspendable) 84 } 85 86 func TestOutputVerifyUnoptimized(t *testing.T) { 87 require := require.New(t) 88 out := TransferOutput{ 89 Amt: 1, 90 OutputOwners: OutputOwners{ 91 Locktime: 1, 92 Threshold: 0, 93 Addrs: []ids.ShortID{ 94 ids.ShortEmpty, 95 }, 96 }, 97 } 98 err := out.Verify() 99 require.ErrorIs(err, ErrOutputUnoptimized) 100 } 101 102 func TestOutputVerifyUnsorted(t *testing.T) { 103 require := require.New(t) 104 out := TransferOutput{ 105 Amt: 1, 106 OutputOwners: OutputOwners{ 107 Locktime: 1, 108 Threshold: 1, 109 Addrs: []ids.ShortID{ 110 {1}, 111 {0}, 112 }, 113 }, 114 } 115 err := out.Verify() 116 require.ErrorIs(err, ErrAddrsNotSortedUnique) 117 } 118 119 func TestOutputVerifyDuplicated(t *testing.T) { 120 require := require.New(t) 121 out := TransferOutput{ 122 Amt: 1, 123 OutputOwners: OutputOwners{ 124 Locktime: 1, 125 Threshold: 1, 126 Addrs: []ids.ShortID{ 127 ids.ShortEmpty, 128 ids.ShortEmpty, 129 }, 130 }, 131 } 132 err := out.Verify() 133 require.ErrorIs(err, ErrAddrsNotSortedUnique) 134 } 135 136 func TestOutputSerialize(t *testing.T) { 137 require := require.New(t) 138 c := linearcodec.NewDefault() 139 m := codec.NewDefaultManager() 140 require.NoError(m.RegisterCodec(0, c)) 141 142 expected := []byte{ 143 // Codec version 144 0x00, 0x00, 145 // amount: 146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 147 // locktime: 148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, 149 // threshold: 150 0x00, 0x00, 0x00, 0x01, 151 // number of addresses: 152 0x00, 0x00, 0x00, 0x02, 153 // addrs[0]: 154 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 155 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 156 0x6d, 0x55, 0xa9, 0x55, 157 // addrs[1]: 158 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 159 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 160 0x43, 0xab, 0x08, 0x59, 161 } 162 out := TransferOutput{ 163 Amt: 12345, 164 OutputOwners: OutputOwners{ 165 Locktime: 54321, 166 Threshold: 1, 167 Addrs: []ids.ShortID{ 168 { 169 0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78, 170 0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2, 171 0x6d, 0x55, 0xa9, 0x55, 172 }, 173 { 174 0xc3, 0x34, 0x41, 0x28, 0xe0, 0x60, 0x12, 0x8e, 175 0xde, 0x35, 0x23, 0xa2, 0x4a, 0x46, 0x1c, 0x89, 176 0x43, 0xab, 0x08, 0x59, 177 }, 178 }, 179 }, 180 } 181 require.NoError(out.Verify()) 182 183 result, err := m.Marshal(0, &out) 184 require.NoError(err) 185 require.Equal(expected, result) 186 } 187 188 func TestOutputAddresses(t *testing.T) { 189 require := require.New(t) 190 out := TransferOutput{ 191 Amt: 12345, 192 OutputOwners: OutputOwners{ 193 Locktime: 54321, 194 Threshold: 1, 195 Addrs: []ids.ShortID{ 196 { 197 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 198 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 199 0x10, 0x11, 0x12, 0x13, 200 }, 201 { 202 0x14, 0x15, 0x16, 0x17, 203 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 204 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 205 }, 206 }, 207 }, 208 } 209 require.NoError(out.Verify()) 210 require.Equal([][]byte{ 211 out.Addrs[0].Bytes(), 212 out.Addrs[1].Bytes(), 213 }, out.Addresses()) 214 } 215 216 func TestTransferOutputState(t *testing.T) { 217 require := require.New(t) 218 intf := interface{}(&TransferOutput{}) 219 _, ok := intf.(verify.State) 220 require.True(ok) 221 }