104 lines
No EOL
2.5 KiB
JavaScript
104 lines
No EOL
2.5 KiB
JavaScript
const Websocket = require('ws');
|
|
|
|
const P2P_PORT = process.env.P2P_PORT || 5000;
|
|
const peers = process.env.PEERS ? process.env.PEERS.split(',') : [];
|
|
const MESSAGE_TYPES = {
|
|
chain: 'CHAIN',
|
|
transaction: 'TRANSACTION',
|
|
clear_transactions: 'CLEAR_TRANSACTIONS',
|
|
metadata: 'METADATA'
|
|
};
|
|
|
|
class P2pServer {
|
|
constructor(blockchain, transactionPool) {
|
|
this.blockchain = blockchain;
|
|
this.transactionPool = transactionPool;
|
|
this.sockets = [];
|
|
}
|
|
|
|
listen() {
|
|
const server = new Websocket.Server({ port: P2P_PORT });
|
|
server.on('connection', socket => this.connectSocket(socket));
|
|
|
|
this.connectToPeers();
|
|
|
|
console.log(`Listening for peer-to-peer connections on: ${P2P_PORT}`);
|
|
}
|
|
|
|
connectToPeers() {
|
|
peers.forEach(peer => {
|
|
const socket = new Websocket(peer);
|
|
|
|
socket.on('open', () => this.connectSocket(socket));
|
|
});
|
|
}
|
|
|
|
connectSocket(socket) {
|
|
this.sockets.push(socket);
|
|
console.log('Socket connected');
|
|
|
|
this.messageHandler(socket);
|
|
|
|
this.sendChain(socket);
|
|
}
|
|
|
|
messageHandler(socket) {
|
|
socket.on('message', message => {
|
|
const data = JSON.parse(message);
|
|
switch(data.type) {
|
|
case MESSAGE_TYPES.chain:
|
|
this.blockchain.replaceChain(data.chain);
|
|
break;
|
|
case MESSAGE_TYPES.transaction:
|
|
this.transactionPool.updateOrAddTransaction(data.transaction);
|
|
break;
|
|
case MESSAGE_TYPES.metadata:
|
|
this.transactionPool.updateOrAddMetadata(data.metadata);
|
|
break;
|
|
case MESSAGE_TYPES.clear_transactions:
|
|
this.transactionPool.clear();
|
|
break;
|
|
}
|
|
});
|
|
}
|
|
|
|
sendChain(socket) {
|
|
socket.send(JSON.stringify({
|
|
type: MESSAGE_TYPES.chain,
|
|
chain: this.blockchain.chain
|
|
}));
|
|
}
|
|
|
|
sendTransaction(socket, transaction) {
|
|
socket.send(JSON.stringify({
|
|
type: MESSAGE_TYPES.transaction,
|
|
transaction
|
|
}));
|
|
}
|
|
|
|
sendMetadata(socket, metadata) {
|
|
socket.send(JSON.stringify({
|
|
type: MESSAGE_TYPES.metadata,
|
|
metadata
|
|
}));
|
|
}
|
|
syncChains() {
|
|
this.sockets.forEach(socket => this.sendChain(socket));
|
|
}
|
|
|
|
broadcastTransaction(transaction) {
|
|
this.sockets.forEach(socket => this.sendTransaction(socket, transaction));
|
|
}
|
|
|
|
broadcastMetadata(metadata) {
|
|
this.sockets.forEach(socket => this.sendMetadata(socket, metadata));
|
|
}
|
|
|
|
broadcastClearTransactions() {
|
|
this.sockets.forEach(socket => socket.send(JSON.stringify({
|
|
type: MESSAGE_TYPES.clear_transactions
|
|
})));
|
|
}
|
|
}
|
|
|
|
module.exports = P2pServer; |