//Run ``process_proposer_slashing``, yielding: //- pre-state('pre') //- proposer_slashing('proposer_slashing') //- post-state('post'). //If ``valid == False``, run expecting ``AssertionError`` private void RunProposerSlashingProcessing(IServiceProvider testServiceProvider, BeaconState state, ProposerSlashing proposerSlashing, bool expectValid) { var chainConstants = testServiceProvider.GetService <ChainConstants>(); var beaconStateTransition = testServiceProvider.GetService <BeaconStateTransition>(); if (!expectValid) { Should.Throw <Exception>(() => { beaconStateTransition.ProcessProposerSlashing(state, proposerSlashing); }); return; } var preProposerBalance = TestState.GetBalance(state, proposerSlashing.ProposerIndex); beaconStateTransition.ProcessProposerSlashing(state, proposerSlashing); var slashedValidator = state.Validators[(int)(ulong)proposerSlashing.ProposerIndex]; slashedValidator.IsSlashed.ShouldBeTrue(); slashedValidator.ExitEpoch.ShouldBeLessThan(chainConstants.FarFutureEpoch); slashedValidator.WithdrawableEpoch.ShouldBeLessThan(chainConstants.FarFutureEpoch); var balance = TestState.GetBalance(state, proposerSlashing.ProposerIndex); balance.ShouldBeLessThan(preProposerBalance); }
public void after_istanbul_selfbalance_opcode_puts_current_address_balance_onto_the_stack() { byte[] contractCode = Prepare.EvmCode .Op(Instruction.SELFBALANCE) .PushData(0) .Op(Instruction.SSTORE) .Done; Keccak codeHash = TestState.UpdateCode(contractCode); TestState.CreateAccount(TestItem.AddressC, 1.Ether()); TestState.UpdateCodeHash(TestItem.AddressC, codeHash, Spec); TestState.CreateAccount(TestItem.AddressD, 1.Ether()); TestState.UpdateCodeHash(TestItem.AddressD, codeHash, Spec); var code = Prepare.EvmCode .Call(TestItem.AddressC, 50000) .DelegateCall(TestItem.AddressD, 50000) .Op(Instruction.SELFBALANCE) .PushData(1) .Op(Instruction.SSTORE) .Done; var result = Execute(code); Assert.AreEqual(StatusCode.Success, result.StatusCode); AssertGas(result, 21000 + 2 * GasCostOf.CallEip150 + 24 + 21 + GasCostOf.VeryLow + 3 * GasCostOf.SelfBalance + 3 * GasCostOf.SSet); var balanceB = TestState.GetBalance(TestItem.AddressB); var balanceC = TestState.GetBalance(TestItem.AddressC); AssertStorage(new StorageCell(TestItem.AddressB, UInt256.Zero), balanceB); AssertStorage(new StorageCell(TestItem.AddressB, UInt256.One), balanceB); AssertStorage(new StorageCell(TestItem.AddressC, UInt256.Zero), balanceC); }
// Run ``process_deposit``, yielding: // - pre-state('pre') // - deposit('deposit') // - post-state('post'). //If ``valid == False``, run expecting ``AssertionError`` private void RunDepositProcessing(IServiceProvider testServiceProvider, BeaconState state, Deposit deposit, ValidatorIndex validatorIndex, bool expectValid, bool effective) { GweiValues gweiValues = testServiceProvider.GetService <IOptions <GweiValues> >().Value; BeaconStateTransition beaconStateTransition = testServiceProvider.GetService <BeaconStateTransition>(); int preValidatorCount = state.Validators.Count; Gwei preBalance = Gwei.Zero; if ((int)(ulong)validatorIndex < preValidatorCount) { preBalance = TestState.GetBalance(state, validatorIndex); } if (!expectValid) { Should.Throw <Exception>(() => { beaconStateTransition.ProcessDeposit(state, deposit); }); return; } beaconStateTransition.ProcessDeposit(state, deposit); if (!effective) { state.Validators.Count.ShouldBe(preValidatorCount); state.Balances.Count.ShouldBe(preValidatorCount); if ((int)(ulong)validatorIndex < preValidatorCount) { Gwei balance = TestState.GetBalance(state, validatorIndex); balance.ShouldBe(preBalance); } } else { if ((int)(ulong)validatorIndex < preValidatorCount) { // top up state.Validators.Count.ShouldBe(preValidatorCount); state.Balances.Count.ShouldBe(preValidatorCount); } else { // new validator state.Validators.Count.ShouldBe(preValidatorCount + 1); state.Balances.Count.ShouldBe(preValidatorCount + 1); } Gwei balance = TestState.GetBalance(state, validatorIndex); Gwei expectedBalance = preBalance + deposit.Data.Item.Amount; balance.ShouldBe(expectedBalance); Gwei expectedEffectiveBalance = Gwei.Min(gweiValues.MaximumEffectiveBalance, expectedBalance); expectedEffectiveBalance -= expectedEffectiveBalance % gweiValues.EffectiveBalanceIncrement; state.Validators[(int)(ulong)validatorIndex].EffectiveBalance.ShouldBe(expectedEffectiveBalance); } state.Eth1DepositIndex.ShouldBe(state.Eth1Data.DepositCount); }
// Run ``process_attester_slashing``, yielding: // - pre-state('pre') // - attester_slashing('attester_slashing') // - post-state('post'). //If ``valid == False``, run expecting ``AssertionError`` private void RunAttesterSlashingProcessing(IServiceProvider testServiceProvider, BeaconState state, AttesterSlashing attesterSlashing, bool expectValid) { ChainConstants chainConstants = testServiceProvider.GetService <ChainConstants>(); StateListLengths stateListLengths = testServiceProvider.GetService <IOptions <StateListLengths> >().Value; RewardsAndPenalties rewardsAndPenalties = testServiceProvider.GetService <IOptions <RewardsAndPenalties> >().Value; BeaconStateAccessor beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>(); BeaconStateTransition beaconStateTransition = testServiceProvider.GetService <BeaconStateTransition>(); if (!expectValid) { Should.Throw <Exception>(() => { beaconStateTransition.ProcessAttesterSlashing(state, attesterSlashing); }); return; } var slashedIndices = attesterSlashing.Attestation1.CustodyBit0Indices .Union(attesterSlashing.Attestation1.CustodyBit1Indices) .ToList(); ValidatorIndex proposerIndex = beaconStateAccessor.GetBeaconProposerIndex(state); Gwei preProposerBalance = TestState.GetBalance(state, proposerIndex); var preSlashings = slashedIndices.ToDictionary(x => x, x => TestState.GetBalance(state, x)); var preWithdrawableEpochs = slashedIndices.ToDictionary(x => x, x => state.Validators[(int)(ulong)x].WithdrawableEpoch); Gwei totalProposerRewards = preSlashings.Values.Aggregate(Gwei.Zero, (sum, x) => sum + x / rewardsAndPenalties.WhistleblowerRewardQuotient); // Process slashing beaconStateTransition.ProcessAttesterSlashing(state, attesterSlashing); foreach (ValidatorIndex slashedIndex in slashedIndices) { Console.WriteLine($"Checking index {slashedIndex}"); Epoch preWithdrawableEpoch = preWithdrawableEpochs[slashedIndex]; Validator slashedValidator = state.Validators[(int)(ulong)slashedIndex]; // Check Slashing slashedValidator.IsSlashed.ShouldBeTrue(); slashedValidator.ExitEpoch.ShouldBeLessThan(chainConstants.FarFutureEpoch); if (preWithdrawableEpoch < chainConstants.FarFutureEpoch) { ulong slashingsEpoch = beaconStateAccessor.GetCurrentEpoch(state) + stateListLengths.EpochsPerSlashingsVector; Epoch expectedWithdrawableEpoch = Epoch.Max(preWithdrawableEpoch, (Epoch)slashingsEpoch); slashedValidator.WithdrawableEpoch.ShouldBe(expectedWithdrawableEpoch); } else { slashedValidator.WithdrawableEpoch.ShouldBeLessThan(chainConstants.FarFutureEpoch); } Gwei preSlashing = preSlashings[slashedIndex]; Gwei slashedBalance = TestState.GetBalance(state, slashedIndex); slashedBalance.ShouldBeLessThan(preSlashing); } if (!slashedIndices.Contains(proposerIndex)) { // gained whistleblower reward Gwei expectedProposerBalance = preProposerBalance + totalProposerRewards; Gwei proposerBalance = TestState.GetBalance(state, proposerIndex); proposerBalance.ShouldBe(expectedProposerBalance); } else { // gained rewards for all slashings, which may include others. And only lost that of themselves. Gwei expectedProposerBalance = preProposerBalance + totalProposerRewards - (preSlashings[proposerIndex] / rewardsAndPenalties.MinimumSlashingPenaltyQuotient); Gwei proposerBalance = TestState.GetBalance(state, proposerIndex); proposerBalance.ShouldBe(expectedProposerBalance); } }