Esempio n. 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="block"></param>
        /// <returns></returns>
        public async Task <VerifyResult> BlockExists(Block block)
        {
            Guard.Argument(block, nameof(block)).NotNull();
            var hasSeen = await _unitOfWork.HashChainRepository.GetAsync(block.ToIdentifier());

            return(hasSeen != null ? VerifyResult.AlreadyExists : VerifyResult.Succeed);
        }
Esempio n. 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="block"></param>
        /// <returns></returns>
        public async Task <VerifyResult> VerifyMerkel(Block block)
        {
            Guard.Argument(block, nameof(block)).NotNull();
            var height = await _unitOfWork.HashChainRepository.CountAsync() - 1;

            var prevBlock =
                await _unitOfWork.HashChainRepository.GetAsync(x => new ValueTask <bool>(x.Height == (ulong)height));

            if (prevBlock == null)
            {
                _logger.Here().Error("No previous block available");
                return(VerifyResult.UnableToVerify);
            }

            var merkelRoot   = BlockHeader.ToMerkelRoot(prevBlock.BlockHeader.MerkleRoot, block.Txs);
            var verifyMerkel = merkelRoot.Xor(block.BlockHeader.MerkleRoot);

            return(verifyMerkel ? VerifyResult.Succeed : VerifyResult.UnableToVerify);
        }
Esempio n. 3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="block"></param>
        /// <returns></returns>
        public async Task <VerifyResult> VerifyBlockHash(Block block)
        {
            Guard.Argument(block, nameof(block)).NotNull();
            using var hasher = Hasher.New();
            var height = await _unitOfWork.HashChainRepository.CountAsync() - 1;

            var prevBlock =
                await _unitOfWork.HashChainRepository.GetAsync(x => new ValueTask <bool>(x.Height == (ulong)height));

            if (prevBlock == null)
            {
                _logger.Here().Error("No previous block available");
                return(VerifyResult.UnableToVerify);
            }

            hasher.Update(prevBlock.Hash);
            hasher.Update(block.ToHash());
            var hash         = hasher.Finalize();
            var verifyHasher = hash.HexToByte().Xor(block.Hash);

            return(verifyHasher ? VerifyResult.Succeed : VerifyResult.UnableToVerify);
        }
Esempio n. 4
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);
        }