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)); }
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); }
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); }
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)); }
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); }
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); }
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()); }
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); }
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); }
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); }
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); }