What changed, and why it matters
This commit fixes a regression in LND's new v2 SQL database layer. The v2 code accidentally used a 25-connection pool for SQLite, matching PostgreSQL defaults, instead of the v1 value of 2. SQLite handles writes poorly with many concurrent connections, so this change restores the low default to reduce lock contention and resource use. It is a reliability/performance fix, not a security vulnerability that can be directly exploited by an attacker.
Treat as a normal reliability/performance fix. No urgent security action required. Users running v2 SQLite stores should upgrade to avoid lock contention and degraded performance under load.
Security signals we found
No security-relevant signals in diff: no input handling, crypto, auth, or network changes
Fix is framed by author as performance/reliability regression, not security
Change reduces resource contention and operational instability
Evidence from the diff
The patch restores DefaultSqliteMaxConns = 2 in sqldb/v2, adds a SqliteConfig.MaxConns() helper that returns the caller override or the safe default, wires NewSqliteStore to use cfg.MaxConns(), renames the generic defaultMaxConns to DefaultPostgresMaxConns for Postgres use, and adds a unit test. The regression caused SQLite to open up to 25 connections, which is hostile to SQLite’s single-writer concurrency model and can increase busy_timeout/lock contention. There is no evidence in the commit of an exploitable security flaw such as injection, auth bypass, or memory corruption.
Changed components
sqldb/v2/config.gosqldb/v2/sqlite.gosqldb/v2/postgres.gosqldb/v2/config_test.goInspect captured patch +62 / −9
diff --git a/sqldb/v2/config.go b/sqldb/v2/config.go
index 5d4100a..d0d3351 100644
--- a/sqldb/v2/config.go
+++ b/sqldb/v2/config.go
@@ -7,12 +7,18 @@ import (
)
const (
- // defaultMaxConns is the number of permitted active and idle
+ // DefaultSqliteMaxConns is the default number of maximum open
+ // connections for SQLite. SQLite only supports a single writer, so a
+ // low default reduces contention on the busy_timeout and limits
+ // resource usage.
+ DefaultSqliteMaxConns = 2
+
+ // DefaultPostgresMaxConns is the number of permitted active and idle
// connections. We want to limit this so it isn't unlimited. We use the
// same value for the number of idle connections as, this can speed up
// queries given a new connection doesn't need to be established each
// time.
- defaultMaxConns = 25
+ DefaultPostgresMaxConns = 25
// defaultMaxIdleConns is the number of permitted idle connections.
defaultMaxIdleConns = 6
@@ -62,6 +68,15 @@ func (s *SqliteConfig) busyTimeoutMs() int64 {
return DefaultSqliteBusyTimeout.Milliseconds()
}
+// MaxConns returns the effective maximum number of SQLite connections.
+func (s *SqliteConfig) MaxConns() int {
+ if s.MaxConnections > 0 {
+ return s.MaxConnections
+ }
+
+ return DefaultSqliteMaxConns
+}
+
// Validate checks that the SqliteConfig values are valid.
func (p *SqliteConfig) Validate() error {
if err := p.QueryConfig.Validate(true); err != nil {
diff --git a/sqldb/v2/config_test.go b/sqldb/v2/config_test.go
new file mode 100644
index 0000000..dcf8666
--- /dev/null
+++ b/sqldb/v2/config_test.go
@@ -0,0 +1,43 @@
+package sqldb
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+// TestSqliteConfigMaxConns verifies that SQLite keeps the low default
+// connection limit unless the caller overrides it explicitly.
+func TestSqliteConfigMaxConns(t *testing.T) {
+ t.Parallel()
+
+ testCases := []struct {
+ name string
+ maxConns int
+ expectedConn int
+ }{
+ {
+ name: "default limit",
+ expectedConn: DefaultSqliteMaxConns,
+ },
+ {
+ name: "explicit limit",
+ maxConns: 7,
+ expectedConn: 7,
+ },
+ }
+
+ for _, testCase := range testCases {
+ testCase := testCase
+
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+
+ cfg := &SqliteConfig{
+ MaxConnections: testCase.maxConns,
+ }
+
+ require.Equal(t, testCase.expectedConn, cfg.MaxConns())
+ })
+ }
+}
diff --git a/sqldb/v2/postgres.go b/sqldb/v2/postgres.go
index d6b4912..e3753dc 100644
--- a/sqldb/v2/postgres.go
+++ b/sqldb/v2/postgres.go
@@ -168,7 +168,7 @@ func NewPostgresStore(cfg *PostgresConfig) (*PostgresStore, error) {
err)
}
- maxConns := defaultMaxConns
+ maxConns := DefaultPostgresMaxConns
if cfg.MaxOpenConnections > 0 {
maxConns = cfg.MaxOpenConnections
}
diff --git a/sqldb/v2/sqlite.go b/sqldb/v2/sqlite.go
index b988a72..f53685f 100644
--- a/sqldb/v2/sqlite.go
+++ b/sqldb/v2/sqlite.go
@@ -136,11 +136,6 @@ func NewSqliteStore(cfg *SqliteConfig, dbPath string) (*SqliteStore, error) {
err)
}
- maxConns := defaultMaxConns
- if cfg.MaxConnections > 0 {
- maxConns = cfg.MaxConnections
- }
-
maxIdleConns := defaultMaxIdleConns
if cfg.MaxIdleConnections > 0 {
maxIdleConns = cfg.MaxIdleConnections
@@ -151,7 +146,7 @@ func NewSqliteStore(cfg *SqliteConfig, dbPath string) (*SqliteStore, error) {
connMaxLifetime = cfg.ConnMaxLifetime
}
- db.SetMaxOpenConns(maxConns)
+ db.SetMaxOpenConns(cfg.MaxConns())
db.SetMaxIdleConns(maxIdleConns)
db.SetConnMaxLifetime(connMaxLifetime)
Why this scored 25/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.