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()); }
//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); }
public Task BroadcastAsync(BlockHashed block) { foreach (var peer in _peers.Values) { BroadcastToPeer(block, peer); } return(Task.CompletedTask); }
public static HashBits CalculateTargetHash(BlockHashed lastBlock, BlockData blockToProcess) { var targetHashBits = lastBlock.Signed.HashTargetBits.Adjust( blockToProcess.TimeStamp - lastBlock.Signed.Data.TimeStamp, BlockData.BlockTime); return(targetHashBits); }
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()}"); }
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); }
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)); }
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); }
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); }
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"); } }
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 ); }
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); }
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); }
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); }
//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); }
private IEnumerable <TransactionSigned> GetNewBlockTransactions(Address inFavor, BlockHashed lastBlock, IEnumerable <TransactionSigned> transactionsToProcess) { var mineReward = GenerateCoinbaseTransaction(inFavor, lastBlock); var transactions = mineReward.Union(transactionsToProcess); return(transactions); }
public void ValidateBlockHash(BlockHashed newBlock) { ValidateBlockHash(newBlock.Signed, newBlock.HashTarget); }
public static BlockIdentity Identity(this BlockHashed block) { return(block == null ? null : new BlockIdentity(block.Signed.Data.Index, block.HashTarget.Hash)); }
public BlockBundle(BlockHashed block, string sender) { Block = block; Sender = sender; }
public static long CalulateBlockReward(BlockHashed lastBlock) { var rewardReduction = lastBlock.Signed.Data.Index / Transaction.BlockCountRewardReduction; return(Genesis.Reward >> rewardReduction); }