@@ -71,10 +71,24 @@ type BoundedBlockService interface {
7171 Allowlist () verifcid.Allowlist
7272}
7373
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+
7486var _ BoundedBlockService = (* blockService )(nil )
87+ var _ BlockedBlockService = (* blockService )(nil )
7588
7689type blockService struct {
7790 allowlist verifcid.Allowlist
91+ blocker Blocker
7892 blockstore blockstore.Blockstore
7993 exchange exchange.Interface
8094 // If checkFirst is true then first check that a block doesn't
@@ -99,6 +113,13 @@ func WithAllowlist(allowlist verifcid.Allowlist) Option {
99113 }
100114}
101115
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+
102123// New creates a BlockService with given datastore instance.
103124func New (bs blockstore.Blockstore , exchange exchange.Interface , opts ... Option ) BlockService {
104125 if exchange == nil {
@@ -141,6 +162,10 @@ func (s *blockService) Allowlist() verifcid.Allowlist {
141162 return s .allowlist
142163}
143164
165+ func (s * blockService ) Blocker () Blocker {
166+ return s .blocker
167+ }
168+
144169// NewSession creates a new session that allows for
145170// controlled exchange of wantlists to decrease the bandwidth overhead.
146171// 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 {
171196 if err != nil {
172197 return err
173198 }
199+
200+ if s .blocker != nil {
201+ if err := s .blocker (c ); err != nil {
202+ return err
203+ }
204+ }
205+
174206 if s .checkFirst {
175207 if has , err := s .blockstore .Has (ctx , c ); has || err != nil {
176208 return err
@@ -198,10 +230,17 @@ func (s *blockService) AddBlocks(ctx context.Context, bs []blocks.Block) error {
198230
199231 // hash security
200232 for _ , b := range bs {
201- err := verifcid .ValidateCid (s .allowlist , b .Cid ())
233+ c := b .Cid ()
234+ err := verifcid .ValidateCid (s .allowlist , c )
202235 if err != nil {
203236 return err
204237 }
238+
239+ if s .blocker != nil {
240+ if err := s .blocker (c ); err != nil {
241+ return err
242+ }
243+ }
205244 }
206245 var toput []blocks.Block
207246 if s .checkFirst {
@@ -261,6 +300,12 @@ func getBlock(ctx context.Context, c cid.Cid, bs BlockService, fetchFactory func
261300 return nil , err
262301 }
263302
303+ if blocker := grabBlockerFromBlockservice (bs ); blocker != nil {
304+ if err := blocker (c ); err != nil {
305+ return nil , err
306+ }
307+ }
308+
264309 blockstore := bs .Blockstore ()
265310
266311 block , err := blockstore .Get (ctx , c )
@@ -320,13 +365,20 @@ func getBlocks(ctx context.Context, ks []cid.Cid, blockservice BlockService, fet
320365 defer close (out )
321366
322367 allowlist := grabAllowlistFromBlockservice (blockservice )
368+ blocker := grabBlockerFromBlockservice (blockservice )
323369
324370 var lastAllValidIndex int
325371 var c cid.Cid
326372 for lastAllValidIndex , c = range ks {
327373 if err := verifcid .ValidateCid (allowlist , c ); err != nil {
328374 break
329375 }
376+
377+ if blocker != nil {
378+ if err := blocker (c ); err != nil {
379+ break
380+ }
381+ }
330382 }
331383
332384 if lastAllValidIndex != len (ks ) {
@@ -335,11 +387,19 @@ func getBlocks(ctx context.Context, ks []cid.Cid, blockservice BlockService, fet
335387 copy (ks2 , ks [:lastAllValidIndex ]) // fast path for already filtered elements
336388 for _ , c := range ks [lastAllValidIndex :] { // don't rescan already scanned elements
337389 // 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 {
341391 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+ }
342400 }
401+
402+ ks2 = append (ks2 , c )
343403 }
344404 ks = ks2
345405 }
@@ -526,3 +586,10 @@ func grabAllowlistFromBlockservice(bs BlockService) verifcid.Allowlist {
526586 }
527587 return verifcid .DefaultAllowlist
528588}
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