persistence for the blockchain + everything through the chain instead of broadcasting
This commit is contained in:
parent
1cb1070d45
commit
ea81105df6
5 changed files with 127 additions and 61 deletions
|
@ -1,4 +1,9 @@
|
|||
const Websocket = require('ws');
|
||||
const N3 = require('n3');
|
||||
const parser = new N3.Parser(); //({format: 'application/n-quads'});
|
||||
const DataFactory = require('n3').DataFactory;
|
||||
const fs = require('fs');
|
||||
const process = require('process');
|
||||
|
||||
const P2P_PORT = process.env.P2P_PORT || 5000;
|
||||
const peers = process.env.PEERS ? process.env.PEERS.split(',') : [];
|
||||
|
@ -10,10 +15,21 @@ const MESSAGE_TYPES = {
|
|||
};
|
||||
|
||||
class P2pServer {
|
||||
constructor(blockchain, transactionPool) {
|
||||
constructor(blockchain, transactionPool,chainStorageLocation) {
|
||||
this.blockchain = blockchain;
|
||||
this.transactionPool = transactionPool;
|
||||
this.sockets = [];
|
||||
this.store = new N3.Store();
|
||||
this.chainStorageLocation = chainStorageLocation;
|
||||
|
||||
//possible race if deleted after check, but we live with it I guess
|
||||
if (fs.existsSync(this.chainStorageLocation)) {
|
||||
const rawPersistedChain = fs.readFileSync(this.chainStorageLocation, 'utf8');
|
||||
const chain = JSON.parse(rawPersistedChain);
|
||||
this.newChain(chain, false);
|
||||
} else {
|
||||
console.log("Didn't find a persisted chain, starting from genesis");
|
||||
}
|
||||
}
|
||||
|
||||
listen() {
|
||||
|
@ -47,7 +63,7 @@ class P2pServer {
|
|||
const data = JSON.parse(message);
|
||||
switch(data.type) {
|
||||
case MESSAGE_TYPES.chain:
|
||||
this.blockchain.replaceChain(data.chain);
|
||||
newChain(data.chain);
|
||||
break;
|
||||
case MESSAGE_TYPES.transaction:
|
||||
this.transactionPool.updateOrAddTransaction(data.transaction);
|
||||
|
@ -62,6 +78,67 @@ class P2pServer {
|
|||
});
|
||||
}
|
||||
|
||||
newBlock(block) {
|
||||
this.onNewBlock(block.data);
|
||||
this.syncChains();
|
||||
this.persistChain(this.blockchain.chain);
|
||||
}
|
||||
|
||||
newChain(chain,persist) {
|
||||
if (!this.blockchain.replaceChain(chain)) {
|
||||
//failed to replace
|
||||
return;
|
||||
}
|
||||
if (typeof persist === "undefined" || persist) {
|
||||
this.persistChain(chain);
|
||||
}
|
||||
//dirty clear
|
||||
this.store = new N3.Store();
|
||||
for (var block in this.blockchain.chain) {
|
||||
this.onNewBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
persistChain(chain) {
|
||||
try {
|
||||
fs.writeFileSync(
|
||||
this.chainStorageLocation,
|
||||
JSON.stringify(chain));
|
||||
} catch (err) {
|
||||
console.error("Couldn't persist chain, aborting");
|
||||
process.exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
onNewBlock(block) {
|
||||
//block data is of form [transactions,metadatas]
|
||||
if (block.length != 2) {
|
||||
//assert?
|
||||
return;
|
||||
}
|
||||
const metadatas = block[1];
|
||||
|
||||
for (var metadata in metadatas) {
|
||||
if (!(SSNmetadata in metadata)) {
|
||||
//assert?
|
||||
return;
|
||||
}
|
||||
|
||||
var ssn = metadata.SSNmetadata;
|
||||
|
||||
parser.parse(
|
||||
ssn,
|
||||
(error, quadN, prefixes) => {
|
||||
if (quadN) {
|
||||
store.addQuad(DataFactory.quad(
|
||||
DataFactory.namedNode(quadN.subject.id),
|
||||
DataFactory.namedNode(quadN.predicate.id),
|
||||
DataFactory.namedNode(quadN.object.id)));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
sendChain(socket) {
|
||||
socket.send(JSON.stringify({
|
||||
type: MESSAGE_TYPES.chain,
|
||||
|
@ -69,36 +146,36 @@ class P2pServer {
|
|||
}));
|
||||
}
|
||||
|
||||
sendTransaction(socket, transaction) {
|
||||
socket.send(JSON.stringify({
|
||||
type: MESSAGE_TYPES.transaction,
|
||||
transaction
|
||||
}));
|
||||
}
|
||||
//sendTransaction(socket, transaction) {
|
||||
// socket.send(JSON.stringify({
|
||||
// type: MESSAGE_TYPES.transaction,
|
||||
// transaction
|
||||
// }));
|
||||
//}
|
||||
|
||||
sendMetadata(socket, metadata) {
|
||||
socket.send(JSON.stringify({
|
||||
type: MESSAGE_TYPES.metadata,
|
||||
metadata
|
||||
}));
|
||||
}
|
||||
//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));
|
||||
}
|
||||
//broadcastTransaction(transaction) {
|
||||
// this.sockets.forEach(socket => this.sendTransaction(socket, transaction));
|
||||
//}
|
||||
|
||||
broadcastMetadata(metadata) {
|
||||
this.sockets.forEach(socket => this.sendMetadata(socket, metadata));
|
||||
}
|
||||
//broadcastMetadata(metadata) {
|
||||
// this.sockets.forEach(socket => this.sendMetadata(socket, metadata));
|
||||
//}
|
||||
|
||||
broadcastClearTransactions() {
|
||||
this.sockets.forEach(socket => socket.send(JSON.stringify({
|
||||
type: MESSAGE_TYPES.clear_transactions
|
||||
})));
|
||||
}
|
||||
//broadcastClearTransactions() {
|
||||
// this.sockets.forEach(socket => socket.send(JSON.stringify({
|
||||
// type: MESSAGE_TYPES.clear_transactions
|
||||
// })));
|
||||
//}
|
||||
}
|
||||
|
||||
module.exports = P2pServer;
|
Loading…
Add table
Add a link
Reference in a new issue