Commit 9cf59871 authored by Cédric Moreau's avatar Cédric Moreau

Add currency parameters configuration

parent c20eaf46
......@@ -16,7 +16,7 @@ var IPV6_REGEXP = /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}
function Wizard () {
this.configAll = function (conf, done) {
doTasks(['currency', 'openpgp', 'network', 'key'], conf, done);
doTasks(['currency', 'openpgp', 'network', 'key', 'ucp'], conf, done);
};
this.configCurrency = function (conf, done) {
......@@ -34,6 +34,10 @@ function Wizard () {
this.configKey = function (conf, done) {
doTasks(['key'], conf, done);
};
this.configUCP = function (conf, done) {
doTasks(['ucp'], conf, done);
};
}
function doTasks (todos, conf, done) {
......@@ -279,6 +283,42 @@ var tasks = {
}
}
], done);
},
ucp: function (conf, done) {
async.waterfall([
async.apply(simpleInteger, "Delay between 2 identical certifications", "sigDelay", conf),
async.apply(simpleInteger, "Certification validity duration", "sigValidity", conf),
async.apply(simpleInteger, "Number of valid certifications required to be a member", "sigQty", conf),
async.apply(simpleInteger, "Minimum number of leading zeros for a proof-of-work", "powZeroMin", conf),
function (next){
choose("Lowering proof-of-work difficulty using a percentage of WoT size", !conf.powPeriodC,
function ifPercentage () {
conf.powPeriodC = false;
async.waterfall([
async.apply(simpleInteger, "Number of blocks to wait for lowering difficulty = % members count, how much", "powPeriod", conf),
], next);
},
function ifConstant () {
conf.powPeriodC = true;
async.waterfall([
async.apply(simpleInteger, "Number of blocks to wait to lower proof-of-work difficulty", "powPeriod", conf),
], next);
});
},
function (next){
choose("Participate writing the keychain (when member)", conf.participate,
function participate () {
conf.participate = true;
next();
},
function doNotParticipate () {
conf.participate = false;
next();
});
},
async.apply(simpleInteger, "Acceptable time offset when receiving a new keyblock", "tsInterval", conf),
], done);
}
};
......
......@@ -18,6 +18,14 @@ var ConfigurationSchema = new Schema({
kmanagement: {"type": String, "default": "ALL"},
kaccept: {"type": String, "default": "ALL"},
upInterval: {"type": Number, "default": 3600*1000},
sigDelay: {"type": Number, "default": 3600*24*365*5}, // 5 years by default
sigValidity: {"type": Number, "default": 3600*24*365}, // 1 year by default
sigQty: {"type": Number, "default": 5},
powZeroMin: {"type": Number, "default": 4},
powPeriod: {"type": Number, "default": 1},
powPeriodC: {"type": Boolean, "default": true}, // Default using Constant value '1'
participate: {"type": Boolean, "default": true}, // Participate to writing the keychain
tsInterval: {"type": Number, "default": 30},
});
ConfigurationSchema.virtual('createNext').get(function () {
......
......@@ -27,13 +27,6 @@ function KeyService (conn, conf, PublicKeyService) {
var Link = conn.model('Link');
var Key = conn.model('Key');
var MINIMUM_ZERO_START = 1;
var PROOF_OF_WORK_PERIOD = 1; // Value 1 allows for continuous single-member writing with minimum difficulty
var LINK_QUANTITY_MIN = 1;
var MAX_STEPS = 1;
var MAX_LINK_VALIDITY = 3600*24*30; // 30 days
var MAX_TIMESTAMP_DELAY = 30; // in seconds
this.load = function (done) {
done();
};
......@@ -137,7 +130,7 @@ function KeyService (conn, conf, PublicKeyService) {
return;
}
// Test timestamp
if (Math.abs(block.timestamp - now.utcZero().timestamp()) > MAX_TIMESTAMP_DELAY) {
if (Math.abs(block.timestamp - now.utcZero().timestamp()) > conf.tsInterval) {
next('Timestamp does not match this node\'s time');
return;
}
......@@ -477,13 +470,13 @@ function KeyService (conn, conf, PublicKeyService) {
var count = links.length;
if (newLinks[target] && newLinks[target].length)
count += newLinks[target].length;
next(count < LINK_QUANTITY_MIN && 'Key ' + target.substring(24) + ' does not have enough links (' + count + '/' + LINK_QUANTITY_MIN + ')');
next(count < conf.sigQty && 'Key ' + target.substring(24) + ' does not have enough links (' + count + '/' + conf.sigQty + ')');
},
], done);
}
function checkProofOfWork (block, done) {
var powRegexp = new RegExp('^0{' + MINIMUM_ZERO_START + '}');
var powRegexp = new RegExp('^0{' + conf.powZeroMin + '}');
if (!block.hash.match(powRegexp))
done('Not a proof-of-work');
else {
......@@ -497,15 +490,17 @@ function KeyService (conn, conf, PublicKeyService) {
function (last, next){
if (last) {
var leadingZeros = last.hash.match(/^0+/)[0];
lastBlockPenality = leadingZeros.length - MINIMUM_ZERO_START + 1;
nbWaitedPeriods = Math.floor((block.number - last.number) / PROOF_OF_WORK_PERIOD);
lastBlockPenality = leadingZeros.length - conf.powZeroMin + 1;
var powPeriodIsContant = conf.powPeriodC;
var nbPeriodsToWait = (powPeriodIsContant ? conf.powPeriod : Math.floor(conf.powPeriod/100*block.membersCount));
nbWaitedPeriods = Math.floor((block.number - last.number) / nbPeriodsToWait);
next();
} else {
next();
}
},
function (next){
var nbZeros = Math.max(MINIMUM_ZERO_START, MINIMUM_ZERO_START + lastBlockPenality - nbWaitedPeriods);
var nbZeros = Math.max(conf.powZeroMin, conf.powZeroMin + lastBlockPenality - nbWaitedPeriods);
var powRegexp = new RegExp('^0{' + nbZeros + ',}');
if (!block.hash.match(powRegexp))
next('Wrong proof-of-work level: given ' + block.hash.match(/^0+/)[0].length + ' zeros, required was ' + nbZeros + ' zeros');
......@@ -721,7 +716,7 @@ function KeyService (conn, conf, PublicKeyService) {
function computeObsoleteLinks (block, done) {
async.waterfall([
function (next){
Link.obsoletes(block.timestamp - MAX_LINK_VALIDITY, next);
Link.obsoletes(block.timestamp - conf.sigValidity, next);
},
function (next){
Key.getMembers(next);
......
......@@ -27,22 +27,29 @@ var DO_NOT_LISTEN_HTTP = false;
program
.version('0.6.1')
.usage('<command> [options]')
.option('-p, --port <port>', 'Port to listen for requests', parseInt)
.option('-c, --currency <name>', 'Name of the currency managed by this node.')
.option('--mhost <host>', 'MongoDB host.')
.option('--mport <port>', 'MongoDB port.')
.option('-d, --mdb <name>', 'MongoDB database name (defaults to "ucoin_default").')
.option('--pgpkey <keyPath>', 'Path to the private key used for signing HTTP responses.')
.option('--pgppasswd <password>', 'Password for the key provided with --httpgp-key option.')
.option('--ipv4 <address>', 'IPV4 interface to listen for requests')
.option('--ipv6 <address>', 'IPV6 interface to listen for requests')
.option('--remoteh <host>', 'Remote interface others may use to contact this node')
.option('--remote4 <host>', 'Remote interface for IPv4 access')
.option('--remote6 <host>', 'Remote interface for IPv6 access')
.option('--remotep <port>', 'Remote port others may use to contact this node')
.option('--kmanagement <ALL|KEYS>', 'Define key management policy')
.option('--kaccept <ALL|KEYS>', 'Define key acceptance policy')
.option('--openpgpjs', 'Prefer using embedded Openpgpjs implementation for signing requests')
.option('-p, --port <port>', 'Port to listen for requests', parseInt)
.option('-c, --currency <name>', 'Name of the currency managed by this node.')
.option('--mhost <host>', 'MongoDB host.')
.option('--mport <port>', 'MongoDB port.')
.option('-d, --mdb <name>', 'MongoDB database name (defaults to "ucoin_default").')
.option('--pgpkey <keyPath>', 'Path to the private key used for signing HTTP responses.')
.option('--pgppasswd <password>', 'Password for the key provided with --httpgp-key option.')
.option('--ipv4 <address>', 'IPV4 interface to listen for requests')
.option('--ipv6 <address>', 'IPV6 interface to listen for requests')
.option('--remoteh <host>', 'Remote interface others may use to contact this node')
.option('--remote4 <host>', 'Remote interface for IPv4 access')
.option('--remote6 <host>', 'Remote interface for IPv6 access')
.option('--remotep <port>', 'Remote port others may use to contact this node')
.option('--kmanagement <ALL|KEYS>', 'Define key management policy')
.option('--kaccept <ALL|KEYS>', 'Define key acceptance policy')
.option('--sigDelay <timestamp>', 'Minimum delay between 2 certifications of a same issuer for a same recipient, in seconds.')
.option('--sigValidity <timestamp>', 'Validity duration of a certification, in seconds.')
.option('--sigQty <number>', 'Minimum number of required certifications to be a member/stay as a member')
.option('--powZeroMin <number>', 'Minimum number of leading zeros for a proof-of-work')
.option('--powPeriod <number>', 'Number of blocks to wait to decrease proof-of-work difficulty by one')
.option('--particpate <Y|N>', 'Participate to writing the keychain')
.option('--tsInterval <number>', 'Number of seconds as acceptable offset when receiving a keyblock')
.option('--openpgpjs', 'Prefer using embedded Openpgpjs implementation for signing requests')
;
program
......@@ -103,7 +110,8 @@ program
'currency': wiz.configCurrency,
'openpgp': wiz.configOpenpgp,
'network': wiz.configNetwork,
'key': wiz.configKey
'key': wiz.configKey,
'ucp': wiz.configUCP
};
var wizDo = task[step] || wiz.configAll;
async.waterfall([
......@@ -444,6 +452,15 @@ function overrideConf(conf) {
policy: {
keys: program.kmanagement,
pubkeys: program.kaccept
},
ucp: {
sigDelay: program.sigDelay,
sigValidity: program.sigValidity,
sigQty: program.sigQty,
powZeroMin: program.powZeroMin,
powPeriod: program.powPeriod,
particpate: program.particpate,
tsInterval: program.tsInterval
}
};
......@@ -463,6 +480,13 @@ function overrideConf(conf) {
if (cli.server.remote.port != undefined) conf.remoteport = cli.server.remote.port;
if (cli.policy.keys) conf.kmanagement = cli.policy.keys;
if (cli.policy.pubkeys) conf.kaccept = cli.policy.pubkeys;
if (cli.ucp.sigDelay) conf.sigDelay = cli.ucp.sigDelay;
if (cli.ucp.sigValidity) conf.sigValidity = cli.ucp.sigValidity;
if (cli.ucp.sigQty) conf.sigQty = cli.ucp.sigQty;
if (cli.ucp.powZeroMin) conf.powZeroMin = cli.ucp.powZeroMin;
if (cli.ucp.powPeriod) conf.powPeriod = cli.ucp.powPeriod;
if (cli.ucp.participate) conf.participate = cli.ucp.participate == 'Y';
if (cli.ucp.tsInterval) conf.tsInterval = cli.ucp.tsInterval;
// Specific internal settings
conf.createNext = true;
......
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