Esempio n. 1
0
        private ISealEngine ConfigureSealEngine()
        {
//            var sealEngine = NullSealEngine.Instance;
            var difficultyCalculator = new DifficultyCalculator(_specProvider);
            var sealEngine           = new EthashSealEngine(new Ethash(_logManager), difficultyCalculator, _logManager);

//            var blockMiningTime = TimeSpan.FromMilliseconds(_initConfig.FakeMiningDelay);
//            var sealEngine = new FakeSealEngine(blockMiningTime, false);
//            sealEngine.IsMining = _initConfig.IsMining;
//            if (sealEngine.IsMining)
//            {
//                var transactionDelay = TimeSpan.FromMilliseconds(_initConfig.FakeMiningDelay / 4);
//                TestTransactionsGenerator testTransactionsGenerator =
//                    new TestTransactionsGenerator(transactionStore, ethereumSigner, transactionDelay, _logManager);
//                // stateProvider.CreateAccount(testTransactionsGenerator.SenderAddress, 1000.Ether());
            return(sealEngine);
        }
        public async Task Can_cancel()
        {
            ulong badNonce = 971086423715459953; // change if valid

            BlockHeader header = new BlockHeader(Keccak.Zero, Keccak.OfAnEmptySequenceRlp, Address.Zero, (UInt256)BigInteger.Pow(2, 32), 1, 21000, 1, new byte[] { 1, 2, 3 });

            header.TransactionsRoot = Keccak.Zero;
            header.ReceiptsRoot     = Keccak.Zero;
            header.OmmersHash       = Keccak.Zero;
            header.StateRoot        = Keccak.Zero;
            header.Bloom            = Bloom.Empty;

            Block            block            = new Block(header);
            EthashSealEngine ethashSealEngine = new EthashSealEngine(new Ethash(LimboLogs.Instance), Substitute.For <IDifficultyCalculator>(), LimboLogs.Instance);
            await ethashSealEngine.MineAsync(new CancellationTokenSource(TimeSpan.FromMilliseconds(2000)).Token, block, badNonce).ContinueWith(t =>
            {
                Assert.True(t.IsCanceled);
            });
        }
        public async Task Can_mine()
        {
            ulong validNonce = 971086423715459953;

            BlockHeader header = new BlockHeader(Keccak.Zero, Keccak.OfAnEmptySequenceRlp, Address.Zero, 1000, 1, 21000, 1, new byte[] { 1, 2, 3 });

            header.TransactionsRoot = Keccak.Zero;
            header.ReceiptsRoot     = Keccak.Zero;
            header.OmmersHash       = Keccak.Zero;
            header.StateRoot        = Keccak.Zero;
            header.Bloom            = Bloom.Empty;

            Block            block            = new Block(header);
            EthashSealEngine ethashSealEngine = new EthashSealEngine(new Ethash(LimboLogs.Instance), Substitute.For <IDifficultyCalculator>(), LimboLogs.Instance);
            await ethashSealEngine.MineAsync(new CancellationTokenSource(TimeSpan.FromSeconds(20)).Token, block, validNonce - 10);

            Assert.AreEqual(validNonce, block.Header.Nonce);
            Assert.AreEqual(new Keccak("0xff2c80283f139148a9b3f2a9dd19d698475937a85296225a96857599cce6d1e2"), block.Header.MixHash);

            Console.WriteLine(block.Header.Nonce);
        }
        public async Task Find_nonce()
        {
            BlockHeader parentHeader = new BlockHeader(Keccak.Zero, Keccak.OfAnEmptySequenceRlp, Address.Zero, 131072, 0, 21000, 0, new byte[] { });

            parentHeader.Hash = BlockHeader.CalculateHash(parentHeader);

            BlockHeader blockHeader = new BlockHeader(parentHeader.Hash, Keccak.OfAnEmptySequenceRlp, Address.Zero, 131136, 1, 21000, 1, new byte[] { });

            blockHeader.Nonce   = 7217048144105167954;
            blockHeader.MixHash = new Keccak("0x37d9fb46a55e9dbbffc428f3a1be6f191b3f8eaf52f2b6f53c4b9bae62937105");
            blockHeader.Hash    = BlockHeader.CalculateHash(blockHeader);
            Block block = new Block(blockHeader);

            IEthash          ethash           = new Ethash(LimboLogs.Instance);
            EthashSealEngine ethashSealEngine = new EthashSealEngine(ethash, Substitute.For <IDifficultyCalculator>(), LimboLogs.Instance);
            await ethashSealEngine.MineAsync(CancellationToken.None, block, 7217048144105167954);

            Assert.True(ethash.Validate(block.Header));

            Console.WriteLine(block.Header.Nonce);
            Console.WriteLine(block.Header.MixHash);
        }
Esempio n. 5
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);
        }