@@ -9,13 +9,16 @@ import (
99 "github.com/lightninglabs/lndclient"
1010 "github.com/lightninglabs/taproot-assets/tapgarden"
1111 "github.com/lightningnetwork/lnd/chainntnfs"
12+ "github.com/lightningnetwork/lnd/lnrpc/verrpc"
1213 "github.com/lightningnetwork/lnd/lnwallet/chainfee"
1314)
1415
1516// LndRpcChainBridge is an implementation of the tapgarden.ChainBridge
1617// interface backed by an active remote lnd node.
1718type LndRpcChainBridge struct {
1819 lnd * lndclient.LndServices
20+
21+ getBlockHeaderSupported * bool
1922}
2023
2124// NewLndRpcChainBridge creates a new chain bridge from an active lnd services
@@ -79,6 +82,19 @@ func (l *LndRpcChainBridge) GetBlock(ctx context.Context,
7982 return block , nil
8083}
8184
85+ // GetBlockHeader returns a block header given its hash.
86+ func (l * LndRpcChainBridge ) GetBlockHeader (ctx context.Context ,
87+ hash chainhash.Hash ) (* wire.BlockHeader , error ) {
88+
89+ header , err := l .lnd .ChainKit .GetBlockHeader (ctx , hash )
90+ if err != nil {
91+ return nil , fmt .Errorf ("unable to retrieve block header: %w" ,
92+ err )
93+ }
94+
95+ return header , nil
96+ }
97+
8298// GetBlockHash returns the hash of the block in the best blockchain at the
8399// given height.
84100func (l * LndRpcChainBridge ) GetBlockHash (ctx context.Context ,
@@ -93,6 +109,31 @@ func (l *LndRpcChainBridge) GetBlockHash(ctx context.Context,
93109 return blockHash , nil
94110}
95111
112+ // GetBlockHeaderSupported returns true if the chain backend supports the
113+ // `GetBlockHeader` RPC call.
114+ func (l * LndRpcChainBridge ) GetBlockHeaderSupported (ctx context.Context ) bool {
115+ // Check if we've already asserted the compatibility of the chain
116+ // backend.
117+ if l .getBlockHeaderSupported != nil {
118+ return * l .getBlockHeaderSupported
119+ }
120+
121+ // The ChainKit.GetBlockHeader() RPC call was added in lnd v0.17.1.
122+ getBlockHeaderMinimalVersion := & verrpc.Version {
123+ AppMajor : 0 ,
124+ AppMinor : 17 ,
125+ AppPatch : 1 ,
126+ }
127+
128+ getBlockHeaderUnsupported := lndclient .AssertVersionCompatible (
129+ l .lnd .Version , getBlockHeaderMinimalVersion ,
130+ )
131+ getBlockHeaderSupported := getBlockHeaderUnsupported == nil
132+
133+ l .getBlockHeaderSupported = & getBlockHeaderSupported
134+ return * l .getBlockHeaderSupported
135+ }
136+
96137// VerifyBlock returns an error if a block (with given header and height) is not
97138// present on-chain. It also checks to ensure that block height corresponds to
98139// the given block header.
@@ -121,7 +162,14 @@ func (l *LndRpcChainBridge) VerifyBlock(ctx context.Context,
121162 "expectedHash: %s)" , height , hash , expectedHash )
122163 }
123164
124- // Ensure that the block header corresponds to a block on-chain.
165+ // Ensure that the block header corresponds to a block on-chain. Fetch
166+ // only the corresponding block header and not the entire block if
167+ // supported.
168+ if l .GetBlockHeaderSupported (ctx ) {
169+ _ , err = l .GetBlockHeader (ctx , header .BlockHash ())
170+ return err
171+ }
172+
125173 _ , err = l .GetBlock (ctx , header .BlockHash ())
126174 return err
127175}
0 commit comments