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);
        }