@@ -20,7 +20,7 @@ import (
20
20
21
21
const defaultMaxRevFuture = time .Hour
22
22
23
- func NewValidator (directory identity.Directory , inductionTraceLog * slog.Logger ) * Validator {
23
+ func NewValidator (directory identity.Directory , inductionTraceLog * slog.Logger , sync11ErrorsAreWarnings bool ) * Validator {
24
24
maxRevFuture := defaultMaxRevFuture // TODO: configurable
25
25
ErrRevTooFarFuture := fmt .Errorf ("new rev is > %s in the future" , maxRevFuture )
26
26
@@ -30,9 +30,10 @@ func NewValidator(directory identity.Directory, inductionTraceLog *slog.Logger)
30
30
inductionTraceLog : inductionTraceLog ,
31
31
directory : directory ,
32
32
33
- maxRevFuture : maxRevFuture ,
34
- ErrRevTooFarFuture : ErrRevTooFarFuture ,
35
- AllowSignatureNotFound : true , // TODO: configurable
33
+ maxRevFuture : maxRevFuture ,
34
+ ErrRevTooFarFuture : ErrRevTooFarFuture ,
35
+ AllowSignatureNotFound : true , // TODO: configurable
36
+ Sync11ErrorsAreWarnings : sync11ErrorsAreWarnings ,
36
37
}
37
38
}
38
39
@@ -56,6 +57,8 @@ type Validator struct {
56
57
// AllowSignatureNotFound enables counting messages without findable public key to pass through with a warning counter
57
58
// TODO: refine this for what kind of 'not found' we accept.
58
59
AllowSignatureNotFound bool
60
+
61
+ Sync11ErrorsAreWarnings bool
59
62
}
60
63
61
64
type NextCommitHandler interface {
@@ -129,36 +132,56 @@ func (val *Validator) VerifyCommitMessage(ctx context.Context, host *models.PDS,
129
132
hostname := host .Host
130
133
hasWarning := false
131
134
commitVerifyStarts .Inc ()
132
- logger := slog .Default ().With ("did" , msg .Repo , "rev" , msg .Rev , "seq" , msg .Seq , "time" , msg .Time )
135
+ logger := slog .Default ().With ("host" , hostname , " did" , msg .Repo , "rev" , msg .Rev , "seq" , msg .Seq , "time" , msg .Time )
133
136
134
137
did , err := syntax .ParseDID (msg .Repo )
135
138
if err != nil {
136
139
commitVerifyErrors .WithLabelValues (hostname , "did" ).Inc ()
137
- return nil , err
140
+ if ! val .Sync11ErrorsAreWarnings {
141
+ return nil , err
142
+ } else {
143
+ logger .Warn ("invalid did" , "err" , err )
144
+ }
138
145
}
139
146
rev , err := syntax .ParseTID (msg .Rev )
140
147
if err != nil {
141
148
commitVerifyErrors .WithLabelValues (hostname , "tid" ).Inc ()
142
- return nil , err
149
+ if ! val .Sync11ErrorsAreWarnings {
150
+ return nil , err
151
+ } else {
152
+ logger .Warn ("invalid rev" , "err" , err )
153
+ }
143
154
}
144
155
if prevRoot != nil {
145
156
prevRev := prevRoot .GetRev ()
146
157
curTime := rev .Time ()
147
158
prevTime := prevRev .Time ()
148
159
if curTime .Before (prevTime ) {
149
160
commitVerifyErrors .WithLabelValues (hostname , "revb" ).Inc ()
150
- dt := prevTime .Sub (curTime )
151
- return nil , & revOutOfOrderError {dt }
161
+ if ! val .Sync11ErrorsAreWarnings {
162
+ dt := prevTime .Sub (curTime )
163
+ return nil , & revOutOfOrderError {dt }
164
+ } else {
165
+ logger .Warn ("new rev before old rev" , "prev rev" , prevRev , "rev" , rev )
166
+ }
152
167
}
153
168
}
154
169
if rev .Time ().After (time .Now ().Add (val .maxRevFuture )) {
155
170
commitVerifyErrors .WithLabelValues (hostname , "revf" ).Inc ()
156
- return nil , val .ErrRevTooFarFuture
171
+ if ! val .Sync11ErrorsAreWarnings {
172
+ return nil , val .ErrRevTooFarFuture
173
+ } else {
174
+ logger .Warn ("far future rev" , "now" , time .Now (), "rev" , rev .Time (), "err" , err )
175
+ }
157
176
}
158
177
_ , err = syntax .ParseDatetime (msg .Time )
159
178
if err != nil {
160
179
commitVerifyErrors .WithLabelValues (hostname , "time" ).Inc ()
161
- return nil , err
180
+ if ! val .Sync11ErrorsAreWarnings {
181
+ return nil , err
182
+ } else {
183
+ logger .Warn ("invalid time" , "err" , err )
184
+ }
162
185
}
163
186
164
187
if msg .TooBig {
@@ -177,16 +200,28 @@ func (val *Validator) VerifyCommitMessage(ctx context.Context, host *models.PDS,
177
200
commit , repoFragment , err := atrepo .LoadFromCAR (ctx , bytes .NewReader ([]byte (msg .Blocks )))
178
201
if err != nil {
179
202
commitVerifyErrors .WithLabelValues (hostname , "car" ).Inc ()
180
- return nil , err
203
+ if ! val .Sync11ErrorsAreWarnings {
204
+ return nil , err
205
+ } else {
206
+ logger .Warn ("invalid car" , "err" , err )
207
+ }
181
208
}
182
209
183
210
if commit .Rev != rev .String () {
184
211
commitVerifyErrors .WithLabelValues (hostname , "rev" ).Inc ()
185
- return nil , fmt .Errorf ("rev did not match commit" )
212
+ if ! val .Sync11ErrorsAreWarnings {
213
+ return nil , fmt .Errorf ("rev did not match commit" )
214
+ } else {
215
+ logger .Warn ("message rev != commit.rev" )
216
+ }
186
217
}
187
218
if commit .DID != did .String () {
188
219
commitVerifyErrors .WithLabelValues (hostname , "did2" ).Inc ()
189
- return nil , fmt .Errorf ("rev did not match commit" )
220
+ if ! val .Sync11ErrorsAreWarnings {
221
+ return nil , fmt .Errorf ("rev did not match commit" )
222
+ } else {
223
+ logger .Warn ("message did != commit.did" )
224
+ }
190
225
}
191
226
192
227
err = val .VerifyCommitSignature (ctx , commit , hostname , & hasWarning )
@@ -202,21 +237,37 @@ func (val *Validator) VerifyCommitMessage(ctx context.Context, host *models.PDS,
202
237
nsid , rkey , err := syntax .ParseRepoPath (op .Path )
203
238
if err != nil {
204
239
commitVerifyErrors .WithLabelValues (hostname , "opp" ).Inc ()
205
- return nil , fmt .Errorf ("invalid repo path in ops list: %w" , err )
240
+ if ! val .Sync11ErrorsAreWarnings {
241
+ return nil , fmt .Errorf ("invalid repo path in ops list: %w" , err )
242
+ } else {
243
+ logger .Warn ("invalid repo path" , "err" , err )
244
+ }
206
245
}
207
- val , err := repoFragment .GetRecordCID (ctx , nsid , rkey )
246
+ rcid , err := repoFragment .GetRecordCID (ctx , nsid , rkey )
208
247
if err != nil {
209
248
commitVerifyErrors .WithLabelValues (hostname , "rcid" ).Inc ()
210
- return nil , err
249
+ if ! val .Sync11ErrorsAreWarnings {
250
+ return nil , err
251
+ } else {
252
+ logger .Warn ("invalid record cid" , "err" , err )
253
+ }
211
254
}
212
- if * c != * val {
255
+ if * c != * rcid {
213
256
commitVerifyErrors .WithLabelValues (hostname , "opc" ).Inc ()
214
- return nil , fmt .Errorf ("record op doesn't match MST tree value" )
257
+ if ! val .Sync11ErrorsAreWarnings {
258
+ return nil , fmt .Errorf ("record op doesn't match MST tree value" )
259
+ } else {
260
+ logger .Warn ("record op doesn't match MST tree value" )
261
+ }
215
262
}
216
263
_ , _ , err = repoFragment .GetRecordBytes (ctx , nsid , rkey )
217
264
if err != nil {
218
265
commitVerifyErrors .WithLabelValues (hostname , "rec" ).Inc ()
219
- return nil , err
266
+ if ! val .Sync11ErrorsAreWarnings {
267
+ return nil , err
268
+ } else {
269
+ logger .Warn ("could not get record bytes" , "err" , err )
270
+ }
220
271
}
221
272
}
222
273
}
@@ -257,30 +308,50 @@ func (val *Validator) VerifyCommitMessage(ctx context.Context, host *models.PDS,
257
308
ops , err := ParseCommitOps (msg .Ops )
258
309
if err != nil {
259
310
commitVerifyErrors .WithLabelValues (hostname , "pop" ).Inc ()
260
- return nil , err
311
+ if ! val .Sync11ErrorsAreWarnings {
312
+ return nil , err
313
+ } else {
314
+ logger .Warn ("invalid commit ops" , "err" , err )
315
+ }
261
316
}
262
317
ops , err = atrepo .NormalizeOps (ops )
263
318
if err != nil {
264
319
commitVerifyErrors .WithLabelValues (hostname , "nop" ).Inc ()
265
- return nil , err
320
+ if ! val .Sync11ErrorsAreWarnings {
321
+ return nil , err
322
+ } else {
323
+ logger .Warn ("could not normalize ops" , "err" , err )
324
+ }
266
325
}
267
326
268
327
invTree := repoFragment .MST .Copy ()
269
328
for _ , op := range ops {
270
329
if err := atrepo .InvertOp (& invTree , & op ); err != nil {
271
330
commitVerifyErrors .WithLabelValues (hostname , "inv" ).Inc ()
272
- return nil , err
331
+ if ! val .Sync11ErrorsAreWarnings {
332
+ return nil , err
333
+ } else {
334
+ logger .Warn ("could not invert op" , "err" , err )
335
+ }
273
336
}
274
337
}
275
338
computed , err := invTree .RootCID ()
276
339
if err != nil {
277
340
commitVerifyErrors .WithLabelValues (hostname , "it" ).Inc ()
278
- return nil , err
341
+ if ! val .Sync11ErrorsAreWarnings {
342
+ return nil , err
343
+ } else {
344
+ logger .Warn ("inverted tree could not get root cid" , "err" , err )
345
+ }
279
346
}
280
347
if * computed != * c {
281
348
// this is self-inconsistent malformed data
282
349
commitVerifyErrors .WithLabelValues (hostname , "pd" ).Inc ()
283
- return nil , fmt .Errorf ("inverted tree root didn't match prevData" )
350
+ if ! val .Sync11ErrorsAreWarnings {
351
+ return nil , fmt .Errorf ("inverted tree root didn't match prevData" )
352
+ } else {
353
+ logger .Warn ("inverted tree root didn't match prevData" )
354
+ }
284
355
}
285
356
//logger.Debug("prevData matched", "prevData", c.String(), "computed", computed.String())
286
357
@@ -305,46 +376,79 @@ func (val *Validator) VerifyCommitMessage(ctx context.Context, host *models.PDS,
305
376
func (val * Validator ) HandleSync (ctx context.Context , host * models.PDS , msg * atproto.SyncSubscribeRepos_Sync ) (newRoot * cid.Cid , err error ) {
306
377
hostname := host .Host
307
378
hasWarning := false
379
+ logger := slog .Default ().With ("host" , hostname , "did" , msg .Did , "rev" , msg .Rev , "seq" , msg .Seq , "time" , msg .Time )
308
380
309
381
did , err := syntax .ParseDID (msg .Did )
310
382
if err != nil {
311
383
syncVerifyErrors .WithLabelValues (hostname , "did" ).Inc ()
312
- return nil , err
384
+ if ! val .Sync11ErrorsAreWarnings {
385
+ return nil , err
386
+ } else {
387
+ logger .Warn ("invalid did" , "err" , err )
388
+ }
313
389
}
314
390
rev , err := syntax .ParseTID (msg .Rev )
315
391
if err != nil {
316
392
syncVerifyErrors .WithLabelValues (hostname , "tid" ).Inc ()
317
- return nil , err
393
+ if ! val .Sync11ErrorsAreWarnings {
394
+ return nil , err
395
+ } else {
396
+ logger .Warn ("invalid rev" , "err" , err )
397
+ }
318
398
}
319
399
if rev .Time ().After (time .Now ().Add (val .maxRevFuture )) {
320
400
syncVerifyErrors .WithLabelValues (hostname , "revf" ).Inc ()
321
- return nil , val .ErrRevTooFarFuture
401
+ if ! val .Sync11ErrorsAreWarnings {
402
+ return nil , val .ErrRevTooFarFuture
403
+ } else {
404
+ logger .Warn ("invalid rev too far future" , "now" , time .Now (), "rev" , rev .Time ())
405
+ }
322
406
}
323
407
_ , err = syntax .ParseDatetime (msg .Time )
324
408
if err != nil {
325
409
syncVerifyErrors .WithLabelValues (hostname , "time" ).Inc ()
326
- return nil , err
410
+ if ! val .Sync11ErrorsAreWarnings {
411
+ return nil , err
412
+ } else {
413
+ logger .Warn ("invalid time" , "err" , err )
414
+ }
327
415
}
328
416
329
417
commit , err := atrepo .LoadCARCommit (ctx , bytes .NewReader ([]byte (msg .Blocks )))
330
418
if err != nil {
331
419
commitVerifyErrors .WithLabelValues (hostname , "car" ).Inc ()
332
- return nil , err
420
+ if ! val .Sync11ErrorsAreWarnings {
421
+ return nil , err
422
+ } else {
423
+ logger .Warn ("invalid car" , "err" , err )
424
+ }
333
425
}
334
426
335
427
if commit .Rev != rev .String () {
336
428
commitVerifyErrors .WithLabelValues (hostname , "rev" ).Inc ()
337
- return nil , fmt .Errorf ("rev did not match commit" )
429
+ if ! val .Sync11ErrorsAreWarnings {
430
+ return nil , fmt .Errorf ("rev did not match commit" )
431
+ } else {
432
+ logger .Warn ("message rev != commit.rev" )
433
+ }
338
434
}
339
435
if commit .DID != did .String () {
340
436
commitVerifyErrors .WithLabelValues (hostname , "did2" ).Inc ()
341
- return nil , fmt .Errorf ("rev did not match commit" )
437
+ if ! val .Sync11ErrorsAreWarnings {
438
+ return nil , fmt .Errorf ("did did not match commit" )
439
+ } else {
440
+ logger .Warn ("message did != commit.did" )
441
+ }
342
442
}
343
443
344
444
err = val .VerifyCommitSignature (ctx , commit , hostname , & hasWarning )
345
445
if err != nil {
346
446
// signature errors are metrics counted inside VerifyCommitSignature()
347
- return nil , err
447
+ if ! val .Sync11ErrorsAreWarnings {
448
+ return nil , err
449
+ } else {
450
+ logger .Warn ("invalid sig" , "err" , err )
451
+ }
348
452
}
349
453
350
454
return & commit .Data , nil
0 commit comments