Exemple #1
0
        /// <summary>
        /// </summary>
        /// <param name="block"></param>
        /// <returns></returns>
        public async Task <VerifyResult> VerifyBlock(Block block)
        {
            Guard.Argument(block, nameof(block)).NotNull();

            var verifySloth = VerifySloth(block.BlockPos.Bits, block.BlockPos.VrfSig,
                                          block.BlockPos.Nonce.ToStr().ToBytes());

            if (verifySloth == VerifyResult.UnableToVerify)
            {
                _logger.Here().Fatal("Unable to verify the delay function");
                return(verifySloth);
            }

            var runningDistribution = await CurrentRunningDistribution(block.BlockPos.Solution);

            var verifyCoinbase = VerifyCoinbaseTransaction(block.Txs.First().Vout.First(),
                                                           block.BlockPos.Solution, runningDistribution);

            if (verifyCoinbase == VerifyResult.UnableToVerify)
            {
                _logger.Here().Fatal("Unable to verify the coinbase transaction");
                return(verifyCoinbase);
            }

            byte[] hash;
            using (var ts = new TangramStream())
            {
                block.Txs.Skip(1).ForEach(x =>
                {
                    if (block.Height == 0ul)
                    {
                        ts.Append(x.ToStream());
                    }
                    else
                    {
                        var hasAny = x.Validate();
                        if (hasAny.Any())
                        {
                            throw new ArithmeticException("Unable to verify the transaction");
                        }
                        ts.Append(x.ToStream());
                    }
                });
                hash = Hasher.Hash(ts.ToArray()).HexToByte();
            }

            var verifyVrfProof = VerifyVrfProof(block.BlockPos.PublicKey, block.BlockPos.VrfProof, hash, block.BlockPos.VrfSig);

            if (verifyVrfProof == VerifyResult.UnableToVerify)
            {
                _logger.Here().Fatal("Unable to verify the Vrf Proof");
                return(verifyVrfProof);
            }

            var verifySolution = VerifySolution(block.BlockPos.VrfSig, hash,
                                                block.BlockPos.Solution);

            if (verifySolution == VerifyResult.UnableToVerify)
            {
                _logger.Here().Fatal("Unable to verify the solution");
                return(verifySolution);
            }

            var bits = Difficulty(block.BlockPos.Solution,
                                  block.Txs.First().Vout.First().A.DivWithNanoTan());

            if (block.BlockPos.Bits != bits)
            {
                _logger.Here().Fatal("Unable to verify the bits");
                return(VerifyResult.UnableToVerify);
            }

            var verifyLockTime = VerifyLockTime(new LockTime(Utils.UnixTimeToDateTime(block.BlockHeader.Locktime)),
                                                block.BlockHeader.LocktimeScript);

            if (verifyLockTime == VerifyResult.UnableToVerify)
            {
                _logger.Here().Fatal("Unable to verify the block lock time");
                return(verifyLockTime);
            }

            if (block.BlockHeader.MerkleRoot.Xor(BlockZeroHash) &&
                block.BlockHeader.PrevBlockHash.Xor(Hasher.Hash(BlockZeroPreHash).HexToByte()))
            {
                return(VerifyResult.Succeed);
            }

            var prevBlock = await _unitOfWork.HashChainRepository.GetAsync(x =>
                                                                           new ValueTask <bool>(x.Hash.Xor(block.BlockHeader.PrevBlockHash)));

            if (prevBlock == null)
            {
                _logger.Here().Fatal("Unable to find the previous block");
                return(VerifyResult.UnableToVerify);
            }

            var verifyPreviousHasher = await VerifyBlockHash(block);

            if (verifyPreviousHasher == VerifyResult.UnableToVerify)
            {
                _logger.Here().Fatal("Unable to verify the block hash");
                return(verifyPreviousHasher);
            }

            var verifyMerkel = await VerifyMerkel(block);

            if (verifyMerkel == VerifyResult.UnableToVerify)
            {
                _logger.Here().Fatal("Unable to verify the merkel tree");
                return(verifyMerkel);
            }

            var verifyTransactions = await VerifyTransactions(block.Txs);

            if (verifyTransactions == VerifyResult.Succeed)
            {
                return(VerifyResult.Succeed);
            }
            _logger.Here().Fatal("Unable to verify the block transactions");
            return(VerifyResult.UnableToVerify);
        }
Exemple #2
0
        /// <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);
        }