@@ -350,7 +350,6 @@ func TestIsKeyInCommittee(t *testing.T) {
350
350
ParamsVersion : pVersionWithCovenant ,
351
351
}
352
352
353
- // simple mock with the parameter versions
354
353
paramsGet := NewMockParam (map [uint32 ]* types.StakingParams {
355
354
pVersionWithoutCovenant : paramsWithoutCovenant ,
356
355
pVersionWithCovenant : paramsWithCovenant ,
@@ -411,3 +410,134 @@ func NewMockParamError(err error) *MockParamError {
411
410
func (m * MockParamError ) Get (version uint32 ) (* types.StakingParams , error ) {
412
411
return nil , m .err
413
412
}
413
+
414
+ func TestValidateStakeExpansion (t * testing.T ) {
415
+ r := rand .New (rand .NewSource (time .Now ().Unix ()))
416
+
417
+ covenantConfig := covcfg .DefaultConfig ()
418
+ covenantConfig .BabylonConfig .KeyDirectory = t .TempDir ()
419
+
420
+ covKeyPairInCommittee , err := keyring .CreateCovenantKey (
421
+ covenantConfig .BabylonConfig .KeyDirectory ,
422
+ covenantConfig .BabylonConfig .ChainID ,
423
+ covenantConfig .BabylonConfig .Key ,
424
+ covenantConfig .BabylonConfig .KeyringBackend ,
425
+ passphrase ,
426
+ hdPath ,
427
+ )
428
+ require .NoError (t , err )
429
+
430
+ covKeyInCommittee := schnorr .SerializePubKey (covKeyPairInCommittee .PublicKey )
431
+ pubKeyFromSchnorr , err := schnorr .ParsePubKey (covKeyInCommittee )
432
+ require .NoError (t , err )
433
+
434
+ badCovKey , err := keyring .CreateCovenantKey (
435
+ covenantConfig .BabylonConfig .KeyDirectory ,
436
+ covenantConfig .BabylonConfig .ChainID ,
437
+ "other-covenant-key" ,
438
+ covenantConfig .BabylonConfig .KeyringBackend ,
439
+ passphrase ,
440
+ hdPath ,
441
+ )
442
+ require .NoError (t , err )
443
+ covKeyNotInCommittee := schnorr .SerializePubKey (badCovKey .PublicKey )
444
+
445
+ pVersionWithoutCovenant := uint32 (datagen .RandomInRange (r , 1 , 10 ))
446
+ pVersionWithCovenant := pVersionWithoutCovenant + 1
447
+
448
+ paramsWithoutCovenant := testutil .GenRandomParams (r , t )
449
+ paramsWithCovenant := testutil .GenRandomParams (r , t )
450
+ paramsWithCovenant .CovenantPks = append (paramsWithCovenant .CovenantPks , covKeyPairInCommittee .PublicKey )
451
+
452
+ paramsGet := NewMockParam (map [uint32 ]* types.StakingParams {
453
+ pVersionWithoutCovenant : paramsWithoutCovenant ,
454
+ pVersionWithCovenant : paramsWithCovenant ,
455
+ })
456
+
457
+ stkTxHex := "02000000012c1ca601b81bf5bdd97081d1bf17241d4d688f51ccbe8be3d3f3174d0e4e4aa40100000000ffffffff0250c3000000000000225120d0d55103aa70a12162f733805c3a2f5ff8e857d5fc92381c3d6f22a791165ac115400f00000000002251206f5ec73002ee8b5b2bb942f26e169354821e6ec06f9b3a1d3cf355d6f276c5d800000000"
458
+ stakingMsgTx , _ , err := bbntypes .NewBTCTxFromHex (stkTxHex )
459
+ require .NoError (t , err )
460
+
461
+ prevStakingTxHashHex := stakingMsgTx .TxHash ().String ()
462
+ prevStk := types.Delegation {
463
+ StakingTxHex : stkTxHex ,
464
+ ParamsVersion : pVersionWithCovenant ,
465
+ CovenantSigs : []* types.CovenantAdaptorSigInfo {},
466
+ }
467
+ stkExp := types.Delegation {
468
+ StakingTxHex : testutil .GenRandomHexStr (r , 100 ),
469
+ ParamsVersion : pVersionWithCovenant ,
470
+ CovenantSigs : []* types.CovenantAdaptorSigInfo {},
471
+ StakeExpansion : & types.DelegationStakeExpansion {
472
+ PreviousStakingTxHashHex : prevStakingTxHashHex ,
473
+ },
474
+ }
475
+
476
+ t .Run ("successful validation - covenant in previous committee and didn't sign" , func (t * testing.T ) {
477
+ valid , err := covenant .ValidateStakeExpansion (paramsGet , covKeyInCommittee , & stkExp , & prevStk )
478
+ require .NoError (t , err )
479
+ require .True (t , valid , "should be valid when covenant was in previous committee, even if it didn't sign" )
480
+ })
481
+
482
+ t .Run ("successful validation - covenant in previous committee and signed old del" , func (t * testing.T ) {
483
+ prevDel := prevStk
484
+ prevDel .CovenantSigs = append (prevDel .CovenantSigs , & types.CovenantAdaptorSigInfo {
485
+ Pk : pubKeyFromSchnorr ,
486
+ })
487
+
488
+ valid , err := covenant .ValidateStakeExpansion (paramsGet , covKeyInCommittee , & stkExp , & prevDel )
489
+ require .NoError (t , err )
490
+ require .True (t , valid , "should be valid when covenant was in previous committee even if it did sign the previous" )
491
+ })
492
+
493
+ t .Run ("fails when param cache returns error" , func (t * testing.T ) {
494
+ cacheErr := fmt .Errorf ("param cache connection error" )
495
+ errorParamCache := NewMockParamError (cacheErr )
496
+
497
+ valid , errParamCache := covenant .ValidateStakeExpansion (errorParamCache , covKeyInCommittee , & stkExp , & prevStk )
498
+ require .False (t , valid )
499
+ require .EqualError (t , errParamCache , fmt .Sprintf ("unable to verify if covenant key is in committee: unable to get the param version: %d, reason: %s" , prevStk .ParamsVersion , cacheErr .Error ()))
500
+ })
501
+
502
+ t .Run ("fails when covenant never in previous committee" , func (t * testing.T ) {
503
+ valid , err := covenant .ValidateStakeExpansion (paramsGet , covKeyNotInCommittee , & stkExp , & prevStk )
504
+ require .NoError (t , err )
505
+ require .False (t , valid , "should fail when covenant was never in previous committee" )
506
+ })
507
+
508
+ t .Run ("fails when covenant not in previous committee" , func (t * testing.T ) {
509
+ prevDelWithoutCov := prevStk
510
+ prevDelWithoutCov .ParamsVersion = pVersionWithoutCovenant
511
+ valid , err := covenant .ValidateStakeExpansion (paramsGet , covKeyInCommittee , & stkExp , & prevDelWithoutCov )
512
+ require .NoError (t , err )
513
+ require .False (t , valid , "should fail when covenant was not in previous committee" )
514
+ })
515
+
516
+ t .Run ("fails when previous delegation is nil" , func (t * testing.T ) {
517
+ valid , err := covenant .ValidateStakeExpansion (paramsGet , covKeyInCommittee , & stkExp , nil )
518
+ require .False (t , valid )
519
+ require .EqualError (t , err , fmt .Sprintf ("previous delegation is nil for stake expansion delegation: %s" , prevStakingTxHashHex ))
520
+ })
521
+
522
+ t .Run ("fails when transaction hash mismatch" , func (t * testing.T ) {
523
+ wrongHash := datagen .GenRandomHexStr (r , 10 )
524
+ mismatchedStkExp := stkExp
525
+ mismatchedStkExp .StakeExpansion .PreviousStakingTxHashHex = wrongHash
526
+
527
+ valid , err := covenant .ValidateStakeExpansion (paramsGet , covKeyInCommittee , & mismatchedStkExp , & prevStk )
528
+ require .False (t , valid )
529
+ require .EqualError (t , err , fmt .Sprintf ("previous delegation staking tx hash mismatch: expected %s, got %s" , wrongHash , prevStakingTxHashHex ))
530
+ })
531
+
532
+ t .Run ("fails when previous delegation has invalid staking tx" , func (t * testing.T ) {
533
+ invalidPrevDel := & types.Delegation {
534
+ StakingTxHex : "invalid-hex-string" ,
535
+ ParamsVersion : pVersionWithCovenant ,
536
+ }
537
+
538
+ valid , err := covenant .ValidateStakeExpansion (paramsGet , covKeyInCommittee , & stkExp , invalidPrevDel )
539
+ require .False (t , valid )
540
+ require .EqualError (t , err , "failed to decode previous delegation staking tx: encoding/hex: invalid byte: U+0069 'i'" )
541
+ })
542
+
543
+ }
0 commit comments