コード例 #1
0
        public async Task <ApiResponse <Syncing> > GetSyncingAsync(CancellationToken cancellationToken)
        {
            try
            {
                Slot currentSlot = Slot.Zero;
                if (_store.IsInitialized)
                {
                    Root head = await _forkChoice.GetHeadAsync(_store).ConfigureAwait(false);

                    BeaconBlock block = (await _store.GetSignedBlockAsync(head).ConfigureAwait(false)).Message;
                    currentSlot = block.Slot;
                }

                Slot highestSlot = Slot.Max(currentSlot, _networkPeering.HighestPeerSlot);

                Slot startingSlot = _networkPeering.SyncStartingSlot;

                bool isSyncing = highestSlot > currentSlot;

                Syncing syncing = new Syncing(isSyncing, new SyncingStatus(startingSlot, currentSlot, highestSlot));

                return(ApiResponse.Create(StatusCode.Success, syncing));
            }
            catch (Exception ex)
            {
                if (_logger.IsWarn())
                {
                    Log.ApiErrorGetSyncing(_logger, ex);
                }
                throw;
            }
        }
コード例 #2
0
        public async Task OnPeerDialOutConnected(string peerId)
        {
            Root headRoot = await _forkChoice.GetHeadAsync(_store).ConfigureAwait(false);

            BeaconState beaconState = await _store.GetBlockStateAsync(headRoot).ConfigureAwait(false);

            // Send request
            var status = BuildStatusFromHead(headRoot, beaconState);

            if (_logger.IsDebug())
            {
                LogDebug.SendingStatusToPeer(_logger, RpcDirection.Request, status, peerId, null);
            }
            await _networkPeering.SendStatusAsync(peerId, RpcDirection.Request, status).ConfigureAwait(false);
        }
コード例 #3
0
        public async Task ChainNoAttestations()
        {
            // Arrange
            IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider(useStore: true);
            BeaconState      state = TestState.PrepareTestState(testServiceProvider);

            // Initialization
            ICryptographyService cryptographyService = testServiceProvider.GetService <ICryptographyService>();
            IForkChoice          forkChoice          = testServiceProvider.GetService <IForkChoice>();
            IStore store = testServiceProvider.GetService <IStore>();
            await forkChoice.InitializeForkChoiceStoreAsync(store, state);

            // On receiving a block of `GENESIS_SLOT + 1` slot
            BeaconBlock       block1       = TestBlock.BuildEmptyBlockForNextSlot(testServiceProvider, state, BlsSignature.Zero);
            SignedBeaconBlock signedBlock1 = TestState.StateTransitionAndSignBlock(testServiceProvider, state, block1);

            await AddBlockToStore(testServiceProvider, store, signedBlock1);

            // On receiving a block of next epoch
            BeaconBlock       block2       = TestBlock.BuildEmptyBlockForNextSlot(testServiceProvider, state, BlsSignature.Zero);
            SignedBeaconBlock signedBlock2 = TestState.StateTransitionAndSignBlock(testServiceProvider, state, block2);

            await AddBlockToStore(testServiceProvider, store, signedBlock2);

            // Act
            Root headRoot = await forkChoice.GetHeadAsync(store);

            // Assert
            Root expectedRoot = cryptographyService.HashTreeRoot(block2);

            headRoot.ShouldBe(expectedRoot);
        }
コード例 #4
0
        public async Task GenesisHead()
        {
            // Arrange
            IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider(useStore: true);
            BeaconState      state = TestState.PrepareTestState(testServiceProvider);

            JsonSerializerOptions options = new System.Text.Json.JsonSerializerOptions {
                WriteIndented = true
            };

            options.ConfigureNethermindCore2();
            string debugState = System.Text.Json.JsonSerializer.Serialize(state, options);

            // Initialization
            IBeaconChainUtility  beaconChainUtility  = testServiceProvider.GetService <IBeaconChainUtility>();
            ICryptographyService cryptographyService = testServiceProvider.GetService <ICryptographyService>();
            IForkChoice          forkChoice          = testServiceProvider.GetService <IForkChoice>();

            IStore store = testServiceProvider.GetService <IStore>();
            await forkChoice.InitializeForkChoiceStoreAsync(store, state);

            // Act
            Root headRoot = await forkChoice.GetHeadAsync(store);

            // Assert
            Root stateRoot = cryptographyService.HashTreeRoot(state);

            BeaconBlock genesisBlock = new BeaconBlock(Slot.Zero, Root.Zero, stateRoot, BeaconBlockBody.Zero);
            Root        expectedRoot = cryptographyService.HashTreeRoot(genesisBlock);

            headRoot.ShouldBe(expectedRoot);
        }
コード例 #5
0
        public async Task <BeaconBlock> NewBlockAsync(Slot slot, BlsSignature randaoReveal,
                                                      CancellationToken cancellationToken)
        {
            if (slot == Slot.Zero)
            {
                throw new ArgumentException("Can't generate new block for slot 0, as it is the genesis block.");
            }

            Slot previousSlot = slot - Slot.One;
            Root head         = await _forkChoice.GetHeadAsync(_store).ConfigureAwait(false);

            BeaconBlock headBeaconBlock = (await _store.GetSignedBlockAsync(head).ConfigureAwait(false)).Message;

            BeaconState parentState;
            Root        parentRoot;

            if (headBeaconBlock !.Slot > previousSlot)
            {
                // Requesting a block for a past slot?
                Root ancestorRoot =
                    await _forkChoice.GetAncestorAsync(_store, head, previousSlot).ConfigureAwait(false);

                parentState = await _store.GetBlockStateAsync(ancestorRoot).ConfigureAwait(false);

                parentRoot = ancestorRoot;
            }
コード例 #6
0
        public async Task ShorterChainButHeavierWeight()
        {
            // Arrange
            IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider(useStore: true);
            BeaconState      state = TestState.PrepareTestState(testServiceProvider);

            // Initialization
            ICryptographyService cryptographyService = testServiceProvider.GetService <ICryptographyService>();
            IForkChoice          forkChoice          = testServiceProvider.GetService <IForkChoice>();
            IStore store = testServiceProvider.GetService <IStore>();
            await forkChoice.InitializeForkChoiceStoreAsync(store, state);

            BeaconState genesisState = BeaconState.Clone(state);

            // build longer tree
            Root        longRoot  = Root.Zero;
            BeaconState longState = BeaconState.Clone(genesisState);

            for (int i = 0; i < 3; i++)
            {
                BeaconBlock       longBlock       = TestBlock.BuildEmptyBlockForNextSlot(testServiceProvider, longState, BlsSignature.Zero);
                SignedBeaconBlock signedLongBlock = TestState.StateTransitionAndSignBlock(testServiceProvider, longState, longBlock);
                await AddBlockToStore(testServiceProvider, store, signedLongBlock);

                if (i == 2)
                {
                    longRoot = cryptographyService.HashTreeRoot(longBlock);
                }
            }

            // build short tree
            BeaconState shortState = BeaconState.Clone(genesisState);
            BeaconBlock shortBlock = TestBlock.BuildEmptyBlockForNextSlot(testServiceProvider, shortState, BlsSignature.Zero);

            shortBlock.Body.SetGraffiti(new Bytes32(Enumerable.Repeat((byte)0x42, 32).ToArray()));
            TestBlock.SignBlock(testServiceProvider, shortState, shortBlock, ValidatorIndex.None);
            SignedBeaconBlock signedShortBlock = TestState.StateTransitionAndSignBlock(testServiceProvider, shortState, shortBlock);

            await AddBlockToStore(testServiceProvider, store, signedShortBlock);

            Attestation shortAttestation = TestAttestation.GetValidAttestation(testServiceProvider, shortState, shortBlock.Slot, CommitteeIndex.None, signed: true);

            await AddAttestationToStore(testServiceProvider, store, shortAttestation);

            // Act
            Root headRoot = await forkChoice.GetHeadAsync(store);

            // Assert
            Root expectedRoot = cryptographyService.HashTreeRoot(shortBlock);

            headRoot.ShouldBe(expectedRoot);
            headRoot.ShouldNotBe(longRoot);
        }
コード例 #7
0
        public async IAsyncEnumerable <Eth1Data> GetEth1DataDescendingAsync(ulong maximumTimestampInclusive,
                                                                            ulong minimumTimestampInclusive, [EnumeratorCancellation] CancellationToken cancellationToken)
        {
            Root head = await _forkChoice.GetHeadAsync(_store);

            BeaconState state = await _store.GetBlockStateAsync(head);

            Epoch    currentEpoch = _beaconStateAccessor.GetCurrentEpoch(state !);
            Eth1Data eth1Data     = GetEth1DataStub(state !, currentEpoch);

            yield return(eth1Data);
        }
コード例 #8
0
        public async Task SplitTieBreakerNoAttestations()
        {
            // Arrange
            IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider(useStore: true);
            BeaconState      state = TestState.PrepareTestState(testServiceProvider);

            // Initialization
            ICryptographyService cryptographyService = testServiceProvider.GetService <ICryptographyService>();
            IForkChoice          forkChoice          = testServiceProvider.GetService <IForkChoice>();
            IStore store = testServiceProvider.GetService <IStore>();
            await forkChoice.InitializeForkChoiceStoreAsync(store, state);

            BeaconState genesisState = BeaconState.Clone(state);

            // block at slot 1
            BeaconState       block1State  = BeaconState.Clone(genesisState);
            BeaconBlock       block1       = TestBlock.BuildEmptyBlockForNextSlot(testServiceProvider, block1State, BlsSignature.Zero);
            SignedBeaconBlock signedBlock1 = TestState.StateTransitionAndSignBlock(testServiceProvider, block1State, block1);

            await AddBlockToStore(testServiceProvider, store, signedBlock1);

            Root block1Root = cryptographyService.HashTreeRoot(block1);

            // build short tree
            BeaconState block2State = BeaconState.Clone(genesisState);
            BeaconBlock block2      = TestBlock.BuildEmptyBlockForNextSlot(testServiceProvider, block2State, BlsSignature.Zero);

            block2.Body.SetGraffiti(new Bytes32(Enumerable.Repeat((byte)0x42, 32).ToArray()));
            TestBlock.SignBlock(testServiceProvider, block2State, block2, ValidatorIndex.None);
            SignedBeaconBlock signedBlock2 = TestState.StateTransitionAndSignBlock(testServiceProvider, block2State, block2);

            await AddBlockToStore(testServiceProvider, store, signedBlock2);

            Root block2Root = cryptographyService.HashTreeRoot(block2);

            // Act
            Root headRoot = await forkChoice.GetHeadAsync(store);

            // Assert
            Console.WriteLine("block1 {0}", block1Root);
            Console.WriteLine("block2 {0}", block2Root);
            Root highestRoot = block1Root.CompareTo(block2Root) > 0 ? block1Root : block2Root;

            Console.WriteLine("highest {0}", highestRoot);
            headRoot.ShouldBe(highestRoot);
        }
コード例 #9
0
        public async Task <IList <ValidatorDuty> > GetValidatorDutiesAsync(
            IList <BlsPublicKey> validatorPublicKeys,
            Epoch?optionalEpoch)
        {
            Root head = await _forkChoice.GetHeadAsync(_store).ConfigureAwait(false);

            BeaconState headState = await _store.GetBlockStateAsync(head).ConfigureAwait(false);

            Epoch currentEpoch = _beaconStateAccessor.GetCurrentEpoch(headState);
            Epoch epoch        = optionalEpoch ?? currentEpoch;

            Epoch nextEpoch = currentEpoch + Epoch.One;

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

            Slot startSlot      = _beaconChainUtility.ComputeStartSlotOfEpoch(epoch);
            Root epochStartRoot = await _store.GetAncestorAsync(head, startSlot);

            TimeParameters timeParameters = _timeParameterOptions.CurrentValue;

            (Root epochStartRoot, Epoch epoch)cacheKey = (epochStartRoot, epoch);
            ConcurrentDictionary <BlsPublicKey, ValidatorDuty> dutiesForEpoch =
                await _validatorAssignmentsCache.Cache.GetOrCreateAsync(cacheKey, entry =>
            {
                entry.SlidingExpiration = TimeSpan.FromSeconds(2 * timeParameters.SecondsPerSlot);
                return(Task.FromResult(new ConcurrentDictionary <BlsPublicKey, ValidatorDuty>()));
            }).ConfigureAwait(false);

            IEnumerable <BlsPublicKey> missingValidators = validatorPublicKeys.Except(dutiesForEpoch.Keys);

            if (missingValidators.Any())
            {
                if (_logger.IsDebug())
                {
                    LogDebug.GettingMissingValidatorDutiesForCache(_logger, missingValidators.Count(), epoch,
                                                                   epochStartRoot,
                                                                   null);
                }

                BeaconState storedState = await _store.GetBlockStateAsync(epochStartRoot);

                // Clone, so that it can be safely mutated (transitioned forward)
                BeaconState state = BeaconState.Clone(storedState);

                // Transition to start slot, of target epoch (may have been a skip slot, i.e. stored state root may have been older)
                _beaconStateTransition.ProcessSlots(state, startSlot);

                // Check validators are valid (if not duties are empty).
                IList <DutyDetails> dutyDetailsList = new List <DutyDetails>();
                foreach (BlsPublicKey validatorPublicKey in missingValidators)
                {
                    ValidatorIndex?validatorIndex = FindValidatorIndexByPublicKey(state, validatorPublicKey);

                    if (validatorIndex.HasValue)
                    {
                        bool validatorActive = CheckIfValidatorActive(state, validatorIndex.Value);
                        if (validatorActive)
                        {
                            dutyDetailsList.Add(new DutyDetails(validatorPublicKey, validatorIndex.Value));
                        }
                        else
                        {
                            if (_logger.IsWarn())
                            {
                                Log.ValidatorNotActiveAtEpoch(_logger, epoch, validatorIndex.Value, validatorPublicKey,
                                                              null);
                            }
                            dutiesForEpoch[validatorPublicKey] =
                                new ValidatorDuty(validatorPublicKey, Slot.None, CommitteeIndex.None, Slot.None);
                        }
                    }
                    else
                    {
                        if (_logger.IsWarn())
                        {
                            Log.ValidatorNotFoundAtEpoch(_logger, epoch, validatorPublicKey, null);
                        }
                        dutiesForEpoch[validatorPublicKey] =
                            new ValidatorDuty(validatorPublicKey, Slot.None, CommitteeIndex.None, Slot.None);
                    }
                }

                if (dutyDetailsList.Any())
                {
                    // Check starting state
                    UpdateDutyDetailsForState(dutyDetailsList, state);

                    // Check other slots in epoch, if needed
                    Slot endSlotExclusive = startSlot + new Slot(timeParameters.SlotsPerEpoch);
                    Slot slotToCheck      = startSlot + Slot.One;
                    while (slotToCheck < endSlotExclusive)
                    {
                        _beaconStateTransition.ProcessSlots(state, slotToCheck);
                        UpdateDutyDetailsForState(dutyDetailsList, state);
                        slotToCheck += Slot.One;
                    }

                    // Active validators should always have attestation slots; warn if they don't
                    foreach (var dutyDetails in dutyDetailsList)
                    {
                        if (!dutyDetails.AttestationSlot.HasValue)
                        {
                            if (_logger.IsWarn())
                            {
                                Log.ValidatorDoesNotHaveAttestationSlot(_logger, epoch, dutyDetails.ValidatorPublicKey,
                                                                        null);
                            }
                        }
                    }

                    // Add to cached dictionary
                    foreach (var dutyDetails in dutyDetailsList)
                    {
                        ValidatorDuty validatorDuty =
                            new ValidatorDuty(dutyDetails.ValidatorPublicKey,
                                              dutyDetails.AttestationSlot,
                                              dutyDetails.AttestationCommitteeIndex,
                                              dutyDetails.BlockProposalSlot);
                        dutiesForEpoch[dutyDetails.ValidatorPublicKey] = validatorDuty;
                    }
                }
            }

            return(dutiesForEpoch
                   .Where(x => validatorPublicKeys.Contains(x.Key))
                   .Select(x => x.Value)
                   .ToList());
        }
コード例 #10
0
        public async Task <ValidatorDuty> GetValidatorDutyAsync(BlsPublicKey validatorPublicKey, Epoch epoch)
        {
            Root head = await _forkChoice.GetHeadAsync(_store).ConfigureAwait(false);

            BeaconState headState = await _store.GetBlockStateAsync(head).ConfigureAwait(false);

            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);

            Duty duty = new Duty()
            {
                AttestationSlot           = Slot.None,
                AttestationCommitteeIndex = CommitteeIndex.None,
                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);
                duty = CheckStateDuty(state, validatorIndex, duty);

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

                // Check base state
                ValidatorIndex validatorIndex = CheckValidatorIndex(state, validatorPublicKey);
                duty = CheckStateDuty(state, validatorIndex, duty);

                // Check future states
                duty = CheckFutureSlots(state, endSlot, validatorIndex, duty);

                // Check historical states
                if (startSlot < fromSlot && (duty.AttestationSlot == Slot.None || duty.BlockProposalSlot == Slot.None))
                {
                    duty = await CheckHistoricalSlotsAsync(_store, historicalBlockRoots, fromSlot, startSlot,
                                                           validatorIndex, duty).ConfigureAwait(false);
                }
            }
            else
            {
                Root endRoot = await _forkChoice.GetAncestorAsync(_store, head, endSlot - Slot.One);

                BeaconState state = await _store.GetBlockStateAsync(endRoot).ConfigureAwait(false);

                // Check base state
                ValidatorIndex validatorIndex = CheckValidatorIndex(state, validatorPublicKey);
                duty = CheckStateDuty(state, validatorIndex, duty);

                // Check historical states
                IReadOnlyList <Root> historicalBlockRoots = state.BlockRoots;
                if (duty.AttestationSlot == Slot.None || duty.BlockProposalSlot == Slot.None)
                {
                    Slot fromSlot = state.Slot;
                    duty = await CheckHistoricalSlotsAsync(_store, historicalBlockRoots, fromSlot, startSlot,
                                                           validatorIndex, duty).ConfigureAwait(false);
                }
            }

            // HACK: Shards were removed from Phase 0, but analogy is committee index, so use for initial testing.
            Shard attestationShard = new Shard((ulong)duty.AttestationCommitteeIndex);

            ValidatorDuty validatorDuty =
                new ValidatorDuty(validatorPublicKey, duty.AttestationSlot, attestationShard, duty.BlockProposalSlot);

            return(validatorDuty);
        }