@leofcoin/peernet 0.8.5 → 0.8.9

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.
@@ -86,15 +86,16 @@ globalThis.pubsub = globalThis.pubsub || new PubSub__default['default']({verbose
86
86
  class PeernetClient {
87
87
  constructor(options = {}) {
88
88
  if (!options.id) options.id = Buffer.from('00000000000000000000000000000000');
89
-
89
+ if (!options.networkVersion) options.networkVersion = 'v0.1.0';
90
+ if (!options.networkName) options.networkName = 'peernet';
90
91
  this.id = options.id;
91
92
 
92
- this.topic = Buffer.from(sha256__default['default']('peernet-v0.1.0').toString());
93
+ this.topic = Buffer.from(sha256__default['default'](`${option.networkName}-${options.networkVersion}`).toString());
93
94
 
94
95
  const trackers = [
95
96
  'wss://star.leofcoin.org:7575',
96
97
  'wss://tracker.openwebtorrent.com',
97
- 'wss://tracker.sloppyta.co:443/announce',
98
+ // 'wss://tracker.sloppyta.co:443/announce',
98
99
  ];
99
100
  this.p2p = new P2P__default['default'](trackers, this.topic.slice(0, 20));
100
101
  this.p2p.on('peerconnect', (peer) => {
@@ -104,77 +105,13 @@ class PeernetClient {
104
105
  });
105
106
 
106
107
  this.p2p.on('peerclose', (peer) => {
108
+ // TODO: close peernetPeer
107
109
  connections.delete(peer.id);
108
110
  pubsub.publish('peer:disconnected', peer);
109
111
  });
110
112
 
111
113
  this.p2p.start();
112
114
 
113
-
114
- // this.sw.join(this.topic.slice(0, 32))
115
- //
116
- // const arrayOfPeers = this.sw.getPeers()
117
- //
118
- // this.sw.on('connection', async (connection, info) => {
119
- // // connected
120
- // const id = info.id.toString()
121
- // if (id === this.id.toString()) return
122
- //
123
- // const channel = connection.channelName
124
- // let channels = [channel]
125
- // let peer
126
- // if (connections.has(id)) {
127
- // const value = connections.get(id)
128
- // const _channels = value.channels
129
- // channels = [...channels, ..._channels]
130
- // peer = value.peer
131
- // } else {
132
- // peer = new PeernetPeer(id, connection)
133
- // pubsub.publish('peer:connected', peer)
134
- // }
135
- // connections.set(id, {channels, peer})
136
- // // connection.on('data', (data) => console.log({data}))
137
- // // connection.write('peerId')
138
- // });
139
- //
140
- // this.sw.on('candidates-updated', async (channel, candidates) => {
141
- // // TODO: Channels ...
142
- // for (const candidate of candidates) {
143
- // const id = candidate.toString()
144
- // let channels = [channel]
145
- // if (id === this.id.toString()) return
146
- //
147
- // if (!connections.has(id)) {
148
- // try {
149
- // const connection = await this.sw.connect(channel, candidate)
150
- // const peer = new PeernetPeer(id, connection)
151
- // connections.set(id, {channels, peer})
152
- // if (recentConnections.has(id)) {
153
- // setTimeout(() => {
154
- // pubsub.publish('peer:connected', peer)
155
- // }, 1000)
156
- // } else {
157
- // pubsub.publish('peer:connected', peer)
158
- // }
159
- // } catch (e) {
160
- // console.warn(e);
161
- // }
162
- // } else {
163
- // const value = connections.get(id)
164
- // const _channels = value.channels
165
- // channels = [...channels, ..._channels]
166
- // connections.set(id, {channels, peer: value.peer})
167
- // }
168
- // }
169
- // })
170
- //
171
- // this.sw.on('connection-closed', (connection, info) => {
172
- // if (!recentConnections.has(info.id.toString())) {
173
- // recentConnections.set(info.id.toString(), new Date().getTime())
174
- // }
175
- // if (connections.has(info.id.toString())) connections.delete(info.id.toString())
176
- // })
177
- //
178
115
  if (globalThis.process) {
179
116
  process.on('SIGINT', async () => {
180
117
  console.log('Caught interrupt signal');
@@ -324,7 +261,7 @@ class LeofcoinStorage$1 {
324
261
 
325
262
  }
326
263
 
327
- var version = "0.8.4";
264
+ var version = "0.8.9";
328
265
 
329
266
  var api$1 = {
330
267
  version: ({send}) => send({client: '@peernet/api/http', version}),
@@ -1995,605 +1932,605 @@ const nothingFoundError = (hash) => {
1995
1932
  return new Error(`nothing found for ${hash}`)
1996
1933
  };
1997
1934
 
1998
- globalThis.leofcoin = globalThis.leofcoin || {};
1999
- globalThis.globalSub = globalThis.globalSub || new PubSub__default['default']({verbose: true});
2000
-
2001
- /**
2002
- * @access public
2003
- * @example
2004
- * const peernet = new Peernet();
2005
- */
2006
- class Peernet {
2007
- /**
2008
- * @access public
2009
- * @param {Object} options
2010
- * @param {String} options.network - desired network
2011
- * @param {String} options.root - path to root directory
2012
- * @param {String} options.storePrefix - prefix for datatores (lfc)
2013
- *
2014
- * @return {Promise} instance of Peernet
2015
- *
2016
- * @example
2017
- * const peernet = new Peernet({network: 'leofcoin', root: '.leofcoin'});
2018
- */
2019
- constructor(options = {}) {
2020
- this._discovered = [];
2021
- /**
2022
- * @property {String} network - current network
2023
- */
2024
- this.network = options.network || 'leofcoin';
2025
- const parts = this.network.split(':');
2026
-
2027
- if (!options.storePrefix) options.storePrefix = 'lfc';
2028
- if (!options.port) options.port = 2000;
2029
- if (!options.root) {
2030
- if (parts[1]) options.root = `.${parts[0]}/peernet/${parts[1]}`;
2031
- else options.root = `.${this.network}/peernet`;
2032
- }
2033
- globalThis.peernet = this;
2034
- return this._init(options)
2035
- }
2036
-
2037
- get defaultStores() {
2038
- return ['account', 'wallet', 'block', 'transaction', 'chain', 'data']
2039
- }
2040
-
2041
- addProto(name, proto) {
2042
- if (!globalThis.peernet.protos[name]) globalThis.peernet.protos[name] = proto;
2043
- }
2044
-
2045
- addCodec(name, proto) {
2046
- if (!globalThis.peernet.codecs[name]) globalThis.peernet.codecs[name] = proto;
2047
- }
2048
-
2049
- async addStore(name, prefix, root, isPrivate = true) {
2050
- if (name === 'block' || name === 'transaction' || name === 'chain' ||
2051
- name === 'data') isPrivate = false;
2052
-
2053
- let Storage;
2054
- if (this.hasDaemon) {
2055
- Storage = LeofcoinStorageClient;
2056
- } else {
2057
- Storage = LeofcoinStorage$1;
2058
- }
2059
- globalThis[`${name}Store`] = globalThis[`${name}Store`] ||
2060
- await new Storage(`${prefix}-${name}`, root);
2061
-
2062
- globalThis[`${name}Store`].private = isPrivate;
2063
- if (!isPrivate) this.stores.push(name);
2064
- }
2065
-
2066
-
2067
- /**
2068
- * @see MessageHandler
2069
- */
2070
- prepareMessage(to, data) {
2071
- return this._messageHandler.prepareMessage(this.id, to, data)
2072
- }
2073
-
2074
- get peers() {
2075
- return [...connections.values()]
2076
- }
2077
-
2078
- /**
2079
- * @private
2080
- *
2081
- * @param {Object} options
2082
- * @param {String} options.root - path to root directory
2083
- *
2084
- * @return {Promise} instance of Peernet
2085
- */
2086
- async _init(options) {
2087
- // peernetDHT aka closesPeer by coordinates
2088
- /**
2089
- * @type {Object}
2090
- * @property {Object} peer Instance of Peer
2091
- */
2092
- this.dht = new DhtEarth();
2093
- this.peerMap = new Map();
2094
- this.stores = [];
2095
-
2096
- /**
2097
- * proto Object containing protos
2098
- * @type {Object}
2099
- * @property {PeernetMessage} protos[peernet-message] messageNode
2100
- * @property {DHTMessage} protos[peernet-dht] messageNode
2101
- * @property {DHTMessageResponse} protos[peernet-dht-response] messageNode
2102
- * @property {DataMessage} protos[peernet-data] messageNode
2103
- * @property {DataMessageResponse} protos[peernet-data-response] messageNode
2104
- */
2105
- globalThis.peernet.protos = {
2106
- 'peernet-request': RequestMessage,
2107
- 'peernet-response': ResponseMessage,
2108
- 'peernet-peer': PeerMessage,
2109
- 'peernet-peer-response': PeerMessageResponse,
2110
- 'peernet-message': PeernetMessage,
2111
- 'peernet-dht': DHTMessage,
2112
- 'peernet-dht-response': DHTMessageResponse,
2113
- 'peernet-data': DataMessage,
2114
- 'peernet-data-response': DataMessageResponse,
2115
- 'peernet-ps': PsMessage,
2116
- };
2117
- this.protos = globalThis.peernet.protos;
2118
-
2119
- this._messageHandler = new MessageHandler(this.network);
2120
-
2121
-
2122
- const {daemon, environment} = await target();
2123
- this.hasDaemon = daemon;
2124
-
2125
- if (this.hasDaemon) {
2126
- globalThis.peernet.client = await httpClient({
2127
- protocol: 'peernet-v0.1.0', host: '127.0.0.1', port: options.port,
2128
- });
2129
- } else {
2130
- if (environment !== 'browser') http(options);
2131
- }
2132
-
2133
- for (const store of this.defaultStores) {
2134
- await this.addStore(store, options.storePrefix, options.root);
2135
- }
2136
-
2137
- try {
2138
- const pub = await accountStore.get('public');
2139
- this.id = pub.walletId;
2140
- } catch (e) {
2141
- if (e.code === 'ERR_NOT_FOUND') {
2142
- const wallet = {};
2143
- const {identity, accounts, config} = await generateAccount(this.network);
2144
- wallet.identity = identity;
2145
- wallet.accounts = accounts;
2146
- wallet.version = 1;
2147
- walletStore.put(wallet);
2148
- await accountStore.put('config', config);
2149
- await accountStore.put('public', {walletId: wallet.identity.walletId});
2150
-
2151
- this.id = wallet.identity.walletId;
2152
- } else {
2153
- throw e
2154
- }
2155
- }
2156
- this._peerHandler = new PeerDiscovery(this.id);
2157
- // peernet id
2158
- const id = Buffer.from(this.id.slice(0, 32));
2159
- this.peerId = id;
2160
-
2161
- pubsub.subscribe('peer:discovered', async (peer) => {
2162
- this._peerHandler.discover(peer);
2163
- peer.on('peernet.data', async (message) => {
2164
- const id = message.id;
2165
- message = new PeernetMessage(Buffer.from(message.data.data));
2166
- const proto = protoFor(message.decoded.data);
2167
- await this._protoHandler({id, proto}, peer);
2168
- const fulldId = this._getPeerId(peer.id);
2169
- if (fulldId && this._discovered.indexOf(peer.id) === -1) {
2170
- this._discovered.push(peer.id);
2171
- pubsub.publish('peer:connected', peer);
2172
- }
2173
- });
2174
- });
2175
- pubsub.subscribe('peer:disconnected', async (peer) => {
2176
- let index = this._discovered.indexOf(peer.id);
2177
- if (index !== -1) this._discovered.splice(index, 1);
2178
- const id = this._getPeerId(peer.id);
2179
- let peerIds = this.peerMap.get(id);
2180
-
2181
- if (peerIds) {
2182
- index = peerIds.indexOf(peer.id);
2183
- if (index !== -1) peerIds.splice(index, 1);
2184
- } else {
2185
- peerIds = [];
2186
- }
2187
-
2188
- if (peerIds.length === 0) this.peerMap.delete(id);
2189
- else this.peerMap.set(id, peerIds);
2190
- });
2191
- pubsub.subscribe('peer:connected', async (peer) => {
2192
- console.log({connected: peer.id, as: this._getPeerId(peer.id) });
2193
- // peer.on('peernet.data', async (message) => {
2194
- // const id = message.id
2195
- // message = new PeernetMessage(Buffer.from(message.data.data))
2196
- // const proto = protoFor(message.decoded.data)
2197
- // this._protoHandler({id, proto}, peer)
2198
- // })
2199
- });
2200
-
2201
- /**
2202
- * @access public
2203
- * @type {PeernetClient}
2204
- */
2205
- this.client = new PeernetClient({...options, id});
2206
- return this
2207
- }
2208
-
2209
- _getPeerId(id) {
2210
- for (const entry of [...this.peerMap.entries()]) {
2211
- for (const _id of entry[1]) {
2212
- if (_id === id) return entry[0]
2213
- }
2214
- }
2215
- }
2216
-
2217
- /**
2218
- * @private
2219
- *
2220
- * @param {Buffer} message - peernet message
2221
- * @param {PeernetPeer} peer - peernet peer
2222
- */
2223
- async _protoHandler(message, peer) {
2224
- const {id, proto} = message;
2225
- if (proto.name === 'peernet-peer') {
2226
- const from = proto.decoded.id;
2227
- if (!this.peerMap.has(from)) this.peerMap.set(from, [peer.id]);
2228
- else {
2229
- const connections = this.peerMap.get(from);
2230
- if (connections.indexOf(peer.id) === -1) {
2231
- connections.push(peer.id);
2232
- this.peerMap.set(from, connections);
2233
- }
2234
- }
2235
- const data = new PeerMessageResponse({id: this.id});
2236
- const node = await this.prepareMessage(from, data.encoded);
2237
-
2238
- peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})));
2239
- } else if (proto.name === 'peernet-peer-response') {
2240
- const from = proto.decoded.id;
2241
- if (!this.peerMap.has(from)) this.peerMap.set(from, [peer.id]);
2242
- else {
2243
- const connections = this.peerMap.get(from);
2244
- if (connections.indexOf(peer.id) === -1) {
2245
- connections.push(peer.id);
2246
- this.peerMap.set(from, connections);
2247
- }
2248
- }
2249
- } else {
2250
- let from = this._getPeerId(peer.id);
2251
- if (!from) {
2252
- const data = new PeerMessage({id: this.id});
2253
- const node = await this.prepareMessage(peer.id, data.encoded);
2254
-
2255
- let response = await peer.request(node.encoded);
2256
- response = protoFor(response);
2257
- response = new PeerMessageResponse(response.decoded.data);
2258
-
2259
- from = response.decoded.id;
2260
- if (!this.peerMap.has(from)) this.peerMap.set(from, [peer.id]);
2261
- else {
2262
- const connections = this.peerMap.get(from);
2263
- if (connections.indexOf(peer.id) === -1) {
2264
- connections.push(peer.id);
2265
- this.peerMap.set(from, connections);
2266
- }
2267
- }
2268
- }
2269
- if (proto.name === 'peernet-dht') {
2270
- let { hash, store } = proto.decoded;
2271
- let has;
2272
-
2273
- if (!store) {
2274
- has = await this.has(hash);
2275
- } else {
2276
- store = globalThis[`${store}Store`];
2277
- if (store.private) has = false;
2278
- else has = await store.has(hash);
2279
- }
2280
- const data = new DHTMessageResponse({hash, has});
2281
- const node = await this.prepareMessage(from, data.encoded);
2282
-
2283
- peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})));
2284
- } else if (proto.name === 'peernet-data') {
2285
- let { hash, store } = proto.decoded;
2286
- let data;
2287
-
2288
- if (!store) {
2289
- data = await this.get(hash);
2290
- } else {
2291
- store = globalThis[`${store}Store`];
2292
- if (store.private) {
2293
- // TODO: ban
2294
- return
2295
- } else data = await store.get(hash);
2296
- }
2297
-
2298
- if (data) {
2299
- data = new DataMessageResponse({hash, data: Buffer.from(data)});
2300
-
2301
- const node = await this.prepareMessage(from, data.encoded);
2302
- peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})));
2303
- }
2304
- } else if (proto.name === 'peernet-peer') {
2305
- const from = proto.decoded.id;
2306
- if (!this.peerMap.has(from)) this.peerMap.set(from, [peer.id]);
2307
- else {
2308
- const connections = this.peerMap.get(from);
2309
- connections.push(peer.id);
2310
- this.peerMap.set(from, connections);
2311
- }
2312
- const data = new PeerMessage({id: this.id});
2313
- const node = await this.prepareMessage(from, data.encoded);
2314
-
2315
- peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})));
2316
- } else if (proto.name === 'peernet-request') {
2317
- // TODO: make dynamic
2318
- // exposeddevapi[proto.decoded.request](proto.decoded.params)
2319
- let response;
2320
- if (proto.decoded.request === 'lastBlock') {
2321
- const height = await chainStore.get('localIndex');
2322
- const hash = await chainStore.get('localBlock');
2323
- response = JSON.stringify({ height: height.toString(), hash: hash.toString() });
2324
- const data = new ResponseMessage({ response });
2325
- const node = await this.prepareMessage(from, data.encoded);
2326
-
2327
- peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})));
2328
- }
2329
- } else if (proto.name === 'peernet-ps' &&
2330
- this._getPeerId(peer.id) !== this.id.toString()) {
2331
- globalSub.publish(proto.decoded.topic.toString(), proto.decoded.data.toString());
2332
- }
2333
- }
2334
- }
2335
-
2336
- /**
2337
- * performs a walk and resolves first encounter
2338
- *
2339
- * @param {String} hash
2340
- */
2341
- async walk(hash) {
2342
- if (!hash) throw new Error('hash expected, received undefined')
2343
- const data = new DHTMessage({hash});
2344
- this.client.id;
2345
- for (const peer of this.peers) {
2346
- const node = await this.prepareMessage(peer.id, data.encoded);
2347
-
2348
- const result = await peer.request(node.encoded);
2349
-
2350
- let proto = protoFor(result.data);
2351
-
2352
- if (proto.name !== 'peernet-message') throw encapsulatedError()
2353
- const from = proto.decoded.from;
2354
- proto = protoFor(proto.decoded.data);
2355
-
2356
- if (proto.name !== 'peernet-dht-response') throw dhtError(proto.name)
2357
-
2358
- // TODO: give ip and port (just used for location)
2359
- if (!peer.connection.remoteAddress || !peer.connection.localAddress) {
2360
- peer.connection.remoteFamily = 'ipv4';
2361
- peer.connection.remoteAddress = '127.0.0.1';
2362
- peer.connection.remotePort = '0000';
2363
- }
2364
-
2365
- const peerInfo = {
2366
- family: peer.connection.remoteFamily || peer.connection.localFamily,
2367
- address: peer.connection.remoteAddress || peer.connection.localAddress,
2368
- port: peer.connection.remotePort || peer.connection.localPort,
2369
- id: from,
2370
- };
2371
-
2372
- if (proto.decoded.has) this.dht.addProvider(peerInfo, proto.decoded.hash);
2373
- }
2374
- return
2375
- }
2376
-
2377
- /**
2378
- * Override DHT behavior, try's finding the content three times
2379
- *
2380
- * @param {String} hash
2381
- */
2382
- async providersFor(hash) {
2383
- let providers = await this.dht.providersFor(hash);
2384
- // walk the network to find a provider
2385
- if (!providers || providers.length === 0) {
2386
- await this.walk(hash);
2387
- providers = await this.dht.providersFor(hash);
2388
- // second walk the network to find a provider
2389
- if (!providers || providers.length === 0) {
2390
- await this.walk(hash);
2391
- providers = await this.dht.providersFor(hash);
2392
- }
2393
- // last walk
2394
- if (!providers || providers.length === 0) {
2395
- await this.walk(hash);
2396
- providers = await this.dht.providersFor(hash);
2397
- }
2398
- }
2399
- // undefined if no providers given
2400
- return providers
2401
- }
2402
-
2403
- get block() {
2404
- return {
2405
- get: async (hash) => {
2406
- const data = await blockStore.has(hash);
2407
- if (data) return await blockStore.get(hash)
2408
- return this.requestData(hash)
2409
- },
2410
- put: async (hash, data) => {
2411
- if (await blockStore.has(hash)) return
2412
- return await blockStore.put(hash, data)
2413
- },
2414
- has: async (hash) => await blockStore.has(hash, 'block'),
2415
- }
2416
- }
2417
-
2418
- get transaction() {
2419
- return {
2420
- get: async (hash) => {
2421
- const data = await transactionStore.has(hash);
2422
- if (data) return await transactionStore.get(hash)
2423
- return this.requestData(hash, 'transaction')
2424
- },
2425
- put: async (hash, data) => {
2426
- if (await transactionStore.has(hash)) return
2427
- return await transactionStore.put(hash, data)
2428
- },
2429
- has: async (hash) => await transactionStore.has(hash),
2430
- }
2431
- }
2432
-
2433
- async requestData(hash, store) {
2434
- const providers = await this.providersFor(hash);
2435
- if (!providers || providers.size === 0) throw nothingFoundError(hash)
2436
- debug(`found ${providers.size} provider(s) for ${hash}`);
2437
- // get closest peer on earth
2438
- const closestPeer = await this.dht.closestPeer(providers);
2439
- // get peer instance by id
2440
- if (!closestPeer || !closestPeer.id) return this.requestData(hash, store)
2441
-
2442
- const id = closestPeer.id.toString();
2443
- if (this.peers) {
2444
- let closest = this.peers.filter((peer) => {
2445
- if (this._getPeerId(peer.id) === id) return peer
2446
- });
2447
-
2448
- let data = new DataMessage({hash, store});
2449
-
2450
- const node = await this.prepareMessage(id, data.encoded);
2451
- if (closest[0]) data = await closest[0].request(node.encoded);
2452
- else {
2453
- closest = this.peers.filter((peer) => {
2454
- if (peer.id.toString() === id) return peer
2455
- });
2456
- if (closest[0]) data = await closest[0].request(node.encoded);
2457
- }
2458
- if (data.data) {
2459
- let proto = protoFor(Buffer.from(data.data));
2460
- proto = protoFor(proto.decoded.data);
2461
- return proto.decoded.data
2462
- }
2463
-
2464
- // this.put(hash, proto.decoded.data)
2465
- }
2466
- return null
2467
- }
2468
-
2469
- get data() {
2470
- return {
2471
- /**
2472
- * Get content for given data hash
2473
- *
2474
- * @param {String} hash
2475
- */
2476
- get: async (hash) => {
2477
- debug(`get data ${hash}`);
2478
- const data = await dataStore.has(hash);
2479
- if (data) return await dataStore.get(hash)
2480
- return this.requestData(hash, 'data')
2481
- },
2482
- /**
2483
- * put data content
2484
- *
2485
- * @param {String} hash
2486
- * @param {Buffer} data
2487
- */
2488
- put: async (hash, data) => await dataStore.put(hash, data),
2489
- /**
2490
- * @param {String} hash
2491
- * @return {Boolean}
2492
- */
2493
- has: async (hash) => await dataStore.has(hash),
2494
- }
2495
- }
2496
-
2497
- /**
2498
- * goes trough given stores and tries to find data for given hash
2499
- * @param {Array} stores
2500
- * @param {string} hash
2501
- */
2502
- async whichStore(stores, hash) {
2503
- let store = stores.pop();
2504
- store = globalThis[`${store}Store`];
2505
- if (store) {
2506
- const has = await store.has(hash);
2507
- if (has) return store
2508
- if (stores.length > 0) return this.whichStore(stores, hash)
2509
- } else return null
2510
- }
2511
-
2512
- /**
2513
- * Get content for given hash
2514
- *
2515
- * @param {String} hash
2516
- */
2517
- async get(hash, store) {
2518
- debug(`get ${hash}`);
2519
- let data;
2520
- if (store) store = globalThis[`${store}Store`];
2521
- if (!store) store = await this.whichStore([...this.stores], hash);
2522
- if (store && await store.has(hash)) data = await store.get(hash);
2523
- if (data) return data
2524
-
2525
- return this.requestData(hash, 'data')
2526
- }
2527
-
2528
- /**
2529
- * put content
2530
- *
2531
- * @param {String} hash
2532
- * @param {Buffer} data
2533
- */
2534
- async put(hash, data, store = 'data') {
2535
- store = globalThis[`${store}Store`];
2536
- return await store.put(hash, data)
2537
- }
2538
-
2539
- /**
2540
- * @param {String} hash
2541
- * @return {Boolean}
2542
- */
2543
- async has(hash) {
2544
- const store = await this.whichStore([...this.stores], hash);
2545
- if (store) {
2546
- if (store.private) return false
2547
- else return true
2548
- }
2549
- return false
2550
- }
2551
-
2552
- /**
2553
- *
2554
- * @param {String} topic
2555
- * @param {String|Object|Array|Boolean|Buffer} data
2556
- */
2557
- async publish(topic, data) {
2558
- // globalSub.publish(topic, data)
2559
-
2560
-
2561
- if (!Buffer.isBuffer(topic)) topic = Buffer.from(topic);
2562
- if (!Buffer.isBuffer(data)) data = Buffer.from(data);
2563
- const id = Math.random().toString(36).slice(-12);
2564
- data = new PsMessage({data, topic});
2565
- for (const peer of this.peers) {
2566
- if (peer.connection._connected && peer.id.toString() !== this.peerId.toString()) {
2567
- const node = await this.prepareMessage(peer.id, data.encoded);
2568
- peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})));
2569
- } else {
2570
- this.removePeer(peer);
2571
- }
2572
- // TODO: if peer subscribed
2573
- }
2574
- }
2575
-
2576
- /**
2577
- *
2578
- * @param {String} topic
2579
- * @param {Method} cb
2580
- */
2581
- async subscribe(topic, cb) {
2582
- // TODO: if peer subscribed
2583
- globalSub.subscribe(topic, cb);
2584
- }
2585
-
2586
- async removePeer(peer) {
2587
- connections.delete(peer.id);
2588
- }
2589
- // async block(index) {
2590
- // const _values = []
2591
- // for (const peer of this.peers) {
2592
- // const value = await peer.request({type: 'block', index})
2593
- // console.log(value);
2594
- // }
2595
- //
2596
- // }
1935
+ globalThis.leofcoin = globalThis.leofcoin || {};
1936
+ globalThis.globalSub = globalThis.globalSub || new PubSub__default['default']({verbose: true});
1937
+
1938
+ /**
1939
+ * @access public
1940
+ * @example
1941
+ * const peernet = new Peernet();
1942
+ */
1943
+ class Peernet {
1944
+ /**
1945
+ * @access public
1946
+ * @param {Object} options
1947
+ * @param {String} options.network - desired network
1948
+ * @param {String} options.root - path to root directory
1949
+ * @param {String} options.storePrefix - prefix for datatores (lfc)
1950
+ *
1951
+ * @return {Promise} instance of Peernet
1952
+ *
1953
+ * @example
1954
+ * const peernet = new Peernet({network: 'leofcoin', root: '.leofcoin'});
1955
+ */
1956
+ constructor(options = {}) {
1957
+ this._discovered = [];
1958
+ /**
1959
+ * @property {String} network - current network
1960
+ */
1961
+ this.network = options.network || 'leofcoin';
1962
+ const parts = this.network.split(':');
1963
+
1964
+ if (!options.storePrefix) options.storePrefix = 'lfc';
1965
+ if (!options.port) options.port = 2000;
1966
+ if (!options.root) {
1967
+ if (parts[1]) options.root = `.${parts[0]}/peernet/${parts[1]}`;
1968
+ else options.root = `.${this.network}/peernet`;
1969
+ }
1970
+ globalThis.peernet = this;
1971
+ return this._init(options)
1972
+ }
1973
+
1974
+ get defaultStores() {
1975
+ return ['account', 'wallet', 'block', 'transaction', 'chain', 'data']
1976
+ }
1977
+
1978
+ addProto(name, proto) {
1979
+ if (!globalThis.peernet.protos[name]) globalThis.peernet.protos[name] = proto;
1980
+ }
1981
+
1982
+ addCodec(name, proto) {
1983
+ if (!globalThis.peernet.codecs[name]) globalThis.peernet.codecs[name] = proto;
1984
+ }
1985
+
1986
+ async addStore(name, prefix, root, isPrivate = true) {
1987
+ if (name === 'block' || name === 'transaction' || name === 'chain' ||
1988
+ name === 'data') isPrivate = false;
1989
+
1990
+ let Storage;
1991
+ if (this.hasDaemon) {
1992
+ Storage = LeofcoinStorageClient;
1993
+ } else {
1994
+ Storage = LeofcoinStorage$1;
1995
+ }
1996
+ globalThis[`${name}Store`] = globalThis[`${name}Store`] ||
1997
+ await new Storage(`${prefix}-${name}`, root);
1998
+
1999
+ globalThis[`${name}Store`].private = isPrivate;
2000
+ if (!isPrivate) this.stores.push(name);
2001
+ }
2002
+
2003
+
2004
+ /**
2005
+ * @see MessageHandler
2006
+ */
2007
+ prepareMessage(to, data) {
2008
+ return this._messageHandler.prepareMessage(this.id, to, data)
2009
+ }
2010
+
2011
+ get peers() {
2012
+ return [...connections.values()]
2013
+ }
2014
+
2015
+ /**
2016
+ * @private
2017
+ *
2018
+ * @param {Object} options
2019
+ * @param {String} options.root - path to root directory
2020
+ *
2021
+ * @return {Promise} instance of Peernet
2022
+ */
2023
+ async _init(options) {
2024
+ // peernetDHT aka closesPeer by coordinates
2025
+ /**
2026
+ * @type {Object}
2027
+ * @property {Object} peer Instance of Peer
2028
+ */
2029
+ this.dht = new DhtEarth();
2030
+ this.peerMap = new Map();
2031
+ this.stores = [];
2032
+
2033
+ /**
2034
+ * proto Object containing protos
2035
+ * @type {Object}
2036
+ * @property {PeernetMessage} protos[peernet-message] messageNode
2037
+ * @property {DHTMessage} protos[peernet-dht] messageNode
2038
+ * @property {DHTMessageResponse} protos[peernet-dht-response] messageNode
2039
+ * @property {DataMessage} protos[peernet-data] messageNode
2040
+ * @property {DataMessageResponse} protos[peernet-data-response] messageNode
2041
+ */
2042
+ globalThis.peernet.protos = {
2043
+ 'peernet-request': RequestMessage,
2044
+ 'peernet-response': ResponseMessage,
2045
+ 'peernet-peer': PeerMessage,
2046
+ 'peernet-peer-response': PeerMessageResponse,
2047
+ 'peernet-message': PeernetMessage,
2048
+ 'peernet-dht': DHTMessage,
2049
+ 'peernet-dht-response': DHTMessageResponse,
2050
+ 'peernet-data': DataMessage,
2051
+ 'peernet-data-response': DataMessageResponse,
2052
+ 'peernet-ps': PsMessage,
2053
+ };
2054
+ this.protos = globalThis.peernet.protos;
2055
+
2056
+ this._messageHandler = new MessageHandler(this.network);
2057
+
2058
+
2059
+ const {daemon, environment} = await target();
2060
+ this.hasDaemon = daemon;
2061
+
2062
+ if (this.hasDaemon) {
2063
+ globalThis.peernet.client = await httpClient({
2064
+ protocol: 'peernet-v0.1.0', host: '127.0.0.1', port: options.port,
2065
+ });
2066
+ } else {
2067
+ if (environment !== 'browser') http(options);
2068
+ }
2069
+
2070
+ for (const store of this.defaultStores) {
2071
+ await this.addStore(store, options.storePrefix, options.root);
2072
+ }
2073
+
2074
+ try {
2075
+ const pub = await accountStore.get('public');
2076
+ this.id = pub.walletId;
2077
+ } catch (e) {
2078
+ if (e.code === 'ERR_NOT_FOUND') {
2079
+ const wallet = {};
2080
+ const {identity, accounts, config} = await generateAccount(this.network);
2081
+ wallet.identity = identity;
2082
+ wallet.accounts = accounts;
2083
+ wallet.version = 1;
2084
+ walletStore.put(wallet);
2085
+ await accountStore.put('config', config);
2086
+ await accountStore.put('public', {walletId: wallet.identity.walletId});
2087
+
2088
+ this.id = wallet.identity.walletId;
2089
+ } else {
2090
+ throw e
2091
+ }
2092
+ }
2093
+ this._peerHandler = new PeerDiscovery(this.id);
2094
+ // peernet id
2095
+ const id = Buffer.from(this.id.slice(0, 32));
2096
+ this.peerId = id;
2097
+
2098
+ pubsub.subscribe('peer:discovered', async (peer) => {
2099
+ this._peerHandler.discover(peer);
2100
+ peer.on('peernet.data', async (message) => {
2101
+ const id = message.id;
2102
+ message = new PeernetMessage(Buffer.from(message.data.data));
2103
+ const proto = protoFor(message.decoded.data);
2104
+ await this._protoHandler({id, proto}, peer);
2105
+ const fulldId = this._getPeerId(peer.id);
2106
+ if (fulldId && this._discovered.indexOf(peer.id) === -1) {
2107
+ this._discovered.push(peer.id);
2108
+ pubsub.publish('peer:connected', peer);
2109
+ }
2110
+ });
2111
+ });
2112
+ pubsub.subscribe('peer:disconnected', async (peer) => {
2113
+ let index = this._discovered.indexOf(peer.id);
2114
+ if (index !== -1) this._discovered.splice(index, 1);
2115
+ const id = this._getPeerId(peer.id);
2116
+ let peerIds = this.peerMap.get(id);
2117
+
2118
+ if (peerIds) {
2119
+ index = peerIds.indexOf(peer.id);
2120
+ if (index !== -1) peerIds.splice(index, 1);
2121
+ } else {
2122
+ peerIds = [];
2123
+ }
2124
+
2125
+ if (peerIds.length === 0) this.peerMap.delete(id);
2126
+ else this.peerMap.set(id, peerIds);
2127
+ });
2128
+ pubsub.subscribe('peer:connected', async (peer) => {
2129
+ console.log({connected: peer.id, as: this._getPeerId(peer.id) });
2130
+ // peer.on('peernet.data', async (message) => {
2131
+ // const id = message.id
2132
+ // message = new PeernetMessage(Buffer.from(message.data.data))
2133
+ // const proto = protoFor(message.decoded.data)
2134
+ // this._protoHandler({id, proto}, peer)
2135
+ // })
2136
+ });
2137
+
2138
+ /**
2139
+ * @access public
2140
+ * @type {PeernetClient}
2141
+ */
2142
+ this.client = new PeernetClient({...options, id});
2143
+ return this
2144
+ }
2145
+
2146
+ _getPeerId(id) {
2147
+ for (const entry of [...this.peerMap.entries()]) {
2148
+ for (const _id of entry[1]) {
2149
+ if (_id === id) return entry[0]
2150
+ }
2151
+ }
2152
+ }
2153
+
2154
+ /**
2155
+ * @private
2156
+ *
2157
+ * @param {Buffer} message - peernet message
2158
+ * @param {PeernetPeer} peer - peernet peer
2159
+ */
2160
+ async _protoHandler(message, peer) {
2161
+ const {id, proto} = message;
2162
+ if (proto.name === 'peernet-peer') {
2163
+ const from = proto.decoded.id;
2164
+ if (!this.peerMap.has(from)) this.peerMap.set(from, [peer.id]);
2165
+ else {
2166
+ const connections = this.peerMap.get(from);
2167
+ if (connections.indexOf(peer.id) === -1) {
2168
+ connections.push(peer.id);
2169
+ this.peerMap.set(from, connections);
2170
+ }
2171
+ }
2172
+ const data = new PeerMessageResponse({id: this.id});
2173
+ const node = await this.prepareMessage(from, data.encoded);
2174
+
2175
+ peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})));
2176
+ } else if (proto.name === 'peernet-peer-response') {
2177
+ const from = proto.decoded.id;
2178
+ if (!this.peerMap.has(from)) this.peerMap.set(from, [peer.id]);
2179
+ else {
2180
+ const connections = this.peerMap.get(from);
2181
+ if (connections.indexOf(peer.id) === -1) {
2182
+ connections.push(peer.id);
2183
+ this.peerMap.set(from, connections);
2184
+ }
2185
+ }
2186
+ } else {
2187
+ let from = this._getPeerId(peer.id);
2188
+ if (!from) {
2189
+ const data = new PeerMessage({id: this.id});
2190
+ const node = await this.prepareMessage(peer.id, data.encoded);
2191
+
2192
+ let response = await peer.request(node.encoded);
2193
+ response = protoFor(response);
2194
+ response = new PeerMessageResponse(response.decoded.data);
2195
+
2196
+ from = response.decoded.id;
2197
+ if (!this.peerMap.has(from)) this.peerMap.set(from, [peer.id]);
2198
+ else {
2199
+ const connections = this.peerMap.get(from);
2200
+ if (connections.indexOf(peer.id) === -1) {
2201
+ connections.push(peer.id);
2202
+ this.peerMap.set(from, connections);
2203
+ }
2204
+ }
2205
+ }
2206
+ if (proto.name === 'peernet-dht') {
2207
+ let { hash, store } = proto.decoded;
2208
+ let has;
2209
+
2210
+ if (!store) {
2211
+ has = await this.has(hash);
2212
+ } else {
2213
+ store = globalThis[`${store}Store`];
2214
+ if (store.private) has = false;
2215
+ else has = await store.has(hash);
2216
+ }
2217
+ const data = new DHTMessageResponse({hash, has});
2218
+ const node = await this.prepareMessage(from, data.encoded);
2219
+
2220
+ peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})));
2221
+ } else if (proto.name === 'peernet-data') {
2222
+ let { hash, store } = proto.decoded;
2223
+ let data;
2224
+
2225
+ if (!store) {
2226
+ data = await this.get(hash);
2227
+ } else {
2228
+ store = globalThis[`${store}Store`];
2229
+ if (store.private) {
2230
+ // TODO: ban
2231
+ return
2232
+ } else data = await store.get(hash);
2233
+ }
2234
+
2235
+ if (data) {
2236
+ data = new DataMessageResponse({hash, data: Buffer.from(data)});
2237
+
2238
+ const node = await this.prepareMessage(from, data.encoded);
2239
+ peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})));
2240
+ }
2241
+ } else if (proto.name === 'peernet-peer') {
2242
+ const from = proto.decoded.id;
2243
+ if (!this.peerMap.has(from)) this.peerMap.set(from, [peer.id]);
2244
+ else {
2245
+ const connections = this.peerMap.get(from);
2246
+ connections.push(peer.id);
2247
+ this.peerMap.set(from, connections);
2248
+ }
2249
+ const data = new PeerMessage({id: this.id});
2250
+ const node = await this.prepareMessage(from, data.encoded);
2251
+
2252
+ peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})));
2253
+ } else if (proto.name === 'peernet-request') {
2254
+ // TODO: make dynamic
2255
+ // exposeddevapi[proto.decoded.request](proto.decoded.params)
2256
+ let response;
2257
+ if (proto.decoded.request === 'lastBlock') {
2258
+ const height = await chainStore.get('localIndex');
2259
+ const hash = await chainStore.get('localBlock');
2260
+ response = JSON.stringify({ height: height.toString(), hash: hash.toString() });
2261
+ const data = new ResponseMessage({ response });
2262
+ const node = await this.prepareMessage(from, data.encoded);
2263
+
2264
+ peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})));
2265
+ }
2266
+ } else if (proto.name === 'peernet-ps' &&
2267
+ this._getPeerId(peer.id) !== this.id.toString()) {
2268
+ globalSub.publish(proto.decoded.topic.toString(), proto.decoded.data.toString());
2269
+ }
2270
+ }
2271
+ }
2272
+
2273
+ /**
2274
+ * performs a walk and resolves first encounter
2275
+ *
2276
+ * @param {String} hash
2277
+ */
2278
+ async walk(hash) {
2279
+ if (!hash) throw new Error('hash expected, received undefined')
2280
+ const data = new DHTMessage({hash});
2281
+ this.client.id;
2282
+ for (const peer of this.peers) {
2283
+ const node = await this.prepareMessage(peer.id, data.encoded);
2284
+
2285
+ const result = await peer.request(node.encoded);
2286
+
2287
+ let proto = protoFor(result.data);
2288
+
2289
+ if (proto.name !== 'peernet-message') throw encapsulatedError()
2290
+ const from = proto.decoded.from;
2291
+ proto = protoFor(proto.decoded.data);
2292
+
2293
+ if (proto.name !== 'peernet-dht-response') throw dhtError(proto.name)
2294
+
2295
+ // TODO: give ip and port (just used for location)
2296
+ if (!peer.connection.remoteAddress || !peer.connection.localAddress) {
2297
+ peer.connection.remoteFamily = 'ipv4';
2298
+ peer.connection.remoteAddress = '127.0.0.1';
2299
+ peer.connection.remotePort = '0000';
2300
+ }
2301
+
2302
+ const peerInfo = {
2303
+ family: peer.connection.remoteFamily || peer.connection.localFamily,
2304
+ address: peer.connection.remoteAddress || peer.connection.localAddress,
2305
+ port: peer.connection.remotePort || peer.connection.localPort,
2306
+ id: from,
2307
+ };
2308
+
2309
+ if (proto.decoded.has) this.dht.addProvider(peerInfo, proto.decoded.hash);
2310
+ }
2311
+ return
2312
+ }
2313
+
2314
+ /**
2315
+ * Override DHT behavior, try's finding the content three times
2316
+ *
2317
+ * @param {String} hash
2318
+ */
2319
+ async providersFor(hash) {
2320
+ let providers = await this.dht.providersFor(hash);
2321
+ // walk the network to find a provider
2322
+ if (!providers || providers.length === 0) {
2323
+ await this.walk(hash);
2324
+ providers = await this.dht.providersFor(hash);
2325
+ // second walk the network to find a provider
2326
+ if (!providers || providers.length === 0) {
2327
+ await this.walk(hash);
2328
+ providers = await this.dht.providersFor(hash);
2329
+ }
2330
+ // last walk
2331
+ if (!providers || providers.length === 0) {
2332
+ await this.walk(hash);
2333
+ providers = await this.dht.providersFor(hash);
2334
+ }
2335
+ }
2336
+ // undefined if no providers given
2337
+ return providers
2338
+ }
2339
+
2340
+ get block() {
2341
+ return {
2342
+ get: async (hash) => {
2343
+ const data = await blockStore.has(hash);
2344
+ if (data) return await blockStore.get(hash)
2345
+ return this.requestData(hash)
2346
+ },
2347
+ put: async (hash, data) => {
2348
+ if (await blockStore.has(hash)) return
2349
+ return await blockStore.put(hash, data)
2350
+ },
2351
+ has: async (hash) => await blockStore.has(hash, 'block'),
2352
+ }
2353
+ }
2354
+
2355
+ get transaction() {
2356
+ return {
2357
+ get: async (hash) => {
2358
+ const data = await transactionStore.has(hash);
2359
+ if (data) return await transactionStore.get(hash)
2360
+ return this.requestData(hash, 'transaction')
2361
+ },
2362
+ put: async (hash, data) => {
2363
+ if (await transactionStore.has(hash)) return
2364
+ return await transactionStore.put(hash, data)
2365
+ },
2366
+ has: async (hash) => await transactionStore.has(hash),
2367
+ }
2368
+ }
2369
+
2370
+ async requestData(hash, store) {
2371
+ const providers = await this.providersFor(hash);
2372
+ if (!providers || providers.size === 0) throw nothingFoundError(hash)
2373
+ debug(`found ${providers.size} provider(s) for ${hash}`);
2374
+ // get closest peer on earth
2375
+ const closestPeer = await this.dht.closestPeer(providers);
2376
+ // get peer instance by id
2377
+ if (!closestPeer || !closestPeer.id) return this.requestData(hash, store)
2378
+
2379
+ const id = closestPeer.id.toString();
2380
+ if (this.peers) {
2381
+ let closest = this.peers.filter((peer) => {
2382
+ if (this._getPeerId(peer.id) === id) return peer
2383
+ });
2384
+
2385
+ let data = new DataMessage({hash, store});
2386
+
2387
+ const node = await this.prepareMessage(id, data.encoded);
2388
+ if (closest[0]) data = await closest[0].request(node.encoded);
2389
+ else {
2390
+ closest = this.peers.filter((peer) => {
2391
+ if (peer.id.toString() === id) return peer
2392
+ });
2393
+ if (closest[0]) data = await closest[0].request(node.encoded);
2394
+ }
2395
+ if (data.data) {
2396
+ let proto = protoFor(Buffer.from(data.data));
2397
+ proto = protoFor(proto.decoded.data);
2398
+ return proto.decoded.data
2399
+ }
2400
+
2401
+ // this.put(hash, proto.decoded.data)
2402
+ }
2403
+ return null
2404
+ }
2405
+
2406
+ get data() {
2407
+ return {
2408
+ /**
2409
+ * Get content for given data hash
2410
+ *
2411
+ * @param {String} hash
2412
+ */
2413
+ get: async (hash) => {
2414
+ debug(`get data ${hash}`);
2415
+ const data = await dataStore.has(hash);
2416
+ if (data) return await dataStore.get(hash)
2417
+ return this.requestData(hash, 'data')
2418
+ },
2419
+ /**
2420
+ * put data content
2421
+ *
2422
+ * @param {String} hash
2423
+ * @param {Buffer} data
2424
+ */
2425
+ put: async (hash, data) => await dataStore.put(hash, data),
2426
+ /**
2427
+ * @param {String} hash
2428
+ * @return {Boolean}
2429
+ */
2430
+ has: async (hash) => await dataStore.has(hash),
2431
+ }
2432
+ }
2433
+
2434
+ /**
2435
+ * goes trough given stores and tries to find data for given hash
2436
+ * @param {Array} stores
2437
+ * @param {string} hash
2438
+ */
2439
+ async whichStore(stores, hash) {
2440
+ let store = stores.pop();
2441
+ store = globalThis[`${store}Store`];
2442
+ if (store) {
2443
+ const has = await store.has(hash);
2444
+ if (has) return store
2445
+ if (stores.length > 0) return this.whichStore(stores, hash)
2446
+ } else return null
2447
+ }
2448
+
2449
+ /**
2450
+ * Get content for given hash
2451
+ *
2452
+ * @param {String} hash
2453
+ */
2454
+ async get(hash, store) {
2455
+ debug(`get ${hash}`);
2456
+ let data;
2457
+ if (store) store = globalThis[`${store}Store`];
2458
+ if (!store) store = await this.whichStore([...this.stores], hash);
2459
+ if (store && await store.has(hash)) data = await store.get(hash);
2460
+ if (data) return data
2461
+
2462
+ return this.requestData(hash, 'data')
2463
+ }
2464
+
2465
+ /**
2466
+ * put content
2467
+ *
2468
+ * @param {String} hash
2469
+ * @param {Buffer} data
2470
+ */
2471
+ async put(hash, data, store = 'data') {
2472
+ store = globalThis[`${store}Store`];
2473
+ return await store.put(hash, data)
2474
+ }
2475
+
2476
+ /**
2477
+ * @param {String} hash
2478
+ * @return {Boolean}
2479
+ */
2480
+ async has(hash) {
2481
+ const store = await this.whichStore([...this.stores], hash);
2482
+ if (store) {
2483
+ if (store.private) return false
2484
+ else return true
2485
+ }
2486
+ return false
2487
+ }
2488
+
2489
+ /**
2490
+ *
2491
+ * @param {String} topic
2492
+ * @param {String|Object|Array|Boolean|Buffer} data
2493
+ */
2494
+ async publish(topic, data) {
2495
+ // globalSub.publish(topic, data)
2496
+
2497
+
2498
+ if (!Buffer.isBuffer(topic)) topic = Buffer.from(topic);
2499
+ if (!Buffer.isBuffer(data)) data = Buffer.from(data);
2500
+ const id = Math.random().toString(36).slice(-12);
2501
+ data = new PsMessage({data, topic});
2502
+ for (const peer of this.peers) {
2503
+ if (peer.connection._connected && peer.id.toString() !== this.peerId.toString()) {
2504
+ const node = await this.prepareMessage(peer.id, data.encoded);
2505
+ peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})));
2506
+ } else {
2507
+ this.removePeer(peer);
2508
+ }
2509
+ // TODO: if peer subscribed
2510
+ }
2511
+ }
2512
+
2513
+ /**
2514
+ *
2515
+ * @param {String} topic
2516
+ * @param {Method} cb
2517
+ */
2518
+ async subscribe(topic, cb) {
2519
+ // TODO: if peer subscribed
2520
+ globalSub.subscribe(topic, cb);
2521
+ }
2522
+
2523
+ async removePeer(peer) {
2524
+ connections.delete(peer.id);
2525
+ }
2526
+ // async block(index) {
2527
+ // const _values = []
2528
+ // for (const peer of this.peers) {
2529
+ // const value = await peer.request({type: 'block', index})
2530
+ // console.log(value);
2531
+ // }
2532
+ //
2533
+ // }
2597
2534
  }
2598
2535
 
2599
2536
  module.exports = Peernet;