mirror of
https://github.com/fluencelabs/js-libp2p-interfaces
synced 2025-04-28 17:52:16 +00:00
feat: record interface (#52)
* feat: record interface * chore: add readme reference * chore: address review
This commit is contained in:
parent
4adedcc4bf
commit
1cc943e1b2
@ -18,6 +18,7 @@
|
|||||||
- [Crypto](./src/crypto)
|
- [Crypto](./src/crypto)
|
||||||
- [Peer Discovery](./src/peer-discovery)
|
- [Peer Discovery](./src/peer-discovery)
|
||||||
- [Peer Routing](./src/peer-routing)
|
- [Peer Routing](./src/peer-routing)
|
||||||
|
- [Record](./src/record)
|
||||||
- [Stream Muxer](./src/stream-muxer)
|
- [Stream Muxer](./src/stream-muxer)
|
||||||
- [Topology](./src/topology)
|
- [Topology](./src/topology)
|
||||||
- [Transport](./src/transport)
|
- [Transport](./src/transport)
|
||||||
|
75
src/record/README.md
Normal file
75
src/record/README.md
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
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 Buffer 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 Protobuf = require('./record.proto')
|
||||||
|
|
||||||
|
const ENVELOPE_DOMAIN_PEER_RECORD = 'libp2p-peer-record'
|
||||||
|
const ENVELOPE_PAYLOAD_TYPE_PEER_RECORD = Buffer.from('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 {Buffer} 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(Buffer.isBuffer(rawData)).to.eql(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('is able to compare two records', () => {
|
||||||
|
const equals = record.equals(record)
|
||||||
|
expect(equals).to.eql(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user