diff --git a/log.go b/log.go index 5e57fbbc..9ed37a0a 100644 --- a/log.go +++ b/log.go @@ -12,6 +12,7 @@ import ( "github.com/lightninglabs/neutrino/filterdb" "github.com/lightninglabs/neutrino/pushtx" "github.com/lightninglabs/neutrino/query" + "github.com/lightninglabs/neutrino/sideload" ) // log is a logger that is initialized with no output filters. This @@ -45,4 +46,5 @@ func UseLogger(logger btclog.Logger) { query.UseLogger(logger) filterdb.UseLogger(logger) chanutils.UseLogger(logger) + sideload.UseLogger(logger) } diff --git a/neutrino.go b/neutrino.go index 4a64cfb8..2d77a00a 100644 --- a/neutrino.go +++ b/neutrino.go @@ -6,6 +6,7 @@ package neutrino import ( "errors" "fmt" + "io" "net" "strconv" "strings" @@ -31,6 +32,7 @@ import ( "github.com/lightninglabs/neutrino/headerlist" "github.com/lightninglabs/neutrino/pushtx" "github.com/lightninglabs/neutrino/query" + "github.com/lightninglabs/neutrino/sideload" ) // These are exported variables so they can be changed by users. @@ -85,6 +87,8 @@ var ( // DefaultBlockCacheSize is the size (in bytes) of blocks neutrino will // keep in memory if no size is specified in the neutrino.Config. DefaultBlockCacheSize uint64 = 4096 * 10 * 1000 // 40 MB + + SideloadRange uint32 = 2000 ) // isDevNetwork indicates if the chain is a private development network, namely @@ -114,6 +118,18 @@ type peerState struct { outboundGroups map[string]int } +type SideloadOpt struct { + // SourceType is the format type of the sideload source. + SourceType sideload.SourceType + + // Reader is the sideload's source. + Reader io.ReadSeeker + + SkipVerify bool + + SideloadRange uint32 +} + // Count returns the count of all known peers. func (ps *peerState) Count() int { return len(ps.outboundPeers) + len(ps.persistentPeers) @@ -619,6 +635,8 @@ type Config struct { // not, replies with a getdata message. // 3. Neutrino sends the raw transaction. BroadcastTimeout time.Duration + + BlkHdrSideload *SideloadOpt } // peerSubscription holds a peer subscription which we'll notify about any @@ -679,6 +697,8 @@ type ChainService struct { // nolint:maligned dialer func(net.Addr) (net.Conn, error) broadcastTimeout time.Duration + + BlockHeaderSideloader *sideload.SideLoader[*wire.BlockHeader] } // NewChainService returns a new chain service configured to connect to the @@ -815,6 +835,46 @@ func NewChainService(cfg Config) (*ChainService, error) { return nil, err } s.blockManager = bm + + if cfg.BlkHdrSideload != nil { + blockHdrChkptMgr := NewBlockHeaderCheckpoints(s.chainParams) + blockHeaderWriter := &blkHeaderWriter{ + store: s.BlockHeaders, + tipHeight: s.blockManager.headerTip, + } + + loader := sideload.LoaderInternal[*wire.BlockHeader]{ + HeaderWriter: blockHeaderWriter, + HeaderValidator: &blockHeaderValidator{ + BlockHeaderCheckpoints: blockHdrChkptMgr, + headerList: bm.headerList, + minRetargetTimespan: bm.minRetargetTimespan, + maxRetargetTimespan: bm.maxRetargetTimespan, + blocksPerRetarget: bm.blocksPerRetarget, + ChainParams: s.chainParams, + TimeSource: s.timeSource, + nextCheckpoint: bm.nextCheckpoint, + store: s.BlockHeaders, + }, + SkipVerify: cfg.BlkHdrSideload.SkipVerify, + Chkpt: blockHdrChkptMgr, + SideloadRange: SideloadRange, + } + + blkHdrSideload, err := sideload.NewBlockHeaderLoader( + &sideload.LoaderConfig[*wire.BlockHeader]{ + LoaderInternal: loader, + SourceType: cfg.BlkHdrSideload.SourceType, + Reader: cfg.BlkHdrSideload.Reader, + Chain: s.chainParams.Net, + }) + if err != nil { + return nil, err + } + + s.BlockHeaderSideloader = blkHdrSideload + } + s.blockSubscriptionMgr = blockntfns.NewSubscriptionManager(s.blockManager) // Only setup a function to return new addresses to connect to when not @@ -1606,8 +1666,13 @@ func (s *ChainService) Start() error { return nil } - // Start the address manager and block manager, both of which are - // needed by peers. + if s.BlockHeaderSideloader != nil { + err := s.BlockHeaderSideloader.Load() + if err != nil { + log.Warnf("error while sideloading: %v", err) + } + } + s.addrManager.Start() s.blockManager.Start() s.blockSubscriptionMgr.Start()