public void Can_collect_stats() { MemDb memDb = new MemDb(); IDb stateDb = memDb; TrieStore trieStore = new TrieStore(stateDb, new MemoryLimit(0.MB()), Persist.EveryBlock, LimboLogs.Instance); StateProvider stateProvider = new StateProvider(trieStore, stateDb, LimboLogs.Instance); StorageProvider storageProvider = new StorageProvider(trieStore, stateProvider, LimboLogs.Instance); stateProvider.CreateAccount(TestItem.AddressA, 1); Keccak codeHash = stateProvider.UpdateCode(new byte[] { 1, 2, 3 }); stateProvider.UpdateCodeHash(TestItem.AddressA, codeHash, Istanbul.Instance); stateProvider.CreateAccount(TestItem.AddressB, 1); Keccak codeHash2 = stateProvider.UpdateCode(new byte[] { 1, 2, 3, 4 }); stateProvider.UpdateCodeHash(TestItem.AddressB, codeHash2, Istanbul.Instance); for (int i = 0; i < 1000; i++) { StorageCell storageCell = new StorageCell(TestItem.AddressA, (UInt256)i); storageProvider.Set(storageCell, new byte[] { (byte)i }); } storageProvider.Commit(); stateProvider.Commit(Istanbul.Instance); storageProvider.CommitTrees(0); stateProvider.CommitTree(0); storageProvider.CommitTrees(1); stateProvider.CommitTree(1); memDb.Delete(codeHash2); // missing code Keccak storageKey = new Keccak("0x345e54154080bfa9e8f20c99d7a0139773926479bc59e5b4f830ad94b6425332"); memDb.Delete(storageKey); // deletes some storage trieStore.ClearCache(); TrieStatsCollector statsCollector = new TrieStatsCollector(stateDb, LimboLogs.Instance); stateProvider.Accept(statsCollector, stateProvider.StateRoot); var stats = statsCollector.Stats; stats.CodeCount.Should().Be(1); stats.MissingCode.Should().Be(1); stats.NodesCount.Should().Be(1348); stats.StateBranchCount.Should().Be(1); stats.StateExtensionCount.Should().Be(1); stats.AccountCount.Should().Be(2); stats.StorageCount.Should().Be(1343); stats.StorageBranchCount.Should().Be(337); stats.StorageExtensionCount.Should().Be(12); stats.StorageLeafCount.Should().Be(994); stats.MissingStorage.Should().Be(1); }
private void AddAccount(StateProvider stateProvider, Address account, UInt256 initialBalance) { stateProvider.CreateAccount(account, initialBalance); stateProvider.Commit(MuirGlacier.Instance, null); stateProvider.CommitTree(); _dbProvider.StateDb.Commit(); }
public void Non_existing() { StorageCell storageCell = new StorageCell(_address1, UInt256.One); IReleaseSpec spec = MuirGlacier.Instance; MemDb stateDb = new MemDb(); TrieStore trieStore = new TrieStore(stateDb, Logger); StateProvider provider = new StateProvider(trieStore, new MemDb(), Logger); StorageProvider storageProvider = new StorageProvider(trieStore, provider, Logger); void CommitEverything() { storageProvider.Commit(); storageProvider.CommitTrees(0); provider.Commit(spec); provider.CommitTree(0); } provider.CreateAccount(_address1, 1); storageProvider.Set(storageCell, new byte[] { 1 }); CommitEverything(); Keccak stateRoot0 = provider.StateRoot; StateReader reader = new StateReader(new TrieStore(stateDb, LimboLogs.Instance), Substitute.For <IDb>(), Logger); Keccak storageRoot = reader.GetStorageRoot(stateRoot0, _address1); reader.GetStorage(storageRoot, storageCell.Index + 1).Should().BeEquivalentTo(new byte[] { 0 }); reader.GetStorage(Keccak.EmptyTreeHash, storageCell.Index + 1).Should().BeEquivalentTo(new byte[] { 0 }); }
private static void InitializeTestState(GeneralStateTest test, StateProvider stateProvider, IStorageProvider storageProvider, ISpecProvider specProvider) { foreach (KeyValuePair <Address, AccountState> accountState in test.Pre) { foreach (KeyValuePair <UInt256, byte[]> storageItem in accountState.Value.Storage) { storageProvider.Set(new StorageCell(accountState.Key, storageItem.Key), storageItem.Value.WithoutLeadingZeros().ToArray()); } stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance); Keccak codeHash = stateProvider.UpdateCode(accountState.Value.Code); stateProvider.UpdateCodeHash(accountState.Key, codeHash, specProvider.GenesisSpec); stateProvider.SetNonce(accountState.Key, accountState.Value.Nonce); } storageProvider.Commit(); stateProvider.Commit(specProvider.GenesisSpec); storageProvider.CommitTrees(0); stateProvider.CommitTree(0); storageProvider.Reset(); stateProvider.Reset(); }
public async Task Can_ask_about_storage_in_parallel() { StorageCell storageCell = new StorageCell(_address1, UInt256.One); IReleaseSpec spec = MuirGlacier.Instance; MemDb stateDb = new MemDb(); TrieStore trieStore = new TrieStore(stateDb, Logger); StateProvider provider = new StateProvider(trieStore, new MemDb(), Logger); StorageProvider storageProvider = new StorageProvider(trieStore, provider, Logger); void UpdateStorageValue(byte[] newValue) { storageProvider.Set(storageCell, newValue); } void AddOneToBalance() { provider.AddToBalance(_address1, 1, spec); } void CommitEverything() { storageProvider.Commit(); storageProvider.CommitTrees(0); provider.Commit(spec); provider.CommitTree(0); } provider.CreateAccount(_address1, 1); CommitEverything(); AddOneToBalance(); UpdateStorageValue(new byte[] { 1 }); CommitEverything(); Keccak stateRoot0 = provider.StateRoot; AddOneToBalance(); UpdateStorageValue(new byte[] { 2 }); CommitEverything(); Keccak stateRoot1 = provider.StateRoot; AddOneToBalance(); UpdateStorageValue(new byte[] { 3 }); CommitEverything(); Keccak stateRoot2 = provider.StateRoot; AddOneToBalance(); UpdateStorageValue(new byte[] { 4 }); CommitEverything(); Keccak stateRoot3 = provider.StateRoot; StateReader reader = new StateReader(new TrieStore(stateDb, LimboLogs.Instance), Substitute.For <IDb>(), Logger); Task a = StartStorageTask(reader, stateRoot0, storageCell, new byte[] { 1 }); Task b = StartStorageTask(reader, stateRoot1, storageCell, new byte[] { 2 }); Task c = StartStorageTask(reader, stateRoot2, storageCell, new byte[] { 3 }); Task d = StartStorageTask(reader, stateRoot3, storageCell, new byte[] { 4 }); await Task.WhenAll(a, b, c, d); }
public void Get_storage() { /* all testing will be touching just a single storage cell */ var storageCell = new StorageCell(TestItem.AddressA, 1); /* to start with we need to create an account that we will be setting storage at */ _stateProvider.CreateAccount(storageCell.Address, UInt256.One); _stateProvider.Commit(MuirGlacier.Instance); _stateProvider.CommitTree(); /* at this stage we have an account with empty storage at the address that we want to test */ byte[] initialValue = new byte[] { 1, 2, 3 }; _storageProvider.Set(storageCell, initialValue); _storageProvider.Commit(); _storageProvider.CommitTrees(); _stateProvider.Commit(MuirGlacier.Instance); _stateProvider.CommitTree(); var retrieved = _blockchainBridge.GetStorage(storageCell.Address, storageCell.Index, _stateProvider.StateRoot); retrieved.Should().BeEquivalentTo(initialValue); /* at this stage we set the value in storage to 1,2,3 at the tested storage cell */ /* Now we are testing scenario where the storage is being changed by the block processor. * To do that we create some different storage / state access stack that represents the processor. * It is a different stack of objects than the one that is used by the blockchain bridge. */ byte[] newValue = new byte[] { 1, 2, 3, 4, 5 }; StateProvider processorStateProvider = new StateProvider(_dbProvider.StateDb, _dbProvider.CodeDb, LimboLogs.Instance); processorStateProvider.StateRoot = _stateProvider.StateRoot; StorageProvider processorStorageProvider = new StorageProvider(_dbProvider.StateDb, processorStateProvider, LimboLogs.Instance); processorStorageProvider.Set(storageCell, newValue); processorStorageProvider.Commit(); processorStorageProvider.CommitTrees(); processorStateProvider.Commit(MuirGlacier.Instance); processorStateProvider.CommitTree(); /* At this stage the DB should have the storage value updated to 5. * We will try to retrieve the value by taking the state root from the processor.*/ retrieved = _blockchainBridge.GetStorage(storageCell.Address, storageCell.Index, processorStateProvider.StateRoot); retrieved.Should().BeEquivalentTo(newValue); /* If it failed then it means that the blockchain bridge cached the previous call value */ }
private void AddCode(StateProvider stateProvider, Address account, byte[] code) { Keccak codeHash = stateProvider.UpdateCode(code); stateProvider.UpdateCodeHash(account, codeHash, MuirGlacier.Instance); stateProvider.Commit(MainnetSpecProvider.Instance.GenesisSpec, null); stateProvider.CommitTree(); _dbProvider.CodeDb.Commit(); _dbProvider.StateDb.Commit(); }
public void Can_collect_stats() { StateProvider provider = new StateProvider(new TrieStore(new MemDb(), Logger), _codeDb, Logger); provider.CreateAccount(TestItem.AddressA, 1.Ether()); provider.Commit(MuirGlacier.Instance); provider.CommitTree(0); var stats = provider.CollectStats(_codeDb, Logger); stats.AccountCount.Should().Be(1); }
public void Can_collect_stats() { StateProvider provider = new StateProvider(new StateDb(new MemDb()), Substitute.For <IDb>(), Logger); provider.CreateAccount(TestItem.AddressA, 1.Ether()); provider.Commit(MuirGlacier.Instance); provider.CommitTree(); var stats = provider.CollectStats(); stats.AccountCount.Should().Be(1); }
public void Can_dump_state() { StateProvider provider = new StateProvider(new TrieStore(new MemDb(), Logger), _codeDb, Logger); provider.CreateAccount(TestItem.AddressA, 1.Ether()); provider.Commit(MuirGlacier.Instance); provider.CommitTree(0); string state = provider.DumpState(); state.Should().NotBeEmpty(); }
public void Can_dump_state() { StateProvider provider = new StateProvider(new StateDb(new MemDb()), Substitute.For <IDb>(), Logger); provider.CreateAccount(TestItem.AddressA, 1.Ether()); provider.Commit(MuirGlacier.Instance); provider.CommitTree(); string state = provider.DumpState(); state.Should().NotBeEmpty(); }
public void Can_accepts_visitors() { StateProvider provider = new StateProvider(new StateDb(new MemDb()), Substitute.For <IDb>(), Logger); provider.CreateAccount(TestItem.AddressA, 1.Ether()); provider.Commit(MuirGlacier.Instance); provider.CommitTree(); TrieStatsCollector visitor = new TrieStatsCollector(new MemDb(), LimboLogs.Instance); provider.Accept(visitor, provider.StateRoot); }
public async Task Can_ask_about_balance_in_parallel() { IReleaseSpec spec = MainnetSpecProvider.Instance.GetSpec(MainnetSpecProvider.ConstantinopleFixBlockNumber); MemDb stateDb = new MemDb(); StateProvider provider = new StateProvider(new TrieStore(stateDb, Logger), Substitute.For <IDb>(), Logger); provider.CreateAccount(_address1, 0); provider.AddToBalance(_address1, 1, spec); provider.Commit(spec); provider.CommitTree(0); Keccak stateRoot0 = provider.StateRoot; provider.AddToBalance(_address1, 1, spec); provider.Commit(spec); provider.CommitTree(0); Keccak stateRoot1 = provider.StateRoot; provider.AddToBalance(_address1, 1, spec); provider.Commit(spec); provider.CommitTree(0); Keccak stateRoot2 = provider.StateRoot; provider.AddToBalance(_address1, 1, spec); provider.Commit(spec); provider.CommitTree(0); Keccak stateRoot3 = provider.StateRoot; provider.CommitTree(0); StateReader reader = new StateReader(new TrieStore(stateDb, LimboLogs.Instance), Substitute.For <IDb>(), Logger); Task a = StartTask(reader, stateRoot0, 1); Task b = StartTask(reader, stateRoot1, 2); Task c = StartTask(reader, stateRoot2, 3); Task d = StartTask(reader, stateRoot3, 4); await Task.WhenAll(a, b, c, d); }
public void Setup() { StateDb stateDb = new StateDb(); _stateProvider = new StateProvider(stateDb, new MemDb(), LimboLogs.Instance); _stateProvider.CreateAccount(TestItem.AddressA, 1.Ether()); _stateProvider.Commit(_specProvider.GenesisSpec); _stateProvider.CommitTree(); StorageProvider storageProvider = new StorageProvider(stateDb, _stateProvider, LimboLogs.Instance); VirtualMachine virtualMachine = new VirtualMachine(_stateProvider, storageProvider, Substitute.For <IBlockhashProvider>(), _specProvider, LimboLogs.Instance); _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, storageProvider, virtualMachine, LimboLogs.Instance); _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); }
public void Eip_158_zero_value_transfer_deletes() { ISnapshotableDb stateDb = new StateDb(new MemDb()); StateProvider frontierProvider = new StateProvider(stateDb, Substitute.For <IDb>(), Logger); frontierProvider.CreateAccount(_address1, 0); frontierProvider.Commit(Frontier.Instance); frontierProvider.CommitTree(); StateProvider provider = new StateProvider(stateDb, Substitute.For <IDb>(), Logger); provider.StateRoot = frontierProvider.StateRoot; provider.AddToBalance(_address1, 0, SpuriousDragon.Instance); provider.Commit(SpuriousDragon.Instance); Assert.False(provider.AccountExists(_address1)); }
private StateProvider CreateInitialState(byte[] code) { StateProvider stateProvider = new StateProvider(new TrieStore(_dbProvider.StateDb, LimboLogs.Instance), _dbProvider.CodeDb, LimboLogs.Instance); AddAccount(stateProvider, TestItem.AddressA, 1.Ether()); AddAccount(stateProvider, TestItem.AddressB, 1.Ether()); if (code != null) { AddCode(stateProvider, TestItem.AddressB, code); } if (_createSystemAccount) { AddAccount(stateProvider, Address.SystemUser, 1.Ether()); } stateProvider.CommitTree(0); return(stateProvider); }
public async Task Get_storage() { IDbProvider dbProvider = await TestMemDbProvider.InitAsync(); /* all testing will be touching just a single storage cell */ StorageCell storageCell = new StorageCell(_address1, UInt256.One); TrieStore trieStore = new TrieStore(dbProvider.StateDb, Logger); StateProvider state = new StateProvider(trieStore, dbProvider.CodeDb, Logger); StorageProvider storage = new StorageProvider(trieStore, state, Logger); /* to start with we need to create an account that we will be setting storage at */ state.CreateAccount(storageCell.Address, UInt256.One); state.Commit(MuirGlacier.Instance); state.CommitTree(1); /* at this stage we have an account with empty storage at the address that we want to test */ byte[] initialValue = new byte[] { 1, 2, 3 }; storage.Set(storageCell, initialValue); storage.Commit(); storage.CommitTrees(2); state.Commit(MuirGlacier.Instance); state.CommitTree(2); StateReader reader = new StateReader( new TrieStore(dbProvider.StateDb, LimboLogs.Instance), dbProvider.CodeDb, Logger); var account = reader.GetAccount(state.StateRoot, _address1); var retrieved = reader.GetStorage(account.StorageRoot, storageCell.Index); retrieved.Should().BeEquivalentTo(initialValue); /* at this stage we set the value in storage to 1,2,3 at the tested storage cell */ /* Now we are testing scenario where the storage is being changed by the block processor. * To do that we create some different storage / state access stack that represents the processor. * It is a different stack of objects than the one that is used by the blockchain bridge. */ byte[] newValue = new byte[] { 1, 2, 3, 4, 5 }; StateProvider processorStateProvider = new StateProvider(trieStore, new MemDb(), LimboLogs.Instance); processorStateProvider.StateRoot = state.StateRoot; StorageProvider processorStorageProvider = new StorageProvider(trieStore, processorStateProvider, LimboLogs.Instance); processorStorageProvider.Set(storageCell, newValue); processorStorageProvider.Commit(); processorStorageProvider.CommitTrees(3); processorStateProvider.Commit(MuirGlacier.Instance); processorStateProvider.CommitTree(3); /* At this stage the DB should have the storage value updated to 5. * We will try to retrieve the value by taking the state root from the processor.*/ retrieved = reader.GetStorage(processorStateProvider.GetStorageRoot(storageCell.Address), storageCell.Index); retrieved.Should().BeEquivalentTo(newValue); /* If it failed then it means that the blockchain bridge cached the previous call value */ }
public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = false) { if (_logger.IsInfo) { _logger.Info($"CREATING NODE {privateKey.Address}"); } _logManagers[privateKey] = LimboLogs.Instance; // _logManagers[privateKey] = new OneLoggerLogManager(new ConsoleAsyncLogger(LogLevel.Debug, $"{privateKey.Address} ")); var nodeLogManager = _logManagers[privateKey]; AutoResetEvent newHeadBlockEvent = new AutoResetEvent(false); _blockEvents.Add(privateKey, newHeadBlockEvent); MemDb blocksDb = new MemDb(); MemDb headersDb = new MemDb(); MemDb blockInfoDb = new MemDb(); MemDb stateDb = new MemDb(); MemDb codeDb = new MemDb(); ISpecProvider specProvider = RinkebySpecProvider.Instance; var trieStore = new TrieStore(stateDb, nodeLogManager); StateReader stateReader = new StateReader(trieStore, codeDb, nodeLogManager); StateProvider stateProvider = new StateProvider(trieStore, codeDb, nodeLogManager); stateProvider.CreateAccount(TestItem.PrivateKeyD.Address, 100.Ether()); GoerliSpecProvider goerliSpecProvider = GoerliSpecProvider.Instance; stateProvider.Commit(goerliSpecProvider.GenesisSpec); stateProvider.CommitTree(0); BlockTree blockTree = new BlockTree(blocksDb, headersDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), goerliSpecProvider, NullBloomStorage.Instance, nodeLogManager); blockTree.NewHeadBlock += (sender, args) => { _blockEvents[privateKey].Set(); }; ITransactionComparerProvider transactionComparerProvider = new TransactionComparerProvider(specProvider, blockTree); TxPool.TxPool txPool = new TxPool.TxPool(new InMemoryTxStorage(), _ethereumEcdsa, new ChainHeadInfoProvider(new FixedBlockChainHeadSpecProvider(GoerliSpecProvider.Instance), blockTree, stateProvider), new TxPoolConfig(), new TxValidator(goerliSpecProvider.ChainId), _logManager, transactionComparerProvider.GetDefaultComparer()); _pools[privateKey] = txPool; BlockhashProvider blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance); _blockTrees.Add(privateKey, blockTree); SnapshotManager snapshotManager = new SnapshotManager(_cliqueConfig, blocksDb, blockTree, _ethereumEcdsa, nodeLogManager); _snapshotManager[privateKey] = snapshotManager; CliqueSealer cliqueSealer = new CliqueSealer(new Signer(ChainId.Goerli, privateKey, LimboLogs.Instance), _cliqueConfig, snapshotManager, nodeLogManager); _genesis.Header.StateRoot = _genesis3Validators.Header.StateRoot = stateProvider.StateRoot; _genesis.Header.Hash = _genesis.Header.CalculateHash(); _genesis3Validators.Header.Hash = _genesis3Validators.Header.CalculateHash(); StorageProvider storageProvider = new StorageProvider(trieStore, stateProvider, nodeLogManager); TransactionProcessor transactionProcessor = new TransactionProcessor(goerliSpecProvider, stateProvider, storageProvider, new VirtualMachine(stateProvider, storageProvider, blockhashProvider, specProvider, nodeLogManager), nodeLogManager); BlockProcessor blockProcessor = new BlockProcessor( goerliSpecProvider, Always.Valid, NoBlockRewards.Instance, transactionProcessor, stateProvider, storageProvider, txPool, NullReceiptStorage.Instance, NullWitnessCollector.Instance, nodeLogManager); BlockchainProcessor processor = new BlockchainProcessor(blockTree, blockProcessor, new AuthorRecoveryStep(snapshotManager), nodeLogManager, BlockchainProcessor.Options.NoReceipts); processor.Start(); var minerTrieStore = trieStore.AsReadOnly(); StateProvider minerStateProvider = new StateProvider(minerTrieStore, codeDb, nodeLogManager); StorageProvider minerStorageProvider = new StorageProvider(minerTrieStore, minerStateProvider, nodeLogManager); VirtualMachine minerVirtualMachine = new VirtualMachine(minerStateProvider, minerStorageProvider, blockhashProvider, specProvider, nodeLogManager); TransactionProcessor minerTransactionProcessor = new TransactionProcessor(goerliSpecProvider, minerStateProvider, minerStorageProvider, minerVirtualMachine, nodeLogManager); BlockProcessor minerBlockProcessor = new BlockProcessor( goerliSpecProvider, Always.Valid, NoBlockRewards.Instance, minerTransactionProcessor, minerStateProvider, minerStorageProvider, txPool, NullReceiptStorage.Instance, NullWitnessCollector.Instance, nodeLogManager); BlockchainProcessor minerProcessor = new BlockchainProcessor(blockTree, minerBlockProcessor, new AuthorRecoveryStep(snapshotManager), nodeLogManager, BlockchainProcessor.Options.NoReceipts); if (withGenesisAlreadyProcessed) { ProcessGenesis(privateKey); } ITxFilterPipeline txFilterPipeline = TxFilterPipelineBuilder.CreateStandardFilteringPipeline(nodeLogManager, specProvider); TxPoolTxSource txPoolTxSource = new TxPoolTxSource(txPool, stateReader, specProvider, transactionComparerProvider, nodeLogManager, txFilterPipeline); CliqueBlockProducer blockProducer = new CliqueBlockProducer( txPoolTxSource, minerProcessor, minerStateProvider, blockTree, _timestamper, new CryptoRandom(), snapshotManager, cliqueSealer, new TargetAdjustedGasLimitCalculator(goerliSpecProvider, new MiningConfig()), MainnetSpecProvider.Instance, _cliqueConfig, nodeLogManager); blockProducer.Start(); _producers.Add(privateKey, blockProducer); return(this); }
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; }
public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = false) { if (_logger.IsInfo) { _logger.Info($"CREATING NODE {privateKey.Address}"); } _logManagers[privateKey] = LimboLogs.Instance; // _logManagers[privateKey] = new OneLoggerLogManager(new ConsoleAsyncLogger(LogLevel.Debug, $"{privateKey.Address} ")); var nodeLogManager = _logManagers[privateKey]; AutoResetEvent newHeadBlockEvent = new AutoResetEvent(false); _blockEvents.Add(privateKey, newHeadBlockEvent); MemDb blocksDb = new MemDb(); MemDb headersDb = new MemDb(); MemDb blockInfoDb = new MemDb(); ISnapshotableDb stateDb = new StateDb(); ISnapshotableDb codeDb = new StateDb(); ISpecProvider specProvider = RinkebySpecProvider.Instance; StateProvider stateProvider = new StateProvider(stateDb, codeDb, nodeLogManager); stateProvider.CreateAccount(TestItem.PrivateKeyD.Address, 100.Ether()); stateProvider.Commit(GoerliSpecProvider.Instance.GenesisSpec); stateProvider.CommitTree(); TxPool.TxPool txPool = new TxPool.TxPool(new InMemoryTxStorage(), _timestamper, _ethereumEcdsa, GoerliSpecProvider.Instance, new TxPoolConfig(), stateProvider, _logManager); _pools[privateKey] = txPool; BlockTree blockTree = new BlockTree(blocksDb, headersDb, blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), GoerliSpecProvider.Instance, txPool, NullBloomStorage.Instance, nodeLogManager); blockTree.NewHeadBlock += (sender, args) => { _blockEvents[privateKey].Set(); }; BlockhashProvider blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance); _blockTrees.Add(privateKey, blockTree); IBasicWallet wallet = new BasicWallet(privateKey); SnapshotManager snapshotManager = new SnapshotManager(_cliqueConfig, blocksDb, blockTree, _ethereumEcdsa, nodeLogManager); _snapshotManager[privateKey] = snapshotManager; CliqueSealer cliqueSealer = new CliqueSealer(wallet, _cliqueConfig, snapshotManager, privateKey.Address, nodeLogManager); _genesis.Header.StateRoot = _genesis3Validators.Header.StateRoot = stateProvider.StateRoot; _genesis.Header.Hash = _genesis.Header.CalculateHash(); _genesis3Validators.Header.Hash = _genesis3Validators.Header.CalculateHash(); StorageProvider storageProvider = new StorageProvider(stateDb, stateProvider, nodeLogManager); TransactionProcessor transactionProcessor = new TransactionProcessor(GoerliSpecProvider.Instance, stateProvider, storageProvider, new VirtualMachine(stateProvider, storageProvider, blockhashProvider, specProvider, nodeLogManager), nodeLogManager); BlockProcessor blockProcessor = new BlockProcessor(GoerliSpecProvider.Instance, AlwaysValidBlockValidator.Instance, NoBlockRewards.Instance, transactionProcessor, stateDb, codeDb, stateProvider, storageProvider, txPool, NullReceiptStorage.Instance, nodeLogManager); BlockchainProcessor processor = new BlockchainProcessor(blockTree, blockProcessor, new AuthorRecoveryStep(snapshotManager), nodeLogManager, false); processor.Start(); StateProvider minerStateProvider = new StateProvider(stateDb, codeDb, nodeLogManager); StorageProvider minerStorageProvider = new StorageProvider(stateDb, minerStateProvider, nodeLogManager); VirtualMachine minerVirtualMachine = new VirtualMachine(minerStateProvider, minerStorageProvider, blockhashProvider, specProvider, nodeLogManager); TransactionProcessor minerTransactionProcessor = new TransactionProcessor(GoerliSpecProvider.Instance, minerStateProvider, minerStorageProvider, minerVirtualMachine, nodeLogManager); BlockProcessor minerBlockProcessor = new BlockProcessor(GoerliSpecProvider.Instance, AlwaysValidBlockValidator.Instance, NoBlockRewards.Instance, minerTransactionProcessor, stateDb, codeDb, minerStateProvider, minerStorageProvider, txPool, NullReceiptStorage.Instance, nodeLogManager); BlockchainProcessor minerProcessor = new BlockchainProcessor(blockTree, minerBlockProcessor, new AuthorRecoveryStep(snapshotManager), nodeLogManager, false); if (withGenesisAlreadyProcessed) { ProcessGenesis(privateKey); } PendingTxSelector pendingTxSelector = new PendingTxSelector(txPool, stateProvider, nodeLogManager); CliqueBlockProducer blockProducer = new CliqueBlockProducer(pendingTxSelector, minerProcessor, minerStateProvider, blockTree, _timestamper, new CryptoRandom(), snapshotManager, cliqueSealer, privateKey.Address, _cliqueConfig, nodeLogManager); blockProducer.Start(); _producers.Add(privateKey, blockProducer); return(this); }
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); }
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); }
protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer) { TestContext.Write($"Running {test.Name} at {DateTime.UtcNow:HH:mm:ss.ffffff}"); Stopwatch stopwatch = Stopwatch.StartNew(); Assert.IsNull(test.LoadFailure, "test data loading failure"); ISnapshotableDb stateDb = new StateDb(); ISnapshotableDb codeDb = new StateDb(); ISpecProvider 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.Fork)); if (specProvider.GenesisSpec != Frontier.Instance) { Assert.Fail("Expected genesis spec to be Frontier for blockchain tests"); } IStateProvider stateProvider = new StateProvider(stateDb, codeDb, _logManager); IBlockhashProvider blockhashProvider = new TestBlockhashProvider(); IStorageProvider storageProvider = new StorageProvider(stateDb, stateProvider, _logManager); IVirtualMachine virtualMachine = new VirtualMachine( stateProvider, storageProvider, blockhashProvider, specProvider, _logManager); TransactionProcessor transactionProcessor = new TransactionProcessor( specProvider, stateProvider, storageProvider, virtualMachine, _logManager); InitializeTestState(test, stateProvider, storageProvider, specProvider); BlockHeader header = new BlockHeader(test.PreviousHash, Keccak.OfAnEmptySequenceRlp, test.CurrentCoinbase, test.CurrentDifficulty, test.CurrentNumber, test.CurrentGasLimit, test.CurrentTimestamp, new byte[0]); header.StateRoot = test.PostHash; header.Hash = Keccak.Compute("1"); stateProvider.Commit(specProvider.GenesisSpec); stateProvider.CommitTree(); transactionProcessor.Execute(test.Transaction, header, txTracer); stateProvider.Commit(specProvider.GenesisSpec); stateProvider.CommitTree(); // '@winsvega added a 0-wei reward to the miner , so we had to add that into the state test execution phase. He needed it for retesteth.' if (!stateProvider.AccountExists(test.CurrentCoinbase)) { stateProvider.CreateAccount(test.CurrentCoinbase, 0); } stateProvider.RecalculateStateRoot(); List <string> differences = RunAssertions(test, stateProvider); EthereumTestResult testResult = new EthereumTestResult(); testResult.Pass = differences.Count == 0; testResult.Fork = test.ForkName; testResult.Name = test.Name; testResult.TimeInMs = (int)stopwatch.Elapsed.TotalMilliseconds; testResult.StateRoot = stateProvider.StateRoot; // Assert.Zero(differences.Count, "differences"); return(testResult); }
// [TestCase(8, 32, 8, 1543322391)] public void Fuzz_accounts_with_storage( int accountsCount, int blocksCount, int lookupLimit, int?seed) { int usedSeed = seed ?? _random.Next(int.MaxValue); _random = new Random(usedSeed); _logger.Info($"RANDOM SEED {usedSeed}"); string fileName = Path.GetTempFileName(); //string fileName = "C:\\Temp\\fuzz.txt"; _logger.Info( $"Fuzzing with accounts: {accountsCount}, " + $"blocks {blocksCount}, " + $"lookup: {lookupLimit} into file {fileName}"); using FileStream fileStream = new FileStream(fileName, FileMode.Create); using StreamWriter streamWriter = new StreamWriter(fileStream); Queue <Keccak> rootQueue = new Queue <Keccak>(); MemDb memDb = new MemDb(); TrieStore trieStore = new TrieStore(memDb, Prune.WhenCacheReaches(1.MB()), Persist.IfBlockOlderThan(lookupLimit), _logManager); StateProvider stateProvider = new StateProvider(trieStore, new MemDb(), _logManager); StorageProvider storageProvider = new StorageProvider(trieStore, stateProvider, _logManager); Account[] accounts = new Account[accountsCount]; Address[] addresses = new Address[accountsCount]; for (int i = 0; i < accounts.Length; i++) { bool isEmptyValue = _random.Next(0, 2) == 0; if (isEmptyValue) { accounts[i] = Account.TotallyEmpty; } else { accounts[i] = GenerateRandomAccount(); } addresses[i] = TestItem.GetRandomAddress(_random); } for (int blockNumber = 0; blockNumber < blocksCount; blockNumber++) { bool isEmptyBlock = _random.Next(5) == 0; if (!isEmptyBlock) { for (int i = 0; i < Math.Max(1, accountsCount / 8); i++) { int randomAddressIndex = _random.Next(addresses.Length); int randomAccountIndex = _random.Next(accounts.Length); Address address = addresses[randomAddressIndex]; Account account = accounts[randomAccountIndex]; if (stateProvider.AccountExists(address)) { Account existing = stateProvider.GetAccount(address); if (existing.Balance != account.Balance) { if (account.Balance > existing.Balance) { stateProvider.AddToBalance( address, account.Balance - existing.Balance, MuirGlacier.Instance); } else { stateProvider.SubtractFromBalance( address, existing.Balance - account.Balance, MuirGlacier.Instance); } stateProvider.IncrementNonce(address); } byte[] storage = new byte[1]; _random.NextBytes(storage); storageProvider.Set(new StorageCell(address, 1), storage); } else if (!account.IsTotallyEmpty) { stateProvider.CreateAccount(address, account.Balance); byte[] storage = new byte[1]; _random.NextBytes(storage); storageProvider.Set(new StorageCell(address, 1), storage); } } } streamWriter.WriteLine( $"Commit block {blockNumber} | empty: {isEmptyBlock}"); storageProvider.Commit(); stateProvider.Commit(MuirGlacier.Instance); storageProvider.CommitTrees(blockNumber); stateProvider.CommitTree(blockNumber); rootQueue.Enqueue(stateProvider.StateRoot); } streamWriter.Flush(); fileStream.Seek(0, SeekOrigin.Begin); streamWriter.WriteLine($"DB size: {memDb.Keys.Count}"); _logger.Info($"DB size: {memDb.Keys.Count}"); int verifiedBlocks = 0; while (rootQueue.TryDequeue(out Keccak currentRoot)) { try { stateProvider.StateRoot = currentRoot; for (int i = 0; i < addresses.Length; i++) { Account account = stateProvider.GetAccount(addresses[i]); if (account != null) { for (int j = 0; j < 256; j++) { storageProvider.Get(new StorageCell(addresses[i], (UInt256)j)); } } } _logger.Info($"Verified positive {verifiedBlocks}"); } catch (Exception ex) { if (verifiedBlocks % lookupLimit == 0) { throw new InvalidDataException(ex.ToString()); } else { _logger.Info($"Verified negative {verifiedBlocks} which is ok here"); } } verifiedBlocks++; } }
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); }
private void TestCallWithStorageAndCode(byte[] code, UInt256 gasPrice, Address from = null) { StateProvider stateProvider = CreateInitialState(code); StorageProvider storageProvider = new StorageProvider(new TrieStore(_dbProvider.StateDb, LimboLogs.Instance), stateProvider, LimboLogs.Instance); for (int i = 0; i < 10000; i++) { storageProvider.Set(new StorageCell(TestItem.AddressB, (UInt256)i), i.ToBigEndianByteArray()); } storageProvider.Commit(); storageProvider.CommitTrees(0); stateProvider.Commit(MainnetSpecProvider.Instance.GenesisSpec, null); stateProvider.CommitTree(0); Keccak root = stateProvider.StateRoot; Block block = Build.A.Block.WithParent(_blockTree.Head).WithStateRoot(root).TestObject; BlockTreeBuilder.AddBlock(_blockTree, block); Block blockOnTop = Build.A.Block.WithParent(block).WithStateRoot(root).TestObject; BlockTreeBuilder.AddBlock(_blockTree, blockOnTop); // would need to setup state root somehow... TransactionForRpc tx = new TransactionForRpc { // we are testing system transaction here when From is null From = from, To = TestItem.AddressB, GasPrice = gasPrice, Nonce = 1000 }; CallResultWithProof callResultWithProof = _proofModule.proof_call(tx, new BlockParameter(blockOnTop.Number)).Data; Assert.Greater(callResultWithProof.Accounts.Length, 0); // just the keys for debugging Span <byte> span = stackalloc byte[32]; new UInt256(0).ToBigEndian(span); Keccak k0 = Keccak.Compute(span); // just the keys for debugging new UInt256(1).ToBigEndian(span); Keccak k1 = Keccak.Compute(span); // just the keys for debugging new UInt256(2).ToBigEndian(span); Keccak k2 = Keccak.Compute(span); foreach (AccountProof accountProof in callResultWithProof.Accounts) { // this is here for diagnostics - so you can read what happens in the test // generally the account here should be consistent with the values inside the proof // the exception will be thrown if the account did not exist before the call Account account; try { account = new AccountDecoder().Decode(new RlpStream(ProofVerifier.Verify(accountProof.Proof, block.StateRoot))); } catch (Exception) { // ignored } foreach (StorageProof storageProof in accountProof.StorageProofs) { // we read the values here just to allow easier debugging so you can confirm that the value is same as the one in the proof and in the trie byte[] value = ProofVerifier.Verify(storageProof.Proof, accountProof.StorageRoot); } } EthereumJsonSerializer serializer = new EthereumJsonSerializer(); string response = RpcTest.TestSerializedRequest(_proofModule, "proof_call", $"{serializer.Serialize(tx)}", $"{blockOnTop.Number}"); Assert.True(response.Contains("\"result\"")); }