server-pool.js
const Net = require('net'); const url = require('url'); const bitcore = require('bitcore-lib'); const Hash = bitcore.crypto.Hash; const BufferUtil = bitcore.util.buffer; const _ = require('./util'); const prettify = require('../prettify.js')(); const stdin = process.openStdin(); const fs = require('fs'); const users_file ='./user.json'; const DT = require('./datatypes'); const $ = require('./util'); const get = require('./manageGetRequest'); const MBP = require('./make-block-project'); var t_url = url.parse('http://127.0.0.1:3000/'); var port = t_url.port; /* const options = { key: fs.readFileSync('./openssl/key.pem'), cert: fs.readFileSync('./openssl/cert.pem') }; */ const server = new Net.Server(); var chats = []; var current_chat = null; var current_block_project = null; var ids = 0; var users = JSON.parse(fs.readFileSync(users_file, function(err){ if(err) throw(err); })); const MAX_HISTORY_SIZE = 40; const QUORUM_PERCENT = 74; // //percentage of minimum number of miners to proceed mining var jobready_count = 0; server.listen(port, function() { console.log('\x1b[36m\x1b[2m[Server listening for connection requests on socket\x1b[0m:'); //console.log(users); }); stdin.addListener("data", function(d) { /* var sentence = d.toString().trim(); talkTo(sentence); sanitizeChats(); */ var sentence = d.toString().trim(); var line = sentence.split('>'); var header = line[0]; var body =line[1]; switch (header){ case 'stop': broadcast2All(DT.StopMessage()); break; case 'new'://'new-block-project': MBP.startNewBlockProject(false); //true =>get actual data from blockchain.info break; case 'ping': if(current_chat) current_chat.socket.write(DT.PingMessage()); else console.error({error:'no clients connected'}); break; case 'broadcast': broadcast2All(DT.testMessage()); break; case 'exit': console.log("\x1b[33m[Server is about to be closed]\x1b[0m"); server.destroy(); setTimeout(function(){ process.exit(0)}, 1000); // kill client break; case 'exit': break; default: talkTo(sentence); sanitizeChats(); break; } }); server.on('connection', function(socket) { console.log('\x1b[36mA new connection has been established\x1b[0m.'); //current_chat = setChat(socket); //talkTo(); socket.on('data', function(chunk) { current_chat = setChat(socket); var msg = DT.readMessage(chunk); if(msg)talkFromMessage(msg); else { var sentence = chunk.toString().split('\n'); var w = chunk.toString().split(' '); var word = w[0]; switch(word){ case 'GET': /* current_chat.socket.write([ 'HTTP/1.1 200 OK', 'Content-Type: text/html; charset=UTF-8', 'Content-Encoding: UTF-8', 'Accept-Ranges: bytes', 'Connection: keep-alive', ].join('\n') + '\n\n'); current_chat.socket.write('<h1> Example </h1> <img src ="../uploads/building.jpg"> '); // console.log(sentence[0].split(' ')[1]); //current_chat.socket.end(); */ get.ManageGetRequest(chunk,socket) console.log(chunk.toString()); break; default: talkFrom(chunk.toString()); break; } } }); socket.on('end', function() { current_chat = setChat(socket); console.log('\x1b[36m\x1b[2mClosing connection with the client %s\x1b[0m.',current_chat.user); removeChat(socket); current_chat = null; }); socket.on('error', function(err) { current_chat = setChat(socket); console.log(err); }); }); function talkTo(message){ if(current_chat){ var msg = message; if(current_chat.user === 'anonymous' ){ msg = '\x1b[32mHello, \x1b[1mUSER:PWD\x1b[0m\x1b[32m, please\x1b[0m' } if(msg){ current_chat.socket.write(msg); current_chat.history.push(msg); } } } function talkFrom(message){ if(current_chat){ if(current_chat.user === 'anonymous'){ var msg = message.split(':'); if(msg.length == 2) checkUserPwd(msg,current_chat); talkTo(); } console.log('%s: \x1b[33m%s\x1b[0m',current_chat.user, message); current_chat.history.push(message); } } function talkFromMessage(m){ if(current_chat){ if(current_chat.user === 'anonymous'){ var msg = m.payload.toString('utf8').split(':'); if(msg.length == 2) checkUserPwd(msg,current_chat); talkTo(); } onCommand(m); var obj = {};obj[current_chat.user]= m; console.log(obj); current_chat.history.push(JSON.stringify(m)); } } /* function checkUserPwd(msg, chat){ for(var e in users){ if(msg[0] === e && msg[1] === users[e].pwd ){ for(var f in chats){ if(chats[f].socket == chat.socket){ chats[f].user = msg[0]; chat.socket.write('Thanks ' + chats[f].user); return true; } } } } return false; } */ function checkUserPwd(msg, chat){ for(var e in users){ if(msg[0] === e && msg[1] === users[e].pwd){ for(var f in chats){ if(chats[f].user == msg[0]) return false; if(chats[f].socket == chat.socket){ chats[f].user = msg[0]; chat.socket.write('Welcome ' + chats[f].user); return true; } } } } return false; } function sanitizeChats(){ for(var e in chats){ if(chats[e].history.length > MAX_HISTORY_SIZE) chats[e].history.shift(); } } function setChat(socket){ var chat = {user:'anonymous',id :-1,socket:socket,history:[]}; for(var e in chats){ if(chat.socket == chats[e].socket) return chats[e]; } chat.id =ids++; chats.push(chat); return chat; } function resumeChat(user, socket){ var chat = {user:user, id:-1, socket:socket, history:[]}; for(var e in chats){ if(user == chats[e].user){ chats[e].socket = socket; return chats[e]; } } chat.id =ids++; chats.push(chat); return chat; } function removeChat(socket){ for(var e in chats){ if(chats[e].socket == socket){ chats.splice(e, 1); } } } function broadcast2All(message){ if(chats)for(var e in chats){ chats[e].socket.write(message); } } function sendNoncePartition2All(){ var size = chats.length; var a = getNoncePartition(); var buf = new Buffer.alloc(8); if(chats)for(var e=0;e<size;e++){ buf.writeUInt32BE(a[e],0); buf.writeUInt32BE(a[e+1],4); var nonce_p ={ command: 'nonce_p', networkMagic: new Buffer.from('FF00FF00', 'hex'), payload: buf }; var msg = DT.makeMessage(nonce_p); /* var msg2 = DT.readMessage(msg); var p = [ msg2.payload.readUInt32BE(0), msg2.payload.readUInt32BE(4) ]; console.log(msg2); */ chats[e].socket.write(msg); } } function getNoncePartition(){ var size = chats.length; const nonce = 0xffffffff; var p = Math.floor(parseFloat(nonce)/size); var b = []; for(var i = 0;i<size;i++){ b.push(i*p); } b.push(nonce); return b; //return_.SplitInterval([0,45676543],6)); } function onCommand(msg){ var command = msg.command; switch(command){ case 'ping': current_chat.socket.write(DT.PongMessage(msg)); break; case 'joback': jobready_count++; if(jobready_count >= chats.length){ jobready_count=0; sendNoncePartition2All(); } break; case 'block_solved': try{ var file = 'solved-'+ Date.now()+'.hex'; fs.writeFileSync(file,msg.payload.toString('hex'),'utf8'); broadcast2All(DT.StopMessage()); }catch(e){ console.error(e); } break; /* case: break; case: break; case: break; */ } } MBP.emitter.on('new-block-project-ready', () => { console.log('\x1b[33mnew-\x1b[1mblock-project\x1b[0m\x1b[33m-ready:\x1b[0m'); current_block_project = new bitcore.Block.fromBuffer(MBP.get_block_project()); console.log(current_block_project.header.toObject()); broadcast2All(DT.JobMessage(current_block_project.header.toBuffer())); });
util.js
'use strict'; const bitcore = require('bitcore-lib'); const Random = bitcore.crypto.Random; var $ = bitcore.util.preconditions; const BufferReader = bitcore.encoding.BufferReader; const BufferWriter = bitcore.encoding.BufferWriter; const OUTPUT = 1; const INPUT = 0; /* Can parse a JSON object even if there are comment tags between its items */ var parseW = function(str){ return JSON.parse(str.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '$1')); } function variantToBufferFromNum(n){ return new BufferWriter(new Buffer.alloc(0)) .writeVarintNum(n) .toBuffer(); } function SplitInterval(partition,n){ if(typeof partition !== 'object') return null; if(typeof partition[0] !== 'number' || typeof partition[1] !== 'number') return null; if( partition[1] - partition[0] <= 0) return null; var d = Math.floor((partition[1]-partition[0])/n); var b = []; for(var j = 0;j<n;j++){ var c = []; c.push(partition[0] + d*j); c.push(partition[0] + d*(j+1)-1); b.push(c); } b[n-1][1] = partition[1]; return b; } function format_date(timestamp){ var date = new Date(timestamp * 1000); var day = date.getDate(); //var month = months_arr[date.getMonth()]; var month = date.getMonth()+1; var year = date.getFullYear(); var hours = date.getHours(); var minutes = "0" + date.getMinutes(); var seconds = "0" + date.getSeconds(); // Will display time in 10:30:23 format var formattedTime = month + '/' + day + '/' +year + ' ' + hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2); return formattedTime; } /* split buffer buf into an array of subbuffers, separator must be a string of bytes in hexadecimal mode. */ function Split(buf, separator){ var occurr =[]; var sp =[]; var b = new Buffer.from(buf); var pos = 0; var i = 0; const magic = new Buffer.from(separator, 'hex'); while(1){ var index = b.indexOf(magic); if(index > -1){ pos += index; occurr.push(pos+magic.length*i);i++; b = b.slice(index+magic.length); }else break; } if(occurr.length){ if(occurr[0]>0) sp.push(buf.slice(0,occurr[0])); for(var i = 0;i<occurr.length;i++) sp.push(buf.slice(occurr[i],occurr[i+1])); /*if(occurr[occurr.length-1]< buf.length-1) sp.push(buf.slice(occurr[occurr.length-1]));*/ } else sp.push(buf); return sp; } Buffer['split'] = Split; //let Global Object, Buffer, manages this. JSON['parseW'] = parseW; //let Global Object, JSON, manages this. function WM_Encrypt(buffer, mode){ if(buffer.length){ var puntero = 0; var size = buffer.length; while(puntero < size/2) { Traspuesta(puntero,size-puntero-1,mode,buffer); puntero++; } } return buffer; } function Traspuesta(i, j, modo, buffer){ var nparam1,nparam2; nparam1 = buffer.readUInt8(i); if(modo)nparam1 = nparam1 - 10; else nparam1 = nparam1 + 10; nparam1 = nparam1<0?256+nparam1:nparam1; nparam1 = nparam1>0xff?nparam1-256:nparam1; nparam2 = buffer.readUInt8(j);//flujofichero.charCodeAt(j); if(modo)nparam2 = nparam2 - 10; else nparam2 = nparam2 + 10; nparam2 = nparam2<0?256+nparam2:nparam2; nparam2 = nparam2>0xff?nparam2-256:nparam2; buffer.writeUInt8(nparam2, i); buffer.writeUInt8(nparam1, j); } function wm_encode(buffer){ return WM_Encrypt(buffer, OUTPUT); } function wm_decode(buffer){ return WM_Encrypt(buffer, INPUT); } function stochash256(buffer){ if(buffer.length !== 256) return null; var pt =0; var hash = [] while(1){ var byte = buffer.readUInt8(pt); var repunit = getRepunit(byte); var rnd = Random.getRandomBuffer(1).readUInt8(0); hash.push(repunit[rnd]); pt++; if(pt == buffer.length)break; } var result = new bitcore.crypto.BN.fromString(hash.join(''),2); return result.toBuffer(); } function getRepunit(byte){ const two = new bitcore.crypto.BN(2); const one = new bitcore.crypto.BN(1); var b = new bitcore.crypto.BN(byte); var repunit = two.pow(b); repunit = repunit.sub(one); return repunit.toString(2,256); } module.exports = { SplitInterval:SplitInterval, variantToBufferFromNum:variantToBufferFromNum, format_date:format_date, WM_Encrypt:WM_Encrypt, wm_encode:wm_encode, wm_decode:wm_decode, stochash256:stochash256, getRepunit:getRepunit };