public Slot GetCurrentSlot(BeaconChainInformation beaconChainInformation) { ulong slotValue = (beaconChainInformation.Time - beaconChainInformation.GenesisTime) / _timeParameterOptions.CurrentValue.SecondsPerSlot; return(new Slot(slotValue)); }
public Slot GetNextAttestationSlotToCheck(BeaconChainInformation beaconChainInformation) { // Generally no point in attesting for slots <= current (head) slot Slot slotToCheckAttestation = Slot.Max(beaconChainInformation.LastAttestationSlotChecked + Slot.One, beaconChainInformation.SyncStatus.CurrentSlot); return(slotToCheckAttestation); }
public ulong GetAttestationTime(BeaconChainInformation beaconChainInformation, Slot slot) { TimeParameters timeParameters = _timeParameterOptions.CurrentValue; ulong startTimeOfSlot = beaconChainInformation.GenesisTime + timeParameters.SecondsPerSlot * slot; // Attest 1/3 way through slot ulong attestationTime = startTimeOfSlot + (_timeParameterOptions.CurrentValue.SecondsPerSlot / 3); return(attestationTime); }
public HonestValidatorWorker(ILogger <HonestValidatorWorker> logger, IClock clock, IHostEnvironment environment, DataDirectory dataDirectory, IBeaconNodeApi beaconNodeApi, BeaconChainInformation beaconChainInformation, ValidatorClient validatorClient, IClientVersion clientVersion) { _logger = logger; _clock = clock; _environment = environment; _dataDirectory = dataDirectory; _beaconNodeApi = beaconNodeApi; _beaconChainInformation = beaconChainInformation; _validatorClient = validatorClient; _clientVersion = clientVersion; }
public ValidatorClient(ILogger <ValidatorClient> logger, IOptionsMonitor <InitialValues> initialValueOptions, IOptionsMonitor <TimeParameters> timeParameterOptions, IOptionsMonitor <SignatureDomains> signatureDomainOptions, ICryptographyService cryptographyService, IBeaconNodeApi beaconNodeApi, IValidatorKeyProvider validatorKeyProvider, BeaconChainInformation beaconChainInformation) { _logger = logger; _initialValueOptions = initialValueOptions; _timeParameterOptions = timeParameterOptions; _signatureDomainOptions = signatureDomainOptions; _cryptographyService = cryptographyService; _beaconNodeApi = beaconNodeApi; _validatorKeyProvider = validatorKeyProvider; _beaconChainInformation = beaconChainInformation; _validatorState = new ValidatorState(); _cache = new MemoryCache(new MemoryCacheOptions()); }
public ValidatorClient(ILogger <ValidatorClient> logger, IOptionsMonitor <MiscellaneousParameters> miscellaneousParameterOptions, IOptionsMonitor <InitialValues> initialValueOptions, IOptionsMonitor <TimeParameters> timeParameterOptions, IOptionsMonitor <MaxOperationsPerBlock> maxOperationsPerBlockOptions, IOptionsMonitor <SignatureDomains> signatureDomainOptions, ICryptographyService cryptographyService, IBeaconNodeApi beaconNodeApi, IValidatorKeyProvider validatorKeyProvider, BeaconChainInformation beaconChainInformation) { _logger = logger; _miscellaneousParameterOptions = miscellaneousParameterOptions; _initialValueOptions = initialValueOptions; _timeParameterOptions = timeParameterOptions; _maxOperationsPerBlockOptions = maxOperationsPerBlockOptions; _signatureDomainOptions = signatureDomainOptions; _cryptographyService = cryptographyService; _beaconNodeApi = beaconNodeApi; _validatorKeyProvider = validatorKeyProvider; _beaconChainInformation = beaconChainInformation; _validatorState = new ValidatorState(); }
public async Task OnTickAsync(BeaconChainInformation beaconChainInformation, ulong time, CancellationToken cancellationToken) { // update time await beaconChainInformation.SetTimeAsync(time).ConfigureAwait(false); Slot currentSlot = GetCurrentSlot(beaconChainInformation); // TODO: attestation is done 1/3 way through slot // Not a new slot (clock is still the same as the slot we just checked), return bool shouldCheckSlot = currentSlot > beaconChainInformation.LastSlotChecked; if (!shouldCheckSlot) { return; } await UpdateForkVersionActivityAsync(cancellationToken).ConfigureAwait(false); // TODO: For beacon nodes that don't report SyncingStatus (which is nullable/optional), // then need a different strategy to determine the current head known by the beacon node. // The current code (2020-03-15) will simply start from slot 0 and process 1/second until // caught up with clock slot; at 6 seconds/slot, this is 6x faster, i.e. 1 day still takes 4 hours. // (okay for testing). // Alternative 1: see if the node supports /beacon/head, and use that slot // Alternative 2: try UpdateDuties, and if you get 406 DutiesNotAvailableForRequestedEpoch then use a // divide & conquer algorithm to determine block to check. (Could be a back off x1, x2, x4, x8, etc if 406) await UpdateSyncStatusActivityAsync(cancellationToken).ConfigureAwait(false); // Need to have an anchor block (will provide the genesis time) before can do anything // Absolutely no point in generating blocks < anchor slot // Irrespective of clock time, can't check duties >= 2 epochs ahead of current (head), as don't have data // - actually, validator only cares about what they need to sign this slot // - the beacon node takes care of subscribing to topics an epoch in advance, etc // While signing a block < highest (seen) slot may be a waste, there is no penalty for doing so // Generally no point in generating blocks <= current (head) slot Slot slotToCheck = Slot.Max(beaconChainInformation.LastSlotChecked, beaconChainInformation.SyncStatus.CurrentSlot) + Slot.One; LogDebug.ProcessingSlot(_logger, slotToCheck, currentSlot, beaconChainInformation.SyncStatus.CurrentSlot, null); // Slot is set before processing; if there is an error (in process; update duties has a try/catch), it will skip to the next slot // (maybe the error will be resolved; trade off of whether error can be fixed by retrying, e.g. network error, // but potentially getting stuck in a slot, vs missing a slot) // TODO: Maybe add a retry policy/retry count when to advance last slot checked regardless await beaconChainInformation.SetLastSlotChecked(slotToCheck); // TODO: Attestations should run checks one epoch ahead, for topic subscriptions, although this is more a beacon node thing to do. // Note that UpdateDuties will continue even if there is an error/issue (i.e. assume no change and process what we have) Epoch epochToCheck = ComputeEpochAtSlot(slotToCheck); await UpdateDutiesActivityAsync(epochToCheck, cancellationToken).ConfigureAwait(false); await ProcessProposalDutiesAsync(slotToCheck, cancellationToken).ConfigureAwait(false); // If upcoming attester, join (or change) topics // Subscribe to topics // Attest 1/3 way through slot }