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