Skip to content

Commit 129d128

Browse files
committed
lndservices+tapcfg: use block header cache in LndRpcChainBridge
Adds a block header cache to LndRpcChainBridge, which indirectly improves performance of methods like GetBlockTimestamp by avoiding repeated block header fetches.
1 parent fe15b0d commit 129d128

File tree

3 files changed

+48
-5
lines changed

3 files changed

+48
-5
lines changed

lndservices/chain_bridge.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,22 @@ type LndRpcChainBridge struct {
4242

4343
// assetStore is a handle to the asset store.
4444
assetStore *tapdb.AssetStore
45+
46+
// headerCache is a cache for block headers to reduce RPC calls.
47+
headerCache *BlockHeaderCache
4548
}
4649

4750
// NewLndRpcChainBridge creates a new chain bridge from an active lnd services
4851
// client.
4952
func NewLndRpcChainBridge(lnd *lndclient.LndServices,
50-
assetStore *tapdb.AssetStore) *LndRpcChainBridge {
53+
assetStore *tapdb.AssetStore,
54+
headerCache *BlockHeaderCache) *LndRpcChainBridge {
5155

5256
return &LndRpcChainBridge{
5357
lnd: lnd,
5458
retryConfig: fn.DefaultRetryConfig(),
5559
assetStore: assetStore,
60+
headerCache: headerCache,
5661
}
5762
}
5863

@@ -118,6 +123,11 @@ func (l *LndRpcChainBridge) GetBlock(ctx context.Context,
118123
func (l *LndRpcChainBridge) GetBlockHeader(ctx context.Context,
119124
hash chainhash.Hash) (*wire.BlockHeader, error) {
120125

126+
// First, check the cache for the requested block header.
127+
if header, ok := l.headerCache.GetByHash(hash); ok {
128+
return &header, nil
129+
}
130+
121131
return fn.RetryFuncN(
122132
ctx, l.retryConfig, func() (*wire.BlockHeader, error) {
123133
header, err := l.lnd.ChainKit.GetBlockHeader(ctx, hash)
@@ -136,6 +146,14 @@ func (l *LndRpcChainBridge) GetBlockHeader(ctx context.Context,
136146
func (l *LndRpcChainBridge) GetBlockHeaderByHeight(ctx context.Context,
137147
blockHeight int64) (*wire.BlockHeader, error) {
138148

149+
// Convert to uint32 for cache operations.
150+
height := uint32(blockHeight)
151+
152+
// First, check the cache for the requested block header by height.
153+
if header, ok := l.headerCache.GetByHeight(height); ok {
154+
return &header, nil
155+
}
156+
139157
// First, we need to resolve the block hash at the given height.
140158
blockHash, err := fn.RetryFuncN(
141159
ctx, l.retryConfig, func() (chainhash.Hash, error) {
@@ -171,6 +189,13 @@ func (l *LndRpcChainBridge) GetBlockHeaderByHeight(ctx context.Context,
171189
)
172190
}
173191

192+
// Store the retrieved header in the cache.
193+
err = l.headerCache.Put(height, *header)
194+
if err != nil {
195+
return nil, fmt.Errorf("failed to cache block "+
196+
"header: %w", err)
197+
}
198+
174199
return header, nil
175200
},
176201
)

lndservices/daemon_adapters.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,16 @@ type LndFsmDaemonAdapters struct {
5151
}
5252

5353
// NewLndFsmDaemonAdapters creates a new instance of LndFsmDaemonAdapters.
54-
func NewLndFsmDaemonAdapters(lnd *lndclient.LndServices) *LndFsmDaemonAdapters {
54+
func NewLndFsmDaemonAdapters(lnd *lndclient.LndServices,
55+
headerCache *BlockHeaderCache) *LndFsmDaemonAdapters {
56+
5557
retryConfig := fn.DefaultRetryConfig()
5658

5759
msgTransport := NewLndMsgTransportClient(lnd)
5860

5961
// Initialize the chain bridge without the asset store, as it is not
6062
// needed for the FSM adapters.
61-
chainBridge := NewLndRpcChainBridge(lnd, nil)
63+
chainBridge := NewLndRpcChainBridge(lnd, nil, headerCache)
6264
chainBridge.retryConfig = retryConfig
6365

6466
return &LndFsmDaemonAdapters{

tapcfg/server.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,30 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger,
112112
lndServices,
113113
lndservices.WithPsbtMaxFeeRatio(cfg.Wallet.PsbtMaxFeeRatio),
114114
)
115-
chainBridge := lndservices.NewLndRpcChainBridge(lndServices, assetStore)
115+
116+
// Create a block header cache with default configuration.
117+
headerCache, err := lndservices.NewBlockHeaderCache(
118+
lndservices.DefaultBlockHeaderCacheConfig(),
119+
)
120+
if err != nil {
121+
return nil, fmt.Errorf("failed to create block header cache: "+
122+
"%w", err)
123+
}
124+
125+
chainBridge := lndservices.NewLndRpcChainBridge(
126+
lndServices, assetStore, headerCache,
127+
)
128+
116129
msgTransportClient := lndservices.NewLndMsgTransportClient(lndServices)
117130
lndRouterClient := lndservices.NewLndRouterClient(lndServices)
118131
lndInvoicesClient := lndservices.NewLndInvoicesClient(lndServices)
119132
lndFeatureBitsVerifier := lndservices.NewLndFeatureBitVerifier(
120133
lndServices,
121134
)
122-
lndFsmDaemonAdapters := lndservices.NewLndFsmDaemonAdapters(lndServices)
135+
136+
lndFsmDaemonAdapters := lndservices.NewLndFsmDaemonAdapters(
137+
lndServices, headerCache,
138+
)
123139

124140
uniDB := tapdb.NewTransactionExecutor(
125141
db, func(tx *sql.Tx) tapdb.BaseUniverseStore {

0 commit comments

Comments
 (0)