/// <summary> /// /// </summary> /// <param name="blockHeader"></param> /// <returns></returns> public async Task <VerifyResult> BlockExists(BlockHeaderProto blockHeader) { Guard.Argument(blockHeader, nameof(blockHeader)).NotNull(); var hasSeen = await _unitOfWork.HashChainRepository.GetAsync(blockHeader.ToIdentifier()); return(hasSeen != null ? VerifyResult.AlreadyExists : VerifyResult.Succeed); }
/// <summary> /// /// </summary> /// <param name="blockHeader"></param> /// <param name="prevBlockHeader"></param> /// <returns></returns> private BlockGraph CopyBlockGraph(BlockHeaderProto blockHeader, BlockHeaderProto prevBlockHeader) { var blockGraph = new BlockGraph { Block = new Block(blockHeader.MerkelRoot, _serfClient.ClientId, (ulong)blockHeader.Height, Helper.Util.SerializeFlatBuffer(blockHeader)), Prev = new Block { Data = Helper.Util.SerializeFlatBuffer(prevBlockHeader), Hash = prevBlockHeader.MerkelRoot, Node = _serfClient.ClientId, Round = (ulong)prevBlockHeader.Height } }; return(blockGraph); }
/// <summary> /// </summary> /// <param name="blockHeader"></param> /// <returns></returns> public async Task <VerifyResult> VerifyBlockHeader(BlockHeaderProto blockHeader) { Guard.Argument(blockHeader, nameof(blockHeader)).NotNull(); var verifySignature = _signing.VerifySignature(blockHeader.Signature.HexToByte(), blockHeader.PublicKey.HexToByte(), blockHeader.ToFinalStream()); if (verifySignature == false) { _logger.Here().Fatal("Unable to verify the block signature"); return(VerifyResult.UnableToVerify); } var verifySloth = VerifySloth(blockHeader.Bits, blockHeader.VrfSignature.HexToByte(), blockHeader.Nonce.ToBytes(), blockHeader.Sec.ToBytes()); if (verifySloth == VerifyResult.UnableToVerify) { _logger.Here().Fatal("Unable to verify the Verified Delay Function"); return(verifySloth); } var runningDistribution = await CurrentRunningDistribution(blockHeader.Solution); var verifyCoinbase = VerifyCoinbaseTransaction(blockHeader.Transactions.First().Vout.First(), blockHeader.Solution, runningDistribution); if (verifyCoinbase == VerifyResult.UnableToVerify) { _logger.Here().Fatal("Unable to verify the coinbase transaction"); return(verifyCoinbase); } uint256 hash; using (var ts = new TangramStream()) { blockHeader.Transactions.Skip(1).ForEach(x => ts.Append(x.Stream())); hash = Hashes.DoubleSHA256(ts.ToArray()); } var verifySolution = VerifySolution(blockHeader.VrfSignature.HexToByte(), hash.ToBytes(false), blockHeader.Solution); if (verifySolution == VerifyResult.UnableToVerify) { _logger.Here().Fatal("Unable to verify the solution"); return(verifySolution); } var bits = Difficulty(blockHeader.Solution, blockHeader.Transactions.First().Vout.First().A.DivWithNanoTan()); if (blockHeader.Bits != bits) { _logger.Here().Fatal("Unable to verify the bits"); return(VerifyResult.UnableToVerify); } Trie.Put(blockHeader.ToHash(), blockHeader.ToHash()); if (!blockHeader.MerkelRoot.Equals(Trie.GetRootHash().ByteToHex())) { _logger.Here().Fatal("Unable to verify the merkel"); var key = Trie.Get(blockHeader.ToHash()); if (key != null) { Trie.Delete(blockHeader.ToHash()); } return(VerifyResult.UnableToVerify); } var verifyLockTime = VerifyLockTime(new LockTime(Utils.UnixTimeToDateTime(blockHeader.Locktime)), blockHeader.LocktimeScript); if (verifyLockTime == VerifyResult.UnableToVerify) { _logger.Here().Fatal("Unable to verify the block lock time"); return(verifyLockTime); } if (blockHeader.MerkelRoot.HexToByte().Xor(BlockZeroMerkel.HexToByte()) && blockHeader.PrevMerkelRoot.HexToByte().Xor(BlockZeroPreMerkel.HexToByte())) { return(VerifyResult.Succeed); } if (blockHeader.Height == 0) { if (!blockHeader.MerkelRoot.HexToByte().Xor(BlockZeroMerkel.HexToByte()) && !blockHeader.PrevMerkelRoot.HexToByte().Xor(BlockZeroPreMerkel.HexToByte())) { return(VerifyResult.UnableToVerify); } } var prevBlock = await _unitOfWork.HashChainRepository.GetAsync(x => new ValueTask <bool>(x.MerkelRoot.Equals(blockHeader.PrevMerkelRoot))); if (prevBlock == null) { _logger.Here().Fatal("Unable to find the previous block"); return(VerifyResult.UnableToVerify); } var verifyTransactions = await VerifyTransactions(blockHeader.Transactions); if (verifyTransactions == VerifyResult.Succeed) { return(VerifyResult.Succeed); } _logger.Here().Fatal("Unable to verify the block transactions"); return(VerifyResult.UnableToVerify); }