diff --git a/config.go b/config.go index e9ce410354..d5f4a90d89 100644 --- a/config.go +++ b/config.go @@ -1819,6 +1819,15 @@ func ValidateConfig(cfg Config, interceptor signal.Interceptor, fileParser, return nil, mkErr("unable to parse node color: %v", err) } + // Validate TrickleDelay and default to 1ms if non-positive to ensure + // the trickle timer can still function. + if cfg.TrickleDelay <= 0 { + srvrLog.Infof("TrickleDelay is non-positive (%v ms), "+ + "setting to 1ms", cfg.TrickleDelay) + + cfg.TrickleDelay = 1 + } + // All good, return the sanitized result. return &cfg, nil } diff --git a/config_test.go b/config_test.go index 7655807491..e287b59db6 100644 --- a/config_test.go +++ b/config_test.go @@ -117,3 +117,59 @@ func TestSupplyEnvValue(t *testing.T) { }) } } + +// TestValidateConfigTrickleDelay tests that the TrickleDelay configuration +// is properly validated and defaulted in ValidateConfig. This test directly +// verifies the validation logic without going through the full ValidateConfig +// function which has many dependencies. +func TestValidateConfigTrickleDelay(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + trickleDelay int + expectedDelay int + }{ + { + name: "zero delay defaults to 1ms", + trickleDelay: 0, + expectedDelay: 1, + }, + { + name: "negative delay defaults to 1ms", + trickleDelay: -1000, + expectedDelay: 1, + }, + { + name: "positive delay unchanged", + trickleDelay: 5000, + expectedDelay: 5000, + }, + { + name: "minimum valid delay (1ms)", + trickleDelay: 1, + expectedDelay: 1, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + // Create a config with the test's TrickleDelay. + cfg := Config{ + TrickleDelay: tc.trickleDelay, + } + + // Simulate the validation logic from ValidateConfig. + if cfg.TrickleDelay <= 0 { + cfg.TrickleDelay = 1 + } + + // Verify the TrickleDelay was set to the expected + // value. + require.Equal( + t, tc.expectedDelay, cfg.TrickleDelay, + "TrickleDelay mismatch", + ) + }) + } +} diff --git a/docs/release-notes/release-notes-0.21.0.md b/docs/release-notes/release-notes-0.21.0.md index 5c8360bc62..89211391ec 100644 --- a/docs/release-notes/release-notes-0.21.0.md +++ b/docs/release-notes/release-notes-0.21.0.md @@ -57,6 +57,12 @@ transactions as locally initiated, even when they were initiated by the remote peer. +- [Fixed a panic in the gossiper](https://github.com/lightningnetwork/lnd/pull/10463) + when `TrickleDelay` is configured with a non-positive value. The configuration + validation now checks `TrickleDelay` at startup and defaults it to 1 + millisecond if set to zero or a negative value, preventing `time.NewTicker` + from panicking. + # New Features - Basic Support for [onion messaging forwarding](https://github.com/lightningnetwork/lnd/pull/9868) @@ -141,7 +147,7 @@ ## Testing -* [Added unit tests for TLV length validation across multiple packages](https://github.com/lightningnetwork/lnd/pull/10249). +* [Added unit tests for TLV length validation across multiple packages](https://github.com/lightningnetwork/lnd/pull/10249). New tests ensure that fixed-size TLV decoders reject malformed records with invalid lengths, including roundtrip tests for Fee, Musig2Nonce, ShortChannelID and Vertex records. diff --git a/sqldb/postgres_fixture.go b/sqldb/postgres_fixture.go index 91b95d66ef..6cae3e0757 100644 --- a/sqldb/postgres_fixture.go +++ b/sqldb/postgres_fixture.go @@ -155,6 +155,10 @@ func NewTestPostgresDB(t testing.TB, fixture *TestPgFixture) *PostgresStore { context.Background(), GetMigrations()), ) + t.Cleanup(func() { + require.NoError(t, store.DB.Close()) + }) + return store } @@ -182,5 +186,9 @@ func NewTestPostgresDBWithVersion(t *testing.T, fixture *TestPgFixture, err = store.ExecuteMigrations(TargetVersion(version)) require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, store.DB.Close()) + }) + return store }