Esempio n. 1
0
        //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);
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        //    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);
            }
        }