/// <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); }
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); }
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); }
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); }
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); }