From 5f5eb2be81a125fd60b14638fb2dc54b492fc220 Mon Sep 17 00:00:00 2001 From: cgeek <cem.moreau@gmail.com> Date: Thu, 9 Oct 2014 01:06:17 +0200 Subject: [PATCH] Certifications from WoT to WoT are also integrated within new blocks --- app/models/certification.js | 12 +++++- app/models/identity.js | 7 ++++ app/service/BlockchainService.js | 71 +++++++++++++++++++++----------- app/service/IdentityService.js | 6 +-- 4 files changed, 68 insertions(+), 28 deletions(-) diff --git a/app/models/certification.js b/app/models/certification.js index 6f618ecdf..0bda45725 100644 --- a/app/models/certification.js +++ b/app/models/certification.js @@ -15,6 +15,7 @@ var CertificationSchema = new Schema({ time: { type: Date, default: Date.now }, target: String, to: String, + linked: { type: Boolean, default: false }, created: { type: Date, default: Date.now }, updated: { type: Date, default: Date.now } }); @@ -34,9 +35,9 @@ CertificationSchema.virtual('when').get(function () { CertificationSchema.methods = { - exists: function (done) { + existing: function (done) { this.model('Certification').find({ "pubkey": this.pubkey, "sig": this.sig, "time": this.time, "target": this.target }, function (err, certs) { - done(err, certs && certs.length > 0); + done(err, certs && certs.length > 0 ? certs[0] : null); }); }, @@ -77,4 +78,11 @@ CertificationSchema.statics.from = function (pubkey, done) { }); }; +CertificationSchema.statics.findNew = function (done) { + var Certification = this.model('Certification'); + Certification.find({ "linked": false }, function (err, certs) { + done(err, certs); + }); +}; + module.exports = CertificationSchema; diff --git a/app/models/identity.js b/app/models/identity.js index b3497f7fd..ecab6b5c8 100644 --- a/app/models/identity.js +++ b/app/models/identity.js @@ -144,6 +144,13 @@ IdentitySchema.statics.isMember = function(pubkey, done){ }); } +IdentitySchema.statics.isMemberOrError = function(pubkey, done){ + var Identity = this.model('Identity'); + Identity.isMember(pubkey, function (err, isMember) { + done(err || (!isMember && "Not a member")); + }); +} + IdentitySchema.statics.getMember = function(pubkey, done){ var Identity = this.model('Identity'); Identity.find({ "pubkey": pubkey, "member": true }, function (err, identities) { diff --git a/app/service/BlockchainService.js b/app/service/BlockchainService.js index 54ff51121..f9c1e95dc 100644 --- a/app/service/BlockchainService.js +++ b/app/service/BlockchainService.js @@ -317,16 +317,16 @@ function BlockchainService (conn, conf, IdentityService, PeeringService) { }, function (idty, next){ cert.target = idty.getTargetHash(); - cert.exists(next); + cert.existing(next); }, - function (exists, next) { - if (exists) { - next(); - } else { - cert.save(function (err) { - next(err); - }); + function (existing, next) { + if (existing) { + cert = existing; } + cert.linked = true; + cert.save(function (err) { + next(err); + }); } ], callback); }, done); @@ -508,23 +508,49 @@ function BlockchainService (conn, conf, IdentityService, PeeringService) { function (next){ findUpdates(next); }, - function (updates, subupdates, next){ + function (updates, next){ Block.current(function (err, current) { - next(null, current || null, updates, subupdates); + next(null, current || null, updates); }); }, - function (current, updates, subupdates, next){ - createNewcomerBlock(current, null, {}, updates, subupdates, next); + function (current, updates, next){ + createNewcomerBlock(current, null, {}, updates, next); }, ], done); } function findUpdates (done) { var updates = {}; - var subupdates = {}; done(null, [], []); // TODO: certifications - // updates[pubkey] = certifications; + async.waterfall([ + function (next){ + Certification.findNew(next); + }, + function (certs, next){ + async.forEachSeries(certs, function(cert, callback){ + async.waterfall([ + function (next){ + // Signatory must be a member + Identity.isMemberOrError(cert.from, next); + }, + function (next){ + // Certified must be a member + Identity.isMemberOrError(cert.to, next); + }, + function (next){ + updates[cert.to] = updates[cert.to] || []; + updates[cert.to].push(cert); + next(); + }, + ], function (err) { + callback(); + }); + }, next); + }, + ], function (err) { + done(err, updates); + }); } /** @@ -605,7 +631,9 @@ function BlockchainService (conn, conf, IdentityService, PeeringService) { * Generate a "newcomers" keyblock */ this.generateNewcomersBlock = function (filteringFunc, checkingWoTFunc, done) { - var withoutUpdates = function(updates) { updates(null, {}, {}); }; + var withoutUpdates = function(updatesDone) { + updatesDone(null, {}); + }; KeychainService.generateNextBlock(withoutUpdates, filteringFunc, checkingWoTFunc, done); }; @@ -614,7 +642,6 @@ function BlockchainService (conn, conf, IdentityService, PeeringService) { */ this.generateNextBlock = function (findUpdateFunc, filteringFunc, checkingWoTFunc, done) { var updates = {}; - var subupdates = {}; async.waterfall([ function (next) { // First, check for members' key updates @@ -622,7 +649,6 @@ function BlockchainService (conn, conf, IdentityService, PeeringService) { }, function (theUpdates, theSubupdates, next) { updates = theUpdates; - subupdates = theSubupdates; findNewcomers(filteringFunc, checkingWoTFunc, next); }, function (current, newWoT, joinData, otherUpdates, next){ @@ -631,10 +657,10 @@ function BlockchainService (conn, conf, IdentityService, PeeringService) { if (!updates[fpr]) updates[fpr] = otherUpdates[fpr]; else - updates[fpr].concat(otherUpdates[fpr]); + updates[fpr] = updates[fpr].concat(otherUpdates[fpr]); }); // Create the block - createNewcomerBlock(current, joinData, updates, subupdates, next); + createNewcomerBlock(current, joinData, updates, next); }, ], done); }; @@ -805,7 +831,6 @@ function BlockchainService (conn, conf, IdentityService, PeeringService) { } function findSignaturesFromNewcomerToWoT (newcomer, done) { - var updates = {}; async.waterfall([ function (next){ @@ -844,7 +869,7 @@ function BlockchainService (conn, conf, IdentityService, PeeringService) { return matched; } - function createNewcomerBlock (current, joinData, updates, subupdates, done) { + function createNewcomerBlock (current, joinData, updates, done) { var block = new Block(); block.version = 1; block.currency = current ? current.currency : conf.currency; @@ -880,7 +905,7 @@ function BlockchainService (conn, conf, IdentityService, PeeringService) { block.leavers = []; // Kicked people block.excluded = []; - // Certifications FROM the WoT + // Certifications from the WoT, to newcomers block.certifications = []; joiners.forEach(function(joiner){ var data = joinData[joiner]; @@ -888,7 +913,7 @@ function BlockchainService (conn, conf, IdentityService, PeeringService) { block.certifications.push(cert.inline()); }); }); - // Certifications TO the WoT + // Certifications from the WoT, to the WoT _(updates).keys().forEach(function(certifiedMember){ var certs = updates[certifiedMember]; certs.forEach(function(cert){ diff --git a/app/service/IdentityService.js b/app/service/IdentityService.js index 7a44c2274..f50efdcb3 100644 --- a/app/service/IdentityService.js +++ b/app/service/IdentityService.js @@ -54,10 +54,10 @@ function IdentityService (conn, conf) { var mCert = new Certification({ pubkey: cert.from, sig: cert.sig, time: cert.time, target: obj.hash, to: idty.pubkey }); async.waterfall([ function (next){ - mCert.exists(next); + mCert.existing(next); }, - function (exists, next){ - if (exists) next(); + function (existing, next){ + if (existing) next(); else mCert.save(function (err) { next(err); }); -- GitLab