From ddd4ba7a65c089f6005382eb682a32e61c3000dd Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 28 Dec 2023 19:44:06 +0100 Subject: [PATCH] blockservice: add WithProvider option This allows to recreate the behavior of advertising added blocks the bitswap server used to do. --- CHANGELOG.md | 1 + blockservice/blockservice.go | 36 +++++++++++++++++++++++++++++++ blockservice/blockservice_test.go | 28 ++++++++++++++++++++++++ examples/go.mod | 1 + examples/go.sum | 2 ++ 5 files changed, 68 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2328d9d25..673f44f98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The following emojis are used to highlight certain changes: - `blockservice` now has `ContextWithSession` and `EmbedSessionInContext` functions, which allows to embed a session in a context. Future calls to `BlockGetter.GetBlock`, `BlockGetter.GetBlocks` and `NewSession` will use the session in the context. - `blockservice.NewWritethrough` deprecated function has been removed, instead you can do `blockservice.New(..., ..., WriteThrough())` like previously. - `blockservice` now has `WithContentBlocker` option which allows to filter Add and Get requests by CID. +- `blockservice` now have a `WithProvider` option, this allows to recreate the behavior of advertising added blocks the bitswap server used to do. ### Changed diff --git a/blockservice/blockservice.go b/blockservice/blockservice.go index 4cac1d87f..4211df610 100644 --- a/blockservice/blockservice.go +++ b/blockservice/blockservice.go @@ -12,6 +12,7 @@ import ( "github.com/ipfs/boxo/blockstore" "github.com/ipfs/boxo/exchange" + "github.com/ipfs/boxo/provider" "github.com/ipfs/boxo/verifcid" blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" @@ -50,6 +51,7 @@ type BlockService struct { blocker Blocker blockstore blockstore.Blockstore exchange exchange.Interface + provider provider.Provider // If checkFirst is true then first check that a block doesn't // already exist to avoid republishing the block on the exchange. checkFirst bool @@ -79,6 +81,13 @@ func WithContentBlocker(blocker Blocker) Option { } } +// WithProvider allows to advertise anything that is added through the blockservice. +func WithProvider(prov provider.Provider) Option { + return func(bs *BlockService) { + bs.provider = prov + } +} + // New creates a BlockService with given datastore instance. func New(bs blockstore.Blockstore, exchange exchange.Interface, opts ...Option) *BlockService { if exchange == nil { @@ -153,6 +162,11 @@ func (s *BlockService) AddBlock(ctx context.Context, o blocks.Block) error { logger.Errorf("NotifyNewBlocks: %s", err.Error()) } } + if s.provider != nil { + if err := s.provider.Provide(o.Cid()); err != nil { + logger.Errorf("Provide: %s", err.Error()) + } + } return nil } @@ -206,6 +220,14 @@ func (s *BlockService) AddBlocks(ctx context.Context, bs []blocks.Block) error { logger.Errorf("NotifyNewBlocks: %s", err.Error()) } } + if s.provider != nil { + for _, o := range toput { + if err := s.provider.Provide(o.Cid()); err != nil { + logger.Errorf("Provide: %s", err.Error()) + } + } + } + return nil } @@ -271,6 +293,12 @@ func (s *BlockService) getBlock(ctx context.Context, c cid.Cid, fetchFactory fun return nil, err } } + if s.provider != nil { + err = s.provider.Provide(blk.Cid()) + if err != nil { + return nil, err + } + } logger.Debugf("BlockService.BlockFetched %s", c) return blk, nil } @@ -388,6 +416,14 @@ func (s *BlockService) getBlocks(ctx context.Context, ks []cid.Cid, fetchFactory cache[0] = nil // early gc } + if s.provider != nil { + err = s.provider.Provide(b.Cid()) + if err != nil { + logger.Errorf("could not tell the provider about new blocks: %s", err) + return + } + } + select { case out <- b: case <-ctx.Done(): diff --git a/blockservice/blockservice_test.go b/blockservice/blockservice_test.go index 16dd92940..9c768b316 100644 --- a/blockservice/blockservice_test.go +++ b/blockservice/blockservice_test.go @@ -423,3 +423,31 @@ func TestBlocker(t *testing.T) { } a.True(gotAllowed, "did not got allowed block") } + +type mockProvider []cid.Cid + +func (p *mockProvider) Provide(c cid.Cid) error { + *p = append(*p, c) + return nil +} + +func TestProviding(t *testing.T) { + t.Parallel() + a := assert.New(t) + + bgen := butil.NewBlockGenerator() + blocks := bgen.Blocks(3) + + prov := mockProvider{} + blockservice := New(blockstore.NewBlockstore(dssync.MutexWrap(ds.NewMapDatastore())), nil, WithProvider(&prov)) + var added []cid.Cid + + a.NoError(blockservice.AddBlock(context.Background(), blocks[0])) + added = append(added, blocks[0].Cid()) + + a.NoError(blockservice.AddBlocks(context.Background(), blocks[1:])) + added = append(added, blocks[1].Cid()) + added = append(added, blocks[2].Cid()) + + a.ElementsMatch(added, []cid.Cid(prov)) +} diff --git a/examples/go.mod b/examples/go.mod index 6c0630543..7b91ade2a 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -60,6 +60,7 @@ require ( github.com/huin/goupnp v1.3.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect + github.com/ipfs/go-cidutil v0.1.0 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect diff --git a/examples/go.sum b/examples/go.sum index cfb0944d0..725c2e244 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -167,6 +167,8 @@ github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4 github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= +github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q= +github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=