keys_test.mx raw
1 package index
2
3 import (
4 "bytes"
5 "testing"
6
7 "git.smesh.lol/morly/pkg/store/serial"
8 )
9
10 func ixHash8(fill byte) (b []byte) {
11 b = []byte{:serial.HashLen}
12 for i := range b {
13 b[i] = fill
14 }
15 return
16 }
17
18 func ixHash32(fill byte) (b []byte) {
19 b = []byte{:32}
20 for i := range b {
21 b[i] = fill
22 }
23 return
24 }
25
26 // TestKeyLengthConstants ties each declared key length to the length the
27 // builder actually produces. A drift between the two corrupts every fixed
28 // width record read.
29 func TestKeyLengthConstants(t *testing.T) {
30 ih := ixHash8(0x11)
31 ph := ixHash8(0x22)
32 if len(MakeEid(ih, 9)) != EidKeyLen {
33 t.Fatal("EidKeyLen")
34 }
35 if len(MakeEidPrefix(ih)) != 3+serial.HashLen {
36 t.Fatal("MakeEidPrefix length")
37 }
38 if len(MakeSei(9)) != SeiKeyLen {
39 t.Fatal("SeiKeyLen")
40 }
41 if len(MakeCA(7, 9)) != CAKeyLen {
42 t.Fatal("CAKeyLen")
43 }
44 if len(MakeExp(7, 9)) != ExpKeyLen {
45 t.Fatal("ExpKeyLen")
46 }
47 if len(MakeKC(7, 7, 9)) != KCKeyLen {
48 t.Fatal("KCKeyLen")
49 }
50 if len(MakePC(ph, 7, 9)) != PCKeyLen {
51 t.Fatal("PCKeyLen")
52 }
53 if len(MakeKPC(7, ph, 7, 9)) != KPCKeyLen {
54 t.Fatal("KPCKeyLen")
55 }
56 if len(MakeTC('t', ph, 7, 9)) != TCKeyLen {
57 t.Fatal("TCKeyLen")
58 }
59 if len(MakeTKC(7, 't', ph, 7, 9)) != TKCKeyLen {
60 t.Fatal("TKCKeyLen")
61 }
62 if len(MakeTPC(ph, 't', ph, 7, 9)) != TPCKeyLen {
63 t.Fatal("TPCKeyLen")
64 }
65 if len(MakeTKP(7, ph, 't', ph, 7, 9)) != TKPKeyLen {
66 t.Fatal("TKPKeyLen")
67 }
68 if len(MakeWrd(ph, 9)) != WrdKeyLen {
69 t.Fatal("WrdKeyLen")
70 }
71 if len(MakePks(ph, 9)) != PksKeyLen {
72 t.Fatal("PksKeyLen")
73 }
74 if len(MakeSpk(9)) != SpkKeyLen {
75 t.Fatal("SpkKeyLen")
76 }
77 if len(MakeSeiRec(9, ixHash32(3))) != SeiRecLen {
78 t.Fatal("SeiRecLen")
79 }
80 if len(MakeSpkRec(9, ixHash32(4))) != SpkRecLen {
81 t.Fatal("SpkRecLen")
82 }
83 if len(MakeFpc(9, ixHash32(5), ph, 7)) != FpcKeyLen {
84 t.Fatal("FpcKeyLen")
85 }
86 if len(MakeEpg(1, 2, 7, 3)) != EpgKeyLen {
87 t.Fatal("EpgKeyLen")
88 }
89 if len(MakePeg(1, 7, 3, 2)) != PegKeyLen {
90 t.Fatal("PegKeyLen")
91 }
92 if len(MakeEeg(1, 2, 7, 3)) != EegKeyLen {
93 t.Fatal("EegKeyLen")
94 }
95 if len(MakeGee(1, 7, 3, 2)) != GeeKeyLen {
96 t.Fatal("GeeKeyLen")
97 }
98 if len(MakePpg(1, 2, 7, 3, 4)) != PpgKeyLen {
99 t.Fatal("PpgKeyLen")
100 }
101 if len(MakeGpp(1, 7, 3, 2, 4)) != GppKeyLen {
102 t.Fatal("GppKeyLen")
103 }
104 }
105
106 func TestEidKeys(t *testing.T) {
107 ih := ixHash8(0xAB)
108 k := MakeEid(ih, 0x0102030405)
109 if !bytes.Equal(k[:3], Eid[:]) {
110 t.Fatalf("Eid prefix = %x", k[:3])
111 }
112 if !bytes.Equal(k[3:3+serial.HashLen], ih) {
113 t.Fatal("Eid hash field")
114 }
115 if serial.Get(k[3+serial.HashLen:]) != 0x0102030405 {
116 t.Fatal("Eid serial field")
117 }
118 // The prefix is exactly the key with the serial stripped.
119 p := MakeEidPrefix(ih)
120 if len(p) != 3+serial.HashLen {
121 t.Fatalf("EidPrefix len = %d", len(p))
122 }
123 if !bytes.Equal(p, k[:3+serial.HashLen]) {
124 t.Fatal("EidPrefix is not the key prefix")
125 }
126 if EidCmpLen != 3+serial.HashLen {
127 t.Fatal("EidCmpLen must stop at the hash")
128 }
129 }
130
131 func TestSeiKeys(t *testing.T) {
132 k := MakeSei(0x0102030405)
133 if !bytes.Equal(k[:3], Sei[:]) {
134 t.Fatal("Sei prefix")
135 }
136 if serial.Get(k[3:]) != 0x0102030405 {
137 t.Fatal("Sei serial")
138 }
139 id := ixHash32(0x7E)
140 rec := MakeSeiRec(0x0102030405, id)
141 if !bytes.Equal(rec[:SeiKeyLen], k) {
142 t.Fatal("SeiRec key portion")
143 }
144 if !bytes.Equal(rec[SeiKeyLen:], id) {
145 t.Fatal("SeiRec value portion")
146 }
147 }
148
149 func TestOrderingKeys(t *testing.T) {
150 ts := int64(1700000000)
151 ser := uint64(0x0102030405)
152
153 ca := MakeCA(ts, ser)
154 if !bytes.Equal(ca[:3], CA[:]) {
155 t.Fatal("CA prefix")
156 }
157 if serial.GetTimestamp(ca[3:11]) != ts {
158 t.Fatal("CA timestamp")
159 }
160 if serial.Get(ca[11:]) != ser {
161 t.Fatal("CA serial")
162 }
163
164 kc := MakeKC(30023, ts, ser)
165 if !bytes.Equal(kc[:3], KC[:]) {
166 t.Fatal("KC prefix")
167 }
168 if serial.GetKind(kc[3:5]) != 30023 {
169 t.Fatal("KC kind")
170 }
171 if serial.GetTimestamp(kc[5:13]) != ts {
172 t.Fatal("KC timestamp")
173 }
174 if serial.Get(kc[13:]) != ser {
175 t.Fatal("KC serial")
176 }
177
178 ph := ixHash8(0x33)
179 pc := MakePC(ph, ts, ser)
180 if !bytes.Equal(pc[:3], PC[:]) {
181 t.Fatal("PC prefix")
182 }
183 if !bytes.Equal(pc[3:3+serial.HashLen], ph) {
184 t.Fatal("PC pubhash")
185 }
186 if serial.GetTimestamp(pc[3+serial.HashLen:3+serial.HashLen+8]) != ts {
187 t.Fatal("PC timestamp")
188 }
189 if serial.Get(pc[3+serial.HashLen+8:]) != ser {
190 t.Fatal("PC serial")
191 }
192
193 kpc := MakeKPC(7, ph, ts, ser)
194 if !bytes.Equal(kpc[:3], KPC[:]) {
195 t.Fatal("KPC prefix")
196 }
197 if serial.GetKind(kpc[3:5]) != 7 {
198 t.Fatal("KPC kind")
199 }
200 if !bytes.Equal(kpc[5:5+serial.HashLen], ph) {
201 t.Fatal("KPC pubhash")
202 }
203 if serial.GetTimestamp(kpc[5+serial.HashLen:5+serial.HashLen+8]) != ts {
204 t.Fatal("KPC timestamp")
205 }
206 if serial.Get(kpc[5+serial.HashLen+8:]) != ser {
207 t.Fatal("KPC serial")
208 }
209 }
210
211 func TestTagKeys(t *testing.T) {
212 ts := int64(1700000000)
213 ser := uint64(0x0102030405)
214 vh := ixHash8(0x44)
215 ph := ixHash8(0x55)
216
217 tc := MakeTC('t', vh, ts, ser)
218 if !bytes.Equal(tc[:3], TC[:]) {
219 t.Fatal("TC prefix")
220 }
221 if tc[3] != 't' {
222 t.Fatal("TC tag key")
223 }
224 if !bytes.Equal(tc[4:4+serial.HashLen], vh) {
225 t.Fatal("TC value hash")
226 }
227 if serial.GetTimestamp(tc[4+serial.HashLen:4+serial.HashLen+8]) != ts {
228 t.Fatal("TC timestamp")
229 }
230 if serial.Get(tc[4+serial.HashLen+8:]) != ser {
231 t.Fatal("TC serial")
232 }
233
234 tkc := MakeTKC(7, 'p', vh, ts, ser)
235 if !bytes.Equal(tkc[:3], TKC[:]) {
236 t.Fatal("TKC prefix")
237 }
238 if serial.GetKind(tkc[3:5]) != 7 {
239 t.Fatal("TKC kind")
240 }
241 if tkc[5] != 'p' {
242 t.Fatal("TKC tag key")
243 }
244 if !bytes.Equal(tkc[6:6+serial.HashLen], vh) {
245 t.Fatal("TKC value hash")
246 }
247 if serial.GetTimestamp(tkc[6+serial.HashLen:6+serial.HashLen+8]) != ts {
248 t.Fatal("TKC timestamp")
249 }
250 if serial.Get(tkc[6+serial.HashLen+8:]) != ser {
251 t.Fatal("TKC serial")
252 }
253
254 tpc := MakeTPC(ph, 'e', vh, ts, ser)
255 if !bytes.Equal(tpc[:3], TPC[:]) {
256 t.Fatal("TPC prefix")
257 }
258 if !bytes.Equal(tpc[3:3+serial.HashLen], ph) {
259 t.Fatal("TPC pubhash")
260 }
261 if tpc[3+serial.HashLen] != 'e' {
262 t.Fatal("TPC tag key")
263 }
264 if !bytes.Equal(tpc[3+serial.HashLen+1:3+serial.HashLen+1+serial.HashLen], vh) {
265 t.Fatal("TPC value hash")
266 }
267 if serial.GetTimestamp(tpc[3+serial.HashLen+1+serial.HashLen:3+serial.HashLen+1+serial.HashLen+8]) != ts {
268 t.Fatal("TPC timestamp")
269 }
270 if serial.Get(tpc[3+serial.HashLen+1+serial.HashLen+8:]) != ser {
271 t.Fatal("TPC serial")
272 }
273
274 tkp := MakeTKP(7, ph, 'e', vh, ts, ser)
275 if !bytes.Equal(tkp[:3], TKP[:]) {
276 t.Fatal("TKP prefix")
277 }
278 if serial.GetKind(tkp[3:5]) != 7 {
279 t.Fatal("TKP kind")
280 }
281 if !bytes.Equal(tkp[5:5+serial.HashLen], ph) {
282 t.Fatal("TKP pubhash")
283 }
284 if tkp[5+serial.HashLen] != 'e' {
285 t.Fatal("TKP tag key")
286 }
287 if !bytes.Equal(tkp[5+serial.HashLen+1:5+serial.HashLen+1+serial.HashLen], vh) {
288 t.Fatal("TKP value hash")
289 }
290 if serial.GetTimestamp(tkp[5+serial.HashLen+1+serial.HashLen:5+serial.HashLen+1+serial.HashLen+8]) != ts {
291 t.Fatal("TKP timestamp")
292 }
293 if serial.Get(tkp[5+serial.HashLen+1+serial.HashLen+8:]) != ser {
294 t.Fatal("TKP serial")
295 }
296 }
297
298 func TestWordPubkeyExpFpcKeys(t *testing.T) {
299 ph := ixHash8(0x66)
300 ser := uint64(0x0102030405)
301 ts := int64(1700000000)
302
303 wrd := MakeWrd(ph, ser)
304 if !bytes.Equal(wrd[:3], Wrd[:]) {
305 t.Fatal("Wrd prefix")
306 }
307 if !bytes.Equal(wrd[3:3+serial.HashLen], ph) {
308 t.Fatal("Wrd hash")
309 }
310 if serial.Get(wrd[3+serial.HashLen:]) != ser {
311 t.Fatal("Wrd serial")
312 }
313
314 pks := MakePks(ph, ser)
315 if !bytes.Equal(pks[:3], Pks[:]) {
316 t.Fatal("Pks prefix")
317 }
318 if !bytes.Equal(pks[3:3+serial.HashLen], ph) {
319 t.Fatal("Pks hash")
320 }
321 if serial.Get(pks[3+serial.HashLen:]) != ser {
322 t.Fatal("Pks serial")
323 }
324 if PksCmpLen != 3+serial.HashLen {
325 t.Fatal("PksCmpLen must stop at the hash")
326 }
327
328 spk := MakeSpk(ser)
329 if !bytes.Equal(spk[:3], Spk[:]) {
330 t.Fatal("Spk prefix")
331 }
332 if serial.Get(spk[3:]) != ser {
333 t.Fatal("Spk serial")
334 }
335 pub := ixHash32(0x77)
336 spkRec := MakeSpkRec(ser, pub)
337 if !bytes.Equal(spkRec[:SpkKeyLen], spk) {
338 t.Fatal("SpkRec key portion")
339 }
340 if !bytes.Equal(spkRec[SpkKeyLen:], pub) {
341 t.Fatal("SpkRec value portion")
342 }
343
344 exp := MakeExp(ts, ser)
345 if !bytes.Equal(exp[:3], Exp[:]) {
346 t.Fatal("Exp prefix")
347 }
348 if serial.GetTimestamp(exp[3:11]) != ts {
349 t.Fatal("Exp timestamp")
350 }
351 if serial.Get(exp[11:]) != ser {
352 t.Fatal("Exp serial")
353 }
354
355 id := ixHash32(0x88)
356 fpc := MakeFpc(ser, id, ph, ts)
357 if !bytes.Equal(fpc[:3], Fpc[:]) {
358 t.Fatal("Fpc prefix")
359 }
360 if serial.Get(fpc[3:3+serial.Len]) != ser {
361 t.Fatal("Fpc serial")
362 }
363 if !bytes.Equal(fpc[3+serial.Len:3+serial.Len+32], id) {
364 t.Fatal("Fpc full id")
365 }
366 if !bytes.Equal(fpc[3+serial.Len+32:3+serial.Len+32+serial.HashLen], ph) {
367 t.Fatal("Fpc pubhash")
368 }
369 if serial.GetTimestamp(fpc[3+serial.Len+32+serial.HashLen:]) != ts {
370 t.Fatal("Fpc timestamp")
371 }
372 if FpcCmpLen != 3+serial.Len {
373 t.Fatal("FpcCmpLen must stop at the serial")
374 }
375 }
376
377 func TestGraphKeys(t *testing.T) {
378 ser := uint64(0x0102030405)
379 ser2 := uint64(0x060708090A)
380
381 epg := MakeEpg(ser, ser2, 7, DirPTagOut)
382 if !bytes.Equal(epg[:3], Epg[:]) {
383 t.Fatal("Epg prefix")
384 }
385 if serial.Get(epg[3:8]) != ser {
386 t.Fatal("Epg event serial")
387 }
388 if serial.Get(epg[8:13]) != ser2 {
389 t.Fatal("Epg pubkey serial")
390 }
391 if serial.GetKind(epg[13:15]) != 7 {
392 t.Fatal("Epg kind")
393 }
394 if epg[15] != DirPTagOut {
395 t.Fatal("Epg direction")
396 }
397
398 peg := MakePeg(ser2, 7, DirPTagIn, ser)
399 if !bytes.Equal(peg[:3], Peg[:]) {
400 t.Fatal("Peg prefix")
401 }
402 if serial.Get(peg[3:8]) != ser2 {
403 t.Fatal("Peg pubkey serial")
404 }
405 if serial.GetKind(peg[8:10]) != 7 {
406 t.Fatal("Peg kind")
407 }
408 if peg[10] != DirPTagIn {
409 t.Fatal("Peg direction")
410 }
411 if serial.Get(peg[11:]) != ser {
412 t.Fatal("Peg event serial")
413 }
414
415 eeg := MakeEeg(ser, ser2, 7, DirETagOut)
416 if !bytes.Equal(eeg[:3], Eeg[:]) {
417 t.Fatal("Eeg prefix")
418 }
419 if serial.Get(eeg[3:8]) != ser || serial.Get(eeg[8:13]) != ser2 {
420 t.Fatal("Eeg serials")
421 }
422 if serial.GetKind(eeg[13:15]) != 7 || eeg[15] != DirETagOut {
423 t.Fatal("Eeg kind/dir")
424 }
425
426 gee := MakeGee(ser2, 7, DirETagIn, ser)
427 if !bytes.Equal(gee[:3], Gee[:]) {
428 t.Fatal("Gee prefix")
429 }
430 if serial.Get(gee[3:8]) != ser2 {
431 t.Fatal("Gee target serial")
432 }
433 if serial.GetKind(gee[8:10]) != 7 || gee[10] != DirETagIn {
434 t.Fatal("Gee kind/dir")
435 }
436 if serial.Get(gee[11:]) != ser {
437 t.Fatal("Gee source serial")
438 }
439
440 ppg := MakePpg(ser, ser2, 7, DirPKOut, 42)
441 if !bytes.Equal(ppg[:3], Ppg[:]) {
442 t.Fatal("Ppg prefix")
443 }
444 if serial.Get(ppg[3:8]) != ser || serial.Get(ppg[8:13]) != ser2 {
445 t.Fatal("Ppg serials")
446 }
447 if serial.GetKind(ppg[13:15]) != 7 || ppg[15] != DirPKOut {
448 t.Fatal("Ppg kind/dir")
449 }
450 if serial.Get(ppg[16:]) != 42 {
451 t.Fatal("Ppg event serial")
452 }
453
454 gpp := MakeGpp(ser2, 7, DirPKIn, ser, 42)
455 if !bytes.Equal(gpp[:3], Gpp[:]) {
456 t.Fatal("Gpp prefix")
457 }
458 if serial.Get(gpp[3:8]) != ser2 {
459 t.Fatal("Gpp target pk")
460 }
461 if serial.GetKind(gpp[8:10]) != 7 || gpp[10] != DirPKIn {
462 t.Fatal("Gpp kind/dir")
463 }
464 if serial.Get(gpp[11:16]) != ser {
465 t.Fatal("Gpp source pk")
466 }
467 if serial.Get(gpp[16:]) != 42 {
468 t.Fatal("Gpp event serial")
469 }
470 }
471
472 // TestEdgeDirections pins the numeric direction values: they are on-disk bytes,
473 // so a renumbering silently changes the meaning of every stored edge.
474 func TestEdgeDirections(t *testing.T) {
475 if DirAuthor != 0 || DirPTagOut != 1 || DirPTagIn != 2 {
476 t.Fatal("event-pubkey directions")
477 }
478 if DirETagOut != 0 || DirETagIn != 1 {
479 t.Fatal("event-event directions")
480 }
481 if DirPKOut != 0 || DirPKIn != 1 {
482 t.Fatal("pubkey-pubkey directions")
483 }
484 }
485