Skip to content

Commit

Permalink
feat: metadata book (#638)
Browse files Browse the repository at this point in the history
* feat: metadata book

* chore: address review

* chore: address review
  • Loading branch information
vasco-santos authored and jacobheun committed May 28, 2020
1 parent a89c456 commit 166d705
Show file tree
Hide file tree
Showing 11 changed files with 861 additions and 39 deletions.
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

0 comments on commit 166d705

Please sign in to comment.