Documentation
¶
Overview ¶
Package headers is a chain tracker over a header source: an overlay bridge's native /v1 routes (github.com/lightwebinc/overlay-bridge), the public WhatsOnChain API, or a chaintracks v2 service.
It is the root of trust for every proof checked against it. A transaction is only as trustworthy as the headers its BUMP is checked against, so the question of WHO answers "what root does height N commit to" is the whole security question, not a configuration detail. A bridge that received the headers itself, off the same network that delivered the transaction, needs no further check. A source that serves header fields (WhatsOnChain, chaintracks) is not taken at its word: every header it answers is hashed here and must carry the work its bits claim, at or above the network's floor, so a lie costs a mined block rather than an edited response.
It speaks HTTP and imports nothing from the bridge. That is deliberate: this module has exactly one direct dependency, and an HTTP contract plus a vendored fixture is a cheaper coupling than a Go dependency on a service. The fixtures in testdata/fixtures are the bridge's own generated bytes, copied verbatim, so a change to its wire shape fails here rather than in production.
Index ¶
Constants ¶
const ( Mainnet = "main" Testnet = "test" Regtest = "regtest" )
Networks a source may be checked against. The network decides the proof-of-work floor, nothing else.
const MainnetMinDifficulty = 4e9
MainnetMinDifficulty is the lowest difficulty a mainnet header may claim.
Every mainnet block since the 2018 split has carried a difficulty between about 2.6e10 and 5.2e11 (sampled across that range in 2026). The floor sits well below the lowest of those, so a real header never trips it, and well above what anyone could mine for the price of a lie: a header at 4e9 takes about 1.7e19 hashes. Without a floor a lying source would hand back a header whose bits claim a target nobody needs to work for, and the header would pass its own proof-of-work check.
Variables ¶
var ErrBodyTooLarge = errors.New("headers: response body exceeds the bound")
ErrBodyTooLarge refuses a response above the bound.
var ErrProofOfWork = errors.New("headers: header fails its proof of work")
ErrProofOfWork is a header that does not carry the work it claims, or claims less than its network's floor. It is the header source lying (or serving another chain), never a proof that failed: a caller must not read it as "not yet".
var ErrSource = errors.New("headers: bad header source")
ErrSource is a header source specification that cannot be used.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// Base is the source's base URL, with no path suffix.
Base string
// Kind is the dialect Base speaks. The zero value is a bridge's /v1.
Kind Kind
// Network sets the proof-of-work floor for a source that serves header
// fields: Mainnet checks MainnetMinDifficulty, anything else checks each
// header against its own target only.
Network string
// MinDifficulty overrides the network's floor when positive.
MinDifficulty float64
// HTTP is optional.
HTTP *http.Client
// Timeout defaults to 10s when HTTP is nil.
Timeout time.Duration
// contains filtered or unexported fields
}
Client reads block headers from one header source.
func New ¶
New returns a client for a header source specification (see Parse). A specification that does not parse yields a client whose every call returns the parse error, so a caller that cannot handle an error at construction still refuses rather than guessing.
func NewSource ¶ added in v0.3.0
NewSource returns a client for a header source specification (see Parse). A source with header fields is checked for proof of work at the floor of the network it implies; set Network after construction to check it against another.
func (*Client) CurrentHeight ¶
CurrentHeight reports the header service's tip.
Needed as well as root validation, not instead of it: a health check reports how far the header source has got, and a service that answers roots while reporting height zero is a service that has not started.
func (*Client) IsValidRootForHeight ¶
func (c *Client) IsValidRootForHeight(ctx context.Context, root *chainhash.Hash, height uint32) (bool, error)
IsValidRootForHeight reports whether root is the merkle root committed at height.
A 404 is (false, nil): the bridge does not hold that height yet, which means the proof cannot be checked, not that anything is broken. Any OTHER non-ok status is an ERROR, and the distinction is load-bearing. Collapsing the two makes an unreachable or misconfigured header service look exactly like a forged proof, and a verifier that cannot tell those apart will either accept forgeries during an outage or reject good proofs during one, depending on which way it guessed.
type Kind ¶ added in v0.3.0
type Kind int
Kind names the dialect a header source speaks.
const ( // Native is an overlay bridge's /v1 routes: a root per height and a tip, // with no header fields, so no proof of work can be checked. Native Kind = iota // WhatsOnChain is the public WhatsOnChain API for one network. WhatsOnChain // Chaintracks is a chaintracks v2 service (GET /height and // GET /header/height/{h} under the base). Chaintracks )
func Parse ¶ added in v0.3.0
Parse reads a header source specification:
woc:main | woc:test the public WhatsOnChain API chaintracks:https://host/v2 a chaintracks v2 service https://host:port an overlay bridge's native /v1 routes
and reports the kind, the base URL and the network the kind implies ("" for a native source, which carries no header fields to check).