public void EffectiveBalanceHysteresis() { // Arrange var testServiceProvider = TestSystem.BuildTestServiceProvider(); var state = TestState.PrepareTestState(testServiceProvider); //# Prepare state up to the final-updates. //# Then overwrite the balances, we only want to focus to be on the hysteresis based changes. TestProcessUtility.RunEpochProcessingTo(testServiceProvider, state, TestProcessStep.ProcessFinalUpdates); var gweiValues = testServiceProvider.GetService <IOptions <GweiValues> >().Value; var beaconChainUtility = testServiceProvider.GetService <BeaconChainUtility>(); var beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>(); var beaconStateTransition = testServiceProvider.GetService <BeaconStateTransition>(); // Set some edge cases for balances var maximum = gweiValues.MaximumEffectiveBalance; var minimum = gweiValues.EjectionBalance; var increment = gweiValues.EffectiveBalanceIncrement; var halfIncrement = increment / 2; var testCases = new[] { new EffectiveBalanceCase(maximum, maximum, maximum, "as-is"), new EffectiveBalanceCase(maximum, (Gwei)(maximum - 1), maximum - increment, "round down, step lower"), new EffectiveBalanceCase(maximum, (Gwei)(maximum + 1), maximum, "round down"), new EffectiveBalanceCase(maximum, (Gwei)(maximum - increment), maximum - increment, "exactly 1 step lower"), new EffectiveBalanceCase(maximum, (Gwei)(maximum - increment - 1), maximum - (increment * 2), "just 1 over 1 step lower"), new EffectiveBalanceCase(maximum, (Gwei)(maximum - increment + 1), maximum - increment, "close to 1 step lower"), new EffectiveBalanceCase(minimum, (Gwei)(minimum + (halfIncrement * 3)), minimum, "bigger balance, but not high enough"), new EffectiveBalanceCase(minimum, (Gwei)(minimum + (halfIncrement * 3) + 1), minimum + increment, "bigger balance, high enough, but small step"), new EffectiveBalanceCase(minimum, (Gwei)(minimum + (halfIncrement * 4) - 1), minimum + increment, "bigger balance, high enough, close to double step"), new EffectiveBalanceCase(minimum, (Gwei)(minimum + (halfIncrement * 4)), minimum + (increment * 2), "exact two step balance increment"), new EffectiveBalanceCase(minimum, (Gwei)(minimum + (halfIncrement * 4) + 1), minimum + (increment * 2), "over two steps, round down"), }; var currentEpoch = beaconStateAccessor.GetCurrentEpoch(state); for (var index = 0; index < testCases.Length; index++) { var validator = state.Validators[index]; var isActive = beaconChainUtility.IsActiveValidator(validator, currentEpoch); isActive.ShouldBeTrue(); var testCase = testCases[index]; validator.SetEffectiveBalance(testCase.PreEffective); var validatorIndex = new ValidatorIndex((ulong)index); state.SetBalance(validatorIndex, testCase.Balance); } // Act beaconStateTransition.ProcessFinalUpdates(state); // Assert for (var index = 0; index < testCases.Length; index++) { var testCase = testCases[index]; var validator = state.Validators[index]; validator.EffectiveBalance.ShouldBe(testCase.PostEffective, testCase.Name); } }
private void RunProcessRegistryUpdates(IServiceProvider testServiceProvider, BeaconState state) { TestProcessUtility.RunEpochProcessingWith(testServiceProvider, state, TestProcessStep.ProcessRegistryUpdates); }
private void RunProcessRewardsAndPenalties(IServiceProvider testServiceProvider, BeaconState state) { TestProcessUtility.RunEpochProcessingWith(testServiceProvider, state, TestProcessStep.ProcessRewardsAndPenalties); }