daemon

package
v1.9.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2026 License: Apache-2.0, MIT Imports: 40 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Gateway is the Lantern gateway URL used for state-tree backfill +
	// chain-head bootstrap. Defaults to https://gateway.lantern.reiers.io.
	Gateway string

	// DataDir is the directory the daemon reads + writes (header store,
	// JWT secret, tokens). REQUIRED.
	DataDir string

	// Wallet is the keystore-backed wallet used to sign messages. REQUIRED.
	// Callers that don't need signing (read-only embedding) can pass a
	// wallet with no keys.
	Wallet *wallet.Wallet

	// Passphrase is the keystore decryption passphrase. Optional when
	// Wallet was constructed already-unlocked.
	Passphrase string

	// RPCListen is the JSON-RPC server bind address. Default 127.0.0.1:1234.
	RPCListen string

	// MetricsListen is the optional Prometheus + dashboard bind address.
	// Default empty (no metrics endpoint).
	MetricsListen string

	// P2PListen is comma-separated libp2p listen multiaddrs. Default
	// "/ip4/0.0.0.0/tcp/0,/ip4/0.0.0.0/udp/0/quic-v1". Set to "" to
	// disable the libp2p host entirely (RPC stays up, Net* RPCs return
	// empty data).
	P2PListen string

	// NoHeaderStore disables the persistent header store. Useful for
	// short-lived embedded uses where ChainNotify history isn't needed.
	NoHeaderStore bool

	// HeaderStorePath overrides the default Badger location ($DataDir/headerstore).
	HeaderStorePath string

	// SyncInterval is the header-store poll cadence. Default 6s.
	SyncInterval time.Duration

	// DevnetHeadPollInterval, when > 0, overrides the header-store poll
	// cadence on devnet only. Zero (default) means auto: use
	// build.GetDevnetConfig().BlockDelaySecs (persisted by
	// `lantern devnet-init`), or 4s if unavailable. Fixes lantern#123
	// findings 8+9: a single-node docker devnet can't form a gossipsub
	// mesh, so head arrives ONLY via RPC polling; the mainnet-oriented
	// 30s cadence lags a 4s-epoch devnet by ~7x block time. Ignored on
	// mainnet + calibration (SyncInterval / gossip logic is unchanged
	// there).
	DevnetHeadPollInterval time.Duration

	// PersistentCache enables the on-disk (Badger) block cache instead of
	// the in-memory MemBlockStore. This is the PDP / mid-node tier: the warm
	// contract subtrees (PDP/payments/registry/USDFC) SURVIVE restart, so a
	// restarted node doesn't cold-fetch its whole warm set from the gateway
	// on the first head advance (which for a PDP node could stall inside a
	// proving window). The light node leaves this false and stays
	// memory-cached. Cache lives at <DataDir>/<network>/blockcache.
	PersistentCache bool

	// PersistentCacheBytes is the soft byte budget for the persistent block
	// cache (only used when PersistentCache=true). 0 => default 3 GiB (the
	// middle of the 2-5 GB PDP-tier target). Eviction is sampled-LRU over
	// unpinned blocks; pinned warm-set subtrees are never evicted.
	PersistentCacheBytes int64

	// FullValidation enables the Full-tier per-block consensus pipeline
	// (chain/fullvalidate, #90): signature / VRF / win-count re-verified
	// against resident F3-anchored state on every ingested block. Light/PDP
	// leave this false. Requires an accessor-backed ChainAPI.
	FullValidation bool

	// FullValidationFatal decides whether a FullValidation failure rejects
	// the tipset (true) or is only logged (false = observe mode). Defaults
	// to observe so a Full node can be brought up + watched on calibration
	// before the pipeline is trusted to gate ingest.
	FullValidationFatal bool

	// WinningPoStVerify enables pure-Go WinningPoSt SNARK verification on
	// every ingested Full-tier block (#87 + #88). Only takes effect when
	// FullValidation=true. Observe mode by default (respects
	// FullValidationFatal). Requires WinningPoStParamsDir to hold the
	// Filecoin proof-parameter verifying keys for the sector-size range
	// the network uses.
	WinningPoStVerify bool

	// WinningPoStParamsDir is the directory holding the Filecoin proof-
	// parameters (specifically the WinningPoSt verifying keys). Empty =>
	// the daemon uses its default (<DataDir>/proof-params). Ignored when
	// WinningPoStVerify=false.
	WinningPoStParamsDir string

	// HeadCorroborationPeers (#80 part 2) is the number of distinct gossip
	// peers that must forward a block before the ingestor adopts it as the
	// new head. A trusted floor peer (protected bootstrap/beacon/direct
	// peer) counts as a super-vote, and the requirement clamps to the
	// connected-peer count so a small node never wedges. 0 disables (the
	// Light/PDP default; their head safety comes from the divergence
	// monitor + heaviest-weight fork choice).
	HeadCorroborationPeers int

	// StaleResetThreshold is the number of epochs behind live head past
	// which a persisted header store re-anchors near live head instead of
	// trying (and failing) to backfill an un-connectable gap (#51). This is
	// the "down for a maintenance window / crash / long proving gap"
	// auto-heal: without it, an embedded node that falls further than
	// MaxBacktrack (~900 epochs) behind wedges its head forever and needs a
	// manual `lantern reset --chain-state`. Chain-state pointers only are
	// discarded on re-anchor; keys/wallets/tokens live in separate files and
	// are never touched. 0 = use the default; a negative value disables.
	// Default (when 0): 2880 epochs (~1 day at 30s blocks), matching the
	// standalone cmd/lantern daemon.
	StaleResetThreshold abi.ChainEpoch

	// NotifyBufSize is the ChainNotify per-subscriber buffer. Default 64.
	NotifyBufSize int

	// NoLibp2p disables libp2p host startup. Equivalent to P2PListen="".
	NoLibp2p bool

	// BitswapEnabled inserts Bitswap between cache and HTTP gateway.
	// Default true.
	BitswapEnabled bool

	// BitswapFastDeadline is the preferred-peer Bitswap stage deadline.
	// Default 1.5s.
	BitswapFastDeadline time.Duration

	// BitswapFullDeadline is the swarm-broadcast Bitswap stage deadline.
	// Default 5s.
	BitswapFullDeadline time.Duration

	// BitswapPeers is a comma-separated multiaddr list of always-keep-
	// connected Bitswap providers (beacon nodes typically).
	BitswapPeers string

	// FallbackRPC overrides the Lotus-compatible RPC URL used as the
	// polling Sync head source and the cold state-block fallback. Empty
	// uses the built-in Glif URL for the active network (the historical
	// default). Point this at your own Forest/Lotus node to remove the
	// Glif dependency without going fully bridge-off (lantern#50 part 3).
	FallbackRPC string

	// HeadCheckRPCs is an optional list of Lotus-compatible JSON-RPC URLs
	// used by the running-head divergence monitor (chain/headcheck,
	// #85) to CORROBORATE the gossip-derived head. These are never
	// the source of truth for the head - they only raise an eclipse/fork
	// alarm when a diversity of independent observers disagrees with our
	// head beyond the 3-block lookback. Empty disables the monitor.
	HeadCheckRPCs []string

	// NoFallbackRPC, when true, wires NO upstream RPC as the Sync head
	// source or cold-block fallback - the node relies purely on gossipsub
	// for the head and Bitswap for cold blocks (lantern#50 part 3). This
	// makes the bridge-off trust posture EXPLICIT: under the old default a
	// bridge-off node silently fell back to Glif whenever gossip stalled,
	// a hidden third-party dependency. With this set, a gossip stall
	// surfaces as a stalled head (observable) instead of a silent Glif
	// fetch. Intended for operators who have a healthy swarm/beacon set
	// and want a provably-Glif-free node. Overrides FallbackRPC.
	NoFallbackRPC bool

	// VMBridgeRPC is an upstream Forest/Lotus JSON-RPC URL for the VM
	// bridge (needed for AllowBlockSubmit=true). Empty disables bridge.
	VMBridgeRPC string

	// VMBridgeToken is the optional Bearer token for the bridge.
	VMBridgeToken string

	// VMBridgeTimeout caps each bridge call. Default 30s.
	VMBridgeTimeout time.Duration

	// AllowBlockSubmit lifts the SyncSubmitBlock gate. Requires VMBridgeRPC.
	AllowBlockSubmit bool

	// Network selects the Filecoin network the embedded daemon syncs.
	// Accepted values: "mainnet" (default), "calibration". Drives the
	// gateway URL, Glif fallback URL, bootstrap peers, network name,
	// genesis CID, F3 manifest, and the Filecoin.Version label.
	Network string

	// EmbeddedMode is set by callers (e.g. Curio Core) that want to
	// suppress some CLI-shaped stdout/stderr noise. Functionally no-op
	// otherwise.
	EmbeddedMode bool

	// FEVMPrefetchAddrs is the optional list of EVM contract addresses
	// (20-byte hex, 0x-prefixed or bare) whose state subtrees should be
	// warmed into the local blockstore cache on every head advance, so
	// later eth_calls hit the cache instead of falling back to the VM
	// bridge or returning "block not found" (lantern#44).
	//
	// Embedded callers should set this to the proxy + impl addresses of
	// the contracts they read (PDPVerifier, FWSS, ServiceProviderRegistry,
	// USDFC, ...). The standalone daemon leaves this empty by default;
	// curio-core will wire defaults from its pdp/contract/addresses.go.
	FEVMPrefetchAddrs []string

	// FEVMPrefetchMaxBlocksPerAddr caps the BFS node-count per address
	// per head advance. Default 256.
	FEVMPrefetchMaxBlocksPerAddr int

	// FEVMPrefetchPerAddrTimeout bounds one address's walk. Default 20s.
	FEVMPrefetchPerAddrTimeout time.Duration

	// FEVMPrefetchMinInterval coalesces rapid head advances: each
	// address is walked at most once per MinInterval. Default 60s.
	FEVMPrefetchMinInterval time.Duration

	// FEVMFetchRetries / FEVMFetchTimeout control the retry-on-miss
	// wrapper used by the eth_call backend for bytecode + KAMT storage
	// reads (lantern#44). Zero values pick sensible defaults
	// (2 retries / 8s total). Set FEVMFetchRetries < 0 to disable.
	FEVMFetchRetries int
	FEVMFetchTimeout time.Duration

	// MpoolPersistDisabled turns OFF the durable pending-message store
	// (#119). Zero value = enabled: user pushed messages survive daemon
	// restart, and the sender's next nonce stays consistent because
	// MpoolGetNonce reads the restored pending set. Set to true only for
	// stateless embedded uses (CI, ephemeral tests) that don't want the
	// per-network mpool directory.
	MpoolPersistDisabled bool

	// MpoolPersistPath overrides the default persist journal path
	// (<DataDir>/<Network>/mpool/pending.jsonl). Empty uses the default.
	MpoolPersistPath string
}

Config holds every knob the embedded daemon exposes. All fields are optional except DataDir + Wallet. Zero values get the same defaults the CLI would use.

type Daemon

type Daemon struct {
	// contains filtered or unexported fields
}

Daemon is a running Lantern node. Construct via New, then Start.

func New

func New(cfg Config) (*Daemon, error)

New constructs a Daemon from a Config. Validates required fields. Does NOT start the network; call Start.

func (*Daemon) AdminToken

func (d *Daemon) AdminToken() string

Start brings the daemon up: fetches the trusted head, opens the header store, brings up libp2p + gossipsub, mounts the JSON-RPC server, and (optionally) the metrics + dashboard endpoints. Blocks until ctx is cancelled or a fatal startup error occurs.

AdminToken returns the pre-minted admin-scope JWT for the embedded RPC server. Only valid after Start has returned nil (or Started() returns true) and only when the RPC server was actually mounted (RPCListen != "" in Config). Returns "" otherwise.

Embedded callers (notably curio-core) use this to self-issue a token against the in-process Lantern without going through disk files or environment variables.

func (*Daemon) BlockCacheStats

func (d *Daemon) BlockCacheStats() (statecache.Stats, bool)

HeadCorroboration returns the latest running-head divergence-monitor result (chain/headcheck, #85/#86) and true when the monitor is running. This is the observable answer to "is my running head corroborated by a diversity of independent sources right now, or does it look eclipsed?" - it surfaces the monitor's verdict (agree / diverge / insufficient) plus the local vs median-external head epochs and the agree/disagree tallies, so an operator (or the dashboard) can SEE an eclipse alarm instead of grepping logs. Returns (zero, false) when the monitor is disabled (no HeadCheckRPCs configured) or the daemon isn't started.

It deliberately reports status only; it never halts the node. Divergence is an alarm, not an auto-stop - a false positive must not become a self-inflicted DoS. Closing the loop on #79 (periodic re-quorum) / #80 (head-source diversity) is about making the running head continuously, visibly corroborated; the head itself still advances on gossip + the #79 heaviest-weight fork choice. BlockCacheStats returns the persistent block-cache counters (live bytes, soft cap, hits/misses/puts/evictions) and true when the PDP-tier persistent cache is enabled. Returns (zero, false) for the memory-cached light node. Lets the dashboard show the warm-set footprint + hit rate.

func (*Daemon) Config

func (d *Daemon) Config() Config

Config returns the effective configuration (with defaults applied).

func (*Daemon) ECFinality

func (d *Daemon) ECFinality() (*ecfinality.Status, bool)

ECFinality returns the current FRC-0089 observed-data finality status (#96): the shallowest depth at which reorg probability drops below 2^-30 given the observed block counts, the finalized epoch at that depth, and how many epochs of history the calculator had. Returns (nil, false) when no header store is configured. Computation is on-demand and cached per head.

func (*Daemon) FEVMPrefetchStats

func (d *Daemon) FEVMPrefetchStats() (prefetch.Stats, bool)

FEVMPrefetchStats returns a snapshot of the FEVM state-block prefetcher's counters and true when the prefetcher is wired. Returns (zero, false) when the merged warm-set (built-in + consumer) was empty, so the prefetcher never started (lantern#44, #69).

func (*Daemon) FullNodeAPIInfo

func (d *Daemon) FullNodeAPIInfo() (string, error)

FullNodeAPIInfo returns the Lotus-compatible FULLNODE_API_INFO string for the admin-scoped token, ready to be set into the environment by embedded callers running a Lotus-API client. Only valid after Start has mounted the RPC server.

func (*Daemon) GossipStats

func (d *Daemon) GossipStats() (blockingest.Stats, bool)

GossipStats returns a snapshot of gossipsub block-ingestor counters and true when gossipsub head-tracking is active. Returns (zero, false) when running on the polling Sync alone. Useful for verifying the 0-1 epoch latency soak in #40.

func (*Daemon) HeadChanges

func (d *Daemon) HeadChanges(ctx context.Context) <-chan []lapi.HeadChange

HeadChanges returns a channel of head-change events from the in-process distributor. The first event is always {Type:"current"} with the current head (or nil if the store hasn't observed a head yet). Cancelling ctx unsubscribes and closes the channel.

Returns nil when NoHeaderStore=true (no distributor wired) OR when Start has not yet completed.

Embedded consumers (curio-core) call this to drive chain-sched event loops without going through the JSON-RPC ChainNotify path (which can't carry channels over HTTP POST). External consumers reach the same distributor via the standard JSON-RPC ChainNotify when the RPC server is upgraded to WebSocket transport.

func (*Daemon) HeadCorroboration

func (d *Daemon) HeadCorroboration() (headcheck.Result, bool)

func (*Daemon) HeadEpoch

func (d *Daemon) HeadEpoch() abi.ChainEpoch

HeadEpoch returns the current head epoch from the captured TrustedRoot. Returns 0 if Start hasn't completed.

func (*Daemon) Host

func (d *Daemon) Host() *llibp2p.Host

Host returns the libp2p host, or nil when libp2p is disabled (NoLibp2p / empty P2PListen) or Start hasn't completed. See #40.

func (*Daemon) LocalEthCallStats

func (d *Daemon) LocalEthCallStats() (handlers.LocalEthCallStatsView, bool)

LocalEthCallStats returns a snapshot of the local-eth_call counters (lantern#44). A healthy embedded daemon with state-block availability should approach Served/Total = 1.0. Returns (zero, false) when the daemon hasn't reached the point where ChainAPI is wired (i.e. before Start completes), so callers can poll safely.

func (*Daemon) MintToken

func (d *Daemon) MintToken(perms []auth.Permission) ([]byte, error)

MintToken issues a fresh JWT with the requested permissions. Use AdminToken() when the pre-minted admin token suffices; use this only when a narrower scope is needed (e.g. minting a read-only token for a constrained consumer). Returns an error if the RPC server hasn't been mounted yet.

func (*Daemon) MpoolStats

func (d *Daemon) MpoolStats() (mpool.Stats, bool)

MpoolStats returns a snapshot of gossipsub-mempool counters (including #119 Restored + PersistPath) and true when the mempool is wired. Returns (zero, false) when the pool wasn't wired (e.g. libp2p disabled or mpool init failure). Useful for verifying restart-persistence behavior after a soft restart.

func (*Daemon) RPCAddr

func (d *Daemon) RPCAddr() string

RPCAddr returns the resolved RPC listen address. Only valid after Start has returned nil (or after Started() returns true).

func (*Daemon) Start

func (d *Daemon) Start(ctx context.Context) error

Original Start doc continues:

On a clean ctx cancellation, Start returns nil. On startup failure, Start returns the error and the daemon is half-built (caller should still call Stop to clean up partial state).

Concurrency: not safe to call twice on the same Daemon.

func (*Daemon) Started

func (d *Daemon) Started() bool

Started reports whether Start has finished bringing the daemon up.

func (*Daemon) Stop

func (d *Daemon) Stop(ctx context.Context) error

Stop signals the daemon to shut down. Returns nil if the daemon was not running. Otherwise blocks (with a 5s timeout) until shutdown is complete or ctx is cancelled.

func (*Daemon) TrustedRoot

func (d *Daemon) TrustedRoot() *trustedroot.TrustedRoot

TrustedRoot returns the daemon's captured anchor. Only valid after Start has returned nil. Returns nil before that.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL