@@ -712,6 +712,149 @@ void stakingEffectsWorkAsExpectedWhenStakingToAccount() {
712
712
assertThat (modifiedPayer .stakePeriodStart ()).isEqualTo (stakePeriodStart );
713
713
}
714
714
715
+ @ Test
716
+ void userSwitchesStakingFromAccountToNode () {
717
+ // payer is staked to owner, has account balance of 55L, and no rewards
718
+ // payer switches stake from owner to node
719
+ // payer should get reward from the node
720
+ // owner should get no reward
721
+ final var accountBalance = 55L * HBARS_TO_TINYBARS ;
722
+ final var ownerBalance = 11L * HBARS_TO_TINYBARS ;
723
+ final var payerAccountBefore = new AccountCustomizer ()
724
+ .withAccount (account )
725
+ .withBalance (accountBalance )
726
+ .withStakeAtStartOfLastRewardPeriod (accountBalance / 5 )
727
+ .withStakedAccountId (ownerId )
728
+ .withStakedToMe (0 )
729
+ .withStakePeriodStart (stakePeriodStart )
730
+ .withDeclineReward (false )
731
+ .withDeleted (false )
732
+ .build ();
733
+ final var ownerAccountBefore = new AccountCustomizer ()
734
+ .withAccount (ownerAccount )
735
+ .withBalance (ownerBalance )
736
+ .withStakeAtStartOfLastRewardPeriod (-1L )
737
+ .withStakePeriodStart (stakePeriodStart )
738
+ .withDeclineReward (false )
739
+ .withStakedToMe (0L )
740
+ .withDeleted (false )
741
+ .build ();
742
+ addToState (Map .of (payerId , payerAccountBefore , ownerId , ownerAccountBefore ));
743
+
744
+ // transfer from payer to owner
745
+ // change payer stake from owner account to node 1
746
+ writableAccountStore .put (payerAccountBefore
747
+ .copyBuilder ()
748
+ .tinybarBalance (accountBalance - HBARS_TO_TINYBARS )
749
+ .stakedNodeId (node1Id .number ())
750
+ .build ());
751
+ writableAccountStore .put (ownerAccount
752
+ .copyBuilder ()
753
+ .tinybarBalance (ownerBalance + HBARS_TO_TINYBARS )
754
+ .build ());
755
+
756
+ // run forward two periods
757
+ final Instant nextDayInstant = originalInstant .plus (2 , ChronoUnit .DAYS );
758
+ given (context .consensusTime ()).willReturn (nextDayInstant );
759
+ stakePeriodManager .setCurrentStakePeriodFor (nextDayInstant );
760
+
761
+ mockEntityIdFactory ();
762
+ final var rewards = subject .applyStakingRewards (context , Collections .emptySet (), emptyMap ());
763
+ assertThat (rewards ).hasSize (0 );
764
+ }
765
+
766
+ @ Test
767
+ void userSwitchesStakingFromNothingToAccount () {
768
+ // payer is staked to owner, has account balance of 55L, and no rewards
769
+ // payer switches stake from owner to node
770
+ // payer should get no reward
771
+ // owner should get no reward
772
+ final var accountBalance = 55L * HBARS_TO_TINYBARS ;
773
+ final var ownerBalance = 11L * HBARS_TO_TINYBARS ;
774
+ final var payerAccountBefore = new AccountCustomizer ()
775
+ .withAccount (account )
776
+ .withBalance (accountBalance )
777
+ .withStakedNodeId (-1L )
778
+ .withStakedToMe (0 )
779
+ .withStakePeriodStart (stakePeriodStart )
780
+ .withDeclineReward (true )
781
+ .build ();
782
+ addToState (Map .of (payerId , payerAccountBefore ));
783
+
784
+ // transfer from payer to owner
785
+ // change payer stake from owner account to node 1
786
+ writableAccountStore .put (payerAccountBefore
787
+ .copyBuilder ()
788
+ .tinybarBalance (accountBalance - HBARS_TO_TINYBARS )
789
+ .stakedAccountId (ownerId )
790
+ .build ());
791
+ writableAccountStore .put (ownerAccount
792
+ .copyBuilder ()
793
+ .tinybarBalance (ownerBalance + HBARS_TO_TINYBARS )
794
+ .build ());
795
+
796
+ // run forward two periods
797
+ Instant nextDayInstant = originalInstant .plus (2 , ChronoUnit .DAYS );
798
+ given (context .consensusTime ()).willReturn (nextDayInstant );
799
+ stakePeriodManager .setCurrentStakePeriodFor (nextDayInstant );
800
+
801
+ mockEntityIdFactory ();
802
+ final var rewards = subject .applyStakingRewards (context , Collections .emptySet (), emptyMap ());
803
+ // confirm no rewards
804
+ assertThat (rewards ).hasSize (0 );
805
+ }
806
+
807
+ @ Test
808
+ void userSwitchesStakingFromAccountToNothing () {
809
+ // payer is staked to owner, has account balance of 55L, and no rewards
810
+ // payer switches stake from owner to nothing (node -1)
811
+ // payer should get no reward
812
+ // owner should still get the reward from before the switch
813
+ final var accountBalance = 55L * HBARS_TO_TINYBARS ;
814
+ final var ownerBalance = 11L * HBARS_TO_TINYBARS ;
815
+ final var payerAccountBefore = new AccountCustomizer ()
816
+ .withAccount (account )
817
+ .withBalance (accountBalance )
818
+ .withStakedAccountId (ownerId )
819
+ .withStakedToMe (0 )
820
+ .withStakePeriodStart (stakePeriodStart )
821
+ .withDeclineReward (true )
822
+ .build ();
823
+ final var ownerAccountBefore = new AccountCustomizer ()
824
+ .withAccount (ownerAccount )
825
+ .withBalance (ownerBalance )
826
+ .withStakeAtStartOfLastRewardPeriod (-1L )
827
+ .withStakePeriodStart (stakePeriodStart )
828
+ .withDeclineReward (false )
829
+ .withStakedNodeId (node1Id .number ())
830
+ .withStakedToMe (0L )
831
+ .withDeleted (false )
832
+ .build ();
833
+ addToState (Map .of (payerId , payerAccountBefore , ownerId , ownerAccountBefore ));
834
+
835
+ // transfer from payer to owner
836
+ // change payer stake from owner account to node -1
837
+ writableAccountStore .put (payerAccountBefore
838
+ .copyBuilder ()
839
+ .tinybarBalance (accountBalance - HBARS_TO_TINYBARS )
840
+ .stakedNodeId (-1 ) // switch to staking to nothing
841
+ .build ());
842
+ writableAccountStore .put (ownerAccount
843
+ .copyBuilder ()
844
+ .tinybarBalance (ownerBalance + HBARS_TO_TINYBARS )
845
+ .build ());
846
+
847
+ // run forward two periods
848
+ Instant nextDayInstant = originalInstant .plus (2 , ChronoUnit .DAYS );
849
+ given (context .consensusTime ()).willReturn (nextDayInstant );
850
+ stakePeriodManager .setCurrentStakePeriodFor (nextDayInstant );
851
+
852
+ mockEntityIdFactory ();
853
+ final var rewards = subject .applyStakingRewards (context , Collections .emptySet (), emptyMap ());
854
+ // check that owner still gets reward, but payer gets nothing
855
+ assertThat (rewards ).hasSize (1 ).containsEntry (ownerId , 2200L );
856
+ }
857
+
715
858
@ Test
716
859
void rewardsUltimateBeneficiaryInsteadOfDeletedAccount () {
717
860
final var accountBalance = 555L * HBARS_TO_TINYBARS ;
0 commit comments