public static INdmBlockchainBridge BuildABridge() { MemDbProvider memDbProvider = new MemDbProvider(); StateReader stateReader = new StateReader(memDbProvider.StateDb, memDbProvider.CodeDb, LimboLogs.Instance); StateProvider stateProvider = new StateProvider(memDbProvider.StateDb, memDbProvider.CodeDb, LimboLogs.Instance); IEthereumEcdsa ecdsa = new EthereumEcdsa(ChainId.Mainnet, LimboLogs.Instance); ITxPool txPool = new TxPool.TxPool(new InMemoryTxStorage(), ecdsa, MainnetSpecProvider.Instance, new TxPoolConfig(), stateProvider, LimboLogs.Instance); BlockTree blockTree = Build.A.BlockTree().OfChainLength(1).TestObject; IWallet wallet = new DevWallet(new WalletConfig(), LimboLogs.Instance); ReceiptsRecovery receiptsRecovery = new ReceiptsRecovery(ecdsa, MainnetSpecProvider.Instance); LogFinder logFinder = new LogFinder(blockTree, new InMemoryReceiptStorage(), NullBloomStorage.Instance, LimboLogs.Instance, receiptsRecovery, 1024); ReadOnlyTxProcessingEnv processingEnv = new ReadOnlyTxProcessingEnv( new ReadOnlyDbProvider(memDbProvider, false), new ReadOnlyBlockTree(blockTree), MainnetSpecProvider.Instance, LimboLogs.Instance); BlockchainBridge blockchainBridge = new BlockchainBridge( processingEnv, txPool, new InMemoryReceiptStorage(), NullFilterStore.Instance, NullFilterManager.Instance, ecdsa, Timestamper.Default, logFinder, false, false); WalletTxSigner txSigner = new WalletTxSigner(wallet, ChainId.Mainnet); ITxSealer txSealer0 = new TxSealer(txSigner, Timestamper.Default); ITxSealer txSealer1 = new NonceReservingTxSealer(txSigner, Timestamper.Default, txPool); ITxSender txSender = new TxPoolSender(txPool, txSealer0, txSealer1); return(new NdmBlockchainBridge(blockchainBridge, blockTree, stateReader, txSender)); }
private void ResetMigrationIndexIfNeeded() { ReceiptsRecovery recovery = new ReceiptsRecovery(); if (_receiptStorage.MigratedBlockNumber != long.MaxValue) { var blockNumber = _blockTree.Head?.Number ?? 0; while (blockNumber > 0) { var level = _chainLevelInfoRepository.LoadLevel(blockNumber); var firstBlockInfo = level?.BlockInfos.FirstOrDefault(); if (firstBlockInfo != null) { var receipts = _receiptStorage.Get(firstBlockInfo.BlockHash); if (receipts?.Length > 0) { if (recovery.NeedRecover(receipts)) { _receiptStorage.MigratedBlockNumber = long.MaxValue; } break; } } blockNumber--; } } }
private void ResetMigrationIndexIfNeeded() { ReceiptsRecovery recovery = new ReceiptsRecovery(_api.EthereumEcdsa, _api.SpecProvider); if (_receiptStorage.MigratedBlockNumber != long.MaxValue) { long blockNumber = _blockTree.Head?.Number ?? 0; while (blockNumber > 0) { ChainLevelInfo?level = _chainLevelInfoRepository.LoadLevel(blockNumber); BlockInfo? firstBlockInfo = level?.BlockInfos.FirstOrDefault(); if (firstBlockInfo != null) { TxReceipt[] receipts = _receiptStorage.Get(firstBlockInfo.BlockHash); if (receipts.Length > 0) { if (recovery.NeedRecover(receipts)) { _receiptStorage.MigratedBlockNumber = long.MaxValue; } break; } } blockNumber--; } } }
public Task Execute(CancellationToken cancellationToken) { IInitConfig initConfig = _get.Config <IInitConfig>(); IBloomConfig bloomConfig = _get.Config <IBloomConfig>(); IFileStoreFactory fileStoreFactory = initConfig.DiagnosticMode == DiagnosticMode.MemDb ? (IFileStoreFactory) new InMemoryDictionaryFileStoreFactory() : new FixedSizeFileStoreFactory(Path.Combine(initConfig.BaseDbPath, DbNames.Bloom), DbNames.Bloom, Bloom.ByteLength); var bloomStorage = _set.BloomStorage = bloomConfig.Index ? new BloomStorage(bloomConfig, _get.DbProvider !.BloomDb, fileStoreFactory) : (IBloomStorage)NullBloomStorage.Instance; _get.DisposeStack.Push(bloomStorage); var chainLevelInfoRepository = _set.ChainLevelInfoRepository = new ChainLevelInfoRepository(_get.DbProvider !.BlockInfosDb); var blockTree = _set.BlockTree = new BlockTree( _get.DbProvider, chainLevelInfoRepository, _get.SpecProvider, bloomStorage, _get.Config <ISyncConfig>(), _get.LogManager); ISigner signer = NullSigner.Instance; ISignerStore signerStore = NullSigner.Instance; if (_get.Config <IMiningConfig>().Enabled) { Signer signerAndStore = new Signer(_get.SpecProvider !.ChainId, _get.OriginalSignerKey, _get.LogManager); signer = signerAndStore; signerStore = signerAndStore; } _set.EngineSigner = signer; _set.EngineSignerStore = signerStore; ReceiptsRecovery receiptsRecovery = new ReceiptsRecovery(_get.EthereumEcdsa, _get.SpecProvider); var receiptStorage = _set.ReceiptStorage = initConfig.StoreReceipts ? (IReceiptStorage?)new PersistentReceiptStorage(_get.DbProvider.ReceiptsDb, _get.SpecProvider, receiptsRecovery) : NullReceiptStorage.Instance; var receiptFinder = _set.ReceiptFinder = new FullInfoReceiptFinder(receiptStorage, receiptsRecovery, blockTree); LogFinder logFinder = new LogFinder( blockTree, receiptFinder, bloomStorage, _get.LogManager, new ReceiptsRecovery(_get.EthereumEcdsa, _get.SpecProvider), 1024); _set.LogFinder = logFinder; return(Task.CompletedTask); }
public void Setup() { _specProvider = RopstenSpecProvider.Instance; _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); ReceiptsRecovery receiptsRecovery = new ReceiptsRecovery(_ethereumEcdsa, _specProvider); _persistentStorage = new PersistentReceiptStorage(new MemColumnsDb <ReceiptsColumns>(), _specProvider, receiptsRecovery); _inMemoryStorage = new InMemoryReceiptStorage(); }
public void SetUp() { var specProvider = RopstenSpecProvider.Instance; var ethereumEcdsa = new EthereumEcdsa(specProvider.ChainId, LimboLogs.Instance); ReceiptsRecovery receiptsRecovery = new ReceiptsRecovery(ethereumEcdsa, specProvider); _receiptsDb = new MemColumnsDb <ReceiptsColumns>(); _storage = new PersistentReceiptStorage(_receiptsDb, MainnetSpecProvider.Instance, receiptsRecovery) { MigratedBlockNumber = 0 }; _receiptsDb.GetColumnDb(ReceiptsColumns.Blocks).Set(Keccak.Zero, Array.Empty <byte>()); }
public static INdmBlockchainBridge BuildABridge() { IDbProvider memDbProvider = TestMemDbProvider.Init(); StateReader stateReader = new StateReader( new TrieStore(memDbProvider.StateDb, LimboLogs.Instance), memDbProvider.CodeDb, LimboLogs.Instance); var trieStore = new TrieStore(memDbProvider.StateDb, LimboLogs.Instance); StateProvider stateProvider = new StateProvider(trieStore, memDbProvider.CodeDb, LimboLogs.Instance); IEthereumEcdsa ecdsa = new EthereumEcdsa(ChainId.Mainnet, LimboLogs.Instance); BlockTree blockTree = Build.A.BlockTree().OfChainLength(1).TestObject; MainnetSpecProvider specProvider = MainnetSpecProvider.Instance; ITransactionComparerProvider transactionComparerProvider = new TransactionComparerProvider(MainnetSpecProvider.Instance, blockTree); ITxPool txPool = new TxPool.TxPool( ecdsa, new ChainHeadInfoProvider(specProvider, blockTree, stateProvider), new TxPoolConfig(), new TxValidator(specProvider.ChainId), LimboLogs.Instance, transactionComparerProvider.GetDefaultComparer()); IWallet wallet = new DevWallet(new WalletConfig(), LimboLogs.Instance); ReceiptsRecovery receiptsRecovery = new ReceiptsRecovery(ecdsa, specProvider); LogFinder logFinder = new LogFinder(blockTree, new InMemoryReceiptStorage(), NullBloomStorage.Instance, LimboLogs.Instance, receiptsRecovery, 1024); ReadOnlyTxProcessingEnv processingEnv = new ReadOnlyTxProcessingEnv( new ReadOnlyDbProvider(memDbProvider, false), new TrieStore(memDbProvider.StateDb, LimboLogs.Instance).AsReadOnly(memDbProvider.StateDb), new ReadOnlyBlockTree(blockTree), specProvider, LimboLogs.Instance); BlockchainBridge blockchainBridge = new BlockchainBridge( processingEnv, txPool, new InMemoryReceiptStorage(), NullFilterStore.Instance, NullFilterManager.Instance, ecdsa, Timestamper.Default, logFinder, specProvider, false); WalletTxSigner txSigner = new WalletTxSigner(wallet, ChainId.Mainnet); ITxSealer txSealer0 = new TxSealer(txSigner, Timestamper.Default); ITxSealer txSealer1 = new NonceReservingTxSealer(txSigner, Timestamper.Default, txPool); ITxSender txSender = new TxPoolSender(txPool, txSealer0, txSealer1); return(new NdmBlockchainBridge(blockchainBridge, blockTree, stateReader, txSender)); }
protected override async Task <TestBlockchain> Build(ISpecProvider specProvider = null, UInt256?initialValues = null) { BloomStorage bloomStorage = new BloomStorage(new BloomConfig(), new MemDb(), new InMemoryDictionaryFileStoreFactory()); specProvider ??= MainnetSpecProvider.Instance; await base.Build(specProvider, initialValues); IFilterStore filterStore = new FilterStore(); IFilterManager filterManager = new FilterManager(filterStore, BlockProcessor, TxPool, LimboLogs.Instance); ReceiptsRecovery receiptsRecovery = new ReceiptsRecovery(new EthereumEcdsa(specProvider.ChainId, LimboLogs.Instance), specProvider); LogFinder = new LogFinder(BlockTree, ReceiptStorage, bloomStorage, LimboLogs.Instance, receiptsRecovery); ReadOnlyTxProcessingEnv processingEnv = new ReadOnlyTxProcessingEnv( new ReadOnlyDbProvider(DbProvider, false), new TrieStore(DbProvider.StateDb, LimboLogs.Instance).AsReadOnly(), new ReadOnlyBlockTree(BlockTree), SpecProvider, LimboLogs.Instance); Bridge ??= new BlockchainBridge(processingEnv, TxPool, ReceiptStorage, filterStore, filterManager, EthereumEcdsa, Timestamper, LogFinder, SpecProvider, false, false); BlockFinder ??= BlockTree; ITxSigner txSigner = new WalletTxSigner(TestWallet, specProvider?.ChainId ?? 0); ITxSealer txSealer0 = new TxSealer(txSigner, Timestamper); ITxSealer txSealer1 = new NonceReservingTxSealer(txSigner, Timestamper, TxPool); TxSender ??= new TxPoolSender(TxPool, txSealer0, txSealer1); EthRpcModule = new EthRpcModule( new JsonRpcConfig(), Bridge, BlockFinder, StateReader, TxPool, TxSender, TestWallet, LimboLogs.Instance, SpecProvider); return(this); }
public async Task <long> DownloadBlocks(PeerInfo bestPeer, int numberOfLatestBlocksToBeIgnored, CancellationToken cancellation, BlockDownloaderOptions options = BlockDownloaderOptions.Process) { IReceiptsRecovery receiptsRecovery = new ReceiptsRecovery(); if (bestPeer == null) { string message = $"Not expecting best peer to be null inside the {nameof(BlockDownloader)}"; if (_logger.IsError) { _logger.Error(message); } throw new ArgumentNullException(message); } bool downloadReceipts = (options & BlockDownloaderOptions.DownloadReceipts) == BlockDownloaderOptions.DownloadReceipts; bool shouldProcess = (options & BlockDownloaderOptions.Process) == BlockDownloaderOptions.Process; bool shouldMoveToMain = (options & BlockDownloaderOptions.MoveToMain) == BlockDownloaderOptions.MoveToMain; int blocksSynced = 0; int ancestorLookupLevel = 0; long currentNumber = Math.Max(0, Math.Min(_blockTree.BestKnownNumber, bestPeer.HeadNumber - 1)); // pivot number - 6 for uncle validation // long currentNumber = Math.Max(Math.Max(0, pivotNumber - 6), Math.Min(_blockTree.BestKnownNumber, bestPeer.HeadNumber - 1)); while (bestPeer.TotalDifficulty > (_blockTree.BestSuggestedHeader?.TotalDifficulty ?? 0) && currentNumber <= bestPeer.HeadNumber) { if (_logger.IsDebug) { _logger.Debug($"Continue full sync with {bestPeer} (our best {_blockTree.BestKnownNumber})"); } long blocksLeft = bestPeer.HeadNumber - currentNumber - numberOfLatestBlocksToBeIgnored; int headersToRequest = (int)Math.Min(blocksLeft + 1, _syncBatchSize.Current); if (headersToRequest <= 1) { break; } headersToRequest = Math.Min(headersToRequest, bestPeer.MaxHeadersPerRequest()); if (_logger.IsTrace) { _logger.Trace($"Full sync request {currentNumber}+{headersToRequest} to peer {bestPeer} with {bestPeer.HeadNumber} blocks. Got {currentNumber} and asking for {headersToRequest} more."); } if (cancellation.IsCancellationRequested) { return(blocksSynced); // check before every heavy operation } BlockHeader[] headers = await RequestHeaders(bestPeer, cancellation, currentNumber, headersToRequest); BlockDownloadContext context = new BlockDownloadContext(_specProvider, bestPeer, headers, downloadReceipts, receiptsRecovery); if (cancellation.IsCancellationRequested) { return(blocksSynced); // check before every heavy operation } await RequestBodies(bestPeer, cancellation, context); if (downloadReceipts) { if (cancellation.IsCancellationRequested) { return(blocksSynced); // check before every heavy operation } await RequestReceipts(bestPeer, cancellation, context); } _sinceLastTimeout++; if (_sinceLastTimeout > 2) { _syncBatchSize.Expand(); } Block[] blocks = context.Blocks; Block blockZero = blocks[0]; if (context.FullBlocksCount > 0) { bool parentIsKnown = _blockTree.IsKnownBlock(blockZero.Number - 1, blockZero.ParentHash); if (!parentIsKnown) { ancestorLookupLevel++; if (ancestorLookupLevel >= _ancestorJumps.Length) { if (_logger.IsWarn) { _logger.Warn($"Could not find common ancestor with {bestPeer}"); } throw new EthSynchronizationException("Peer with inconsistent chain in sync"); } int ancestorJump = _ancestorJumps[ancestorLookupLevel] - _ancestorJumps[ancestorLookupLevel - 1]; currentNumber = currentNumber >= ancestorJump ? (currentNumber - ancestorJump) : 0L; continue; } } ancestorLookupLevel = 0; for (int blockIndex = 0; blockIndex < context.FullBlocksCount; blockIndex++) { if (cancellation.IsCancellationRequested) { if (_logger.IsTrace) { _logger.Trace("Peer sync cancelled"); } break; } Block currentBlock = blocks[blockIndex]; if (_logger.IsTrace) { _logger.Trace($"Received {currentBlock} from {bestPeer}"); } // can move this to block tree now? if (!_blockValidator.ValidateSuggestedBlock(currentBlock)) { throw new EthSynchronizationException($"{bestPeer} sent an invalid block {currentBlock.ToString(Block.Format.Short)}."); } if (HandleAddResult(bestPeer, currentBlock.Header, blockIndex == 0, _blockTree.SuggestBlock(currentBlock, shouldProcess))) { if (downloadReceipts) { for (int receiptIndex = 0; receiptIndex < (context.ReceiptsForBlocks[blockIndex]?.Length ?? 0); receiptIndex++) { _receiptStorage.Add(context.ReceiptsForBlocks[blockIndex][receiptIndex], true); } } blocksSynced++; } if (shouldMoveToMain) { _blockTree.UpdateMainChain(new[] { currentBlock }, false); } currentNumber += 1; } if (blocksSynced > 0) { _syncReport.FullSyncBlocksDownloaded.Update(_blockTree.BestSuggestedHeader?.Number ?? 0); _syncReport.FullSyncBlocksKnown = bestPeer.HeadNumber; } else { break; } } return(blocksSynced); }
private void Initialize(bool auRa = false) { ISpecProvider specProvider = MainnetSpecProvider.Instance; IEthereumEcdsa ethereumEcdsa = new EthereumEcdsa(specProvider, LimboLogs.Instance); ITxStorage txStorage = new InMemoryTxStorage(); _stateDb = new StateDb(); ISnapshotableDb codeDb = new StateDb(); IStateReader stateReader = new StateReader(_stateDb, codeDb, LimboLogs.Instance); _stateProvider = new StateProvider(_stateDb, codeDb, LimboLogs.Instance); _stateProvider.CreateAccount(TestItem.AddressA, 1000.Ether()); _stateProvider.CreateAccount(TestItem.AddressB, 1000.Ether()); _stateProvider.CreateAccount(TestItem.AddressC, 1000.Ether()); byte[] code = Bytes.FromHexString("0xabcd"); Keccak codeHash = Keccak.Compute(code); _stateProvider.UpdateCode(code); _stateProvider.UpdateCodeHash(TestItem.AddressA, codeHash, specProvider.GenesisSpec); IStorageProvider storageProvider = new StorageProvider(_stateDb, _stateProvider, LimboLogs.Instance); storageProvider.Set(new StorageCell(TestItem.AddressA, UInt256.One), Bytes.FromHexString("0xabcdef")); storageProvider.Commit(); _stateProvider.Commit(specProvider.GenesisSpec); _stateProvider.CommitTree(); ITxPool txPool = new TxPool.TxPool(txStorage, Timestamper.Default, ethereumEcdsa, specProvider, new TxPoolConfig(), _stateProvider, LimboLogs.Instance); IDb blockDb = new MemDb(); IDb headerDb = new MemDb(); IDb blockInfoDb = new MemDb(); IBlockTree blockTree = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockDb), specProvider, txPool, NullBloomStorage.Instance, LimboLogs.Instance); IReceiptStorage receiptStorage = new InMemoryReceiptStorage(); VirtualMachine virtualMachine = new VirtualMachine(_stateProvider, storageProvider, new BlockhashProvider(blockTree, LimboLogs.Instance), specProvider, LimboLogs.Instance); TransactionProcessor txProcessor = new TransactionProcessor(specProvider, _stateProvider, storageProvider, virtualMachine, LimboLogs.Instance); IBlockProcessor blockProcessor = new BlockProcessor(specProvider, Always.Valid, new RewardCalculator(specProvider), txProcessor, _stateDb, codeDb, _stateProvider, storageProvider, txPool, receiptStorage, LimboLogs.Instance); IFilterStore filterStore = new FilterStore(); IFilterManager filterManager = new FilterManager(filterStore, blockProcessor, txPool, LimboLogs.Instance); _blockchainBridge = new BlockchainBridge(stateReader, _stateProvider, storageProvider, blockTree, txPool, receiptStorage, filterStore, filterManager, NullWallet.Instance, txProcessor, ethereumEcdsa, NullBloomStorage.Instance, LimboLogs.Instance, false); BlockchainProcessor blockchainProcessor = new BlockchainProcessor(blockTree, blockProcessor, new TxSignaturesRecoveryStep(ethereumEcdsa, txPool, LimboLogs.Instance), LimboLogs.Instance, true); blockchainProcessor.Start(); ManualResetEventSlim resetEvent = new ManualResetEventSlim(false); blockTree.NewHeadBlock += (s, e) => { Console.WriteLine(e.Block.Header.Hash); if (e.Block.Number == 9) { resetEvent.Set(); } }; var genesisBlockBuilder = Build.A.Block.Genesis.WithStateRoot(new Keccak("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")); if (auRa) { genesisBlockBuilder.WithAura(0, new byte[65]); } Block genesis = genesisBlockBuilder.TestObject; blockTree.SuggestBlock(genesis); Block previousBlock = genesis; for (int i = 1; i < 10; i++) { List <Transaction> transactions = new List <Transaction>(); for (int j = 0; j < i; j++) { transactions.Add(Build.A.Transaction.WithNonce((UInt256)j).SignedAndResolved().TestObject); } BlockBuilder builder = Build.A.Block.WithNumber(i).WithParent(previousBlock).WithTransactions(transactions.ToArray()).WithStateRoot(new Keccak("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")); if (auRa) { builder.WithAura(i, i.ToByteArray()); } Block block = builder.TestObject; blockTree.SuggestBlock(block); previousBlock = block; } IReceiptsRecovery receiptsRecovery = new ReceiptsRecovery(); IReceiptFinder receiptFinder = new FullInfoReceiptFinder(receiptStorage, receiptsRecovery, blockTree); resetEvent.Wait(2000); _traceModule = new TraceModule(receiptFinder, new Tracer(_stateProvider, blockchainProcessor), _blockchainBridge); _blockTree = blockTree; }