public void InvalidSignature()
        {
            // Arrange
            IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider();
            BeaconState      state = TestState.PrepareTestState(testServiceProvider);

            TimeParameters      timeParameters      = testServiceProvider.GetService <IOptions <TimeParameters> >().Value;
            BeaconStateAccessor beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>();

            // move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
            ulong move    = timeParameters.SlotsPerEpoch * (ulong)timeParameters.PersistentCommitteePeriod;
            ulong newSlot = state.Slot + move;

            state.SetSlot((Slot)newSlot);

            Epoch          currentEpoch   = beaconStateAccessor.GetCurrentEpoch(state);
            ValidatorIndex validatorIndex = beaconStateAccessor.GetActiveValidatorIndices(state, currentEpoch)[0];
            Validator      validator      = state.Validators[(int)(ulong)validatorIndex];

            byte[] privateKey = TestKeys.PublicKeyToPrivateKey(validator.PublicKey, timeParameters);

            VoluntaryExit       voluntaryExit       = TestVoluntaryExit.BuildVoluntaryExit(testServiceProvider, currentEpoch, validatorIndex);
            SignedVoluntaryExit signedVoluntaryExit = new SignedVoluntaryExit(voluntaryExit, BlsSignature.Zero);

            RunVoluntaryExitProcessing(testServiceProvider, state, signedVoluntaryExit, expectValid: false);
        }
示例#2
0
        private static SignedVoluntaryExit DecodeSignedVoluntaryExit(ReadOnlySpan <byte> span, ref int offset)
        {
            VoluntaryExit message   = DecodeVoluntaryExit(span, ref offset);
            BlsSignature  signature = DecodeBlsSignature(span, ref offset);

            return(new SignedVoluntaryExit(message, signature));
        }
        public Root HashTreeRoot(VoluntaryExit voluntaryExit)
        {
            Merkle.Ize(out UInt256 root, voluntaryExit);
            Span <byte> bytes = MemoryMarshal.Cast <UInt256, byte>(MemoryMarshal.CreateSpan(ref root, 1));

            return(new Root(bytes));
        }
示例#4
0
        public static void Ize(out UInt256 root, VoluntaryExit container)
        {
            Merkleizer merkleizer = new Merkleizer(1);

            merkleizer.Feed(container.Epoch);
            merkleizer.Feed(container.ValidatorIndex);
            merkleizer.CalculateRoot(out root);
        }
示例#5
0
        private static VoluntaryExit DecodeVoluntaryExit(ReadOnlySpan <byte> span, ref int offset)
        {
            VoluntaryExit container =
                DecodeVoluntaryExit(span.Slice(offset, VoluntaryExitLength));

            offset += VoluntaryExitLength;
            return(container);
        }
示例#6
0
        public static VoluntaryExit BuildVoluntaryExit(IServiceProvider testServiceProvider, BeaconState state, Epoch epoch, ValidatorIndex validatorIndex, byte[] privateKey, bool signed)
        {
            var voluntaryExit = new VoluntaryExit(epoch, validatorIndex, BlsSignature.Empty);

            if (signed)
            {
                SignVoluntaryExit(testServiceProvider, state, voluntaryExit, privateKey);
            }
            return(voluntaryExit);
        }
示例#7
0
        private static void TestVoluntaryExitSsz(byte[] serialized, UInt256 expectedMerkleRoot, string testCaseDir)
        {
            VoluntaryExit container = Nethermind.Ssz.Ssz.DecodeVoluntaryExit(serialized);

            byte[] again = new byte[serialized.Length];
            Nethermind.Ssz.Ssz.Encode(again, container);
            Assert.AreEqual(serialized.ToHexString(), again.ToHexString(), testCaseDir);

            Merkle.Ize(out UInt256 root, container);
            Assert.AreEqual(expectedMerkleRoot, root);
        }
        private static IEnumerable <SszElement> GetValues(VoluntaryExit item, bool forSigning)
        {
            yield return(item.Epoch.ToSszBasicElement());

            yield return(item.ValidatorIndex.ToSszBasicElement());

            if (!forSigning)
            {
                yield return(item.Signature.ToSszBasicVector());
            }
        }
示例#9
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);
        }
示例#10
0
        public static VoluntaryExit DecodeVoluntaryExit(ReadOnlySpan <byte> span)
        {
            if (span.Length != Ssz.VoluntaryExitLength)
            {
                ThrowSourceLength <VoluntaryExit>(span.Length, Ssz.VoluntaryExitLength);
            }
            int            offset         = 0;
            Epoch          epoch          = DecodeEpoch(span, ref offset);
            ValidatorIndex validatorIndex = DecodeValidatorIndex(span, ref offset);
            VoluntaryExit  container      = new VoluntaryExit(epoch, validatorIndex);

            return(container);
        }
示例#11
0
        public static void Ize(out UInt256 root, VoluntaryExit container)
        {
            if (container == null)
            {
                root = RootOfNull;
                return;
            }

            Merkleizer merkleizer = new Merkleizer(2);

            merkleizer.Feed(container.Epoch);
            merkleizer.Feed(container.ValidatorIndex);
            merkleizer.Feed(container.Signature);
            merkleizer.CalculateRoot(out root);
        }
示例#12
0
        public static void Encode(Span <byte> span, VoluntaryExit container)
        {
            if (span.Length != Ssz.VoluntaryExitLength)
            {
                ThrowTargetLength <VoluntaryExit>(span.Length, Ssz.VoluntaryExitLength);
            }
            if (container == null)
            {
                return;
            }
            int offset = 0;

            Encode(span, container.Epoch, ref offset);
            Encode(span, container.ValidatorIndex, ref offset);
        }
示例#13
0
        public void Voluntary_exit_there_and_back()
        {
            VoluntaryExit container = new VoluntaryExit(
                new Epoch(1),
                new ValidatorIndex(2));

            Span <byte> encoded = new byte[Ssz.VoluntaryExitLength];

            Ssz.Encode(encoded, container);
            VoluntaryExit?decoded = Ssz.DecodeVoluntaryExit(encoded);

            Assert.AreEqual(container, decoded);

            Merkle.Ize(out UInt256 root, container);
        }
示例#14
0
        public static VoluntaryExit[] DecodeVoluntaryExits(Span <byte> span)
        {
            if (span.Length % VoluntaryExit.SszLength != 0)
            {
                ThrowInvalidSourceArrayLength <VoluntaryExit>(span.Length, VoluntaryExit.SszLength);
            }

            int count = span.Length / VoluntaryExit.SszLength;

            VoluntaryExit[] containers = new VoluntaryExit[count];
            for (int i = 0; i < count; i++)
            {
                containers[i] = DecodeVoluntaryExit(span.Slice(i * VoluntaryExit.SszLength, VoluntaryExit.SszLength));
            }

            return(containers);
        }
示例#15
0
        public void Voluntary_exit_there_and_back()
        {
            VoluntaryExit container = new VoluntaryExit();

            container.Epoch          = new Epoch(1);
            container.ValidatorIndex = new ValidatorIndex(2);
            container.Signature      = BlsSignature.TestSig1;

            Span <byte> encoded = new byte[VoluntaryExit.SszLength];

            Ssz.Encode(encoded, container);
            VoluntaryExit?decoded = Ssz.DecodeVoluntaryExit(encoded);

            Assert.AreEqual(container, decoded);

            Merkle.Ize(out UInt256 root, container);
        }
示例#16
0
        public static VoluntaryExit?DecodeVoluntaryExit(Span <byte> span)
        {
            if (span.Length != Ssz.VoluntaryExitLength)
            {
                ThrowSourceLength <VoluntaryExit>(span.Length, Ssz.VoluntaryExitLength);
            }
            if (span.SequenceEqual(_nullVoluntaryExit))
            {
                return(null);
            }
            int            offset         = 0;
            Epoch          epoch          = DecodeEpoch(span, ref offset);
            ValidatorIndex validatorIndex = DecodeValidatorIndex(span, ref offset);
            BlsSignature   signature      = DecodeBlsSignature(span, ref offset);
            VoluntaryExit  container      = new VoluntaryExit(epoch, validatorIndex, signature);

            return(container);
        }
示例#17
0
        public static VoluntaryExit?DecodeVoluntaryExit(Span <byte> span)
        {
            if (span.Length != VoluntaryExit.SszLength)
            {
                ThrowSourceLength <VoluntaryExit>(span.Length, VoluntaryExit.SszLength);
            }
            if (span.SequenceEqual(_nullVoluntaryExit))
            {
                return(null);
            }
            int           offset    = 0;
            VoluntaryExit container = new VoluntaryExit();

            container.Epoch          = DecodeEpoch(span, ref offset);
            container.ValidatorIndex = DecodeValidatorIndex(span, ref offset);
            container.Signature      = DecodeBlsSignature(span, ref offset);
            return(container);
        }
 public static SszContainer ToSszContainer(this VoluntaryExit item)
 {
     return(new SszContainer(GetValues(item, false)));
 }
        public static Hash32 SigningRoot(this VoluntaryExit item)
        {
            var tree = new SszTree(new SszContainer(GetValues(item, true)));

            return(new Hash32(tree.HashTreeRoot()));
        }
示例#20
0
 public Hash32 SigningRoot(VoluntaryExit voluntaryExit)
 {
     return voluntaryExit.SigningRoot();
 }
示例#21
0
 private static void Encode(Span <byte> span, VoluntaryExit value, ref int offset)
 {
     Encode(span.Slice(offset, VoluntaryExitLength), value);
     offset += VoluntaryExitLength;
 }
示例#22
0
        //    Run ``process_voluntary_exit``, yielding:
        //  - pre-state('pre')
        //  - voluntary_exit('voluntary_exit')
        //  - post-state('post').
        //If ``valid == False``, run expecting ``AssertionError``
        private void RunVoluntaryExitProcessing(IServiceProvider testServiceProvider, BeaconState state, VoluntaryExit voluntaryExit, bool expectValid)
        {
            TimeParameters        timeParameters        = testServiceProvider.GetService <IOptions <TimeParameters> >().Value;
            MaxOperationsPerBlock maxOperationsPerBlock = testServiceProvider.GetService <IOptions <MaxOperationsPerBlock> >().Value;

            ChainConstants        chainConstants        = testServiceProvider.GetService <ChainConstants>();
            BeaconStateAccessor   beaconStateAccessor   = testServiceProvider.GetService <BeaconStateAccessor>();
            BeaconStateTransition beaconStateTransition = testServiceProvider.GetService <BeaconStateTransition>();

            // Act
            if (!expectValid)
            {
                Should.Throw <Exception>(() =>
                {
                    beaconStateTransition.ProcessVoluntaryExit(state, voluntaryExit);
                });
                return;
            }

            ValidatorIndex validatorIndex = voluntaryExit.ValidatorIndex;

            Epoch preExitEpoch = state.Validators[(int)(ulong)validatorIndex].ExitEpoch;

            beaconStateTransition.ProcessVoluntaryExit(state, voluntaryExit);

            // Assert
            preExitEpoch.ShouldBe(chainConstants.FarFutureEpoch);

            Epoch postExitEpoch = state.Validators[(int)(ulong)validatorIndex].ExitEpoch;

            postExitEpoch.ShouldBeLessThan(chainConstants.FarFutureEpoch);
        }
        public static SignedVoluntaryExit SignVoluntaryExit(IServiceProvider testServiceProvider, BeaconState state, VoluntaryExit voluntaryExit, byte[] privateKey)
        {
            var signatureDomains = testServiceProvider.GetService <IOptions <SignatureDomains> >().Value;
            BeaconChainUtility beaconChainUtility = testServiceProvider.GetService <BeaconChainUtility>();
            var beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>();
            ICryptographyService cryptographyService = testServiceProvider.GetService <ICryptographyService>();

            var voluntaryExitRoot = cryptographyService.HashTreeRoot(voluntaryExit);
            var domain            = beaconStateAccessor.GetDomain(state, signatureDomains.VoluntaryExit, voluntaryExit.Epoch);
            var signingRoot       = beaconChainUtility.ComputeSigningRoot(voluntaryExitRoot, domain);
            var signature         = TestSecurity.BlsSign(signingRoot, privateKey);

            return(new SignedVoluntaryExit(voluntaryExit, signature));
        }
        public static VoluntaryExit BuildVoluntaryExit(IServiceProvider testServiceProvider, Epoch epoch, ValidatorIndex validatorIndex)
        {
            var voluntaryExit = new VoluntaryExit(epoch, validatorIndex);

            return(voluntaryExit);
        }
示例#25
0
 public Hash32 SigningRoot(VoluntaryExit voluntaryExit)
 {
     throw new NotImplementedException();
 }
示例#26
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);
        }
 public Root HashTreeRoot(VoluntaryExit voluntaryExit)
 {
     return(voluntaryExit.HashTreeRoot());
 }
        public SszBeaconBlockBodyBenchmark()
        {
            AttestationData data = new AttestationData(
                new Slot(1),
                new CommitteeIndex(4),
                Sha256.OfAnEmptyString,
                new Checkpoint(new Epoch(2), Sha256.OfAnEmptyString),
                new Checkpoint(new Epoch(3), Sha256.OfAnEmptyString));

            Attestation attestation = new Attestation(
                new BitArray(new byte[5]),
                data,
                SszTest.TestSig1
                );

            DepositData depositData = new DepositData(
                SszTest.TestKey1,
                Sha256.OfAnEmptyString,
                new Gwei(7),
                SszTest.TestSig1);

            Deposit deposit = new Deposit(
                new Hash32[Ssz.DepositContractTreeDepth + 1],
                depositData);

            IndexedAttestation indexedAttestation1 = new IndexedAttestation(
                new ValidatorIndex[8],
                data,
                SszTest.TestSig1);

            IndexedAttestation indexedAttestation2 = new IndexedAttestation(
                new ValidatorIndex[8],
                data,
                SszTest.TestSig1);

            AttesterSlashing slashing = new AttesterSlashing(indexedAttestation1, indexedAttestation2);

            Eth1Data eth1Data = new Eth1Data(
                Sha256.OfAnEmptyString,
                9,
                Sha256.OfAnEmptyString);

            Attestation[] attestations = new Attestation[3];
            attestations[1] = attestation;

            Deposit[] deposits = new Deposit[3];
            deposits[2] = deposit;

            Bytes32 graffiti = new Bytes32(new byte[32]);

            AttesterSlashing[] attesterSlashings = new AttesterSlashing[3];
            attesterSlashings[0] = slashing;

            ProposerSlashing[] proposerSlashings = new ProposerSlashing[10];

            BlsSignature randaoReveal = SszTest.TestSig1;

            VoluntaryExit[] voluntaryExits = new VoluntaryExit[11];

            _body = new BeaconBlockBody(randaoReveal,
                                        eth1Data,
                                        graffiti,
                                        proposerSlashings,
                                        attesterSlashings,
                                        attestations,
                                        deposits,
                                        voluntaryExits);

            _encoded = new byte[Ssz.BeaconBlockBodyLength(_body)];
        }
示例#29
0
 public Root HashTreeRoot(VoluntaryExit voluntaryExit)
 {
     throw new NotImplementedException();
 }
示例#30
0
 public SignedVoluntaryExit(VoluntaryExit message, BlsSignature signature)
 {
     Message   = message;
     Signature = signature;
 }