Skip to content

neutrino: add fast initial sync via header import#10552

Open
Roasbeef wants to merge 6 commits intolightningnetwork:masterfrom
Roasbeef:neutrino-fast-sync
Open

neutrino: add fast initial sync via header import#10552
Roasbeef wants to merge 6 commits intolightningnetwork:masterfrom
Roasbeef:neutrino-fast-sync

Conversation

@Roasbeef
Copy link
Member

@Roasbeef Roasbeef commented Feb 4, 2026

This PR wires neutrino's chainimport feature into lnd, enabling fast initial sync by importing pre-built block and filter headers from local files or HTTP URLs before falling back to P2P sync for the remainder of the chain. On mainnet, this can reduce initial sync from hours to minutes by downloading headers from a trusted source like block-dn.org instead of fetching them one-by-one from peers.

Two new config options are added under the [neutrino] section: neutrino.blockheaderssource and neutrino.filterheaderssource. Both accept either a local file path or an HTTP(S) URL. When configured, neutrino imports headers from these sources on startup, validates proof-of-work, and then continues syncing any remaining blocks via its normal P2P protocol. Both sources must be specified together or not at all.

The neutrino dependency is updated to include the chainimport package (PRs #317, #320, #324) as well as a bug fix for the block manager's internal state after import (lightninglabs/neutrino#335). Without this fix, the block manager would retain stale genesis-based locators after import and fail to sync additional blocks via P2P. The Start() method signature change to accept context.Context is propagated to all call sites.

An integration test exercises the full end-to-end flow: mining blocks, syncing a reference node to generate header files, copying those files with import metadata, starting a fresh node with the import config, and verifying it syncs to the chain tip and can continue syncing additional blocks mined after the import snapshot.

Depends on lightninglabs/neutrino#335.

@gemini-code-assist
Copy link

Summary of Changes

Hello @Roasbeef, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant performance improvement for LND nodes utilizing the Neutrino backend. By integrating a 'fast initial sync' mechanism, users can now bootstrap their nodes using pre-existing block and filter headers, drastically cutting down the time required to get a node up and running. This enhancement is designed to make LND more accessible and efficient for new users or those re-syncing, without compromising on security through robust validation and a P2P fallback.

Highlights

  • Fast Initial Sync for Neutrino: Implemented a new feature enabling Neutrino nodes to perform a fast initial sync by importing pre-built block and filter headers from local files or HTTP URLs, significantly reducing sync times.
  • New Configuration Options: Introduced neutrino.blockheaderssource and neutrino.filterheaderssource configuration options to specify the sources for header import, which must be configured together.
  • Neutrino Dependency Update: Updated the underlying neutrino dependency to incorporate the chainimport package and a crucial bug fix related to the block manager's internal state after import.
  • Context Propagation for Start Methods: Propagated context.Context to the Start() method across various chain backend implementations, aligning with modern Go concurrency patterns.
  • Comprehensive Documentation and Testing: Added detailed documentation (docs/neutrino_headers_import.md) explaining the feature, configuration, and security, alongside a new integration test (itest/lnd_neutrino_headers_import_test.go) to validate the end-to-end flow.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • chainntnfs/bitcoindnotify/bitcoind.go
    • Updated Start() method signature to accept context.Context.
  • chainntnfs/bitcoindnotify/bitcoind_dev.go
    • Updated Start() method signature to accept context.Context.
  • chainreg/no_chain_backend.go
    • Updated Start() method signature to accept context.Context.
  • config_builder.go
    • Added import for github.com/btcsuite/btcd/blockchain.
    • Implemented validation for Neutrino headers import configuration.
    • Configured HeadersImportConfig based on new BlockHeadersSource and FilterHeadersSource options.
    • Applied blockchain.BFFastAdd flag for regtest and simnet during header import to handle rapid block mining.
    • Updated neutrinoCS.Start() call to pass context.Context.
  • docs/neutrino_headers_import.md
    • Added new documentation file detailing Neutrino fast sync via headers import, including how it works, configuration, security considerations, and troubleshooting.
  • go.mod
    • Updated various Go module dependencies to newer versions.
    • Replaced github.com/lightninglabs/neutrino with a specific commit from github.com/Roasbeef/neutrino to include the chainimport package and a block manager fix.
  • go.sum
    • Updated checksums for various Go module dependencies to reflect changes in go.mod.
  • itest/list_on_test.go
    • Added a new entry for testNeutrinoHeadersImport to the list of integration tests.
  • itest/lnd_neutrino_headers_import_test.go
    • Added a new integration test to verify the functionality of Neutrino headers import, including creating header files, adding metadata, and validating sync.
  • lncfg/neutrino.go
    • Added BlockHeadersSource and FilterHeadersSource fields to the Neutrino configuration struct.
    • Implemented a Validate() method for Neutrino config to ensure both header source options are specified together.
  • lnmock/chain.go
    • Updated Start() method signature to accept context.Context.
  • lntest/unittest/backend.go
    • Updated spvNode.Start() call to pass context.Context.
  • lnwallet/btcwallet/btcwallet.go
    • Updated b.chain.Start() call to pass context.Context.
  • lnwallet/test/test_interface.go
    • Updated aliceChain.Start() and bobChain.Start() calls to pass context.Context.
  • routing/chainview/bitcoind.go
    • Updated b.chainClient.Start() call to pass context.Context.
  • routing/chainview/interface_test.go
    • Updated spvNode.Start() call to pass context.Context.
  • sample-lnd.conf
    • Added comments and examples for the new neutrino.blockheaderssource and neutrino.filterheaderssource configuration options.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Update the neutrino dependency to a version that includes the
chainimport package for fast initial header sync, and the
ResetHeaderState fix that allows P2P sync to continue after import.

The updated neutrino dependency changes the ChainService.Start method
signature to accept a context.Context parameter. Update all call sites
to pass context.TODO() to maintain existing behavior.
Add BlockHeadersSource and FilterHeadersSource fields to the Neutrino
config struct. These accept either local file paths or HTTP(S) URLs
pointing to pre-built header files for fast initial sync.

Add a Validate method that ensures both sources are specified together
or both are empty.
Pass the configured BlockHeadersSource and FilterHeadersSource into
neutrino's HeadersImportConfig when initializing the neutrino backend.
Set blockchain.BFFastAdd validation flags for regtest and simnet to
skip contextual timestamp checks on rapidly-mined blocks.

Call Validate on the neutrino config before proceeding to catch
misconfiguration early.
Add commented examples for the new neutrino.blockheaderssource and
neutrino.filterheaderssource options, showing both URL-based import
from block-dn.org and local file path usage.
Add an integration test that verifies neutrino header import from local
files. The test mines blocks, starts a reference node to generate header
files via normal P2P sync, copies those files with import metadata, then
starts a new node configured to import headers from the prepared files.

The test verifies the import node syncs to the chain tip and can
continue syncing additional blocks mined after import via P2P, exercising
the hybrid import-then-P2P sync path.
Document the neutrino fast sync feature that allows importing block and
filter headers from local files or HTTP URLs on startup. Cover
configuration for mainnet (block-dn.org), testnet3, testnet4, signet,
file format details, security considerations, and troubleshooting.
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a valuable feature for fast initial sync in neutrino mode by importing pre-built block and filter headers. The implementation is well-rounded, including new configuration options, necessary dependency updates, and excellent documentation. The addition of a comprehensive integration test is particularly noteworthy as it ensures the end-to-end flow is working correctly. The code is clean and follows the project's style. My only suggestion for future improvement is to address the use of context.TODO() which was introduced to adapt to dependency changes, to ensure robust cancellation and timeout handling throughout the application.

// Connect to bitcoind, and register for notifications on connected,
// and disconnected blocks.
if err := b.chainConn.Start(); err != nil {
if err := b.chainConn.Start(context.TODO()); err != nil {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using context.TODO() is a pragmatic way to adapt to the updated dependency interface without a major refactoring. However, it introduces some technical debt. For improved robustness, especially during shutdown, it would be beneficial to propagate a proper context with cancellation capabilities from the callers. I recommend creating a follow-up issue to address this throughout the codebase where context.TODO() has been introduced.

@lightninglabs-deploy
Copy link
Collaborator

🔴 PR Severity: CRITICAL

neutrino: add fast initial sync via header import | 17 files | 595 lines changed

🔴 Critical (1 file)
  • lnwallet/btcwallet/btcwallet.go - Wallet operations and chain backend integration
🟠 High (4 files)
  • chainntnfs/bitcoindnotify/bitcoind.go - Chain notification handling
  • chainntnfs/bitcoindnotify/bitcoind_dev.go - Chain notification handling (dev mode)
  • lncfg/neutrino.go - Neutrino chain sync configuration
  • routing/chainview/bitcoind.go - Chain view for routing decisions
🟡 Medium (3 files)
  • chainreg/no_chain_backend.go - Chain registry
  • config_builder.go - Configuration builder
  • go.mod + go.sum - Dependency updates (neutrino upgrade)
🟢 Low (9 files)
  • docs/neutrino_headers_import.md - Documentation
  • itest/list_on_test.go - Integration test list
  • itest/lnd_neutrino_headers_import_test.go - Integration test
  • lnmock/chain.go - Mock chain interface
  • lntest/unittest/backend.go - Test backend
  • lnwallet/test/test_interface.go - Test interface
  • routing/chainview/interface_test.go - Test file
  • sample-lnd.conf - Sample configuration

Analysis

This PR is classified as CRITICAL because it modifies lnwallet/btcwallet/btcwallet.go, which is part of the core wallet operations layer. While the feature itself (fast header import) is primarily a chain sync optimization, the changes touch the wallet's chain backend initialization code path, which is critical infrastructure.

The PR introduces neutrino's chainimport feature to enable fast initial sync by importing pre-built block and filter headers from local files or HTTP URLs. This modifies how the chain backend starts up and initializes, affecting the wallet's interaction with the blockchain backend.

Key concerns for reviewers:

  1. Wallet Backend Integration: Changes to lnwallet/btcwallet/btcwallet.go affect how the wallet initializes its chain backend - requires careful review of the Start() signature change and context propagation
  2. Chain Notifications: Multiple changes to chain notification handlers need verification to ensure proper startup sequencing
  3. Dependency Update: The neutrino dependency upgrade includes the new chainimport functionality and a critical bug fix for block manager state after import
  4. Trust Assumptions: The feature allows importing headers from external sources (HTTP URLs) - security implications should be reviewed even though PoW validation is performed

The integration test coverage is thorough and the documentation is comprehensive, which is positive. However, given this touches the wallet's chain backend initialization path, it requires expert review.


To override, add a severity-override-{critical,high,medium,low} label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants