What changed, and why it matters
This commit only adds new unit tests for an existing database network-validation feature. It does not change any production code, fix a bug, or alter behavior users would see. There is no security issue here.
No action required; this is a test-only change. Reviewers may optionally verify the tests accurately describe the intended production behavior of ValidateNetwork.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit introduces three test-only files under chainparams/: store_test.go with five test cases for Store.ValidateNetwork, plus test_postgres.go and test_sqlite.go providing database fixtures. The tests exercise existing behavior: persisting the first network, rejecting mismatched networks, idempotent same-network calls, normalizing testnet aliases, and rejecting empty or nil params. No production logic is modified.
Changed components
chainparams/store_test.gochainparams/test_postgres.gochainparams/test_sqlite.goInspect captured patch +122 / −0
diff --git a/chainparams/store_test.go b/chainparams/store_test.go
new file mode 100644
index 0000000..bc0f45b
--- /dev/null
+++ b/chainparams/store_test.go
@@ -0,0 +1,87 @@
+//go:build test_db_postgres || test_db_sqlite
+
+package chainparams
+
+import (
+ "testing"
+
+ "github.com/btcsuite/btcd/chaincfg"
+ "github.com/stretchr/testify/require"
+)
+
+// TestValidateNetworkMismatch verifies that ValidateNetwork persists the first
+// network and fails when a different network is used later.
+func TestValidateNetworkMismatch(t *testing.T) {
+ t.Parallel()
+
+ store := NewStore(newTestDB(t))
+
+ // First call: persists regtest into the store.
+ err := store.ValidateNetwork(t.Context(), &chaincfg.RegressionNetParams)
+ require.NoError(t, err)
+
+ // Second call: a different network — must fail with ErrNetworkMismatch.
+ err = store.ValidateNetwork(t.Context(), &chaincfg.SimNetParams)
+ require.ErrorIs(t, err, ErrNetworkMismatch)
+}
+
+// TestValidateNetworkSameNetwork verifies that ValidateNetwork succeeds when
+// called repeatedly with the same network (idempotent-match path).
+func TestValidateNetworkSameNetwork(t *testing.T) {
+ t.Parallel()
+
+ store := NewStore(newTestDB(t))
+
+ // First call: persists the network.
+ err := store.ValidateNetwork(t.Context(), &chaincfg.RegressionNetParams)
+ require.NoError(t, err)
+
+ // Second call: same network again — reads the stored value and must
+ // succeed (idempotent match).
+ err = store.ValidateNetwork(t.Context(), &chaincfg.RegressionNetParams)
+ require.NoError(t, err)
+}
+
+// TestValidateNetworkNormalizesTestnet verifies that network aliases collapse
+// to the same persisted value.
+func TestValidateNetworkNormalizesTestnet(t *testing.T) {
+ t.Parallel()
+
+ store := NewStore(newTestDB(t))
+
+ // First call: persists canonical testnet3 parameters.
+ err := store.ValidateNetwork(t.Context(), &chaincfg.TestNet3Params)
+ require.NoError(t, err)
+
+ // Second call: same logical network, different Name field — still
+ // matches after normalization (not ErrNetworkMismatch).
+ testnetAlias := chaincfg.TestNet3Params
+ testnetAlias.Name = "testnet"
+
+ err = store.ValidateNetwork(t.Context(), &testnetAlias)
+ require.NoError(t, err)
+}
+
+// TestValidateNetworkRejectsEmptyName verifies that malformed network params
+// are rejected before touching the database.
+func TestValidateNetworkRejectsEmptyName(t *testing.T) {
+ t.Parallel()
+
+ store := NewStore(newTestDB(t))
+
+ // Empty Params.Name — rejected before any database read or write.
+ err := store.ValidateNetwork(t.Context(), &chaincfg.Params{})
+ require.ErrorContains(t, err, "must define a network")
+}
+
+// TestValidateNetworkRejectsNilParams verifies that callers provide network
+// parameters.
+func TestValidateNetworkRejectsNilParams(t *testing.T) {
+ t.Parallel()
+
+ store := NewStore(newTestDB(t))
+
+ // Nil params — rejected before any database read or write.
+ err := store.ValidateNetwork(t.Context(), nil)
+ require.ErrorContains(t, err, "must not be nil")
+}
diff --git a/chainparams/test_postgres.go b/chainparams/test_postgres.go
new file mode 100644
index 0000000..698f150
--- /dev/null
+++ b/chainparams/test_postgres.go
@@ -0,0 +1,21 @@
+//go:build test_db_postgres && !test_db_sqlite
+
+package chainparams
+
+import (
+ "testing"
+
+ "github.com/lightningnetwork/lnd/sqldb"
+)
+
+// newTestDB creates a Postgres-backed BaseDB for use in unit tests.
+func newTestDB(t testing.TB) *sqldb.BaseDB {
+ pgFixture := sqldb.NewTestPgFixture(
+ t, sqldb.DefaultPostgresFixtureLifetime,
+ )
+ t.Cleanup(func() {
+ pgFixture.TearDown(t)
+ })
+
+ return sqldb.NewTestPostgresDB(t, pgFixture).GetBaseDB()
+}
diff --git a/chainparams/test_sqlite.go b/chainparams/test_sqlite.go
new file mode 100644
index 0000000..998b57d
--- /dev/null
+++ b/chainparams/test_sqlite.go
@@ -0,0 +1,14 @@
+//go:build !test_db_postgres && test_db_sqlite
+
+package chainparams
+
+import (
+ "testing"
+
+ "github.com/lightningnetwork/lnd/sqldb"
+)
+
+// newTestDB creates a SQLite-backed BaseDB for use in unit tests.
+func newTestDB(t testing.TB) *sqldb.BaseDB {
+ return sqldb.NewTestSqliteDB(t).GetBaseDB()
+}
Why this scored 15/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.