Skip to content

Commit 77fb828

Browse files
authored
Merge pull request #417 from ipfs/release-v0.11.0
Release v0.11.0
2 parents 61f2939 + 7c4111d commit 77fb828

File tree

158 files changed

+2866
-16707
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

158 files changed

+2866
-16707
lines changed

.github/pull_request_template.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<!--
2-
PR Creation Checklist
3-
- [ ] Update Changelog
2+
Please update the CHANGELOG.md if you're modifying Go files. If your change does not require a changelog entry, please do one of the following:
3+
- add `[skip changelog]` to the PR title
4+
- label the PR with `skip/changelog`
45
-->

.github/workflows/changelog.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Changelog
2+
3+
on:
4+
pull_request:
5+
types:
6+
- opened
7+
- edited
8+
- synchronize
9+
- reopened
10+
- labeled
11+
- unlabeled
12+
paths:
13+
- '**.go'
14+
- '**/go.mod'
15+
- '**/go.sum'
16+
17+
jobs:
18+
changelog:
19+
if: contains(github.event.pull_request.title, '[skip changelog]') == false &&
20+
contains(github.event.pull_request.labels.*.name, 'skip/changelog') == false
21+
runs-on: ubuntu-latest
22+
name: Changelog
23+
steps:
24+
- id: changelog
25+
env:
26+
GITHUB_TOKEN: ${{ github.token }}
27+
ENDPOINT: repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files
28+
SELECTOR: 'map(select(.filename == "CHANGELOG.md")) | length'
29+
run: gh api "$ENDPOINT" --jq "$SELECTOR" | xargs -I{} echo "modified={}" | tee -a $GITHUB_OUTPUT
30+
- if: steps.changelog.outputs.modified == '0'
31+
env:
32+
MESSAGE: |
33+
CHANGELOG.md was not modified in this PR. Please do one of the following:
34+
- add a changelog entry
35+
- add `[skip changelog]` to the PR title
36+
- label the PR with `skip/changelog`
37+
run: |
38+
echo "::error::${MESSAGE//$'\n'/%0A}"
39+
exit 1

.github/workflows/gateway-conformance.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
steps:
1717
# 1. Download the gateway-conformance fixtures
1818
- name: Download gateway-conformance fixtures
19-
uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.1
19+
uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.2
2020
with:
2121
output: fixtures
2222
merged: true
@@ -40,15 +40,15 @@ jobs:
4040

4141
# 4. Run the gateway-conformance tests
4242
- name: Run gateway-conformance tests
43-
uses: ipfs/gateway-conformance/.github/actions/test@v0.1
43+
uses: ipfs/gateway-conformance/.github/actions/test@v0.2
4444
with:
4545
gateway-url: http://127.0.0.1:8040
4646
json: output.json
4747
xml: output.xml
4848
html: output.html
4949
markdown: output.md
5050
subdomain-url: http://example.net
51-
specs: -dnslink-resolver,-ipns-resolver
51+
specs: -trustless-ipns-gateway,-path-ipns-gateway,-subdomain-ipns-gateway,-dnslink-gateway
5252
args: -skip 'TestGatewayCar/GET_response_for_application/vnd.ipld.car/Header_Content-Length'
5353

5454
# 5. Upload the results

.github/workflows/stale.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ name: Close and mark stale issue
22

33
on:
44
schedule:
5-
- cron: '0 0 * * *'
5+
- cron: '0 0 * * *'
6+
7+
permissions:
8+
issues: write
9+
pull-requests: write
610

711
jobs:
812
stale:

CHANGELOG.md

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,48 @@ The following emojis are used to highlight certain changes:
2424

2525
### Security
2626

27+
## [v0.11.0]
28+
29+
### Added
30+
31+
* ✨ The gateway now supports the optional `order` and `dups` CAR parameters
32+
from [IPIP-412](https://github.com/ipfs/specs/pull/412).
33+
* The `BlocksBackend` only implements `order=dfs` (Depth-First Search)
34+
ordering, which was already the default behavior.
35+
* If a request specifies no `dups`, response with `dups=n` is returned, which
36+
was already the default behavior.
37+
* If a request explicitly specifies a CAR `order` other than `dfs`, it will
38+
result in an error.
39+
* The only change to the default behavior on CAR responses is that we follow
40+
IPIP-412 and make `order=dfs;dups=n` explicit in the returned
41+
`Content-Type` HTTP header.
42+
* ✨ While the call signature remains the same, the blocks that Bitswap returns can now be cast to [traceability.Block](./bitswap/client/traceability/block.go), which will additionally tell you where the Block came from and how long it took to fetch. This helps consumers of Bitswap collect better metrics on Bitswap behavior.
43+
44+
### Changed
45+
46+
* 🛠 The `ipns` package has been refactored.
47+
* You should no longer use the direct Protobuf version of the IPNS Record.
48+
Instead, we have a shiny new `ipns.Record` type that wraps all the required
49+
functionality to work the best as possible with IPNS v2 Records. Please
50+
check the [documentation](https://pkg.go.dev/github.com/ipfs/boxo/ipns) for
51+
more information, and follow
52+
[ipfs/specs#376](https://github.com/ipfs/specs/issues/376) for related
53+
IPIP.
54+
* There is no change to IPNS Records produced by `boxo/ipns`, it still
55+
produces both V1 and V2 signatures by default, it is still backward-compatible.
56+
57+
### Removed
58+
59+
- 🛠 `ipld/car` has been removed. Please use [ipld/go-car](https://github.com/ipld/go-car) instead.
60+
More information regarding this decision can be found in [issue 218](https://github.com/ipfs/boxo/issues/218).
61+
62+
### Fixed
63+
64+
- Removed mentions of unused ARC algorithm ([#336](https://github.com/ipfs/boxo/issues/366#issuecomment-1597253540))
65+
- Handle `_redirects` file when `If-None-Match` header is present ([#412](https://github.com/ipfs/boxo/pull/412))
66+
67+
### Security
68+
2769
## [0.10.2] - 2023-06-29
2870

2971
### Fixed
@@ -105,8 +147,9 @@ None.
105147
- `RecursiveKeys`
106148
- `InternalKeys`
107149
- 🛠 `provider/batched.New` has been moved to `provider.New` and arguments has been changed. (https://github.com/ipfs/boxo/pulls/273)
108-
- a routing system is now passed with the `provider.Online` option, by default the system run in offline mode (push stuff onto the queue); and
109-
- you do not have to pass a queue anymore, you pass a `datastore.Datastore` exclusively.
150+
- A routing system is now passed with the `provider.Online` option, by default the system run in offline mode (push stuff onto the queue).
151+
- When using `provider.Online` calling the `.Run` method is not required anymore, the background worker is implicitely started in the background by `provider.New`.
152+
- You do not have to pass a queue anymore, you pass a `datastore.Datastore` exclusively.
110153
- 🛠 `provider.NewOfflineProvider` has been renamed to `provider.NewNoopProvider` to show more clearly that is does nothing. (https://github.com/ipfs/boxo/pulls/273)
111154
- 🛠 `provider.Provider` and `provider.Reprovider` has been merged under one `provider.System`. (https://github.com/ipfs/boxo/pulls/273)
112155
- 🛠 `routing/http` responses now return a streaming `iter.ResultIter` generic interface. (https://github.com/ipfs/boxo/pulls/18)

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
<h1 align="center">
2-
Boxo 🍌
3-
<br>
4-
<img src="https://raw.githubusercontent.com/ipfs/boxo/main/logo.svg" alt="Boxo logo" title="Boxo logo" width="200">
2+
<img src="https://github.com/ipfs/boxo/assets/157609/3c5e7391-fbc2-405b-9efc-920f4fd13b39" alt="Boxo logo" title="Boxo logo" width="200">
53
<br>
4+
BOXO: IPFS SDK for GO
65
</h1>
7-
<p align="center" style="font-size: 1.2rem;">A library for building IPFS applications and implementations.</p>
6+
<p align="center" style="font-size: 1.2rem;">A set of libraries for building IPFS applications and implementations in GO.</p>
87

98
<hr />
109

bitswap/client/bitswap_with_sessions_test.go

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/ipfs/boxo/bitswap"
1010
"github.com/ipfs/boxo/bitswap/client/internal/session"
11+
"github.com/ipfs/boxo/bitswap/client/traceability"
1112
testinstance "github.com/ipfs/boxo/bitswap/testinstance"
1213
tn "github.com/ipfs/boxo/bitswap/testnet"
1314
"github.com/ipfs/boxo/internal/test"
@@ -17,6 +18,7 @@ import (
1718
blocksutil "github.com/ipfs/go-ipfs-blocksutil"
1819
delay "github.com/ipfs/go-ipfs-delay"
1920
tu "github.com/libp2p/go-libp2p-testing/etc"
21+
"github.com/libp2p/go-libp2p/core/peer"
2022
)
2123

2224
func getVirtualNetwork() tn.Network {
@@ -71,16 +73,32 @@ func TestBasicSessions(t *testing.T) {
7173
if !blkout.Cid().Equals(block.Cid()) {
7274
t.Fatal("got wrong block")
7375
}
76+
77+
traceBlock, ok := blkout.(traceability.Block)
78+
if !ok {
79+
t.Fatal("did not get tracable block")
80+
}
81+
82+
if traceBlock.From != b.Peer {
83+
t.Fatal("should have received block from peer B, did not")
84+
}
7485
}
7586

76-
func assertBlockLists(got, exp []blocks.Block) error {
87+
func assertBlockListsFrom(from peer.ID, got, exp []blocks.Block) error {
7788
if len(got) != len(exp) {
7889
return fmt.Errorf("got wrong number of blocks, %d != %d", len(got), len(exp))
7990
}
8091

8192
h := cid.NewSet()
8293
for _, b := range got {
8394
h.Add(b.Cid())
95+
traceableBlock, ok := b.(traceability.Block)
96+
if !ok {
97+
return fmt.Errorf("not a traceable block: %s", b.Cid())
98+
}
99+
if traceableBlock.From != from {
100+
return fmt.Errorf("incorrect peer sent block, expect %s, got %s", from, traceableBlock.From)
101+
}
84102
}
85103
for _, b := range exp {
86104
if !h.Has(b.Cid()) {
@@ -133,7 +151,7 @@ func TestSessionBetweenPeers(t *testing.T) {
133151
for b := range ch {
134152
got = append(got, b)
135153
}
136-
if err := assertBlockLists(got, blks[i*10:(i+1)*10]); err != nil {
154+
if err := assertBlockListsFrom(inst[0].Peer, got, blks[i*10:(i+1)*10]); err != nil {
137155
t.Fatal(err)
138156
}
139157
}
@@ -192,7 +210,7 @@ func TestSessionSplitFetch(t *testing.T) {
192210
for b := range ch {
193211
got = append(got, b)
194212
}
195-
if err := assertBlockLists(got, blks[i*10:(i+1)*10]); err != nil {
213+
if err := assertBlockListsFrom(inst[i].Peer, got, blks[i*10:(i+1)*10]); err != nil {
196214
t.Fatal(err)
197215
}
198216
}
@@ -238,7 +256,7 @@ func TestFetchNotConnected(t *testing.T) {
238256
for b := range ch {
239257
got = append(got, b)
240258
}
241-
if err := assertBlockLists(got, blks); err != nil {
259+
if err := assertBlockListsFrom(other.Peer, got, blks); err != nil {
242260
t.Fatal(err)
243261
}
244262
}
@@ -289,7 +307,7 @@ func TestFetchAfterDisconnect(t *testing.T) {
289307
got = append(got, b)
290308
}
291309

292-
if err := assertBlockLists(got, blks[:5]); err != nil {
310+
if err := assertBlockListsFrom(peerA.Peer, got, blks[:5]); err != nil {
293311
t.Fatal(err)
294312
}
295313

@@ -318,7 +336,7 @@ func TestFetchAfterDisconnect(t *testing.T) {
318336
}
319337
}
320338

321-
if err := assertBlockLists(got, blks); err != nil {
339+
if err := assertBlockListsFrom(peerA.Peer, got, blks); err != nil {
322340
t.Fatal(err)
323341
}
324342
}

bitswap/client/client.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,9 @@ package client
55
import (
66
"context"
77
"errors"
8-
98
"sync"
109
"time"
1110

12-
delay "github.com/ipfs/go-ipfs-delay"
13-
"go.opentelemetry.io/otel/attribute"
14-
"go.opentelemetry.io/otel/trace"
15-
1611
bsbpm "github.com/ipfs/boxo/bitswap/client/internal/blockpresencemanager"
1712
bsgetter "github.com/ipfs/boxo/bitswap/client/internal/getter"
1813
bsmq "github.com/ipfs/boxo/bitswap/client/internal/messagequeue"
@@ -33,11 +28,14 @@ import (
3328
exchange "github.com/ipfs/boxo/exchange"
3429
blocks "github.com/ipfs/go-block-format"
3530
"github.com/ipfs/go-cid"
31+
delay "github.com/ipfs/go-ipfs-delay"
3632
logging "github.com/ipfs/go-log/v2"
3733
"github.com/ipfs/go-metrics-interface"
3834
process "github.com/jbenet/goprocess"
3935
procctx "github.com/jbenet/goprocess/context"
4036
"github.com/libp2p/go-libp2p/core/peer"
37+
"go.opentelemetry.io/otel/attribute"
38+
"go.opentelemetry.io/otel/trace"
4139
)
4240

4341
var log = logging.Logger("bitswap-client")
@@ -239,6 +237,7 @@ type counters struct {
239237

240238
// GetBlock attempts to retrieve a particular block from peers within the
241239
// deadline enforced by the context.
240+
// It returns a [github.com/ipfs/boxo/bitswap/client/traceability.Block] assertable [blocks.Block].
242241
func (bs *Client) GetBlock(ctx context.Context, k cid.Cid) (blocks.Block, error) {
243242
ctx, span := internal.StartSpan(ctx, "GetBlock", trace.WithAttributes(attribute.String("Key", k.String())))
244243
defer span.End()
@@ -248,6 +247,7 @@ func (bs *Client) GetBlock(ctx context.Context, k cid.Cid) (blocks.Block, error)
248247
// GetBlocks returns a channel where the caller may receive blocks that
249248
// correspond to the provided |keys|. Returns an error if BitSwap is unable to
250249
// begin this request within the deadline enforced by the context.
250+
// It returns a [github.com/ipfs/boxo/bitswap/client/traceability.Block] assertable [blocks.Block].
251251
//
252252
// NB: Your request remains open until the context expires. To conserve
253253
// resources, provide a context with a reasonably short deadline (ie. not one
@@ -284,7 +284,8 @@ func (bs *Client) NotifyNewBlocks(ctx context.Context, blks ...blocks.Block) err
284284
// Publish the block to any Bitswap clients that had requested blocks.
285285
// (the sessions use this pubsub mechanism to inform clients of incoming
286286
// blocks)
287-
bs.notif.Publish(blks...)
287+
var zero peer.ID
288+
bs.notif.Publish(zero, blks...)
288289

289290
return nil
290291
}
@@ -325,7 +326,7 @@ func (bs *Client) receiveBlocksFrom(ctx context.Context, from peer.ID, blks []bl
325326
// (the sessions use this pubsub mechanism to inform clients of incoming
326327
// blocks)
327328
for _, b := range wanted {
328-
bs.notif.Publish(b)
329+
bs.notif.Publish(from, b)
329330
}
330331

331332
for _, b := range wanted {

bitswap/client/internal/notifications/notifications.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ package notifications
33
import (
44
"context"
55
"sync"
6+
"time"
67

78
pubsub "github.com/cskr/pubsub"
9+
"github.com/ipfs/boxo/bitswap/client/traceability"
810
blocks "github.com/ipfs/go-block-format"
911
cid "github.com/ipfs/go-cid"
12+
"github.com/libp2p/go-libp2p/core/peer"
1013
)
1114

1215
const bufferSize = 16
@@ -15,7 +18,7 @@ const bufferSize = 16
1518
// for cids. It's used internally by bitswap to decouple receiving blocks
1619
// and actually providing them back to the GetBlocks caller.
1720
type PubSub interface {
18-
Publish(blocks ...blocks.Block)
21+
Publish(from peer.ID, blocks ...blocks.Block)
1922
Subscribe(ctx context.Context, keys ...cid.Cid) <-chan blocks.Block
2023
Shutdown()
2124
}
@@ -35,7 +38,7 @@ type impl struct {
3538
closed chan struct{}
3639
}
3740

38-
func (ps *impl) Publish(blocks ...blocks.Block) {
41+
func (ps *impl) Publish(from peer.ID, blocks ...blocks.Block) {
3942
ps.lk.RLock()
4043
defer ps.lk.RUnlock()
4144
select {
@@ -45,7 +48,7 @@ func (ps *impl) Publish(blocks ...blocks.Block) {
4548
}
4649

4750
for _, block := range blocks {
48-
ps.wrapped.Pub(block, block.Cid().KeyString())
51+
ps.wrapped.Pub(traceability.Block{Block: block, From: from}, block.Cid().KeyString())
4952
}
5053
}
5154

@@ -84,6 +87,8 @@ func (ps *impl) Subscribe(ctx context.Context, keys ...cid.Cid) <-chan blocks.Bl
8487
default:
8588
}
8689

90+
subscribe := time.Now()
91+
8792
// AddSubOnceEach listens for each key in the list, and closes the channel
8893
// once all keys have been received
8994
ps.wrapped.AddSubOnceEach(valuesCh, toStrings(keys)...)
@@ -113,10 +118,13 @@ func (ps *impl) Subscribe(ctx context.Context, keys ...cid.Cid) <-chan blocks.Bl
113118
if !ok {
114119
return
115120
}
116-
block, ok := val.(blocks.Block)
121+
block, ok := val.(traceability.Block)
117122
if !ok {
123+
// FIXME: silently dropping errors wtf ?
118124
return
119125
}
126+
block.Delay = time.Since(subscribe)
127+
120128
select {
121129
case <-ctx.Done():
122130
return

0 commit comments

Comments
 (0)