public void ProcessNextBlock(MiningJobRequestModel miningJobRM)
        {
            bool isFound = this.blockCandidates.TryGetValue(miningJobRM.MinerAddress, out BlockCandidate foundBlockCandidate);

            if (!isFound)
            {
                throw new Exception("No miner job associated with this miner address.");
            }

            if (foundBlockCandidate.BlockDataHash != miningJobRM.BlockDataHash)
            {
                throw new Exception("Mining job block data hash is different than the hash of the prepared block candidate.");
            }

            if (this.blocks.Any() && foundBlockCandidate.Index <= this.blocks.Last().Index)
            {
                this.SyncNode(foundBlockCandidate.Index);
                throw new Exception($"Sorry but a block with index {foundBlockCandidate.Index} was already mined.");
            }

            if (!this.IsFoundBlockHashValid(miningJobRM))
            {
                throw new Exception("Found block hash is invalid");
            }
            //TODO: During synchronization with other nodes, a check for valid hash for incoming blocks must be done as well.

            Block newBlock = this.CreateNewBlock(miningJobRM, foundBlockCandidate);

            this.blocks.Add(newBlock);
            this.transactionService.ClearAllAddedToBlockPendingTransactions(newBlock.ConfirmedTransactions);
            this.blockCandidates.Clear();
        }
        private bool IsFoundBlockHashValid(MiningJobRequestModel miningJobRM)
        {
            // Can be added to utils if needed elsewhere
            string timestampIso8601 = miningJobRM.Timestamp.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
            string combinedInput    = $"{miningJobRM.BlockDataHash}{timestampIso8601}{miningJobRM.Nonce}";
            string calculatedHash   = Crypto.CalculateSHA256ToString(combinedInput);

            return(miningJobRM.MinedBlockHash == calculatedHash);
        }
Esempio n. 3
0
 public IActionResult SubmitMinedJob([FromBody] MiningJobRequestModel miningJobRM)
 {
     try
     {
         this.blockService.ProcessNextBlock(miningJobRM);
         return(Ok("New block sucessfully added to the chain."));
     }
     catch (Exception ex)
     {
         return(BadRequest($"Error: {ex}"));
     }
 }
        private Block CreateNewBlock(MiningJobRequestModel miningJobRM, BlockCandidate blockCandidate)
        {
            Block newBlock = new Block()
            {
                Index = blockCandidate.Index,
                ConfirmedTransactions = blockCandidate.ConfirmedTransactions,
                Difficulty            = blockCandidate.Difficulty,
                PreviousBlockHash     = blockCandidate.PreviousBlockHash,
                MinedBy       = blockCandidate.MinedBy,
                BlockDataHash = blockCandidate.BlockDataHash,
                Nonce         = miningJobRM.Nonce,
                DateCreated   = miningJobRM.Timestamp,
                BlockHash     = miningJobRM.MinedBlockHash
            };

            return(newBlock);
        }