github.com/ava-labs/avalanchego@v1.11.11/vms/secp256k1fx/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 secp256k1fx 5 6 import ( 7 "testing" 8 "time" 9 10 "github.com/stretchr/testify/require" 11 12 "github.com/ava-labs/avalanchego/codec/linearcodec" 13 "github.com/ava-labs/avalanchego/ids" 14 "github.com/ava-labs/avalanchego/utils/cb58" 15 "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" 16 "github.com/ava-labs/avalanchego/utils/logging" 17 ) 18 19 var ( 20 txBytes = []byte{0, 1, 2, 3, 4, 5} 21 sigBytes = [secp256k1.SignatureLen]byte{ // signature of addr on txBytes 22 0x0e, 0x33, 0x4e, 0xbc, 0x67, 0xa7, 0x3f, 0xe8, 23 0x24, 0x33, 0xac, 0xa3, 0x47, 0x88, 0xa6, 0x3d, 24 0x58, 0xe5, 0x8e, 0xf0, 0x3a, 0xd5, 0x84, 0xf1, 25 0xbc, 0xa3, 0xb2, 0xd2, 0x5d, 0x51, 0xd6, 0x9b, 26 0x0f, 0x28, 0x5d, 0xcd, 0x3f, 0x71, 0x17, 0x0a, 27 0xf9, 0xbf, 0x2d, 0xb1, 0x10, 0x26, 0x5c, 0xe9, 28 0xdc, 0xc3, 0x9d, 0x7a, 0x01, 0x50, 0x9d, 0xe8, 29 0x35, 0xbd, 0xcb, 0x29, 0x3a, 0xd1, 0x49, 0x32, 30 0x00, 31 } 32 addr = ids.ShortID{ 33 0x01, 0x5c, 0xce, 0x6c, 0x55, 0xd6, 0xb5, 0x09, 34 0x84, 0x5c, 0x8c, 0x4e, 0x30, 0xbe, 0xd9, 0x8d, 35 0x39, 0x1a, 0xe7, 0xf0, 36 } 37 addr2 ids.ShortID 38 sig2Bytes [secp256k1.SignatureLen]byte // signature of addr2 on txBytes 39 ) 40 41 func init() { 42 b, err := cb58.Decode("31SoC6ehdWUWFcuzkXci7ymFEQ8HGTJgw") 43 if err != nil { 44 panic(err) 45 } 46 copy(addr2[:], b) 47 b, err = cb58.Decode("c7doHa86hWYyfXTVnNsdP1CG1gxhXVpZ9Q5CiHi2oFRdnaxh2YR2Mvu2cUNMgyQy4BNQaXAxWWPt36BJ5pDWX1Xeos4h9L") 48 if err != nil { 49 panic(err) 50 } 51 copy(sig2Bytes[:], b) 52 } 53 54 func TestFxInitialize(t *testing.T) { 55 vm := TestVM{ 56 Codec: linearcodec.NewDefault(), 57 Log: logging.NoLog{}, 58 } 59 fx := Fx{} 60 require.NoError(t, fx.Initialize(&vm)) 61 } 62 63 func TestFxInitializeInvalid(t *testing.T) { 64 fx := Fx{} 65 err := fx.Initialize(nil) 66 require.ErrorIs(t, err, ErrWrongVMType) 67 } 68 69 func TestFxVerifyTransfer(t *testing.T) { 70 require := require.New(t) 71 vm := TestVM{ 72 Codec: linearcodec.NewDefault(), 73 Log: logging.NoLog{}, 74 } 75 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 76 vm.Clk.Set(date) 77 fx := Fx{} 78 require.NoError(fx.Initialize(&vm)) 79 require.NoError(fx.Bootstrapping()) 80 require.NoError(fx.Bootstrapped()) 81 tx := &TestTx{UnsignedBytes: txBytes} 82 out := &TransferOutput{ 83 Amt: 1, 84 OutputOwners: OutputOwners{ 85 Locktime: 0, 86 Threshold: 1, 87 Addrs: []ids.ShortID{ 88 addr, 89 }, 90 }, 91 } 92 in := &TransferInput{ 93 Amt: 1, 94 Input: Input{ 95 SigIndices: []uint32{0}, 96 }, 97 } 98 cred := &Credential{ 99 Sigs: [][secp256k1.SignatureLen]byte{ 100 sigBytes, 101 }, 102 } 103 104 require.NoError(fx.VerifyTransfer(tx, in, cred, out)) 105 } 106 107 func TestFxVerifyTransferNilTx(t *testing.T) { 108 require := require.New(t) 109 vm := TestVM{ 110 Codec: linearcodec.NewDefault(), 111 Log: logging.NoLog{}, 112 } 113 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 114 vm.Clk.Set(date) 115 fx := Fx{} 116 require.NoError(fx.Initialize(&vm)) 117 out := &TransferOutput{ 118 Amt: 1, 119 OutputOwners: OutputOwners{ 120 Locktime: 0, 121 Threshold: 1, 122 Addrs: []ids.ShortID{ 123 addr, 124 }, 125 }, 126 } 127 in := &TransferInput{ 128 Amt: 1, 129 Input: Input{ 130 SigIndices: []uint32{0}, 131 }, 132 } 133 cred := &Credential{ 134 Sigs: [][secp256k1.SignatureLen]byte{ 135 sigBytes, 136 }, 137 } 138 139 err := fx.VerifyTransfer(nil, in, cred, out) 140 require.ErrorIs(err, ErrWrongTxType) 141 } 142 143 func TestFxVerifyTransferNilOutput(t *testing.T) { 144 require := require.New(t) 145 vm := TestVM{ 146 Codec: linearcodec.NewDefault(), 147 Log: logging.NoLog{}, 148 } 149 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 150 vm.Clk.Set(date) 151 fx := Fx{} 152 require.NoError(fx.Initialize(&vm)) 153 tx := &TestTx{UnsignedBytes: txBytes} 154 in := &TransferInput{ 155 Amt: 1, 156 Input: Input{ 157 SigIndices: []uint32{0}, 158 }, 159 } 160 cred := &Credential{ 161 Sigs: [][secp256k1.SignatureLen]byte{ 162 sigBytes, 163 }, 164 } 165 166 err := fx.VerifyTransfer(tx, in, cred, nil) 167 require.ErrorIs(err, ErrWrongUTXOType) 168 } 169 170 func TestFxVerifyTransferNilInput(t *testing.T) { 171 require := require.New(t) 172 vm := TestVM{ 173 Codec: linearcodec.NewDefault(), 174 Log: logging.NoLog{}, 175 } 176 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 177 vm.Clk.Set(date) 178 fx := Fx{} 179 require.NoError(fx.Initialize(&vm)) 180 tx := &TestTx{UnsignedBytes: txBytes} 181 out := &TransferOutput{ 182 Amt: 1, 183 OutputOwners: OutputOwners{ 184 Locktime: 0, 185 Threshold: 1, 186 Addrs: []ids.ShortID{ 187 addr, 188 }, 189 }, 190 } 191 cred := &Credential{ 192 Sigs: [][secp256k1.SignatureLen]byte{ 193 sigBytes, 194 }, 195 } 196 197 err := fx.VerifyTransfer(tx, nil, cred, out) 198 require.ErrorIs(err, ErrWrongInputType) 199 } 200 201 func TestFxVerifyTransferNilCredential(t *testing.T) { 202 require := require.New(t) 203 vm := TestVM{ 204 Codec: linearcodec.NewDefault(), 205 Log: logging.NoLog{}, 206 } 207 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 208 vm.Clk.Set(date) 209 fx := Fx{} 210 require.NoError(fx.Initialize(&vm)) 211 tx := &TestTx{UnsignedBytes: txBytes} 212 out := &TransferOutput{ 213 Amt: 1, 214 OutputOwners: OutputOwners{ 215 Locktime: 0, 216 Threshold: 1, 217 Addrs: []ids.ShortID{ 218 addr, 219 }, 220 }, 221 } 222 in := &TransferInput{ 223 Amt: 1, 224 Input: Input{ 225 SigIndices: []uint32{0}, 226 }, 227 } 228 229 err := fx.VerifyTransfer(tx, in, nil, out) 230 require.ErrorIs(err, ErrWrongCredentialType) 231 } 232 233 func TestFxVerifyTransferInvalidOutput(t *testing.T) { 234 require := require.New(t) 235 vm := TestVM{ 236 Codec: linearcodec.NewDefault(), 237 Log: logging.NoLog{}, 238 } 239 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 240 vm.Clk.Set(date) 241 fx := Fx{} 242 require.NoError(fx.Initialize(&vm)) 243 tx := &TestTx{UnsignedBytes: txBytes} 244 out := &TransferOutput{ 245 Amt: 1, 246 OutputOwners: OutputOwners{ 247 Locktime: 0, 248 Threshold: 0, 249 Addrs: []ids.ShortID{ 250 addr, 251 }, 252 }, 253 } 254 in := &TransferInput{ 255 Amt: 1, 256 Input: Input{ 257 SigIndices: []uint32{0}, 258 }, 259 } 260 cred := &Credential{ 261 Sigs: [][secp256k1.SignatureLen]byte{ 262 sigBytes, 263 }, 264 } 265 266 err := fx.VerifyTransfer(tx, in, cred, out) 267 require.ErrorIs(err, ErrOutputUnoptimized) 268 } 269 270 func TestFxVerifyTransferWrongAmounts(t *testing.T) { 271 require := require.New(t) 272 vm := TestVM{ 273 Codec: linearcodec.NewDefault(), 274 Log: logging.NoLog{}, 275 } 276 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 277 vm.Clk.Set(date) 278 fx := Fx{} 279 require.NoError(fx.Initialize(&vm)) 280 tx := &TestTx{UnsignedBytes: txBytes} 281 out := &TransferOutput{ 282 Amt: 1, 283 OutputOwners: OutputOwners{ 284 Locktime: 0, 285 Threshold: 1, 286 Addrs: []ids.ShortID{ 287 addr, 288 }, 289 }, 290 } 291 in := &TransferInput{ 292 Amt: 2, 293 Input: Input{ 294 SigIndices: []uint32{0}, 295 }, 296 } 297 cred := &Credential{ 298 Sigs: [][secp256k1.SignatureLen]byte{ 299 sigBytes, 300 }, 301 } 302 303 err := fx.VerifyTransfer(tx, in, cred, out) 304 require.ErrorIs(err, ErrMismatchedAmounts) 305 } 306 307 func TestFxVerifyTransferTimelocked(t *testing.T) { 308 require := require.New(t) 309 vm := TestVM{ 310 Codec: linearcodec.NewDefault(), 311 Log: logging.NoLog{}, 312 } 313 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 314 vm.Clk.Set(date) 315 fx := Fx{} 316 require.NoError(fx.Initialize(&vm)) 317 tx := &TestTx{UnsignedBytes: txBytes} 318 out := &TransferOutput{ 319 Amt: 1, 320 OutputOwners: OutputOwners{ 321 Locktime: uint64(date.Add(time.Second).Unix()), 322 Threshold: 1, 323 Addrs: []ids.ShortID{ 324 addr, 325 }, 326 }, 327 } 328 in := &TransferInput{ 329 Amt: 1, 330 Input: Input{ 331 SigIndices: []uint32{0}, 332 }, 333 } 334 cred := &Credential{ 335 Sigs: [][secp256k1.SignatureLen]byte{ 336 sigBytes, 337 }, 338 } 339 340 err := fx.VerifyTransfer(tx, in, cred, out) 341 require.ErrorIs(err, ErrTimelocked) 342 } 343 344 func TestFxVerifyTransferTooManySigners(t *testing.T) { 345 require := require.New(t) 346 vm := TestVM{ 347 Codec: linearcodec.NewDefault(), 348 Log: logging.NoLog{}, 349 } 350 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 351 vm.Clk.Set(date) 352 fx := Fx{} 353 require.NoError(fx.Initialize(&vm)) 354 tx := &TestTx{UnsignedBytes: txBytes} 355 out := &TransferOutput{ 356 Amt: 1, 357 OutputOwners: OutputOwners{ 358 Locktime: 0, 359 Threshold: 1, 360 Addrs: []ids.ShortID{ 361 addr, 362 }, 363 }, 364 } 365 in := &TransferInput{ 366 Amt: 1, 367 Input: Input{ 368 SigIndices: []uint32{0, 1}, 369 }, 370 } 371 cred := &Credential{ 372 Sigs: [][secp256k1.SignatureLen]byte{ 373 sigBytes, 374 {}, 375 }, 376 } 377 378 err := fx.VerifyTransfer(tx, in, cred, out) 379 require.ErrorIs(err, ErrTooManySigners) 380 } 381 382 func TestFxVerifyTransferTooFewSigners(t *testing.T) { 383 require := require.New(t) 384 vm := TestVM{ 385 Codec: linearcodec.NewDefault(), 386 Log: logging.NoLog{}, 387 } 388 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 389 vm.Clk.Set(date) 390 fx := Fx{} 391 require.NoError(fx.Initialize(&vm)) 392 tx := &TestTx{UnsignedBytes: txBytes} 393 out := &TransferOutput{ 394 Amt: 1, 395 OutputOwners: OutputOwners{ 396 Locktime: 0, 397 Threshold: 1, 398 Addrs: []ids.ShortID{ 399 addr, 400 }, 401 }, 402 } 403 in := &TransferInput{ 404 Amt: 1, 405 Input: Input{ 406 SigIndices: []uint32{}, 407 }, 408 } 409 cred := &Credential{ 410 Sigs: [][secp256k1.SignatureLen]byte{}, 411 } 412 413 err := fx.VerifyTransfer(tx, in, cred, out) 414 require.ErrorIs(err, ErrTooFewSigners) 415 } 416 417 func TestFxVerifyTransferMismatchedSigners(t *testing.T) { 418 require := require.New(t) 419 vm := TestVM{ 420 Codec: linearcodec.NewDefault(), 421 Log: logging.NoLog{}, 422 } 423 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 424 vm.Clk.Set(date) 425 fx := Fx{} 426 require.NoError(fx.Initialize(&vm)) 427 tx := &TestTx{UnsignedBytes: txBytes} 428 out := &TransferOutput{ 429 Amt: 1, 430 OutputOwners: OutputOwners{ 431 Locktime: 0, 432 Threshold: 1, 433 Addrs: []ids.ShortID{ 434 addr, 435 }, 436 }, 437 } 438 in := &TransferInput{ 439 Amt: 1, 440 Input: Input{ 441 SigIndices: []uint32{0}, 442 }, 443 } 444 cred := &Credential{ 445 Sigs: [][secp256k1.SignatureLen]byte{ 446 sigBytes, 447 {}, 448 }, 449 } 450 451 err := fx.VerifyTransfer(tx, in, cred, out) 452 require.ErrorIs(err, ErrInputCredentialSignersMismatch) 453 } 454 455 func TestFxVerifyTransferInvalidSignature(t *testing.T) { 456 require := require.New(t) 457 vm := TestVM{ 458 Codec: linearcodec.NewDefault(), 459 Log: logging.NoLog{}, 460 } 461 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 462 vm.Clk.Set(date) 463 fx := Fx{} 464 require.NoError(fx.Initialize(&vm)) 465 require.NoError(fx.Bootstrapping()) 466 tx := &TestTx{UnsignedBytes: txBytes} 467 out := &TransferOutput{ 468 Amt: 1, 469 OutputOwners: OutputOwners{ 470 Locktime: 0, 471 Threshold: 1, 472 Addrs: []ids.ShortID{ 473 addr, 474 }, 475 }, 476 } 477 in := &TransferInput{ 478 Amt: 1, 479 Input: Input{ 480 SigIndices: []uint32{0}, 481 }, 482 } 483 cred := &Credential{ 484 Sigs: [][secp256k1.SignatureLen]byte{ 485 {}, 486 }, 487 } 488 489 require.NoError(fx.VerifyTransfer(tx, in, cred, out)) 490 require.NoError(fx.Bootstrapped()) 491 err := fx.VerifyTransfer(tx, in, cred, out) 492 require.ErrorIs(err, secp256k1.ErrInvalidSig) 493 } 494 495 func TestFxVerifyTransferWrongSigner(t *testing.T) { 496 require := require.New(t) 497 vm := TestVM{ 498 Codec: linearcodec.NewDefault(), 499 Log: logging.NoLog{}, 500 } 501 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 502 vm.Clk.Set(date) 503 fx := Fx{} 504 require.NoError(fx.Initialize(&vm)) 505 require.NoError(fx.Bootstrapping()) 506 tx := &TestTx{UnsignedBytes: txBytes} 507 out := &TransferOutput{ 508 Amt: 1, 509 OutputOwners: OutputOwners{ 510 Locktime: 0, 511 Threshold: 1, 512 Addrs: []ids.ShortID{ 513 ids.ShortEmpty, 514 }, 515 }, 516 } 517 in := &TransferInput{ 518 Amt: 1, 519 Input: Input{ 520 SigIndices: []uint32{0}, 521 }, 522 } 523 cred := &Credential{ 524 Sigs: [][secp256k1.SignatureLen]byte{ 525 sigBytes, 526 }, 527 } 528 529 require.NoError(fx.VerifyTransfer(tx, in, cred, out)) 530 require.NoError(fx.Bootstrapped()) 531 err := fx.VerifyTransfer(tx, in, cred, out) 532 require.ErrorIs(err, ErrWrongSig) 533 } 534 535 func TestFxVerifyTransferSigIndexOOB(t *testing.T) { 536 require := require.New(t) 537 vm := TestVM{ 538 Codec: linearcodec.NewDefault(), 539 Log: logging.NoLog{}, 540 } 541 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 542 vm.Clk.Set(date) 543 fx := Fx{} 544 require.NoError(fx.Initialize(&vm)) 545 require.NoError(fx.Bootstrapping()) 546 tx := &TestTx{UnsignedBytes: txBytes} 547 out := &TransferOutput{ 548 Amt: 1, 549 OutputOwners: OutputOwners{ 550 Locktime: 0, 551 Threshold: 1, 552 Addrs: []ids.ShortID{ 553 addr, 554 }, 555 }, 556 } 557 in := &TransferInput{ 558 Amt: 1, 559 Input: Input{ 560 SigIndices: []uint32{1}, // There is no address at index 1 561 }, 562 } 563 cred := &Credential{ 564 Sigs: [][secp256k1.SignatureLen]byte{ 565 sigBytes, 566 }, 567 } 568 569 require.NoError(fx.VerifyTransfer(tx, in, cred, out)) 570 require.NoError(fx.Bootstrapped()) 571 err := fx.VerifyTransfer(tx, in, cred, out) 572 require.ErrorIs(err, ErrInputOutputIndexOutOfBounds) 573 } 574 575 func TestFxVerifyOperation(t *testing.T) { 576 require := require.New(t) 577 vm := TestVM{ 578 Codec: linearcodec.NewDefault(), 579 Log: logging.NoLog{}, 580 } 581 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 582 vm.Clk.Set(date) 583 fx := Fx{} 584 require.NoError(fx.Initialize(&vm)) 585 tx := &TestTx{UnsignedBytes: txBytes} 586 utxo := &MintOutput{ 587 OutputOwners: OutputOwners{ 588 Threshold: 1, 589 Addrs: []ids.ShortID{ 590 addr, 591 }, 592 }, 593 } 594 op := &MintOperation{ 595 MintInput: Input{ 596 SigIndices: []uint32{0}, 597 }, 598 MintOutput: MintOutput{ 599 OutputOwners: OutputOwners{ 600 Threshold: 1, 601 Addrs: []ids.ShortID{ 602 addr, 603 }, 604 }, 605 }, 606 TransferOutput: TransferOutput{ 607 Amt: 1, 608 OutputOwners: OutputOwners{ 609 Locktime: 0, 610 Threshold: 1, 611 Addrs: []ids.ShortID{ 612 addr, 613 }, 614 }, 615 }, 616 } 617 cred := &Credential{ 618 Sigs: [][secp256k1.SignatureLen]byte{ 619 sigBytes, 620 }, 621 } 622 623 utxos := []interface{}{utxo} 624 require.NoError(fx.VerifyOperation(tx, op, cred, utxos)) 625 } 626 627 func TestFxVerifyOperationUnknownTx(t *testing.T) { 628 require := require.New(t) 629 vm := TestVM{ 630 Codec: linearcodec.NewDefault(), 631 Log: logging.NoLog{}, 632 } 633 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 634 vm.Clk.Set(date) 635 fx := Fx{} 636 require.NoError(fx.Initialize(&vm)) 637 utxo := &MintOutput{ 638 OutputOwners: OutputOwners{ 639 Threshold: 1, 640 Addrs: []ids.ShortID{ 641 addr, 642 }, 643 }, 644 } 645 op := &MintOperation{ 646 MintInput: Input{ 647 SigIndices: []uint32{0}, 648 }, 649 MintOutput: MintOutput{ 650 OutputOwners: OutputOwners{ 651 Threshold: 1, 652 Addrs: []ids.ShortID{ 653 addr, 654 }, 655 }, 656 }, 657 TransferOutput: TransferOutput{ 658 Amt: 1, 659 OutputOwners: OutputOwners{ 660 Locktime: 0, 661 Threshold: 1, 662 Addrs: []ids.ShortID{ 663 addr, 664 }, 665 }, 666 }, 667 } 668 cred := &Credential{ 669 Sigs: [][secp256k1.SignatureLen]byte{ 670 sigBytes, 671 }, 672 } 673 674 utxos := []interface{}{utxo} 675 err := fx.VerifyOperation(nil, op, cred, utxos) 676 require.ErrorIs(err, ErrWrongTxType) 677 } 678 679 func TestFxVerifyOperationUnknownOperation(t *testing.T) { 680 require := require.New(t) 681 vm := TestVM{ 682 Codec: linearcodec.NewDefault(), 683 Log: logging.NoLog{}, 684 } 685 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 686 vm.Clk.Set(date) 687 fx := Fx{} 688 require.NoError(fx.Initialize(&vm)) 689 tx := &TestTx{UnsignedBytes: txBytes} 690 utxo := &MintOutput{ 691 OutputOwners: OutputOwners{ 692 Threshold: 1, 693 Addrs: []ids.ShortID{ 694 addr, 695 }, 696 }, 697 } 698 cred := &Credential{ 699 Sigs: [][secp256k1.SignatureLen]byte{ 700 sigBytes, 701 }, 702 } 703 704 utxos := []interface{}{utxo} 705 err := fx.VerifyOperation(tx, nil, cred, utxos) 706 require.ErrorIs(err, ErrWrongOpType) 707 } 708 709 func TestFxVerifyOperationUnknownCredential(t *testing.T) { 710 require := require.New(t) 711 vm := TestVM{ 712 Codec: linearcodec.NewDefault(), 713 Log: logging.NoLog{}, 714 } 715 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 716 vm.Clk.Set(date) 717 fx := Fx{} 718 require.NoError(fx.Initialize(&vm)) 719 tx := &TestTx{UnsignedBytes: txBytes} 720 utxo := &MintOutput{ 721 OutputOwners: OutputOwners{ 722 Threshold: 1, 723 Addrs: []ids.ShortID{ 724 addr, 725 }, 726 }, 727 } 728 op := &MintOperation{ 729 MintInput: Input{ 730 SigIndices: []uint32{0}, 731 }, 732 MintOutput: MintOutput{ 733 OutputOwners: OutputOwners{ 734 Threshold: 1, 735 Addrs: []ids.ShortID{ 736 addr, 737 }, 738 }, 739 }, 740 TransferOutput: TransferOutput{ 741 Amt: 1, 742 OutputOwners: OutputOwners{ 743 Locktime: 0, 744 Threshold: 1, 745 Addrs: []ids.ShortID{ 746 addr, 747 }, 748 }, 749 }, 750 } 751 752 utxos := []interface{}{utxo} 753 err := fx.VerifyOperation(tx, op, nil, utxos) 754 require.ErrorIs(err, ErrWrongCredentialType) 755 } 756 757 func TestFxVerifyOperationWrongNumberOfUTXOs(t *testing.T) { 758 require := require.New(t) 759 vm := TestVM{ 760 Codec: linearcodec.NewDefault(), 761 Log: logging.NoLog{}, 762 } 763 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 764 vm.Clk.Set(date) 765 fx := Fx{} 766 require.NoError(fx.Initialize(&vm)) 767 tx := &TestTx{UnsignedBytes: txBytes} 768 utxo := &MintOutput{ 769 OutputOwners: OutputOwners{ 770 Threshold: 1, 771 Addrs: []ids.ShortID{ 772 addr, 773 }, 774 }, 775 } 776 op := &MintOperation{ 777 MintInput: Input{ 778 SigIndices: []uint32{0}, 779 }, 780 MintOutput: MintOutput{ 781 OutputOwners: OutputOwners{ 782 Threshold: 1, 783 Addrs: []ids.ShortID{ 784 addr, 785 }, 786 }, 787 }, 788 TransferOutput: TransferOutput{ 789 Amt: 1, 790 OutputOwners: OutputOwners{ 791 Locktime: 0, 792 Threshold: 1, 793 Addrs: []ids.ShortID{ 794 addr, 795 }, 796 }, 797 }, 798 } 799 cred := &Credential{ 800 Sigs: [][secp256k1.SignatureLen]byte{ 801 sigBytes, 802 }, 803 } 804 805 utxos := []interface{}{utxo, utxo} 806 err := fx.VerifyOperation(tx, op, cred, utxos) 807 require.ErrorIs(err, ErrWrongNumberOfUTXOs) 808 } 809 810 func TestFxVerifyOperationUnknownUTXOType(t *testing.T) { 811 require := require.New(t) 812 vm := TestVM{ 813 Codec: linearcodec.NewDefault(), 814 Log: logging.NoLog{}, 815 } 816 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 817 vm.Clk.Set(date) 818 fx := Fx{} 819 require.NoError(fx.Initialize(&vm)) 820 tx := &TestTx{UnsignedBytes: txBytes} 821 op := &MintOperation{ 822 MintInput: Input{ 823 SigIndices: []uint32{0}, 824 }, 825 MintOutput: MintOutput{ 826 OutputOwners: OutputOwners{ 827 Threshold: 1, 828 Addrs: []ids.ShortID{ 829 addr, 830 }, 831 }, 832 }, 833 TransferOutput: TransferOutput{ 834 Amt: 1, 835 OutputOwners: OutputOwners{ 836 Locktime: 0, 837 Threshold: 1, 838 Addrs: []ids.ShortID{ 839 addr, 840 }, 841 }, 842 }, 843 } 844 cred := &Credential{ 845 Sigs: [][secp256k1.SignatureLen]byte{ 846 sigBytes, 847 }, 848 } 849 850 utxos := []interface{}{nil} 851 err := fx.VerifyOperation(tx, op, cred, utxos) 852 require.ErrorIs(err, ErrWrongUTXOType) 853 } 854 855 func TestFxVerifyOperationInvalidOperationVerify(t *testing.T) { 856 require := require.New(t) 857 vm := TestVM{ 858 Codec: linearcodec.NewDefault(), 859 Log: logging.NoLog{}, 860 } 861 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 862 vm.Clk.Set(date) 863 fx := Fx{} 864 require.NoError(fx.Initialize(&vm)) 865 tx := &TestTx{UnsignedBytes: txBytes} 866 utxo := &MintOutput{ 867 OutputOwners: OutputOwners{ 868 Threshold: 1, 869 Addrs: []ids.ShortID{ 870 addr, 871 }, 872 }, 873 } 874 op := &MintOperation{ 875 MintInput: Input{ 876 SigIndices: []uint32{0}, 877 }, 878 MintOutput: MintOutput{ 879 OutputOwners: OutputOwners{ 880 Threshold: 1, 881 Addrs: []ids.ShortID{ 882 addr, 883 }, 884 }, 885 }, 886 TransferOutput: TransferOutput{ 887 Amt: 1, 888 OutputOwners: OutputOwners{ 889 Locktime: 0, 890 Threshold: 1, 891 }, 892 }, 893 } 894 cred := &Credential{ 895 Sigs: [][secp256k1.SignatureLen]byte{ 896 sigBytes, 897 }, 898 } 899 900 utxos := []interface{}{utxo} 901 err := fx.VerifyOperation(tx, op, cred, utxos) 902 require.ErrorIs(err, ErrOutputUnspendable) 903 } 904 905 func TestFxVerifyOperationMismatchedMintOutputs(t *testing.T) { 906 require := require.New(t) 907 vm := TestVM{ 908 Codec: linearcodec.NewDefault(), 909 Log: logging.NoLog{}, 910 } 911 date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) 912 vm.Clk.Set(date) 913 fx := Fx{} 914 require.NoError(fx.Initialize(&vm)) 915 tx := &TestTx{UnsignedBytes: txBytes} 916 utxo := &MintOutput{ 917 OutputOwners: OutputOwners{ 918 Threshold: 1, 919 Addrs: []ids.ShortID{ 920 addr, 921 }, 922 }, 923 } 924 op := &MintOperation{ 925 MintInput: Input{ 926 SigIndices: []uint32{0}, 927 }, 928 MintOutput: MintOutput{ 929 OutputOwners: OutputOwners{}, 930 }, 931 TransferOutput: TransferOutput{ 932 Amt: 1, 933 OutputOwners: OutputOwners{ 934 Locktime: 0, 935 Threshold: 1, 936 Addrs: []ids.ShortID{ 937 addr, 938 }, 939 }, 940 }, 941 } 942 cred := &Credential{ 943 Sigs: [][secp256k1.SignatureLen]byte{ 944 sigBytes, 945 }, 946 } 947 948 utxos := []interface{}{utxo} 949 err := fx.VerifyOperation(tx, op, cred, utxos) 950 require.ErrorIs(err, ErrWrongMintCreated) 951 } 952 953 func TestVerifyPermission(t *testing.T) { 954 vm := TestVM{ 955 Codec: linearcodec.NewDefault(), 956 Log: logging.NoLog{}, 957 } 958 fx := Fx{} 959 require.NoError(t, fx.Initialize(&vm)) 960 require.NoError(t, fx.Bootstrapping()) 961 require.NoError(t, fx.Bootstrapped()) 962 963 now := time.Now() 964 fx.VM.Clock().Set(now) 965 966 type test struct { 967 description string 968 tx UnsignedTx 969 in *Input 970 cred *Credential 971 cg *OutputOwners 972 expectedErr error 973 } 974 tests := []test{ 975 { 976 "threshold 0, no sigs, has addrs", 977 &TestTx{UnsignedBytes: txBytes}, 978 &Input{SigIndices: []uint32{}}, 979 &Credential{Sigs: [][secp256k1.SignatureLen]byte{}}, 980 &OutputOwners{ 981 Threshold: 0, 982 Addrs: []ids.ShortID{addr}, 983 }, 984 ErrOutputUnoptimized, 985 }, 986 { 987 "threshold 0, no sigs, no addrs", 988 &TestTx{UnsignedBytes: txBytes}, 989 &Input{SigIndices: []uint32{}}, 990 &Credential{Sigs: [][secp256k1.SignatureLen]byte{}}, 991 &OutputOwners{ 992 Threshold: 0, 993 Addrs: []ids.ShortID{}, 994 }, 995 nil, 996 }, 997 { 998 "threshold 1, 1 sig", 999 &TestTx{UnsignedBytes: txBytes}, 1000 &Input{SigIndices: []uint32{0}}, 1001 &Credential{Sigs: [][secp256k1.SignatureLen]byte{sigBytes}}, 1002 &OutputOwners{ 1003 Threshold: 1, 1004 Addrs: []ids.ShortID{addr}, 1005 }, 1006 nil, 1007 }, 1008 { 1009 "threshold 0, 1 sig (too many sigs)", 1010 &TestTx{UnsignedBytes: txBytes}, 1011 &Input{SigIndices: []uint32{0}}, 1012 &Credential{Sigs: [][secp256k1.SignatureLen]byte{sigBytes}}, 1013 &OutputOwners{ 1014 Threshold: 0, 1015 Addrs: []ids.ShortID{addr}, 1016 }, 1017 ErrOutputUnoptimized, 1018 }, 1019 { 1020 "threshold 1, 0 sigs (too few sigs)", 1021 &TestTx{UnsignedBytes: txBytes}, 1022 &Input{SigIndices: []uint32{}}, 1023 &Credential{Sigs: [][secp256k1.SignatureLen]byte{}}, 1024 &OutputOwners{ 1025 Threshold: 1, 1026 Addrs: []ids.ShortID{addr}, 1027 }, 1028 ErrTooFewSigners, 1029 }, 1030 { 1031 "threshold 1, 1 incorrect sig", 1032 &TestTx{UnsignedBytes: txBytes}, 1033 &Input{SigIndices: []uint32{0}}, 1034 &Credential{Sigs: [][secp256k1.SignatureLen]byte{sigBytes}}, 1035 &OutputOwners{ 1036 Threshold: 1, 1037 Addrs: []ids.ShortID{ids.GenerateTestShortID()}, 1038 }, 1039 ErrWrongSig, 1040 }, 1041 { 1042 "repeated sig", 1043 &TestTx{UnsignedBytes: txBytes}, 1044 &Input{SigIndices: []uint32{0, 0}}, 1045 &Credential{Sigs: [][secp256k1.SignatureLen]byte{sigBytes, sigBytes}}, 1046 &OutputOwners{ 1047 Threshold: 2, 1048 Addrs: []ids.ShortID{addr, addr2}, 1049 }, 1050 ErrInputIndicesNotSortedUnique, 1051 }, 1052 { 1053 "threshold 2, repeated address and repeated sig", 1054 &TestTx{UnsignedBytes: txBytes}, 1055 &Input{SigIndices: []uint32{0, 1}}, 1056 &Credential{Sigs: [][secp256k1.SignatureLen]byte{sigBytes, sigBytes}}, 1057 &OutputOwners{ 1058 Threshold: 2, 1059 Addrs: []ids.ShortID{addr, addr}, 1060 }, 1061 ErrAddrsNotSortedUnique, 1062 }, 1063 { 1064 "threshold 2, 2 sigs", 1065 &TestTx{UnsignedBytes: txBytes}, 1066 &Input{SigIndices: []uint32{0, 1}}, 1067 &Credential{Sigs: [][secp256k1.SignatureLen]byte{sigBytes, sig2Bytes}}, 1068 &OutputOwners{ 1069 Threshold: 2, 1070 Addrs: []ids.ShortID{addr, addr2}, 1071 }, 1072 nil, 1073 }, 1074 { 1075 "threshold 2, 2 sigs reversed (should be sorted)", 1076 &TestTx{UnsignedBytes: txBytes}, 1077 &Input{SigIndices: []uint32{1, 0}}, 1078 &Credential{Sigs: [][secp256k1.SignatureLen]byte{sig2Bytes, sigBytes}}, 1079 &OutputOwners{ 1080 Threshold: 2, 1081 Addrs: []ids.ShortID{addr, addr2}, 1082 }, 1083 ErrInputIndicesNotSortedUnique, 1084 }, 1085 { 1086 "threshold 1, 1 sig, index out of bounds", 1087 &TestTx{UnsignedBytes: txBytes}, 1088 &Input{SigIndices: []uint32{1}}, 1089 &Credential{Sigs: [][secp256k1.SignatureLen]byte{sigBytes}}, 1090 &OutputOwners{ 1091 Threshold: 1, 1092 Addrs: []ids.ShortID{addr}, 1093 }, 1094 ErrInputOutputIndexOutOfBounds, 1095 }, 1096 { 1097 "too many signers", 1098 &TestTx{UnsignedBytes: txBytes}, 1099 &Input{SigIndices: []uint32{0, 1}}, 1100 &Credential{Sigs: [][secp256k1.SignatureLen]byte{sigBytes, sig2Bytes}}, 1101 &OutputOwners{ 1102 Threshold: 1, 1103 Addrs: []ids.ShortID{addr, addr2}, 1104 }, 1105 ErrTooManySigners, 1106 }, 1107 { 1108 "number of signatures doesn't match", 1109 &TestTx{UnsignedBytes: txBytes}, 1110 &Input{SigIndices: []uint32{0}}, 1111 &Credential{Sigs: [][secp256k1.SignatureLen]byte{sigBytes, sig2Bytes}}, 1112 &OutputOwners{ 1113 Threshold: 1, 1114 Addrs: []ids.ShortID{addr, addr2}, 1115 }, 1116 ErrInputCredentialSignersMismatch, 1117 }, 1118 { 1119 "output is locked", 1120 &TestTx{UnsignedBytes: txBytes}, 1121 &Input{SigIndices: []uint32{0}}, 1122 &Credential{Sigs: [][secp256k1.SignatureLen]byte{sigBytes, sig2Bytes}}, 1123 &OutputOwners{ 1124 Threshold: 1, 1125 Locktime: uint64(now.Add(time.Second).Unix()), 1126 Addrs: []ids.ShortID{addr, addr2}, 1127 }, 1128 ErrTimelocked, 1129 }, 1130 } 1131 1132 for _, test := range tests { 1133 t.Run(test.description, func(t *testing.T) { 1134 err := fx.VerifyPermission(test.tx, test.in, test.cred, test.cg) 1135 require.ErrorIs(t, err, test.expectedErr) 1136 }) 1137 } 1138 }