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); }
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()); }
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); }
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); }
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); }
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; } }
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); }
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); }
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)); }
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); }
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))); }
public static int PendingAttestationLength(PendingAttestation value) { return(Ssz.PendingAttestationDynamicOffset + (value.AggregationBits.Length + 8) / 8); }
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))); }