public MinedBlockInfoResponse GetBlock(string blockHash) { MinedBlockInfo block = dbService.GetAllBlocks().Where(b => b.BlockHash.Equals(blockHash) || b.BlockDataHash.Equals(blockHash)).FirstOrDefault(); if (block != null) { return(MinedBlockInfoResponse.FromMinedBlockInfo(block)); } return(null); }
private bool IsPeersBlockValid(MinedBlockInfo block) { var mbi = new MinedBlockInfo(MiningBlockInfo.FromMinedBlockInfo(block)) { Nonce = block.Nonce, DateCreated = block.DateCreated, }; var isGenesisBlock = block.Index == 0; var hashCoversDifficulty = mbi.BlockHash.StartsWith("".PadLeft(appSettings.Difficulty, '0')); var hashesMatch = mbi.BlockHash == block.BlockHash; return(hashesMatch && (hashCoversDifficulty || isGenesisBlock)); }
private void AddToCurrentChain(MinedBlockInfo block) { lock (dbService.GetBlocksLockObject()) { lock (dbService.GetTransactionsLockObject()) { if (dbService.TryAddBlock(block)) { //remove pending transactions that are already verified in the other chain block.Transactions.ForEach(t => dbService.RemoveTransaction(t)); } } } }
private void PropagateBlockToPeers(MinedBlockInfo block) { var tasks = new List <Task>(); var body = new NewBlockNotification { LastBlock = MinedBlockInfoResponse.FromMinedBlockInfo(block), Sender = thisPeer }; dbService.GetPeers().ForEach(p => { tasks.Add(Task.Run(() => HttpUtils.DoApiPost <NewBlockNotification, object>(p.Url, NOTIFY_API_PATH, body))); }); Task.WaitAll(tasks.ToArray()); }
public SubmitBlockResponse SubmitBlockInfo(MinedBlockInfoRequest data) { lock (dbService.GetBlocksLockObject()) { lock (dbService.GetTransactionsLockObject()) { var info = dbService.GetMiningInfo(data.BlockDataHash); if (null == info) { return(new SubmitBlockResponse { Status = BlockResponseStatus.Error, Message = "Wrong block hash!" }); } var mbi = new MinedBlockInfo(info) { Nonce = data.Nonce, DateCreated = data.DateCreated, }; if (mbi.BlockHash.StartsWith("".PadLeft(appSettings.Difficulty, '0'))) { var success = dbService.TryAddBlock(mbi); if (!success) { return(new SubmitBlockResponse { Status = BlockResponseStatus.Error, Message = "Old block! Someone mined it already" }); } //UPDATE transactions in the block. mbi.Transactions.ForEach(t => { t.MinedInBlockIndex = info.Index; t.TransferSuccessful = true; dbService.RemoveTransaction(t); }); PropagateBlockToPeers(mbi); return(new SubmitBlockResponse { Status = BlockResponseStatus.Success, Message = $"Block is valid" }); } else { return(new SubmitBlockResponse { Status = BlockResponseStatus.Error, Message = $"Hash must start with {appSettings.Difficulty} zeroes" }); } } } }
public bool TryAddBlock(MinedBlockInfo block) { return(allBlocks.TryAdd(block.Index, block)); }