Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v0.25.0 #746

Merged
merged 42 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
98850cf
Merge pull request #714 from ipfs/release
lidel Nov 7, 2024
1b8954c
Remove dependency on goprocess
gammazero Oct 30, 2024
4a077bc
client Close needs to return error
gammazero Oct 30, 2024
19d1d6b
Simplify provide woker goroutines
gammazero Nov 5, 2024
625aadd
Merge pull request #710 from ipfs/no-goprocess
gammazero Nov 7, 2024
1bf1488
feat(routing/http/server): expose prometheus metrics (#718)
2color Nov 19, 2024
e38f236
feat(routing/http/server): add routing timeout (#720)
2color Nov 19, 2024
6043002
fix: use more realistic size buckets for metrics
2color Nov 19, 2024
139b7a5
chore: update changelog
2color Nov 19, 2024
cfe68d8
docs: fix url of tracing env vars (#719)
2color Nov 19, 2024
5929aca
fix(bitswap/server): pass context to server engine to register metric…
gammazero Nov 19, 2024
b363199
docs: update CHANGELOG.md
lidel Nov 19, 2024
d228a3e
Merge branch 'main' into refine-buckets
gammazero Nov 19, 2024
13d0b32
fix(bitswap/client/providerquerymanager): use non-timed out context f…
aschmahmann Nov 19, 2024
55f0233
Merge branch 'main' into refine-buckets
2color Nov 20, 2024
138b596
Merge pull request #724 from ipfs:refine-buckets
2color Nov 21, 2024
c91cc1d
fix(bitswap/client/providerquerymanager): don't end trace span until …
gammazero Nov 21, 2024
37756ce
Bitswap: move providing -> Exchange-layer, providerQueryManager -> ro…
aschmahmann Nov 25, 2024
e2d2f36
fix(bitswap/client/msgq): prevent duplicate requests (#691)
Wondertan Nov 25, 2024
91c4d50
Tests can signal immediate rebroadcast (#726)
gammazero Nov 26, 2024
8673560
dspinner: RecursiveKeys(): do not hang on cancellations (#727)
hsanjuan Nov 26, 2024
821f539
chore: minor Improvements to providerquerymanager (#728)
gammazero Nov 27, 2024
cdefbf2
refactor: default to prometheus.DefaultRegisterer (#722)
lidel Nov 27, 2024
970dcb3
[skip changelog] staticcheck fixes / remove ununsed variables (#730)
hsanjuan Nov 27, 2024
33c7b9c
Add debug logging for deduplicated queries (#729)
gammazero Nov 27, 2024
b5656aa
bitswap/client: fix wiring when passing custom providerFinder
hsanjuan Nov 28, 2024
a6723bf
bitswap/client: add test using custom providerQueryManager
hsanjuan Nov 29, 2024
ef02abc
Merge pull request #732 from ipfs/fix/pqm-wiring
hsanjuan Nov 29, 2024
59fbac9
chore: fix invalid url in docs (#733)
hishope Nov 29, 2024
caa6763
misc comments and spelling (#735)
gammazero Dec 2, 2024
984fa89
chore: minor examples cleanup (#736)
gammazero Dec 2, 2024
9069a29
Bitswap default ProviderQueryManager uses explicit options (#737)
gammazero Dec 3, 2024
3a3e8af
refactor(remote/pinning): `Ls` to take results channel instead of ret…
gammazero Dec 3, 2024
6c7f2b7
chore: update to latest go-libp2p (#739)
gammazero Dec 3, 2024
5965637
feat(filestore): add mmap reader option (#665)
Dreamacro Dec 3, 2024
86120e2
feat(session): do not record erroneous session want sends (#452)
hannahhoward Dec 4, 2024
e9446bb
Reenable flaky bitswap tests (#740)
gammazero Dec 4, 2024
f6befaf
removed Startup function from ProviderQueryManager (#741)
gammazero Dec 5, 2024
ef25808
chore: no lifecycle context to shutdown ProviderQueryManager (#734)
gammazero Dec 6, 2024
9709204
Use deque instead of slice for queues (#742)
gammazero Dec 6, 2024
266017f
tidy changelog
gammazero Dec 9, 2024
87c3914
update version
gammazero Dec 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 77 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,80 @@ The following emojis are used to highlight certain changes:

### Security

## [v0.25.0]

- `bitswap`, `routing`, `exchange` ([#641](https://github.com/ipfs/boxo/pull/641)):
- ✨ Bitswap is no longer in charge of providing blocks to the newtork: providing functionality is now handled by a `exchange/providing.Exchange`, meant to be used with `provider.System` so that all provides follow the same rules (multiple parts of the code where handling provides) before.
- 🛠 `bitswap/client/internal/providerquerymanager` has been moved to `routing/providerquerymanager` where it belongs. In order to keep compatibility, Bitswap now receives a `routing.ContentDiscovery` parameter which implements `FindProvidersAsync(...)` and uses it to create a `providerquerymanager` with the default settings as before. Custom settings can be used by using a custom `providerquerymanager` to manually wrap a `ContentDiscovery` object and pass that in as `ContentDiscovery` on initialization while setting `bitswap.WithDefaultProviderQueryManager(false)` (to avoid re-wrapping it again).
- The renovated `providedQueryManager` will trigger lookups until it manages to connect to `MaxProviders`. Before it would lookup at most `MaxInProcessRequests*MaxProviders` and connection failures may have limited the actual number of providers found.
- 🛠 We have aligned our routing-related interfaces with the libp2p [`routing`](https://pkg.go.dev/github.com/libp2p/go-libp2p/core/routing#ContentRouting) ones, including in the `reprovider.System`.
- In order to obtain exactly the same behaviour as before (i.e. particularly ensuring that new blocks are still provided), what was done like:

```go
bswapnet := network.NewFromIpfsHost(host, contentRouter)
bswap := bitswap.New(p.ctx, bswapnet, blockstore)
bserv = blockservice.New(blockstore, bswap)
```
- becomes:

```go
// Create network: no contentRouter anymore
bswapnet := network.NewFromIpfsHost(host)
// Create Bitswap: a new "discovery" parameter, usually the "contentRouter"
// which does both discovery and providing.
bswap := bitswap.New(p.ctx, bswapnet, discovery, blockstore)
// A provider system that handles concurrent provides etc. "contentProvider"
// is usually the "contentRouter" which does both discovery and providing.
// "contentProvider" could be used directly without wrapping, but it is recommended
// to do so to provide more efficiently.
provider := provider.New(datastore, provider.Online(contentProvider)
// A wrapped providing exchange using the previous exchange and the provider.
exch := providing.New(bswap, provider)

// Finally the blockservice
bserv := blockservice.New(blockstore, exch)
...
```

- The above is only necessary if content routing is needed. Otherwise:

```go
// Create network: no contentRouter anymore
bswapnet := network.NewFromIpfsHost(host)
// Create Bitswap: a new "discovery" parameter set to nil (disable content discovery)
bswap := bitswap.New(p.ctx, bswapnet, nil, blockstore)
// Finally the blockservice
bserv := blockservice.New(blockstore, exch)
```



### Added

- `routing/http/server`: added built-in Prometheus instrumentation to http delegated `/routing/v1/` endpoints, with custom buckets for response size and duration to match real world data observed at [the `delegated-ipfs.dev` instance](https://docs.ipfs.tech/concepts/public-utilities/#delegated-routing). [#718](https://github.com/ipfs/boxo/pull/718) [#724](https://github.com/ipfs/boxo/pull/724)
- `routing/http/server`: added configurable routing timeout (`DefaultRoutingTimeout` being 30s) to prevent indefinite hangs during content/peer routing. Set custom duration via `WithRoutingTimeout`. [#720](https://github.com/ipfs/boxo/pull/720)
- `routing/http/server`: exposes Prometheus metrics on `prometheus.DefaultRegisterer` and a custom one can be provided via `WithPrometheusRegistry` [#722](https://github.com/ipfs/boxo/pull/722)
- `gateway`: `NewCacheBlockStore` and `NewCarBackend` will use `prometheus.DefaultRegisterer` when a custom one is not specified via `WithPrometheusRegistry` [#722](https://github.com/ipfs/boxo/pull/722)
- `filestore`: added opt-in `WithMMapReader` option to `FileManager` to enable memory-mapped file reads [#665](https://github.com/ipfs/boxo/pull/665)
- `bitswap/routing` `ProviderQueryManager` does not require calling `Startup` separate from `New`. [#741](https://github.com/ipfs/boxo/pull/741)
- `bitswap/routing` ProviderQueryManager does not use liftcycle context.

### Changed

- `routing/http/client`: creating delegated routing client with `New` now defaults to querying delegated routing server with `DefaultProtocolFilter` ([IPIP-484](https://github.com/ipfs/specs/pull/484)) [#689](https://github.com/ipfs/boxo/pull/689)
- `bitswap/client`: Wait at lease one broadcast interval before resending wants to a peer. Check for peers to rebroadcast to more often than one broadcast interval.
- No longer using `github.com/jbenet/goprocess` to avoid requiring in dependents. [#710](https://github.com/ipfs/boxo/pull/710)
- `pinning/remote/client`: Refactor remote pinning `Ls` to take results channel instead of returning one. The previous `Ls` behavior is implemented by the GoLs function, which creates the channels, starts the goroutine that calls Ls, and returns the channels to the caller [#738](https://github.com/ipfs/boxo/pull/738)
- updated to go-libp2p to [v0.37.2](https://github.com/libp2p/go-libp2p/releases/tag/v0.37.2)

### Removed

### Fixed

- Do not erroneously update the state of sent wants when a send a peer disconnected and the send did not happen. [#452](https://github.com/ipfs/boxo/pull/452)

### Security

## [v0.24.3]

### Changed
Expand Down Expand Up @@ -76,7 +150,8 @@ The following emojis are used to highlight certain changes:

### Fixed

- `unixfs/hamt` Log error instead of panic if both link and shard are nil [#393](https://github.com/ipfs/boxo/pull/393)
- `unixfs/hamt`: Log error instead of panic if both link and shard are nil [#393](https://github.com/ipfs/boxo/pull/393)
- `pinner/dspinner`: do not hang when listing keys and the `out` channel is no longer read [#727](https://github.com/ipfs/boxo/pull/727)

### Security

Expand Down Expand Up @@ -112,6 +187,7 @@ The following emojis are used to highlight certain changes:
- `bitswap/client` fix memory leak in BlockPresenceManager due to unlimited map growth. [#636](https://github.com/ipfs/boxo/pull/636)
- `bitswap/network` fixed race condition when a timeout occurred before hole punching completed while establishing a first-time stream to a peer behind a NAT [#651](https://github.com/ipfs/boxo/pull/651)
- `bitswap`: wantlist overflow handling now cancels existing entries to make room for newer entries. This fix prevents the wantlist from filling up with CIDs that the server does not have. [#629](https://github.com/ipfs/boxo/pull/629)
- 🛠 `bitswap` & `bitswap/server` no longer provide to content routers, instead you can use the `provider` package because it uses a datastore queue and batches calls to ProvideMany.

## [v0.21.0]

Expand Down
43 changes: 22 additions & 21 deletions bitswap/benchmarks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,16 @@ import (
"testing"
"time"

blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-test/random"
protocol "github.com/libp2p/go-libp2p/core/protocol"

"github.com/ipfs/boxo/bitswap"
bsnet "github.com/ipfs/boxo/bitswap/network"
testinstance "github.com/ipfs/boxo/bitswap/testinstance"
tn "github.com/ipfs/boxo/bitswap/testnet"
mockrouting "github.com/ipfs/boxo/routing/mock"
blocks "github.com/ipfs/go-block-format"
cid "github.com/ipfs/go-cid"
delay "github.com/ipfs/go-ipfs-delay"
"github.com/ipfs/go-test/random"
protocol "github.com/libp2p/go-libp2p/core/protocol"
)

type fetchFunc func(b *testing.B, bs *bitswap.Bitswap, ks []cid.Cid)
Expand Down Expand Up @@ -135,24 +134,25 @@ func BenchmarkFetchFromOldBitswap(b *testing.B) {
benchmarkLog = nil
fixedDelay := delay.Fixed(10 * time.Millisecond)
bstoreLatency := time.Duration(0)
router := mockrouting.NewServer()

for _, bch := range mixedBenches {
b.Run(bch.name, func(b *testing.B) {
fetcherCount := bch.fetcherCount
oldSeedCount := bch.oldSeedCount
newSeedCount := bch.nodeCount - (fetcherCount + oldSeedCount)

net := tn.VirtualNetwork(mockrouting.NewServer(), fixedDelay)
net := tn.VirtualNetwork(fixedDelay)

// Simulate an older Bitswap node (old protocol ID) that doesn't
// send DONT_HAVE responses
oldProtocol := []protocol.ID{bsnet.ProtocolBitswapOneOne}
oldNetOpts := []bsnet.NetOpt{bsnet.SupportedProtocols(oldProtocol)}
oldBsOpts := []bitswap.Option{bitswap.SetSendDontHaves(false)}
oldNodeGenerator := testinstance.NewTestInstanceGenerator(net, oldNetOpts, oldBsOpts)
oldNodeGenerator := testinstance.NewTestInstanceGenerator(net, router, oldNetOpts, oldBsOpts)

// Regular new Bitswap node
newNodeGenerator := testinstance.NewTestInstanceGenerator(net, nil, nil)
newNodeGenerator := testinstance.NewTestInstanceGenerator(net, router, nil, nil)
var instances []testinstance.Instance

// Create new nodes (fetchers + seeds)
Expand Down Expand Up @@ -294,9 +294,10 @@ func BenchmarkDatacenterMultiLeechMultiSeed(b *testing.B) {
numblks := 1000

for i := 0; i < b.N; i++ {
net := tn.RateLimitedVirtualNetwork(mockrouting.NewServer(), d, rateLimitGenerator)
net := tn.RateLimitedVirtualNetwork(d, rateLimitGenerator)

ig := testinstance.NewTestInstanceGenerator(net, nil, nil)
router := mockrouting.NewServer()
ig := testinstance.NewTestInstanceGenerator(net, router, nil, nil)
defer ig.Close()

instances := ig.Instances(numnodes)
Expand All @@ -312,9 +313,9 @@ func BenchmarkDatacenterMultiLeechMultiSeed(b *testing.B) {

func subtestDistributeAndFetch(b *testing.B, numnodes, numblks int, d delay.D, bstoreLatency time.Duration, df distFunc, ff fetchFunc) {
for i := 0; i < b.N; i++ {
net := tn.VirtualNetwork(mockrouting.NewServer(), d)

ig := testinstance.NewTestInstanceGenerator(net, nil, nil)
net := tn.VirtualNetwork(d)
router := mockrouting.NewServer()
ig := testinstance.NewTestInstanceGenerator(net, router, nil, nil)

instances := ig.Instances(numnodes)
rootBlock := random.BlocksOfSize(1, rootBlockSize)
Expand All @@ -327,9 +328,9 @@ func subtestDistributeAndFetch(b *testing.B, numnodes, numblks int, d delay.D, b

func subtestDistributeAndFetchRateLimited(b *testing.B, numnodes, numblks int, d delay.D, rateLimitGenerator tn.RateLimitGenerator, blockSize int64, bstoreLatency time.Duration, df distFunc, ff fetchFunc) {
for i := 0; i < b.N; i++ {
net := tn.RateLimitedVirtualNetwork(mockrouting.NewServer(), d, rateLimitGenerator)

ig := testinstance.NewTestInstanceGenerator(net, nil, nil)
net := tn.RateLimitedVirtualNetwork(d, rateLimitGenerator)
router := mockrouting.NewServer()
ig := testinstance.NewTestInstanceGenerator(net, router, nil, nil)
defer ig.Close()

instances := ig.Instances(numnodes)
Expand Down Expand Up @@ -437,7 +438,7 @@ func runDistribution(b *testing.B, instances []testinstance.Instance, blocks []b

func allToAll(b *testing.B, provs []testinstance.Instance, blocks []blocks.Block) {
for _, p := range provs {
if err := p.Blockstore().PutMany(context.Background(), blocks); err != nil {
if err := p.Blockstore.PutMany(context.Background(), blocks); err != nil {
b.Fatal(err)
}
}
Expand All @@ -452,10 +453,10 @@ func overlap1(b *testing.B, provs []testinstance.Instance, blks []blocks.Block)
bill := provs[0]
jeff := provs[1]

if err := bill.Blockstore().PutMany(context.Background(), blks[:75]); err != nil {
if err := bill.Blockstore.PutMany(context.Background(), blks[:75]); err != nil {
b.Fatal(err)
}
if err := jeff.Blockstore().PutMany(context.Background(), blks[25:]); err != nil {
if err := jeff.Blockstore.PutMany(context.Background(), blks[25:]); err != nil {
b.Fatal(err)
}
}
Expand All @@ -473,12 +474,12 @@ func overlap2(b *testing.B, provs []testinstance.Instance, blks []blocks.Block)
even := i%2 == 0
third := i%3 == 0
if third || even {
if err := bill.Blockstore().Put(context.Background(), blk); err != nil {
if err := bill.Blockstore.Put(context.Background(), blk); err != nil {
b.Fatal(err)
}
}
if third || !even {
if err := jeff.Blockstore().Put(context.Background(), blk); err != nil {
if err := jeff.Blockstore.Put(context.Background(), blk); err != nil {
b.Fatal(err)
}
}
Expand All @@ -490,7 +491,7 @@ func overlap2(b *testing.B, provs []testinstance.Instance, blks []blocks.Block)
// but we're mostly just testing performance of the sync algorithm
func onePeerPerBlock(b *testing.B, provs []testinstance.Instance, blks []blocks.Block) {
for _, blk := range blks {
err := provs[rand.Intn(len(provs))].Blockstore().Put(context.Background(), blk)
err := provs[rand.Intn(len(provs))].Blockstore.Put(context.Background(), blk)
if err != nil {
b.Fatal(err)
}
Expand Down
23 changes: 7 additions & 16 deletions bitswap/bitswap.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"

"github.com/ipfs/boxo/bitswap/client"
"github.com/ipfs/boxo/bitswap/internal/defaults"
"github.com/ipfs/boxo/bitswap/message"
"github.com/ipfs/boxo/bitswap/network"
"github.com/ipfs/boxo/bitswap/server"
Expand Down Expand Up @@ -45,9 +44,8 @@ type bitswap interface {
}

var (
_ exchange.SessionExchange = (*Bitswap)(nil)
_ bitswap = (*Bitswap)(nil)
HasBlockBufferSize = defaults.HasBlockBufferSize
_ exchange.SessionExchange = (*Bitswap)(nil)
_ bitswap = (*Bitswap)(nil)
)

type Bitswap struct {
Expand All @@ -58,7 +56,7 @@ type Bitswap struct {
net network.BitSwapNetwork
}

func New(ctx context.Context, net network.BitSwapNetwork, bstore blockstore.Blockstore, options ...Option) *Bitswap {
func New(ctx context.Context, net network.BitSwapNetwork, providerFinder client.ProviderFinder, bstore blockstore.Blockstore, options ...Option) *Bitswap {
bs := &Bitswap{
net: net,
}
Expand All @@ -85,14 +83,10 @@ func New(ctx context.Context, net network.BitSwapNetwork, bstore blockstore.Bloc
serverOptions = append(serverOptions, server.WithTracer(tracer))
}

if HasBlockBufferSize != defaults.HasBlockBufferSize {
serverOptions = append(serverOptions, server.HasBlockBufferSize(HasBlockBufferSize))
}

ctx = metrics.CtxSubScope(ctx, "bitswap")

bs.Server = server.New(ctx, net, bstore, serverOptions...)
bs.Client = client.New(ctx, net, bstore, append(clientOptions, client.WithBlockReceivedNotifier(bs.Server))...)
bs.Client = client.New(ctx, net, providerFinder, bstore, append(clientOptions, client.WithBlockReceivedNotifier(bs.Server))...)
net.Start(bs) // use the polyfill receiver to log received errors and trace messages only once

return bs
Expand All @@ -115,7 +109,6 @@ type Stat struct {
MessagesReceived uint64
BlocksSent uint64
DataSent uint64
ProvideBufLen int
}

func (bs *Bitswap) Stat() (*Stat, error) {
Expand All @@ -138,16 +131,14 @@ func (bs *Bitswap) Stat() (*Stat, error) {
Peers: ss.Peers,
BlocksSent: ss.BlocksSent,
DataSent: ss.DataSent,
ProvideBufLen: ss.ProvideBufLen,
}, nil
}

func (bs *Bitswap) Close() error {
bs.net.Stop()
return multierr.Combine(
bs.Client.Close(),
bs.Server.Close(),
)
bs.Client.Close()
bs.Server.Close()
return nil
}

func (bs *Bitswap) WantlistForPeer(p peer.ID) []cid.Cid {
Expand Down
Loading
Loading