public Slot ComputeSlotsSinceEpochStart(Slot slot) { var epoch = _beaconChainUtility.ComputeEpochAtSlot(slot); var startSlot = _beaconChainUtility.ComputeStartSlotOfEpoch(epoch); return(slot - startSlot); }
/// <summary> /// Return the beacon committee at ``slot`` for ``index``. /// </summary> public IReadOnlyList <ValidatorIndex> GetBeaconCommittee(BeaconState state, Slot slot, CommitteeIndex index) { var epoch = _beaconChainUtility.ComputeEpochAtSlot(slot); var committeesPerSlot = GetCommitteeCountAtSlot(state, slot); //var committeeCount = GetCommitteeCount(state, epoch); var indices = GetActiveValidatorIndices(state, epoch); var seed = GetSeed(state, epoch, _signatureDomainOptions.CurrentValue.BeaconAttester); //var index = (shard + miscellaneousParameters.ShardCount - GetStartShard(state, epoch)) % miscellaneousParameters.ShardCount; var committeeIndex = (ulong)(slot % _timeParameterOptions.CurrentValue.SlotsPerEpoch) * committeesPerSlot + (ulong)index; var committeeCount = committeesPerSlot * (ulong)_timeParameterOptions.CurrentValue.SlotsPerEpoch; var committee = _beaconChainUtility.ComputeCommittee(indices, seed, committeeIndex, committeeCount); return(committee); }
public void ProcessProposerSlashing(BeaconState state, ProposerSlashing proposerSlashing) { _logger.LogInformation(Event.ProcessProposerSlashing, "Process block operation proposer slashing {ProposerSlashing}", proposerSlashing); var proposer = state.Validators[(int)(ulong)proposerSlashing.ProposerIndex]; // Verify slots match if (proposerSlashing.Header1.Slot != proposerSlashing.Header2.Slot) { throw new Exception($"Proposer slashing header 1 slot {proposerSlashing.Header1.Slot} must match header 2 slot {proposerSlashing.Header2.Slot}."); } // But the headers are different if (proposerSlashing.Header1.Equals(proposerSlashing.Header2)) { throw new Exception($"Proposer slashing must be for two different headers."); } // Check proposer is slashable var currentEpoch = _beaconStateAccessor.GetCurrentEpoch(state); var isSlashable = _beaconChainUtility.IsSlashableValidator(proposer, currentEpoch); if (!isSlashable) { throw new Exception($"Proposer {proposerSlashing.ProposerIndex} is not slashable at epoch {currentEpoch}."); } // Signatures are valid var slashingEpoch = _beaconChainUtility.ComputeEpochAtSlot(proposerSlashing.Header1.Slot); var domain = _beaconStateAccessor.GetDomain(state, _signatureDomainOptions.CurrentValue.BeaconProposer, slashingEpoch); var signingRoot1 = proposerSlashing.Header1.SigningRoot(); var signature1 = proposerSlashing.Header1.Signature; var header1Valid = _cryptographyService.BlsVerify(proposer.PublicKey, signingRoot1, signature1, domain); if (!header1Valid) { throw new Exception("Proposer slashing header 1 signature is not valid."); } var signingRoot2 = proposerSlashing.Header2.SigningRoot(); var signature2 = proposerSlashing.Header2.Signature; var header2Valid = _cryptographyService.BlsVerify(proposer.PublicKey, signingRoot2, signature2, domain); if (!header2Valid) { throw new Exception("Proposer slashing header 2 signature is not valid."); } _beaconStateMutator.SlashValidator(state, proposerSlashing.ProposerIndex, ValidatorIndex.None); }