Esempio n. 1
0
        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)}.");
                        }
                    }
                }
            }
        }
Esempio n. 2
0
        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)}].");
                }
            }
        }
Esempio n. 3
0
        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;
        }