mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-07-23 12:31:57 +00:00
Compare commits
48 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
4e3fc19623 | ||
|
2fa82b387c | ||
|
8fc6f8af81 | ||
|
924585b143 | ||
|
556f0203db | ||
|
b5a9eb2087 | ||
|
e5187d02ba | ||
|
150e4f97c1 | ||
|
302bb90058 | ||
|
f860ffb3e7 | ||
|
2572f3e034 | ||
|
d76356e56a | ||
|
e9543eb2e1 | ||
|
5282708263 | ||
|
ed494f03ae | ||
|
ac370fc967 | ||
|
ef4393649f | ||
|
f23fd4b7c7 | ||
|
5372f7af2f | ||
|
97da0ba740 | ||
|
88b04156bf | ||
|
64f3af897b | ||
|
54e502afcb | ||
|
086b0ec0df | ||
|
cc1f4af879 | ||
|
6456a0fff8 | ||
|
44463b9145 | ||
|
7eb2cea570 | ||
|
c381be3510 | ||
|
975e77991e | ||
|
b043bca607 | ||
|
3ffeb4ebe6 | ||
|
06e8f3dd42 | ||
|
3f7dde3e13 | ||
|
6f4e7ceeac | ||
|
2af692fb4d | ||
|
906315ce73 | ||
|
49f04cbe70 | ||
|
3d0a79eff3 | ||
|
55ee332907 | ||
|
ffe122d47e | ||
|
21c9aeecb1 | ||
|
a93cca9178 | ||
|
828a32d4f5 | ||
|
b4fb9b7bf2 | ||
|
0aed9fe1b3 | ||
|
9d1b917e8a | ||
|
8506414ea1 |
24
.aegir.js
24
.aegir.js
@@ -1,5 +1,6 @@
|
||||
'use strict'
|
||||
|
||||
const path = require('path')
|
||||
const Libp2p = require('./src')
|
||||
const { MULTIADDRS_WEBSOCKETS } = require('./test/fixtures/browser')
|
||||
const Peers = require('./test/fixtures/peers')
|
||||
@@ -47,16 +48,23 @@ const after = async () => {
|
||||
await libp2p.stop()
|
||||
}
|
||||
|
||||
/** @type {import('aegir').Options["build"]["config"]} */
|
||||
const esbuild = {
|
||||
inject: [path.join(__dirname, './scripts/node-globals.js')]
|
||||
}
|
||||
|
||||
/** @type {import('aegir').PartialOptions} */
|
||||
module.exports = {
|
||||
bundlesize: { maxSize: '223kB' },
|
||||
hooks: {
|
||||
pre: before,
|
||||
post: after
|
||||
build: {
|
||||
bundlesizeMax: '253kB'
|
||||
},
|
||||
webpack: {
|
||||
node: {
|
||||
// needed by bcrypto
|
||||
Buffer: true
|
||||
test: {
|
||||
before,
|
||||
after,
|
||||
browser: {
|
||||
config: {
|
||||
buildConfig: esbuild
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
102
.github/workflows/examples.yml
vendored
Normal file
102
.github/workflows/examples.yml
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
name: examples
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- '**'
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm install
|
||||
- run: npx aegir lint
|
||||
- run: npx aegir ts -p check
|
||||
- run: npx aegir build
|
||||
test-auto-relay-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm install
|
||||
- run: cd examples && yarn && npm run test -- auto-relay
|
||||
test-chat-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm install
|
||||
- run: cd examples && yarn && npm run test -- chat
|
||||
test-connection-encryption-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm install
|
||||
- run: cd examples && yarn && npm run test -- connection-encryption
|
||||
test-discovery-mechanisms-example:
|
||||
needs: check
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm install
|
||||
- run: cd examples && yarn && npm run test -- discovery-mechanisms
|
||||
test-echo-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm install
|
||||
- run: cd examples && yarn && npm run test -- echo
|
||||
test-libp2p-in-the-browser-example:
|
||||
needs: check
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm install
|
||||
- run: cd examples && yarn && npm run test -- libp2p-in-the-browser
|
||||
test-peer-and-content-routing-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm install
|
||||
- run: cd examples && yarn && npm run test -- peer-and-content-routing
|
||||
test-pnet-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm install
|
||||
- run: cd examples && yarn && npm run test -- pnet
|
||||
test-protocol-and-stream-muxing-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm install
|
||||
- run: cd examples && yarn && npm run test -- protocol-and-stream-muxing
|
||||
test-pubsub-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm install
|
||||
- run: cd examples && yarn && npm run test -- pubsub
|
||||
test-transports-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm install
|
||||
- run: cd examples && yarn && npm run test -- transports
|
||||
test-webrtc-direct-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm install
|
||||
- run: cd examples && yarn && npm run test -- webrtc-direct
|
111
.github/workflows/main.yml
vendored
111
.github/workflows/main.yml
vendored
@@ -12,11 +12,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn
|
||||
- run: yarn lint
|
||||
- run: npm install
|
||||
- run: npx aegir lint
|
||||
- uses: gozala/typescript-error-reporter-action@v1.0.8
|
||||
- run: yarn build
|
||||
- run: yarn aegir dep-check
|
||||
- run: npx aegir build
|
||||
- run: npx aegir dep-check
|
||||
- uses: ipfs/aegir/actions/bundle-size@master
|
||||
name: size
|
||||
with:
|
||||
@@ -34,111 +34,34 @@ jobs:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
- run: yarn
|
||||
- run: npx nyc --reporter=lcov aegir test -t node -- --bail
|
||||
- run: npm install
|
||||
- run: npx aegir test -t node --cov --bail
|
||||
- uses: codecov/codecov-action@v1
|
||||
test-chrome:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn
|
||||
- run: npm install
|
||||
- run: npx aegir test -t browser -t webworker --bail
|
||||
test-firefox:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn
|
||||
- run: npx aegir test -t browser -t webworker --bail -- --browsers FirefoxHeadless
|
||||
- run: npm install
|
||||
- run: npx aegir test -t browser -t webworker --bail -- --browser firefox
|
||||
test-ts:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm install
|
||||
- run: npm run test:ts
|
||||
test-interop:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn
|
||||
- run: npm install
|
||||
- run: cd node_modules/interop-libp2p && yarn && LIBP2P_JS=${GITHUB_WORKSPACE}/src/index.js npx aegir test -t node --bail
|
||||
test-auto-relay-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn
|
||||
- run: cd examples && yarn && npm run test -- auto-relay
|
||||
test-chat-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn
|
||||
- run: cd examples && yarn && npm run test -- chat
|
||||
test-connection-encryption-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn
|
||||
- run: cd examples && yarn && npm run test -- connection-encryption
|
||||
test-discovery-mechanisms-example:
|
||||
needs: check
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn
|
||||
- run: cd examples && yarn && npm run test -- discovery-mechanisms
|
||||
test-echo-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn
|
||||
- run: cd examples && yarn && npm run test -- echo
|
||||
test-libp2p-in-the-browser-example:
|
||||
needs: check
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn
|
||||
- run: cd examples && yarn && npm run test -- libp2p-in-the-browser
|
||||
test-peer-and-content-routing-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn
|
||||
- run: cd examples && yarn && npm run test -- peer-and-content-routing
|
||||
test-pnet-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn
|
||||
- run: cd examples && yarn && npm run test -- pnet
|
||||
test-protocol-and-stream-muxing-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn
|
||||
- run: cd examples && yarn && npm run test -- protocol-and-stream-muxing
|
||||
test-pubsub-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn
|
||||
- run: cd examples && yarn && npm run test -- pubsub
|
||||
test-transports-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn
|
||||
- run: cd examples && yarn && npm run test -- transports
|
||||
test-webrtc-direct-example:
|
||||
needs: check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn
|
||||
- run: cd examples && yarn && npm run test -- webrtc-direct
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@ docs
|
||||
test/repo-tests*
|
||||
**/bundle.js
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Logs
|
||||
logs
|
||||
|
102
CHANGELOG.md
102
CHANGELOG.md
@@ -1,3 +1,105 @@
|
||||
## [0.31.3](https://github.com/libp2p/js-libp2p/compare/v0.31.2...v0.31.3) (2021-05-04)
|
||||
|
||||
|
||||
|
||||
## [0.31.2](https://github.com/libp2p/js-libp2p/compare/v0.31.1...v0.31.2) (2021-04-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* moving averages record types ([#935](https://github.com/libp2p/js-libp2p/issues/935)) ([b5a9eb2](https://github.com/libp2p/js-libp2p/commit/b5a9eb208763efa027d0b4caae87c515b6f5869b))
|
||||
|
||||
|
||||
|
||||
## [0.31.1](https://github.com/libp2p/js-libp2p/compare/v0.31.0...v0.31.1) (2021-04-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* event emitter and interfaces types for discovery and routing ([#934](https://github.com/libp2p/js-libp2p/issues/934)) ([302bb90](https://github.com/libp2p/js-libp2p/commit/302bb9005891aa06b70a5f354bfac6b2d5a3c3b8))
|
||||
|
||||
|
||||
|
||||
# [0.31.0](https://github.com/libp2p/js-libp2p/compare/v0.31.0-rc.7...v0.31.0) (2021-04-28)
|
||||
|
||||
|
||||
|
||||
# [0.31.0-rc.7](https://github.com/libp2p/js-libp2p/compare/v0.31.0-rc.6...v0.31.0-rc.7) (2021-04-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* address book guarantees no replicated entries are added ([#927](https://github.com/libp2p/js-libp2p/issues/927)) ([ac370fc](https://github.com/libp2p/js-libp2p/commit/ac370fc9679b51da8cee3791b6dd268d0695d136))
|
||||
|
||||
|
||||
|
||||
# [0.31.0-rc.6](https://github.com/libp2p/js-libp2p/compare/v0.31.0-rc.5...v0.31.0-rc.6) (2021-04-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* keychain optional pw and use interfaces for validators and selectors instead ([#924](https://github.com/libp2p/js-libp2p/issues/924)) ([88b0415](https://github.com/libp2p/js-libp2p/commit/88b04156bf614650c2b14d49b12e969c5eecf04d))
|
||||
|
||||
|
||||
|
||||
# [0.31.0-rc.5](https://github.com/libp2p/js-libp2p/compare/v0.31.0-rc.4...v0.31.0-rc.5) (2021-04-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* address book should not emit peer event if no addresses are known ([b4fb9b7](https://github.com/libp2p/js-libp2p/commit/b4fb9b7bf266ba03c4462c0a41b1c2691e4e88d4))
|
||||
* demand pubsub subclass instead of pubsub instance ([#922](https://github.com/libp2p/js-libp2p/issues/922)) ([086b0ec](https://github.com/libp2p/js-libp2p/commit/086b0ec0df2fac93845d0a0a6b2e2464e869afcd))
|
||||
* dht configuration selectors and validators ([#919](https://github.com/libp2p/js-libp2p/issues/919)) ([cc1f4af](https://github.com/libp2p/js-libp2p/commit/cc1f4af879a58e94538591851d0085ff98cd2641))
|
||||
|
||||
|
||||
|
||||
# [0.31.0-rc.4](https://github.com/libp2p/js-libp2p/compare/v0.31.0-rc.3...v0.31.0-rc.4) (2021-04-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add clientMode dht arg and upgrade interface-datastore ([#918](https://github.com/libp2p/js-libp2p/issues/918)) ([975e779](https://github.com/libp2p/js-libp2p/commit/975e77991e67dd9bff790b83df7bd6fa5ddcfc67))
|
||||
* do not add abort signals to useless addresses ([#913](https://github.com/libp2p/js-libp2p/issues/913)) ([06e8f3d](https://github.com/libp2p/js-libp2p/commit/06e8f3dd42432e4b37ab7904b02abde7d1cadda3))
|
||||
* specify pbjs root ([#917](https://github.com/libp2p/js-libp2p/issues/917)) ([b043bca](https://github.com/libp2p/js-libp2p/commit/b043bca607565cf534771e6cf975288a8ff3030b))
|
||||
|
||||
|
||||
|
||||
# [0.31.0-rc.3](https://github.com/libp2p/js-libp2p/compare/v0.31.0-rc.2...v0.31.0-rc.3) (2021-04-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* remove inline arg types from function definitions ([#916](https://github.com/libp2p/js-libp2p/issues/916)) ([2af692f](https://github.com/libp2p/js-libp2p/commit/2af692fb4de572168524ae684608fc6526de4ef7))
|
||||
|
||||
|
||||
|
||||
# [0.31.0-rc.2](https://github.com/libp2p/js-libp2p/compare/v0.31.0-rc.1...v0.31.0-rc.2) (2021-04-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* metrics stats and moving averages types ([#915](https://github.com/libp2p/js-libp2p/issues/915)) ([3d0a79e](https://github.com/libp2p/js-libp2p/commit/3d0a79eff3bc34a5bdc8ffa31e9b09345a02ad9d))
|
||||
|
||||
|
||||
|
||||
# [0.31.0-rc.1](https://github.com/libp2p/js-libp2p/compare/v0.31.0-rc.0...v0.31.0-rc.1) (2021-04-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* dial protocol should throw if no protocol is provided ([#914](https://github.com/libp2p/js-libp2p/issues/914)) ([21c9aee](https://github.com/libp2p/js-libp2p/commit/21c9aeecb13440238aa6b0fb5a6731d2f87d4938))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* dialProtocol does not return connection when no protocols are provided
|
||||
|
||||
|
||||
|
||||
# [0.31.0-rc.0](https://github.com/libp2p/js-libp2p/compare/v0.30.12...v0.31.0-rc.0) (2021-04-15)
|
||||
|
||||
|
||||
|
||||
## [0.30.12](https://github.com/libp2p/js-libp2p/compare/v0.30.11...v0.30.12) (2021-03-27)
|
||||
|
||||
|
||||
|
@@ -25,7 +25,6 @@
|
||||
- [ ] [js-ipfs](https://github.com/ipfs/js-ipfs)
|
||||
- Documentation
|
||||
- [ ] Ensure that README.md is up to date
|
||||
- [ ] Ensure that all the examples run
|
||||
- [ ] Ensure [libp2p/js-libp2p-examples](https://github.com/libp2p/js-libp2p-examples) is updated
|
||||
- [ ] Ensure that [libp2p/docs](https://github.com/libp2p/docs) is updated
|
||||
- Communication
|
||||
|
@@ -599,7 +599,7 @@ const TCP = require('libp2p-tcp')
|
||||
const MPLEX = require('libp2p-mplex')
|
||||
const { NOISE } = require('libp2p-noise')
|
||||
|
||||
const { FaultTolerance } = require('libp2p/src/transport-manager')}
|
||||
const { FaultTolerance } = require('libp2p/src/transport-manager')
|
||||
|
||||
const node = await Libp2p.create({
|
||||
modules: {
|
||||
|
123
doc/migrations/v0.30-v0.31.md
Normal file
123
doc/migrations/v0.30-v0.31.md
Normal file
@@ -0,0 +1,123 @@
|
||||
<!--Specify versions for migration below-->
|
||||
# Migrating to libp2p@31
|
||||
|
||||
A migration guide for refactoring your application code from libp2p v0.30.x to v0.31.0.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Types](#types)
|
||||
- [API](#api)
|
||||
- [Module Updates](#module-updates)
|
||||
|
||||
## Types
|
||||
|
||||
Most of the type definitions in the libp2p configuration were `any` or were not included before this release. This might cause breaking changes on upstream projects relying on the previous provided types, as well as to libp2p modules implemented by the libp2p community.
|
||||
|
||||
## API
|
||||
|
||||
### Core API
|
||||
|
||||
`libp2p.dialProtocol` does not accept empty or null protocols returning a connection anymore and `dial` must be used instead.
|
||||
|
||||
```js
|
||||
const connection = await libp2p.dialProtocol(peerId)
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```js
|
||||
const connection = await libp2p.dial(peerId)
|
||||
```
|
||||
|
||||
### Connection Manager Options
|
||||
|
||||
We updated the connection manager options naming in `libp2p@0.29` but kept it backward compatible until now.
|
||||
|
||||
**Before**
|
||||
|
||||
```js
|
||||
const node = await Libp2p.create({
|
||||
connectionManager: {
|
||||
minPeers: 0
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```js
|
||||
const node = await Libp2p.create({
|
||||
connectionManager: {
|
||||
minConnections: 0
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
You can see full details on how to configure the connection manager [here](https://github.com/libp2p/js-libp2p/blob/master/doc/CONFIGURATION.md#configuring-connection-manager).
|
||||
|
||||
### Dialer and Keychain components
|
||||
|
||||
Internal property names to create a libp2p `Dialer` and `Keychain` were updated to reflect the properties naming in the libp2p configuration. These are internal modules of libp2p core and should not impact most of the users, but as it is possible to use them separately here follow the changes:
|
||||
|
||||
***Before**
|
||||
|
||||
```js
|
||||
const dialer = new Dialer({
|
||||
transportManager,
|
||||
peerStore,
|
||||
concurrency,
|
||||
perPeerLimit,
|
||||
timeout,
|
||||
resolvers,
|
||||
addressSorter
|
||||
})
|
||||
|
||||
const keychain = new Keychain(datastore, {
|
||||
passPhrase
|
||||
})
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```js
|
||||
this.dialer = new Dialer({
|
||||
transportManager,
|
||||
peerStore,
|
||||
maxParallelDials,
|
||||
maxDialsPerPeer,
|
||||
dialTimeout,
|
||||
resolvers,
|
||||
addressSorter
|
||||
})
|
||||
|
||||
const keychain = new Keychain(datastore, {
|
||||
pass
|
||||
})
|
||||
```
|
||||
|
||||
## Module Updates
|
||||
|
||||
With this release you should update the following libp2p modules if you are relying on them:
|
||||
|
||||
<!--Specify module versions in JSON for migration below.
|
||||
It's recommended to check package.json changes for this:
|
||||
`git diff <release> <prev> -- package.json`
|
||||
-->
|
||||
|
||||
```json
|
||||
"libp2p-bootstrap": "^0.12.3",
|
||||
"libp2p-crypto": "^0.19.4",
|
||||
"libp2p-interfaces": "^0.10.0",
|
||||
"libp2p-delegated-content-routing": "^0.10.0",
|
||||
"libp2p-delegated-peer-routing": "^0.9.0",
|
||||
"libp2p-floodsub": "^0.25.1",
|
||||
"libp2p-gossipsub": "^0.9.0",
|
||||
"libp2p-kad-dht": "^0.22.0",
|
||||
"libp2p-mdns": "^0.16.0",
|
||||
"libp2p-noise": "^3.0.0",
|
||||
"libp2p-tcp": "^0.15.4",
|
||||
"libp2p-webrtc-star": "^0.22.2",
|
||||
"libp2p-websockets": "^0.15.6"
|
||||
```
|
||||
|
||||
One of the main changes in this new release is the update to `multiaddr@9.0.0`. This should also be updated in upstream projects to avoid several multiaddr versions in the bundle and to avoid potential problems when libp2p interacts with provided outdated multiaddr instances.
|
@@ -4,9 +4,13 @@ This example leverages the [Parcel.js bundler](https://parceljs.org/) to compile
|
||||
|
||||
## Setup
|
||||
|
||||
In order to run the example, first install the dependencies from same directory as this README:
|
||||
In order to run the example:
|
||||
|
||||
- Install dependencey at the root of the js-libp2p repository (if not already done),
|
||||
- then, install the dependencies from same directory as this README:
|
||||
|
||||
```
|
||||
npm install
|
||||
cd ./examples/libp2p-in-the-browser
|
||||
npm install
|
||||
```
|
||||
|
@@ -2,7 +2,7 @@
|
||||
"name": "libp2p-in-browser",
|
||||
"version": "1.0.0",
|
||||
"description": "A libp2p node running in the browser",
|
||||
"main": "index.js",
|
||||
"main": "dist/index.html",
|
||||
"browserslist": [
|
||||
"last 2 Chrome versions"
|
||||
],
|
||||
@@ -20,8 +20,8 @@
|
||||
"libp2p-bootstrap": "^0.12.1",
|
||||
"libp2p-mplex": "^0.10.0",
|
||||
"libp2p-noise": "^2.0.0",
|
||||
"libp2p-webrtc-star": "^0.20.0",
|
||||
"libp2p-websockets": "^0.14.0"
|
||||
"libp2p-webrtc-star": "^0.22.0",
|
||||
"libp2p-websockets": "^0.15.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.13.10",
|
||||
@@ -29,6 +29,6 @@
|
||||
"babel-plugin-syntax-async-functions": "^6.13.0",
|
||||
"babel-plugin-transform-regenerator": "^6.26.0",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"parcel-bundler": "1.12.3"
|
||||
"parcel": "next"
|
||||
}
|
||||
}
|
||||
|
@@ -17,10 +17,10 @@ async function run() {
|
||||
const out = chunk.toString()
|
||||
|
||||
if (out.includes('Server running at')) {
|
||||
url = out.replace('Server running at ', '')
|
||||
url = out.split('Server running at ')[1]
|
||||
}
|
||||
|
||||
if (out.includes('✨ Built in ')) {
|
||||
if (out.includes('Built in')) {
|
||||
try {
|
||||
const browser = await chromium.launch();
|
||||
const page = await browser.newPage();
|
||||
|
@@ -3,6 +3,7 @@
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"description": "",
|
||||
"main": "dist/index.html",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "parcel build index.html",
|
||||
@@ -15,14 +16,15 @@
|
||||
"babel-plugin-syntax-async-functions": "^6.13.0",
|
||||
"babel-plugin-transform-regenerator": "^6.26.0",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"parcel-bundler": "1.12.3"
|
||||
"parcel-bundler": "1.12.3",
|
||||
"util": "^0.12.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"libp2p": "../../",
|
||||
"libp2p-bootstrap": "^0.12.1",
|
||||
"libp2p-mplex": "^0.10.1",
|
||||
"libp2p-noise": "^2.0.1",
|
||||
"libp2p-webrtc-direct": "^0.5.0",
|
||||
"libp2p-webrtc-direct": "^0.6.0",
|
||||
"peer-id": "^0.14.3"
|
||||
},
|
||||
"browser": {
|
||||
|
@@ -50,10 +50,12 @@ async function test () {
|
||||
const out = chunk.toString()
|
||||
|
||||
if (out.includes('Server running at')) {
|
||||
dialerUrl = out.replace('Server running at ', '')
|
||||
dialerUrl = out.split('Server running at ')[1]
|
||||
}
|
||||
|
||||
if (out.includes('✨ Built in ')) {
|
||||
|
||||
if (out.includes('Built in ')) {
|
||||
|
||||
try {
|
||||
const browser = await chromium.launch();
|
||||
const page = await browser.newPage();
|
||||
|
157
package.json
157
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "libp2p",
|
||||
"version": "0.30.12",
|
||||
"version": "0.31.3",
|
||||
"description": "JavaScript implementation of libp2p, a modular peer to peer network stack",
|
||||
"leadMaintainer": "Jacob Heun <jacobheun@gmail.com>",
|
||||
"main": "src/index.js",
|
||||
@@ -20,10 +20,28 @@
|
||||
"scripts": {
|
||||
"lint": "aegir lint",
|
||||
"build": "aegir build",
|
||||
"test": "npm run test:node && npm run test:browser",
|
||||
"build:proto": "npm run build:proto:circuit && npm run build:proto:identify && npm run build:proto:plaintext && npm run build:proto:address-book && npm run build:proto:proto-book && npm run build:proto:peer-record && npm run build:proto:envelope",
|
||||
"build:proto:circuit": "pbjs -t static-module -w commonjs -r libp2p-circuit --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/circuit/protocol/index.js ./src/circuit/protocol/index.proto",
|
||||
"build:proto:identify": "pbjs -t static-module -w commonjs -r libp2p-identify --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/identify/message.js ./src/identify/message.proto",
|
||||
"build:proto:plaintext": "pbjs -t static-module -w commonjs -r libp2p-plaintext --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/insecure/proto.js ./src/insecure/proto.proto",
|
||||
"build:proto:address-book": "pbjs -t static-module -w commonjs -r libp2p-address-book --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/peer-store/persistent/pb/address-book.js ./src/peer-store/persistent/pb/address-book.proto",
|
||||
"build:proto:proto-book": "pbjs -t static-module -w commonjs -r libp2p-proto-book --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/peer-store/persistent/pb/proto-book.js ./src/peer-store/persistent/pb/proto-book.proto",
|
||||
"build:proto:peer-record": "pbjs -t static-module -w commonjs -r libp2p-peer-record --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/record/peer-record/peer-record.js ./src/record/peer-record/peer-record.proto",
|
||||
"build:proto:envelope": "pbjs -t static-module -w commonjs -r libp2p-envelope --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/record/envelope/envelope.js ./src/record/envelope/envelope.proto",
|
||||
"build:proto-types": "npm run build:proto-types:circuit && npm run build:proto-types:identify && npm run build:proto-types:plaintext && npm run build:proto-types:address-book && npm run build:proto-types:proto-book && npm run build:proto-types:peer-record && npm run build:proto-types:envelope",
|
||||
"build:proto-types:circuit": "pbts -o src/circuit/protocol/index.d.ts src/circuit/protocol/index.js",
|
||||
"build:proto-types:identify": "pbts -o src/identify/message.d.ts src/identify/message.js",
|
||||
"build:proto-types:plaintext": "pbts -o src/insecure/proto.d.ts src/insecure/proto.js",
|
||||
"build:proto-types:address-book": "pbts -o src/peer-store/persistent/pb/address-book.d.ts src/peer-store/persistent/pb/address-book.js",
|
||||
"build:proto-types:proto-book": "pbts -o src/peer-store/persistent/pb/proto-book.d.ts src/peer-store/persistent/pb/proto-book.js",
|
||||
"build:proto-types:peer-record": "pbts -o src/record/peer-record/peer-record.d.ts src/record/peer-record/peer-record.js",
|
||||
"build:proto-types:envelope": "pbts -o src/record/envelope/envelope.d.ts src/record/envelope/envelope.js",
|
||||
"test": "aegir test",
|
||||
"test:ts": "aegir build --no-bundle && npm run test --prefix test/ts-use",
|
||||
"test:node": "aegir test -t node -f \"./test/**/*.{node,spec}.js\"",
|
||||
"test:browser": "aegir test -t browser",
|
||||
"test:examples": "cd examples && npm run test:all",
|
||||
"prepare": "aegir build --no-bundle",
|
||||
"release": "aegir release -t node -t browser",
|
||||
"release-minor": "aegir release --type minor -t node -t browser",
|
||||
"release-major": "aegir release --type major -t node -t browser",
|
||||
@@ -47,12 +65,18 @@
|
||||
"homepage": "https://libp2p.io",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12.0.0",
|
||||
"npm": ">=6.0.0"
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"browser": {
|
||||
"@motrix/nat-api": false
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "ipfs",
|
||||
"ignorePatterns": [
|
||||
"!.aegir.js",
|
||||
"test/ts-use"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@motrix/nat-api": "^0.3.1",
|
||||
"abort-controller": "^3.0.0",
|
||||
@@ -62,142 +86,143 @@
|
||||
"cids": "^1.1.5",
|
||||
"class-is": "^1.1.0",
|
||||
"debug": "^4.3.1",
|
||||
"err-code": "^2.0.0",
|
||||
"err-code": "^3.0.0",
|
||||
"es6-promisify": "^6.1.1",
|
||||
"events": "^3.2.0",
|
||||
"events": "^3.3.0",
|
||||
"hashlru": "^2.3.0",
|
||||
"interface-datastore": "^3.0.3",
|
||||
"ipfs-utils": "^6.0.0",
|
||||
"interface-datastore": "^4.0.0",
|
||||
"ipfs-utils": "^7.0.0",
|
||||
"it-all": "^1.0.4",
|
||||
"it-buffer": "^0.1.2",
|
||||
"it-drain": "^1.0.3",
|
||||
"it-filter": "^1.0.1",
|
||||
"it-first": "^1.0.4",
|
||||
"it-handshake": "^1.0.2",
|
||||
"it-length-prefixed": "^3.1.0",
|
||||
"it-handshake": "^2.0.0",
|
||||
"it-length-prefixed": "^5.0.2",
|
||||
"it-map": "^1.0.4",
|
||||
"it-merge": "1.0.0",
|
||||
"it-pipe": "^1.1.0",
|
||||
"it-protocol-buffers": "^0.2.0",
|
||||
"it-take": "1.0.0",
|
||||
"libp2p-crypto": "^0.19.0",
|
||||
"libp2p-interfaces": "^0.8.1",
|
||||
"libp2p-utils": "^0.2.2",
|
||||
"mafmt": "^8.0.0",
|
||||
"libp2p-crypto": "^0.19.4",
|
||||
"libp2p-interfaces": "^0.10.4",
|
||||
"libp2p-utils": "^0.3.1",
|
||||
"mafmt": "^9.0.0",
|
||||
"merge-options": "^3.0.4",
|
||||
"moving-average": "^1.0.0",
|
||||
"multiaddr": "^8.1.0",
|
||||
"multicodec": "^2.1.0",
|
||||
"multihashing-async": "^2.0.1",
|
||||
"multistream-select": "^1.0.0",
|
||||
"@vascosantos/moving-average": "^1.1.0",
|
||||
"multiaddr": "^9.0.1",
|
||||
"multicodec": "^3.0.1",
|
||||
"multihashing-async": "^2.1.2",
|
||||
"multistream-select": "^2.0.0",
|
||||
"mutable-proxy": "^1.0.0",
|
||||
"node-forge": "^0.10.0",
|
||||
"p-any": "^3.0.0",
|
||||
"p-fifo": "^1.0.0",
|
||||
"p-retry": "^4.2.0",
|
||||
"p-settle": "^4.0.1",
|
||||
"p-retry": "^4.4.0",
|
||||
"p-settle": "^4.1.1",
|
||||
"peer-id": "^0.14.2",
|
||||
"private-ip": "^2.0.0",
|
||||
"protons": "^2.0.0",
|
||||
"retimer": "^2.0.0",
|
||||
"private-ip": "^2.1.0",
|
||||
"protobufjs": "^6.10.2",
|
||||
"retimer": "^3.0.0",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"set-delayed-interval": "^1.0.0",
|
||||
"streaming-iterables": "^5.0.2",
|
||||
"timeout-abort-controller": "^1.1.1",
|
||||
"varint": "^6.0.0",
|
||||
"xsalsa20": "^1.0.2"
|
||||
"xsalsa20": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nodeutils/defaults-deep": "^1.1.0",
|
||||
"@types/es6-promisify": "^6.0.0",
|
||||
"@types/node-forge": "^0.9.7",
|
||||
"@types/varint": "^6.0.0",
|
||||
"abortable-iterator": "^3.0.0",
|
||||
"aegir": "^29.2.0",
|
||||
"chai-bytes": "^0.1.2",
|
||||
"chai-string": "^1.5.0",
|
||||
"delay": "^4.4.0",
|
||||
"aegir": "^33.1.1",
|
||||
"buffer": "^6.0.3",
|
||||
"delay": "^5.0.0",
|
||||
"interop-libp2p": "^0.3.0",
|
||||
"into-stream": "^6.0.0",
|
||||
"ipfs-http-client": "^48.2.2",
|
||||
"ipfs-http-client": "^49.0.4",
|
||||
"it-concat": "^1.0.0",
|
||||
"it-pair": "^1.0.0",
|
||||
"it-pushable": "^1.4.0",
|
||||
"libp2p": ".",
|
||||
"libp2p-bootstrap": "^0.12.0",
|
||||
"libp2p-delegated-content-routing": "^0.9.0",
|
||||
"libp2p-delegated-peer-routing": "^0.8.0",
|
||||
"libp2p-floodsub": "^0.24.0",
|
||||
"libp2p-gossipsub": "^0.8.0",
|
||||
"libp2p-kad-dht": "^0.20.5",
|
||||
"libp2p-mdns": "^0.15.0",
|
||||
"libp2p-bootstrap": "^0.12.3",
|
||||
"libp2p-delegated-content-routing": "^0.10.0",
|
||||
"libp2p-delegated-peer-routing": "^0.9.0",
|
||||
"libp2p-floodsub": "^0.25.0",
|
||||
"libp2p-gossipsub": "^0.9.0",
|
||||
"libp2p-kad-dht": "^0.22.0",
|
||||
"libp2p-mdns": "^0.16.0",
|
||||
"libp2p-mplex": "^0.10.1",
|
||||
"libp2p-noise": "^2.0.0",
|
||||
"libp2p-secio": "^0.13.1",
|
||||
"libp2p-tcp": "^0.15.1",
|
||||
"libp2p-webrtc-star": "^0.20.0",
|
||||
"libp2p-websockets": "^0.15.0",
|
||||
"multihashes": "^3.0.1",
|
||||
"libp2p-noise": "^3.0.0",
|
||||
"libp2p-tcp": "^0.15.4",
|
||||
"libp2p-webrtc-star": "^0.22.2",
|
||||
"libp2p-websockets": "^0.15.6",
|
||||
"multihashes": "^4.0.2",
|
||||
"nock": "^13.0.3",
|
||||
"p-defer": "^3.0.0",
|
||||
"p-times": "^3.0.0",
|
||||
"p-wait-for": "^3.2.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"sinon": "^9.2.4",
|
||||
"uint8arrays": "^2.0.5"
|
||||
"sinon": "^10.0.0",
|
||||
"uint8arrays": "^2.1.3",
|
||||
"util": "^0.12.3"
|
||||
},
|
||||
"contributors": [
|
||||
"David Dias <daviddias.p@gmail.com>",
|
||||
"Jacob Heun <jacobheun@gmail.com>",
|
||||
"Vasco Santos <vasco.santos@moxy.studio>",
|
||||
"Alan Shaw <alan@tableflip.io>",
|
||||
"Jacob Heun <jacobheun@gmail.com>",
|
||||
"Alex Potsides <alex@achingbrain.net>",
|
||||
"Alan Shaw <alan@tableflip.io>",
|
||||
"Cayman <caymannava@gmail.com>",
|
||||
"Pedro Teixeira <i@pgte.me>",
|
||||
"Friedel Ziegelmayer <dignifiedquire@gmail.com>",
|
||||
"Maciej Krüger <mkg20001@gmail.com>",
|
||||
"Hugo Dias <mail@hugodias.me>",
|
||||
"Volker Mische <volker.mische@gmail.com>",
|
||||
"dirkmc <dirkmdev@gmail.com>",
|
||||
"Volker Mische <volker.mische@gmail.com>",
|
||||
"Richard Littauer <richard.littauer@gmail.com>",
|
||||
"a1300 <matthias-knopp@gmx.net>",
|
||||
"Elven <mon.samuel@qq.com>",
|
||||
"Andrew Nesbitt <andrewnez@gmail.com>",
|
||||
"ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <victorbjelkholm@gmail.com>",
|
||||
"Giovanni T. Parra <fiatjaf@gmail.com>",
|
||||
"Ryan Bell <ryan@piing.net>",
|
||||
"ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <victorbjelkholm@gmail.com>",
|
||||
"Thomas Eizinger <thomas@eizinger.io>",
|
||||
"Samlior <samlior@foxmail.com>",
|
||||
"Didrik Nordström <didrik@betamos.se>",
|
||||
"Julien Bouquillon <contact@revolunet.com>",
|
||||
"Kevin Kwok <antimatter15@gmail.com>",
|
||||
"Kevin Lacker <lacker@gmail.com>",
|
||||
"Miguel Mota <miguelmota2@gmail.com>",
|
||||
"Ryan Bell <ryan@piing.net>",
|
||||
"Andrew Nesbitt <andrewnez@gmail.com>",
|
||||
"Didrik Nordström <didrik.nordstrom@gmail.com>",
|
||||
"Nuno Nogueira <nunofmn@gmail.com>",
|
||||
"Philipp Muens <raute1337@gmx.de>",
|
||||
"RasmusErik Voel Jensen <github@solsort.com>",
|
||||
"Smite Chow <xiaopengyou@live.com>",
|
||||
"Soeren <nikorpoulsen@gmail.com>",
|
||||
"Sönke Hahn <soenkehahn@gmail.com>",
|
||||
"TJKoury <TJKoury@gmail.com>",
|
||||
"Tiago Alves <alvesjtiago@gmail.com>",
|
||||
"Daijiro Wachi <daijiro.wachi@gmail.com>",
|
||||
"Cindy Wu <ciindy.wu@gmail.com>",
|
||||
"Chris Bratlien <chrisbratlien@gmail.com>",
|
||||
"Yusef Napora <yusef@napora.org>",
|
||||
"Zane Starr <zcstarr@gmail.com>",
|
||||
"Bernd Strehl <bernd.strehl@gmail.com>",
|
||||
"ebinks <elizabethjbinks@gmail.com>",
|
||||
"Ethan Lam <elmemphis2000@gmail.com>",
|
||||
"isan_rivkin <isanrivkin@gmail.com>",
|
||||
"robertkiel <robert.kiel@validitylabs.org>",
|
||||
"RasmusErik Voel Jensen <github@solsort.com>",
|
||||
"Aleksei <vozhdb@gmail.com>",
|
||||
"Bernd Strehl <bernd.strehl@gmail.com>",
|
||||
"Chris Bratlien <chrisbratlien@gmail.com>",
|
||||
"Cindy Wu <ciindy.wu@gmail.com>",
|
||||
"Daijiro Wachi <daijiro.wachi@gmail.com>",
|
||||
"Diogo Silva <fsdiogo@gmail.com>",
|
||||
"Dmitriy Ryajov <dryajov@gmail.com>",
|
||||
"Ethan Lam <elmemphis2000@gmail.com>",
|
||||
"Fei Liu <liu.feiwood@gmail.com>",
|
||||
"Felipe Martins <felipebrasil93@gmail.com>",
|
||||
"Florian-Merle <florian.david.merle@gmail.com>",
|
||||
"Francis Gulotta <wizard@roborooter.com>",
|
||||
"Dmitriy Ryajov <dryajov@gmail.com>",
|
||||
"Franck Royer <franck@royer.one>",
|
||||
"Henrique Dias <hacdias@gmail.com>",
|
||||
"Irakli Gozalishvili <rfobic@gmail.com>",
|
||||
"Diogo Silva <fsdiogo@gmail.com>",
|
||||
"Joel Gustafson <joelg@mit.edu>"
|
||||
"Joel Gustafson <joelg@mit.edu>",
|
||||
"Julien Bouquillon <contact@revolunet.com>",
|
||||
"Kevin Kwok <antimatter15@gmail.com>",
|
||||
"Kevin Lacker <lacker@gmail.com>",
|
||||
"Miguel Mota <miguelmota2@gmail.com>"
|
||||
]
|
||||
}
|
||||
|
2
scripts/node-globals.js
Normal file
2
scripts/node-globals.js
Normal file
@@ -0,0 +1,2 @@
|
||||
// @ts-nocheck
|
||||
export const { Buffer } = require('buffer')
|
@@ -1,15 +1,9 @@
|
||||
'use strict'
|
||||
|
||||
/** @typedef {import('../types').EventEmitterFactory} Events */
|
||||
/** @type Events */
|
||||
const EventEmitter = require('events')
|
||||
const multiaddr = require('multiaddr')
|
||||
const { EventEmitter } = require('events')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const PeerId = require('peer-id')
|
||||
|
||||
/**
|
||||
* @typedef {import('multiaddr')} Multiaddr
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} AddressManagerOptions
|
||||
* @property {string[]} [listen = []] - list of multiaddrs string representation to listen.
|
||||
@@ -47,7 +41,7 @@ class AddressManager extends EventEmitter {
|
||||
* @returns {Multiaddr[]}
|
||||
*/
|
||||
getListenAddrs () {
|
||||
return Array.from(this.listen).map((a) => multiaddr(a))
|
||||
return Array.from(this.listen).map((a) => new Multiaddr(a))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,7 +50,7 @@ class AddressManager extends EventEmitter {
|
||||
* @returns {Multiaddr[]}
|
||||
*/
|
||||
getAnnounceAddrs () {
|
||||
return Array.from(this.announce).map((a) => multiaddr(a))
|
||||
return Array.from(this.announce).map((a) => new Multiaddr(a))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +59,7 @@ class AddressManager extends EventEmitter {
|
||||
* @returns {Array<Multiaddr>}
|
||||
*/
|
||||
getObservedAddrs () {
|
||||
return Array.from(this.observed).map((a) => multiaddr(a))
|
||||
return Array.from(this.observed).map((a) => new Multiaddr(a))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,7 +68,7 @@ class AddressManager extends EventEmitter {
|
||||
* @param {string | Multiaddr} addr
|
||||
*/
|
||||
addObservedAddr (addr) {
|
||||
let ma = multiaddr(addr)
|
||||
let ma = new Multiaddr(addr)
|
||||
const remotePeer = ma.getPeerId()
|
||||
|
||||
// strip our peer id if it has been passed
|
||||
@@ -83,7 +77,7 @@ class AddressManager extends EventEmitter {
|
||||
|
||||
// use same encoding for comparison
|
||||
if (remotePeerId.equals(this.peerId)) {
|
||||
ma = ma.decapsulate(multiaddr(`/p2p/${this.peerId}`))
|
||||
ma = ma.decapsulate(new Multiaddr(`/p2p/${this.peerId}`))
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -37,7 +37,7 @@ Libp2p circuit configuration can be seen at [Setup with Relay](../../doc/CONFIGU
|
||||
Once you have a circuit relay node running, you can configure other nodes to use it as a relay as follows:
|
||||
|
||||
```js
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const Libp2p = require('libp2p')
|
||||
const TCP = require('libp2p-tcp')
|
||||
const MPLEX = require('libp2p-mplex')
|
||||
@@ -47,7 +47,7 @@ const relayAddr = ...
|
||||
|
||||
const node = await Libp2p.create({
|
||||
addresses: {
|
||||
listen: [multiaddr(`${relayAddr}/p2p-circuit`)]
|
||||
listen: [new Multiaddr(`${relayAddr}/p2p-circuit`)]
|
||||
},
|
||||
modules: {
|
||||
transport: [TCP],
|
||||
|
@@ -7,7 +7,7 @@ const log = Object.assign(debug('libp2p:auto-relay'), {
|
||||
|
||||
const uint8ArrayFromString = require('uint8arrays/from-string')
|
||||
const uint8ArrayToString = require('uint8arrays/to-string')
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const PeerId = require('peer-id')
|
||||
|
||||
const { relay: multicodec } = require('./multicodec')
|
||||
@@ -31,6 +31,7 @@ const {
|
||||
*
|
||||
* @typedef {Object} AutoRelayOptions
|
||||
* @property {number} [maxListeners = 1] - maximum number of relays to listen.
|
||||
* @property {(error: Error, msg?: string) => {}} [onError]
|
||||
*/
|
||||
|
||||
class AutoRelay {
|
||||
@@ -40,7 +41,7 @@ class AutoRelay {
|
||||
* @class
|
||||
* @param {AutoRelayProperties & AutoRelayOptions} props
|
||||
*/
|
||||
constructor ({ libp2p, maxListeners = 1 }) {
|
||||
constructor ({ libp2p, maxListeners = 1, onError }) {
|
||||
this._libp2p = libp2p
|
||||
this._peerId = libp2p.peerId
|
||||
this._peerStore = libp2p.peerStore
|
||||
@@ -60,6 +61,15 @@ class AutoRelay {
|
||||
|
||||
this._peerStore.on('change:protocols', this._onProtocolChange)
|
||||
this._connectionManager.on('peer:disconnect', this._onPeerDisconnected)
|
||||
|
||||
/**
|
||||
* @param {Error} error
|
||||
* @param {string} [msg]
|
||||
*/
|
||||
this._onError = (error, msg) => {
|
||||
log.error(msg || error)
|
||||
onError && onError(error, msg)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,7 +117,7 @@ class AutoRelay {
|
||||
await this._addListenRelay(connection, id)
|
||||
}
|
||||
} catch (err) {
|
||||
log.error(err)
|
||||
this._onError(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,10 +167,10 @@ class AutoRelay {
|
||||
|
||||
// Attempt to listen on relay
|
||||
try {
|
||||
await this._transportManager.listen([multiaddr(listenAddr)])
|
||||
await this._transportManager.listen([new Multiaddr(listenAddr)])
|
||||
// Announce multiaddrs will update on listen success by TransportManager event being triggered
|
||||
} catch (err) {
|
||||
log.error(err)
|
||||
this._onError(err)
|
||||
this._listenRelays.delete(id)
|
||||
}
|
||||
}
|
||||
@@ -231,8 +241,7 @@ class AutoRelay {
|
||||
|
||||
// Try to listen on known peers that are not connected
|
||||
for (const peerId of knownHopsToDial) {
|
||||
const connection = await this._libp2p.dial(peerId)
|
||||
await this._addListenRelay(connection, peerId.toB58String())
|
||||
await this._tryToListenOnRelay(peerId)
|
||||
|
||||
// Check if already listening on enough relays
|
||||
if (this._listenRelays.size >= this.maxListeners) {
|
||||
@@ -247,12 +256,11 @@ class AutoRelay {
|
||||
if (!provider.multiaddrs.length) {
|
||||
continue
|
||||
}
|
||||
|
||||
const peerId = provider.id
|
||||
|
||||
this._peerStore.addressBook.add(peerId, provider.multiaddrs)
|
||||
const connection = await this._libp2p.dial(peerId)
|
||||
|
||||
await this._addListenRelay(connection, peerId.toB58String())
|
||||
await this._tryToListenOnRelay(peerId)
|
||||
|
||||
// Check if already listening on enough relays
|
||||
if (this._listenRelays.size >= this.maxListeners) {
|
||||
@@ -260,7 +268,19 @@ class AutoRelay {
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
log.error(err)
|
||||
this._onError(err)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PeerId} peerId
|
||||
*/
|
||||
async _tryToListenOnRelay (peerId) {
|
||||
try {
|
||||
const connection = await this._libp2p.dial(peerId)
|
||||
await this._addListenRelay(connection, peerId.toB58String())
|
||||
} catch (err) {
|
||||
this._onError(err, `could not connect and listen on known hop relay ${peerId.toB58String()}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -18,17 +18,17 @@ const { stop } = require('./stop')
|
||||
const multicodec = require('./../multicodec')
|
||||
|
||||
/**
|
||||
* @typedef {import('../../types').CircuitRequest} CircuitRequest
|
||||
* @typedef {import('../protocol').ICircuitRelay} ICircuitRelay
|
||||
* @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
|
||||
* @typedef {import('./stream-handler')<CircuitRequest>} StreamHandlerT
|
||||
* @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
|
||||
* @typedef {import('../transport')} Transport
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} HopRequest
|
||||
* @property {Connection} connection
|
||||
* @property {CircuitRequest} request
|
||||
* @property {StreamHandlerT} streamHandler
|
||||
* @property {ICircuitRelay} request
|
||||
* @property {StreamHandler} streamHandler
|
||||
* @property {Transport} circuit
|
||||
*/
|
||||
|
||||
@@ -58,6 +58,11 @@ async function handleHop ({
|
||||
return log.error('invalid hop request via peer %s', connection.remotePeer.toB58String(), err)
|
||||
}
|
||||
|
||||
if (!request.dstPeer) {
|
||||
log('HOP request received but we do not receive a dstPeer')
|
||||
return
|
||||
}
|
||||
|
||||
// Get the connection to the destination (stop) peer
|
||||
const destinationPeer = new PeerId(request.dstPeer.id)
|
||||
|
||||
@@ -113,8 +118,8 @@ async function handleHop ({
|
||||
*
|
||||
* @param {object} options
|
||||
* @param {Connection} options.connection - Connection to the relay
|
||||
* @param {CircuitRequest} options.request
|
||||
* @returns {Promise<Connection>}
|
||||
* @param {ICircuitRelay} options.request
|
||||
* @returns {Promise<MuxedStream>}
|
||||
*/
|
||||
async function hop ({
|
||||
connection,
|
||||
@@ -128,6 +133,10 @@ async function hop ({
|
||||
|
||||
const response = await streamHandler.read()
|
||||
|
||||
if (!response) {
|
||||
throw errCode(new Error('HOP request had no response'), Errors.ERR_HOP_REQUEST_FAILED)
|
||||
}
|
||||
|
||||
if (response.code === CircuitPB.Status.SUCCESS) {
|
||||
log('hop request was successful')
|
||||
return streamHandler.rest()
|
||||
@@ -159,7 +168,7 @@ async function canHop ({
|
||||
const response = await streamHandler.read()
|
||||
await streamHandler.close()
|
||||
|
||||
if (response.code !== CircuitPB.Status.SUCCESS) {
|
||||
if (!response || response.code !== CircuitPB.Status.SUCCESS) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -171,7 +180,7 @@ async function canHop ({
|
||||
*
|
||||
* @param {Object} options
|
||||
* @param {Connection} options.connection
|
||||
* @param {StreamHandlerT} options.streamHandler
|
||||
* @param {StreamHandler} options.streamHandler
|
||||
* @param {Transport} options.circuit
|
||||
* @private
|
||||
*/
|
||||
|
@@ -13,8 +13,7 @@ const { validateAddrs } = require('./utils')
|
||||
/**
|
||||
* @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
|
||||
* @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
|
||||
* @typedef {import('../../types').CircuitRequest} CircuitRequest
|
||||
* @typedef {import('./stream-handler')<CircuitRequest>} StreamHandlerT
|
||||
* @typedef {import('../protocol').ICircuitRelay} ICircuitRelay
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -23,8 +22,8 @@ const { validateAddrs } = require('./utils')
|
||||
* @private
|
||||
* @param {Object} options
|
||||
* @param {Connection} options.connection
|
||||
* @param {CircuitRequest} options.request - The CircuitRelay protobuf request (unencoded)
|
||||
* @param {StreamHandlerT} options.streamHandler
|
||||
* @param {ICircuitRelay} options.request - The CircuitRelay protobuf request (unencoded)
|
||||
* @param {StreamHandler} options.streamHandler
|
||||
* @returns {Promise<MuxedStream>|void} Resolves a duplex iterable
|
||||
*/
|
||||
module.exports.handleStop = function handleStop ({
|
||||
@@ -54,7 +53,7 @@ module.exports.handleStop = function handleStop ({
|
||||
* @private
|
||||
* @param {Object} options
|
||||
* @param {Connection} options.connection
|
||||
* @param {CircuitRequest} options.request - The CircuitRelay protobuf request (unencoded)
|
||||
* @param {ICircuitRelay} options.request - The CircuitRelay protobuf request (unencoded)
|
||||
* @returns {Promise<MuxedStream|void>} Resolves a duplex iterable
|
||||
*/
|
||||
module.exports.stop = async function stop ({
|
||||
@@ -68,6 +67,10 @@ module.exports.stop = async function stop ({
|
||||
streamHandler.write(request)
|
||||
const response = await streamHandler.read()
|
||||
|
||||
if (!response) {
|
||||
return streamHandler.close()
|
||||
}
|
||||
|
||||
if (response.code === CircuitPB.Status.SUCCESS) {
|
||||
log('stop request to %s was successful', connection.remotePeer.toB58String())
|
||||
return streamHandler.rest()
|
||||
|
@@ -6,16 +6,15 @@ const log = Object.assign(debug('libp2p:circuit:stream-handler'), {
|
||||
})
|
||||
|
||||
const lp = require('it-length-prefixed')
|
||||
// @ts-ignore it-handshake does not export types
|
||||
const handshake = require('it-handshake')
|
||||
const { CircuitRelay: CircuitPB } = require('../protocol')
|
||||
const { CircuitRelay } = require('../protocol')
|
||||
|
||||
/**
|
||||
* @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
|
||||
* @typedef {import('../protocol').ICircuitRelay} ICircuitRelay
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template T
|
||||
*/
|
||||
class StreamHandler {
|
||||
/**
|
||||
* Create a stream handler for connection
|
||||
@@ -29,6 +28,7 @@ class StreamHandler {
|
||||
this.stream = stream
|
||||
|
||||
this.shake = handshake(this.stream)
|
||||
// @ts-ignore options are not optional
|
||||
this.decoder = lp.decode.fromReader(this.shake.reader, { maxDataLength: maxLength })
|
||||
}
|
||||
|
||||
@@ -36,12 +36,11 @@ class StreamHandler {
|
||||
* Read and decode message
|
||||
*
|
||||
* @async
|
||||
* @returns {Promise<T|undefined>}
|
||||
*/
|
||||
async read () {
|
||||
const msg = await this.decoder.next()
|
||||
if (msg.value) {
|
||||
const value = CircuitPB.decode(msg.value.slice())
|
||||
const value = CircuitRelay.decode(msg.value.slice())
|
||||
log('read message type', value.type)
|
||||
return value
|
||||
}
|
||||
@@ -54,13 +53,13 @@ class StreamHandler {
|
||||
/**
|
||||
* Encode and write array of buffers
|
||||
*
|
||||
* @param {CircuitPB} msg - An unencoded CircuitRelay protobuf message
|
||||
* @param {ICircuitRelay} msg - An unencoded CircuitRelay protobuf message
|
||||
* @returns {void}
|
||||
*/
|
||||
write (msg) {
|
||||
log('write message type %s', msg.type)
|
||||
// @ts-ignore lp.encode expects type type 'Buffer | BufferList', not 'Uint8Array'
|
||||
this.shake.write(lp.encode.single(CircuitPB.encode(msg)))
|
||||
this.shake.write(lp.encode.single(CircuitRelay.encode(msg).finish()))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,6 +72,9 @@ class StreamHandler {
|
||||
return this.shake.stream
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ICircuitRelay} msg - An unencoded CircuitRelay protobuf message
|
||||
*/
|
||||
end (msg) {
|
||||
this.write(msg)
|
||||
this.close()
|
||||
|
@@ -1,18 +1,18 @@
|
||||
'use strict'
|
||||
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const { CircuitRelay } = require('../protocol')
|
||||
|
||||
/**
|
||||
* @typedef {import('./stream-handler')} StreamHandler
|
||||
* @typedef {import('../../types').CircuitStatus} CircuitStatus
|
||||
* @typedef {import('../protocol').ICircuitRelay} ICircuitRelay
|
||||
*/
|
||||
|
||||
/**
|
||||
* Write a response
|
||||
*
|
||||
* @param {StreamHandler} streamHandler
|
||||
* @param {CircuitStatus} status
|
||||
* @param {import('../protocol').CircuitRelay.Status} status
|
||||
*/
|
||||
function writeResponse (streamHandler, status) {
|
||||
streamHandler.write({
|
||||
@@ -24,14 +24,16 @@ function writeResponse (streamHandler, status) {
|
||||
/**
|
||||
* Validate incomming HOP/STOP message
|
||||
*
|
||||
* @param {*} msg - A CircuitRelay unencoded protobuf message
|
||||
* @param {ICircuitRelay} msg - A CircuitRelay unencoded protobuf message
|
||||
* @param {StreamHandler} streamHandler
|
||||
*/
|
||||
function validateAddrs (msg, streamHandler) {
|
||||
try {
|
||||
msg.dstPeer.addrs.forEach((addr) => {
|
||||
return multiaddr(addr)
|
||||
})
|
||||
if (msg.dstPeer && msg.dstPeer.addrs) {
|
||||
msg.dstPeer.addrs.forEach((addr) => {
|
||||
return new Multiaddr(addr)
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
writeResponse(streamHandler, msg.type === CircuitRelay.Type.HOP
|
||||
? CircuitRelay.Status.HOP_DST_MULTIADDR_INVALID
|
||||
@@ -40,9 +42,11 @@ function validateAddrs (msg, streamHandler) {
|
||||
}
|
||||
|
||||
try {
|
||||
msg.srcPeer.addrs.forEach((addr) => {
|
||||
return multiaddr(addr)
|
||||
})
|
||||
if (msg.srcPeer && msg.srcPeer.addrs) {
|
||||
msg.srcPeer.addrs.forEach((addr) => {
|
||||
return new Multiaddr(addr)
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
writeResponse(streamHandler, msg.type === CircuitRelay.Type.HOP
|
||||
? CircuitRelay.Status.HOP_SRC_MULTIADDR_INVALID
|
||||
|
@@ -8,13 +8,12 @@ const log = Object.assign(debug('libp2p:relay'), {
|
||||
const {
|
||||
setDelayedInterval,
|
||||
clearDelayedInterval
|
||||
// @ts-ignore set-delayed-interval does not export types
|
||||
} = require('set-delayed-interval')
|
||||
|
||||
const AutoRelay = require('./auto-relay')
|
||||
const { namespaceToCid } = require('./utils')
|
||||
const {
|
||||
ADVERTISE_BOOT_DELAY,
|
||||
ADVERTISE_TTL,
|
||||
RELAY_RENDEZVOUS_NS
|
||||
} = require('./constants')
|
||||
|
||||
@@ -45,12 +44,6 @@ class Relay {
|
||||
constructor (libp2p) {
|
||||
this._libp2p = libp2p
|
||||
this._options = {
|
||||
advertise: {
|
||||
bootDelay: ADVERTISE_BOOT_DELAY,
|
||||
enabled: true,
|
||||
ttl: ADVERTISE_TTL,
|
||||
...libp2p._config.relay.advertise
|
||||
},
|
||||
...libp2p._config.relay
|
||||
}
|
||||
|
||||
|
@@ -1,10 +1,9 @@
|
||||
'use strict'
|
||||
|
||||
const { EventEmitter } = require('events')
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
|
||||
/**
|
||||
* @typedef {import('multiaddr')} Multiaddr
|
||||
* @typedef {import('libp2p-interfaces/src/transport/types').Listener} Listener
|
||||
*/
|
||||
|
||||
@@ -24,7 +23,7 @@ module.exports = (libp2p) => {
|
||||
async function listen (addr) {
|
||||
const addrString = String(addr).split('/p2p-circuit').find(a => a !== '')
|
||||
|
||||
const relayConn = await libp2p.dial(multiaddr(addrString))
|
||||
const relayConn = await libp2p.dial(new Multiaddr(addrString))
|
||||
const relayedAddr = relayConn.remoteAddr.encapsulate('/p2p-circuit')
|
||||
|
||||
listeningAddrs.set(relayConn.remotePeer.toB58String(), relayedAddr)
|
||||
|
173
src/circuit/protocol/index.d.ts
vendored
Normal file
173
src/circuit/protocol/index.d.ts
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
import * as $protobuf from "protobufjs";
|
||||
/** Properties of a CircuitRelay. */
|
||||
export interface ICircuitRelay {
|
||||
|
||||
/** CircuitRelay type */
|
||||
type?: (CircuitRelay.Type|null);
|
||||
|
||||
/** CircuitRelay srcPeer */
|
||||
srcPeer?: (CircuitRelay.IPeer|null);
|
||||
|
||||
/** CircuitRelay dstPeer */
|
||||
dstPeer?: (CircuitRelay.IPeer|null);
|
||||
|
||||
/** CircuitRelay code */
|
||||
code?: (CircuitRelay.Status|null);
|
||||
}
|
||||
|
||||
/** Represents a CircuitRelay. */
|
||||
export class CircuitRelay implements ICircuitRelay {
|
||||
|
||||
/**
|
||||
* Constructs a new CircuitRelay.
|
||||
* @param [p] Properties to set
|
||||
*/
|
||||
constructor(p?: ICircuitRelay);
|
||||
|
||||
/** CircuitRelay type. */
|
||||
public type: CircuitRelay.Type;
|
||||
|
||||
/** CircuitRelay srcPeer. */
|
||||
public srcPeer?: (CircuitRelay.IPeer|null);
|
||||
|
||||
/** CircuitRelay dstPeer. */
|
||||
public dstPeer?: (CircuitRelay.IPeer|null);
|
||||
|
||||
/** CircuitRelay code. */
|
||||
public code: CircuitRelay.Status;
|
||||
|
||||
/**
|
||||
* Encodes the specified CircuitRelay message. Does not implicitly {@link CircuitRelay.verify|verify} messages.
|
||||
* @param m CircuitRelay message or plain object to encode
|
||||
* @param [w] Writer to encode to
|
||||
* @returns Writer
|
||||
*/
|
||||
public static encode(m: ICircuitRelay, w?: $protobuf.Writer): $protobuf.Writer;
|
||||
|
||||
/**
|
||||
* Decodes a CircuitRelay message from the specified reader or buffer.
|
||||
* @param r Reader or buffer to decode from
|
||||
* @param [l] Message length if known beforehand
|
||||
* @returns CircuitRelay
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
public static decode(r: ($protobuf.Reader|Uint8Array), l?: number): CircuitRelay;
|
||||
|
||||
/**
|
||||
* Creates a CircuitRelay message from a plain object. Also converts values to their respective internal types.
|
||||
* @param d Plain object
|
||||
* @returns CircuitRelay
|
||||
*/
|
||||
public static fromObject(d: { [k: string]: any }): CircuitRelay;
|
||||
|
||||
/**
|
||||
* Creates a plain object from a CircuitRelay message. Also converts values to other types if specified.
|
||||
* @param m CircuitRelay
|
||||
* @param [o] Conversion options
|
||||
* @returns Plain object
|
||||
*/
|
||||
public static toObject(m: CircuitRelay, o?: $protobuf.IConversionOptions): { [k: string]: any };
|
||||
|
||||
/**
|
||||
* Converts this CircuitRelay to JSON.
|
||||
* @returns JSON object
|
||||
*/
|
||||
public toJSON(): { [k: string]: any };
|
||||
}
|
||||
|
||||
export namespace CircuitRelay {
|
||||
|
||||
/** Status enum. */
|
||||
enum Status {
|
||||
SUCCESS = 100,
|
||||
HOP_SRC_ADDR_TOO_LONG = 220,
|
||||
HOP_DST_ADDR_TOO_LONG = 221,
|
||||
HOP_SRC_MULTIADDR_INVALID = 250,
|
||||
HOP_DST_MULTIADDR_INVALID = 251,
|
||||
HOP_NO_CONN_TO_DST = 260,
|
||||
HOP_CANT_DIAL_DST = 261,
|
||||
HOP_CANT_OPEN_DST_STREAM = 262,
|
||||
HOP_CANT_SPEAK_RELAY = 270,
|
||||
HOP_CANT_RELAY_TO_SELF = 280,
|
||||
STOP_SRC_ADDR_TOO_LONG = 320,
|
||||
STOP_DST_ADDR_TOO_LONG = 321,
|
||||
STOP_SRC_MULTIADDR_INVALID = 350,
|
||||
STOP_DST_MULTIADDR_INVALID = 351,
|
||||
STOP_RELAY_REFUSED = 390,
|
||||
MALFORMED_MESSAGE = 400
|
||||
}
|
||||
|
||||
/** Type enum. */
|
||||
enum Type {
|
||||
HOP = 1,
|
||||
STOP = 2,
|
||||
STATUS = 3,
|
||||
CAN_HOP = 4
|
||||
}
|
||||
|
||||
/** Properties of a Peer. */
|
||||
interface IPeer {
|
||||
|
||||
/** Peer id */
|
||||
id: Uint8Array;
|
||||
|
||||
/** Peer addrs */
|
||||
addrs?: (Uint8Array[]|null);
|
||||
}
|
||||
|
||||
/** Represents a Peer. */
|
||||
class Peer implements IPeer {
|
||||
|
||||
/**
|
||||
* Constructs a new Peer.
|
||||
* @param [p] Properties to set
|
||||
*/
|
||||
constructor(p?: CircuitRelay.IPeer);
|
||||
|
||||
/** Peer id. */
|
||||
public id: Uint8Array;
|
||||
|
||||
/** Peer addrs. */
|
||||
public addrs: Uint8Array[];
|
||||
|
||||
/**
|
||||
* Encodes the specified Peer message. Does not implicitly {@link CircuitRelay.Peer.verify|verify} messages.
|
||||
* @param m Peer message or plain object to encode
|
||||
* @param [w] Writer to encode to
|
||||
* @returns Writer
|
||||
*/
|
||||
public static encode(m: CircuitRelay.IPeer, w?: $protobuf.Writer): $protobuf.Writer;
|
||||
|
||||
/**
|
||||
* Decodes a Peer message from the specified reader or buffer.
|
||||
* @param r Reader or buffer to decode from
|
||||
* @param [l] Message length if known beforehand
|
||||
* @returns Peer
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
public static decode(r: ($protobuf.Reader|Uint8Array), l?: number): CircuitRelay.Peer;
|
||||
|
||||
/**
|
||||
* Creates a Peer message from a plain object. Also converts values to their respective internal types.
|
||||
* @param d Plain object
|
||||
* @returns Peer
|
||||
*/
|
||||
public static fromObject(d: { [k: string]: any }): CircuitRelay.Peer;
|
||||
|
||||
/**
|
||||
* Creates a plain object from a Peer message. Also converts values to other types if specified.
|
||||
* @param m Peer
|
||||
* @param [o] Conversion options
|
||||
* @returns Plain object
|
||||
*/
|
||||
public static toObject(m: CircuitRelay.Peer, o?: $protobuf.IConversionOptions): { [k: string]: any };
|
||||
|
||||
/**
|
||||
* Converts this Peer to JSON.
|
||||
* @returns JSON object
|
||||
*/
|
||||
public toJSON(): { [k: string]: any };
|
||||
}
|
||||
}
|
@@ -1,46 +1,530 @@
|
||||
'use strict'
|
||||
const protobuf = require('protons')
|
||||
/*eslint-disable*/
|
||||
"use strict";
|
||||
|
||||
/** @type {{CircuitRelay: import('../../types').CircuitMessageProto}} */
|
||||
module.exports = protobuf(`
|
||||
message CircuitRelay {
|
||||
var $protobuf = require("protobufjs/minimal");
|
||||
|
||||
enum Status {
|
||||
SUCCESS = 100;
|
||||
HOP_SRC_ADDR_TOO_LONG = 220;
|
||||
HOP_DST_ADDR_TOO_LONG = 221;
|
||||
HOP_SRC_MULTIADDR_INVALID = 250;
|
||||
HOP_DST_MULTIADDR_INVALID = 251;
|
||||
HOP_NO_CONN_TO_DST = 260;
|
||||
HOP_CANT_DIAL_DST = 261;
|
||||
HOP_CANT_OPEN_DST_STREAM = 262;
|
||||
HOP_CANT_SPEAK_RELAY = 270;
|
||||
HOP_CANT_RELAY_TO_SELF = 280;
|
||||
STOP_SRC_ADDR_TOO_LONG = 320;
|
||||
STOP_DST_ADDR_TOO_LONG = 321;
|
||||
STOP_SRC_MULTIADDR_INVALID = 350;
|
||||
STOP_DST_MULTIADDR_INVALID = 351;
|
||||
STOP_RELAY_REFUSED = 390;
|
||||
MALFORMED_MESSAGE = 400;
|
||||
}
|
||||
// Common aliases
|
||||
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
|
||||
|
||||
enum Type { // RPC identifier, either HOP, STOP or STATUS
|
||||
HOP = 1;
|
||||
STOP = 2;
|
||||
STATUS = 3;
|
||||
CAN_HOP = 4;
|
||||
}
|
||||
// Exported root namespace
|
||||
var $root = $protobuf.roots["libp2p-circuit"] || ($protobuf.roots["libp2p-circuit"] = {});
|
||||
|
||||
message Peer {
|
||||
required bytes id = 1; // peer id
|
||||
repeated bytes addrs = 2; // peer's known addresses
|
||||
}
|
||||
$root.CircuitRelay = (function() {
|
||||
|
||||
optional Type type = 1; // Type of the message
|
||||
/**
|
||||
* Properties of a CircuitRelay.
|
||||
* @exports ICircuitRelay
|
||||
* @interface ICircuitRelay
|
||||
* @property {CircuitRelay.Type|null} [type] CircuitRelay type
|
||||
* @property {CircuitRelay.IPeer|null} [srcPeer] CircuitRelay srcPeer
|
||||
* @property {CircuitRelay.IPeer|null} [dstPeer] CircuitRelay dstPeer
|
||||
* @property {CircuitRelay.Status|null} [code] CircuitRelay code
|
||||
*/
|
||||
|
||||
optional Peer srcPeer = 2; // srcPeer and dstPeer are used when Type is HOP or STATUS
|
||||
optional Peer dstPeer = 3;
|
||||
/**
|
||||
* Constructs a new CircuitRelay.
|
||||
* @exports CircuitRelay
|
||||
* @classdesc Represents a CircuitRelay.
|
||||
* @implements ICircuitRelay
|
||||
* @constructor
|
||||
* @param {ICircuitRelay=} [p] Properties to set
|
||||
*/
|
||||
function CircuitRelay(p) {
|
||||
if (p)
|
||||
for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
|
||||
if (p[ks[i]] != null)
|
||||
this[ks[i]] = p[ks[i]];
|
||||
}
|
||||
|
||||
optional Status code = 4; // Status code, used when Type is STATUS
|
||||
}
|
||||
`)
|
||||
/**
|
||||
* CircuitRelay type.
|
||||
* @member {CircuitRelay.Type} type
|
||||
* @memberof CircuitRelay
|
||||
* @instance
|
||||
*/
|
||||
CircuitRelay.prototype.type = 1;
|
||||
|
||||
/**
|
||||
* CircuitRelay srcPeer.
|
||||
* @member {CircuitRelay.IPeer|null|undefined} srcPeer
|
||||
* @memberof CircuitRelay
|
||||
* @instance
|
||||
*/
|
||||
CircuitRelay.prototype.srcPeer = null;
|
||||
|
||||
/**
|
||||
* CircuitRelay dstPeer.
|
||||
* @member {CircuitRelay.IPeer|null|undefined} dstPeer
|
||||
* @memberof CircuitRelay
|
||||
* @instance
|
||||
*/
|
||||
CircuitRelay.prototype.dstPeer = null;
|
||||
|
||||
/**
|
||||
* CircuitRelay code.
|
||||
* @member {CircuitRelay.Status} code
|
||||
* @memberof CircuitRelay
|
||||
* @instance
|
||||
*/
|
||||
CircuitRelay.prototype.code = 100;
|
||||
|
||||
/**
|
||||
* Encodes the specified CircuitRelay message. Does not implicitly {@link CircuitRelay.verify|verify} messages.
|
||||
* @function encode
|
||||
* @memberof CircuitRelay
|
||||
* @static
|
||||
* @param {ICircuitRelay} m CircuitRelay message or plain object to encode
|
||||
* @param {$protobuf.Writer} [w] Writer to encode to
|
||||
* @returns {$protobuf.Writer} Writer
|
||||
*/
|
||||
CircuitRelay.encode = function encode(m, w) {
|
||||
if (!w)
|
||||
w = $Writer.create();
|
||||
if (m.type != null && Object.hasOwnProperty.call(m, "type"))
|
||||
w.uint32(8).int32(m.type);
|
||||
if (m.srcPeer != null && Object.hasOwnProperty.call(m, "srcPeer"))
|
||||
$root.CircuitRelay.Peer.encode(m.srcPeer, w.uint32(18).fork()).ldelim();
|
||||
if (m.dstPeer != null && Object.hasOwnProperty.call(m, "dstPeer"))
|
||||
$root.CircuitRelay.Peer.encode(m.dstPeer, w.uint32(26).fork()).ldelim();
|
||||
if (m.code != null && Object.hasOwnProperty.call(m, "code"))
|
||||
w.uint32(32).int32(m.code);
|
||||
return w;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decodes a CircuitRelay message from the specified reader or buffer.
|
||||
* @function decode
|
||||
* @memberof CircuitRelay
|
||||
* @static
|
||||
* @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
|
||||
* @param {number} [l] Message length if known beforehand
|
||||
* @returns {CircuitRelay} CircuitRelay
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
CircuitRelay.decode = function decode(r, l) {
|
||||
if (!(r instanceof $Reader))
|
||||
r = $Reader.create(r);
|
||||
var c = l === undefined ? r.len : r.pos + l, m = new $root.CircuitRelay();
|
||||
while (r.pos < c) {
|
||||
var t = r.uint32();
|
||||
switch (t >>> 3) {
|
||||
case 1:
|
||||
m.type = r.int32();
|
||||
break;
|
||||
case 2:
|
||||
m.srcPeer = $root.CircuitRelay.Peer.decode(r, r.uint32());
|
||||
break;
|
||||
case 3:
|
||||
m.dstPeer = $root.CircuitRelay.Peer.decode(r, r.uint32());
|
||||
break;
|
||||
case 4:
|
||||
m.code = r.int32();
|
||||
break;
|
||||
default:
|
||||
r.skipType(t & 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a CircuitRelay message from a plain object. Also converts values to their respective internal types.
|
||||
* @function fromObject
|
||||
* @memberof CircuitRelay
|
||||
* @static
|
||||
* @param {Object.<string,*>} d Plain object
|
||||
* @returns {CircuitRelay} CircuitRelay
|
||||
*/
|
||||
CircuitRelay.fromObject = function fromObject(d) {
|
||||
if (d instanceof $root.CircuitRelay)
|
||||
return d;
|
||||
var m = new $root.CircuitRelay();
|
||||
switch (d.type) {
|
||||
case "HOP":
|
||||
case 1:
|
||||
m.type = 1;
|
||||
break;
|
||||
case "STOP":
|
||||
case 2:
|
||||
m.type = 2;
|
||||
break;
|
||||
case "STATUS":
|
||||
case 3:
|
||||
m.type = 3;
|
||||
break;
|
||||
case "CAN_HOP":
|
||||
case 4:
|
||||
m.type = 4;
|
||||
break;
|
||||
}
|
||||
if (d.srcPeer != null) {
|
||||
if (typeof d.srcPeer !== "object")
|
||||
throw TypeError(".CircuitRelay.srcPeer: object expected");
|
||||
m.srcPeer = $root.CircuitRelay.Peer.fromObject(d.srcPeer);
|
||||
}
|
||||
if (d.dstPeer != null) {
|
||||
if (typeof d.dstPeer !== "object")
|
||||
throw TypeError(".CircuitRelay.dstPeer: object expected");
|
||||
m.dstPeer = $root.CircuitRelay.Peer.fromObject(d.dstPeer);
|
||||
}
|
||||
switch (d.code) {
|
||||
case "SUCCESS":
|
||||
case 100:
|
||||
m.code = 100;
|
||||
break;
|
||||
case "HOP_SRC_ADDR_TOO_LONG":
|
||||
case 220:
|
||||
m.code = 220;
|
||||
break;
|
||||
case "HOP_DST_ADDR_TOO_LONG":
|
||||
case 221:
|
||||
m.code = 221;
|
||||
break;
|
||||
case "HOP_SRC_MULTIADDR_INVALID":
|
||||
case 250:
|
||||
m.code = 250;
|
||||
break;
|
||||
case "HOP_DST_MULTIADDR_INVALID":
|
||||
case 251:
|
||||
m.code = 251;
|
||||
break;
|
||||
case "HOP_NO_CONN_TO_DST":
|
||||
case 260:
|
||||
m.code = 260;
|
||||
break;
|
||||
case "HOP_CANT_DIAL_DST":
|
||||
case 261:
|
||||
m.code = 261;
|
||||
break;
|
||||
case "HOP_CANT_OPEN_DST_STREAM":
|
||||
case 262:
|
||||
m.code = 262;
|
||||
break;
|
||||
case "HOP_CANT_SPEAK_RELAY":
|
||||
case 270:
|
||||
m.code = 270;
|
||||
break;
|
||||
case "HOP_CANT_RELAY_TO_SELF":
|
||||
case 280:
|
||||
m.code = 280;
|
||||
break;
|
||||
case "STOP_SRC_ADDR_TOO_LONG":
|
||||
case 320:
|
||||
m.code = 320;
|
||||
break;
|
||||
case "STOP_DST_ADDR_TOO_LONG":
|
||||
case 321:
|
||||
m.code = 321;
|
||||
break;
|
||||
case "STOP_SRC_MULTIADDR_INVALID":
|
||||
case 350:
|
||||
m.code = 350;
|
||||
break;
|
||||
case "STOP_DST_MULTIADDR_INVALID":
|
||||
case 351:
|
||||
m.code = 351;
|
||||
break;
|
||||
case "STOP_RELAY_REFUSED":
|
||||
case 390:
|
||||
m.code = 390;
|
||||
break;
|
||||
case "MALFORMED_MESSAGE":
|
||||
case 400:
|
||||
m.code = 400;
|
||||
break;
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a plain object from a CircuitRelay message. Also converts values to other types if specified.
|
||||
* @function toObject
|
||||
* @memberof CircuitRelay
|
||||
* @static
|
||||
* @param {CircuitRelay} m CircuitRelay
|
||||
* @param {$protobuf.IConversionOptions} [o] Conversion options
|
||||
* @returns {Object.<string,*>} Plain object
|
||||
*/
|
||||
CircuitRelay.toObject = function toObject(m, o) {
|
||||
if (!o)
|
||||
o = {};
|
||||
var d = {};
|
||||
if (o.defaults) {
|
||||
d.type = o.enums === String ? "HOP" : 1;
|
||||
d.srcPeer = null;
|
||||
d.dstPeer = null;
|
||||
d.code = o.enums === String ? "SUCCESS" : 100;
|
||||
}
|
||||
if (m.type != null && m.hasOwnProperty("type")) {
|
||||
d.type = o.enums === String ? $root.CircuitRelay.Type[m.type] : m.type;
|
||||
}
|
||||
if (m.srcPeer != null && m.hasOwnProperty("srcPeer")) {
|
||||
d.srcPeer = $root.CircuitRelay.Peer.toObject(m.srcPeer, o);
|
||||
}
|
||||
if (m.dstPeer != null && m.hasOwnProperty("dstPeer")) {
|
||||
d.dstPeer = $root.CircuitRelay.Peer.toObject(m.dstPeer, o);
|
||||
}
|
||||
if (m.code != null && m.hasOwnProperty("code")) {
|
||||
d.code = o.enums === String ? $root.CircuitRelay.Status[m.code] : m.code;
|
||||
}
|
||||
return d;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts this CircuitRelay to JSON.
|
||||
* @function toJSON
|
||||
* @memberof CircuitRelay
|
||||
* @instance
|
||||
* @returns {Object.<string,*>} JSON object
|
||||
*/
|
||||
CircuitRelay.prototype.toJSON = function toJSON() {
|
||||
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
|
||||
};
|
||||
|
||||
/**
|
||||
* Status enum.
|
||||
* @name CircuitRelay.Status
|
||||
* @enum {number}
|
||||
* @property {number} SUCCESS=100 SUCCESS value
|
||||
* @property {number} HOP_SRC_ADDR_TOO_LONG=220 HOP_SRC_ADDR_TOO_LONG value
|
||||
* @property {number} HOP_DST_ADDR_TOO_LONG=221 HOP_DST_ADDR_TOO_LONG value
|
||||
* @property {number} HOP_SRC_MULTIADDR_INVALID=250 HOP_SRC_MULTIADDR_INVALID value
|
||||
* @property {number} HOP_DST_MULTIADDR_INVALID=251 HOP_DST_MULTIADDR_INVALID value
|
||||
* @property {number} HOP_NO_CONN_TO_DST=260 HOP_NO_CONN_TO_DST value
|
||||
* @property {number} HOP_CANT_DIAL_DST=261 HOP_CANT_DIAL_DST value
|
||||
* @property {number} HOP_CANT_OPEN_DST_STREAM=262 HOP_CANT_OPEN_DST_STREAM value
|
||||
* @property {number} HOP_CANT_SPEAK_RELAY=270 HOP_CANT_SPEAK_RELAY value
|
||||
* @property {number} HOP_CANT_RELAY_TO_SELF=280 HOP_CANT_RELAY_TO_SELF value
|
||||
* @property {number} STOP_SRC_ADDR_TOO_LONG=320 STOP_SRC_ADDR_TOO_LONG value
|
||||
* @property {number} STOP_DST_ADDR_TOO_LONG=321 STOP_DST_ADDR_TOO_LONG value
|
||||
* @property {number} STOP_SRC_MULTIADDR_INVALID=350 STOP_SRC_MULTIADDR_INVALID value
|
||||
* @property {number} STOP_DST_MULTIADDR_INVALID=351 STOP_DST_MULTIADDR_INVALID value
|
||||
* @property {number} STOP_RELAY_REFUSED=390 STOP_RELAY_REFUSED value
|
||||
* @property {number} MALFORMED_MESSAGE=400 MALFORMED_MESSAGE value
|
||||
*/
|
||||
CircuitRelay.Status = (function() {
|
||||
var valuesById = {}, values = Object.create(valuesById);
|
||||
values[valuesById[100] = "SUCCESS"] = 100;
|
||||
values[valuesById[220] = "HOP_SRC_ADDR_TOO_LONG"] = 220;
|
||||
values[valuesById[221] = "HOP_DST_ADDR_TOO_LONG"] = 221;
|
||||
values[valuesById[250] = "HOP_SRC_MULTIADDR_INVALID"] = 250;
|
||||
values[valuesById[251] = "HOP_DST_MULTIADDR_INVALID"] = 251;
|
||||
values[valuesById[260] = "HOP_NO_CONN_TO_DST"] = 260;
|
||||
values[valuesById[261] = "HOP_CANT_DIAL_DST"] = 261;
|
||||
values[valuesById[262] = "HOP_CANT_OPEN_DST_STREAM"] = 262;
|
||||
values[valuesById[270] = "HOP_CANT_SPEAK_RELAY"] = 270;
|
||||
values[valuesById[280] = "HOP_CANT_RELAY_TO_SELF"] = 280;
|
||||
values[valuesById[320] = "STOP_SRC_ADDR_TOO_LONG"] = 320;
|
||||
values[valuesById[321] = "STOP_DST_ADDR_TOO_LONG"] = 321;
|
||||
values[valuesById[350] = "STOP_SRC_MULTIADDR_INVALID"] = 350;
|
||||
values[valuesById[351] = "STOP_DST_MULTIADDR_INVALID"] = 351;
|
||||
values[valuesById[390] = "STOP_RELAY_REFUSED"] = 390;
|
||||
values[valuesById[400] = "MALFORMED_MESSAGE"] = 400;
|
||||
return values;
|
||||
})();
|
||||
|
||||
/**
|
||||
* Type enum.
|
||||
* @name CircuitRelay.Type
|
||||
* @enum {number}
|
||||
* @property {number} HOP=1 HOP value
|
||||
* @property {number} STOP=2 STOP value
|
||||
* @property {number} STATUS=3 STATUS value
|
||||
* @property {number} CAN_HOP=4 CAN_HOP value
|
||||
*/
|
||||
CircuitRelay.Type = (function() {
|
||||
var valuesById = {}, values = Object.create(valuesById);
|
||||
values[valuesById[1] = "HOP"] = 1;
|
||||
values[valuesById[2] = "STOP"] = 2;
|
||||
values[valuesById[3] = "STATUS"] = 3;
|
||||
values[valuesById[4] = "CAN_HOP"] = 4;
|
||||
return values;
|
||||
})();
|
||||
|
||||
CircuitRelay.Peer = (function() {
|
||||
|
||||
/**
|
||||
* Properties of a Peer.
|
||||
* @memberof CircuitRelay
|
||||
* @interface IPeer
|
||||
* @property {Uint8Array} id Peer id
|
||||
* @property {Array.<Uint8Array>|null} [addrs] Peer addrs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructs a new Peer.
|
||||
* @memberof CircuitRelay
|
||||
* @classdesc Represents a Peer.
|
||||
* @implements IPeer
|
||||
* @constructor
|
||||
* @param {CircuitRelay.IPeer=} [p] Properties to set
|
||||
*/
|
||||
function Peer(p) {
|
||||
this.addrs = [];
|
||||
if (p)
|
||||
for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
|
||||
if (p[ks[i]] != null)
|
||||
this[ks[i]] = p[ks[i]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Peer id.
|
||||
* @member {Uint8Array} id
|
||||
* @memberof CircuitRelay.Peer
|
||||
* @instance
|
||||
*/
|
||||
Peer.prototype.id = $util.newBuffer([]);
|
||||
|
||||
/**
|
||||
* Peer addrs.
|
||||
* @member {Array.<Uint8Array>} addrs
|
||||
* @memberof CircuitRelay.Peer
|
||||
* @instance
|
||||
*/
|
||||
Peer.prototype.addrs = $util.emptyArray;
|
||||
|
||||
/**
|
||||
* Encodes the specified Peer message. Does not implicitly {@link CircuitRelay.Peer.verify|verify} messages.
|
||||
* @function encode
|
||||
* @memberof CircuitRelay.Peer
|
||||
* @static
|
||||
* @param {CircuitRelay.IPeer} m Peer message or plain object to encode
|
||||
* @param {$protobuf.Writer} [w] Writer to encode to
|
||||
* @returns {$protobuf.Writer} Writer
|
||||
*/
|
||||
Peer.encode = function encode(m, w) {
|
||||
if (!w)
|
||||
w = $Writer.create();
|
||||
w.uint32(10).bytes(m.id);
|
||||
if (m.addrs != null && m.addrs.length) {
|
||||
for (var i = 0; i < m.addrs.length; ++i)
|
||||
w.uint32(18).bytes(m.addrs[i]);
|
||||
}
|
||||
return w;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decodes a Peer message from the specified reader or buffer.
|
||||
* @function decode
|
||||
* @memberof CircuitRelay.Peer
|
||||
* @static
|
||||
* @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
|
||||
* @param {number} [l] Message length if known beforehand
|
||||
* @returns {CircuitRelay.Peer} Peer
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
Peer.decode = function decode(r, l) {
|
||||
if (!(r instanceof $Reader))
|
||||
r = $Reader.create(r);
|
||||
var c = l === undefined ? r.len : r.pos + l, m = new $root.CircuitRelay.Peer();
|
||||
while (r.pos < c) {
|
||||
var t = r.uint32();
|
||||
switch (t >>> 3) {
|
||||
case 1:
|
||||
m.id = r.bytes();
|
||||
break;
|
||||
case 2:
|
||||
if (!(m.addrs && m.addrs.length))
|
||||
m.addrs = [];
|
||||
m.addrs.push(r.bytes());
|
||||
break;
|
||||
default:
|
||||
r.skipType(t & 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!m.hasOwnProperty("id"))
|
||||
throw $util.ProtocolError("missing required 'id'", { instance: m });
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a Peer message from a plain object. Also converts values to their respective internal types.
|
||||
* @function fromObject
|
||||
* @memberof CircuitRelay.Peer
|
||||
* @static
|
||||
* @param {Object.<string,*>} d Plain object
|
||||
* @returns {CircuitRelay.Peer} Peer
|
||||
*/
|
||||
Peer.fromObject = function fromObject(d) {
|
||||
if (d instanceof $root.CircuitRelay.Peer)
|
||||
return d;
|
||||
var m = new $root.CircuitRelay.Peer();
|
||||
if (d.id != null) {
|
||||
if (typeof d.id === "string")
|
||||
$util.base64.decode(d.id, m.id = $util.newBuffer($util.base64.length(d.id)), 0);
|
||||
else if (d.id.length)
|
||||
m.id = d.id;
|
||||
}
|
||||
if (d.addrs) {
|
||||
if (!Array.isArray(d.addrs))
|
||||
throw TypeError(".CircuitRelay.Peer.addrs: array expected");
|
||||
m.addrs = [];
|
||||
for (var i = 0; i < d.addrs.length; ++i) {
|
||||
if (typeof d.addrs[i] === "string")
|
||||
$util.base64.decode(d.addrs[i], m.addrs[i] = $util.newBuffer($util.base64.length(d.addrs[i])), 0);
|
||||
else if (d.addrs[i].length)
|
||||
m.addrs[i] = d.addrs[i];
|
||||
}
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a plain object from a Peer message. Also converts values to other types if specified.
|
||||
* @function toObject
|
||||
* @memberof CircuitRelay.Peer
|
||||
* @static
|
||||
* @param {CircuitRelay.Peer} m Peer
|
||||
* @param {$protobuf.IConversionOptions} [o] Conversion options
|
||||
* @returns {Object.<string,*>} Plain object
|
||||
*/
|
||||
Peer.toObject = function toObject(m, o) {
|
||||
if (!o)
|
||||
o = {};
|
||||
var d = {};
|
||||
if (o.arrays || o.defaults) {
|
||||
d.addrs = [];
|
||||
}
|
||||
if (o.defaults) {
|
||||
if (o.bytes === String)
|
||||
d.id = "";
|
||||
else {
|
||||
d.id = [];
|
||||
if (o.bytes !== Array)
|
||||
d.id = $util.newBuffer(d.id);
|
||||
}
|
||||
}
|
||||
if (m.id != null && m.hasOwnProperty("id")) {
|
||||
d.id = o.bytes === String ? $util.base64.encode(m.id, 0, m.id.length) : o.bytes === Array ? Array.prototype.slice.call(m.id) : m.id;
|
||||
}
|
||||
if (m.addrs && m.addrs.length) {
|
||||
d.addrs = [];
|
||||
for (var j = 0; j < m.addrs.length; ++j) {
|
||||
d.addrs[j] = o.bytes === String ? $util.base64.encode(m.addrs[j], 0, m.addrs[j].length) : o.bytes === Array ? Array.prototype.slice.call(m.addrs[j]) : m.addrs[j];
|
||||
}
|
||||
}
|
||||
return d;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts this Peer to JSON.
|
||||
* @function toJSON
|
||||
* @memberof CircuitRelay.Peer
|
||||
* @instance
|
||||
* @returns {Object.<string,*>} JSON object
|
||||
*/
|
||||
Peer.prototype.toJSON = function toJSON() {
|
||||
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
|
||||
};
|
||||
|
||||
return Peer;
|
||||
})();
|
||||
|
||||
return CircuitRelay;
|
||||
})();
|
||||
|
||||
module.exports = $root;
|
||||
|
42
src/circuit/protocol/index.proto
Normal file
42
src/circuit/protocol/index.proto
Normal file
@@ -0,0 +1,42 @@
|
||||
syntax = "proto2";
|
||||
|
||||
message CircuitRelay {
|
||||
|
||||
enum Status {
|
||||
SUCCESS = 100;
|
||||
HOP_SRC_ADDR_TOO_LONG = 220;
|
||||
HOP_DST_ADDR_TOO_LONG = 221;
|
||||
HOP_SRC_MULTIADDR_INVALID = 250;
|
||||
HOP_DST_MULTIADDR_INVALID = 251;
|
||||
HOP_NO_CONN_TO_DST = 260;
|
||||
HOP_CANT_DIAL_DST = 261;
|
||||
HOP_CANT_OPEN_DST_STREAM = 262;
|
||||
HOP_CANT_SPEAK_RELAY = 270;
|
||||
HOP_CANT_RELAY_TO_SELF = 280;
|
||||
STOP_SRC_ADDR_TOO_LONG = 320;
|
||||
STOP_DST_ADDR_TOO_LONG = 321;
|
||||
STOP_SRC_MULTIADDR_INVALID = 350;
|
||||
STOP_DST_MULTIADDR_INVALID = 351;
|
||||
STOP_RELAY_REFUSED = 390;
|
||||
MALFORMED_MESSAGE = 400;
|
||||
}
|
||||
|
||||
enum Type { // RPC identifier, either HOP, STOP or STATUS
|
||||
HOP = 1;
|
||||
STOP = 2;
|
||||
STATUS = 3;
|
||||
CAN_HOP = 4;
|
||||
}
|
||||
|
||||
message Peer {
|
||||
required bytes id = 1; // peer id
|
||||
repeated bytes addrs = 2; // peer's known addresses
|
||||
}
|
||||
|
||||
optional Type type = 1; // Type of the message
|
||||
|
||||
optional Peer srcPeer = 2; // srcPeer and dstPeer are used when Type is HOP or STATUS
|
||||
optional Peer dstPeer = 3;
|
||||
|
||||
optional Status code = 4; // Status code, used when Type is STATUS
|
||||
}
|
@@ -5,10 +5,12 @@ const log = Object.assign(debug('libp2p:circuit'), {
|
||||
error: debug('libp2p:circuit:err')
|
||||
})
|
||||
|
||||
const errCode = require('err-code')
|
||||
const mafmt = require('mafmt')
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const PeerId = require('peer-id')
|
||||
const { CircuitRelay: CircuitPB } = require('./protocol')
|
||||
const { codes } = require('../errors')
|
||||
|
||||
const toConnection = require('libp2p-utils/src/stream-to-ma-conn')
|
||||
|
||||
@@ -21,10 +23,8 @@ const StreamHandler = require('./circuit/stream-handler')
|
||||
const transportSymbol = Symbol.for('@libp2p/js-libp2p-circuit/circuit')
|
||||
|
||||
/**
|
||||
* @typedef {import('multiaddr')} Multiaddr
|
||||
* @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
|
||||
* @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
|
||||
* @typedef {import('../types').CircuitRequest} CircuitRequest
|
||||
*/
|
||||
|
||||
class Circuit {
|
||||
@@ -54,7 +54,7 @@ class Circuit {
|
||||
* @param {MuxedStream} props.stream
|
||||
*/
|
||||
async _onProtocol ({ connection, stream }) {
|
||||
/** @type {import('./circuit/stream-handler')<CircuitRequest>} */
|
||||
/** @type {import('./circuit/stream-handler')} */
|
||||
const streamHandler = new StreamHandler({ stream })
|
||||
const request = await streamHandler.read()
|
||||
|
||||
@@ -96,8 +96,10 @@ class Circuit {
|
||||
}
|
||||
|
||||
if (virtualConnection) {
|
||||
const remoteAddr = multiaddr(request.dstPeer.addrs[0])
|
||||
const localAddr = multiaddr(request.srcPeer.addrs[0])
|
||||
// @ts-ignore dst peer will not be undefined
|
||||
const remoteAddr = new Multiaddr(request.dstPeer.addrs[0])
|
||||
// @ts-ignore src peer will not be undefined
|
||||
const localAddr = new Multiaddr(request.srcPeer.addrs[0])
|
||||
const maConn = toConnection({
|
||||
stream: virtualConnection,
|
||||
remoteAddr,
|
||||
@@ -123,10 +125,19 @@ class Circuit {
|
||||
async dial (ma, options) {
|
||||
// Check the multiaddr to see if it contains a relay and a destination peer
|
||||
const addrs = ma.toString().split('/p2p-circuit')
|
||||
const relayAddr = multiaddr(addrs[0])
|
||||
const destinationAddr = multiaddr(addrs[addrs.length - 1])
|
||||
const relayPeer = PeerId.createFromCID(relayAddr.getPeerId())
|
||||
const destinationPeer = PeerId.createFromCID(destinationAddr.getPeerId())
|
||||
const relayAddr = new Multiaddr(addrs[0])
|
||||
const destinationAddr = new Multiaddr(addrs[addrs.length - 1])
|
||||
const relayId = relayAddr.getPeerId()
|
||||
const destinationId = destinationAddr.getPeerId()
|
||||
|
||||
if (!relayId || !destinationId) {
|
||||
const errMsg = 'Circuit relay dial failed as addresses did not have peer id'
|
||||
log.error(errMsg)
|
||||
throw errCode(new Error(errMsg), codes.ERR_RELAYED_DIAL)
|
||||
}
|
||||
|
||||
const relayPeer = PeerId.createFromCID(relayId)
|
||||
const destinationPeer = PeerId.createFromCID(destinationId)
|
||||
|
||||
let disconnectOnFailure = false
|
||||
let relayConnection = this._connectionManager.get(relayPeer)
|
||||
@@ -146,7 +157,7 @@ class Circuit {
|
||||
},
|
||||
dstPeer: {
|
||||
id: destinationPeer.toBytes(),
|
||||
addrs: [multiaddr(destinationAddr).bytes]
|
||||
addrs: [new Multiaddr(destinationAddr).bytes]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@@ -1,6 +1,7 @@
|
||||
'use strict'
|
||||
|
||||
const mergeOptions = require('merge-options')
|
||||
// @ts-ignore no types in multiaddr path
|
||||
const { dnsaddrResolver } = require('multiaddr/src/resolvers')
|
||||
|
||||
const Constants = require('./constants')
|
||||
@@ -10,11 +11,18 @@ const RelayConstants = require('./circuit/constants')
|
||||
const { publicAddressesFirst } = require('libp2p-utils/src/address-sort')
|
||||
const { FaultTolerance } = require('./transport-manager')
|
||||
|
||||
/**
|
||||
* @typedef {import('multiaddr').Multiaddr} Multiaddr
|
||||
* @typedef {import('.').Libp2pOptions} Libp2pOptions
|
||||
* @typedef {import('.').constructorOptions} constructorOptions
|
||||
*/
|
||||
|
||||
const DefaultConfig = {
|
||||
addresses: {
|
||||
listen: [],
|
||||
announce: [],
|
||||
noAnnounce: []
|
||||
noAnnounce: [],
|
||||
announceFilter: (/** @type {Multiaddr[]} */ multiaddrs) => multiaddrs
|
||||
},
|
||||
connectionManager: {
|
||||
minConnections: 25
|
||||
@@ -95,10 +103,15 @@ const DefaultConfig = {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Libp2pOptions} opts
|
||||
* @returns {DefaultConfig & Libp2pOptions & constructorOptions}
|
||||
*/
|
||||
module.exports.validate = (opts) => {
|
||||
opts = mergeOptions(DefaultConfig, opts)
|
||||
/** @type {DefaultConfig & Libp2pOptions & constructorOptions} */
|
||||
const resultingOptions = mergeOptions(DefaultConfig, opts)
|
||||
|
||||
if (opts.modules.transport.length < 1) throw new Error("'options.modules.transport' must contain at least 1 transport")
|
||||
if (resultingOptions.modules.transport.length < 1) throw new Error("'options.modules.transport' must contain at least 1 transport")
|
||||
|
||||
return opts
|
||||
return resultingOptions
|
||||
}
|
||||
|
@@ -8,11 +8,10 @@ const log = Object.assign(debug('libp2p:connection-manager'), {
|
||||
const errcode = require('err-code')
|
||||
const mergeOptions = require('merge-options')
|
||||
const LatencyMonitor = require('./latency-monitor')
|
||||
// @ts-ignore retimer does not have types
|
||||
const retimer = require('retimer')
|
||||
|
||||
/** @typedef {import('../types').EventEmitterFactory} Events */
|
||||
/** @type Events */
|
||||
const EventEmitter = require('events')
|
||||
const { EventEmitter } = require('events')
|
||||
|
||||
const PeerId = require('peer-id')
|
||||
|
||||
@@ -188,8 +187,10 @@ class ConnectionManager extends EventEmitter {
|
||||
_checkMetrics () {
|
||||
if (this._libp2p.metrics) {
|
||||
const movingAverages = this._libp2p.metrics.global.movingAverages
|
||||
// @ts-ignore moving averages object types
|
||||
const received = movingAverages.dataReceived[this._options.movingAverageInterval].movingAverage()
|
||||
this._checkMaxLimit('maxReceivedData', received)
|
||||
// @ts-ignore moving averages object types
|
||||
const sent = movingAverages.dataSent[this._options.movingAverageInterval].movingAverage()
|
||||
this._checkMaxLimit('maxSentData', sent)
|
||||
const total = received + sent
|
||||
@@ -362,7 +363,7 @@ class ConnectionManager extends EventEmitter {
|
||||
*/
|
||||
_maybeDisconnectOne () {
|
||||
if (this._options.minConnections < this.connections.size) {
|
||||
const peerValues = Array.from(this._peerValues).sort(byPeerValue)
|
||||
const peerValues = Array.from(new Map([...this._peerValues.entries()].sort((a, b) => a[1] - b[1])))
|
||||
log('%s: sorted peer values: %j', this._peerId, peerValues)
|
||||
const disconnectPeer = peerValues[0]
|
||||
if (disconnectPeer) {
|
||||
@@ -381,7 +382,3 @@ class ConnectionManager extends EventEmitter {
|
||||
}
|
||||
|
||||
module.exports = ConnectionManager
|
||||
|
||||
function byPeerValue (peerValueEntryA, peerValueEntryB) {
|
||||
return peerValueEntryA[1] - peerValueEntryB[1]
|
||||
}
|
||||
|
@@ -5,9 +5,7 @@
|
||||
* This code is based on `latency-monitor` (https://github.com/mlucool/latency-monitor) by `mlucool` (https://github.com/mlucool), available under Apache License 2.0 (https://github.com/mlucool/latency-monitor/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
/** @typedef {import('../types').EventEmitterFactory} Events */
|
||||
/** @type Events */
|
||||
const EventEmitter = require('events')
|
||||
const { EventEmitter } = require('events')
|
||||
const VisibilityChangeEmitter = require('./visibility-change-emitter')
|
||||
const debug = require('debug')('latency-monitor:LatencyMonitor')
|
||||
|
||||
@@ -59,7 +57,8 @@ class LatencyMonitor extends EventEmitter {
|
||||
that._latecyCheckMultiply = 2 * (that.latencyRandomPercentage / 100.0) * that.latencyCheckIntervalMs
|
||||
that._latecyCheckSubtract = that._latecyCheckMultiply / 2
|
||||
|
||||
that.dataEmitIntervalMs = (dataEmitIntervalMs === null || dataEmitIntervalMs === 0) ? undefined
|
||||
that.dataEmitIntervalMs = (dataEmitIntervalMs === null || dataEmitIntervalMs === 0)
|
||||
? undefined
|
||||
: dataEmitIntervalMs || 5 * 1000 // 5s
|
||||
debug('latencyCheckIntervalMs: %s dataEmitIntervalMs: %s',
|
||||
that.latencyCheckIntervalMs, that.dataEmitIntervalMs)
|
||||
@@ -174,7 +173,8 @@ class LatencyMonitor extends EventEmitter {
|
||||
events: this._latencyData.events,
|
||||
minMs: this._latencyData.minMs,
|
||||
maxMs: this._latencyData.maxMs,
|
||||
avgMs: this._latencyData.events ? this._latencyData.totalMs / this._latencyData.events
|
||||
avgMs: this._latencyData.events
|
||||
? this._latencyData.totalMs / this._latencyData.events
|
||||
: Number.POSITIVE_INFINITY,
|
||||
lengthMs: this.getDeltaMS(this._latencyData.startTime)
|
||||
}
|
||||
|
@@ -6,9 +6,7 @@
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
/** @typedef {import('../types').EventEmitterFactory} Events */
|
||||
/** @type Events */
|
||||
const EventEmitter = require('events')
|
||||
const { EventEmitter } = require('events')
|
||||
|
||||
const debug = require('debug')('latency-monitor:VisibilityChangeEmitter')
|
||||
|
||||
|
@@ -14,8 +14,9 @@ const { pipe } = require('it-pipe')
|
||||
|
||||
/**
|
||||
* @typedef {import('peer-id')} PeerId
|
||||
* @typedef {import('multiaddr')} Multiaddr
|
||||
* @typedef {import('multiaddr').Multiaddr} Multiaddr
|
||||
* @typedef {import('cids')} CID
|
||||
* @typedef {import('libp2p-interfaces/src/content-routing/types').ContentRouting} ContentRoutingModule
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -31,6 +32,7 @@ class ContentRouting {
|
||||
*/
|
||||
constructor (libp2p) {
|
||||
this.libp2p = libp2p
|
||||
/** @type {ContentRoutingModule[]} */
|
||||
this.routers = libp2p._modules.contentRouting || []
|
||||
this.dht = libp2p._dht
|
||||
|
||||
|
@@ -7,7 +7,7 @@ const take = require('it-take')
|
||||
|
||||
/**
|
||||
* @typedef {import('peer-id')} PeerId
|
||||
* @typedef {import('multiaddr')} Multiaddr
|
||||
* @typedef {import('multiaddr').Multiaddr} Multiaddr
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -3,13 +3,14 @@
|
||||
const errCode = require('err-code')
|
||||
const AbortController = require('abort-controller').default
|
||||
const { anySignal } = require('any-signal')
|
||||
// @ts-ignore p-fifo does not export types
|
||||
const FIFO = require('p-fifo')
|
||||
const pAny = require('p-any')
|
||||
|
||||
/**
|
||||
* @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
|
||||
* @typedef {import('./')} Dialer
|
||||
* @typedef {import('multiaddr')} Multiaddr
|
||||
* @typedef {import('multiaddr').Multiaddr} Multiaddr
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -5,7 +5,8 @@ const log = Object.assign(debug('libp2p:dialer'), {
|
||||
error: debug('libp2p:dialer:err')
|
||||
})
|
||||
const errCode = require('err-code')
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
// @ts-ignore timeout-abourt-controles does not export types
|
||||
const TimeoutController = require('timeout-abort-controller')
|
||||
const { anySignal } = require('any-signal')
|
||||
|
||||
@@ -22,7 +23,6 @@ const {
|
||||
|
||||
/**
|
||||
* @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
|
||||
* @typedef {import('multiaddr')} Multiaddr
|
||||
* @typedef {import('peer-id')} PeerId
|
||||
* @typedef {import('../peer-store')} PeerStore
|
||||
* @typedef {import('../peer-store/address-book').Address} Address
|
||||
@@ -38,9 +38,9 @@ const {
|
||||
*
|
||||
* @typedef {Object} DialerOptions
|
||||
* @property {(addresses: Address[]) => Address[]} [options.addressSorter = publicAddressesFirst] - Sort the known addresses of a peer before trying to dial.
|
||||
* @property {number} [concurrency = MAX_PARALLEL_DIALS] - Number of max concurrent dials.
|
||||
* @property {number} [perPeerLimit = MAX_PER_PEER_DIALS] - Number of max concurrent dials per peer.
|
||||
* @property {number} [timeout = DIAL_TIMEOUT] - How long a dial attempt is allowed to take.
|
||||
* @property {number} [maxParallelDials = MAX_PARALLEL_DIALS] - Number of max concurrent dials.
|
||||
* @property {number} [maxDialsPerPeer = MAX_PER_PEER_DIALS] - Number of max concurrent dials per peer.
|
||||
* @property {number} [dialTimeout = DIAL_TIMEOUT] - How long a dial attempt is allowed to take.
|
||||
* @property {Record<string, Resolver>} [resolvers = {}] - multiaddr resolvers to use when dialing
|
||||
*
|
||||
* @typedef DialTarget
|
||||
@@ -50,7 +50,7 @@ const {
|
||||
* @typedef PendingDial
|
||||
* @property {DialRequest} dialRequest
|
||||
* @property {TimeoutController} controller
|
||||
* @property {Promise} promise
|
||||
* @property {Promise<Connection>} promise
|
||||
* @property {function():void} destroy
|
||||
*/
|
||||
|
||||
@@ -63,22 +63,22 @@ class Dialer {
|
||||
transportManager,
|
||||
peerStore,
|
||||
addressSorter = publicAddressesFirst,
|
||||
concurrency = MAX_PARALLEL_DIALS,
|
||||
timeout = DIAL_TIMEOUT,
|
||||
perPeerLimit = MAX_PER_PEER_DIALS,
|
||||
maxParallelDials = MAX_PARALLEL_DIALS,
|
||||
dialTimeout = DIAL_TIMEOUT,
|
||||
maxDialsPerPeer = MAX_PER_PEER_DIALS,
|
||||
resolvers = {}
|
||||
}) {
|
||||
this.transportManager = transportManager
|
||||
this.peerStore = peerStore
|
||||
this.addressSorter = addressSorter
|
||||
this.concurrency = concurrency
|
||||
this.timeout = timeout
|
||||
this.perPeerLimit = perPeerLimit
|
||||
this.tokens = [...new Array(concurrency)].map((_, index) => index)
|
||||
this.maxParallelDials = maxParallelDials
|
||||
this.timeout = dialTimeout
|
||||
this.maxDialsPerPeer = maxDialsPerPeer
|
||||
this.tokens = [...new Array(maxParallelDials)].map((_, index) => index)
|
||||
this._pendingDials = new Map()
|
||||
|
||||
for (const [key, value] of Object.entries(resolvers)) {
|
||||
multiaddr.resolvers.set(key, value)
|
||||
Multiaddr.resolvers.set(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ class Dialer {
|
||||
const dialTarget = await this._createDialTarget(peer)
|
||||
|
||||
if (!dialTarget.addrs.length) {
|
||||
throw errCode(new Error('The dial request has no addresses'), codes.ERR_NO_VALID_ADDRESSES)
|
||||
throw errCode(new Error('The dial request has no valid addresses'), codes.ERR_NO_VALID_ADDRESSES)
|
||||
}
|
||||
const pendingDial = this._pendingDials.get(dialTarget.id) || this._createPendingDial(dialTarget, options)
|
||||
|
||||
@@ -134,6 +134,7 @@ class Dialer {
|
||||
* Creates a DialTarget. The DialTarget is used to create and track
|
||||
* the DialRequest to a given peer.
|
||||
* If a multiaddr is received it should be the first address attempted.
|
||||
* Multiaddrs not supported by the available transports will be filtered out.
|
||||
*
|
||||
* @private
|
||||
* @param {PeerId|Multiaddr|string} peer - A PeerId or Multiaddr
|
||||
@@ -150,20 +151,24 @@ class Dialer {
|
||||
|
||||
// If received a multiaddr to dial, it should be the first to use
|
||||
// But, if we know other multiaddrs for the peer, we should try them too.
|
||||
if (multiaddr.isMultiaddr(peer)) {
|
||||
if (Multiaddr.isMultiaddr(peer)) {
|
||||
knownAddrs = knownAddrs.filter((addr) => !peer.equals(addr))
|
||||
knownAddrs.unshift(peer)
|
||||
}
|
||||
|
||||
/** @type {Multiaddr[]} */
|
||||
const addrs = []
|
||||
for (const a of knownAddrs) {
|
||||
const resolvedAddrs = await this._resolve(a)
|
||||
resolvedAddrs.forEach(ra => addrs.push(ra))
|
||||
}
|
||||
|
||||
// Multiaddrs not supported by the available transports will be filtered out.
|
||||
const supportedAddrs = addrs.filter(a => this.transportManager.transportForMultiaddr(a))
|
||||
|
||||
return {
|
||||
id: id.toB58String(),
|
||||
addrs
|
||||
addrs: supportedAddrs
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,6 +182,10 @@ class Dialer {
|
||||
* @returns {PendingDial}
|
||||
*/
|
||||
_createPendingDial (dialTarget, options = {}) {
|
||||
/**
|
||||
* @param {Multiaddr} addr
|
||||
* @param {{ signal: { aborted: any; }; }} options
|
||||
*/
|
||||
const dialAction = (addr, options) => {
|
||||
if (options.signal.aborted) throw errCode(new Error('already aborted'), codes.ERR_ALREADY_ABORTED)
|
||||
return this.transportManager.dial(addr, options)
|
||||
@@ -207,13 +216,19 @@ class Dialer {
|
||||
return pendingDial
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} num
|
||||
*/
|
||||
getTokens (num) {
|
||||
const total = Math.min(num, this.perPeerLimit, this.tokens.length)
|
||||
const total = Math.min(num, this.maxDialsPerPeer, this.tokens.length)
|
||||
const tokens = this.tokens.splice(0, total)
|
||||
log('%d tokens request, returning %d, %d remaining', num, total, this.tokens.length)
|
||||
return tokens
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} token
|
||||
*/
|
||||
releaseToken (token) {
|
||||
// Guard against duplicate releases
|
||||
if (this.tokens.indexOf(token) > -1) return
|
||||
@@ -259,7 +274,7 @@ class Dialer {
|
||||
*/
|
||||
async _resolveRecord (ma) {
|
||||
try {
|
||||
ma = multiaddr(ma.toString()) // Use current multiaddr module
|
||||
ma = new Multiaddr(ma.toString()) // Use current multiaddr module
|
||||
const multiaddrs = await ma.resolve()
|
||||
return multiaddrs
|
||||
} catch (_) {
|
||||
|
@@ -11,11 +11,13 @@ exports.codes = {
|
||||
PUBSUB_NOT_STARTED: 'ERR_PUBSUB_NOT_STARTED',
|
||||
DHT_NOT_STARTED: 'ERR_DHT_NOT_STARTED',
|
||||
CONN_ENCRYPTION_REQUIRED: 'ERR_CONN_ENCRYPTION_REQUIRED',
|
||||
ERR_INVALID_PROTOCOLS_FOR_STREAM: 'ERR_INVALID_PROTOCOLS_FOR_STREAM',
|
||||
ERR_CONNECTION_ENDED: 'ERR_CONNECTION_ENDED',
|
||||
ERR_CONNECTION_FAILED: 'ERR_CONNECTION_FAILED',
|
||||
ERR_NODE_NOT_STARTED: 'ERR_NODE_NOT_STARTED',
|
||||
ERR_ALREADY_ABORTED: 'ERR_ALREADY_ABORTED',
|
||||
ERR_NO_VALID_ADDRESSES: 'ERR_NO_VALID_ADDRESSES',
|
||||
ERR_RELAYED_DIAL: 'ERR_RELAYED_DIAL',
|
||||
ERR_DIALED_SELF: 'ERR_DIALED_SELF',
|
||||
ERR_DISCOVERED_SELF: 'ERR_DISCOVERED_SELF',
|
||||
ERR_DUPLICATE_TRANSPORT: 'ERR_DUPLICATE_TRANSPORT',
|
||||
|
@@ -1,15 +1,11 @@
|
||||
'use strict'
|
||||
|
||||
const PeerId = require('peer-id')
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const errCode = require('err-code')
|
||||
|
||||
const { codes } = require('./errors')
|
||||
|
||||
/**
|
||||
* @typedef {import('multiaddr')} Multiaddr
|
||||
*/
|
||||
|
||||
/**
|
||||
* Converts the given `peer` to a `Peer` object.
|
||||
* If a multiaddr is received, the addressBook is updated.
|
||||
@@ -19,14 +15,23 @@ const { codes } = require('./errors')
|
||||
*/
|
||||
function getPeer (peer) {
|
||||
if (typeof peer === 'string') {
|
||||
peer = multiaddr(peer)
|
||||
peer = new Multiaddr(peer)
|
||||
}
|
||||
|
||||
let addr
|
||||
if (multiaddr.isMultiaddr(peer)) {
|
||||
if (Multiaddr.isMultiaddr(peer)) {
|
||||
addr = peer
|
||||
const idStr = peer.getPeerId()
|
||||
|
||||
if (!idStr) {
|
||||
throw errCode(
|
||||
new Error(`${peer} does not have a valid peer type`),
|
||||
codes.ERR_INVALID_MULTIADDR
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
peer = PeerId.createFromB58String(peer.getPeerId())
|
||||
peer = PeerId.createFromB58String(idStr)
|
||||
} catch (err) {
|
||||
throw errCode(
|
||||
new Error(`${peer} is not a valid peer type`),
|
||||
|
@@ -5,14 +5,14 @@ const log = Object.assign(debug('libp2p:identify'), {
|
||||
error: debug('libp2p:identify:err')
|
||||
})
|
||||
const errCode = require('err-code')
|
||||
const pb = require('it-protocol-buffers')
|
||||
const lp = require('it-length-prefixed')
|
||||
const { pipe } = require('it-pipe')
|
||||
const { collect, take, consume } = require('streaming-iterables')
|
||||
const uint8ArrayFromString = require('uint8arrays/from-string')
|
||||
|
||||
const PeerId = require('peer-id')
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
// @ts-ignore it-buffer does not have types
|
||||
const { toBuffer } = require('it-buffer')
|
||||
|
||||
const Message = require('./message')
|
||||
@@ -23,7 +23,6 @@ const PeerRecord = require('../record/peer-record')
|
||||
const {
|
||||
MULTICODEC_IDENTIFY,
|
||||
MULTICODEC_IDENTIFY_PUSH,
|
||||
AGENT_VERSION,
|
||||
PROTOCOL_VERSION
|
||||
} = require('./consts')
|
||||
|
||||
@@ -34,6 +33,11 @@ const { codes } = require('../errors')
|
||||
* @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} HostProperties
|
||||
* @property {string} agentVersion
|
||||
*/
|
||||
|
||||
class IdentifyService {
|
||||
/**
|
||||
* @class
|
||||
@@ -51,7 +55,6 @@ class IdentifyService {
|
||||
|
||||
// Store self host metadata
|
||||
this._host = {
|
||||
agentVersion: AGENT_VERSION,
|
||||
protocolVersion: PROTOCOL_VERSION,
|
||||
...libp2p._options.host
|
||||
}
|
||||
@@ -94,12 +97,12 @@ class IdentifyService {
|
||||
const { stream } = await connection.newStream(MULTICODEC_IDENTIFY_PUSH)
|
||||
|
||||
await pipe(
|
||||
[{
|
||||
[Message.Identify.encode({
|
||||
listenAddrs,
|
||||
signedPeerRecord,
|
||||
protocols
|
||||
}],
|
||||
pb.encode(Message),
|
||||
}).finish()],
|
||||
lp.encode(),
|
||||
stream,
|
||||
consume
|
||||
)
|
||||
@@ -160,12 +163,12 @@ class IdentifyService {
|
||||
|
||||
let message
|
||||
try {
|
||||
message = Message.decode(data)
|
||||
message = Message.Identify.decode(data)
|
||||
} catch (err) {
|
||||
throw errCode(err, codes.ERR_INVALID_MESSAGE)
|
||||
}
|
||||
|
||||
let {
|
||||
const {
|
||||
publicKey,
|
||||
listenAddrs,
|
||||
protocols,
|
||||
@@ -180,7 +183,7 @@ class IdentifyService {
|
||||
}
|
||||
|
||||
// Get the observedAddr if there is one
|
||||
observedAddr = IdentifyService.getCleanMultiaddr(observedAddr)
|
||||
const cleanObservedAddr = IdentifyService.getCleanMultiaddr(observedAddr)
|
||||
|
||||
try {
|
||||
const envelope = await Envelope.openAndCertify(signedPeerRecord, PeerRecord.DOMAIN)
|
||||
@@ -194,7 +197,7 @@ class IdentifyService {
|
||||
|
||||
// LEGACY: Update peers data in PeerStore
|
||||
try {
|
||||
this.peerStore.addressBook.set(id, listenAddrs.map((addr) => multiaddr(addr)))
|
||||
this.peerStore.addressBook.set(id, listenAddrs.map((addr) => new Multiaddr(addr)))
|
||||
} catch (err) {
|
||||
log.error('received invalid addrs', err)
|
||||
}
|
||||
@@ -203,7 +206,7 @@ class IdentifyService {
|
||||
this.peerStore.metadataBook.set(id, 'AgentVersion', uint8ArrayFromString(message.agentVersion))
|
||||
|
||||
// TODO: Add and score our observed addr
|
||||
log('received observed address of %s', observedAddr)
|
||||
log('received observed address of %s', cleanObservedAddr)
|
||||
// this.addressManager.addObservedAddr(observedAddr)
|
||||
}
|
||||
|
||||
@@ -246,7 +249,7 @@ class IdentifyService {
|
||||
const signedPeerRecord = await this.peerStore.addressBook.getRawEnvelope(this.peerId)
|
||||
const protocols = this.peerStore.protoBook.get(this.peerId) || []
|
||||
|
||||
const message = Message.encode({
|
||||
const message = Message.Identify.encode({
|
||||
protocolVersion: this._host.protocolVersion,
|
||||
agentVersion: this._host.agentVersion,
|
||||
publicKey,
|
||||
@@ -254,7 +257,7 @@ class IdentifyService {
|
||||
signedPeerRecord,
|
||||
observedAddr: connection.remoteAddr.bytes,
|
||||
protocols
|
||||
})
|
||||
}).finish()
|
||||
|
||||
try {
|
||||
await pipe(
|
||||
@@ -288,7 +291,7 @@ class IdentifyService {
|
||||
toBuffer,
|
||||
collect
|
||||
)
|
||||
message = Message.decode(data)
|
||||
message = Message.Identify.decode(data)
|
||||
} catch (err) {
|
||||
return log.error('received invalid message', err)
|
||||
}
|
||||
@@ -307,7 +310,8 @@ class IdentifyService {
|
||||
|
||||
// LEGACY: Update peers data in PeerStore
|
||||
try {
|
||||
this.peerStore.addressBook.set(id, message.listenAddrs.map((addr) => multiaddr(addr)))
|
||||
this.peerStore.addressBook.set(id,
|
||||
message.listenAddrs.map((addr) => new Multiaddr(addr)))
|
||||
} catch (err) {
|
||||
log.error('received invalid addrs', err)
|
||||
}
|
||||
@@ -320,12 +324,12 @@ class IdentifyService {
|
||||
* Takes the `addr` and converts it to a Multiaddr if possible
|
||||
*
|
||||
* @param {Uint8Array | string} addr
|
||||
* @returns {multiaddr|null}
|
||||
* @returns {Multiaddr|null}
|
||||
*/
|
||||
static getCleanMultiaddr (addr) {
|
||||
if (addr && addr.length > 0) {
|
||||
try {
|
||||
return multiaddr(addr)
|
||||
return new Multiaddr(addr)
|
||||
} catch (_) {
|
||||
return null
|
||||
}
|
||||
|
95
src/identify/message.d.ts
vendored
Normal file
95
src/identify/message.d.ts
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
import * as $protobuf from "protobufjs";
|
||||
/** Properties of an Identify. */
|
||||
export interface IIdentify {
|
||||
|
||||
/** Identify protocolVersion */
|
||||
protocolVersion?: (string|null);
|
||||
|
||||
/** Identify agentVersion */
|
||||
agentVersion?: (string|null);
|
||||
|
||||
/** Identify publicKey */
|
||||
publicKey?: (Uint8Array|null);
|
||||
|
||||
/** Identify listenAddrs */
|
||||
listenAddrs?: (Uint8Array[]|null);
|
||||
|
||||
/** Identify observedAddr */
|
||||
observedAddr?: (Uint8Array|null);
|
||||
|
||||
/** Identify protocols */
|
||||
protocols?: (string[]|null);
|
||||
|
||||
/** Identify signedPeerRecord */
|
||||
signedPeerRecord?: (Uint8Array|null);
|
||||
}
|
||||
|
||||
/** Represents an Identify. */
|
||||
export class Identify implements IIdentify {
|
||||
|
||||
/**
|
||||
* Constructs a new Identify.
|
||||
* @param [p] Properties to set
|
||||
*/
|
||||
constructor(p?: IIdentify);
|
||||
|
||||
/** Identify protocolVersion. */
|
||||
public protocolVersion: string;
|
||||
|
||||
/** Identify agentVersion. */
|
||||
public agentVersion: string;
|
||||
|
||||
/** Identify publicKey. */
|
||||
public publicKey: Uint8Array;
|
||||
|
||||
/** Identify listenAddrs. */
|
||||
public listenAddrs: Uint8Array[];
|
||||
|
||||
/** Identify observedAddr. */
|
||||
public observedAddr: Uint8Array;
|
||||
|
||||
/** Identify protocols. */
|
||||
public protocols: string[];
|
||||
|
||||
/** Identify signedPeerRecord. */
|
||||
public signedPeerRecord: Uint8Array;
|
||||
|
||||
/**
|
||||
* Encodes the specified Identify message. Does not implicitly {@link Identify.verify|verify} messages.
|
||||
* @param m Identify message or plain object to encode
|
||||
* @param [w] Writer to encode to
|
||||
* @returns Writer
|
||||
*/
|
||||
public static encode(m: IIdentify, w?: $protobuf.Writer): $protobuf.Writer;
|
||||
|
||||
/**
|
||||
* Decodes an Identify message from the specified reader or buffer.
|
||||
* @param r Reader or buffer to decode from
|
||||
* @param [l] Message length if known beforehand
|
||||
* @returns Identify
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
public static decode(r: ($protobuf.Reader|Uint8Array), l?: number): Identify;
|
||||
|
||||
/**
|
||||
* Creates an Identify message from a plain object. Also converts values to their respective internal types.
|
||||
* @param d Plain object
|
||||
* @returns Identify
|
||||
*/
|
||||
public static fromObject(d: { [k: string]: any }): Identify;
|
||||
|
||||
/**
|
||||
* Creates a plain object from an Identify message. Also converts values to other types if specified.
|
||||
* @param m Identify
|
||||
* @param [o] Conversion options
|
||||
* @returns Plain object
|
||||
*/
|
||||
public static toObject(m: Identify, o?: $protobuf.IConversionOptions): { [k: string]: any };
|
||||
|
||||
/**
|
||||
* Converts this Identify to JSON.
|
||||
* @returns JSON object
|
||||
*/
|
||||
public toJSON(): { [k: string]: any };
|
||||
}
|
@@ -1,35 +1,328 @@
|
||||
'use strict'
|
||||
/*eslint-disable*/
|
||||
"use strict";
|
||||
|
||||
const protons = require('protons')
|
||||
const schema = `
|
||||
message Identify {
|
||||
// protocolVersion determines compatibility between peers
|
||||
optional string protocolVersion = 5; // e.g. ipfs/1.0.0
|
||||
var $protobuf = require("protobufjs/minimal");
|
||||
|
||||
// agentVersion is like a UserAgent string in browsers, or client version in bittorrent
|
||||
// includes the client name and client.
|
||||
optional string agentVersion = 6; // e.g. go-ipfs/0.1.0
|
||||
// Common aliases
|
||||
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
|
||||
|
||||
// publicKey is this node's public key (which also gives its node.ID)
|
||||
// - may not need to be sent, as secure channel implies it has been sent.
|
||||
// - then again, if we change / disable secure channel, may still want it.
|
||||
optional bytes publicKey = 1;
|
||||
// Exported root namespace
|
||||
var $root = $protobuf.roots["libp2p-identify"] || ($protobuf.roots["libp2p-identify"] = {});
|
||||
|
||||
// listenAddrs are the multiaddrs the sender node listens for open connections on
|
||||
repeated bytes listenAddrs = 2;
|
||||
$root.Identify = (function() {
|
||||
|
||||
// oservedAddr is the multiaddr of the remote endpoint that the sender node perceives
|
||||
// this is useful information to convey to the other side, as it helps the remote endpoint
|
||||
// determine whether its connection to the local peer goes through NAT.
|
||||
optional bytes observedAddr = 4;
|
||||
/**
|
||||
* Properties of an Identify.
|
||||
* @exports IIdentify
|
||||
* @interface IIdentify
|
||||
* @property {string|null} [protocolVersion] Identify protocolVersion
|
||||
* @property {string|null} [agentVersion] Identify agentVersion
|
||||
* @property {Uint8Array|null} [publicKey] Identify publicKey
|
||||
* @property {Array.<Uint8Array>|null} [listenAddrs] Identify listenAddrs
|
||||
* @property {Uint8Array|null} [observedAddr] Identify observedAddr
|
||||
* @property {Array.<string>|null} [protocols] Identify protocols
|
||||
* @property {Uint8Array|null} [signedPeerRecord] Identify signedPeerRecord
|
||||
*/
|
||||
|
||||
repeated string protocols = 3;
|
||||
/**
|
||||
* Constructs a new Identify.
|
||||
* @exports Identify
|
||||
* @classdesc Represents an Identify.
|
||||
* @implements IIdentify
|
||||
* @constructor
|
||||
* @param {IIdentify=} [p] Properties to set
|
||||
*/
|
||||
function Identify(p) {
|
||||
this.listenAddrs = [];
|
||||
this.protocols = [];
|
||||
if (p)
|
||||
for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
|
||||
if (p[ks[i]] != null)
|
||||
this[ks[i]] = p[ks[i]];
|
||||
}
|
||||
|
||||
// signedPeerRecord contains a serialized SignedEnvelope containing a PeerRecord,
|
||||
// signed by the sending node. It contains the same addresses as the listenAddrs field, but
|
||||
// in a form that lets us share authenticated addrs with other peers.
|
||||
optional bytes signedPeerRecord = 8;
|
||||
}
|
||||
`
|
||||
/**
|
||||
* Identify protocolVersion.
|
||||
* @member {string} protocolVersion
|
||||
* @memberof Identify
|
||||
* @instance
|
||||
*/
|
||||
Identify.prototype.protocolVersion = "";
|
||||
|
||||
module.exports = protons(schema).Identify
|
||||
/**
|
||||
* Identify agentVersion.
|
||||
* @member {string} agentVersion
|
||||
* @memberof Identify
|
||||
* @instance
|
||||
*/
|
||||
Identify.prototype.agentVersion = "";
|
||||
|
||||
/**
|
||||
* Identify publicKey.
|
||||
* @member {Uint8Array} publicKey
|
||||
* @memberof Identify
|
||||
* @instance
|
||||
*/
|
||||
Identify.prototype.publicKey = $util.newBuffer([]);
|
||||
|
||||
/**
|
||||
* Identify listenAddrs.
|
||||
* @member {Array.<Uint8Array>} listenAddrs
|
||||
* @memberof Identify
|
||||
* @instance
|
||||
*/
|
||||
Identify.prototype.listenAddrs = $util.emptyArray;
|
||||
|
||||
/**
|
||||
* Identify observedAddr.
|
||||
* @member {Uint8Array} observedAddr
|
||||
* @memberof Identify
|
||||
* @instance
|
||||
*/
|
||||
Identify.prototype.observedAddr = $util.newBuffer([]);
|
||||
|
||||
/**
|
||||
* Identify protocols.
|
||||
* @member {Array.<string>} protocols
|
||||
* @memberof Identify
|
||||
* @instance
|
||||
*/
|
||||
Identify.prototype.protocols = $util.emptyArray;
|
||||
|
||||
/**
|
||||
* Identify signedPeerRecord.
|
||||
* @member {Uint8Array} signedPeerRecord
|
||||
* @memberof Identify
|
||||
* @instance
|
||||
*/
|
||||
Identify.prototype.signedPeerRecord = $util.newBuffer([]);
|
||||
|
||||
/**
|
||||
* Encodes the specified Identify message. Does not implicitly {@link Identify.verify|verify} messages.
|
||||
* @function encode
|
||||
* @memberof Identify
|
||||
* @static
|
||||
* @param {IIdentify} m Identify message or plain object to encode
|
||||
* @param {$protobuf.Writer} [w] Writer to encode to
|
||||
* @returns {$protobuf.Writer} Writer
|
||||
*/
|
||||
Identify.encode = function encode(m, w) {
|
||||
if (!w)
|
||||
w = $Writer.create();
|
||||
if (m.publicKey != null && Object.hasOwnProperty.call(m, "publicKey"))
|
||||
w.uint32(10).bytes(m.publicKey);
|
||||
if (m.listenAddrs != null && m.listenAddrs.length) {
|
||||
for (var i = 0; i < m.listenAddrs.length; ++i)
|
||||
w.uint32(18).bytes(m.listenAddrs[i]);
|
||||
}
|
||||
if (m.protocols != null && m.protocols.length) {
|
||||
for (var i = 0; i < m.protocols.length; ++i)
|
||||
w.uint32(26).string(m.protocols[i]);
|
||||
}
|
||||
if (m.observedAddr != null && Object.hasOwnProperty.call(m, "observedAddr"))
|
||||
w.uint32(34).bytes(m.observedAddr);
|
||||
if (m.protocolVersion != null && Object.hasOwnProperty.call(m, "protocolVersion"))
|
||||
w.uint32(42).string(m.protocolVersion);
|
||||
if (m.agentVersion != null && Object.hasOwnProperty.call(m, "agentVersion"))
|
||||
w.uint32(50).string(m.agentVersion);
|
||||
if (m.signedPeerRecord != null && Object.hasOwnProperty.call(m, "signedPeerRecord"))
|
||||
w.uint32(66).bytes(m.signedPeerRecord);
|
||||
return w;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decodes an Identify message from the specified reader or buffer.
|
||||
* @function decode
|
||||
* @memberof Identify
|
||||
* @static
|
||||
* @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
|
||||
* @param {number} [l] Message length if known beforehand
|
||||
* @returns {Identify} Identify
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
Identify.decode = function decode(r, l) {
|
||||
if (!(r instanceof $Reader))
|
||||
r = $Reader.create(r);
|
||||
var c = l === undefined ? r.len : r.pos + l, m = new $root.Identify();
|
||||
while (r.pos < c) {
|
||||
var t = r.uint32();
|
||||
switch (t >>> 3) {
|
||||
case 5:
|
||||
m.protocolVersion = r.string();
|
||||
break;
|
||||
case 6:
|
||||
m.agentVersion = r.string();
|
||||
break;
|
||||
case 1:
|
||||
m.publicKey = r.bytes();
|
||||
break;
|
||||
case 2:
|
||||
if (!(m.listenAddrs && m.listenAddrs.length))
|
||||
m.listenAddrs = [];
|
||||
m.listenAddrs.push(r.bytes());
|
||||
break;
|
||||
case 4:
|
||||
m.observedAddr = r.bytes();
|
||||
break;
|
||||
case 3:
|
||||
if (!(m.protocols && m.protocols.length))
|
||||
m.protocols = [];
|
||||
m.protocols.push(r.string());
|
||||
break;
|
||||
case 8:
|
||||
m.signedPeerRecord = r.bytes();
|
||||
break;
|
||||
default:
|
||||
r.skipType(t & 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an Identify message from a plain object. Also converts values to their respective internal types.
|
||||
* @function fromObject
|
||||
* @memberof Identify
|
||||
* @static
|
||||
* @param {Object.<string,*>} d Plain object
|
||||
* @returns {Identify} Identify
|
||||
*/
|
||||
Identify.fromObject = function fromObject(d) {
|
||||
if (d instanceof $root.Identify)
|
||||
return d;
|
||||
var m = new $root.Identify();
|
||||
if (d.protocolVersion != null) {
|
||||
m.protocolVersion = String(d.protocolVersion);
|
||||
}
|
||||
if (d.agentVersion != null) {
|
||||
m.agentVersion = String(d.agentVersion);
|
||||
}
|
||||
if (d.publicKey != null) {
|
||||
if (typeof d.publicKey === "string")
|
||||
$util.base64.decode(d.publicKey, m.publicKey = $util.newBuffer($util.base64.length(d.publicKey)), 0);
|
||||
else if (d.publicKey.length)
|
||||
m.publicKey = d.publicKey;
|
||||
}
|
||||
if (d.listenAddrs) {
|
||||
if (!Array.isArray(d.listenAddrs))
|
||||
throw TypeError(".Identify.listenAddrs: array expected");
|
||||
m.listenAddrs = [];
|
||||
for (var i = 0; i < d.listenAddrs.length; ++i) {
|
||||
if (typeof d.listenAddrs[i] === "string")
|
||||
$util.base64.decode(d.listenAddrs[i], m.listenAddrs[i] = $util.newBuffer($util.base64.length(d.listenAddrs[i])), 0);
|
||||
else if (d.listenAddrs[i].length)
|
||||
m.listenAddrs[i] = d.listenAddrs[i];
|
||||
}
|
||||
}
|
||||
if (d.observedAddr != null) {
|
||||
if (typeof d.observedAddr === "string")
|
||||
$util.base64.decode(d.observedAddr, m.observedAddr = $util.newBuffer($util.base64.length(d.observedAddr)), 0);
|
||||
else if (d.observedAddr.length)
|
||||
m.observedAddr = d.observedAddr;
|
||||
}
|
||||
if (d.protocols) {
|
||||
if (!Array.isArray(d.protocols))
|
||||
throw TypeError(".Identify.protocols: array expected");
|
||||
m.protocols = [];
|
||||
for (var i = 0; i < d.protocols.length; ++i) {
|
||||
m.protocols[i] = String(d.protocols[i]);
|
||||
}
|
||||
}
|
||||
if (d.signedPeerRecord != null) {
|
||||
if (typeof d.signedPeerRecord === "string")
|
||||
$util.base64.decode(d.signedPeerRecord, m.signedPeerRecord = $util.newBuffer($util.base64.length(d.signedPeerRecord)), 0);
|
||||
else if (d.signedPeerRecord.length)
|
||||
m.signedPeerRecord = d.signedPeerRecord;
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a plain object from an Identify message. Also converts values to other types if specified.
|
||||
* @function toObject
|
||||
* @memberof Identify
|
||||
* @static
|
||||
* @param {Identify} m Identify
|
||||
* @param {$protobuf.IConversionOptions} [o] Conversion options
|
||||
* @returns {Object.<string,*>} Plain object
|
||||
*/
|
||||
Identify.toObject = function toObject(m, o) {
|
||||
if (!o)
|
||||
o = {};
|
||||
var d = {};
|
||||
if (o.arrays || o.defaults) {
|
||||
d.listenAddrs = [];
|
||||
d.protocols = [];
|
||||
}
|
||||
if (o.defaults) {
|
||||
if (o.bytes === String)
|
||||
d.publicKey = "";
|
||||
else {
|
||||
d.publicKey = [];
|
||||
if (o.bytes !== Array)
|
||||
d.publicKey = $util.newBuffer(d.publicKey);
|
||||
}
|
||||
if (o.bytes === String)
|
||||
d.observedAddr = "";
|
||||
else {
|
||||
d.observedAddr = [];
|
||||
if (o.bytes !== Array)
|
||||
d.observedAddr = $util.newBuffer(d.observedAddr);
|
||||
}
|
||||
d.protocolVersion = "";
|
||||
d.agentVersion = "";
|
||||
if (o.bytes === String)
|
||||
d.signedPeerRecord = "";
|
||||
else {
|
||||
d.signedPeerRecord = [];
|
||||
if (o.bytes !== Array)
|
||||
d.signedPeerRecord = $util.newBuffer(d.signedPeerRecord);
|
||||
}
|
||||
}
|
||||
if (m.publicKey != null && m.hasOwnProperty("publicKey")) {
|
||||
d.publicKey = o.bytes === String ? $util.base64.encode(m.publicKey, 0, m.publicKey.length) : o.bytes === Array ? Array.prototype.slice.call(m.publicKey) : m.publicKey;
|
||||
}
|
||||
if (m.listenAddrs && m.listenAddrs.length) {
|
||||
d.listenAddrs = [];
|
||||
for (var j = 0; j < m.listenAddrs.length; ++j) {
|
||||
d.listenAddrs[j] = o.bytes === String ? $util.base64.encode(m.listenAddrs[j], 0, m.listenAddrs[j].length) : o.bytes === Array ? Array.prototype.slice.call(m.listenAddrs[j]) : m.listenAddrs[j];
|
||||
}
|
||||
}
|
||||
if (m.protocols && m.protocols.length) {
|
||||
d.protocols = [];
|
||||
for (var j = 0; j < m.protocols.length; ++j) {
|
||||
d.protocols[j] = m.protocols[j];
|
||||
}
|
||||
}
|
||||
if (m.observedAddr != null && m.hasOwnProperty("observedAddr")) {
|
||||
d.observedAddr = o.bytes === String ? $util.base64.encode(m.observedAddr, 0, m.observedAddr.length) : o.bytes === Array ? Array.prototype.slice.call(m.observedAddr) : m.observedAddr;
|
||||
}
|
||||
if (m.protocolVersion != null && m.hasOwnProperty("protocolVersion")) {
|
||||
d.protocolVersion = m.protocolVersion;
|
||||
}
|
||||
if (m.agentVersion != null && m.hasOwnProperty("agentVersion")) {
|
||||
d.agentVersion = m.agentVersion;
|
||||
}
|
||||
if (m.signedPeerRecord != null && m.hasOwnProperty("signedPeerRecord")) {
|
||||
d.signedPeerRecord = o.bytes === String ? $util.base64.encode(m.signedPeerRecord, 0, m.signedPeerRecord.length) : o.bytes === Array ? Array.prototype.slice.call(m.signedPeerRecord) : m.signedPeerRecord;
|
||||
}
|
||||
return d;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts this Identify to JSON.
|
||||
* @function toJSON
|
||||
* @memberof Identify
|
||||
* @instance
|
||||
* @returns {Object.<string,*>} JSON object
|
||||
*/
|
||||
Identify.prototype.toJSON = function toJSON() {
|
||||
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
|
||||
};
|
||||
|
||||
return Identify;
|
||||
})();
|
||||
|
||||
module.exports = $root;
|
||||
|
30
src/identify/message.proto
Normal file
30
src/identify/message.proto
Normal file
@@ -0,0 +1,30 @@
|
||||
syntax = "proto3";
|
||||
|
||||
message Identify {
|
||||
// protocolVersion determines compatibility between peers
|
||||
optional string protocolVersion = 5; // e.g. ipfs/1.0.0
|
||||
|
||||
// agentVersion is like a UserAgent string in browsers, or client version in bittorrent
|
||||
// includes the client name and client.
|
||||
optional string agentVersion = 6; // e.g. go-ipfs/0.1.0
|
||||
|
||||
// publicKey is this node's public key (which also gives its node.ID)
|
||||
// - may not need to be sent, as secure channel implies it has been sent.
|
||||
// - then again, if we change / disable secure channel, may still want it.
|
||||
optional bytes publicKey = 1;
|
||||
|
||||
// listenAddrs are the multiaddrs the sender node listens for open connections on
|
||||
repeated bytes listenAddrs = 2;
|
||||
|
||||
// oservedAddr is the multiaddr of the remote endpoint that the sender node perceives
|
||||
// this is useful information to convey to the other side, as it helps the remote endpoint
|
||||
// determine whether its connection to the local peer goes through NAT.
|
||||
optional bytes observedAddr = 4;
|
||||
|
||||
repeated string protocols = 3;
|
||||
|
||||
// signedPeerRecord contains a serialized SignedEnvelope containing a PeerRecord,
|
||||
// signed by the sending node. It contains the same addresses as the listenAddrs field, but
|
||||
// in a form that lets us share authenticated addrs with other peers.
|
||||
optional bytes signedPeerRecord = 8;
|
||||
}
|
125
src/index.js
125
src/index.js
@@ -4,13 +4,11 @@ const debug = require('debug')
|
||||
const log = Object.assign(debug('libp2p'), {
|
||||
error: debug('libp2p:err')
|
||||
})
|
||||
/** @typedef {import('./types').EventEmitterFactory} Events */
|
||||
/** @type Events */
|
||||
const EventEmitter = require('events')
|
||||
const { EventEmitter } = require('events')
|
||||
|
||||
const errCode = require('err-code')
|
||||
const PeerId = require('peer-id')
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
|
||||
const PeerRouting = require('./peer-routing')
|
||||
const ContentRouting = require('./content-routing')
|
||||
@@ -38,29 +36,63 @@ const NatManager = require('./nat-manager')
|
||||
const { updateSelfPeerRecord } = require('./record/utils')
|
||||
|
||||
/**
|
||||
* @typedef {import('multiaddr')} Multiaddr
|
||||
* @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
|
||||
* @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
|
||||
* @typedef {import('libp2p-interfaces/src/transport/types').TransportFactory} TransportFactory
|
||||
* @typedef {import('libp2p-interfaces/src/transport/types').TransportFactory<any, any>} TransportFactory
|
||||
* @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxerFactory} MuxerFactory
|
||||
* @typedef {import('libp2p-interfaces/src/content-routing/types').ContentRouting} ContentRoutingModule
|
||||
* @typedef {import('libp2p-interfaces/src/peer-discovery/types').PeerDiscoveryFactory} PeerDiscoveryFactory
|
||||
* @typedef {import('libp2p-interfaces/src/peer-routing/types').PeerRouting} PeerRoutingModule
|
||||
* @typedef {import('libp2p-interfaces/src/crypto/types').Crypto} Crypto
|
||||
* @typedef {import('libp2p-interfaces/src/pubsub')} Pubsub
|
||||
* @typedef {import('libp2p-interfaces/src/pubsub').PubsubOptions} PubsubOptions
|
||||
* @typedef {import('interface-datastore').Datastore} Datastore
|
||||
* @typedef {import('./pnet')} Protector
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} HandlerProps
|
||||
* @property {Connection} connection
|
||||
* @property {MuxedStream} stream
|
||||
* @property {string} protocol
|
||||
*
|
||||
* @typedef {Object} RandomWalkOptions
|
||||
* @property {boolean} [enabled = false]
|
||||
* @property {number} [queriesPerPeriod = 1]
|
||||
* @property {number} [interval = 300e3]
|
||||
* @property {number} [timeout = 10e3]
|
||||
*
|
||||
* @typedef {Object} DhtOptions
|
||||
* @property {boolean} [enabled = false]
|
||||
* @property {number} [kBucketSize = 20]
|
||||
* @property {RandomWalkOptions} [randomWalk]
|
||||
* @property {boolean} [clientMode]
|
||||
* @property {import('libp2p-interfaces/src/types').DhtSelectors} [selectors]
|
||||
* @property {import('libp2p-interfaces/src/types').DhtValidators} [validators]
|
||||
*
|
||||
* @typedef {Object} KeychainOptions
|
||||
* @property {Datastore} [datastore]
|
||||
*
|
||||
* @typedef {Object} PeerStoreOptions
|
||||
* @property {boolean} persistence
|
||||
*
|
||||
* @typedef {Object} RelayOptions
|
||||
* @typedef {Object} PubsubLocalOptions
|
||||
* @property {boolean} enabled
|
||||
* @property {import('./circuit').RelayAdvertiseOptions} advertise
|
||||
* @property {import('./circuit').HopOptions} hop
|
||||
* @property {import('./circuit').AutoRelayOptions} autoRelay
|
||||
*
|
||||
* @typedef {Object} MetricsOptions
|
||||
* @property {boolean} enabled
|
||||
*
|
||||
* @typedef {Object} RelayOptions
|
||||
* @property {boolean} [enabled = true]
|
||||
* @property {import('./circuit').RelayAdvertiseOptions} [advertise]
|
||||
* @property {import('./circuit').HopOptions} [hop]
|
||||
* @property {import('./circuit').AutoRelayOptions} [autoRelay]
|
||||
*
|
||||
* @typedef {Object} Libp2pConfig
|
||||
* @property {Object} [dht] dht module options
|
||||
* @property {Object} [peerDiscovery]
|
||||
* @property {Pubsub} [pubsub] pubsub module options
|
||||
* @property {DhtOptions} [dht] dht module options
|
||||
* @property {import('./nat-manager').NatManagerOptions} [nat]
|
||||
* @property {Record<string, Object|boolean>} [peerDiscovery]
|
||||
* @property {PubsubLocalOptions & PubsubOptions} [pubsub] pubsub module options
|
||||
* @property {RelayOptions} [relay]
|
||||
* @property {Record<string, Object>} [transport] transport options indexed by transport key
|
||||
*
|
||||
@@ -68,16 +100,25 @@ const { updateSelfPeerRecord } = require('./record/utils')
|
||||
* @property {TransportFactory[]} transport
|
||||
* @property {MuxerFactory[]} streamMuxer
|
||||
* @property {Crypto[]} connEncryption
|
||||
* @property {PeerDiscoveryFactory[]} [peerDiscovery]
|
||||
* @property {PeerRoutingModule[]} [peerRouting]
|
||||
* @property {ContentRoutingModule[]} [contentRouting]
|
||||
* @property {Object} [dht]
|
||||
* @property {{new(...args: any[]): Pubsub}} [pubsub]
|
||||
* @property {Protector} [connProtector]
|
||||
*
|
||||
* @typedef {Object} Libp2pOptions
|
||||
* @property {Libp2pModules} modules libp2p modules to use
|
||||
* @property {import('./address-manager').AddressManagerOptions} [addresses]
|
||||
* @property {import('./connection-manager').ConnectionManagerOptions} [connectionManager]
|
||||
* @property {Datastore} [datastore]
|
||||
* @property {import('./dialer').DialerOptions} [dialer]
|
||||
* @property {import('./metrics').MetricsOptions} [metrics]
|
||||
* @property {Object} [keychain]
|
||||
* @property {import('./transport-manager').TransportManagerOptions} [transportManager]
|
||||
* @property {import('./identify/index').HostProperties} [host] libp2p host
|
||||
* @property {KeychainOptions & import('./keychain/index').KeychainOptions} [keychain]
|
||||
* @property {MetricsOptions & import('./metrics').MetricsOptions} [metrics]
|
||||
* @property {import('./peer-routing').PeerRoutingOptions} [peerRouting]
|
||||
* @property {PeerStoreOptions & import('./peer-store/persistent').PersistentPeerStoreOptions} [peerStore]
|
||||
* @property {import('./transport-manager').TransportManagerOptions} [transportManager]
|
||||
* @property {Libp2pConfig} [config]
|
||||
*
|
||||
* @typedef {Object} constructorOptions
|
||||
@@ -152,9 +193,6 @@ class Libp2p extends EventEmitter {
|
||||
this._discovery = new Map() // Discovery service instances/references
|
||||
|
||||
// Create the Connection Manager
|
||||
if (this._options.connectionManager.minPeers) { // Remove in 0.29
|
||||
this._options.connectionManager.minConnections = this._options.connectionManager.minPeers
|
||||
}
|
||||
this.connectionManager = new ConnectionManager(this, {
|
||||
autoDial: this._config.peerDiscovery.autoDial,
|
||||
...this._options.connectionManager
|
||||
@@ -175,7 +213,6 @@ class Libp2p extends EventEmitter {
|
||||
const keychainOpts = Keychain.generateOptions()
|
||||
|
||||
this.keychain = new Keychain(this._options.keychain.datastore, {
|
||||
passPhrase: this._options.keychain.pass,
|
||||
...keychainOpts,
|
||||
...this._options.keychain
|
||||
})
|
||||
@@ -203,6 +240,7 @@ class Libp2p extends EventEmitter {
|
||||
peerId: this.peerId,
|
||||
addressManager: this.addressManager,
|
||||
transportManager: this.transportManager,
|
||||
// @ts-ignore Nat typedef is not understood as Object
|
||||
...this._options.config.nat
|
||||
})
|
||||
|
||||
@@ -227,11 +265,7 @@ class Libp2p extends EventEmitter {
|
||||
this.dialer = new Dialer({
|
||||
transportManager: this.transportManager,
|
||||
peerStore: this.peerStore,
|
||||
concurrency: this._options.dialer.maxParallelDials,
|
||||
perPeerLimit: this._options.dialer.maxDialsPerPeer,
|
||||
timeout: this._options.dialer.dialTimeout,
|
||||
resolvers: this._options.dialer.resolvers,
|
||||
addressSorter: this._options.dialer.addressSorter
|
||||
...this._options.dialer
|
||||
})
|
||||
|
||||
this._modules.transport.forEach((Transport) => {
|
||||
@@ -268,6 +302,7 @@ class Libp2p extends EventEmitter {
|
||||
// dht provided components (peerRouting, contentRouting, dht)
|
||||
if (this._modules.dht) {
|
||||
const DHT = this._modules.dht
|
||||
// @ts-ignore Object is not constructable
|
||||
this._dht = new DHT({
|
||||
libp2p: this,
|
||||
dialer: this.dialer,
|
||||
@@ -426,22 +461,36 @@ class Libp2p extends EventEmitter {
|
||||
* @returns {Promise<Connection>}
|
||||
*/
|
||||
dial (peer, options) {
|
||||
return this.dialProtocol(peer, [], options)
|
||||
return this._dial(peer, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Dials to the provided peer and handshakes with the given protocol.
|
||||
* Dials to the provided peer and tries to handshake with the given protocols in order.
|
||||
* If successful, the known metadata of the peer will be added to the nodes `peerStore`,
|
||||
* and the `Connection` will be returned
|
||||
* and the `MuxedStream` will be returned together with the successful negotiated protocol.
|
||||
*
|
||||
* @async
|
||||
* @param {PeerId|Multiaddr|string} peer - The peer to dial
|
||||
* @param {string[]|string} protocols
|
||||
* @param {object} [options]
|
||||
* @param {AbortSignal} [options.signal]
|
||||
* @returns {Promise<Connection|*>}
|
||||
*/
|
||||
async dialProtocol (peer, protocols, options) {
|
||||
if (!protocols || !protocols.length) {
|
||||
throw errCode(new Error('no protocols were provided to open a stream'), codes.ERR_INVALID_PROTOCOLS_FOR_STREAM)
|
||||
}
|
||||
|
||||
const connection = await this._dial(peer, options)
|
||||
return connection.newStream(protocols)
|
||||
}
|
||||
|
||||
/**
|
||||
* @async
|
||||
* @param {PeerId|Multiaddr|string} peer - The peer to dial
|
||||
* @param {object} [options]
|
||||
* @returns {Promise<Connection>}
|
||||
*/
|
||||
async _dial (peer, options) {
|
||||
const { id, multiaddrs } = getPeer(peer)
|
||||
|
||||
if (id.equals(this.peerId)) {
|
||||
@@ -456,11 +505,6 @@ class Libp2p extends EventEmitter {
|
||||
this.peerStore.addressBook.add(id, multiaddrs)
|
||||
}
|
||||
|
||||
// If a protocol was provided, create a new stream
|
||||
if (protocols && protocols.length) {
|
||||
return connection.newStream(protocols)
|
||||
}
|
||||
|
||||
return connection
|
||||
}
|
||||
|
||||
@@ -484,13 +528,13 @@ class Libp2p extends EventEmitter {
|
||||
|
||||
addrs = addrs.concat(this.addressManager.getObservedAddrs().map(ma => ma.toString()))
|
||||
|
||||
const announceFilter = this._options.addresses.announceFilter || ((multiaddrs) => multiaddrs)
|
||||
const announceFilter = this._options.addresses.announceFilter
|
||||
|
||||
// dedupe multiaddrs
|
||||
const addrSet = new Set(addrs)
|
||||
|
||||
// Create advertising list
|
||||
return announceFilter(Array.from(addrSet).map(str => multiaddr(str)))
|
||||
return announceFilter(Array.from(addrSet).map(str => new Multiaddr(str)))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -536,7 +580,7 @@ class Libp2p extends EventEmitter {
|
||||
* Registers the `handler` for each protocol
|
||||
*
|
||||
* @param {string[]|string} protocols
|
||||
* @param {({ connection: Connection, stream: MuxedStream, protocol: string }) => void} handler
|
||||
* @param {(props: HandlerProps) => void} handler
|
||||
*/
|
||||
handle (protocols, handler) {
|
||||
protocols = Array.isArray(protocols) ? protocols : [protocols]
|
||||
@@ -656,7 +700,7 @@ class Libp2p extends EventEmitter {
|
||||
try {
|
||||
await this.dialer.connectToPeer(peerId)
|
||||
} catch (err) {
|
||||
log.error('could not connect to discovered peer', err)
|
||||
log.error(`could not connect to discovered peer ${peerId.toB58String()} with ${err}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -669,6 +713,9 @@ class Libp2p extends EventEmitter {
|
||||
* @private
|
||||
*/
|
||||
async _setupPeerDiscovery () {
|
||||
/**
|
||||
* @param {PeerDiscoveryFactory} DiscoveryService
|
||||
*/
|
||||
const setupService = (DiscoveryService) => {
|
||||
let config = {
|
||||
enabled: true // on by default
|
||||
@@ -677,6 +724,7 @@ class Libp2p extends EventEmitter {
|
||||
if (DiscoveryService.tag &&
|
||||
this._config.peerDiscovery &&
|
||||
this._config.peerDiscovery[DiscoveryService.tag]) {
|
||||
// @ts-ignore PeerDiscovery not understood as an Object for spread
|
||||
config = { ...config, ...this._config.peerDiscovery[DiscoveryService.tag] }
|
||||
}
|
||||
|
||||
@@ -685,6 +733,7 @@ class Libp2p extends EventEmitter {
|
||||
let discoveryService
|
||||
|
||||
if (typeof DiscoveryService === 'function') {
|
||||
// @ts-ignore DiscoveryService has no constructor type inferred
|
||||
discoveryService = new DiscoveryService(Object.assign({}, config, {
|
||||
peerId: this.peerId,
|
||||
libp2p: this
|
||||
|
@@ -4,6 +4,7 @@ const debug = require('debug')
|
||||
const log = Object.assign(debug('libp2p:plaintext'), {
|
||||
error: debug('libp2p:plaintext:err')
|
||||
})
|
||||
// @ts-ignore it-handshake do not export types
|
||||
const handshake = require('it-handshake')
|
||||
const lp = require('it-length-prefixed')
|
||||
const PeerId = require('peer-id')
|
||||
@@ -16,8 +17,12 @@ const protocol = '/plaintext/2.0.0'
|
||||
* @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {import('./proto').IExchange} exchange
|
||||
*/
|
||||
function lpEncodeExchange (exchange) {
|
||||
const pb = Exchange.encode(exchange)
|
||||
const pb = Exchange.encode(exchange).finish()
|
||||
// @ts-ignore TODO: Uint8Array not assignable to Buffer
|
||||
return lp.encode.single(pb)
|
||||
}
|
||||
|
||||
@@ -68,12 +73,23 @@ async function encrypt (localId, conn, remoteId) {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
protocol,
|
||||
secureInbound: (localId, conn, remoteId) => {
|
||||
return encrypt(localId, conn, remoteId)
|
||||
},
|
||||
secureOutbound: (localId, conn, remoteId) => {
|
||||
return encrypt(localId, conn, remoteId)
|
||||
}
|
||||
}
|
||||
module.exports =
|
||||
{
|
||||
protocol,
|
||||
/**
|
||||
* @param {PeerId} localId
|
||||
* @param {Connection} conn
|
||||
* @param {PeerId | undefined} remoteId
|
||||
*/
|
||||
secureInbound: (localId, conn, remoteId) => {
|
||||
return encrypt(localId, conn, remoteId)
|
||||
},
|
||||
/**
|
||||
* @param {PeerId} localId
|
||||
* @param {Connection} conn
|
||||
* @param {PeerId | undefined} remoteId
|
||||
*/
|
||||
secureOutbound: (localId, conn, remoteId) => {
|
||||
return encrypt(localId, conn, remoteId)
|
||||
}
|
||||
}
|
||||
|
128
src/insecure/proto.d.ts
vendored
Normal file
128
src/insecure/proto.d.ts
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
import * as $protobuf from "protobufjs";
|
||||
/** Properties of an Exchange. */
|
||||
export interface IExchange {
|
||||
|
||||
/** Exchange id */
|
||||
id?: (Uint8Array|null);
|
||||
|
||||
/** Exchange pubkey */
|
||||
pubkey?: (IPublicKey|null);
|
||||
}
|
||||
|
||||
/** Represents an Exchange. */
|
||||
export class Exchange implements IExchange {
|
||||
|
||||
/**
|
||||
* Constructs a new Exchange.
|
||||
* @param [p] Properties to set
|
||||
*/
|
||||
constructor(p?: IExchange);
|
||||
|
||||
/** Exchange id. */
|
||||
public id: Uint8Array;
|
||||
|
||||
/** Exchange pubkey. */
|
||||
public pubkey?: (IPublicKey|null);
|
||||
|
||||
/**
|
||||
* Encodes the specified Exchange message. Does not implicitly {@link Exchange.verify|verify} messages.
|
||||
* @param m Exchange message or plain object to encode
|
||||
* @param [w] Writer to encode to
|
||||
* @returns Writer
|
||||
*/
|
||||
public static encode(m: IExchange, w?: $protobuf.Writer): $protobuf.Writer;
|
||||
|
||||
/**
|
||||
* Decodes an Exchange message from the specified reader or buffer.
|
||||
* @param r Reader or buffer to decode from
|
||||
* @param [l] Message length if known beforehand
|
||||
* @returns Exchange
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
public static decode(r: ($protobuf.Reader|Uint8Array), l?: number): Exchange;
|
||||
|
||||
/**
|
||||
* Creates an Exchange message from a plain object. Also converts values to their respective internal types.
|
||||
* @param d Plain object
|
||||
* @returns Exchange
|
||||
*/
|
||||
public static fromObject(d: { [k: string]: any }): Exchange;
|
||||
|
||||
/**
|
||||
* Creates a plain object from an Exchange message. Also converts values to other types if specified.
|
||||
* @param m Exchange
|
||||
* @param [o] Conversion options
|
||||
* @returns Plain object
|
||||
*/
|
||||
public static toObject(m: Exchange, o?: $protobuf.IConversionOptions): { [k: string]: any };
|
||||
|
||||
/**
|
||||
* Converts this Exchange to JSON.
|
||||
* @returns JSON object
|
||||
*/
|
||||
public toJSON(): { [k: string]: any };
|
||||
}
|
||||
|
||||
/** KeyType enum. */
|
||||
export enum KeyType {
|
||||
RSA = 0,
|
||||
Ed25519 = 1,
|
||||
Secp256k1 = 2,
|
||||
ECDSA = 3
|
||||
}
|
||||
|
||||
/** Represents a PublicKey. */
|
||||
export class PublicKey implements IPublicKey {
|
||||
|
||||
/**
|
||||
* Constructs a new PublicKey.
|
||||
* @param [p] Properties to set
|
||||
*/
|
||||
constructor(p?: IPublicKey);
|
||||
|
||||
/** PublicKey Type. */
|
||||
public Type: KeyType;
|
||||
|
||||
/** PublicKey Data. */
|
||||
public Data: Uint8Array;
|
||||
|
||||
/**
|
||||
* Encodes the specified PublicKey message. Does not implicitly {@link PublicKey.verify|verify} messages.
|
||||
* @param m PublicKey message or plain object to encode
|
||||
* @param [w] Writer to encode to
|
||||
* @returns Writer
|
||||
*/
|
||||
public static encode(m: IPublicKey, w?: $protobuf.Writer): $protobuf.Writer;
|
||||
|
||||
/**
|
||||
* Decodes a PublicKey message from the specified reader or buffer.
|
||||
* @param r Reader or buffer to decode from
|
||||
* @param [l] Message length if known beforehand
|
||||
* @returns PublicKey
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
public static decode(r: ($protobuf.Reader|Uint8Array), l?: number): PublicKey;
|
||||
|
||||
/**
|
||||
* Creates a PublicKey message from a plain object. Also converts values to their respective internal types.
|
||||
* @param d Plain object
|
||||
* @returns PublicKey
|
||||
*/
|
||||
public static fromObject(d: { [k: string]: any }): PublicKey;
|
||||
|
||||
/**
|
||||
* Creates a plain object from a PublicKey message. Also converts values to other types if specified.
|
||||
* @param m PublicKey
|
||||
* @param [o] Conversion options
|
||||
* @returns Plain object
|
||||
*/
|
||||
public static toObject(m: PublicKey, o?: $protobuf.IConversionOptions): { [k: string]: any };
|
||||
|
||||
/**
|
||||
* Converts this PublicKey to JSON.
|
||||
* @returns JSON object
|
||||
*/
|
||||
public toJSON(): { [k: string]: any };
|
||||
}
|
@@ -1,22 +1,371 @@
|
||||
'use strict'
|
||||
/*eslint-disable*/
|
||||
"use strict";
|
||||
|
||||
const protobuf = require('protons')
|
||||
var $protobuf = require("protobufjs/minimal");
|
||||
|
||||
module.exports = protobuf(`
|
||||
message Exchange {
|
||||
optional bytes id = 1;
|
||||
optional PublicKey pubkey = 2;
|
||||
}
|
||||
// Common aliases
|
||||
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
|
||||
|
||||
enum KeyType {
|
||||
RSA = 0;
|
||||
Ed25519 = 1;
|
||||
Secp256k1 = 2;
|
||||
ECDSA = 3;
|
||||
}
|
||||
// Exported root namespace
|
||||
var $root = $protobuf.roots["libp2p-plaintext"] || ($protobuf.roots["libp2p-plaintext"] = {});
|
||||
|
||||
message PublicKey {
|
||||
required KeyType Type = 1;
|
||||
required bytes Data = 2;
|
||||
}
|
||||
`)
|
||||
$root.Exchange = (function() {
|
||||
|
||||
/**
|
||||
* Properties of an Exchange.
|
||||
* @exports IExchange
|
||||
* @interface IExchange
|
||||
* @property {Uint8Array|null} [id] Exchange id
|
||||
* @property {IPublicKey|null} [pubkey] Exchange pubkey
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructs a new Exchange.
|
||||
* @exports Exchange
|
||||
* @classdesc Represents an Exchange.
|
||||
* @implements IExchange
|
||||
* @constructor
|
||||
* @param {IExchange=} [p] Properties to set
|
||||
*/
|
||||
function Exchange(p) {
|
||||
if (p)
|
||||
for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
|
||||
if (p[ks[i]] != null)
|
||||
this[ks[i]] = p[ks[i]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Exchange id.
|
||||
* @member {Uint8Array} id
|
||||
* @memberof Exchange
|
||||
* @instance
|
||||
*/
|
||||
Exchange.prototype.id = $util.newBuffer([]);
|
||||
|
||||
/**
|
||||
* Exchange pubkey.
|
||||
* @member {IPublicKey|null|undefined} pubkey
|
||||
* @memberof Exchange
|
||||
* @instance
|
||||
*/
|
||||
Exchange.prototype.pubkey = null;
|
||||
|
||||
/**
|
||||
* Encodes the specified Exchange message. Does not implicitly {@link Exchange.verify|verify} messages.
|
||||
* @function encode
|
||||
* @memberof Exchange
|
||||
* @static
|
||||
* @param {IExchange} m Exchange message or plain object to encode
|
||||
* @param {$protobuf.Writer} [w] Writer to encode to
|
||||
* @returns {$protobuf.Writer} Writer
|
||||
*/
|
||||
Exchange.encode = function encode(m, w) {
|
||||
if (!w)
|
||||
w = $Writer.create();
|
||||
if (m.id != null && Object.hasOwnProperty.call(m, "id"))
|
||||
w.uint32(10).bytes(m.id);
|
||||
if (m.pubkey != null && Object.hasOwnProperty.call(m, "pubkey"))
|
||||
$root.PublicKey.encode(m.pubkey, w.uint32(18).fork()).ldelim();
|
||||
return w;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decodes an Exchange message from the specified reader or buffer.
|
||||
* @function decode
|
||||
* @memberof Exchange
|
||||
* @static
|
||||
* @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
|
||||
* @param {number} [l] Message length if known beforehand
|
||||
* @returns {Exchange} Exchange
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
Exchange.decode = function decode(r, l) {
|
||||
if (!(r instanceof $Reader))
|
||||
r = $Reader.create(r);
|
||||
var c = l === undefined ? r.len : r.pos + l, m = new $root.Exchange();
|
||||
while (r.pos < c) {
|
||||
var t = r.uint32();
|
||||
switch (t >>> 3) {
|
||||
case 1:
|
||||
m.id = r.bytes();
|
||||
break;
|
||||
case 2:
|
||||
m.pubkey = $root.PublicKey.decode(r, r.uint32());
|
||||
break;
|
||||
default:
|
||||
r.skipType(t & 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an Exchange message from a plain object. Also converts values to their respective internal types.
|
||||
* @function fromObject
|
||||
* @memberof Exchange
|
||||
* @static
|
||||
* @param {Object.<string,*>} d Plain object
|
||||
* @returns {Exchange} Exchange
|
||||
*/
|
||||
Exchange.fromObject = function fromObject(d) {
|
||||
if (d instanceof $root.Exchange)
|
||||
return d;
|
||||
var m = new $root.Exchange();
|
||||
if (d.id != null) {
|
||||
if (typeof d.id === "string")
|
||||
$util.base64.decode(d.id, m.id = $util.newBuffer($util.base64.length(d.id)), 0);
|
||||
else if (d.id.length)
|
||||
m.id = d.id;
|
||||
}
|
||||
if (d.pubkey != null) {
|
||||
if (typeof d.pubkey !== "object")
|
||||
throw TypeError(".Exchange.pubkey: object expected");
|
||||
m.pubkey = $root.PublicKey.fromObject(d.pubkey);
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a plain object from an Exchange message. Also converts values to other types if specified.
|
||||
* @function toObject
|
||||
* @memberof Exchange
|
||||
* @static
|
||||
* @param {Exchange} m Exchange
|
||||
* @param {$protobuf.IConversionOptions} [o] Conversion options
|
||||
* @returns {Object.<string,*>} Plain object
|
||||
*/
|
||||
Exchange.toObject = function toObject(m, o) {
|
||||
if (!o)
|
||||
o = {};
|
||||
var d = {};
|
||||
if (o.defaults) {
|
||||
if (o.bytes === String)
|
||||
d.id = "";
|
||||
else {
|
||||
d.id = [];
|
||||
if (o.bytes !== Array)
|
||||
d.id = $util.newBuffer(d.id);
|
||||
}
|
||||
d.pubkey = null;
|
||||
}
|
||||
if (m.id != null && m.hasOwnProperty("id")) {
|
||||
d.id = o.bytes === String ? $util.base64.encode(m.id, 0, m.id.length) : o.bytes === Array ? Array.prototype.slice.call(m.id) : m.id;
|
||||
}
|
||||
if (m.pubkey != null && m.hasOwnProperty("pubkey")) {
|
||||
d.pubkey = $root.PublicKey.toObject(m.pubkey, o);
|
||||
}
|
||||
return d;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts this Exchange to JSON.
|
||||
* @function toJSON
|
||||
* @memberof Exchange
|
||||
* @instance
|
||||
* @returns {Object.<string,*>} JSON object
|
||||
*/
|
||||
Exchange.prototype.toJSON = function toJSON() {
|
||||
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
|
||||
};
|
||||
|
||||
return Exchange;
|
||||
})();
|
||||
|
||||
/**
|
||||
* KeyType enum.
|
||||
* @exports KeyType
|
||||
* @enum {number}
|
||||
* @property {number} RSA=0 RSA value
|
||||
* @property {number} Ed25519=1 Ed25519 value
|
||||
* @property {number} Secp256k1=2 Secp256k1 value
|
||||
* @property {number} ECDSA=3 ECDSA value
|
||||
*/
|
||||
$root.KeyType = (function() {
|
||||
var valuesById = {}, values = Object.create(valuesById);
|
||||
values[valuesById[0] = "RSA"] = 0;
|
||||
values[valuesById[1] = "Ed25519"] = 1;
|
||||
values[valuesById[2] = "Secp256k1"] = 2;
|
||||
values[valuesById[3] = "ECDSA"] = 3;
|
||||
return values;
|
||||
})();
|
||||
|
||||
$root.PublicKey = (function() {
|
||||
|
||||
/**
|
||||
* Properties of a PublicKey.
|
||||
* @exports IPublicKey
|
||||
* @interface IPublicKey
|
||||
* @property {KeyType|null} [Type] PublicKey Type
|
||||
* @property {Uint8Array|null} [Data] PublicKey Data
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructs a new PublicKey.
|
||||
* @exports PublicKey
|
||||
* @classdesc Represents a PublicKey.
|
||||
* @implements IPublicKey
|
||||
* @constructor
|
||||
* @param {IPublicKey=} [p] Properties to set
|
||||
*/
|
||||
function PublicKey(p) {
|
||||
if (p)
|
||||
for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
|
||||
if (p[ks[i]] != null)
|
||||
this[ks[i]] = p[ks[i]];
|
||||
}
|
||||
|
||||
/**
|
||||
* PublicKey Type.
|
||||
* @member {KeyType} Type
|
||||
* @memberof PublicKey
|
||||
* @instance
|
||||
*/
|
||||
PublicKey.prototype.Type = 0;
|
||||
|
||||
/**
|
||||
* PublicKey Data.
|
||||
* @member {Uint8Array} Data
|
||||
* @memberof PublicKey
|
||||
* @instance
|
||||
*/
|
||||
PublicKey.prototype.Data = $util.newBuffer([]);
|
||||
|
||||
/**
|
||||
* Encodes the specified PublicKey message. Does not implicitly {@link PublicKey.verify|verify} messages.
|
||||
* @function encode
|
||||
* @memberof PublicKey
|
||||
* @static
|
||||
* @param {IPublicKey} m PublicKey message or plain object to encode
|
||||
* @param {$protobuf.Writer} [w] Writer to encode to
|
||||
* @returns {$protobuf.Writer} Writer
|
||||
*/
|
||||
PublicKey.encode = function encode(m, w) {
|
||||
if (!w)
|
||||
w = $Writer.create();
|
||||
if (m.Type != null && Object.hasOwnProperty.call(m, "Type"))
|
||||
w.uint32(8).int32(m.Type);
|
||||
if (m.Data != null && Object.hasOwnProperty.call(m, "Data"))
|
||||
w.uint32(18).bytes(m.Data);
|
||||
return w;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decodes a PublicKey message from the specified reader or buffer.
|
||||
* @function decode
|
||||
* @memberof PublicKey
|
||||
* @static
|
||||
* @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
|
||||
* @param {number} [l] Message length if known beforehand
|
||||
* @returns {PublicKey} PublicKey
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
PublicKey.decode = function decode(r, l) {
|
||||
if (!(r instanceof $Reader))
|
||||
r = $Reader.create(r);
|
||||
var c = l === undefined ? r.len : r.pos + l, m = new $root.PublicKey();
|
||||
while (r.pos < c) {
|
||||
var t = r.uint32();
|
||||
switch (t >>> 3) {
|
||||
case 1:
|
||||
m.Type = r.int32();
|
||||
break;
|
||||
case 2:
|
||||
m.Data = r.bytes();
|
||||
break;
|
||||
default:
|
||||
r.skipType(t & 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a PublicKey message from a plain object. Also converts values to their respective internal types.
|
||||
* @function fromObject
|
||||
* @memberof PublicKey
|
||||
* @static
|
||||
* @param {Object.<string,*>} d Plain object
|
||||
* @returns {PublicKey} PublicKey
|
||||
*/
|
||||
PublicKey.fromObject = function fromObject(d) {
|
||||
if (d instanceof $root.PublicKey)
|
||||
return d;
|
||||
var m = new $root.PublicKey();
|
||||
switch (d.Type) {
|
||||
case "RSA":
|
||||
case 0:
|
||||
m.Type = 0;
|
||||
break;
|
||||
case "Ed25519":
|
||||
case 1:
|
||||
m.Type = 1;
|
||||
break;
|
||||
case "Secp256k1":
|
||||
case 2:
|
||||
m.Type = 2;
|
||||
break;
|
||||
case "ECDSA":
|
||||
case 3:
|
||||
m.Type = 3;
|
||||
break;
|
||||
}
|
||||
if (d.Data != null) {
|
||||
if (typeof d.Data === "string")
|
||||
$util.base64.decode(d.Data, m.Data = $util.newBuffer($util.base64.length(d.Data)), 0);
|
||||
else if (d.Data.length)
|
||||
m.Data = d.Data;
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a plain object from a PublicKey message. Also converts values to other types if specified.
|
||||
* @function toObject
|
||||
* @memberof PublicKey
|
||||
* @static
|
||||
* @param {PublicKey} m PublicKey
|
||||
* @param {$protobuf.IConversionOptions} [o] Conversion options
|
||||
* @returns {Object.<string,*>} Plain object
|
||||
*/
|
||||
PublicKey.toObject = function toObject(m, o) {
|
||||
if (!o)
|
||||
o = {};
|
||||
var d = {};
|
||||
if (o.defaults) {
|
||||
d.Type = o.enums === String ? "RSA" : 0;
|
||||
if (o.bytes === String)
|
||||
d.Data = "";
|
||||
else {
|
||||
d.Data = [];
|
||||
if (o.bytes !== Array)
|
||||
d.Data = $util.newBuffer(d.Data);
|
||||
}
|
||||
}
|
||||
if (m.Type != null && m.hasOwnProperty("Type")) {
|
||||
d.Type = o.enums === String ? $root.KeyType[m.Type] : m.Type;
|
||||
}
|
||||
if (m.Data != null && m.hasOwnProperty("Data")) {
|
||||
d.Data = o.bytes === String ? $util.base64.encode(m.Data, 0, m.Data.length) : o.bytes === Array ? Array.prototype.slice.call(m.Data) : m.Data;
|
||||
}
|
||||
return d;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts this PublicKey to JSON.
|
||||
* @function toJSON
|
||||
* @memberof PublicKey
|
||||
* @instance
|
||||
* @returns {Object.<string,*>} JSON object
|
||||
*/
|
||||
PublicKey.prototype.toJSON = function toJSON() {
|
||||
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
|
||||
};
|
||||
|
||||
return PublicKey;
|
||||
})();
|
||||
|
||||
module.exports = $root;
|
||||
|
18
src/insecure/proto.proto
Normal file
18
src/insecure/proto.proto
Normal file
@@ -0,0 +1,18 @@
|
||||
syntax = "proto3";
|
||||
|
||||
message Exchange {
|
||||
optional bytes id = 1;
|
||||
optional PublicKey pubkey = 2;
|
||||
}
|
||||
|
||||
enum KeyType {
|
||||
RSA = 0;
|
||||
Ed25519 = 1;
|
||||
Secp256k1 = 2;
|
||||
ECDSA = 3;
|
||||
}
|
||||
|
||||
message PublicKey {
|
||||
KeyType Type = 1;
|
||||
bytes Data = 2;
|
||||
}
|
@@ -1,7 +1,10 @@
|
||||
'use strict'
|
||||
|
||||
// @ts-ignore node-forge types not exported
|
||||
require('node-forge/lib/pkcs7')
|
||||
// @ts-ignore node-forge types not exported
|
||||
require('node-forge/lib/pbe')
|
||||
// @ts-ignore node-forge types not exported
|
||||
const forge = require('node-forge/lib/forge')
|
||||
const { certificateForKey, findAsync } = require('./util')
|
||||
const errcode = require('err-code')
|
||||
@@ -85,6 +88,7 @@ class CMS {
|
||||
try {
|
||||
const buf = forge.util.createBuffer(uint8ArrayToString(cmsData, 'ascii'))
|
||||
const obj = forge.asn1.fromDer(buf)
|
||||
// @ts-ignore not defined
|
||||
cms = forge.pkcs7.messageFromAsn1(obj)
|
||||
} catch (err) {
|
||||
throw errcode(new Error('Invalid CMS: ' + err.message), 'ERR_INVALID_CMS')
|
||||
@@ -93,11 +97,15 @@ class CMS {
|
||||
// Find a recipient whose key we hold. We only deal with recipient certs
|
||||
// issued by ipfs (O=ipfs).
|
||||
const recipients = cms.recipients
|
||||
// @ts-ignore cms types not defined
|
||||
.filter(r => r.issuer.find(a => a.shortName === 'O' && a.value === 'ipfs'))
|
||||
// @ts-ignore cms types not defined
|
||||
.filter(r => r.issuer.find(a => a.shortName === 'CN'))
|
||||
// @ts-ignore cms types not defined
|
||||
.map(r => {
|
||||
return {
|
||||
recipient: r,
|
||||
// @ts-ignore cms types not defined
|
||||
keyId: r.issuer.find(a => a.shortName === 'CN').value
|
||||
}
|
||||
})
|
||||
@@ -113,6 +121,7 @@ class CMS {
|
||||
})
|
||||
|
||||
if (!r) {
|
||||
// @ts-ignore cms types not defined
|
||||
const missingKeys = recipients.map(r => r.keyId)
|
||||
throw errcode(new Error('Decryption needs one of the key(s): ' + missingKeys.join(', ')), 'ERR_MISSING_KEYS', {
|
||||
missingKeys
|
||||
|
@@ -10,6 +10,7 @@ const errcode = require('err-code')
|
||||
const uint8ArrayToString = require('uint8arrays/to-string')
|
||||
const uint8ArrayFromString = require('uint8arrays/from-string')
|
||||
|
||||
// @ts-ignore node-forge sha512 types not exported
|
||||
require('node-forge/lib/sha512')
|
||||
|
||||
/**
|
||||
@@ -17,6 +18,26 @@ require('node-forge/lib/sha512')
|
||||
* @typedef {import('interface-datastore').Datastore} Datastore
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} DekOptions
|
||||
* @property {string} hash
|
||||
* @property {string} salt
|
||||
* @property {number} iterationCount
|
||||
* @property {number} keyLength
|
||||
*
|
||||
* @typedef {Object} KeychainOptions
|
||||
* @property {string} [pass]
|
||||
* @property {DekOptions} [dek]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Information about a key.
|
||||
*
|
||||
* @typedef {Object} KeyInfo
|
||||
* @property {string} id - The universally unique key id.
|
||||
* @property {string} name - The local key name.
|
||||
*/
|
||||
|
||||
const keyPrefix = '/pkcs8/'
|
||||
const infoPrefix = '/info/'
|
||||
const privates = new WeakMap()
|
||||
@@ -38,6 +59,9 @@ const defaultOptions = {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
*/
|
||||
function validateKeyName (name) {
|
||||
if (!name) return false
|
||||
if (typeof name !== 'string') return false
|
||||
@@ -85,14 +109,6 @@ function DsInfoName (name) {
|
||||
return new Key(infoPrefix + name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Information about a key.
|
||||
*
|
||||
* @typedef {Object} KeyInfo
|
||||
* @property {string} id - The universally unique key id.
|
||||
* @property {string} name - The local key name.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages the lifecycle of a key. Keys are encrypted at rest using PKCS #8.
|
||||
*
|
||||
@@ -106,7 +122,7 @@ class Keychain {
|
||||
* Creates a new instance of a key chain.
|
||||
*
|
||||
* @param {Datastore} store - where the key are.
|
||||
* @param {object} options
|
||||
* @param {KeychainOptions} options
|
||||
* @class
|
||||
*/
|
||||
constructor (store, options) {
|
||||
@@ -118,8 +134,8 @@ class Keychain {
|
||||
this.opts = mergeOptions(defaultOptions, options)
|
||||
|
||||
// Enforce NIST SP 800-132
|
||||
if (this.opts.passPhrase && this.opts.passPhrase.length < 20) {
|
||||
throw new Error('passPhrase must be least 20 characters')
|
||||
if (this.opts.pass && this.opts.pass.length < 20) {
|
||||
throw new Error('pass must be least 20 characters')
|
||||
}
|
||||
if (this.opts.dek.keyLength < NIST.minKeyLength) {
|
||||
throw new Error(`dek.keyLength must be least ${NIST.minKeyLength} bytes`)
|
||||
@@ -131,12 +147,14 @@ class Keychain {
|
||||
throw new Error(`dek.iterationCount must be least ${NIST.minIterationCount}`)
|
||||
}
|
||||
|
||||
const dek = this.opts.passPhrase ? crypto.pbkdf2(
|
||||
this.opts.passPhrase,
|
||||
this.opts.dek.salt,
|
||||
this.opts.dek.iterationCount,
|
||||
this.opts.dek.keyLength,
|
||||
this.opts.dek.hash) : ''
|
||||
const dek = this.opts.pass
|
||||
? crypto.pbkdf2(
|
||||
this.opts.pass,
|
||||
this.opts.dek.salt,
|
||||
this.opts.dek.iterationCount,
|
||||
this.opts.dek.keyLength,
|
||||
this.opts.dek.hash)
|
||||
: ''
|
||||
|
||||
privates.set(this, { dek })
|
||||
}
|
||||
|
@@ -4,7 +4,6 @@
|
||||
require('node-forge/lib/x509')
|
||||
const forge = require('node-forge/lib/forge')
|
||||
const pki = forge.pki
|
||||
exports = module.exports
|
||||
|
||||
/**
|
||||
* Gets a self-signed X.509 certificate for the key.
|
||||
@@ -17,7 +16,7 @@ exports = module.exports
|
||||
* @param {RsaPrivateKey} privateKey - The naked key
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
exports.certificateForKey = (key, privateKey) => {
|
||||
const certificateForKey = (key, privateKey) => {
|
||||
const publicKey = pki.setRsaPublicKey(privateKey.n, privateKey.e)
|
||||
const cert = pki.createCertificate()
|
||||
cert.publicKey = publicKey
|
||||
@@ -87,4 +86,7 @@ async function findAsync (array, asyncCompare) {
|
||||
return array[index]
|
||||
}
|
||||
|
||||
module.exports.findAsync = findAsync
|
||||
module.exports = {
|
||||
certificateForKey,
|
||||
findAsync
|
||||
}
|
||||
|
@@ -1,13 +1,15 @@
|
||||
// @ts-nocheck
|
||||
'use strict'
|
||||
|
||||
/** @typedef {import('../types').EventEmitterFactory} Events */
|
||||
/** @type Events */
|
||||
const EventEmitter = require('events')
|
||||
const Big = require('bignumber.js')
|
||||
const MovingAverage = require('moving-average')
|
||||
const { EventEmitter } = require('events')
|
||||
const { BigNumber: Big } = require('bignumber.js')
|
||||
const MovingAverage = require('@vascosantos/moving-average')
|
||||
const retimer = require('retimer')
|
||||
|
||||
/**
|
||||
* @typedef {import('@vascosantos/moving-average').IMovingAverage} IMovingAverage
|
||||
*/
|
||||
|
||||
class Stats extends EventEmitter {
|
||||
/**
|
||||
* A queue based manager for stat processing
|
||||
@@ -21,24 +23,30 @@ class Stats extends EventEmitter {
|
||||
|
||||
this._options = options
|
||||
this._queue = []
|
||||
this._stats = {}
|
||||
|
||||
/** @type {{ dataReceived: Big, dataSent: Big }} */
|
||||
this._stats = {
|
||||
dataReceived: Big(0),
|
||||
dataSent: Big(0)
|
||||
}
|
||||
|
||||
this._frequencyLastTime = Date.now()
|
||||
this._frequencyAccumulators = {}
|
||||
|
||||
/** @type {{ dataReceived: IMovingAverage[], dataSent: IMovingAverage[] }} */
|
||||
this._movingAverages = {}
|
||||
|
||||
this._update = this._update.bind(this)
|
||||
|
||||
const intervals = this._options.movingAverageIntervals
|
||||
|
||||
for (var i = 0; i < initialCounters.length; i++) {
|
||||
var key = initialCounters[i]
|
||||
for (let i = 0; i < initialCounters.length; i++) {
|
||||
const key = initialCounters[i]
|
||||
this._stats[key] = Big(0)
|
||||
this._movingAverages[key] = {}
|
||||
for (var k = 0; k < intervals.length; k++) {
|
||||
var interval = intervals[k]
|
||||
var ma = this._movingAverages[key][interval] = MovingAverage(interval)
|
||||
for (let k = 0; k < intervals.length; k++) {
|
||||
const interval = intervals[k]
|
||||
const ma = this._movingAverages[key][interval] = MovingAverage(interval)
|
||||
ma.push(this._frequencyLastTime, 0)
|
||||
}
|
||||
}
|
||||
@@ -72,8 +80,6 @@ class Stats extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Returns a clone of the current stats.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
get snapshot () {
|
||||
return Object.assign({}, this._stats)
|
||||
@@ -81,8 +87,6 @@ class Stats extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Returns a clone of the internal movingAverages
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
get movingAverages () {
|
||||
return Object.assign({}, this._movingAverages)
|
||||
@@ -219,9 +223,9 @@ class Stats extends EventEmitter {
|
||||
|
||||
const intervals = this._options.movingAverageIntervals
|
||||
|
||||
for (var i = 0; i < intervals.length; i++) {
|
||||
var movingAverageInterval = intervals[i]
|
||||
var movingAverage = movingAverages[movingAverageInterval]
|
||||
for (let i = 0; i < intervals.length; i++) {
|
||||
const movingAverageInterval = intervals[i]
|
||||
let movingAverage = movingAverages[movingAverageInterval]
|
||||
if (!movingAverage) {
|
||||
movingAverage = movingAverages[movingAverageInterval] = MovingAverage(movingAverageInterval)
|
||||
}
|
||||
|
@@ -1,14 +1,16 @@
|
||||
'use strict'
|
||||
|
||||
// @ts-ignore nat-api does not export types
|
||||
const NatAPI = require('@motrix/nat-api')
|
||||
const debug = require('debug')
|
||||
const { promisify } = require('es6-promisify')
|
||||
const Multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const log = Object.assign(debug('libp2p:nat'), {
|
||||
error: debug('libp2p:nat:err')
|
||||
})
|
||||
const { isBrowser } = require('ipfs-utils/src/env')
|
||||
const retry = require('p-retry')
|
||||
// @ts-ignore private-api does not export types
|
||||
const isPrivateIp = require('private-ip')
|
||||
const pkg = require('../package.json')
|
||||
const errcode = require('err-code')
|
||||
@@ -17,33 +19,39 @@ const {
|
||||
} = require('./errors')
|
||||
const isLoopback = require('libp2p-utils/src/multiaddr/is-loopback')
|
||||
|
||||
const DEFAULT_TTL = 7200
|
||||
|
||||
/**
|
||||
* @typedef {import('peer-id')} PeerId
|
||||
* @typedef {import('./transport-manager')} TransportManager
|
||||
* @typedef {import('./address-manager')} AddressManager
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} NatManagerProperties
|
||||
* @property {PeerId} peerId - The peer ID of the current node
|
||||
* @property {TransportManager} transportManager - A transport manager
|
||||
* @property {AddressManager} addressManager - An address manager
|
||||
*
|
||||
* @typedef {Object} NatManagerOptions
|
||||
* @property {boolean} enabled - Whether to enable the NAT manager
|
||||
* @property {string} [externalIp] - Pass a value to use instead of auto-detection
|
||||
* @property {string} [description] - A string value to use for the port mapping description on the gateway
|
||||
* @property {number} [ttl = DEFAULT_TTL] - How long UPnP port mappings should last for in seconds (minimum 1200)
|
||||
* @property {boolean} [keepAlive] - Whether to automatically refresh UPnP port mappings when their TTL is reached
|
||||
* @property {string} [gateway] - Pass a value to use instead of auto-detection
|
||||
* @property {object} [pmp] - PMP options
|
||||
* @property {boolean} [pmp.enabled] - Whether to enable PMP as well as UPnP
|
||||
*/
|
||||
|
||||
function highPort (min = 1024, max = 65535) {
|
||||
return Math.floor(Math.random() * (max - min + 1) + min)
|
||||
}
|
||||
|
||||
const DEFAULT_TTL = 7200
|
||||
|
||||
class NatManager {
|
||||
/**
|
||||
* @class
|
||||
* @param {object} options
|
||||
* @param {PeerId} options.peerId - The peer ID of the current node
|
||||
* @param {TransportManager} options.transportManager - A transport manager
|
||||
* @param {AddressManager} options.addressManager - An address manager
|
||||
* @param {boolean} options.enabled - Whether to enable the NAT manager
|
||||
* @param {string} [options.externalIp] - Pass a value to use instead of auto-detection
|
||||
* @param {string} [options.description] - A string value to use for the port mapping description on the gateway
|
||||
* @param {number} [options.ttl] - How long UPnP port mappings should last for in seconds (minimum 1200)
|
||||
* @param {boolean} [options.keepAlive] - Whether to automatically refresh UPnP port mappings when their TTL is reached
|
||||
* @param {string} [options.gateway] - Pass a value to use instead of auto-detection
|
||||
* @param {object} [options.pmp] - PMP options
|
||||
* @param {boolean} [options.pmp.enabled] - Whether to enable PMP as well as UPnP
|
||||
* @param {NatManagerProperties & NatManagerOptions} options
|
||||
*/
|
||||
constructor ({ peerId, addressManager, transportManager, ...options }) {
|
||||
this._peerId = peerId
|
||||
@@ -89,15 +97,18 @@ class NatManager {
|
||||
|
||||
if (!addr.isThinWaistAddress() || transport !== 'tcp') {
|
||||
// only bare tcp addresses
|
||||
// eslint-disable-next-line no-continue
|
||||
continue
|
||||
}
|
||||
|
||||
if (isLoopback(addr)) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue
|
||||
}
|
||||
|
||||
if (family !== 'ipv4') {
|
||||
if (family !== 4) {
|
||||
// ignore ipv6
|
||||
// eslint-disable-next-line no-continue
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -119,9 +130,9 @@ class NatManager {
|
||||
})
|
||||
|
||||
this._addressManager.addObservedAddr(Multiaddr.fromNodeAddress({
|
||||
family: 'IPv4',
|
||||
family: 4,
|
||||
address: publicIp,
|
||||
port: `${publicPort}`
|
||||
port: publicPort
|
||||
}, transport))
|
||||
}
|
||||
}
|
||||
@@ -133,11 +144,11 @@ class NatManager {
|
||||
|
||||
const client = new NatAPI(this._options)
|
||||
|
||||
/** @type {(...any) => any} */
|
||||
/** @type {(...any: any) => any} */
|
||||
const map = promisify(client.map.bind(client))
|
||||
/** @type {(...any) => any} */
|
||||
/** @type {(...any: any) => any} */
|
||||
const destroy = promisify(client.destroy.bind(client))
|
||||
/** @type {(...any) => any} */
|
||||
/** @type {(...any: any) => any} */
|
||||
const externalIp = promisify(client.externalIp.bind(client))
|
||||
|
||||
// these are all network operations so add a retry
|
||||
|
@@ -19,12 +19,25 @@ const filter = require('it-filter')
|
||||
const {
|
||||
setDelayedInterval,
|
||||
clearDelayedInterval
|
||||
// @ts-ignore module with no types
|
||||
} = require('set-delayed-interval')
|
||||
const PeerId = require('peer-id')
|
||||
|
||||
/**
|
||||
* @typedef {import('multiaddr')} Multiaddr
|
||||
* @typedef {import('peer-id')} PeerId
|
||||
* @typedef {import('multiaddr').Multiaddr} Multiaddr
|
||||
* @typedef {import('libp2p-interfaces/src/peer-routing/types').PeerRouting} PeerRoutingModule
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} RefreshManagerOptions
|
||||
* @property {boolean} [enabled = true] - Whether to enable the Refresh manager
|
||||
* @property {number} [bootDelay = 6e5] - Boot delay to start the Refresh Manager (in ms)
|
||||
* @property {number} [interval = 10e3] - Interval between each Refresh Manager run (in ms)
|
||||
*
|
||||
* @typedef {Object} PeerRoutingOptions
|
||||
* @property {RefreshManagerOptions} [refreshManager]
|
||||
*/
|
||||
|
||||
class PeerRouting {
|
||||
/**
|
||||
* @class
|
||||
@@ -33,6 +46,7 @@ class PeerRouting {
|
||||
constructor (libp2p) {
|
||||
this._peerId = libp2p.peerId
|
||||
this._peerStore = libp2p.peerStore
|
||||
/** @type {PeerRoutingModule[]} */
|
||||
this._routers = libp2p._modules.peerRouting || []
|
||||
|
||||
// If we have the dht, add it to the available peer routers
|
||||
@@ -95,6 +109,7 @@ class PeerRouting {
|
||||
...this._routers.map(router => [router.findPeer(id, options)])
|
||||
),
|
||||
(source) => filter(source, Boolean),
|
||||
// @ts-ignore findPeer resolves a Promise
|
||||
(source) => storeAddresses(source, this._peerStore),
|
||||
(source) => first(source)
|
||||
)
|
||||
|
@@ -6,7 +6,7 @@ const log = Object.assign(debug('libp2p:peer-store:address-book'), {
|
||||
})
|
||||
const errcode = require('err-code')
|
||||
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const PeerId = require('peer-id')
|
||||
|
||||
const Book = require('./book')
|
||||
@@ -18,7 +18,6 @@ const {
|
||||
const Envelope = require('../record/envelope')
|
||||
|
||||
/**
|
||||
* @typedef {import('multiaddr')} Multiaddr
|
||||
* @typedef {import('./')} PeerStore
|
||||
*/
|
||||
|
||||
@@ -60,7 +59,7 @@ class AddressBook extends Book {
|
||||
if (!data.addresses) {
|
||||
return []
|
||||
}
|
||||
return data.addresses.map((address) => address.multiaddr)
|
||||
return data.addresses.map((/** @type {Address} */ address) => address.multiaddr)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -230,6 +229,11 @@ class AddressBook extends Book {
|
||||
const addresses = this._toAddresses(multiaddrs)
|
||||
const id = peerId.toB58String()
|
||||
|
||||
// No addresses to be added
|
||||
if (!addresses.length) {
|
||||
return this
|
||||
}
|
||||
|
||||
const entry = this.data.get(id)
|
||||
|
||||
if (entry && entry.addresses) {
|
||||
@@ -295,17 +299,21 @@ class AddressBook extends Book {
|
||||
}
|
||||
|
||||
// create Address for each address
|
||||
/** @type {Address[]} */
|
||||
const addresses = []
|
||||
multiaddrs.forEach((addr) => {
|
||||
if (!multiaddr.isMultiaddr(addr)) {
|
||||
if (!Multiaddr.isMultiaddr(addr)) {
|
||||
log.error(`multiaddr ${addr} must be an instance of multiaddr`)
|
||||
throw errcode(new Error(`multiaddr ${addr} must be an instance of multiaddr`), ERR_INVALID_PARAMETERS)
|
||||
}
|
||||
|
||||
addresses.push({
|
||||
multiaddr: addr,
|
||||
isCertified
|
||||
})
|
||||
// Guarantee no replicates
|
||||
if (!addresses.find((a) => a.multiaddr.equals(addr))) {
|
||||
addresses.push({
|
||||
multiaddr: addr,
|
||||
isCertified
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return addresses
|
||||
|
@@ -7,6 +7,9 @@ const {
|
||||
codes: { ERR_INVALID_PARAMETERS }
|
||||
} = require('../errors')
|
||||
|
||||
/**
|
||||
* @param {any} data
|
||||
*/
|
||||
const passthrough = data => data
|
||||
|
||||
/**
|
||||
|
@@ -2,9 +2,7 @@
|
||||
|
||||
const errcode = require('err-code')
|
||||
|
||||
/** @typedef {import('../types').EventEmitterFactory} Events */
|
||||
/** @type Events */
|
||||
const EventEmitter = require('events')
|
||||
const { EventEmitter } = require('events')
|
||||
const PeerId = require('peer-id')
|
||||
|
||||
const AddressBook = require('./address-book')
|
||||
|
@@ -81,6 +81,9 @@ class MetadataBook extends Book {
|
||||
* Set data into the datastructure
|
||||
*
|
||||
* @override
|
||||
* @param {PeerId} peerId
|
||||
* @param {string} key
|
||||
* @param {Uint8Array} value
|
||||
*/
|
||||
_setValue (peerId, key, value, { emit = true } = {}) {
|
||||
const id = peerId.toB58String()
|
||||
|
@@ -5,7 +5,7 @@ const log = Object.assign(debug('libp2p:persistent-peer-store'), {
|
||||
error: debug('libp2p:persistent-peer-store:err')
|
||||
})
|
||||
const { Key } = require('interface-datastore')
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const PeerId = require('peer-id')
|
||||
|
||||
const PeerStore = require('..')
|
||||
@@ -18,13 +18,18 @@ const {
|
||||
NAMESPACE_PROTOCOL
|
||||
} = require('./consts')
|
||||
|
||||
const Addresses = require('./pb/address-book.proto')
|
||||
const Protocols = require('./pb/proto-book.proto')
|
||||
const { Addresses } = require('./pb/address-book')
|
||||
const { Protocols } = require('./pb/proto-book')
|
||||
|
||||
/**
|
||||
* @typedef {import('interface-datastore').Batch} Batch
|
||||
* @typedef {import('../address-book.js').Address} Address
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} PersistentPeerStoreProperties
|
||||
* @property {PeerId} peerId
|
||||
* @property {any} datastore
|
||||
* @property {import('interface-datastore').Datastore} datastore
|
||||
*
|
||||
* @typedef {Object} PersistentPeerStoreOptions
|
||||
* @property {number} [threshold = 5] - Number of dirty peers allowed before commit data.
|
||||
@@ -214,7 +219,7 @@ class PersistentPeerStore extends PeerStore {
|
||||
*
|
||||
* @private
|
||||
* @param {PeerId} peerId
|
||||
* @param {Object} batch
|
||||
* @param {Batch} batch
|
||||
*/
|
||||
_batchAddressBook (peerId, batch) {
|
||||
const b32key = peerId.toString()
|
||||
@@ -234,11 +239,13 @@ class PersistentPeerStore extends PeerStore {
|
||||
multiaddr: address.multiaddr.bytes,
|
||||
isCertified: address.isCertified
|
||||
})),
|
||||
certified_record: entry.record ? {
|
||||
seq: entry.record.seqNumber,
|
||||
raw: entry.record.raw
|
||||
} : undefined
|
||||
})
|
||||
certifiedRecord: entry.record
|
||||
? {
|
||||
seq: entry.record.seqNumber,
|
||||
raw: entry.record.raw
|
||||
}
|
||||
: undefined
|
||||
}).finish()
|
||||
|
||||
batch.put(key, encodedData)
|
||||
} catch (err) {
|
||||
@@ -251,7 +258,7 @@ class PersistentPeerStore extends PeerStore {
|
||||
*
|
||||
* @private
|
||||
* @param {PeerId} peerId
|
||||
* @param {Object} batch
|
||||
* @param {Batch} batch
|
||||
*/
|
||||
_batchKeyBook (peerId, batch) {
|
||||
const b32key = peerId.toString()
|
||||
@@ -277,14 +284,14 @@ class PersistentPeerStore extends PeerStore {
|
||||
*
|
||||
* @private
|
||||
* @param {PeerId} peerId
|
||||
* @param {Object} batch
|
||||
* @param {Batch} batch
|
||||
*/
|
||||
_batchMetadataBook (peerId, batch) {
|
||||
const b32key = peerId.toString()
|
||||
const dirtyMetada = this._dirtyMetadata.get(peerId.toB58String()) || []
|
||||
|
||||
try {
|
||||
dirtyMetada.forEach((dirtyKey) => {
|
||||
dirtyMetada.forEach((/** @type {string} */ dirtyKey) => {
|
||||
const key = new Key(`${NAMESPACE_METADATA}${b32key}/${dirtyKey}`)
|
||||
const dirtyValue = this.metadataBook.getValue(peerId, dirtyKey)
|
||||
|
||||
@@ -304,7 +311,7 @@ class PersistentPeerStore extends PeerStore {
|
||||
*
|
||||
* @private
|
||||
* @param {PeerId} peerId
|
||||
* @param {Object} batch
|
||||
* @param {Batch} batch
|
||||
*/
|
||||
_batchProtoBook (peerId, batch) {
|
||||
const b32key = peerId.toString()
|
||||
@@ -319,7 +326,7 @@ class PersistentPeerStore extends PeerStore {
|
||||
return
|
||||
}
|
||||
|
||||
const encodedData = Protocols.encode({ protocols })
|
||||
const encodedData = Protocols.encode({ protocols }).finish()
|
||||
|
||||
batch.put(key, encodedData)
|
||||
} catch (err) {
|
||||
@@ -351,13 +358,15 @@ class PersistentPeerStore extends PeerStore {
|
||||
peerId,
|
||||
{
|
||||
addresses: decoded.addrs.map((address) => ({
|
||||
multiaddr: multiaddr(address.multiaddr),
|
||||
multiaddr: new Multiaddr(address.multiaddr),
|
||||
isCertified: Boolean(address.isCertified)
|
||||
})),
|
||||
record: decoded.certified_record ? {
|
||||
raw: decoded.certified_record.raw,
|
||||
seqNumber: decoded.certified_record.seq
|
||||
} : undefined
|
||||
record: decoded.certifiedRecord
|
||||
? {
|
||||
raw: decoded.certifiedRecord.raw,
|
||||
seqNumber: decoded.certifiedRecord.seq
|
||||
}
|
||||
: undefined
|
||||
},
|
||||
{ emit: false })
|
||||
break
|
||||
|
198
src/peer-store/persistent/pb/address-book.d.ts
vendored
Normal file
198
src/peer-store/persistent/pb/address-book.d.ts
vendored
Normal file
@@ -0,0 +1,198 @@
|
||||
import * as $protobuf from "protobufjs";
|
||||
/** Properties of an Addresses. */
|
||||
export interface IAddresses {
|
||||
|
||||
/** Addresses addrs */
|
||||
addrs?: (Addresses.IAddress[]|null);
|
||||
|
||||
/** Addresses certifiedRecord */
|
||||
certifiedRecord?: (Addresses.ICertifiedRecord|null);
|
||||
}
|
||||
|
||||
/** Represents an Addresses. */
|
||||
export class Addresses implements IAddresses {
|
||||
|
||||
/**
|
||||
* Constructs a new Addresses.
|
||||
* @param [p] Properties to set
|
||||
*/
|
||||
constructor(p?: IAddresses);
|
||||
|
||||
/** Addresses addrs. */
|
||||
public addrs: Addresses.IAddress[];
|
||||
|
||||
/** Addresses certifiedRecord. */
|
||||
public certifiedRecord?: (Addresses.ICertifiedRecord|null);
|
||||
|
||||
/**
|
||||
* Encodes the specified Addresses message. Does not implicitly {@link Addresses.verify|verify} messages.
|
||||
* @param m Addresses message or plain object to encode
|
||||
* @param [w] Writer to encode to
|
||||
* @returns Writer
|
||||
*/
|
||||
public static encode(m: IAddresses, w?: $protobuf.Writer): $protobuf.Writer;
|
||||
|
||||
/**
|
||||
* Decodes an Addresses message from the specified reader or buffer.
|
||||
* @param r Reader or buffer to decode from
|
||||
* @param [l] Message length if known beforehand
|
||||
* @returns Addresses
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
public static decode(r: ($protobuf.Reader|Uint8Array), l?: number): Addresses;
|
||||
|
||||
/**
|
||||
* Creates an Addresses message from a plain object. Also converts values to their respective internal types.
|
||||
* @param d Plain object
|
||||
* @returns Addresses
|
||||
*/
|
||||
public static fromObject(d: { [k: string]: any }): Addresses;
|
||||
|
||||
/**
|
||||
* Creates a plain object from an Addresses message. Also converts values to other types if specified.
|
||||
* @param m Addresses
|
||||
* @param [o] Conversion options
|
||||
* @returns Plain object
|
||||
*/
|
||||
public static toObject(m: Addresses, o?: $protobuf.IConversionOptions): { [k: string]: any };
|
||||
|
||||
/**
|
||||
* Converts this Addresses to JSON.
|
||||
* @returns JSON object
|
||||
*/
|
||||
public toJSON(): { [k: string]: any };
|
||||
}
|
||||
|
||||
export namespace Addresses {
|
||||
|
||||
/** Properties of an Address. */
|
||||
interface IAddress {
|
||||
|
||||
/** Address multiaddr */
|
||||
multiaddr?: (Uint8Array|null);
|
||||
|
||||
/** Address isCertified */
|
||||
isCertified?: (boolean|null);
|
||||
}
|
||||
|
||||
/** Represents an Address. */
|
||||
class Address implements IAddress {
|
||||
|
||||
/**
|
||||
* Constructs a new Address.
|
||||
* @param [p] Properties to set
|
||||
*/
|
||||
constructor(p?: Addresses.IAddress);
|
||||
|
||||
/** Address multiaddr. */
|
||||
public multiaddr: Uint8Array;
|
||||
|
||||
/** Address isCertified. */
|
||||
public isCertified: boolean;
|
||||
|
||||
/**
|
||||
* Encodes the specified Address message. Does not implicitly {@link Addresses.Address.verify|verify} messages.
|
||||
* @param m Address message or plain object to encode
|
||||
* @param [w] Writer to encode to
|
||||
* @returns Writer
|
||||
*/
|
||||
public static encode(m: Addresses.IAddress, w?: $protobuf.Writer): $protobuf.Writer;
|
||||
|
||||
/**
|
||||
* Decodes an Address message from the specified reader or buffer.
|
||||
* @param r Reader or buffer to decode from
|
||||
* @param [l] Message length if known beforehand
|
||||
* @returns Address
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
public static decode(r: ($protobuf.Reader|Uint8Array), l?: number): Addresses.Address;
|
||||
|
||||
/**
|
||||
* Creates an Address message from a plain object. Also converts values to their respective internal types.
|
||||
* @param d Plain object
|
||||
* @returns Address
|
||||
*/
|
||||
public static fromObject(d: { [k: string]: any }): Addresses.Address;
|
||||
|
||||
/**
|
||||
* Creates a plain object from an Address message. Also converts values to other types if specified.
|
||||
* @param m Address
|
||||
* @param [o] Conversion options
|
||||
* @returns Plain object
|
||||
*/
|
||||
public static toObject(m: Addresses.Address, o?: $protobuf.IConversionOptions): { [k: string]: any };
|
||||
|
||||
/**
|
||||
* Converts this Address to JSON.
|
||||
* @returns JSON object
|
||||
*/
|
||||
public toJSON(): { [k: string]: any };
|
||||
}
|
||||
|
||||
/** Properties of a CertifiedRecord. */
|
||||
interface ICertifiedRecord {
|
||||
|
||||
/** CertifiedRecord seq */
|
||||
seq?: (number|null);
|
||||
|
||||
/** CertifiedRecord raw */
|
||||
raw?: (Uint8Array|null);
|
||||
}
|
||||
|
||||
/** Represents a CertifiedRecord. */
|
||||
class CertifiedRecord implements ICertifiedRecord {
|
||||
|
||||
/**
|
||||
* Constructs a new CertifiedRecord.
|
||||
* @param [p] Properties to set
|
||||
*/
|
||||
constructor(p?: Addresses.ICertifiedRecord);
|
||||
|
||||
/** CertifiedRecord seq. */
|
||||
public seq: number;
|
||||
|
||||
/** CertifiedRecord raw. */
|
||||
public raw: Uint8Array;
|
||||
|
||||
/**
|
||||
* Encodes the specified CertifiedRecord message. Does not implicitly {@link Addresses.CertifiedRecord.verify|verify} messages.
|
||||
* @param m CertifiedRecord message or plain object to encode
|
||||
* @param [w] Writer to encode to
|
||||
* @returns Writer
|
||||
*/
|
||||
public static encode(m: Addresses.ICertifiedRecord, w?: $protobuf.Writer): $protobuf.Writer;
|
||||
|
||||
/**
|
||||
* Decodes a CertifiedRecord message from the specified reader or buffer.
|
||||
* @param r Reader or buffer to decode from
|
||||
* @param [l] Message length if known beforehand
|
||||
* @returns CertifiedRecord
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
public static decode(r: ($protobuf.Reader|Uint8Array), l?: number): Addresses.CertifiedRecord;
|
||||
|
||||
/**
|
||||
* Creates a CertifiedRecord message from a plain object. Also converts values to their respective internal types.
|
||||
* @param d Plain object
|
||||
* @returns CertifiedRecord
|
||||
*/
|
||||
public static fromObject(d: { [k: string]: any }): Addresses.CertifiedRecord;
|
||||
|
||||
/**
|
||||
* Creates a plain object from a CertifiedRecord message. Also converts values to other types if specified.
|
||||
* @param m CertifiedRecord
|
||||
* @param [o] Conversion options
|
||||
* @returns Plain object
|
||||
*/
|
||||
public static toObject(m: Addresses.CertifiedRecord, o?: $protobuf.IConversionOptions): { [k: string]: any };
|
||||
|
||||
/**
|
||||
* Converts this CertifiedRecord to JSON.
|
||||
* @returns JSON object
|
||||
*/
|
||||
public toJSON(): { [k: string]: any };
|
||||
}
|
||||
}
|
522
src/peer-store/persistent/pb/address-book.js
Normal file
522
src/peer-store/persistent/pb/address-book.js
Normal file
@@ -0,0 +1,522 @@
|
||||
/*eslint-disable*/
|
||||
"use strict";
|
||||
|
||||
var $protobuf = require("protobufjs/minimal");
|
||||
|
||||
// Common aliases
|
||||
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
|
||||
|
||||
// Exported root namespace
|
||||
var $root = $protobuf.roots["libp2p-address-book"] || ($protobuf.roots["libp2p-address-book"] = {});
|
||||
|
||||
$root.Addresses = (function() {
|
||||
|
||||
/**
|
||||
* Properties of an Addresses.
|
||||
* @exports IAddresses
|
||||
* @interface IAddresses
|
||||
* @property {Array.<Addresses.IAddress>|null} [addrs] Addresses addrs
|
||||
* @property {Addresses.ICertifiedRecord|null} [certifiedRecord] Addresses certifiedRecord
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructs a new Addresses.
|
||||
* @exports Addresses
|
||||
* @classdesc Represents an Addresses.
|
||||
* @implements IAddresses
|
||||
* @constructor
|
||||
* @param {IAddresses=} [p] Properties to set
|
||||
*/
|
||||
function Addresses(p) {
|
||||
this.addrs = [];
|
||||
if (p)
|
||||
for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
|
||||
if (p[ks[i]] != null)
|
||||
this[ks[i]] = p[ks[i]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Addresses addrs.
|
||||
* @member {Array.<Addresses.IAddress>} addrs
|
||||
* @memberof Addresses
|
||||
* @instance
|
||||
*/
|
||||
Addresses.prototype.addrs = $util.emptyArray;
|
||||
|
||||
/**
|
||||
* Addresses certifiedRecord.
|
||||
* @member {Addresses.ICertifiedRecord|null|undefined} certifiedRecord
|
||||
* @memberof Addresses
|
||||
* @instance
|
||||
*/
|
||||
Addresses.prototype.certifiedRecord = null;
|
||||
|
||||
/**
|
||||
* Encodes the specified Addresses message. Does not implicitly {@link Addresses.verify|verify} messages.
|
||||
* @function encode
|
||||
* @memberof Addresses
|
||||
* @static
|
||||
* @param {IAddresses} m Addresses message or plain object to encode
|
||||
* @param {$protobuf.Writer} [w] Writer to encode to
|
||||
* @returns {$protobuf.Writer} Writer
|
||||
*/
|
||||
Addresses.encode = function encode(m, w) {
|
||||
if (!w)
|
||||
w = $Writer.create();
|
||||
if (m.addrs != null && m.addrs.length) {
|
||||
for (var i = 0; i < m.addrs.length; ++i)
|
||||
$root.Addresses.Address.encode(m.addrs[i], w.uint32(10).fork()).ldelim();
|
||||
}
|
||||
if (m.certifiedRecord != null && Object.hasOwnProperty.call(m, "certifiedRecord"))
|
||||
$root.Addresses.CertifiedRecord.encode(m.certifiedRecord, w.uint32(18).fork()).ldelim();
|
||||
return w;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decodes an Addresses message from the specified reader or buffer.
|
||||
* @function decode
|
||||
* @memberof Addresses
|
||||
* @static
|
||||
* @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
|
||||
* @param {number} [l] Message length if known beforehand
|
||||
* @returns {Addresses} Addresses
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
Addresses.decode = function decode(r, l) {
|
||||
if (!(r instanceof $Reader))
|
||||
r = $Reader.create(r);
|
||||
var c = l === undefined ? r.len : r.pos + l, m = new $root.Addresses();
|
||||
while (r.pos < c) {
|
||||
var t = r.uint32();
|
||||
switch (t >>> 3) {
|
||||
case 1:
|
||||
if (!(m.addrs && m.addrs.length))
|
||||
m.addrs = [];
|
||||
m.addrs.push($root.Addresses.Address.decode(r, r.uint32()));
|
||||
break;
|
||||
case 2:
|
||||
m.certifiedRecord = $root.Addresses.CertifiedRecord.decode(r, r.uint32());
|
||||
break;
|
||||
default:
|
||||
r.skipType(t & 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an Addresses message from a plain object. Also converts values to their respective internal types.
|
||||
* @function fromObject
|
||||
* @memberof Addresses
|
||||
* @static
|
||||
* @param {Object.<string,*>} d Plain object
|
||||
* @returns {Addresses} Addresses
|
||||
*/
|
||||
Addresses.fromObject = function fromObject(d) {
|
||||
if (d instanceof $root.Addresses)
|
||||
return d;
|
||||
var m = new $root.Addresses();
|
||||
if (d.addrs) {
|
||||
if (!Array.isArray(d.addrs))
|
||||
throw TypeError(".Addresses.addrs: array expected");
|
||||
m.addrs = [];
|
||||
for (var i = 0; i < d.addrs.length; ++i) {
|
||||
if (typeof d.addrs[i] !== "object")
|
||||
throw TypeError(".Addresses.addrs: object expected");
|
||||
m.addrs[i] = $root.Addresses.Address.fromObject(d.addrs[i]);
|
||||
}
|
||||
}
|
||||
if (d.certifiedRecord != null) {
|
||||
if (typeof d.certifiedRecord !== "object")
|
||||
throw TypeError(".Addresses.certifiedRecord: object expected");
|
||||
m.certifiedRecord = $root.Addresses.CertifiedRecord.fromObject(d.certifiedRecord);
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a plain object from an Addresses message. Also converts values to other types if specified.
|
||||
* @function toObject
|
||||
* @memberof Addresses
|
||||
* @static
|
||||
* @param {Addresses} m Addresses
|
||||
* @param {$protobuf.IConversionOptions} [o] Conversion options
|
||||
* @returns {Object.<string,*>} Plain object
|
||||
*/
|
||||
Addresses.toObject = function toObject(m, o) {
|
||||
if (!o)
|
||||
o = {};
|
||||
var d = {};
|
||||
if (o.arrays || o.defaults) {
|
||||
d.addrs = [];
|
||||
}
|
||||
if (o.defaults) {
|
||||
d.certifiedRecord = null;
|
||||
}
|
||||
if (m.addrs && m.addrs.length) {
|
||||
d.addrs = [];
|
||||
for (var j = 0; j < m.addrs.length; ++j) {
|
||||
d.addrs[j] = $root.Addresses.Address.toObject(m.addrs[j], o);
|
||||
}
|
||||
}
|
||||
if (m.certifiedRecord != null && m.hasOwnProperty("certifiedRecord")) {
|
||||
d.certifiedRecord = $root.Addresses.CertifiedRecord.toObject(m.certifiedRecord, o);
|
||||
}
|
||||
return d;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts this Addresses to JSON.
|
||||
* @function toJSON
|
||||
* @memberof Addresses
|
||||
* @instance
|
||||
* @returns {Object.<string,*>} JSON object
|
||||
*/
|
||||
Addresses.prototype.toJSON = function toJSON() {
|
||||
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
|
||||
};
|
||||
|
||||
Addresses.Address = (function() {
|
||||
|
||||
/**
|
||||
* Properties of an Address.
|
||||
* @memberof Addresses
|
||||
* @interface IAddress
|
||||
* @property {Uint8Array|null} [multiaddr] Address multiaddr
|
||||
* @property {boolean|null} [isCertified] Address isCertified
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructs a new Address.
|
||||
* @memberof Addresses
|
||||
* @classdesc Represents an Address.
|
||||
* @implements IAddress
|
||||
* @constructor
|
||||
* @param {Addresses.IAddress=} [p] Properties to set
|
||||
*/
|
||||
function Address(p) {
|
||||
if (p)
|
||||
for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
|
||||
if (p[ks[i]] != null)
|
||||
this[ks[i]] = p[ks[i]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Address multiaddr.
|
||||
* @member {Uint8Array} multiaddr
|
||||
* @memberof Addresses.Address
|
||||
* @instance
|
||||
*/
|
||||
Address.prototype.multiaddr = $util.newBuffer([]);
|
||||
|
||||
/**
|
||||
* Address isCertified.
|
||||
* @member {boolean} isCertified
|
||||
* @memberof Addresses.Address
|
||||
* @instance
|
||||
*/
|
||||
Address.prototype.isCertified = false;
|
||||
|
||||
/**
|
||||
* Encodes the specified Address message. Does not implicitly {@link Addresses.Address.verify|verify} messages.
|
||||
* @function encode
|
||||
* @memberof Addresses.Address
|
||||
* @static
|
||||
* @param {Addresses.IAddress} m Address message or plain object to encode
|
||||
* @param {$protobuf.Writer} [w] Writer to encode to
|
||||
* @returns {$protobuf.Writer} Writer
|
||||
*/
|
||||
Address.encode = function encode(m, w) {
|
||||
if (!w)
|
||||
w = $Writer.create();
|
||||
if (m.multiaddr != null && Object.hasOwnProperty.call(m, "multiaddr"))
|
||||
w.uint32(10).bytes(m.multiaddr);
|
||||
if (m.isCertified != null && Object.hasOwnProperty.call(m, "isCertified"))
|
||||
w.uint32(16).bool(m.isCertified);
|
||||
return w;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decodes an Address message from the specified reader or buffer.
|
||||
* @function decode
|
||||
* @memberof Addresses.Address
|
||||
* @static
|
||||
* @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
|
||||
* @param {number} [l] Message length if known beforehand
|
||||
* @returns {Addresses.Address} Address
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
Address.decode = function decode(r, l) {
|
||||
if (!(r instanceof $Reader))
|
||||
r = $Reader.create(r);
|
||||
var c = l === undefined ? r.len : r.pos + l, m = new $root.Addresses.Address();
|
||||
while (r.pos < c) {
|
||||
var t = r.uint32();
|
||||
switch (t >>> 3) {
|
||||
case 1:
|
||||
m.multiaddr = r.bytes();
|
||||
break;
|
||||
case 2:
|
||||
m.isCertified = r.bool();
|
||||
break;
|
||||
default:
|
||||
r.skipType(t & 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an Address message from a plain object. Also converts values to their respective internal types.
|
||||
* @function fromObject
|
||||
* @memberof Addresses.Address
|
||||
* @static
|
||||
* @param {Object.<string,*>} d Plain object
|
||||
* @returns {Addresses.Address} Address
|
||||
*/
|
||||
Address.fromObject = function fromObject(d) {
|
||||
if (d instanceof $root.Addresses.Address)
|
||||
return d;
|
||||
var m = new $root.Addresses.Address();
|
||||
if (d.multiaddr != null) {
|
||||
if (typeof d.multiaddr === "string")
|
||||
$util.base64.decode(d.multiaddr, m.multiaddr = $util.newBuffer($util.base64.length(d.multiaddr)), 0);
|
||||
else if (d.multiaddr.length)
|
||||
m.multiaddr = d.multiaddr;
|
||||
}
|
||||
if (d.isCertified != null) {
|
||||
m.isCertified = Boolean(d.isCertified);
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a plain object from an Address message. Also converts values to other types if specified.
|
||||
* @function toObject
|
||||
* @memberof Addresses.Address
|
||||
* @static
|
||||
* @param {Addresses.Address} m Address
|
||||
* @param {$protobuf.IConversionOptions} [o] Conversion options
|
||||
* @returns {Object.<string,*>} Plain object
|
||||
*/
|
||||
Address.toObject = function toObject(m, o) {
|
||||
if (!o)
|
||||
o = {};
|
||||
var d = {};
|
||||
if (o.defaults) {
|
||||
if (o.bytes === String)
|
||||
d.multiaddr = "";
|
||||
else {
|
||||
d.multiaddr = [];
|
||||
if (o.bytes !== Array)
|
||||
d.multiaddr = $util.newBuffer(d.multiaddr);
|
||||
}
|
||||
d.isCertified = false;
|
||||
}
|
||||
if (m.multiaddr != null && m.hasOwnProperty("multiaddr")) {
|
||||
d.multiaddr = o.bytes === String ? $util.base64.encode(m.multiaddr, 0, m.multiaddr.length) : o.bytes === Array ? Array.prototype.slice.call(m.multiaddr) : m.multiaddr;
|
||||
}
|
||||
if (m.isCertified != null && m.hasOwnProperty("isCertified")) {
|
||||
d.isCertified = m.isCertified;
|
||||
}
|
||||
return d;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts this Address to JSON.
|
||||
* @function toJSON
|
||||
* @memberof Addresses.Address
|
||||
* @instance
|
||||
* @returns {Object.<string,*>} JSON object
|
||||
*/
|
||||
Address.prototype.toJSON = function toJSON() {
|
||||
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
|
||||
};
|
||||
|
||||
return Address;
|
||||
})();
|
||||
|
||||
Addresses.CertifiedRecord = (function() {
|
||||
|
||||
/**
|
||||
* Properties of a CertifiedRecord.
|
||||
* @memberof Addresses
|
||||
* @interface ICertifiedRecord
|
||||
* @property {number|null} [seq] CertifiedRecord seq
|
||||
* @property {Uint8Array|null} [raw] CertifiedRecord raw
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructs a new CertifiedRecord.
|
||||
* @memberof Addresses
|
||||
* @classdesc Represents a CertifiedRecord.
|
||||
* @implements ICertifiedRecord
|
||||
* @constructor
|
||||
* @param {Addresses.ICertifiedRecord=} [p] Properties to set
|
||||
*/
|
||||
function CertifiedRecord(p) {
|
||||
if (p)
|
||||
for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
|
||||
if (p[ks[i]] != null)
|
||||
this[ks[i]] = p[ks[i]];
|
||||
}
|
||||
|
||||
/**
|
||||
* CertifiedRecord seq.
|
||||
* @member {number} seq
|
||||
* @memberof Addresses.CertifiedRecord
|
||||
* @instance
|
||||
*/
|
||||
CertifiedRecord.prototype.seq = $util.Long ? $util.Long.fromBits(0,0,true) : 0;
|
||||
|
||||
/**
|
||||
* CertifiedRecord raw.
|
||||
* @member {Uint8Array} raw
|
||||
* @memberof Addresses.CertifiedRecord
|
||||
* @instance
|
||||
*/
|
||||
CertifiedRecord.prototype.raw = $util.newBuffer([]);
|
||||
|
||||
/**
|
||||
* Encodes the specified CertifiedRecord message. Does not implicitly {@link Addresses.CertifiedRecord.verify|verify} messages.
|
||||
* @function encode
|
||||
* @memberof Addresses.CertifiedRecord
|
||||
* @static
|
||||
* @param {Addresses.ICertifiedRecord} m CertifiedRecord message or plain object to encode
|
||||
* @param {$protobuf.Writer} [w] Writer to encode to
|
||||
* @returns {$protobuf.Writer} Writer
|
||||
*/
|
||||
CertifiedRecord.encode = function encode(m, w) {
|
||||
if (!w)
|
||||
w = $Writer.create();
|
||||
if (m.seq != null && Object.hasOwnProperty.call(m, "seq"))
|
||||
w.uint32(8).uint64(m.seq);
|
||||
if (m.raw != null && Object.hasOwnProperty.call(m, "raw"))
|
||||
w.uint32(18).bytes(m.raw);
|
||||
return w;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decodes a CertifiedRecord message from the specified reader or buffer.
|
||||
* @function decode
|
||||
* @memberof Addresses.CertifiedRecord
|
||||
* @static
|
||||
* @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
|
||||
* @param {number} [l] Message length if known beforehand
|
||||
* @returns {Addresses.CertifiedRecord} CertifiedRecord
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
CertifiedRecord.decode = function decode(r, l) {
|
||||
if (!(r instanceof $Reader))
|
||||
r = $Reader.create(r);
|
||||
var c = l === undefined ? r.len : r.pos + l, m = new $root.Addresses.CertifiedRecord();
|
||||
while (r.pos < c) {
|
||||
var t = r.uint32();
|
||||
switch (t >>> 3) {
|
||||
case 1:
|
||||
m.seq = r.uint64();
|
||||
break;
|
||||
case 2:
|
||||
m.raw = r.bytes();
|
||||
break;
|
||||
default:
|
||||
r.skipType(t & 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a CertifiedRecord message from a plain object. Also converts values to their respective internal types.
|
||||
* @function fromObject
|
||||
* @memberof Addresses.CertifiedRecord
|
||||
* @static
|
||||
* @param {Object.<string,*>} d Plain object
|
||||
* @returns {Addresses.CertifiedRecord} CertifiedRecord
|
||||
*/
|
||||
CertifiedRecord.fromObject = function fromObject(d) {
|
||||
if (d instanceof $root.Addresses.CertifiedRecord)
|
||||
return d;
|
||||
var m = new $root.Addresses.CertifiedRecord();
|
||||
if (d.seq != null) {
|
||||
if ($util.Long)
|
||||
(m.seq = $util.Long.fromValue(d.seq)).unsigned = true;
|
||||
else if (typeof d.seq === "string")
|
||||
m.seq = parseInt(d.seq, 10);
|
||||
else if (typeof d.seq === "number")
|
||||
m.seq = d.seq;
|
||||
else if (typeof d.seq === "object")
|
||||
m.seq = new $util.LongBits(d.seq.low >>> 0, d.seq.high >>> 0).toNumber(true);
|
||||
}
|
||||
if (d.raw != null) {
|
||||
if (typeof d.raw === "string")
|
||||
$util.base64.decode(d.raw, m.raw = $util.newBuffer($util.base64.length(d.raw)), 0);
|
||||
else if (d.raw.length)
|
||||
m.raw = d.raw;
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a plain object from a CertifiedRecord message. Also converts values to other types if specified.
|
||||
* @function toObject
|
||||
* @memberof Addresses.CertifiedRecord
|
||||
* @static
|
||||
* @param {Addresses.CertifiedRecord} m CertifiedRecord
|
||||
* @param {$protobuf.IConversionOptions} [o] Conversion options
|
||||
* @returns {Object.<string,*>} Plain object
|
||||
*/
|
||||
CertifiedRecord.toObject = function toObject(m, o) {
|
||||
if (!o)
|
||||
o = {};
|
||||
var d = {};
|
||||
if (o.defaults) {
|
||||
if ($util.Long) {
|
||||
var n = new $util.Long(0, 0, true);
|
||||
d.seq = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
|
||||
} else
|
||||
d.seq = o.longs === String ? "0" : 0;
|
||||
if (o.bytes === String)
|
||||
d.raw = "";
|
||||
else {
|
||||
d.raw = [];
|
||||
if (o.bytes !== Array)
|
||||
d.raw = $util.newBuffer(d.raw);
|
||||
}
|
||||
}
|
||||
if (m.seq != null && m.hasOwnProperty("seq")) {
|
||||
if (typeof m.seq === "number")
|
||||
d.seq = o.longs === String ? String(m.seq) : m.seq;
|
||||
else
|
||||
d.seq = o.longs === String ? $util.Long.prototype.toString.call(m.seq) : o.longs === Number ? new $util.LongBits(m.seq.low >>> 0, m.seq.high >>> 0).toNumber(true) : m.seq;
|
||||
}
|
||||
if (m.raw != null && m.hasOwnProperty("raw")) {
|
||||
d.raw = o.bytes === String ? $util.base64.encode(m.raw, 0, m.raw.length) : o.bytes === Array ? Array.prototype.slice.call(m.raw) : m.raw;
|
||||
}
|
||||
return d;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts this CertifiedRecord to JSON.
|
||||
* @function toJSON
|
||||
* @memberof Addresses.CertifiedRecord
|
||||
* @instance
|
||||
* @returns {Object.<string,*>} JSON object
|
||||
*/
|
||||
CertifiedRecord.prototype.toJSON = function toJSON() {
|
||||
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
|
||||
};
|
||||
|
||||
return CertifiedRecord;
|
||||
})();
|
||||
|
||||
return Addresses;
|
||||
})();
|
||||
|
||||
module.exports = $root;
|
@@ -1,12 +1,9 @@
|
||||
'use strict'
|
||||
syntax = "proto3";
|
||||
|
||||
const protons = require('protons')
|
||||
|
||||
const message = `
|
||||
message Addresses {
|
||||
// Address represents a single multiaddr.
|
||||
message Address {
|
||||
required bytes multiaddr = 1;
|
||||
bytes multiaddr = 1;
|
||||
|
||||
// Flag to indicate if the address comes from a certified source.
|
||||
optional bool isCertified = 2;
|
||||
@@ -27,7 +24,4 @@ message Addresses {
|
||||
|
||||
// The most recently received signed PeerRecord.
|
||||
CertifiedRecord certified_record = 2;
|
||||
}
|
||||
`
|
||||
|
||||
module.exports = protons(message).Addresses
|
||||
}
|
59
src/peer-store/persistent/pb/proto-book.d.ts
vendored
Normal file
59
src/peer-store/persistent/pb/proto-book.d.ts
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
import * as $protobuf from "protobufjs";
|
||||
/** Properties of a Protocols. */
|
||||
export interface IProtocols {
|
||||
|
||||
/** Protocols protocols */
|
||||
protocols?: (string[]|null);
|
||||
}
|
||||
|
||||
/** Represents a Protocols. */
|
||||
export class Protocols implements IProtocols {
|
||||
|
||||
/**
|
||||
* Constructs a new Protocols.
|
||||
* @param [p] Properties to set
|
||||
*/
|
||||
constructor(p?: IProtocols);
|
||||
|
||||
/** Protocols protocols. */
|
||||
public protocols: string[];
|
||||
|
||||
/**
|
||||
* Encodes the specified Protocols message. Does not implicitly {@link Protocols.verify|verify} messages.
|
||||
* @param m Protocols message or plain object to encode
|
||||
* @param [w] Writer to encode to
|
||||
* @returns Writer
|
||||
*/
|
||||
public static encode(m: IProtocols, w?: $protobuf.Writer): $protobuf.Writer;
|
||||
|
||||
/**
|
||||
* Decodes a Protocols message from the specified reader or buffer.
|
||||
* @param r Reader or buffer to decode from
|
||||
* @param [l] Message length if known beforehand
|
||||
* @returns Protocols
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
public static decode(r: ($protobuf.Reader|Uint8Array), l?: number): Protocols;
|
||||
|
||||
/**
|
||||
* Creates a Protocols message from a plain object. Also converts values to their respective internal types.
|
||||
* @param d Plain object
|
||||
* @returns Protocols
|
||||
*/
|
||||
public static fromObject(d: { [k: string]: any }): Protocols;
|
||||
|
||||
/**
|
||||
* Creates a plain object from a Protocols message. Also converts values to other types if specified.
|
||||
* @param m Protocols
|
||||
* @param [o] Conversion options
|
||||
* @returns Plain object
|
||||
*/
|
||||
public static toObject(m: Protocols, o?: $protobuf.IConversionOptions): { [k: string]: any };
|
||||
|
||||
/**
|
||||
* Converts this Protocols to JSON.
|
||||
* @returns JSON object
|
||||
*/
|
||||
public toJSON(): { [k: string]: any };
|
||||
}
|
157
src/peer-store/persistent/pb/proto-book.js
Normal file
157
src/peer-store/persistent/pb/proto-book.js
Normal file
@@ -0,0 +1,157 @@
|
||||
/*eslint-disable*/
|
||||
"use strict";
|
||||
|
||||
var $protobuf = require("protobufjs/minimal");
|
||||
|
||||
// Common aliases
|
||||
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
|
||||
|
||||
// Exported root namespace
|
||||
var $root = $protobuf.roots["libp2p-proto-book"] || ($protobuf.roots["libp2p-proto-book"] = {});
|
||||
|
||||
$root.Protocols = (function() {
|
||||
|
||||
/**
|
||||
* Properties of a Protocols.
|
||||
* @exports IProtocols
|
||||
* @interface IProtocols
|
||||
* @property {Array.<string>|null} [protocols] Protocols protocols
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructs a new Protocols.
|
||||
* @exports Protocols
|
||||
* @classdesc Represents a Protocols.
|
||||
* @implements IProtocols
|
||||
* @constructor
|
||||
* @param {IProtocols=} [p] Properties to set
|
||||
*/
|
||||
function Protocols(p) {
|
||||
this.protocols = [];
|
||||
if (p)
|
||||
for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
|
||||
if (p[ks[i]] != null)
|
||||
this[ks[i]] = p[ks[i]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Protocols protocols.
|
||||
* @member {Array.<string>} protocols
|
||||
* @memberof Protocols
|
||||
* @instance
|
||||
*/
|
||||
Protocols.prototype.protocols = $util.emptyArray;
|
||||
|
||||
/**
|
||||
* Encodes the specified Protocols message. Does not implicitly {@link Protocols.verify|verify} messages.
|
||||
* @function encode
|
||||
* @memberof Protocols
|
||||
* @static
|
||||
* @param {IProtocols} m Protocols message or plain object to encode
|
||||
* @param {$protobuf.Writer} [w] Writer to encode to
|
||||
* @returns {$protobuf.Writer} Writer
|
||||
*/
|
||||
Protocols.encode = function encode(m, w) {
|
||||
if (!w)
|
||||
w = $Writer.create();
|
||||
if (m.protocols != null && m.protocols.length) {
|
||||
for (var i = 0; i < m.protocols.length; ++i)
|
||||
w.uint32(10).string(m.protocols[i]);
|
||||
}
|
||||
return w;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decodes a Protocols message from the specified reader or buffer.
|
||||
* @function decode
|
||||
* @memberof Protocols
|
||||
* @static
|
||||
* @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
|
||||
* @param {number} [l] Message length if known beforehand
|
||||
* @returns {Protocols} Protocols
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
Protocols.decode = function decode(r, l) {
|
||||
if (!(r instanceof $Reader))
|
||||
r = $Reader.create(r);
|
||||
var c = l === undefined ? r.len : r.pos + l, m = new $root.Protocols();
|
||||
while (r.pos < c) {
|
||||
var t = r.uint32();
|
||||
switch (t >>> 3) {
|
||||
case 1:
|
||||
if (!(m.protocols && m.protocols.length))
|
||||
m.protocols = [];
|
||||
m.protocols.push(r.string());
|
||||
break;
|
||||
default:
|
||||
r.skipType(t & 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a Protocols message from a plain object. Also converts values to their respective internal types.
|
||||
* @function fromObject
|
||||
* @memberof Protocols
|
||||
* @static
|
||||
* @param {Object.<string,*>} d Plain object
|
||||
* @returns {Protocols} Protocols
|
||||
*/
|
||||
Protocols.fromObject = function fromObject(d) {
|
||||
if (d instanceof $root.Protocols)
|
||||
return d;
|
||||
var m = new $root.Protocols();
|
||||
if (d.protocols) {
|
||||
if (!Array.isArray(d.protocols))
|
||||
throw TypeError(".Protocols.protocols: array expected");
|
||||
m.protocols = [];
|
||||
for (var i = 0; i < d.protocols.length; ++i) {
|
||||
m.protocols[i] = String(d.protocols[i]);
|
||||
}
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a plain object from a Protocols message. Also converts values to other types if specified.
|
||||
* @function toObject
|
||||
* @memberof Protocols
|
||||
* @static
|
||||
* @param {Protocols} m Protocols
|
||||
* @param {$protobuf.IConversionOptions} [o] Conversion options
|
||||
* @returns {Object.<string,*>} Plain object
|
||||
*/
|
||||
Protocols.toObject = function toObject(m, o) {
|
||||
if (!o)
|
||||
o = {};
|
||||
var d = {};
|
||||
if (o.arrays || o.defaults) {
|
||||
d.protocols = [];
|
||||
}
|
||||
if (m.protocols && m.protocols.length) {
|
||||
d.protocols = [];
|
||||
for (var j = 0; j < m.protocols.length; ++j) {
|
||||
d.protocols[j] = m.protocols[j];
|
||||
}
|
||||
}
|
||||
return d;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts this Protocols to JSON.
|
||||
* @function toJSON
|
||||
* @memberof Protocols
|
||||
* @instance
|
||||
* @returns {Object.<string,*>} JSON object
|
||||
*/
|
||||
Protocols.prototype.toJSON = function toJSON() {
|
||||
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
|
||||
};
|
||||
|
||||
return Protocols;
|
||||
})();
|
||||
|
||||
module.exports = $root;
|
5
src/peer-store/persistent/pb/proto-book.proto
Normal file
5
src/peer-store/persistent/pb/proto-book.proto
Normal file
@@ -0,0 +1,5 @@
|
||||
syntax = "proto3";
|
||||
|
||||
message Protocols {
|
||||
repeated string protocols = 1;
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const protons = require('protons')
|
||||
|
||||
/* eslint-disable no-tabs */
|
||||
const message = `
|
||||
message Protocols {
|
||||
repeated string protocols = 1;
|
||||
}
|
||||
`
|
||||
|
||||
module.exports = protons(message).Protocols
|
@@ -74,6 +74,10 @@ class ProtoBook extends Book {
|
||||
const recSet = this.data.get(id)
|
||||
const newSet = new Set(protocols)
|
||||
|
||||
/**
|
||||
* @param {Set<string>} a
|
||||
* @param {Set<string>} b
|
||||
*/
|
||||
const isSetEqual = (a, b) => a.size === b.size && [...a].every(value => b.has(value))
|
||||
|
||||
// Already knows the peer and the recorded protocols are the same?
|
||||
|
@@ -8,6 +8,7 @@ const errCode = require('err-code')
|
||||
|
||||
const crypto = require('libp2p-crypto')
|
||||
const { pipe } = require('it-pipe')
|
||||
// @ts-ignore it-buffer has no types exported
|
||||
const { toBuffer } = require('it-buffer')
|
||||
const { collect, take } = require('streaming-iterables')
|
||||
const equals = require('uint8arrays/equals')
|
||||
@@ -16,8 +17,9 @@ const { PROTOCOL, PING_LENGTH } = require('./constants')
|
||||
|
||||
/**
|
||||
* @typedef {import('../')} Libp2p
|
||||
* @typedef {import('multiaddr')} Multiaddr
|
||||
* @typedef {import('multiaddr').Multiaddr} Multiaddr
|
||||
* @typedef {import('peer-id')} PeerId
|
||||
* @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -31,7 +33,8 @@ async function ping (node, peer) {
|
||||
// @ts-ignore multiaddr might not have toB58String
|
||||
log('dialing %s to %s', PROTOCOL, peer.toB58String ? peer.toB58String() : peer)
|
||||
|
||||
const { stream } = await node.dialProtocol(peer, PROTOCOL)
|
||||
const connection = await node.dial(peer)
|
||||
const { stream } = await connection.newStream(PROTOCOL)
|
||||
|
||||
const start = Date.now()
|
||||
const data = crypto.randomBytes(PING_LENGTH)
|
||||
@@ -39,7 +42,7 @@ async function ping (node, peer) {
|
||||
const [result] = await pipe(
|
||||
[data],
|
||||
stream,
|
||||
stream => take(1, stream),
|
||||
(/** @type {MuxedStream} */ stream) => take(1, stream),
|
||||
toBuffer,
|
||||
collect
|
||||
)
|
||||
|
@@ -3,11 +3,16 @@
|
||||
const crypto = require('libp2p-crypto')
|
||||
const constants = require('./constants')
|
||||
|
||||
exports = module.exports
|
||||
|
||||
exports.rnd = (length) => {
|
||||
/**
|
||||
* @param {number} length
|
||||
*/
|
||||
function rnd (length) {
|
||||
if (!length) {
|
||||
length = constants.PING_LENGTH
|
||||
}
|
||||
return crypto.randomBytes(length)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
rnd
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ const log = Object.assign(debug('libp2p:pnet'), {
|
||||
})
|
||||
|
||||
const Errors = require('./errors')
|
||||
// @ts-ignore xsalsa20 has no types exported
|
||||
const xsalsa20 = require('xsalsa20')
|
||||
const KEY_LENGTH = require('./key-generator').KEY_LENGTH
|
||||
const uint8ArrayFromString = require('uint8arrays/from-string')
|
||||
@@ -21,7 +22,8 @@ const uint8ArrayToString = require('uint8arrays/to-string')
|
||||
*/
|
||||
module.exports.createBoxStream = (nonce, psk) => {
|
||||
const xor = xsalsa20(nonce, psk)
|
||||
return (source) => (async function * () {
|
||||
|
||||
return (/** @type {AsyncIterable<Uint8Array>} */ source) => (async function * () {
|
||||
for await (const chunk of source) {
|
||||
yield Uint8Array.from(xor.update(chunk.slice()))
|
||||
}
|
||||
@@ -36,7 +38,7 @@ module.exports.createBoxStream = (nonce, psk) => {
|
||||
* @returns {*} a through iterable
|
||||
*/
|
||||
module.exports.createUnboxStream = (nonce, psk) => {
|
||||
return (source) => (async function * () {
|
||||
return (/** @type {AsyncIterable<Uint8Array>} */ source) => (async function * () {
|
||||
const xor = xsalsa20(nonce, psk)
|
||||
log.trace('Decryption enabled')
|
||||
|
||||
@@ -51,7 +53,7 @@ module.exports.createUnboxStream = (nonce, psk) => {
|
||||
*
|
||||
* @param {Uint8Array} pskBuffer
|
||||
* @throws {INVALID_PSK}
|
||||
* @returns {Object} The PSK metadata (tag, codecName, psk)
|
||||
* @returns {{ tag?: string, codecName?: string, psk: Uint8Array }} The PSK metadata (tag, codecName, psk)
|
||||
*/
|
||||
module.exports.decodeV1PSK = (pskBuffer) => {
|
||||
try {
|
||||
|
@@ -6,6 +6,7 @@ const log = Object.assign(debug('libp2p:pnet'), {
|
||||
})
|
||||
const { pipe } = require('it-pipe')
|
||||
const errcode = require('err-code')
|
||||
// @ts-ignore it-pair has no types exported
|
||||
const duplexPair = require('it-pair/duplex')
|
||||
const crypto = require('libp2p-crypto')
|
||||
const Errors = require('./errors')
|
||||
@@ -17,6 +18,7 @@ const {
|
||||
createUnboxStream,
|
||||
decodeV1PSK
|
||||
} = require('./crypto')
|
||||
// @ts-ignore it-handshake has no types exported
|
||||
const handshake = require('it-handshake')
|
||||
const { NONCE_LENGTH } = require('./key-generator')
|
||||
|
||||
|
@@ -22,8 +22,12 @@ module.exports = generate
|
||||
module.exports.NONCE_LENGTH = 24
|
||||
module.exports.KEY_LENGTH = KEY_LENGTH
|
||||
|
||||
// @ts-ignore This condition will always return 'false' since the types 'Module | undefined'
|
||||
if (require.main === module) {
|
||||
// @ts-ignore
|
||||
generate(process.stdout)
|
||||
try {
|
||||
// @ts-ignore This condition will always return 'false' since the types 'Module | undefined'
|
||||
if (require.main === module) {
|
||||
// @ts-ignore
|
||||
generate(process.stdout)
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
|
@@ -1,12 +1,19 @@
|
||||
'use strict'
|
||||
|
||||
// Pubsub adapter to keep API with handlers while not removed.
|
||||
/**
|
||||
* @typedef {import('libp2p-interfaces/src/pubsub').InMessage} InMessage
|
||||
* @typedef {import('libp2p-interfaces/src/pubsub')} PubsubRouter
|
||||
*/
|
||||
|
||||
// Pubsub adapter to keep API with handlers while not removed.
|
||||
/**
|
||||
* @param {{new(...args: any[]): PubsubRouter}} PubsubRouter
|
||||
* @param {import('.')} libp2p
|
||||
* @param {{ enabled: boolean; } & import(".").PubsubLocalOptions & import("libp2p-interfaces/src/pubsub").PubsubOptions} options
|
||||
*/
|
||||
function pubsubAdapter (PubsubRouter, libp2p, options) {
|
||||
/** @type {PubsubRouter & { _subscribeAdapter: PubsubRouter['subscribe'], _unsubscribeAdapter: PubsubRouter['unsubscribe'] }} */
|
||||
// @ts-ignore we set the extra _subscribeAdapter and _unsubscribeAdapter properties afterwards
|
||||
const pubsub = new PubsubRouter(libp2p, options)
|
||||
pubsub._subscribeAdapter = pubsub.subscribe
|
||||
pubsub._unsubscribeAdapter = pubsub.unsubscribe
|
||||
|
77
src/record/envelope/envelope.d.ts
vendored
Normal file
77
src/record/envelope/envelope.d.ts
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
import * as $protobuf from "protobufjs";
|
||||
/** Properties of an Envelope. */
|
||||
export interface IEnvelope {
|
||||
|
||||
/** Envelope publicKey */
|
||||
publicKey?: (Uint8Array|null);
|
||||
|
||||
/** Envelope payloadType */
|
||||
payloadType?: (Uint8Array|null);
|
||||
|
||||
/** Envelope payload */
|
||||
payload?: (Uint8Array|null);
|
||||
|
||||
/** Envelope signature */
|
||||
signature?: (Uint8Array|null);
|
||||
}
|
||||
|
||||
/** Represents an Envelope. */
|
||||
export class Envelope implements IEnvelope {
|
||||
|
||||
/**
|
||||
* Constructs a new Envelope.
|
||||
* @param [p] Properties to set
|
||||
*/
|
||||
constructor(p?: IEnvelope);
|
||||
|
||||
/** Envelope publicKey. */
|
||||
public publicKey: Uint8Array;
|
||||
|
||||
/** Envelope payloadType. */
|
||||
public payloadType: Uint8Array;
|
||||
|
||||
/** Envelope payload. */
|
||||
public payload: Uint8Array;
|
||||
|
||||
/** Envelope signature. */
|
||||
public signature: Uint8Array;
|
||||
|
||||
/**
|
||||
* Encodes the specified Envelope message. Does not implicitly {@link Envelope.verify|verify} messages.
|
||||
* @param m Envelope message or plain object to encode
|
||||
* @param [w] Writer to encode to
|
||||
* @returns Writer
|
||||
*/
|
||||
public static encode(m: IEnvelope, w?: $protobuf.Writer): $protobuf.Writer;
|
||||
|
||||
/**
|
||||
* Decodes an Envelope message from the specified reader or buffer.
|
||||
* @param r Reader or buffer to decode from
|
||||
* @param [l] Message length if known beforehand
|
||||
* @returns Envelope
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
public static decode(r: ($protobuf.Reader|Uint8Array), l?: number): Envelope;
|
||||
|
||||
/**
|
||||
* Creates an Envelope message from a plain object. Also converts values to their respective internal types.
|
||||
* @param d Plain object
|
||||
* @returns Envelope
|
||||
*/
|
||||
public static fromObject(d: { [k: string]: any }): Envelope;
|
||||
|
||||
/**
|
||||
* Creates a plain object from an Envelope message. Also converts values to other types if specified.
|
||||
* @param m Envelope
|
||||
* @param [o] Conversion options
|
||||
* @returns Plain object
|
||||
*/
|
||||
public static toObject(m: Envelope, o?: $protobuf.IConversionOptions): { [k: string]: any };
|
||||
|
||||
/**
|
||||
* Converts this Envelope to JSON.
|
||||
* @returns JSON object
|
||||
*/
|
||||
public toJSON(): { [k: string]: any };
|
||||
}
|
243
src/record/envelope/envelope.js
Normal file
243
src/record/envelope/envelope.js
Normal file
@@ -0,0 +1,243 @@
|
||||
/*eslint-disable*/
|
||||
"use strict";
|
||||
|
||||
var $protobuf = require("protobufjs/minimal");
|
||||
|
||||
// Common aliases
|
||||
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
|
||||
|
||||
// Exported root namespace
|
||||
var $root = $protobuf.roots["libp2p-envelope"] || ($protobuf.roots["libp2p-envelope"] = {});
|
||||
|
||||
$root.Envelope = (function() {
|
||||
|
||||
/**
|
||||
* Properties of an Envelope.
|
||||
* @exports IEnvelope
|
||||
* @interface IEnvelope
|
||||
* @property {Uint8Array|null} [publicKey] Envelope publicKey
|
||||
* @property {Uint8Array|null} [payloadType] Envelope payloadType
|
||||
* @property {Uint8Array|null} [payload] Envelope payload
|
||||
* @property {Uint8Array|null} [signature] Envelope signature
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructs a new Envelope.
|
||||
* @exports Envelope
|
||||
* @classdesc Represents an Envelope.
|
||||
* @implements IEnvelope
|
||||
* @constructor
|
||||
* @param {IEnvelope=} [p] Properties to set
|
||||
*/
|
||||
function Envelope(p) {
|
||||
if (p)
|
||||
for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
|
||||
if (p[ks[i]] != null)
|
||||
this[ks[i]] = p[ks[i]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Envelope publicKey.
|
||||
* @member {Uint8Array} publicKey
|
||||
* @memberof Envelope
|
||||
* @instance
|
||||
*/
|
||||
Envelope.prototype.publicKey = $util.newBuffer([]);
|
||||
|
||||
/**
|
||||
* Envelope payloadType.
|
||||
* @member {Uint8Array} payloadType
|
||||
* @memberof Envelope
|
||||
* @instance
|
||||
*/
|
||||
Envelope.prototype.payloadType = $util.newBuffer([]);
|
||||
|
||||
/**
|
||||
* Envelope payload.
|
||||
* @member {Uint8Array} payload
|
||||
* @memberof Envelope
|
||||
* @instance
|
||||
*/
|
||||
Envelope.prototype.payload = $util.newBuffer([]);
|
||||
|
||||
/**
|
||||
* Envelope signature.
|
||||
* @member {Uint8Array} signature
|
||||
* @memberof Envelope
|
||||
* @instance
|
||||
*/
|
||||
Envelope.prototype.signature = $util.newBuffer([]);
|
||||
|
||||
/**
|
||||
* Encodes the specified Envelope message. Does not implicitly {@link Envelope.verify|verify} messages.
|
||||
* @function encode
|
||||
* @memberof Envelope
|
||||
* @static
|
||||
* @param {IEnvelope} m Envelope message or plain object to encode
|
||||
* @param {$protobuf.Writer} [w] Writer to encode to
|
||||
* @returns {$protobuf.Writer} Writer
|
||||
*/
|
||||
Envelope.encode = function encode(m, w) {
|
||||
if (!w)
|
||||
w = $Writer.create();
|
||||
if (m.publicKey != null && Object.hasOwnProperty.call(m, "publicKey"))
|
||||
w.uint32(10).bytes(m.publicKey);
|
||||
if (m.payloadType != null && Object.hasOwnProperty.call(m, "payloadType"))
|
||||
w.uint32(18).bytes(m.payloadType);
|
||||
if (m.payload != null && Object.hasOwnProperty.call(m, "payload"))
|
||||
w.uint32(26).bytes(m.payload);
|
||||
if (m.signature != null && Object.hasOwnProperty.call(m, "signature"))
|
||||
w.uint32(42).bytes(m.signature);
|
||||
return w;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decodes an Envelope message from the specified reader or buffer.
|
||||
* @function decode
|
||||
* @memberof Envelope
|
||||
* @static
|
||||
* @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
|
||||
* @param {number} [l] Message length if known beforehand
|
||||
* @returns {Envelope} Envelope
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
Envelope.decode = function decode(r, l) {
|
||||
if (!(r instanceof $Reader))
|
||||
r = $Reader.create(r);
|
||||
var c = l === undefined ? r.len : r.pos + l, m = new $root.Envelope();
|
||||
while (r.pos < c) {
|
||||
var t = r.uint32();
|
||||
switch (t >>> 3) {
|
||||
case 1:
|
||||
m.publicKey = r.bytes();
|
||||
break;
|
||||
case 2:
|
||||
m.payloadType = r.bytes();
|
||||
break;
|
||||
case 3:
|
||||
m.payload = r.bytes();
|
||||
break;
|
||||
case 5:
|
||||
m.signature = r.bytes();
|
||||
break;
|
||||
default:
|
||||
r.skipType(t & 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an Envelope message from a plain object. Also converts values to their respective internal types.
|
||||
* @function fromObject
|
||||
* @memberof Envelope
|
||||
* @static
|
||||
* @param {Object.<string,*>} d Plain object
|
||||
* @returns {Envelope} Envelope
|
||||
*/
|
||||
Envelope.fromObject = function fromObject(d) {
|
||||
if (d instanceof $root.Envelope)
|
||||
return d;
|
||||
var m = new $root.Envelope();
|
||||
if (d.publicKey != null) {
|
||||
if (typeof d.publicKey === "string")
|
||||
$util.base64.decode(d.publicKey, m.publicKey = $util.newBuffer($util.base64.length(d.publicKey)), 0);
|
||||
else if (d.publicKey.length)
|
||||
m.publicKey = d.publicKey;
|
||||
}
|
||||
if (d.payloadType != null) {
|
||||
if (typeof d.payloadType === "string")
|
||||
$util.base64.decode(d.payloadType, m.payloadType = $util.newBuffer($util.base64.length(d.payloadType)), 0);
|
||||
else if (d.payloadType.length)
|
||||
m.payloadType = d.payloadType;
|
||||
}
|
||||
if (d.payload != null) {
|
||||
if (typeof d.payload === "string")
|
||||
$util.base64.decode(d.payload, m.payload = $util.newBuffer($util.base64.length(d.payload)), 0);
|
||||
else if (d.payload.length)
|
||||
m.payload = d.payload;
|
||||
}
|
||||
if (d.signature != null) {
|
||||
if (typeof d.signature === "string")
|
||||
$util.base64.decode(d.signature, m.signature = $util.newBuffer($util.base64.length(d.signature)), 0);
|
||||
else if (d.signature.length)
|
||||
m.signature = d.signature;
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a plain object from an Envelope message. Also converts values to other types if specified.
|
||||
* @function toObject
|
||||
* @memberof Envelope
|
||||
* @static
|
||||
* @param {Envelope} m Envelope
|
||||
* @param {$protobuf.IConversionOptions} [o] Conversion options
|
||||
* @returns {Object.<string,*>} Plain object
|
||||
*/
|
||||
Envelope.toObject = function toObject(m, o) {
|
||||
if (!o)
|
||||
o = {};
|
||||
var d = {};
|
||||
if (o.defaults) {
|
||||
if (o.bytes === String)
|
||||
d.publicKey = "";
|
||||
else {
|
||||
d.publicKey = [];
|
||||
if (o.bytes !== Array)
|
||||
d.publicKey = $util.newBuffer(d.publicKey);
|
||||
}
|
||||
if (o.bytes === String)
|
||||
d.payloadType = "";
|
||||
else {
|
||||
d.payloadType = [];
|
||||
if (o.bytes !== Array)
|
||||
d.payloadType = $util.newBuffer(d.payloadType);
|
||||
}
|
||||
if (o.bytes === String)
|
||||
d.payload = "";
|
||||
else {
|
||||
d.payload = [];
|
||||
if (o.bytes !== Array)
|
||||
d.payload = $util.newBuffer(d.payload);
|
||||
}
|
||||
if (o.bytes === String)
|
||||
d.signature = "";
|
||||
else {
|
||||
d.signature = [];
|
||||
if (o.bytes !== Array)
|
||||
d.signature = $util.newBuffer(d.signature);
|
||||
}
|
||||
}
|
||||
if (m.publicKey != null && m.hasOwnProperty("publicKey")) {
|
||||
d.publicKey = o.bytes === String ? $util.base64.encode(m.publicKey, 0, m.publicKey.length) : o.bytes === Array ? Array.prototype.slice.call(m.publicKey) : m.publicKey;
|
||||
}
|
||||
if (m.payloadType != null && m.hasOwnProperty("payloadType")) {
|
||||
d.payloadType = o.bytes === String ? $util.base64.encode(m.payloadType, 0, m.payloadType.length) : o.bytes === Array ? Array.prototype.slice.call(m.payloadType) : m.payloadType;
|
||||
}
|
||||
if (m.payload != null && m.hasOwnProperty("payload")) {
|
||||
d.payload = o.bytes === String ? $util.base64.encode(m.payload, 0, m.payload.length) : o.bytes === Array ? Array.prototype.slice.call(m.payload) : m.payload;
|
||||
}
|
||||
if (m.signature != null && m.hasOwnProperty("signature")) {
|
||||
d.signature = o.bytes === String ? $util.base64.encode(m.signature, 0, m.signature.length) : o.bytes === Array ? Array.prototype.slice.call(m.signature) : m.signature;
|
||||
}
|
||||
return d;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts this Envelope to JSON.
|
||||
* @function toJSON
|
||||
* @memberof Envelope
|
||||
* @instance
|
||||
* @returns {Object.<string,*>} JSON object
|
||||
*/
|
||||
Envelope.prototype.toJSON = function toJSON() {
|
||||
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
|
||||
};
|
||||
|
||||
return Envelope;
|
||||
})();
|
||||
|
||||
module.exports = $root;
|
@@ -1,9 +1,5 @@
|
||||
'use strict'
|
||||
syntax = "proto3";
|
||||
|
||||
const protons = require('protons')
|
||||
|
||||
/** @type {{Envelope: import('../../types').MessageProto}} */
|
||||
module.exports = protons(`
|
||||
message Envelope {
|
||||
// public_key is the public key of the keypair the enclosed payload was
|
||||
// signed with.
|
||||
@@ -20,5 +16,4 @@ message Envelope {
|
||||
// the enclosed public key, over the payload, prefixing a domain string for
|
||||
// additional security.
|
||||
bytes signature = 5;
|
||||
}
|
||||
`)
|
||||
}
|
@@ -3,13 +3,14 @@
|
||||
const errCode = require('err-code')
|
||||
const uint8arraysConcat = require('uint8arrays/concat')
|
||||
const uint8arraysFromString = require('uint8arrays/from-string')
|
||||
// @ts-ignore libp2p-crypto does not support types
|
||||
const cryptoKeys = require('libp2p-crypto/src/keys')
|
||||
const PeerId = require('peer-id')
|
||||
const varint = require('varint')
|
||||
const uint8arraysEquals = require('uint8arrays/equals')
|
||||
|
||||
const { codes } = require('../../errors')
|
||||
const Protobuf = require('./envelope.proto')
|
||||
const { Envelope: Protobuf } = require('./envelope')
|
||||
|
||||
/**
|
||||
* @typedef {import('libp2p-interfaces/src/record/types').Record} Record
|
||||
@@ -49,12 +50,12 @@ class Envelope {
|
||||
|
||||
const publicKey = cryptoKeys.marshalPublicKey(this.peerId.pubKey)
|
||||
|
||||
this._marshal = Protobuf.Envelope.encode({
|
||||
public_key: publicKey,
|
||||
payload_type: this.payloadType,
|
||||
this._marshal = Protobuf.encode({
|
||||
publicKey: publicKey,
|
||||
payloadType: this.payloadType,
|
||||
payload: this.payload,
|
||||
signature: this.signature
|
||||
})
|
||||
}).finish()
|
||||
|
||||
return this._marshal
|
||||
}
|
||||
@@ -124,12 +125,12 @@ const formatSignaturePayload = (domain, payloadType, payload) => {
|
||||
* @returns {Promise<Envelope>}
|
||||
*/
|
||||
Envelope.createFromProtobuf = async (data) => {
|
||||
const envelopeData = Protobuf.Envelope.decode(data)
|
||||
const peerId = await PeerId.createFromPubKey(envelopeData.public_key)
|
||||
const envelopeData = Protobuf.decode(data)
|
||||
const peerId = await PeerId.createFromPubKey(envelopeData.publicKey)
|
||||
|
||||
return new Envelope({
|
||||
peerId,
|
||||
payloadType: envelopeData.payload_type,
|
||||
payloadType: envelopeData.payloadType,
|
||||
payload: envelopeData.payload,
|
||||
signature: envelopeData.signature
|
||||
})
|
||||
|
@@ -1,18 +1,17 @@
|
||||
'use strict'
|
||||
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const PeerId = require('peer-id')
|
||||
const arrayEquals = require('libp2p-utils/src/array-equals')
|
||||
|
||||
const Protobuf = require('./peer-record.proto')
|
||||
const { PeerRecord: Protobuf } = require('./peer-record')
|
||||
const {
|
||||
ENVELOPE_DOMAIN_PEER_RECORD,
|
||||
ENVELOPE_PAYLOAD_TYPE_PEER_RECORD
|
||||
} = require('./consts')
|
||||
|
||||
/**
|
||||
* @typedef {import('peer-id')} PeerId
|
||||
* @typedef {import('multiaddr')} Multiaddr
|
||||
* @typedef {import('../../peer-store/address-book.js').Address} Address
|
||||
* @typedef {import('libp2p-interfaces/src/record/types').Record} Record
|
||||
*/
|
||||
|
||||
@@ -52,13 +51,13 @@ class PeerRecord {
|
||||
return this._marshal
|
||||
}
|
||||
|
||||
this._marshal = Protobuf.PeerRecord.encode({
|
||||
peer_id: this.peerId.toBytes(),
|
||||
this._marshal = Protobuf.encode({
|
||||
peerId: this.peerId.toBytes(),
|
||||
seq: this.seqNumber,
|
||||
addresses: this.multiaddrs.map((m) => ({
|
||||
multiaddr: m.bytes
|
||||
}))
|
||||
})
|
||||
}).finish()
|
||||
|
||||
return this._marshal
|
||||
}
|
||||
@@ -100,12 +99,11 @@ class PeerRecord {
|
||||
* @returns {PeerRecord}
|
||||
*/
|
||||
PeerRecord.createFromProtobuf = (buf) => {
|
||||
// Decode
|
||||
const peerRecord = Protobuf.PeerRecord.decode(buf)
|
||||
const peerRecord = Protobuf.decode(buf)
|
||||
|
||||
const peerId = PeerId.createFromBytes(peerRecord.peer_id)
|
||||
const multiaddrs = (peerRecord.addresses || []).map((a) => multiaddr(a.multiaddr))
|
||||
const seqNumber = peerRecord.seq
|
||||
const peerId = PeerId.createFromBytes(peerRecord.peerId)
|
||||
const multiaddrs = (peerRecord.addresses || []).map((a) => new Multiaddr(a.multiaddr))
|
||||
const seqNumber = Number(peerRecord.seq)
|
||||
|
||||
return new PeerRecord({ peerId, multiaddrs, seqNumber })
|
||||
}
|
||||
|
133
src/record/peer-record/peer-record.d.ts
vendored
Normal file
133
src/record/peer-record/peer-record.d.ts
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
import * as $protobuf from "protobufjs";
|
||||
/** Properties of a PeerRecord. */
|
||||
export interface IPeerRecord {
|
||||
|
||||
/** PeerRecord peerId */
|
||||
peerId?: (Uint8Array|null);
|
||||
|
||||
/** PeerRecord seq */
|
||||
seq?: (number|null);
|
||||
|
||||
/** PeerRecord addresses */
|
||||
addresses?: (PeerRecord.IAddressInfo[]|null);
|
||||
}
|
||||
|
||||
/** Represents a PeerRecord. */
|
||||
export class PeerRecord implements IPeerRecord {
|
||||
|
||||
/**
|
||||
* Constructs a new PeerRecord.
|
||||
* @param [p] Properties to set
|
||||
*/
|
||||
constructor(p?: IPeerRecord);
|
||||
|
||||
/** PeerRecord peerId. */
|
||||
public peerId: Uint8Array;
|
||||
|
||||
/** PeerRecord seq. */
|
||||
public seq: number;
|
||||
|
||||
/** PeerRecord addresses. */
|
||||
public addresses: PeerRecord.IAddressInfo[];
|
||||
|
||||
/**
|
||||
* Encodes the specified PeerRecord message. Does not implicitly {@link PeerRecord.verify|verify} messages.
|
||||
* @param m PeerRecord message or plain object to encode
|
||||
* @param [w] Writer to encode to
|
||||
* @returns Writer
|
||||
*/
|
||||
public static encode(m: IPeerRecord, w?: $protobuf.Writer): $protobuf.Writer;
|
||||
|
||||
/**
|
||||
* Decodes a PeerRecord message from the specified reader or buffer.
|
||||
* @param r Reader or buffer to decode from
|
||||
* @param [l] Message length if known beforehand
|
||||
* @returns PeerRecord
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
public static decode(r: ($protobuf.Reader|Uint8Array), l?: number): PeerRecord;
|
||||
|
||||
/**
|
||||
* Creates a PeerRecord message from a plain object. Also converts values to their respective internal types.
|
||||
* @param d Plain object
|
||||
* @returns PeerRecord
|
||||
*/
|
||||
public static fromObject(d: { [k: string]: any }): PeerRecord;
|
||||
|
||||
/**
|
||||
* Creates a plain object from a PeerRecord message. Also converts values to other types if specified.
|
||||
* @param m PeerRecord
|
||||
* @param [o] Conversion options
|
||||
* @returns Plain object
|
||||
*/
|
||||
public static toObject(m: PeerRecord, o?: $protobuf.IConversionOptions): { [k: string]: any };
|
||||
|
||||
/**
|
||||
* Converts this PeerRecord to JSON.
|
||||
* @returns JSON object
|
||||
*/
|
||||
public toJSON(): { [k: string]: any };
|
||||
}
|
||||
|
||||
export namespace PeerRecord {
|
||||
|
||||
/** Properties of an AddressInfo. */
|
||||
interface IAddressInfo {
|
||||
|
||||
/** AddressInfo multiaddr */
|
||||
multiaddr?: (Uint8Array|null);
|
||||
}
|
||||
|
||||
/** Represents an AddressInfo. */
|
||||
class AddressInfo implements IAddressInfo {
|
||||
|
||||
/**
|
||||
* Constructs a new AddressInfo.
|
||||
* @param [p] Properties to set
|
||||
*/
|
||||
constructor(p?: PeerRecord.IAddressInfo);
|
||||
|
||||
/** AddressInfo multiaddr. */
|
||||
public multiaddr: Uint8Array;
|
||||
|
||||
/**
|
||||
* Encodes the specified AddressInfo message. Does not implicitly {@link PeerRecord.AddressInfo.verify|verify} messages.
|
||||
* @param m AddressInfo message or plain object to encode
|
||||
* @param [w] Writer to encode to
|
||||
* @returns Writer
|
||||
*/
|
||||
public static encode(m: PeerRecord.IAddressInfo, w?: $protobuf.Writer): $protobuf.Writer;
|
||||
|
||||
/**
|
||||
* Decodes an AddressInfo message from the specified reader or buffer.
|
||||
* @param r Reader or buffer to decode from
|
||||
* @param [l] Message length if known beforehand
|
||||
* @returns AddressInfo
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
public static decode(r: ($protobuf.Reader|Uint8Array), l?: number): PeerRecord.AddressInfo;
|
||||
|
||||
/**
|
||||
* Creates an AddressInfo message from a plain object. Also converts values to their respective internal types.
|
||||
* @param d Plain object
|
||||
* @returns AddressInfo
|
||||
*/
|
||||
public static fromObject(d: { [k: string]: any }): PeerRecord.AddressInfo;
|
||||
|
||||
/**
|
||||
* Creates a plain object from an AddressInfo message. Also converts values to other types if specified.
|
||||
* @param m AddressInfo
|
||||
* @param [o] Conversion options
|
||||
* @returns Plain object
|
||||
*/
|
||||
public static toObject(m: PeerRecord.AddressInfo, o?: $protobuf.IConversionOptions): { [k: string]: any };
|
||||
|
||||
/**
|
||||
* Converts this AddressInfo to JSON.
|
||||
* @returns JSON object
|
||||
*/
|
||||
public toJSON(): { [k: string]: any };
|
||||
}
|
||||
}
|
367
src/record/peer-record/peer-record.js
Normal file
367
src/record/peer-record/peer-record.js
Normal file
@@ -0,0 +1,367 @@
|
||||
/*eslint-disable*/
|
||||
"use strict";
|
||||
|
||||
var $protobuf = require("protobufjs/minimal");
|
||||
|
||||
// Common aliases
|
||||
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
|
||||
|
||||
// Exported root namespace
|
||||
var $root = $protobuf.roots["libp2p-peer-record"] || ($protobuf.roots["libp2p-peer-record"] = {});
|
||||
|
||||
$root.PeerRecord = (function() {
|
||||
|
||||
/**
|
||||
* Properties of a PeerRecord.
|
||||
* @exports IPeerRecord
|
||||
* @interface IPeerRecord
|
||||
* @property {Uint8Array|null} [peerId] PeerRecord peerId
|
||||
* @property {number|null} [seq] PeerRecord seq
|
||||
* @property {Array.<PeerRecord.IAddressInfo>|null} [addresses] PeerRecord addresses
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructs a new PeerRecord.
|
||||
* @exports PeerRecord
|
||||
* @classdesc Represents a PeerRecord.
|
||||
* @implements IPeerRecord
|
||||
* @constructor
|
||||
* @param {IPeerRecord=} [p] Properties to set
|
||||
*/
|
||||
function PeerRecord(p) {
|
||||
this.addresses = [];
|
||||
if (p)
|
||||
for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
|
||||
if (p[ks[i]] != null)
|
||||
this[ks[i]] = p[ks[i]];
|
||||
}
|
||||
|
||||
/**
|
||||
* PeerRecord peerId.
|
||||
* @member {Uint8Array} peerId
|
||||
* @memberof PeerRecord
|
||||
* @instance
|
||||
*/
|
||||
PeerRecord.prototype.peerId = $util.newBuffer([]);
|
||||
|
||||
/**
|
||||
* PeerRecord seq.
|
||||
* @member {number} seq
|
||||
* @memberof PeerRecord
|
||||
* @instance
|
||||
*/
|
||||
PeerRecord.prototype.seq = $util.Long ? $util.Long.fromBits(0,0,true) : 0;
|
||||
|
||||
/**
|
||||
* PeerRecord addresses.
|
||||
* @member {Array.<PeerRecord.IAddressInfo>} addresses
|
||||
* @memberof PeerRecord
|
||||
* @instance
|
||||
*/
|
||||
PeerRecord.prototype.addresses = $util.emptyArray;
|
||||
|
||||
/**
|
||||
* Encodes the specified PeerRecord message. Does not implicitly {@link PeerRecord.verify|verify} messages.
|
||||
* @function encode
|
||||
* @memberof PeerRecord
|
||||
* @static
|
||||
* @param {IPeerRecord} m PeerRecord message or plain object to encode
|
||||
* @param {$protobuf.Writer} [w] Writer to encode to
|
||||
* @returns {$protobuf.Writer} Writer
|
||||
*/
|
||||
PeerRecord.encode = function encode(m, w) {
|
||||
if (!w)
|
||||
w = $Writer.create();
|
||||
if (m.peerId != null && Object.hasOwnProperty.call(m, "peerId"))
|
||||
w.uint32(10).bytes(m.peerId);
|
||||
if (m.seq != null && Object.hasOwnProperty.call(m, "seq"))
|
||||
w.uint32(16).uint64(m.seq);
|
||||
if (m.addresses != null && m.addresses.length) {
|
||||
for (var i = 0; i < m.addresses.length; ++i)
|
||||
$root.PeerRecord.AddressInfo.encode(m.addresses[i], w.uint32(26).fork()).ldelim();
|
||||
}
|
||||
return w;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decodes a PeerRecord message from the specified reader or buffer.
|
||||
* @function decode
|
||||
* @memberof PeerRecord
|
||||
* @static
|
||||
* @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
|
||||
* @param {number} [l] Message length if known beforehand
|
||||
* @returns {PeerRecord} PeerRecord
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
PeerRecord.decode = function decode(r, l) {
|
||||
if (!(r instanceof $Reader))
|
||||
r = $Reader.create(r);
|
||||
var c = l === undefined ? r.len : r.pos + l, m = new $root.PeerRecord();
|
||||
while (r.pos < c) {
|
||||
var t = r.uint32();
|
||||
switch (t >>> 3) {
|
||||
case 1:
|
||||
m.peerId = r.bytes();
|
||||
break;
|
||||
case 2:
|
||||
m.seq = r.uint64();
|
||||
break;
|
||||
case 3:
|
||||
if (!(m.addresses && m.addresses.length))
|
||||
m.addresses = [];
|
||||
m.addresses.push($root.PeerRecord.AddressInfo.decode(r, r.uint32()));
|
||||
break;
|
||||
default:
|
||||
r.skipType(t & 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a PeerRecord message from a plain object. Also converts values to their respective internal types.
|
||||
* @function fromObject
|
||||
* @memberof PeerRecord
|
||||
* @static
|
||||
* @param {Object.<string,*>} d Plain object
|
||||
* @returns {PeerRecord} PeerRecord
|
||||
*/
|
||||
PeerRecord.fromObject = function fromObject(d) {
|
||||
if (d instanceof $root.PeerRecord)
|
||||
return d;
|
||||
var m = new $root.PeerRecord();
|
||||
if (d.peerId != null) {
|
||||
if (typeof d.peerId === "string")
|
||||
$util.base64.decode(d.peerId, m.peerId = $util.newBuffer($util.base64.length(d.peerId)), 0);
|
||||
else if (d.peerId.length)
|
||||
m.peerId = d.peerId;
|
||||
}
|
||||
if (d.seq != null) {
|
||||
if ($util.Long)
|
||||
(m.seq = $util.Long.fromValue(d.seq)).unsigned = true;
|
||||
else if (typeof d.seq === "string")
|
||||
m.seq = parseInt(d.seq, 10);
|
||||
else if (typeof d.seq === "number")
|
||||
m.seq = d.seq;
|
||||
else if (typeof d.seq === "object")
|
||||
m.seq = new $util.LongBits(d.seq.low >>> 0, d.seq.high >>> 0).toNumber(true);
|
||||
}
|
||||
if (d.addresses) {
|
||||
if (!Array.isArray(d.addresses))
|
||||
throw TypeError(".PeerRecord.addresses: array expected");
|
||||
m.addresses = [];
|
||||
for (var i = 0; i < d.addresses.length; ++i) {
|
||||
if (typeof d.addresses[i] !== "object")
|
||||
throw TypeError(".PeerRecord.addresses: object expected");
|
||||
m.addresses[i] = $root.PeerRecord.AddressInfo.fromObject(d.addresses[i]);
|
||||
}
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a plain object from a PeerRecord message. Also converts values to other types if specified.
|
||||
* @function toObject
|
||||
* @memberof PeerRecord
|
||||
* @static
|
||||
* @param {PeerRecord} m PeerRecord
|
||||
* @param {$protobuf.IConversionOptions} [o] Conversion options
|
||||
* @returns {Object.<string,*>} Plain object
|
||||
*/
|
||||
PeerRecord.toObject = function toObject(m, o) {
|
||||
if (!o)
|
||||
o = {};
|
||||
var d = {};
|
||||
if (o.arrays || o.defaults) {
|
||||
d.addresses = [];
|
||||
}
|
||||
if (o.defaults) {
|
||||
if (o.bytes === String)
|
||||
d.peerId = "";
|
||||
else {
|
||||
d.peerId = [];
|
||||
if (o.bytes !== Array)
|
||||
d.peerId = $util.newBuffer(d.peerId);
|
||||
}
|
||||
if ($util.Long) {
|
||||
var n = new $util.Long(0, 0, true);
|
||||
d.seq = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
|
||||
} else
|
||||
d.seq = o.longs === String ? "0" : 0;
|
||||
}
|
||||
if (m.peerId != null && m.hasOwnProperty("peerId")) {
|
||||
d.peerId = o.bytes === String ? $util.base64.encode(m.peerId, 0, m.peerId.length) : o.bytes === Array ? Array.prototype.slice.call(m.peerId) : m.peerId;
|
||||
}
|
||||
if (m.seq != null && m.hasOwnProperty("seq")) {
|
||||
if (typeof m.seq === "number")
|
||||
d.seq = o.longs === String ? String(m.seq) : m.seq;
|
||||
else
|
||||
d.seq = o.longs === String ? $util.Long.prototype.toString.call(m.seq) : o.longs === Number ? new $util.LongBits(m.seq.low >>> 0, m.seq.high >>> 0).toNumber(true) : m.seq;
|
||||
}
|
||||
if (m.addresses && m.addresses.length) {
|
||||
d.addresses = [];
|
||||
for (var j = 0; j < m.addresses.length; ++j) {
|
||||
d.addresses[j] = $root.PeerRecord.AddressInfo.toObject(m.addresses[j], o);
|
||||
}
|
||||
}
|
||||
return d;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts this PeerRecord to JSON.
|
||||
* @function toJSON
|
||||
* @memberof PeerRecord
|
||||
* @instance
|
||||
* @returns {Object.<string,*>} JSON object
|
||||
*/
|
||||
PeerRecord.prototype.toJSON = function toJSON() {
|
||||
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
|
||||
};
|
||||
|
||||
PeerRecord.AddressInfo = (function() {
|
||||
|
||||
/**
|
||||
* Properties of an AddressInfo.
|
||||
* @memberof PeerRecord
|
||||
* @interface IAddressInfo
|
||||
* @property {Uint8Array|null} [multiaddr] AddressInfo multiaddr
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructs a new AddressInfo.
|
||||
* @memberof PeerRecord
|
||||
* @classdesc Represents an AddressInfo.
|
||||
* @implements IAddressInfo
|
||||
* @constructor
|
||||
* @param {PeerRecord.IAddressInfo=} [p] Properties to set
|
||||
*/
|
||||
function AddressInfo(p) {
|
||||
if (p)
|
||||
for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
|
||||
if (p[ks[i]] != null)
|
||||
this[ks[i]] = p[ks[i]];
|
||||
}
|
||||
|
||||
/**
|
||||
* AddressInfo multiaddr.
|
||||
* @member {Uint8Array} multiaddr
|
||||
* @memberof PeerRecord.AddressInfo
|
||||
* @instance
|
||||
*/
|
||||
AddressInfo.prototype.multiaddr = $util.newBuffer([]);
|
||||
|
||||
/**
|
||||
* Encodes the specified AddressInfo message. Does not implicitly {@link PeerRecord.AddressInfo.verify|verify} messages.
|
||||
* @function encode
|
||||
* @memberof PeerRecord.AddressInfo
|
||||
* @static
|
||||
* @param {PeerRecord.IAddressInfo} m AddressInfo message or plain object to encode
|
||||
* @param {$protobuf.Writer} [w] Writer to encode to
|
||||
* @returns {$protobuf.Writer} Writer
|
||||
*/
|
||||
AddressInfo.encode = function encode(m, w) {
|
||||
if (!w)
|
||||
w = $Writer.create();
|
||||
if (m.multiaddr != null && Object.hasOwnProperty.call(m, "multiaddr"))
|
||||
w.uint32(10).bytes(m.multiaddr);
|
||||
return w;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decodes an AddressInfo message from the specified reader or buffer.
|
||||
* @function decode
|
||||
* @memberof PeerRecord.AddressInfo
|
||||
* @static
|
||||
* @param {$protobuf.Reader|Uint8Array} r Reader or buffer to decode from
|
||||
* @param {number} [l] Message length if known beforehand
|
||||
* @returns {PeerRecord.AddressInfo} AddressInfo
|
||||
* @throws {Error} If the payload is not a reader or valid buffer
|
||||
* @throws {$protobuf.util.ProtocolError} If required fields are missing
|
||||
*/
|
||||
AddressInfo.decode = function decode(r, l) {
|
||||
if (!(r instanceof $Reader))
|
||||
r = $Reader.create(r);
|
||||
var c = l === undefined ? r.len : r.pos + l, m = new $root.PeerRecord.AddressInfo();
|
||||
while (r.pos < c) {
|
||||
var t = r.uint32();
|
||||
switch (t >>> 3) {
|
||||
case 1:
|
||||
m.multiaddr = r.bytes();
|
||||
break;
|
||||
default:
|
||||
r.skipType(t & 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an AddressInfo message from a plain object. Also converts values to their respective internal types.
|
||||
* @function fromObject
|
||||
* @memberof PeerRecord.AddressInfo
|
||||
* @static
|
||||
* @param {Object.<string,*>} d Plain object
|
||||
* @returns {PeerRecord.AddressInfo} AddressInfo
|
||||
*/
|
||||
AddressInfo.fromObject = function fromObject(d) {
|
||||
if (d instanceof $root.PeerRecord.AddressInfo)
|
||||
return d;
|
||||
var m = new $root.PeerRecord.AddressInfo();
|
||||
if (d.multiaddr != null) {
|
||||
if (typeof d.multiaddr === "string")
|
||||
$util.base64.decode(d.multiaddr, m.multiaddr = $util.newBuffer($util.base64.length(d.multiaddr)), 0);
|
||||
else if (d.multiaddr.length)
|
||||
m.multiaddr = d.multiaddr;
|
||||
}
|
||||
return m;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a plain object from an AddressInfo message. Also converts values to other types if specified.
|
||||
* @function toObject
|
||||
* @memberof PeerRecord.AddressInfo
|
||||
* @static
|
||||
* @param {PeerRecord.AddressInfo} m AddressInfo
|
||||
* @param {$protobuf.IConversionOptions} [o] Conversion options
|
||||
* @returns {Object.<string,*>} Plain object
|
||||
*/
|
||||
AddressInfo.toObject = function toObject(m, o) {
|
||||
if (!o)
|
||||
o = {};
|
||||
var d = {};
|
||||
if (o.defaults) {
|
||||
if (o.bytes === String)
|
||||
d.multiaddr = "";
|
||||
else {
|
||||
d.multiaddr = [];
|
||||
if (o.bytes !== Array)
|
||||
d.multiaddr = $util.newBuffer(d.multiaddr);
|
||||
}
|
||||
}
|
||||
if (m.multiaddr != null && m.hasOwnProperty("multiaddr")) {
|
||||
d.multiaddr = o.bytes === String ? $util.base64.encode(m.multiaddr, 0, m.multiaddr.length) : o.bytes === Array ? Array.prototype.slice.call(m.multiaddr) : m.multiaddr;
|
||||
}
|
||||
return d;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts this AddressInfo to JSON.
|
||||
* @function toJSON
|
||||
* @memberof PeerRecord.AddressInfo
|
||||
* @instance
|
||||
* @returns {Object.<string,*>} JSON object
|
||||
*/
|
||||
AddressInfo.prototype.toJSON = function toJSON() {
|
||||
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
|
||||
};
|
||||
|
||||
return AddressInfo;
|
||||
})();
|
||||
|
||||
return PeerRecord;
|
||||
})();
|
||||
|
||||
module.exports = $root;
|
@@ -1,14 +1,5 @@
|
||||
'use strict'
|
||||
syntax = "proto3";
|
||||
|
||||
const protons = require('protons')
|
||||
|
||||
// PeerRecord messages contain information that is useful to share with other peers.
|
||||
// Currently, a PeerRecord contains the public listen addresses for a peer, but this
|
||||
// is expected to expand to include other information in the future.
|
||||
// PeerRecords are designed to be serialized to bytes and placed inside of
|
||||
// SignedEnvelopes before sharing with other peers.
|
||||
/** @type {{PeerRecord: import('../../types').MessageProto}} */
|
||||
module.exports = protons(`
|
||||
message PeerRecord {
|
||||
// AddressInfo is a wrapper around a binary multiaddr. It is defined as a
|
||||
// separate message to allow us to add per-address metadata in the future.
|
||||
@@ -24,5 +15,4 @@ message PeerRecord {
|
||||
|
||||
// addresses is a list of public listen addresses for the peer.
|
||||
repeated AddressInfo addresses = 3;
|
||||
}
|
||||
`)
|
||||
}
|
@@ -1,8 +1,8 @@
|
||||
'use strict'
|
||||
|
||||
const debug = require('debug')
|
||||
const log = Object.assign(debug('libp2p:peer-store'), {
|
||||
error: debug('libp2p:peer-store:err')
|
||||
const log = Object.assign(debug('libp2p:registrar'), {
|
||||
error: debug('libp2p:registrar:err')
|
||||
})
|
||||
const errcode = require('err-code')
|
||||
|
||||
@@ -16,7 +16,11 @@ const Topology = require('libp2p-interfaces/src/topology')
|
||||
* @typedef {import('./peer-store')} PeerStore
|
||||
* @typedef {import('./connection-manager')} ConnectionManager
|
||||
* @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
|
||||
* @typedef {import('libp2p-interfaces/src/topology')} Topology
|
||||
* @typedef {import('./').HandlerProps} HandlerProps
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -38,20 +42,28 @@ class Registrar {
|
||||
/**
|
||||
* Map of topologies
|
||||
*
|
||||
* @type {Map<string, object>}
|
||||
* @type {Map<string, Topology>}
|
||||
*/
|
||||
this.topologies = new Map()
|
||||
|
||||
/** @type {(protocols: string[]|string, handler: (props: HandlerProps) => void) => void} */
|
||||
// @ts-ignore handle is not optional
|
||||
this._handle = undefined
|
||||
|
||||
this._onDisconnect = this._onDisconnect.bind(this)
|
||||
this.connectionManager.on('peer:disconnect', this._onDisconnect)
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {(protocols: string[]|string, handler: (props: HandlerProps) => void) => void}
|
||||
*/
|
||||
get handle () {
|
||||
return this._handle
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {(protocols: string[]|string, handler: (props: HandlerProps) => void) => void} handle
|
||||
*/
|
||||
set handle (handle) {
|
||||
this._handle = handle
|
||||
}
|
||||
@@ -103,12 +115,11 @@ class Registrar {
|
||||
* Remove a disconnected peer from the record
|
||||
*
|
||||
* @param {Connection} connection
|
||||
* @param {Error} [error]
|
||||
* @returns {void}
|
||||
*/
|
||||
_onDisconnect (connection, error) {
|
||||
_onDisconnect (connection) {
|
||||
for (const [, topology] of this.topologies) {
|
||||
topology.disconnect(connection.remotePeer, error)
|
||||
topology.disconnect(connection.remotePeer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -12,10 +12,10 @@ const errCode = require('err-code')
|
||||
const { updateSelfPeerRecord } = require('./record/utils')
|
||||
|
||||
/**
|
||||
* @typedef {import('multiaddr')} Multiaddr
|
||||
* @typedef {import('multiaddr').Multiaddr} Multiaddr
|
||||
* @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
|
||||
* @typedef {import('libp2p-interfaces/src/transport/types').TransportFactory} TransportFactory
|
||||
* @typedef {import('libp2p-interfaces/src/transport/types').Transport} Transport
|
||||
* @typedef {import('libp2p-interfaces/src/transport/types').TransportFactory<any, any>} TransportFactory
|
||||
* @typedef {import('libp2p-interfaces/src/transport/types').Transport<any, any>} Transport
|
||||
*
|
||||
* @typedef {Object} TransportManagerProperties
|
||||
* @property {import('./')} libp2p
|
||||
@@ -121,6 +121,7 @@ class TransportManager {
|
||||
* @returns {Multiaddr[]}
|
||||
*/
|
||||
getAddrs () {
|
||||
/** @type {Multiaddr[]} */
|
||||
let addrs = []
|
||||
for (const listeners of this._listeners.values()) {
|
||||
for (const listener of listeners) {
|
||||
|
103
src/types.ts
103
src/types.ts
@@ -1,103 +0,0 @@
|
||||
|
||||
// Insecure Message types
|
||||
export enum KeyType {
|
||||
RSA = 0,
|
||||
Ed25519 = 1,
|
||||
Secp256k1 = 2,
|
||||
ECDSA = 3
|
||||
}
|
||||
|
||||
// Protobufs
|
||||
export type MessageProto = {
|
||||
encode(value: any): Uint8Array
|
||||
decode(bytes: Uint8Array): any
|
||||
}
|
||||
|
||||
export type SUCCESS = 100;
|
||||
export type HOP_SRC_ADDR_TOO_LONG = 220;
|
||||
export type HOP_DST_ADDR_TOO_LONG = 221;
|
||||
export type HOP_SRC_MULTIADDR_INVALID = 250;
|
||||
export type HOP_DST_MULTIADDR_INVALID = 251;
|
||||
export type HOP_NO_CONN_TO_DST = 260;
|
||||
export type HOP_CANT_DIAL_DST = 261;
|
||||
export type HOP_CANT_OPEN_DST_STREAM = 262;
|
||||
export type HOP_CANT_SPEAK_RELAY = 270;
|
||||
export type HOP_CANT_RELAY_TO_SELF = 280;
|
||||
export type STOP_SRC_ADDR_TOO_LONG = 320;
|
||||
export type STOP_DST_ADDR_TOO_LONG = 321;
|
||||
export type STOP_SRC_MULTIADDR_INVALID = 350;
|
||||
export type STOP_DST_MULTIADDR_INVALID = 351;
|
||||
export type STOP_RELAY_REFUSED = 390;
|
||||
export type MALFORMED_MESSAGE = 400;
|
||||
|
||||
export type CircuitStatus = SUCCESS | HOP_SRC_ADDR_TOO_LONG | HOP_DST_ADDR_TOO_LONG
|
||||
| HOP_SRC_MULTIADDR_INVALID | HOP_DST_MULTIADDR_INVALID | HOP_NO_CONN_TO_DST
|
||||
| HOP_CANT_DIAL_DST | HOP_CANT_OPEN_DST_STREAM | HOP_CANT_SPEAK_RELAY | HOP_CANT_RELAY_TO_SELF
|
||||
| STOP_SRC_ADDR_TOO_LONG | STOP_DST_ADDR_TOO_LONG | STOP_SRC_MULTIADDR_INVALID
|
||||
| STOP_DST_MULTIADDR_INVALID | STOP_RELAY_REFUSED | MALFORMED_MESSAGE
|
||||
|
||||
export type HOP = 1;
|
||||
export type STOP = 2;
|
||||
export type STATUS = 3;
|
||||
export type CAN_HOP = 4;
|
||||
|
||||
export type CircuitType = HOP | STOP | STATUS | CAN_HOP
|
||||
|
||||
export type CircuitPeer = {
|
||||
id: Uint8Array
|
||||
addrs: Uint8Array[]
|
||||
}
|
||||
|
||||
export type CircuitRequest = {
|
||||
type: CircuitType
|
||||
dstPeer: CircuitPeer
|
||||
srcPeer: CircuitPeer
|
||||
}
|
||||
|
||||
export type CircuitMessageProto = {
|
||||
encode(value: any): Uint8Array
|
||||
decode(bytes: Uint8Array): any
|
||||
Status: {
|
||||
SUCCESS: SUCCESS,
|
||||
HOP_SRC_ADDR_TOO_LONG: HOP_SRC_ADDR_TOO_LONG,
|
||||
HOP_DST_ADDR_TOO_LONG: HOP_DST_ADDR_TOO_LONG,
|
||||
HOP_SRC_MULTIADDR_INVALID: HOP_SRC_MULTIADDR_INVALID,
|
||||
HOP_DST_MULTIADDR_INVALID: HOP_DST_MULTIADDR_INVALID,
|
||||
HOP_NO_CONN_TO_DST: HOP_NO_CONN_TO_DST,
|
||||
HOP_CANT_DIAL_DST: HOP_CANT_DIAL_DST,
|
||||
HOP_CANT_OPEN_DST_STREAM: HOP_CANT_OPEN_DST_STREAM,
|
||||
HOP_CANT_SPEAK_RELAY: HOP_CANT_SPEAK_RELAY,
|
||||
HOP_CANT_RELAY_TO_SELF: HOP_CANT_RELAY_TO_SELF,
|
||||
STOP_SRC_ADDR_TOO_LONG: STOP_SRC_ADDR_TOO_LONG,
|
||||
STOP_DST_ADDR_TOO_LONG: STOP_DST_ADDR_TOO_LONG,
|
||||
STOP_SRC_MULTIADDR_INVALID: STOP_SRC_MULTIADDR_INVALID,
|
||||
STOP_DST_MULTIADDR_INVALID: STOP_DST_MULTIADDR_INVALID,
|
||||
STOP_RELAY_REFUSED: STOP_RELAY_REFUSED,
|
||||
MALFORMED_MESSAGE: MALFORMED_MESSAGE
|
||||
},
|
||||
Type: {
|
||||
HOP: HOP,
|
||||
STOP: STOP,
|
||||
STATUS: STATUS,
|
||||
CAN_HOP: CAN_HOP
|
||||
}
|
||||
}
|
||||
|
||||
export interface EventEmitterFactory {
|
||||
new(): EventEmitter;
|
||||
}
|
||||
|
||||
export interface EventEmitter {
|
||||
addListener(event: string | symbol, listener: (...args: any[]) => void);
|
||||
on(event: string | symbol, listener: (...args: any[]) => void);
|
||||
once(event: string | symbol, listener: (...args: any[]) => void);
|
||||
removeListener(event: string | symbol, listener: (...args: any[]) => void);
|
||||
off(event: string | symbol, listener: (...args: any[]) => void);
|
||||
removeAllListeners(event?: string | symbol);
|
||||
setMaxListeners(n: number);
|
||||
getMaxListeners(): number;
|
||||
listeners(event: string | symbol): Function[]; // eslint-disable-line @typescript-eslint/ban-types
|
||||
rawListeners(event: string | symbol): Function[]; // eslint-disable-line @typescript-eslint/ban-types
|
||||
emit(event: string | symbol, ...args: any[]): boolean;
|
||||
listenerCount(event: string | symbol): number;
|
||||
}
|
@@ -5,10 +5,12 @@ const log = Object.assign(debug('libp2p:upgrader'), {
|
||||
error: debug('libp2p:upgrader:err')
|
||||
})
|
||||
const errCode = require('err-code')
|
||||
// @ts-ignore multistream-select does not export types
|
||||
const Multistream = require('multistream-select')
|
||||
const { Connection } = require('libp2p-interfaces/src/connection')
|
||||
const PeerId = require('peer-id')
|
||||
const { pipe } = require('it-pipe')
|
||||
// @ts-ignore mutable-proxy does not export types
|
||||
const mutableProxy = require('mutable-proxy')
|
||||
|
||||
const { codes } = require('./errors')
|
||||
@@ -19,7 +21,8 @@ const { codes } = require('./errors')
|
||||
* @typedef {import('libp2p-interfaces/src/stream-muxer/types').Muxer} Muxer
|
||||
* @typedef {import('libp2p-interfaces/src/stream-muxer/types').MuxedStream} MuxedStream
|
||||
* @typedef {import('libp2p-interfaces/src/crypto/types').Crypto} Crypto
|
||||
* @typedef {import('multiaddr')} Multiaddr
|
||||
* @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
|
||||
* @typedef {import('multiaddr').Multiaddr} Multiaddr
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -36,8 +39,8 @@ class Upgrader {
|
||||
* @param {import('./metrics')} [options.metrics]
|
||||
* @param {Map<string, Crypto>} [options.cryptos]
|
||||
* @param {Map<string, MuxerFactory>} [options.muxers]
|
||||
* @param {(Connection) => void} options.onConnection - Called when a connection is upgraded
|
||||
* @param {(Connection) => void} options.onConnectionEnd
|
||||
* @param {(connection: Connection) => void} options.onConnection - Called when a connection is upgraded
|
||||
* @param {(connection: Connection) => void} options.onConnectionEnd
|
||||
*/
|
||||
constructor ({
|
||||
localPeer,
|
||||
@@ -51,6 +54,7 @@ class Upgrader {
|
||||
this.metrics = metrics
|
||||
this.cryptos = cryptos
|
||||
this.muxers = muxers
|
||||
/** @type {import("./pnet") | null} */
|
||||
this.protector = null
|
||||
this.protocols = new Map()
|
||||
this.onConnection = onConnection
|
||||
@@ -133,7 +137,12 @@ class Upgrader {
|
||||
* @returns {Promise<Connection>}
|
||||
*/
|
||||
async upgradeOutbound (maConn) {
|
||||
const remotePeerId = PeerId.createFromB58String(maConn.remoteAddr.getPeerId())
|
||||
const idStr = maConn.remoteAddr.getPeerId()
|
||||
if (!idStr) {
|
||||
throw errCode(new Error('outbound connection must have a peer id'), codes.ERR_INVALID_MULTIADDR)
|
||||
}
|
||||
|
||||
const remotePeerId = PeerId.createFromB58String(idStr)
|
||||
|
||||
let encryptedConn
|
||||
let remotePeer
|
||||
@@ -216,16 +225,19 @@ class Upgrader {
|
||||
Muxer,
|
||||
remotePeer
|
||||
}) {
|
||||
/** @type {import("libp2p-interfaces/src/stream-muxer/types").Muxer} */
|
||||
let muxer
|
||||
/** @type {import("libp2p-interfaces/src/connection/connection").CreatedMuxedStream | undefined} */
|
||||
let newStream
|
||||
// eslint-disable-next-line prefer-const
|
||||
let connection
|
||||
/** @type {Connection} */
|
||||
let connection // eslint-disable-line prefer-const
|
||||
|
||||
if (Muxer) {
|
||||
// Create the muxer
|
||||
muxer = new Muxer({
|
||||
// Run anytime a remote stream is created
|
||||
onStream: async muxedStream => {
|
||||
if (!connection) return
|
||||
const mss = new Multistream.Listener(muxedStream)
|
||||
try {
|
||||
const { stream, protocol } = await mss.handle(Array.from(this.protocols.keys()))
|
||||
@@ -243,7 +255,7 @@ class Upgrader {
|
||||
}
|
||||
})
|
||||
|
||||
newStream = async protocols => {
|
||||
newStream = async (protocols) => {
|
||||
log('%s: starting new stream on %s', direction, protocols)
|
||||
const muxedStream = muxer.newStream()
|
||||
const mss = new Multistream.Dialer(muxedStream)
|
||||
@@ -302,12 +314,12 @@ class Upgrader {
|
||||
encryption: cryptoProtocol
|
||||
},
|
||||
newStream: newStream || errConnectionNotMultiplexed,
|
||||
getStreams: () => muxer ? muxer.streams : errConnectionNotMultiplexed,
|
||||
close: async (err) => {
|
||||
await maConn.close(err)
|
||||
getStreams: () => muxer ? muxer.streams : errConnectionNotMultiplexed(),
|
||||
close: async () => {
|
||||
await maConn.close()
|
||||
// Ensure remaining streams are aborted
|
||||
if (muxer) {
|
||||
muxer.streams.map(stream => stream.abort(err))
|
||||
muxer.streams.map(stream => stream.abort())
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -371,7 +383,7 @@ class Upgrader {
|
||||
* @private
|
||||
* @async
|
||||
* @param {PeerId} localPeer - The initiators PeerId
|
||||
* @param {*} connection
|
||||
* @param {MultiaddrConnection} connection
|
||||
* @param {PeerId} remotePeerId
|
||||
* @param {Map<string, Crypto>} cryptos
|
||||
* @returns {Promise<CryptoResult>} An encrypted connection, remote peer `PeerId` and the protocol of the `Crypto` used
|
||||
|
@@ -2,7 +2,7 @@
|
||||
/* eslint-env mocha */
|
||||
|
||||
const { expect } = require('aegir/utils/chai')
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const PeerId = require('peer-id')
|
||||
|
||||
const AddressManager = require('../../src/address-manager')
|
||||
@@ -37,8 +37,8 @@ describe('Address Manager', () => {
|
||||
|
||||
const listenMultiaddrs = am.getListenAddrs()
|
||||
expect(listenMultiaddrs.length).to.equal(2)
|
||||
expect(listenMultiaddrs[0].equals(multiaddr(listenAddresses[0]))).to.equal(true)
|
||||
expect(listenMultiaddrs[1].equals(multiaddr(listenAddresses[1]))).to.equal(true)
|
||||
expect(listenMultiaddrs[0].equals(new Multiaddr(listenAddresses[0]))).to.equal(true)
|
||||
expect(listenMultiaddrs[1].equals(new Multiaddr(listenAddresses[1]))).to.equal(true)
|
||||
})
|
||||
|
||||
it('should return announce multiaddrs on get', () => {
|
||||
@@ -52,7 +52,7 @@ describe('Address Manager', () => {
|
||||
|
||||
const announceMultiaddrs = am.getAnnounceAddrs()
|
||||
expect(announceMultiaddrs.length).to.equal(1)
|
||||
expect(announceMultiaddrs[0].equals(multiaddr(announceAddreses[0]))).to.equal(true)
|
||||
expect(announceMultiaddrs[0].equals(new Multiaddr(announceAddreses[0]))).to.equal(true)
|
||||
})
|
||||
|
||||
it('should add observed addresses', () => {
|
||||
|
@@ -4,7 +4,7 @@
|
||||
const { expect } = require('aegir/utils/chai')
|
||||
const sinon = require('sinon')
|
||||
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const isLoopback = require('libp2p-utils/src/multiaddr/is-loopback')
|
||||
|
||||
const { AddressesOptions } = require('./utils')
|
||||
@@ -111,9 +111,9 @@ describe('libp2p.multiaddrs', () => {
|
||||
expect(libp2p.multiaddrs.length).to.equal(0)
|
||||
|
||||
// Stub transportManager addresses to add a public address
|
||||
const stubMa = multiaddr('/ip4/120.220.10.1/tcp/1000')
|
||||
const stubMa = new Multiaddr('/ip4/120.220.10.1/tcp/1000')
|
||||
sinon.stub(libp2p.transportManager, 'getAddrs').returns([
|
||||
...listenAddresses.map((a) => multiaddr(a)),
|
||||
...listenAddresses.map((a) => new Multiaddr(a)),
|
||||
stubMa
|
||||
])
|
||||
|
||||
|
@@ -11,7 +11,7 @@ const mergeOptions = require('merge-options')
|
||||
const CID = require('cids')
|
||||
const ipfsHttpClient = require('ipfs-http-client')
|
||||
const DelegatedContentRouter = require('libp2p-delegated-content-routing')
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const drain = require('it-drain')
|
||||
const all = require('it-all')
|
||||
|
||||
@@ -28,6 +28,8 @@ describe('content-routing', () => {
|
||||
})
|
||||
})
|
||||
|
||||
after(() => node.stop())
|
||||
|
||||
it('.findProviders should return an error', async () => {
|
||||
try {
|
||||
for await (const _ of node.contentRouting.findProviders('a cid')) {} // eslint-disable-line
|
||||
@@ -277,7 +279,7 @@ describe('content-routing', () => {
|
||||
const result = {
|
||||
id: providerPeerId,
|
||||
multiaddrs: [
|
||||
multiaddr('/ip4/123.123.123.123/tcp/49320')
|
||||
new Multiaddr('/ip4/123.123.123.123/tcp/49320')
|
||||
]
|
||||
}
|
||||
|
||||
@@ -301,7 +303,7 @@ describe('content-routing', () => {
|
||||
const result = {
|
||||
id: providerPeerId,
|
||||
multiaddrs: [
|
||||
multiaddr('/ip4/123.123.123.123/tcp/49320')
|
||||
new Multiaddr('/ip4/123.123.123.123/tcp/49320')
|
||||
]
|
||||
}
|
||||
|
||||
@@ -327,7 +329,7 @@ describe('content-routing', () => {
|
||||
const result = {
|
||||
id: providerPeerId,
|
||||
multiaddrs: [
|
||||
multiaddr('/ip4/123.123.123.123/tcp/49320')
|
||||
new Multiaddr('/ip4/123.123.123.123/tcp/49320')
|
||||
]
|
||||
}
|
||||
|
||||
@@ -348,13 +350,13 @@ describe('content-routing', () => {
|
||||
const result1 = {
|
||||
id: providerPeerId,
|
||||
multiaddrs: [
|
||||
multiaddr('/ip4/123.123.123.123/tcp/49320')
|
||||
new Multiaddr('/ip4/123.123.123.123/tcp/49320')
|
||||
]
|
||||
}
|
||||
const result2 = {
|
||||
id: providerPeerId,
|
||||
multiaddrs: [
|
||||
multiaddr('/ip4/213.213.213.213/tcp/2344')
|
||||
new Multiaddr('/ip4/213.213.213.213/tcp/2344')
|
||||
]
|
||||
}
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
const { expect } = require('aegir/utils/chai')
|
||||
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const pWaitFor = require('p-wait-for')
|
||||
const mergeOptions = require('merge-options')
|
||||
const uint8ArrayFromString = require('uint8arrays/from-string')
|
||||
@@ -12,8 +12,8 @@ const { create } = require('../../../src')
|
||||
const { subsystemOptions, subsystemMulticodecs } = require('./utils')
|
||||
const peerUtils = require('../../utils/creators/peer')
|
||||
|
||||
const listenAddr = multiaddr('/ip4/127.0.0.1/tcp/8000')
|
||||
const remoteListenAddr = multiaddr('/ip4/127.0.0.1/tcp/8001')
|
||||
const listenAddr = new Multiaddr('/ip4/127.0.0.1/tcp/8000')
|
||||
const remoteListenAddr = new Multiaddr('/ip4/127.0.0.1/tcp/8001')
|
||||
|
||||
describe('DHT subsystem operates correctly', () => {
|
||||
let peerId, remotePeerId
|
||||
|
@@ -45,7 +45,7 @@ describe('Listening', () => {
|
||||
expect(addrs.length).to.be.at.least(2)
|
||||
for (const addr of addrs) {
|
||||
const opts = addr.toOptions()
|
||||
expect(opts.family).to.equal('ipv4')
|
||||
expect(opts.family).to.equal(4)
|
||||
expect(opts.transport).to.equal('tcp')
|
||||
expect(opts.host).to.match(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)
|
||||
expect(opts.port).to.be.gt(0)
|
||||
|
@@ -23,6 +23,8 @@ describe('ping', () => {
|
||||
nodes[1].peerStore.addressBook.set(nodes[0].peerId, nodes[0].multiaddrs)
|
||||
})
|
||||
|
||||
afterEach(() => Promise.all(nodes.map(n => n.stop())))
|
||||
|
||||
it('ping once from peer0 to peer1 using a multiaddr', async () => {
|
||||
const ma = `${nodes[2].multiaddrs[0]}/p2p/${nodes[2].peerId.toB58String()}`
|
||||
const latency = await nodes[0].ping(ma)
|
||||
@@ -56,6 +58,7 @@ describe('ping', () => {
|
||||
if (firstInvocation) {
|
||||
firstInvocation = false
|
||||
|
||||
// eslint-disable-next-line no-unreachable-loop
|
||||
for await (const data of stream) {
|
||||
return {
|
||||
value: data,
|
||||
|
@@ -6,7 +6,7 @@ const sinon = require('sinon')
|
||||
const Transport = require('libp2p-tcp')
|
||||
const Muxer = require('libp2p-mplex')
|
||||
const { NOISE: Crypto } = require('libp2p-noise')
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const PeerId = require('peer-id')
|
||||
const delay = require('delay')
|
||||
const pDefer = require('p-defer')
|
||||
@@ -33,8 +33,8 @@ const createMockConnection = require('../utils/mockConnection')
|
||||
const Peers = require('../fixtures/peers')
|
||||
const { createPeerId } = require('../utils/creators/peer')
|
||||
|
||||
const listenAddr = multiaddr('/ip4/127.0.0.1/tcp/0')
|
||||
const unsupportedAddr = multiaddr('/ip4/127.0.0.1/tcp/9999/ws/p2p/QmckxVrJw1Yo8LqvmDJNUmdAsKtSbiKWmrXJFyKmUraBoN')
|
||||
const listenAddr = new Multiaddr('/ip4/127.0.0.1/tcp/0')
|
||||
const unsupportedAddr = new Multiaddr('/ip4/127.0.0.1/tcp/9999/ws/p2p/QmckxVrJw1Yo8LqvmDJNUmdAsKtSbiKWmrXJFyKmUraBoN')
|
||||
|
||||
describe('Dialing (direct, TCP)', () => {
|
||||
let remoteTM
|
||||
@@ -98,8 +98,8 @@ describe('Dialing (direct, TCP)', () => {
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
|
||||
await expect(dialer.connectToPeer(unsupportedAddr))
|
||||
.to.eventually.be.rejectedWith(AggregateError)
|
||||
.and.to.have.nested.property('._errors[0].code', ErrorCodes.ERR_TRANSPORT_UNAVAILABLE)
|
||||
.to.eventually.be.rejectedWith(Error)
|
||||
.and.to.have.nested.property('.code', ErrorCodes.ERR_NO_VALID_ADDRESSES)
|
||||
})
|
||||
|
||||
it('should fail to connect if peer has no known addresses', async () => {
|
||||
@@ -139,15 +139,35 @@ describe('Dialing (direct, TCP)', () => {
|
||||
const peerId = await PeerId.createFromJSON(Peers[0])
|
||||
|
||||
await expect(dialer.connectToPeer(peerId))
|
||||
.to.eventually.be.rejectedWith(AggregateError)
|
||||
.and.to.have.nested.property('._errors[0].code', ErrorCodes.ERR_TRANSPORT_UNAVAILABLE)
|
||||
.to.eventually.be.rejectedWith(Error)
|
||||
.and.to.have.nested.property('.code', ErrorCodes.ERR_NO_VALID_ADDRESSES)
|
||||
})
|
||||
|
||||
it('should only try to connect to addresses supported by the transports configured', async () => {
|
||||
const remoteAddrs = remoteTM.getAddrs()
|
||||
const dialer = new Dialer({
|
||||
transportManager: localTM,
|
||||
peerStore: {
|
||||
addressBook: {
|
||||
add: () => { },
|
||||
getMultiaddrsForPeer: () => [...remoteAddrs, unsupportedAddr]
|
||||
}
|
||||
}
|
||||
})
|
||||
const peerId = await PeerId.createFromJSON(Peers[0])
|
||||
|
||||
sinon.spy(localTM, 'dial')
|
||||
const connection = await dialer.connectToPeer(peerId)
|
||||
expect(localTM.dial.callCount).to.equal(remoteAddrs.length)
|
||||
expect(connection).to.exist()
|
||||
await connection.close()
|
||||
})
|
||||
|
||||
it('should abort dials on queue task timeout', async () => {
|
||||
const dialer = new Dialer({
|
||||
transportManager: localTM,
|
||||
peerStore,
|
||||
timeout: 50
|
||||
dialTimeout: 50
|
||||
})
|
||||
sinon.stub(localTM, 'dial').callsFake(async (addr, options) => {
|
||||
expect(options.signal).to.exist()
|
||||
@@ -165,13 +185,13 @@ describe('Dialing (direct, TCP)', () => {
|
||||
|
||||
it('should dial to the max concurrency', async () => {
|
||||
const addrs = [
|
||||
multiaddr('/ip4/0.0.0.0/tcp/8000'),
|
||||
multiaddr('/ip4/0.0.0.0/tcp/8001'),
|
||||
multiaddr('/ip4/0.0.0.0/tcp/8002')
|
||||
new Multiaddr('/ip4/0.0.0.0/tcp/8000'),
|
||||
new Multiaddr('/ip4/0.0.0.0/tcp/8001'),
|
||||
new Multiaddr('/ip4/0.0.0.0/tcp/8002')
|
||||
]
|
||||
const dialer = new Dialer({
|
||||
transportManager: localTM,
|
||||
concurrency: 2,
|
||||
maxParallelDials: 2,
|
||||
peerStore: {
|
||||
addressBook: {
|
||||
add: () => {},
|
||||
@@ -352,6 +372,25 @@ describe('Dialing (direct, TCP)', () => {
|
||||
await pWaitFor(() => remoteConn.streams.length === 0)
|
||||
})
|
||||
|
||||
it('should throw when using dialProtocol with no protocols', async () => {
|
||||
libp2p = new Libp2p({
|
||||
peerId,
|
||||
modules: {
|
||||
transport: [Transport],
|
||||
streamMuxer: [Muxer],
|
||||
connEncryption: [Crypto]
|
||||
}
|
||||
})
|
||||
|
||||
await expect(libp2p.dialProtocol(remotePeerId))
|
||||
.to.eventually.be.rejectedWith(Error)
|
||||
.and.to.have.property('code', ErrorCodes.ERR_INVALID_PROTOCOLS_FOR_STREAM)
|
||||
|
||||
await expect(libp2p.dialProtocol(remotePeerId, []))
|
||||
.to.eventually.be.rejectedWith(Error)
|
||||
.and.to.have.property('code', ErrorCodes.ERR_INVALID_PROTOCOLS_FOR_STREAM)
|
||||
})
|
||||
|
||||
it('should be able to use hangup to close connections', async () => {
|
||||
libp2p = new Libp2p({
|
||||
peerId,
|
||||
|
@@ -10,7 +10,7 @@ const Transport = require('libp2p-websockets')
|
||||
const filters = require('libp2p-websockets/src/filters')
|
||||
const Muxer = require('libp2p-mplex')
|
||||
const { NOISE: Crypto } = require('libp2p-noise')
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const AggregateError = require('aggregate-error')
|
||||
const { AbortError } = require('libp2p-interfaces/src/transport/errors')
|
||||
|
||||
@@ -26,7 +26,7 @@ const { MULTIADDRS_WEBSOCKETS } = require('../fixtures/browser')
|
||||
const mockUpgrader = require('../utils/mockUpgrader')
|
||||
const createMockConnection = require('../utils/mockConnection')
|
||||
const { createPeerId } = require('../utils/creators/peer')
|
||||
const unsupportedAddr = multiaddr('/ip4/127.0.0.1/tcp/9999/ws/p2p/QmckxVrJw1Yo8LqvmDJNUmdAsKtSbiKWmrXJFyKmUraBoN')
|
||||
const unsupportedAddr = new Multiaddr('/ip4/127.0.0.1/tcp/9999/ws/p2p/QmckxVrJw1Yo8LqvmDJNUmdAsKtSbiKWmrXJFyKmUraBoN')
|
||||
const remoteAddr = MULTIADDRS_WEBSOCKETS[0]
|
||||
|
||||
describe('Dialing (direct, WebSockets)', () => {
|
||||
@@ -52,7 +52,7 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
|
||||
it('should have appropriate defaults', () => {
|
||||
const dialer = new Dialer({ transportManager: localTM, peerStore })
|
||||
expect(dialer.concurrency).to.equal(Constants.MAX_PARALLEL_DIALS)
|
||||
expect(dialer.maxParallelDials).to.equal(Constants.MAX_PARALLEL_DIALS)
|
||||
expect(dialer.timeout).to.equal(Constants.DIAL_TIMEOUT)
|
||||
})
|
||||
|
||||
@@ -155,7 +155,7 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
it('should abort dials on queue task timeout', async () => {
|
||||
const dialer = new Dialer({
|
||||
transportManager: localTM,
|
||||
timeout: 50,
|
||||
dialTimeout: 50,
|
||||
peerStore: {
|
||||
addressBook: {
|
||||
add: () => {},
|
||||
@@ -179,9 +179,9 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
|
||||
it('should sort addresses on dial', async () => {
|
||||
const peerMultiaddrs = [
|
||||
multiaddr('/ip4/127.0.0.1/tcp/15001/ws'),
|
||||
multiaddr('/ip4/20.0.0.1/tcp/15001/ws'),
|
||||
multiaddr('/ip4/30.0.0.1/tcp/15001/ws')
|
||||
new Multiaddr('/ip4/127.0.0.1/tcp/15001/ws'),
|
||||
new Multiaddr('/ip4/20.0.0.1/tcp/15001/ws'),
|
||||
new Multiaddr('/ip4/30.0.0.1/tcp/15001/ws')
|
||||
]
|
||||
|
||||
sinon.spy(addressSort, 'publicAddressesFirst')
|
||||
@@ -190,7 +190,7 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
const dialer = new Dialer({
|
||||
transportManager: localTM,
|
||||
addressSorter: addressSort.publicAddressesFirst,
|
||||
concurrency: 3,
|
||||
maxParallelDials: 3,
|
||||
peerStore
|
||||
})
|
||||
|
||||
@@ -211,7 +211,7 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
it('should dial to the max concurrency', async () => {
|
||||
const dialer = new Dialer({
|
||||
transportManager: localTM,
|
||||
concurrency: 2,
|
||||
maxParallelDials: 2,
|
||||
peerStore: {
|
||||
addressBook: {
|
||||
set: () => {},
|
||||
@@ -249,7 +249,7 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
it('.destroy should abort pending dials', async () => {
|
||||
const dialer = new Dialer({
|
||||
transportManager: localTM,
|
||||
concurrency: 2,
|
||||
maxParallelDials: 2,
|
||||
peerStore: {
|
||||
addressBook: {
|
||||
set: () => {},
|
||||
@@ -318,8 +318,8 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
})
|
||||
|
||||
expect(libp2p.dialer).to.exist()
|
||||
expect(libp2p.dialer.concurrency).to.equal(Constants.MAX_PARALLEL_DIALS)
|
||||
expect(libp2p.dialer.perPeerLimit).to.equal(Constants.MAX_PER_PEER_DIALS)
|
||||
expect(libp2p.dialer.maxParallelDials).to.equal(Constants.MAX_PARALLEL_DIALS)
|
||||
expect(libp2p.dialer.maxDialsPerPeer).to.equal(Constants.MAX_PER_PEER_DIALS)
|
||||
expect(libp2p.dialer.timeout).to.equal(Constants.DIAL_TIMEOUT)
|
||||
// Ensure the dialer also has the transport manager
|
||||
expect(libp2p.transportManager).to.equal(libp2p.dialer.transportManager)
|
||||
@@ -349,8 +349,8 @@ describe('Dialing (direct, WebSockets)', () => {
|
||||
libp2p = await Libp2p.create(config)
|
||||
|
||||
expect(libp2p.dialer).to.exist()
|
||||
expect(libp2p.dialer.concurrency).to.equal(config.dialer.maxParallelDials)
|
||||
expect(libp2p.dialer.perPeerLimit).to.equal(config.dialer.maxDialsPerPeer)
|
||||
expect(libp2p.dialer.maxParallelDials).to.equal(config.dialer.maxParallelDials)
|
||||
expect(libp2p.dialer.maxDialsPerPeer).to.equal(config.dialer.maxDialsPerPeer)
|
||||
expect(libp2p.dialer.timeout).to.equal(config.dialer.dialTimeout)
|
||||
})
|
||||
|
||||
|
@@ -4,8 +4,8 @@
|
||||
const { expect } = require('aegir/utils/chai')
|
||||
const sinon = require('sinon')
|
||||
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Resolver } = require('multiaddr/src/resolvers/dns')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const Resolver = require('multiaddr/src/resolvers/dns')
|
||||
|
||||
const { codes: ErrorCodes } = require('../../src/errors')
|
||||
|
||||
@@ -39,7 +39,7 @@ describe('Dialing (resolvable addresses)', () => {
|
||||
config: {
|
||||
...baseOptions,
|
||||
addresses: {
|
||||
listen: [multiaddr(`${relayAddr}/p2p-circuit`)]
|
||||
listen: [new Multiaddr(`${relayAddr}/p2p-circuit`)]
|
||||
},
|
||||
config: {
|
||||
...baseOptions.config,
|
||||
@@ -60,8 +60,8 @@ describe('Dialing (resolvable addresses)', () => {
|
||||
|
||||
it('resolves dnsaddr to ws local address', async () => {
|
||||
const remoteId = remoteLibp2p.peerId.toB58String()
|
||||
const dialAddr = multiaddr(`/dnsaddr/remote.libp2p.io/p2p/${remoteId}`)
|
||||
const relayedAddrFetched = multiaddr(relayedAddr(remoteId))
|
||||
const dialAddr = new Multiaddr(`/dnsaddr/remote.libp2p.io/p2p/${remoteId}`)
|
||||
const relayedAddrFetched = new Multiaddr(relayedAddr(remoteId))
|
||||
|
||||
// Transport spy
|
||||
const transport = libp2p.transportManager._transports.get('Circuit')
|
||||
@@ -82,8 +82,8 @@ describe('Dialing (resolvable addresses)', () => {
|
||||
|
||||
it('resolves a dnsaddr recursively', async () => {
|
||||
const remoteId = remoteLibp2p.peerId.toB58String()
|
||||
const dialAddr = multiaddr(`/dnsaddr/remote.libp2p.io/p2p/${remoteId}`)
|
||||
const relayedAddrFetched = multiaddr(relayedAddr(remoteId))
|
||||
const dialAddr = new Multiaddr(`/dnsaddr/remote.libp2p.io/p2p/${remoteId}`)
|
||||
const relayedAddrFetched = new Multiaddr(relayedAddr(remoteId))
|
||||
|
||||
// Transport spy
|
||||
const transport = libp2p.transportManager._transports.get('Circuit')
|
||||
@@ -114,10 +114,10 @@ describe('Dialing (resolvable addresses)', () => {
|
||||
// Resolver just returns the received multiaddrs
|
||||
it('stops recursive resolve if finds dns4/dns6 and dials it', async () => {
|
||||
const remoteId = remoteLibp2p.peerId.toB58String()
|
||||
const dialAddr = multiaddr(`/dnsaddr/remote.libp2p.io/p2p/${remoteId}`)
|
||||
const dialAddr = new Multiaddr(`/dnsaddr/remote.libp2p.io/p2p/${remoteId}`)
|
||||
|
||||
// Stub resolver
|
||||
const dnsMa = multiaddr(`/dns4/ams-1.remote.libp2p.io/tcp/443/wss/p2p/${remoteId}`)
|
||||
const dnsMa = new Multiaddr(`/dns4/ams-1.remote.libp2p.io/tcp/443/wss/p2p/${remoteId}`)
|
||||
const stubResolve = sinon.stub(Resolver.prototype, 'resolveTxt')
|
||||
stubResolve.returns(Promise.resolve([
|
||||
[`dnsaddr=${dnsMa}`]
|
||||
@@ -135,8 +135,8 @@ describe('Dialing (resolvable addresses)', () => {
|
||||
|
||||
it('resolves a dnsaddr recursively not failing if one address fails to resolve', async () => {
|
||||
const remoteId = remoteLibp2p.peerId.toB58String()
|
||||
const dialAddr = multiaddr(`/dnsaddr/remote.libp2p.io/p2p/${remoteId}`)
|
||||
const relayedAddrFetched = multiaddr(relayedAddr(remoteId))
|
||||
const dialAddr = new Multiaddr(`/dnsaddr/remote.libp2p.io/p2p/${remoteId}`)
|
||||
const relayedAddrFetched = new Multiaddr(relayedAddr(remoteId))
|
||||
|
||||
// Transport spy
|
||||
const transport = libp2p.transportManager._transports.get('Circuit')
|
||||
@@ -159,7 +159,7 @@ describe('Dialing (resolvable addresses)', () => {
|
||||
|
||||
it('fails to dial if resolve fails and there are no addresses to dial', async () => {
|
||||
const remoteId = remoteLibp2p.peerId.toB58String()
|
||||
const dialAddr = multiaddr(`/dnsaddr/remote.libp2p.io/p2p/${remoteId}`)
|
||||
const dialAddr = new Multiaddr(`/dnsaddr/remote.libp2p.io/p2p/${remoteId}`)
|
||||
|
||||
// Stub resolver
|
||||
const stubResolve = sinon.stub(Resolver.prototype, 'resolveTxt')
|
||||
|
4
test/fixtures/browser.js
vendored
4
test/fixtures/browser.js
vendored
@@ -1,7 +1,7 @@
|
||||
'use strict'
|
||||
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
|
||||
module.exports.MULTIADDRS_WEBSOCKETS = [
|
||||
multiaddr('/ip4/127.0.0.1/tcp/15001/ws/p2p/12D3KooWHFKTMzwerBtsVmtz4ZZEQy2heafxzWw6wNn5PPYkBxJ5')
|
||||
new Multiaddr('/ip4/127.0.0.1/tcp/15001/ws/p2p/12D3KooWHFKTMzwerBtsVmtz4ZZEQy2heafxzWw6wNn5PPYkBxJ5')
|
||||
]
|
||||
|
@@ -7,7 +7,7 @@ const sinon = require('sinon')
|
||||
const { EventEmitter } = require('events')
|
||||
const PeerId = require('peer-id')
|
||||
const duplexPair = require('it-pair/duplex')
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const pWaitFor = require('p-wait-for')
|
||||
const unit8ArrayToString = require('uint8arrays/to-string')
|
||||
|
||||
@@ -25,7 +25,7 @@ const AddressManager = require('../../src/address-manager')
|
||||
|
||||
const { MULTIADDRS_WEBSOCKETS } = require('../fixtures/browser')
|
||||
const remoteAddr = MULTIADDRS_WEBSOCKETS[0]
|
||||
const listenMaddrs = [multiaddr('/ip4/127.0.0.1/tcp/15002/ws')]
|
||||
const listenMaddrs = [new Multiaddr('/ip4/127.0.0.1/tcp/15002/ws')]
|
||||
|
||||
describe('Identify', () => {
|
||||
let localPeer, localPeerStore, localAddressManager
|
||||
@@ -74,7 +74,7 @@ describe('Identify', () => {
|
||||
}
|
||||
})
|
||||
|
||||
const observedAddr = multiaddr('/ip4/127.0.0.1/tcp/1234')
|
||||
const observedAddr = new Multiaddr('/ip4/127.0.0.1/tcp/1234')
|
||||
const localConnectionMock = { newStream: () => {}, remotePeer }
|
||||
const remoteConnectionMock = { remoteAddr: observedAddr }
|
||||
|
||||
@@ -110,6 +110,7 @@ describe('Identify', () => {
|
||||
|
||||
// LEGACY
|
||||
it('should be able to identify another peer with no certified peer records support', async () => {
|
||||
const agentVersion = `js-libp2p/${pkg.version}`
|
||||
const localIdentify = new IdentifyService({
|
||||
libp2p: {
|
||||
peerId: localPeer,
|
||||
@@ -118,7 +119,7 @@ describe('Identify', () => {
|
||||
peerStore: localPeerStore,
|
||||
multiaddrs: listenMaddrs,
|
||||
isStarted: () => true,
|
||||
_options: { host: {} }
|
||||
_options: { host: { agentVersion } }
|
||||
}
|
||||
})
|
||||
|
||||
@@ -130,11 +131,11 @@ describe('Identify', () => {
|
||||
peerStore: remotePeerStore,
|
||||
multiaddrs: listenMaddrs,
|
||||
isStarted: () => true,
|
||||
_options: { host: {} }
|
||||
_options: { host: { agentVersion } }
|
||||
}
|
||||
})
|
||||
|
||||
const observedAddr = multiaddr('/ip4/127.0.0.1/tcp/1234')
|
||||
const observedAddr = new Multiaddr('/ip4/127.0.0.1/tcp/1234')
|
||||
const localConnectionMock = { newStream: () => {}, remotePeer }
|
||||
const remoteConnectionMock = { remoteAddr: observedAddr }
|
||||
|
||||
@@ -162,7 +163,7 @@ describe('Identify', () => {
|
||||
const metadataArgs = localIdentify.peerStore.metadataBook.set.firstCall.args
|
||||
expect(metadataArgs[0].id.bytes).to.equal(remotePeer.bytes)
|
||||
expect(metadataArgs[1]).to.equal('AgentVersion')
|
||||
expect(unit8ArrayToString(metadataArgs[2])).to.equal(`js-libp2p/${pkg.version}`)
|
||||
expect(unit8ArrayToString(metadataArgs[2])).to.equal(agentVersion)
|
||||
|
||||
// Validate the remote peer gets updated in the peer store
|
||||
const call = localIdentify.peerStore.addressBook.set.firstCall
|
||||
@@ -192,7 +193,7 @@ describe('Identify', () => {
|
||||
}
|
||||
})
|
||||
|
||||
const observedAddr = multiaddr('/ip4/127.0.0.1/tcp/1234')
|
||||
const observedAddr = new Multiaddr('/ip4/127.0.0.1/tcp/1234')
|
||||
const localConnectionMock = { newStream: () => {}, remotePeer: localPeer }
|
||||
const remoteConnectionMock = { remoteAddr: observedAddr }
|
||||
|
||||
@@ -500,7 +501,7 @@ describe('Identify', () => {
|
||||
await libp2p.identifyService.identify.firstCall.returnValue
|
||||
sinon.stub(libp2p, 'isStarted').returns(true)
|
||||
|
||||
libp2p.peerStore.addressBook.add(libp2p.peerId, [multiaddr('/ip4/180.0.0.1/tcp/15001/ws')])
|
||||
libp2p.peerStore.addressBook.add(libp2p.peerId, [new Multiaddr('/ip4/180.0.0.1/tcp/15001/ws')])
|
||||
|
||||
// Verify the remote peer is notified of change
|
||||
expect(libp2p.identifyService.push.callCount).to.equal(1)
|
||||
|
@@ -2,8 +2,7 @@
|
||||
/* eslint-env mocha */
|
||||
'use strict'
|
||||
|
||||
const { chai, expect } = require('aegir/utils/chai')
|
||||
chai.use(require('chai-string'))
|
||||
const { expect } = require('aegir/utils/chai')
|
||||
const uint8ArrayFromString = require('uint8arrays/from-string')
|
||||
const uint8ArrayToString = require('uint8arrays/to-string')
|
||||
const { MemoryDatastore } = require('interface-datastore')
|
||||
|
@@ -2,9 +2,8 @@
|
||||
/* eslint-env mocha */
|
||||
'use strict'
|
||||
|
||||
const { chai, expect } = require('aegir/utils/chai')
|
||||
const { expect } = require('aegir/utils/chai')
|
||||
const fail = expect.fail
|
||||
chai.use(require('chai-string'))
|
||||
const uint8ArrayFromString = require('uint8arrays/from-string')
|
||||
const uint8ArrayToString = require('uint8arrays/to-string')
|
||||
|
||||
@@ -27,8 +26,8 @@ describe('keychain', () => {
|
||||
datastore1 = new MemoryDatastore()
|
||||
datastore2 = new MemoryDatastore()
|
||||
|
||||
ks = new Keychain(datastore2, { passPhrase: passPhrase })
|
||||
emptyKeystore = new Keychain(datastore1, { passPhrase: passPhrase })
|
||||
ks = new Keychain(datastore2, { pass: passPhrase })
|
||||
emptyKeystore = new Keychain(datastore1, { pass: passPhrase })
|
||||
|
||||
await datastore1.open()
|
||||
await datastore2.open()
|
||||
@@ -44,11 +43,11 @@ describe('keychain', () => {
|
||||
})
|
||||
|
||||
it('needs a NIST SP 800-132 non-weak pass phrase', () => {
|
||||
expect(() => new Keychain(datastore2, { passPhrase: '< 20 character' })).to.throw()
|
||||
expect(() => new Keychain(datastore2, { pass: '< 20 character' })).to.throw()
|
||||
})
|
||||
|
||||
it('needs a store to persist a key', () => {
|
||||
expect(() => new Keychain(null, { passPhrase: passPhrase })).to.throw()
|
||||
expect(() => new Keychain(null, { pass: passPhrase })).to.throw()
|
||||
})
|
||||
|
||||
it('has default options', () => {
|
||||
@@ -56,12 +55,12 @@ describe('keychain', () => {
|
||||
})
|
||||
|
||||
it('supports supported hashing alorithms', () => {
|
||||
const ok = new Keychain(datastore2, { passPhrase: passPhrase, dek: { hash: 'sha2-256' } })
|
||||
const ok = new Keychain(datastore2, { pass: passPhrase, dek: { hash: 'sha2-256' } })
|
||||
expect(ok).to.exist()
|
||||
})
|
||||
|
||||
it('does not support unsupported hashing alorithms', () => {
|
||||
expect(() => new Keychain(datastore2, { passPhrase: passPhrase, dek: { hash: 'my-hash' } })).to.throw()
|
||||
expect(() => new Keychain(datastore2, { pass: passPhrase, dek: { hash: 'my-hash' } })).to.throw()
|
||||
})
|
||||
|
||||
it('can list keys without a password', async () => {
|
||||
@@ -72,7 +71,7 @@ describe('keychain', () => {
|
||||
|
||||
it('can find a key without a password', async () => {
|
||||
const keychain = new Keychain(datastore2)
|
||||
const keychainWithPassword = new Keychain(datastore2, { passPhrase: `hello-${Date.now()}-${Date.now()}` })
|
||||
const keychainWithPassword = new Keychain(datastore2, { pass: `hello-${Date.now()}-${Date.now()}` })
|
||||
const name = `key-${Math.random()}`
|
||||
|
||||
const { id } = await keychainWithPassword.createKey(name, 'ed25519')
|
||||
@@ -82,7 +81,7 @@ describe('keychain', () => {
|
||||
|
||||
it('can remove a key without a password', async () => {
|
||||
const keychainWithoutPassword = new Keychain(datastore2)
|
||||
const keychainWithPassword = new Keychain(datastore2, { passPhrase: `hello-${Date.now()}-${Date.now()}` })
|
||||
const keychainWithPassword = new Keychain(datastore2, { pass: `hello-${Date.now()}-${Date.now()}` })
|
||||
const name = `key-${Math.random()}`
|
||||
|
||||
expect(await keychainWithPassword.createKey(name, 'ed25519')).to.have.property('name', name)
|
||||
@@ -99,7 +98,7 @@ describe('keychain', () => {
|
||||
|
||||
it('can generate options', () => {
|
||||
const options = Keychain.generateOptions()
|
||||
options.passPhrase = passPhrase
|
||||
options.pass = passPhrase
|
||||
const chain = new Keychain(datastore2, options)
|
||||
expect(chain).to.exist()
|
||||
})
|
||||
|
@@ -71,7 +71,7 @@ describe('Nat Manager (TCP)', () => {
|
||||
}
|
||||
}
|
||||
|
||||
afterEach(() => Promise.all(teardown))
|
||||
afterEach(() => Promise.all(teardown.map(t => t())))
|
||||
|
||||
it('should map TCP connections to external ports', async () => {
|
||||
const {
|
||||
|
@@ -10,14 +10,14 @@ const Bootstrap = require('libp2p-bootstrap')
|
||||
const crypto = require('libp2p-crypto')
|
||||
const KadDht = require('libp2p-kad-dht')
|
||||
const MulticastDNS = require('libp2p-mdns')
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const uint8ArrayToString = require('uint8arrays/to-string')
|
||||
|
||||
const Libp2p = require('../../src')
|
||||
const baseOptions = require('../utils/base-options')
|
||||
const { createPeerId } = require('../utils/creators/peer')
|
||||
|
||||
const listenAddr = multiaddr('/ip4/127.0.0.1/tcp/0')
|
||||
const listenAddr = new Multiaddr('/ip4/127.0.0.1/tcp/0')
|
||||
|
||||
describe('peer discovery scenarios', () => {
|
||||
let peerId, remotePeerId1, remotePeerId2
|
||||
@@ -30,6 +30,7 @@ describe('peer discovery scenarios', () => {
|
||||
afterEach(async () => {
|
||||
libp2p && await libp2p.stop()
|
||||
})
|
||||
|
||||
it('should ignore self on discovery', async () => {
|
||||
libp2p = new Libp2p(mergeOptions(baseOptions, {
|
||||
peerId,
|
||||
|
@@ -7,7 +7,7 @@ const sinon = require('sinon')
|
||||
const defer = require('p-defer')
|
||||
const mergeOptions = require('merge-options')
|
||||
|
||||
const multiaddr = require('multiaddr')
|
||||
const { Multiaddr } = require('multiaddr')
|
||||
const WebRTCStar = require('libp2p-webrtc-star')
|
||||
|
||||
const Libp2p = require('../../src')
|
||||
@@ -38,7 +38,7 @@ describe('peer discovery', () => {
|
||||
}
|
||||
})
|
||||
|
||||
libp2p.peerStore.addressBook.set(remotePeerId, [multiaddr('/ip4/165.1.1.1/tcp/80')])
|
||||
libp2p.peerStore.addressBook.set(remotePeerId, [new Multiaddr('/ip4/165.1.1.1/tcp/80')])
|
||||
|
||||
const deferred = defer()
|
||||
sinon.stub(libp2p.dialer, 'connectToPeer').callsFake((remotePeerId) => {
|
||||
@@ -89,6 +89,10 @@ describe('peer discovery', () => {
|
||||
[peerId] = await createPeerId()
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
libp2p && await libp2p.stop()
|
||||
})
|
||||
|
||||
it('should add discovery module if present in transports and enabled', async () => {
|
||||
libp2p = new Libp2p(mergeOptions(baseOptions, {
|
||||
peerId,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user