-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathp2p-engine.js
137 lines (119 loc) · 4.54 KB
/
p2p-engine.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
50
51
52
53
54
55
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
require('dotenv').config()
const crypto = require('crypto')
const sign = require('./libs/sign.js')
const encryption = require('./libs/encryption.js')
const utilities = require('./libs/utilities.js')
const messages = require('./libs/messages.js')
const request = require('request')
var argv = require('minimist')(process.argv.slice(2))
const app = require('express')()
const isPortAvailable = require('is-port-available')
var server = require('http').Server(app)
global['io'] = { server: null, client: null, sockets: {} }
global['io'].server = require('socket.io')(server)
const getPort = require('get-port')
var dns = require('dns')
const publicIp = require('public-ip');
global['clients'] = {}
global['nodes'] = {}
global['connected'] = {}
let hook
async function initEngine (){
//SETTING UP EXPRESS
let expressPort
if(process.env.EXPRESS_PORT !== undefined){
expressPort = process.env.EXPRESS_PORT
}else{
expressPort = await getPort()
}
var available = await isPortAvailable(expressPort)
while(!available){
expressPort = await getPort()
available = await isPortAvailable(expressPort)
}
app.get('/', (req, res) => res.send('Scrypta P2P Engine is online'))
app.post('/broadcast', async (req,res) => {
var parsed = await utilities.parse(req)
var body = parsed.body
if(body.message !== undefined){
let signed = await sign.signWithKey(process.env.NODE_KEY, body.message)
signed.message = body.message
let broadcasted = await messages.broadcast('message', signed)
res.send({success: true, broadcasted: broadcasted})
}else{
res.send({error: true, message: 'Specify message first.'})
}
})
app.listen(expressPort, () => console.log(`Communications API listening on port: ${expressPort}`))
encryption.generateKeys()
console.log('Starting P2P client.')
global['identity'] = await sign.returnAddress(process.env.NODE_KEY)
console.log('Identity loaded: ' + global['identity'])
let bootstrap = process.env.BOOTSTRAP_NODES.split(',')
for (var k in bootstrap) {
if (!global['clients'][bootstrap[k]]) {
//INIT CONNECTION
let lookupURL = bootstrap[k].replace('http://', '').replace(':' + process.env.PORT, '')
let ip = await lookup(lookupURL)
let publicip = await publicIp.v4().catch(err => {
console.log('Public IP not available')
})
let node = bootstrap[k]
if (ip !== publicip) {
console.log('Bootstrap connection to ' + bootstrap[k])
global['nodes'][node] = require('socket.io-client')(node, { reconnect: true })
global['nodes'][node].on('connect', function () {
console.log('Connected to peer: ' + global['nodes'][node].io.uri)
global['connected'][node] = true
})
global['nodes'][node].on('disconnect', function () {
console.log('Disconnected from peer: ' + global['nodes'][node].io.uri)
global['connected'][node] = false
})
//PROTOCOLS
global['nodes'][bootstrap[k]].on('message', async function (data) {
let verified = await sign.verifySign(data.pubKey, data.signature, data.message)
if(verified === true){
console.log('Received message from ' + data.address + '.')
request.post(hook, data, function (error, response, body) {
if(error){
console.log('Hook failed.')
}
})
}
})
}
}
}
//INIT SOCKETIO SERVER
let p2pport = process.env.PORT;
console.log('Starting P2P server on port ' + p2pport)
server.listen(p2pport);
global['io'].server.on('connection', function (socket) {
console.log('New peer connected: ' + socket.id)
global['io'].sockets[socket.id] = socket
//PROTOCOLS
socket.on('message', function (data) {
console.log('Relaying received message to peers.');
messages.relay(data)
})
});
}
//HOOK DEFINITION
if(argv.hook !== undefined){
hook = argv.hook
console.log('Relay hook is: ' + hook)
}else if(process.env.HOOK !== undefined){
hook = process.env.HOOK
console.log('Relay hook is: ' + hook)
}else{
console.log('WARNING, NO HOOK DETECTED, THE ENGINE WILL NOT RELAY TO DAPP!')
}
async function lookup(lookupURL) {
return new Promise(response => {
dns.lookup(lookupURL, async function onLookup(err, ip, family) {
response(ip)
})
})
}
initEngine()