Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: metadata book #638

Merged
merged 3 commits into from
May 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions doc/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
* [`peerStore.keyBook.delete`](#peerstorekeybookdelete)
* [`peerStore.keyBook.get`](#peerstorekeybookget)
* [`peerStore.keyBook.set`](#peerstorekeybookset)
* [`peerStore.metadataBook.delete`](#peerstoremetadatabookdelete)
* [`peerStore.metadataBook.deleteValue`](#peerstoremetadatabookdeletevalue)
* [`peerStore.metadataBook.get`](#peerstoremetadatabookget)
* [`peerStore.metadataBook.getValue`](#peerstoremetadatabookgetvalue)
* [`peerStore.metadataBook.set`](#peerstoremetadatabookset)
* [`peerStore.protoBook.add`](#peerstoreprotobookadd)
* [`peerStore.protoBook.delete`](#peerstoreprotobookdelete)
* [`peerStore.protoBook.get`](#peerstoreprotobookget)
Expand Down Expand Up @@ -939,6 +944,146 @@ const publicKey = peerId.pubKey
peerStore.keyBook.set(peerId, publicKey)
```

### peerStore.metadataBook.delete

Delete the provided peer from the book.

`peerStore.metadataBook.delete(peerId)`

#### Parameters

| Name | Type | Description |
|------|------|-------------|
| peerId | [`PeerId`][peer-id] | peerId to remove |

#### Returns

| Type | Description |
|------|-------------|
| `boolean` | true if found and removed |

#### Example

```js
peerStore.metadataBook.delete(peerId)
// false
peerStore.metadataBook.set(peerId, 'nickname', Buffer.from('homePeer'))
peerStore.metadataBook.delete(peerId)
// true
```

### peerStore.metadataBook.deleteValue

Deletes the provided peer metadata key-value pair from the book.

`peerStore.metadataBook.deleteValue(peerId, key)`

#### Parameters

| Name | Type | Description |
|------|------|-------------|
| peerId | [`PeerId`][peer-id] | peerId to remove |
| key | `string` | key of the metadata value to remove |

#### Returns

| Type | Description |
|------|-------------|
| `boolean` | true if found and removed |

#### Example

```js
peerStore.metadataBook.deleteValue(peerId, 'location')
// false
peerStore.metadataBook.set(peerId, 'location', Buffer.from('Berlin'))
peerStore.metadataBook.deleteValue(peerId, 'location')
// true
```

### peerStore.metadataBook.get

Get the known metadata of a provided peer.

`peerStore.metadataBook.get(peerId)`

#### Parameters

| Name | Type | Description |
|------|------|-------------|
| peerId | [`PeerId`][peer-id] | peerId to get |

#### Returns

| Type | Description |
|------|-------------|
| `Map<string, Buffer>` | Peer Metadata |

#### Example

```js
peerStore.metadataBook.get(peerId)
// undefined
peerStore.metadataBook.set(peerId, 'location', Buffer.from('Berlin'))
peerStore.metadataBook.get(peerId)
// Metadata Map
```

### peerStore.metadataBook.getValue

Get specific metadata of a provided peer.

`peerStore.metadataBook.getValue(peerId)`

#### Parameters

| Name | Type | Description |
|------|------|-------------|
| peerId | [`PeerId`][peer-id] | peerId to get |
| key | `string` | key of the metadata value to get |

#### Returns

| Type | Description |
|------|-------------|
| `Map<string, Buffer>` | Peer Metadata |

#### Example

```js
peerStore.metadataBook.getValue(peerId, 'location')
// undefined
peerStore.metadataBook.set(peerId, 'location', Buffer.from('Berlin'))
peerStore.metadataBook.getValue(peerId, 'location')
// Metadata Map
```

### peerStore.metadataBook.set

Set known metadata of a given `peerId`.

`peerStore.metadataBook.set(peerId, key, value)`

#### Parameters

| Name | Type | Description |
|------|------|-------------|
| peerId | [`PeerId`][peer-id] | peerId to set |
| key | `string` | key of the metadata value to store |
| value | `Buffer` | metadata value to store |

#### Returns

| Type | Description |
|------|-------------|
| `MetadataBook` | Returns the Metadata Book component |

#### Example

```js
peerStore.metadataBook.set(peerId, 'location', Buffer.from('Berlin'))
```

### peerStore.protoBook.delete

Delete the provided peer from the book.
Expand Down
11 changes: 8 additions & 3 deletions src/peer-store/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ A `peerId.toB58String()` identifier mapping to a `Set` of protocol identifier st

#### Metadata Book

**Not Yet Implemented**
The `metadataBook` keeps track of the known metadata of a peer. Its metadata is stored in a key value fashion, where a key identifier (`string`) represents a metadata value (`Buffer`).

`Map<string, Map<string, Buffer>>`

A `peerId.toB58String()` identifier mapping to the peer metadata Map.

### API

Expand All @@ -85,13 +89,16 @@ Access to its underlying books:

- `peerStore.addressBook.*`
- `peerStore.keyBook.*`
- `peerStore.metadataBook.*`
- `peerStore.protoBook.*`

### Events

- `peer` - emitted when a new peer is added.
- `change:multiaadrs` - emitted when a known peer has a different set of multiaddrs.
- `change:protocols` - emitted when a known peer supports a different set of protocols.
- `change:pubkey` - emitted when a peer's public key is known.
- `change:metadata` - emitted when known metadata of a peer changes.

## Data Persistence

Expand Down Expand Up @@ -123,8 +130,6 @@ All public keys are stored under the following pattern:

**MetadataBook**

_NOT_YET_IMPLEMENTED_

Metadata is stored under the following key pattern:

`/peers/metadata/<b32 peer id no padding>/<key>`
Expand Down
1 change: 0 additions & 1 deletion src/peer-store/address-book.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ class AddressBook extends Book {
/**
* Add known addresses of a provided peer.
* If the peer is not known, it is set with the given addresses.
* @override
* @param {PeerId} peerId
* @param {Array<Multiaddr>} multiaddrs
* @returns {AddressBook}
Expand Down
51 changes: 24 additions & 27 deletions src/peer-store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const PeerId = require('peer-id')

const AddressBook = require('./address-book')
const KeyBook = require('./key-book')
const MetadataBook = require('./metadata-book')
const ProtoBook = require('./proto-book')

const {
Expand All @@ -21,6 +22,8 @@ const {
* @fires PeerStore#peer Emitted when a new peer is added.
* @fires PeerStore#change:protocols Emitted when a known peer supports a different set of protocols.
* @fires PeerStore#change:multiaddrs Emitted when a known peer has a different set of multiaddrs.
* @fires PeerStore#change:pubkey Emitted emitted when a peer's public key is known.
* @fires PeerStore#change:metadata Emitted when the known metadata of a peer change.
*/
class PeerStore extends EventEmitter {
/**
Expand All @@ -47,6 +50,11 @@ class PeerStore extends EventEmitter {
*/
this.keyBook = new KeyBook(this)

/**
* MetadataBook containing a map of peerIdStr to their metadata Map.
*/
this.metadataBook = new MetadataBook(this)

/**
* ProtoBook containing a map of peerIdStr to supported protocols.
*/
Expand All @@ -68,31 +76,17 @@ class PeerStore extends EventEmitter {
* @returns {Map<string, Peer>}
*/
get peers () {
const peersData = new Map()
const storedPeers = new Set([
...this.addressBook.data.keys(),
...this.keyBook.data.keys(),
...this.protoBook.data.keys(),
...this.metadataBook.data.keys()
])

// AddressBook
for (const [idStr, addresses] of this.addressBook.data.entries()) {
const id = this.keyBook.data.get(idStr) || PeerId.createFromCID(idStr)
peersData.set(idStr, {
id,
addresses,
protocols: this.protoBook.get(id) || []
})
}

// ProtoBook
for (const [idStr, protocols] of this.protoBook.data.entries()) {
const pData = peersData.get(idStr)
const id = this.keyBook.data.get(idStr) || PeerId.createFromCID(idStr)

if (!pData) {
peersData.set(idStr, {
id,
addresses: [],
protocols: Array.from(protocols)
})
}
}
const peersData = new Map()
storedPeers.forEach((idStr) => {
peersData.set(idStr, this.get(PeerId.createFromCID(idStr)))
})

return peersData
}
Expand All @@ -106,8 +100,9 @@ class PeerStore extends EventEmitter {
const addressesDeleted = this.addressBook.delete(peerId)
const keyDeleted = this.keyBook.delete(peerId)
const protocolsDeleted = this.protoBook.delete(peerId)
const metadataDeleted = this.metadataBook.delete(peerId)

return addressesDeleted || keyDeleted || protocolsDeleted
return addressesDeleted || keyDeleted || protocolsDeleted || metadataDeleted
}

/**
Expand All @@ -122,16 +117,18 @@ class PeerStore extends EventEmitter {

const id = this.keyBook.data.get(peerId.toB58String())
const addresses = this.addressBook.get(peerId)
const metadata = this.metadataBook.get(peerId)
const protocols = this.protoBook.get(peerId)

if (!addresses && !protocols) {
if (!id && !addresses && !metadata && !protocols) {
return undefined
}

return {
id: id || peerId,
addresses: addresses || [],
protocols: protocols || []
protocols: protocols || [],
metadata: metadata
}
}
}
Expand Down
Loading