# Class BSV::Network::HeaderSyncer <a id="class-BSV-Network-HeaderSyncer"></a>

**Inherits:** `Object`

Extends the wallet's locally-validated block-header chain (HLR #335).

Single responsibility: the fetch → validate → persist process that grows a
contiguous, PoW-checked run of headers upward from a trust anchor (the
{Checkpoints checkpoint}). Each candidate header is fetched per-height from a
chain-query Service, parsed and validated by {BlockHeader} (PoW + linkage to
its already-validated predecessor), and only then persisted. The result is a
chain the wallet trusts because it verified every link — not because a service
asserted it.

## Fail-closed

A sole misbehaving service is the threat model. Every failure mode —a network
miss, a header that fails PoW, a header that does not link to its predecessor,
a malformed field set — **stops** the sync at the last good height. The bad
header is never persisted and the validated tip never advances past it. A
caller asking about a height the sync could not reach gets "not covered",
which the tracker resolves to a failed verification.

## DoS bound

<code>sync_to!</code> refuses any target more than {MAX_SYNC_SPAN} above the
current validated tip *before fetching anything*. A hostile BEEF can claim a
leaf at height 10^9; without the cap that would spin an unbounded fetch loop.
The cap is generous enough to absorb a stale checkpoint (a release that fell
behind the tip) yet bounded enough that an absurd height costs one comparison,
not millions of HTTP round-trips.

## In-process tip memo

The validated tip and the tip header are memoised for the syncer's lifetime
and advanced as rows are persisted, so repeated <code>sync_to!</code> calls
for nearby heights do not re-read the tip from the database each time. The
memo is a cache over canonical state: cold, it is seeded from the store (or
from the checkpoint when the chain is unseeded); dropping it and rebuilding
from the `blocks` table reproduces identical behaviour.

## Constants
### `MAX_SYNC_SPAN` <a id="constant-MAX_SYNC_SPAN"></a> <a id="MAX_SYNC_SPAN-constant"></a>
Maximum number of headers a single <code>sync_to!</code> may extend the chain
by. Generous on purpose — covers a checkpoint that has drifted well below the
tip — while still refusing the absurd heights a malicious service or BEEF
could feed (the DoS bound).

## Attributes
### `checkpoint_height` [R] <a id="attribute-i-checkpoint_height"></a> <a id="checkpoint_height-instance_method"></a>
- **@return** [Integer] the checkpoint (anchor) height

## Public Instance Methods
### `initialize(store:, services:, checkpoint:)` <a id="method-i-initialize"></a> <a id="initialize-instance_method"></a>
- **@param** `store` [BSV::Wallet::Store] block-header persistence
- **@param** `services` [BSV::Network::Services] chain-query routing layer
- **@param** `checkpoint` [Hash{Symbol => Object}] +{ height:, header: }+ —
the trust anchor (see {Checkpoints.for}). +header+ is a
{BlockHeader} or the raw 80 bytes.
- **@return** [HeaderSyncer] a new instance of HeaderSyncer

### `sync_to!(target_height)` <a id="method-i-sync_to-21"></a> <a id="sync_to!-instance_method"></a>
Extend the validated chain up to `target_height`.

No-op when the tip already covers the target. Returns the validated tip after
the attempt (which equals the last good height when the sync stopped
fail-closed short of the target).
- **@param** `target_height` [Integer]
- **@return** [Integer] the validated tip after syncing

### `validated_tip()` <a id="method-i-validated_tip"></a> <a id="validated_tip-instance_method"></a>
The current validated tip (seeds from the store / checkpoint on first read).
- **@return** [Integer]
