@leofcoin/peernet 0.10.7 → 0.11.1
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 +1 -1
- package/README.md +49 -49
- package/coverage/lcov-report/block-navigation.js +8 -0
- package/coverage/lcov-report/codec-format-interface.js.html +224 -120
- package/coverage/lcov-report/dht-response.js.html +44 -39
- package/coverage/lcov-report/index.html +39 -64
- package/coverage/lcov-report/sorter.js +26 -0
- package/coverage/lcov.info +164 -424
- package/dist/browser/peernet.js +101788 -93018
- package/dist/commonjs/client-1a1f75e6.js +324 -0
- package/dist/commonjs/{codec-6367213c.js → codec-8c8c652f.js} +198 -188
- package/dist/commonjs/codec-format-interface.js +169 -152
- package/dist/commonjs/codec.js +4 -4
- package/dist/commonjs/dht-response.js +13 -13
- package/dist/commonjs/dht.js +24 -24
- package/dist/commonjs/hash.js +151 -141
- package/dist/commonjs/{http-a94c5a81.js → http-7bbac90a.js} +19 -15
- package/dist/commonjs/peernet-message.js +13 -13
- package/dist/commonjs/peernet.js +1901 -1794
- package/dist/commonjs/request.js +13 -13
- package/dist/commonjs/response.js +13 -13
- package/dist/module/peernet.js +2460 -2346
- package/index.html +4 -6
- package/package.json +22 -14
- package/rollup.config.js +33 -5
- package/rollup0.config.js +7 -0
- package/src/client.js +75 -75
- package/src/codec/codec-format-interface.js +172 -155
- package/src/codec/codec.js +124 -114
- package/src/codec/codecs.js +79 -79
- package/src/dht/dht.js +121 -121
- package/src/discovery/peer-discovery.js +75 -75
- package/src/handlers/message.js +52 -52
- package/src/hash/hash.js +155 -145
- package/src/http/client/http-client.js +44 -44
- package/src/messages/chat-message.js +14 -14
- package/src/messages/data-response.js +14 -14
- package/src/messages/data.js +18 -18
- package/src/messages/dht-response.js +14 -15
- package/src/messages/dht.js +25 -25
- package/src/messages/peer-response.js +14 -14
- package/src/messages/peer.js +14 -14
- package/src/messages/peernet-message.js +14 -14
- package/src/messages/ps.js +14 -14
- package/src/messages/request.js +14 -14
- package/src/messages/response.js +14 -14
- package/src/peer.js +67 -67
- package/src/peernet.js +612 -697
- package/src/proto/chat-message.proto.js +7 -7
- package/src/utils/utils.js +78 -78
- package/test/codec.js +3 -2
- package/test/messages.js +7 -4
- package/test.js +11 -4
- package/webpack.config.js +35 -0
- package/coverage/lcov-report/codec.js.html +0 -677
- package/coverage/lcov-report/hash.js.html +0 -551
- package/debug.log +0 -3
- package/dist/browser/peernet.js.tmp-browserify-14074318104595318069 +0 -0
- package/dist/browser/peernet.js.tmp-browserify-45407634493269122267 +0 -0
- package/dist/browser/peernet.js.tmp-browserify-53722389064799025427 +0 -0
- package/dist/browser/peernet.js.tmp-browserify-96323030449218949300 +0 -0
- package/dist/codec/codec-format-interface.js +0 -433
- package/dist/codec/codec.js +0 -199
- package/dist/commonjs/codec-73adfc0f.js +0 -205
- package/dist/commonjs/http-2c603501.js +0 -324
- package/dist/commonjs/http-42a6e555.js +0 -324
- package/dist/commonjs/http-43f4fafe.js +0 -324
- package/dist/commonjs/peernet-message-b6925673.js +0 -32
- package/dist/hash/hash.js +0 -340
- package/dist/messages/dht-response.js +0 -454
- package/dist/messages/dht.js +0 -453
- package/dist/messages/peernet.js +0 -456
- package/dist/module/http-273664bd.js +0 -317
- package/dist/module/http-8fe3c0d7.js +0 -317
- package/dist/module/http-c780c991.js +0 -317
- package/dist/module/http-f13e0d77.js +0 -317
package/src/codec/codec.js
CHANGED
|
@@ -1,114 +1,124 @@
|
|
|
1
|
-
import varint from 'varint';
|
|
2
|
-
import bs32 from '
|
|
3
|
-
import bs58 from '
|
|
4
|
-
import isHex from 'is-hex';
|
|
5
|
-
import codecs from './codecs'
|
|
6
|
-
|
|
7
|
-
export default class PeernetCodec {
|
|
8
|
-
get codecs() {
|
|
9
|
-
return {...globalThis.peernet.codecs, ...codecs}
|
|
10
|
-
}
|
|
11
|
-
constructor(buffer) {
|
|
12
|
-
if (buffer) {
|
|
13
|
-
if (
|
|
14
|
-
const codec = varint.decode(buffer);
|
|
15
|
-
const name = this.getCodecName(codec)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
this.
|
|
19
|
-
this.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
this.encoded =
|
|
50
|
-
this.decode()
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
this.encoded =
|
|
55
|
-
this.decode()
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
this.
|
|
86
|
-
this.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
this.
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
this.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
this.encoded
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
1
|
+
import varint from 'varint';
|
|
2
|
+
import bs32 from '@vandeurenglenn/base32';
|
|
3
|
+
import bs58 from '@vandeurenglenn/base58';
|
|
4
|
+
import isHex from '@vandeurenglenn/is-hex';
|
|
5
|
+
import codecs from './codecs'
|
|
6
|
+
|
|
7
|
+
export default class PeernetCodec {
|
|
8
|
+
get codecs() {
|
|
9
|
+
return {...globalThis.peernet.codecs, ...codecs}
|
|
10
|
+
}
|
|
11
|
+
constructor(buffer) {
|
|
12
|
+
if (buffer) {
|
|
13
|
+
if (buffer instanceof Uint8Array) {
|
|
14
|
+
const codec = varint.decode(buffer);
|
|
15
|
+
const name = this.getCodecName(codec)
|
|
16
|
+
if (name) {
|
|
17
|
+
this.name = name
|
|
18
|
+
this.encoded = buffer
|
|
19
|
+
this.decode(buffer)
|
|
20
|
+
} else {
|
|
21
|
+
this.encode(buffer)
|
|
22
|
+
}
|
|
23
|
+
} else if (buffer instanceof ArrayBuffer) {
|
|
24
|
+
const encoded = new Uint8Array(buffer.byteLength)
|
|
25
|
+
|
|
26
|
+
for (let i = 0; i < buffer.byteLength; i++) {
|
|
27
|
+
encoded[i] = buffer[i]
|
|
28
|
+
}
|
|
29
|
+
this.encoded = encoded
|
|
30
|
+
// this.encoded = new Uint8Array(buffer, buffer.byteOffset, buffer.byteLength)
|
|
31
|
+
this.decode(buffer)
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
if (typeof buffer === 'string') {
|
|
35
|
+
if (this.codecs[buffer]) this.fromName(buffer)
|
|
36
|
+
else if (isHex(buffer)) this.fromHex(buffer)
|
|
37
|
+
else if (bs32.isBase32(buffer)) this.fromBs32(buffer)
|
|
38
|
+
else if (bs58.isBase58(buffer)) this.fromBs58(buffer)
|
|
39
|
+
else throw new Error(`unsupported string ${buffer}`)
|
|
40
|
+
}
|
|
41
|
+
if (!isNaN(buffer)) if (this.codecs[this.getCodecName(buffer)]) this.fromCodec(buffer)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
fromEncoded(encoded) {
|
|
46
|
+
const codec = varint.decode(encoded);
|
|
47
|
+
const name = this.getCodecName(codec)
|
|
48
|
+
this.name = name
|
|
49
|
+
this.encoded = encoded
|
|
50
|
+
this.decode(encoded)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
fromHex(hex) {
|
|
54
|
+
this.encoded = Buffer.from(hex, 'hex')
|
|
55
|
+
this.decode()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
fromBs32(input) {
|
|
59
|
+
this.encoded = bs32.decode(input)
|
|
60
|
+
this.decode()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
fromBs58(input) {
|
|
64
|
+
this.encoded = bs58.decode(input)
|
|
65
|
+
this.decode()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
getCodec(name) {
|
|
69
|
+
return this.codecs[name].codec
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
getCodecName(codec) {
|
|
73
|
+
return Object.keys(this.codecs).reduce((p, c) => {
|
|
74
|
+
const item = this.codecs[c]
|
|
75
|
+
if (item.codec === codec) return c;
|
|
76
|
+
else return p;
|
|
77
|
+
}, undefined)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
getHashAlg(name) {
|
|
81
|
+
return this.codecs[name].hashAlg
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
fromCodec(codec) {
|
|
85
|
+
this.name = this.getCodecName(codec)
|
|
86
|
+
this.hashAlg = this.getHashAlg(this.name)
|
|
87
|
+
|
|
88
|
+
this.codec = this.getCodec(this.name)
|
|
89
|
+
this.codecBuffer = varint.encode(codec)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
fromName(name) {
|
|
93
|
+
const codec = this.getCodec(name)
|
|
94
|
+
this.name = name
|
|
95
|
+
this.codec = codec
|
|
96
|
+
this.hashAlg = this.getHashAlg(name)
|
|
97
|
+
this.codecBuffer = varint.encode(codec)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
toBs32() {
|
|
101
|
+
this.encode()
|
|
102
|
+
return bs32.encode(this.encoded)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
toBs58() {
|
|
106
|
+
this.encode()
|
|
107
|
+
return bs58.encode(this.encoded)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
toHex() {
|
|
111
|
+
return this.encoded.toString('hex')
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
decode() {
|
|
115
|
+
const codec = varint.decode(this.encoded);
|
|
116
|
+
this.fromCodec(codec)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
encode() {
|
|
120
|
+
const codec = varint.encode(this.decoded)
|
|
121
|
+
this.encoded = codec
|
|
122
|
+
return this.encoded
|
|
123
|
+
}
|
|
124
|
+
}
|
package/src/codec/codecs.js
CHANGED
|
@@ -1,79 +1,79 @@
|
|
|
1
|
-
export default {
|
|
2
|
-
// just a hash
|
|
3
|
-
'disco-hash': {
|
|
4
|
-
codec: '30',
|
|
5
|
-
hashAlg: 'dbl-keccak-512', // ,
|
|
6
|
-
// testnet: 'olivia'
|
|
7
|
-
},
|
|
8
|
-
'peernet-peer-response': {
|
|
9
|
-
codec: '707072',
|
|
10
|
-
hashAlg: 'keccak-256',
|
|
11
|
-
},
|
|
12
|
-
'peernet-peer': {
|
|
13
|
-
codec: '7070',
|
|
14
|
-
hashAlg: 'keccak-256',
|
|
15
|
-
},
|
|
16
|
-
'peernet-dht': {
|
|
17
|
-
codec: '706468',
|
|
18
|
-
hashAlg: 'keccak-256',
|
|
19
|
-
},
|
|
20
|
-
'peernet-dht-response': {
|
|
21
|
-
codec: '706472',
|
|
22
|
-
hashAlg: 'keccak-256',
|
|
23
|
-
},
|
|
24
|
-
// data
|
|
25
|
-
'peernet-data': {
|
|
26
|
-
codec: '706461',
|
|
27
|
-
hashAlg: 'keccak-256',
|
|
28
|
-
},
|
|
29
|
-
'peernet-data-response': {
|
|
30
|
-
codec: '70646172',
|
|
31
|
-
hashAlg: 'keccak-256',
|
|
32
|
-
},
|
|
33
|
-
// message
|
|
34
|
-
'peernet-message': {
|
|
35
|
-
codec: '706d65',
|
|
36
|
-
hashAlg: 'keccak-512',
|
|
37
|
-
},
|
|
38
|
-
// pubsub
|
|
39
|
-
'peernet-ps': {
|
|
40
|
-
codec: '707073',
|
|
41
|
-
hashAlg: 'keccak-256',
|
|
42
|
-
},
|
|
43
|
-
'peernet-response': {
|
|
44
|
-
codec: '7072',
|
|
45
|
-
hashAlg: 'keccak-256',
|
|
46
|
-
},
|
|
47
|
-
'peernet-request': {
|
|
48
|
-
codec: '707271',
|
|
49
|
-
hashAlg: 'keccak-256',
|
|
50
|
-
},
|
|
51
|
-
// normal block
|
|
52
|
-
'leofcoin-block': {
|
|
53
|
-
codec: '6c62',
|
|
54
|
-
hashAlg: 'dbl-keccak-512', // ,
|
|
55
|
-
// testnet: 'olivia'
|
|
56
|
-
},
|
|
57
|
-
'leofcoin-tx': {
|
|
58
|
-
codec: '6c74',
|
|
59
|
-
hashAlg: 'dbl-keccak-512', // ,
|
|
60
|
-
// testnet: 'olivia'
|
|
61
|
-
},
|
|
62
|
-
// itx
|
|
63
|
-
'leofcoin-itx': {
|
|
64
|
-
codec: '6c69',
|
|
65
|
-
hashAlg: 'keccak-512', // ,
|
|
66
|
-
// testnet: 'olivia'
|
|
67
|
-
},
|
|
68
|
-
// peer reputation
|
|
69
|
-
'leofcoin-pr': {
|
|
70
|
-
codec: '6c70',
|
|
71
|
-
hashAlg: 'keccak-256', // ,
|
|
72
|
-
// testnet: 'olivia'
|
|
73
|
-
},
|
|
74
|
-
// chat message
|
|
75
|
-
'chat-message': {
|
|
76
|
-
codec: '636d',
|
|
77
|
-
hashAlg: 'dbl-keccak-512',
|
|
78
|
-
},
|
|
79
|
-
}
|
|
1
|
+
export default {
|
|
2
|
+
// just a hash
|
|
3
|
+
'disco-hash': {
|
|
4
|
+
codec: parseInt('30', 16),
|
|
5
|
+
hashAlg: 'dbl-keccak-512', // ,
|
|
6
|
+
// testnet: 'olivia'
|
|
7
|
+
},
|
|
8
|
+
'peernet-peer-response': {
|
|
9
|
+
codec: parseInt('707072', 16),
|
|
10
|
+
hashAlg: 'keccak-256',
|
|
11
|
+
},
|
|
12
|
+
'peernet-peer': {
|
|
13
|
+
codec: parseInt('7070', 16),
|
|
14
|
+
hashAlg: 'keccak-256',
|
|
15
|
+
},
|
|
16
|
+
'peernet-dht': {
|
|
17
|
+
codec: parseInt('706468', 16),
|
|
18
|
+
hashAlg: 'keccak-256',
|
|
19
|
+
},
|
|
20
|
+
'peernet-dht-response': {
|
|
21
|
+
codec: parseInt('706472', 16),
|
|
22
|
+
hashAlg: 'keccak-256',
|
|
23
|
+
},
|
|
24
|
+
// data
|
|
25
|
+
'peernet-data': {
|
|
26
|
+
codec: parseInt('706461', 16),
|
|
27
|
+
hashAlg: 'keccak-256',
|
|
28
|
+
},
|
|
29
|
+
'peernet-data-response': {
|
|
30
|
+
codec: parseInt('70646172', 16),
|
|
31
|
+
hashAlg: 'keccak-256',
|
|
32
|
+
},
|
|
33
|
+
// message
|
|
34
|
+
'peernet-message': {
|
|
35
|
+
codec: parseInt('706d65', 16),
|
|
36
|
+
hashAlg: 'keccak-512',
|
|
37
|
+
},
|
|
38
|
+
// pubsub
|
|
39
|
+
'peernet-ps': {
|
|
40
|
+
codec: parseInt('707073', 16),
|
|
41
|
+
hashAlg: 'keccak-256',
|
|
42
|
+
},
|
|
43
|
+
'peernet-response': {
|
|
44
|
+
codec: parseInt('7072', 16),
|
|
45
|
+
hashAlg: 'keccak-256',
|
|
46
|
+
},
|
|
47
|
+
'peernet-request': {
|
|
48
|
+
codec: parseInt('707271', 16),
|
|
49
|
+
hashAlg: 'keccak-256',
|
|
50
|
+
},
|
|
51
|
+
// normal block
|
|
52
|
+
'leofcoin-block': {
|
|
53
|
+
codec: parseInt('6c62', 16),
|
|
54
|
+
hashAlg: 'dbl-keccak-512', // ,
|
|
55
|
+
// testnet: 'olivia'
|
|
56
|
+
},
|
|
57
|
+
'leofcoin-tx': {
|
|
58
|
+
codec: parseInt('6c74', 16),
|
|
59
|
+
hashAlg: 'dbl-keccak-512', // ,
|
|
60
|
+
// testnet: 'olivia'
|
|
61
|
+
},
|
|
62
|
+
// itx
|
|
63
|
+
'leofcoin-itx': {
|
|
64
|
+
codec: parseInt('6c69', 16),
|
|
65
|
+
hashAlg: 'keccak-512', // ,
|
|
66
|
+
// testnet: 'olivia'
|
|
67
|
+
},
|
|
68
|
+
// peer reputation
|
|
69
|
+
'leofcoin-pr': {
|
|
70
|
+
codec: parseInt('6c70', 16),
|
|
71
|
+
hashAlg: 'keccak-256', // ,
|
|
72
|
+
// testnet: 'olivia'
|
|
73
|
+
},
|
|
74
|
+
// chat message
|
|
75
|
+
'chat-message': {
|
|
76
|
+
codec: parseInt('636d', 16),
|
|
77
|
+
hashAlg: 'dbl-keccak-512',
|
|
78
|
+
},
|
|
79
|
+
}
|
package/src/dht/dht.js
CHANGED
|
@@ -1,121 +1,121 @@
|
|
|
1
|
-
import fetch from 'node-fetch'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Keep history of fetched address and ptr
|
|
5
|
-
* @property {Object} address
|
|
6
|
-
* @property {Object} ptr
|
|
7
|
-
*/
|
|
8
|
-
const lastFetched = {
|
|
9
|
-
address: {
|
|
10
|
-
value: undefined,
|
|
11
|
-
timestamp: 0,
|
|
12
|
-
},
|
|
13
|
-
ptr: {
|
|
14
|
-
value: undefined,
|
|
15
|
-
timestamp: 0,
|
|
16
|
-
},
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const getAddress = async () => {
|
|
20
|
-
const {address} = lastFetched
|
|
21
|
-
const now = Math.round(new Date().getTime() / 1000);
|
|
22
|
-
if (now - address.timestamp > 1200000) {
|
|
23
|
-
address.value = await fetch('https://icanhazip.com/')
|
|
24
|
-
address.value = await address.value.text()
|
|
25
|
-
address.timestamp = Math.round(new Date().getTime() / 1000);
|
|
26
|
-
lastFetched.address = address;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return address.value
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const degreesToRadians = (degrees) => {
|
|
33
|
-
return degrees * Math.PI / 180;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const distanceInKmBetweenEarthCoordinates = (lat1, lon1, lat2, lon2) => {
|
|
37
|
-
const earthRadiusKm = 6371;
|
|
38
|
-
|
|
39
|
-
const dLat = degreesToRadians(lat2-lat1);
|
|
40
|
-
const dLon = degreesToRadians(lon2-lon1);
|
|
41
|
-
|
|
42
|
-
lat1 = degreesToRadians(lat1);
|
|
43
|
-
lat2 = degreesToRadians(lat2);
|
|
44
|
-
const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
|
|
45
|
-
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
|
|
46
|
-
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
|
|
47
|
-
return earthRadiusKm * c;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export default class DhtEarth {
|
|
51
|
-
/**
|
|
52
|
-
*
|
|
53
|
-
*/
|
|
54
|
-
constructor() {
|
|
55
|
-
this.providerMap = new Map();
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* @param {Object} address
|
|
60
|
-
* @return {Object} {latitude: lat, longitude: lon}
|
|
61
|
-
*/
|
|
62
|
-
async getCoordinates(address) {
|
|
63
|
-
// const {address} = parseAddress(provider)
|
|
64
|
-
const request = `https://whereis.leofcoin.org/?ip=${address}`
|
|
65
|
-
let response = await fetch(request)
|
|
66
|
-
response = await response.json()
|
|
67
|
-
const {lat, lon} = response;
|
|
68
|
-
return {latitude: lat, longitude: lon}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* @param {Object} peer
|
|
73
|
-
* @param {Object} provider
|
|
74
|
-
* @return {Object} {provider, distance}
|
|
75
|
-
*/
|
|
76
|
-
async getDistance(peer, provider) {
|
|
77
|
-
const {latitude, longitude} = await this.getCoordinates(provider.address)
|
|
78
|
-
return {provider, distance: distanceInKmBetweenEarthCoordinates(peer.latitude, peer.longitude, latitude, longitude)}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* @param {Array} providers
|
|
83
|
-
* @return {Object} closestPeer
|
|
84
|
-
*/
|
|
85
|
-
async closestPeer(providers) {
|
|
86
|
-
let all = []
|
|
87
|
-
const address = await getAddress();
|
|
88
|
-
const peerLoc = await this.getCoordinates(address)
|
|
89
|
-
|
|
90
|
-
for (const provider of providers) {
|
|
91
|
-
if (provider.address === '127.0.0.1') all.push({provider, distance: 0})
|
|
92
|
-
else all.push(this.getDistance(peerLoc, provider))
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
all = await Promise.all(all);
|
|
96
|
-
all = all.sort((previous, current) => previous.distance - current.distance)
|
|
97
|
-
return all[0].provider;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* @param {String} hash
|
|
102
|
-
* @return {Array} providers
|
|
103
|
-
*/
|
|
104
|
-
providersFor(hash) {
|
|
105
|
-
return this.providerMap.get(hash);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* @param {String} address
|
|
110
|
-
* @param {String} hash
|
|
111
|
-
* @return {Array} providers
|
|
112
|
-
*/
|
|
113
|
-
async addProvider(address, hash) {
|
|
114
|
-
let providers = [];
|
|
115
|
-
if (this.providerMap.has(hash)) providers = this.providerMap.get(hash)
|
|
116
|
-
|
|
117
|
-
providers = new Set([...providers, address])
|
|
118
|
-
this.providerMap.set(hash, providers)
|
|
119
|
-
return providers;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
1
|
+
import fetch from 'node-fetch'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Keep history of fetched address and ptr
|
|
5
|
+
* @property {Object} address
|
|
6
|
+
* @property {Object} ptr
|
|
7
|
+
*/
|
|
8
|
+
const lastFetched = {
|
|
9
|
+
address: {
|
|
10
|
+
value: undefined,
|
|
11
|
+
timestamp: 0,
|
|
12
|
+
},
|
|
13
|
+
ptr: {
|
|
14
|
+
value: undefined,
|
|
15
|
+
timestamp: 0,
|
|
16
|
+
},
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const getAddress = async () => {
|
|
20
|
+
const {address} = lastFetched
|
|
21
|
+
const now = Math.round(new Date().getTime() / 1000);
|
|
22
|
+
if (now - address.timestamp > 1200000) {
|
|
23
|
+
address.value = await fetch('https://icanhazip.com/')
|
|
24
|
+
address.value = await address.value.text()
|
|
25
|
+
address.timestamp = Math.round(new Date().getTime() / 1000);
|
|
26
|
+
lastFetched.address = address;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return address.value
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const degreesToRadians = (degrees) => {
|
|
33
|
+
return degrees * Math.PI / 180;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const distanceInKmBetweenEarthCoordinates = (lat1, lon1, lat2, lon2) => {
|
|
37
|
+
const earthRadiusKm = 6371;
|
|
38
|
+
|
|
39
|
+
const dLat = degreesToRadians(lat2-lat1);
|
|
40
|
+
const dLon = degreesToRadians(lon2-lon1);
|
|
41
|
+
|
|
42
|
+
lat1 = degreesToRadians(lat1);
|
|
43
|
+
lat2 = degreesToRadians(lat2);
|
|
44
|
+
const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
|
|
45
|
+
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
|
|
46
|
+
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
|
|
47
|
+
return earthRadiusKm * c;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export default class DhtEarth {
|
|
51
|
+
/**
|
|
52
|
+
*
|
|
53
|
+
*/
|
|
54
|
+
constructor() {
|
|
55
|
+
this.providerMap = new Map();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param {Object} address
|
|
60
|
+
* @return {Object} {latitude: lat, longitude: lon}
|
|
61
|
+
*/
|
|
62
|
+
async getCoordinates(address) {
|
|
63
|
+
// const {address} = parseAddress(provider)
|
|
64
|
+
const request = `https://whereis.leofcoin.org/?ip=${address}`
|
|
65
|
+
let response = await fetch(request)
|
|
66
|
+
response = await response.json()
|
|
67
|
+
const {lat, lon} = response;
|
|
68
|
+
return {latitude: lat, longitude: lon}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @param {Object} peer
|
|
73
|
+
* @param {Object} provider
|
|
74
|
+
* @return {Object} {provider, distance}
|
|
75
|
+
*/
|
|
76
|
+
async getDistance(peer, provider) {
|
|
77
|
+
const {latitude, longitude} = await this.getCoordinates(provider.address)
|
|
78
|
+
return {provider, distance: distanceInKmBetweenEarthCoordinates(peer.latitude, peer.longitude, latitude, longitude)}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @param {Array} providers
|
|
83
|
+
* @return {Object} closestPeer
|
|
84
|
+
*/
|
|
85
|
+
async closestPeer(providers) {
|
|
86
|
+
let all = []
|
|
87
|
+
const address = await getAddress();
|
|
88
|
+
const peerLoc = await this.getCoordinates(address)
|
|
89
|
+
|
|
90
|
+
for (const provider of providers) {
|
|
91
|
+
if (provider.address === '127.0.0.1') all.push({provider, distance: 0})
|
|
92
|
+
else all.push(this.getDistance(peerLoc, provider))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
all = await Promise.all(all);
|
|
96
|
+
all = all.sort((previous, current) => previous.distance - current.distance)
|
|
97
|
+
return all[0].provider;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @param {String} hash
|
|
102
|
+
* @return {Array} providers
|
|
103
|
+
*/
|
|
104
|
+
providersFor(hash) {
|
|
105
|
+
return this.providerMap.get(hash);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @param {String} address
|
|
110
|
+
* @param {String} hash
|
|
111
|
+
* @return {Array} providers
|
|
112
|
+
*/
|
|
113
|
+
async addProvider(address, hash) {
|
|
114
|
+
let providers = [];
|
|
115
|
+
if (this.providerMap.has(hash)) providers = this.providerMap.get(hash)
|
|
116
|
+
|
|
117
|
+
providers = new Set([...providers, address])
|
|
118
|
+
this.providerMap.set(hash, providers)
|
|
119
|
+
return providers;
|
|
120
|
+
}
|
|
121
|
+
}
|