Example #1
0
        public BlockProcessor(
            ISpecProvider specProvider,
            IBlockValidator blockValidator,
            IRewardCalculator rewardCalculator,
            ITransactionProcessor transactionProcessor,
            IStateProvider stateProvider,
            IStorageProvider storageProvider,
            ITxPool txPool,
            IReceiptStorage receiptStorage,
            IWitnessCollector witnessCollector,
            ILogManager logManager)
        {
            _logger               = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
            _specProvider         = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
            _blockValidator       = blockValidator ?? throw new ArgumentNullException(nameof(blockValidator));
            _stateProvider        = stateProvider ?? throw new ArgumentNullException(nameof(stateProvider));
            _storageProvider      = storageProvider ?? throw new ArgumentNullException(nameof(storageProvider));
            _txPool               = txPool ?? throw new ArgumentNullException(nameof(txPool));
            _receiptStorage       = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
            _witnessCollector     = witnessCollector ?? throw new ArgumentNullException(nameof(witnessCollector));
            _rewardCalculator     = rewardCalculator ?? throw new ArgumentNullException(nameof(rewardCalculator));
            _transactionProcessor = transactionProcessor ?? throw new ArgumentNullException(nameof(transactionProcessor));

            _receiptsTracer = new BlockReceiptsTracer();
        }
        public void Can_store_a_witness()
        {
            IDb stateDb   = new MemDb();
            IDb codeDb    = new MemDb();
            var trieStore = new TrieStore(stateDb, LimboLogs.Instance);

            IStateProvider        stateProvider        = new StateProvider(trieStore, codeDb, LimboLogs.Instance);
            ITransactionProcessor transactionProcessor = Substitute.For <ITransactionProcessor>();
            IWitnessCollector     witnessCollector     = Substitute.For <IWitnessCollector>();
            BlockProcessor        processor            = new(
                RinkebySpecProvider.Instance,
                TestBlockValidator.AlwaysValid,
                NoBlockRewards.Instance,
                new BlockProcessor.BlockValidationTransactionsExecutor(transactionProcessor, stateProvider),
                stateProvider,
                new StorageProvider(trieStore, stateProvider, LimboLogs.Instance),
                NullReceiptStorage.Instance,
                witnessCollector,
                LimboLogs.Instance);

            BlockHeader header = Build.A.BlockHeader.WithAuthor(TestItem.AddressD).TestObject;
            Block       block  = Build.A.Block.WithHeader(header).TestObject;

            _ = processor.Process(
                Keccak.EmptyTreeHash,
                new List <Block> {
                block
            },
                ProcessingOptions.None,
                NullBlockTracer.Instance);

            witnessCollector.Received(1).Persist(block.Hash);
        }
Example #3
0
 public static IKeyValueStoreWithBatching WitnessedBy(
     this IKeyValueStoreWithBatching @this,
     IWitnessCollector witnessCollector)
 {
     return(witnessCollector == NullWitnessCollector.Instance
         ? @this
         : new WitnessingStore(@this, witnessCollector));
 }
Example #4
0
 public static IWitnessCollector WithPruning(
     this IWitnessCollector collector,
     IBlockTree blockTree,
     ILogManager logManager,
     int followDistance = 16)
 {
     new WitnessPruner(blockTree, collector, logManager, followDistance).Start();
     return(collector);
 }
Example #5
0
        public BlockProcessor(
            ISpecProvider?specProvider,
            IBlockValidator?blockValidator,
            IRewardCalculator?rewardCalculator,
            IBlockProcessor.IBlockTransactionsExecutor?blockTransactionsExecutor,
            IStateProvider?stateProvider,
            IStorageProvider?storageProvider,
            IReceiptStorage?receiptStorage,
            IWitnessCollector?witnessCollector,
            ILogManager?logManager)
        {
            _logger                    = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
            _specProvider              = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
            _blockValidator            = blockValidator ?? throw new ArgumentNullException(nameof(blockValidator));
            _stateProvider             = stateProvider ?? throw new ArgumentNullException(nameof(stateProvider));
            _storageProvider           = storageProvider ?? throw new ArgumentNullException(nameof(storageProvider));
            _receiptStorage            = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
            _witnessCollector          = witnessCollector ?? throw new ArgumentNullException(nameof(witnessCollector));
            _rewardCalculator          = rewardCalculator ?? throw new ArgumentNullException(nameof(rewardCalculator));
            _blockTransactionsExecutor = blockTransactionsExecutor ?? throw new ArgumentNullException(nameof(blockTransactionsExecutor));

            _receiptsTracer = new BlockReceiptsTracer();
        }
Example #6
0
 public WitnessingStore(IKeyValueStoreWithBatching?wrapped, IWitnessCollector?witnessCollector)
 {
     _wrapped          = wrapped ?? throw new ArgumentNullException(nameof(wrapped));
     _witnessCollector = witnessCollector ?? throw new ArgumentNullException(nameof(witnessCollector));
 }
 public Context(int cacheSize)
 {
     WitnessCollector = new WitnessCollector(new MemDb(), LimboLogs.Instance);
     Database         = new WitnessingStore(new CachingStore(Wrapped, cacheSize), WitnessCollector);
 }
 public Context()
 {
     WitnessCollector = new WitnessCollector(new MemDb(), LimboLogs.Instance);
     Database         = new WitnessingStore(Wrapped, WitnessCollector);
 }
Example #9
0
        private Task InitBlockchain()
        {
            BlockTraceDumper.Converters.AddRange(DebugModuleFactory.Converters);
            BlockTraceDumper.Converters.AddRange(TraceModuleFactory.Converters);

            var(getApi, setApi) = _api.ForBlockchain;

            if (getApi.ChainSpec == null)
            {
                throw new StepDependencyException(nameof(getApi.ChainSpec));
            }
            if (getApi.DbProvider == null)
            {
                throw new StepDependencyException(nameof(getApi.DbProvider));
            }
            if (getApi.SpecProvider == null)
            {
                throw new StepDependencyException(nameof(getApi.SpecProvider));
            }

            _logger = getApi.LogManager.GetClassLogger();
            IInitConfig    initConfig    = getApi.Config <IInitConfig>();
            ISyncConfig    syncConfig    = getApi.Config <ISyncConfig>();
            IPruningConfig pruningConfig = getApi.Config <IPruningConfig>();

            if (syncConfig.DownloadReceiptsInFastSync && !syncConfig.DownloadBodiesInFastSync)
            {
                _logger.Warn($"{nameof(syncConfig.DownloadReceiptsInFastSync)} is selected but {nameof(syncConfig.DownloadBodiesInFastSync)} - enabling bodies to support receipts download.");
                syncConfig.DownloadBodiesInFastSync = true;
            }

            Account.AccountStartNonce = getApi.ChainSpec.Parameters.AccountStartNonce;

            IWitnessCollector witnessCollector = setApi.WitnessCollector = syncConfig.WitnessProtocolEnabled
                ? new WitnessCollector(getApi.DbProvider.WitnessDb, _api.LogManager)
                                                                           .WithPruning(getApi.BlockTree !, getApi.LogManager)
                : NullWitnessCollector.Instance;

            IKeyValueStoreWithBatching cachedStateDb = getApi.DbProvider.StateDb
                                                       .Cached(Trie.MemoryAllowance.TrieNodeCacheCount);

            setApi.MainStateDbWithCache = cachedStateDb;
            IKeyValueStore codeDb = getApi.DbProvider.CodeDb
                                    .WitnessedBy(witnessCollector);

            TrieStore trieStore;

            if (pruningConfig.Enabled)
            {
                setApi.TrieStore = trieStore = new TrieStore(
                    setApi.MainStateDbWithCache.WitnessedBy(witnessCollector),
                    Prune.WhenCacheReaches(pruningConfig.CacheMb.MB()),          // TODO: memory hint should define this
                    Persist.IfBlockOlderThan(pruningConfig.PersistenceInterval), // TODO: this should be based on time
                    getApi.LogManager);
            }
            else
            {
                setApi.TrieStore = trieStore = new TrieStore(
                    setApi.MainStateDbWithCache.WitnessedBy(witnessCollector),
                    No.Pruning,
                    Persist.EveryBlock,
                    getApi.LogManager);
            }

            getApi.DisposeStack.Push(trieStore);
            trieStore.ReorgBoundaryReached += ReorgBoundaryReached;
            ITrieStore readOnlyTrieStore = setApi.ReadOnlyTrieStore = trieStore.AsReadOnly(cachedStateDb);

            IStateProvider stateProvider = setApi.StateProvider = new StateProvider(
                trieStore,
                codeDb,
                getApi.LogManager);

            ReadOnlyDbProvider readOnly = new(getApi.DbProvider, false);

            PersistentTxStorage txStorage   = new(getApi.DbProvider.PendingTxsDb);
            IStateReader        stateReader = setApi.StateReader = new StateReader(readOnlyTrieStore, readOnly.GetDb <IDb>(DbNames.Code), getApi.LogManager);

            setApi.TransactionComparerProvider =
                new TransactionComparerProvider(getApi.SpecProvider !, getApi.BlockTree.AsReadOnly());
            setApi.ChainHeadStateProvider = new ChainHeadReadOnlyStateProvider(getApi.BlockTree, stateReader);
            Account.AccountStartNonce     = getApi.ChainSpec.Parameters.AccountStartNonce;

            stateProvider.StateRoot = getApi.BlockTree !.Head?.StateRoot ?? Keccak.EmptyTreeHash;

            if (_api.Config <IInitConfig>().DiagnosticMode == DiagnosticMode.VerifyTrie)
            {
                _logger.Info("Collecting trie stats and verifying that no nodes are missing...");
                TrieStats stats = stateProvider.CollectStats(getApi.DbProvider.CodeDb, _api.LogManager);
                _logger.Info($"Starting from {getApi.BlockTree.Head?.Number} {getApi.BlockTree.Head?.StateRoot}{Environment.NewLine}" + stats);
            }

            // Init state if we need system calls before actual processing starts
            if (getApi.BlockTree !.Head?.StateRoot != null)
            {
                stateProvider.StateRoot = getApi.BlockTree.Head.StateRoot;
            }

            var txValidator = setApi.TxValidator = new TxValidator(getApi.SpecProvider.ChainId);

            ITxPool txPool = _api.TxPool = CreateTxPool(txStorage);

            OnChainTxWatcher onChainTxWatcher = new(getApi.BlockTree, txPool, getApi.SpecProvider, _api.LogManager);

            getApi.DisposeStack.Push(onChainTxWatcher);

            ReceiptCanonicalityMonitor receiptCanonicalityMonitor = new(getApi.BlockTree, getApi.ReceiptStorage, _api.LogManager);

            getApi.DisposeStack.Push(receiptCanonicalityMonitor);

            _api.BlockPreprocessor.AddFirst(
                new RecoverSignatures(getApi.EthereumEcdsa, txPool, getApi.SpecProvider, getApi.LogManager));

            IStorageProvider storageProvider = setApi.StorageProvider = new StorageProvider(
                trieStore,
                stateProvider,
                getApi.LogManager);

            // blockchain processing
            BlockhashProvider blockhashProvider = new BlockhashProvider(
                getApi.BlockTree, getApi.LogManager);

            VirtualMachine virtualMachine = new VirtualMachine(
                stateProvider,
                storageProvider,
                blockhashProvider,
                getApi.SpecProvider,
                getApi.LogManager);

            _api.TransactionProcessor = new TransactionProcessor(
                getApi.SpecProvider,
                stateProvider,
                storageProvider,
                virtualMachine,
                getApi.LogManager);

            InitSealEngine();
            if (_api.SealValidator == null)
            {
                throw new StepDependencyException(nameof(_api.SealValidator));
            }

            /* validation */
            var headerValidator = setApi.HeaderValidator = CreateHeaderValidator();

            OmmersValidator ommersValidator = new(
                getApi.BlockTree,
                headerValidator,
                getApi.LogManager);

            var blockValidator = setApi.BlockValidator = new BlockValidator(
                txValidator,
                headerValidator,
                ommersValidator,
                getApi.SpecProvider,
                getApi.LogManager);

            setApi.TxPoolInfoProvider = new TxPoolInfoProvider(stateReader, txPool);
            var mainBlockProcessor = setApi.MainBlockProcessor = CreateBlockProcessor();

            BlockchainProcessor blockchainProcessor = new(
                getApi.BlockTree,
                mainBlockProcessor,
                _api.BlockPreprocessor,
                getApi.LogManager,
                new BlockchainProcessor.Options
            {
                AutoProcess = !syncConfig.BeamSync,
                StoreReceiptsByDefault = initConfig.StoreReceipts,
            });

            setApi.BlockProcessingQueue = blockchainProcessor;
            setApi.BlockchainProcessor  = blockchainProcessor;

            if (syncConfig.BeamSync)
            {
                BeamBlockchainProcessor beamBlockchainProcessor = new(
                    new ReadOnlyDbProvider(_api.DbProvider, false),
                    getApi.BlockTree,
                    getApi.SpecProvider,
                    getApi.LogManager,
                    blockValidator,
                    _api.BlockPreprocessor,
                    _api.RewardCalculatorSource !, // TODO: does it work with AuRa?
                    blockchainProcessor,
                    getApi.SyncModeSelector !);

                _api.DisposeStack.Push(beamBlockchainProcessor);
            }

            // TODO: can take the tx sender from plugin here maybe
            ITxSigner txSigner       = new WalletTxSigner(getApi.Wallet, getApi.SpecProvider.ChainId);
            TxSealer  standardSealer = new(txSigner, getApi.Timestamper);
            NonceReservingTxSealer nonceReservingTxSealer =
                new(txSigner, getApi.Timestamper, txPool);

            setApi.TxSender = new TxPoolSender(txPool, nonceReservingTxSealer, standardSealer);

            // TODO: possibly hide it (but need to confirm that NDM does not really need it)
            var filterStore = setApi.FilterStore = new FilterStore();

            setApi.FilterManager     = new FilterManager(filterStore, mainBlockProcessor, txPool, getApi.LogManager);
            setApi.HealthHintService = CreateHealthHintService();
            return(Task.CompletedTask);
        }