@@ -71,10 +71,24 @@ type BoundedBlockService interface {
71
71
Allowlist () verifcid.Allowlist
72
72
}
73
73
74
+ // Blocker returns err != nil if the CID is disallowed to be fetched or stored in blockservice.
75
+ // It returns an error so error messages could be passed.
76
+ type Blocker func (cid.Cid ) error
77
+
78
+ // BlockedBlockService is a Blockservice bounded via an arbitrary cid [Blocker].
79
+ type BlockedBlockService interface {
80
+ BlockService
81
+
82
+ // Blocker might return [nil], then no blocking is to be done.
83
+ Blocker () Blocker
84
+ }
85
+
74
86
var _ BoundedBlockService = (* blockService )(nil )
87
+ var _ BlockedBlockService = (* blockService )(nil )
75
88
76
89
type blockService struct {
77
90
allowlist verifcid.Allowlist
91
+ blocker Blocker
78
92
blockstore blockstore.Blockstore
79
93
exchange exchange.Interface
80
94
// If checkFirst is true then first check that a block doesn't
@@ -99,6 +113,13 @@ func WithAllowlist(allowlist verifcid.Allowlist) Option {
99
113
}
100
114
}
101
115
116
+ // WithContentBlocker allows to filter what blocks can be fetched or added to the blockservice.
117
+ func WithContentBlocker (blocker Blocker ) Option {
118
+ return func (bs * blockService ) {
119
+ bs .blocker = blocker
120
+ }
121
+ }
122
+
102
123
// New creates a BlockService with given datastore instance.
103
124
func New (bs blockstore.Blockstore , exchange exchange.Interface , opts ... Option ) BlockService {
104
125
if exchange == nil {
@@ -141,6 +162,10 @@ func (s *blockService) Allowlist() verifcid.Allowlist {
141
162
return s .allowlist
142
163
}
143
164
165
+ func (s * blockService ) Blocker () Blocker {
166
+ return s .blocker
167
+ }
168
+
144
169
// NewSession creates a new session that allows for
145
170
// controlled exchange of wantlists to decrease the bandwidth overhead.
146
171
// If the current exchange is a SessionExchange, a new exchange
@@ -171,6 +196,13 @@ func (s *blockService) AddBlock(ctx context.Context, o blocks.Block) error {
171
196
if err != nil {
172
197
return err
173
198
}
199
+
200
+ if s .blocker != nil {
201
+ if err := s .blocker (c ); err != nil {
202
+ return err
203
+ }
204
+ }
205
+
174
206
if s .checkFirst {
175
207
if has , err := s .blockstore .Has (ctx , c ); has || err != nil {
176
208
return err
@@ -198,10 +230,17 @@ func (s *blockService) AddBlocks(ctx context.Context, bs []blocks.Block) error {
198
230
199
231
// hash security
200
232
for _ , b := range bs {
201
- err := verifcid .ValidateCid (s .allowlist , b .Cid ())
233
+ c := b .Cid ()
234
+ err := verifcid .ValidateCid (s .allowlist , c )
202
235
if err != nil {
203
236
return err
204
237
}
238
+
239
+ if s .blocker != nil {
240
+ if err := s .blocker (c ); err != nil {
241
+ return err
242
+ }
243
+ }
205
244
}
206
245
var toput []blocks.Block
207
246
if s .checkFirst {
@@ -261,6 +300,12 @@ func getBlock(ctx context.Context, c cid.Cid, bs BlockService, fetchFactory func
261
300
return nil , err
262
301
}
263
302
303
+ if blocker := grabBlockerFromBlockservice (bs ); blocker != nil {
304
+ if err := blocker (c ); err != nil {
305
+ return nil , err
306
+ }
307
+ }
308
+
264
309
blockstore := bs .Blockstore ()
265
310
266
311
block , err := blockstore .Get (ctx , c )
@@ -320,13 +365,20 @@ func getBlocks(ctx context.Context, ks []cid.Cid, blockservice BlockService, fet
320
365
defer close (out )
321
366
322
367
allowlist := grabAllowlistFromBlockservice (blockservice )
368
+ blocker := grabBlockerFromBlockservice (blockservice )
323
369
324
370
var lastAllValidIndex int
325
371
var c cid.Cid
326
372
for lastAllValidIndex , c = range ks {
327
373
if err := verifcid .ValidateCid (allowlist , c ); err != nil {
328
374
break
329
375
}
376
+
377
+ if blocker != nil {
378
+ if err := blocker (c ); err != nil {
379
+ break
380
+ }
381
+ }
330
382
}
331
383
332
384
if lastAllValidIndex != len (ks ) {
@@ -335,11 +387,19 @@ func getBlocks(ctx context.Context, ks []cid.Cid, blockservice BlockService, fet
335
387
copy (ks2 , ks [:lastAllValidIndex ]) // fast path for already filtered elements
336
388
for _ , c := range ks [lastAllValidIndex :] { // don't rescan already scanned elements
337
389
// hash security
338
- if err := verifcid .ValidateCid (allowlist , c ); err == nil {
339
- ks2 = append (ks2 , c )
340
- } else {
390
+ if err := verifcid .ValidateCid (allowlist , c ); err != nil {
341
391
logger .Errorf ("unsafe CID (%s) passed to blockService.GetBlocks: %s" , c , err )
392
+ continue
393
+ }
394
+
395
+ if blocker != nil {
396
+ if err := blocker (c ); err != nil {
397
+ logger .Errorf ("blocked CID (%s) passed to blockService.GetBlocks: %s" , c , err )
398
+ continue
399
+ }
342
400
}
401
+
402
+ ks2 = append (ks2 , c )
343
403
}
344
404
ks = ks2
345
405
}
@@ -526,3 +586,10 @@ func grabAllowlistFromBlockservice(bs BlockService) verifcid.Allowlist {
526
586
}
527
587
return verifcid .DefaultAllowlist
528
588
}
589
+
590
+ func grabBlockerFromBlockservice (bs BlockService ) Blocker {
591
+ if bbs , ok := bs .(BlockedBlockService ); ok {
592
+ return bbs .Blocker ()
593
+ }
594
+ return nil
595
+ }
0 commit comments