public async Task Throws_on_incorrect_receipts_root() { InMemoryReceiptStorage inMemoryReceiptStorage = new InMemoryReceiptStorage(); BlockDownloader blockDownloader = new BlockDownloader(_blockTree, TestBlockValidator.AlwaysValid, TestSealValidator.AlwaysValid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); ISyncPeer syncPeer = Substitute.For <ISyncPeer>(); Task <BlockHeader[]> buildHeadersResponse = null; syncPeer.GetBlockHeaders(Arg.Any <long>(), Arg.Any <int>(), Arg.Any <int>(), Arg.Any <CancellationToken>()) .Returns(ci => buildHeadersResponse = _responseBuilder.BuildHeaderResponse(ci.ArgAt <long>(0), ci.ArgAt <int>(1), Response.AllCorrect)); Task <BlockBody[]> buildBlocksResponse = null; syncPeer.GetBlocks(Arg.Any <IList <Keccak> >(), Arg.Any <CancellationToken>()) .Returns(ci => buildBlocksResponse = _responseBuilder.BuildBlocksResponse(ci.ArgAt <IList <Keccak> >(0), Response.AllCorrect | Response.WithTransactions)); syncPeer.GetReceipts(Arg.Any <IList <Keccak> >(), Arg.Any <CancellationToken>()) .Returns(ci => _responseBuilder.BuildReceiptsResponse(buildHeadersResponse.Result, buildBlocksResponse.Result, Response.IncorrectReceiptRoot).Result); PeerInfo peerInfo = new PeerInfo(syncPeer) { TotalDifficulty = UInt256.MaxValue, HeadNumber = 1 }; await blockDownloader.DownloadHeaders(peerInfo, SyncModeSelector.FullSyncThreshold, CancellationToken.None); peerInfo.HeadNumber *= 2; Func <Task> action = async() => await blockDownloader.DownloadBlocks(peerInfo, 0, CancellationToken.None, BlockDownloader.DownloadOptions.DownloadWithReceipts); action.Should().Throw <EthSynchronizationException>(); }
public void parity_netPeers_null_ActivePeers() { var logger = LimboLogs.Instance; var specProvider = MainnetSpecProvider.Instance; var ethereumEcdsa = new EthereumEcdsa(specProvider.ChainId, logger); var txStorage = new InMemoryTxStorage(); IDb blockDb = new MemDb(); IDb headerDb = new MemDb(); IDb blockInfoDb = new MemDb(); IBlockTree blockTree = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, NullBloomStorage.Instance, LimboLogs.Instance); var txPool = new TxPool.TxPool(txStorage, ethereumEcdsa, new ChainHeadSpecProvider(specProvider, blockTree), new TxPoolConfig(), new StateProvider(new TrieStore(new MemDb(), LimboLogs.Instance), new MemDb(), LimboLogs.Instance), new TxValidator(specProvider.ChainId), LimboLogs.Instance); new OnChainTxWatcher(blockTree, txPool, specProvider, LimboLogs.Instance); IReceiptStorage receiptStorage = new InMemoryReceiptStorage(); IPeerManager peerManager = Substitute.For <IPeerManager>(); IParityModule parityModule = new ParityModule(ethereumEcdsa, txPool, blockTree, receiptStorage, new Enode(TestItem.PublicKeyA, IPAddress.Loopback, 8545), _signerStore, new MemKeyStore(new[] { TestItem.PrivateKeyA }), logger, peerManager); string serialized = RpcTest.TestSerializedRequest(parityModule, "parity_netPeers"); var expectedResult = "{\"jsonrpc\":\"2.0\",\"result\":{\"active\":0,\"connected\":0,\"max\":0,\"peers\":[]},\"id\":67}"; Assert.AreEqual(expectedResult, serialized); }
public void RunMigration(int?migratedBlockNumber) { var chainLength = 10; var configProvider = Substitute.For <IConfigProvider>(); var blockTreeBuilder = Core.Test.Builders.Build.A.BlockTree().OfChainLength(chainLength); var inMemoryReceiptStorage = new InMemoryReceiptStorage() { MigratedBlockNumber = migratedBlockNumber != null ? 0 : long.MaxValue }; var outMemoryReceiptStorage = new InMemoryReceiptStorage() { MigratedBlockNumber = migratedBlockNumber != null ? 0 : long.MaxValue }; var context = new Runner.Ethereum.Api.NethermindApi(configProvider, LimboLogs.Instance) { ReceiptStorage = new TestReceiptStorage(inMemoryReceiptStorage, outMemoryReceiptStorage), DbProvider = Substitute.For <IDbProvider>(), BlockTree = blockTreeBuilder.TestObject, Synchronizer = Substitute.For <ISynchronizer>(), ChainLevelInfoRepository = blockTreeBuilder.ChainLevelInfoRepository, SyncModeSelector = Substitute.For <ISyncModeSelector>() }; configProvider.GetConfig <IInitConfig>().StoreReceipts.Returns(true); configProvider.GetConfig <IInitConfig>().ReceiptsMigration.Returns(true); context.SyncModeSelector.Current.Returns(SyncMode.WaitingForBlock); int txIndex = 0; for (int i = 1; i < chainLength; i++) { var block = context.BlockTree.FindBlock(i); inMemoryReceiptStorage.Insert(block, Core.Test.Builders.Build.A.Receipt.WithTransactionHash(TestItem.Keccaks[txIndex++]).TestObject, Core.Test.Builders.Build.A.Receipt.WithTransactionHash(TestItem.Keccaks[txIndex++]).TestObject); } ManualResetEvent guard = new ManualResetEvent(false); Keccak lastTransaction = TestItem.Keccaks[txIndex - 1]; context.DbProvider.ReceiptsDb.When(x => x.Remove(lastTransaction.Bytes)).Do(c => guard.Set()); var migration = new ReceiptMigration(context); if (migratedBlockNumber.HasValue) { migration.Run(migratedBlockNumber.Value); } else { migration.Run(); } guard.WaitOne(TimeSpan.FromSeconds(1)); var txCount = ((migratedBlockNumber ?? chainLength) - 1 - 1) * 2; context.DbProvider.ReceiptsDb.Received(Quantity.Exactly(txCount)).Remove(Arg.Any <byte[]>()); outMemoryReceiptStorage.Count.Should().Be(txCount); }
public void nonconsecutive_non_producing_preProcess_loads_pending_validators_from_receipts(int lastLevelFinalized, int initialValidatorsIndex, int?expectedBlockValidators) { IEnumerable <Block> GetAllBlocks(BlockTree bt) { var block = bt.FindBlock(bt.Head.Hash, BlockTreeLookupOptions.None); while (block != null) { yield return(block); block = bt.FindBlock(block.ParentHash, BlockTreeLookupOptions.None); } } var validators = TestItem.Addresses[initialValidatorsIndex * 10]; var inMemoryReceiptStorage = new InMemoryReceiptStorage(); var blockTreeBuilder = Build.A.BlockTree().WithTransactions(inMemoryReceiptStorage, RopstenSpecProvider.Instance, delegate(Block block, Transaction transaction) { byte i = 0; return(new[] { Build.A.LogEntry.WithAddress(_contractAddress) .WithData(new[] { (byte)(block.Number * 10 + i++) }) .WithTopics(ValidatorContract.Definition.initiateChangeEventHash, block.ParentHash) .TestObject }); }) .OfChainLength(9, 0, 0, validators); var blockTree = blockTreeBuilder.TestObject; SetupInitialValidators(blockTree.Head, validators); IAuRaValidatorProcessor validator = new ContractValidator(_validator, _db, _stateProvider, _abiEncoder, _transactionProcessor, blockTree, inMemoryReceiptStorage, _logManager, 1); validator.SetFinalizationManager(_blockFinalizationManager); _abiEncoder.Decode(ValidatorContract.Definition.addressArrayResult, Arg.Any <byte[]>()) .Returns(c => { var addressIndex = c.Arg <byte[]>()[0]; return(new object[] { new Address[] { TestItem.Addresses[addressIndex] } }); }); _blockFinalizationManager.GetLastLevelFinalizedBy(blockTree.Head.ParentHash).Returns(lastLevelFinalized); validator.PreProcess(blockTree.FindBlock(blockTree.Head.Hash, BlockTreeLookupOptions.None)); byte[] expectedPendingValidatorsBytes = Rlp.OfEmptySequence.Bytes; if (expectedBlockValidators.HasValue) { var block = GetAllBlocks(blockTree).First(b => b.Number == expectedBlockValidators.Value); var pendingValidators = new ContractValidator.PendingValidators(block.Number, block.Hash, new [] { TestItem.Addresses[block.Number * 10] }); expectedPendingValidatorsBytes = Rlp.Encode(pendingValidators).Bytes; } _db.Received()[ContractValidator.PendingValidatorsKey.Bytes] = Arg.Is <byte[]>(r => r.SequenceEqual(expectedPendingValidatorsBytes)); }
public FastBlocksFeedTests() { // make trees lazy _remoteReceiptStorage = new InMemoryReceiptStorage(); _validTree2048 = Build.A.BlockTree().WithTransactions(_remoteReceiptStorage, _specProvider).OfChainLength(2048).TestObject; _validTree1024 = Build.A.BlockTree().WithTransactions(_remoteReceiptStorage, _specProvider).OfChainLength(1024).TestObject; _validTree8 = Build.A.BlockTree().WithTransactions(_remoteReceiptStorage, _specProvider).OfChainLength(8).TestObject; _badTreeAfter1024 = Build.A.BlockTree().WithTransactions(_remoteReceiptStorage, _specProvider).OfChainLength(2048, 1, 1024).TestObject; }
public void Setup() { InMemoryReceiptStorage receiptStorage = new InMemoryReceiptStorage(); _specProvider = new TestSpecProvider(Homestead.Instance); _blockTree = Build.A.BlockTree().WithTransactions(receiptStorage, _specProvider).OfChainLength(10).TestObject; _dbProvider = new MemDbProvider(); ProofModuleFactory moduleFactory = new ProofModuleFactory( _dbProvider, _blockTree, new CompositeBlockPreprocessorStep(new RecoverSignatures(new EthereumEcdsa(ChainId.Mainnet, LimboLogs.Instance), NullTxPool.Instance, _specProvider, LimboLogs.Instance)), receiptStorage, _specProvider, LimboLogs.Instance); _proofModule = moduleFactory.Create(); }
public async Task Happy_path(long headNumber, int options) { BlockDownloader.DownloadOptions downloadOptions = (BlockDownloader.DownloadOptions)options; bool withReceipts = downloadOptions == BlockDownloader.DownloadOptions.DownloadWithReceipts; InMemoryReceiptStorage inMemoryReceiptStorage = new InMemoryReceiptStorage(); BlockDownloader blockDownloader = new BlockDownloader(_blockTree, TestBlockValidator.AlwaysValid, TestSealValidator.AlwaysValid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); ISyncPeer syncPeer = Substitute.For <ISyncPeer>(); Task <BlockHeader[]> buildHeadersResponse = null; syncPeer.GetBlockHeaders(Arg.Any <long>(), Arg.Any <int>(), Arg.Any <int>(), Arg.Any <CancellationToken>()) .Returns(ci => buildHeadersResponse = _responseBuilder.BuildHeaderResponse(ci.ArgAt <long>(0), ci.ArgAt <int>(1), Response.AllCorrect)); Response blockResponseOptions = Response.AllCorrect; if (withReceipts) { blockResponseOptions |= Response.WithTransactions; } Task <BlockBody[]> buildBlocksResponse = null; syncPeer.GetBlocks(Arg.Any <IList <Keccak> >(), Arg.Any <CancellationToken>()) .Returns(ci => buildBlocksResponse = _responseBuilder.BuildBlocksResponse(ci.ArgAt <IList <Keccak> >(0), blockResponseOptions)); syncPeer.GetReceipts(Arg.Any <IList <Keccak> >(), Arg.Any <CancellationToken>()) .Returns(ci => _responseBuilder.BuildReceiptsResponse(buildHeadersResponse.Result, buildBlocksResponse.Result)); PeerInfo peerInfo = new PeerInfo(syncPeer); peerInfo.TotalDifficulty = UInt256.MaxValue; peerInfo.HeadNumber = headNumber; await blockDownloader.DownloadHeaders(peerInfo, SyncModeSelector.FullSyncThreshold, CancellationToken.None); Assert.AreEqual(Math.Max(0, headNumber - SyncModeSelector.FullSyncThreshold), _blockTree.BestSuggestedHeader.Number, "headers"); peerInfo.HeadNumber *= 2; await blockDownloader.DownloadBlocks(peerInfo, 0, CancellationToken.None, downloadOptions); _blockTree.BestSuggestedHeader.Number.Should().Be(Math.Max(0, headNumber * 2)); _blockTree.IsMainChain(_blockTree.BestSuggestedHeader.Hash).Should().Be(downloadOptions != BlockDownloader.DownloadOptions.DownloadAndProcess); inMemoryReceiptStorage.Count.Should().Be(withReceipts ? buildBlocksResponse.Result.Sum(b => b.Transactions?.Length ?? 0) : 0); }
public async Task Throws_on_receipt_task_exception_when_downloading_receipts(int options, bool shouldThrow) { BlockDownloader.DownloadOptions downloadOptions = (BlockDownloader.DownloadOptions)options; InMemoryReceiptStorage inMemoryReceiptStorage = new InMemoryReceiptStorage(); BlockDownloader blockDownloader = new BlockDownloader(_blockTree, TestBlockValidator.AlwaysValid, TestSealValidator.AlwaysValid, NullSyncReport.Instance, inMemoryReceiptStorage, RopstenSpecProvider.Instance, LimboLogs.Instance); ISyncPeer syncPeer = Substitute.For <ISyncPeer>(); Task <BlockHeader[]> buildHeadersResponse = null; syncPeer.GetBlockHeaders(Arg.Any <long>(), Arg.Any <int>(), Arg.Any <int>(), Arg.Any <CancellationToken>()) .Returns(ci => buildHeadersResponse = _responseBuilder.BuildHeaderResponse(ci.ArgAt <long>(0), ci.ArgAt <int>(1), Response.AllCorrect)); Task <BlockBody[]> buildBlocksResponse = null; syncPeer.GetBlocks(Arg.Any <IList <Keccak> >(), Arg.Any <CancellationToken>()) .Returns(ci => buildBlocksResponse = _responseBuilder.BuildBlocksResponse(ci.ArgAt <IList <Keccak> >(0), Response.AllCorrect | Response.WithTransactions)); syncPeer.GetReceipts(Arg.Any <IList <Keccak> >(), Arg.Any <CancellationToken>()) .Returns(Task.FromException <TxReceipt[][]>(new TimeoutException())); PeerInfo peerInfo = new PeerInfo(syncPeer) { TotalDifficulty = UInt256.MaxValue, HeadNumber = 1 }; await blockDownloader.DownloadHeaders(peerInfo, SyncModeSelector.FullSyncThreshold, CancellationToken.None); peerInfo.HeadNumber *= 2; Func <Task> action = async() => await blockDownloader.DownloadBlocks(peerInfo, 0, CancellationToken.None, downloadOptions); if (shouldThrow) { action.Should().Throw <EthSynchronizationException>().WithInnerException <AggregateException>().WithInnerException <TimeoutException>(); } else { action.Should().NotThrow(); } }
public void parity_netPeers_empty_ActivePeers() { LimboLogs logger = LimboLogs.Instance; MainnetSpecProvider specProvider = MainnetSpecProvider.Instance; EthereumEcdsa ethereumEcdsa = new EthereumEcdsa(specProvider.ChainId, logger); InMemoryTxStorage txStorage = new InMemoryTxStorage(); IDb blockDb = new MemDb(); IDb headerDb = new MemDb(); IDb blockInfoDb = new MemDb(); IBlockTree blockTree = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, NullBloomStorage.Instance, LimboLogs.Instance); ITransactionComparerProvider transactionComparerProvider = new TransactionComparerProvider(specProvider, blockTree); TxPool.TxPool txPool = new TxPool.TxPool(txStorage, ethereumEcdsa, new ChainHeadInfoProvider(new FixedBlockChainHeadSpecProvider(specProvider), blockTree, new StateProvider(new TrieStore(new MemDb(), LimboLogs.Instance), new MemDb(), LimboLogs.Instance)), new TxPoolConfig(), new TxValidator(specProvider.ChainId), LimboLogs.Instance, transactionComparerProvider.GetDefaultComparer()); new OnChainTxWatcher(blockTree, txPool, specProvider, LimboLogs.Instance); IReceiptStorage receiptStorage = new InMemoryReceiptStorage(); IPeerManager peerManager = Substitute.For <IPeerManager>(); peerManager.ActivePeers.Returns(new List <Peer> { }); peerManager.ConnectedPeers.Returns(new List <Peer> { new Peer(new Node("111.1.1.1", 11111, true)) }); IParityRpcModule parityRpcModule = new ParityRpcModule(ethereumEcdsa, txPool, blockTree, receiptStorage, new Enode(TestItem.PublicKeyA, IPAddress.Loopback, 8545), _signerStore, new MemKeyStore(new[] { TestItem.PrivateKeyA }), logger, peerManager); string serialized = RpcTest.TestSerializedRequest(parityRpcModule, "parity_netPeers"); string expectedResult = "{\"jsonrpc\":\"2.0\",\"result\":{\"active\":0,\"connected\":1,\"max\":0,\"peers\":[]},\"id\":67}"; Assert.AreEqual(expectedResult, serialized); }
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 traceDb = new MemDb(); 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(); stateDb.Commit(); var storageProvider = new StorageProvider(stateDb, stateProvider, logManager); var receiptStorage = new InMemoryReceiptStorage(); var ecdsa = new EthereumEcdsa(specProvider, logManager); var txPool = new TxPool(new InMemoryTransactionStorage(), new PendingTransactionThresholdValidator(), new Timestamp(), ecdsa, specProvider, logManager); var tree = new BlockTree(blockDb, headerDb, blockInfoDb, specProvider, txPool, logManager); var blockhashProvider = new BlockhashProvider(tree, LimboLogs.Instance); var virtualMachine = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, 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, traceDb, stateProvider, storageProvider, txPool, receiptStorage, syncConfig, logManager); var step = new TxSignaturesRecoveryStep(ecdsa, txPool, logManager); var processor = new BlockchainProcessor(tree, blockProcessor, step, logManager, true, true); var nodeStatsManager = new NodeStatsManager(new StatsConfig(), logManager); var syncPeerPool = new EthSyncPeerPool(tree, nodeStatsManager, syncConfig, logManager); StateProvider devState = new StateProvider(stateDb, codeDb, logManager); StorageProvider devStorage = new StorageProvider(stateDb, devState, logManager); var devEvm = new VirtualMachine(devState, devStorage, blockhashProvider, logManager); var devTxProcessor = new TransactionProcessor(specProvider, devState, devStorage, devEvm, logManager); var devBlockProcessor = new BlockProcessor(specProvider, blockValidator, rewardCalculator, devTxProcessor, stateDb, codeDb, traceDb, devState, devStorage, txPool, receiptStorage, syncConfig, logManager); var devChainProcessor = new BlockchainProcessor(tree, devBlockProcessor, step, logManager, false, false); var producer = new DevBlockProducer(txPool, devChainProcessor, tree, new Timestamp(), logManager); NodeDataFeed feed = new NodeDataFeed(codeDb, stateDb, logManager); NodeDataDownloader downloader = new NodeDataDownloader(syncPeerPool, feed, logManager); Synchronizer synchronizer = new Synchronizer( tree, blockValidator, sealValidator, syncPeerPool, syncConfig, downloader, logManager); var syncServer = new SyncServer(stateDb, codeDb, tree, receiptStorage, TestSealValidator.AlwaysValid, syncPeerPool, synchronizer, 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); }
public void Setup() { _localReceiptStorage = new InMemoryReceiptStorage(); _syncPeers = new List <LatencySyncPeerMock>(); _peerTrees = new Dictionary <LatencySyncPeerMock, IBlockTree>(); _peerMaxResponseSizes = new Dictionary <LatencySyncPeerMock, int>(); _pendingResponses = new Dictionary <LatencySyncPeerMock, FastBlocksBatch>(); _invalidBlocks = new Dictionary <LatencySyncPeerMock, HashSet <long> >(); _maliciousByRepetition = new HashSet <LatencySyncPeerMock>(); _maliciousByInvalidTxs = new HashSet <LatencySyncPeerMock>(); _maliciousByInvalidOmmers = new HashSet <LatencySyncPeerMock>(); _maliciousByShiftedOneForward = new HashSet <LatencySyncPeerMock>(); _maliciousByShiftedOneBack = new HashSet <LatencySyncPeerMock>(); _maliciousByShortAtStart = new HashSet <LatencySyncPeerMock>(); _maliciousByInvalidReceipts = new HashSet <LatencySyncPeerMock>(); _incorrectByTooShortMessages = new HashSet <LatencySyncPeerMock>(); _incorrectByTooLongMessages = new HashSet <LatencySyncPeerMock>(); _timingOut = new HashSet <LatencySyncPeerMock>(); _scheduledActions = new Dictionary <long, Action>(); LatencySyncPeerMock.RemoteIndex = 1; _time = 0; _syncPeerPool = Substitute.For <IEthSyncPeerPool>(); _syncPeerPool.WhenForAnyArgs(p => p.ReportNoSyncProgress(Arg.Any <SyncPeerAllocation>())) .Do(ci => { LatencySyncPeerMock mock = ((LatencySyncPeerMock)ci.Arg <SyncPeerAllocation>().Current.SyncPeer); mock.BusyUntil = _time + 5000; mock.IsReported = true; }); _syncPeerPool.WhenForAnyArgs(p => p.ReportNoSyncProgress(Arg.Any <PeerInfo>())) .Do(ci => { LatencySyncPeerMock mock = ((LatencySyncPeerMock)ci.Arg <PeerInfo>().SyncPeer); mock.BusyUntil = _time + 5000; mock.IsReported = true; }); _syncPeerPool.WhenForAnyArgs(p => p.ReportInvalid(Arg.Any <SyncPeerAllocation>())) .Do(ci => { LatencySyncPeerMock mock = ((LatencySyncPeerMock)ci.Arg <SyncPeerAllocation>().Current.SyncPeer); mock.BusyUntil = _time + 30000; mock.IsReported = true; }); _syncPeerPool.WhenForAnyArgs(p => p.ReportInvalid(Arg.Any <PeerInfo>())) .Do(ci => { LatencySyncPeerMock mock = ((LatencySyncPeerMock)ci.Arg <PeerInfo>().SyncPeer); mock.BusyUntil = _time + 30000; mock.IsReported = true; }); _syncPeerPool.AllPeers.Returns((ci) => _syncPeers.Select(sp => new PeerInfo(sp) { HeadNumber = sp.Tree.Head.Number })); _syncConfig = new SyncConfig(); _syncConfig.PivotHash = _validTree2048.Head.Hash.ToString(); _syncConfig.PivotNumber = _validTree2048.Head.Number.ToString(); _syncConfig.PivotTotalDifficulty = _validTree2048.Head.TotalDifficulty.ToString(); SetupLocalTree(); SetupFeed(); }
private SyncTestContext CreateSyncManager(int index) { var logManager = NoErrorLimboLogs.Instance; ConsoleAsyncLogger logger = new ConsoleAsyncLogger(LogLevel.Debug, "PEER " + index + " "); // var logManager = new OneLoggerLogManager(logger); var specProvider = new SingleReleaseSpecProvider(ConstantinopleFix.Instance, MainnetSpecProvider.Instance.ChainId); var dbProvider = TestMemDbProvider.Init(); IDb blockDb = dbProvider.BlocksDb; IDb headerDb = dbProvider.HeadersDb; IDb blockInfoDb = dbProvider.BlockInfosDb; ISnapshotableDb codeDb = dbProvider.CodeDb; ISnapshotableDb stateDb = dbProvider.StateDb; var stateReader = new StateReader(stateDb, codeDb, logManager); var stateProvider = new StateProvider(stateDb, codeDb, logManager); stateProvider.CreateAccount(TestItem.AddressA, 10000.Ether()); stateProvider.Commit(specProvider.GenesisSpec); stateProvider.CommitTree(); stateProvider.RecalculateStateRoot(); stateDb.Commit(); var storageProvider = new StorageProvider(stateDb, stateProvider, logManager); var receiptStorage = new InMemoryReceiptStorage(); var ecdsa = new EthereumEcdsa(specProvider.ChainId, logManager); var txPool = new TxPool.TxPool(new InMemoryTxStorage(), ecdsa, specProvider, new TxPoolConfig(), stateProvider, logManager); var tree = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, NullBloomStorage.Instance, logManager); var blockhashProvider = new BlockhashProvider(tree, LimboLogs.Instance); var virtualMachine = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, specProvider, logManager); var sealValidator = Always.Valid; var headerValidator = new HeaderValidator(tree, sealValidator, specProvider, logManager); var txValidator = Always.Valid; var ommersValidator = new OmmersValidator(tree, headerValidator, logManager); var blockValidator = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, logManager); ISyncConfig syncConfig = _synchronizerType == SynchronizerType.Fast ? SyncConfig.WithFastSync : SyncConfig.WithFullSyncOnly; var rewardCalculator = new RewardCalculator(specProvider); var txProcessor = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, logManager); var blockProcessor = new BlockProcessor(specProvider, blockValidator, rewardCalculator, txProcessor, stateDb, codeDb, stateProvider, storageProvider, txPool, receiptStorage, logManager); var step = new RecoverSignatures(ecdsa, txPool, specProvider, logManager); var processor = new BlockchainProcessor(tree, blockProcessor, step, logManager, BlockchainProcessor.Options.Default); var nodeStatsManager = new NodeStatsManager(logManager); var syncPeerPool = new SyncPeerPool(tree, nodeStatsManager, 25, logManager); StateProvider devState = new StateProvider(stateDb, codeDb, logManager); StorageProvider devStorage = new StorageProvider(stateDb, devState, logManager); var devEvm = new VirtualMachine(devState, devStorage, blockhashProvider, specProvider, logManager); var devTxProcessor = new TransactionProcessor(specProvider, devState, devStorage, devEvm, logManager); var devBlockProcessor = new BlockProcessor(specProvider, blockValidator, rewardCalculator, devTxProcessor, stateDb, codeDb, devState, devStorage, txPool, receiptStorage, logManager); var devChainProcessor = new BlockchainProcessor(tree, devBlockProcessor, step, logManager, BlockchainProcessor.Options.NoReceipts); var transactionSelector = new TxPoolTxSource(txPool, stateReader, logManager); var producer = new DevBlockProducer( transactionSelector, devChainProcessor, stateProvider, tree, processor, txPool, Timestamper.Default, logManager); SyncProgressResolver resolver = new SyncProgressResolver(tree, receiptStorage, stateDb, new MemDb(), syncConfig, logManager); MultiSyncModeSelector selector = new MultiSyncModeSelector(resolver, syncPeerPool, syncConfig, logManager); Synchronizer synchronizer = new Synchronizer( dbProvider, MainnetSpecProvider.Instance, tree, NullReceiptStorage.Instance, blockValidator, sealValidator, syncPeerPool, nodeStatsManager, StaticSelector.Full, syncConfig, logManager); var syncServer = new SyncServer(stateDb, codeDb, tree, receiptStorage, Always.Valid, Always.Valid, syncPeerPool, selector, syncConfig, logManager); ManualResetEventSlim waitEvent = new ManualResetEventSlim(); tree.NewHeadBlock += (s, e) => waitEvent.Set(); if (index == 0) { _genesis = Build.A.Block.Genesis.WithStateRoot(stateProvider.StateRoot).TestObject; producer.Start(); } syncPeerPool.Start(); synchronizer.Start(); processor.Start(); tree.SuggestBlock(_genesis); if (!waitEvent.Wait(1000)) { throw new Exception("No genesis"); } SyncTestContext context = new SyncTestContext(); context.Ecdsa = ecdsa; context.BlockchainProcessor = processor; context.PeerPool = syncPeerPool; context.StateProvider = stateProvider; context.Synchronizer = synchronizer; context.SyncServer = syncServer; context.Tree = tree; context.BlockProducer = producer; context.TxPool = txPool; context.Logger = logger; return(context); }
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; }
private static async Task RunBenchmarkBlocks() { Rlp.RegisterDecoders(typeof(ParityTraceDecoder).Assembly); /* logging & instrumentation */ _logManager = new NLogManager("perfTest.logs.txt", null); _logger = _logManager.GetClassLogger(); if (_logger.IsInfo) { _logger.Info("Deleting state DBs"); } DeleteDb(FullStateDbPath); DeleteDb(FullCodeDbPath); DeleteDb(FullReceiptsDbPath); DeleteDb(FullPendingTxsDbPath); if (_logger.IsInfo) { _logger.Info("State DBs deleted"); } /* load spec */ ChainSpecLoader loader = new ChainSpecLoader(new EthereumJsonSerializer()); string path = Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"chainspec", "ropsten.json")); _logger.Info($"Loading ChainSpec from {path}"); ChainSpec chainSpec = loader.Load(File.ReadAllText(path)); _logger.Info($"ChainSpec loaded"); var specProvider = new ChainSpecBasedSpecProvider(chainSpec); IRewardCalculator rewardCalculator = new RewardCalculator(specProvider); var dbProvider = new RocksDbProvider(DbBasePath, DbConfig.Default, _logManager, true, true); var stateDb = dbProvider.StateDb; var codeDb = dbProvider.CodeDb; var traceDb = dbProvider.TraceDb; var blocksDb = dbProvider.BlocksDb; var headersDb = dbProvider.HeadersDb; var blockInfosDb = dbProvider.BlockInfosDb; var receiptsDb = dbProvider.ReceiptsDb; /* state & storage */ var stateProvider = new StateProvider(stateDb, codeDb, _logManager); var storageProvider = new StorageProvider(stateDb, stateProvider, _logManager); var ethereumSigner = new EthereumEcdsa(specProvider, _logManager); var transactionPool = new TxPool( NullTxStorage.Instance, Timestamper.Default, ethereumSigner, specProvider, new TxPoolConfig(), stateProvider, _logManager); var blockInfoRepository = new ChainLevelInfoRepository(blockInfosDb); var blockTree = new UnprocessedBlockTreeWrapper(new BlockTree(blocksDb, headersDb, blockInfosDb, blockInfoRepository, specProvider, transactionPool, _logManager)); var receiptStorage = new InMemoryReceiptStorage(); IBlockDataRecoveryStep recoveryStep = new TxSignaturesRecoveryStep(ethereumSigner, transactionPool, _logManager); /* blockchain processing */ IList <IAdditionalBlockProcessor> blockProcessors = new List <IAdditionalBlockProcessor>(); var blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance); var virtualMachine = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, specProvider, _logManager); var processor = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, _logManager); ISealValidator sealValidator; if (specProvider.ChainId == RopstenSpecProvider.Instance.ChainId) { var difficultyCalculator = new DifficultyCalculator(specProvider); sealValidator = new EthashSealValidator(_logManager, difficultyCalculator, new Ethash(_logManager)); } else if (chainSpec.SealEngineType == SealEngineType.Clique) { var snapshotManager = new SnapshotManager(CliqueConfig.Default, blocksDb, blockTree, ethereumSigner, _logManager); sealValidator = new CliqueSealValidator(CliqueConfig.Default, snapshotManager, _logManager); rewardCalculator = NoBlockRewards.Instance; recoveryStep = new CompositeDataRecoveryStep(recoveryStep, new AuthorRecoveryStep(snapshotManager)); } else if (chainSpec.SealEngineType == SealEngineType.AuRa) { var abiEncoder = new AbiEncoder(); var validatorProcessor = new AuRaAdditionalBlockProcessorFactory(dbProvider.StateDb, stateProvider, abiEncoder, processor, blockTree, receiptStorage, _logManager) .CreateValidatorProcessor(chainSpec.AuRa.Validators); sealValidator = new AuRaSealValidator(chainSpec.AuRa, new AuRaStepCalculator(chainSpec.AuRa.StepDuration, new Timestamper()), validatorProcessor, ethereumSigner, _logManager); rewardCalculator = new AuRaRewardCalculator(chainSpec.AuRa, abiEncoder, processor); blockProcessors.Add(validatorProcessor); } else { throw new NotSupportedException(); } /* store & validation */ var headerValidator = new HeaderValidator(blockTree, sealValidator, specProvider, _logManager); var ommersValidator = new OmmersValidator(blockTree, headerValidator, _logManager); var transactionValidator = new TxValidator(chainSpec.ChainId); var blockValidator = new BlockValidator(transactionValidator, headerValidator, ommersValidator, specProvider, _logManager); /* blockchain processing */ var blockProcessor = new BlockProcessor(specProvider, blockValidator, rewardCalculator, processor, stateDb, codeDb, traceDb, stateProvider, storageProvider, transactionPool, receiptStorage, _logManager, blockProcessors); var blockchainProcessor = new BlockchainProcessor(blockTree, blockProcessor, recoveryStep, _logManager, true, false); if (chainSpec.SealEngineType == SealEngineType.AuRa) { stateProvider.CreateAccount(Address.Zero, UInt256.Zero); storageProvider.Commit(); stateProvider.Commit(Homestead.Instance); var finalizationManager = new AuRaBlockFinalizationManager(blockTree, blockInfoRepository, blockProcessor, blockProcessors.OfType <IAuRaValidator>().First(), _logManager); } foreach ((Address address, ChainSpecAllocation allocation) in chainSpec.Allocations) { stateProvider.CreateAccount(address, allocation.Balance); if (allocation.Code != null) { Keccak codeHash = stateProvider.UpdateCode(allocation.Code); stateProvider.UpdateCodeHash(address, codeHash, specProvider.GenesisSpec); } if (allocation.Constructor != null) { Transaction constructorTransaction = new Transaction(true) { SenderAddress = address, Init = allocation.Constructor, GasLimit = chainSpec.Genesis.GasLimit }; processor.Execute(constructorTransaction, chainSpec.Genesis.Header, NullTxTracer.Instance); } } _logger.Info($"Allocations configured, committing..."); stateProvider.Commit(specProvider.GenesisSpec); _logger.Info($"Finalizing genesis..."); chainSpec.Genesis.Header.StateRoot = stateProvider.StateRoot; chainSpec.Genesis.Header.Hash = BlockHeader.CalculateHash(chainSpec.Genesis.Header); if (chainSpec.Genesis.Hash != blockTree.Genesis.Hash) { throw new Exception("Unexpected genesis hash"); } _logger.Info($"Starting benchmark processor..."); /* start processing */ BigInteger totalGas = BigInteger.Zero; Stopwatch stopwatch = new Stopwatch(); Block currentHead; long maxMemory = 0; blockTree.NewHeadBlock += (sender, args) => { currentHead = args.Block; if (currentHead.Number == 0) { return; } maxMemory = Math.Max(maxMemory, GC.GetTotalMemory(false)); totalGas += currentHead.GasUsed; if ((BigInteger)args.Block.Number % 10000 == 9999) { stopwatch.Stop(); long ms = 1_000L * stopwatch.ElapsedTicks / Stopwatch.Frequency; BigInteger number = args.Block.Number + 1; _logger.Warn($"TOTAL after {number} (ms) : " + ms); _logger.Warn($"TOTAL after {number} blocks/s : {(decimal) currentHead.Number / (ms / 1000m),5}"); _logger.Warn($"TOTAL after {number} Mgas/s : {((decimal) totalGas / 1000000) / (ms / 1000m),5}"); _logger.Warn($"TOTAL after {number} max mem : {maxMemory}"); _logger.Warn($"TOTAL after {number} GC (0/1/2) : {GC.CollectionCount(0)}/{GC.CollectionCount(1)}/{GC.CollectionCount(2)}"); _logger.Warn($"Is server GC {number} : {System.Runtime.GCSettings.IsServerGC}"); _logger.Warn($"GC latency mode {number} : {System.Runtime.GCSettings.LatencyMode}"); _logger.Warn($"TOTAL after {number} blocks DB reads : {Store.Metrics.BlocksDbReads}"); _logger.Warn($"TOTAL after {number} blocks DB writes : {Store.Metrics.BlocksDbWrites}"); _logger.Warn($"TOTAL after {number} infos DB reads : {Store.Metrics.BlockInfosDbReads}"); _logger.Warn($"TOTAL after {number} infos DB writes : {Store.Metrics.BlockInfosDbWrites}"); _logger.Warn($"TOTAL after {number} state tree reads : {Store.Metrics.StateTreeReads}"); _logger.Warn($"TOTAL after {number} state tree writes : {Store.Metrics.StateTreeWrites}"); _logger.Warn($"TOTAL after {number} state DB reads : {Store.Metrics.StateDbReads}"); _logger.Warn($"TOTAL after {number} state DB writes : {Store.Metrics.StateDbWrites}"); _logger.Warn($"TOTAL after {number} storage tree reads : {Store.Metrics.StorageTreeReads}"); _logger.Warn($"TOTAL after {number} storage tree writes : {Store.Metrics.StorageTreeWrites}"); _logger.Warn($"TOTAL after {number} tree node hash : {Store.Metrics.TreeNodeHashCalculations}"); _logger.Warn($"TOTAL after {number} tree node RLP decode : {Store.Metrics.TreeNodeRlpDecodings}"); _logger.Warn($"TOTAL after {number} tree node RLP encode : {Store.Metrics.TreeNodeRlpEncodings}"); _logger.Warn($"TOTAL after {number} code DB reads : {Store.Metrics.CodeDbReads}"); _logger.Warn($"TOTAL after {number} code DB writes : {Store.Metrics.CodeDbWrites}"); _logger.Warn($"TOTAL after {number} receipts DB reads : {Store.Metrics.ReceiptsDbReads}"); _logger.Warn($"TOTAL after {number} receipts DB writes : {Store.Metrics.ReceiptsDbWrites}"); _logger.Warn($"TOTAL after {number} other DB reads : {Store.Metrics.OtherDbReads}"); _logger.Warn($"TOTAL after {number} other DB writes : {Store.Metrics.OtherDbWrites}"); _logger.Warn($"TOTAL after {number} EVM exceptions : {Evm.Metrics.EvmExceptions}"); _logger.Warn($"TOTAL after {number} SLOAD opcodes : {Evm.Metrics.SloadOpcode}"); _logger.Warn($"TOTAL after {number} SSTORE opcodes : {Evm.Metrics.SstoreOpcode}"); _logger.Warn($"TOTAL after {number} EXP opcodes : {Evm.Metrics.ModExpOpcode}"); _logger.Warn($"TOTAL after {number} BLOCKHASH opcodes : {Evm.Metrics.BlockhashOpcode}"); _logger.Warn($"TOTAL after {number} EVM calls : {Evm.Metrics.Calls}"); _logger.Warn($"TOTAL after {number} RIPEMD Precompiles : {Evm.Metrics.Ripemd160Precompile}"); _logger.Warn($"TOTAL after {number} SHA256 Precompiles : {Evm.Metrics.Sha256Precompile}"); // disk space stopwatch.Start(); } }; bool isStarted = false; TaskCompletionSource <object> completionSource = new TaskCompletionSource <object>(); blockTree.NewBestSuggestedBlock += (sender, args) => { if (!isStarted) { blockchainProcessor.Process(blockTree.FindBlock(blockTree.Genesis.Hash, BlockTreeLookupOptions.RequireCanonical), ProcessingOptions.None, NullBlockTracer.Instance); stopwatch.Start(); blockchainProcessor.Start(); isStarted = true; } if (args.Block.Number == BlocksToLoad) { completionSource.SetResult(null); } }; await Task.WhenAny(completionSource.Task, blockTree.LoadBlocksFromDb(CancellationToken.None, 0, 10000, BlocksToLoad)); await blockchainProcessor.StopAsync(true).ContinueWith( t => { if (t.IsFaulted) { _logger.Error("processing failed", t.Exception); _logger.Error("inner", t.Exception.InnerException); Console.ReadLine(); } _logger.Info("Block processing completed."); }); stopwatch.Stop(); Console.ReadLine(); }
public void Initialize() { var logger = LimboLogs.Instance; var specProvider = MainnetSpecProvider.Instance; var ethereumEcdsa = new EthereumEcdsa(specProvider.ChainId, logger); var txStorage = new InMemoryTxStorage(); Peer peerA = SetUpPeerA(); //standard case Peer peerB = SetUpPeerB(); //Session is null Peer peerC = SetUpPeerC(); //Node is null, Caps are empty IPeerManager peerManager = Substitute.For <IPeerManager>(); peerManager.ActivePeers.Returns(new List <Peer> { peerA, peerB, peerC }); peerManager.ConnectedPeers.Returns(new List <Peer> { peerA, peerB, peerA, peerC, peerB }); peerManager.MaxActivePeers.Returns(15); StateProvider stateProvider = new StateProvider(new TrieStore(new MemDb(), LimboLogs.Instance), new MemDb(), LimboLogs.Instance); var txPool = new TxPool.TxPool(txStorage, ethereumEcdsa, new FixedBlockChainHeadSpecProvider(specProvider), new TxPoolConfig(), stateProvider, new TxValidator(specProvider.ChainId), LimboLogs.Instance); IDb blockDb = new MemDb(); IDb headerDb = new MemDb(); IDb blockInfoDb = new MemDb(); IBlockTree blockTree = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, NullBloomStorage.Instance, LimboLogs.Instance); new OnChainTxWatcher(blockTree, txPool, specProvider, LimboLogs.Instance); IReceiptStorage receiptStorage = new InMemoryReceiptStorage(); _signerStore = new Signer(specProvider.ChainId, TestItem.PrivateKeyB, logger); _parityModule = new ParityModule(ethereumEcdsa, txPool, blockTree, receiptStorage, new Enode(TestItem.PublicKeyA, IPAddress.Loopback, 8545), _signerStore, new MemKeyStore(new[] { TestItem.PrivateKeyA }), logger, peerManager); var blockNumber = 2; var pendingTransaction = Build.A.Transaction.Signed(ethereumEcdsa, TestItem.PrivateKeyD, false) .WithSenderAddress(Address.FromNumber((UInt256)blockNumber)).TestObject; pendingTransaction.Signature.V = 37; stateProvider.CreateAccount(pendingTransaction.SenderAddress, UInt256.UInt128MaxValue); txPool.AddTransaction(pendingTransaction, TxHandlingOptions.None); blockNumber = 1; var transaction = Build.A.Transaction.Signed(ethereumEcdsa, TestItem.PrivateKeyD, false) .WithSenderAddress(Address.FromNumber((UInt256)blockNumber)) .WithNonce(100).TestObject; transaction.Signature.V = 37; stateProvider.CreateAccount(transaction.SenderAddress, UInt256.UInt128MaxValue); txPool.AddTransaction(transaction, TxHandlingOptions.None); Block genesis = Build.A.Block.Genesis .WithStateRoot(new Keccak("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")) .TestObject; blockTree.SuggestBlock(genesis); blockTree.UpdateMainChain(new[] { genesis }, true); Block previousBlock = genesis; Block block = Build.A.Block.WithNumber(blockNumber).WithParent(previousBlock) .WithStateRoot(new Keccak("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")) .WithTransactions(MuirGlacier.Instance, transaction) .TestObject; blockTree.SuggestBlock(block); blockTree.UpdateMainChain(new[] { block }, true); var logEntries = new[] { Build.A.LogEntry.TestObject }; receiptStorage.Insert(block, new TxReceipt() { Bloom = new Bloom(logEntries), Index = 1, Recipient = TestItem.AddressA, Sender = TestItem.AddressB, BlockHash = TestItem.KeccakA, BlockNumber = 1, ContractAddress = TestItem.AddressC, GasUsed = 1000, TxHash = transaction.Hash, StatusCode = 0, GasUsedTotal = 2000, Logs = logEntries }); }
public void Initialize() { Rlp.RegisterDecoders(typeof(ParityTraceDecoder).Assembly); _ethSerializer = new EthereumJsonSerializer(); ISpecProvider specProvider = MainNetSpecProvider.Instance; IEthereumEcdsa ethereumEcdsa = new EthereumEcdsa(specProvider, LimboLogs.Instance); ITxStorage txStorage = new InMemoryTxStorage(); ISnapshotableDb stateDb = new StateDb(); ISnapshotableDb codeDb = new StateDb(); IStateReader stateReader = new StateReader(stateDb, codeDb, LimboLogs.Instance); IStateProvider 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 StorageAddress(TestItem.AddressA, UInt256.One), Bytes.FromHexString("0xabcdef")); storageProvider.Commit(); stateProvider.Commit(specProvider.GenesisSpec); ITxPool txPool = new TxPool(txStorage, Timestamper.Default, ethereumEcdsa, specProvider, new TxPoolConfig(), stateProvider, LimboLogs.Instance); IDb blockDb = new MemDb(); IDb headerDb = new MemDb(); IDb blockInfoDb = new MemDb(); IDb traceDb = new MemDb(); IBlockTree blockTree = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockDb), specProvider, txPool, 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, AlwaysValidBlockValidator.Instance, new RewardCalculator(specProvider), txProcessor, stateDb, codeDb, traceDb, 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); BlockchainProcessor blockchainProcessor = new BlockchainProcessor(blockTree, blockProcessor, new TxSignaturesRecoveryStep(ethereumEcdsa, txPool, LimboLogs.Instance), LimboLogs.Instance, true, true); blockchainProcessor.Start(); ManualResetEventSlim resetEvent = new ManualResetEventSlim(false); blockTree.NewHeadBlock += (s, e) => { if (e.Block.Number == 9) { resetEvent.Set(); } }; Block genesis = Build.A.Block.Genesis.WithStateRoot(new Keccak("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")).TestObject; blockTree.SuggestBlock(genesis); Block previousBlock = genesis; for (int i = 1; i < 10; i++) { Block block = Build.A.Block.WithNumber(i).WithParent(previousBlock).WithStateRoot(new Keccak("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")).TestObject; blockTree.SuggestBlock(block); previousBlock = block; } resetEvent.Wait(); _ethModule = new EthModule(LimboLogs.Instance, _blockchainBridge); _blockTree = blockTree; }
protected virtual async Task <TestBlockchain> Build(ISpecProvider specProvider = null) { Timestamper = new ManualTimestamper(new DateTime(2020, 2, 15, 12, 50, 30, DateTimeKind.Utc)); JsonSerializer = new EthereumJsonSerializer(); SpecProvider = specProvider ?? MainnetSpecProvider.Instance; EthereumEcdsa = new EthereumEcdsa(ChainId.Mainnet, LimboLogs.Instance); ITxStorage txStorage = new InMemoryTxStorage(); DbProvider = new MemDbProvider(); State = new StateProvider(StateDb, CodeDb, LimboLogs.Instance); State.CreateAccount(TestItem.AddressA, 1000.Ether()); State.CreateAccount(TestItem.AddressB, 1000.Ether()); State.CreateAccount(TestItem.AddressC, 1000.Ether()); byte[] code = Bytes.FromHexString("0xabcd"); Keccak codeHash = Keccak.Compute(code); State.UpdateCode(code); State.UpdateCodeHash(TestItem.AddressA, codeHash, SpecProvider.GenesisSpec); Storage = new StorageProvider(StateDb, State, LimboLogs.Instance); Storage.Set(new StorageCell(TestItem.AddressA, UInt256.One), Bytes.FromHexString("0xabcdef")); Storage.Commit(); State.Commit(SpecProvider.GenesisSpec); State.CommitTree(); TxPool = new TxPool.TxPool(txStorage, Timestamper, EthereumEcdsa, SpecProvider, new TxPoolConfig(), State, LimboLogs.Instance); IDb blockDb = new MemDb(); IDb headerDb = new MemDb(); IDb blockInfoDb = new MemDb(); BlockTree = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockDb), SpecProvider, TxPool, NullBloomStorage.Instance, LimboLogs.Instance); ReceiptStorage = new InMemoryReceiptStorage(); VirtualMachine virtualMachine = new VirtualMachine(State, Storage, new BlockhashProvider(BlockTree, LimboLogs.Instance), SpecProvider, LimboLogs.Instance); TxProcessor = new TransactionProcessor(SpecProvider, State, Storage, virtualMachine, LimboLogs.Instance); BlockProcessor = CreateBlockProcessor(); BlockchainProcessor chainProcessor = new BlockchainProcessor(BlockTree, BlockProcessor, new TxSignaturesRecoveryStep(EthereumEcdsa, TxPool, LimboLogs.Instance), LimboLogs.Instance, BlockchainProcessor.Options.Default); chainProcessor.Start(); StateReader = new StateReader(StateDb, CodeDb, LimboLogs.Instance); TxPoolTxSource txPoolTxSource = new TxPoolTxSource(TxPool, StateReader, LimboLogs.Instance); ISealer sealer = new FakeSealer(TimeSpan.Zero); BlockProducer = new TestBlockProducer(txPoolTxSource, chainProcessor, State, sealer, BlockTree, chainProcessor, Timestamper, LimboLogs.Instance); BlockProducer.Start(); _resetEvent = new AutoResetEvent(false); BlockTree.NewHeadBlock += (s, e) => { Console.WriteLine(e.Block.Header.Hash); _resetEvent.Set(); }; var genesis = GetGenesisBlock(); BlockTree.SuggestBlock(genesis); await _resetEvent.WaitOneAsync(CancellationToken.None); await AddBlocksOnStart(); return(this); }
public void Initialize() { LimboLogs logger = LimboLogs.Instance; MainnetSpecProvider specProvider = MainnetSpecProvider.Instance; EthereumEcdsa ethereumEcdsa = new(specProvider.ChainId, logger); Peer peerA = SetUpPeerA(); //standard case Peer peerB = SetUpPeerB(); //Session is null Peer peerC = SetUpPeerC(); //Node is null, Caps are empty IPeerManager peerManager = Substitute.For <IPeerManager>(); peerManager.ActivePeers.Returns(new List <Peer> { peerA, peerB, peerC }); peerManager.ConnectedPeers.Returns(new List <Peer> { peerA, peerB, peerA, peerC, peerB }); peerManager.MaxActivePeers.Returns(15); StateProvider stateProvider = new(new TrieStore(new MemDb(), LimboLogs.Instance), new MemDb(), LimboLogs.Instance); StateReader stateReader = new(new TrieStore(new MemDb(), LimboLogs.Instance), new MemDb(), LimboLogs.Instance); IDb blockDb = new MemDb(); IDb headerDb = new MemDb(); IDb blockInfoDb = new MemDb(); IBlockTree blockTree = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, NullBloomStorage.Instance, LimboLogs.Instance); ITransactionComparerProvider transactionComparerProvider = new TransactionComparerProvider(specProvider, blockTree); TxPool.TxPool txPool = new(ethereumEcdsa, new ChainHeadInfoProvider(new FixedBlockChainHeadSpecProvider(specProvider), blockTree, stateProvider), new TxPoolConfig(), new TxValidator(specProvider.ChainId), LimboLogs.Instance, transactionComparerProvider.GetDefaultComparer()); IReceiptStorage receiptStorage = new InMemoryReceiptStorage(); _signerStore = new Signer(specProvider.ChainId, TestItem.PrivateKeyB, logger); _parityRpcModule = new ParityRpcModule(ethereumEcdsa, txPool, blockTree, receiptStorage, new Enode(TestItem.PublicKeyA, IPAddress.Loopback, 8545), _signerStore, new MemKeyStore(new[] { TestItem.PrivateKeyA }), MainnetSpecProvider.Instance, peerManager); int blockNumber = 2; Transaction pendingTransaction = Build.A.Transaction.Signed(ethereumEcdsa, TestItem.PrivateKeyD, false) .WithSenderAddress(Address.FromNumber((UInt256)blockNumber)).TestObject; pendingTransaction.Signature.V = 37; stateProvider.CreateAccount(pendingTransaction.SenderAddress, UInt256.UInt128MaxValue); txPool.SubmitTx(pendingTransaction, TxHandlingOptions.None); blockNumber = 1; Transaction transaction1 = Build.A.Transaction.Signed(ethereumEcdsa, TestItem.PrivateKeyD, false) .WithSenderAddress(Address.FromNumber((UInt256)blockNumber)) .WithNonce(100).TestObject; transaction1.Signature.V = 37; stateProvider.CreateAccount(transaction1.SenderAddress, UInt256.UInt128MaxValue); var transaction2 = Build.A.Transaction.Signed(ethereumEcdsa, TestItem.PrivateKeyD, false) .WithSenderAddress(Address.FromNumber((UInt256)blockNumber)) .WithNonce(120).TestObject; transaction2.Signature.V = 37; var transaction3 = Build.A.Transaction.Signed(ethereumEcdsa, TestItem.PrivateKeyD, false) .WithSenderAddress(Address.FromNumber((UInt256)blockNumber)) .WithNonce(110).TestObject; transaction2.Signature.V = 37; Block genesis = Build.A.Block.Genesis .WithStateRoot(new Keccak("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")) .TestObject; blockTree.SuggestBlock(genesis); blockTree.UpdateMainChain(new[] { genesis }, true); Block previousBlock = genesis; Block block = Build.A.Block.WithNumber(blockNumber).WithParent(previousBlock) .WithStateRoot(new Keccak("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")) .WithTransactions(transaction1, transaction2, transaction3) .TestObject; blockTree.SuggestBlock(block); blockTree.UpdateMainChain(new[] { block }, true); LogEntry[] logEntries = new[] { Build.A.LogEntry.TestObject }; TxReceipt receipt1 = new() { Bloom = new Bloom(logEntries), Index = 0, Recipient = TestItem.AddressA, Sender = TestItem.AddressB, BlockHash = TestItem.KeccakA, BlockNumber = 1, ContractAddress = TestItem.AddressC, GasUsed = 1000, TxHash = transaction1.Hash, StatusCode = 0, GasUsedTotal = 2000, Logs = logEntries }; TxReceipt receipt2 = new() { Bloom = new Bloom(logEntries), Index = 1, Recipient = TestItem.AddressA, Sender = TestItem.AddressB, BlockHash = TestItem.KeccakA, BlockNumber = 1, ContractAddress = TestItem.AddressC, GasUsed = 1000, TxHash = transaction2.Hash, StatusCode = 0, GasUsedTotal = 2000, Logs = logEntries }; TxReceipt receipt3 = new() { Bloom = new Bloom(logEntries), Index = 2, Recipient = TestItem.AddressA, Sender = TestItem.AddressB, BlockHash = TestItem.KeccakA, BlockNumber = 1, ContractAddress = TestItem.AddressC, GasUsed = 1000, TxHash = transaction3.Hash, StatusCode = 0, GasUsedTotal = 2000, Logs = logEntries }; receiptStorage.Insert(block, receipt1, receipt2, receipt3); } private static Peer SetUpPeerA() { Node node = new(TestItem.PublicKeyA, "127.0.0.1", 30303, true); node.ClientId = "Geth/v1.9.21-stable/linux-amd64/go1.15.2"; Peer peer = new(node); peer.InSession = null; peer.OutSession = Substitute.For <ISession>(); peer.OutSession.RemoteNodeId.Returns(TestItem.PublicKeyA); IProtocolHandler protocolHandler = Substitute.For <IProtocolHandler, ISyncPeer>(); peer.OutSession.TryGetProtocolHandler(Protocol.Eth, out Arg.Any <IProtocolHandler>()).Returns(x => { x[1] = protocolHandler; return(true); }); byte version = 65; protocolHandler.ProtocolVersion.Returns(version); if (protocolHandler is ISyncPeer syncPeer) { UInt256 difficulty = 0x5ea4ed; syncPeer.TotalDifficulty.Returns(difficulty); syncPeer.HeadHash.Returns(TestItem.KeccakA); } IProtocolHandler p2PProtocolHandler = Substitute.For <IProtocolHandler, IP2PProtocolHandler>(); peer.OutSession.TryGetProtocolHandler(Protocol.P2P, out Arg.Any <IProtocolHandler>()).Returns(x => { x[1] = p2PProtocolHandler; return(true); }); if (p2PProtocolHandler is IP2PProtocolHandler p2PHandler) { p2PHandler.AgreedCapabilities.Returns(new List <Capability> { new("eth", 65), new("eth", 64) }); }
protected virtual async Task <TestBlockchain> Build(ISpecProvider specProvider = null, UInt256?initialValues = null) { Timestamper = new ManualTimestamper(new DateTime(2020, 2, 15, 12, 50, 30, DateTimeKind.Utc)); JsonSerializer = new EthereumJsonSerializer(); SpecProvider = specProvider ?? MainnetSpecProvider.Instance; EthereumEcdsa = new EthereumEcdsa(ChainId.Mainnet, LimboLogs.Instance); ITxStorage txStorage = new InMemoryTxStorage(); DbProvider = await TestMemDbProvider.InitAsync(); State = new StateProvider(StateDb, CodeDb, LimboLogs.Instance); State.CreateAccount(TestItem.AddressA, (initialValues ?? 1000.Ether())); State.CreateAccount(TestItem.AddressB, (initialValues ?? 1000.Ether())); State.CreateAccount(TestItem.AddressC, (initialValues ?? 1000.Ether())); byte[] code = Bytes.FromHexString("0xabcd"); Keccak codeHash = Keccak.Compute(code); State.UpdateCode(code); State.UpdateCodeHash(TestItem.AddressA, codeHash, SpecProvider.GenesisSpec); Storage = new StorageProvider(StateDb, State, LimboLogs.Instance); Storage.Set(new StorageCell(TestItem.AddressA, UInt256.One), Bytes.FromHexString("0xabcdef")); Storage.Commit(); State.Commit(SpecProvider.GenesisSpec); State.CommitTree(); TxPool = new TxPool.TxPool( txStorage, EthereumEcdsa, SpecProvider, new TxPoolConfig(), new StateProvider(StateDb, CodeDb, LimboLogs.Instance), LimboLogs.Instance); IDb blockDb = new MemDb(); IDb headerDb = new MemDb(); IDb blockInfoDb = new MemDb(); BlockTree = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockDb), SpecProvider, NullBloomStorage.Instance, LimboLogs.Instance); new OnChainTxWatcher(BlockTree, TxPool, SpecProvider, LimboLogs.Instance); ReceiptStorage = new InMemoryReceiptStorage(); VirtualMachine virtualMachine = new VirtualMachine(State, Storage, new BlockhashProvider(BlockTree, LimboLogs.Instance), SpecProvider, LimboLogs.Instance); TxProcessor = new TransactionProcessor(SpecProvider, State, Storage, virtualMachine, LimboLogs.Instance); BlockProcessor = CreateBlockProcessor(); BlockchainProcessor chainProcessor = new BlockchainProcessor(BlockTree, BlockProcessor, new RecoverSignatures(EthereumEcdsa, TxPool, SpecProvider, LimboLogs.Instance), LimboLogs.Instance, Nethermind.Blockchain.Processing.BlockchainProcessor.Options.Default); BlockchainProcessor = chainProcessor; chainProcessor.Start(); StateReader = new StateReader(StateDb, CodeDb, LimboLogs.Instance); TxPoolTxSource txPoolTxSource = CreateTxPoolTxSource(); ISealer sealer = new NethDevSealEngine(TestItem.AddressD); BlockProducer = new TestBlockProducer(txPoolTxSource, chainProcessor, State, sealer, BlockTree, chainProcessor, Timestamper, LimboLogs.Instance); BlockProducer.Start(); _resetEvent = new SemaphoreSlim(0); _suggestedBlockResetEvent = new ManualResetEvent(true); BlockTree.NewHeadBlock += (s, e) => { _resetEvent.Release(1); }; BlockProducer.LastProducedBlockChanged += (s, e) => { _suggestedBlockResetEvent.Set(); }; var genesis = GetGenesisBlock(); BlockTree.SuggestBlock(genesis); await _resetEvent.WaitAsync(); //if (!await _resetEvent.WaitAsync(1000)) // { // throw new InvalidOperationException("Failed to process genesis in 1s."); // } await AddBlocksOnStart(); return(this); }
public void Initialize() { var logger = LimboLogs.Instance; var specProvider = MainnetSpecProvider.Instance; var ethereumEcdsa = new EthereumEcdsa(specProvider.ChainId, logger); var txStorage = new InMemoryTxStorage(); var txPool = new TxPool.TxPool(txStorage, Timestamper.Default, ethereumEcdsa, specProvider, new TxPoolConfig(), new StateProvider(new StateDb(), new MemDb(), LimboLogs.Instance), LimboLogs.Instance); IDb blockDb = new MemDb(); IDb headerDb = new MemDb(); IDb blockInfoDb = new MemDb(); IBlockTree blockTree = new BlockTree(blockDb, headerDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, txPool, NullBloomStorage.Instance, LimboLogs.Instance); IReceiptStorage receiptStorage = new InMemoryReceiptStorage(); _parityModule = new ParityModule(ethereumEcdsa, txPool, blockTree, receiptStorage, logger); var blockNumber = 2; var pendingTransaction = Build.A.Transaction.Signed(ethereumEcdsa, TestItem.PrivateKeyD, false) .WithSenderAddress(Address.FromNumber((UInt256)blockNumber)).TestObject; pendingTransaction.Signature.V = 37; txPool.AddTransaction(pendingTransaction, TxHandlingOptions.None); blockNumber = 1; var transaction = Build.A.Transaction.Signed(ethereumEcdsa, TestItem.PrivateKeyD, false) .WithSenderAddress(Address.FromNumber((UInt256)blockNumber)) .WithNonce(100).TestObject; transaction.Signature.V = 37; txPool.AddTransaction(transaction, TxHandlingOptions.None); Block genesis = Build.A.Block.Genesis .WithStateRoot(new Keccak("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")) .TestObject; blockTree.SuggestBlock(genesis); blockTree.UpdateMainChain(new[] { genesis }, true); Block previousBlock = genesis; Block block = Build.A.Block.WithNumber(blockNumber).WithParent(previousBlock) .WithStateRoot(new Keccak("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")) .WithTransactions(transaction) .TestObject; blockTree.SuggestBlock(block); blockTree.UpdateMainChain(new[] { block }, true); var logEntries = new[] { Build.A.LogEntry.TestObject }; receiptStorage.Insert(block, false, new TxReceipt() { Bloom = new Bloom(logEntries), Index = 1, Recipient = TestItem.AddressA, Sender = TestItem.AddressB, BlockHash = TestItem.KeccakA, BlockNumber = 1, ContractAddress = TestItem.AddressC, GasUsed = 1000, TxHash = transaction.Hash, StatusCode = 0, GasUsedTotal = 2000, Logs = logEntries }); }