Skip to content

Commit 0648c83

Browse files
committed
itest: cover postgres network separation
1 parent 943bb67 commit 0648c83

3 files changed

Lines changed: 81 additions & 0 deletions

File tree

itest/list_on_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,10 @@ var allTestCases = []*lntest.TestCase{
791791
Name: "estimate on chain fee auto selected inputs",
792792
TestFunc: testEstimateOnChainFeeAutoSelectedInputs,
793793
},
794+
{
795+
Name: "postgres network separation",
796+
TestFunc: testPostgresNetworkSeparation,
797+
},
794798
}
795799

796800
// appendPrefixed is used to add a prefix to each test name in the subtests
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package itest
2+
3+
import (
4+
"github.com/btcsuite/btcd/chaincfg"
5+
"github.com/lightningnetwork/lnd/chainparams"
6+
"github.com/lightningnetwork/lnd/lntest"
7+
"github.com/lightningnetwork/lnd/sqldb"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
const networkMismatchErr = "database network mismatch"
12+
13+
// testPostgresNetworkSeparation verifies that lnd refuses to start when the
14+
// active Bitcoin network does not match the network stored in the postgres
15+
// chain_params table. This prevents silent data corruption that would occur if
16+
// a user accidentally reused the same postgres DSN across different networks.
17+
//
18+
// The test flow is:
19+
// 1. Start lnd on regtest with native SQL enabled → first startup writes
20+
// "regtest" into the chain_params table.
21+
// 2. Stop the node.
22+
// 3. Restart lnd with the same postgres DSN but switch to simnet → lnd must
23+
// detect the network mismatch and exit with an error.
24+
func testPostgresNetworkSeparation(ht *lntest.HarnessTest) {
25+
// This test is only relevant for the postgres backend with native SQL.
26+
if !ht.IsPostgresBackend() {
27+
ht.Skip("node not running with postgres backend")
28+
}
29+
30+
alice := ht.NewNodeWithCoins("Alice", []string{"--db.use-native-sql"})
31+
32+
// Confirm the node started successfully on the initial network.
33+
require.NoError(ht, alice.Stop())
34+
35+
// Assert the mismatch condition directly at the store layer so this
36+
// test can't pass due to an unrelated startup failure.
37+
store, err := sqldb.NewPostgresStore(&sqldb.PostgresConfig{
38+
Dsn: alice.Cfg.PostgresDsn,
39+
Timeout: defaultTimeout,
40+
})
41+
require.NoError(ht, err)
42+
defer store.Close()
43+
44+
chainParamsStore := chainparams.NewStore(store.GetBaseDB())
45+
err = chainParamsStore.ValidateNetwork(
46+
ht.Context(), &chaincfg.SimNetParams,
47+
)
48+
require.ErrorContains(ht, err, networkMismatchErr)
49+
50+
// Now restart alice but override the network to simnet. The DSN still
51+
// points at the same postgres database, so lnd should detect the
52+
// mismatch and refuse to start.
53+
//
54+
// We append --bitcoin.simnet and remove --bitcoin.regtest by
55+
// overriding via ExtraArgs (ExtraArgs are appended last and take
56+
// precedence over the generated args).
57+
alice.Cfg.NetParams = &chaincfg.SimNetParams
58+
alice.SetExtraArgs([]string{
59+
"--db.use-native-sql",
60+
"--bitcoin.simnet",
61+
"--bitcoin.node=neutrino",
62+
})
63+
64+
// StartLndCmd launches the process without waiting for it to become
65+
// ready, which is what we want since we expect it to exit early.
66+
require.NoError(ht, alice.StartLndCmd(ht.Context()))
67+
68+
// The process should exit with a non-zero status due to the network
69+
// mismatch error returned by ValidateNetwork.
70+
require.ErrorContains(ht, alice.WaitForProcessExit(), "exit status 1")
71+
}

lntest/harness.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,6 +1438,12 @@ func (h *HarnessTest) IsNeutrinoBackend() bool {
14381438
return h.manager.chainBackend.Name() == NeutrinoBackendName
14391439
}
14401440

1441+
// IsPostgresBackend returns true if the test harness is configured to use a
1442+
// Postgres database backend.
1443+
func (h *HarnessTest) IsPostgresBackend() bool {
1444+
return h.manager.dbBackend == node.BackendPostgres
1445+
}
1446+
14411447
// fundCoins attempts to send amt satoshis from the internal mining node to the
14421448
// targeted lightning node. The confirmed boolean indicates whether the
14431449
// transaction that pays to the target should confirm. For neutrino backend,

0 commit comments

Comments
 (0)