Skip to content

Commit 98486ac

Browse files
committed
fix!: move block event reporting to bitswap's blockstore
BREAKING CHANGE because the signature of NewByteCountingLinkSystem has changed to include a peer.ID. We need to report BlockReceived events from the immediate blockstore that bitswap writes to so we don't incur a delay and have our preload cache race to report it's got the block before our "loader" has time to register it has it.
1 parent 9613e24 commit 98486ac

File tree

4 files changed

+48
-28
lines changed

4 files changed

+48
-28
lines changed

pkg/retriever/bitswaphelpers/countinglinksystem.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55

66
"github.com/ipld/go-ipld-prime/datamodel"
77
"github.com/ipld/go-ipld-prime/linking"
8+
"github.com/libp2p/go-libp2p/core/peer"
89
)
910

1011
type cumulativeCountWriter struct {
@@ -32,15 +33,19 @@ func (ccw *cumulativeCountWriter) Commit(link datamodel.Link) error {
3233
return nil
3334
}
3435

35-
func NewByteCountingLinkSystem(lsys *linking.LinkSystem, bytesWritten func(count uint64)) *linking.LinkSystem {
36+
func NewByteCountingLinkSystem(lsys *linking.LinkSystem, blockWritten func(from *peer.ID, count uint64)) *linking.LinkSystem {
3637
newLsys := *lsys // copy all values from old system
3738
oldWriteOpener := lsys.StorageWriteOpener
3839
newLsys.StorageWriteOpener = func(lctx linking.LinkContext) (io.Writer, linking.BlockWriteCommitter, error) {
40+
var from *peer.ID = nil
41+
if p, ok := lctx.Ctx.Value(peerIdContextKey).(peer.ID); ok {
42+
from = &p
43+
}
3944
w, committer, err := oldWriteOpener(lctx)
4045
if err != nil {
4146
return w, committer, err
4247
}
43-
ccw := &cumulativeCountWriter{w, 0, committer, bytesWritten}
48+
ccw := &cumulativeCountWriter{w, 0, committer, func(count uint64) { blockWritten(from, count) }}
4449
return ccw, ccw.Commit, err
4550
}
4651
return &newLsys

pkg/retriever/bitswaphelpers/multiblockstore.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"sync"
88

99
"github.com/filecoin-project/lassie/pkg/types"
10+
"github.com/ipfs/boxo/bitswap/client/traceability"
1011
blocks "github.com/ipfs/go-block-format"
1112
"github.com/ipfs/go-cid"
1213
format "github.com/ipfs/go-ipld-format"
@@ -23,6 +24,10 @@ var ErrAlreadyRegisterd = errors.New("already registered")
2324
// ErrAlreadyRegistered means there is nothing registered for a retrieval id
2425
var ErrNotRegistered = errors.New("not registered")
2526

27+
type contextKey string
28+
29+
const peerIdContextKey = contextKey("traceableBlock.peerId")
30+
2631
// MultiBlockstore creates a blockstore based on one or more linkystems, extracting the target linksystem for each request
2732
// from the retrieval id context key
2833
type MultiBlockstore struct {
@@ -123,7 +128,13 @@ func (mbs *MultiBlockstore) PutMany(ctx context.Context, blks []blocks.Block) er
123128
return ErrNotRegistered
124129
}
125130
for _, blk := range blks {
126-
w, commit, err := lsys.StorageWriteOpener(linking.LinkContext{Ctx: ctx})
131+
lctx := ctx
132+
if traceableBlock, ok := blk.(traceability.Block); ok {
133+
lctx = context.WithValue(lctx, peerIdContextKey, traceableBlock.From)
134+
} else {
135+
logger.Warn("Got untraceable block from bitswap")
136+
}
137+
w, commit, err := lsys.StorageWriteOpener(linking.LinkContext{Ctx: lctx})
127138
if err != nil {
128139
return err
129140
}

pkg/retriever/bitswaphelpers/preloadcachingstorage.go

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -362,18 +362,25 @@ func (cs *PreloadCachingStorage) preloadLink(pl *preloadingLink, linkCtx linking
362362
}
363363
pl.err = err
364364
} else {
365-
w, c, err := cs.cacheLinkSystem.StorageWriteOpener(linkCtx)
366-
if err != nil {
367-
pl.err = err
368-
return
369-
}
370-
if _, err := io.Copy(w, reader); err != nil {
371-
pl.err = err
372-
return
373-
}
374-
if err := c(link); err != nil {
365+
// the user of PreloadCachingStorage may have already wired up the
366+
// cacheLinkSystem to receive the blocks from fetcher()
367+
if has, err := linkSystemHas(cs.cacheLinkSystem, linkCtx, link); err != nil {
375368
pl.err = err
376369
return
370+
} else if !has {
371+
w, c, err := cs.cacheLinkSystem.StorageWriteOpener(linkCtx)
372+
if err != nil {
373+
pl.err = err
374+
return
375+
}
376+
if _, err := io.Copy(w, reader); err != nil {
377+
pl.err = err
378+
return
379+
}
380+
if err := c(link); err != nil {
381+
pl.err = err
382+
return
383+
}
377384
}
378385
}
379386
})

pkg/retriever/bitswapretriever.go

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
"github.com/filecoin-project/lassie/pkg/retriever/bitswaphelpers/groupworkpool"
1717
"github.com/filecoin-project/lassie/pkg/types"
1818
"github.com/ipfs/boxo/bitswap/client"
19-
"github.com/ipfs/boxo/bitswap/client/traceability"
2019
"github.com/ipfs/boxo/bitswap/network"
2120
"github.com/ipfs/boxo/blockservice"
2221
"github.com/ipfs/go-cid"
@@ -184,13 +183,22 @@ func (br *bitswapRetrieval) runRetrieval(ctx context.Context, ayncCandidates typ
184183

185184
totalWritten := atomic.Uint64{}
186185
blockCount := atomic.Uint64{}
187-
bytesWrittenCb := func(bytesWritten uint64) {
186+
blockWrittenCb := func(from *peer.ID, bytesWritten uint64) {
188187
// record first byte received
189188
if totalWritten.Load() == 0 {
190189
shared.sendEvent(ctx, events.FirstByte(br.clock.Now(), br.request.RetrievalID, bitswapCandidate, br.clock.Since(startTime), multicodec.TransportBitswap))
191190
}
192191
totalWritten.Add(bytesWritten)
193192
blockCount.Add(1)
193+
if from != nil {
194+
shared.sendEvent(ctx, events.BlockReceived(
195+
br.clock.Now(),
196+
br.request.RetrievalID,
197+
types.RetrievalCandidate{RootCid: br.request.Root, MinerPeer: peer.AddrInfo{ID: *from}},
198+
multicodec.TransportBitswap,
199+
bytesWritten,
200+
))
201+
}
194202
// reset the timer
195203
if bytesWritten > 0 && lastBytesReceivedTimer != nil {
196204
lastBytesReceivedTimer.Reset(br.cfg.BlockTimeout)
@@ -253,12 +261,12 @@ func (br *bitswapRetrieval) runRetrieval(ctx context.Context, ayncCandidates typ
253261

254262
br.bstore.AddLinkSystem(
255263
br.request.RetrievalID,
256-
bitswaphelpers.NewByteCountingLinkSystem(storage.BitswapLinkSystem, bytesWrittenCb),
264+
bitswaphelpers.NewByteCountingLinkSystem(storage.BitswapLinkSystem, blockWrittenCb),
257265
)
258266
} else {
259267
br.bstore.AddLinkSystem(
260268
br.request.RetrievalID,
261-
bitswaphelpers.NewByteCountingLinkSystem(&br.request.LinkSystem, bytesWrittenCb),
269+
bitswaphelpers.NewByteCountingLinkSystem(&br.request.LinkSystem, blockWrittenCb),
262270
)
263271
traversalLinkSys.StorageReadOpener = loader
264272
}
@@ -347,17 +355,6 @@ func (br *bitswapRetrieval) loader(ctx context.Context, shared *retrievalShared)
347355
return nil, err
348356
}
349357
logger.Debugw("Got block from bitswap", "retrievalID", br.request.RetrievalID, "root", br.request.Root, "block", cidLink.Cid, "size", len(blk.RawData()))
350-
if traceableBlock, ok := blk.(traceability.Block); ok {
351-
shared.sendEvent(ctx, events.BlockReceived(
352-
br.clock.Now(),
353-
br.request.RetrievalID,
354-
types.RetrievalCandidate{RootCid: br.request.Root, MinerPeer: peer.AddrInfo{ID: traceableBlock.From}},
355-
multicodec.TransportBitswap,
356-
uint64(len(blk.RawData()))),
357-
)
358-
} else {
359-
logger.Warn("Got untraceable block from bitswap")
360-
}
361358
return bytes.NewReader(blk.RawData()), nil
362359
}
363360
}

0 commit comments

Comments
 (0)