Skip to content
Snippets Groups Projects
Commit 98cd2566 authored by Cédric Moreau's avatar Cédric Moreau
Browse files

Implemented wot/add (no signature checking)

parent 12453c02
No related branches found
No related tags found
No related merge requests found
Showing
with 438 additions and 337 deletions
var fs = require('fs');
var util = require('util');
var async = require('async');
var _ = require('underscore');
var stream = require('stream');
var unix2dos = require('../lib/unix2dos');
var dos2unix = require('../lib/dos2unix');
var http2raw = require('../lib/streams/parsers/http2raw');
var jsoner = require('../lib/streams/jsoner');
var parsers = require('../lib/streams/parsers/doc');
var es = require('event-stream');
var http400 = require('../lib/http/http400');
var logger = require('../lib/logger')();
module.exports = function (wotServer) {
return new WOTBinding(wotServer);
}
function WOTBinding (wotServer) {
var conn = wotServer.conn;
var http = wotServer.HTTPService;
var ParametersService = wotServer.ParametersService;
var IdentityService = wotServer.IdentityService;
var Identity = conn.model('Identity');
this.lookup = function (req, res) {
async.waterfall([
function (next){
ParametersService.getSearch(req, next);
},
function (search, next){
IdentityService.search(search, next);
}
], function (err, identities) {
if(err){
res.send(400, err);
return;
}
var json = {
partial: false,
results: []
};
identities.forEach(function(identity){
json.results.push(identity.json());
});
res.send(200, JSON.stringify(json, null, " "));
});
};
this.add = function (req, res) {
var onError = http400(res);
http2raw.identity(req, onError)
.pipe(dos2unix())
.pipe(parsers.parseIdentity(onError))
.pipe(wotServer.singleWriteStream(onError))
.pipe(jsoner())
.pipe(es.stringify())
.pipe(res);
};
};
var META_TS = /^META:TS:[1-9][0-9]*$/;
module.exports = { module.exports = {
ERROR: { ERROR: {
...@@ -7,5 +10,18 @@ module.exports = { ...@@ -7,5 +10,18 @@ module.exports = {
} }
}, },
UDID2_FORMAT: /\(udid2;c;([A-Z-]*);([A-Z-]*);(\d{4}-\d{2}-\d{2});(e\+\d{2}\.\d{2}(\+|-)\d{3}\.\d{2});(\d+)(;?)\)/ UDID2_FORMAT: /\(udid2;c;([A-Z-]*);([A-Z-]*);(\d{4}-\d{2}-\d{2});(e\+\d{2}\.\d{2}(\+|-)\d{3}\.\d{2});(\d+)(;?)\)/,
BASE58: /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$/,
PUBLIC_KEY: /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{44}$/,
SIG: /^[A-Za-z0-9-_=]{87}$/,
CERT: {
SELF: {
UID: /^UID:udid2;c;([A-Z-]*);([A-Z-]*);(\d{4}-\d{2}-\d{2});(e\+\d{2}\.\d{2}(\+|-)\d{3}\.\d{2});(\d+)(;?)$/,
META: META_TS
},
OTHER: {
META: META_TS,
INLINE: /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{44}:[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{44}:[1-9][0-9]*:[A-Za-z0-9-_=]{87}$/
}
}
}; };
module.exports = function dos2unix(str){ var util = require('util');
var stream = require('stream');
module.exports = function (str) {
if (str)
return dos2unix(str);
else
return new Dos2UnixStream();
}
function dos2unix(str){
return str.replace(/\r\n/g, '\n'); return str.replace(/\r\n/g, '\n');
}; }
function Dos2UnixStream () {
stream.Transform.apply(this);
this._write = function (str, enc, done) {
this.push(dos2unix(str.toString()));
done();
}
}
util.inherits(Dos2UnixStream, stream.Transform);
var unix2dos = require('./unix2dos'); var dos2unix = require('./dos2unix');
module.exports = new function() { module.exports = new function() {
var that = this; var that = this;
this.getIdentity = function (json) {
var raw = "";
raw += json.pubkey + '\n';
raw += "UID:" + json.uid + '\n';
raw += "META:TS:" + json.time.timestamp() + '\n';
raw += json.sig + '\n';
return dos2unix(raw);
};
this.getAmendment = function (json) { this.getAmendment = function (json) {
var raw = ""; var raw = "";
raw += "Version: " + json.version + "\n"; raw += "Version: " + json.version + "\n";
...@@ -27,11 +36,11 @@ module.exports = new function() { ...@@ -27,11 +36,11 @@ module.exports = new function() {
raw += json.membersChanges[i] + "\n"; raw += json.membersChanges[i] + "\n";
} }
} }
return unix2dos(raw); return dos2unix(raw);
}; };
this.getPubkey = function (json) { this.getPubkey = function (json) {
return unix2dos(json.raw); return dos2unix(json.raw);
}; };
this.getTransactionWithoutSignature = function (json) { this.getTransactionWithoutSignature = function (json) {
...@@ -51,11 +60,11 @@ module.exports = new function() { ...@@ -51,11 +60,11 @@ module.exports = new function() {
raw += "Comment:\n" + json.comment; raw += "Comment:\n" + json.comment;
if (!raw.match(/\n$/)) if (!raw.match(/\n$/))
raw += '\n'; raw += '\n';
return unix2dos(raw); return dos2unix(raw);
}; };
this.getTransaction = function (json) { this.getTransaction = function (json) {
return unix2dos(signed(that.getTransactionWithoutSignature(json), json)); return dos2unix(signed(that.getTransactionWithoutSignature(json), json));
}; };
this.getPeerWithoutSignature = function (json) { this.getPeerWithoutSignature = function (json) {
...@@ -67,11 +76,11 @@ module.exports = new function() { ...@@ -67,11 +76,11 @@ module.exports = new function() {
json.endpoints.forEach(function(ep){ json.endpoints.forEach(function(ep){
raw += ep + "\n"; raw += ep + "\n";
}); });
return unix2dos(raw); return dos2unix(raw);
}; };
this.getPeer = function (json) { this.getPeer = function (json) {
return unix2dos(signed(that.getPeerWithoutSignature(json), json)); return dos2unix(signed(that.getPeerWithoutSignature(json), json));
}; };
this.getForwardWithoutSignature = function (json) { this.getForwardWithoutSignature = function (json) {
...@@ -87,11 +96,11 @@ module.exports = new function() { ...@@ -87,11 +96,11 @@ module.exports = new function() {
raw += json.keys[i] + "\n"; raw += json.keys[i] + "\n";
} }
} }
return unix2dos(raw); return dos2unix(raw);
}; };
this.getForward = function (json) { this.getForward = function (json) {
return unix2dos(signed(that.getForwardWithoutSignature(json), json)); return dos2unix(signed(that.getForwardWithoutSignature(json), json));
}; };
this.getStatusWithoutSignature = function (json) { this.getStatusWithoutSignature = function (json) {
...@@ -101,11 +110,11 @@ module.exports = new function() { ...@@ -101,11 +110,11 @@ module.exports = new function() {
raw += "Status: " + json.status + "\n"; raw += "Status: " + json.status + "\n";
raw += "From: " + json.from + "\n"; raw += "From: " + json.from + "\n";
raw += "To: " + json.to + "\n"; raw += "To: " + json.to + "\n";
return unix2dos(raw); return dos2unix(raw);
}; };
this.getStatus = function (json) { this.getStatus = function (json) {
return unix2dos(signed(that.getStatusWithoutSignature(json), json)); return dos2unix(signed(that.getStatusWithoutSignature(json), json));
}; };
this.getWalletWithoutSignature = function (json) { this.getWalletWithoutSignature = function (json) {
...@@ -123,11 +132,11 @@ module.exports = new function() { ...@@ -123,11 +132,11 @@ module.exports = new function() {
json.trusts.forEach(function (fingerprint) { json.trusts.forEach(function (fingerprint) {
raw += fingerprint + "\n"; raw += fingerprint + "\n";
}); });
return unix2dos(raw); return dos2unix(raw);
}; };
this.getWallet = function (json) { this.getWallet = function (json) {
return unix2dos(signed(that.getWalletWithoutSignature(json), json)); return dos2unix(signed(that.getWalletWithoutSignature(json), json));
}; };
this.getMembershipWithoutSignature = function (json) { this.getMembershipWithoutSignature = function (json) {
...@@ -138,11 +147,11 @@ module.exports = new function() { ...@@ -138,11 +147,11 @@ module.exports = new function() {
raw += "Date: " + json.date.timestamp() + "\n"; raw += "Date: " + json.date.timestamp() + "\n";
raw += "Membership: " + json.membership + "\n"; raw += "Membership: " + json.membership + "\n";
raw += "UserID: " + json.userid + "\n"; raw += "UserID: " + json.userid + "\n";
return unix2dos(raw); return dos2unix(raw);
}; };
this.getMembership = function (json) { this.getMembership = function (json) {
return unix2dos(signed(that.getMembershipWithoutSignature(json), json)); return dos2unix(signed(that.getMembershipWithoutSignature(json), json));
}; };
var KEYBLOCK_PUBK_PREFIX = "#####----"; var KEYBLOCK_PUBK_PREFIX = "#####----";
...@@ -170,11 +179,11 @@ module.exports = new function() { ...@@ -170,11 +179,11 @@ module.exports = new function() {
for(var i = 0; i < json.keysChanges.length; i++){ for(var i = 0; i < json.keysChanges.length; i++){
raw += this.getKeychange(json.keysChanges[i]); raw += this.getKeychange(json.keysChanges[i]);
} }
return unix2dos(raw); return dos2unix(raw);
}; };
this.getKeyblock = function (json) { this.getKeyblock = function (json) {
return unix2dos(signed(that.getKeyblockWithoutSignature(json), json)); return dos2unix(signed(that.getKeyblockWithoutSignature(json), json));
}; };
var KEYCHANGE_PREFIX = "#####----"; var KEYCHANGE_PREFIX = "#####----";
...@@ -195,11 +204,11 @@ module.exports = new function() { ...@@ -195,11 +204,11 @@ module.exports = new function() {
raw += json.membership.membership + "\n"; raw += json.membership.membership + "\n";
raw += json.membership.signature; raw += json.membership.signature;
} }
return unix2dos(raw); return dos2unix(raw);
}; };
this.getKeychange = function (json) { this.getKeychange = function (json) {
return unix2dos(signed(that.getKeychangeWithoutSignature(json), json)); return dos2unix(signed(that.getKeychangeWithoutSignature(json), json));
}; };
function signed (raw, json) { function signed (raw, json) {
......
var GenericParser = require('./GenericParser');
var util = require('util');
var split = require('../../../split');
var rawer = require('../../../rawer');
var sha1 = require('sha1');
var unix2dos = require('../../../unix2dos');
var jpgp = require('../../../jpgp');
var constants = require('../../../constants');
module.exports = IdentityParser;
function IdentityParser (onError) {
var captures = [];
var multilineFields = [];
GenericParser.call(this, captures, multilineFields, rawer.getIdentity, onError);
this._parse = function (str, obj) {
obj.certs = [];
var lines = str.split('\n');
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
switch (i) {
case 0:
if (line.match(constants.PUBLIC_KEY)) {
obj.pubkey = line;
}
break;
case 1:
if (line.match(constants.CERT.SELF.UID)) {
obj.uid = line.split(':')[1];
}
break;
case 2:
if (line.match(constants.CERT.SELF.META)) {
var timestamp = parseInt(line.match(/TS:(\d+)/)[1]);
obj.time = new Date(timestamp*1000);
}
break;
case 3:
if (line.match(constants.SIG)) {
obj.sig = line;
}
break;
default:
if (line.match(constants.CERT.OTHER.INLINE)) {
var sp = line.split(':');
var cert = { from: sp[0], time: sp[1], sig: sp[2] };
obj.certs.push(cert);
}
break;
}
}
};
this._clean = function (obj) {
if (obj.uid && obj.time && obj.sig) {
obj.hash = sha1(obj.uid + obj.time.timestamp() + obj.sig).toUpperCase();
}
};
this._verify = function (obj) {
if (!obj.pubkey) {
return "No pubkey found";
}
if (!obj.uid) {
return "Cannot extract udid2";
}
if (!obj.time) {
return "Cannot extract signature time";
}
if (!obj.sig) {
return "No signature found for self-certification";
}
};
}
util.inherits(IdentityParser, GenericParser);
module.exports = { module.exports = {
parsePubkey: instanciate.bind(instanciate, require('./pubkey')), parseIdentity: instanciate.bind(instanciate, require('./identity')),
parseTransaction: instanciate.bind(instanciate, require('./transaction')), parseTransaction: instanciate.bind(instanciate, require('./transaction')),
parsePeer: instanciate.bind(instanciate, require('./peer')), parsePeer: instanciate.bind(instanciate, require('./peer')),
parseForward: instanciate.bind(instanciate, require('./forward')), parseForward: instanciate.bind(instanciate, require('./forward')),
......
...@@ -2,7 +2,7 @@ var stream = require('stream'); ...@@ -2,7 +2,7 @@ var stream = require('stream');
var util = require('util'); var util = require('util');
module.exports = { module.exports = {
pubkey: instanciate.bind(null, Http2RawPubkey), identity: instanciate.bind(null, Http2RawIdentity),
transaction: instanciate.bind(null, Http2RawTransaction), transaction: instanciate.bind(null, Http2RawTransaction),
peer: instanciate.bind(null, Http2RawPeer), peer: instanciate.bind(null, Http2RawPeer),
forward: instanciate.bind(null, Http2RawForward), forward: instanciate.bind(null, Http2RawForward),
...@@ -16,19 +16,21 @@ function instanciate (constructorFunc, req, onError) { ...@@ -16,19 +16,21 @@ function instanciate (constructorFunc, req, onError) {
return new constructorFunc(req, onError); return new constructorFunc(req, onError);
}; };
function Http2RawPubkey (req, onError) { function Http2RawIdentity (req, onError) {
stream.Readable.call(this); stream.Readable.call(this);
this._read = function () { this._read = function () {
if(!req.body || !req.body.keytext){ if(!req.body || !req.body.pubkey){
onError('Parameter `keytext` is required'); onError('Parameter `pubkey` is required');
} }
else if(!req.body.keytext.match(/BEGIN PGP PUBLIC KEY/) || !req.body.keytext.match(/END PGP PUBLIC KEY/)){ else if(!req.body || !req.body.self){
onError('Keytext does not look like a public key message'); onError('Parameter `self` is required');
} }
else { else {
this.push(req.body.keytext); var raw = req.body.pubkey + '\n' + req.body.self + (req.body.other ? '\n' + req.body.other : '');
console.log(raw);
this.push(raw);
} }
this.push(null); this.push(null);
} }
...@@ -139,7 +141,7 @@ function Http2RawKeyblock (req, onError) { ...@@ -139,7 +141,7 @@ function Http2RawKeyblock (req, onError) {
} }
} }
util.inherits(Http2RawPubkey, stream.Readable); util.inherits(Http2RawIdentity, stream.Readable);
util.inherits(Http2RawTransaction, stream.Readable); util.inherits(Http2RawTransaction, stream.Readable);
util.inherits(Http2RawPeer, stream.Readable); util.inherits(Http2RawPeer, stream.Readable);
util.inherits(Http2RawForward, stream.Readable); util.inherits(Http2RawForward, stream.Readable);
......
var mongoose = require('mongoose');
var async = require('async');
var sha1 = require('sha1');
var _ = require('underscore');
var Schema = mongoose.Schema;
var unix2dos = require('../lib/unix2dos');
var parsers = require('../lib/streams/parsers/doc');
var constants = require('../lib/constants');
var logger = require('../lib/logger')('pubkey');
var IdentitySchema = new Schema({
uid: String,
pubkey: String,
sig: String,
time: { type: Date, default: Date.now },
hash: { type: String, unique: true },
created: { type: Date, default: Date.now },
updated: { type: Date, default: Date.now }
});
IdentitySchema.pre('save', function (next) {
this.updated = Date.now();
next();
});
IdentitySchema.virtual('certifs').get(function () {
return this._certifs || [];
});
IdentitySchema.virtual('certifs').set(function (newCertifs) {
this._certifs = (newCertifs && newCertifs.length) || [newCertifs];
});
IdentitySchema.methods = {
json: function () {
var uids = [{
"uid": this.uid,
"meta": {
"timestamp": this.time.timestamp()
},
"self": this.sig
}];
return {
"pubkey": this.pubkey,
"uids": uids
};
}
};
IdentitySchema.statics.getByHash = function (hash, done) {
var Identity = this.model('Identity');
Identity.find({ "hash": hash }, function (err, identities) {
if(identities.length > 1){
done('Multiple identities found for hash ' + hash + '.');
return;
}
done(null, identities[0] || null);
});
};
IdentitySchema.statics.search = function (search, done) {
var obj = this;
var found = [];
var searchByUID = {
byPublicKey: function(callback){
obj.find({ pubkey: new RegExp(search)}, function (err, keys) {
found.push(keys);
callback();
});
},
byUID: function(callback){
obj.find({ uid: new RegExp(search)}, function (err, keys) {
found.push(keys);
callback();
});
}
};
async.parallel(searchByUID, function(err) {
var identities = {};
var foundIds = _(found).flatten();
async.each(foundIds, function (key, done) {
identities[key.id] = key;
done();
}, function (err) {
done(err, _(identities).values());
});
});
};
module.exports = IdentitySchema;
var jpgp = require('../lib/jpgp');
var async = require('async');
var _ = require('underscore');
var merkle = require('merkle');
var vucoin = require('vucoin');
var keyhelper = require('../lib/keyhelper');
var logger = require('../lib/logger')('pubkey');
module.exports.get = function (conn, conf) {
return new IdentityService(conn, conf);
};
function IdentityService (conn, conf) {
var Identity = conn.model('Identity');
var fifo = async.queue(function (task, callback) {
task(callback);
}, 1);
this.search = function(search, done) {
var identities = [];
async.waterfall([
function (next){
Identity.search(search, next);
},
], done);
};
/**
* Tries to persist a public key given in ASCII-armored format.
* Returns the database stored public key.
*/
this.submitIdentity = function(obj, done) {
var idty = new Identity(obj);
var that = this;
fifo.push(function (cb) {
async.waterfall([
function (next) {
Identity.getByHash(obj.hash, next);
},
function (existing, next){
if (existing)
next(null, existing);
else {
// Create
idty.save(function (err) {
next(err, idty);
});
}
},
], cb);
}, done);
};
}
...@@ -17,6 +17,14 @@ function ParameterNamespace (conn, currency) { ...@@ -17,6 +17,14 @@ function ParameterNamespace (conn, currency) {
var Forward = conn.model('Forward'); var Forward = conn.model('Forward');
var Wallet = conn.model('Wallet'); var Wallet = conn.model('Wallet');
this.getSearch = function (req, callback) {
if(!req.params || !req.params.search){
callback("No search criteria given");
return;
}
callback(null, req.params.search);
};
this.getTransaction = function (req, callback) { this.getTransaction = function (req, callback) {
async.waterfall([ async.waterfall([
function (next){ function (next){
......
<% for(var i = 0; i < pubKeys.length; i++){ %>
<%= pubKeys[i].fingerprint %>
<%- pubKeys[i].name %> (<%- pubKeys[i].comment %>) <<%- pubKeys[i].email %>>
RAW:
<%= pubKeys[i].raw %>
<% } %>
\ No newline at end of file
<% for(var i = 0; i < pubKeys.length; i++){ %>
<%= pubKeys[i].fingerprint %>
<%= pubKeys[i].name %> (<%= pubKeys[i].comment %>) <<%= pubKeys[i].email %>>
<% } %>
\ No newline at end of file
<html>
<body>
<h1>Public Key Server -- Get "<%= search %>" (key count: <%= nbKeys %>)</h1>
<pre>
<%= armor %>
</pre>
</body>
</html>
...@@ -407,32 +407,32 @@ program ...@@ -407,32 +407,32 @@ program
program program
.command('start') .command('start')
.description('Start uCoin server using given --currency') .description('Start uCoin server using given --currency')
.action(service(ucoin.createTxServer, function (server, conf) { .action(service(ucoin.createWOTServer, function (server, conf) {
server // server
.pipe(router(server.PeeringService.cert.fingerprint, server.conn)) // .pipe(router(server.PeeringService.cert.fingerprint, server.conn))
.pipe(multicaster()); // .pipe(multicaster());
async.waterfall([ async.waterfall([
function (next){ // function (next){
server.checkConfig(function (err) { // server.checkConfig(function (err) {
if (err) { // if (err) {
// If required, launch config // // If required, launch config
var wiz = wizard(server); // var wiz = wizard(server);
async.waterfall([ // async.waterfall([
function (next){ // function (next){
wiz.doTasks(['currency', 'openpgp', 'key', 'network'], conf, next); // wiz.doTasks(['currency', 'openpgp', 'key', 'network'], conf, next);
}, // },
function (next){ // function (next){
conf.save(next); // conf.save(next);
}, // },
], function (err) { // ], function (err) {
next(err); // next(err);
}); // });
} // }
else next(); // else next();
}); // });
}, // },
function (next){ function (next){
// Launching server // Launching server
server.start(function (err, app) { server.start(function (err, app) {
......
# Coin algorithms
In uCoin's [amendments](./HDC.md#amendment), a field name `CoinAlgo` is dedicated to describe the rules for both generation and interpretation of `CoinList` and `CoinBase` amendment's fields.
Here is a list of known algorithms (only `1` for now).
## Base2Draft
### Usage
In an [Amendment](./HDC.md#amendment) : `CoinAlgo: Base2Draft`.
### Properties
This algorithm uses « base 2 » numerical representation for coins' quantitative value.
### Coin value
Each number in `CoinList` field represents a 2<sup>`n`</sup> value, starting from left first number = 2<sup>`CoinBase`</sup>, and for each number, increase the `CoinBase` value.
Each number in `CoinList` tells how much coins of each value are issued.
#### Example
```bash
CoinAlgo: Base2Draft
CoinBase: 3
CoinList: 2 1 0 5
```
In such case, generated coins are:
* `2` coins of value 2<sup>3</sup> = 2<sup>`CoinBase`</sup>
* `1` coins of value 2<sup>4</sup> = 2<sup>`CoinBase + 1`</sup>
* `0` coins of value 2<sup>5</sup> = 2<sup>`CoinBase + 2`</sup>
* `5` coins of value 2<sup>6</sup> = 2<sup>`CoinBase + 3`</sup>
We can deduce here that `UniversalDividend` equals `352`.
### Coin determination
#### Prerequisties
* `UniversalDividend` amount, abbreviated `UD`
#### Algorithm
##### Parameters
* `p` : the threshlod under which the algorithm should not create coins while it can
##### Functions
`L(n, p) = [ P(n-1,p) P(n-1,p) ... P(0,p) ]`
`P(n, p) = [ min(n,p) min(n,p)+0 min(n,p)+1 ... min(n,p)+(n-1) ]`
##### Description
// Initialization
coins = []
groups = {}
rest = UD
// Compute coins 2^ values
while (rest >= 0)
pow2 = highestPow2Value(rest)
rest = rest - pow(2, pow2)
coins = concat(coins, L(pow2, p))
// Count the number of occurences for each coin
foreach pow2 in coins
if (exists(groups(pow2)))
groups(pow2) = groups(pow2) + 1
else
groups(pow2) = 1
// Sort the coins counts by their coin value
sortByKey(groups)
### Example 1
Let's make coins with `UD = 32`, and `p = 0` (`2^p = 1`):
32 = 16 + 8 + 4 + 2 + 1 + 1
=
8 =
+4 4 =
+2 +2 2 =
+1 +1 +1 1 = =
+1 +1 +1 +1 1 1
Giving:
CoinAlgo: Base2Draft
CoinBase: 0
CoinList: 10 3 2 1
### Example 2
Let's make coins with `UD = 13`, and `p = 0` (`2^p = 1`):
#### Decimal format
13 = 8 + 4 + 1
=
4 =
+2 2
+1 +1 =
+1 +1 1
#### Binary format
13 = 8 + 4 + 1
=
2 =
+1 1
+0 +0 =
+0 +0 0
Giving:
CoinAlgo: Base2Draft
CoinBase: 0
CoinList: 5 2 1
### Example 3
Let's make coins with `UD = 13`, and `p = 1` (`2^p = 2`):
13 = 8 + 4 + 1
=
4 =
+2 2
+2 +2 =
1
Giving:
CoinAlgo: Base2Draft
CoinBase: 0
CoinList: 1 4 1
### Example 4
Let's make coins with `UD = 13`, and `p = 2` (`2^p = 4`):
13 = 8 + 4 + 1
=
4 =
+4 4
=
1
Giving:
CoinAlgo: Base2Draft
CoinBase: 0
CoinList: 1 4 1
\ No newline at end of file
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
----------------- -----------------
| UCP | uCoin protocol | UCP | uCoin protocol
| ------------- | | ------------- |
| | OpenPGP | | Cryptography features | | Ed25519 | | Cryptography features
----------------- -----------------
``` ```
...@@ -30,4 +30,4 @@ Layer | Role ...@@ -30,4 +30,4 @@ Layer | Role
uCoin | The software that implements UCP. May implement UCP throught BMA or any other future protocol. uCoin | The software that implements UCP. May implement UCP throught BMA or any other future protocol.
[BMA](./HTTP_API.md) | A communication protocol to exchange HDC and Network messages over HTTP. [BMA](./HTTP_API.md) | A communication protocol to exchange HDC and Network messages over HTTP.
[UCP](./Protocol.md) | A protocol defining how to handle Network and HDC messages in order to build a uCoin network. [UCP](./Protocol.md) | A protocol defining how to handle Network and HDC messages in order to build a uCoin network.
OpenPGP | Cryptography format providing horizontal authentication features. Ed25519 | Cryptography format providing authentication features.
var Server = require('./server'); var Server = require('./server');
var PKSServer = require('./pksserver');
var WOTServer = require('./wotserver'); var WOTServer = require('./wotserver');
var PeerServer = require('./peerserver'); var PeerServer = require('./peerserver');
var TxServer = require('./txserver'); var TxServer = require('./txserver');
...@@ -9,9 +8,6 @@ module.exports = { ...@@ -9,9 +8,6 @@ module.exports = {
connect: function (dbConf, overConf) { connect: function (dbConf, overConf) {
return new Server(dbConf, overConf); return new Server(dbConf, overConf);
}, },
createPKSServer: function (dbConf, overConf) {
return new PKSServer(dbConf, overConf);
},
createWOTServer: function (dbConf, overConf) { createWOTServer: function (dbConf, overConf) {
return new WOTServer(dbConf, overConf); return new WOTServer(dbConf, overConf);
}, },
......
...@@ -29,13 +29,11 @@ ...@@ -29,13 +29,11 @@
"dependencies": { "dependencies": {
"express": "~3.4.7", "express": "~3.4.7",
"commander": "~2.1.0", "commander": "~2.1.0",
"ejs": "~0.8.5",
"mongoose": "~3.8.4", "mongoose": "~3.8.4",
"async": "~0.2.9", "async": "~0.2.9",
"sha1": "~1.1.0", "sha1": "~1.1.0",
"openpgp": "0.5.1", "openpgp": "0.5.1",
"merkle": "~0.1.0", "merkle": "~0.1.0",
"connect-pgp": "~0.3.0",
"underscore": "~1.5.2", "underscore": "~1.5.2",
"vucoin": "~0.20.0", "vucoin": "~0.20.0",
"request": "~2.31.0", "request": "~2.31.0",
......
...@@ -17,74 +17,70 @@ function PeerServer (dbConf, overrideConf, interceptors, onInit) { ...@@ -17,74 +17,70 @@ function PeerServer (dbConf, overrideConf, interceptors, onInit) {
var selfInterceptors = [ var selfInterceptors = [
{ {
// Peer // Membership
matches: function (obj) { matches: function (obj) {
return obj.endpoints ? true : false; return obj.userid ? true : false;
}, },
treatment: function (server, obj, next) { treatment: function (server, obj, next) {
plogger.debug('⬇ PEER %s', obj.pubkey.fingerprint);
async.waterfall([ async.waterfall([
function (next){ function (next){
that.PeeringService.submit(obj, next); that.KeychainService.submitMembership(obj, next);
}, },
function (peer, next){ function (membership, next){
plogger.debug('✔ PEER %s %s:%s', peer.fingerprint, peer.getIPv4() || peer.getIPv6(), peer.getPort()); that.emit('membership', membership);
that.emit('peer', peer); next(null, membership);
next(null, peer);
}, },
], next); ], next);
} }
},{ },{
// Forward // KeyBlock
matches: function (obj) { matches: function (obj) {
return obj.forward ? true : false; return obj.type && obj.type == 'KeyBlock' ? true : false;
}, },
treatment: function (server, obj, next) { treatment: function (server, obj, next) {
flogger.debug('⬇ FWD %s type %s', obj.from, obj.forward);
async.waterfall([ async.waterfall([
function (next){ function (next){
that.PeeringService.submitForward(obj, next); server.KeychainService.submitKeyBlock(obj, next);
}, },
function (forward, next){ function (kb, next){
flogger.debug('✔ FWD %s type %s', forward.from, forward.forward); server.emit('keyblock', kb);
that.emit('forward', forward); next(null, kb);
next(null, forward);
}, },
], next); ], next);
} }
},{ },{
// Status // Peer
matches: function (obj) { matches: function (obj) {
return obj.status ? true : false; return obj.endpoints ? true : false;
}, },
treatment: function (server, obj, next) { treatment: function (server, obj, next) {
slogger.debug('STATUS %s %s', obj.pubkey.fingerprint, obj.status); plogger.debug('PEER %s', obj.pubkey.fingerprint);
async.waterfall([ async.waterfall([
function (next){ function (next){
that.PeeringService.submitStatus(obj, next); that.PeeringService.submit(obj, next);
}, },
function (status, peer, wasStatus, next){ function (peer, next){
slogger.debug('STATUS %s %s', status.pubkey.fingerprint, status.status); plogger.debug('PEER %s %s:%s', peer.fingerprint, peer.getIPv4() || peer.getIPv6(), peer.getPort());
that.emit('status', status); that.emit('peer', peer);
next(null, status); next(null, peer);
}, },
], next); ], next);
} }
},{ },{
// Wallet // Status
matches: function (obj) { matches: function (obj) {
return obj.requiredTrusts ? true : false; return obj.status ? true : false;
}, },
treatment: function (server, obj, next) { treatment: function (server, obj, next) {
slogger.debug('WALLET %s', obj.pubkey.fingerprint); slogger.debug('STATUS %s %s', obj.pubkey.fingerprint, obj.status);
async.waterfall([ async.waterfall([
function (next){ function (next){
that.WalletService.submit(obj, next); that.PeeringService.submitStatus(obj, next);
}, },
function (wallet, next){ function (status, peer, wasStatus, next){
wlogger.debug('WALLET %s', obj.pubkey.fingerprint); slogger.debug('STATUS %s %s', status.pubkey.fingerprint, status.status);
that.emit('wallet', wallet); that.emit('status', status);
next(null, wallet); next(null, status);
}, },
], next); ], next);
} }
...@@ -355,6 +351,16 @@ function PeerServer (dbConf, overrideConf, interceptors, onInit) { ...@@ -355,6 +351,16 @@ function PeerServer (dbConf, overrideConf, interceptors, onInit) {
this.listenNET(app); this.listenNET(app);
}; };
this.listenWOT = function (app) {
var keychain = require('./app/controllers/keychain')(that);
app.get( '/keychain/parameters', keychain.parameters);
app.post( '/keychain/membership', keychain.parseMembership);
app.post( '/keychain/keyblock', keychain.parseKeyblock);
app.get( '/keychain/keyblock/:number', keychain.promoted);
app.get( '/keychain/current', keychain.current);
app.get( '/keychain/hardship/:fpr', keychain.hardship);
};
this.listenNET = function (app) { this.listenNET = function (app) {
var net = require('./app/controllers/network')(that, that.conf); var net = require('./app/controllers/network')(that, that.conf);
app.get( '/network/pubkey', net.pubkey); app.get( '/network/pubkey', net.pubkey);
......
var async = require('async');
var util = require('util');
var parsers = require('./app/lib/streams/parsers/doc');
var Server = require('./server');
function PKSServer (dbConf, overrideConf, interceptors, onInit) {
var logger = require('./app/lib/logger')(dbConf.name);
var selfInterceptors = [
{
// Pubkey
matches: function (obj) {
return typeof obj.email != "undefined";
},
treatment: function (server, obj, next) {
logger.debug('⬇ PUBKEY %s', obj.fingerprint);
async.waterfall([
function (next){
server.PublicKeyService.submitPubkey(obj, next);
},
function (pubkey, next){
logger.debug('✔ PUBKEY %s', pubkey.fingerprint);
server.emit('pubkey', pubkey);
next(null, pubkey);
},
], next);
}
}
];
Server.call(this, dbConf, overrideConf, selfInterceptors.concat(interceptors || []), onInit || []);
var that = this;
this._read = function (size) {
};
this.writeRawPubkey = function (raw) {
var source = parsers.parsePubkey();
var dest = that.singleWriteStream();
source.pipe(dest);
source.end(raw);
};
this._initServices = function(conn, done) {
this.KeyService = require('./app/service/KeyService').get(conn);
this.PublicKeyService = require('./app/service/PublicKeyService').get(conn, that.conf, that.KeyService);
done();
};
this._listenBMA = function (app) {
this.listenPKS(app);
};
this.listenPKS = function (app) {
var pks = require('./app/controllers/pks')(this);
app.get( '/pks/all', pks.getAll);
app.get( '/pks/lookup', pks.lookup);
app.post( '/pks/add', pks.add);
};
}
util.inherits(PKSServer, Server);
module.exports = PKSServer;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment