rpcserver: wire ForwardingLog into router backend
What changed, and why it matters
This commit is a routine plumbing change: it wires a new configuration option (fwd-history-delete-batch-size) through LND's RPC server so operators can tune how many forwarding history records are deleted in each database batch. It does not fix a vulnerability or change any security boundary; it simply exposes an existing internal batch size as a user-configurable setting and adds a startup warning if the value is set too high.
No security action required. Treat as a normal feature/configuration commit. Operators may review the new fwd-history-delete-batch-size option if they run resource-constrained nodes and use DeleteForwardingHistory.
Security signals we found
No security-relevant behavior change: only a tunable batch size is exposed
Adds a startup clamp/warning for values exceeding MaxResponseEvents, which is a defensive configuration guard
No new RPC permissions, authentication, or authorization changes
No memory safety, cryptographic, or consensus changes
Evidence from the diff
The change completes dependency injection of ForwardingLog and FwdHistoryDeleteBatchSize from the main server config into the routerrpc RouterBackend, then uses that value in DeleteForwardingHistory instead of the hard-coded 10,000. A new config option is declared in Config, defaulted to 10,000, clamped to channeldb.MaxResponseEvents (50,000) with a warning, and documented in sample-lnd.conf. No logic for the actual deletion or access control is modified.
Changed components
lnrpc/routerrpc/router_backend.golnrpc/routerrpc/router_server.gorpcserver.goconfig.gosample-lnd.confInspect captured patch +35 / −3
diff --git a/config.go b/config.go
index d5f4a90..aaf748b 100644
--- a/config.go
+++ b/config.go
@@ -212,6 +212,10 @@ const (
// commitment.
defaultChannelCommitBatchSize = 10
+ // defaultFwdHistoryDeleteBatchSize is the default number of forwarding
+ // events deleted per database transaction when purging history.
+ defaultFwdHistoryDeleteBatchSize = 10_000
+
// defaultCoinSelectionStrategy is the coin selection strategy that is
// used by default to fund transactions.
defaultCoinSelectionStrategy = "largest"
@@ -418,6 +422,8 @@ type Config struct {
ChannelCommitBatchSize uint32 `long:"channel-commit-batch-size" description:"The maximum number of channel state updates that is accumulated before signing a new commitment."`
+ FwdHistoryDeleteBatchSize int `long:"fwd-history-delete-batch-size" description:"The number of forwarding events deleted per database transaction when running deletefwdhistory. Lower this on resource-constrained nodes to reduce lock contention (max: 50000)."`
+
KeepFailedPaymentAttempts bool `long:"keep-failed-payment-attempts" description:"Keeps persistent record of all failed payment attempts for successfully settled payments."`
StoreFinalHtlcResolutions bool `long:"store-final-htlc-resolutions" description:"Persistently store the final resolution of incoming htlcs."`
@@ -755,6 +761,7 @@ func DefaultConfig() Config {
ChannelCommitInterval: defaultChannelCommitInterval,
PendingCommitInterval: defaultPendingCommitInterval,
ChannelCommitBatchSize: defaultChannelCommitBatchSize,
+ FwdHistoryDeleteBatchSize: defaultFwdHistoryDeleteBatchSize,
CoinSelectionStrategy: defaultCoinSelectionStrategy,
KeepFailedPaymentAttempts: defaultKeepFailedPaymentAttempts,
RemoteSigner: &lncfg.RemoteSigner{
@@ -1722,6 +1729,19 @@ func ValidateConfig(cfg Config, interceptor signal.Interceptor, fileParser,
maxPendingCommitInterval)
}
+ // Warn and clamp fwd-history-delete-batch-size if it exceeds the DB
+ // layer maximum. The DB silently clamps anyway, but surfacing this at
+ // startup gives the operator immediate feedback that their configured
+ // value is not being honoured.
+ if cfg.FwdHistoryDeleteBatchSize > channeldb.MaxResponseEvents {
+ ltndLog.Warnf("fwd-history-delete-batch-size=%d exceeds "+
+ "maximum (%d), clamping to maximum",
+ cfg.FwdHistoryDeleteBatchSize,
+ channeldb.MaxResponseEvents)
+
+ cfg.FwdHistoryDeleteBatchSize = channeldb.MaxResponseEvents
+ }
+
if err := cfg.Gossip.Parse(); err != nil {
return nil, mkErr("error parsing gossip syncer: %v", err)
}
diff --git a/lnrpc/routerrpc/router_backend.go b/lnrpc/routerrpc/router_backend.go
index ca05606..3bb4d82 100644
--- a/lnrpc/routerrpc/router_backend.go
+++ b/lnrpc/routerrpc/router_backend.go
@@ -138,6 +138,12 @@ type RouterBackend struct {
// have before it can be deleted. If zero the handler defaults to 1
// hour.
MinForwardingHistoryAge time.Duration
+
+ // FwdHistoryDeleteBatchSize is the number of forwarding events deleted
+ // per database transaction. If zero the DB layer applies its own
+ // default (10 000). Exposed here so operators can tune the value via
+ // lnd.conf on resource-constrained nodes.
+ FwdHistoryDeleteBatchSize int
}
// ForwardingLogDB defines the interface for forwarding log database operations.
diff --git a/lnrpc/routerrpc/router_server.go b/lnrpc/routerrpc/router_server.go
index 40201cb..e3ac207 100644
--- a/lnrpc/routerrpc/router_server.go
+++ b/lnrpc/routerrpc/router_server.go
@@ -2036,9 +2036,7 @@ func (s *Server) DeleteForwardingHistory(ctx context.Context,
minAge, deleteBeforeTime, now)
}
- // Default batch size is 10000, will be replaces by a config value in
- // later commit.
- batchSize := 10000
+ batchSize := s.cfg.RouterBackend.FwdHistoryDeleteBatchSize
log.Infof("DeleteForwardingHistory: deleting events at or before %v "+
"with batch size %d", deleteBeforeTime, batchSize)
diff --git a/rpcserver.go b/rpcserver.go
index 816635b..ded2bba 100644
--- a/rpcserver.go
+++ b/rpcserver.go
@@ -785,6 +785,9 @@ func (r *rpcServer) addDeps(ctx context.Context, s *server,
ShouldSetExpAccountability: func() bool {
return !s.cfg.ProtocolOptions.NoExpAccountability()
},
+ ForwardingLog: s.miscDB.ForwardingLog(),
+ MinForwardingHistoryAge: s.cfg.Dev.GetMinFwdHistoryAge(),
+ FwdHistoryDeleteBatchSize: s.cfg.FwdHistoryDeleteBatchSize,
}
genInvoiceFeatures := func() *lnwire.FeatureVector {
diff --git a/sample-lnd.conf b/sample-lnd.conf
index 6f3d849..f3a9c51 100644
--- a/sample-lnd.conf
+++ b/sample-lnd.conf
@@ -405,6 +405,11 @@
; a new commitment.
; channel-commit-batch-size=10
+; The number of forwarding events deleted per database transaction when running
+; deletefwdhistory. Lower this on resource-constrained nodes (e.g. Raspberry Pi)
+; to reduce lock contention. Maximum value is 50000.
+; fwd-history-delete-batch-size=10000
+
; Keeps persistent record of all failed payment attempts for successfully
; settled payments.
; keep-failed-payment-attempts=false
Why this scored 20/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.