Пример #1
0
        private async Task <BlockHashed> GenerateBlock(BlockHashed previousBlock, int?threads = null)
        {
            var miner = _minerFactory.Create(_address, previousBlock, new TransactionSigned[] { }, _feedback);

            miner.Start(threads ?? Environment.ProcessorCount);
            return(await miner.GetBlock());
        }
Пример #2
0
        //Fire and forget
        private void BroadcastToPeer(BlockHashed block, PeerConnection peer)
        {
            Debug.WriteLine($"Enqueue block {block.Signed.Data.Index}");
            var queuedTask = peer.Client.BroadcastAsync(new BlockBundle(block, _peerUrl));

            Debug.WriteLine($"Block {block.Signed.Data.Index} enqueued");
            FireBroadCast(peer, queuedTask);
        }
Пример #3
0
        public Task BroadcastAsync(BlockHashed block)
        {
            foreach (var peer in _peers.Values)
            {
                BroadcastToPeer(block, peer);
            }

            return(Task.CompletedTask);
        }
Пример #4
0
        public static HashBits CalculateTargetHash(BlockHashed lastBlock, BlockData blockToProcess)
        {
            var targetHashBits =
                lastBlock.Signed.HashTargetBits.Adjust(
                    blockToProcess.TimeStamp - lastBlock.Signed.Data.TimeStamp,
                    BlockData.BlockTime);

            return(targetHashBits);
        }
Пример #5
0
 private void AddNewBlock(BlockHashed newBlock)
 {
     _feedback.Execute("AddNewBlock",
                       () =>
     {
         //TODO: Any chance the block to need sync here? Rely on AcceptBlockAsync for now
         _chainData.AddNewBlock(newBlock);
     },
                       () => $"{nameof(newBlock)}: {newBlock.SerializeToJson()}");
 }
Пример #6
0
        private BlockData GetNewBlock(Address inFavor, BlockHashed lastBlock, IEnumerable <TransactionSigned> transactionsToProcess)
        {
            var transactions   = GetNewBlockTransactions(inFavor, lastBlock, transactionsToProcess);
            var blockToProcess = new BlockData(
                lastBlock.Signed.Data.Index + 1,
                DateTime.UtcNow.Ticks,
                "^v^",
                transactions.ToArray(),
                lastBlock.HashTarget.Hash);

            return(blockToProcess);
        }
Пример #7
0
        public Miner Create(
            Address inFavor,
            BlockHashed lastBlock,
            IEnumerable <TransactionSigned> transactionsToProcess,
            IFeedback feedback)
        {
            var blockToProcess = GetNewBlock(inFavor, lastBlock, transactionsToProcess);

            var targetHashBits = Rules.CalculateTargetHash(lastBlock, blockToProcess);
            var signedBlock    = _cryptography.SignBlock(blockToProcess, inFavor, targetHashBits);

            return(Create(signedBlock, feedback));
        }
Пример #8
0
        public bool ValidateGenesisBlock(BlockHashed newBlock, out BlockchainState blockchainState)
        {
            var expectedSignedGenesis = Genesis.GetBlockData(_cryptography, newBlock.Signed.Data.TimeStamp);
            var result = ValidateParent(0, Genesis.Hash, newBlock.Signed.Data,
                                        out blockchainState);

            if (result)
            {
                ValidateSignature(expectedSignedGenesis.Stamp, newBlock.Signed);
                ValidateBlockHash(expectedSignedGenesis, newBlock.HashTarget);
            }

            return(result);
        }
Пример #9
0
        public bool ValidateNewBlock(BlockHashed lastBlock, BlockHashed newBlock, out BlockchainState blockchainState)
        {
            var result = ValidateParent(lastBlock.Signed.Data.Index + 1, lastBlock.HashTarget.Hash, newBlock.Signed.Data,
                                        out blockchainState);

            if (result)
            {
                ValidateHashTarget(lastBlock, newBlock);
                ValidateSignature(newBlock.Signed.Stamp, newBlock.Signed);
                ValidateBlockHash(newBlock);
                ValidateTransactions(newBlock.Signed.Data.Transactions);
            }

            return(result);
        }
Пример #10
0
        public void ValidateHashTarget(BlockHashed lastBlock, BlockHashed newBlock)
        {
            var targetHashBits = Rules.CalculateTargetHash(lastBlock, newBlock.Signed.Data);

            if (newBlock.Signed.HashTargetBits.Value != targetHashBits.Value)
            {
                throw new BlockchainValidationException("Block target hash bits are not valid");
            }
            var targetHash = newBlock.Signed.HashTargetBits.ToHash();

            if (newBlock.HashTarget.Hash.Compare(targetHash) >= 0)
            {
                throw new BlockchainValidationException("Block hash is not below a necessary target");
            }
        }
Пример #11
0
        public static async Task Encrypt(Stream stream, long length)
        {
            int step = (int)Math.Ceiling(length / 100d);

            int readBytes;
            var readTime   = new Stopwatch();
            var SHA256Time = new Stopwatch();
            var KHATime    = new Stopwatch();

            do
            {
                byte[] blockBytes = new byte[step];

                readTime.Start();
                readBytes = await stream.ReadAsync(blockBytes, 0, step);

                readTime.Stop();

                if (readBytes != step)
                {
                    blockBytes = blockBytes.Take(readBytes).ToArray();
                }

                SHA256Time.Start();
                string kha = await GetKHA(blockBytes);

                SHA256Time.Stop();

                KHATime.Start();
                string sha256 = await GetSHA512(blockBytes);

                KHATime.Stop();

                BlockHashed?.Invoke(
                    kha,
                    sha256);
            } while (readBytes > 0);

            var lengthKb = length / 1000.0;

            AllFileHashed?.Invoke(
                lengthKb / readTime.ElapsedMilliseconds,
                lengthKb / KHATime.ElapsedMilliseconds,
                lengthKb / SHA256Time.ElapsedMilliseconds
                );
        }
Пример #12
0
        private bool ValidateBlock(BlockHashed newBlock, BlockHashed lastBlock, out BlockchainState blockchainState)
        {
            bool result;

            if (lastBlock == null)
            {
                result = ValidateGenesisBlock(newBlock, out blockchainState);
            }
            else
            {
                result = ValidateNewBlock(lastBlock, newBlock, out blockchainState);
                if (result)
                {
                    RemovePendingTransactions(newBlock.Signed.Data.Transactions);
                }
            }

            return(result);
        }
Пример #13
0
        public BlockchainState AddNewBlock(BlockHashed newBlock)
        {
            var lastBlock = GetLastBlock();
            var blockTime = newBlock.Signed.Data.TimeStamp - lastBlock?.Signed.Data.TimeStamp ?? 0;

            try
            {
                if (ValidateBlock(newBlock, lastBlock, out var blockchainState))
                {
                    Chain.Add(newBlock);
                    _feedback.NewBlockAccepted(newBlock.Signed.Data.Index, blockTime, newBlock.HashTarget.Hash);
                }

                return(blockchainState);
            }
            catch (BlockchainValidationException e)
            {
                _feedback.NewBlockRejected(newBlock.Signed.Data.Index, blockTime, newBlock.HashTarget.Hash, e.Message);
            }

            return(BlockchainState.ValidationError);
        }
Пример #14
0
        public async Task <Miner> MineAsync(Address mineAddress, int?numberOfThreads, BlockHashed lastBlock, IEnumerable <TransactionSigned> transactions)
        {
            var miner          = MinerFactory.Create(mineAddress, lastBlock, transactions, _feedback);
            var threadsClosure = numberOfThreads;

            await _feedback.Execute("Mine",
                                    () => MineAsync(miner, threadsClosure),
                                    () => $"{nameof(mineAddress)}: {mineAddress}, {nameof(numberOfThreads)}: {threadsClosure}");

            return(miner);
        }
Пример #15
0
        //TODO: Allow multiple recipients
        private IEnumerable <TransactionSigned> GenerateCoinbaseTransaction(Address inFavor, BlockHashed lastBlock)
        {
            var mineReward = new[]
            {
                _cryptography.Sign(
                    new Transaction(
                        Genesis.God,
                        new[] { new Recipient(inFavor, Rules.CalulateBlockReward(lastBlock)) },
                        0),
                    inFavor),
            };

            return(mineReward);
        }
Пример #16
0
        private IEnumerable <TransactionSigned> GetNewBlockTransactions(Address inFavor, BlockHashed lastBlock, IEnumerable <TransactionSigned> transactionsToProcess)
        {
            var mineReward   = GenerateCoinbaseTransaction(inFavor, lastBlock);
            var transactions = mineReward.Union(transactionsToProcess);

            return(transactions);
        }
Пример #17
0
 public void ValidateBlockHash(BlockHashed newBlock)
 {
     ValidateBlockHash(newBlock.Signed, newBlock.HashTarget);
 }
Пример #18
0
 public static BlockIdentity Identity(this BlockHashed block)
 {
     return(block == null ? null : new BlockIdentity(block.Signed.Data.Index, block.HashTarget.Hash));
 }
Пример #19
0
 public BlockBundle(BlockHashed block, string sender)
 {
     Block  = block;
     Sender = sender;
 }
Пример #20
0
        public static long CalulateBlockReward(BlockHashed lastBlock)
        {
            var rewardReduction = lastBlock.Signed.Data.Index / Transaction.BlockCountRewardReduction;

            return(Genesis.Reward >> rewardReduction);
        }