Skip to content

Commit 94b7573

Browse files
committed
firewalldb: actions mig handle empty RPCParamsJson
If there are no RPCParamsJson set for an action, the value is represented differently in KVDB vs SQL. In the SQL DB, empty RPCParamsJson are represented as nil, while they are represented as an empty array in the KVDB version. Therefore, we need to override the RPCParamsJson in that scenario, so that they are set to the same representation when a KVDB and an SQL action is compared.
1 parent e3a8589 commit 94b7573

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)