Esempio n. 1
0
            protected override IBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolTxSource, ISealer sealer, ITransactionComparerProvider transactionComparerProvider)
            {
                MiningConfig miningConfig = new() { MinGasPrice = UInt256.One };

                BlockProducerEnvFactory blockProducerEnvFactory = new BlockProducerEnvFactory(
                    DbProvider,
                    BlockTree,
                    ReadOnlyTrieStore,
                    SpecProvider,
                    BlockValidator,
                    NoBlockRewards.Instance,
                    ReceiptStorage,
                    BlockPreprocessorStep,
                    TxPool,
                    transactionComparerProvider,
                    miningConfig,
                    LogManager);

                UserOperationTxSource = new(UserOperationTxBuilder, UserOperationPool, UserOperationSimulator, SpecProvider, LogManager.GetClassLogger());

                Eth2TestBlockProducerFactory producerFactory = new Eth2TestBlockProducerFactory(GasLimitCalculator, UserOperationTxSource);
                Eth2BlockProducer            blockProducer   = producerFactory.Create(
                    blockProducerEnvFactory,
                    BlockTree,
                    BlockProductionTrigger,
                    SpecProvider,
                    new Eth2Signer(MinerAddress),
                    Timestamper,
                    miningConfig,
                    LogManager);

                return(blockProducer);
            }
            protected override IBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolTxSource, ISealer sealer, ITransactionComparerProvider transactionComparerProvider)
            {
                MiningConfig miningConfig = new();
                TargetAdjustedGasLimitCalculator targetAdjustedGasLimitCalculator = new(SpecProvider, miningConfig);

                BlockProducerEnvFactory blockProducerEnvFactory = new(
                    DbProvider,
                    BlockTree,
                    ReadOnlyTrieStore,
                    SpecProvider,
                    BlockValidator,
                    NoBlockRewards.Instance,
                    ReceiptStorage,
                    BlockPreprocessorStep,
                    TxPool,
                    transactionComparerProvider,
                    miningConfig,
                    LogManager);

                return(new Eth2TestBlockProducerFactory(targetAdjustedGasLimitCalculator).Create(
                           blockProducerEnvFactory,
                           BlockTree,
                           BlockProductionTrigger,
                           SpecProvider,
                           Signer,
                           Timestamper,
                           miningConfig,
                           LogManager));
            }
Esempio n. 3
0
        public Task InitBlockProducer()
        {
            if (_nethermindApi !.SealEngineType != SealEngineType.NethDev)
            {
                return(Task.CompletedTask);
            }

            var(getFromApi, setInApi) = _nethermindApi !.ForProducer;
            ITxFilter txFilter = new NullTxFilter();
            ITxSource txSource = new TxPoolTxSource(
                getFromApi.TxPool, getFromApi.StateReader, getFromApi.LogManager, txFilter);

            ILogger logger = getFromApi.LogManager.GetClassLogger();

            if (logger.IsWarn)
            {
                logger.Warn("Starting Neth Dev block producer & sealer");
            }

            ReadOnlyDbProvider readOnlyDbProvider = new ReadOnlyDbProvider(getFromApi.DbProvider, false);
            ReadOnlyBlockTree  readOnlyBlockTree  = new ReadOnlyBlockTree(getFromApi.BlockTree);

            ReadOnlyTxProcessingEnv producerEnv = new ReadOnlyTxProcessingEnv(
                readOnlyDbProvider,
                readOnlyBlockTree,
                getFromApi.SpecProvider,
                getFromApi.LogManager);

            BlockProcessor producerProcessor = new BlockProcessor(
                getFromApi !.SpecProvider,
                getFromApi !.BlockValidator,
                NoBlockRewards.Instance,
                producerEnv.TransactionProcessor,
                producerEnv.DbProvider.StateDb,
                producerEnv.DbProvider.CodeDb,
                producerEnv.StateProvider,
                producerEnv.StorageProvider,
                NullTxPool.Instance,
                NullReceiptStorage.Instance,
                getFromApi.LogManager);

            IBlockchainProcessor producerChainProcessor = new BlockchainProcessor(
                readOnlyBlockTree,
                producerProcessor,
                getFromApi.BlockPreprocessor,
                getFromApi.LogManager,
                BlockchainProcessor.Options.NoReceipts);

            setInApi.BlockProducer = new DevBlockProducer(
                txSource,
                producerChainProcessor,
                producerEnv.StateProvider,
                getFromApi.BlockTree,
                getFromApi.BlockProcessingQueue,
                getFromApi.TxPool,
                getFromApi.Timestamper,
                getFromApi.LogManager);

            return(Task.CompletedTask);
        }
Esempio n. 4
0
            protected override TxPoolTxSource CreateTxPoolTxSource()
            {
                TxPoolTxSource txPoolTxSource = base.CreateTxPoolTxSource();

                TxPriorityContract = new TxPriorityContract(new AbiEncoder(), TestItem.AddressA,
                                                            new ReadOnlyTxProcessingEnv(DbProvider, TrieStore.AsReadOnly(), BlockTree, SpecProvider, LimboLogs.Instance));

                Priorities = new DictionaryContractDataStore <TxPriorityContract.Destination>(
                    new TxPriorityContract.DestinationSortedListContractDataStoreCollection(),
                    TxPriorityContract.Priorities,
                    BlockTree,
                    ReceiptStorage,
                    LimboLogs.Instance,
                    GetPrioritiesLocalDataStore());

                MinGasPrices = new DictionaryContractDataStore <TxPriorityContract.Destination>(
                    new TxPriorityContract.DestinationSortedListContractDataStoreCollection(),
                    TxPriorityContract.MinGasPrices,
                    BlockTree,
                    ReceiptStorage,
                    LimboLogs.Instance,
                    GetMinGasPricesLocalDataStore());

                SendersWhitelist = new ContractDataStoreWithLocalData <Address>(new HashSetContractDataStoreCollection <Address>(),
                                                                                TxPriorityContract.SendersWhitelist,
                                                                                BlockTree,
                                                                                ReceiptStorage,
                                                                                LimboLogs.Instance,
                                                                                GetWhitelistLocalDataStore());

                return(txPoolTxSource);
            }
Esempio n. 5
0
        protected virtual ITxSource CreateTxSourceForProducer(
            ReadOnlyTxProcessingEnv processingEnv,
            ReadOnlyTxProcessorSource readOnlyTxProcessorSource)
        {
            ITxSource innerSource = new TxPoolTxSource(_api.TxPool, processingEnv.StateReader, _api.LogManager);

            return(new FilteredTxSource(innerSource, CreateGasPriceTxFilter(readOnlyTxProcessorSource)));
        }
            protected override TxPoolTxSource CreateTxPoolTxSource()
            {
                TxPoolTxSource txPoolTxSource = base.CreateTxPoolTxSource();

                TxPriorityContract = new TxPriorityContract(new AbiEncoder(), TestItem.AddressA,
                                                            new ReadOnlyTxProcessorSource(DbProvider, BlockTree, SpecProvider, LimboLogs.Instance));

                var comparer = TxPriorityContract.DestinationMethodComparer.Instance;

                Priorities       = new SortedListContractDataStore <TxPriorityContract.Destination>(TxPriorityContract.Priorities, BlockProcessor, comparer);
                MinGasPrices     = new DictionaryContractDataStore <TxPriorityContract.Destination>(TxPriorityContract.MinGasPrices, BlockProcessor, comparer);
                SendersWhitelist = new HashSetContractDataStore <Address>(TxPriorityContract.SendersWhitelist, BlockProcessor);
                return(txPoolTxSource);
            }
            protected override IBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolTxSource, ISealer sealer,
                                                                      ITransactionComparerProvider transactionComparerProvider)
            {
                MiningConfig miningConfig = new() { MinGasPrice = UInt256.One };

                SpecProvider.UpdateMergeTransitionInfo(1, 0);

                BlockProducerEnvFactory blockProducerEnvFactory = new BlockProducerEnvFactory(
                    DbProvider,
                    BlockTree,
                    ReadOnlyTrieStore,
                    SpecProvider,
                    BlockValidator,
                    NoBlockRewards.Instance,
                    ReceiptStorage,
                    BlockPreprocessorStep,
                    TxPool,
                    transactionComparerProvider,
                    miningConfig,
                    LogManager)
                {
                    TransactionsExecutorFactory =
                        new AABlockProducerTransactionsExecutorFactory(
                            SpecProvider,
                            LogManager,
                            Signer,
                            EntryPointAddresses)
                };

                UserOperationTxSource = new(UserOperationTxBuilder, UserOperationPool, UserOperationSimulator, SpecProvider, State, Signer, LogManager.GetClassLogger());

                PostMergeBlockProducer CreatePostMergeBlockProducer(IBlockProductionTrigger blockProductionTrigger,
                                                                    ITxSource?txSource = null)
                {
                    var blockProducerEnv = blockProducerEnvFactory.Create(txSource);

                    return(new PostMergeBlockProducerFactory(SpecProvider, SealEngine, Timestamper, miningConfig,
                                                             LogManager, GasLimitCalculator).Create(
                               blockProducerEnv, blockProductionTrigger));
                }

                IBlockProducer blockProducer =
                    CreatePostMergeBlockProducer(BlockProductionTrigger, UserOperationTxSource);

                blockProducer.BlockProduced += OnBlockProduced;

                return(blockProducer);
            }
            protected override IBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolTxSource, ISealer sealer, ITransactionComparerProvider transactionComparerProvider)
            {
                SealEngine = new MergeSealEngine(SealEngine, PoSSwitcher, SealValidator, LogManager);
                IBlockProducer preMergeBlockProducer =
                    base.CreateTestBlockProducer(txPoolTxSource, sealer, transactionComparerProvider);
                MiningConfig miningConfig = new() { Enabled = true, MinGasPrice = 0 };
                TargetAdjustedGasLimitCalculator targetAdjustedGasLimitCalculator = new(SpecProvider, miningConfig);

                EthSyncingInfo = new EthSyncingInfo(BlockTree);
                PostMergeBlockProducerFactory?blockProducerFactory = new(
                    SpecProvider,
                    SealEngine,
                    Timestamper,
                    miningConfig,
                    LogManager,
                    targetAdjustedGasLimitCalculator);

                BlockProducerEnvFactory blockProducerEnvFactory = new(
                    DbProvider,
                    BlockTree,
                    ReadOnlyTrieStore,
                    SpecProvider,
                    BlockValidator,
                    NoBlockRewards.Instance,
                    ReceiptStorage,
                    BlockPreprocessorStep,
                    TxPool,
                    transactionComparerProvider,
                    miningConfig,
                    LogManager);


                BlockProducerEnv       blockProducerEnv       = blockProducerEnvFactory.Create();
                PostMergeBlockProducer?postMergeBlockProducer = blockProducerFactory.Create(
                    blockProducerEnv, BlockProductionTrigger);

                PostMergeBlockProducer = postMergeBlockProducer;
                PayloadPreparationService ??= new PayloadPreparationService(
                    postMergeBlockProducer,
                    new BlockImprovementContextFactory(BlockProductionTrigger, TimeSpan.FromSeconds(MergeConfig.SecondsPerSlot)),
                    TimerFactory.Default,
                    LogManager,
                    TimeSpan.FromSeconds(MergeConfig.SecondsPerSlot));
                return(new MergeBlockProducer(preMergeBlockProducer, postMergeBlockProducer, PoSSwitcher));
            }
 protected override ITestBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolTxSource, BlockchainProcessor chainProcessor, IStateProvider producerStateProvider, ISealer sealer)
 {
     return((ITestBlockProducer) new Eth2TestBlockProducerFactory().Create(
                BlockTree,
                DbProvider,
                ReadOnlyTrieStore,
                new RecoverSignatures(new EthereumEcdsa(SpecProvider.ChainId, LogManager), TxPool, SpecProvider, LogManager),
                TxPool,
                new BlockValidator(
                    new TxValidator(SpecProvider.ChainId),
                    new HeaderValidator(BlockTree, new Eth2SealEngine(Signer), SpecProvider, LogManager),
                    Always.Valid,
                    SpecProvider,
                    LogManager),
                NoBlockRewards.Instance,
                ReceiptStorage,
                BlockProcessingQueue,
                SpecProvider,
                Signer,
                new MiningConfig(),
                LogManager));
 }
Esempio n. 10
0
        private SyncTestContext CreateSyncManager(int index)
        {
            var logManager            = NoErrorLimboLogs.Instance;
            ConsoleAsyncLogger logger = new ConsoleAsyncLogger(LogLevel.Debug, "PEER " + index + " ");
//            var logManager = new OneLoggerLogManager(logger);
            var specProvider = new SingleReleaseSpecProvider(ConstantinopleFix.Instance, MainnetSpecProvider.Instance.ChainId);

            var             dbProvider  = TestMemDbProvider.Init();
            IDb             blockDb     = dbProvider.BlocksDb;
            IDb             headerDb    = dbProvider.HeadersDb;
            IDb             blockInfoDb = dbProvider.BlockInfosDb;
            ISnapshotableDb codeDb      = dbProvider.CodeDb;
            ISnapshotableDb stateDb     = dbProvider.StateDb;

            var stateReader   = new StateReader(stateDb, codeDb, logManager);
            var stateProvider = new StateProvider(stateDb, codeDb, logManager);

            stateProvider.CreateAccount(TestItem.AddressA, 10000.Ether());
            stateProvider.Commit(specProvider.GenesisSpec);
            stateProvider.CommitTree();
            stateProvider.RecalculateStateRoot();
            stateDb.Commit();

            var storageProvider = new StorageProvider(stateDb, stateProvider, logManager);
            var receiptStorage  = new InMemoryReceiptStorage();

            var ecdsa             = new EthereumEcdsa(specProvider.ChainId, logManager);
            var txPool            = new TxPool.TxPool(new InMemoryTxStorage(), ecdsa, specProvider, new TxPoolConfig(), stateProvider, logManager);
            var tree              = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, NullBloomStorage.Instance, logManager);
            var blockhashProvider = new BlockhashProvider(tree, LimboLogs.Instance);
            var virtualMachine    = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, specProvider, logManager);

            var sealValidator   = Always.Valid;
            var headerValidator = new HeaderValidator(tree, sealValidator, specProvider, logManager);
            var txValidator     = Always.Valid;
            var ommersValidator = new OmmersValidator(tree, headerValidator, logManager);
            var blockValidator  = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, logManager);

            ISyncConfig syncConfig = _synchronizerType == SynchronizerType.Fast ? SyncConfig.WithFastSync : SyncConfig.WithFullSyncOnly;

            var rewardCalculator = new RewardCalculator(specProvider);
            var txProcessor      = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, logManager);
            var blockProcessor   = new BlockProcessor(specProvider, blockValidator, rewardCalculator, txProcessor, stateDb, codeDb, stateProvider, storageProvider, txPool, receiptStorage, logManager);

            var step      = new RecoverSignatures(ecdsa, txPool, specProvider, logManager);
            var processor = new BlockchainProcessor(tree, blockProcessor, step, logManager, BlockchainProcessor.Options.Default);

            var nodeStatsManager = new NodeStatsManager(logManager);
            var syncPeerPool     = new SyncPeerPool(tree, nodeStatsManager, 25, logManager);

            StateProvider   devState            = new StateProvider(stateDb, codeDb, logManager);
            StorageProvider devStorage          = new StorageProvider(stateDb, devState, logManager);
            var             devEvm              = new VirtualMachine(devState, devStorage, blockhashProvider, specProvider, logManager);
            var             devTxProcessor      = new TransactionProcessor(specProvider, devState, devStorage, devEvm, logManager);
            var             devBlockProcessor   = new BlockProcessor(specProvider, blockValidator, rewardCalculator, devTxProcessor, stateDb, codeDb, devState, devStorage, txPool, receiptStorage, logManager);
            var             devChainProcessor   = new BlockchainProcessor(tree, devBlockProcessor, step, logManager, BlockchainProcessor.Options.NoReceipts);
            var             transactionSelector = new TxPoolTxSource(txPool, stateReader, logManager);
            var             producer            = new DevBlockProducer(
                transactionSelector,
                devChainProcessor,
                stateProvider, tree,
                processor,
                txPool,
                Timestamper.Default,
                logManager);

            SyncProgressResolver  resolver     = new SyncProgressResolver(tree, receiptStorage, stateDb, new MemDb(), syncConfig, logManager);
            MultiSyncModeSelector selector     = new MultiSyncModeSelector(resolver, syncPeerPool, syncConfig, logManager);
            Synchronizer          synchronizer = new Synchronizer(
                dbProvider,
                MainnetSpecProvider.Instance,
                tree,
                NullReceiptStorage.Instance,
                blockValidator,
                sealValidator,
                syncPeerPool,
                nodeStatsManager,
                StaticSelector.Full,
                syncConfig,
                logManager);
            var syncServer = new SyncServer(stateDb, codeDb, tree, receiptStorage, Always.Valid, Always.Valid, syncPeerPool, selector, syncConfig, logManager);

            ManualResetEventSlim waitEvent = new ManualResetEventSlim();

            tree.NewHeadBlock += (s, e) => waitEvent.Set();

            if (index == 0)
            {
                _genesis = Build.A.Block.Genesis.WithStateRoot(stateProvider.StateRoot).TestObject;
                producer.Start();
            }

            syncPeerPool.Start();
            synchronizer.Start();
            processor.Start();
            tree.SuggestBlock(_genesis);

            if (!waitEvent.Wait(1000))
            {
                throw new Exception("No genesis");
            }

            SyncTestContext context = new SyncTestContext();

            context.Ecdsa = ecdsa;
            context.BlockchainProcessor = processor;
            context.PeerPool            = syncPeerPool;
            context.StateProvider       = stateProvider;
            context.Synchronizer        = synchronizer;
            context.SyncServer          = syncServer;
            context.Tree          = tree;
            context.BlockProducer = producer;
            context.TxPool        = txPool;
            context.Logger        = logger;
            return(context);
        }
            protected override IBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolTxSource, ISealer sealer,
                                                                      ITransactionComparerProvider transactionComparerProvider)
            {
                MiningConfig miningConfig = new() { MinGasPrice = UInt256.One };

                SpecProvider.UpdateMergeTransitionInfo(1, 0);

                BlockProducerEnvFactory blockProducerEnvFactory = new(
                    DbProvider,
                    BlockTree,
                    ReadOnlyTrieStore,
                    SpecProvider,
                    BlockValidator,
                    NoBlockRewards.Instance,
                    ReceiptStorage,
                    BlockPreprocessorStep,
                    TxPool,
                    transactionComparerProvider,
                    miningConfig,
                    LogManager)
                {
                    TransactionsExecutorFactory =
                        new MevBlockProducerTransactionsExecutorFactory(SpecProvider, LogManager)
                };

                PostMergeBlockProducer CreatePostMergeBlockProducer(IBlockProductionTrigger blockProductionTrigger,
                                                                    ITxSource?txSource = null)
                {
                    BlockProducerEnv blockProducerEnv = blockProducerEnvFactory.Create(txSource);

                    return(new PostMergeBlockProducerFactory(SpecProvider, SealEngine, Timestamper, miningConfig,
                                                             LogManager).Create(
                               blockProducerEnv, blockProductionTrigger, txSource));
                }

                MevBlockProducer.MevBlockProducerInfo CreateProducer(int bundleLimit = 0,
                                                                     ITxSource?additionalTxSource = null)
                {
                    // TODO: this could be simplified a lot of the parent was not retrieved, not sure why do we need the parent here
                    bool BundleLimitTriggerCondition(BlockProductionEventArgs e)
                    {
                        // TODO: why do we need this parent? later we use only the current block number
                        BlockHeader?parent = BlockTree.GetProducedBlockParent(e.ParentHeader);

                        if (parent is not null)
                        {
                            // ToDo resolved conflict parent.Timestamp?
                            IEnumerable <MevBundle> bundles = BundlePool.GetBundles(parent.Number + 1, parent.Timestamp);
                            return(bundles.Count() >= bundleLimit);
                        }

                        return(false);
                    }

                    IManualBlockProductionTrigger manualTrigger = new BuildBlocksWhenRequested();
                    IBlockProductionTrigger       trigger       = manualTrigger;

                    if (bundleLimit != 0)
                    {
                        trigger = new TriggerWithCondition(manualTrigger, BundleLimitTriggerCondition);
                    }

                    IBlockProducer producer = CreatePostMergeBlockProducer(trigger, additionalTxSource);

                    return(new MevBlockProducer.MevBlockProducerInfo(producer, manualTrigger, new BeneficiaryTracer()));
                }

                int megabundleProducerCount = _relayAddresses.Any() ? 1 : 0;
                List <MevBlockProducer.MevBlockProducerInfo> blockProducers =
                    new(_maxMergedBundles + megabundleProducerCount + 1);

                // Add non-mev block
                MevBlockProducer.MevBlockProducerInfo standardProducer = CreateProducer();
                blockProducers.Add(standardProducer);

                // Try blocks with all bundle numbers <= maxMergedBundles
                for (int bundleLimit = 1; bundleLimit <= _maxMergedBundles; bundleLimit++)
                {
                    BundleSelector bundleSelector = new(BundlePool, bundleLimit);
                    BundleTxSource bundleTxSource = new(bundleSelector, Timestamper);
                    MevBlockProducer.MevBlockProducerInfo bundleProducer = CreateProducer(bundleLimit, bundleTxSource);
                    blockProducers.Add(bundleProducer);
                }

                if (megabundleProducerCount > 0)
                {
                    MegabundleSelector megabundleSelector = new(BundlePool);
                    BundleTxSource     megabundleTxSource = new(megabundleSelector, Timestamper);
                    MevBlockProducer.MevBlockProducerInfo bundleProducer = CreateProducer(0, megabundleTxSource);
                    blockProducers.Add(bundleProducer);
                }

                MevBlockProducer blockProducer = new MevBlockProducer(BlockProductionTrigger, LogManager, blockProducers.ToArray());

                blockProducer.BlockProduced += OnBlockProduced;
                return(blockProducer);
            }
Esempio n. 12
0
 protected virtual ITestBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolTxSource, BlockchainProcessor chainProcessor, IStateProvider producerStateProvider, ISealer sealer)
 {
     return(new TestBlockProducer(txPoolTxSource, chainProcessor, producerStateProvider, sealer, BlockTree, chainProcessor, Timestamper, SpecProvider, LogManager));
 }
        protected override IBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolTxSource, ISealer sealer, ITransactionComparerProvider transactionComparerProvider)
        {
            SealEngine = new MergeSealEngine(SealEngine, PoSSwitcher, SealValidator, LogManager);
            MiningConfig miningConfig = new() { Enabled = true, MinGasPrice = 0 };
            TargetAdjustedGasLimitCalculator targetAdjustedGasLimitCalculator = new(SpecProvider, miningConfig);

            EthSyncingInfo = new EthSyncingInfo(BlockTree);
            PostMergeBlockProducerFactory blockProducerFactory = new(
                SpecProvider,
                SealEngine,
                Timestamper,
                miningConfig,
                LogManager,
                targetAdjustedGasLimitCalculator);

            BlockProducerEnvFactory blockProducerEnvFactory = new(
                DbProvider,
                BlockTree,
                ReadOnlyTrieStore,
                SpecProvider,
                BlockValidator,
                NoBlockRewards.Instance,
                ReceiptStorage,
                BlockPreprocessorStep,
                TxPool,
                transactionComparerProvider,
                miningConfig,
                LogManager);


            BlockProducerEnv       blockProducerEnv       = blockProducerEnvFactory.Create();
            PostMergeBlockProducer postMergeBlockProducer = blockProducerFactory.Create(blockProducerEnv, BlockProductionTrigger);

            PostMergeBlockProducer = postMergeBlockProducer;
            PayloadPreparationService ??= new PayloadPreparationService(
                postMergeBlockProducer,
                new BlockImprovementContextFactory(BlockProductionTrigger, TimeSpan.FromSeconds(MergeConfig.SecondsPerSlot)
                                                   ),
                TimerFactory.Default,
                LogManager,
                TimeSpan.FromSeconds(MergeConfig.SecondsPerSlot)
                );

            IAuRaStepCalculator auraStepCalculator = Substitute.For <IAuRaStepCalculator>();

            auraStepCalculator.TimeToNextStep.Returns(TimeSpan.FromMilliseconds(0));
            FollowOtherMiners gasLimitCalculator    = new(MainnetSpecProvider.Instance);
            AuRaBlockProducer preMergeBlockProducer = new(
                txPoolTxSource,
                blockProducerEnvFactory.Create().ChainProcessor,
                ((TestBlockchain)this).BlockProductionTrigger,
                State,
                sealer,
                BlockTree,
                Timestamper,
                auraStepCalculator,
                NullReportingValidator.Instance,
                new AuRaConfig(),
                gasLimitCalculator,
                SpecProvider,
                LogManager
                );

            return(new MergeBlockProducer(preMergeBlockProducer, postMergeBlockProducer, PoSSwitcher));
        }
    }
        // It takes dotCover to run it quite long, increased timeouts
        public async Task Can_process_mined_blocks()
        {
            int timeMultiplier = 1; // for debugging

            TimeSpan miningDelay = TimeSpan.FromMilliseconds(200 * timeMultiplier);

            /* logging & instrumentation */
//            OneLoggerLogManager logger = new OneLoggerLogManager(new SimpleConsoleLogger(true));
            ILogManager logManager = LimboLogs.Instance;
            ILogger     logger     = logManager.GetClassLogger();

            /* spec */
            FakeSealer sealer = new FakeSealer(miningDelay);

            RopstenSpecProvider specProvider = RopstenSpecProvider.Instance;

            /* state & storage */
            StateDb         codeDb          = new StateDb();
            StateDb         stateDb         = new StateDb();
            StateProvider   stateProvider   = new StateProvider(stateDb, codeDb, logManager);
            StorageProvider storageProvider = new StorageProvider(stateDb, stateProvider, logManager);
            StateReader     stateReader     = new StateReader(stateDb, codeDb, logManager);

            /* store & validation */

            EthereumEcdsa ecdsa = new EthereumEcdsa(specProvider, logManager);
            MemColumnsDb <ReceiptsColumns> receiptsDb = new MemColumnsDb <ReceiptsColumns>();

            TxPool.TxPool        txPool               = new TxPool.TxPool(NullTxStorage.Instance, Timestamper.Default, ecdsa, specProvider, new TxPoolConfig(), stateProvider, logManager);
            IReceiptStorage      receiptStorage       = new PersistentReceiptStorage(receiptsDb, specProvider, new ReceiptsRecovery());
            var                  blockInfoDb          = new MemDb();
            BlockTree            blockTree            = new BlockTree(new MemDb(), new MemDb(), blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, txPool, NullBloomStorage.Instance, logManager);
            Timestamper          timestamper          = new Timestamper();
            DifficultyCalculator difficultyCalculator = new DifficultyCalculator(specProvider);
            HeaderValidator      headerValidator      = new HeaderValidator(blockTree, sealer, specProvider, logManager);
            OmmersValidator      ommersValidator      = new OmmersValidator(blockTree, headerValidator, logManager);
            TxValidator          txValidator          = new TxValidator(ChainId.Ropsten);
            BlockValidator       blockValidator       = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, logManager);

            TestTransactionsGenerator generator = new TestTransactionsGenerator(txPool, ecdsa, TimeSpan.FromMilliseconds(50 * timeMultiplier), LimboLogs.Instance);

            generator.Start();

            /* blockchain processing */
            BlockhashProvider    blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance);
            VirtualMachine       virtualMachine    = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, specProvider, logManager);
            TransactionProcessor processor         = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, logManager);
            RewardCalculator     rewardCalculator  = new RewardCalculator(specProvider);
            BlockProcessor       blockProcessor    = new BlockProcessor(specProvider, blockValidator, rewardCalculator,
                                                                        processor, stateDb, codeDb, stateProvider, storageProvider, txPool, receiptStorage, logManager);
            BlockchainProcessor blockchainProcessor = new BlockchainProcessor(blockTree, blockProcessor, new TxSignaturesRecoveryStep(ecdsa, NullTxPool.Instance, LimboLogs.Instance), logManager, false);

            /* load ChainSpec and init */
            ChainSpecLoader loader = new ChainSpecLoader(new EthereumJsonSerializer());
            string          path   = "chainspec.json";

            logManager.GetClassLogger().Info($"Loading ChainSpec from {path}");
            ChainSpec chainSpec = loader.Load(File.ReadAllText(path));

            foreach (var allocation in chainSpec.Allocations)
            {
                stateProvider.CreateAccount(allocation.Key, allocation.Value.Balance);
                if (allocation.Value.Code != null)
                {
                    Keccak codeHash = stateProvider.UpdateCode(allocation.Value.Code);
                    stateProvider.UpdateCodeHash(allocation.Key, codeHash, specProvider.GenesisSpec);
                }
            }

            stateProvider.Commit(specProvider.GenesisSpec);
            chainSpec.Genesis.Header.StateRoot = stateProvider.StateRoot;
            chainSpec.Genesis.Header.Hash      = chainSpec.Genesis.Header.CalculateHash();
            if (chainSpec.Genesis.Hash != new Keccak("0xafbc3c327d2d18ff2b843e89226ef288fcee379542f854f982e4cfb85916d126"))
            {
                throw new Exception("Unexpected genesis hash");
            }

            /* start processing */
            blockTree.SuggestBlock(chainSpec.Genesis);
            blockchainProcessor.Start();

            var transactionSelector = new TxPoolTxSource(txPool, stateReader, logManager);
            MinedBlockProducer minedBlockProducer = new MinedBlockProducer(transactionSelector, blockchainProcessor, sealer, blockTree, blockchainProcessor, stateProvider, timestamper, LimboLogs.Instance, difficultyCalculator);

            minedBlockProducer.Start();

            ManualResetEventSlim manualResetEvent = new ManualResetEventSlim(false);

            blockTree.NewHeadBlock += (sender, args) =>
            {
                if (args.Block.Number == 6)
                {
                    manualResetEvent.Set();
                }
            };

            manualResetEvent.Wait(miningDelay * 100);
            await minedBlockProducer.StopAsync();

            int previousCount = 0;
            int totalTx       = 0;

            for (int i = 0; i < 6; i++)
            {
                Block block = blockTree.FindBlock(i, BlockTreeLookupOptions.None);
                Assert.That(block, Is.Not.Null, $"Block {i} not produced");
                logger.Info($"Block {i} with {block.Transactions.Length} txs");

                ManualResetEventSlim blockProcessedEvent = new ManualResetEventSlim(false);
                blockchainProcessor.ProcessingQueueEmpty += (sender, args) => blockProcessedEvent.Set();
                blockchainProcessor.Enqueue(block, ProcessingOptions.ForceProcessing | ProcessingOptions.StoreReceipts | ProcessingOptions.ReadOnlyChain);
                blockProcessedEvent.Wait(miningDelay);

                GethStyleTracer gethStyleTracer = new GethStyleTracer(blockchainProcessor, receiptStorage, blockTree);

                int currentCount = receiptsDb.Keys.Count;
                logger.Info($"Current count of receipts {currentCount}");
                logger.Info($"Previous count of receipts {previousCount}");

                if (block.Transactions.Length > 0)
                {
                    Assert.AreNotEqual(previousCount, currentCount, $"receipts at block {i}");
                    totalTx += block.Transactions.Length;
                }

                previousCount = currentCount;
            }

            Assert.AreNotEqual(0, totalTx, "no tx in blocks");
        }
        public void order_is_correct(Func <IEnumerable <Transaction>, IEnumerable <Transaction> > transactionSelect)
        {
            IContractDataStore <Address> sendersWhitelist = Substitute.For <IContractDataStore <Address> >();
            IDictionaryContractDataStore <TxPriorityContract.Destination> priorities = Substitute.For <IDictionaryContractDataStore <TxPriorityContract.Destination> >();
            BlockHeader blockHeader = Build.A.BlockHeader.TestObject;

            byte[] p5Signature = { 0, 1, 2, 3 };
            byte[] p6Signature = { 0, 0, 0, 2 };
            byte[] p0signature = { 0, 0, 0, 1 };
            sendersWhitelist.GetItemsFromContractAtBlock(blockHeader).Returns(WhitelistedSenders);

            SetPriority(priorities, blockHeader, TestItem.AddressB, p5Signature, 5);
            SetPriority(priorities, blockHeader, TestItem.AddressB, p6Signature, 6);

            Transaction A_B_0_10_10_P6 = Build.A.NamedTransaction(nameof(A_B_0_10_10_P6))
                                         .WithSenderAddress(TestItem.AddressA)
                                         .To(TestItem.AddressB)
                                         .WithNonce(0)
                                         .WithGasPrice(10)
                                         .WithGasLimit(10)
                                         .WithData(p6Signature)
                                         .TestObject;

            Transaction A_B_0_10_20_P6 = Build.A.NamedTransaction(nameof(A_B_0_10_20_P6))
                                         .WithSenderAddress(TestItem.AddressA)
                                         .To(TestItem.AddressB)
                                         .WithNonce(0)
                                         .WithGasPrice(10)
                                         .WithGasLimit(20)
                                         .WithData(p6Signature)
                                         .TestObject;

            Transaction A_B_0_10_5_P6 = Build.A.NamedTransaction(nameof(A_B_0_10_5_P6))
                                        .WithSenderAddress(TestItem.AddressA)
                                        .To(TestItem.AddressB)
                                        .WithNonce(0)
                                        .WithGasPrice(10)
                                        .WithGasLimit(5)
                                        .WithData(p6Signature)
                                        .TestObject;

            Transaction A_B_0_10_10_P5 = Build.A.NamedTransaction(nameof(A_B_0_10_10_P5))
                                         .WithSenderAddress(TestItem.AddressA)
                                         .To(TestItem.AddressB)
                                         .WithNonce(0)
                                         .WithGasPrice(10)
                                         .WithGasLimit(10)
                                         .WithData(p5Signature)
                                         .TestObject;

            Transaction A_B_0_20_10_P5 = Build.A.NamedTransaction(nameof(A_B_0_20_10_P5))
                                         .WithSenderAddress(TestItem.AddressA)
                                         .To(TestItem.AddressB)
                                         .WithNonce(0)
                                         .WithGasPrice(20)
                                         .WithGasLimit(10)
                                         .WithData(p5Signature)
                                         .TestObject;

            Transaction A_B_1_20_10_P5 = Build.A.NamedTransaction(nameof(A_B_1_20_10_P5))
                                         .WithSenderAddress(TestItem.AddressA)
                                         .To(TestItem.AddressB)
                                         .WithNonce(1)
                                         .WithGasPrice(20)
                                         .WithGasLimit(10)
                                         .WithData(p5Signature)
                                         .TestObject;

            Transaction A_B_1_200_10_P0 = Build.A.NamedTransaction(nameof(A_B_1_200_10_P0))
                                          .WithSenderAddress(TestItem.AddressA)
                                          .To(TestItem.AddressB)
                                          .WithNonce(1)
                                          .WithGasPrice(200)
                                          .WithGasLimit(10)
                                          .WithData(p0signature)
                                          .TestObject;

            Transaction A_A_0_100_100_P0 = Build.A.NamedTransaction(nameof(A_A_0_100_100_P0))
                                           .WithSenderAddress(TestItem.AddressA)
                                           .To(TestItem.AddressA)
                                           .WithNonce(0)
                                           .WithGasPrice(100)
                                           .WithGasLimit(100)
                                           .WithData(p5Signature)
                                           .TestObject;

            Transaction A_A_1_100_100_P0 = Build.A.NamedTransaction(nameof(A_A_1_100_100_P0))
                                           .WithSenderAddress(TestItem.AddressA)
                                           .To(TestItem.AddressA)
                                           .WithNonce(1)
                                           .WithGasPrice(100)
                                           .WithGasLimit(100)
                                           .WithData(p5Signature)
                                           .TestObject;

            Transaction A_A_1_1000_1000_P0 = Build.A.NamedTransaction(nameof(A_A_1_1000_1000_P0))
                                             .WithSenderAddress(TestItem.AddressA)
                                             .To(TestItem.AddressA)
                                             .WithNonce(1)
                                             .WithGasPrice(1000)
                                             .WithGasLimit(1000)
                                             .WithData(p5Signature)
                                             .TestObject;

            Transaction A_A_2_1000_1_P0 = Build.A.NamedTransaction(nameof(A_A_2_1000_1_P0))
                                          .WithSenderAddress(TestItem.AddressA)
                                          .To(TestItem.AddressA)
                                          .WithNonce(2)
                                          .WithGasPrice(1000)
                                          .WithGasLimit(1)
                                          .WithData(p5Signature)
                                          .TestObject;

            Transaction B_B_2_1000_1_P6 = Build.A.NamedTransaction(nameof(B_B_2_1000_1_P6))
                                          .WithSenderAddress(TestItem.AddressB)
                                          .To(TestItem.AddressB)
                                          .WithNonce(2)
                                          .WithGasPrice(1000)
                                          .WithGasLimit(1)
                                          .WithData(p6Signature)
                                          .TestObject;

            Transaction B_B_2_15_1_P5 = Build.A.NamedTransaction(nameof(B_B_2_15_1_P5))
                                        .WithSenderAddress(TestItem.AddressB)
                                        .To(TestItem.AddressB)
                                        .WithNonce(2)
                                        .WithGasPrice(15)
                                        .WithGasLimit(1)
                                        .WithData(p5Signature)
                                        .TestObject;

            Transaction B_B_3_15_1_P6 = Build.A.NamedTransaction(nameof(B_B_3_15_1_P6))
                                        .WithSenderAddress(TestItem.AddressB)
                                        .To(TestItem.AddressB)
                                        .WithNonce(3)
                                        .WithGasPrice(15)
                                        .WithGasLimit(1)
                                        .WithData(p6Signature)
                                        .TestObject;

            Transaction C_B_3_10_1_P6_W = Build.A.NamedTransaction(nameof(C_B_3_10_1_P6_W))
                                          .WithSenderAddress(TestItem.AddressC)
                                          .To(TestItem.AddressB)
                                          .WithNonce(3)
                                          .WithGasPrice(10)
                                          .WithGasLimit(1)
                                          .WithData(p6Signature)
                                          .TestObject;

            Transaction C_B_4_10_1_P0_W = Build.A.NamedTransaction(nameof(C_B_4_10_1_P0_W))
                                          .WithSenderAddress(TestItem.AddressC)
                                          .To(TestItem.AddressB)
                                          .WithNonce(4)
                                          .WithGasPrice(10)
                                          .WithGasLimit(1)
                                          .TestObject;

            Transaction D_B_4_100_1_P0_W = Build.A.NamedTransaction(nameof(D_B_4_100_1_P0_W))
                                           .WithSenderAddress(TestItem.AddressD)
                                           .To(TestItem.AddressB)
                                           .WithNonce(4)
                                           .WithGasPrice(100)
                                           .WithGasLimit(1)
                                           .TestObject;

            IEnumerable <Transaction> transactions = new []
            {
                A_B_1_200_10_P0,
                A_A_2_1000_1_P0,
                A_A_1_1000_1000_P0,
                C_B_4_10_1_P0_W,
                A_A_1_100_100_P0,
                A_A_0_100_100_P0,
                A_B_0_10_10_P5,
                D_B_4_100_1_P0_W,
                C_B_3_10_1_P6_W,
                A_B_0_10_10_P6,
                A_B_0_20_10_P5,
                B_B_2_15_1_P5,
                A_B_0_10_5_P6,
                B_B_3_15_1_P6,
                A_B_0_10_20_P6,
                A_B_1_20_10_P5,
                B_B_2_1000_1_P6
            };

            IEnumerable <Transaction> expectation = new []
            {
                C_B_3_10_1_P6_W,
                D_B_4_100_1_P0_W,
                C_B_4_10_1_P0_W,
                B_B_2_1000_1_P6,
                A_B_0_10_5_P6,
                A_B_0_10_10_P6,
                A_B_0_10_20_P6,
                A_B_0_20_10_P5,
                B_B_2_15_1_P5,
                B_B_3_15_1_P6,
                A_B_0_10_10_P5,
                A_A_0_100_100_P0,
                A_B_1_20_10_P5,
                A_A_1_1000_1000_P0,
                A_B_1_200_10_P0,
                A_A_1_100_100_P0,
                A_A_2_1000_1_P0
            };

            transactions = transactionSelect?.Invoke(transactions) ?? transactions;
            expectation  = transactionSelect?.Invoke(expectation) ?? expectation;

            IBlockTree blockTree = Substitute.For <IBlockTree>();
            Block      block     = Build.A.Block.WithNumber(0).TestObject;

            blockTree.Head.Returns(block);
            ISpecProvider specProvider = Substitute.For <ISpecProvider>();

            specProvider.GetSpec(Arg.Any <long>()).Returns(new ReleaseSpec()
            {
                IsEip1559Enabled = false
            });
            TransactionComparerProvider transactionComparerProvider = new(specProvider, blockTree);
            IComparer <Transaction>     defaultComparer             = transactionComparerProvider.GetDefaultComparer();
            IComparer <Transaction>     comparer = new CompareTxByPriorityOnSpecifiedBlock(sendersWhitelist, priorities, blockHeader)
                                                   .ThenBy(defaultComparer);


            Dictionary <Address?, Transaction[]> txBySender = transactions.GroupBy(t => t.SenderAddress)
                                                              .ToDictionary(
                g => g.Key,
                g => g.OrderBy(t => t,
                               // to simulate order coming from TxPool
                               comparer.GetPoolUniqueTxComparerByNonce()).ToArray());


            Transaction[] orderedTransactions = TxPoolTxSource.Order(txBySender, comparer).ToArray();
            orderedTransactions.Should().BeEquivalentTo(expectation, o => o.WithStrictOrdering());
        }
            protected override IBlockProducer CreateTestBlockProducer(TxPoolTxSource txPoolTxSource, ISealer sealer, ITransactionComparerProvider transactionComparerProvider)
            {
                MiningConfig miningConfig = new() { MinGasPrice = UInt256.One };

                BlockProducerEnvFactory blockProducerEnvFactory = new(
                    DbProvider,
                    BlockTree,
                    ReadOnlyTrieStore,
                    SpecProvider,
                    BlockValidator,
                    NoBlockRewards.Instance,
                    ReceiptStorage,
                    BlockPreprocessorStep,
                    TxPool,
                    transactionComparerProvider,
                    miningConfig,
                    LogManager)
                {
                    TransactionsExecutorFactory = new MevBlockProducerTransactionsExecutorFactory(SpecProvider, LogManager)
                };

                Eth2BlockProducer CreateEth2BlockProducer(IBlockProductionTrigger blockProductionTrigger, ITxSource?txSource = null) =>
                new Eth2TestBlockProducerFactory(GasLimitCalculator, txSource).Create(
                    blockProducerEnvFactory,
                    BlockTree,
                    blockProductionTrigger,
                    SpecProvider,
                    Signer,
                    Timestamper,
                    miningConfig,
                    LogManager);

                MevBlockProducer.MevBlockProducerInfo CreateProducer(int bundleLimit = 0, ITxSource?additionalTxSource = null)
                {
                    bool BundleLimitTriggerCondition(BlockProductionEventArgs e)
                    {
                        BlockHeader?parent = BlockTree.GetProducedBlockParent(e.ParentHeader);

                        if (parent is not null)
                        {
                            IEnumerable <MevBundle> bundles = BundlePool.GetBundles(parent, Timestamper);
                            return(bundles.Count() >= bundleLimit);
                        }

                        return(false);
                    }

                    IManualBlockProductionTrigger manualTrigger = new BuildBlocksWhenRequested();
                    IBlockProductionTrigger       trigger       = manualTrigger;

                    if (bundleLimit != 0)
                    {
                        trigger = new TriggerWithCondition(manualTrigger, BundleLimitTriggerCondition);
                    }

                    IBlockProducer producer = CreateEth2BlockProducer(trigger, additionalTxSource);

                    return(new MevBlockProducer.MevBlockProducerInfo(producer, manualTrigger, new BeneficiaryTracer()));
                }

                int megabundleProducerCount = _relayAddresses.Any() ? 1 : 0;
                List <MevBlockProducer.MevBlockProducerInfo> blockProducers =
                    new(_maxMergedBundles + megabundleProducerCount + 1);

                // Add non-mev block
                MevBlockProducer.MevBlockProducerInfo standardProducer = CreateProducer();
                blockProducers.Add(standardProducer);

                // Try blocks with all bundle numbers <= maxMergedBundles
                for (int bundleLimit = 1; bundleLimit <= _maxMergedBundles; bundleLimit++)
                {
                    BundleSelector bundleSelector = new(BundlePool, bundleLimit);
                    BundleTxSource bundleTxSource = new(bundleSelector, Timestamper);
                    MevBlockProducer.MevBlockProducerInfo bundleProducer = CreateProducer(bundleLimit, bundleTxSource);
                    blockProducers.Add(bundleProducer);
                }

                if (megabundleProducerCount > 0)
                {
                    MegabundleSelector megabundleSelector = new(BundlePool);
                    BundleTxSource     megabundleTxSource = new(megabundleSelector, Timestamper);
                    MevBlockProducer.MevBlockProducerInfo bundleProducer = CreateProducer(0, megabundleTxSource);
                    blockProducers.Add(bundleProducer);
                }

                return(new MevBlockProducer(BlockProductionTrigger, LogManager, blockProducers.ToArray()));
            }
            public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = false)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"CREATING NODE {privateKey.Address}");
                }
                _logManagers[privateKey] = LimboLogs.Instance;
//                _logManagers[privateKey] = new OneLoggerLogManager(new ConsoleAsyncLogger(LogLevel.Debug, $"{privateKey.Address} "));
                var nodeLogManager = _logManagers[privateKey];

                AutoResetEvent newHeadBlockEvent = new AutoResetEvent(false);

                _blockEvents.Add(privateKey, newHeadBlockEvent);

                MemDb blocksDb    = new MemDb();
                MemDb headersDb   = new MemDb();
                MemDb blockInfoDb = new MemDb();

                ISnapshotableDb stateDb = new StateDb();
                ISnapshotableDb codeDb  = new StateDb();

                ISpecProvider specProvider = RinkebySpecProvider.Instance;

                StateReader   stateReader   = new StateReader(stateDb, codeDb, nodeLogManager);
                StateProvider stateProvider = new StateProvider(stateDb, codeDb, nodeLogManager);

                stateProvider.CreateAccount(TestItem.PrivateKeyD.Address, 100.Ether());
                stateProvider.Commit(GoerliSpecProvider.Instance.GenesisSpec);
                stateProvider.CommitTree();

                TxPool.TxPool txPool = new TxPool.TxPool(new InMemoryTxStorage(), _timestamper, _ethereumEcdsa, GoerliSpecProvider.Instance, new TxPoolConfig(), stateProvider, _logManager);
                _pools[privateKey] = txPool;

                BlockTree blockTree = new BlockTree(blocksDb, headersDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), GoerliSpecProvider.Instance, txPool, NullBloomStorage.Instance, nodeLogManager);

                blockTree.NewHeadBlock += (sender, args) => { _blockEvents[privateKey].Set(); };

                BlockhashProvider blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance);

                _blockTrees.Add(privateKey, blockTree);

                IBasicWallet    wallet          = new BasicWallet(privateKey);
                SnapshotManager snapshotManager = new SnapshotManager(_cliqueConfig, blocksDb, blockTree, _ethereumEcdsa, nodeLogManager);

                _snapshotManager[privateKey] = snapshotManager;
                CliqueSealer cliqueSealer = new CliqueSealer(wallet, _cliqueConfig, snapshotManager, privateKey.Address, nodeLogManager);



                _genesis.Header.StateRoot       = _genesis3Validators.Header.StateRoot = stateProvider.StateRoot;
                _genesis.Header.Hash            = _genesis.Header.CalculateHash();
                _genesis3Validators.Header.Hash = _genesis3Validators.Header.CalculateHash();

                StorageProvider      storageProvider      = new StorageProvider(stateDb, stateProvider, nodeLogManager);
                TransactionProcessor transactionProcessor = new TransactionProcessor(GoerliSpecProvider.Instance, stateProvider, storageProvider, new VirtualMachine(stateProvider, storageProvider, blockhashProvider, specProvider, nodeLogManager), nodeLogManager);
                BlockProcessor       blockProcessor       = new BlockProcessor(GoerliSpecProvider.Instance, Always.Valid, NoBlockRewards.Instance, transactionProcessor, stateDb, codeDb, stateProvider, storageProvider, txPool, NullReceiptStorage.Instance, nodeLogManager);
                BlockchainProcessor  processor            = new BlockchainProcessor(blockTree, blockProcessor, new AuthorRecoveryStep(snapshotManager), nodeLogManager, false);

                processor.Start();

                StateProvider        minerStateProvider        = new StateProvider(stateDb, codeDb, nodeLogManager);
                StorageProvider      minerStorageProvider      = new StorageProvider(stateDb, minerStateProvider, nodeLogManager);
                VirtualMachine       minerVirtualMachine       = new VirtualMachine(minerStateProvider, minerStorageProvider, blockhashProvider, specProvider, nodeLogManager);
                TransactionProcessor minerTransactionProcessor = new TransactionProcessor(GoerliSpecProvider.Instance, minerStateProvider, minerStorageProvider, minerVirtualMachine, nodeLogManager);
                BlockProcessor       minerBlockProcessor       = new BlockProcessor(GoerliSpecProvider.Instance, Always.Valid, NoBlockRewards.Instance, minerTransactionProcessor, stateDb, codeDb, minerStateProvider, minerStorageProvider, txPool, NullReceiptStorage.Instance, nodeLogManager);
                BlockchainProcessor  minerProcessor            = new BlockchainProcessor(blockTree, minerBlockProcessor, new AuthorRecoveryStep(snapshotManager), nodeLogManager, false);

                if (withGenesisAlreadyProcessed)
                {
                    ProcessGenesis(privateKey);
                }

                TxPoolTxSource      txPoolTxSource = new TxPoolTxSource(txPool, stateReader, nodeLogManager);
                CliqueBlockProducer blockProducer  = new CliqueBlockProducer(txPoolTxSource, minerProcessor, minerStateProvider, blockTree, _timestamper, new CryptoRandom(), snapshotManager, cliqueSealer, privateKey.Address, _cliqueConfig, nodeLogManager);

                blockProducer.Start();

                _producers.Add(privateKey, blockProducer);

                return(this);
            }
Esempio n. 18
0
        public Task InitBlockProducer()
        {
            if (_nethermindApi !.SealEngineType != SealEngineType.Clique)
            {
                return(Task.CompletedTask);
            }

            var(getFromApi, setInApi) = _nethermindApi !.ForProducer;

            _miningConfig = getFromApi.Config <IMiningConfig>();
            if (!_miningConfig.Enabled)
            {
                throw new InvalidOperationException("Request to start block producer while mining disabled.");
            }

            setInApi.Sealer = new CliqueSealer(
                getFromApi.EngineSigner !,
                _cliqueConfig !,
                _snapshotManager !,
                getFromApi.LogManager);

            ReadOnlyDbProvider readOnlyDbProvider = getFromApi.DbProvider.AsReadOnly(false);
            ReadOnlyBlockTree  readOnlyBlockTree  = getFromApi.BlockTree.AsReadOnly();

            ReadOnlyTxProcessingEnv producerEnv = new ReadOnlyTxProcessingEnv(
                readOnlyDbProvider,
                getFromApi.ReadOnlyTrieStore,
                readOnlyBlockTree,
                getFromApi.SpecProvider,
                getFromApi.LogManager);

            BlockProcessor producerProcessor = new BlockProcessor(
                getFromApi !.SpecProvider,
                getFromApi !.BlockValidator,
                NoBlockRewards.Instance,
                producerEnv.TransactionProcessor,
                producerEnv.StateProvider,
                producerEnv.StorageProvider,
                NullTxPool.Instance, // do not remove transactions from the pool when preprocessing
                NullReceiptStorage.Instance,
                NullWitnessCollector.Instance,
                getFromApi.LogManager);

            IBlockchainProcessor producerChainProcessor = new BlockchainProcessor(
                readOnlyBlockTree,
                producerProcessor,
                getFromApi.BlockPreprocessor,
                getFromApi.LogManager,
                BlockchainProcessor.Options.NoReceipts);

            OneTimeChainProcessor chainProcessor = new OneTimeChainProcessor(
                readOnlyDbProvider,
                producerChainProcessor);

            ITxFilter txFilter = new MinGasPriceTxFilter(_miningConfig !.MinGasPrice);
            ITxSource txSource = new TxPoolTxSource(
                getFromApi.TxPool,
                getFromApi.StateReader,
                getFromApi.LogManager,
                txFilter);

            var gasLimitCalculator = new TargetAdjustedGasLimitCalculator(getFromApi.SpecProvider, _miningConfig);

            setInApi.BlockProducer = new CliqueBlockProducer(
                txSource,
                chainProcessor,
                producerEnv.StateProvider,
                getFromApi.BlockTree !,
                getFromApi.Timestamper,
                getFromApi.CryptoRandom,
                _snapshotManager !,
                getFromApi.Sealer !,
                gasLimitCalculator,
                getFromApi.SpecProvider,
                _cliqueConfig !,
                getFromApi.LogManager);

            return(Task.CompletedTask);
        }
        public void order_is_correct(Func <IEnumerable <Transaction>, IEnumerable <Transaction> > transactionSelect)
        {
            var sendersWhitelist = Substitute.For <IContractDataStore <Address> >();
            var priorities       = Substitute.For <IDictionaryContractDataStore <TxPriorityContract.Destination> >();
            var blockHeader      = Build.A.BlockHeader.TestObject;

            byte[] p5Signature = { 0, 1, 2, 3 };
            byte[] p6Signature = { 0, 0, 0, 2 };
            byte[] p0signature = { 0, 0, 0, 1 };
            sendersWhitelist.GetItemsFromContractAtBlock(blockHeader).Returns(WhitelistedSenders);

            SetPriority(priorities, blockHeader, TestItem.AddressB, p5Signature, 5);
            SetPriority(priorities, blockHeader, TestItem.AddressB, p6Signature, 6);

            Transaction A_B_0_10_10_P6 = Build.A.NamedTransaction(nameof(A_B_0_10_10_P6))
                                         .WithSenderAddress(TestItem.AddressA)
                                         .To(TestItem.AddressB)
                                         .WithNonce(0)
                                         .WithGasPrice(10)
                                         .WithGasLimit(10)
                                         .WithData(p6Signature)
                                         .TestObject;

            Transaction A_B_0_10_20_P6 = Build.A.NamedTransaction(nameof(A_B_0_10_20_P6))
                                         .WithSenderAddress(TestItem.AddressA)
                                         .To(TestItem.AddressB)
                                         .WithNonce(0)
                                         .WithGasPrice(10)
                                         .WithGasLimit(20)
                                         .WithData(p6Signature)
                                         .TestObject;

            Transaction A_B_0_10_5_P6 = Build.A.NamedTransaction(nameof(A_B_0_10_5_P6))
                                        .WithSenderAddress(TestItem.AddressA)
                                        .To(TestItem.AddressB)
                                        .WithNonce(0)
                                        .WithGasPrice(10)
                                        .WithGasLimit(5)
                                        .WithData(p6Signature)
                                        .TestObject;

            Transaction A_B_0_10_10_P5 = Build.A.NamedTransaction(nameof(A_B_0_10_10_P5))
                                         .WithSenderAddress(TestItem.AddressA)
                                         .To(TestItem.AddressB)
                                         .WithNonce(0)
                                         .WithGasPrice(10)
                                         .WithGasLimit(10)
                                         .WithData(p5Signature)
                                         .TestObject;

            Transaction A_B_0_20_10_P5 = Build.A.NamedTransaction(nameof(A_B_0_20_10_P5))
                                         .WithSenderAddress(TestItem.AddressA)
                                         .To(TestItem.AddressB)
                                         .WithNonce(0)
                                         .WithGasPrice(20)
                                         .WithGasLimit(10)
                                         .WithData(p5Signature)
                                         .TestObject;

            Transaction A_B_1_20_10_P5 = Build.A.NamedTransaction(nameof(A_B_1_20_10_P5))
                                         .WithSenderAddress(TestItem.AddressA)
                                         .To(TestItem.AddressB)
                                         .WithNonce(1)
                                         .WithGasPrice(20)
                                         .WithGasLimit(10)
                                         .WithData(p5Signature)
                                         .TestObject;

            Transaction A_B_1_200_10_P0 = Build.A.NamedTransaction(nameof(A_B_1_200_10_P0))
                                          .WithSenderAddress(TestItem.AddressA)
                                          .To(TestItem.AddressB)
                                          .WithNonce(1)
                                          .WithGasPrice(200)
                                          .WithGasLimit(10)
                                          .WithData(p0signature)
                                          .TestObject;

            Transaction A_A_0_100_100_P0 = Build.A.NamedTransaction(nameof(A_A_0_100_100_P0))
                                           .WithSenderAddress(TestItem.AddressA)
                                           .To(TestItem.AddressA)
                                           .WithNonce(0)
                                           .WithGasPrice(100)
                                           .WithGasLimit(100)
                                           .WithData(p5Signature)
                                           .TestObject;

            Transaction A_A_1_100_100_P0 = Build.A.NamedTransaction(nameof(A_A_1_100_100_P0))
                                           .WithSenderAddress(TestItem.AddressA)
                                           .To(TestItem.AddressA)
                                           .WithNonce(1)
                                           .WithGasPrice(100)
                                           .WithGasLimit(100)
                                           .WithData(p5Signature)
                                           .TestObject;

            Transaction A_A_1_1000_1000_P0 = Build.A.NamedTransaction(nameof(A_A_1_1000_1000_P0))
                                             .WithSenderAddress(TestItem.AddressA)
                                             .To(TestItem.AddressA)
                                             .WithNonce(1)
                                             .WithGasPrice(1000)
                                             .WithGasLimit(1000)
                                             .WithData(p5Signature)
                                             .TestObject;

            Transaction A_A_2_1000_1_P0 = Build.A.NamedTransaction(nameof(A_A_2_1000_1_P0))
                                          .WithSenderAddress(TestItem.AddressA)
                                          .To(TestItem.AddressA)
                                          .WithNonce(2)
                                          .WithGasPrice(1000)
                                          .WithGasLimit(1)
                                          .WithData(p5Signature)
                                          .TestObject;

            Transaction B_B_2_1000_1_P6 = Build.A.NamedTransaction(nameof(B_B_2_1000_1_P6))
                                          .WithSenderAddress(TestItem.AddressB)
                                          .To(TestItem.AddressB)
                                          .WithNonce(2)
                                          .WithGasPrice(1000)
                                          .WithGasLimit(1)
                                          .WithData(p6Signature)
                                          .TestObject;

            Transaction B_B_2_15_1_P5 = Build.A.NamedTransaction(nameof(B_B_2_15_1_P5))
                                        .WithSenderAddress(TestItem.AddressB)
                                        .To(TestItem.AddressB)
                                        .WithNonce(2)
                                        .WithGasPrice(15)
                                        .WithGasLimit(1)
                                        .WithData(p5Signature)
                                        .TestObject;

            Transaction B_B_3_15_1_P6 = Build.A.NamedTransaction(nameof(B_B_3_15_1_P6))
                                        .WithSenderAddress(TestItem.AddressB)
                                        .To(TestItem.AddressB)
                                        .WithNonce(3)
                                        .WithGasPrice(15)
                                        .WithGasLimit(1)
                                        .WithData(p6Signature)
                                        .TestObject;

            Transaction C_B_3_10_1_P6_W = Build.A.NamedTransaction(nameof(C_B_3_10_1_P6_W))
                                          .WithSenderAddress(TestItem.AddressC)
                                          .To(TestItem.AddressB)
                                          .WithNonce(3)
                                          .WithGasPrice(10)
                                          .WithGasLimit(1)
                                          .WithData(p6Signature)
                                          .TestObject;

            Transaction C_B_4_10_1_P0_W = Build.A.NamedTransaction(nameof(C_B_4_10_1_P0_W))
                                          .WithSenderAddress(TestItem.AddressC)
                                          .To(TestItem.AddressB)
                                          .WithNonce(4)
                                          .WithGasPrice(10)
                                          .WithGasLimit(1)
                                          .TestObject;

            Transaction D_B_4_100_1_P0_W = Build.A.NamedTransaction(nameof(D_B_4_100_1_P0_W))
                                           .WithSenderAddress(TestItem.AddressD)
                                           .To(TestItem.AddressB)
                                           .WithNonce(4)
                                           .WithGasPrice(100)
                                           .WithGasLimit(1)
                                           .TestObject;

            IEnumerable <Transaction> transactions = new []
            {
                A_B_1_200_10_P0,
                A_A_2_1000_1_P0,
                A_A_1_1000_1000_P0,
                C_B_4_10_1_P0_W,
                A_A_1_100_100_P0,
                A_A_0_100_100_P0,
                A_B_0_10_10_P5,
                D_B_4_100_1_P0_W,
                C_B_3_10_1_P6_W,
                A_B_0_10_10_P6,
                A_B_0_20_10_P5,
                B_B_2_15_1_P5,
                A_B_0_10_5_P6,
                B_B_3_15_1_P6,
                A_B_0_10_20_P6,
                A_B_1_20_10_P5,
                B_B_2_1000_1_P6
            };

            IEnumerable <Transaction> expectation = new []
            {
                C_B_3_10_1_P6_W,
                D_B_4_100_1_P0_W,
                C_B_4_10_1_P0_W,
                B_B_2_1000_1_P6,
                A_B_0_10_5_P6,
                A_B_0_10_10_P6,
                A_B_0_10_20_P6,
                A_B_0_20_10_P5,
                B_B_2_15_1_P5,
                B_B_3_15_1_P6,
                A_B_0_10_10_P5,
                A_A_0_100_100_P0,
                A_B_1_20_10_P5,
                A_A_1_1000_1000_P0,
                A_B_1_200_10_P0,
                A_A_1_100_100_P0,
                A_A_2_1000_1_P0
            };

            transactions = transactionSelect?.Invoke(transactions) ?? transactions;
            expectation  = transactionSelect?.Invoke(expectation) ?? expectation;

            IComparer <Transaction> comparer = new CompareTxByPermissionOnSpecifiedBlock(sendersWhitelist, priorities, blockHeader)
                                               .ThenBy(CompareTxByGas.Instance);


            var txBySender = transactions.GroupBy(t => t.SenderAddress)
                             .ToDictionary(
                g => g.Key,
                g => g.OrderBy(t => t,
                               // to simulate order coming from TxPool
                               TxSortedPool.GetPoolUniqueTxComparerByNonce(comparer)).ToArray());


            var orderedTransactions = TxPoolTxSource.Order(txBySender, comparer).ToArray();

            orderedTransactions.Should().BeEquivalentTo(expectation, o => o.WithStrictOrdering());
        }
Esempio n. 20
0
            public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = false)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"CREATING NODE {privateKey.Address}");
                }
                _logManagers[privateKey] = LimboLogs.Instance;
//                _logManagers[privateKey] = new OneLoggerLogManager(new ConsoleAsyncLogger(LogLevel.Debug, $"{privateKey.Address} "));
                var nodeLogManager = _logManagers[privateKey];

                AutoResetEvent newHeadBlockEvent = new AutoResetEvent(false);

                _blockEvents.Add(privateKey, newHeadBlockEvent);

                MemDb blocksDb    = new MemDb();
                MemDb headersDb   = new MemDb();
                MemDb blockInfoDb = new MemDb();

                MemDb stateDb = new MemDb();
                MemDb codeDb  = new MemDb();

                ISpecProvider specProvider = RinkebySpecProvider.Instance;

                var           trieStore     = new TrieStore(stateDb, nodeLogManager);
                StateReader   stateReader   = new StateReader(trieStore, codeDb, nodeLogManager);
                StateProvider stateProvider = new StateProvider(trieStore, codeDb, nodeLogManager);

                stateProvider.CreateAccount(TestItem.PrivateKeyD.Address, 100.Ether());
                GoerliSpecProvider goerliSpecProvider = GoerliSpecProvider.Instance;

                stateProvider.Commit(goerliSpecProvider.GenesisSpec);
                stateProvider.CommitTree(0);

                BlockTree blockTree = new BlockTree(blocksDb, headersDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), goerliSpecProvider, NullBloomStorage.Instance, nodeLogManager);

                blockTree.NewHeadBlock += (sender, args) => { _blockEvents[privateKey].Set(); };
                ITransactionComparerProvider transactionComparerProvider =
                    new TransactionComparerProvider(specProvider, blockTree);

                TxPool.TxPool txPool = new TxPool.TxPool(new InMemoryTxStorage(), _ethereumEcdsa, new ChainHeadInfoProvider(new FixedBlockChainHeadSpecProvider(GoerliSpecProvider.Instance), blockTree, stateProvider), new TxPoolConfig(), new TxValidator(goerliSpecProvider.ChainId), _logManager, transactionComparerProvider.GetDefaultComparer());
                _pools[privateKey] = txPool;

                BlockhashProvider blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance);

                _blockTrees.Add(privateKey, blockTree);

                SnapshotManager snapshotManager = new SnapshotManager(_cliqueConfig, blocksDb, blockTree, _ethereumEcdsa, nodeLogManager);

                _snapshotManager[privateKey] = snapshotManager;
                CliqueSealer cliqueSealer = new CliqueSealer(new Signer(ChainId.Goerli, privateKey, LimboLogs.Instance), _cliqueConfig, snapshotManager, nodeLogManager);



                _genesis.Header.StateRoot       = _genesis3Validators.Header.StateRoot = stateProvider.StateRoot;
                _genesis.Header.Hash            = _genesis.Header.CalculateHash();
                _genesis3Validators.Header.Hash = _genesis3Validators.Header.CalculateHash();

                StorageProvider      storageProvider      = new StorageProvider(trieStore, stateProvider, nodeLogManager);
                TransactionProcessor transactionProcessor = new TransactionProcessor(goerliSpecProvider, stateProvider, storageProvider, new VirtualMachine(stateProvider, storageProvider, blockhashProvider, specProvider, nodeLogManager), nodeLogManager);

                BlockProcessor blockProcessor = new BlockProcessor(
                    goerliSpecProvider,
                    Always.Valid,
                    NoBlockRewards.Instance,
                    transactionProcessor,
                    stateProvider,
                    storageProvider,
                    txPool,
                    NullReceiptStorage.Instance,
                    NullWitnessCollector.Instance,
                    nodeLogManager);

                BlockchainProcessor processor = new BlockchainProcessor(blockTree, blockProcessor, new AuthorRecoveryStep(snapshotManager), nodeLogManager, BlockchainProcessor.Options.NoReceipts);

                processor.Start();

                var minerTrieStore = trieStore.AsReadOnly();

                StateProvider        minerStateProvider        = new StateProvider(minerTrieStore, codeDb, nodeLogManager);
                StorageProvider      minerStorageProvider      = new StorageProvider(minerTrieStore, minerStateProvider, nodeLogManager);
                VirtualMachine       minerVirtualMachine       = new VirtualMachine(minerStateProvider, minerStorageProvider, blockhashProvider, specProvider, nodeLogManager);
                TransactionProcessor minerTransactionProcessor = new TransactionProcessor(goerliSpecProvider, minerStateProvider, minerStorageProvider, minerVirtualMachine, nodeLogManager);

                BlockProcessor minerBlockProcessor = new BlockProcessor(
                    goerliSpecProvider,
                    Always.Valid,
                    NoBlockRewards.Instance,
                    minerTransactionProcessor,
                    minerStateProvider,
                    minerStorageProvider,
                    txPool,
                    NullReceiptStorage.Instance,
                    NullWitnessCollector.Instance,
                    nodeLogManager);

                BlockchainProcessor minerProcessor = new BlockchainProcessor(blockTree, minerBlockProcessor, new AuthorRecoveryStep(snapshotManager), nodeLogManager, BlockchainProcessor.Options.NoReceipts);

                if (withGenesisAlreadyProcessed)
                {
                    ProcessGenesis(privateKey);
                }

                ITxFilterPipeline   txFilterPipeline = TxFilterPipelineBuilder.CreateStandardFilteringPipeline(nodeLogManager, specProvider);
                TxPoolTxSource      txPoolTxSource   = new TxPoolTxSource(txPool, stateReader, specProvider, transactionComparerProvider, nodeLogManager, txFilterPipeline);
                CliqueBlockProducer blockProducer    = new CliqueBlockProducer(
                    txPoolTxSource,
                    minerProcessor,
                    minerStateProvider,
                    blockTree,
                    _timestamper,
                    new CryptoRandom(),
                    snapshotManager,
                    cliqueSealer,
                    new TargetAdjustedGasLimitCalculator(goerliSpecProvider, new MiningConfig()),
                    MainnetSpecProvider.Instance,
                    _cliqueConfig,
                    nodeLogManager);

                blockProducer.Start();

                _producers.Add(privateKey, blockProducer);

                return(this);
            }
Esempio n. 21
0
        public Task InitBlockProducer()
        {
            if (_nethermindApi !.SealEngineType != Nethermind.Core.SealEngineType.NethDev)
            {
                return(Task.CompletedTask);
            }

            var(getFromApi, setInApi) = _nethermindApi !.ForProducer;
            ITxFilter txFilter = new NullTxFilter();
            ITxSource txSource = new TxPoolTxSource(
                getFromApi.TxPool, getFromApi.StateReader, getFromApi.LogManager, txFilter);

            ILogger logger = getFromApi.LogManager.GetClassLogger();

            if (logger.IsWarn)
            {
                logger.Warn("Starting Neth Dev block producer & sealer");
            }

            ReadOnlyDbProvider readOnlyDbProvider = getFromApi.DbProvider.AsReadOnly(false);
            ReadOnlyBlockTree  readOnlyBlockTree  = getFromApi.BlockTree.AsReadOnly();

            ReadOnlyTxProcessingEnv producerEnv = new(
                readOnlyDbProvider,
                getFromApi.ReadOnlyTrieStore,
                readOnlyBlockTree,
                getFromApi.SpecProvider,
                getFromApi.LogManager);

            BlockProcessor producerProcessor = new(
                getFromApi !.SpecProvider,
                getFromApi !.BlockValidator,
                NoBlockRewards.Instance,
                producerEnv.TransactionProcessor,
                producerEnv.StateProvider,
                producerEnv.StorageProvider,
                NullTxPool.Instance,
                NullReceiptStorage.Instance,
                NullWitnessCollector.Instance,
                getFromApi.LogManager);

            IBlockchainProcessor producerChainProcessor = new BlockchainProcessor(
                readOnlyBlockTree,
                producerProcessor,
                getFromApi.BlockPreprocessor,
                getFromApi.LogManager,
                BlockchainProcessor.Options.NoReceipts);

            setInApi.BlockProducer = new DevBlockProducer(
                txSource.ServeTxsOneByOne(),
                producerChainProcessor,
                producerEnv.StateProvider,
                getFromApi.BlockTree,
                getFromApi.BlockProcessingQueue,
                new BuildBlocksRegularly(TimeSpan.FromMilliseconds(200))
                .IfPoolIsNotEmpty(getFromApi.TxPool)
                .Or(getFromApi.ManualBlockProductionTrigger),
                getFromApi.Timestamper,
                getFromApi.SpecProvider,
                getFromApi.Config <IMiningConfig>(),
                getFromApi.LogManager);

            return(Task.CompletedTask);
        }
Esempio n. 22
0
        protected virtual async Task <TestBlockchain> Build(ISpecProvider specProvider = null, UInt256?initialValues = null)
        {
            Timestamper    = new ManualTimestamper(new DateTime(2020, 2, 15, 12, 50, 30, DateTimeKind.Utc));
            JsonSerializer = new EthereumJsonSerializer();
            SpecProvider   = specProvider ?? MainnetSpecProvider.Instance;
            EthereumEcdsa  = new EthereumEcdsa(ChainId.Mainnet, LimboLogs.Instance);
            ITxStorage txStorage = new InMemoryTxStorage();

            DbProvider = await TestMemDbProvider.InitAsync();

            State = new StateProvider(StateDb, CodeDb, LimboLogs.Instance);
            State.CreateAccount(TestItem.AddressA, (initialValues ?? 1000.Ether()));
            State.CreateAccount(TestItem.AddressB, (initialValues ?? 1000.Ether()));
            State.CreateAccount(TestItem.AddressC, (initialValues ?? 1000.Ether()));
            byte[] code     = Bytes.FromHexString("0xabcd");
            Keccak codeHash = Keccak.Compute(code);

            State.UpdateCode(code);
            State.UpdateCodeHash(TestItem.AddressA, codeHash, SpecProvider.GenesisSpec);

            Storage = new StorageProvider(StateDb, State, LimboLogs.Instance);
            Storage.Set(new StorageCell(TestItem.AddressA, UInt256.One), Bytes.FromHexString("0xabcdef"));
            Storage.Commit();

            State.Commit(SpecProvider.GenesisSpec);
            State.CommitTree();

            TxPool = new TxPool.TxPool(
                txStorage,
                EthereumEcdsa,
                SpecProvider,
                new TxPoolConfig(),
                new StateProvider(StateDb, CodeDb, LimboLogs.Instance),
                LimboLogs.Instance);

            IDb blockDb     = new MemDb();
            IDb headerDb    = new MemDb();
            IDb blockInfoDb = new MemDb();

            BlockTree = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockDb), SpecProvider, NullBloomStorage.Instance, LimboLogs.Instance);
            new OnChainTxWatcher(BlockTree, TxPool, SpecProvider, LimboLogs.Instance);

            ReceiptStorage = new InMemoryReceiptStorage();
            VirtualMachine virtualMachine = new VirtualMachine(State, Storage, new BlockhashProvider(BlockTree, LimboLogs.Instance), SpecProvider, LimboLogs.Instance);

            TxProcessor    = new TransactionProcessor(SpecProvider, State, Storage, virtualMachine, LimboLogs.Instance);
            BlockProcessor = CreateBlockProcessor();

            BlockchainProcessor chainProcessor = new BlockchainProcessor(BlockTree, BlockProcessor, new RecoverSignatures(EthereumEcdsa, TxPool, SpecProvider, LimboLogs.Instance), LimboLogs.Instance, Nethermind.Blockchain.Processing.BlockchainProcessor.Options.Default);

            BlockchainProcessor = chainProcessor;
            chainProcessor.Start();

            StateReader = new StateReader(StateDb, CodeDb, LimboLogs.Instance);
            TxPoolTxSource txPoolTxSource = CreateTxPoolTxSource();
            ISealer        sealer         = new NethDevSealEngine(TestItem.AddressD);

            BlockProducer = new TestBlockProducer(txPoolTxSource, chainProcessor, State, sealer, BlockTree, chainProcessor, Timestamper, LimboLogs.Instance);
            BlockProducer.Start();

            _resetEvent = new SemaphoreSlim(0);
            _suggestedBlockResetEvent = new ManualResetEvent(true);
            BlockTree.NewHeadBlock   += (s, e) =>
            {
                _resetEvent.Release(1);
            };
            BlockProducer.LastProducedBlockChanged += (s, e) =>
            {
                _suggestedBlockResetEvent.Set();
            };

            var genesis = GetGenesisBlock();

            BlockTree.SuggestBlock(genesis);
            await _resetEvent.WaitAsync();

            //if (!await _resetEvent.WaitAsync(1000))
            // {
            //     throw new InvalidOperationException("Failed to process genesis in 1s.");
            // }

            await AddBlocksOnStart();

            return(this);
        }
Esempio n. 23
0
        protected virtual async Task <TestBlockchain> Build(ISpecProvider specProvider = null)
        {
            Timestamper    = new ManualTimestamper(new DateTime(2020, 2, 15, 12, 50, 30, DateTimeKind.Utc));
            JsonSerializer = new EthereumJsonSerializer();
            SpecProvider   = specProvider ?? MainnetSpecProvider.Instance;
            EthereumEcdsa  = new EthereumEcdsa(ChainId.Mainnet, LimboLogs.Instance);
            ITxStorage txStorage = new InMemoryTxStorage();

            DbProvider = new MemDbProvider();
            State      = new StateProvider(StateDb, CodeDb, LimboLogs.Instance);
            State.CreateAccount(TestItem.AddressA, 1000.Ether());
            State.CreateAccount(TestItem.AddressB, 1000.Ether());
            State.CreateAccount(TestItem.AddressC, 1000.Ether());
            byte[] code     = Bytes.FromHexString("0xabcd");
            Keccak codeHash = Keccak.Compute(code);

            State.UpdateCode(code);
            State.UpdateCodeHash(TestItem.AddressA, codeHash, SpecProvider.GenesisSpec);

            Storage = new StorageProvider(StateDb, State, LimboLogs.Instance);
            Storage.Set(new StorageCell(TestItem.AddressA, UInt256.One), Bytes.FromHexString("0xabcdef"));
            Storage.Commit();

            State.Commit(SpecProvider.GenesisSpec);
            State.CommitTree();

            TxPool = new TxPool.TxPool(txStorage, Timestamper, EthereumEcdsa, SpecProvider, new TxPoolConfig(), State, LimboLogs.Instance);

            IDb blockDb     = new MemDb();
            IDb headerDb    = new MemDb();
            IDb blockInfoDb = new MemDb();

            BlockTree = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockDb), SpecProvider, TxPool, NullBloomStorage.Instance, LimboLogs.Instance);

            ReceiptStorage = new InMemoryReceiptStorage();
            VirtualMachine virtualMachine = new VirtualMachine(State, Storage, new BlockhashProvider(BlockTree, LimboLogs.Instance), SpecProvider, LimboLogs.Instance);

            TxProcessor    = new TransactionProcessor(SpecProvider, State, Storage, virtualMachine, LimboLogs.Instance);
            BlockProcessor = CreateBlockProcessor();

            BlockchainProcessor chainProcessor = new BlockchainProcessor(BlockTree, BlockProcessor, new TxSignaturesRecoveryStep(EthereumEcdsa, TxPool, LimboLogs.Instance), LimboLogs.Instance, BlockchainProcessor.Options.Default);

            chainProcessor.Start();

            StateReader = new StateReader(StateDb, CodeDb, LimboLogs.Instance);
            TxPoolTxSource txPoolTxSource = new TxPoolTxSource(TxPool, StateReader, LimboLogs.Instance);
            ISealer        sealer         = new FakeSealer(TimeSpan.Zero);

            BlockProducer = new TestBlockProducer(txPoolTxSource, chainProcessor, State, sealer, BlockTree, chainProcessor, Timestamper, LimboLogs.Instance);
            BlockProducer.Start();

            _resetEvent             = new AutoResetEvent(false);
            BlockTree.NewHeadBlock += (s, e) =>
            {
                Console.WriteLine(e.Block.Header.Hash);
                _resetEvent.Set();
            };

            var genesis = GetGenesisBlock();

            BlockTree.SuggestBlock(genesis);
            await _resetEvent.WaitOneAsync(CancellationToken.None);

            await AddBlocksOnStart();

            return(this);
        }