protected override void InitSealEngine()
        {
            _context.RewardCalculatorSource = RewardCalculator.GetSource(_context.SpecProvider);
            DifficultyCalculator difficultyCalculator = new DifficultyCalculator(_context.SpecProvider);

            _context.Sealer        = _context.Config <IInitConfig>().IsMining ? (ISealer) new EthashSealer(new Ethash(_context.LogManager), _context.LogManager) : NullSealEngine.Instance;
            _context.SealValidator = new EthashSealValidator(_context.LogManager, difficultyCalculator, _context.CryptoRandom, new Ethash(_context.LogManager));
        }
        public void CalculateRewards_NullRewardPeriod_Throws_NullArgumentException_Test()
        {
            // 1. ARRANGE
            var calculator = new RewardCalculator(null);

            // 2. ACTION
            calculator.CalculateRewards(null);
        }
        public void No_uncles()
        {
            Block block = Build.A.Block.WithNumber(3).TestObject;

            RewardCalculator calculator = new RewardCalculator(RopstenSpecProvider.Instance);

            BlockReward[] rewards = calculator.CalculateRewards(block);

            Assert.AreEqual(1, rewards.Length);
            Assert.AreEqual(5000000000000000000, (long)rewards[0].Value, "miner");
        }
        public void One_uncle()
        {
            Block ommer = Build.A.Block.WithNumber(1).TestObject;
            Block block = Build.A.Block.WithNumber(3).WithOmmers(ommer).TestObject;

            RewardCalculator calculator = new RewardCalculator(RopstenSpecProvider.Instance);

            BlockReward[] rewards = calculator.CalculateRewards(block);

            Assert.AreEqual(2, rewards.Length);
            Assert.AreEqual(5156250000000000000, (long)rewards[0].Value, "miner");
            Assert.AreEqual(3750000000000000000, (long)rewards[1].Value, "uncle1");
        }
        public void Two_uncles_from_the_same_coinbase()
        {
            Block ommer  = Build.A.Block.WithNumber(1).TestObject;
            Block ommer2 = Build.A.Block.WithNumber(1).TestObject;
            Block block  = Build.A.Block.WithNumber(3).WithOmmers(ommer, ommer2).TestObject;

            RewardCalculator calculator = new RewardCalculator(RopstenSpecProvider.Instance);

            BlockReward[] rewards = calculator.CalculateRewards(block);

            Assert.AreEqual(3, rewards.Length);
            Assert.AreEqual(5312500000000000000, (long)rewards[0].Value, "miner");
            Assert.AreEqual(3750000000000000000, (long)rewards[1].Value, "uncle1");
            Assert.AreEqual(3750000000000000000, (long)rewards[2].Value, "uncle2");
        }
        public void Constantinople_reward_two_uncles()
        {
            UInt256 blockNumber = RopstenSpecProvider.ConstantinopleBlockNumber;
            Block   ommer       = Build.A.Block.WithNumber(blockNumber - 2).TestObject;
            Block   ommer2      = Build.A.Block.WithNumber(blockNumber - 2).TestObject;
            Block   block       = Build.A.Block.WithNumber(blockNumber).WithOmmers(ommer, ommer2).TestObject;

            RewardCalculator calculator = new RewardCalculator(RopstenSpecProvider.Instance);

            BlockReward[] rewards = calculator.CalculateRewards(block);

            Assert.AreEqual(3, rewards.Length);
            Assert.AreEqual(2125000000000000000, (long)rewards[0].Value, "miner");
            Assert.AreEqual(1500000000000000000, (long)rewards[1].Value, "uncle1");
            Assert.AreEqual(1500000000000000000, (long)rewards[2].Value, "uncle2");
        }
Beispiel #7
0
        private static void GenerateItemRange(SmallBOD bod, RewardCalculator calc, JsonWriter writer)
        {
            for (int qty = 10; qty <= 20; qty += 5)
            {
                for (int res = 0; res <= (int)BulkMaterialType.Valorite; res++)
                {
                    bod.AmountMax = qty;
                    bod.Material  = (BulkMaterialType)res;

                    bod.RequireExceptional = false;
                    GenerateItem(bod, calc, writer);

                    bod.RequireExceptional = true;
                    GenerateItem(bod, calc, writer);
                    //GenerateItem(calc, qty, res, false, writer);
                }
            }
        }
Beispiel #8
0
        private static void GenerateBods(RewardCalculator calc, string file)
        {
            var stw = new StreamWriter("web/" + file);

            using (JsonWriter writer = new JsonTextWriter(stw))
            {
                writer.Formatting = Formatting.Indented;
                //writer.WritePropertyName("items");
                writer.WriteStartArray();
                if (calc is SmithRewardCalculator)
                {
                    SmallBOD sbod = new SmallSmithBOD();

                    sbod.Type = typeof(PlateArms);

                    GenerateItemRange(sbod, calc, writer);
                    sbod.Type = typeof(Dagger);
                    GenerateItemRange(sbod, calc, writer);

                    GenerateLBod(writer, calc, LargeBulkEntry.LargeRing);
                    GenerateLBod(writer, calc, LargeBulkEntry.LargeChain);
                    GenerateLBod(writer, calc, LargeBulkEntry.LargePlate);
                }
                else
                {
                    var sbod = new SmallTailorBOD();
                    sbod.Type = typeof(TricorneHat);
                    GenerateItemRange(sbod, calc, writer);
                    sbod.Type = typeof(LeatherArms);
                    GenerateItemRange(sbod, calc, writer);

                    GenerateLBod(writer, calc, LargeBulkEntry.LargeRing);
                    GenerateLBod(writer, calc, LargeBulkEntry.LargeChain);
                    GenerateLBod(writer, calc, LargeBulkEntry.LargePlate);
                }
            }
        }
Beispiel #9
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);
        }
        public async Task Can_process_mined_blocks()
        {
            int timeMultiplier = 1; // for debugging

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

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

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

            RopstenSpecProvider specProvider = RopstenSpecProvider.Instance;

            /* store & validation */

            EthereumEcdsa        ecdsa                = new EthereumEcdsa(specProvider, logManager);
            MemDb                receiptsDb           = new MemDb();
            MemDb                traceDb              = new MemDb();
            TxPool               txPool               = new TxPool(NullTxStorage.Instance, Timestamp.Default, ecdsa, specProvider, new TxPoolConfig(), logManager);
            IReceiptStorage      receiptStorage       = new PersistentReceiptStorage(receiptsDb, NullDb.Instance, specProvider, logManager);
            BlockTree            blockTree            = new BlockTree(new MemDb(), new MemDb(), new MemDb(), specProvider, txPool, logManager);
            Timestamp            timestamp            = new Timestamp();
            DifficultyCalculator difficultyCalculator = new DifficultyCalculator(specProvider);
            HeaderValidator      headerValidator      = new HeaderValidator(blockTree, sealer, specProvider, logManager);
            OmmersValidator      ommersValidator      = new OmmersValidator(blockTree, headerValidator, logManager);
            TxValidator          txValidator          = new TxValidator(ChainId.Ropsten);
            BlockValidator       blockValidator       = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, logManager);

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

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

            generator.Start();

            /* blockchain processing */
            BlockhashProvider    blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance);
            VirtualMachine       virtualMachine    = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, logManager);
            TransactionProcessor processor         = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, logManager);
            RewardCalculator     rewardCalculator  = new RewardCalculator(specProvider);
            BlockProcessor       blockProcessor    = new BlockProcessor(specProvider, blockValidator, rewardCalculator,
                                                                        processor, stateDb, codeDb, traceDb, stateProvider, storageProvider, txPool, receiptStorage, logManager);
            BlockchainProcessor blockchainProcessor = new BlockchainProcessor(blockTree, blockProcessor, new TxSignaturesRecoveryStep(ecdsa, NullTxPool.Instance, LimboLogs.Instance), logManager, false, false);

            /* load ChainSpec and init */
            ChainSpecLoader loader = new ChainSpecLoader(new EthereumJsonSerializer());
            string          path   = "chainspec.json";

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

            foreach (var allocation in chainSpec.Allocations)
            {
                stateProvider.CreateAccount(allocation.Key, allocation.Value.Balance);
                if (allocation.Value.Code != null)
                {
                    Keccak codeHash = stateProvider.UpdateCode(allocation.Value.Code);
                    stateProvider.UpdateCodeHash(allocation.Key, codeHash, specProvider.GenesisSpec);
                }
            }

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

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

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

            minedBlockProducer.Start();

            ManualResetEventSlim manualResetEvent = new ManualResetEventSlim(false);

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

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

            int previousCount = 0;
            int totalTx       = 0;

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

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

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

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

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

                previousCount = currentCount;
            }

            Assert.AreNotEqual(0, totalTx, "no tx in blocks");
        }
Beispiel #11
0
        protected async Task RunTest(LegacyBlockchainTest test, Stopwatch stopwatch = null)
        {
            TestContext.Write($"Running {test.Name} at {DateTime.UtcNow:HH:mm:ss.ffffff}");
            Assert.IsNull(test.LoadFailure, "test data loading failure");

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

            ISpecProvider specProvider;

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

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

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

            IEthereumEcdsa     ecdsa             = new EthereumEcdsa(specProvider, _logManager);
            IStateProvider     stateProvider     = new StateProvider(stateDb, codeDb, _logManager);
            ITxPool            transactionPool   = new TxPool(NullTxStorage.Instance, new Timestamper(), ecdsa, specProvider, new TxPoolConfig(), stateProvider, _logManager);
            IReceiptStorage    receiptStorage    = NullReceiptStorage.Instance;
            var                blockInfoDb       = new MemDb();
            IBlockTree         blockTree         = new BlockTree(new MemDb(), new MemDb(), blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, transactionPool, _logManager);
            IBlockhashProvider blockhashProvider = new BlockhashProvider(blockTree, _logManager);
            ITxValidator       txValidator       = new TxValidator(ChainId.MainNet);
            IHeaderValidator   headerValidator   = new HeaderValidator(blockTree, Sealer, specProvider, _logManager);
            IOmmersValidator   ommersValidator   = new OmmersValidator(blockTree, headerValidator, _logManager);
            IBlockValidator    blockValidator    = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, _logManager);
            IStorageProvider   storageProvider   = new StorageProvider(stateDb, stateProvider, _logManager);
            IVirtualMachine    virtualMachine    = new VirtualMachine(
                stateProvider,
                storageProvider,
                blockhashProvider,
                specProvider,
                _logManager);

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

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

            InitializeTestState(test, stateProvider, storageProvider, specProvider);

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

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

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

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

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

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

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

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

            ManualResetEvent genesisProcessed = new ManualResetEvent(false);

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

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

            genesisProcessed.WaitOne();

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

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

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

            await blockchainProcessor.StopAsync(true);

            stopwatch?.Stop();

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

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

            Assert.Zero(differences.Count, "differences");
        }
Beispiel #12
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);
        }
        // It takes dotCover to run it quite long, increased timeouts
        public async Task Can_process_mined_blocks()
        {
            int timeMultiplier = 1; // for debugging

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

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

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

            RopstenSpecProvider specProvider = RopstenSpecProvider.Instance;

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

            /* store & validation */

            EthereumEcdsa ecdsa      = new EthereumEcdsa(specProvider, logManager);
            MemDb         receiptsDb = new MemDb();

            TxPool.TxPool        txPool               = new TxPool.TxPool(NullTxStorage.Instance, Timestamper.Default, ecdsa, specProvider, new TxPoolConfig(), stateProvider, logManager);
            IReceiptStorage      receiptStorage       = new PersistentReceiptStorage(receiptsDb, specProvider, logManager);
            var                  blockInfoDb          = new MemDb();
            BlockTree            blockTree            = new BlockTree(new MemDb(), new MemDb(), blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, txPool, NullBloomStorage.Instance, logManager);
            Timestamper          timestamper          = new Timestamper();
            DifficultyCalculator difficultyCalculator = new DifficultyCalculator(specProvider);
            HeaderValidator      headerValidator      = new HeaderValidator(blockTree, sealer, specProvider, logManager);
            OmmersValidator      ommersValidator      = new OmmersValidator(blockTree, headerValidator, logManager);
            TxValidator          txValidator          = new TxValidator(ChainId.Ropsten);
            BlockValidator       blockValidator       = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, logManager);

            TestTransactionsGenerator generator = new TestTransactionsGenerator(txPool, ecdsa, TimeSpan.FromMilliseconds(50 * timeMultiplier), LimboLogs.Instance);

            generator.Start();

            /* blockchain processing */
            BlockhashProvider    blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance);
            VirtualMachine       virtualMachine    = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, specProvider, logManager);
            TransactionProcessor processor         = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, logManager);
            RewardCalculator     rewardCalculator  = new RewardCalculator(specProvider);
            BlockProcessor       blockProcessor    = new BlockProcessor(specProvider, blockValidator, rewardCalculator,
                                                                        processor, stateDb, codeDb, stateProvider, storageProvider, txPool, receiptStorage, logManager);
            BlockchainProcessor blockchainProcessor = new BlockchainProcessor(blockTree, blockProcessor, new TxSignaturesRecoveryStep(ecdsa, NullTxPool.Instance, LimboLogs.Instance), logManager, false);

            /* load ChainSpec and init */
            ChainSpecLoader loader = new ChainSpecLoader(new EthereumJsonSerializer());
            string          path   = "chainspec.json";

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

            foreach (var allocation in chainSpec.Allocations)
            {
                stateProvider.CreateAccount(allocation.Key, allocation.Value.Balance);
                if (allocation.Value.Code != null)
                {
                    Keccak codeHash = stateProvider.UpdateCode(allocation.Value.Code);
                    stateProvider.UpdateCodeHash(allocation.Key, codeHash, specProvider.GenesisSpec);
                }
            }

            stateProvider.Commit(specProvider.GenesisSpec);
            chainSpec.Genesis.Header.StateRoot = stateProvider.StateRoot;
            chainSpec.Genesis.Header.Hash      = chainSpec.Genesis.Header.CalculateHash();
            if (chainSpec.Genesis.Hash != new Keccak("0xafbc3c327d2d18ff2b843e89226ef288fcee379542f854f982e4cfb85916d126"))
            {
                throw new Exception("Unexpected genesis hash");
            }

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

            var transactionSelector = new PendingTxSelector(txPool, stateProvider, logManager);
            MinedBlockProducer minedBlockProducer = new MinedBlockProducer(transactionSelector, blockchainProcessor, sealer, blockTree, blockchainProcessor, stateProvider, timestamper, LimboLogs.Instance, difficultyCalculator);

            minedBlockProducer.Start();

            ManualResetEventSlim manualResetEvent = new ManualResetEventSlim(false);

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

            manualResetEvent.Wait(miningDelay * 100);
            await minedBlockProducer.StopAsync();

            int previousCount = 0;
            int totalTx       = 0;

            for (int i = 0; i < 6; i++)
            {
                Block block = blockTree.FindBlock(i, BlockTreeLookupOptions.None);
                Assert.That(block, Is.Not.Null, $"Block {i} not produced");
                logger.Info($"Block {i} with {block.Transactions.Length} txs");

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

                GethStyleTracer gethStyleTracer = new GethStyleTracer(blockchainProcessor, receiptStorage, blockTree);

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

                if (block.Transactions.Length > 0)
                {
                    Assert.AreNotEqual(previousCount, currentCount, $"receipts at block {i}");
                    totalTx += block.Transactions.Length;
                }

                previousCount = currentCount;
            }

            Assert.AreNotEqual(0, totalTx, "no tx in blocks");
        }
Beispiel #14
0
        private static async Task RunBenchmarkBlocks()
        {
            Rlp.RegisterDecoders(typeof(ParityTraceDecoder).Assembly);

            /* logging & instrumentation */
            _logManager = new NLogManager("perfTest.logs.txt", null);
            _logger     = _logManager.GetClassLogger();

            if (_logger.IsInfo)
            {
                _logger.Info("Deleting state DBs");
            }

            DeleteDb(FullStateDbPath);
            DeleteDb(FullCodeDbPath);
            DeleteDb(FullReceiptsDbPath);
            DeleteDb(FullPendingTxsDbPath);
            if (_logger.IsInfo)
            {
                _logger.Info("State DBs deleted");
            }

            /* load spec */
            ChainSpecLoader loader = new ChainSpecLoader(new EthereumJsonSerializer());
            string          path   = Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"chainspec", "ropsten.json"));

            _logger.Info($"Loading ChainSpec from {path}");
            ChainSpec chainSpec = loader.Load(File.ReadAllText(path));

            _logger.Info($"ChainSpec loaded");

            var specProvider = new ChainSpecBasedSpecProvider(chainSpec);
            IRewardCalculator rewardCalculator = new RewardCalculator(specProvider);

            var dbProvider   = new RocksDbProvider(DbBasePath, DbConfig.Default, _logManager, true, true);
            var stateDb      = dbProvider.StateDb;
            var codeDb       = dbProvider.CodeDb;
            var traceDb      = dbProvider.TraceDb;
            var blocksDb     = dbProvider.BlocksDb;
            var headersDb    = dbProvider.HeadersDb;
            var blockInfosDb = dbProvider.BlockInfosDb;
            var receiptsDb   = dbProvider.ReceiptsDb;

            /* state & storage */
            var stateProvider   = new StateProvider(stateDb, codeDb, _logManager);
            var storageProvider = new StorageProvider(stateDb, stateProvider, _logManager);

            var ethereumSigner = new EthereumEcdsa(specProvider, _logManager);

            var transactionPool = new TxPool(
                NullTxStorage.Instance,
                Timestamper.Default,
                ethereumSigner,
                specProvider,
                new TxPoolConfig(),
                stateProvider,
                _logManager);

            var blockInfoRepository = new ChainLevelInfoRepository(blockInfosDb);
            var blockTree           = new UnprocessedBlockTreeWrapper(new BlockTree(blocksDb, headersDb, blockInfosDb, blockInfoRepository, specProvider, transactionPool, _logManager));
            var receiptStorage      = new InMemoryReceiptStorage();

            IBlockDataRecoveryStep recoveryStep = new TxSignaturesRecoveryStep(ethereumSigner, transactionPool, _logManager);

            /* blockchain processing */
            IList <IAdditionalBlockProcessor> blockProcessors = new List <IAdditionalBlockProcessor>();
            var blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance);
            var virtualMachine    = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, specProvider, _logManager);
            var processor         = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, _logManager);

            ISealValidator sealValidator;

            if (specProvider.ChainId == RopstenSpecProvider.Instance.ChainId)
            {
                var difficultyCalculator = new DifficultyCalculator(specProvider);
                sealValidator = new EthashSealValidator(_logManager, difficultyCalculator, new Ethash(_logManager));
            }
            else if (chainSpec.SealEngineType == SealEngineType.Clique)
            {
                var snapshotManager = new SnapshotManager(CliqueConfig.Default, blocksDb, blockTree, ethereumSigner, _logManager);
                sealValidator    = new CliqueSealValidator(CliqueConfig.Default, snapshotManager, _logManager);
                rewardCalculator = NoBlockRewards.Instance;
                recoveryStep     = new CompositeDataRecoveryStep(recoveryStep, new AuthorRecoveryStep(snapshotManager));
            }
            else if (chainSpec.SealEngineType == SealEngineType.AuRa)
            {
                var abiEncoder         = new AbiEncoder();
                var validatorProcessor = new AuRaAdditionalBlockProcessorFactory(dbProvider.StateDb, stateProvider, abiEncoder, processor, blockTree, receiptStorage, _logManager)
                                         .CreateValidatorProcessor(chainSpec.AuRa.Validators);

                sealValidator    = new AuRaSealValidator(chainSpec.AuRa, new AuRaStepCalculator(chainSpec.AuRa.StepDuration, new Timestamper()), validatorProcessor, ethereumSigner, _logManager);
                rewardCalculator = new AuRaRewardCalculator(chainSpec.AuRa, abiEncoder, processor);
                blockProcessors.Add(validatorProcessor);
            }
            else
            {
                throw new NotSupportedException();
            }

            /* store & validation */
            var headerValidator      = new HeaderValidator(blockTree, sealValidator, specProvider, _logManager);
            var ommersValidator      = new OmmersValidator(blockTree, headerValidator, _logManager);
            var transactionValidator = new TxValidator(chainSpec.ChainId);
            var blockValidator       = new BlockValidator(transactionValidator, headerValidator, ommersValidator, specProvider, _logManager);

            /* blockchain processing */
            var blockProcessor      = new BlockProcessor(specProvider, blockValidator, rewardCalculator, processor, stateDb, codeDb, traceDb, stateProvider, storageProvider, transactionPool, receiptStorage, _logManager, blockProcessors);
            var blockchainProcessor = new BlockchainProcessor(blockTree, blockProcessor, recoveryStep, _logManager, true, false);

            if (chainSpec.SealEngineType == SealEngineType.AuRa)
            {
                stateProvider.CreateAccount(Address.Zero, UInt256.Zero);
                storageProvider.Commit();
                stateProvider.Commit(Homestead.Instance);
                var finalizationManager = new AuRaBlockFinalizationManager(blockTree, blockInfoRepository, blockProcessor, blockProcessors.OfType <IAuRaValidator>().First(), _logManager);
            }

            foreach ((Address address, ChainSpecAllocation allocation) in chainSpec.Allocations)
            {
                stateProvider.CreateAccount(address, allocation.Balance);
                if (allocation.Code != null)
                {
                    Keccak codeHash = stateProvider.UpdateCode(allocation.Code);
                    stateProvider.UpdateCodeHash(address, codeHash, specProvider.GenesisSpec);
                }

                if (allocation.Constructor != null)
                {
                    Transaction constructorTransaction = new Transaction(true)
                    {
                        SenderAddress = address,
                        Init          = allocation.Constructor,
                        GasLimit      = chainSpec.Genesis.GasLimit
                    };

                    processor.Execute(constructorTransaction, chainSpec.Genesis.Header, NullTxTracer.Instance);
                }
            }

            _logger.Info($"Allocations configured, committing...");

            stateProvider.Commit(specProvider.GenesisSpec);

            _logger.Info($"Finalizing genesis...");
            chainSpec.Genesis.Header.StateRoot = stateProvider.StateRoot;
            chainSpec.Genesis.Header.Hash      = BlockHeader.CalculateHash(chainSpec.Genesis.Header);

            if (chainSpec.Genesis.Hash != blockTree.Genesis.Hash)
            {
                throw new Exception("Unexpected genesis hash");
            }

            _logger.Info($"Starting benchmark processor...");
            /* start processing */
            BigInteger totalGas  = BigInteger.Zero;
            Stopwatch  stopwatch = new Stopwatch();
            Block      currentHead;
            long       maxMemory = 0;

            blockTree.NewHeadBlock += (sender, args) =>
            {
                currentHead = args.Block;
                if (currentHead.Number == 0)
                {
                    return;
                }

                maxMemory = Math.Max(maxMemory, GC.GetTotalMemory(false));
                totalGas += currentHead.GasUsed;
                if ((BigInteger)args.Block.Number % 10000 == 9999)
                {
                    stopwatch.Stop();
                    long       ms     = 1_000L * stopwatch.ElapsedTicks / Stopwatch.Frequency;
                    BigInteger number = args.Block.Number + 1;
                    _logger.Warn($"TOTAL after {number} (ms)       : " + ms);
                    _logger.Warn($"TOTAL after {number} blocks/s   : {(decimal) currentHead.Number / (ms / 1000m),5}");
                    _logger.Warn($"TOTAL after {number} Mgas/s     : {((decimal) totalGas / 1000000) / (ms / 1000m),5}");
                    _logger.Warn($"TOTAL after {number} max mem    : {maxMemory}");
                    _logger.Warn($"TOTAL after {number} GC (0/1/2) : {GC.CollectionCount(0)}/{GC.CollectionCount(1)}/{GC.CollectionCount(2)}");
                    _logger.Warn($"Is server GC {number}           : {System.Runtime.GCSettings.IsServerGC}");
                    _logger.Warn($"GC latency mode {number}        : {System.Runtime.GCSettings.LatencyMode}");

                    _logger.Warn($"TOTAL after {number} blocks DB reads      : {Store.Metrics.BlocksDbReads}");
                    _logger.Warn($"TOTAL after {number} blocks DB writes     : {Store.Metrics.BlocksDbWrites}");
                    _logger.Warn($"TOTAL after {number} infos DB reads       : {Store.Metrics.BlockInfosDbReads}");
                    _logger.Warn($"TOTAL after {number} infos DB writes      : {Store.Metrics.BlockInfosDbWrites}");
                    _logger.Warn($"TOTAL after {number} state tree reads     : {Store.Metrics.StateTreeReads}");
                    _logger.Warn($"TOTAL after {number} state tree writes    : {Store.Metrics.StateTreeWrites}");
                    _logger.Warn($"TOTAL after {number} state DB reads       : {Store.Metrics.StateDbReads}");
                    _logger.Warn($"TOTAL after {number} state DB writes      : {Store.Metrics.StateDbWrites}");
                    _logger.Warn($"TOTAL after {number} storage tree reads   : {Store.Metrics.StorageTreeReads}");
                    _logger.Warn($"TOTAL after {number} storage tree writes  : {Store.Metrics.StorageTreeWrites}");
                    _logger.Warn($"TOTAL after {number} tree node hash       : {Store.Metrics.TreeNodeHashCalculations}");
                    _logger.Warn($"TOTAL after {number} tree node RLP decode : {Store.Metrics.TreeNodeRlpDecodings}");
                    _logger.Warn($"TOTAL after {number} tree node RLP encode : {Store.Metrics.TreeNodeRlpEncodings}");
                    _logger.Warn($"TOTAL after {number} code DB reads        : {Store.Metrics.CodeDbReads}");
                    _logger.Warn($"TOTAL after {number} code DB writes       : {Store.Metrics.CodeDbWrites}");
                    _logger.Warn($"TOTAL after {number} receipts DB reads    : {Store.Metrics.ReceiptsDbReads}");
                    _logger.Warn($"TOTAL after {number} receipts DB writes   : {Store.Metrics.ReceiptsDbWrites}");
                    _logger.Warn($"TOTAL after {number} other DB reads       : {Store.Metrics.OtherDbReads}");
                    _logger.Warn($"TOTAL after {number} other DB writes      : {Store.Metrics.OtherDbWrites}");
                    _logger.Warn($"TOTAL after {number} EVM exceptions       : {Evm.Metrics.EvmExceptions}");
                    _logger.Warn($"TOTAL after {number} SLOAD opcodes        : {Evm.Metrics.SloadOpcode}");
                    _logger.Warn($"TOTAL after {number} SSTORE opcodes       : {Evm.Metrics.SstoreOpcode}");
                    _logger.Warn($"TOTAL after {number} EXP opcodes          : {Evm.Metrics.ModExpOpcode}");
                    _logger.Warn($"TOTAL after {number} BLOCKHASH opcodes    : {Evm.Metrics.BlockhashOpcode}");
                    _logger.Warn($"TOTAL after {number} EVM calls            : {Evm.Metrics.Calls}");
                    _logger.Warn($"TOTAL after {number} RIPEMD Precompiles   : {Evm.Metrics.Ripemd160Precompile}");
                    _logger.Warn($"TOTAL after {number} SHA256 Precompiles   : {Evm.Metrics.Sha256Precompile}");
                    // disk space
                    stopwatch.Start();
                }
            };

            bool isStarted = false;

            TaskCompletionSource <object> completionSource = new TaskCompletionSource <object>();

            blockTree.NewBestSuggestedBlock += (sender, args) =>
            {
                if (!isStarted)
                {
                    blockchainProcessor.Process(blockTree.FindBlock(blockTree.Genesis.Hash, BlockTreeLookupOptions.RequireCanonical), ProcessingOptions.None, NullBlockTracer.Instance);
                    stopwatch.Start();
                    blockchainProcessor.Start();
                    isStarted = true;
                }

                if (args.Block.Number == BlocksToLoad)
                {
                    completionSource.SetResult(null);
                }
            };

            await Task.WhenAny(completionSource.Task, blockTree.LoadBlocksFromDb(CancellationToken.None, 0, 10000, BlocksToLoad));

            await blockchainProcessor.StopAsync(true).ContinueWith(
                t =>
            {
                if (t.IsFaulted)
                {
                    _logger.Error("processing failed", t.Exception);
                    _logger.Error("inner", t.Exception.InnerException);
                    Console.ReadLine();
                }

                _logger.Info("Block processing completed.");
            });

            stopwatch.Stop();
            Console.ReadLine();
        }
        public void Two_uncles_from_the_same_coinbase()
        {
            RewardCalculator calculator = new RewardCalculator(RopstenSpecProvider.Instance);
//            calculator.CalculateRewards()
        }
Beispiel #16
0
        private async Task InitBlockchain(InitParams initParams)
        {
            ChainSpec chainSpec = LoadChainSpec(initParams.ChainSpecPath);

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

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

            var ethereumSigner   = new EthereumSigner(specProvider, _logManager);
            var transactionStore = new TransactionStore();
            var sealEngine       = ConfigureSealEngine(transactionStore, ethereumSigner, initParams);

            /* sync */
            var blocksDb     = new DbOnTheRocks(Path.Combine(_dbBasePath, DbOnTheRocks.BlocksDbPath));
            var blockInfosDb = new DbOnTheRocks(Path.Combine(_dbBasePath, DbOnTheRocks.BlockInfosDbPath));
            var receiptsDb   = new DbOnTheRocks(Path.Combine(_dbBasePath, DbOnTheRocks.ReceiptsDbPath));

            /* blockchain */
            var blockTree            = new BlockTree(blocksDb, blockInfosDb, receiptsDb, specProvider, _logManager);
            var difficultyCalculator = new DifficultyCalculator(specProvider);

            /* validation */
            var headerValidator = new HeaderValidator(difficultyCalculator, blockTree, sealEngine, specProvider, _logManager);
            var ommersValidator = new OmmersValidator(blockTree, headerValidator, _logManager);
            var txValidator     = new TransactionValidator(new SignatureValidator(specProvider.ChainId));
            var blockValidator  = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, _logManager);

            /* state */
            var dbProvider      = new RocksDbProvider(_dbBasePath, _logManager);
            var codeDb          = new DbOnTheRocks(Path.Combine(_dbBasePath, DbOnTheRocks.CodeDbPath));
            var stateDb         = new DbOnTheRocks(Path.Combine(_dbBasePath, DbOnTheRocks.StateDbPath));
            var stateTree       = new StateTree(stateDb);
            var stateProvider   = new StateProvider(stateTree, codeDb, _logManager);
            var storageProvider = new StorageProvider(dbProvider, stateProvider, _logManager);

            /* blockchain processing */
            var blockhashProvider    = new BlockhashProvider(blockTree);
            var virtualMachine       = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, _logManager);
            var transactionProcessor = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, _tracer, _logManager);
            var rewardCalculator     = new RewardCalculator(specProvider);
            var blockProcessor       = new BlockProcessor(specProvider, blockValidator, rewardCalculator, transactionProcessor, dbProvider, stateProvider, storageProvider, transactionStore, _logManager);

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

            // create shared objects between discovery and peer manager
            _nodeFactory       = new NodeFactory();
            _nodeStatsProvider = new NodeStatsProvider(_configProvider);
            var jsonSerializer = new JsonSerializer(_logManager);
            var encrypter      = new AesEncrypter(_configProvider, _logManager);

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

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

            _blockchainProcessor.Start();
            LoadGenesisBlock(chainSpec, string.IsNullOrWhiteSpace(initParams.GenesisHash) ? null : new Keccak(initParams.GenesisHash), blockTree, stateProvider, specProvider);
            await StartProcessing(blockTree, transactionStore, blockValidator, headerValidator, txValidator, initParams);
        }
Beispiel #17
0
        private static void GenerateItem(SmallBOD bod, RewardCalculator calc, JsonWriter writer)
        {
            var items = bod.ComputeRewards(true);

            writer.WriteStartObject();

            writer.WritePropertyName("points");
            writer.WriteValue(calc.ComputePoints(bod).ToString());
            writer.WritePropertyName("material");
            if (bod.Material == BulkMaterialType.None)
            {
                writer.WriteValue("Iron");
            }
            else
            {
                writer.WriteValue(bod.Material.ToString());
            }
            writer.WritePropertyName("materialindex");
            writer.WriteValue((int)bod.Material + "");
            writer.WritePropertyName("qty");
            writer.WriteValue(bod.AmountMax.ToString());

            writer.WritePropertyName("bodtype");
            if (bod.Type.IsSubclassOf(typeof(BaseArmor)))
            {
                writer.WriteValue("Armor");
            }
            if (bod.Type.IsSubclassOf(typeof(BaseWeapon)))
            {
                writer.WriteValue("Weapon");
            }
            writer.WritePropertyName("excep");
            writer.WriteValue(bod.RequireExceptional);
            writer.WritePropertyName("rewards");
            writer.WriteStartArray();
            foreach (var r in items)
            {
                writer.WriteStartObject();
                writer.WritePropertyName("Name");
                if (r is SpecialScroll)
                {
                    var pscroll = r as SpecialScroll;
                    var name    = string.Format("a power scroll of {0} ({1} Skill)", pscroll.GetName(), pscroll.Value);
                    writer.WriteValue(name);
                }
                else
                {
                    if (r.LabelNumber == 0)
                    {
                        writer.WriteValue(r.Name);
                    }
                    else
                    {
                        writer.WriteValue(CliLoc.LocToString(r.LabelNumber));
                    }
                }


                writer.WritePropertyName("type");
                writer.WriteValue(CraftItem.ItemIDOf(r.GetType()));

                writer.WriteEndObject();
            }
            writer.WriteEndArray();

            writer.WriteEndObject();
            // var points = calc.ComputePoints(qty, v, (BulkMaterialType)res, 1, null);
            //  var reward = calc.LookupRewards(points);

            // var gold = calc.ComputeGold(qty, v, (BulkMaterialType)res, 1, null);
        }
        protected async Task <EthereumTestResult> RunTest(BlockchainTest test, Stopwatch?stopwatch = null)
        {
            TestContext.Write($"Running {test.Name} at {DateTime.UtcNow:HH:mm:ss.ffffff}");
            Assert.IsNull(test.LoadFailure, "test data loading failure");

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

            ISpecProvider specProvider;

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

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

            bool isNetworkAfterTransitionLondon = test.NetworkAfterTransition == London.Instance;

            HeaderDecoder.Eip1559TransitionBlock = isNetworkAfterTransitionLondon ? test.TransitionBlockNumber : long.MaxValue;

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

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

            TrieStore      trieStore     = new(stateDb, _logManager);
            IStateProvider stateProvider = new StateProvider(trieStore, codeDb, _logManager);
            MemDb          blockInfoDb   = new MemDb();
            IBlockTree     blockTree     = new BlockTree(new MemDb(), new MemDb(), blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), specProvider, NullBloomStorage.Instance, _logManager);
            ITransactionComparerProvider transactionComparerProvider = new TransactionComparerProvider(specProvider, blockTree);
            IStateReader           stateReader           = new StateReader(trieStore, codeDb, _logManager);
            IChainHeadInfoProvider chainHeadInfoProvider = new ChainHeadInfoProvider(specProvider, blockTree, stateReader);
            ITxPool transactionPool = new TxPool(ecdsa, chainHeadInfoProvider, new TxPoolConfig(), new TxValidator(specProvider.ChainId), _logManager, transactionComparerProvider.GetDefaultComparer());

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

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

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

            InitializeTestState(test, stateProvider, storageProvider, specProvider);

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

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

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

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

            if (correctRlp.Count == 0)
            {
                EthereumTestResult result;
                if (test.GenesisBlockHeader is null)
                {
                    result = new EthereumTestResult(test.Name, "Genesis block header missing in the test spec.");
                }
                else if (!new Keccak(test.GenesisBlockHeader.Hash).Equals(test.LastBlockHash))
                {
                    result = new EthereumTestResult(test.Name, "Genesis hash mismatch");
                }
                else
                {
                    result = new EthereumTestResult(test.Name, null, true);
                }

                return(result);
            }

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

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

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

            ManualResetEvent genesisProcessed = new(false);

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

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

            genesisProcessed.WaitOne();

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

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

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

            await blockchainProcessor.StopAsync(true);

            stopwatch?.Stop();

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

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

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

            return(new EthereumTestResult
                   (
                       test.Name,
                       null,
                       differences.Count == 0
                   ));
        }
Beispiel #19
0
        protected async Task RunTest(BlockchainTest test, Stopwatch stopwatch = null)
        {
            LoggingTraceListener traceListener = new LoggingTraceListener();
            // TODO: not supported in .NET Core, need to replace?
//            Debug.Listeners.Clear();
//            Debug.Listeners.Add(traceListener);

            IDbProvider dbProvider = new MemDbProvider(_logManager);
            StateTree   stateTree  = new StateTree(dbProvider.GetOrCreateStateDb());


            ISpecProvider specProvider;

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

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

            IDifficultyCalculator difficultyCalculator = new DifficultyCalculator(specProvider);
            IRewardCalculator     rewardCalculator     = new RewardCalculator(specProvider);

            IBlockTree            blockTree            = new BlockTree(new MemDb(), new MemDb(), new MemDb(), specProvider, _logManager);
            IBlockhashProvider    blockhashProvider    = new BlockhashProvider(blockTree);
            ISignatureValidator   signatureValidator   = new SignatureValidator(ChainId.MainNet);
            ITransactionValidator transactionValidator = new TransactionValidator(signatureValidator);
            IHeaderValidator      headerValidator      = new HeaderValidator(difficultyCalculator, blockTree, SealEngine, specProvider, _logManager);
            IOmmersValidator      ommersValidator      = new OmmersValidator(blockTree, headerValidator, _logManager);
            IBlockValidator       blockValidator       = new BlockValidator(transactionValidator, headerValidator, ommersValidator, specProvider, _logManager);
            IStateProvider        stateProvider        = new StateProvider(stateTree, dbProvider.GetOrCreateCodeDb(), _logManager);
            IStorageProvider      storageProvider      = new StorageProvider(dbProvider, stateProvider, _logManager);
            IVirtualMachine       virtualMachine       = new VirtualMachine(
                stateProvider,
                storageProvider,
                blockhashProvider,
                _logManager);

            ISealEngine       sealEngine       = new EthashSealEngine(new Ethash(_logManager), _logManager);
            ITransactionStore transactionStore = new TransactionStore();
            IEthereumSigner   signer           = new EthereumSigner(specProvider, _logManager);
            IBlockProcessor   blockProcessor   = new BlockProcessor(
                specProvider,
                blockValidator,
                rewardCalculator,
                new TransactionProcessor(
                    specProvider,
                    stateProvider,
                    storageProvider,
                    virtualMachine,
                    NullTracer.Instance,
                    _logManager),
                dbProvider,
                stateProvider,
                storageProvider,
                transactionStore,
                _logManager);

            IBlockchainProcessor blockchainProcessor = new BlockchainProcessor(blockTree,
                                                                               sealEngine,
                                                                               transactionStore, difficultyCalculator, blockProcessor, signer, _logManager);

            InitializeTestState(test, stateProvider, storageProvider, specProvider);

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

            for (int i = 0; i < test.Blocks.Length; i++)
            {
                try
                {
                    TestBlockJson testBlockJson  = test.Blocks[i];
                    var           rlpContext     = Hex.ToBytes(testBlockJson.Rlp).AsRlpContext();
                    Block         suggestedBlock = Rlp.Decode <Block>(rlpContext);
                    Assert.AreEqual(new Keccak(testBlockJson.BlockHeader.Hash), suggestedBlock.Header.Hash, "hash of the block");
                    for (int ommerIndex = 0; ommerIndex < suggestedBlock.Ommers.Length; ommerIndex++)
                    {
                        Assert.AreEqual(new Keccak(testBlockJson.UncleHeaders[ommerIndex].Hash), suggestedBlock.Ommers[ommerIndex].Hash, "hash of the ommer");
                    }

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

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

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

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

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

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

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

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

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

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

            await blockchainProcessor.StopAsync(true);

            stopwatch?.Stop();

            RunAssertions(test, blockTree.RetrieveHeadBlock(), storageProvider, stateProvider);
        }
Beispiel #20
0
        private async Task InitBlockchain()
        {
            ChainSpec chainSpec = LoadChainSpec(_initConfig.ChainSpecPath);

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

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

            var ethereumSigner = new EthereumSigner(
                specProvider,
                _logManager);

            var transactionStore = new TransactionStore();

            var sealEngine = ConfigureSealEngine(
                transactionStore,
                ethereumSigner);

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

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

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

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

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

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

            var difficultyCalculator = new DifficultyCalculator(
                specProvider);

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

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

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

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

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

            var stateDb = dbProvider.GetOrCreateStateDb();

            var stateTree = new StateTree(stateDb);

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

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

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

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

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

            var rewardCalculator = new RewardCalculator(
                specProvider);

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

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

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

            var jsonSerializer = new JsonSerializer(
                _logManager);

            var encrypter = new AesEncrypter(
                _configProvider,
                _logManager);

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

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

            EthereumSigner = ethereumSigner;

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

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

            await InitializeNetwork(
                transactionStore,
                blockValidator,
                headerValidator,
                txValidator);
        }
Beispiel #21
0
 private static void GenerateLBod(JsonWriter writer, RewardCalculator calc, SmallBulkEntry[] bods)
 {
     throw new NotImplementedException();
 }
Beispiel #22
0
        private static void InitBlockchain(ChainSpec chainSpec, bool isMining, int miningDelay)
        {
            /* spec */
            var blockMiningTime      = TimeSpan.FromMilliseconds(miningDelay);
            var transactionDelay     = TimeSpan.FromMilliseconds(miningDelay / 4);
            var specProvider         = RopstenSpecProvider.Instance;
            var difficultyCalculator = new DifficultyCalculator(specProvider);
            // var sealEngine = new EthashSealEngine(new Ethash());
            var sealEngine = new FakeSealEngine(blockMiningTime, false);

            /* sync */
            var transactionStore = new TransactionStore();
            var blockTree        = new BlockTree(RopstenSpecProvider.Instance, ChainLogger);

            /* validation */
            var headerValidator = new HeaderValidator(difficultyCalculator, blockTree, sealEngine, specProvider, ChainLogger);
            var ommersValidator = new OmmersValidator(blockTree, headerValidator, ChainLogger);
            var txValidator     = new TransactionValidator(new SignatureValidator(ChainId.Ropsten));
            var blockValidator  = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, ChainLogger);

            /* state */
            var dbProvider        = new DbProvider(StateLogger);
            var codeDb            = new InMemoryDb();
            var stateDb           = new InMemoryDb();
            var stateTree         = new StateTree(stateDb);
            var stateProvider     = new StateProvider(stateTree, StateLogger, codeDb);
            var storageProvider   = new StorageProvider(dbProvider, stateProvider, StateLogger);
            var storageDbProvider = new DbProvider(StateLogger);

            /* blockchain */
            var ethereumSigner = new EthereumSigner(specProvider, ChainLogger);

            /* blockchain processing */
            var blockhashProvider    = new BlockhashProvider(blockTree);
            var virtualMachine       = new VirtualMachine(specProvider, stateProvider, storageProvider, blockhashProvider, EvmLogger);
            var transactionProcessor = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, ethereumSigner, ChainLogger);
            var rewardCalculator     = new RewardCalculator(specProvider);
            var blockProcessor       = new BlockProcessor(specProvider, blockValidator, rewardCalculator, transactionProcessor, storageDbProvider, stateProvider, storageProvider, transactionStore, ChainLogger);

            _blockchainProcessor = new BlockchainProcessor(blockTree, sealEngine, transactionStore, difficultyCalculator, blockProcessor, ChainLogger);

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

            stateProvider.Commit(specProvider.GenesisSpec);

            var testTransactionsGenerator = new TestTransactionsGenerator(transactionStore, ethereumSigner, transactionDelay, ChainLogger);

            stateProvider.CreateAccount(testTransactionsGenerator.SenderAddress, 1000.Ether());
            stateProvider.Commit(specProvider.GenesisSpec);

            if (isMining)
            {
                testTransactionsGenerator.Start();
            }

            Block genesis = chainSpec.Genesis;

            genesis.Header.StateRoot = stateProvider.StateRoot;
            genesis.Header.RecomputeHash();
            // we are adding test transactions account so the state root will change (not an actual ropsten at the moment)
//            var expectedGenesisHash = "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d";
//            if (chainSpec.Genesis.Hash != new Keccak(expectedGenesisHash))
//            {
//                throw new Exception($"Unexpected genesis hash for Ropsten, expected {expectedGenesisHash}, but was {chainSpec.Genesis.Hash}");
//            }

            /* start test processing */
            sealEngine.IsMining = isMining;
            _blockchainProcessor.Start();
            blockTree.AddBlock(genesis);

            _syncManager = new SynchronizationManager(
                blockTree,
                blockValidator,
                headerValidator,
                transactionStore,
                txValidator,
                NetworkLogger);
            _syncManager.Start();
        }
Beispiel #23
0
        public async Task Build_some_chain()
        {
            /* logging & instrumentation */
            var logger = new OneLoggerLogManager(new SimpleConsoleLogger());

            /* spec */
            var blockMiningTime = TimeSpan.FromMilliseconds(500);
            var sealEngine      = new FakeSealEngine(blockMiningTime);
            var specProvider    = RopstenSpecProvider.Instance;

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

            /* state & storage */
            var dbProvider      = new MemDbProvider(logger);
            var stateTree       = new StateTree(dbProvider.GetOrCreateStateDb());
            var stateProvider   = new StateProvider(stateTree, dbProvider.GetOrCreateCodeDb(), logger);
            var storageProvider = new StorageProvider(dbProvider, stateProvider, logger);

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

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

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

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

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

            /* start processing */
            sealEngine.IsMining = true;
            var testTransactionsGenerator = new TestTransactionsGenerator(transactionStore, ethereumSigner, blockMiningTime, logger);

            testTransactionsGenerator.Start();

            blockchainProcessor.Start();
            blockTree.SuggestBlock(chainSpec.Genesis);

            BigInteger roughlyNumberOfBlocks = 6;

            Thread.Sleep(blockMiningTime * (int)roughlyNumberOfBlocks);
            await blockchainProcessor.StopAsync(false);

            Assert.GreaterOrEqual(blockTree.Head.Number, roughlyNumberOfBlocks - 2, "number of blocks");
            Assert.GreaterOrEqual(blockTree.Head.TotalTransactions, roughlyNumberOfBlocks - 2, "number of transactions");
        }
Beispiel #24
0
        /// <summary>
        /// Mains the specified arguments.
        /// </summary>
        /// <param name="args">The arguments.</param>
        public static void Main(string[] args)
        {
            var options = new Options();
            var parsed  = CommandLine.Parser.Default.ParseArguments(args, options);

            if (parsed && !string.IsNullOrEmpty(options.InputFile))
            {
                var companyName       = "";
                var status            = "";
                var episodeLength     = 5;
                var redis             = ConnectionMultiplexer.Connect("localhost:6379");
                var manager           = new RedisManager(redis);
                var initialCapital    = 100000;
                var dayNumber         = 0;
                int totalTrainingDays = 0;

                var agentParameters = new DeepRLAgentParameters();
                agentParameters.DiscountFactor     = options.DiscountFactor > 0 ? options.DiscountFactor : agentParameters.DiscountFactor;
                agentParameters.eGreedyProbability = options.eGreedyProbability > 0 ? options.eGreedyProbability : agentParameters.eGreedyProbability;
                agentParameters.MiniBatchSize      = options.MiniBatchSize > 0 ? options.MiniBatchSize : agentParameters.MiniBatchSize;
                agentParameters.MemoryReplaySize   = options.MemoryReplaySize > 0 ? options.MemoryReplaySize : agentParameters.MemoryReplaySize;
                agentParameters.QNetwork.MaxIterationPerTrainging = options.MaxIterationPerTrainging > 0 ? options.MaxIterationPerTrainging : agentParameters.QNetwork.MaxIterationPerTrainging;
                agentParameters.QNetwork.TrainingError            = options.TrainingError > 0 ? options.TrainingError : agentParameters.QNetwork.TrainingError;

                var agent = new DeepRLAgent(agentParameters);;

                var stockParameters = new StockExchangeParameters();
                stockParameters.EpisodeLength      = episodeLength;
                stockParameters.InitialCapital     = initialCapital;
                stockParameters.SimulationVelocity = options.Velocity > 0 ? (int)(options.Velocity * 1000.0) : stockParameters.SimulationVelocity;
                stockParameters.TransactionCost    = options.TransactionCost > 0 ? options.TransactionCost : stockParameters.TransactionCost;
                stockParameters.RewardCalculator   = RewardCalculator.Use(RewardCalculatorType.WinningsOverLoosings);

                var stock = new StockExchange(stockParameters, manager, agent, null);

                manager.Subscribe(RedisPubSubChannels.OnDayComplete, (channel, msg) =>
                {
                    var a        = JsonConvert.DeserializeObject <OnDayComplete>(msg);
                    dayNumber    = a.DayNumber - totalTrainingDays;
                    initialValue = initialValue == 0.0 ? a.Period.Open : initialValue;
                    DrawSummarySection(companyName, status, dayNumber, initialCapital, a);
                });


                agent.OnTrainingEpochComplete += DrawStatusBar;

                var continueSimulated = false;
                companyName = options.InputFile;

                do
                {
                    stock.DataProvider = new CsvDataProvider(companyName, episodeLength);
                    DateTime endTraining = DateTime.Today;

                    if (options.TrainingPhase > 0)
                    {
                        var firstDay = stock.DataProvider.GetAll().ToList().Select(s => s.Date).Min();
                        endTraining = firstDay.AddYears(options.TrainingPhase);

                        stock.DataProvider.Seek(endDate: endTraining);
                        status = "Etapa: Entrenamiento";
                    }


                    System.Console.Clear();
                    System.Console.SetCursorPosition(0, 0);
                    DrawHeaderSection();

                    var stockTask = Task.Run(() => stock.Run(new JobCancellationToken(false)));
                    stockTask.Wait();

                    if (options.TrainingPhase > 0)
                    {
                        status = "Etapa: Entrenamiento Completado";
                        WriteLine(StatusBarLine + 5, "Etapa de entrenamiento Completada, Presione una tecla para continuar con la etapa de evaluacion... ");
                        System.Console.ReadLine();
                        ClearCurrentLine();
                        totalTrainingDays  = dayNumber;
                        stock.TotalOfYears = 0;

                        status = "Etapa: Evaluacion";

                        stock.CurrentState = null;
                        stock.DataProvider.Seek(startDate: endTraining);
                        //agent.Save(context);


                        agentParameters.DiscountFactor     = options.DiscountFactor > 0 ? options.DiscountFactor : agentParameters.DiscountFactor;
                        agentParameters.eGreedyProbability = options.eGreedyProbability > 0 ? options.eGreedyProbability : agentParameters.eGreedyProbability;
                        agentParameters.MiniBatchSize      = options.MiniBatchSize > 0 ? options.MiniBatchSize : agentParameters.MiniBatchSize;
                        agentParameters.MemoryReplaySize   = options.MemoryReplaySize > 0 ? options.MemoryReplaySize : agentParameters.MemoryReplaySize;

                        agent       = new DeepRLAgent(agentParameters);
                        stock.Agent = agent;

                        stockTask = Task.Run(() => stock.Run(new JobCancellationToken(false)));
                        stockTask.Wait();
                    }

                    WriteLine(StatusBarLine + 5, "Simulacion Finalizada, Presione una tecla para finalizar o ingrese otro papel : ");
                    var previousCompany = companyName;
                    companyName       = System.Console.ReadLine();
                    continueSimulated = !string.IsNullOrEmpty(companyName) && companyName != previousCompany;

                    stock.CurrentState = null;
                } while (continueSimulated);
            }
        }
Beispiel #25
0
        public async Task Test()
        {
            TimeSpan miningDelay = TimeSpan.FromMilliseconds(50);

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

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

            sealEngine.IsMining = true;

            var specProvider = RopstenSpecProvider.Instance;

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

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

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

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

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

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

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

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

            ManualResetEvent manualResetEvent = new ManualResetEvent(false);

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

            manualResetEvent.WaitOne(miningDelay * 12);

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

                Assert.GreaterOrEqual((int)blockTree.Head.Number, 6);
            });
        }