Skip to content

Commit 75a67e5

Browse files
authored
Merge pull request #583 from lightninglabs/federation_db_fixes
tapdb: Federation DB fixes
2 parents e695071 + 4ed7bfe commit 75a67e5

File tree

7 files changed

+136
-28
lines changed

7 files changed

+136
-28
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DROP TABLE IF EXISTS federation_uni_sync_config;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
DROP TABLE IF EXISTS federation_uni_sync_config;
2+
3+
-- This table contains universe (asset/asset group) specific federation sync
4+
-- configuration.
5+
CREATE TABLE IF NOT EXISTS federation_uni_sync_config (
6+
-- namespace is the string representation of the universe identifier, and
7+
-- ensures that there are no duplicate configs.
8+
namespace VARCHAR NOT NULL PRIMARY KEY,
9+
10+
-- This field contains the byte serialized ID of the asset to which this
11+
-- configuration is applicable.
12+
asset_id BLOB CHECK(length(asset_id) = 32) NULL,
13+
14+
-- This field contains the byte serialized compressed group key public key
15+
-- of the asset group to which this configuration is applicable.
16+
group_key BLOB CHECK(LENGTH(group_key) = 33) NULL,
17+
18+
-- This field is an enum representing the proof type stored in the given
19+
-- universe.
20+
proof_type TEXT NOT NULL CHECK(proof_type IN ('issuance', 'transfer')),
21+
22+
-- This field is a boolean that indicates whether or not the given universe
23+
-- should accept remote proof insertion via federation sync.
24+
allow_sync_insert BOOLEAN NOT NULL,
25+
26+
-- This field is a boolean that indicates whether or not the given universe
27+
-- should accept remote proof export via federation sync.
28+
allow_sync_export BOOLEAN NOT NULL,
29+
30+
-- Both the asset ID and group key cannot be null at the same time.
31+
CHECK (
32+
(asset_id IS NOT NULL AND group_key IS NULL) OR
33+
(asset_id IS NULL AND group_key IS NOT NULL)
34+
)
35+
);

tapdb/sqlc/models.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tapdb/sqlc/queries/universe.sql

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -327,20 +327,22 @@ ON CONFLICT(proof_type)
327327

328328
-- name: QueryFederationGlobalSyncConfigs :many
329329
SELECT proof_type, allow_sync_insert, allow_sync_export
330-
FROM federation_global_sync_config;
330+
FROM federation_global_sync_config
331+
ORDER BY proof_type;
331332

332333
-- name: UpsertFederationUniSyncConfig :exec
333334
INSERT INTO federation_uni_sync_config (
334-
asset_id, group_key, proof_type, allow_sync_insert, allow_sync_export
335+
namespace, asset_id, group_key, proof_type, allow_sync_insert, allow_sync_export
335336
)
336337
VALUES(
337-
@asset_id, @group_key, @proof_type, @allow_sync_insert, @allow_sync_export
338+
@namespace, @asset_id, @group_key, @proof_type, @allow_sync_insert, @allow_sync_export
338339
)
339-
ON CONFLICT(asset_id, group_key, proof_type)
340+
ON CONFLICT(namespace)
340341
DO UPDATE SET
341342
allow_sync_insert = @allow_sync_insert,
342343
allow_sync_export = @allow_sync_export;
343344

344345
-- name: QueryFederationUniSyncConfigs :many
345-
SELECT asset_id, group_key, proof_type, allow_sync_insert, allow_sync_export
346-
FROM federation_uni_sync_config;
346+
SELECT namespace, asset_id, group_key, proof_type, allow_sync_insert, allow_sync_export
347+
FROM federation_uni_sync_config
348+
ORDER BY group_key NULLS LAST, asset_id NULLS LAST, proof_type;

tapdb/sqlc/universe.sql.go

Lines changed: 11 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tapdb/universe_federation.go

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,8 @@ func (u *UniverseFederationDB) UpsertFederationSyncConfig(
263263
}
264264

265265
// Upsert universe specific sync configs.
266-
for i := range uniSyncConfigs {
266+
for _, config := range uniSyncConfigs {
267267
var (
268-
config = uniSyncConfigs[i]
269-
270268
uniID = config.UniverseID
271269
groupPubKey []byte
272270
assetIDBytes []byte
@@ -285,6 +283,7 @@ func (u *UniverseFederationDB) UpsertFederationSyncConfig(
285283

286284
err := db.UpsertFederationUniSyncConfig(
287285
ctx, UpsertFedUniSyncConfigParams{
286+
Namespace: uniID.String(),
288287
AssetID: assetIDBytes,
289288
GroupKey: groupPubKey,
290289
ProofType: uniID.ProofType.String(),
@@ -379,20 +378,18 @@ func (u *UniverseFederationDB) QueryFederationSyncConfigs(
379378
[]*universe.FedUniSyncConfig, len(uniDbConfigs),
380379
)
381380

382-
for i := range uniDbConfigs {
383-
conf := uniDbConfigs[i]
384-
381+
for i, config := range uniDbConfigs {
385382
proofType, err := universe.ParseStrProofType(
386-
conf.ProofType,
383+
config.ProofType,
387384
)
388385
if err != nil {
389386
return err
390387
}
391388

392389
// Construct group key public key from bytes.
393390
var pubKey *btcec.PublicKey
394-
if conf.GroupKey != nil {
395-
pubKey, err = btcec.ParsePubKey(conf.GroupKey)
391+
if config.GroupKey != nil {
392+
pubKey, err = btcec.ParsePubKey(config.GroupKey)
396393
if err != nil {
397394
return fmt.Errorf("unable to parse "+
398395
"group key: %v", err)
@@ -401,7 +398,7 @@ func (u *UniverseFederationDB) QueryFederationSyncConfigs(
401398

402399
// Construct asset ID from bytes.
403400
var assetID asset.ID
404-
copy(assetID[:], conf.AssetID)
401+
copy(assetID[:], config.AssetID)
405402

406403
uniID := universe.Identifier{
407404
AssetID: assetID,
@@ -411,8 +408,8 @@ func (u *UniverseFederationDB) QueryFederationSyncConfigs(
411408

412409
uniConfigs[i] = &universe.FedUniSyncConfig{
413410
UniverseID: uniID,
414-
AllowSyncInsert: conf.AllowSyncInsert,
415-
AllowSyncExport: conf.AllowSyncExport,
411+
AllowSyncInsert: config.AllowSyncInsert,
412+
AllowSyncExport: config.AllowSyncExport,
416413
}
417414
}
418415
return nil

tapdb/universe_federation_test.go

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"time"
99

1010
"github.com/lightninglabs/taproot-assets/fn"
11+
"github.com/lightninglabs/taproot-assets/internal/test"
1112
"github.com/lightninglabs/taproot-assets/tapdb/sqlc"
1213
"github.com/lightninglabs/taproot-assets/universe"
1314
"github.com/lightningnetwork/lnd/clock"
@@ -114,9 +115,9 @@ func TestFederationConfigDefault(t *testing.T) {
114115
require.Equal(t, defaultGlobalSyncConfigs, globalConfig)
115116
}
116117

117-
// TestFederationGlobalConfigCRUD tests that we're able to properly update the
118-
// global and local federation configs.
119-
func TestFederationGlobalConfigCRUD(t *testing.T) {
118+
// TestFederationConfigCRUD tests that we're able to properly update the global
119+
// and local federation configs.
120+
func TestFederationConfigCRUD(t *testing.T) {
120121
t.Parallel()
121122

122123
testClock := clock.NewTestClock(time.Now())
@@ -166,7 +167,7 @@ func TestFederationGlobalConfigCRUD(t *testing.T) {
166167
expectedCfgs = append(newGlobalProof, newGlobalTransfer...)
167168
require.Equal(t, expectedCfgs, dbGlobalCfg)
168169

169-
// Finally, we should be able to update them both in the same txn.
170+
// We should be able to update them both in the same txn.
170171
for _, cfg := range expectedCfgs {
171172
cfg.AllowSyncInsert = false
172173
cfg.AllowSyncExport = false
@@ -178,4 +179,70 @@ func TestFederationGlobalConfigCRUD(t *testing.T) {
178179
dbGlobalCfg, _, err = fedDB.QueryFederationSyncConfigs(ctx)
179180
require.NoError(t, err)
180181
require.Equal(t, expectedCfgs, dbGlobalCfg)
182+
183+
// Finally, if we insert the current config again, we should see no
184+
// change in the returned configs.
185+
singleCfg := fn.MakeSlice(dbGlobalCfg[0])
186+
err = fedDB.UpsertFederationSyncConfig(ctx, singleCfg, nil)
187+
require.NoError(t, err)
188+
189+
dbGlobalCfg, _, err = fedDB.QueryFederationSyncConfigs(ctx)
190+
require.NoError(t, err)
191+
require.Equal(t, expectedCfgs, dbGlobalCfg)
192+
193+
// Now, create configs for specific assets.
194+
randAssetIDBytes := test.RandBytes(32)
195+
randGroupKey := test.RandPubKey(t)
196+
groupCfg := &universe.FedUniSyncConfig{
197+
UniverseID: universe.Identifier{
198+
GroupKey: randGroupKey,
199+
ProofType: universe.ProofTypeIssuance,
200+
},
201+
AllowSyncInsert: true,
202+
AllowSyncExport: false,
203+
}
204+
assetCfg := &universe.FedUniSyncConfig{
205+
UniverseID: universe.Identifier{
206+
ProofType: universe.ProofTypeTransfer,
207+
},
208+
AllowSyncInsert: false,
209+
AllowSyncExport: true,
210+
}
211+
copy(assetCfg.UniverseID.AssetID[:], randAssetIDBytes)
212+
213+
// Before insertion, there should be no asset-specific configs.
214+
_, dbLocalCfg, err := fedDB.QueryFederationSyncConfigs(ctx)
215+
require.NoError(t, err)
216+
require.Empty(t, dbLocalCfg)
217+
218+
// Next, store the asset configs and verify that we get the same configs
219+
// back from a query.
220+
localCfg := fn.MakeSlice(groupCfg, assetCfg)
221+
err = fedDB.UpsertFederationSyncConfig(ctx, nil, localCfg)
222+
require.NoError(t, err)
223+
224+
_, dbLocalCfg, err = fedDB.QueryFederationSyncConfigs(ctx)
225+
require.NoError(t, err)
226+
require.Equal(t, localCfg, dbLocalCfg)
227+
228+
// We should be able to overwrite a stored config.
229+
groupNewCfg := &universe.FedUniSyncConfig{
230+
UniverseID: universe.Identifier{
231+
GroupKey: randGroupKey,
232+
ProofType: universe.ProofTypeIssuance,
233+
},
234+
AllowSyncInsert: true,
235+
AllowSyncExport: true,
236+
}
237+
err = fedDB.UpsertFederationSyncConfig(
238+
ctx, nil, fn.MakeSlice(groupNewCfg),
239+
)
240+
require.NoError(t, err)
241+
242+
_, dbLocalCfg, err = fedDB.QueryFederationSyncConfigs(ctx)
243+
require.NoError(t, err)
244+
require.NotEqual(t, localCfg, dbLocalCfg)
245+
246+
localCfg = fn.MakeSlice(groupNewCfg, assetCfg)
247+
require.Equal(t, localCfg, dbLocalCfg)
181248
}

0 commit comments

Comments
 (0)