Exemplo n.º 1
0
        /// <summary>
        /// Initiate the exit of the validator with index ``index``.
        /// </summary>
        public void InitiateValidatorExit(BeaconState state, ValidatorIndex index)
        {
            // Return if validator already initiated exit
            Validator validator = state.Validators[(int)index];

            if (validator.ExitEpoch != _chainConstants.FarFutureEpoch)
            {
                return;
            }

            // Compute exit queue epoch
            IEnumerable <Epoch> exitEpochs = state.Validators
                                             .Where(x => x.ExitEpoch != _chainConstants.FarFutureEpoch)
                                             .Select(x => x.ExitEpoch);
            Epoch maxExitEpoch        = exitEpochs.DefaultIfEmpty().Max();
            Epoch currentEpoch        = _beaconStateAccessor.GetCurrentEpoch(state);
            Epoch activationExitEpoch = _beaconChainUtility.ComputeActivationExitEpoch(currentEpoch);
            Epoch exitQueueEpoch      = Epoch.Max(maxExitEpoch, activationExitEpoch);
            int   exitQueueChurn      = state.Validators.Where(x => x.ExitEpoch == exitQueueEpoch).Count();
            ulong validatorChurnLimit = _beaconStateAccessor.GetValidatorChurnLimit(state);

            if ((ulong)exitQueueChurn >= validatorChurnLimit)
            {
                exitQueueEpoch += new Epoch(1);
            }

            // Set validator exit epoch and withdrawable epoch
            validator.SetExitEpoch(exitQueueEpoch);
            Epoch withdrawableEpoch = validator.ExitEpoch + _timeParameterOptions.CurrentValue.MinimumValidatorWithdrawabilityDelay;

            validator.SetWithdrawableEpoch(withdrawableEpoch);
        }
Exemplo n.º 2
0
        public bool CheckIfValidatorActive(BeaconState state, ValidatorIndex validatorIndex)
        {
            if ((int)validatorIndex >= state.Validators.Count)
            {
                return(false);
            }

            Validator validator    = state.Validators[(int)validatorIndex];
            Epoch     currentEpoch = _beaconStateAccessor.GetCurrentEpoch(state);
            bool      isActive     = _beaconChainUtility.IsActiveValidator(validator, currentEpoch);

            return(isActive);
        }
Exemplo n.º 3
0
        public Gwei GetLatestAttestingBalance(IStore store, Hash32 root)
        {
            if (!store.TryGetCheckpointState(store.JustifiedCheckpoint, out var storedState))
            {
                throw new Exception($"Not able to get checkpoint state {store.JustifiedCheckpoint}");
            }

            var state         = storedState !;
            var currentEpoch  = _beaconStateAccessor.GetCurrentEpoch(state);
            var activeIndexes = _beaconStateAccessor.GetActiveValidatorIndices(state, currentEpoch);

            if (!store.TryGetBlock(root, out var rootBlock))
            {
                throw new Exception($"Not ble to find block {root}");
            }

            Slot rootSlot = rootBlock !.Slot;
            Gwei balance  = Gwei.Zero;

            foreach (ValidatorIndex index in activeIndexes)
            {
                if (store.TryGetLatestMessage(index, out var latestMessage))
                {
                    var ancestor = GetAncestor(store, latestMessage !.Root, rootSlot);
                    if (ancestor == root)
                    {
                        var validator = state.Validators[(int)index];
                        balance += validator.EffectiveBalance;
                    }
                }
            }

            return(balance);
        }
Exemplo n.º 4
0
        public async Task <Gwei> GetLatestAttestingBalanceAsync(IStore store, Hash32 root)
        {
            // NOTE: This method should probably live in IStore, for various efficient implementations.

            Checkpoint             justifiedCheckpoint = store.JustifiedCheckpoint;
            BeaconState            state         = (await store.GetCheckpointStateAsync(justifiedCheckpoint, true).ConfigureAwait(false)) !;
            Epoch                  currentEpoch  = _beaconStateAccessor.GetCurrentEpoch(state);
            IList <ValidatorIndex> activeIndexes = _beaconStateAccessor.GetActiveValidatorIndices(state, currentEpoch);
            BeaconBlock            rootBlock     = await store.GetBlockAsync(root).ConfigureAwait(false);

            Slot rootSlot = rootBlock !.Slot;
            Gwei balance  = Gwei.Zero;

            foreach (ValidatorIndex index in activeIndexes)
            {
                LatestMessage?latestMessage = await store.GetLatestMessageAsync(index, false);

                if (latestMessage != null)
                {
                    Hash32 ancestor = await GetAncestorAsync(store, latestMessage.Root, rootSlot);

                    if (ancestor == root)
                    {
                        Validator validator = state.Validators[(int)index];
                        balance += validator.EffectiveBalance;
                    }
                }
            }

            return(balance);
        }
Exemplo n.º 5
0
        public async Task InitializeForkChoiceStoreAsync(IStore store, BeaconState anchorState)
        {
            // Implements the logic for get_genesis_store / get_forkchoice_store

            Root stateRoot = !anchorState.LatestBlockHeader.StateRoot.Equals(Root.Zero)
                ? anchorState.LatestBlockHeader.StateRoot
                : _cryptographyService.HashTreeRoot(anchorState);

            BeaconBlock anchorBlock = new BeaconBlock(anchorState.Slot, anchorState.LatestBlockHeader.ParentRoot,
                                                      stateRoot, BeaconBlockBody.Zero);
            SignedBeaconBlock signedAnchorBlock = new SignedBeaconBlock(anchorBlock, BlsSignature.Zero);

            Root       anchorRoot          = _cryptographyService.HashTreeRoot(anchorBlock);
            Epoch      anchorEpoch         = _beaconStateAccessor.GetCurrentEpoch(anchorState);
            Checkpoint justifiedCheckpoint = new Checkpoint(anchorEpoch, anchorRoot);
            Checkpoint finalizedCheckpoint = new Checkpoint(anchorEpoch, anchorRoot);

            if (_logger.IsInfo())
            {
                Log.CreateGenesisStore(_logger, anchorState.Fork, anchorRoot, anchorState.GenesisTime, anchorState,
                                       anchorBlock, justifiedCheckpoint, null);
            }

            Dictionary <Root, SignedBeaconBlock> signedBlocks = new Dictionary <Root, SignedBeaconBlock>
            {
                [anchorRoot] = signedAnchorBlock
            };
            Dictionary <Root, BeaconState> blockStates = new Dictionary <Root, BeaconState>
            {
                [anchorRoot] = BeaconState.Clone(anchorState)
            };
            Dictionary <Checkpoint, BeaconState> checkpointStates = new Dictionary <Checkpoint, BeaconState>
            {
                [justifiedCheckpoint] = BeaconState.Clone(anchorState)
            };

            await store.InitializeForkChoiceStoreAsync(
                anchorState.GenesisTime,
                anchorState.GenesisTime,
                justifiedCheckpoint,
                finalizedCheckpoint,
                justifiedCheckpoint,
                signedBlocks,
                blockStates,
                checkpointStates);
        }
        private PeeringStatus BuildStatusFromHead(Root headRoot, BeaconState beaconState)
        {
            Epoch       headEpoch = _beaconStateAccessor.GetCurrentEpoch(beaconState);
            ForkVersion headForkVersion;

            if (headEpoch < beaconState.Fork.Epoch)
            {
                headForkVersion = beaconState.Fork.PreviousVersion;
            }
            else
            {
                headForkVersion = beaconState.Fork.CurrentVersion;
            }

            PeeringStatus peeringStatus = new PeeringStatus(headForkVersion, beaconState.FinalizedCheckpoint.Root,
                                                            beaconState.FinalizedCheckpoint.Epoch, headRoot, beaconState.Slot);

            return(peeringStatus);
        }
        public async Task <Attestation> NewAttestationAsync(BlsPublicKey validatorPublicKey,
                                                            bool proofOfCustodyBit, Slot slot, CommitteeIndex index,
                                                            CancellationToken cancellationToken)
        {
            Root head = await _store.GetHeadAsync().ConfigureAwait(false);

            BeaconBlock headBlock   = (await _store.GetSignedBlockAsync(head).ConfigureAwait(false)).Message;
            BeaconState parentState = await _store.GetBlockStateAsync(head).ConfigureAwait(false);

            // Clone state (will mutate) and process outstanding slots
            BeaconState headState = BeaconState.Clone(parentState);

            _beaconStateTransition.ProcessSlots(headState, slot);

            // Set attestation_data.index = index where index is the index associated with the validator's committee.
            ValidatorIndex?validatorIndex = FindValidatorIndexByPublicKey(headState, validatorPublicKey);

            if (validatorIndex == null)
            {
                throw new Exception($"Can not find validator index for public key {validatorPublicKey}");
            }

            // TODO: May need a more efficient way to try and find the committee and position within the committee.
            // Some of this may already be cached in Validator Assignments (generally stable for an epoch),
            // but not with the index within the committee. Easy enough to extend and use the same cache.

            IReadOnlyList <ValidatorIndex> committee =
                _beaconStateAccessor.GetBeaconCommittee(headState, headState.Slot, index);
            int committeeSize = committee.Count;

            int?committeeMemberIndexOfValidator = null;

            for (int committeeMemberIndex = 0; committeeMemberIndex < committee.Count; committeeMemberIndex++)
            {
                if (committee[committeeMemberIndex] == validatorIndex)
                {
                    committeeMemberIndexOfValidator = committeeMemberIndex;
                    break;
                }
            }

            if (committeeMemberIndexOfValidator == null)
            {
                throw new Exception($"Validator index {validatorIndex} is not a member of committee {index}");
            }

            Root beaconBlockRoot = _cryptographyService.HashTreeRoot(headBlock);

            Checkpoint source = headState.CurrentJustifiedCheckpoint;

            Epoch currentEpoch = _beaconStateAccessor.GetCurrentEpoch(headState);
            Slot  startSlot    = _beaconChainUtility.ComputeStartSlotOfEpoch(currentEpoch);
            Root  epochBoundaryBlockRoot;

            if (startSlot == headState.Slot)
            {
                epochBoundaryBlockRoot = beaconBlockRoot;
            }
            else
            {
                epochBoundaryBlockRoot = _beaconStateAccessor.GetBlockRootAtSlot(headState, startSlot);
            }

            Checkpoint target = new Checkpoint(currentEpoch, epochBoundaryBlockRoot);

            AttestationData attestationData = new AttestationData(slot, index, beaconBlockRoot, source, target);

            var aggregationBits = new BitArray(committeeSize);

            aggregationBits.Set(committeeMemberIndexOfValidator.Value, true);

            var attestation = new Attestation(aggregationBits, attestationData, BlsSignature.Zero);

            return(attestation);
        }