コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
 public Hash32 SigningRoot(VoluntaryExit voluntaryExit)
 {
     return voluntaryExit.SigningRoot();
 }