Skip to content

Commit b732d20

Browse files
committed
tapdb: add proof sync log db queries unit test
1 parent fece1d1 commit b732d20

File tree

1 file changed

+278
-0
lines changed

1 file changed

+278
-0
lines changed

tapdb/universe_federation_test.go

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,284 @@ func TestUniverseFederationCRUD(t *testing.T) {
8787
require.NoError(t, err)
8888
}
8989

90+
// TestFederationProofSyncLogCRUD tests that we can add, modify, and remove
91+
// proof sync log entries from the Universe DB.
92+
func TestFederationProofSyncLogCRUD(t *testing.T) {
93+
t.Parallel()
94+
95+
var (
96+
ctx = context.Background()
97+
dbHandle = NewDbHandle(t)
98+
fedStore = dbHandle.UniverseFederationStore
99+
)
100+
101+
// Populate the database with a random asset, its associated proof, and
102+
// a set of servers.
103+
testAsset, testAnnotatedProof := dbHandle.AddRandomAssetProof(t)
104+
uniProof := dbHandle.AddUniProofLeaf(t, testAsset, testAnnotatedProof)
105+
uniId := universe.NewUniIDFromAsset(*testAsset)
106+
107+
servers := dbHandle.AddRandomServerAddrs(t, 3)
108+
109+
// Designate pending sync status for all servers except the first.
110+
// Make a map set of pending sync servers.
111+
pendingSyncServers := make(map[universe.ServerAddr]struct{})
112+
for i := range servers {
113+
server := servers[i]
114+
if i == 0 {
115+
continue
116+
}
117+
pendingSyncServers[server] = struct{}{}
118+
}
119+
120+
// Add log entries for the first server.
121+
syncServer := servers[0]
122+
123+
// Add push log entry.
124+
_, err := fedStore.UpsertFederationProofSyncLog(
125+
ctx, uniId, uniProof.LeafKey, syncServer,
126+
universe.SyncDirectionPush, universe.ProofSyncStatusComplete,
127+
true,
128+
)
129+
require.NoError(t, err)
130+
131+
// Add pull log entry.
132+
_, err = fedStore.UpsertFederationProofSyncLog(
133+
ctx, uniId, uniProof.LeafKey, syncServer,
134+
universe.SyncDirectionPull, universe.ProofSyncStatusComplete,
135+
true,
136+
)
137+
require.NoError(t, err)
138+
139+
// We've already added log entries for the first server. We will now
140+
// insert new proof sync log entries for the remaining servers.
141+
for _, server := range servers[1:] {
142+
_, err := fedStore.UpsertFederationProofSyncLog(
143+
ctx, uniId, uniProof.LeafKey, server,
144+
universe.SyncDirectionPush,
145+
universe.ProofSyncStatusPending, false,
146+
)
147+
require.NoError(t, err)
148+
}
149+
150+
// Retrieve all sync status pending log entries.
151+
syncDirectionPush := universe.SyncDirectionPush
152+
pendingLogEntries, err := fedStore.FetchPendingProofsSyncLog(
153+
ctx, &syncDirectionPush,
154+
)
155+
require.NoError(t, err)
156+
require.Len(t, pendingLogEntries, 2)
157+
158+
for i := range pendingLogEntries {
159+
entry := pendingLogEntries[i]
160+
require.Equal(
161+
t, universe.ProofSyncStatusPending, entry.SyncStatus,
162+
)
163+
require.Equal(
164+
t, universe.SyncDirectionPush, entry.SyncDirection,
165+
)
166+
require.Equal(t, uniId.String(), entry.UniID.String())
167+
require.Equal(t, int64(0), entry.AttemptCounter)
168+
169+
assertProofSyncLogLeafKey(t, uniProof.LeafKey, entry.LeafKey)
170+
assertProofSyncLogLeaf(t, *uniProof.Leaf, entry.Leaf)
171+
172+
// Check for server address in pending sync server set.
173+
_, ok := pendingSyncServers[entry.ServerAddr]
174+
require.True(t, ok)
175+
}
176+
177+
// Retrieve all push sync status complete log entries.
178+
completePushLogEntries, err := fedStore.QueryFederationProofSyncLog(
179+
ctx, uniId, uniProof.LeafKey, universe.SyncDirectionPush,
180+
universe.ProofSyncStatusComplete,
181+
)
182+
require.NoError(t, err)
183+
184+
// There should only be one complete push log entry.
185+
require.Len(t, completePushLogEntries, 1)
186+
187+
// Check that the complete log entry is as expected.
188+
completePushEntry := completePushLogEntries[0]
189+
190+
require.Equal(t, servers[0], completePushEntry.ServerAddr)
191+
require.Equal(
192+
t, universe.ProofSyncStatusComplete,
193+
completePushEntry.SyncStatus,
194+
)
195+
require.Equal(
196+
t, universe.SyncDirectionPush, completePushEntry.SyncDirection,
197+
)
198+
require.Equal(t, uniId.String(), completePushEntry.UniID.String())
199+
require.Equal(t, int64(0), completePushEntry.AttemptCounter)
200+
201+
assertProofSyncLogLeafKey(
202+
t, uniProof.LeafKey, completePushEntry.LeafKey,
203+
)
204+
assertProofSyncLogLeaf(t, *uniProof.Leaf, completePushEntry.Leaf)
205+
206+
// Retrieve all pull sync status complete log entries.
207+
completePullLogEntries, err := fedStore.QueryFederationProofSyncLog(
208+
ctx, uniId, uniProof.LeafKey, universe.SyncDirectionPull,
209+
universe.ProofSyncStatusComplete,
210+
)
211+
require.NoError(t, err)
212+
213+
// There should only be one complete push log entry.
214+
require.Len(t, completePullLogEntries, 1)
215+
216+
// Check that the complete log entry is as expected.
217+
completePullEntry := completePullLogEntries[0]
218+
219+
require.Equal(t, servers[0], completePullEntry.ServerAddr)
220+
require.Equal(
221+
t, universe.ProofSyncStatusComplete,
222+
completePullEntry.SyncStatus,
223+
)
224+
require.Equal(
225+
t, universe.SyncDirectionPull, completePullEntry.SyncDirection,
226+
)
227+
require.Equal(t, uniId.String(), completePullEntry.UniID.String())
228+
require.Equal(t, int64(0), completePullEntry.AttemptCounter)
229+
230+
assertProofSyncLogLeafKey(
231+
t, uniProof.LeafKey, completePullEntry.LeafKey,
232+
)
233+
assertProofSyncLogLeaf(t, *uniProof.Leaf, completePullEntry.Leaf)
234+
235+
// Increment the attempt counter for one of the pending log entries.
236+
_, err = fedStore.UpsertFederationProofSyncLog(
237+
ctx, uniId, uniProof.LeafKey, servers[1],
238+
universe.SyncDirectionPush, universe.ProofSyncStatusPending,
239+
true,
240+
)
241+
require.NoError(t, err)
242+
243+
// Check that the attempt counter was incremented as expected.
244+
pendingLogEntries, err = fedStore.QueryFederationProofSyncLog(
245+
ctx, uniId, uniProof.LeafKey, universe.SyncDirectionPush,
246+
universe.ProofSyncStatusPending,
247+
)
248+
require.NoError(t, err)
249+
require.Len(t, pendingLogEntries, 2)
250+
251+
for i := range pendingLogEntries {
252+
entry := pendingLogEntries[i]
253+
if entry.ServerAddr == servers[1] {
254+
require.Equal(t, int64(1), entry.AttemptCounter)
255+
} else {
256+
require.Equal(t, int64(0), entry.AttemptCounter)
257+
}
258+
}
259+
260+
// Upsert without incrementing the attempt counter for one of the
261+
// pending log entries.
262+
_, err = fedStore.UpsertFederationProofSyncLog(
263+
ctx, uniId, uniProof.LeafKey, servers[1],
264+
universe.SyncDirectionPush, universe.ProofSyncStatusPending,
265+
false,
266+
)
267+
require.NoError(t, err)
268+
269+
// Check that the attempt counter was not changed as expected.
270+
pendingLogEntries, err = fedStore.QueryFederationProofSyncLog(
271+
ctx, uniId, uniProof.LeafKey, universe.SyncDirectionPush,
272+
universe.ProofSyncStatusPending,
273+
)
274+
require.NoError(t, err)
275+
require.Len(t, pendingLogEntries, 2)
276+
277+
for i := range pendingLogEntries {
278+
entry := pendingLogEntries[i]
279+
if entry.ServerAddr == servers[1] {
280+
require.Equal(t, int64(1), entry.AttemptCounter)
281+
} else {
282+
require.Equal(t, int64(0), entry.AttemptCounter)
283+
}
284+
}
285+
286+
// Set the sync status to complete for one of the pending log entries.
287+
_, err = fedStore.UpsertFederationProofSyncLog(
288+
ctx, uniId, uniProof.LeafKey, servers[1],
289+
universe.SyncDirectionPush, universe.ProofSyncStatusComplete,
290+
false,
291+
)
292+
require.NoError(t, err)
293+
294+
// Check that the sync status was updated as expected.
295+
pendingLogEntries, err = fedStore.QueryFederationProofSyncLog(
296+
ctx, uniId, uniProof.LeafKey, universe.SyncDirectionPush,
297+
universe.ProofSyncStatusPending,
298+
)
299+
require.NoError(t, err)
300+
require.Len(t, pendingLogEntries, 1)
301+
302+
completePushLogEntries, err = fedStore.QueryFederationProofSyncLog(
303+
ctx, uniId, uniProof.LeafKey, universe.SyncDirectionPush,
304+
universe.ProofSyncStatusComplete,
305+
)
306+
require.NoError(t, err)
307+
require.Len(t, completePushLogEntries, 2)
308+
309+
// Delete log entries for one of the servers.
310+
err = fedStore.DeleteProofsSyncLogEntries(ctx, servers[0], servers[1])
311+
require.NoError(t, err)
312+
313+
// Only one log entry should remain and it should have sync status
314+
// pending.
315+
pendingLogEntries, err = fedStore.QueryFederationProofSyncLog(
316+
ctx, uniId, uniProof.LeafKey, universe.SyncDirectionPush,
317+
universe.ProofSyncStatusPending,
318+
)
319+
require.NoError(t, err)
320+
require.Len(t, pendingLogEntries, 1)
321+
322+
// Check that the remaining log entry is as expected.
323+
pendingEntry := pendingLogEntries[0]
324+
require.Equal(t, servers[2], pendingEntry.ServerAddr)
325+
}
326+
327+
// assertProofSyncLogLeafKey asserts that a leaf key derived from a proof sync
328+
// log entry is equal to a given leaf key.
329+
func assertProofSyncLogLeafKey(t *testing.T, actualLeafKey universe.LeafKey,
330+
logLeafKey universe.LeafKey) {
331+
332+
// We can safely ignore the tweaked script key as it is the derivation
333+
// information for the script key. It is only ever known to the owner of
334+
// the asset and is never serialized in a proof
335+
actualLeafKey.ScriptKey.TweakedScriptKey = nil
336+
require.Equal(t, actualLeafKey, logLeafKey)
337+
}
338+
339+
// assertProofSyncLogLeaf asserts that a leaf derived from a proof sync log
340+
// entry is equal to a given universe leaf.
341+
func assertProofSyncLogLeaf(t *testing.T, actualLeaf universe.Leaf,
342+
logLeaf universe.Leaf) {
343+
344+
if actualLeaf.GenesisWithGroup.GroupKey != nil {
345+
// We can safely ignore the group key witness as it is the
346+
// basically just extracted from the asset and won't be relevant
347+
// when parsing the proof.
348+
actualLeaf.GenesisWithGroup.GroupKey.Witness = nil
349+
350+
// We can safely ignore the pre-tweaked group key
351+
// (GroupKey.RawKey) as it is the derivation information for the
352+
// group key. It is only ever known to the owner of the asset
353+
// and is never serialized in a proof.
354+
actualLeaf.GenesisWithGroup.GroupKey.RawKey.PubKey = nil
355+
}
356+
357+
require.Equal(t, actualLeaf.Amt, logLeaf.Amt)
358+
require.Equal(t, actualLeaf.RawProof, logLeaf.RawProof)
359+
require.Equal(t, actualLeaf.GenesisWithGroup, logLeaf.GenesisWithGroup)
360+
361+
// We compare the assets with our custom asset quality function as the
362+
// SplitCommitmentRoot field MS-SMT node types will differ. A computed
363+
// node is derived from the database data whereas the generated asset
364+
// may have a MS-SMT branch node type.
365+
actualLeaf.Asset.DeepEqual(logLeaf.Asset)
366+
}
367+
90368
// TestFederationConfigDefault tests that we're able to fetch the default
91369
// federation config.
92370
func TestFederationConfigDefault(t *testing.T) {

0 commit comments

Comments
 (0)