Esempio n. 1
0
        /// <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);
        }
Esempio n. 2
0
        /// <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);
        }
Esempio n. 3
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);
        }