Commit db47f12b authored by Cédric Moreau's avatar Cédric Moreau
Browse files

LokiJS: CertDAL

parent bb82c7f2
......@@ -95,14 +95,13 @@ function FileDAL(profile, home, localDir, myFS, parentFileDAL, levelupInstance,
this.coresDAL = new CoresDAL(rootPath, myDB, parentFileDAL && parentFileDAL.coresDAL.coreFS, that, LevelDBStorage);
this.linksDAL = new LinksDAL(rootPath, myDB, parentFileDAL && parentFileDAL.linksDAL.coreFS, that, LevelDBStorage);
this.idtyDAL = new IdentityDAL(that, loki);
this.certDAL = new CertDAL(rootPath, myDB, parentFileDAL && parentFileDAL.certDAL.coreFS, that, LevelDBStorage);
this.certDAL = new CertDAL(that, loki);
this.msDAL = new MembershipDAL(rootPath, myDB, parentFileDAL && parentFileDAL.msDAL.coreFS, that, LevelDBStorage);
this.udDAL = new DividendDAL(rootPath, myDB, parentFileDAL && parentFileDAL.udDAL.coreFS, that, LevelDBStorage);
this.newDals = {
'peerDAL': that.peerDAL,
'sourcesDAL': that.sourcesDAL,
'certDAL': that.certDAL,
'txsDAL': that.txsDAL,
'indicatorsDAL': that.indicatorsDAL,
'confDAL': that.confDAL,
......@@ -1011,10 +1010,7 @@ function FileDAL(profile, home, localDir, myFS, parentFileDAL, levelupInstance,
};
this.officializeCertification = function(cert) {
return that.certDAL.saveOfficial(cert)
.then(function(){
return that.certDAL.removeNotLinked(cert);
});
return that.certDAL.saveOfficial(cert);
};
this.listLocalPendingIdentities = function() {
......
......@@ -101,15 +101,19 @@ function AbstractLoki(collection, fileDAL) {
this.metaKey = () => metaKey(fileDAL.core);
this.lokiSave = (entity) => {
this.lokiExisting = (entity) => {
let uniqueFindConditions = this.idKeys.map((key) => {
let cond = {};
cond[key] = entity[key];
return cond;
});
let existing = collection.find({
return collection.find({
$and: uniqueFindConditions
})[0];
};
this.lokiSave = (entity) => {
let existing = this.lokiExisting(entity);
if (existing) {
if (!fileDAL.parentDAL) {
// Save in main branch: overrides main data
......
......@@ -3,172 +3,75 @@
*/
var Q = require('q');
var _ = require('underscore');
var co = require('co');
var sha1 = require('sha1');
var AbstractLoki = require('./AbstractLoki');
module.exports = CertDAL;
function CertDAL(rootPath, db, parentCore, localDAL, AbstractStorage) {
function CertDAL(fileDAL, loki) {
"use strict";
var that = this;
AbstractStorage.call(this, rootPath, db, parentCore, localDAL);
this.cachedLists = {
};
this.init = () => {
return Q.all([
that.coreFS.makeTree('certs/linked/from/'),
that.coreFS.makeTree('certs/linked/target/'),
that.coreFS.makeTree('certs/pending/from/'),
that.coreFS.makeTree('certs/pending/target/')
]);
};
this.getToTarget = function(hash) {
return co(function *() {
var linked = yield that.getLinkedToTarget(hash);
var notLinked = yield that.getNotLinkedToTarget(hash);
// Merge all results. Override unlinked certifications by their linked version
var mapOfCert = {};
linked.concat(notLinked).forEach(function(cert){
var cid = getCertID(cert);
if (!mapOfCert[cid] || !mapOfCert[cid].linked) {
mapOfCert[cid] = cert;
}
});
return _.values(mapOfCert);
});
};
this.getFromPubkey = function(pubkey) {
return co(function *() {
var linked = yield that.getLinkedFrom(pubkey);
var notLinked = yield that.getNotLinkedFrom(pubkey);
// Merge all results. Override unlinked certifications by their linked version
var mapOfCert = {};
linked.concat(notLinked).forEach(function(cert){
var cid = getCertID(cert);
if (!mapOfCert[cid] || !mapOfCert[cid].linked) {
mapOfCert[cid] = cert;
}
});
return _.values(mapOfCert);
});
};
this.getNotLinked = function() {
return co(function *() {
var certs = [], filesFound = [];
var files = yield that.coreFS.list('certs/pending/target');
yield files.map((file) => {
return co(function *() {
var files2 = yield that.coreFS.list('certs/pending/target/' + file + '/');
filesFound = _.uniq(filesFound.concat(files2.map(function(f2) {
return 'certs/pending/target/' + file + '/' + f2;
})));
});
});
files = _.uniq(filesFound);
yield files.map((file) => {
return that.coreFS.readJSON(file)
.then(function(data){
certs.push(data);
});
});
return certs;
});
};
this.getNotLinkedFrom = (pubkey) => that.coreFS.listJSON('certs/pending/from/' + pubkey + '/');
this.getLinkedFrom = function(pubkey) {
return co(function *() {
var certs = [];
var files = yield that.coreFS.list('certs/linked/from/' + pubkey + '/');
yield files.map((file) => {
return that.coreFS.listJSON('certs/linked/from/' + pubkey + '/' + file + '/').then(found => certs = certs.concat(found));
});
return certs;
});
};
this.getNotLinkedToTarget = (hash) =>
that.coreFS.listJSON('certs/pending/target/' + hash + '/');
this.listLocalPending = function() {
return co(function *() {
var certs = [];
var files = yield that.coreFS.listLocal('certs/pending/target/');
yield files.map((target) => {
return that.coreFS.listJSON('certs/pending/target/' + target + '/').then(found => certs = certs.concat(found));
});
return certs;
});
};
this.getLinkedToTarget = (hash) => that.coreFS.listJSON('certs/linked/target/' + hash + '/');
this.saveOfficial = function(cert) {
return co(function *() {
yield [
that.coreFS.makeTree('certs/linked/from/' + cert.from + '/' + cert.to + '/'),
that.coreFS.makeTree('certs/linked/target/' + cert.target + '/'),
that.coreFS.makeTree('certs/linked/from_uid/' + cert.from_uid + '/' + cert.to_uid + '/', cert)
];
yield that.coreFS.writeJSON('certs/linked/from/' + cert.from + '/' + cert.to + '/' + cert.block_number + '.json', cert);
yield that.coreFS.writeJSON('certs/linked/target/' + cert.target + '/' + getCertID(cert) + '.json', cert);
yield that.coreFS.writeJSON('certs/linked/from_uid/' + cert.from_uid + '/' + cert.to_uid + '/' + getCertID(cert) + '.json', cert);
return cert;
});
};
this.saveNewCertification = function(cert) {
return co(function *() {
yield [
that.coreFS.makeTree('certs/pending/target/' + cert.target + '/'),
that.coreFS.makeTree('certs/pending/from/' + cert.from + '/')
];
yield that.coreFS.writeJSON('certs/pending/target/' + cert.target + '/' + getCertID(cert) + '.json', cert);
yield that.coreFS.writeJSON('certs/pending/from/' + cert.from + '/' + getCertID(cert) + '.json', cert);
return cert;
});
let collection = loki.getCollection('certs') || loki.addCollection('certs', { indices: ['from', 'target', 'linked', 'written'] });
let blockCollection = loki.getCollection('blocks');
let current = blockCollection.chain().find({ fork: false }).simplesort('number', true).limit(1).data()[0];
let blocks = [], p = fileDAL;
let branchView;
while (p) {
if (p.core) {
blocks.push(p.core);
}
p = p.parentDAL;
}
let conditions = blocks.map((b) => {
return {
$and: [{
block_number: b.forkPointNumber
}, {
block_hash: b.forkPointHash
}]
};
});
conditions.unshift({
block_number: { $lte: current ? current.number : -1 }
});
branchView = collection.addDynamicView(['branch', fileDAL.name].join('_'));
branchView.applyFind({ '$or': conditions });
branchView.conditions = conditions;
AbstractLoki.call(this, collection, fileDAL);
this.idKeys = ['sig', 'from', 'target'];
this.metaProps = ['linked'];
this.init = () => null;
this.getToTarget = (hash) => this.lokiFind({
target: hash
});
this.getFromPubkey = (pubkey) => this.lokiFind({
from: pubkey
});
this.getNotLinked = () => this.lokiFindInAll({
linked: false
});
this.getNotLinkedToTarget = (hash) => this.lokiFind({
target: hash
},{
linked: false
});
this.listLocalPending = () => Q([]);
this.saveOfficial = (cert) => {
cert.linked = true;
return this.lokiSave(cert);
};
this.removeNotLinked = function(cert) {
return co(function *() {
var pendingTarget = 'certs/pending/target/' + cert.target + '/' + getCertID(cert) + '.json';
var pendingFromG = 'certs/pending/from/' + cert.from + '/' + getCertID(cert) + '.json';
var existsFrom = yield that.coreFS.exists(pendingFromG);
var existsTarget = yield that.coreFS.exists(pendingTarget);
if (existsTarget) {
yield that.coreFS.remove(pendingTarget);
}
if (existsFrom) {
yield that.coreFS.remove(pendingFromG);
}
});
};
this.saveNewCertification = (cert) =>
this.lokiSave(cert);
this.existsGivenCert = function(cert) {
return co(function *() {
var found = yield that.coreFS.read('certs/pending/target/' + cert.target + '/' + getCertID(cert) + '.json');
if (!found) {
found = yield that.coreFS.read('certs/linked/target/' + cert.target + '/' + getCertID(cert) + '.json');
}
if (found) {
found = JSON.parse(found);
}
return found;
});
};
function getCertID(cert) {
var sigHash = (sha1(cert.sig) + "").toUpperCase();
return [cert.from, cert.target, cert.block, sigHash].join('-');
}
this.existsGivenCert = (cert) => Q(this.lokiExisting(cert));
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ var _ = require('underscore');
var blockchainDao = require('../lib/blockchainDao');
var globalValidator = require('../lib/globalValidator');
var crypto = require('../lib/crypto');
var co = require('co');
var DO_NOT_THROW_ABOUT_EXPIRATION = true;
......@@ -71,12 +72,8 @@ function IdentityService (conf, dal) {
fifo.push(function (cb) {
logger.info('⬇ IDTY %s %s', idty.pubkey, idty.uid);
certs = _.sortBy(certs, function(c){ return parseInt(c.block_number); });
var hasCert2 = false;
certs.forEach(function(cert){
logger.info('⬇ CERT %s block#%s', cert.from, cert.block_number);
if (cert.block_number == 2) {
hasCert2 = true;
}
});
async.waterfall([
function (next) {
......@@ -98,10 +95,32 @@ function IdentityService (conf, dal) {
}, DO_NOT_THROW_ABOUT_EXPIRATION);
}, next);
},
function (next) {
co(function *() {
for (let i = 0; i < certs.length; i++) {
let cert = certs[i];
let basedBlock = yield dal.getBlock(cert.block_number);
if (cert.block_number == 0 && !basedBlock) {
basedBlock = {
number: 0,
hash: 'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'
};
}
cert.block_hash = basedBlock.hash;
}
}).then(() => next()).catch(next);
},
function (next){
certs = _.filter(certs, function(cert){ return !cert.err; });
async.forEachSeries(certs, function(cert, cb){
var mCert = new Certification({ pubkey: cert.from, sig: cert.sig, block_number: cert.block_number, target: obj.hash, to: idty.pubkey });
var mCert = new Certification({
pubkey: cert.from,
sig: cert.sig,
block_number: cert.block_number,
block_hash: cert.block_hash,
target: obj.hash,
to: idty.pubkey
});
async.waterfall([
function (next){
dal.existsCert(mCert).then(_.partial(next, null)).catch(next);
......
Supports Markdown
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