Skip to content

Commit 48da1b0

Browse files
authored
Merge pull request #1156 from ViktorT-11/2025-10-action-mig-handle-empty-RPCParamsJson
[sql-55] firewalldb: actions mig handle empty RPCParamsJson
2 parents 367bfa5 + 94b7573 commit 48da1b0

File tree

5 files changed

+69
-0
lines changed

5 files changed

+69
-0
lines changed

firewalldb/sql_migration.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,6 +1131,11 @@ func validateMigratedAction(ctx context.Context, sqlTx SQLQueries,
11311131
// the SQL action has the full 8 bytes set.
11321132
overrideMacRootKeyID(migAction)
11331133

1134+
// If there are no RPCParamsJson set for the actions, that's represented
1135+
// differently in KVDB vs SQL. We therefore override the RPCParamsJson
1136+
// so that both actions represent them in the same way.
1137+
overrideRPCParamsJson(kvAction, migAction)
1138+
11341139
// Now that we have overridden the fields that are expected to differ
11351140
// between the original KVDB action and the migrated SQL action, we can
11361141
// compare the two actions to ensure that they match.
@@ -1606,3 +1611,14 @@ func overrideMacRootKeyID(action *Action) {
16061611
action.MacaroonRootKeyID = fn.Some(last32)
16071612
})
16081613
}
1614+
1615+
// overrideRPCParamsJson overrides the SQL action's RPCParamsJson in case they
1616+
// are empty for the kvAction. In the SQL DB, empty RPCParamsJson are
1617+
// represented as nil, while they are represented as an empty array in the
1618+
// KVDB version. Therefore, this function overrides the SQL action's
1619+
// RPCParamsJson to an empty array if they are nil.
1620+
func overrideRPCParamsJson(kvAction *Action, sqlAction *Action) {
1621+
if len(kvAction.RPCParamsJson) == 0 && sqlAction.RPCParamsJson == nil {
1622+
sqlAction.RPCParamsJson = []byte{}
1623+
}
1624+
}

firewalldb/sql_migration_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,10 @@ func TestFirewallDBMigration(t *testing.T) {
474474
name: "action with no session or account",
475475
populateDB: actionNoSessionOrAccount,
476476
},
477+
{
478+
name: "action with empty RPCParamsJson",
479+
populateDB: actionEmptyRPCParamsJson,
480+
},
477481
{
478482
name: "action with session but no account",
479483
populateDB: actionWithSessionNoAccount,
@@ -1268,6 +1272,32 @@ func actionNoSessionOrAccount(t *testing.T, ctx context.Context,
12681272
}
12691273
}
12701274

1275+
// actionEmptyRPCParamsJson adds an action which has no RPCParamsJson set.
1276+
func actionEmptyRPCParamsJson(t *testing.T, ctx context.Context,
1277+
boltDB *BoltDB, _ session.Store, _ accounts.Store,
1278+
rStore *rootKeyMockStore) *expectedResult {
1279+
1280+
// As the action is not linked to any session, we add a random root
1281+
// key which we use as the macaroon identifier for the action.
1282+
// This simulates how similar actions would have been created in
1283+
// production.
1284+
rootKey := rStore.addRandomRootKey()
1285+
1286+
actionReq := testActionReq
1287+
actionReq.MacaroonRootKeyID = fn.Some(rootKey)
1288+
actionReq.SessionID = fn.None[session.ID]()
1289+
actionReq.AccountID = fn.None[accounts.AccountID]()
1290+
actionReq.RPCParamsJson = []byte{}
1291+
1292+
action := addAction(t, ctx, boltDB, &actionReq)
1293+
1294+
return &expectedResult{
1295+
kvEntries: []*kvEntry{},
1296+
privPairs: make(privacyPairs),
1297+
actions: []*Action{action},
1298+
}
1299+
}
1300+
12711301
// actionWithSessionNoAccount adds an action which is linked a session but no
12721302
// account.
12731303
func actionWithSessionNoAccount(t *testing.T, ctx context.Context,
@@ -1967,6 +1997,15 @@ func addAction(t *testing.T, ctx context.Context, boltDB *BoltDB,
19671997
action.AccountID = actionReq.AccountID
19681998
action.MacaroonRootKeyID = actionReq.MacaroonRootKeyID
19691999

2000+
// In case the actionReq's RPCParamsJson wasn't set, we need to set the
2001+
// expected action's RPCParamsJson to nil for Sqlite tests as that's
2002+
// how such RPCParamsJson are represented in the Sqlite database, which
2003+
// the returned expected action should reflect. Note that for Postgres
2004+
// dbs, this param is stored as an empty array and not nil.
2005+
if len(actionReq.RPCParamsJson) == 0 && isSqlite {
2006+
action.RPCParamsJson = nil
2007+
}
2008+
19702009
return action
19712010
}
19722011

@@ -2155,6 +2194,11 @@ func randomBytes(n int) []byte {
21552194
// Keys are random strings like "key1", "key2"...
21562195
// Values are random ints, floats, or strings.
21572196
func randomJSON(n int) (string, error) {
2197+
// When 0 pairs are requested, we can return immediately.
2198+
if n <= 0 {
2199+
return "", nil
2200+
}
2201+
21582202
obj := make(map[string]any, n)
21592203
for i := 0; i < n; i++ {
21602204
key := fmt.Sprintf("key%d", i+1)

firewalldb/test_kvdb.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import (
1212
"github.com/stretchr/testify/require"
1313
)
1414

15+
// isSqlite is true if the test_db_sqlite build flag is set.
16+
var isSqlite = false
17+
1518
// NewTestDB is a helper function that creates an BBolt database for testing.
1619
func NewTestDB(t *testing.T, clock clock.Clock) FirewallDBs {
1720
return NewTestDBFromPath(t, t.TempDir(), clock)

firewalldb/test_postgres.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import (
99
"github.com/lightningnetwork/lnd/clock"
1010
)
1111

12+
// isSqlite is true if the test_db_sqlite build flag is set.
13+
var isSqlite = false
14+
1215
// NewTestDB is a helper function that creates an BBolt database for testing.
1316
func NewTestDB(t *testing.T, clock clock.Clock) FirewallDBs {
1417
return createStore(t, db.NewTestPostgresDB(t).BaseDB, clock)

firewalldb/test_sqlite.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import (
99
"github.com/lightningnetwork/lnd/clock"
1010
)
1111

12+
// isSqlite is true if the test_db_sqlite build flag is set.
13+
var isSqlite = true
14+
1215
// NewTestDB is a helper function that creates an BBolt database for testing.
1316
func NewTestDB(t *testing.T, clock clock.Clock) FirewallDBs {
1417
return createStore(t, db.NewTestSqliteDB(t).BaseDB, clock)

0 commit comments

Comments
 (0)