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);
        }
示例#2
0
 private void AddAccount(StateProvider stateProvider, Address account, UInt256 initialBalance)
 {
     stateProvider.CreateAccount(account, initialBalance);
     stateProvider.Commit(MuirGlacier.Instance, null);
     stateProvider.CommitTree();
     _dbProvider.StateDb.Commit();
 }
示例#3
0
        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 });
        }
示例#4
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();
        }
示例#5
0
        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 */
        }
示例#7
0
        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();
        }
示例#8
0
        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);
        }
示例#10
0
        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);
        }
示例#13
0
        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);
        }
示例#15
0
        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));
        }
示例#16
0
        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);
        }
示例#17
0
        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 */
        }
示例#18
0
            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);
            }
示例#19
0
        private SyncTestContext CreateSyncManager(int index)
        {
            var logManager            = NoErrorLimboLogs.Instance;
            ConsoleAsyncLogger logger = new ConsoleAsyncLogger(LogLevel.Debug, "PEER " + index + " ");
//            var logManager = new OneLoggerLogManager(logger);
            var specProvider = new SingleReleaseSpecProvider(ConstantinopleFix.Instance, MainnetSpecProvider.Instance.ChainId);

            var             dbProvider  = 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);
        }
示例#20
0
        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);
            }
示例#22
0
        private SyncTestContext CreateSyncManager(int index)
        {
            Rlp.RegisterDecoders(typeof(ParityTraceDecoder).Assembly);

            var logManager            = NoErrorLimboLogs.Instance;
            ConsoleAsyncLogger logger = new ConsoleAsyncLogger(LogLevel.Debug, "PEER " + index + " ");
//            var logManager = new OneLoggerLogManager(logger);
            var specProvider = new SingleReleaseSpecProvider(ConstantinopleFix.Instance, MainNetSpecProvider.Instance.ChainId);

            MemDb   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);
        }
示例#23
0
        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);
        }
示例#24
0
        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);
        }
示例#25
0
        // [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++;
            }
        }
示例#26
0
        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);
        }
示例#27
0
        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\""));
        }