Example #1
0
        public void Pending_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);

            PendingAttestation container = new PendingAttestation();

            container.AggregationBits = new byte[3];
            container.Data            = data;
            container.InclusionDelay  = new Slot(7);
            container.ProposerIndex   = new ValidatorIndex(13);

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

            Ssz.Encode(encoded, container);
            PendingAttestation?decoded = Ssz.DecodePendingAttestation(encoded);

            Assert.AreEqual(container, decoded);

            Merkle.Ize(out UInt256 root, container);
        }
Example #2
0
        public static PendingAttestation[] DecodePendingAttestations(Span <byte> span)
        {
            if (span.Length == 0)
            {
                return(Array.Empty <PendingAttestation>());
            }

            int offset = 0;

            DecodeDynamicOffset(span, ref offset, out int dynamicOffset);

            int itemsCount = dynamicOffset / VarOffsetSize;

            PendingAttestation[] containers = new PendingAttestation[itemsCount];
            for (int i = 0; i < itemsCount; i++)
            {
                int nextDynamicOffset        = i == itemsCount - 1 ? span.Length : BinaryPrimitives.ReadInt32LittleEndian(span.Slice(offset, VarOffsetSize));
                int length                   = nextDynamicOffset - dynamicOffset;
                PendingAttestation container = DecodePendingAttestation(span.Slice(dynamicOffset, length));
                containers[i] = container;
                dynamicOffset = nextDynamicOffset;
                offset       += VarOffsetSize;
            }

            return(containers);
        }
        private static IEnumerable <SszElement> GetValues(PendingAttestation item, MiscellaneousParameters miscellaneousParameters)
        {
            yield return(item.AggregationBits.ToSszBitlist(miscellaneousParameters.MaximumValidatorsPerCommittee));

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

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

            yield return(item.ProposerIndex.ToSszBasicElement());
        }
Example #4
0
        private static void TestPendingAttestationSsz(byte[] serialized, UInt256 expectedMerkleRoot, string testCaseDir)
        {
            PendingAttestation container = Nethermind.Ssz.Ssz.DecodePendingAttestation(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);
        }
Example #5
0
        public static PendingAttestation DecodePendingAttestation(Span <byte> span)
        {
            int offset = 0;

            DecodeDynamicOffset(span, ref offset, out int dynamicOffset);
            BitArray           aggregationBits    = DecodeBitlist(span.Slice(dynamicOffset, span.Length - dynamicOffset));
            AttestationData    data               = DecodeAttestationData(span, ref offset);
            Slot               inclusionDelay     = DecodeSlot(span, ref offset);
            ValidatorIndex     proposerIndex      = DecodeValidatorIndex(span, ref offset);
            PendingAttestation pendingAttestation = new PendingAttestation(aggregationBits, data, inclusionDelay, proposerIndex);

            return(pendingAttestation);
        }
Example #6
0
        public static void Encode(Span <byte> span, PendingAttestation container)
        {
            if (span.Length != Ssz.PendingAttestationLength(container))
            {
                ThrowTargetLength <PendingAttestation>(span.Length, Ssz.PendingAttestationLength(container));
            }
            int offset        = 0;
            int dynamicOffset = Ssz.PendingAttestationDynamicOffset;

            Encode(span, container.AggregationBits, ref offset, ref dynamicOffset);
            Encode(span, container.Data, ref offset);
            Encode(span, container.InclusionDelay, ref offset);
            Encode(span, container.ProposerIndex, ref offset);
        }
Example #7
0
        public static void Encode(Span <byte> span, PendingAttestation[] containers)
        {
            int offset        = 0;
            int dynamicOffset = containers.Length * VarOffsetSize;

            for (int i = 0; i < containers.Length; i++)
            {
                int currentLength = PendingAttestation.SszLength(containers[i]);
                Encode(span.Slice(offset, VarOffsetSize), dynamicOffset);
                Encode(span.Slice(dynamicOffset, currentLength), containers[i]);
                offset        += VarOffsetSize;
                dynamicOffset += currentLength;
            }
        }
Example #8
0
        public static void Ize(out UInt256 root, PendingAttestation container)
        {
            if (container == null)
            {
                root = RootOfNull;
                return;
            }

            Merkleizer merkleizer = new Merkleizer(2);

            merkleizer.FeedBits(container.AggregationBits, (Attestation.MaxValidatorsPerCommittee + 255) / 256);
            merkleizer.Feed(container.Data);
            merkleizer.Feed(container.InclusionDelay);
            merkleizer.Feed(container.ProposerIndex);
            merkleizer.CalculateRoot(out root);
        }
Example #9
0
        public static PendingAttestation DecodePendingAttestation(Span <byte> span)
        {
            if (span.Length == 0)
            {
                return(null);
            }
            int offset = 0;

            DecodeDynamicOffset(span, ref offset, out int dynamicOffset);
            PendingAttestation pendingAttestation = new PendingAttestation();

            pendingAttestation.AggregationBits = DecodeBytes(span.Slice(dynamicOffset, span.Length - dynamicOffset)).ToArray();
            pendingAttestation.Data            = DecodeAttestationData(span, ref offset);
            pendingAttestation.InclusionDelay  = DecodeSlot(span, ref offset);
            pendingAttestation.ProposerIndex   = DecodeValidatorIndex(span, ref offset);
            return(pendingAttestation);
        }
Example #10
0
        public void SlotInterlockedOnlyAffectsOneValue()
        {
            // arrange
            Slot slot  = new Slot(10);
            Slot slot2 = slot;
            PendingAttestation slotContainer =
                new PendingAttestation(new BitArray(0), AttestationData.Zero, slot, ValidatorIndex.Zero);

            // act
            Slot comparand = new Slot(10);
            PendingAttestation containerToSourceUpdatedSlotFrom = new PendingAttestation(new BitArray(0),
                                                                                         AttestationData.Zero, new Slot(20), ValidatorIndex.Zero);
            Slot original = Slot.InterlockedCompareExchange(ref slot, containerToSourceUpdatedSlotFrom.InclusionDelay, comparand);

            // NOTE: Doesn't make properties mutable, as you need the field ref (not a property), e.g. the following doesn't compile:
            // Example: Slot.InterlockedCompareExchange(ref slotContainer.InclusionDelay, slot, containerToSourceUpdatedSlotFrom.InclusionDelay, comparand);

            // assert
            slot.ShouldBe(new Slot(20));

            slot2.ShouldBe(new Slot(10));
            slotContainer.InclusionDelay.ShouldBe(new Slot(10));
            original.ShouldBe(new Slot(10));
        }
Example #11
0
        public void Pending_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));

            PendingAttestation container = new PendingAttestation(
                new BitArray(new byte[3]),
                data,
                new Slot(7),
                new ValidatorIndex(13));

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

            Ssz.Encode(encoded, container);
            PendingAttestation?decoded = Ssz.DecodePendingAttestation(encoded);

            decoded.ShouldBe(container);

            Merkle.Ize(out UInt256 root, container);
        }
Example #12
0
        public void ProcessAttestation(BeaconState state, Attestation attestation)
        {
            _logger.LogInformation(Event.ProcessAttestation, "Process block operation attestation {Attestation} for state {BeaconState}.", attestation, state);

            var timeParameters = _timeParameterOptions.CurrentValue;
            var data           = attestation.Data;

            var committeeCount = _beaconStateAccessor.GetCommitteeCountAtSlot(state, data.Slot);

            if ((ulong)data.Index >= committeeCount)
            {
                throw new ArgumentOutOfRangeException("attestation.Data.Index", data.Index, $"Attestation data committee index must be less that the committee count {committeeCount}.");
            }
            var previousEpoch = _beaconStateAccessor.GetPreviousEpoch(state);
            var currentEpoch  = _beaconStateAccessor.GetCurrentEpoch(state);

            if (data.Target.Epoch != previousEpoch && data.Target.Epoch != currentEpoch)
            {
                throw new ArgumentOutOfRangeException("attestation.Data.Target.Epoch", data.Target.Epoch, $"Attestation data target epoch must be either the previous epoch {previousEpoch} or the current epoch {currentEpoch}.");
            }
            var minimumSlot = data.Slot + timeParameters.MinimumAttestationInclusionDelay;
            var maximumSlot = data.Slot + timeParameters.SlotsPerEpoch;

            if (state.Slot < minimumSlot)
            {
                throw new Exception($"Current state slot {state.Slot} must be equal or greater than the attestion slot {data.Slot} plus minimum delay {timeParameters.MinimumAttestationInclusionDelay}.");
            }
            if (state.Slot > maximumSlot)
            {
                throw new Exception($"Current state slot {state.Slot} must be equal or less than the attestation slot {data.Slot} plus slots per epoch {timeParameters.SlotsPerEpoch}.");
            }

            var committee = _beaconStateAccessor.GetBeaconCommittee(state, data.Slot, data.Index);

            if (attestation.AggregationBits.Count != attestation.CustodyBits.Count)
            {
                throw new Exception($"The attestation aggregation bit length {attestation.AggregationBits.Count} must be the same as the custody bit length {attestation.CustodyBits.Count}.");
            }
            if (attestation.AggregationBits.Count != committee.Count)
            {
                throw new Exception($"The attestation aggregation bit (and custody bit) length {attestation.AggregationBits.Count} must be the same as the committee length {committee.Count}.");
            }

            var inclusionDelay     = state.Slot - data.Slot;
            var proposerIndex      = _beaconStateAccessor.GetBeaconProposerIndex(state);
            var pendingAttestation = new PendingAttestation(attestation.AggregationBits, data, inclusionDelay, proposerIndex);

            if (data.Target.Epoch == currentEpoch)
            {
                if (!data.Source.Equals(state.CurrentJustifiedCheckpoint))
                {
                    throw new Exception($"For a current epoch target attestation the data source checkpoint {data.Source} must be the same as the current justified checkpoint {state.CurrentJustifiedCheckpoint}.");
                }
                state.AddCurrentAttestation(pendingAttestation);
            }
            else
            {
                if (!data.Source.Equals(state.PreviousJustifiedCheckpoint))
                {
                    throw new Exception($"For a previous epoch target attestation the data source checkpoint {data.Source} must be the same as the previous justified checkpoint {state.PreviousJustifiedCheckpoint}.");
                }
                state.AddPreviousAttestation(pendingAttestation);
            }

            // Check signature
            var indexedAttestation = _beaconStateAccessor.GetIndexedAttestation(state, attestation);
            var domain             = _beaconStateAccessor.GetDomain(state, _signatureDomainOptions.CurrentValue.BeaconAttester, data.Target.Epoch);
            var isValid            = _beaconChainUtility.IsValidIndexedAttestation(state, indexedAttestation, domain);

            if (!isValid)
            {
                throw new Exception($"Indexed attestation {indexedAttestation} is not valid.");
            }
        }
 public static SszContainer ToSszContainer(this PendingAttestation item, MiscellaneousParameters miscellaneousParameters)
 {
     return(new SszContainer(GetValues(item, miscellaneousParameters)));
 }
Example #14
0
 public static int PendingAttestationLength(PendingAttestation value)
 {
     return(Ssz.PendingAttestationDynamicOffset + (value.AggregationBits.Length + 8) / 8);
 }
Example #15
0
        public static void Encode(Span <byte> span, BeaconState container)
        {
            if (span.Length != BeaconState.SszLength(container))
            {
                ThrowTargetLength <BeaconState>(span.Length, BeaconState.SszLength(container));
            }

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

            Encode(span.Slice(offset, sizeof(ulong)), container.GenesisTime);
            offset += sizeof(ulong);
            Encode(span, container.Slot, ref offset);
            Encode(span, container.Fork, ref offset);
            Encode(span.Slice(offset, BeaconBlockHeader.SszLength), container.LatestBlockHeader);
            offset += BeaconBlockHeader.SszLength;
            Encode(span.Slice(offset, Time.SlotsPerHistoricalRoot * Sha256.SszLength), container.BlockRoots);
            offset += Time.SlotsPerHistoricalRoot * Sha256.SszLength;
            Encode(span.Slice(offset, Time.SlotsPerHistoricalRoot * Sha256.SszLength), container.StateRoots);
            offset += Time.SlotsPerHistoricalRoot * Sha256.SszLength;
            int length1 = container.HistoricalRoots.Length * Sha256.SszLength;

            Encode(span.Slice(offset, VarOffsetSize), dynamicOffset);
            Encode(span.Slice(dynamicOffset, length1), container.HistoricalRoots);
            dynamicOffset += length1;
            offset        += VarOffsetSize;
            Encode(span, container.Eth1Data, ref offset);
            int length2 = container.Eth1DataVotes.Length * Eth1Data.SszLength;

            Encode(span.Slice(offset, VarOffsetSize), dynamicOffset);
            Encode(span.Slice(dynamicOffset, length2), container.Eth1DataVotes);
            dynamicOffset += length2;
            offset        += VarOffsetSize;
            Encode(span.Slice(offset, sizeof(ulong)), container.Eth1DepositIndex);
            offset += sizeof(ulong);
            int length3 = container.Validators.Length * Validator.SszLength;

            Encode(span.Slice(offset, VarOffsetSize), dynamicOffset);
            Encode(span.Slice(dynamicOffset, length3), container.Validators);
            dynamicOffset += length3;
            offset        += VarOffsetSize;
            int length4 = container.Balances.Length * Gwei.SszLength;

            Encode(span.Slice(offset, VarOffsetSize), dynamicOffset);
            Encode(span.Slice(dynamicOffset, length4), container.Balances);
            dynamicOffset += length4;
            offset        += VarOffsetSize;
            Encode(span.Slice(offset, Time.EpochsPerHistoricalVector * Sha256.SszLength), container.RandaoMixes);
            offset += Time.EpochsPerHistoricalVector * Sha256.SszLength;
            Encode(span.Slice(offset, Time.EpochsPerSlashingsVector * Gwei.SszLength), container.Slashings);
            offset += Time.EpochsPerSlashingsVector * Gwei.SszLength;

            int length5 = container.PreviousEpochAttestations.Length * VarOffsetSize;

            for (int i = 0; i < container.PreviousEpochAttestations.Length; i++)
            {
                length5 += PendingAttestation.SszLength(container.PreviousEpochAttestations[i]);
            }

            Encode(span.Slice(offset, VarOffsetSize), dynamicOffset);
            Encode(span.Slice(dynamicOffset, length5), container.PreviousEpochAttestations);
            dynamicOffset += length5;
            offset        += VarOffsetSize;

            int length6 = container.CurrentEpochAttestations.Length * VarOffsetSize;

            for (int i = 0; i < container.CurrentEpochAttestations.Length; i++)
            {
                length6 += PendingAttestation.SszLength(container.CurrentEpochAttestations[i]);
            }

            Encode(span.Slice(offset, VarOffsetSize), dynamicOffset);
            Encode(span.Slice(dynamicOffset, length6), container.CurrentEpochAttestations);
            dynamicOffset += length6;
            offset        += VarOffsetSize;

            Encode(span.Slice(offset, 1), container.JustificationBits);
            offset += 1;
            Encode(span, container.PreviousJustifiedCheckpoint, ref offset);
            Encode(span, container.CurrentJustifiedCheckpoint, ref offset);
            Encode(span, container.FinalizedCheckpoint, ref offset);
        }
 public static SszContainer ToSszContainer(this PendingAttestation item, ulong maximumValidatorsPerCommittee)
 {
     return(new SszContainer(GetValues(item, maximumValidatorsPerCommittee)));
 }