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 }