@libp2p/peer-store 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +4 -0
- package/README.md +44 -0
- package/dist/src/address-book.d.ts +31 -0
- package/dist/src/address-book.d.ts.map +1 -0
- package/dist/src/address-book.js +265 -0
- package/dist/src/address-book.js.map +1 -0
- package/dist/src/errors.d.ts +5 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +5 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/index.d.ts +43 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +88 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/key-book.d.ts +21 -0
- package/dist/src/key-book.d.ts.map +1 -0
- package/dist/src/key-book.js +98 -0
- package/dist/src/key-book.js.map +1 -0
- package/dist/src/metadata-book.d.ts +28 -0
- package/dist/src/metadata-book.d.ts.map +1 -0
- package/dist/src/metadata-book.js +168 -0
- package/dist/src/metadata-book.js.map +1 -0
- package/dist/src/pb/peer.d.ts +222 -0
- package/dist/src/pb/peer.js +641 -0
- package/dist/src/proto-book.d.ts +18 -0
- package/dist/src/proto-book.d.ts.map +1 -0
- package/dist/src/proto-book.js +170 -0
- package/dist/src/proto-book.js.map +1 -0
- package/dist/src/store.d.ts +37 -0
- package/dist/src/store.d.ts.map +1 -0
- package/dist/src/store.js +169 -0
- package/dist/src/store.js.map +1 -0
- package/package.json +162 -0
- package/src/README.md +145 -0
- package/src/address-book.ts +330 -0
- package/src/errors.ts +5 -0
- package/src/index.ts +123 -0
- package/src/key-book.ts +117 -0
- package/src/metadata-book.ts +200 -0
- package/src/pb/peer.d.ts +222 -0
- package/src/pb/peer.js +641 -0
- package/src/pb/peer.proto +31 -0
- package/src/proto-book.ts +204 -0
- package/src/store.ts +224 -0
package/LICENSE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# libp2p-tracked-map <!-- omit in toc -->
|
|
2
|
+
|
|
3
|
+
> allows tracking metrics in libp2p
|
|
4
|
+
|
|
5
|
+
## Table of Contents <!-- omit in toc -->
|
|
6
|
+
|
|
7
|
+
- [Description](#description)
|
|
8
|
+
- [Example](#example)
|
|
9
|
+
- [Installation](#installation)
|
|
10
|
+
- [License](#license)
|
|
11
|
+
- [Contribution](#contribution)
|
|
12
|
+
|
|
13
|
+
## Description
|
|
14
|
+
|
|
15
|
+
A map that reports it's size to the libp2p [Metrics](https://github.com/libp2p/js-libp2p-interfaces/tree/master/packages/libp2p-interfaces/src/metrics#readme) system.
|
|
16
|
+
|
|
17
|
+
If metrics are disabled a regular map is used.
|
|
18
|
+
|
|
19
|
+
## Example
|
|
20
|
+
|
|
21
|
+
```JavaScript
|
|
22
|
+
import { trackedMap } from '@libp2p/tracked-map'
|
|
23
|
+
|
|
24
|
+
const map = trackedMap<string, string>({ metrics })
|
|
25
|
+
|
|
26
|
+
map.set('key', 'value')
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
```console
|
|
32
|
+
$ npm i @libp2p/tracked-map
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## License
|
|
36
|
+
|
|
37
|
+
Licensed under either of
|
|
38
|
+
|
|
39
|
+
* Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / http://www.apache.org/licenses/LICENSE-2.0)
|
|
40
|
+
* MIT ([LICENSE-MIT](LICENSE-MIT) / http://opensource.org/licenses/MIT)
|
|
41
|
+
|
|
42
|
+
### Contribution
|
|
43
|
+
|
|
44
|
+
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Multiaddr } from '@multiformats/multiaddr';
|
|
2
|
+
import { RecordEnvelope } from '@libp2p/peer-record';
|
|
3
|
+
import { PeerId } from '@libp2p/peer-id';
|
|
4
|
+
import type { PeerStore } from '@libp2p/interfaces/peer-store';
|
|
5
|
+
import type { Store } from './store.js';
|
|
6
|
+
import type { AddressFilter, AddressSorter } from './index.js';
|
|
7
|
+
import type { Envelope } from '@libp2p/interfaces/record';
|
|
8
|
+
export declare class PeerStoreAddressBook {
|
|
9
|
+
private emit;
|
|
10
|
+
private store;
|
|
11
|
+
private addressFilter;
|
|
12
|
+
constructor(emit: PeerStore["emit"], store: Store, addressFilter?: AddressFilter);
|
|
13
|
+
/**
|
|
14
|
+
* ConsumePeerRecord adds addresses from a signed peer record contained in a record envelope.
|
|
15
|
+
* This will return a boolean that indicates if the record was successfully processed and added
|
|
16
|
+
* into the AddressBook.
|
|
17
|
+
*/
|
|
18
|
+
consumePeerRecord(envelope: Envelope): Promise<boolean>;
|
|
19
|
+
getRawEnvelope(peerId: PeerId): Promise<Uint8Array | undefined>;
|
|
20
|
+
/**
|
|
21
|
+
* Get an Envelope containing a PeerRecord for the given peer.
|
|
22
|
+
* Returns undefined if no record exists.
|
|
23
|
+
*/
|
|
24
|
+
getPeerRecord(peerId: PeerId): Promise<RecordEnvelope | undefined>;
|
|
25
|
+
get(peerId: PeerId): Promise<import("@libp2p/interfaces/peer-store").Address[]>;
|
|
26
|
+
set(peerId: PeerId, multiaddrs: Multiaddr[]): Promise<void>;
|
|
27
|
+
add(peerId: PeerId, multiaddrs: Multiaddr[]): Promise<void>;
|
|
28
|
+
delete(peerId: PeerId): Promise<void>;
|
|
29
|
+
getMultiaddrsForPeer(peerId: PeerId, addressSorter?: AddressSorter): Promise<Multiaddr[]>;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=address-book.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address-book.d.ts","sourceRoot":"","sources":["../../src/address-book.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAEnD,OAAO,EAAc,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAOhE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AASzD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,IAAI,CAAmB;IAC/B,OAAO,CAAC,KAAK,CAAO;IACpB,OAAO,CAAC,aAAa,CAAe;gBAEvB,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC,EAAE,aAAa;IAMjF;;;;OAIG;IACG,iBAAiB,CAAE,QAAQ,EAAE,QAAQ;IA+DrC,cAAc,CAAE,MAAM,EAAE,MAAM;IAmBpC;;;OAGG;IACG,aAAa,CAAE,MAAM,EAAE,MAAM;IAU7B,GAAG,CAAE,MAAM,EAAE,MAAM;IAuBnB,GAAG,CAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE;IAwD5C,GAAG,CAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE;IAuD5C,MAAM,CAAE,MAAM,EAAE,MAAM;IAyBtB,oBAAoB,CAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAE,aAA4B;CAcxF"}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { logger } from '@libp2p/logger';
|
|
2
|
+
import errcode from 'err-code';
|
|
3
|
+
import { Multiaddr } from '@multiformats/multiaddr';
|
|
4
|
+
import { codes } from './errors.js';
|
|
5
|
+
import { PeerRecord, RecordEnvelope } from '@libp2p/peer-record';
|
|
6
|
+
import { pipe } from 'it-pipe';
|
|
7
|
+
import all from 'it-all';
|
|
8
|
+
import filter from 'it-filter';
|
|
9
|
+
import map from 'it-map';
|
|
10
|
+
import each from 'it-foreach';
|
|
11
|
+
import { base58btc } from 'multiformats/bases/base58';
|
|
12
|
+
import { PeerId } from '@libp2p/peer-id';
|
|
13
|
+
const log = logger('libp2p:peer-store:address-book');
|
|
14
|
+
const EVENT_NAME = 'change:multiaddrs';
|
|
15
|
+
async function allowAll() {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
export class PeerStoreAddressBook {
|
|
19
|
+
constructor(emit, store, addressFilter) {
|
|
20
|
+
this.emit = emit;
|
|
21
|
+
this.store = store;
|
|
22
|
+
this.addressFilter = addressFilter ?? allowAll;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* ConsumePeerRecord adds addresses from a signed peer record contained in a record envelope.
|
|
26
|
+
* This will return a boolean that indicates if the record was successfully processed and added
|
|
27
|
+
* into the AddressBook.
|
|
28
|
+
*/
|
|
29
|
+
async consumePeerRecord(envelope) {
|
|
30
|
+
log('consumePeerRecord await write lock');
|
|
31
|
+
const release = await this.store.lock.writeLock();
|
|
32
|
+
log('consumePeerRecord got write lock');
|
|
33
|
+
let peerId;
|
|
34
|
+
let updatedPeer;
|
|
35
|
+
try {
|
|
36
|
+
let peerRecord;
|
|
37
|
+
try {
|
|
38
|
+
peerRecord = PeerRecord.createFromProtobuf(envelope.payload);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
log.error('invalid peer record received');
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
peerId = peerRecord.peerId;
|
|
45
|
+
const multiaddrs = peerRecord.multiaddrs;
|
|
46
|
+
// Verify peerId
|
|
47
|
+
if (!peerId.equals(envelope.peerId)) {
|
|
48
|
+
log('signing key does not match PeerId in the PeerRecord');
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
// ensure the record has multiaddrs
|
|
52
|
+
if (!multiaddrs || !multiaddrs.length) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
if (await this.store.has(peerId)) {
|
|
56
|
+
const peer = await this.store.load(peerId);
|
|
57
|
+
if (peer.peerRecordEnvelope) {
|
|
58
|
+
const storedEnvelope = await RecordEnvelope.createFromProtobuf(peer.peerRecordEnvelope);
|
|
59
|
+
const storedRecord = PeerRecord.createFromProtobuf(storedEnvelope.payload);
|
|
60
|
+
// ensure seq is greater than, or equal to, the last received
|
|
61
|
+
if (storedRecord.seqNumber >= peerRecord.seqNumber) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Replace unsigned addresses by the new ones from the record
|
|
67
|
+
// TODO: Once we have ttls for the addresses, we should merge these in
|
|
68
|
+
updatedPeer = await this.store.patchOrCreate(peerId, {
|
|
69
|
+
addresses: await filterMultiaddrs(peerId, multiaddrs, this.addressFilter, true),
|
|
70
|
+
peerRecordEnvelope: envelope.marshal()
|
|
71
|
+
});
|
|
72
|
+
log(`stored provided peer record for ${peerRecord.peerId.toString(base58btc)}`);
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
log('consumePeerRecord release write lock');
|
|
76
|
+
release();
|
|
77
|
+
}
|
|
78
|
+
this.emit(EVENT_NAME, { peerId, multiaddrs: updatedPeer.addresses.map(({ multiaddr }) => multiaddr) });
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
async getRawEnvelope(peerId) {
|
|
82
|
+
log('getRawEnvelope await read lock');
|
|
83
|
+
const release = await this.store.lock.readLock();
|
|
84
|
+
log('getRawEnvelope got read lock');
|
|
85
|
+
try {
|
|
86
|
+
const peer = await this.store.load(peerId);
|
|
87
|
+
return peer.peerRecordEnvelope;
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
if (err.code !== codes.ERR_NOT_FOUND) {
|
|
91
|
+
throw err;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
log('getRawEnvelope release read lock');
|
|
96
|
+
release();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get an Envelope containing a PeerRecord for the given peer.
|
|
101
|
+
* Returns undefined if no record exists.
|
|
102
|
+
*/
|
|
103
|
+
async getPeerRecord(peerId) {
|
|
104
|
+
const raw = await this.getRawEnvelope(peerId);
|
|
105
|
+
if (!raw) {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
return RecordEnvelope.createFromProtobuf(raw);
|
|
109
|
+
}
|
|
110
|
+
async get(peerId) {
|
|
111
|
+
peerId = PeerId.fromPeerId(peerId);
|
|
112
|
+
log('get wait for read lock');
|
|
113
|
+
const release = await this.store.lock.readLock();
|
|
114
|
+
log('get got read lock');
|
|
115
|
+
try {
|
|
116
|
+
const peer = await this.store.load(peerId);
|
|
117
|
+
return peer.addresses;
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
if (err.code !== codes.ERR_NOT_FOUND) {
|
|
121
|
+
throw err;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
log('get release read lock');
|
|
126
|
+
release();
|
|
127
|
+
}
|
|
128
|
+
return [];
|
|
129
|
+
}
|
|
130
|
+
async set(peerId, multiaddrs) {
|
|
131
|
+
peerId = PeerId.fromPeerId(peerId);
|
|
132
|
+
if (!Array.isArray(multiaddrs)) {
|
|
133
|
+
log.error('multiaddrs must be an array of Multiaddrs');
|
|
134
|
+
throw errcode(new Error('multiaddrs must be an array of Multiaddrs'), codes.ERR_INVALID_PARAMETERS);
|
|
135
|
+
}
|
|
136
|
+
log('set await write lock');
|
|
137
|
+
const release = await this.store.lock.writeLock();
|
|
138
|
+
log('set got write lock');
|
|
139
|
+
let hasPeer = false;
|
|
140
|
+
let updatedPeer;
|
|
141
|
+
try {
|
|
142
|
+
const addresses = await filterMultiaddrs(peerId, multiaddrs, this.addressFilter);
|
|
143
|
+
// No valid addresses found
|
|
144
|
+
if (!addresses.length) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
const peer = await this.store.load(peerId);
|
|
149
|
+
hasPeer = true;
|
|
150
|
+
if (new Set([
|
|
151
|
+
...addresses.map(({ multiaddr }) => multiaddr.toString()),
|
|
152
|
+
...peer.addresses.map(({ multiaddr }) => multiaddr.toString())
|
|
153
|
+
]).size === peer.addresses.length && addresses.length === peer.addresses.length) {
|
|
154
|
+
// not changing anything, no need to update
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
if (err.code !== codes.ERR_NOT_FOUND) {
|
|
160
|
+
throw err;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
updatedPeer = await this.store.patchOrCreate(peerId, { addresses });
|
|
164
|
+
log(`set multiaddrs for ${peerId.toString(base58btc)}`);
|
|
165
|
+
}
|
|
166
|
+
finally {
|
|
167
|
+
log('set release write lock');
|
|
168
|
+
release();
|
|
169
|
+
}
|
|
170
|
+
this.emit(EVENT_NAME, { peerId, multiaddrs: updatedPeer.addresses.map(addr => addr.multiaddr) });
|
|
171
|
+
// Notify the existence of a new peer
|
|
172
|
+
if (!hasPeer) {
|
|
173
|
+
this.emit('peer', peerId);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async add(peerId, multiaddrs) {
|
|
177
|
+
peerId = PeerId.fromPeerId(peerId);
|
|
178
|
+
if (!Array.isArray(multiaddrs)) {
|
|
179
|
+
log.error('multiaddrs must be an array of Multiaddrs');
|
|
180
|
+
throw errcode(new Error('multiaddrs must be an array of Multiaddrs'), codes.ERR_INVALID_PARAMETERS);
|
|
181
|
+
}
|
|
182
|
+
log('add await write lock');
|
|
183
|
+
const release = await this.store.lock.writeLock();
|
|
184
|
+
log('add got write lock');
|
|
185
|
+
let hasPeer;
|
|
186
|
+
let updatedPeer;
|
|
187
|
+
try {
|
|
188
|
+
const addresses = await filterMultiaddrs(peerId, multiaddrs, this.addressFilter);
|
|
189
|
+
// No valid addresses found
|
|
190
|
+
if (!addresses.length) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
try {
|
|
194
|
+
const peer = await this.store.load(peerId);
|
|
195
|
+
hasPeer = true;
|
|
196
|
+
if (new Set([
|
|
197
|
+
...addresses.map(({ multiaddr }) => multiaddr.toString()),
|
|
198
|
+
...peer.addresses.map(({ multiaddr }) => multiaddr.toString())
|
|
199
|
+
]).size === peer.addresses.length) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
if (err.code !== codes.ERR_NOT_FOUND) {
|
|
205
|
+
throw err;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
updatedPeer = await this.store.mergeOrCreate(peerId, { addresses });
|
|
209
|
+
log(`added multiaddrs for ${peerId.toString(base58btc)}`);
|
|
210
|
+
}
|
|
211
|
+
finally {
|
|
212
|
+
log('set release write lock');
|
|
213
|
+
release();
|
|
214
|
+
}
|
|
215
|
+
this.emit(EVENT_NAME, { peerId, multiaddrs: updatedPeer.addresses.map(addr => addr.multiaddr) });
|
|
216
|
+
// Notify the existence of a new peer
|
|
217
|
+
if (!hasPeer) {
|
|
218
|
+
this.emit('peer', peerId);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
async delete(peerId) {
|
|
222
|
+
peerId = PeerId.fromPeerId(peerId);
|
|
223
|
+
log('delete await write lock');
|
|
224
|
+
const release = await this.store.lock.writeLock();
|
|
225
|
+
log('delete got write lock');
|
|
226
|
+
let has;
|
|
227
|
+
try {
|
|
228
|
+
has = await this.store.has(peerId);
|
|
229
|
+
await this.store.patchOrCreate(peerId, {
|
|
230
|
+
addresses: []
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
finally {
|
|
234
|
+
log('delete release write lock');
|
|
235
|
+
release();
|
|
236
|
+
}
|
|
237
|
+
if (has) {
|
|
238
|
+
this.emit(EVENT_NAME, { peerId, multiaddrs: [] });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
async getMultiaddrsForPeer(peerId, addressSorter = (mas) => mas) {
|
|
242
|
+
const addresses = await this.get(peerId);
|
|
243
|
+
return addressSorter(addresses).map((address) => {
|
|
244
|
+
const multiaddr = address.multiaddr;
|
|
245
|
+
const idString = multiaddr.getPeerId();
|
|
246
|
+
if (idString && idString === peerId.toString())
|
|
247
|
+
return multiaddr;
|
|
248
|
+
return multiaddr.encapsulate(`/p2p/${peerId.toString(base58btc)}`);
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
function filterMultiaddrs(peerId, multiaddrs, addressFilter, isCertified = false) {
|
|
253
|
+
return pipe(multiaddrs, (source) => each(source, (multiaddr) => {
|
|
254
|
+
if (!Multiaddr.isMultiaddr(multiaddr)) {
|
|
255
|
+
log.error('multiaddr must be an instance of Multiaddr');
|
|
256
|
+
throw errcode(new Error('multiaddr must be an instance of Multiaddr'), codes.ERR_INVALID_PARAMETERS);
|
|
257
|
+
}
|
|
258
|
+
}), (source) => filter(source, (multiaddr) => addressFilter(peerId, multiaddr)), (source) => map(source, (multiaddr) => {
|
|
259
|
+
return {
|
|
260
|
+
multiaddr: new Multiaddr(multiaddr.toString()),
|
|
261
|
+
isCertified
|
|
262
|
+
};
|
|
263
|
+
}), (source) => all(source));
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=address-book.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address-book.js","sourceRoot":"","sources":["../../src/address-book.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,KAAK;;;CAGjB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,sBAAsB,EAAE,wBAAwB;IAChD,aAAa,EAAE,eAAe;CAC/B,CAAA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import type { PeerStore, Address, AddressBook, KeyBook, MetadataBook, ProtoBook } from '@libp2p/interfaces/peer-store';
|
|
4
|
+
import type { PeerId } from '@libp2p/interfaces/peer-id';
|
|
5
|
+
import type { Multiaddr } from '@multiformats/multiaddr';
|
|
6
|
+
import type { Datastore } from 'interface-datastore';
|
|
7
|
+
export interface AddressFilter {
|
|
8
|
+
(peerId: PeerId, multiaddr: Multiaddr): Promise<boolean>;
|
|
9
|
+
}
|
|
10
|
+
export interface AddressSorter {
|
|
11
|
+
(addresses: Address[]): Address[];
|
|
12
|
+
}
|
|
13
|
+
export interface PeerStoreOptions {
|
|
14
|
+
peerId: PeerId;
|
|
15
|
+
datastore: Datastore;
|
|
16
|
+
addressFilter?: AddressFilter;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* An implementation of PeerStore that stores data in a Datastore
|
|
20
|
+
*/
|
|
21
|
+
export declare class DefaultPeerStore extends EventEmitter implements PeerStore {
|
|
22
|
+
addressBook: AddressBook;
|
|
23
|
+
keyBook: KeyBook;
|
|
24
|
+
metadataBook: MetadataBook;
|
|
25
|
+
protoBook: ProtoBook;
|
|
26
|
+
private peerId;
|
|
27
|
+
private store;
|
|
28
|
+
constructor(options: PeerStoreOptions);
|
|
29
|
+
getPeers(): AsyncGenerator<import("@libp2p/interfaces/peer-store").Peer, void, unknown>;
|
|
30
|
+
/**
|
|
31
|
+
* Delete the information of the given peer in every book
|
|
32
|
+
*/
|
|
33
|
+
delete(peerId: PeerId): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Get the stored information of a given peer
|
|
36
|
+
*/
|
|
37
|
+
get(peerId: PeerId): Promise<import("@libp2p/interfaces/peer-store").Peer>;
|
|
38
|
+
/**
|
|
39
|
+
* Returns true if we have a record of the peer
|
|
40
|
+
*/
|
|
41
|
+
has(peerId: PeerId): Promise<boolean>;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAMrC,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;AACtH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAKpD,MAAM,WAAW,aAAa;IAC5B,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACzD;AAED,MAAM,WAAW,aAAa;IAC5B,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAA;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,SAAS,CAAA;IACpB,aAAa,CAAC,EAAE,aAAa,CAAA;CAC9B;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,YAAa,YAAW,SAAS;IAC9D,WAAW,EAAE,WAAW,CAAA;IACxB,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,EAAE,YAAY,CAAA;IAC1B,SAAS,EAAE,SAAS,CAAA;IAE3B,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,KAAK,CAAO;gBAEP,OAAO,EAAE,gBAAgB;IAc9B,QAAQ;IAoBhB;;OAEG;IACG,MAAM,CAAE,MAAM,EAAE,MAAM;IAa5B;;OAEG;IACG,GAAG,CAAE,MAAM,EAAE,MAAM;IAazB;;OAEG;IACG,GAAG,CAAE,MAAM,EAAE,MAAM;CAY1B"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { logger } from '@libp2p/logger';
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import { PeerStoreAddressBook } from './address-book.js';
|
|
4
|
+
import { PeerStoreKeyBook } from './key-book.js';
|
|
5
|
+
import { PeerStoreMetadataBook } from './metadata-book.js';
|
|
6
|
+
import { PeerStoreProtoBook } from './proto-book.js';
|
|
7
|
+
import { PersistentStore } from './store.js';
|
|
8
|
+
import { base58btc } from 'multiformats/bases/base58';
|
|
9
|
+
const log = logger('libp2p:peer-store');
|
|
10
|
+
/**
|
|
11
|
+
* An implementation of PeerStore that stores data in a Datastore
|
|
12
|
+
*/
|
|
13
|
+
export class DefaultPeerStore extends EventEmitter {
|
|
14
|
+
constructor(options) {
|
|
15
|
+
super();
|
|
16
|
+
const { peerId, datastore, addressFilter } = options;
|
|
17
|
+
this.peerId = peerId;
|
|
18
|
+
this.store = new PersistentStore(datastore);
|
|
19
|
+
this.addressBook = new PeerStoreAddressBook(this.emit.bind(this), this.store, addressFilter);
|
|
20
|
+
this.keyBook = new PeerStoreKeyBook(this.emit.bind(this), this.store);
|
|
21
|
+
this.metadataBook = new PeerStoreMetadataBook(this.emit.bind(this), this.store);
|
|
22
|
+
this.protoBook = new PeerStoreProtoBook(this.emit.bind(this), this.store);
|
|
23
|
+
}
|
|
24
|
+
async *getPeers() {
|
|
25
|
+
log('getPeers await read lock');
|
|
26
|
+
const release = await this.store.lock.readLock();
|
|
27
|
+
log('getPeers got read lock');
|
|
28
|
+
try {
|
|
29
|
+
for await (const peer of this.store.all()) {
|
|
30
|
+
if (peer.id.toString(base58btc) === this.peerId.toString(base58btc)) {
|
|
31
|
+
// Remove self peer if present
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
yield peer;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
log('getPeers release read lock');
|
|
39
|
+
release();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Delete the information of the given peer in every book
|
|
44
|
+
*/
|
|
45
|
+
async delete(peerId) {
|
|
46
|
+
log('delete await write lock');
|
|
47
|
+
const release = await this.store.lock.writeLock();
|
|
48
|
+
log('delete got write lock');
|
|
49
|
+
try {
|
|
50
|
+
await this.store.delete(peerId);
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
log('delete release write lock');
|
|
54
|
+
release();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get the stored information of a given peer
|
|
59
|
+
*/
|
|
60
|
+
async get(peerId) {
|
|
61
|
+
log('get await read lock');
|
|
62
|
+
const release = await this.store.lock.readLock();
|
|
63
|
+
log('get got read lock');
|
|
64
|
+
try {
|
|
65
|
+
return this.store.load(peerId);
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
log('get release read lock');
|
|
69
|
+
release();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Returns true if we have a record of the peer
|
|
74
|
+
*/
|
|
75
|
+
async has(peerId) {
|
|
76
|
+
log('has await read lock');
|
|
77
|
+
const release = await this.store.lock.readLock();
|
|
78
|
+
log('has got read lock');
|
|
79
|
+
try {
|
|
80
|
+
return this.store.has(peerId);
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
log('has release read lock');
|
|
84
|
+
release();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { PeerId } from '@libp2p/peer-id';
|
|
2
|
+
import type { Store } from './store.js';
|
|
3
|
+
import type { PeerStore, KeyBook } from '@libp2p/interfaces/src/peer-store';
|
|
4
|
+
export declare class PeerStoreKeyBook implements KeyBook {
|
|
5
|
+
private emit;
|
|
6
|
+
private store;
|
|
7
|
+
/**
|
|
8
|
+
* The KeyBook is responsible for keeping the known public keys of a peer
|
|
9
|
+
*/
|
|
10
|
+
constructor(emit: PeerStore["emit"], store: Store);
|
|
11
|
+
/**
|
|
12
|
+
* Set the Peer public key
|
|
13
|
+
*/
|
|
14
|
+
set(peerId: PeerId, publicKey: Uint8Array): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Get Public key of the given PeerId, if stored
|
|
17
|
+
*/
|
|
18
|
+
get(peerId: PeerId): Promise<Uint8Array | undefined>;
|
|
19
|
+
delete(peerId: PeerId): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=key-book.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-book.d.ts","sourceRoot":"","sources":["../../src/key-book.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAExC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAA;AAY3E,qBAAa,gBAAiB,YAAW,OAAO;IAC9C,OAAO,CAAC,IAAI,CAAmB;IAC/B,OAAO,CAAC,KAAK,CAAO;IAEpB;;OAEG;gBACU,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK;IAKlD;;OAEG;IACG,GAAG,CAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU;IAyChD;;OAEG;IACG,GAAG,CAAE,MAAM,EAAE,MAAM;IAqBnB,MAAM,CAAE,MAAM,EAAE,MAAM;CAkB7B"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { logger } from '@libp2p/logger';
|
|
2
|
+
import errcode from 'err-code';
|
|
3
|
+
import { codes } from './errors.js';
|
|
4
|
+
import { PeerId } from '@libp2p/peer-id';
|
|
5
|
+
import { equals as uint8arrayEquals } from 'uint8arrays/equals';
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {import('./types').PeerStore} PeerStore
|
|
8
|
+
* @typedef {import('./types').KeyBook} KeyBook
|
|
9
|
+
* @typedef {import('libp2p-interfaces/src/keys/types').PublicKey} PublicKey
|
|
10
|
+
*/
|
|
11
|
+
const log = logger('libp2p:peer-store:key-book');
|
|
12
|
+
const EVENT_NAME = 'change:pubkey';
|
|
13
|
+
export class PeerStoreKeyBook {
|
|
14
|
+
/**
|
|
15
|
+
* The KeyBook is responsible for keeping the known public keys of a peer
|
|
16
|
+
*/
|
|
17
|
+
constructor(emit, store) {
|
|
18
|
+
this.emit = emit;
|
|
19
|
+
this.store = store;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Set the Peer public key
|
|
23
|
+
*/
|
|
24
|
+
async set(peerId, publicKey) {
|
|
25
|
+
peerId = PeerId.fromPeerId(peerId);
|
|
26
|
+
if (!publicKey) {
|
|
27
|
+
log.error('publicKey must be an instance of PublicKey to store data');
|
|
28
|
+
throw errcode(new Error('publicKey must be an instance of PublicKey'), codes.ERR_INVALID_PARAMETERS);
|
|
29
|
+
}
|
|
30
|
+
log('set await write lock');
|
|
31
|
+
const release = await this.store.lock.writeLock();
|
|
32
|
+
log('set got write lock');
|
|
33
|
+
let updatedKey = false;
|
|
34
|
+
try {
|
|
35
|
+
try {
|
|
36
|
+
const existing = await this.store.load(peerId);
|
|
37
|
+
if (existing.pubKey && uint8arrayEquals(existing.pubKey, publicKey)) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
if (err.code !== codes.ERR_NOT_FOUND) {
|
|
43
|
+
throw err;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
await this.store.patchOrCreate(peerId, {
|
|
47
|
+
pubKey: publicKey
|
|
48
|
+
});
|
|
49
|
+
updatedKey = true;
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
log('set release write lock');
|
|
53
|
+
release();
|
|
54
|
+
}
|
|
55
|
+
if (updatedKey) {
|
|
56
|
+
this.emit(EVENT_NAME, { peerId, pubKey: publicKey });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get Public key of the given PeerId, if stored
|
|
61
|
+
*/
|
|
62
|
+
async get(peerId) {
|
|
63
|
+
peerId = PeerId.fromPeerId(peerId);
|
|
64
|
+
log('get await write lock');
|
|
65
|
+
const release = await this.store.lock.readLock();
|
|
66
|
+
log('get got write lock');
|
|
67
|
+
try {
|
|
68
|
+
const peer = await this.store.load(peerId);
|
|
69
|
+
return peer.pubKey;
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
if (err.code !== codes.ERR_NOT_FOUND) {
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
log('get release write lock');
|
|
78
|
+
release();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async delete(peerId) {
|
|
82
|
+
peerId = PeerId.fromPeerId(peerId);
|
|
83
|
+
log('delete await write lock');
|
|
84
|
+
const release = await this.store.lock.writeLock();
|
|
85
|
+
log('delete got write lock');
|
|
86
|
+
try {
|
|
87
|
+
await this.store.patchOrCreate(peerId, {
|
|
88
|
+
pubKey: undefined
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
log('delete release write lock');
|
|
93
|
+
release();
|
|
94
|
+
}
|
|
95
|
+
this.emit(EVENT_NAME, { peerId, pubKey: undefined });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=key-book.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-book.js","sourceRoot":"","sources":["../../src/key-book.ts"],"names":[],"mappings":"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"}
|