internal HeaderNode LastCommonAncestor(HeaderNode otherHeaderNode) { //move both chains at the height of the lower one HeaderNode?left = Height > otherHeaderNode.Height ? GetAncestor(otherHeaderNode.Height) : this; HeaderNode?right = otherHeaderNode.Height > Height?otherHeaderNode.GetAncestor(Height) : otherHeaderNode; // walk back walking previous header, until we find that both are the header while (left != right && left != null && right != null) { left = left.Previous; right = right.Previous; } //at this point returning left or right is the same, both are equals and at worst case they go back down to genesis return(left !); }
internal HeaderNode(BlockHeader header, HeaderNode previous) { if (header == null) { ThrowHelper.ThrowArgumentNullException(nameof(header)); } if (header.Hash == null) { ThrowHelper.ThrowArgumentException($"{nameof(header)} hash cannot be null."); } Hash = header.Hash; Height = previous.Height + 1; Previous = previous; ChainWork = previous.ChainWork + new Target(header.Bits).GetBlockProof(); Skip = previous.GetAncestor(GetSkipHeight(Height)); _status = (int)HeaderValidityStatuses.ValidTree; //pindexNew.TimeMax = (pindexNew->pprev ? std::max(pindexNew->pprev.TimeMax, pindexNew.Time) : pindexNew.Time); }