Beispiel #1
0
        public void PostProcess(Block block, TxReceipt[] receipts, ProcessingOptions options = ProcessingOptions.None)
        {
            _currentValidator?.PostProcess(block, receipts, options);

            if (!block.IsGenesis)
            {
                var notProducing = !options.IsProducingBlock();

                if (TryGetValidator(block.Number, out var validator))
                {
                    if (validator.ValidatorType.CanChangeImmediately())
                    {
                        SetCurrentValidator(block.Number, validator);
                        if (_logger.IsInfo && notProducing)
                        {
                            _logger.Info($"Immediately applying chainspec validator change signalled at block {block.ToString(Block.Format.Short)} to {validator.ValidatorType}.");
                        }
                    }
                    else if (_logger.IsInfo && notProducing)
                    {
                        _logger.Info($"Signal for switch to chainspec {validator.ValidatorType} based validator set at block {block.ToString(Block.Format.Short)}.");
                    }
                }

                _lastProcessedBlock = block.Number;
            }
        }
Beispiel #2
0
        public void PreProcess(Block block, ProcessingOptions options = ProcessingOptions.None)
        {
            bool isProducingBlock    = options.IsProducingBlock();
            long previousBlockNumber = block.Number - 1;
            bool isNotConsecutive    = previousBlockNumber != _lastProcessedBlock;

            if (isProducingBlock || isNotConsecutive)
            {
                if (TryGetLastValidator(previousBlockNumber, out var validatorInfo))
                {
                    if (validatorInfo.Value.ValidatorType.CanChangeImmediately())
                    {
                        SetCurrentValidator(validatorInfo);
                    }
                    else if (!isProducingBlock)
                    {
                        bool canSetValidatorAsCurrent = !TryGetLastValidator(validatorInfo.Key - 1, out var previousValidatorInfo);
                        long?finalizedAtBlockNumber   = null;
                        if (!canSetValidatorAsCurrent)
                        {
                            SetCurrentValidator(previousValidatorInfo);
                            finalizedAtBlockNumber   = _blockFinalizationManager.GetFinalizedLevel(validatorInfo.Key);
                            canSetValidatorAsCurrent = finalizedAtBlockNumber != null;
                        }

                        if (canSetValidatorAsCurrent)
                        {
                            SetCurrentValidator(finalizedAtBlockNumber ?? validatorInfo.Key, validatorInfo.Value);
                        }
                    }
                }
            }

            _currentValidator?.PreProcess(block, options);
        }
Beispiel #3
0
        public void PreProcess(Block block, ProcessingOptions options = ProcessingOptions.None)
        {
            bool isProducingBlock = options.IsProducingBlock();

            if (isProducingBlock && TryGetLastValidator(block.Number - 1, out var validatorInfo))
            {
                AuRaParameters.Validator validator = validatorInfo?.Value;
                if (CanChangeImmediately(validator.ValidatorType))
                {
                    SetCurrentValidator(block.Number, validator);
                }
            }

            _currentValidator?.PreProcess(block, options);
        }
Beispiel #4
0
 public virtual void OnBlockProcessingStart(Block block, ProcessingOptions options = ProcessingOptions.None)
 {
     if (!options.IsProducingBlock() && !block.IsGenesis)
     {
         var auRaStep = block.Header.AuRaStep.Value;
         if (!_validSealerStrategy.IsValidSealer(Validators, block.Beneficiary, auRaStep))
         {
             if (_logger.IsError)
             {
                 _logger.Error($"Block from incorrect proposer at block {block.ToString(Block.Format.FullHashAndNumber)}, step {auRaStep} from author {block.Beneficiary}.");
             }
             throw new InvalidBlockException(block.Hash);
         }
     }
 }
Beispiel #5
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)}].");
                }
            }
        }
Beispiel #6
0
        public void OnBlockProcessingStart(Block block, ProcessingOptions options = ProcessingOptions.None)
        {
            if (!block.IsGenesis)
            {
                bool ValidatorWasAlreadyFinalized(KeyValuePair <long, AuRaParameters.Validator> validatorInfo) => _blockFinalizationManager.LastFinalizedBlockLevel >= validatorInfo.Key;

                bool isProducingBlock    = options.IsProducingBlock();
                long previousBlockNumber = block.Number - 1;
                bool isNotConsecutive    = previousBlockNumber != _lastProcessedBlock;

                if (isProducingBlock || isNotConsecutive)
                {
                    if (TryGetLastValidator(previousBlockNumber, out var validatorInfo))
                    {
                        var parentHeader = _blockTree.FindParentHeader(block.Header, BlockTreeLookupOptions.None);
                        if (validatorInfo.Value.ValidatorType.CanChangeImmediately() || ValidatorWasAlreadyFinalized(validatorInfo))
                        {
                            SetCurrentValidator(validatorInfo, parentHeader);
                        }
                        else if (!isProducingBlock)
                        {
                            bool canSetValidatorAsCurrent = !TryGetLastValidator(validatorInfo.Key - 1, out var previousValidatorInfo);
                            long?finalizedAtBlockNumber   = null;
                            if (!canSetValidatorAsCurrent)
                            {
                                SetCurrentValidator(previousValidatorInfo, parentHeader);
                                finalizedAtBlockNumber   = _blockFinalizationManager.GetLastLevelFinalizedBy(block.ParentHash);
                                canSetValidatorAsCurrent = finalizedAtBlockNumber >= validatorInfo.Key;
                            }

                            if (canSetValidatorAsCurrent)
                            {
                                SetCurrentValidator(finalizedAtBlockNumber ?? validatorInfo.Key, validatorInfo.Value, parentHeader);
                            }
                        }
                    }
                }
            }

            _currentValidator?.OnBlockProcessingStart(block, options);
        }
Beispiel #7
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;
        }