@@ -362,3 +362,276 @@ func TestAddDelegatorTxSemanticVerify(t *testing.T) {
362362 })
363363 }
364364}
365+
366+ func TestAddDelegatorTxOverDelegatedRegression (t * testing.T ) {
367+ vm , _ := defaultVM ()
368+ vm .Ctx .Lock .Lock ()
369+ defer func () {
370+ if err := vm .Shutdown (); err != nil {
371+ t .Fatal (err )
372+ }
373+ vm .Ctx .Lock .Unlock ()
374+ }()
375+
376+ validatorStartTime := defaultGenesisTime .Add (syncBound ).Add (1 * time .Second )
377+ validatorEndTime := validatorStartTime .Add (360 * 24 * time .Hour )
378+ key , err := vm .factory .NewPrivateKey ()
379+ if err != nil {
380+ t .Fatal (err )
381+ }
382+ id := key .PublicKey ().Address ()
383+
384+ // create valid tx
385+ addValidatorTx , err := vm .newAddValidatorTx (
386+ vm .minValidatorStake ,
387+ uint64 (validatorStartTime .Unix ()),
388+ uint64 (validatorEndTime .Unix ()),
389+ id ,
390+ id ,
391+ PercentDenominator ,
392+ []* crypto.PrivateKeySECP256K1R {keys [0 ]},
393+ ids .ShortEmpty , // change addr
394+ )
395+ if err != nil {
396+ t .Fatal (err )
397+ }
398+
399+ // trigger block creation
400+ if err := vm .mempool .IssueTx (addValidatorTx ); err != nil {
401+ t .Fatal (err )
402+ }
403+ addValidatorBlockIntf , err := vm .BuildBlock ()
404+ if err != nil {
405+ t .Fatal (err )
406+ }
407+
408+ // Verify the proposed block
409+ if err := addValidatorBlockIntf .Verify (); err != nil {
410+ t .Fatal (err )
411+ }
412+
413+ // Assert preferences are correct
414+ addValidatorBlock := addValidatorBlockIntf .(* ProposalBlock )
415+ options , err := addValidatorBlock .Options ()
416+ if err != nil {
417+ t .Fatal (err )
418+ }
419+
420+ // verify the commit block
421+ commit := options [0 ].(* Commit )
422+ if err := commit .Verify (); err != nil {
423+ t .Fatal (err )
424+ }
425+
426+ // Accept the proposal block and the commit block
427+ if err := addValidatorBlock .Accept (); err != nil {
428+ t .Fatal (err )
429+ }
430+ if err := commit .Accept (); err != nil {
431+ t .Fatal (err )
432+ }
433+
434+ vm .clock .Set (validatorStartTime )
435+
436+ firstAdvanceTimeBlockIntf , err := vm .BuildBlock ()
437+ if err != nil {
438+ t .Fatal (err )
439+ }
440+
441+ // Verify the proposed block
442+ if err := firstAdvanceTimeBlockIntf .Verify (); err != nil {
443+ t .Fatal (err )
444+ }
445+
446+ // Assert preferences are correct
447+ firstAdvanceTimeBlock := firstAdvanceTimeBlockIntf .(* ProposalBlock )
448+ options , err = firstAdvanceTimeBlock .Options ()
449+ if err != nil {
450+ t .Fatal (err )
451+ }
452+
453+ // verify the commit block
454+ commit = options [0 ].(* Commit )
455+ if err := commit .Verify (); err != nil {
456+ t .Fatal (err )
457+ }
458+
459+ // Accept the proposal block and the commit block
460+ if err := firstAdvanceTimeBlock .Accept (); err != nil {
461+ t .Fatal (err )
462+ }
463+ if err := commit .Accept (); err != nil {
464+ t .Fatal (err )
465+ }
466+
467+ firstDelegatorStartTime := validatorStartTime .Add (syncBound ).Add (1 * time .Second )
468+ firstDelegatorEndTime := firstDelegatorStartTime .Add (vm .minStakeDuration )
469+
470+ // create valid tx
471+ addFirstDelegatorTx , err := vm .newAddDelegatorTx (
472+ 4 * vm .minValidatorStake , // maximum amount of stake this delegator can provide
473+ uint64 (firstDelegatorStartTime .Unix ()),
474+ uint64 (firstDelegatorEndTime .Unix ()),
475+ id ,
476+ keys [0 ].PublicKey ().Address (),
477+ []* crypto.PrivateKeySECP256K1R {keys [0 ], keys [1 ]},
478+ ids .ShortEmpty , // change addr
479+ )
480+ if err != nil {
481+ t .Fatal (err )
482+ }
483+
484+ // trigger block creation
485+ if err := vm .mempool .IssueTx (addFirstDelegatorTx ); err != nil {
486+ t .Fatal (err )
487+ }
488+ addFirstDelegatorBlockIntf , err := vm .BuildBlock ()
489+ if err != nil {
490+ t .Fatal (err )
491+ }
492+
493+ // Verify the proposed block
494+ if err := addFirstDelegatorBlockIntf .Verify (); err != nil {
495+ t .Fatal (err )
496+ }
497+
498+ // Assert preferences are correct
499+ addFirstDelegatorBlock := addFirstDelegatorBlockIntf .(* ProposalBlock )
500+ options , err = addFirstDelegatorBlock .Options ()
501+ if err != nil {
502+ t .Fatal (err )
503+ }
504+
505+ // verify the commit block
506+ commit = options [0 ].(* Commit )
507+ if err := commit .Verify (); err != nil {
508+ t .Fatal (err )
509+ }
510+
511+ // Accept the proposal block and the commit block
512+ if err := addFirstDelegatorBlock .Accept (); err != nil {
513+ t .Fatal (err )
514+ }
515+ if err := commit .Accept (); err != nil {
516+ t .Fatal (err )
517+ }
518+
519+ vm .clock .Set (firstDelegatorStartTime )
520+
521+ secondAdvanceTimeBlockIntf , err := vm .BuildBlock ()
522+ if err != nil {
523+ t .Fatal (err )
524+ }
525+
526+ // Verify the proposed block
527+ if err := secondAdvanceTimeBlockIntf .Verify (); err != nil {
528+ t .Fatal (err )
529+ }
530+
531+ // Assert preferences are correct
532+ secondAdvanceTimeBlock := secondAdvanceTimeBlockIntf .(* ProposalBlock )
533+ options , err = secondAdvanceTimeBlock .Options ()
534+ if err != nil {
535+ t .Fatal (err )
536+ }
537+
538+ // verify the commit block
539+ commit = options [0 ].(* Commit )
540+ if err := commit .Verify (); err != nil {
541+ t .Fatal (err )
542+ }
543+
544+ // Accept the proposal block and the commit block
545+ if err := secondAdvanceTimeBlock .Accept (); err != nil {
546+ t .Fatal (err )
547+ }
548+ if err := commit .Accept (); err != nil {
549+ t .Fatal (err )
550+ }
551+
552+ secondDelegatorStartTime := firstDelegatorEndTime .Add (2 * time .Second )
553+ secondDelegatorEndTime := secondDelegatorStartTime .Add (vm .minStakeDuration )
554+
555+ vm .clock .Set (secondDelegatorStartTime .Add (- 10 * syncBound ))
556+
557+ // create valid tx
558+ addSecondDelegatorTx , err := vm .newAddDelegatorTx (
559+ vm .minDelegatorStake ,
560+ uint64 (secondDelegatorStartTime .Unix ()),
561+ uint64 (secondDelegatorEndTime .Unix ()),
562+ id ,
563+ keys [0 ].PublicKey ().Address (),
564+ []* crypto.PrivateKeySECP256K1R {keys [0 ], keys [1 ], keys [3 ]},
565+ ids .ShortEmpty , // change addr
566+ )
567+ if err != nil {
568+ t .Fatal (err )
569+ }
570+
571+ // trigger block creation
572+ if err := vm .mempool .IssueTx (addSecondDelegatorTx ); err != nil {
573+ t .Fatal (err )
574+ }
575+ addSecondDelegatorBlockIntf , err := vm .BuildBlock ()
576+ if err != nil {
577+ t .Fatal (err )
578+ }
579+
580+ // Verify the proposed block
581+ if err := addSecondDelegatorBlockIntf .Verify (); err != nil {
582+ t .Fatal (err )
583+ }
584+
585+ // Assert preferences are correct
586+ addSecondDelegatorBlock := addSecondDelegatorBlockIntf .(* ProposalBlock )
587+ options , err = addSecondDelegatorBlock .Options ()
588+ if err != nil {
589+ t .Fatal (err )
590+ }
591+
592+ // verify the commit block
593+ commit = options [0 ].(* Commit )
594+ if err := commit .Verify (); err != nil {
595+ t .Fatal (err )
596+ }
597+
598+ // Accept the proposal block and the commit block
599+ if err := addSecondDelegatorBlock .Accept (); err != nil {
600+ t .Fatal (err )
601+ }
602+ if err := commit .Accept (); err != nil {
603+ t .Fatal (err )
604+ }
605+
606+ thirdDelegatorStartTime := firstDelegatorEndTime .Add (- time .Second )
607+ thirdDelegatorEndTime := thirdDelegatorStartTime .Add (vm .minStakeDuration )
608+
609+ // create valid tx
610+ addThirdDelegatorTx , err := vm .newAddDelegatorTx (
611+ vm .minDelegatorStake ,
612+ uint64 (thirdDelegatorStartTime .Unix ()),
613+ uint64 (thirdDelegatorEndTime .Unix ()),
614+ id ,
615+ keys [0 ].PublicKey ().Address (),
616+ []* crypto.PrivateKeySECP256K1R {keys [0 ], keys [1 ], keys [4 ]},
617+ ids .ShortEmpty , // change addr
618+ )
619+ if err != nil {
620+ t .Fatal (err )
621+ }
622+
623+ // trigger block creation
624+ if err := vm .mempool .IssueTx (addThirdDelegatorTx ); err != nil {
625+ t .Fatal (err )
626+ }
627+
628+ addThirdDelegatorBlockIntf , err := vm .BuildBlock ()
629+ if err != nil {
630+ t .Fatal (err )
631+ }
632+
633+ // Verify the proposed block is invalid
634+ if err := addThirdDelegatorBlockIntf .Verify (); err == nil {
635+ t .Fatalf ("should have marked the delegator as being over delegated" )
636+ }
637+ }
0 commit comments