Skip to content

Commit 93ec16c

Browse files
committed
Merge branch 'main' into prevent-duplicate-connections
2 parents 9b1d86b + ae595d8 commit 93ec16c

File tree

720 files changed

+24680
-10397
lines changed

Some content is hidden

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

720 files changed

+24680
-10397
lines changed

.cspell.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"import": [
3+
"./node_modules/aegir/cspell.json"
4+
],
5+
"dictionaries": ["project"],
6+
"dictionaryDefinitions": [{
7+
"name": "project",
8+
"path": "./.github/dictionary.txt",
9+
"addWords": true
10+
}]
11+
}

.github/dependabot.yml

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
version: 2
22
updates:
33
- package-ecosystem: npm
4-
directories:
5-
- "**/*"
4+
directory: "/"
65
schedule:
76
interval: daily
87
time: "10:00"
@@ -11,19 +10,12 @@ updates:
1110
prefix: "deps"
1211
prefix-development: "chore"
1312
groups:
14-
helia-deps: # group all deps that should be updated when Helia deps need updated
13+
libp2p-deps:
1514
patterns:
16-
- "*helia*"
1715
- "*libp2p*"
1816
- "*multiformats*"
19-
store-deps: # group all blockstore and datastore updates (interface & impl)
20-
patterns:
2117
- "*blockstore*"
2218
- "*datastore*"
23-
kubo-deps: # group kubo, kubo-rpc-client, and ipfsd-ctl updates
24-
patterns:
25-
- "*kubo*"
26-
- "ipfsd-ctl"
2719
- package-ecosystem: "github-actions"
2820
directory: "/"
2921
schedule:

.github/dictionary.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
setbit
2+
getbit
3+
stopstr
4+
rlflx
5+
incrby
6+
hopr
7+
dout
8+
supercop
9+
nothrow
10+
buildx
11+
blpop
12+
rpush
13+
additionals
14+
SECG
15+
Certicom
16+
RSAES

.github/workflows/examples.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,15 @@ jobs:
7474
- '@libp2p/identify@$PWD/packages/protocol-identify'
7575
- '@libp2p/kad-dht@$PWD/packages/kad-dht'
7676
- '@libp2p/mdns@$PWD/packages/peer-discovery-mdns'
77+
- '@libp2p/ping@$PWD/packages/protocol-ping'
7778
- '@libp2p/tcp@$PWD/packages/transport-tcp'
7879
- 'libp2p@$PWD/packages/libp2p'
7980
- name: js-libp2p-example-peer-and-content-routing
8081
repo: https://github.com/libp2p/js-libp2p-example-peer-and-content-routing.git
8182
deps:
8283
- '@libp2p/identify@$PWD/packages/protocol-identify'
8384
- '@libp2p/kad-dht@$PWD/packages/kad-dht'
85+
- '@libp2p/ping@$PWD/packages/protocol-ping'
8486
- '@libp2p/tcp@$PWD/packages/transport-tcp'
8587
- 'libp2p@$PWD/packages/libp2p'
8688
- name: js-libp2p-example-pnet

.github/workflows/generated-pr.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: Close Generated PRs
2+
3+
on:
4+
schedule:
5+
- cron: '0 0 * * *'
6+
workflow_dispatch:
7+
8+
permissions:
9+
issues: write
10+
pull-requests: write
11+
12+
jobs:
13+
stale:
14+
uses: ipdxco/unified-github-workflows/.github/workflows/reusable-generated-pr.yml@v1

.github/workflows/main.yml

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,31 @@ jobs:
1818
build:
1919
runs-on: ubuntu-latest
2020
steps:
21-
- uses: actions/checkout@v4
22-
- uses: actions/setup-node@v4
23-
with:
24-
node-version: lts/*
25-
- uses: ipfs/aegir/actions/cache-node-modules@main
26-
with:
27-
directories: ${{ env.CACHE_DIRS }}
21+
- uses: actions/checkout@v4
22+
- uses: actions/setup-node@v4
23+
with:
24+
node-version: lts/*
25+
- uses: ipfs/aegir/actions/cache-node-modules@main
26+
with:
27+
directories: ${{ env.CACHE_DIRS }}
2828

2929
check:
3030
needs: build
3131
runs-on: ubuntu-latest
3232
steps:
33-
- uses: actions/checkout@v4
34-
- uses: actions/setup-node@v4
35-
with:
36-
node-version: lts/*
37-
- uses: ipfs/aegir/actions/cache-node-modules@main
38-
with:
39-
directories: ${{ env.CACHE_DIRS }}
40-
- run: npm run --if-present lint
41-
- run: npm run --if-present dep-check
42-
- run: npm run --if-present docs:no-publish
43-
- run: npm run --if-present doc-check
33+
- uses: actions/checkout@v4
34+
- uses: actions/setup-node@v4
35+
with:
36+
node-version: lts/*
37+
- uses: ipfs/aegir/actions/cache-node-modules@main
38+
with:
39+
directories: ${{ env.CACHE_DIRS }}
40+
- run: npm run --if-present lint
41+
- run: npm run --if-present dep-check
42+
- run: npm run --if-present docs:no-publish
43+
- run: npm run --if-present doc-check
44+
- run: npm run --if-present spell-check
45+
4446
test-node:
4547
needs: build
4648
runs-on: ${{ matrix.os }}
@@ -58,7 +60,7 @@ jobs:
5860
with:
5961
directories: ${{ env.CACHE_DIRS }}
6062
- run: npm run --if-present test:node
61-
- uses: codecov/codecov-action@7f8b4b4bde536c465e797be725718b88c5d95e0e # v5.1.1
63+
- uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0
6264
with:
6365
flags: node
6466
files: .coverage/*,packages/*/.coverage/*
@@ -76,7 +78,7 @@ jobs:
7678
with:
7779
directories: ${{ env.CACHE_DIRS }}
7880
- run: npm run --if-present test:chrome
79-
- uses: codecov/codecov-action@7f8b4b4bde536c465e797be725718b88c5d95e0e # v5.1.1
81+
- uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0
8082
with:
8183
flags: chrome
8284
files: .coverage/*,packages/*/.coverage/*
@@ -94,7 +96,7 @@ jobs:
9496
with:
9597
directories: ${{ env.CACHE_DIRS }}
9698
- run: npm run --if-present test:chrome-webworker
97-
- uses: codecov/codecov-action@7f8b4b4bde536c465e797be725718b88c5d95e0e # v5.1.1
99+
- uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0
98100
with:
99101
flags: chrome-webworker
100102
files: .coverage/*,packages/*/.coverage/*
@@ -112,7 +114,7 @@ jobs:
112114
with:
113115
directories: ${{ env.CACHE_DIRS }}
114116
- run: npm run --if-present test:firefox
115-
- uses: codecov/codecov-action@7f8b4b4bde536c465e797be725718b88c5d95e0e # v5.1.1
117+
- uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0
116118
with:
117119
flags: firefox
118120
files: .coverage/*,packages/*/.coverage/*
@@ -130,7 +132,7 @@ jobs:
130132
with:
131133
directories: ${{ env.CACHE_DIRS }}
132134
- run: npm run --if-present test:firefox-webworker
133-
- uses: codecov/codecov-action@7f8b4b4bde536c465e797be725718b88c5d95e0e # v5.1.1
135+
- uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0
134136
with:
135137
flags: firefox-webworker
136138
files: .coverage/*,packages/*/.coverage/*
@@ -153,7 +155,7 @@ jobs:
153155
sudo apt-get update
154156
- run: npx playwright install-deps
155157
- run: npm run --if-present test:webkit
156-
- uses: codecov/codecov-action@7f8b4b4bde536c465e797be725718b88c5d95e0e # v5.1.1
158+
- uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0
157159
with:
158160
flags: webkit
159161
files: .coverage/*,packages/*/.coverage/*
@@ -171,7 +173,7 @@ jobs:
171173
with:
172174
directories: ${{ env.CACHE_DIRS }}
173175
- run: npx xvfb-maybe npm run --if-present test:electron-main
174-
- uses: codecov/codecov-action@7f8b4b4bde536c465e797be725718b88c5d95e0e # v5.1.1
176+
- uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0
175177
with:
176178
flags: electron-main
177179
files: .coverage/*,packages/*/.coverage/*
@@ -189,7 +191,7 @@ jobs:
189191
with:
190192
directories: ${{ env.CACHE_DIRS }}
191193
- run: npx xvfb-maybe npm run --if-present test:electron-renderer
192-
- uses: codecov/codecov-action@7f8b4b4bde536c465e797be725718b88c5d95e0e # v5.1.1
194+
- uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0
193195
with:
194196
flags: electron-renderer
195197
files: .coverage/*,packages/*/.coverage/*
@@ -228,10 +230,11 @@ jobs:
228230
path: |
229231
package-lock.json
230232
interop/package-lock.json
231-
- uses: libp2p/test-plans/.github/actions/run-interop-ping-test@master
233+
- uses: libp2p/test-plans/.github/actions/run-transport-interop-test@master
232234
with:
233235
test-filter: js-libp2p-head
234-
extra-versions: ${{ github.workspace }}/interop/node-version.json ${{ github.workspace }}/interop/chromium-version.json ${{ github.workspace }}/interop/firefox-version.json
236+
test-ignore: nim
237+
extra-versions: ${{ github.workspace }}/interop/node-version.json ${{ github.workspace }}/interop/chromium-version.json ${{ github.workspace }}/interop/firefox-version.json ${{ github.workspace }}/interop/webkit-version.json
235238
s3-cache-bucket: ${{ vars.S3_LIBP2P_BUILD_CACHE_BUCKET_NAME }}
236239
s3-access-key-id: ${{ vars.S3_LIBP2P_BUILD_CACHE_AWS_ACCESS_KEY_ID }}
237240
s3-secret-access-key: ${{ secrets.S3_LIBP2P_BUILD_CACHE_AWS_SECRET_ACCESS_KEY }}

.github/workflows/semantic-pull-request.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ on:
99

1010
jobs:
1111
main:
12-
uses: pl-strflt/.github/.github/workflows/reusable-semantic-pull-request.yml@v0.3
12+
uses: ipdxco/unified-github-workflows/.github/workflows/reusable-semantic-pull-request.yml@v1

.github/workflows/stale.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
name: Close and mark stale issue
1+
name: Close Stale Issues
22

33
on:
44
schedule:
55
- cron: '0 0 * * *'
6+
workflow_dispatch:
67

78
permissions:
89
issues: write
910
pull-requests: write
1011

1112
jobs:
1213
stale:
13-
uses: pl-strflt/.github/.github/workflows/reusable-stale-issue.yml@v0.3
14+
uses: ipdxco/unified-github-workflows/.github/workflows/reusable-stale-issue.yml@v1

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ node_modules
77
package-lock.json
88
yarn.lock
99
.vscode
10+
interop/*-image.json
11+
.tmp-compiled-docs
12+
tsconfig-doc-check.aegir.json

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"packages/auto-tls":"1.0.4","packages/config":"1.0.1","packages/connection-encrypter-plaintext":"2.0.13","packages/connection-encrypter-tls":"2.0.13","packages/crypto":"5.0.9","packages/interface":"2.4.0","packages/interface-compliance-tests":"6.2.3","packages/interface-internal":"2.2.2","packages/kad-dht":"14.2.0","packages/keychain":"5.0.12","packages/libp2p":"2.5.0","packages/logger":"5.1.6","packages/metrics-devtools":"1.2.0","packages/metrics-opentelemetry":"1.0.0","packages/metrics-prometheus":"4.3.0","packages/metrics-simple":"1.3.0","packages/multistream-select":"6.0.11","packages/peer-collections":"6.0.14","packages/peer-discovery-bootstrap":"11.0.17","packages/peer-discovery-mdns":"11.0.17","packages/peer-id":"5.0.10","packages/peer-record":"8.0.14","packages/peer-store":"11.0.14","packages/pnet":"2.0.17","packages/protocol-autonat":"2.0.16","packages/protocol-dcutr":"2.0.15","packages/protocol-echo":"2.1.6","packages/protocol-fetch":"3.0.0","packages/protocol-identify":"3.0.15","packages/protocol-perf":"4.0.17","packages/protocol-ping":"2.0.15","packages/pubsub":"10.0.15","packages/pubsub-floodsub":"10.1.16","packages/record":"4.0.4","packages/stream-multiplexer-mplex":"11.0.17","packages/transport-circuit-relay-v2":"3.1.7","packages/transport-memory":"1.0.3","packages/transport-tcp":"10.0.15","packages/transport-webrtc":"5.0.23","packages/transport-websockets":"9.1.2","packages/transport-webtransport":"5.0.22","packages/upnp-nat":"3.0.4","packages/utils":"6.3.1"}
1+
{"packages/config":"1.1.10","packages/connection-encrypter-plaintext":"2.0.26","packages/connection-encrypter-tls":"2.2.4","packages/crypto":"5.1.5","packages/interface":"2.10.3","packages/interface-compliance-tests":"6.4.9","packages/interface-internal":"2.3.15","packages/kad-dht":"15.1.3","packages/keychain":"5.2.5","packages/libp2p":"2.8.9","packages/logger":"5.1.19","packages/metrics-opentelemetry":"1.0.17","packages/metrics-prometheus":"4.3.22","packages/metrics-simple":"1.3.13","packages/multistream-select":"6.0.26","packages/peer-collections":"6.0.31","packages/peer-discovery-bootstrap":"11.0.39","packages/peer-discovery-mdns":"11.0.39","packages/peer-id":"5.1.6","packages/peer-record":"8.0.31","packages/peer-store":"11.2.3","packages/pnet":"2.0.39","packages/protocol-autonat":"2.0.34","packages/protocol-dcutr":"2.0.33","packages/protocol-echo":"2.1.24","packages/protocol-fetch":"3.0.18","packages/protocol-identify":"3.0.33","packages/protocol-perf":"4.0.39","packages/protocol-ping":"2.0.33","packages/pubsub":"10.1.14","packages/pubsub-floodsub":"10.1.38","packages/record":"4.0.7","packages/stream-multiplexer-mplex":"11.0.39","packages/transport-circuit-relay-v2":"3.2.15","packages/transport-memory":"1.1.10","packages/transport-tcp":"10.1.14","packages/transport-webrtc":"5.2.16","packages/transport-websockets":"9.2.14","packages/transport-webtransport":"5.0.44","packages/upnp-nat":"3.1.17","packages/utils":"6.6.6"}

.release-please.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
{ "type": "refactor", "section": "Refactors", "hidden": false }
1010
],
1111
"packages": {
12-
"packages/auto-tls": {},
1312
"packages/config": {},
1413
"packages/connection-encrypter-plaintext": {},
1514
"packages/connection-encrypter-tls": {},
@@ -21,7 +20,6 @@
2120
"packages/keychain": {},
2221
"packages/libp2p": {},
2322
"packages/logger": {},
24-
"packages/metrics-devtools": {},
2523
"packages/metrics-opentelemetry": {},
2624
"packages/metrics-prometheus": {},
2725
"packages/metrics-simple": {},

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
👉 Please see the [IPFS JavaScript Community contributing guidelines](https://github.com/ipfs/community/blob/master/CONTRIBUTING_JS.md) for how to collaborate and contribute to js-libp2p.
66

7-
💪 The [core maintainers](https://github.com/libp2p/js-libp2p/blob/main/CODEOWNERS) hang out in #libp2p-implementers in ipfs.io Matrix, FIL Slack, and IPFS Discord. They perform weekly triage of issues and PRs per https://lu.ma/libp2p
7+
💪 The [core maintainers](https://github.com/libp2p/js-libp2p/blob/main/CODEOWNERS) hang out in #libp2p-implementers in ipfs.io Matrix, FIL Slack, and IPFS Discord. They perform weekly triage of issues and PRs on the Open Maintainers Call - see the [Libp2p Events Calendar](https://lu.ma/libp2p) to find out when the next one is.
88

99
🤲 Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed in [README.md](https://github.com/libp2p/js-libp2p/blob/main/README.md), without any additional terms or conditions.
1010

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/main.yml?branch=main\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/main.yml?query=branch%3Amain)
1414

1515
> [!NOTE]
16-
> Are you tring to upgrade libp2p to the latest version? Check out the [migration guides](https://github.com/libp2p/js-libp2p/tree/main/doc/migrations) for any changes you need to make.
16+
> Are you trying to upgrade libp2p to the latest version? Check out the [migration guides](https://github.com/libp2p/js-libp2p/tree/main/doc/migrations) for any changes you need to make.
1717
1818
### Project status
1919

@@ -24,7 +24,7 @@ The documentation in the main branch may contain changes from a pre-release.
2424
If you are looking for the documentation of the latest release, you can view the latest release on [npm](https://www.npmjs.com/package/libp2p), or select the tag in github that matches the version you are looking for.
2525

2626
> [!TIP]
27-
> Just tring to figure out what this is all about? Check our [GETTING\_STARTED.md](https://github.com/libp2p/js-libp2p/blob/main/doc/GETTING_STARTED.md) guide and [examples](https://github.com/libp2p/js-libp2p-examples).
27+
> Just trying to figure out what this is all about? Check our [GETTING\_STARTED.md](https://github.com/libp2p/js-libp2p/blob/main/doc/GETTING_STARTED.md) guide and [examples](https://github.com/libp2p/js-libp2p-examples).
2828
2929
## Background
3030

@@ -41,7 +41,7 @@ We are in the process of writing better documentation, blog posts, tutorials and
4141
- Articles
4242
- [The overview of libp2p](https://github.com/libp2p/libp2p#description)
4343

44-
To sum up, libp2p is a "network stack" -- a protocol suite -- that cleanly separates concerns, and enables sophisticated applications to only use the protocols they absolutely need, without giving up interoperability and upgradeability. libp2p grew out of IPFS, but it is built so that lots of people can use it, for lots of different projects.
44+
To sum up, libp2p is a "network stack" -- a protocol suite -- that cleanly separates concerns, and enables sophisticated applications to only use the protocols they absolutely need, without giving up interoperability and upgradability. libp2p grew out of IPFS, but it is built so that lots of people can use it, for lots of different projects.
4545

4646
## Roadmap
4747

@@ -76,7 +76,7 @@ You can find multiple examples on the [examples repo](https://github.com/libp2p/
7676
## Structure
7777

7878
- [`/doc`](https://github.com/libp2p/js-libp2p/blob/main/doc) Docs for libp2p
79-
- [`/interop`](https://github.com/libp2p/js-libp2p/tree/main/interop) Multidimension Interop Test
79+
- [`/interop`](https://github.com/libp2p/js-libp2p/tree/main/interop) Multidimensional Interop Test
8080
- [`/packages/crypto`](https://github.com/libp2p/js-libp2p/tree/main/packages/crypto) Crypto primitives for libp2p
8181
- [`/packages/interface`](https://github.com/libp2p/js-libp2p/tree/main/packages/interface) The interface implemented by a libp2p node
8282
- [`/packages/interface-compliance-tests`](https://github.com/libp2p/js-libp2p/tree/main/packages/interface-compliance-tests) Compliance tests for JS libp2p interfaces
@@ -121,7 +121,7 @@ You can find multiple examples on the [examples repo](https://github.com/libp2p/
121121
#### Run unit tests
122122

123123
```sh
124-
# run all the unit tsts
124+
# run all the unit tests
125125
> npm test
126126

127127
# run just Node.js tests

ROADMAP.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ js-libp2p is deployed in many production environments so to take adoption to the
88

99
### js-libp2p amino DHT bootstrapper
1010

11-
Deploying a public bootstrapper is a great test of the capacity of js-libp2p since it will need to maintain several thousand simultaneous connections and service many DHT RPC requests. Comprehensive metrics and logging will also give us insight into real world usage patterns that can further direct performance optimisations.
11+
Deploying a public bootstrapper is a great test of the capacity of js-libp2p since it will need to maintain several thousand simultaneous connections and service many DHT RPC requests. Comprehensive metrics and logging will also give us insight into real world usage patterns that can further direct performance optimizations.
1212

1313
- Deploy a bootstrap server that acts as an entry point to the network for DHT clients
1414
- Ship it in the default config of majority libp2p/IPFS implementations
@@ -74,7 +74,7 @@ The specification is [in progress](https://github.com/libp2p/specs/pull/625) the
7474

7575
### QUIC in Node.js
7676

77-
There's a decent chance the Node.js QUIC implementation is [not going to be exposed to userland](https://github.com/nodejs/node/pull/52628#issuecomment-2143475066), but we need this to have compatibility with other libp2p implementations.
77+
There's a decent chance the Node.js QUIC implementation is [not going to be exposed to user land](https://github.com/nodejs/node/pull/52628#issuecomment-2143475066), but we need this to have compatibility with other libp2p implementations.
7878

7979
https://github.com/ChainSafe/js-libp2p-quic is in-progress to add QUIC support via a native module that uses the Rust implementation.
8080

doc/ARCHITECTURE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Libp2p Architecture
22

3-
js-libp2p is comprised of a number of components that work together to provide functionality such as dailling peers, managing connections, registering protocols, storing information about peers and much more. This document aims to provide a high level overview of the components and how they interact with each other.
3+
js-libp2p is comprised of a number of components that work together to provide functionality such as dialing peers, managing connections, registering protocols, storing information about peers and much more. This document aims to provide a high level overview of the components and how they interact with each other.
44

55
- [Libp2p Architecture](#libp2p-architecture)
66
- [Component Diagram](#component-diagram)

0 commit comments

Comments
 (0)