Example #1
0
        public void ProcessFinalUpdates(BeaconState state)
        {
            _logger.LogInformation(Event.ProcessFinalUpdates, "Process epoch final updates state {BeaconState}", state);

            var timeParameters   = _timeParameterOptions.CurrentValue;
            var gweiValues       = _gweiValueOptions.CurrentValue;
            var stateListLengths = _stateListLengthOptions.CurrentValue;

            var currentEpoch = _beaconStateAccessor.GetCurrentEpoch(state);
            var nextEpoch    = currentEpoch + new Epoch(1);

            // Reset eth1 data votes
            var nextSlot = state.Slot + new Slot(1);

            if (nextSlot % timeParameters.SlotsPerEth1VotingPeriod == Slot.Zero)
            {
                state.ClearEth1DataVotes();
            }

            // Update effective balances with hysteresis
            var halfIncrement = gweiValues.EffectiveBalanceIncrement / 2;

            for (var index = 0; index < state.Validators.Count; index++)
            {
                var validator = state.Validators[index];
                var balance   = state.Balances[index];
                if (balance < validator.EffectiveBalance || (validator.EffectiveBalance + (halfIncrement * 3)) < balance)
                {
                    var roundedBalance   = balance - (balance % gweiValues.EffectiveBalanceIncrement);
                    var effectiveBalance = Gwei.Min(roundedBalance, gweiValues.MaximumEffectiveBalance);
                    validator.SetEffectiveBalance(effectiveBalance);
                }
            }

            // Reset slashings
            var slashingsIndex = nextEpoch % stateListLengths.EpochsPerSlashingsVector;

            state.SetSlashings(slashingsIndex, Gwei.Zero);

            // Set randao mix
            var randaoIndex = nextEpoch % stateListLengths.EpochsPerHistoricalVector;
            var randaoMix   = _beaconStateAccessor.GetRandaoMix(state, currentEpoch);

            state.SetRandaoMix(randaoIndex, randaoMix);

            // Set historical root accumulator
            var divisor = timeParameters.SlotsPerHistoricalRoot / timeParameters.SlotsPerEpoch;

            if ((ulong)nextEpoch % divisor == 0)
            {
                var historicalBatch = new HistoricalBatch(state.BlockRoots.ToArray(), state.StateRoots.ToArray());
                var historicalRoot  = historicalBatch.HashTreeRoot();
                state.AddHistoricalRoot(historicalRoot);
            }

            // Rotate current/previous epoch attestations
            state.SetPreviousEpochAttestations(state.CurrentEpochAttestations);
            state.SetCurrentEpochAttestations(new PendingAttestation[0]);
        }
Example #2
0
        public void ProcessRandao(BeaconState state, BeaconBlockBody body)
        {
            _logger.LogInformation(Event.ProcessRandao, "Process block randao for block body {BeaconBlockBody}", body);
            var epoch = _beaconStateAccessor.GetCurrentEpoch(state);
            // Verify RANDAO reveal
            var beaconProposerIndex = _beaconStateAccessor.GetBeaconProposerIndex(state);
            var proposer            = state.Validators[(int)(ulong)beaconProposerIndex];
            var epochRoot           = epoch.HashTreeRoot();
            var domain            = _beaconStateAccessor.GetDomain(state, _signatureDomainOptions.CurrentValue.Randao, Epoch.None);
            var validRandaoReveal = _cryptographyService.BlsVerify(proposer.PublicKey, epochRoot, body.RandaoReveal, domain);

            if (!validRandaoReveal)
            {
                throw new Exception($"Randao reveal {body.RandaoReveal} must match proposer public key {proposer.PublicKey}");
            }
            // Mix in RANDAO reveal
            var randaoMix   = _beaconStateAccessor.GetRandaoMix(state, epoch);
            var randaoHash  = _cryptographyService.Hash(body.RandaoReveal.AsSpan());
            var mix         = randaoMix.Xor(randaoHash);
            var randaoIndex = epoch % _stateListLengthOptions.CurrentValue.EpochsPerHistoricalVector;

            state.SetRandaoMix(randaoIndex, mix);
        }