private async Task RunOnAttestation(IServiceProvider testServiceProvider, BeaconState state, IStore store, Attestation attestation, bool expectValid)
        {
            MiscellaneousParameters miscellaneousParameters = testServiceProvider.GetService <IOptions <MiscellaneousParameters> >().Value;
            MaxOperationsPerBlock   maxOperationsPerBlock   = testServiceProvider.GetService <IOptions <MaxOperationsPerBlock> >().Value;

            IForkChoice forkChoice = testServiceProvider.GetService <IForkChoice>();

            if (!expectValid)
            {
                Should.Throw <Exception>(async() =>
                {
                    await forkChoice.OnAttestationAsync(store, attestation);
                });
                return;
            }

            BeaconStateAccessor beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>();
            IndexedAttestation  indexedAttestation  = beaconStateAccessor.GetIndexedAttestation(state, attestation);
            await forkChoice.OnAttestationAsync(store, attestation);

            IEnumerable <ValidatorIndex> attestingIndices = beaconStateAccessor.GetAttestingIndices(state, attestation.Data, attestation.AggregationBits);
            ValidatorIndex firstAttestingIndex            = attestingIndices.First();
            LatestMessage  latestMessage = (await store.GetLatestMessageAsync(firstAttestingIndex, true)) !;

            latestMessage.Epoch.ShouldBe(attestation.Data.Target.Epoch);
            latestMessage.Root.ShouldBe(attestation.Data.BeaconBlockRoot);
        }
Beispiel #2
0
        public static AttesterSlashing GetValidAttesterSlashing(IServiceProvider testServiceProvider, BeaconState state, bool signed1, bool signed2)
        {
            TimeParameters      timeParameters      = testServiceProvider.GetService <IOptions <TimeParameters> >().Value;
            BeaconStateAccessor beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>();

            Attestation attestation1 = TestAttestation.GetValidAttestation(testServiceProvider, state, Slot.None, CommitteeIndex.None, signed1);

            Hash32      targetRoot2  = new Hash32(Enumerable.Repeat((byte)0x01, 32).ToArray());
            Attestation attestation2 = new Attestation(
                attestation1.AggregationBits,
                new AttestationData(attestation1.Data.Slot,
                                    attestation1.Data.Index,
                                    attestation1.Data.BeaconBlockRoot,
                                    attestation1.Data.Source,
                                    new Checkpoint(
                                        attestation1.Data.Target.Epoch,
                                        targetRoot2
                                        )),
                BlsSignature.Empty
                );

            if (signed2)
            {
                TestAttestation.SignAttestation(testServiceProvider, state, attestation2);
            }

            IndexedAttestation indexedAttestation1 = beaconStateAccessor.GetIndexedAttestation(state, attestation1);
            IndexedAttestation indexedAttestation2 = beaconStateAccessor.GetIndexedAttestation(state, attestation2);

            AttesterSlashing attesterSlashing = new AttesterSlashing(indexedAttestation1, indexedAttestation2);

            return(attesterSlashing);
        }
Beispiel #3
0
 public AttesterSlashing(
     IndexedAttestation attestation1,
     IndexedAttestation attestation2)
 {
     Attestation1 = attestation1;
     Attestation2 = attestation2;
 }
        public void Indexed_attestation_there_and_back()
        {
            AttestationData data = new AttestationData();

            data.Slot            = new Slot(1);
            data.CommitteeIndex  = new CommitteeIndex(2);
            data.BeaconBlockRoot = Sha256.OfAnEmptyString;
            data.Source          = new Checkpoint(new Epoch(1), Sha256.OfAnEmptyString);
            data.Target          = new Checkpoint(new Epoch(2), Sha256.OfAnEmptyString);

            IndexedAttestation container = new IndexedAttestation();

            container.AttestingIndices = new ValidatorIndex[3];
            container.Data             = data;
            container.Signature        = BlsSignature.TestSig1;

            Span <byte> encoded = new byte[IndexedAttestation.SszLength(container)];

            Ssz.Encode(encoded, container);
            IndexedAttestation decoded = Ssz.DecodeIndexedAttestation(encoded);

            Assert.AreEqual(container, decoded);

            Merkle.Ize(out UInt256 root, container);
        }
Beispiel #5
0
        public void Attester_slashing_there_and_back()
        {
            AttestationData data = new AttestationData(
                new Slot(1),
                new CommitteeIndex(2),
                Sha256.RootOfAnEmptyString,
                new Checkpoint(new Epoch(1), Sha256.RootOfAnEmptyString),
                new Checkpoint(new Epoch(2), Sha256.RootOfAnEmptyString));

            IndexedAttestation indexedAttestation1 = new IndexedAttestation(
                new ValidatorIndex[3],
                data,
                TestSig1);

            IndexedAttestation indexedAttestation2 = new IndexedAttestation(
                new ValidatorIndex[5],
                data,
                TestSig1);

            AttesterSlashing container = new AttesterSlashing(indexedAttestation1, indexedAttestation2);

            Span <byte> encoded = new byte[Ssz.AttesterSlashingLength(container)];

            Ssz.Encode(encoded, container);
            AttesterSlashing?decoded = Ssz.DecodeAttesterSlashing(encoded);

            Assert.AreEqual(container, decoded);

            Merkle.Ize(out UInt256 root, container);
        }
        private static IEnumerable <SszElement> GetValues(IndexedAttestation item, ulong maximumValidatorsPerCommittee)
        {
            yield return(item.AttestingIndices.ToSszBasicList(maximumValidatorsPerCommittee));

            yield return(item.Data.ToSszContainer());

            yield return(item.Signature.ToSszBasicVector());
        }
Beispiel #7
0
        public static void Ize(out UInt256 root, IndexedAttestation container)
        {
            Merkleizer merkleizer = new Merkleizer(2);

            merkleizer.Feed(container.AttestingIndices, Attestation.MaxValidatorsPerCommittee);
            merkleizer.Feed(container.Data);
            merkleizer.Feed(container.Signature);
            merkleizer.CalculateRoot(out root);
        }
Beispiel #8
0
        private static IEnumerable <SszElement> GetValues(IndexedAttestation item, MiscellaneousParameters miscellaneousParameters)
        {
            yield return(item.CustodyBit0Indices.ToSszBasicList(miscellaneousParameters.MaximumValidatorsPerCommittee));

            yield return(item.CustodyBit1Indices.ToSszBasicList(miscellaneousParameters.MaximumValidatorsPerCommittee));

            yield return(item.Data.ToSszContainer());

            yield return(item.Signature.ToSszBasicVector());
        }
Beispiel #9
0
        /// <summary>
        /// Return the indexed attestation corresponding to ``attestation``.
        /// </summary>
        public IndexedAttestation GetIndexedAttestation(BeaconState state, Attestation attestation)
        {
            IEnumerable <ValidatorIndex> attestingIndices = GetAttestingIndices(state, attestation.Data, attestation.AggregationBits);

            IOrderedEnumerable <ValidatorIndex> sortedAttestingIndices = attestingIndices.OrderBy(x => x);

            IndexedAttestation indexedAttestation = new IndexedAttestation(sortedAttestingIndices, attestation.Data, attestation.Signature);

            return(indexedAttestation);
        }
Beispiel #10
0
        public static IndexedAttestation DecodeIndexedAttestation(Span <byte> span)
        {
            IndexedAttestation container = new IndexedAttestation();
            int offset = 0;

            DecodeDynamicOffset(span, ref offset, out int dynamicOffset1);
            container.AttestingIndices = DecodeValidatorIndexes(span.Slice(dynamicOffset1));
            container.Data             = DecodeAttestationData(span, ref offset);
            container.Signature        = DecodeBlsSignature(span, ref offset);
            return(container);
        }
Beispiel #11
0
        private static void TestIndexedAttestationSsz(byte[] serialized, UInt256 expectedMerkleRoot, string testCaseDir)
        {
            IndexedAttestation container = Nethermind.Ssz.Ssz.DecodeIndexedAttestation(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);
        }
Beispiel #12
0
        public static IndexedAttestation DecodeIndexedAttestation(ReadOnlySpan <byte> span)
        {
            int offset = 0;

            DecodeDynamicOffset(span, ref offset, out int dynamicOffset1);
            ValidatorIndex[]   attestingIndices = DecodeValidatorIndexes(span.Slice(dynamicOffset1));
            AttestationData    data             = DecodeAttestationData(span, ref offset);
            BlsSignature       signature        = DecodeBlsSignature(span, ref offset);
            IndexedAttestation container        = new IndexedAttestation(attestingIndices, data, signature);

            return(container);
        }
Beispiel #13
0
        public static void Encode(Span <byte> span, IndexedAttestation container)
        {
            if (span.Length != IndexedAttestation.SszLength(container))
            {
                ThrowTargetLength <IndexedAttestation>(span.Length, IndexedAttestation.SszLength(container));
            }

            int offset        = 0;
            int dynamicOffset = IndexedAttestation.SszDynamicOffset;

            Encode(span, container.AttestingIndices, ref offset, ref dynamicOffset);
            Encode(span, container.Data, ref offset);
            Encode(span, container.Signature, ref offset);
        }
Beispiel #14
0
        public static AttesterSlashing DecodeAttesterSlashing(ReadOnlySpan <byte> span)
        {
            int offset1 = (int)DecodeUInt(span.Slice(0, VarOffsetSize));
            int offset2 = (int)DecodeUInt(span.Slice(VarOffsetSize, VarOffsetSize));

            int length1 = offset2 - offset1;
            int length2 = span.Length - offset2;

            IndexedAttestation attestation1 = DecodeIndexedAttestation(span.Slice(offset1, length1));
            IndexedAttestation attestation2 = DecodeIndexedAttestation(span.Slice(offset2, length2));

            AttesterSlashing attesterSlashing = new AttesterSlashing(attestation1, attestation2);

            return(attesterSlashing);
        }
        /// <summary>
        /// Return the indexed attestation corresponding to ``attestation``.
        /// </summary>
        public IndexedAttestation GetIndexedAttestation(BeaconState state, Attestation attestation)
        {
            var attestingIndices   = GetAttestingIndices(state, attestation.Data, attestation.AggregationBits);
            var custodyBit1Indices = GetAttestingIndices(state, attestation.Data, attestation.CustodyBits);

            var isSubset = custodyBit1Indices.All(x => attestingIndices.Contains(x));

            if (!isSubset)
            {
                throw new Exception("Custody bit indices must be a subset of attesting indices");
            }

            var custodyBit0Indices = attestingIndices.Except(custodyBit1Indices);

            var sortedCustodyBit0Indices = custodyBit0Indices.OrderBy(x => x);
            var sortedCustodyBit1Indices = custodyBit1Indices.OrderBy(x => x);

            var indexedAttestation = new IndexedAttestation(sortedCustodyBit0Indices, sortedCustodyBit1Indices, attestation.Data, attestation.Signature);

            return(indexedAttestation);
        }
Beispiel #16
0
        /// <summary>
        /// Return the indexed attestation corresponding to ``attestation``.
        /// </summary>
        public IndexedAttestation GetIndexedAttestation(BeaconState state, Attestation attestation)
        {
            IEnumerable <ValidatorIndex> attestingIndices   = GetAttestingIndices(state, attestation.Data, attestation.AggregationBits);
            IEnumerable <ValidatorIndex> custodyBit1Indices = GetAttestingIndices(state, attestation.Data, attestation.CustodyBits);

            bool isSubset = custodyBit1Indices.All(x => attestingIndices.Contains(x));

            if (!isSubset)
            {
                throw new Exception("Custody bit indices must be a subset of attesting indices");
            }

            IEnumerable <ValidatorIndex> custodyBit0Indices = attestingIndices.Except(custodyBit1Indices);

            IOrderedEnumerable <ValidatorIndex> sortedCustodyBit0Indices = custodyBit0Indices.OrderBy(x => x);
            IOrderedEnumerable <ValidatorIndex> sortedCustodyBit1Indices = custodyBit1Indices.OrderBy(x => x);

            IndexedAttestation indexedAttestation = new IndexedAttestation(sortedCustodyBit0Indices, sortedCustodyBit1Indices, attestation.Data, attestation.Signature);

            return(indexedAttestation);
        }
        /// <summary>
        /// Check if ``indexed_attestation`` has valid indices and signature.
        /// </summary>
        public bool IsValidIndexedAttestation(BeaconState state, IndexedAttestation indexedAttestation, Domain domain)
        {
            MiscellaneousParameters miscellaneousParameters = _miscellaneousParameterOptions.CurrentValue;
            IReadOnlyList<ValidatorIndex> attestingIndices = indexedAttestation.AttestingIndices;

            // Verify max number of indices
            if ((ulong) attestingIndices.Count > miscellaneousParameters.MaximumValidatorsPerCommittee)
            {
                if (_logger.IsWarn()) Log.InvalidIndexedAttestationTooMany(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, attestingIndices.Count, miscellaneousParameters.MaximumValidatorsPerCommittee, null);
                return false;
            }

            // Verify indices are sorted
            if (attestingIndices.Count() > 1)
            {
                for (int index = 0; index < attestingIndices.Count() - 1; index++)
                {
                    if (!(attestingIndices[index] < attestingIndices[index + 1]))
                    {
                        if (_logger.IsWarn()) Log.InvalidIndexedAttestationNotSorted(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, 0, index, null);
                        return false;
                    }
                }
            }

            // Verify aggregate signature
            IEnumerable<BlsPublicKey> publicKeys = attestingIndices.Select(x => state.Validators[(int) (ulong) x].PublicKey);
            BlsPublicKey aggregatePublicKey = _cryptographyService.BlsAggregatePublicKeys(publicKeys);
            Hash32 messageHash = _cryptographyService.HashTreeRoot(indexedAttestation.Data);
            BlsSignature signature = indexedAttestation.Signature;

            bool isValid = _cryptographyService.BlsVerify(aggregatePublicKey, messageHash, signature, domain);
            if (!isValid)
            {
                if (_logger.IsWarn()) Log.InvalidIndexedAttestationSignature(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, null);
                return false;
            }

            return true;
        }
Beispiel #18
0
        public void Indexed_attestation_there_and_back()
        {
            AttestationData data = new AttestationData(
                new Slot(1),
                new CommitteeIndex(2),
                Sha256.RootOfAnEmptyString,
                new Checkpoint(new Epoch(1), Sha256.RootOfAnEmptyString),
                new Checkpoint(new Epoch(2), Sha256.RootOfAnEmptyString));

            IndexedAttestation container = new IndexedAttestation(
                new ValidatorIndex[3],
                data,
                TestSig1);

            Span <byte> encoded = new byte[Ssz.IndexedAttestationLength(container)];

            Ssz.Encode(encoded, container);
            IndexedAttestation decoded = Ssz.DecodeIndexedAttestation(encoded);

            decoded.ShouldBe(container);

            Merkle.Ize(out UInt256 root, container);
        }
Beispiel #19
0
        public static void Encode(Span <byte> span, AttesterSlashing?container)
        {
            if (span.Length != AttesterSlashing.SszLength(container))
            {
                ThrowTargetLength <AttesterSlashing>(span.Length, AttesterSlashing.SszLength(container));
            }

            if (container == null)
            {
                return;
            }

            int dynamicOffset = 2 * VarOffsetSize;
            int length1       = IndexedAttestation.SszLength(container.Attestation1);

            Encode(span.Slice(0, VarOffsetSize), dynamicOffset);
            Encode(span.Slice(dynamicOffset, length1), container.Attestation1);

            dynamicOffset += IndexedAttestation.SszLength(container.Attestation1);
            int length2 = IndexedAttestation.SszLength(container.Attestation2);

            Encode(span.Slice(VarOffsetSize, VarOffsetSize), dynamicOffset);
            Encode(span.Slice(dynamicOffset, length2), container.Attestation2);
        }
        /// <summary>
        /// Run ``on_attestation`` upon receiving a new ``attestation`` from either within a block or directly on the wire.
        /// An ``attestation`` that is asserted as invalid may be valid at a later time,
        /// consider scheduling it for later processing in such case.
        /// </summary>
        public async Task OnAttestationAsync(IStore store, Attestation attestation)
        {
            if (_logger.IsInfo())
            {
                Log.OnAttestation(_logger, attestation, null);
            }

            TimeParameters timeParameters = _timeParameterOptions.CurrentValue;

            Checkpoint target = attestation.Data.Target;

            // Attestations must be from the current or previous epoch
            Slot  currentSlot  = GetCurrentSlot(store);
            Epoch currentEpoch = _beaconChainUtility.ComputeEpochAtSlot(currentSlot);

            // Use GENESIS_EPOCH for previous when genesis to avoid underflow
            Epoch previousEpoch = currentEpoch > _chainConstants.GenesisEpoch
                ? currentEpoch - new Epoch(1)
                : _chainConstants.GenesisEpoch;

            if (target.Epoch != currentEpoch && target.Epoch != previousEpoch)
            {
                throw new ArgumentOutOfRangeException("attestation.Target.Epoch", target.Epoch,
                                                      $"Attestation target epoch must be either the current epoch {currentEpoch} or previous epoch {previousEpoch}.");
            }

            Epoch dataSlotEpoch = _beaconChainUtility.ComputeEpochAtSlot(attestation.Data.Slot);

            if (attestation.Data.Target.Epoch != dataSlotEpoch)
            {
                throw new ArgumentOutOfRangeException("attestation.Data.Target.Epoch", attestation.Data.Target.Epoch,
                                                      $"Attestation data target epoch must match the attestation data slot {attestation.Data.Slot} (epoch {dataSlotEpoch}).");
            }

            // Attestations target be for a known block. If target block is unknown, delay consideration until the block is found
            BeaconBlock targetBlock = (await store.GetSignedBlockAsync(target.Root).ConfigureAwait(false)).Message;

            // Attestations cannot be from future epochs. If they are, delay consideration until the epoch arrives
            BeaconState targetStoredState = await store.GetBlockStateAsync(target.Root).ConfigureAwait(false);

            BeaconState baseState            = BeaconState.Clone(targetStoredState);
            Slot        targetEpochStartSlot = _beaconChainUtility.ComputeStartSlotOfEpoch(target.Epoch);

            if (currentSlot < targetEpochStartSlot)
            {
                throw new Exception(
                          $"Ättestation target epoch start slot {targetEpochStartSlot} should not be larger than the store current slot {currentSlot}).");
            }

            // Attestations must be for a known block. If block is unknown, delay consideration until the block is found
            BeaconBlock attestationBlock =
                (await store.GetSignedBlockAsync(attestation.Data.BeaconBlockRoot).ConfigureAwait(false)).Message;

            // Attestations must not be for blocks in the future. If not, the attestation should not be considered
            if (attestationBlock.Slot > attestation.Data.Slot)
            {
                throw new Exception(
                          $"Attestation data root slot {attestationBlock.Slot} should not be larger than the attestation data slot {attestation.Data.Slot}).");
            }

            // Store target checkpoint state if not yet seen
            BeaconState?targetState = await store.GetCheckpointStateAsync(target, false).ConfigureAwait(false);

            if (targetState == null)
            {
                _beaconStateTransition.ProcessSlots(baseState, targetEpochStartSlot);
                await store.SetCheckpointStateAsync(target, baseState).ConfigureAwait(false);

                targetState = baseState;
            }

            // Attestations can only affect the fork choice of subsequent slots.
            // Delay consideration in the fork choice until their slot is in the past.
            Slot newCurrentSlot = GetCurrentSlot(store);

            if (newCurrentSlot < attestation.Data.Slot + 1)
            {
                throw new Exception(
                          $"Attestation data slot {attestation.Data.Slot} should not be larger than the store current slot {newCurrentSlot}).");
            }

            // Get state at the `target` to validate attestation and calculate the committees
            IndexedAttestation indexedAttestation =
                _beaconStateAccessor.GetIndexedAttestation(targetState, attestation);
            Domain domain = _beaconStateAccessor.GetDomain(targetState,
                                                           _signatureDomainOptions.CurrentValue.BeaconAttester, indexedAttestation.Data.Target.Epoch);
            bool isValid = _beaconChainUtility.IsValidIndexedAttestation(targetState, indexedAttestation, domain);

            if (!isValid)
            {
                throw new Exception($"Indexed attestation {indexedAttestation} is not valid.");
            }

            // Update latest messages
            IEnumerable <ValidatorIndex> attestingIndices =
                _beaconStateAccessor.GetAttestingIndices(targetState, attestation.Data, attestation.AggregationBits);

            foreach (ValidatorIndex index in attestingIndices)
            {
                LatestMessage?latestMessage = await store.GetLatestMessageAsync(index, false).ConfigureAwait(false);

                if (latestMessage == null || target.Epoch > latestMessage !.Epoch)
                {
                    latestMessage = new LatestMessage(target.Epoch, attestation.Data.BeaconBlockRoot);
                    await store.SetLatestMessageAsync(index, latestMessage).ConfigureAwait(false);
                }
            }
        }
Beispiel #21
0
        public SszBeaconBlockBodyBenchmark()
        {
            AttestationData data = new AttestationData(
                new Slot(1),
                new CommitteeIndex(4),
                Sha256.RootOfAnEmptyString,
                new Checkpoint(new Epoch(2), Sha256.RootOfAnEmptyString),
                new Checkpoint(new Epoch(3), Sha256.RootOfAnEmptyString));

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

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

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

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

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

            AttesterSlashing slashing = new AttesterSlashing(indexedAttestation1, indexedAttestation2);

            Eth1Data eth1Data = new Eth1Data(
                Sha256.RootOfAnEmptyString,
                9,
                Sha256.Bytes32OfAnEmptyString);

            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 = TestSig1;

            SignedVoluntaryExit[] signedVoluntaryExits = new SignedVoluntaryExit[11];

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

            _encoded = new byte[Ssz.BeaconBlockBodyLength(_body)];
        }
        public void Beacon_block_body_more_detailed()
        {
            BeaconBlockBody body = new BeaconBlockBody();

            AttestationData data = new AttestationData();

            data.Slot            = new Slot(1);
            data.Source          = new Checkpoint(new Epoch(2), Sha256.OfAnEmptyString);
            data.Target          = new Checkpoint(new Epoch(3), Sha256.OfAnEmptyString);
            data.CommitteeIndex  = new CommitteeIndex(4);
            data.BeaconBlockRoot = Sha256.OfAnEmptyString;

            Attestation attestation = new Attestation();

            attestation.Data            = data;
            attestation.Signature       = BlsSignature.TestSig1;
            attestation.AggregationBits = new byte[5];

            DepositData depositData = new DepositData();

            depositData.Amount                = new Gwei(7);
            depositData.Signature             = BlsSignature.TestSig1;
            depositData.PublicKey             = BlsPublicKey.TestKey1;
            depositData.WithdrawalCredentials = Sha256.OfAnEmptyString;

            Deposit deposit = new Deposit();

            deposit.Data  = depositData;
            deposit.Proof = new Hash32[Deposit.ContractTreeDepth + 1];

            IndexedAttestation indexedAttestation1 = new IndexedAttestation();

            indexedAttestation1.Data             = data;
            indexedAttestation1.Signature        = BlsSignature.TestSig1;
            indexedAttestation1.AttestingIndices = new ValidatorIndex[8];

            IndexedAttestation indexedAttestation2 = new IndexedAttestation();

            indexedAttestation2.Data             = data;
            indexedAttestation2.Signature        = BlsSignature.TestSig1;
            indexedAttestation2.AttestingIndices = new ValidatorIndex[8];

            AttesterSlashing slashing = new AttesterSlashing();

            slashing.Attestation1 = indexedAttestation1;
            slashing.Attestation2 = indexedAttestation2;

            Eth1Data eth1Data = new Eth1Data();

            eth1Data.BlockHash    = Sha256.OfAnEmptyString;
            eth1Data.DepositCount = 9;
            eth1Data.DepositRoot  = Sha256.OfAnEmptyString;

            body.Attestations    = new Attestation[3];
            body.Attestations[1] = attestation;

            body.Deposits    = new Deposit[3];
            body.Deposits[2] = deposit;

            body.Graffiti             = new byte[32];
            body.AttesterSlashings    = new AttesterSlashing[3];
            body.AttesterSlashings[0] = slashing;
            body.Eth1Data             = eth1Data;
            body.ProposerSlashings    = new ProposerSlashing[10];
            body.RandaoReversal       = BlsSignature.TestSig1;
            body.VoluntaryExits       = new VoluntaryExit[11];

            byte[] encoded = new byte[BeaconBlockBody.SszLength(body)];
            Ssz.Encode(encoded, body);
        }
Beispiel #23
0
        public void Beacon_block_body_more_detailed()
        {
            AttestationData data = new AttestationData(
                new Slot(1),
                new CommitteeIndex(4),
                Sha256.RootOfAnEmptyString,
                new Checkpoint(new Epoch(2), Sha256.RootOfAnEmptyString),
                new Checkpoint(new Epoch(3), Sha256.RootOfAnEmptyString));

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

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

            Deposit deposit = new Deposit(Enumerable.Repeat(Bytes32.Zero, Ssz.DepositContractTreeDepth + 1), depositData);

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

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

            AttesterSlashing slashing = new AttesterSlashing(indexedAttestation1, indexedAttestation2);

            Eth1Data eth1Data = new Eth1Data(
                Sha256.RootOfAnEmptyString,
                9,
                Sha256.Bytes32OfAnEmptyString);

            Attestation[] attestations = Enumerable.Repeat(Attestation.Zero, 3).ToArray();
            attestations[1] = attestation;

            Deposit zeroDeposit = new Deposit(Enumerable.Repeat(Bytes32.Zero, Ssz.DepositContractTreeDepth + 1), DepositData.Zero);

            Deposit[] deposits = Enumerable.Repeat(zeroDeposit, 3).ToArray();
            deposits[2] = deposit;

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

            AttesterSlashing[] attesterSlashings = Enumerable.Repeat(AttesterSlashing.Zero, 3).ToArray();
            attesterSlashings[0] = slashing;

            ProposerSlashing[] proposerSlashings = Enumerable.Repeat(ProposerSlashing.Zero, 10).ToArray();

            SignedVoluntaryExit[] signedVoluntaryExits = Enumerable.Repeat(SignedVoluntaryExit.Zero, 11).ToArray();

            BeaconBlockBody body = new BeaconBlockBody(
                TestSig1,
                eth1Data,
                graffiti,
                proposerSlashings,
                attesterSlashings,
                attestations,
                deposits,
                signedVoluntaryExits
                );

            byte[] encoded = new byte[Ssz.BeaconBlockBodyLength(body)];
            Ssz.Encode(encoded, body);
        }
        public void Beacon_block_body_more_detailed()
        {
            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];
            VoluntaryExit[]    voluntaryExits    = new VoluntaryExit[11];

            BeaconBlockBody body = new BeaconBlockBody(
                SszTest.TestSig1,
                eth1Data,
                graffiti,
                proposerSlashings,
                attesterSlashings,
                attestations,
                deposits,
                voluntaryExits
                );

            byte[] encoded = new byte[Ssz.BeaconBlockBodyLength(body)];
            Ssz.Encode(encoded, body);
        }
 public static SszContainer ToSszContainer(this IndexedAttestation item, ulong maximumValidatorsPerCommittee)
 {
     return(new SszContainer(GetValues(item, maximumValidatorsPerCommittee)));
 }
Beispiel #26
0
        /// <summary>
        /// Check if ``indexed_attestation`` has valid indices and signature.
        /// </summary>
        public bool IsValidIndexedAttestation(BeaconState state, IndexedAttestation indexedAttestation, Domain domain)
        {
            MiscellaneousParameters miscellaneousParameters = _miscellaneousParameterOptions.CurrentValue;
            IList <ValidatorIndex>  bit0Indices             = indexedAttestation.CustodyBit0Indices;
            IList <ValidatorIndex>  bit1Indices             = indexedAttestation.CustodyBit1Indices;

            // Verify no index has custody bit equal to 1 [to be removed in phase 1]
            if (bit1Indices.Count != 0) // [to be removed in phase 1]
            {
                if (_logger.IsWarn())
                {
                    _logger.LogWarning(Event.InvalidIndexedAttestation,
                                       "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because it has {BitIndicesCount} bit 1 indices.",
                                       indexedAttestation.Data.Index, indexedAttestation.Data.Slot, bit1Indices.Count());
                }
                return(false); //[to be removed in phase 1]
            }

            // Verify max number of indices
            int totalIndices = bit0Indices.Count + bit1Indices.Count;

            if ((ulong)totalIndices > miscellaneousParameters.MaximumValidatorsPerCommittee)
            {
                if (_logger.IsWarn())
                {
                    _logger.LogWarning(Event.InvalidIndexedAttestation,
                                       "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because it has total indices {TotalIndices}, more than the maximum validators per committe {MaximumValidatorsPerCommittee}.",
                                       indexedAttestation.Data.Index, indexedAttestation.Data.Slot, totalIndices, miscellaneousParameters.MaximumValidatorsPerCommittee);
                }
                return(false);
            }

            // Verify index sets are disjoint
            IEnumerable <ValidatorIndex> intersect = bit0Indices.Intersect(bit1Indices);

            if (intersect.Count() != 0)
            {
                if (_logger.IsWarn())
                {
                    _logger.LogWarning(Event.InvalidIndexedAttestation,
                                       "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because it has {IntersectingValidatorCount} validator indexes in common between custody bit 0 and custody bit 1.",
                                       indexedAttestation.Data.Index, indexedAttestation.Data.Slot, intersect.Count());
                }
                return(false);
            }

            // Verify indices are sorted
            if (bit0Indices.Count() > 1)
            {
                for (int index = 0; index < bit0Indices.Count() - 1; index++)
                {
                    if (!(bit0Indices[index] < bit0Indices[index + 1]))
                    {
                        if (_logger.IsWarn())
                        {
                            _logger.LogWarning(Event.InvalidIndexedAttestation,
                                               "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because custody bit 0 index {IndexNumber} is not sorted.",
                                               indexedAttestation.Data.Index, indexedAttestation.Data.Slot, index);
                        }
                        return(false);
                    }
                }
            }

            if (bit1Indices.Count() > 1)
            {
                for (int index = 0; index < bit1Indices.Count() - 1; index++)
                {
                    if (!(bit1Indices[index] < bit1Indices[index + 1]))
                    {
                        if (_logger.IsWarn())
                        {
                            _logger.LogWarning(Event.InvalidIndexedAttestation,
                                               "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because custody bit 1 index {IndexNumber} is not sorted.",
                                               indexedAttestation.Data.Index, indexedAttestation.Data.Slot, index);
                        }
                        return(false);
                    }
                }
            }

            // Verify aggregate signature
            IEnumerable <BlsPublicKey> bit0PublicKeys = bit0Indices.Select(x => state.Validators[(int)(ulong)x].PublicKey);
            BlsPublicKey bit0AggregatePublicKey       = _cryptographyService.BlsAggregatePublicKeys(bit0PublicKeys);
            IEnumerable <BlsPublicKey> bit1PublicKeys = bit1Indices.Select(x => state.Validators[(int)(ulong)x].PublicKey);
            BlsPublicKey bit1AggregatePublicKey       = _cryptographyService.BlsAggregatePublicKeys(bit1PublicKeys);

            BlsPublicKey[] publicKeys = new[] { bit0AggregatePublicKey, bit1AggregatePublicKey };

            AttestationDataAndCustodyBit attestationDataAndCustodyBit0 = new AttestationDataAndCustodyBit(indexedAttestation.Data, false);
            Hash32 messageHashBit0 = attestationDataAndCustodyBit0.HashTreeRoot();
            AttestationDataAndCustodyBit attestationDataAndCustodyBit1 = new AttestationDataAndCustodyBit(indexedAttestation.Data, true);
            Hash32 messageHashBit1 = attestationDataAndCustodyBit1.HashTreeRoot();

            Hash32[] messageHashes = new[] { messageHashBit0, messageHashBit1 };

            BlsSignature signature = indexedAttestation.Signature;

            bool isValid = _cryptographyService.BlsVerifyMultiple(publicKeys, messageHashes, signature, domain);

            if (!isValid)
            {
                if (_logger.IsWarn())
                {
                    _logger.LogWarning(Event.InvalidIndexedAttestation,
                                       "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because the aggregate signature does not match.",
                                       indexedAttestation.Data.Index, indexedAttestation.Data.Slot);
                }
                return(false);
            }

            return(true);
        }
Beispiel #27
0
        /// <summary>
        /// Check if ``indexed_attestation`` has valid indices and signature.
        /// </summary>
        public bool IsValidIndexedAttestation(BeaconState state, IndexedAttestation indexedAttestation, Domain domain)
        {
            MiscellaneousParameters        miscellaneousParameters = _miscellaneousParameterOptions.CurrentValue;
            IReadOnlyList <ValidatorIndex> attestingIndices        = indexedAttestation.AttestingIndices;

            // Verify max number of indices
            if ((ulong)attestingIndices.Count > miscellaneousParameters.MaximumValidatorsPerCommittee)
            {
                if (_logger.IsWarn())
                {
                    Log.InvalidIndexedAttestationTooMany(_logger, indexedAttestation.Data.Index,
                                                         indexedAttestation.Data.Slot, attestingIndices.Count,
                                                         miscellaneousParameters.MaximumValidatorsPerCommittee, null);
                }
                return(false);
            }

            // Verify indices are sorted and unique
            if (attestingIndices.Count() > 1)
            {
                for (int index = 0; index < attestingIndices.Count() - 1; index++)
                {
                    if (!(attestingIndices[index] < attestingIndices[index + 1]))
                    {
                        if (attestingIndices[index] == attestingIndices[index + 1])
                        {
                            if (_logger.IsWarn())
                            {
                                Log.InvalidIndexedAttestationNotUnique(_logger, indexedAttestation.Data.Index,
                                                                       indexedAttestation.Data.Slot, 0, index, null);
                            }
                        }
                        else
                        {
                            if (_logger.IsWarn())
                            {
                                Log.InvalidIndexedAttestationNotSorted(_logger, indexedAttestation.Data.Index,
                                                                       indexedAttestation.Data.Slot, 0, index, null);
                            }
                        }

                        return(false);
                    }
                }
            }

            // TODO: BLS FastAggregateVerify (see spec)

            // Verify aggregate signature
            IList <BlsPublicKey> publicKeys = attestingIndices.Select(x => state.Validators[(int)(ulong)x].PublicKey)
                                              .ToList();

            Root attestationDataRoot = _cryptographyService.HashTreeRoot(indexedAttestation.Data);
            Root signingRoot         = ComputeSigningRoot(attestationDataRoot, domain);

            BlsSignature signature = indexedAttestation.Signature;

            //BlsPublicKey aggregatePublicKey = _cryptographyService.BlsAggregatePublicKeys(publicKeys);
            //bool isValid = _cryptographyService.BlsVerify(aggregatePublicKey, signingRoot, signature);

            bool isValid = _cryptographyService.BlsFastAggregateVerify(publicKeys, signingRoot, signature);

            if (!isValid)
            {
                if (_logger.IsWarn())
                {
                    Log.InvalidIndexedAttestationSignature(_logger, indexedAttestation.Data.Index,
                                                           indexedAttestation.Data.Slot, null);
                }
                return(false);
            }

            return(true);
        }
Beispiel #28
0
 public static SszContainer ToSszContainer(this IndexedAttestation item, MiscellaneousParameters miscellaneousParameters)
 {
     return(new SszContainer(GetValues(item, miscellaneousParameters)));
 }