Esempio n. 1
0
        public static (TxPriorityContract?Contract, TxPriorityContract.LocalDataSource?DataSource) CreateTxPrioritySources(
            IAuraConfig config,
            AuRaNethermindApi api,
            IReadOnlyTxProcessorSource readOnlyTxProcessorSource)
        {
            Address.TryParse(config.TxPriorityContractAddress, out Address? txPriorityContractAddress);
            bool usesTxPriorityContract = txPriorityContractAddress != null;

            TxPriorityContract?txPriorityContract = null;

            if (usesTxPriorityContract)
            {
                txPriorityContract = new TxPriorityContract(api.AbiEncoder, txPriorityContractAddress, readOnlyTxProcessorSource);
            }

            string?auraConfigTxPriorityConfigFilePath = config.TxPriorityConfigFilePath;
            bool   usesTxPriorityLocalData            = auraConfigTxPriorityConfigFilePath != null;

            if (usesTxPriorityLocalData)
            {
                api.TxPriorityContractLocalDataSource ??= new TxPriorityContract.LocalDataSource(auraConfigTxPriorityConfigFilePath, api.EthereumJsonSerializer, api.FileSystem, api.LogManager);
            }

            return(txPriorityContract, api.TxPriorityContractLocalDataSource);
        }
Esempio n. 2
0
 private ITxFilter CreateAuraTxFilterForProducer(IReadOnlyTxProcessorSource readOnlyTxProcessorSource, ISpecProvider specProvider) =>
 TxAuRaFilterBuilders.CreateAuRaTxFilterForProducer(
     NethermindApi.Config <IMiningConfig>(),
     _api,
     readOnlyTxProcessorSource,
     _minGasPricesContractDataStore,
     specProvider);
 public AuRaValidatorFactory(IStateProvider stateProvider,
                             IAbiEncoder abiEncoder,
                             ITransactionProcessor transactionProcessor,
                             IReadOnlyTxProcessorSource readOnlyTxProcessorSource,
                             IBlockTree blockTree,
                             IReceiptFinder receiptFinder,
                             IValidatorStore validatorStore,
                             IBlockFinalizationManager finalizationManager,
                             ITxSender txSender,
                             ITxPool txPool,
                             IMiningConfig miningConfig,
                             ILogManager logManager,
                             ISigner signer,
                             ReportingContractBasedValidator.Cache reportingValidatorCache,
                             long posdaoTransition,
                             bool forSealing = false)
 {
     _stateProvider             = stateProvider;
     _abiEncoder                = abiEncoder;
     _transactionProcessor      = transactionProcessor;
     _readOnlyTxProcessorSource = readOnlyTxProcessorSource;
     _blockTree           = blockTree;
     _receiptFinder       = receiptFinder;
     _validatorStore      = validatorStore;
     _finalizationManager = finalizationManager;
     _txSender            = txSender;
     _txPool                  = txPool;
     _miningConfig            = miningConfig;
     _logManager              = logManager;
     _signer                  = signer;
     _reportingValidatorCache = reportingValidatorCache;
     _posdaoTransition        = posdaoTransition;
     _forSealing              = forSealing;
 }
Esempio n. 4
0
 public TransactionPermissionContractV2(
     IAbiEncoder abiEncoder,
     Address contractAddress,
     IReadOnlyTxProcessorSource readOnlyTxProcessorSource)
     : base(abiEncoder, contractAddress, readOnlyTxProcessorSource)
 {
 }
        private IGasLimitCalculator CreateGasLimitCalculator(IReadOnlyTxProcessorSource readOnlyTxProcessorSource)
        {
            if (_api.ChainSpec == null)
            {
                throw new StepDependencyException(nameof(_api.ChainSpec));
            }
            var blockGasLimitContractTransitions = _api.ChainSpec.AuRa.BlockGasLimitContractTransitions;

            IGasLimitCalculator gasLimitCalculator =
                new TargetAdjustedGasLimitCalculator(_api.SpecProvider, NethermindApi.Config <IMiningConfig>());

            if (blockGasLimitContractTransitions?.Any() == true)
            {
                AuRaContractGasLimitOverride auRaContractGasLimitOverride =
                    new AuRaContractGasLimitOverride(
                        blockGasLimitContractTransitions.Select(blockGasLimitContractTransition =>
                                                                new BlockGasLimitContract(
                                                                    _api.AbiEncoder,
                                                                    blockGasLimitContractTransition.Value,
                                                                    blockGasLimitContractTransition.Key,
                                                                    readOnlyTxProcessorSource))
                        .ToArray <IBlockGasLimitContract>(),
                        _api.GasLimitCalculatorCache,
                        _auraConfig?.Minimum2MlnGasPerBlockWhenUsingBlockGasLimitContract == true,
                        gasLimitCalculator,
                        _api.LogManager);

                gasLimitCalculator = auRaContractGasLimitOverride;
            }

            return(gasLimitCalculator);
        }
Esempio n. 6
0
        public static ITxFilter?CreateTxPermissionFilter(AuRaNethermindApi api, IReadOnlyTxProcessorSource readOnlyTxProcessorSource)
        {
            if (api.ChainSpec == null)
            {
                throw new StepDependencyException(nameof(api.ChainSpec));
            }

            if (api.ChainSpec.Parameters.TransactionPermissionContract != null)
            {
                api.TxFilterCache ??= new PermissionBasedTxFilter.Cache();

                var txPermissionFilter = new PermissionBasedTxFilter(
                    new VersionedTransactionPermissionContract(api.AbiEncoder,
                                                               api.ChainSpec.Parameters.TransactionPermissionContract,
                                                               api.ChainSpec.Parameters.TransactionPermissionContractTransition ?? 0,
                                                               readOnlyTxProcessorSource,
                                                               api.TransactionPermissionContractVersions,
                                                               api.LogManager),
                    api.TxFilterCache,
                    api.LogManager);

                return(txPermissionFilter);
            }

            return(null);
        }
 public TransactionPermissionContractV2(
     IAbiEncoder abiEncoder,
     Address contractAddress,
     IReadOnlyTxProcessorSource readOnlyTxProcessorSource)
     : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress)), readOnlyTxProcessorSource)
 {
 }
Esempio n. 8
0
        private static ITxFilter CreateBaseAuRaTxFilter(
            IMiningConfig miningConfig,
            AuRaNethermindApi api,
            IReadOnlyTxProcessorSource readOnlyTxProcessorSource,
            IDictionaryContractDataStore <TxPriorityContract.Destination>?minGasPricesContractDataStore,
            ISpecProvider specProvider)
        {
            IMinGasPriceTxFilter minGasPriceTxFilter = CreateStandardMinGasPriceTxFilter(miningConfig, specProvider);
            ITxFilter            gasPriceTxFilter    = minGasPriceTxFilter;

            if (minGasPricesContractDataStore != null)
            {
                gasPriceTxFilter = new MinGasPriceContractTxFilter(minGasPriceTxFilter, minGasPricesContractDataStore);
            }

            Address?registrar = api.ChainSpec?.Parameters.Registrar;

            if (registrar != null)
            {
                RegisterContract  registerContract  = new(api.AbiEncoder, registrar, readOnlyTxProcessorSource);
                CertifierContract certifierContract = new(api.AbiEncoder, registerContract, readOnlyTxProcessorSource);
                return(new TxCertifierFilter(certifierContract, gasPriceTxFilter, specProvider, api.LogManager));
            }

            return(gasPriceTxFilter);
        }
 public ConstantContract(
     Contract contract, 
     IReadOnlyTxProcessorSource readOnlyTxProcessorSource)
 {
     _contract = contract;
     _readOnlyTxProcessorSource = readOnlyTxProcessorSource ?? throw new ArgumentNullException(nameof(readOnlyTxProcessorSource));
 }
Esempio n. 10
0
 public RegisterContract(
     IAbiEncoder abiEncoder,
     Address contractAddress,
     IReadOnlyTxProcessorSource readOnlyTxProcessorSource)
     : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress)))
 {
     Constant = GetConstant(readOnlyTxProcessorSource);
 }
Esempio n. 11
0
 public RegisterContract(
     IAbiEncoder abiEncoder,
     Address contractAddress,
     IReadOnlyTxProcessorSource readOnlyTxProcessorSource)
     : base(abiEncoder, contractAddress)
 {
     Constant = GetConstant(readOnlyTxProcessorSource);
 }
 public CertifierContract(
     IAbiEncoder abiEncoder,
     IRegisterContract registerContract,
     IReadOnlyTxProcessorSource readOnlyTransactionProcessorSource)
     : base(abiEncoder, registerContract, ServiceTransactionContractRegistryName)
 {
     Constant = GetConstant(readOnlyTransactionProcessorSource);
 }
 protected TransactionPermissionContract(
     IAbiEncoder abiEncoder,
     Address contractAddress,
     IReadOnlyTxProcessorSource readOnlyTxProcessorSource)
     : base(abiEncoder, contractAddress)
 {
     Constant = new PermissionConstantContract(this, readOnlyTxProcessorSource);
 }
Esempio n. 14
0
        private IAuRaValidator CreateAuRaValidator(IBlockProcessor processor, IReadOnlyTxProcessorSource readOnlyTxProcessorSource)
        {
            if (_api.ChainSpec == null)
            {
                throw new StepDependencyException(nameof(_api.ChainSpec));
            }
            if (_api.BlockTree == null)
            {
                throw new StepDependencyException(nameof(_api.BlockTree));
            }
            if (_api.EngineSigner == null)
            {
                throw new StepDependencyException(nameof(_api.EngineSigner));
            }
            if (_api.SpecProvider == null)
            {
                throw new StepDependencyException(nameof(_api.SpecProvider));
            }

            var chainSpecAuRa = _api.ChainSpec.AuRa;

            _api.FinalizationManager = new AuRaBlockFinalizationManager(
                _api.BlockTree,
                _api.ChainLevelInfoRepository,
                processor,
                _api.ValidatorStore,
                new ValidSealerStrategy(),
                _api.LogManager,
                chainSpecAuRa.TwoThirdsMajorityTransition);

            IAuRaValidator validator = new AuRaValidatorFactory(
                _api.StateProvider,
                _api.AbiEncoder,
                _api.TransactionProcessor,
                readOnlyTxProcessorSource,
                _api.BlockTree,
                _api.ReceiptStorage,
                _api.ValidatorStore,
                _api.FinalizationManager,
                new TxPoolSender(_api.TxPool, new NonceReservingTxSealer(_api.EngineSigner, _api.Timestamper, _api.TxPool)),
                _api.TxPool,
                NethermindApi.Config <IMiningConfig>(),
                _api.LogManager,
                _api.EngineSigner,
                _api.SpecProvider,
                _api.ReportingContractValidatorCache,
                chainSpecAuRa.PosdaoTransition,
                false)
                                       .CreateValidatorProcessor(chainSpecAuRa.Validators, _api.BlockTree.Head?.Header);

            if (validator is IDisposable disposableValidator)
            {
                _api.DisposeStack.Push(disposableValidator);
            }

            return(validator);
        }
 public TransactionPermissionContractV4(
     IAbiEncoder abiEncoder,
     Address contractAddress,
     IReadOnlyTxProcessorSource readOnlyTxProcessorSource,
     ISpecProvider specProvider)
     : base(abiEncoder, contractAddress, readOnlyTxProcessorSource)
 {
     _specProvider = specProvider;
 }
 public void SetUp()
 {
     _block = new Block(Build.A.BlockHeader.TestObject, new BlockBody());
     _transactionProcessor      = Substitute.For <IReadOnlyTransactionProcessor>();
     _readOnlyTxProcessorSource = Substitute.For <IReadOnlyTxProcessorSource>();
     _readOnlyTxProcessorSource.Build(TestItem.KeccakA).Returns(_transactionProcessor);
     _stateProvider = Substitute.For <IStateProvider>();
     _stateProvider.StateRoot.Returns(TestItem.KeccakA);
 }
 private static TransactionPermissionContractV3 CreateV3(IAbiEncoder abiEncoder,
                                                         Address contractAddress,
                                                         IReadOnlyTxProcessorSource readOnlyTxProcessorSource)
 {
     return(new TransactionPermissionContractV3(
                abiEncoder,
                contractAddress,
                readOnlyTxProcessorSource));
 }
Esempio n. 18
0
 public BlockGasLimitContract(
     IAbiEncoder abiEncoder,
     Address contractAddress,
     long transitionBlock,
     IReadOnlyTxProcessorSource readOnlyTxProcessorSource)
     : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress)))
 {
     Activation = transitionBlock;
     Constant   = GetConstant(readOnlyTxProcessorSource);
 }
 public BlockGasLimitContract(
     IAbiEncoder abiEncoder,
     Address contractAddress,
     long transitionBlock,
     IReadOnlyTxProcessorSource readOnlyTxProcessorSource)
     : base(abiEncoder, contractAddress)
 {
     Activation = transitionBlock;
     Constant   = GetConstant(readOnlyTxProcessorSource);
 }
 public TxPriorityContract(
     IAbiEncoder abiEncoder,
     Address contractAddress,
     IReadOnlyTxProcessorSource readOnlyTxProcessorSource)
     : base(abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress)))
 {
     Constant         = GetConstant(readOnlyTxProcessorSource);
     SendersWhitelist = new DataContract <Address>(GetSendersWhitelist, SendersWhitelistSet);
     MinGasPrices     = new DataContract <Destination>(GetMinGasPrices, MinGasPriceSet);
     Priorities       = new DataContract <Destination>(GetPriorities, PrioritySet);
 }
Esempio n. 21
0
 private static TransactionPermissionContractV4 CreateV4(IAbiEncoder abiEncoder,
                                                         Address contractAddress,
                                                         IReadOnlyTxProcessorSource readOnlyTxProcessorSource,
                                                         ISpecProvider specProvider)
 {
     return(new(
                abiEncoder,
                contractAddress,
                readOnlyTxProcessorSource,
                specProvider));
 }
Esempio n. 22
0
        public static ITxFilter CreateAuRaTxFilter(
            AuRaNethermindApi api,
            IReadOnlyTxProcessorSource readOnlyTxProcessorSource,
            ISpecProvider specProvider)
        {
            ITxFilter baseAuRaTxFilter   = CreateBaseAuRaTxFilter(api, readOnlyTxProcessorSource, specProvider);
            ITxFilter?txPermissionFilter = CreateTxPermissionFilter(api, readOnlyTxProcessorSource);

            return(txPermissionFilter != null
                ? new CompositeTxFilter(baseAuRaTxFilter, txPermissionFilter)
                : baseAuRaTxFilter);
        }
Esempio n. 23
0
 public ValidatorContract(
     ITransactionProcessor transactionProcessor,
     IAbiEncoder abiEncoder,
     Address contractAddress,
     IStateProvider stateProvider,
     IReadOnlyTxProcessorSource readOnlyTxProcessorSource,
     ISigner signer)
     : base(transactionProcessor, abiEncoder, contractAddress ?? throw new ArgumentNullException(nameof(contractAddress)))
 {
     _stateProvider = stateProvider ?? throw new ArgumentNullException(nameof(stateProvider));
     _signer        = signer ?? throw new ArgumentNullException(nameof(signer));
     Constant       = GetConstant(readOnlyTxProcessorSource);
 }
Esempio n. 24
0
        public static ITxFilter CreateAuRaTxFilter(
            IMiningConfig miningConfig,
            AuRaNethermindApi api,
            IReadOnlyTxProcessorSource readOnlyTxProcessorSource,
            IDictionaryContractDataStore <TxPriorityContract.Destination>?minGasPricesContractDataStore)
        {
            ITxFilter baseAuRaTxFilter   = CreateBaseAuRaTxFilter(miningConfig, api, readOnlyTxProcessorSource, minGasPricesContractDataStore);
            ITxFilter?txPermissionFilter = CreateTxPermissionFilter(api, readOnlyTxProcessorSource);

            return(txPermissionFilter != null
                ? new CompositeTxFilter(baseAuRaTxFilter, txPermissionFilter)
                : baseAuRaTxFilter);
        }
 public VersionedTransactionPermissionContract(IAbiEncoder abiEncoder,
                                               Address contractAddress,
                                               long activation,
                                               IReadOnlyTxProcessorSource readOnlyTxProcessorSource,
                                               ICache <Keccak, UInt256> cache,
                                               ILogManager logManager)
     : base(
         CreateAllVersions(abiEncoder,
                           contractAddress,
                           readOnlyTxProcessorSource),
         cache,
         activation,
         logManager)
 {
 }
Esempio n. 26
0
        private static ITxFilter CreateBaseAuRaTxFilter(
            AuRaNethermindApi api,
            IReadOnlyTxProcessorSource readOnlyTxProcessorSource,
            ISpecProvider specProvider)
        {
            Address?registrar = api.ChainSpec?.Parameters.Registrar;

            if (registrar != null)
            {
                RegisterContract  registerContract  = new(api.AbiEncoder, registrar, readOnlyTxProcessorSource);
                CertifierContract certifierContract = new(api.AbiEncoder, registerContract, readOnlyTxProcessorSource);
                return(new TxCertifierFilter(certifierContract, NullTxFilter.Instance, specProvider, api.LogManager));
            }

            return(NullTxFilter.Instance);
        }
Esempio n. 27
0
        protected virtual BlockProcessor CreateBlockProcessor(
            ReadOnlyTxProcessingEnv readOnlyTxProcessingEnv,
            IReadOnlyTxProcessorSource readOnlyTxProcessorSource,
            IReadOnlyDbProvider readOnlyDbProvider)
        {
            if (_api.SpecProvider == null)
            {
                throw new StepDependencyException(nameof(_api.SpecProvider));
            }
            if (_api.BlockValidator == null)
            {
                throw new StepDependencyException(nameof(_api.BlockValidator));
            }
            if (_api.RewardCalculatorSource == null)
            {
                throw new StepDependencyException(nameof(_api.RewardCalculatorSource));
            }
            if (_api.ReceiptStorage == null)
            {
                throw new StepDependencyException(nameof(_api.ReceiptStorage));
            }
            if (_api.TxPool == null)
            {
                throw new StepDependencyException(nameof(_api.TxPool));
            }

            return(new BlockProcessor(
                       _api.SpecProvider,
                       _api.BlockValidator,
                       _api.RewardCalculatorSource.Get(readOnlyTxProcessingEnv.TransactionProcessor),
                       readOnlyTxProcessingEnv.TransactionProcessor,
                       readOnlyTxProcessingEnv.StateProvider,
                       readOnlyTxProcessingEnv.StorageProvider,
                       _api.TxPool,
                       _api.ReceiptStorage,
                       NullWitnessCollector.Instance,
                       _api.LogManager));
        }
 protected override ITxFilter CreateTxSourceFilter(ReadOnlyTxProcessingEnv readOnlyTxProcessingEnv, IReadOnlyTxProcessorSource readOnlyTxProcessorSource) =>
 TxFilterBuilders.CreateAuRaTxFilter(
     NethermindApi.Config <IMiningConfig>(),
     _api,
     readOnlyTxProcessorSource,
     _minGasPricesContractDataStore);
        protected override ITxSource CreateTxSourceForProducer(ReadOnlyTxProcessingEnv processingEnv, IReadOnlyTxProcessorSource readOnlyTxProcessorSource)
        {
            bool CheckAddPosdaoTransactions(IList <ITxSource> list, long auRaPosdaoTransition)
            {
                if (auRaPosdaoTransition < AuRaParameters.TransitionDisabled && _validator is ITxSource validatorSource)
                {
                    list.Insert(0, validatorSource);
                    return(true);
                }

                return(false);
            }

            bool CheckAddRandomnessTransactions(IList <ITxSource> list, IDictionary <long, Address>?randomnessContractAddress, ISigner signer)
            {
                IList <IRandomContract> GetRandomContracts(
                    IDictionary <long, Address> randomnessContractAddressPerBlock,
                    IAbiEncoder abiEncoder,
                    IReadOnlyTxProcessorSource txProcessorSource,
                    ISigner signerLocal) =>
                randomnessContractAddressPerBlock
                .Select(kvp => new RandomContract(
                            abiEncoder,
                            kvp.Value,
                            txProcessorSource,
                            kvp.Key,
                            signerLocal))
                .ToArray <IRandomContract>();

                if (randomnessContractAddress?.Any() == true)
                {
                    var randomContractTxSource = new RandomContractTxSource(
                        GetRandomContracts(randomnessContractAddress, _api.AbiEncoder,
                                           readOnlyTxProcessorSource,
                                           signer),
                        new EciesCipher(_api.CryptoRandom),
                        signer,
                        _api.NodeKey,
                        _api.CryptoRandom,
                        _api.LogManager);

                    list.Insert(0, randomContractTxSource);
                    return(true);
                }

                return(false);
            }

            if (_api.ChainSpec == null)
            {
                throw new StepDependencyException(nameof(_api.ChainSpec));
            }
            if (_api.BlockTree == null)
            {
                throw new StepDependencyException(nameof(_api.BlockTree));
            }
            if (_api.EngineSigner == null)
            {
                throw new StepDependencyException(nameof(_api.EngineSigner));
            }

            IList <ITxSource> txSources = new List <ITxSource> {
                base.CreateTxSourceForProducer(processingEnv, readOnlyTxProcessorSource)
            };
            bool needSigner = false;

            needSigner |= CheckAddPosdaoTransactions(txSources, _api.ChainSpec.AuRa.PosdaoTransition);
            needSigner |= CheckAddRandomnessTransactions(txSources, _api.ChainSpec.AuRa.RandomnessContractAddress, _api.EngineSigner);

            ITxSource txSource = txSources.Count > 1 ? new CompositeTxSource(txSources.ToArray()) : txSources[0];

            if (needSigner)
            {
                TxSealer transactionSealer = new TxSealer(_api.EngineSigner, _api.Timestamper);
                txSource = new GeneratedTxSource(txSource, transactionSealer, processingEnv.StateReader, _api.LogManager);
            }

            if (_txPermissionFilter != null)
            {
                // we now only need to filter generated transactions here, as regular ones are filtered on TxPoolTxSource filter based on CreateTxSourceFilter method
                txSource = new FilteredTxSource <GeneratedTransaction>(txSource, _txPermissionFilter, _api.LogManager);
            }

            return(txSource);
        }
        protected override TxPoolTxSource CreateTxPoolTxSource(ReadOnlyTxProcessingEnv processingEnv, IReadOnlyTxProcessorSource readOnlyTxProcessorSource)
        {
            // We need special one for TxPriority as its following Head separately with events and we want rules from Head, not produced block
            IReadOnlyTxProcessorSource readOnlyTxProcessorSourceForTxPriority =
                new ReadOnlyTxProcessingEnv(_api.DbProvider, _api.ReadOnlyTrieStore, _api.BlockTree, _api.SpecProvider, _api.LogManager);

            (_txPriorityContract, _localDataSource) = TxFilterBuilders.CreateTxPrioritySources(_auraConfig, _api, readOnlyTxProcessorSourceForTxPriority);

            if (_txPriorityContract != null || _localDataSource != null)
            {
                _minGasPricesContractDataStore = TxFilterBuilders.CreateMinGasPricesDataStore(_api, _txPriorityContract, _localDataSource) !;
                _api.DisposeStack.Push(_minGasPricesContractDataStore);

                ContractDataStore <Address> whitelistContractDataStore = new ContractDataStoreWithLocalData <Address>(
                    new HashSetContractDataStoreCollection <Address>(),
                    _txPriorityContract?.SendersWhitelist,
                    _api.BlockTree,
                    _api.ReceiptFinder,
                    _api.LogManager,
                    _localDataSource?.GetWhitelistLocalDataSource() ?? new EmptyLocalDataSource <IEnumerable <Address> >());

                DictionaryContractDataStore <TxPriorityContract.Destination> prioritiesContractDataStore =
                    new DictionaryContractDataStore <TxPriorityContract.Destination>(
                        new TxPriorityContract.DestinationSortedListContractDataStoreCollection(),
                        _txPriorityContract?.Priorities,
                        _api.BlockTree,
                        _api.ReceiptFinder,
                        _api.LogManager,
                        _localDataSource?.GetPrioritiesLocalDataSource());

                _api.DisposeStack.Push(whitelistContractDataStore);
                _api.DisposeStack.Push(prioritiesContractDataStore);


                return(new TxPriorityTxSource(
                           _api.TxPool,
                           processingEnv.StateReader,
                           _api.LogManager,
                           CreateTxSourceFilter(processingEnv, readOnlyTxProcessorSource),
                           whitelistContractDataStore,
                           prioritiesContractDataStore));
            }
            else
            {
                return(base.CreateTxPoolTxSource(processingEnv, readOnlyTxProcessorSource));
            }
        }