Commit 5bdf39d3 authored by Cédric Moreau's avatar Cédric Moreau

Added time reference in Block & Status documents

parent 4326ddac
......@@ -13,6 +13,7 @@ var link2pubkey = require('../lib/streams/link2pubkey');
var extractSignature = require('../lib/streams/extractSignature');
var verifySignature = require('../lib/streams/verifySignature');
var logger = require('../lib/logger');
var constants = require('../lib/constants');
var plogger = logger('peering');
var slogger = logger('status');
......@@ -87,36 +88,45 @@ function NetworkBinding (peerServer, conf) {
var onError = http400(res);
async.waterfall([
function (next) {
function errorPeer (err) {
if (err == constants.ERROR.PEER.ALREADY_RECORDED)
next();
else
next(err);
}
// If peer is provided, parse it first
if (req.body && req.body.peer) {
http2raw.peer(req, onError)
http2raw.peer(req, errorPeer)
.pipe(dos2unix())
.pipe(parsers.parsePeer(onError))
.pipe(versionFilter(onError))
.pipe(currencyFilter(conf.currency, onError))
// .pipe(verifySignature(onError))
.pipe(peerServer.singleWriteStream(onError))
.pipe(es.mapSync(function () {
.pipe(parsers.parsePeer(errorPeer))
.pipe(versionFilter(errorPeer))
.pipe(currencyFilter(conf.currency, errorPeer))
// .pipe(verifySignature(errorPeer))
.pipe(peerServer.singleWriteStream(errorPeer))
.pipe(es.mapSync(function (data) {
next();
}))
}
else next();
},
function (next) {
http2raw.status(req, onError)
http2raw.status(req, next)
.pipe(dos2unix())
.pipe(parsers.parseStatus(onError))
.pipe(versionFilter(onError))
.pipe(currencyFilter(conf.currency, onError))
// .pipe(extractSignature(onError))
// .pipe(link2pubkey(peerServer.PublicKeyService, onError))
// .pipe(verifySignature(onError))
.pipe(peerServer.singleWriteStream(onError))
.pipe(parsers.parseStatus(next))
.pipe(versionFilter(next))
.pipe(currencyFilter(conf.currency, next))
// .pipe(extractSignature(next))
// .pipe(link2pubkey(peerServer.PublicKeyService, next))
// .pipe(verifySignature(next))
.pipe(peerServer.singleWriteStream(next))
.pipe(jsoner())
.pipe(es.stringify())
.pipe(res);
next();
}
]);
], function (err) {
if (err)
onError(err);
});
}
}
......@@ -20,6 +20,9 @@ module.exports = {
PUBKEY: {
ALREADY_UPDATED: 1
},
PEER: {
ALREADY_RECORDED: 'Peer document is older than currently recorded'
}
},
......@@ -69,6 +72,14 @@ module.exports = {
TARGET: exact(PUBKEY + ":" + POSITIVE_INT),
COMMENT: find("Comment: (" + COMMENT + ")"),
},
PEER: {
BLOCK: find("Block: (" + INTEGER + "-" + FINGERPRINT + ")"),
SPECIAL_BLOCK: '0-DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'
},
STATUS: {
BLOCK: find("Block: (" + INTEGER + "-" + FINGERPRINT + ")"),
SPECIAL_BLOCK: '0-DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'
},
setUDID2Format: function () {
module.exports.USER_ID = module.exports.UDID2_FORMAT;
......
......@@ -33,6 +33,7 @@ module.exports = new function() {
raw += "Type: Peer\n";
raw += "Currency: " + json.currency + "\n";
raw += "PublicKey: " + json.pub + "\n";
raw += "Block: " + json.block + "\n";
raw += "Endpoints:" + "\n";
json.endpoints.forEach(function(ep){
raw += ep + "\n";
......@@ -50,6 +51,7 @@ module.exports = new function() {
raw += "Type: Status\n";
raw += "Currency: " + json.currency + "\n";
raw += "Status: " + json.status + "\n";
raw += "Block: " + json.block + "\n";
raw += "From: " + json.from + "\n";
raw += "To: " + json.to + "\n";
return dos2unix(raw);
......
......@@ -17,7 +17,7 @@ function PeerParser (onError) {
{prop: "version", regexp: /Version: (.*)/},
{prop: "currency", regexp: /Currency: (.*)/},
{prop: "pub", regexp: /PublicKey: (.*)/},
{prop: "time", regexp: /Time: (.*)/},
{prop: "block", regexp: constants.PEER.BLOCK},
{prop: "endpoints", regexp: /Endpoints:\n([\s\S]*)/, parser: split("\n")},
];
var multilineFields = [];
......@@ -59,6 +59,7 @@ function PeerParser (onError) {
'BAD_IPV6': 154,
'BAD_PORT': 155,
'BAD_FINGERPRINT': 156,
'BAD_BLOCK': 157,
'NO_IP_GIVEN': 158
}
if(!err){
......@@ -71,6 +72,11 @@ function PeerParser (onError) {
if(!obj.pub || !obj.pub.match(constants.BASE58))
err = {code: codes['BAD_FINGERPRINT'], message: "Incorrect PublicKey field"};
}
if(!err){
// Block
if(!obj.block)
err = {code: codes['BAD_BLOCK'], message: "Incorrect Block field"};
}
// Basic Merkled API requirements
var bma = obj.getBMA();
if(!err){
......
......@@ -15,7 +15,7 @@ function StatusParser (onError) {
{prop: "version", regexp: /Version: (.*)/},
{prop: "currency", regexp: /Currency: (.*)/},
{prop: "status", regexp: /Status: (.*)/},
{prop: "time", regexp: /Time: (.*)/, parser: parseDateFromTimestamp},
{prop: "block", regexp: constants.STATUS.BLOCK},
{prop: "from", regexp: /From: (.*)/},
{prop: "to", regexp: /To: (.*)/},
];
......@@ -59,8 +59,4 @@ function StatusParser (onError) {
};
}
function parseDateFromTimestamp (value) {
return new Date(parseInt(value)*1000);
}
util.inherits(StatusParser, GenericParser);
......@@ -23,7 +23,10 @@ var PeerSchema = new Schema({
endpoints: [String],
signature: String,
hash: String,
status: { type: String, default: STATUS.NOTHING },
hash: String,
block: { type: String },
statusBlock: { type: String },
status: { type: String },
statusSent: { type: String, default: STATUS.NOTHING },
statusSigDate: { type: Date, default: function(){ return new Date(0); } },
propagated: { type: Boolean, default: false },
......@@ -64,14 +67,14 @@ PeerSchema.methods = {
copyValues: function(to) {
var obj = this;
["version", "currency", "pub", "endpoints", "hash", "status", "signature"].forEach(function (key) {
["version", "currency", "pub", "endpoints", "hash", "status", "block", "signature"].forEach(function (key) {
to[key] = obj[key];
});
},
copyValuesFrom: function(from) {
var obj = this;
["version", "currency", "pub", "endpoints", "signature"].forEach(function (key) {
["version", "currency", "pub", "endpoints", "block", "signature"].forEach(function (key) {
obj[key] = from[key];
});
},
......@@ -79,7 +82,7 @@ PeerSchema.methods = {
json: function() {
var obj = this;
var json = {};
["version", "currency", "endpoints", "status", "signature"].forEach(function (key) {
["version", "currency", "endpoints", "status", "block", "signature"].forEach(function (key) {
json[key] = obj[key];
});
json.raw = this.getRaw();
......
......@@ -6,13 +6,13 @@ var _ = require('underscore');
module.exports = function StatusMessage (values) {
var that = this;
['version', 'currency', 'status', 'from', 'to', 'hash', 'pubkey', 'time', 'signature'].forEach(function(field){
['version', 'currency', 'status', 'from', 'to', 'hash', 'pubkey', 'block', 'signature'].forEach(function(field){
that[field] = values && values[field] || '';
});
this.json = function () {
var obj = {};
['version', 'currency', 'status', 'from', 'to', 'signature'].forEach(function(field){
['version', 'currency', 'status', 'from', 'to', 'block', 'signature'].forEach(function(field){
obj[field] = that[field] || '';
});
obj.raw = this.getRaw();
......
......@@ -7,12 +7,14 @@ var Status = require('../models/statusMessage');
var logger = require('../lib/logger')('peering');
var base58 = require('../lib/base58');
var moment = require('moment');
var constants = require('../lib/constants');
var localValidator = require('../lib/localValidator');
function PeeringService(conn, conf, pair, signFunc, ParametersService) {
var currency = conf.currency;
var Block = conn.model('Block');
var Transaction = conn.model('Transaction');
var Merkle = conn.model('Merkle');
var Peer = conn.model('Peer');
......@@ -71,12 +73,20 @@ function PeeringService(conn, conf, pair, signFunc, ParametersService) {
this.submit = function(peering, callback){
var peer = new Peer(peering);
var sp = peer.block.split('-');
var number = sp[0], fpr = sp[1];
async.waterfall([
function (next) {
localValidator(null).checkPeerSignature(peer, next);
},
function (next){
that.addPeer(peer);
function (next) {
if (peer.block == constants.PEER.SPECIAL_BLOCK)
next(null, null);
else
// Check if document is based upon an existing block as time reference
Block.findByNumberAndHash(number, fpr, next);
},
function (block, next){
Peer.find({ pub: peer.pub }, next);
},
function (peers, next){
......@@ -84,8 +94,10 @@ function PeeringService(conn, conf, pair, signFunc, ParametersService) {
var previousHash = null;
if(peers.length > 0){
// Already existing peer
if(peers[0].sigDate > peerEntity.sigDate){
next('Cannot record a previous peering');
var sp2 = peers[0].block.split('-');
var number2 = sp2[0], fpr2 = sp2[1];
if(number <= number2){
next(constants.ERROR.PEER.ALREADY_RECORDED);
return;
}
peerEntity = peers[0];
......@@ -108,18 +120,31 @@ function PeeringService(conn, conf, pair, signFunc, ParametersService) {
var status = new Status(obj);
var peer;
var wasStatus = null;
var sp = status.block.split('-');
var number = sp[0], fpr = sp[1];
async.waterfall([
function (next) {
localValidator(null).checkStatusSignature(status, next);
},
function (next){
function (next) {
if (status.block == constants.STATUS.SPECIAL_BLOCK)
next(null, null);
else
// Check if document is based upon an existing block as time reference
Block.findByNumberAndHash(number, fpr, next);
},
function (block, next){
Peer.getTheOne(status.from, next);
},
function (theOne, next){
peer = theOne;
if (peer.statusSigDate > status.sigDate) {
next('Old status given');
return;
if (peer.statusBlock) {
var sp2 = peer.statusBlock.split('-');
var number2 = sp2[0], fpr2 = sp2[1];
if(number <= number2){
next('Old status given');
return;
}
}
wasStatus = peer.status;
peer.statusSigDate = status.sigDate;
......@@ -220,7 +245,14 @@ function PeeringService(conn, conf, pair, signFunc, ParametersService) {
* @param pubs List of peers' pubs to which status is to be sent
*/
this.sendStatusTo = function (statusStr, pubs, done) {
var current = null;
async.waterfall([
function (next) {
Block.current(function (err, block) {
current = block;
next();
});
},
async.apply(Peer.getList.bind(Peer), pubs),
function (peers, next) {
async.forEach(peers, function(peer, callback){
......@@ -229,6 +261,7 @@ function PeeringService(conn, conf, pair, signFunc, ParametersService) {
currency: currency,
time: new Date(moment.utc().unix()*1000),
status: statusStr,
block: current ? [current.number, current.hash].join('-') : '0-DA39A3EE5E6B4B0D3255BFEF95601890AFD80709',
from: selfPubkey,
to: peer.pub
});
......
......@@ -9,6 +9,7 @@ var WOTServer = require('./wotserver');
var signature = require('./app/lib/signature');
var parsers = require('./app/lib/streams/parsers/doc');
var multicaster = require('./app/lib/streams/multicaster');
var constants = require('./app/lib/constants');
function PeerServer (dbConf, overrideConf, interceptors, onInit) {
......@@ -244,8 +245,13 @@ function PeerServer (dbConf, overrideConf, interceptors, onInit) {
this.initPeeringEntry = function (conn, conf, done) {
var Peer = conn.model('Peer');
var currency = conf.currency;
var current = null;
async.waterfall([
function (next) {
that.BlockchainService.current(next);
},
function (currentBlock, next) {
current = currentBlock;
Peer.find({ pub: that.PeeringService.pubkey }, next);
},
function (peers, next) {
......@@ -270,6 +276,7 @@ function PeerServer (dbConf, overrideConf, interceptors, onInit) {
version: 1,
currency: currency,
pub: that.PeeringService.pubkey,
block: current ? [current.number, current.hash].join('-') : constants.PEER.SPECIAL_BLOCK,
endpoints: [endpoint]
};
var raw1 = p1.getRaw().dos2unix();
......
......@@ -12,6 +12,7 @@ var rawPeer = "" +
"Type: Peer\n" +
"Currency: beta_brousouf\n" +
"PublicKey: 3Z7w5g4gC9oxwEbATnmK2UFgGWhLZPmZQb5dRxvNrXDu\n" +
"Block: 0-DA39A3EE5E6B4B0D3255BFEF95601890AFD80709\n" +
"Endpoints:\n" +
"BASIC_MERKLED_API ucoin.twiced.fr 88.163.127.43 9101\n" +
"OTHER_PROTOCOL 88.163.127.43 9102\n" +
......
......@@ -12,7 +12,7 @@ var rawStatus = "" +
"Type: Status\n" +
"Currency: beta_brousouf\n" +
"Status: UP\n" +
"Time: 1414937786\n" +
"Block: 0-DA39A3EE5E6B4B0D3255BFEF95601890AFD80709\n" +
"From: 3Z7w5g4gC9oxwEbATnmK2UFgGWhLZPmZQb5dRxvNrXDu\n" +
"To: 6GCnm36t4DnvoJshCYS13i64PxsqyJnGxuNXkzt9Rkh7\n" +
"bvuKzc6+cGWMGC8FIkZHN8kdQhaRL/MK60KYyw5vJqkKEgxXbygQHAzfoojeSY4gPKIu4FggBkR1HndSEm2FAQ==\n";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment