mirror of
https://github.com/fluencelabs/js-libp2p-interfaces
synced 2025-07-08 20:01:45 +00:00
Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
c4be5eed4b | |||
9e0d23de9c | |||
4130e7f098 | |||
d6376377d3 | |||
a60ae091e5 | |||
4902542e78 | |||
4d5f56d06f | |||
13aa6cbfa0 | |||
a8ba13da4b | |||
75f6777d89 | |||
71b813ad3b | |||
46589ce3d0 | |||
f2a18818f2 | |||
1cc943e1b2 |
49
CHANGELOG.md
49
CHANGELOG.md
@ -1,3 +1,52 @@
|
||||
<a name="0.5.0"></a>
|
||||
# [0.5.0](https://github.com/libp2p/js-interfaces/compare/v0.4.1...v0.5.0) (2020-08-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* replace remaining Buffer usage with Uint8Array ([#62](https://github.com/libp2p/js-interfaces/issues/62)) ([4130e7f](https://github.com/libp2p/js-interfaces/commit/4130e7f))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* records now marshal as Uint8Array instead of Buffer
|
||||
|
||||
* fix: refactor remaining Buffer usage to Uint8Array
|
||||
|
||||
|
||||
|
||||
<a name="0.4.1"></a>
|
||||
## [0.4.1](https://github.com/libp2p/js-interfaces/compare/v0.4.0...v0.4.1) (2020-08-11)
|
||||
|
||||
|
||||
|
||||
<a name="0.4.0"></a>
|
||||
# [0.4.0](https://github.com/libp2p/js-interfaces/compare/v0.3.2...v0.4.0) (2020-08-10)
|
||||
|
||||
|
||||
### Chores
|
||||
|
||||
* update deps ([#57](https://github.com/libp2p/js-interfaces/issues/57)) ([75f6777](https://github.com/libp2p/js-interfaces/commit/75f6777))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* - The peer id dep of this module has replaced node Buffers with Uint8Arrays
|
||||
|
||||
* chore: update gh deps
|
||||
|
||||
|
||||
|
||||
<a name="0.3.2"></a>
|
||||
## [0.3.2](https://github.com/libp2p/js-interfaces/compare/v0.3.1...v0.3.2) (2020-07-15)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* record interface ([#52](https://github.com/libp2p/js-interfaces/issues/52)) ([1cc943e](https://github.com/libp2p/js-interfaces/commit/1cc943e))
|
||||
|
||||
|
||||
|
||||
<a name="0.3.1"></a>
|
||||
## [0.3.1](https://github.com/libp2p/js-interfaces/compare/v0.2.8...v0.3.1) (2020-07-03)
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
- [Crypto](./src/crypto)
|
||||
- [Peer Discovery](./src/peer-discovery)
|
||||
- [Peer Routing](./src/peer-routing)
|
||||
- [Record](./src/record)
|
||||
- [Stream Muxer](./src/stream-muxer)
|
||||
- [Topology](./src/topology)
|
||||
- [Transport](./src/transport)
|
||||
|
17
package.json
17
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "libp2p-interfaces",
|
||||
"version": "0.3.1",
|
||||
"version": "0.5.0",
|
||||
"description": "Interfaces for JS Libp2p",
|
||||
"leadMaintainer": "Jacob Heun <jacobheun@gmail.com>",
|
||||
"main": "src/index.js",
|
||||
@ -35,7 +35,6 @@
|
||||
"dependencies": {
|
||||
"abort-controller": "^3.0.0",
|
||||
"abortable-iterator": "^3.0.0",
|
||||
"buffer": "^5.6.0",
|
||||
"chai": "^4.2.0",
|
||||
"chai-checkmark": "^1.0.1",
|
||||
"class-is": "^1.1.0",
|
||||
@ -45,19 +44,19 @@
|
||||
"err-code": "^2.0.0",
|
||||
"it-goodbye": "^2.0.1",
|
||||
"it-pair": "^1.0.0",
|
||||
"it-pipe": "^1.0.1",
|
||||
"libp2p-tcp": "^0.14.1",
|
||||
"multiaddr": "^7.4.3",
|
||||
"it-pipe": "^1.1.0",
|
||||
"libp2p-tcp": "^0.15.0",
|
||||
"multiaddr": "^8.0.0",
|
||||
"p-defer": "^3.0.0",
|
||||
"p-limit": "^2.3.0",
|
||||
"p-wait-for": "^3.1.0",
|
||||
"peer-id": "^0.13.11",
|
||||
"peer-info": "^0.17.0",
|
||||
"peer-id": "^0.14.0",
|
||||
"sinon": "^9.0.2",
|
||||
"streaming-iterables": "^4.1.0"
|
||||
"streaming-iterables": "^5.0.2",
|
||||
"uint8arrays": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"aegir": "^22.0.0",
|
||||
"aegir": "^25.0.0",
|
||||
"it-handshake": "^1.0.1"
|
||||
},
|
||||
"contributors": [
|
||||
|
@ -1,17 +1,19 @@
|
||||
/* eslint-env mocha */
|
||||
'use strict'
|
||||
|
||||
const { Buffer } = require('buffer')
|
||||
const duplexPair = require('it-pair/duplex')
|
||||
const pipe = require('it-pipe')
|
||||
const peers = require('../../utils/peers')
|
||||
const { UnexpectedPeerError } = require('../errors')
|
||||
const PeerId = require('peer-id')
|
||||
const { collect } = require('streaming-iterables')
|
||||
const chai = require('chai')
|
||||
const expect = chai.expect
|
||||
chai.use(require('dirty-chai'))
|
||||
|
||||
const duplexPair = require('it-pair/duplex')
|
||||
const pipe = require('it-pipe')
|
||||
const PeerId = require('peer-id')
|
||||
const { collect } = require('streaming-iterables')
|
||||
const uint8arrayFromString = require('uint8arrays/from-string')
|
||||
|
||||
const peers = require('../../utils/peers')
|
||||
const { UnexpectedPeerError } = require('../errors')
|
||||
|
||||
module.exports = (common) => {
|
||||
describe('interface-crypto', () => {
|
||||
let crypto
|
||||
@ -55,7 +57,7 @@ module.exports = (common) => {
|
||||
pipe(inboundResult.conn, inboundResult.conn)
|
||||
|
||||
// Send some data and collect the result
|
||||
const input = Buffer.from('data to encrypt')
|
||||
const input = uint8arrayFromString('data to encrypt')
|
||||
const result = await pipe(
|
||||
[input],
|
||||
outboundResult.conn,
|
||||
|
@ -33,19 +33,19 @@ Include this badge in your readme if you make a new module that uses interface-p
|
||||
Install `interface-discovery` as one of the dependencies of your project and as a test file. Then, using `mocha` (for JavaScript) or a test runner with compatible API, do:
|
||||
|
||||
```js
|
||||
const test = require('interface-discovery')
|
||||
const tests = require('libp2p-interfaces/src/peer-discovery/tests')
|
||||
|
||||
const common = {
|
||||
setup () {
|
||||
return YourDiscovery
|
||||
},
|
||||
teardown () {
|
||||
// Clean up any resources created by setup()
|
||||
}
|
||||
}
|
||||
|
||||
// use all of the test suits
|
||||
test(common)
|
||||
describe('your discovery', () => {
|
||||
// use all of the test suits
|
||||
tests({
|
||||
setup () {
|
||||
return YourDiscovery
|
||||
},
|
||||
teardown () {
|
||||
// Clean up any resources created by setup()
|
||||
}
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## API
|
||||
|
76
src/record/README.md
Normal file
76
src/record/README.md
Normal file
@ -0,0 +1,76 @@
|
||||
interface-record
|
||||
==================
|
||||
|
||||
A libp2p node needs to store data in a public location (e.g. a DHT), or rely on potentially untrustworthy intermediaries to relay information. Libp2p provides an all-purpose data container called **envelope**, which includes a signature of the data, so that it its authenticity can be verified.
|
||||
|
||||
The record represents the data that will be stored inside the **envelope** when distributing records across the network. The `interface-record` aims to guarantee that any type of record created is compliant with the libp2p **envelope**.
|
||||
|
||||
Taking into account that a record might be used in different contexts, an **envelope** signature made for a specific purpose **must not** be considered valid for a different purpose. Accordingly, each record has a short and descriptive string representing the record use case, known as **domain**. The data to be signed will be prepended with the domain string, in order to create a domain signature.
|
||||
|
||||
A record can also contain a Uint8Array codec (ideally registered as a [multicodec](https://github.com/multiformats/multicodec)). This codec will prefix the record data in the **envelope** , so that it can be deserialized deterministically.
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const tests = require('libp2p-interfaces/src/record/tests')
|
||||
describe('your record', () => {
|
||||
tests({
|
||||
async setup () {
|
||||
return YourRecord
|
||||
},
|
||||
async teardown () {
|
||||
// cleanup resources created by setup()
|
||||
}
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## Create Record
|
||||
|
||||
```js
|
||||
const multicodec = require('multicodec')
|
||||
const Record = require('libp2p-interfaces/src/record')
|
||||
const fromString = require('uint8arrays/from-string')
|
||||
// const Protobuf = require('./record.proto')
|
||||
|
||||
const ENVELOPE_DOMAIN_PEER_RECORD = 'libp2p-peer-record'
|
||||
const ENVELOPE_PAYLOAD_TYPE_PEER_RECORD = fromString('0301', 'hex')
|
||||
|
||||
class PeerRecord extends Record {
|
||||
constructor (peerId, multiaddrs, seqNumber) {
|
||||
super (ENVELOPE_DOMAIN_PEER_RECORD, ENVELOPE_PAYLOAD_TYPE_PEER_RECORD)
|
||||
}
|
||||
|
||||
marshal () {
|
||||
// Implement and return using Protobuf
|
||||
}
|
||||
|
||||
equals (other) {
|
||||
// Verify
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### marshal
|
||||
|
||||
- `record.marshal()`
|
||||
|
||||
Marshal a record to be used in a libp2p envelope.
|
||||
|
||||
**Returns**
|
||||
|
||||
It returns a `Protobuf` containing the record data.
|
||||
|
||||
### equals
|
||||
|
||||
- `record.equals(other)`
|
||||
|
||||
Verifies if the other Record is identical to this one.
|
||||
|
||||
**Parameters**
|
||||
- other is a `Record` to compare with the current instance.
|
||||
|
||||
**Returns**
|
||||
- `boolean`
|
35
src/record/index.js
Normal file
35
src/record/index.js
Normal file
@ -0,0 +1,35 @@
|
||||
'use strict'
|
||||
|
||||
const errcode = require('err-code')
|
||||
|
||||
/**
|
||||
* Record is the base implementation of a record that can be used as the payload of a libp2p envelope.
|
||||
*/
|
||||
class Record {
|
||||
/**
|
||||
* @constructor
|
||||
* @param {String} domain signature domain
|
||||
* @param {Uint8Array} codec identifier of the type of record
|
||||
*/
|
||||
constructor (domain, codec) {
|
||||
this.domain = domain
|
||||
this.codec = codec
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshal a record to be used in an envelope.
|
||||
*/
|
||||
marshal () {
|
||||
throw errcode(new Error('marshal must be implemented by the subclass'), 'ERR_NOT_IMPLEMENTED')
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if the other provided Record is identical to this one.
|
||||
* @param {Record} other
|
||||
*/
|
||||
equals (other) {
|
||||
throw errcode(new Error('equals must be implemented by the subclass'), 'ERR_NOT_IMPLEMENTED')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Record
|
35
src/record/tests/index.js
Normal file
35
src/record/tests/index.js
Normal file
@ -0,0 +1,35 @@
|
||||
/* eslint-env mocha */
|
||||
|
||||
'use strict'
|
||||
|
||||
const chai = require('chai')
|
||||
const expect = chai.expect
|
||||
chai.use(require('dirty-chai'))
|
||||
|
||||
module.exports = (test) => {
|
||||
describe('record', () => {
|
||||
let record
|
||||
|
||||
beforeEach(async () => {
|
||||
record = await test.setup()
|
||||
if (!record) throw new Error('missing record')
|
||||
})
|
||||
|
||||
afterEach(() => test.teardown())
|
||||
|
||||
it('has domain and codec', () => {
|
||||
expect(record.domain).to.exist()
|
||||
expect(record.codec).to.exist()
|
||||
})
|
||||
|
||||
it('is able to marshal', () => {
|
||||
const rawData = record.marshal()
|
||||
expect(rawData).to.be.an.instanceof(Uint8Array)
|
||||
})
|
||||
|
||||
it('is able to compare two records', () => {
|
||||
const equals = record.equals(record)
|
||||
expect(equals).to.eql(true)
|
||||
})
|
||||
})
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
/* eslint max-nested-callbacks: ["error", 8] */
|
||||
'use strict'
|
||||
|
||||
const { Buffer } = require('buffer')
|
||||
const pair = require('it-pair/duplex')
|
||||
const pipe = require('it-pipe')
|
||||
const { consume } = require('streaming-iterables')
|
||||
@ -10,6 +9,7 @@ const Tcp = require('libp2p-tcp')
|
||||
const multiaddr = require('multiaddr')
|
||||
const abortable = require('abortable-iterator')
|
||||
const AbortController = require('abort-controller')
|
||||
const uint8arrayFromString = require('uint8arrays/from-string')
|
||||
|
||||
const mh = multiaddr('/ip4/127.0.0.1/tcp/0')
|
||||
|
||||
@ -18,7 +18,7 @@ function pause (ms) {
|
||||
}
|
||||
|
||||
function randomBuffer () {
|
||||
return Buffer.from(Math.random().toString())
|
||||
return uint8arrayFromString(Math.random().toString())
|
||||
}
|
||||
|
||||
const infiniteRandom = {
|
||||
|
@ -2,7 +2,6 @@
|
||||
/* eslint-env mocha */
|
||||
'use strict'
|
||||
|
||||
const { Buffer } = require('buffer')
|
||||
const chai = require('chai')
|
||||
const dirtyChai = require('dirty-chai')
|
||||
const expect = chai.expect
|
||||
@ -11,6 +10,7 @@ const sinon = require('sinon')
|
||||
|
||||
const pWaitFor = require('p-wait-for')
|
||||
const pipe = require('it-pipe')
|
||||
const uint8arrayFromString = require('uint8arrays/from-string')
|
||||
const { isValidTick } = require('./utils')
|
||||
|
||||
module.exports = (common) => {
|
||||
@ -76,7 +76,7 @@ module.exports = (common) => {
|
||||
// Wait for the data send and close to finish
|
||||
await Promise.all([
|
||||
pipe(
|
||||
[Buffer.from('Some data that is never handled')],
|
||||
[uint8arrayFromString('Some data that is never handled')],
|
||||
socket1
|
||||
),
|
||||
// Closer the listener (will take a couple of seconds to time out)
|
||||
|
Reference in New Issue
Block a user