public static void SignVoluntaryExit(IServiceProvider testServiceProvider, BeaconState state, VoluntaryExit voluntaryExit, byte[] privateKey) { var signatureDomains = testServiceProvider.GetService <IOptions <SignatureDomains> >().Value; var beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>(); var domain = beaconStateAccessor.GetDomain(state, signatureDomains.VoluntaryExit, voluntaryExit.Epoch); var signature = TestSecurity.BlsSign(voluntaryExit.SigningRoot(), privateKey, domain); voluntaryExit.SetSignature(signature); }
public void ProcessVoluntaryExit(BeaconState state, VoluntaryExit exit) { _logger.LogInformation(Event.ProcessVoluntaryExit, "Process block operation voluntary exit {VoluntaryExit} for state {BeaconState}.", exit, state); var validator = state.Validators[(int)(ulong)exit.ValidatorIndex]; //#Verify the validator is active var currentEpoch = _beaconStateAccessor.GetCurrentEpoch(state); var isActiveValidator = _beaconChainUtility.IsActiveValidator(validator, currentEpoch); if (!isActiveValidator) { throw new Exception($"Validator {exit.ValidatorIndex} must be active in order to exit."); } //# Verify the validator has not yet exited var hasExited = validator.ExitEpoch != _chainConstants.FarFutureEpoch; if (hasExited) { throw new Exception($"Validator {exit.ValidatorIndex} already has exit epoch {validator.ExitEpoch}."); } //# Exits must specify an epoch when they become valid; they are not valid before then var isCurrentAtOrAfterExit = currentEpoch >= exit.Epoch; if (!isCurrentAtOrAfterExit) { throw new Exception($"Validator {exit.ValidatorIndex} can not exit because the current epoch {currentEpoch} has not yet reached their exit epoch {validator.ExitEpoch}."); } //# Verify the validator has been active long enough var timeParameters = _timeParameterOptions.CurrentValue; var minimumActiveEpoch = validator.ActivationEpoch + timeParameters.PersistentCommitteePeriod; var isCurrentAtOrAfterMinimum = currentEpoch >= minimumActiveEpoch; if (!isCurrentAtOrAfterMinimum) { throw new Exception($"Validator {exit.ValidatorIndex} can not exit because the current epoch {currentEpoch} has not yet reached the minimum active epoch of {timeParameters.PersistentCommitteePeriod} after their activation epoch {validator.ActivationEpoch}."); } //# Verify signature var domain = _beaconStateAccessor.GetDomain(state, _signatureDomainOptions.CurrentValue.VoluntaryExit, exit.Epoch); var signingRoot = exit.SigningRoot(); var validSignature = _cryptographyService.BlsVerify(validator.PublicKey, signingRoot, exit.Signature, domain); if (!validSignature) { throw new Exception("Voluntary exit signature is not valid."); } //# Initiate exit _beaconStateMutator.InitiateValidatorExit(state, exit.ValidatorIndex); }
public Hash32 SigningRoot(VoluntaryExit voluntaryExit) { return voluntaryExit.SigningRoot(); }