Exemplo n.º 1
0
        private Task InitBlockchain()
        {
            if (_api.ChainSpec == null)
            {
                throw new StepDependencyException(nameof(_api.ChainSpec));
            }
            if (_api.DbProvider == null)
            {
                throw new StepDependencyException(nameof(_api.DbProvider));
            }
            if (_api.SpecProvider == null)
            {
                throw new StepDependencyException(nameof(_api.SpecProvider));
            }

            ILogger     logger     = _api.LogManager.GetClassLogger();
            IInitConfig initConfig = _api.Config <IInitConfig>();
            ISyncConfig syncConfig = _api.Config <ISyncConfig>();

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

            Account.AccountStartNonce = _api.ChainSpec.Parameters.AccountStartNonce;

            Signer signer = new Signer(_api.SpecProvider.ChainId, _api.OriginalSignerKey, _api.LogManager);

            _api.EngineSigner      = signer;
            _api.EngineSignerStore = signer;

            _api.StateProvider = new StateProvider(
                _api.DbProvider.StateDb,
                _api.DbProvider.CodeDb,
                _api.LogManager);

            _api.EthereumEcdsa = new EthereumEcdsa(_api.SpecProvider.ChainId, _api.LogManager);
            _api.TxPool        = new TxPool.TxPool(
                new PersistentTxStorage(_api.DbProvider.PendingTxsDb),
                Timestamper.Default,
                _api.EthereumEcdsa,
                _api.SpecProvider,
                _api.Config <ITxPoolConfig>(),
                _api.StateProvider,
                _api.LogManager);

            IVaultConfig vaultConfig = _api.Config <IVaultConfig>();

            if (!vaultConfig.Enabled)
            {
                ITxSigner txSigner       = new WalletTxSigner(_api.Wallet, _api.SpecProvider.ChainId);
                TxSealer  standardSealer = new TxSealer(txSigner, _api.Timestamper);
                NonceReservingTxSealer nonceReservingTxSealer =
                    new NonceReservingTxSealer(txSigner, _api.Timestamper, _api.TxPool);
                _api.TxSender = new TxPoolSender(_api.TxPool, standardSealer, nonceReservingTxSealer);
            }
            else
            {
                IVaultService vaultService = new VaultService(vaultConfig, _api.LogManager);
                IVaultWallet  wallet       = new VaultWallet(vaultService, vaultConfig.VaultId, _api.LogManager);
                ITxSigner     vaultSigner  = new VaultTxSigner(wallet, _api.ChainSpec.ChainId);

                // change vault to provide, use sealer to set the gas price as well
                _api.TxSender = new VaultTxSender(vaultSigner, vaultConfig, _api.ChainSpec.ChainId);
            }

            IBloomConfig?bloomConfig = _api.Config <IBloomConfig>();

            IFileStoreFactory fileStoreFactory = initConfig.DiagnosticMode == DiagnosticMode.MemDb
                ? (IFileStoreFactory) new InMemoryDictionaryFileStoreFactory()
                : new FixedSizeFileStoreFactory(Path.Combine(initConfig.BaseDbPath, DbNames.Bloom), DbNames.Bloom, Bloom.ByteLength);

            _api.BloomStorage = bloomConfig.Index
                ? new BloomStorage(bloomConfig, _api.DbProvider.BloomDb, fileStoreFactory)
                : (IBloomStorage)NullBloomStorage.Instance;

            _api.DisposeStack.Push(_api.BloomStorage);

            _api.ChainLevelInfoRepository = new ChainLevelInfoRepository(_api.DbProvider.BlockInfosDb);

            _api.BlockTree = new BlockTree(
                _api.DbProvider.BlocksDb,
                _api.DbProvider.HeadersDb,
                _api.DbProvider.BlockInfosDb,
                _api.ChainLevelInfoRepository,
                _api.SpecProvider,
                _api.TxPool,
                _api.BloomStorage,
                _api.Config <ISyncConfig>(),
                _api.LogManager);

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

            _api.ReceiptStorage = initConfig.StoreReceipts ? (IReceiptStorage?)new PersistentReceiptStorage(_api.DbProvider.ReceiptsDb, _api.SpecProvider, new ReceiptsRecovery()) : NullReceiptStorage.Instance;
            _api.ReceiptFinder  = new FullInfoReceiptFinder(_api.ReceiptStorage, new ReceiptsRecovery(), _api.BlockTree);

            _api.RecoveryStep = new TxSignaturesRecoveryStep(_api.EthereumEcdsa, _api.TxPool, _api.SpecProvider, _api.LogManager);

            _api.StorageProvider = new StorageProvider(
                _api.DbProvider.StateDb,
                _api.StateProvider,
                _api.LogManager);

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

            VirtualMachine virtualMachine = new VirtualMachine(
                _api.StateProvider,
                _api.StorageProvider,
                blockhashProvider,
                _api.SpecProvider,
                _api.LogManager);

            _api.TransactionProcessor = new TransactionProcessor(
                _api.SpecProvider,
                _api.StateProvider,
                _api.StorageProvider,
                virtualMachine,
                _api.LogManager);

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

            /* validation */
            _api.HeaderValidator = CreateHeaderValidator();

            OmmersValidator ommersValidator = new OmmersValidator(
                _api.BlockTree,
                _api.HeaderValidator,
                _api.LogManager);

            TxValidator txValidator = new TxValidator(_api.SpecProvider.ChainId);

            _api.BlockValidator = new BlockValidator(
                txValidator,
                _api.HeaderValidator,
                ommersValidator,
                _api.SpecProvider,
                _api.LogManager);

            ReadOnlyDbProvider readOnly    = new ReadOnlyDbProvider(_api.DbProvider, false);
            StateReader        stateReader = new StateReader(readOnly.StateDb, readOnly.CodeDb, _api.LogManager);

            _api.TxPoolInfoProvider = new TxPoolInfoProvider(stateReader, _api.TxPool);

            _api.MainBlockProcessor = CreateBlockProcessor();

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

            _api.BlockProcessingQueue = blockchainProcessor;
            _api.BlockchainProcessor  = blockchainProcessor;

            if (syncConfig.BeamSync)
            {
                BeamBlockchainProcessor beamBlockchainProcessor = new BeamBlockchainProcessor(
                    new ReadOnlyDbProvider(_api.DbProvider, false),
                    _api.BlockTree,
                    _api.SpecProvider,
                    _api.LogManager,
                    _api.BlockValidator,
                    _api.RecoveryStep,
                    _api.RewardCalculatorSource !,
                    _api.BlockProcessingQueue,
                    _api.SyncModeSelector !);

                _api.DisposeStack.Push(beamBlockchainProcessor);
            }

            return(Task.CompletedTask);
        }
Exemplo n.º 2
0
        public async Task Can_process_mined_blocks()
        {
            int timeMultiplier = 1; // for debugging

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

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

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

            RopstenSpecProvider specProvider = RopstenSpecProvider.Instance;

            /* store & validation */

            EthereumEcdsa   ethereumEcdsa   = new EthereumEcdsa(specProvider, logManager);
            MemDb           receiptsDb      = new MemDb();
            MemDb           traceDb         = new MemDb();
            TransactionPool transactionPool = new TransactionPool(new NullTransactionStorage(),
                                                                  new PendingTransactionThresholdValidator(), new Timestamp(), ethereumEcdsa, specProvider, logManager);
            IReceiptStorage      receiptStorage       = new PersistentReceiptStorage(receiptsDb, specProvider);
            BlockTree            blockTree            = new BlockTree(new MemDb(), new MemDb(), specProvider, transactionPool, logManager);
            Timestamp            timestamp            = new Timestamp();
            DifficultyCalculator difficultyCalculator = new DifficultyCalculator(specProvider);
            HeaderValidator      headerValidator      = new HeaderValidator(blockTree, sealer, specProvider, logManager);
            OmmersValidator      ommersValidator      = new OmmersValidator(blockTree, headerValidator, logManager);
            TransactionValidator transactionValidator = new TransactionValidator(new SignatureValidator(ChainId.Ropsten));
            BlockValidator       blockValidator       = new BlockValidator(transactionValidator, headerValidator, ommersValidator, specProvider, logManager);

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

            TestTransactionsGenerator generator = new TestTransactionsGenerator(transactionPool, ethereumEcdsa, TimeSpan.FromMilliseconds(5 * timeMultiplier), NullLogManager.Instance);

            generator.Start();

            /* blockchain processing */
            BlockhashProvider    blockhashProvider = new BlockhashProvider(blockTree);
            VirtualMachine       virtualMachine    = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, 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, traceDb, stateProvider, storageProvider, transactionPool, receiptStorage, logManager);
            BlockchainProcessor blockchainProcessor = new BlockchainProcessor(blockTree, blockProcessor, new TxSignaturesRecoveryStep(ethereumEcdsa, NullTransactionPool.Instance), logManager, false, 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.ReadAllBytes(path));

            foreach (var allocation in chainSpec.Allocations)
            {
                stateProvider.CreateAccount(allocation.Key, allocation.Value);
            }

            stateProvider.Commit(specProvider.GenesisSpec);
            chainSpec.Genesis.Header.StateRoot = stateProvider.StateRoot; // TODO: shall it be HeaderSpec and not BlockHeader?
            chainSpec.Genesis.Header.Hash      = BlockHeader.CalculateHash(chainSpec.Genesis.Header);
            if (chainSpec.Genesis.Hash != new Keccak("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"))
            {
                throw new Exception("Unexpected genesis hash");
            }

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

            MinedBlockProducer minedBlockProducer = new MinedBlockProducer(difficultyCalculator, transactionPool, blockchainProcessor, sealer, blockTree, timestamp, NullLogManager.Instance);

            minedBlockProducer.Start();

            ManualResetEventSlim manualResetEvent = new ManualResetEventSlim(false);

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

            manualResetEvent.Wait(miningDelay * 12 * timeMultiplier);
            await minedBlockProducer.StopAsync();

            int previousCount = 0;
            int totalTx       = 0;

            for (int i = 0; i < 6; i++)
            {
                Block block = blockTree.FindBlock(new UInt256(i));
                logger.Info($"Block {i} with {block.Transactions.Length} txs");

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

                Tracer tracer = new Tracer(blockchainProcessor, receiptStorage, blockTree, new MemDb());

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

                if (block.Transactions.Length > 0)
                {
                    GethLikeTxTrace trace = tracer.Trace(block.Transactions[0].Hash);
                    Assert.AreSame(GethLikeTxTrace.QuickFail, trace);
                    Assert.AreNotEqual(previousCount, currentCount, $"receipts at block {i}");
                    totalTx += block.Transactions.Length;
                }

                previousCount = currentCount;
            }

            Assert.AreNotEqual(0, totalTx, "no tx in blocks");
        }
Exemplo n.º 3
0
        protected async Task <EthereumTestResult> RunTest(BlockchainTest test, Stopwatch stopwatch = null)
        {
            if (test.Network == Berlin.Instance)
            {
                return(new EthereumTestResult(test.Name, "Berlin", null)
                {
                    Pass = true
                });
            }

            TestContext.Write($"Running {test.Name} at {DateTime.UtcNow:HH:mm:ss.ffffff}");
            Assert.IsNull(test.LoadFailure, "test data loading failure");

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

            ISpecProvider specProvider;

            if (test.NetworkAfterTransition != null)
            {
                specProvider = new CustomSpecProvider(1,
                                                      (0, Frontier.Instance),
                                                      (1, test.Network),
                                                      (test.TransitionBlockNumber, test.NetworkAfterTransition));
            }
            else
            {
                specProvider = new CustomSpecProvider(1,
                                                      (0, Frontier.Instance), // TODO: this thing took a lot of time to find after it was removed!, genesis block is always initialized with Frontier
                                                      (1, test.Network));
            }

            if (specProvider.GenesisSpec != Frontier.Instance)
            {
                Assert.Fail("Expected genesis spec to be Frontier for blockchain tests");
            }

            DifficultyCalculator.Wrapped = new DifficultyCalculator(specProvider);
            IRewardCalculator rewardCalculator = new RewardCalculator(specProvider);

            IEthereumEcdsa ecdsa = new EthereumEcdsa(specProvider.ChainId, _logManager);

            TrieStore      trieStore       = new TrieStore(stateDb, _logManager);
            IStateProvider stateProvider   = new StateProvider(trieStore, codeDb, _logManager);
            var            blockInfoDb     = new MemDb();
            IBlockTree     blockTree       = new BlockTree(new MemDb(), new MemDb(), blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, NullBloomStorage.Instance, _logManager);
            ITxPool        transactionPool = new TxPool(NullTxStorage.Instance, ecdsa, new ChainHeadSpecProvider(specProvider, blockTree), new TxPoolConfig(), stateProvider, new TxValidator(specProvider.ChainId), _logManager);

            IReceiptStorage    receiptStorage    = NullReceiptStorage.Instance;
            IBlockhashProvider blockhashProvider = new BlockhashProvider(blockTree, _logManager);
            ITxValidator       txValidator       = new TxValidator(ChainId.Mainnet);
            IHeaderValidator   headerValidator   = new HeaderValidator(blockTree, Sealer, specProvider, _logManager);
            IOmmersValidator   ommersValidator   = new OmmersValidator(blockTree, headerValidator, _logManager);
            IBlockValidator    blockValidator    = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, _logManager);
            IStorageProvider   storageProvider   = new StorageProvider(trieStore, stateProvider, _logManager);
            IVirtualMachine    virtualMachine    = new VirtualMachine(
                stateProvider,
                storageProvider,
                blockhashProvider,
                specProvider,
                _logManager);

            IBlockProcessor blockProcessor = new BlockProcessor(
                specProvider,
                blockValidator,
                rewardCalculator,
                new TransactionProcessor(
                    specProvider,
                    stateProvider,
                    storageProvider,
                    virtualMachine,
                    _logManager),
                stateProvider,
                storageProvider,
                transactionPool,
                receiptStorage,
                NullWitnessCollector.Instance,
                _logManager);

            IBlockchainProcessor blockchainProcessor = new BlockchainProcessor(
                blockTree,
                blockProcessor,
                new RecoverSignatures(ecdsa, NullTxPool.Instance, specProvider, _logManager),
                _logManager,
                BlockchainProcessor.Options.NoReceipts);

            InitializeTestState(test, stateProvider, storageProvider, specProvider);

            List <(Block Block, string ExpectedException)> correctRlp = new List <(Block, string)>();

            for (int i = 0; i < test.Blocks.Length; i++)
            {
                try
                {
                    TestBlockJson testBlockJson  = test.Blocks[i];
                    var           rlpContext     = Bytes.FromHexString(testBlockJson.Rlp).AsRlpStream();
                    Block         suggestedBlock = Rlp.Decode <Block>(rlpContext);
                    suggestedBlock.Header.SealEngineType = test.SealEngineUsed ? SealEngineType.Ethash : SealEngineType.None;

                    Assert.AreEqual(new Keccak(testBlockJson.BlockHeader.Hash), suggestedBlock.Header.Hash, "hash of the block");
                    for (int ommerIndex = 0; ommerIndex < suggestedBlock.Ommers.Length; ommerIndex++)
                    {
                        Assert.AreEqual(new Keccak(testBlockJson.UncleHeaders[ommerIndex].Hash), suggestedBlock.Ommers[ommerIndex].Hash, "hash of the ommer");
                    }

                    correctRlp.Add((suggestedBlock, testBlockJson.ExpectedException));
                }
                catch (Exception)
                {
                    _logger?.Info($"Invalid RLP ({i})");
                }
            }

            if (correctRlp.Count == 0)
            {
                var result = new EthereumTestResult(test.Name, null);

                try
                {
                    Assert.AreEqual(new Keccak(test.GenesisBlockHeader.Hash), test.LastBlockHash);
                }
                catch (AssertionException)
                {
                    result.Pass = false;
                    return(result);
                }

                result.Pass = true;
                return(result);
            }

            if (test.GenesisRlp == null)
            {
                test.GenesisRlp = Rlp.Encode(new Block(JsonToEthereumTest.Convert(test.GenesisBlockHeader)));
            }

            Block genesisBlock = Rlp.Decode <Block>(test.GenesisRlp.Bytes);

            Assert.AreEqual(new Keccak(test.GenesisBlockHeader.Hash), genesisBlock.Header.Hash, "genesis header hash");

            ManualResetEvent genesisProcessed = new ManualResetEvent(false);

            blockTree.NewHeadBlock += (sender, args) =>
            {
                if (args.Block.Number == 0)
                {
                    Assert.AreEqual(genesisBlock.Header.StateRoot, stateProvider.StateRoot, "genesis state root");
                    genesisProcessed.Set();
                }
            };

            blockchainProcessor.Start();
            blockTree.SuggestBlock(genesisBlock);

            genesisProcessed.WaitOne();

            for (int i = 0; i < correctRlp.Count; i++)
            {
                stopwatch?.Start();
                try
                {
                    if (correctRlp[i].ExpectedException != null)
                    {
                        _logger.Info($"Expecting block exception: {correctRlp[i].ExpectedException}");
                    }

                    if (correctRlp[i].Block.Hash == null)
                    {
                        throw new Exception($"null hash in {test.Name} block {i}");
                    }

                    // TODO: mimic the actual behaviour where block goes through validating sync manager?
                    if (!test.SealEngineUsed || blockValidator.ValidateSuggestedBlock(correctRlp[i].Block))
                    {
                        blockTree.SuggestBlock(correctRlp[i].Block);
                    }
                    else
                    {
                        Console.WriteLine("Invalid block");
                    }
                }
                catch (InvalidBlockException)
                {
                }
                catch (Exception ex)
                {
                    _logger?.Info(ex.ToString());
                }
            }

            await blockchainProcessor.StopAsync(true);

            stopwatch?.Stop();

            List <string> differences = RunAssertions(test, blockTree.RetrieveHeadBlock(), storageProvider, stateProvider);

//            if (differences.Any())
//            {
//                BlockTrace blockTrace = blockchainProcessor.TraceBlock(blockTree.BestSuggested.Hash);
//                _logger.Info(new UnforgivingJsonSerializer().Serialize(blockTrace, true));
//            }

            Assert.Zero(differences.Count, "differences");

            return(new EthereumTestResult
            {
                Pass = differences.Count == 0,
                Name = test.Name
            });
        }
Exemplo n.º 4
0
        private async Task InitBlockchain()
        {
            /* spec */
            if (_chainSpec.ChainId == RopstenSpecProvider.Instance.ChainId)
            {
                _specProvider = RopstenSpecProvider.Instance;
            }
            else if (_chainSpec.ChainId == MainNetSpecProvider.Instance.ChainId)
            {
                _specProvider = MainNetSpecProvider.Instance;
            }
            else if (_chainSpec.ChainId == RinkebySpecProvider.Instance.ChainId)
            {
                _specProvider = RinkebySpecProvider.Instance;
            }
            else if (_chainSpec.ChainId == GoerliSpecProvider.Instance.ChainId)
            {
                _specProvider = GoerliSpecProvider.Instance;
            }
            else if (_chainSpec.ChainId == SturebySpecProvider.Instance.ChainId)
            {
                _specProvider = SturebySpecProvider.Instance;
            }
            else
            {
                _specProvider = new SingleReleaseSpecProvider(LatestRelease.Instance, _chainSpec.ChainId);
            }

            /* sync */
            IDbConfig dbConfig = _configProvider.GetConfig <IDbConfig>();

            foreach (PropertyInfo propertyInfo in typeof(IDbConfig).GetProperties())
            {
                if (_logger.IsDebug)
                {
                    _logger.Debug($"DB {propertyInfo.Name}: {propertyInfo.GetValue(dbConfig)}");
                }
            }

            _dbProvider = HiveEnabled
                ? (IDbProvider) new MemDbProvider()
                : new RocksDbProvider(_initConfig.BaseDbPath, dbConfig, _logManager, _initConfig.StoreTraces, _initConfig.StoreReceipts);

            _ethereumEcdsa = new EthereumEcdsa(_specProvider, _logManager);
            _txPool        = new TxPool(
                new PersistentTransactionStorage(_dbProvider.PendingTxsDb, _specProvider),
                new PendingTransactionThresholdValidator(_initConfig.ObsoletePendingTransactionInterval,
                                                         _initConfig.RemovePendingTransactionInterval), new Timestamp(),
                _ethereumEcdsa, _specProvider, _logManager, _initConfig.RemovePendingTransactionInterval,
                _initConfig.PeerNotificationThreshold);
            _receiptStorage = new PersistentReceiptStorage(_dbProvider.ReceiptsDb, _specProvider);

//            IDbProvider debugRecorder = new RocksDbProvider(Path.Combine(_dbBasePath, "debug"), dbConfig);
//            _dbProvider = new RpcDbProvider(_jsonSerializer, new BasicJsonRpcClient(KnownRpcUris.NethVm1, _jsonSerializer, _logManager), _logManager, debugRecorder);

//            IDbProvider debugReader = new ReadOnlyDbProvider(new RocksDbProvider(Path.Combine(_dbBasePath, "debug"), dbConfig));
//            _dbProvider = debugReader;

            _blockTree = new BlockTree(
                _dbProvider.BlocksDb,
                _dbProvider.HeadersDb,
                _dbProvider.BlockInfosDb,
                _specProvider,
                _txPool,
                _logManager);

            _recoveryStep = new TxSignaturesRecoveryStep(_ethereumEcdsa, _txPool);

            CliqueConfig cliqueConfig = null;

            _snapshotManager = null;
            switch (_chainSpec.SealEngineType)
            {
            case SealEngineType.None:
                _sealer           = NullSealEngine.Instance;
                _sealValidator    = NullSealEngine.Instance;
                _rewardCalculator = NoBlockRewards.Instance;
                break;

            case SealEngineType.Clique:
                _rewardCalculator        = NoBlockRewards.Instance;
                cliqueConfig             = new CliqueConfig();
                cliqueConfig.BlockPeriod = _chainSpec.CliquePeriod;
                cliqueConfig.Epoch       = _chainSpec.CliqueEpoch;
                _snapshotManager         = new SnapshotManager(cliqueConfig, _dbProvider.BlocksDb, _blockTree, _ethereumEcdsa, _logManager);
                _sealValidator           = new CliqueSealValidator(cliqueConfig, _snapshotManager, _logManager);
                _recoveryStep            = new CompositeDataRecoveryStep(_recoveryStep, new AuthorRecoveryStep(_snapshotManager));
                if (_initConfig.IsMining)
                {
                    _sealer = new CliqueSealer(new BasicWallet(_nodeKey), cliqueConfig, _snapshotManager, _nodeKey.Address, _logManager);
                }
                else
                {
                    _sealer = NullSealEngine.Instance;
                }

                break;

            case SealEngineType.NethDev:
                _sealer           = NullSealEngine.Instance;
                _sealValidator    = NullSealEngine.Instance;
                _rewardCalculator = NoBlockRewards.Instance;
                break;

            case SealEngineType.Ethash:
                _rewardCalculator = new RewardCalculator(_specProvider);
                var difficultyCalculator = new DifficultyCalculator(_specProvider);
                if (_initConfig.IsMining)
                {
                    _sealer = new EthashSealer(new Ethash(_logManager), _logManager);
                }
                else
                {
                    _sealer = NullSealEngine.Instance;
                }

                _sealValidator = new EthashSealValidator(_logManager, difficultyCalculator, new Ethash(_logManager));
                break;

            default:
                throw new NotSupportedException($"Seal engine type {_chainSpec.SealEngineType} is not supported in Nethermind");
            }

            /* validation */
            _headerValidator = new HeaderValidator(
                _blockTree,
                _sealValidator,
                _specProvider,
                _logManager);

            var ommersValidator = new OmmersValidator(
                _blockTree,
                _headerValidator,
                _logManager);

            var txValidator = new TxValidator(_specProvider.ChainId);

            _blockValidator = new BlockValidator(
                txValidator,
                _headerValidator,
                ommersValidator,
                _specProvider,
                _logManager);

            var stateProvider = new StateProvider(
                _dbProvider.StateDb,
                _dbProvider.CodeDb,
                _logManager);

            _stateProvider = stateProvider;

            var storageProvider = new StorageProvider(
                _dbProvider.StateDb,
                stateProvider,
                _logManager);

            _transactionPoolInfoProvider = new TxPoolInfoProvider(stateProvider);

            /* blockchain processing */
            var blockhashProvider = new BlockhashProvider(
                _blockTree);

            var virtualMachine = new VirtualMachine(
                stateProvider,
                storageProvider,
                blockhashProvider,
                _logManager);

            var transactionProcessor = new TransactionProcessor(
                _specProvider,
                stateProvider,
                storageProvider,
                virtualMachine,
                _logManager);

            _blockProcessor = new BlockProcessor(
                _specProvider,
                _blockValidator,
                _rewardCalculator,
                transactionProcessor,
                _dbProvider.StateDb,
                _dbProvider.CodeDb,
                _dbProvider.TraceDb,
                stateProvider,
                storageProvider,
                _txPool,
                _receiptStorage,
                _configProvider.GetConfig <ISyncConfig>(),
                _logManager);

            _blockchainProcessor = new BlockchainProcessor(
                _blockTree,
                _blockProcessor,
                _recoveryStep,
                _logManager,
                _initConfig.StoreReceipts,
                _initConfig.StoreTraces);

            // create shared objects between discovery and peer manager
            IStatsConfig statsConfig = _configProvider.GetConfig <IStatsConfig>();

            _nodeStatsManager = new NodeStatsManager(statsConfig, _logManager);

            if (_initConfig.IsMining)
            {
                IReadOnlyDbProvider minerDbProvider = new ReadOnlyDbProvider(_dbProvider, false);
                AlternativeChain    producerChain   = new AlternativeChain(_blockTree, _blockValidator, _rewardCalculator,
                                                                           _specProvider, minerDbProvider, _recoveryStep, _logManager, _txPool, _receiptStorage);

                switch (_chainSpec.SealEngineType)
                {
                case SealEngineType.Clique:
                {
                    if (_logger.IsWarn)
                    {
                        _logger.Warn("Starting Clique block producer & sealer");
                    }
                    _blockProducer = new CliqueBlockProducer(_txPool, producerChain.Processor,
                                                             _blockTree, _timestamp, _cryptoRandom, producerChain.StateProvider, _snapshotManager, (CliqueSealer)_sealer, _nodeKey.Address, cliqueConfig, _logManager);
                    break;
                }

                case SealEngineType.NethDev:
                {
                    if (_logger.IsWarn)
                    {
                        _logger.Warn("Starting Dev block producer & sealer");
                    }
                    _blockProducer = new DevBlockProducer(_txPool, producerChain.Processor, _blockTree,
                                                          _timestamp, _logManager);
                    break;
                }

                default:
                    throw new NotSupportedException($"Mining in {_chainSpec.SealEngineType} mode is not supported");
                }

                _blockProducer.Start();
            }

            if (!HiveEnabled)
            {
                _blockchainProcessor.Start();
                LoadGenesisBlock(_chainSpec, string.IsNullOrWhiteSpace(_initConfig.GenesisHash) ? null : new Keccak(_initConfig.GenesisHash), _blockTree, stateProvider, _specProvider);
                if (_initConfig.ProcessingEnabled)
                {
#pragma warning disable 4014
                    LoadBlocksFromDb();
#pragma warning restore 4014
                }
                else
                {
                    if (_logger.IsWarn)
                    {
                        _logger.Warn($"Shutting down processor due to {nameof(InitConfig)}.{nameof(InitConfig.ProcessingEnabled)} set to false");
                    }
                    await _blockchainProcessor.StopAsync();
                }
            }

            await InitializeNetwork(
                _receiptStorage,
                _sealValidator,
                txValidator);
        }
Exemplo n.º 5
0
        private async Task InitBlockchain()
        {
            ChainSpec chainSpec = LoadChainSpec(_initConfig.ChainSpecPath);

            /* spec */
            // TODO: rebuild to use chainspec
            ISpecProvider specProvider;

            if (chainSpec.ChainId == RopstenSpecProvider.Instance.ChainId)
            {
                specProvider = RopstenSpecProvider.Instance;
            }
            else if (chainSpec.ChainId == MainNetSpecProvider.Instance.ChainId)
            {
                specProvider = MainNetSpecProvider.Instance;
            }
            else
            {
                throw new NotSupportedException($"Not yet tested, not yet supported ChainId {chainSpec.ChainId}");
            }

            var ethereumSigner = new EthereumSigner(
                specProvider,
                _logManager);

            var transactionStore = new TransactionStore();

            var sealEngine = ConfigureSealEngine(
                transactionStore,
                ethereumSigner);

            /* sync */
            IDbConfig dbConfig = _configProvider.GetConfig <IDbConfig>();

            foreach (PropertyInfo propertyInfo in typeof(IDbConfig).GetProperties())
            {
                _logger.Info($"DB {propertyInfo.Name}: {propertyInfo.GetValue(dbConfig)}");
            }

            var blocksDb = new DbOnTheRocks(
                Path.Combine(_dbBasePath, DbOnTheRocks.BlocksDbPath),
                dbConfig);

            var blockInfosDb = new DbOnTheRocks(
                Path.Combine(_dbBasePath, DbOnTheRocks.BlockInfosDbPath),
                dbConfig);

            var receiptsDb = new DbOnTheRocks(
                Path.Combine(_dbBasePath, DbOnTheRocks.ReceiptsDbPath),
                dbConfig);

            /* blockchain */
            _blockTree = new BlockTree(
                blocksDb,
                blockInfosDb,
                receiptsDb,
                specProvider,
                _logManager);

            var difficultyCalculator = new DifficultyCalculator(
                specProvider);

            /* validation */
            var headerValidator = new HeaderValidator(
                difficultyCalculator,
                _blockTree,
                sealEngine,
                specProvider,
                _logManager);

            var ommersValidator = new OmmersValidator(
                _blockTree,
                headerValidator,
                _logManager);

            var txValidator = new TransactionValidator(
                new SignatureValidator(specProvider.ChainId));

            var blockValidator = new BlockValidator(
                txValidator,
                headerValidator,
                ommersValidator,
                specProvider,
                _logManager);

            /* state */
            var dbProvider = new RocksDbProvider(
                _dbBasePath,
                _logManager,
                dbConfig);

            var stateDb = dbProvider.GetOrCreateStateDb();

            var stateTree = new StateTree(stateDb);

            var stateProvider = new StateProvider(
                stateTree,
                dbProvider.GetOrCreateCodeDb(),
                _logManager);

            var storageProvider = new StorageProvider(
                dbProvider,
                stateProvider,
                _logManager);

            /* blockchain processing */
            var blockhashProvider = new BlockhashProvider(
                _blockTree);

            var virtualMachine = new VirtualMachine(
                stateProvider,
                storageProvider,
                blockhashProvider,
                _logManager);

            var transactionProcessor = new TransactionProcessor(
                specProvider,
                stateProvider,
                storageProvider,
                virtualMachine,
                _tracer,
                _logManager);

            var rewardCalculator = new RewardCalculator(
                specProvider);

            var blockProcessor = new BlockProcessor(
                specProvider,
                blockValidator,
                rewardCalculator,
                transactionProcessor,
                dbProvider,
                stateProvider,
                storageProvider,
                transactionStore,
                _logManager);

            _blockchainProcessor = new BlockchainProcessor(
                _blockTree,
                sealEngine,
                transactionStore,
                difficultyCalculator,
                blockProcessor,
                ethereumSigner,
                _logManager, _perfService);

            // create shared objects between discovery and peer manager
            _nodeFactory       = new NodeFactory();
            _nodeStatsProvider = new NodeStatsProvider(_configProvider.GetConfig <IStatsConfig>(), _nodeFactory, _logManager);

            var jsonSerializer = new JsonSerializer(
                _logManager);

            var encrypter = new AesEncrypter(
                _configProvider,
                _logManager);

            _keyStore = new FileKeyStore(
                _configProvider,
                jsonSerializer,
                encrypter,
                _cryptoRandom,
                _logManager);

            //creating blockchain bridge
            BlockchainBridge = new BlockchainBridge(
                ethereumSigner,
                stateProvider,
                _keyStore,
                _blockTree,
                stateDb,
                transactionStore);

            EthereumSigner = ethereumSigner;

            _blockchainProcessor.Start();
            LoadGenesisBlock(chainSpec,
                             string.IsNullOrWhiteSpace(_initConfig.GenesisHash) ? null : new Keccak(_initConfig.GenesisHash),
                             _blockTree, stateProvider, specProvider);

#pragma warning disable 4014
            LoadBlocksFromDb();
#pragma warning restore 4014

            await InitializeNetwork(
                transactionStore,
                blockValidator,
                headerValidator,
                txValidator);
        }
Exemplo n.º 6
0
        protected virtual Task InitBlockchain()
        {
            var(_get, _set) = _api.ForBlockchain;

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

            ILogger     logger     = _get.LogManager.GetClassLogger();
            IInitConfig initConfig = _get.Config <IInitConfig>();
            ISyncConfig syncConfig = _get.Config <ISyncConfig>();

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

            Account.AccountStartNonce = _get.ChainSpec.Parameters.AccountStartNonce;

            var stateProvider = _set.StateProvider = new StateProvider(
                _get.DbProvider.StateDb,
                _get.DbProvider.CodeDb,
                _get.LogManager);

            ReadOnlyDbProvider readOnly = new ReadOnlyDbProvider(_api.DbProvider, false);
            var stateReader             = _set.StateReader = new StateReader(
                readOnly.GetDb <ISnapshotableDb>(DbNames.State),
                readOnly.GetDb <ISnapshotableDb>(DbNames.Code),
                _api.LogManager);

            _set.ChainHeadStateProvider = new ChainHeadReadOnlyStateProvider(_get.BlockTree, stateReader);

            PersistentTxStorage txStorage = new PersistentTxStorage(_get.DbProvider.PendingTxsDb);

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

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

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

            _get.DisposeStack.Push(onChainTxWatcher);

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

            var storageProvider = _set.StorageProvider = new StorageProvider(
                _get.DbProvider.StateDb,
                stateProvider,
                _get.LogManager);

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

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

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

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

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

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

            TxValidator txValidator = new TxValidator(_get.SpecProvider.ChainId);

            var blockValidator = _set.BlockValidator = new BlockValidator(
                txValidator,
                headerValidator,
                ommersValidator,
                _get.SpecProvider,
                _get.LogManager);

            _set.StateReader        = new StateReader(readOnly.GetDb <ISnapshotableDb>(DbNames.State), readOnly.GetDb <ISnapshotableDb>(DbNames.Code), _api.LogManager);
            _set.TxPoolInfoProvider = new TxPoolInfoProvider(_api.StateReader, _api.TxPool);

            var mainBlockProcessor = _set.MainBlockProcessor = CreateBlockProcessor();

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

            _set.BlockProcessingQueue = blockchainProcessor;
            _set.BlockchainProcessor  = blockchainProcessor;

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

                _api.DisposeStack.Push(beamBlockchainProcessor);
            }

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

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

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

            _set.FilterManager = new FilterManager(filterStore, mainBlockProcessor, txPool, _get.LogManager);

            return(Task.CompletedTask);
        }
Exemplo n.º 7
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  = new MemDbProvider();
            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, logManager);
            var txPool            = new TxPool.TxPool(new InMemoryTxStorage(), Timestamper.Default, ecdsa, specProvider, new TxPoolConfig(), stateProvider, logManager);
            var tree              = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, txPool, 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 TxSignaturesRecoveryStep(ecdsa, txPool, logManager);
            var processor = new BlockchainProcessor(tree, blockProcessor, step, logManager, true);

            var nodeStatsManager = new NodeStatsManager(new StatsConfig(), 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, false);
            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);
        }
Exemplo n.º 8
0
        // 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(TestItem.AddressA, 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.ChainId, 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);
            ITimestamper         timestamper          = Timestamper.Default;
            DifficultyCalculator difficultyCalculator = new DifficultyCalculator(specProvider);
            HeaderValidator      headerValidator      = new HeaderValidator(blockTree, sealer, specProvider, logManager);
            OmmersValidator      ommersValidator      = new OmmersValidator(blockTree, headerValidator, logManager);
            TxValidator          txValidator          = new TxValidator(specProvider.ChainId);
            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, BlockchainProcessor.Options.NoReceipts);

            /* 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");
        }
Exemplo n.º 9
0
        private async Task InitBlockchain()
        {
            _specProvider = new ChainSpecBasedSpecProvider(_chainSpec);

            Account.AccountStartNonce = _chainSpec.Parameters.AccountStartNonce;

            /* sync */
            IDbConfig dbConfig = _configProvider.GetConfig <IDbConfig>();

            _syncConfig = _configProvider.GetConfig <ISyncConfig>();

            foreach (PropertyInfo propertyInfo in typeof(IDbConfig).GetProperties())
            {
                if (_logger.IsDebug)
                {
                    _logger.Debug($"DB {propertyInfo.Name}: {propertyInfo.GetValue(dbConfig)}");
                }
            }

            _dbProvider = HiveEnabled
                ? (IDbProvider) new MemDbProvider()
                : new RocksDbProvider(_initConfig.BaseDbPath, dbConfig, _logManager, _initConfig.StoreTraces, _initConfig.StoreReceipts || _syncConfig.DownloadReceiptsInFastSync);

            // IDbProvider debugRecorder = new RocksDbProvider(Path.Combine(_initConfig.BaseDbPath, "debug"), dbConfig, _logManager, _initConfig.StoreTraces, _initConfig.StoreReceipts);
            // _dbProvider = new RpcDbProvider(_jsonSerializer, new BasicJsonRpcClient(KnownRpcUris.Localhost, _jsonSerializer, _logManager), _logManager, debugRecorder);

            // IDbProvider debugReader = new ReadOnlyDbProvider(new RocksDbProvider(Path.Combine(_initConfig.BaseDbPath, "debug"), dbConfig, _logManager, _initConfig.StoreTraces, _initConfig.StoreReceipts), false);
            // _dbProvider = debugReader;

            _stateProvider = new StateProvider(
                _dbProvider.StateDb,
                _dbProvider.CodeDb,
                _logManager);

            _ethereumEcdsa = new EthereumEcdsa(_specProvider, _logManager);
            _txPool        = new TxPool(
                new PersistentTxStorage(_dbProvider.PendingTxsDb, _specProvider),
                Timestamper.Default,
                _ethereumEcdsa,
                _specProvider,
                _txPoolConfig, _stateProvider, _logManager);
            var _rc7FixDb = _initConfig.EnableRc7Fix ? _dbProvider.HeadersDb : NullDb.Instance;

            _receiptStorage = new PersistentReceiptStorage(_dbProvider.ReceiptsDb, _rc7FixDb, _specProvider, _logManager);

            _blockTree = new BlockTree(
                _dbProvider.BlocksDb,
                _dbProvider.HeadersDb,
                _dbProvider.BlockInfosDb,
                _specProvider,
                _txPool,
                _syncConfig,
                _logManager);

            _recoveryStep = new TxSignaturesRecoveryStep(_ethereumEcdsa, _txPool, _logManager);

            _snapshotManager = null;


            _storageProvider = new StorageProvider(
                _dbProvider.StateDb,
                _stateProvider,
                _logManager);

            IList <IAdditionalBlockProcessor> blockPreProcessors = new List <IAdditionalBlockProcessor>();
            // blockchain processing
            var blockhashProvider = new BlockhashProvider(
                _blockTree, _logManager);

            var virtualMachine = new VirtualMachine(
                _stateProvider,
                _storageProvider,
                blockhashProvider,
                _specProvider,
                _logManager);

            _transactionProcessor = new TransactionProcessor(
                _specProvider,
                _stateProvider,
                _storageProvider,
                virtualMachine,
                _logManager);

            InitSealEngine(blockPreProcessors);

            /* validation */
            _headerValidator = new HeaderValidator(
                _blockTree,
                _sealValidator,
                _specProvider,
                _logManager);

            var ommersValidator = new OmmersValidator(
                _blockTree,
                _headerValidator,
                _logManager);

            var txValidator = new TxValidator(_specProvider.ChainId);

            _blockValidator = new BlockValidator(
                txValidator,
                _headerValidator,
                ommersValidator,
                _specProvider,
                _logManager);

            _txPoolInfoProvider = new TxPoolInfoProvider(_stateProvider, _txPool);

            _blockProcessor = new BlockProcessor(
                _specProvider,
                _blockValidator,
                _rewardCalculator,
                _transactionProcessor,
                _dbProvider.StateDb,
                _dbProvider.CodeDb,
                _dbProvider.TraceDb,
                _stateProvider,
                _storageProvider,
                _txPool,
                _receiptStorage,
                _logManager,
                blockPreProcessors);

            _blockchainProcessor = new BlockchainProcessor(
                _blockTree,
                _blockProcessor,
                _recoveryStep,
                _logManager,
                _initConfig.StoreReceipts,
                _initConfig.StoreTraces);

            // create shared objects between discovery and peer manager
            IStatsConfig statsConfig = _configProvider.GetConfig <IStatsConfig>();

            _nodeStatsManager = new NodeStatsManager(statsConfig, _logManager);

            InitBlockProducers();

            _blockchainProcessor.Start();
            LoadGenesisBlock(string.IsNullOrWhiteSpace(_initConfig.GenesisHash) ? null : new Keccak(_initConfig.GenesisHash));
            if (_initConfig.ProcessingEnabled)
            {
#pragma warning disable 4014
                RunBlockTreeInitTasks();
#pragma warning restore 4014
            }
            else
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Shutting down the blockchain processor due to {nameof(InitConfig)}.{nameof(InitConfig.ProcessingEnabled)} set to false");
                }
                await _blockchainProcessor.StopAsync();
            }

            if (HiveEnabled)
            {
                await InitHive();
            }

            var producers = new List <IProducer>();

            var kafkaConfig = _configProvider.GetConfig <IKafkaConfig>();
            if (kafkaConfig.Enabled)
            {
                var kafkaProducer = await PrepareKafkaProducer(_blockTree, _configProvider.GetConfig <IKafkaConfig>());

                producers.Add(kafkaProducer);
            }

            var grpcConfig = _configProvider.GetConfig <IGrpcConfig>();
            if (grpcConfig.Enabled && grpcConfig.ProducerEnabled)
            {
                var grpcProducer = new GrpcProducer(_grpcServer);
                producers.Add(grpcProducer);
            }

            ISubscription subscription;
            if (producers.Any())
            {
                subscription = new Subscription(producers, _blockProcessor, _logManager);
            }
            else
            {
                subscription = new EmptySubscription();
            }

            _disposeStack.Push(subscription);

            await InitializeNetwork();
        }
        public async Task Test()
        {
            TimeSpan miningDelay = TimeSpan.FromMilliseconds(50);

            /* logging & instrumentation */
            var logger = new OneLoggerLogManager(new SimpleConsoleLogger());

            /* spec */
            var sealEngine = new FakeSealEngine(miningDelay);

            sealEngine.IsMining = true;

            var specProvider = RopstenSpecProvider.Instance;

            /* store & validation */
            var blockTree            = new BlockTree(new MemDb(), new MemDb(), new MemDb(), specProvider, logger);
            var difficultyCalculator = new DifficultyCalculator(specProvider);
            var headerValidator      = new HeaderValidator(difficultyCalculator, blockTree, sealEngine, specProvider, logger);
            var ommersValidator      = new OmmersValidator(blockTree, headerValidator, logger);
            var transactionValidator = new TransactionValidator(new SignatureValidator(ChainId.Ropsten));
            var blockValidator       = new BlockValidator(transactionValidator, headerValidator, ommersValidator, specProvider, logger);

            /* state & storage */
            var codeDb            = new MemDb();
            var stateDb           = new MemDb();
            var stateTree         = new StateTree(stateDb);
            var stateProvider     = new StateProvider(stateTree, codeDb, logger);
            var storageDbProvider = new MemDbProvider(logger);
            var storageProvider   = new StorageProvider(storageDbProvider, stateProvider, logger);

            /* blockchain processing */
            var ethereumSigner      = new EthereumSigner(specProvider, logger);
            var transactionStore    = new TransactionStore();
            var blockhashProvider   = new BlockhashProvider(blockTree);
            var virtualMachine      = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, logger);
            var processor           = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, NullTracer.Instance, logger);
            var rewardCalculator    = new RewardCalculator(specProvider);
            var blockProcessor      = new BlockProcessor(specProvider, blockValidator, rewardCalculator, processor, storageDbProvider, stateProvider, storageProvider, transactionStore, logger);
            var blockchainProcessor = new BlockchainProcessor(blockTree, sealEngine, transactionStore, difficultyCalculator, blockProcessor, ethereumSigner, logger);

            /* load ChainSpec and init */
            ChainSpecLoader loader = new ChainSpecLoader(new UnforgivingJsonSerializer());
            string          path   = Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\..\Chains", "ropsten.json"));

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

            foreach (KeyValuePair <Address, BigInteger> allocation in chainSpec.Allocations)
            {
                stateProvider.CreateAccount(allocation.Key, allocation.Value);
            }

            stateProvider.Commit(specProvider.GenesisSpec);
            chainSpec.Genesis.Header.StateRoot = stateProvider.StateRoot; // TODO: shall it be HeaderSpec and not BlockHeader?
            chainSpec.Genesis.Header.Hash      = BlockHeader.CalculateHash(chainSpec.Genesis.Header);
            if (chainSpec.Genesis.Hash != new Keccak("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"))
            {
                throw new Exception("Unexpected genesis hash");
            }

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

            Thread.Sleep(miningDelay * 10);

            await blockchainProcessor.StopAsync(true).ContinueWith(
                t =>
            {
                if (t.IsFaulted)
                {
                    throw t.Exception;
                }

                Assert.GreaterOrEqual((int)blockTree.Head.Number, 6);
            });
        }
Exemplo n.º 11
0
        public void When_ommer_was_already_included_return_false()
        {
            OmmersValidator ommersValidator = new OmmersValidator(_blockTree, _headerValidator, LimboLogs.Instance);

            Assert.False(ommersValidator.Validate(_block.Header, new[] { _duplicateOmmer.Header }));
        }
Exemplo n.º 12
0
        protected async Task RunTest(BlockchainTest test, Stopwatch stopwatch = null)
        {
            Assert.IsNull(test.LoadFailure, "test data loading failure");

            // TODO: not supported in .NET Core, need to replace?
            // LoggingTraceListener traceListener = new LoggingTraceListener();
            // Debug.Listeners.Clear();
            // Debug.Listeners.Add(traceListener);

            ISnapshotableDb stateDb   = new StateDb();
            ISnapshotableDb codeDb    = new StateDb();
            IDb             traceDb   = new MemDb();
            StateTree       stateTree = new StateTree(stateDb);


            ISpecProvider specProvider;

            if (test.NetworkAfterTransition != null)
            {
                specProvider = new CustomSpecProvider(
                    (0, Frontier.Instance),
                    (1, test.Network),
                    (test.TransitionBlockNumber, test.NetworkAfterTransition));
            }
            else
            {
                specProvider = new CustomSpecProvider(
                    (0, Frontier.Instance), // TODO: this thing took a lot of time to find after it was removed!, genesis block is always initialized with Frontier
                    (1, test.Network));
            }

            if (specProvider.GenesisSpec != Frontier.Instance)
            {
                Assert.Fail("Expected genesis spec to be Frontier for blockchain tests");
            }

            DifficultyCalculator.Wrapped = new DifficultyCalculator(specProvider);
            IRewardCalculator rewardCalculator = new RewardCalculator(specProvider);


            IEthereumEcdsa   ecdsa           = new EthereumEcdsa(specProvider, _logManager);
            ITransactionPool transactionPool = new TransactionPool(NullTransactionStorage.Instance,
                                                                   new PendingTransactionThresholdValidator(), new Timestamp(), ecdsa, specProvider, _logManager);

            IReceiptStorage       receiptStorage       = NullReceiptStorage.Instance;
            IBlockTree            blockTree            = new BlockTree(new MemDb(), new MemDb(), specProvider, transactionPool, _logManager);
            IBlockhashProvider    blockhashProvider    = new BlockhashProvider(blockTree);
            ISignatureValidator   signatureValidator   = new SignatureValidator(ChainId.MainNet);
            ITransactionValidator transactionValidator = new TransactionValidator(signatureValidator);
            IHeaderValidator      headerValidator      = new HeaderValidator(blockTree, Sealer, specProvider, _logManager);
            IOmmersValidator      ommersValidator      = new OmmersValidator(blockTree, headerValidator, _logManager);
            IBlockValidator       blockValidator       = new BlockValidator(transactionValidator, headerValidator, ommersValidator, specProvider, _logManager);
            IStateProvider        stateProvider        = new StateProvider(stateTree, codeDb, _logManager);
            IStorageProvider      storageProvider      = new StorageProvider(stateDb, stateProvider, _logManager);
            IVirtualMachine       virtualMachine       = new VirtualMachine(
                stateProvider,
                storageProvider,
                blockhashProvider,
                _logManager);

            IBlockProcessor blockProcessor = new BlockProcessor(
                specProvider,
                blockValidator,
                rewardCalculator,
                new TransactionProcessor(
                    specProvider,
                    stateProvider,
                    storageProvider,
                    virtualMachine,
                    _logManager),
                stateDb,
                codeDb,
                traceDb,
                stateProvider,
                storageProvider,
                transactionPool,
                receiptStorage,
                _logManager);

            IBlockchainProcessor blockchainProcessor = new BlockchainProcessor(
                blockTree,
                blockProcessor,
                new TxSignaturesRecoveryStep(ecdsa, NullTransactionPool.Instance),
                _logManager,
                false,
                false);

            InitializeTestState(test, stateProvider, storageProvider, specProvider);

            List <(Block Block, string ExpectedException)> correctRlpsBlocks = new List <(Block, string)>();

            for (int i = 0; i < test.Blocks.Length; i++)
            {
                try
                {
                    TestBlockJson testBlockJson  = test.Blocks[i];
                    var           rlpContext     = Bytes.FromHexString(testBlockJson.Rlp).AsRlpContext();
                    Block         suggestedBlock = Rlp.Decode <Block>(rlpContext);
                    suggestedBlock.Header.SealEngineType = test.SealEngineUsed ? SealEngineType.Ethash : SealEngineType.None;

                    Assert.AreEqual(new Keccak(testBlockJson.BlockHeader.Hash), suggestedBlock.Header.Hash, "hash of the block");
                    for (int ommerIndex = 0; ommerIndex < suggestedBlock.Ommers.Length; ommerIndex++)
                    {
                        Assert.AreEqual(new Keccak(testBlockJson.UncleHeaders[ommerIndex].Hash), suggestedBlock.Ommers[ommerIndex].Hash, "hash of the ommer");
                    }

                    correctRlpsBlocks.Add((suggestedBlock, testBlockJson.ExpectedException));
                }
                catch (Exception)
                {
                    _logger?.Info($"Invalid RLP ({i})");
                }
            }

            if (correctRlpsBlocks.Count == 0)
            {
                Assert.AreEqual(new Keccak(test.GenesisBlockHeader.Hash), test.LastBlockHash);
                return;
            }

            if (test.GenesisRlp == null)
            {
                test.GenesisRlp = Rlp.Encode(new Block(Convert(test.GenesisBlockHeader)));
            }

            Block genesisBlock = Rlp.Decode <Block>(test.GenesisRlp.Bytes);

            Assert.AreEqual(new Keccak(test.GenesisBlockHeader.Hash), genesisBlock.Header.Hash, "genesis header hash");

            ManualResetEvent genesisProcessed = new ManualResetEvent(false);

            blockTree.NewHeadBlock += (sender, args) =>
            {
                if (args.Block.Number == 0)
                {
                    Assert.AreEqual(genesisBlock.Header.StateRoot, stateTree.RootHash, "genesis state root");
                    genesisProcessed.Set();
                }
            };

            blockchainProcessor.Start();
            blockTree.SuggestBlock(genesisBlock);

            genesisProcessed.WaitOne();

            for (int i = 0; i < correctRlpsBlocks.Count; i++)
            {
                stopwatch?.Start();
                try
                {
                    if (correctRlpsBlocks[i].ExpectedException != null)
                    {
                        _logger.Info($"Expecting block exception: {correctRlpsBlocks[i].ExpectedException}");
                    }

                    if (correctRlpsBlocks[i].Block.Hash == null)
                    {
                        throw new Exception($"null hash in {test.Name} block {i}");
                    }

                    // TODO: mimic the actual behaviour where block goes through validating sync manager?
                    if (!test.SealEngineUsed || blockValidator.ValidateSuggestedBlock(correctRlpsBlocks[i].Block))
                    {
                        blockTree.SuggestBlock(correctRlpsBlocks[i].Block);
                    }
                    else
                    {
                        Console.WriteLine("Invalid block");
                    }
                }
                catch (InvalidBlockException)
                {
                }
                catch (Exception ex)
                {
                    _logger?.Info(ex.ToString());
                }
            }

            await blockchainProcessor.StopAsync(true);

            stopwatch?.Stop();

            List <string> differences = RunAssertions(test, blockTree.RetrieveHeadBlock(), storageProvider, stateProvider);

//            if (differences.Any())
//            {
//                BlockTrace blockTrace = blockchainProcessor.TraceBlock(blockTree.BestSuggested.Hash);
//                _logger.Info(new UnforgivingJsonSerializer().Serialize(blockTrace, true));
//            }

            Assert.Zero(differences.Count, "differences");
        }
Exemplo n.º 13
0
        private Task InitBlockchain()
        {
            if (_context.ChainSpec == null)
            {
                throw new StepDependencyException(nameof(_context.ChainSpec));
            }
            if (_context.DbProvider == null)
            {
                throw new StepDependencyException(nameof(_context.DbProvider));
            }
            if (_context.SpecProvider == null)
            {
                throw new StepDependencyException(nameof(_context.SpecProvider));
            }

            ILogger     logger     = _context.LogManager.GetClassLogger();
            IInitConfig initConfig = _context.Config <IInitConfig>();
            ISyncConfig syncConfig = _context.Config <ISyncConfig>();

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

            Account.AccountStartNonce = _context.ChainSpec.Parameters.AccountStartNonce;

            _context.StateProvider = new StateProvider(
                _context.DbProvider.StateDb,
                _context.DbProvider.CodeDb,
                _context.LogManager);

            _context.EthereumEcdsa = new EthereumEcdsa(_context.SpecProvider, _context.LogManager);
            _context.TxPool        = new TxPool.TxPool(
                new PersistentTxStorage(_context.DbProvider.PendingTxsDb, _context.SpecProvider),
                Timestamper.Default,
                _context.EthereumEcdsa,
                _context.SpecProvider,
                _context.Config <ITxPoolConfig>(),
                _context.StateProvider,
                _context.LogManager);

            var bloomConfig = _context.Config <IBloomConfig>();

            var fileStoreFactory = initConfig.DiagnosticMode == DiagnosticMode.MemDb
                ? (IFileStoreFactory) new InMemoryDictionaryFileStoreFactory()
                : new FixedSizeFileStoreFactory(Path.Combine(initConfig.BaseDbPath, DbNames.Bloom), DbNames.Bloom, Bloom.ByteLength);

            _context.BloomStorage = bloomConfig.Index
                ? new BloomStorage(bloomConfig, _context.DbProvider.BloomDb, fileStoreFactory)
                : (IBloomStorage)NullBloomStorage.Instance;

            _context.DisposeStack.Push(_context.BloomStorage);

            _context.ChainLevelInfoRepository = new ChainLevelInfoRepository(_context.DbProvider.BlockInfosDb);

            _context.BlockTree = new BlockTree(
                _context.DbProvider.BlocksDb,
                _context.DbProvider.HeadersDb,
                _context.DbProvider.BlockInfosDb,
                _context.ChainLevelInfoRepository,
                _context.SpecProvider,
                _context.TxPool,
                _context.BloomStorage,
                _context.Config <ISyncConfig>(),
                _context.LogManager);

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

            _context.ReceiptStorage = initConfig.StoreReceipts ? (IReceiptStorage?)new PersistentReceiptStorage(_context.DbProvider.ReceiptsDb, _context.SpecProvider, new ReceiptsRecovery()) : NullReceiptStorage.Instance;
            _context.ReceiptFinder  = new FullInfoReceiptFinder(_context.ReceiptStorage, new ReceiptsRecovery(), _context.BlockTree);

            _context.RecoveryStep = new TxSignaturesRecoveryStep(_context.EthereumEcdsa, _context.TxPool, _context.LogManager);

            _context.StorageProvider = new StorageProvider(
                _context.DbProvider.StateDb,
                _context.StateProvider,
                _context.LogManager);

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

            VirtualMachine virtualMachine = new VirtualMachine(
                _context.StateProvider,
                _context.StorageProvider,
                blockhashProvider,
                _context.SpecProvider,
                _context.LogManager);

            _context.TransactionProcessor = new TransactionProcessor(
                _context.SpecProvider,
                _context.StateProvider,
                _context.StorageProvider,
                virtualMachine,
                _context.LogManager);

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

            /* validation */
            _context.HeaderValidator = CreateHeaderValidator();

            OmmersValidator ommersValidator = new OmmersValidator(
                _context.BlockTree,
                _context.HeaderValidator,
                _context.LogManager);

            TxValidator txValidator = new TxValidator(_context.SpecProvider.ChainId);

            _context.BlockValidator = new BlockValidator(
                txValidator,
                _context.HeaderValidator,
                ommersValidator,
                _context.SpecProvider,
                _context.LogManager);

            ReadOnlyDbProvider readOnly    = new ReadOnlyDbProvider(_context.DbProvider, false);
            StateReader        stateReader = new StateReader(readOnly.StateDb, readOnly.CodeDb, _context.LogManager);

            _context.TxPoolInfoProvider = new TxPoolInfoProvider(stateReader, _context.TxPool);

            _context.MainBlockProcessor = CreateBlockProcessor();

            BlockchainProcessor blockchainProcessor = new BlockchainProcessor(
                _context.BlockTree,
                _context.MainBlockProcessor,
                _context.RecoveryStep,
                _context.LogManager,
                initConfig.StoreReceipts,
                !syncConfig.BeamSync);

            _context.BlockProcessingQueue = blockchainProcessor;
            _context.BlockchainProcessor  = blockchainProcessor;

            if (syncConfig.BeamSync)
            {
                BeamBlockchainProcessor beamBlockchainProcessor = new BeamBlockchainProcessor(
                    new ReadOnlyDbProvider(_context.DbProvider, false),
                    _context.BlockTree,
                    _context.SpecProvider,
                    _context.LogManager,
                    _context.BlockValidator,
                    _context.RecoveryStep,
                    _context.RewardCalculatorSource,
                    _context.BlockProcessingQueue,
                    _context.BlockchainProcessor,
                    _context.SyncModeSelector);

                _context.DisposeStack.Push(beamBlockchainProcessor);
            }

            ThisNodeInfo.AddInfo("Mem est trie :", $"{LruCache<Keccak, byte[]>.CalculateMemorySize(52 + 320, Trie.MemoryAllowance.TrieNodeCacheSize) / 1024 / 1024}MB".PadLeft(8));

            return(Task.CompletedTask);
        }
Exemplo n.º 14
0
        private SyncTestContext CreateSyncManager(int index)
        {
            Rlp.RegisterDecoders(typeof(ParityTraceDecoder).Assembly);

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

            MemDb   blockDb     = new MemDb();
            MemDb   headerDb    = new MemDb();
            MemDb   blockInfoDb = new MemDb();
            StateDb codeDb      = new StateDb();
            StateDb stateDb     = new StateDb();

            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, logManager);
            var txPool            = new TxPool.TxPool(new InMemoryTxStorage(), new Timestamper(), ecdsa, specProvider, new TxPoolConfig(), stateProvider, logManager);
            var tree              = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, txPool, NullBloomStorage.Instance, logManager);
            var blockhashProvider = new BlockhashProvider(tree, LimboLogs.Instance);
            var virtualMachine    = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, specProvider, logManager);

            var sealValidator   = TestSealValidator.AlwaysValid;
            var headerValidator = new HeaderValidator(tree, sealValidator, specProvider, logManager);
            var txValidator     = TestTxValidator.AlwaysValid;
            var ommersValidator = new OmmersValidator(tree, headerValidator, logManager);
            var blockValidator  = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, logManager);
//            var blockValidator = TestBlockValidator.AlwaysValid;

            SyncConfig syncConfig = new SyncConfig();

            syncConfig.FastSync = _synchronizerType == SynchronizerType.Fast;

            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 TxSignaturesRecoveryStep(ecdsa, txPool, logManager);
            var processor = new BlockchainProcessor(tree, blockProcessor, step, logManager, true);

            var nodeStatsManager = new NodeStatsManager(new StatsConfig(), logManager);
            var syncPeerPool     = new EthSyncPeerPool(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, false);
            var             transactionSelector = new PendingTxSelector(txPool, stateProvider, logManager);
            var             producer            = new DevBlockProducer(transactionSelector, devChainProcessor, stateProvider, tree, processor, txPool, new Timestamper(), logManager);

            NodeDataFeed       feed         = new NodeDataFeed(codeDb, stateDb, logManager);
            NodeDataDownloader downloader   = new NodeDataDownloader(syncPeerPool, feed, NullDataConsumer.Instance, logManager);
            Synchronizer       synchronizer = new Synchronizer(
                MainNetSpecProvider.Instance,
                tree,
                NullReceiptStorage.Instance,
                blockValidator,
                sealValidator,
                syncPeerPool, syncConfig, downloader, nodeStatsManager, logManager);
            var syncServer = new SyncServer(stateDb, codeDb, tree, receiptStorage, TestBlockValidator.AlwaysValid, TestSealValidator.AlwaysValid, syncPeerPool, synchronizer, 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);
        }