예제 #1
0
        // ReSharper disable once InconsistentNaming
        // ReSharper disable once IdentifierTypo
        public async Task <IActionResult> GetAsync([FromQuery] byte[] validator_pubkey, [FromQuery] uint poc_bit,
                                                   [FromQuery] ulong slot, [FromQuery] ulong index,
                                                   CancellationToken cancellationToken)
        {
            if (_logger.IsDebug())
            {
                LogDebug.NewAttestationRequested(_logger, slot, index, Bytes.ToHexString(validator_pubkey), null);
            }

            BlsPublicKey validatorPublicKey = new BlsPublicKey(validator_pubkey);
            bool         proofOfCustodyBit  = poc_bit > 0;
            Slot         targetSlot         = new Slot(slot);

            // NOTE: Spec 0.10.1 still has old Shard references in OAPI, although the spec has changed to Index;
            // use Index as it is easier to understand (i.e. the spec OAPI in 0.10.1 is wrong)
            CommitteeIndex targetIndex = new CommitteeIndex(index);

            ApiResponse <Attestation> apiResponse =
                await _beaconNode
                .NewAttestationAsync(validatorPublicKey, proofOfCustodyBit, targetSlot, targetIndex,
                                     cancellationToken).ConfigureAwait(false);

            return(apiResponse.StatusCode switch
            {
                Core2.Api.StatusCode.Success => Ok(apiResponse.Content),
                Core2.Api.StatusCode.InvalidRequest => Problem("Invalid request syntax.",
                                                               statusCode: (int)apiResponse.StatusCode),
                Core2.Api.StatusCode.CurrentlySyncing => Problem("Beacon node is currently syncing, try again later.",
                                                                 statusCode: (int)apiResponse.StatusCode),
                _ => Problem("Beacon node internal error.", statusCode: (int)apiResponse.StatusCode)
            });
예제 #2
0
        private static CommitteeIndex DecodeCommitteeIndex(ReadOnlySpan <byte> span, ref int offset)
        {
            CommitteeIndex committeeIndex = new CommitteeIndex(BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(offset, Ssz.CommitteeIndexLength))); BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(offset, Ssz.CommitteeIndexLength));

            offset += Ssz.CommitteeIndexLength;
            return(committeeIndex);
        }
예제 #3
0
        private void CheckHistoricalSlots(IStore store, IReadOnlyList <Hash32> historicalBlockRoots, Slot fromSlot, Slot startSlot, ValidatorIndex validatorIndex,
                                          ref Slot attestationSlot, ref CommitteeIndex attestationCommitteeIndex, ref Slot blockProposalSlot)
        {
            TimeParameters timeParameters = _timeParameterOptions.CurrentValue;
            Slot           previousSlot   = fromSlot;

            while (true)
            {
                previousSlot -= Slot.One;
                int    index        = (int)(previousSlot % timeParameters.SlotsPerHistoricalRoot);
                Hash32 previousRoot = historicalBlockRoots[index];
                if (!store.TryGetBlockState(previousRoot, out BeaconState? previousState))
                {
                    throw new Exception($"Historical state {previousRoot} for slot {previousSlot} not found.");
                }

                CheckStateDuty(previousState !, validatorIndex, ref attestationSlot, ref attestationCommitteeIndex,
                               ref blockProposalSlot);

                if (previousSlot <= startSlot || (attestationSlot != Slot.None && blockProposalSlot != Slot.None))
                {
                    break;
                }
            }
        }
예제 #4
0
        // def get_valid_attestation(spec, state, slot=None, index=None, signed=False):
        public static Attestation GetValidAttestation(IServiceProvider testServiceProvider, BeaconState state, Slot slot, CommitteeIndex index, bool signed)
        {
            var beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>();

            if (slot == Slot.None)
            {
                slot = state.Slot;
            }
            if (index == CommitteeIndex.None)
            {
                index = new CommitteeIndex(0);
            }

            var attestationData = BuildAttestationData(testServiceProvider, state, slot, index);

            var beaconCommittee = beaconStateAccessor.GetBeaconCommittee(state, attestationData.Slot, attestationData.Index);

            var committeeSize   = beaconCommittee.Count;
            var aggregationBits = new BitArray(committeeSize);
            var custodyBits     = new BitArray(committeeSize);
            var attestation     = new Attestation(aggregationBits, attestationData, custodyBits, BlsSignature.Empty);

            FillAggregateAttestation(state, attestation, beaconStateAccessor);

            if (signed)
            {
                SignAttestation(testServiceProvider, state, attestation);
            }

            return(attestation);
        }
예제 #5
0
        public void BasicGetCommitteeAssignment(ulong index, ulong slot, ulong committeeIndex)
        {
            // Arrange
            IServiceCollection testServiceCollection = TestSystem.BuildTestServiceCollection(useStore: true);

            testServiceCollection.AddSingleton <IHostEnvironment>(Substitute.For <IHostEnvironment>());
            ServiceProvider testServiceProvider = testServiceCollection.BuildServiceProvider();
            BeaconState     state = TestState.PrepareTestState(testServiceProvider);

            // Act
            ValidatorAssignments validatorAssignments = testServiceProvider.GetService <ValidatorAssignments>();
            ValidatorIndex       validatorIndex       = new ValidatorIndex(index);
            CommitteeAssignment  committeeAssignment  =
                validatorAssignments.GetCommitteeAssignment(state, Epoch.Zero, validatorIndex);

            // Assert
            Console.WriteLine("Validator [{0}] {1} in slot {2} committee {3}",
                              validatorIndex, state.Validators[(int)validatorIndex].PublicKey, committeeAssignment.Slot,
                              committeeAssignment.CommitteeIndex);

            committeeAssignment.ShouldNotBe(CommitteeAssignment.None);
            committeeAssignment.Committee.Count.ShouldBeGreaterThan(0);

            Slot           expectedSlot           = new Slot(slot);
            CommitteeIndex expectedCommitteeIndex = new CommitteeIndex(committeeIndex);

            committeeAssignment.Slot.ShouldBe(expectedSlot);
            committeeAssignment.CommitteeIndex.ShouldBe(expectedCommitteeIndex);
        }
        // def get_valid_attestation(spec, state, slot=None, index=None, signed=False):
        public static Attestation GetValidAttestation(IServiceProvider testServiceProvider, BeaconState state, Slot slot, CommitteeIndex index, bool signed)
        {
            BeaconStateAccessor beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>();

            if (slot == Slot.None)
            {
                slot = state.Slot;
            }
            if (index == CommitteeIndex.None)
            {
                index = new CommitteeIndex(0);
            }

            AttestationData attestationData = BuildAttestationData(testServiceProvider, state, slot, index);

            IReadOnlyList <ValidatorIndex> beaconCommittee = beaconStateAccessor.GetBeaconCommittee(state, attestationData.Slot, attestationData.Index);

            int         committeeSize   = beaconCommittee.Count;
            BitArray    aggregationBits = new BitArray(committeeSize);
            Attestation attestation     = new Attestation(aggregationBits, attestationData, BlsSignature.Zero);

            FillAggregateAttestation(state, attestation, beaconStateAccessor);

            if (signed)
            {
                SignAttestation(testServiceProvider, state, attestation);
            }

            return(attestation);
        }
예제 #7
0
        private void UpdateDutyDetailsForState(IList <DutyDetails> dutyDetailsList, BeaconState state)
        {
            // check attestation
            ulong committeeCount = _beaconStateAccessor.GetCommitteeCountAtSlot(state, state.Slot);

            for (CommitteeIndex index = CommitteeIndex.Zero;
                 index < new CommitteeIndex(committeeCount);
                 index += CommitteeIndex.One)
            {
                IReadOnlyList <ValidatorIndex> committee =
                    _beaconStateAccessor.GetBeaconCommittee(state, state.Slot, index);
                foreach (DutyDetails dutyDetails in dutyDetailsList)
                {
                    if (!dutyDetails.AttestationSlot.HasValue && committee.Contains(dutyDetails.ValidatorIndex))
                    {
                        dutyDetails.AttestationSlot           = state.Slot;
                        dutyDetails.AttestationCommitteeIndex = index;
                    }
                }
            }

            // check proposer
            foreach (DutyDetails dutyDetails in dutyDetailsList)
            {
                if (!dutyDetails.BlockProposalSlot.HasValue)
                {
                    bool isProposer = IsProposer(state, dutyDetails.ValidatorIndex);
                    if (isProposer)
                    {
                        dutyDetails.BlockProposalSlot = state.Slot;
                    }
                }
            }
        }
예제 #8
0
        private Duty CheckStateDuty(BeaconState state, ValidatorIndex validatorIndex, Duty duty)
        {
            // check attestation
            if (duty.AttestationSlot == Slot.None)
            {
                ulong committeeCount = _beaconStateAccessor.GetCommitteeCountAtSlot(state, state.Slot);
                for (CommitteeIndex index = CommitteeIndex.Zero;
                     index < new CommitteeIndex(committeeCount);
                     index += CommitteeIndex.One)
                {
                    IReadOnlyList <ValidatorIndex> committee =
                        _beaconStateAccessor.GetBeaconCommittee(state, state.Slot, index);
                    if (committee.Contains(validatorIndex))
                    {
                        duty.AttestationSlot           = state.Slot;
                        duty.AttestationCommitteeIndex = index;
                    }
                }
            }

            // check proposer
            if (duty.BlockProposalSlot == Slot.None)
            {
                bool isProposer = IsProposer(state, validatorIndex);
                if (isProposer)
                {
                    duty.BlockProposalSlot = state.Slot;
                }
            }

            return(duty);
        }
예제 #9
0
        /// <summary>
        ///     Return the committee assignment in the ``epoch`` for ``validator_index``.
        ///     ``assignment`` returned is a tuple of the following form:
        ///     * ``assignment[0]`` is the list of validators in the committee
        ///     * ``assignment[1]`` is the index to which the committee is assigned
        ///     * ``assignment[2]`` is the slot at which the committee is assigned
        ///     Return None if no assignment.
        /// </summary>
        public CommitteeAssignment GetCommitteeAssignment(BeaconState state, Epoch epoch, ValidatorIndex validatorIndex)
        {
            Epoch nextEpoch = _beaconStateAccessor.GetCurrentEpoch(state) + Epoch.One;

            if (epoch > nextEpoch)
            {
                throw new ArgumentOutOfRangeException(nameof(epoch), epoch,
                                                      $"Committee epoch cannot be greater than next epoch {nextEpoch}.");
            }

            TimeParameters timeParameters = _timeParameterOptions.CurrentValue;
            Slot           startSlot      = _beaconChainUtility.ComputeStartSlotOfEpoch(epoch);
            ulong          endSlot        = startSlot + timeParameters.SlotsPerEpoch;

            for (Slot slot = startSlot; slot < endSlot; slot += Slot.One)
            {
                ulong committeeCount = _beaconStateAccessor.GetCommitteeCountAtSlot(state, slot);
                for (CommitteeIndex index = CommitteeIndex.Zero;
                     index < new CommitteeIndex(committeeCount);
                     index += CommitteeIndex.One)
                {
                    IReadOnlyList <ValidatorIndex> committee =
                        _beaconStateAccessor.GetBeaconCommittee(state, slot, index);
                    if (committee.Contains(validatorIndex))
                    {
                        CommitteeAssignment committeeAssignment = new CommitteeAssignment(committee, index, slot);
                        return(committeeAssignment);
                    }
                }
            }

            return(CommitteeAssignment.None);
        }
예제 #10
0
        private static AttestationData DecodeAttestationData(ReadOnlySpan <byte> span, ref int offset)
        {
            Slot            slot            = DecodeSlot(span, ref offset);
            CommitteeIndex  index           = DecodeCommitteeIndex(span, ref offset);
            Root            beaconBlockRoot = DecodeRoot(span, ref offset);
            Checkpoint      source          = DecodeCheckpoint(span, ref offset);
            Checkpoint      target          = DecodeCheckpoint(span, ref offset);
            AttestationData container       = new AttestationData(slot, index, beaconBlockRoot, source, target);

            return(container);
        }
예제 #11
0
        private void CheckFutureSlots(BeaconState state, Slot endSlot, ValidatorIndex validatorIndex,
                                      ref Slot attestationSlot, ref CommitteeIndex attestationCommitteeIndex, ref Slot blockProposalSlot)
        {
            Slot nextSlot = state.Slot + Slot.One;

            while (nextSlot < endSlot && (attestationSlot == Slot.None || blockProposalSlot == Slot.None))
            {
                _beaconStateTransition.ProcessSlots(state, nextSlot);
                CheckStateDuty(state, validatorIndex, ref attestationSlot, ref attestationCommitteeIndex, ref blockProposalSlot);
                nextSlot += Slot.One;
            }
        }
예제 #12
0
 public AttestationData(
     Slot slot,
     CommitteeIndex index,
     Hash32 beaconBlockRoot,
     Checkpoint source,
     Checkpoint target)
 {
     BeaconBlockRoot = beaconBlockRoot;
     Source          = source;
     Target          = target;
     Slot            = slot;
     Index           = index;
 }
        public async Task <Attestation> NewAttestationAsync(BlsPublicKey validatorPublicKey,
                                                            bool proofOfCustodyBit, Slot slot, CommitteeIndex index,
                                                            CancellationToken cancellationToken)
        {
            Root head = await _store.GetHeadAsync().ConfigureAwait(false);

            BeaconBlock headBlock   = (await _store.GetSignedBlockAsync(head).ConfigureAwait(false)).Message;
            BeaconState parentState = await _store.GetBlockStateAsync(head).ConfigureAwait(false);

            // Clone state (will mutate) and process outstanding slots
            BeaconState headState = BeaconState.Clone(parentState);

            _beaconStateTransition.ProcessSlots(headState, slot);

            // Set attestation_data.index = index where index is the index associated with the validator's committee.
            ValidatorIndex?validatorIndex = FindValidatorIndexByPublicKey(headState, validatorPublicKey);

            if (validatorIndex == null)
            {
                throw new Exception($"Can not find validator index for public key {validatorPublicKey}");
            }

            // TODO: May need a more efficient way to try and find the committee and position within the committee.
            // Some of this may already be cached in Validator Assignments (generally stable for an epoch),
            // but not with the index within the committee. Easy enough to extend and use the same cache.

            IReadOnlyList <ValidatorIndex> committee =
                _beaconStateAccessor.GetBeaconCommittee(headState, headState.Slot, index);
            int committeeSize = committee.Count;

            int?committeeMemberIndexOfValidator = null;

            for (int committeeMemberIndex = 0; committeeMemberIndex < committee.Count; committeeMemberIndex++)
            {
                if (committee[committeeMemberIndex] == validatorIndex)
                {
                    committeeMemberIndexOfValidator = committeeMemberIndex;
                    break;
                }
            }

            if (committeeMemberIndexOfValidator == null)
            {
                throw new Exception($"Validator index {validatorIndex} is not a member of committee {index}");
            }

            Root beaconBlockRoot = _cryptographyService.HashTreeRoot(headBlock);

            Checkpoint source = headState.CurrentJustifiedCheckpoint;

            Epoch currentEpoch = _beaconStateAccessor.GetCurrentEpoch(headState);
            Slot  startSlot    = _beaconChainUtility.ComputeStartSlotOfEpoch(currentEpoch);
            Root  epochBoundaryBlockRoot;

            if (startSlot == headState.Slot)
            {
                epochBoundaryBlockRoot = beaconBlockRoot;
            }
            else
            {
                epochBoundaryBlockRoot = _beaconStateAccessor.GetBlockRootAtSlot(headState, startSlot);
            }

            Checkpoint target = new Checkpoint(currentEpoch, epochBoundaryBlockRoot);

            AttestationData attestationData = new AttestationData(slot, index, beaconBlockRoot, source, target);

            var aggregationBits = new BitArray(committeeSize);

            aggregationBits.Set(committeeMemberIndexOfValidator.Value, true);

            var attestation = new Attestation(aggregationBits, attestationData, BlsSignature.Zero);

            return(attestation);
        }
예제 #14
0
        /// <summary>
        /// Return the beacon committee at ``slot`` for ``index``.
        /// </summary>
        public IReadOnlyList <ValidatorIndex> GetBeaconCommittee(BeaconState state, Slot slot, CommitteeIndex index)
        {
            Epoch epoch             = _beaconChainUtility.ComputeEpochAtSlot(slot);
            ulong committeesPerSlot = GetCommitteeCountAtSlot(state, slot);

            IList <ValidatorIndex> indices = GetActiveValidatorIndices(state, epoch);
            Bytes32 seed           = GetSeed(state, epoch, _signatureDomainOptions.CurrentValue.BeaconAttester);
            ulong   committeeIndex = (slot % _timeParameterOptions.CurrentValue.SlotsPerEpoch) * committeesPerSlot + (ulong)index;
            ulong   committeeCount = committeesPerSlot * _timeParameterOptions.CurrentValue.SlotsPerEpoch;

            IReadOnlyList <ValidatorIndex> committee = _beaconChainUtility.ComputeCommittee(indices, seed, committeeIndex, committeeCount);

            return(committee);
        }
예제 #15
0
        public async Task <ApiResponse <Attestation> > NewAttestationAsync(BlsPublicKey validatorPublicKey,
                                                                           bool proofOfCustodyBit, Slot slot, CommitteeIndex index,
                                                                           CancellationToken cancellationToken)
        {
            try
            {
                Attestation unsignedAttestation = await _attestationProducer
                                                  .NewAttestationAsync(validatorPublicKey, proofOfCustodyBit, slot, index, cancellationToken)
                                                  .ConfigureAwait(false);

                return(ApiResponse.Create(StatusCode.Success, unsignedAttestation));
            }
            catch (Exception ex)
            {
                if (_logger.IsWarn())
                {
                    Log.ApiErrorNewAttestation(_logger, ex);
                }
                throw;
            }
        }
예제 #16
0
 public CommitteeAssignment(IEnumerable <ValidatorIndex> committee, CommitteeIndex committeeIndex, Slot slot)
 {
     _committee     = new List <ValidatorIndex>(committee);
     CommitteeIndex = committeeIndex;
     Slot           = slot;
 }
예제 #17
0
 public static SszElement ToSszBasicElement(this CommitteeIndex item)
 {
     return(new SszBasicElement((ulong)item));
 }
예제 #18
0
 public static void Ize(out UInt256 root, CommitteeIndex container)
 {
     Ize(out root, container.Number);
 }
예제 #19
0
        /// <summary>
        /// Return the beacon committee at ``slot`` for ``index``.
        /// </summary>
        public IReadOnlyList <ValidatorIndex> GetBeaconCommittee(BeaconState state, Slot slot, CommitteeIndex index)
        {
            var epoch             = _beaconChainUtility.ComputeEpochAtSlot(slot);
            var committeesPerSlot = GetCommitteeCountAtSlot(state, slot);
            //var committeeCount = GetCommitteeCount(state, epoch);

            var indices = GetActiveValidatorIndices(state, epoch);
            var seed    = GetSeed(state, epoch, _signatureDomainOptions.CurrentValue.BeaconAttester);
            //var index = (shard + miscellaneousParameters.ShardCount - GetStartShard(state, epoch)) % miscellaneousParameters.ShardCount;
            var committeeIndex = (ulong)(slot % _timeParameterOptions.CurrentValue.SlotsPerEpoch) * committeesPerSlot + (ulong)index;
            var committeeCount = committeesPerSlot * (ulong)_timeParameterOptions.CurrentValue.SlotsPerEpoch;

            var committee = _beaconChainUtility.ComputeCommittee(indices, seed, committeeIndex, committeeCount);

            return(committee);
        }
예제 #20
0
        public async Task <ValidatorDuty> GetValidatorDutyAsync(BlsPublicKey validatorPublicKey, Epoch epoch)
        {
            if (!_storeProvider.TryGetStore(out IStore? retrievedStore))
            {
                throw new Exception("Beacon chain is currently syncing or waiting for genesis.");
            }

            IStore store = retrievedStore !;
            Hash32 head  = await _forkChoice.GetHeadAsync(store);

            if (!store.TryGetBlockState(head, out BeaconState? headState))
            {
                throw new Exception($"Head state {head} not found.");
            }

            Epoch currentEpoch = _beaconStateAccessor.GetCurrentEpoch(headState !);
            Epoch nextEpoch    = currentEpoch + Epoch.One;

            if (epoch == Epoch.None)
            {
                epoch = currentEpoch;
            }
            else if (epoch > nextEpoch)
            {
                throw new ArgumentOutOfRangeException(nameof(epoch), epoch,
                                                      $"Duties cannot look ahead more than the next epoch {nextEpoch}.");
            }

            TimeParameters timeParameters = _timeParameterOptions.CurrentValue;

            Slot startSlot = _beaconChainUtility.ComputeStartSlotOfEpoch(epoch);
            Slot endSlot   = startSlot + new Slot(timeParameters.SlotsPerEpoch);

            Slot           attestationSlot           = Slot.None;
            CommitteeIndex attestationCommitteeIndex = CommitteeIndex.None;
            Slot           blockProposalSlot         = Slot.None;

            if (epoch == nextEpoch)
            {
                // Clone for next or current, so that it can be safely mutated (transitioned forward)
                BeaconState state = BeaconState.Clone(headState !);
                _beaconStateTransition.ProcessSlots(state, startSlot);

                // Check base state
                ValidatorIndex validatorIndex = CheckValidatorIndex(state, validatorPublicKey);
                CheckStateDuty(state, validatorIndex, ref attestationSlot, ref attestationCommitteeIndex, ref blockProposalSlot);

                // Check future states
                CheckFutureSlots(state, endSlot, validatorIndex, ref attestationSlot, ref attestationCommitteeIndex, ref blockProposalSlot);
            }
            else if (epoch == currentEpoch)
            {
                // Take block slot and roots before cloning (for historical checks)
                IReadOnlyList <Hash32> historicalBlockRoots = headState !.BlockRoots;
                Slot        fromSlot = headState !.Slot;
                BeaconState state    = BeaconState.Clone(headState !);

                // Check base state
                ValidatorIndex validatorIndex = CheckValidatorIndex(state, validatorPublicKey);
                CheckStateDuty(state, validatorIndex, ref attestationSlot, ref attestationCommitteeIndex, ref blockProposalSlot);

                // Check future states
                CheckFutureSlots(state, endSlot, validatorIndex, ref attestationSlot, ref attestationCommitteeIndex,
                                 ref blockProposalSlot);

                // Check historical states
                if (startSlot < fromSlot && (attestationSlot == Slot.None || blockProposalSlot == Slot.None))
                {
                    CheckHistoricalSlots(store, historicalBlockRoots, fromSlot, startSlot, validatorIndex,
                                         ref attestationSlot, ref attestationCommitteeIndex, ref blockProposalSlot);
                }
            }
            else
            {
                Hash32 endRoot = _forkChoice.GetAncestor(store, head, endSlot - Slot.One);
                if (!store.TryGetBlockState(endRoot, out BeaconState? endState))
                {
                    throw new Exception($"State {endRoot} for slot {endSlot} not found.");
                }
                BeaconState state = endState !;

                // Check base state
                ValidatorIndex validatorIndex = CheckValidatorIndex(state, validatorPublicKey);
                CheckStateDuty(state, validatorIndex, ref attestationSlot, ref attestationCommitteeIndex, ref blockProposalSlot);

                // Check historical states
                IReadOnlyList <Hash32> historicalBlockRoots = state.BlockRoots;
                Slot fromSlot = state.Slot;
                if (attestationSlot == Slot.None || blockProposalSlot == Slot.None)
                {
                    CheckHistoricalSlots(store, historicalBlockRoots, fromSlot, startSlot, validatorIndex,
                                         ref attestationSlot, ref attestationCommitteeIndex, ref blockProposalSlot);
                }
            }

            // HACK: Shards were removed from Phase 0, but analogy is committee index, so use for initial testing.
            Shard         attestationShard = new Shard((ulong)attestationCommitteeIndex);
            ValidatorDuty validatorDuty    =
                new ValidatorDuty(validatorPublicKey, attestationSlot, attestationShard, blockProposalSlot);

            return(validatorDuty);
        }
예제 #21
0
        private static AttestationData BuildAttestationData(IServiceProvider testServiceProvider, BeaconState state, Slot slot, CommitteeIndex index)
        {
            var beaconChainUtility  = testServiceProvider.GetService <BeaconChainUtility>();
            var beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>();

            if (state.Slot > slot)
            {
                throw new ArgumentOutOfRangeException(nameof(slot), slot, $"Slot cannot be greater than state slot {state.Slot}.");
            }

            Hash32 blockRoot;

            if (slot == state.Slot)
            {
                var nextBlock = TestBlock.BuildEmptyBlockForNextSlot(testServiceProvider, state, false);
                blockRoot = nextBlock.ParentRoot;
            }
            else
            {
                blockRoot = beaconStateAccessor.GetBlockRootAtSlot(state, slot);
            }

            Hash32 epochBoundaryRoot;
            var    currentEpoch          = beaconStateAccessor.GetCurrentEpoch(state);
            var    currentEpochStartSlot = beaconChainUtility.ComputeStartSlotOfEpoch(currentEpoch);

            if (slot < currentEpochStartSlot)
            {
                var previousEpoch = beaconStateAccessor.GetPreviousEpoch(state);
                epochBoundaryRoot = beaconStateAccessor.GetBlockRoot(state, previousEpoch);
            }
            else if (slot == currentEpochStartSlot)
            {
                epochBoundaryRoot = blockRoot;
            }
            else
            {
                epochBoundaryRoot = beaconStateAccessor.GetBlockRoot(state, currentEpoch);
            }

            Epoch  sourceEpoch;
            Hash32 sourceRoot;

            if (slot < currentEpochStartSlot)
            {
                sourceEpoch = state.PreviousJustifiedCheckpoint.Epoch;
                sourceRoot  = state.PreviousJustifiedCheckpoint.Root;
            }
            else
            {
                sourceEpoch = state.CurrentJustifiedCheckpoint.Epoch;
                sourceRoot  = state.CurrentJustifiedCheckpoint.Root;
            }

            //Crosslink parentCrosslink;
            //if (epochOfSlot == currentEpoch)
            //{
            //    parentCrosslink = state.CurrentCrosslinks[(int)(ulong)shard];
            //}
            //else
            //{
            //    throw new NotImplementedException();
            //}

            var slotEpoch       = beaconChainUtility.ComputeEpochAtSlot(slot);
            var attestationData = new AttestationData(
                slot,
                index,
                blockRoot,
                new Checkpoint(sourceEpoch, sourceRoot),
                new Checkpoint(slotEpoch, epochBoundaryRoot));

            return(attestationData);
        }
예제 #22
0
 public static void Encode(Span <byte> span, CommitteeIndex value)
 {
     Encode(span, value.Number);
 }
예제 #23
0
 private static void Encode(Span <byte> span, CommitteeIndex value, ref int offset)
 {
     BinaryPrimitives.WriteUInt64LittleEndian(span.Slice(offset), value.Number);
     offset += Ssz.CommitteeIndexLength;
 }
예제 #24
0
        public async Task <ApiResponse <Attestation> > NewAttestationAsync(BlsPublicKey validatorPublicKey,
                                                                           bool proofOfCustodyBit, Slot slot, CommitteeIndex index,
                                                                           CancellationToken cancellationToken)
        {
            string baseUri = "validator/attestation";

            // NOTE: Spec 0.10.1 still has old Shard references in OAPI, although the spec has changed to Index;
            // use Index as it is easier to understand (i.e. the spec OAPI in 0.10.1 is wrong)

            Dictionary <string, string> queryParameters = new Dictionary <string, string>
            {
                ["validator_pubkey"] = validatorPublicKey.ToString(),
                ["poc_bit"]          = proofOfCustodyBit ? "1" : "0",
                ["slot"]             = slot.ToString(),
                ["index"]            = index.ToString()
            };

            string uri = QueryHelpers.AddQueryString(baseUri, queryParameters);

            using HttpResponseMessage httpResponse =
                      await _httpClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, cancellationToken);

            int statusCode = (int)httpResponse.StatusCode;

            if (statusCode == (int)StatusCode.InvalidRequest ||
                statusCode == (int)StatusCode.CurrentlySyncing)
            {
                return(ApiResponse.Create <Attestation>((StatusCode)statusCode));
            }

            httpResponse.EnsureSuccessStatusCode(); // throws if not 200-299
            await using Stream contentStream = await httpResponse.Content.ReadAsStreamAsync();

            Attestation content =
                await JsonSerializer.DeserializeAsync <Attestation>(contentStream, _jsonSerializerOptions,
                                                                    cancellationToken);

            return(ApiResponse.Create((StatusCode)statusCode, content));
        }