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"
                        });
                    }
                }
            }
        }
예제 #6
0
 public bool TryAddBlock(MinedBlockInfo block)
 {
     return(allBlocks.TryAdd(block.Index, block));
 }