@libp2p/peer-store 11.0.21 → 11.0.22-2fbcdb687
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/dist/index.min.js +1 -71
- package/dist/src/constants.d.ts +3 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +3 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/index.d.ts +22 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/pb/peer.d.ts +2 -0
- package/dist/src/pb/peer.d.ts.map +1 -1
- package/dist/src/pb/peer.js +16 -0
- package/dist/src/pb/peer.js.map +1 -1
- package/dist/src/store.d.ts +7 -0
- package/dist/src/store.d.ts.map +1 -1
- package/dist/src/store.js +80 -43
- package/dist/src/store.js.map +1 -1
- package/dist/src/utils/bytes-to-peer.d.ts +3 -1
- package/dist/src/utils/bytes-to-peer.d.ts.map +1 -1
- package/dist/src/utils/bytes-to-peer.js +24 -7
- package/dist/src/utils/bytes-to-peer.js.map +1 -1
- package/dist/src/utils/dedupe-addresses.d.ts +1 -1
- package/dist/src/utils/dedupe-addresses.d.ts.map +1 -1
- package/dist/src/utils/dedupe-addresses.js +1 -1
- package/dist/src/utils/dedupe-addresses.js.map +1 -1
- package/dist/src/utils/peer-equals.d.ts +3 -0
- package/dist/src/utils/peer-equals.d.ts.map +1 -0
- package/dist/src/utils/peer-equals.js +71 -0
- package/dist/src/utils/peer-equals.js.map +1 -0
- package/dist/src/utils/to-peer-pb.d.ts +3 -2
- package/dist/src/utils/to-peer-pb.d.ts.map +1 -1
- package/dist/src/utils/to-peer-pb.js +8 -2
- package/dist/src/utils/to-peer-pb.js.map +1 -1
- package/package.json +8 -7
- package/src/constants.ts +2 -0
- package/src/index.ts +24 -0
- package/src/pb/peer.proto +6 -0
- package/src/pb/peer.ts +20 -0
- package/src/store.ts +95 -55
- package/src/utils/bytes-to-peer.ts +33 -12
- package/src/utils/dedupe-addresses.ts +1 -1
- package/src/utils/peer-equals.ts +91 -0
- package/src/utils/to-peer-pb.ts +17 -4
- package/dist/src/utils/peer-data-to-datastore-peer.d.ts +0 -4
- package/dist/src/utils/peer-data-to-datastore-peer.d.ts.map +0 -1
- package/dist/src/utils/peer-data-to-datastore-peer.js +0 -91
- package/dist/src/utils/peer-data-to-datastore-peer.js.map +0 -1
- package/dist/typedoc-urls.json +0 -10
- package/src/utils/peer-data-to-datastore-peer.ts +0 -113
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { equals as uint8ArrayEquals } from 'uint8arrays/equals';
|
|
2
|
+
export function peerEquals(peerA, peerB) {
|
|
3
|
+
return addressesEqual(peerA.addresses, peerB.addresses) &&
|
|
4
|
+
protocolsEqual(peerA.protocols, peerB.protocols) &&
|
|
5
|
+
publicKeyEqual(peerA.publicKey, peerB.publicKey) &&
|
|
6
|
+
peerRecordEnvelope(peerA.peerRecordEnvelope, peerB.peerRecordEnvelope) &&
|
|
7
|
+
metadataEqual(peerA.metadata, peerB.metadata) &&
|
|
8
|
+
tagsEqual(peerA.tags, peerB.tags);
|
|
9
|
+
}
|
|
10
|
+
function addressesEqual(addressesA, addressesB) {
|
|
11
|
+
return compareArrays(addressesA, addressesB, (a, b) => {
|
|
12
|
+
if (a.isCertified !== b.isCertified) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
if (!uint8ArrayEquals(a.multiaddr, b.multiaddr)) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
return true;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function protocolsEqual(protocolsA, protocolsB) {
|
|
22
|
+
return compareArrays(protocolsA, protocolsB, (a, b) => a === b);
|
|
23
|
+
}
|
|
24
|
+
function publicKeyEqual(publicKeyA, publicKeyB) {
|
|
25
|
+
return compareOptionalUint8Arrays(publicKeyA, publicKeyB);
|
|
26
|
+
}
|
|
27
|
+
function peerRecordEnvelope(envelopeA, envelopeB) {
|
|
28
|
+
return compareOptionalUint8Arrays(envelopeA, envelopeB);
|
|
29
|
+
}
|
|
30
|
+
function metadataEqual(metadataA, metadataB) {
|
|
31
|
+
return compareMaps(metadataA, metadataB, (a, b) => uint8ArrayEquals(a, b));
|
|
32
|
+
}
|
|
33
|
+
function tagsEqual(metadataA, metadataB) {
|
|
34
|
+
return compareMaps(metadataA, metadataB, (a, b) => a.value === b.value && a.expiry === b.expiry);
|
|
35
|
+
}
|
|
36
|
+
function compareOptionalUint8Arrays(arrA, arrB) {
|
|
37
|
+
if (arrA == null && arrB == null) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
if (arrA != null && arrB != null) {
|
|
41
|
+
return uint8ArrayEquals(arrA, arrB);
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
function compareArrays(arrA, arrB, compare) {
|
|
46
|
+
if (arrA.length !== arrB.length) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
for (let i = 0; i < arrA.length; i++) {
|
|
50
|
+
if (!compare(arrA[i], arrB[i])) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
function compareMaps(mapA, mapB, compare) {
|
|
57
|
+
if (mapA.size !== mapB.size) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
for (const [key, value] of mapA.entries()) {
|
|
61
|
+
const valueB = mapB.get(key);
|
|
62
|
+
if (valueB == null) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
if (!compare(value, valueB)) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=peer-equals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peer-equals.js","sourceRoot":"","sources":["../../../src/utils/peer-equals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAG/D,MAAM,UAAU,UAAU,CAAE,KAAW,EAAE,KAAW;IAClD,OAAO,cAAc,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC;QACrD,cAAc,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC;QAChD,cAAc,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC;QAChD,kBAAkB,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC,kBAAkB,CAAC;QACtE,aAAa,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC;QAC7C,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;AACrC,CAAC;AAED,SAAS,cAAc,CAAE,UAAqB,EAAE,UAAqB;IACnE,OAAO,aAAa,CAAC,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACpD,IAAI,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;YACpC,OAAO,KAAK,CAAA;QACd,CAAC;QAED,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;YAChD,OAAO,KAAK,CAAA;QACd,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,cAAc,CAAE,UAAoB,EAAE,UAAoB;IACjE,OAAO,aAAa,CAAC,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;AACjE,CAAC;AAED,SAAS,cAAc,CAAE,UAAuB,EAAE,UAAuB;IACvE,OAAO,0BAA0B,CAAC,UAAU,EAAE,UAAU,CAAC,CAAA;AAC3D,CAAC;AAED,SAAS,kBAAkB,CAAE,SAAsB,EAAE,SAAsB;IACzE,OAAO,0BAA0B,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;AACzD,CAAC;AAED,SAAS,aAAa,CAAE,SAAkC,EAAE,SAAkC;IAC5F,OAAO,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AAC5E,CAAC;AAED,SAAS,SAAS,CAAE,SAA2B,EAAE,SAA2B;IAC1E,OAAO,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC,CAAA;AAClG,CAAC;AAED,SAAS,0BAA0B,CAAE,IAAiB,EAAE,IAAiB;IACvE,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;QACjC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;QACjC,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACrC,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,aAAa,CAAM,IAAS,EAAE,IAAS,EAAE,OAAgC;IAChF,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QAChC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/B,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,WAAW,CAAS,IAAe,EAAE,IAAe,EAAE,OAAgC;IAC7F,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAE5B,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,OAAO,KAAK,CAAA;QACd,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { AddressFilter } from '../index.js';
|
|
2
2
|
import type { Peer as PeerPB } from '../pb/peer.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { ExistingPeer } from '../store.js';
|
|
4
|
+
import type { PeerId, PeerData } from '@libp2p/interface';
|
|
4
5
|
export interface ToPBPeerOptions {
|
|
5
6
|
addressFilter?: AddressFilter;
|
|
6
|
-
existingPeer?:
|
|
7
|
+
existingPeer?: ExistingPeer;
|
|
7
8
|
}
|
|
8
9
|
export declare function toPeerPB(peerId: PeerId, data: Partial<PeerData>, strategy: 'merge' | 'patch', options: ToPBPeerOptions): Promise<PeerPB>;
|
|
9
10
|
//# sourceMappingURL=to-peer-pb.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"to-peer-pb.d.ts","sourceRoot":"","sources":["../../../src/utils/to-peer-pb.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"to-peer-pb.d.ts","sourceRoot":"","sources":["../../../src/utils/to-peer-pb.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,KAAK,EAAO,IAAI,IAAI,MAAM,EAAE,MAAM,eAAe,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAW,QAAQ,EAAc,MAAM,mBAAmB,CAAA;AAE9E,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,YAAY,CAAC,EAAE,YAAY,CAAA;CAC5B;AAED,wBAAsB,QAAQ,CAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CA6J/I"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
/* eslint-disable complexity */
|
|
1
2
|
import { publicKeyToProtobuf } from '@libp2p/crypto/keys';
|
|
2
3
|
import { InvalidParametersError } from '@libp2p/interface';
|
|
4
|
+
import { equals as uint8ArrayEquals } from 'uint8arrays/equals';
|
|
3
5
|
import { dedupeFilterAndSortAddresses } from './dedupe-addresses.js';
|
|
4
6
|
export async function toPeerPB(peerId, data, strategy, options) {
|
|
5
7
|
if (data == null) {
|
|
@@ -8,7 +10,7 @@ export async function toPeerPB(peerId, data, strategy, options) {
|
|
|
8
10
|
if (data.publicKey != null && peerId.publicKey != null && !data.publicKey.equals(peerId.publicKey)) {
|
|
9
11
|
throw new InvalidParametersError('publicKey bytes do not match peer id publicKey bytes');
|
|
10
12
|
}
|
|
11
|
-
const existingPeer = options.existingPeer;
|
|
13
|
+
const existingPeer = options.existingPeer?.peer;
|
|
12
14
|
if (existingPeer != null && !peerId.equals(existingPeer.id)) {
|
|
13
15
|
throw new InvalidParametersError('peer id did not match existing peer id');
|
|
14
16
|
}
|
|
@@ -110,7 +112,7 @@ export async function toPeerPB(peerId, data, strategy, options) {
|
|
|
110
112
|
publicKey = publicKeyToProtobuf(peerId.publicKey);
|
|
111
113
|
}
|
|
112
114
|
const output = {
|
|
113
|
-
addresses: await dedupeFilterAndSortAddresses(peerId, options.addressFilter ?? (async () => true), addresses),
|
|
115
|
+
addresses: await dedupeFilterAndSortAddresses(peerId, options.addressFilter ?? (async () => true), addresses, options.existingPeer?.peerPB.addresses),
|
|
114
116
|
protocols: [...protocols.values()].sort((a, b) => {
|
|
115
117
|
return a.localeCompare(b);
|
|
116
118
|
}),
|
|
@@ -119,6 +121,10 @@ export async function toPeerPB(peerId, data, strategy, options) {
|
|
|
119
121
|
publicKey,
|
|
120
122
|
peerRecordEnvelope
|
|
121
123
|
};
|
|
124
|
+
// add observed addresses to multiaddrs
|
|
125
|
+
output.addresses.forEach(addr => {
|
|
126
|
+
addr.observed = options.existingPeer?.peerPB.addresses?.find(addr => uint8ArrayEquals(addr.multiaddr, addr.multiaddr))?.observed ?? Date.now();
|
|
127
|
+
});
|
|
122
128
|
// Ed25519 and secp256k1 have their public key embedded in them so no need to duplicate it
|
|
123
129
|
if (peerId.type !== 'RSA') {
|
|
124
130
|
delete output.publicKey;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"to-peer-pb.js","sourceRoot":"","sources":["../../../src/utils/to-peer-pb.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"to-peer-pb.js","sourceRoot":"","sources":["../../../src/utils/to-peer-pb.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libp2p/peer-store",
|
|
3
|
-
"version": "11.0.
|
|
3
|
+
"version": "11.0.22-2fbcdb687",
|
|
4
4
|
"description": "Stores information about peers libp2p knows on the network",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/peer-store#readme",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
],
|
|
29
29
|
"exports": {
|
|
30
30
|
".": {
|
|
31
|
-
"types": "./src/index.d.ts",
|
|
31
|
+
"types": "./dist/src/index.d.ts",
|
|
32
32
|
"import": "./dist/src/index.js"
|
|
33
33
|
}
|
|
34
34
|
},
|
|
@@ -59,10 +59,10 @@
|
|
|
59
59
|
"test:electron-main": "aegir test -t electron-main"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@libp2p/crypto": "
|
|
63
|
-
"@libp2p/interface": "
|
|
64
|
-
"@libp2p/peer-id": "
|
|
65
|
-
"@libp2p/peer-record": "
|
|
62
|
+
"@libp2p/crypto": "5.0.14-2fbcdb687",
|
|
63
|
+
"@libp2p/interface": "2.6.1-2fbcdb687",
|
|
64
|
+
"@libp2p/peer-id": "5.0.15-2fbcdb687",
|
|
65
|
+
"@libp2p/peer-record": "8.0.22-2fbcdb687",
|
|
66
66
|
"@multiformats/multiaddr": "^12.3.3",
|
|
67
67
|
"interface-datastore": "^8.3.1",
|
|
68
68
|
"it-all": "^3.0.6",
|
|
@@ -73,9 +73,10 @@
|
|
|
73
73
|
"uint8arrays": "^5.1.0"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@libp2p/logger": "
|
|
76
|
+
"@libp2p/logger": "5.1.11-2fbcdb687",
|
|
77
77
|
"@types/sinon": "^17.0.3",
|
|
78
78
|
"aegir": "^45.1.1",
|
|
79
|
+
"benchmark": "^2.1.4",
|
|
79
80
|
"datastore-core": "^10.0.2",
|
|
80
81
|
"delay": "^6.0.0",
|
|
81
82
|
"p-defer": "^4.0.1",
|
package/src/constants.ts
ADDED
package/src/index.ts
CHANGED
|
@@ -27,7 +27,31 @@ export interface AddressFilter {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
export interface PersistentPeerStoreInit {
|
|
30
|
+
/**
|
|
31
|
+
* Used to remove multiaddrs of peers before storing them. The default is to
|
|
32
|
+
* store all addresses
|
|
33
|
+
*/
|
|
30
34
|
addressFilter?: AddressFilter
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The multiaddrs for a given peer will expire after this number of ms after
|
|
38
|
+
* which they must be re-fetched using the peer routing.
|
|
39
|
+
*
|
|
40
|
+
* Defaults to one hour.
|
|
41
|
+
*
|
|
42
|
+
* @default 3_600_000
|
|
43
|
+
*/
|
|
44
|
+
maxAddressAge?: number
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Any peer without multiaddrs that has not been updated after this number of
|
|
48
|
+
* ms will be evicted from the peer store.
|
|
49
|
+
*
|
|
50
|
+
* Defaults to six hours.
|
|
51
|
+
*
|
|
52
|
+
* @default 21_600_000
|
|
53
|
+
*/
|
|
54
|
+
maxPeerAge?: number
|
|
31
55
|
}
|
|
32
56
|
|
|
33
57
|
/**
|
package/src/pb/peer.proto
CHANGED
|
@@ -18,6 +18,9 @@ message Peer {
|
|
|
18
18
|
|
|
19
19
|
// Any tags the peer has
|
|
20
20
|
map<string, Tag> tags = 7;
|
|
21
|
+
|
|
22
|
+
// timestamp in ms of when this peer was last updated
|
|
23
|
+
optional uint64 updated = 8 [jstype = JS_NUMBER];
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
// Address represents a single multiaddr
|
|
@@ -26,6 +29,9 @@ message Address {
|
|
|
26
29
|
|
|
27
30
|
// Flag to indicate if the address comes from a certified source
|
|
28
31
|
optional bool isCertified = 2;
|
|
32
|
+
|
|
33
|
+
// timestamp in ms of when this address was observed
|
|
34
|
+
optional uint64 observed = 3 [jstype = JS_NUMBER];
|
|
29
35
|
}
|
|
30
36
|
|
|
31
37
|
message Tag {
|
package/src/pb/peer.ts
CHANGED
|
@@ -15,6 +15,7 @@ export interface Peer {
|
|
|
15
15
|
peerRecordEnvelope?: Uint8Array
|
|
16
16
|
metadata: Map<string, Uint8Array>
|
|
17
17
|
tags: Map<string, Tag>
|
|
18
|
+
updated?: number
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export namespace Peer {
|
|
@@ -208,6 +209,11 @@ export namespace Peer {
|
|
|
208
209
|
}
|
|
209
210
|
}
|
|
210
211
|
|
|
212
|
+
if (obj.updated != null) {
|
|
213
|
+
w.uint32(64)
|
|
214
|
+
w.uint64Number(obj.updated)
|
|
215
|
+
}
|
|
216
|
+
|
|
211
217
|
if (opts.lengthDelimited !== false) {
|
|
212
218
|
w.ldelim()
|
|
213
219
|
}
|
|
@@ -273,6 +279,10 @@ export namespace Peer {
|
|
|
273
279
|
obj.tags.set(entry.key, entry.value)
|
|
274
280
|
break
|
|
275
281
|
}
|
|
282
|
+
case 8: {
|
|
283
|
+
obj.updated = reader.uint64Number()
|
|
284
|
+
break
|
|
285
|
+
}
|
|
276
286
|
default: {
|
|
277
287
|
reader.skipType(tag & 7)
|
|
278
288
|
break
|
|
@@ -299,6 +309,7 @@ export namespace Peer {
|
|
|
299
309
|
export interface Address {
|
|
300
310
|
multiaddr: Uint8Array
|
|
301
311
|
isCertified?: boolean
|
|
312
|
+
observed?: number
|
|
302
313
|
}
|
|
303
314
|
|
|
304
315
|
export namespace Address {
|
|
@@ -321,6 +332,11 @@ export namespace Address {
|
|
|
321
332
|
w.bool(obj.isCertified)
|
|
322
333
|
}
|
|
323
334
|
|
|
335
|
+
if (obj.observed != null) {
|
|
336
|
+
w.uint32(24)
|
|
337
|
+
w.uint64Number(obj.observed)
|
|
338
|
+
}
|
|
339
|
+
|
|
324
340
|
if (opts.lengthDelimited !== false) {
|
|
325
341
|
w.ldelim()
|
|
326
342
|
}
|
|
@@ -343,6 +359,10 @@ export namespace Address {
|
|
|
343
359
|
obj.isCertified = reader.bool()
|
|
344
360
|
break
|
|
345
361
|
}
|
|
362
|
+
case 3: {
|
|
363
|
+
obj.observed = reader.uint64Number()
|
|
364
|
+
break
|
|
365
|
+
}
|
|
346
366
|
default: {
|
|
347
367
|
reader.skipType(tag & 7)
|
|
348
368
|
break
|
package/src/store.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NotFoundError } from '@libp2p/interface'
|
|
2
2
|
import { peerIdFromCID } from '@libp2p/peer-id'
|
|
3
3
|
import mortice, { type Mortice } from 'mortice'
|
|
4
4
|
import { base32 } from 'multiformats/bases/base32'
|
|
5
5
|
import { CID } from 'multiformats/cid'
|
|
6
|
-
import {
|
|
6
|
+
import { MAX_ADDRESS_AGE, MAX_PEER_AGE } from './constants.js'
|
|
7
7
|
import { Peer as PeerPB } from './pb/peer.js'
|
|
8
|
-
import { bytesToPeer } from './utils/bytes-to-peer.js'
|
|
8
|
+
import { bytesToPeer, pbToPeer } from './utils/bytes-to-peer.js'
|
|
9
|
+
import { peerEquals } from './utils/peer-equals.js'
|
|
9
10
|
import { NAMESPACE_COMMON, peerIdToDatastoreKey } from './utils/peer-id-to-datastore-key.js'
|
|
10
11
|
import { toPeerPB } from './utils/to-peer-pb.js'
|
|
11
12
|
import type { AddressFilter, PersistentPeerStoreComponents, PersistentPeerStoreInit } from './index.js'
|
|
@@ -19,27 +20,33 @@ export interface PeerUpdate extends PeerUpdateExternal {
|
|
|
19
20
|
updated: boolean
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
export interface ExistingPeer {
|
|
24
|
+
peerPB: PeerPB
|
|
25
|
+
peer: Peer
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function keyToPeerId (key: Key): PeerId {
|
|
23
29
|
// /peers/${peer-id-as-libp2p-key-cid-string-in-base-32}
|
|
24
30
|
const base32Str = key.toString().split('/')[2]
|
|
25
31
|
const buf = CID.parse(base32Str, base32)
|
|
26
|
-
const peerId = peerIdFromCID(buf)
|
|
27
32
|
|
|
28
|
-
return
|
|
33
|
+
return peerIdFromCID(buf)
|
|
29
34
|
}
|
|
30
35
|
|
|
31
|
-
function
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
function decodePeer (key: Key, value: Uint8Array, maxAddressAge: number): Peer {
|
|
37
|
+
const peerId = keyToPeerId(key)
|
|
38
|
+
|
|
39
|
+
return bytesToPeer(peerId, value, maxAddressAge)
|
|
40
|
+
}
|
|
35
41
|
|
|
42
|
+
function mapQuery (query: PeerQuery, maxAddressAge: number): Query {
|
|
36
43
|
return {
|
|
37
44
|
prefix: NAMESPACE_COMMON,
|
|
38
45
|
filters: (query.filters ?? []).map(fn => ({ key, value }) => {
|
|
39
|
-
return fn(decodePeer(key, value))
|
|
46
|
+
return fn(decodePeer(key, value, maxAddressAge))
|
|
40
47
|
}),
|
|
41
48
|
orders: (query.orders ?? []).map(fn => (a, b) => {
|
|
42
|
-
return fn(decodePeer(a.key, a.value), decodePeer(b.key, b.value))
|
|
49
|
+
return fn(decodePeer(a.key, a.value, maxAddressAge), decodePeer(b.key, b.value, maxAddressAge))
|
|
43
50
|
})
|
|
44
51
|
}
|
|
45
52
|
}
|
|
@@ -50,6 +57,8 @@ export class PersistentStore {
|
|
|
50
57
|
public readonly lock: Mortice
|
|
51
58
|
private readonly addressFilter?: AddressFilter
|
|
52
59
|
private readonly log: Logger
|
|
60
|
+
private readonly maxAddressAge: number
|
|
61
|
+
private readonly maxPeerAge: number
|
|
53
62
|
|
|
54
63
|
constructor (components: PersistentPeerStoreComponents, init: PersistentPeerStoreInit = {}) {
|
|
55
64
|
this.log = components.logger.forComponent('libp2p:peer-store')
|
|
@@ -60,115 +69,146 @@ export class PersistentStore {
|
|
|
60
69
|
name: 'peer-store',
|
|
61
70
|
singleProcess: true
|
|
62
71
|
})
|
|
72
|
+
this.maxAddressAge = init.maxAddressAge ?? MAX_ADDRESS_AGE
|
|
73
|
+
this.maxPeerAge = init.maxPeerAge ?? MAX_PEER_AGE
|
|
63
74
|
}
|
|
64
75
|
|
|
65
76
|
async has (peerId: PeerId): Promise<boolean> {
|
|
66
|
-
|
|
77
|
+
try {
|
|
78
|
+
await this.load(peerId)
|
|
79
|
+
|
|
80
|
+
return true
|
|
81
|
+
} catch (err: any) {
|
|
82
|
+
if (err.name !== 'NotFoundError') {
|
|
83
|
+
throw err
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return false
|
|
67
88
|
}
|
|
68
89
|
|
|
69
90
|
async delete (peerId: PeerId): Promise<void> {
|
|
70
91
|
if (this.peerId.equals(peerId)) {
|
|
71
|
-
|
|
92
|
+
return
|
|
72
93
|
}
|
|
73
94
|
|
|
74
95
|
await this.datastore.delete(peerIdToDatastoreKey(peerId))
|
|
75
96
|
}
|
|
76
97
|
|
|
77
98
|
async load (peerId: PeerId): Promise<Peer> {
|
|
78
|
-
const
|
|
99
|
+
const key = peerIdToDatastoreKey(peerId)
|
|
100
|
+
const buf = await this.datastore.get(key)
|
|
101
|
+
const peer = PeerPB.decode(buf)
|
|
102
|
+
|
|
103
|
+
if (this.#peerIsExpired(peer)) {
|
|
104
|
+
await this.datastore.delete(key)
|
|
105
|
+
throw new NotFoundError()
|
|
106
|
+
}
|
|
79
107
|
|
|
80
|
-
return
|
|
108
|
+
return pbToPeer(peerId, peer, this.maxAddressAge)
|
|
81
109
|
}
|
|
82
110
|
|
|
83
111
|
async save (peerId: PeerId, data: PeerData): Promise<PeerUpdate> {
|
|
84
|
-
const
|
|
85
|
-
existingBuf,
|
|
86
|
-
existingPeer
|
|
87
|
-
} = await this.#findExistingPeer(peerId)
|
|
112
|
+
const existingPeer = await this.#findExistingPeer(peerId)
|
|
88
113
|
|
|
89
114
|
const peerPb: PeerPB = await toPeerPB(peerId, data, 'patch', {
|
|
90
115
|
addressFilter: this.addressFilter
|
|
91
116
|
})
|
|
92
117
|
|
|
93
|
-
return this.#saveIfDifferent(peerId, peerPb,
|
|
118
|
+
return this.#saveIfDifferent(peerId, peerPb, existingPeer)
|
|
94
119
|
}
|
|
95
120
|
|
|
96
121
|
async patch (peerId: PeerId, data: Partial<PeerData>): Promise<PeerUpdate> {
|
|
97
|
-
const
|
|
98
|
-
existingBuf,
|
|
99
|
-
existingPeer
|
|
100
|
-
} = await this.#findExistingPeer(peerId)
|
|
122
|
+
const existingPeer = await this.#findExistingPeer(peerId)
|
|
101
123
|
|
|
102
124
|
const peerPb: PeerPB = await toPeerPB(peerId, data, 'patch', {
|
|
103
125
|
addressFilter: this.addressFilter,
|
|
104
126
|
existingPeer
|
|
105
127
|
})
|
|
106
128
|
|
|
107
|
-
return this.#saveIfDifferent(peerId, peerPb,
|
|
129
|
+
return this.#saveIfDifferent(peerId, peerPb, existingPeer)
|
|
108
130
|
}
|
|
109
131
|
|
|
110
132
|
async merge (peerId: PeerId, data: PeerData): Promise<PeerUpdate> {
|
|
111
|
-
const
|
|
112
|
-
existingBuf,
|
|
113
|
-
existingPeer
|
|
114
|
-
} = await this.#findExistingPeer(peerId)
|
|
133
|
+
const existingPeer = await this.#findExistingPeer(peerId)
|
|
115
134
|
|
|
116
135
|
const peerPb: PeerPB = await toPeerPB(peerId, data, 'merge', {
|
|
117
136
|
addressFilter: this.addressFilter,
|
|
118
137
|
existingPeer
|
|
119
138
|
})
|
|
120
139
|
|
|
121
|
-
return this.#saveIfDifferent(peerId, peerPb,
|
|
140
|
+
return this.#saveIfDifferent(peerId, peerPb, existingPeer)
|
|
122
141
|
}
|
|
123
142
|
|
|
124
143
|
async * all (query?: PeerQuery): AsyncGenerator<Peer, void, unknown> {
|
|
125
|
-
for await (const { key, value } of this.datastore.query(mapQuery(query ?? {}))) {
|
|
126
|
-
const
|
|
144
|
+
for await (const { key, value } of this.datastore.query(mapQuery(query ?? {}, this.maxAddressAge))) {
|
|
145
|
+
const peerId = keyToPeerId(key)
|
|
127
146
|
|
|
128
|
-
|
|
129
|
-
|
|
147
|
+
// skip self peer if present
|
|
148
|
+
if (peerId.equals(this.peerId)) {
|
|
130
149
|
continue
|
|
131
150
|
}
|
|
132
151
|
|
|
133
|
-
|
|
152
|
+
const peer = PeerPB.decode(value)
|
|
153
|
+
|
|
154
|
+
// remove expired peer
|
|
155
|
+
if (this.#peerIsExpired(peer)) {
|
|
156
|
+
await this.datastore.delete(key)
|
|
157
|
+
continue
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
yield pbToPeer(peerId, peer, this.maxAddressAge)
|
|
134
161
|
}
|
|
135
162
|
}
|
|
136
163
|
|
|
137
|
-
async #findExistingPeer (peerId: PeerId): Promise<
|
|
164
|
+
async #findExistingPeer (peerId: PeerId): Promise<ExistingPeer | undefined> {
|
|
138
165
|
try {
|
|
139
|
-
const
|
|
140
|
-
const
|
|
166
|
+
const key = peerIdToDatastoreKey(peerId)
|
|
167
|
+
const buf = await this.datastore.get(key)
|
|
168
|
+
const peerPB = PeerPB.decode(buf)
|
|
169
|
+
|
|
170
|
+
// remove expired peer
|
|
171
|
+
if (this.#peerIsExpired(peerPB)) {
|
|
172
|
+
await this.datastore.delete(key)
|
|
173
|
+
throw new NotFoundError()
|
|
174
|
+
}
|
|
141
175
|
|
|
142
176
|
return {
|
|
143
|
-
|
|
144
|
-
|
|
177
|
+
peerPB,
|
|
178
|
+
peer: bytesToPeer(peerId, buf, this.maxAddressAge)
|
|
145
179
|
}
|
|
146
180
|
} catch (err: any) {
|
|
147
181
|
if (err.name !== 'NotFoundError') {
|
|
148
182
|
this.log.error('invalid peer data found in peer store - %e', err)
|
|
149
183
|
}
|
|
150
184
|
}
|
|
151
|
-
|
|
152
|
-
return {}
|
|
153
185
|
}
|
|
154
186
|
|
|
155
|
-
async #saveIfDifferent (peerId: PeerId, peer: PeerPB,
|
|
187
|
+
async #saveIfDifferent (peerId: PeerId, peer: PeerPB, existingPeer?: ExistingPeer): Promise<PeerUpdate> {
|
|
188
|
+
// record last update
|
|
189
|
+
peer.updated = Date.now()
|
|
156
190
|
const buf = PeerPB.encode(peer)
|
|
157
191
|
|
|
158
|
-
if (existingBuf != null && uint8ArrayEquals(buf, existingBuf)) {
|
|
159
|
-
return {
|
|
160
|
-
peer: bytesToPeer(peerId, buf),
|
|
161
|
-
previous: existingPeer,
|
|
162
|
-
updated: false
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
192
|
await this.datastore.put(peerIdToDatastoreKey(peerId), buf)
|
|
167
193
|
|
|
168
194
|
return {
|
|
169
|
-
peer: bytesToPeer(peerId, buf),
|
|
170
|
-
previous: existingPeer,
|
|
171
|
-
updated:
|
|
195
|
+
peer: bytesToPeer(peerId, buf, this.maxAddressAge),
|
|
196
|
+
previous: existingPeer?.peer,
|
|
197
|
+
updated: existingPeer == null || !peerEquals(peer, existingPeer.peerPB)
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
#peerIsExpired (peer: PeerPB): boolean {
|
|
202
|
+
if (peer.updated == null) {
|
|
203
|
+
return true
|
|
172
204
|
}
|
|
205
|
+
|
|
206
|
+
const expired = peer.updated < (Date.now() - this.maxPeerAge)
|
|
207
|
+
const minAddressObserved = Date.now() - this.maxAddressAge
|
|
208
|
+
const addrs = peer.addresses.filter(addr => {
|
|
209
|
+
return addr.observed != null && addr.observed > minAddressObserved
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
return expired && addrs.length === 0
|
|
173
213
|
}
|
|
174
214
|
}
|
|
@@ -1,17 +1,35 @@
|
|
|
1
1
|
import { publicKeyFromProtobuf } from '@libp2p/crypto/keys'
|
|
2
2
|
import { peerIdFromPublicKey } from '@libp2p/peer-id'
|
|
3
3
|
import { multiaddr } from '@multiformats/multiaddr'
|
|
4
|
+
import { base58btc } from 'multiformats/bases/base58'
|
|
5
|
+
import * as Digest from 'multiformats/hashes/digest'
|
|
4
6
|
import { Peer as PeerPB } from '../pb/peer.js'
|
|
5
7
|
import type { PeerId, Peer, Tag } from '@libp2p/interface'
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
function populatePublicKey (peerId: PeerId, protobuf: PeerPB): PeerId {
|
|
10
|
+
if (peerId.publicKey != null || protobuf.publicKey == null) {
|
|
11
|
+
return peerId
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let digest: any
|
|
9
15
|
|
|
10
|
-
if (
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
if (peerId.type === 'RSA') {
|
|
17
|
+
// avoid hashing public key
|
|
18
|
+
const multihash = base58btc.decode(`z${peerId}`)
|
|
19
|
+
digest = Digest.decode(multihash)
|
|
13
20
|
}
|
|
14
21
|
|
|
22
|
+
const publicKey = publicKeyFromProtobuf(protobuf.publicKey, digest)
|
|
23
|
+
return peerIdFromPublicKey(publicKey)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function bytesToPeer (peerId: PeerId, buf: Uint8Array, maxAddressAge: number): Peer {
|
|
27
|
+
const peer = PeerPB.decode(buf)
|
|
28
|
+
|
|
29
|
+
return pbToPeer(peerId, peer, maxAddressAge)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function pbToPeer (peerId: PeerId, peer: PeerPB, maxAddressAge: number): Peer {
|
|
15
33
|
const tags = new Map<string, Tag>()
|
|
16
34
|
|
|
17
35
|
// remove any expired tags
|
|
@@ -27,13 +45,16 @@ export function bytesToPeer (peerId: PeerId, buf: Uint8Array): Peer {
|
|
|
27
45
|
|
|
28
46
|
return {
|
|
29
47
|
...peer,
|
|
30
|
-
id: peerId,
|
|
31
|
-
addresses: peer.addresses
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
48
|
+
id: populatePublicKey(peerId, peer),
|
|
49
|
+
addresses: peer.addresses
|
|
50
|
+
// remove any expired multiaddrs
|
|
51
|
+
.filter(({ observed }) => observed != null && observed > (Date.now() - maxAddressAge))
|
|
52
|
+
.map(({ multiaddr: ma, isCertified }) => {
|
|
53
|
+
return {
|
|
54
|
+
multiaddr: multiaddr(ma),
|
|
55
|
+
isCertified: isCertified ?? false
|
|
56
|
+
}
|
|
57
|
+
}),
|
|
37
58
|
metadata: peer.metadata,
|
|
38
59
|
peerRecordEnvelope: peer.peerRecordEnvelope ?? undefined,
|
|
39
60
|
tags
|
|
@@ -4,7 +4,7 @@ import type { AddressFilter } from '../index.js'
|
|
|
4
4
|
import type { Address as AddressPB } from '../pb/peer.js'
|
|
5
5
|
import type { PeerId, Address } from '@libp2p/interface'
|
|
6
6
|
|
|
7
|
-
export async function dedupeFilterAndSortAddresses (peerId: PeerId, filter: AddressFilter, addresses: Array<Address | AddressPB | undefined
|
|
7
|
+
export async function dedupeFilterAndSortAddresses (peerId: PeerId, filter: AddressFilter, addresses: Array<Address | AddressPB | undefined>, existingAddresses?: AddressPB[]): Promise<AddressPB[]> {
|
|
8
8
|
const addressMap = new Map<string, Address>()
|
|
9
9
|
|
|
10
10
|
for (const addr of addresses) {
|