private void OnBlocksFinalized(object sender, FinalizeEventArgs e) { if (CurrentPendingValidators != null) { // .Any equivalent with for var currentPendingValidatorsBlockGotFinalized = false; for (int i = 0; i < e.FinalizedBlocks.Count && !currentPendingValidatorsBlockGotFinalized; i++) { currentPendingValidatorsBlockGotFinalized = e.FinalizedBlocks[i].Hash == CurrentPendingValidators.BlockHash; } if (currentPendingValidatorsBlockGotFinalized) { CurrentPendingValidators.AreFinalized = true; Validators = CurrentPendingValidators.Addresses; SetPendingValidators(CurrentPendingValidators, true); if (!ForSealing) { ValidatorStore.SetValidators(e.FinalizingBlock.Number, Validators); if (_logger.IsInfo) { _logger.Info($"Finalizing validators for transition within contract signalled at block {CurrentPendingValidators.BlockNumber}. after block {e.FinalizingBlock.ToString(BlockHeader.Format.Short)}."); } } } } }
public override void OnBlockProcessingEnd(Block block, TxReceipt[] receipts, ProcessingOptions options = ProcessingOptions.None) { base.OnBlockProcessingEnd(block, receipts, options); if (block.IsGenesis) { ValidatorStore.SetValidators(block.Number, LoadValidatorsFromContract(block.Header)); } if (ValidatorContract.CheckInitiateChangeEvent(block.Header, receipts, out var potentialValidators)) { var isProcessingBlock = !options.IsProducingBlock(); InitiateChange(block, potentialValidators, isProcessingBlock, Validators.Length == 1); if (_logger.IsInfo && isProcessingBlock) { _logger.Info($"Signal for transition within contract at block {block.ToString(Block.Format.Short)}. New list of {potentialValidators.Length} : [{string.Join<Address>(", ", potentialValidators)}]."); } } }
public override void OnBlockProcessingStart(Block block, ProcessingOptions options = ProcessingOptions.None) { if (block.IsGenesis) { return; } var isProducingBlock = options.IsProducingBlock(); var isProcessingBlock = !isProducingBlock; var isInitBlock = InitBlockNumber == block.Number; var headNumber = _blockTree.Head?.Number ?? -2; // -2, so genesis.Number - 1 > -2. var skippingBlocks = block.Number - 1 > headNumber; var shouldLoadValidators = Validators == null || skippingBlocks || isProducingBlock; var mainChainProcessing = !ForSealing && isProcessingBlock; if (shouldLoadValidators) { Validators = isInitBlock || skippingBlocks ? LoadValidatorsFromContract(_blockTree.FindParentHeader(block.Header, BlockTreeLookupOptions.None)) : ValidatorStore.GetValidators(); if (mainChainProcessing) { if (_logger.IsInfo) { _logger.Info($"{(isInitBlock ? "Initial" : "Current")} contract validators ({Validators.Length}): [{string.Join<Address>(", ", Validators)}]."); } } } if (isInitBlock) { if (mainChainProcessing) { ValidatorStore.SetValidators(InitBlockNumber, Validators); } InitiateChange(block, Validators.ToArray(), isProcessingBlock, true); } else { if (isProcessingBlock) { bool reorganisationHappened = block.Number <= _lastProcessedBlockNumber; if (reorganisationHappened) { var reorganisationToBlockBeforePendingValidatorsInitChange = block.Number <= CurrentPendingValidators?.BlockNumber; SetPendingValidators(reorganisationToBlockBeforePendingValidatorsInitChange ? null : LoadPendingValidators(), reorganisationToBlockBeforePendingValidatorsInitChange); } else if (block.Number > _lastProcessedBlockNumber + 1) // blocks skipped, like fast sync { SetPendingValidators(TryGetInitChangeFromPastBlocks(block.ParentHash), true); } } else { // if we are not processing blocks we are not on consecutive blocks. // We need to initialize pending validators from db on each block being produced. SetPendingValidators(LoadPendingValidators()); } } base.OnBlockProcessingStart(block, options); FinalizePendingValidatorsIfNeeded(block.Header, isProcessingBlock); _lastProcessedBlockNumber = block.Number; }