Ejemplo n.º 1
0
        private bool CheckPrevHash(Node node, Block block)
        {
            // If we don't already have its previous block, shunt it off to holding area until we get it
            if (!this.chainIndex.InAnyTip(block.Header.HashPrevBlock))
            {
                var blockHash = block.GetHash();

                //LogPrintf("ProcessBlock: ORPHAN BLOCK %lu, prev=%s\n", (unsigned long)mapOrphanBlocks.size(), pblock->hashPrevBlock.ToString());

                // Accept orphans as long as there is a node to request its parents from
                if (node != null)
                {
                    // ppcoin: check proof-of-stake
                    if (block.IsProofOfStake())
                    {
                        // Limited duplicity on stake: prevents block flood attack
                        // Duplicate stake allowed only when there is orphan child block
                        //if (setStakeSeenOrphan.count(pblock->GetProofOfStake()) && !mapOrphanBlocksByPrev.count(hash))
                        //	return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for orphan block %s",
                        //		pblock->GetProofOfStake().first.ToString(), pblock->GetProofOfStake().second, hash.ToString());
                    }
                }
                var orphan = new OrphanBlock
                {
                    BlockHash    = blockHash,
                    PreviousHash = block.Header.HashPrevBlock,
                    Block        = block,
                };

                if (block.IsProofOfStake())
                {
                    orphan.Stake = block.GetProofOfStake();
                }

                if (this.orphanBlocks.TryAdd(blockHash, orphan))
                {
                    if (!this.Context.DownloadMode)
                    {
                        if (node != null)
                        {
                            // call get blocks
                            var message = new GetBlocksPayload()
                            {
                                BlockLocators = this.chainIndex.Tip.GetLocator(),
                                HashStop      = this.GetOrphanRoot(blockHash)
                            };
                            node.SendMessage(message);

                            // ppcoin: getblocks may not obtain the ancestor block rejected
                            // earlier by duplicate-stake check so we ask for it again directly
                            //node.SendMessage(new InvPayload(InventoryType.MSG_BLOCK, block.Header.HashPrevBlock));
                        }
                    }
                }
                return(false);
            }

            return(true);
        }
Ejemplo n.º 2
0
        private uint256 GetOrphanRoot(uint256 hash)
        {
            var selector = this.orphanBlocks.TryGet(hash);

            if (selector == null)
            {
                return(hash);
            }

            OrphanBlock prev = null;

            while (selector != null)
            {
                prev     = selector;
                selector = this.orphanBlocks.TryGet(selector.PreviousHash);
            }

            return(prev.BlockHash);
        }