Commit 6a9fe5ea authored by Cédric Moreau's avatar Cédric Moreau

[fix] #1037 Migrate remaining "merkle" "wizard" "constants"

parent 20e89508
......@@ -14,6 +14,8 @@ app/service/*.js
app/lib/rules/*.js
app/lib/system/*.js
app/lib/streams/*.js
app/lib/helpers/*.js
app/lib/*.js
app/modules/wizard.js
app/modules/router.js
app/modules/revert.js
......
......@@ -32,27 +32,25 @@ test/blockchain/*.js
test/blockchain/*.js.map
test/blockchain/lib/*.js
test/blockchain/lib/*.js.map
app/lib/*.js*
app/lib/blockchain/*.js
app/lib/blockchain/*.js.map
app/lib/blockchain/interfaces/*.js
app/lib/blockchain/interfaces/*.js.map
app/lib/computation/*.js
app/lib/computation/*.js.map
app/lib/common.js*
app/lib/db/*.js*
app/lib/dto/*.js*
app/lib/indexer.js*
app/lib/dal/drivers/*.js*
app/lib/dal/sqliteDAL/*.js*
app/lib/dal/sqliteDAL/index/*.js*
app/lib/dal/fileDALs/*.js*
app/lib/dal/fileDAL.js*
app/lib/rules/*.js*
app/lib/logger*js*
app/lib/system/directory.js*
app/lib/streams/*.js*
app/lib/helpers/*.js*
app/service/*.js*
app/lib/wot.js*
app/modules/prover/*.js*
app/modules/prover/lib/*.js*
app/modules/router*.js*
......
This diff is collapsed.
"use strict";
const common = require('duniter-common')
const UDID2 = "udid2;c;([A-Z-]*);([A-Z-]*);(\\d{4}-\\d{2}-\\d{2});(e\\+\\d{2}\\.\\d{2}(\\+|-)\\d{3}\\.\\d{2});(\\d+)(;?)";
const PUBKEY = common.constants.FORMATS.PUBKEY
const TIMESTAMP = common.constants.FORMATS.TIMESTAMP
const IPV4_REGEXP = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/;
const IPV6_REGEXP = /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/;
module.exports = {
TIME_TO_TURN_ON_BRG_107: 1498860000,
ERROR: {
PEER: {
UNKNOWN_REFERENCE_BLOCK: 'Unknown reference block of peer'
},
BLOCK: {
NO_CURRENT_BLOCK: 'No current block'
}
},
ERRORS: {
// Technical errors
UNKNOWN: { httpCode: 500, uerr: { ucode: 1001, message: "An unknown error occured" }},
UNHANDLED: { httpCode: 500, uerr: { ucode: 1002, message: "An unhandled error occured" }},
SIGNATURE_DOES_NOT_MATCH: { httpCode: 400, uerr: { ucode: 1003, message: "Signature does not match" }},
ALREADY_UP_TO_DATE: { httpCode: 400, uerr: { ucode: 1004, message: "Already up-to-date" }},
WRONG_DOCUMENT: common.constants.ERRORS.WRONG_DOCUMENT,
SANDBOX_FOR_IDENTITY_IS_FULL: { httpCode: 503, uerr: { ucode: 1007, message: "The identities' sandbox is full. Please retry with another document or retry later." }},
SANDBOX_FOR_CERT_IS_FULL: { httpCode: 503, uerr: { ucode: 1008, message: "The certifications' sandbox is full. Please retry with another document or retry later." }},
SANDBOX_FOR_MEMERSHIP_IS_FULL: { httpCode: 503, uerr: { ucode: 1009, message: "The memberships' sandbox is full. Please retry with another document or retry later." }},
SANDBOX_FOR_TRANSACTION_IS_FULL: { httpCode: 503, uerr: { ucode: 1010, message: "The transactions' sandbox is full. Please retry with another document or retry later." }},
NO_POTENTIAL_FORK_AS_NEXT: { httpCode: 503, uerr: { ucode: 1011, message: "No fork block exists in the database as a potential next block." }},
INCONSISTENT_DB_MULTI_TXS_SAME_HASH: { httpCode: 503, uerr: { ucode: 1012, message: "Several transactions written with the same hash." }},
CLI_CALLERR_RESET: { httpCode: 503, uerr: { ucode: 1013, message: "Bad command: usage is `reset config`, `reset data`, `reset peers`, `reset stats` or `reset all`" }},
CLI_CALLERR_CONFIG: { httpCode: 503, uerr: { ucode: 1014, message: "Bad command: usage is `config`." }},
// Business errors
NO_MATCHING_IDENTITY: { httpCode: 404, uerr: { ucode: 2001, message: "No matching identity" }},
UID_ALREADY_USED: { httpCode: 400, uerr: { ucode: 2002, message: "UID already used in the blockchain" }},
PUBKEY_ALREADY_USED: { httpCode: 400, uerr: { ucode: 2003, message: "Pubkey already used in the blockchain" }},
NO_MEMBER_MATCHING_PUB_OR_UID: { httpCode: 404, uerr: { ucode: 2004, message: "No member matching this pubkey or uid" }},
WRONG_SIGNATURE_MEMBERSHIP: { httpCode: 400, uerr: { ucode: 2006, message: "wrong signature for membership" }},
ALREADY_RECEIVED_MEMBERSHIP: { httpCode: 400, uerr: { ucode: 2007, message: "Already received membership" }},
MEMBERSHIP_A_NON_MEMBER_CANNOT_LEAVE: { httpCode: 400, uerr: { ucode: 2008, message: "A non-member cannot leave" }},
NOT_A_MEMBER: { httpCode: 400, uerr: { ucode: 2009, message: "Not a member" }},
BLOCK_NOT_FOUND: { httpCode: 404, uerr: { ucode: 2011, message: "Block not found" }},
WRONG_UNLOCKER: common.constants.ERRORS.WRONG_UNLOCKER,
LOCKTIME_PREVENT: common.constants.ERRORS.LOCKTIME_PREVENT,
SOURCE_ALREADY_CONSUMED: common.constants.ERRORS.SOURCE_ALREADY_CONSUMED,
WRONG_AMOUNTS: common.constants.ERRORS.WRONG_AMOUNTS,
WRONG_OUTPUT_BASE: common.constants.ERRORS.WRONG_OUTPUT_BASE,
CANNOT_ROOT_BLOCK_NO_MEMBERS: common.constants.ERRORS.CANNOT_ROOT_BLOCK_NO_MEMBERS,
IDENTITY_WRONGLY_SIGNED: common.constants.ERRORS.IDENTITY_WRONGLY_SIGNED,
TOO_OLD_IDENTITY: common.constants.ERRORS.TOO_OLD_IDENTITY,
NO_IDTY_MATCHING_PUB_OR_UID: { httpCode: 404, uerr: { ucode: 2021, message: "No identity matching this pubkey or uid" }},
NEWER_PEER_DOCUMENT_AVAILABLE: { httpCode: 409, uerr: { ucode: 2022, message: "A newer peer document is available" }},
PEER_DOCUMENT_ALREADY_KNOWN: { httpCode: 400, uerr: { ucode: 2023, message: "Peer document already known" }},
TX_INPUTS_OUTPUTS_NOT_EQUAL: common.constants.ERRORS.TX_INPUTS_OUTPUTS_NOT_EQUAL,
TX_OUTPUT_SUM_NOT_EQUALS_PREV_DELTAS: common.constants.ERRORS.TX_OUTPUT_SUM_NOT_EQUALS_PREV_DELTAS,
BLOCKSTAMP_DOES_NOT_MATCH_A_BLOCK: common.constants.ERRORS.BLOCKSTAMP_DOES_NOT_MATCH_A_BLOCK,
A_TRANSACTION_HAS_A_MAX_SIZE: common.constants.ERRORS.A_TRANSACTION_HAS_A_MAX_SIZE,
BLOCK_ALREADY_PROCESSED: { httpCode: 400, uerr: { ucode: 2028, message: 'Already processed' }},
TOO_OLD_MEMBERSHIP: common.constants.ERRORS.TOO_OLD_MEMBERSHIP,
TX_ALREADY_PROCESSED: { httpCode: 400, uerr: { ucode: 2030, message: "Transaction already processed" }},
A_MORE_RECENT_MEMBERSHIP_EXISTS: { httpCode: 400, uerr: { ucode: 2031, message: "A more recent membership already exists" }},
MAXIMUM_LEN_OF_OUTPUT: common.constants.ERRORS.MAXIMUM_LEN_OF_OUTPUT,
MAXIMUM_LEN_OF_UNLOCK: common.constants.ERRORS.MAXIMUM_LEN_OF_UNLOCK
},
DEBUG: {
LONG_DAL_PROCESS: 50
},
BMA_REGEXP: common.constants.BMA_REGEXP,
IPV4_REGEXP: IPV4_REGEXP,
IPV6_REGEXP: IPV6_REGEXP,
TIMESTAMP: exact(TIMESTAMP),
UDID2_FORMAT: exact(UDID2),
PUBLIC_KEY: exact(PUBKEY),
DOCUMENTS_VERSION: common.constants.DOCUMENTS_VERSION,
BLOCK_GENERATED_VERSION: common.constants.BLOCK_GENERATED_VERSION,
LAST_VERSION_FOR_TX: 10,
TRANSACTION_VERSION: common.constants.TRANSACTION_VERSION,
REVOCATION_FACTOR: common.constants.REVOCATION_FACTOR, // This is protocol fixed value
FIRST_UNIT_BASE: 0,
PEER: common.constants.PEER,
NETWORK: {
MAX_MEMBERS_TO_FORWARD_TO_FOR_SELF_DOCUMENTS: 10,
MAX_NON_MEMBERS_TO_FORWARD_TO_FOR_SELF_DOCUMENTS: 6,
MAX_NON_MEMBERS_TO_FORWARD_TO: 4,
MAX_MEMBERS_TO_FORWARD_TO: 6,
MAX_CONCURRENT_POST: 3,
DEFAULT_TIMEOUT: 10 * 1000, // 10 seconds
SYNC: {
MAX: 20
},
STATUS_INTERVAL: {
UPDATE: 2, // Every X blocks
MAX: 20 // MAX Y blocks
}
},
PROOF_OF_WORK: {
EVALUATION: 1000,
UPPER_BOUND: common.constants.PROOF_OF_WORK.UPPER_BOUND.slice()
},
DEFAULT_CURRENCY_NAME: "no_currency",
CONTRACT: {
DEFAULT: {
C: 0.007376575,
DT: 30.4375 * 24 * 3600,
DT_REEVAL: 30.4375 * 24 * 3600,
UD0: 100,
STEPMAX: 3,
SIGDELAY: 3600 * 24 * 365 * 5,
SIGPERIOD: 0, // Instant
MSPERIOD: 0, // Instant
SIGSTOCK: 40,
SIGWINDOW: 3600 * 24 * 7, // a week
SIGVALIDITY: 3600 * 24 * 365,
MSVALIDITY: 3600 * 24 * 365,
SIGQTY: 5,
X_PERCENT: 0.9,
PERCENTROT: 2 / 3,
BLOCKSROT: 20,
POWDELAY: 0,
AVGGENTIME: 16 * 60,
DTDIFFEVAL: 10,
MEDIANTIMEBLOCKS: 20,
IDTYWINDOW: 3600 * 24 * 7, // a week
MSWINDOW: 3600 * 24 * 7 // a week
},
DSEN_P: 1.2 // dSen proportional factor
},
BRANCHES: {
DEFAULT_WINDOW_SIZE: 100
},
INVALIDATE_CORE_CACHE: true,
WITH_SIGNATURES_AND_POW: true,
NO_FORK_ALLOWED: false,
SAFE_FACTOR: 3,
BLOCKS_COLLECT_THRESHOLD: 30, // Blocks to collect from memory and persist
MUTE_LOGS_DURING_UNIT_TESTS: true,
SANDBOX_SIZE_TRANSACTIONS: 200,
SANDBOX_SIZE_IDENTITIES: 5000,
SANDBOX_SIZE_CERTIFICATIONS: 12,
SANDBOX_SIZE_MEMBERSHIPS: 5000,
CURRENT_BLOCK_CACHE_DURATION: 10 * 1000, // 30 seconds
// With `logs` command, the number of tail lines to show
NB_INITIAL_LINES_TO_SHOW: 100
};
function exact (regexpContent:string) {
return new RegExp("^" + regexpContent + "$");
}
"use strict";
const co = require('co');
module.exports = {
processForURL: (req, merkle, valueCoroutine) => co(function*() {
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.processForURL = (req, merkle, valueCoroutine) => __awaiter(this, void 0, void 0, function* () {
// Result
const json = {
"depth": merkle.depth,
"nodesCount": merkle.nodes,
"leavesCount": merkle.levels[merkle.depth].length,
"root": merkle.levels[0][0] || ""
"depth": merkle.depth,
"nodesCount": merkle.nodes,
"leavesCount": merkle.levels[merkle.depth].length,
"root": merkle.levels[0][0] || ""
};
if (req.query.leaves) {
// Leaves
json.leaves = merkle.leaves();
return json;
} else if (req.query.leaf) {
// Extract of a leaf
json.leaves = {};
const hashes = [req.query.leaf];
// This code is in a loop for historic reasons. Should be set to non-loop style.
const values = yield valueCoroutine(hashes);
hashes.forEach((hash) => {
json.leaf = {
"hash": hash,
"value": values[hash] || ""
};
});
return json;
} else {
return json;
// Leaves
json.leaves = merkle.leaves();
return json;
}
})
}
else if (req.query.leaf) {
// Extract of a leaf
json.leaves = {};
const hashes = [req.query.leaf];
// This code is in a loop for historic reasons. Should be set to non-loop style.
const values = yield valueCoroutine(hashes);
hashes.forEach((hash) => {
json.leaf = {
"hash": hash,
"value": values[hash] || ""
};
});
return json;
}
else {
return json;
}
});
//# sourceMappingURL=merkle.js.map
\ No newline at end of file
export const processForURL = async (req:any, merkle:any, valueCoroutine:any) => {
// Result
const json:any = {
"depth": merkle.depth,
"nodesCount": merkle.nodes,
"leavesCount": merkle.levels[merkle.depth].length,
"root": merkle.levels[0][0] || ""
};
if (req.query.leaves) {
// Leaves
json.leaves = merkle.leaves();
return json;
} else if (req.query.leaf) {
// Extract of a leaf
json.leaves = {};
const hashes = [req.query.leaf];
// This code is in a loop for historic reasons. Should be set to non-loop style.
const values = await valueCoroutine(hashes);
hashes.forEach((hash) => {
json.leaf = {
"hash": hash,
"value": values[hash] || ""
};
});
return json;
} else {
return json;
}
}
"use strict";
const co = require('co');
const constants = require('./constants');
const async = require('async');
const inquirer = require('inquirer');
const logger = require('./logger').NewLogger('wizard');
module.exports = function () {
return new Wizard();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
function Wizard () {
this.configPoW = function (conf) {
return doTasks(['pow'], conf)
}
this.configCurrency = function (conf) {
return doTasks(['currency'], conf)
}
this.configUCP = function (conf) {
return doTasks(['parameters'], conf)
}
Object.defineProperty(exports, "__esModule", { value: true });
const constants = require('./constants');
const async = require('async');
const inquirer = require('inquirer');
const logger = require('./logger').NewLogger('wizard');
class Wizard {
static configPoW(conf) {
return doTasks(['pow'], conf);
}
static configCurrency(conf) {
return doTasks(['currency'], conf);
}
static configUCP(conf) {
return doTasks(['parameters'], conf);
}
}
function doTasks (todos, conf) {
return new Promise((res, rej) => {
async.forEachSeries(todos, function(task, callback){
tasks[task] && tasks[task](conf, callback);
}, (err) => {
if (err) return rej(err)
return res()
exports.Wizard = Wizard;
function doTasks(todos, conf) {
return new Promise((res, rej) => {
async.forEachSeries(todos, function (task, callback) {
tasks[task] && tasks[task](conf, callback);
}, (err) => {
if (err)
return rej(err);
return res();
});
});
})
}
const tasks = {
currency: function (conf, done) {
return co(function*() {
const answers = yield inquirer.prompt([{
type: "input",
name: "currency",
message: "Currency name",
default: conf.currency,
validate: function (input) {
return input.match(/^[a-zA-Z0-9-_ ]+$/) ? true : false;
}
}])
conf.currency = answers.currency
done()
})
},
parameters: function (conf, done) {
async.waterfall([
async.apply(simpleFloat, "Universal Dividend %growth", "c", conf),
async.apply(simpleInteger, "Universal Dividend period (in seconds)", "dt", conf),
async.apply(simpleInteger, "First Universal Dividend (UD[0]) amount", "ud0", conf),
async.apply(simpleInteger, "Delay between 2 certifications of a same issuer", "sigPeriod", conf),
async.apply(simpleInteger, "Maximum stock of valid certifications per member", "sigStock", conf),
async.apply(simpleInteger, "Maximum age of a non-written certification", "sigWindow", 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, "Maximum age of a non-written identity", "idtyWindow", conf),
async.apply(simpleInteger, "Maximum age of a non-written membership", "msWindow", conf),
async.apply(simpleFloat, "Percentage of sentries to be reached to match WoT distance rule", "xpercent", conf),
async.apply(simpleInteger, "Membership validity duration", "msValidity", conf),
async.apply(simpleInteger, "Number of blocks on which is computed median time", "medianTimeBlocks", conf),
async.apply(simpleInteger, "The average time for writing 1 block (wished time)", "avgGenTime", conf),
async.apply(simpleInteger, "Frequency, in number of blocks, to wait for changing common difficulty", "dtDiffEval", conf),
async.apply(simpleFloat, "Weight in percent for previous issuers", "percentRot", conf)
], done);
},
pow: function (conf, done) {
async.waterfall([
function (next){
simpleInteger("Start computation of a new block if none received since (seconds)", "powDelay", conf, next);
}
], done);
}
currency: function (conf, done) {
return __awaiter(this, void 0, void 0, function* () {
const answers = yield inquirer.prompt([{
type: "input",
name: "currency",
message: "Currency name",
default: conf.currency,
validate: function (input) {
return input.match(/^[a-zA-Z0-9-_ ]+$/) ? true : false;
}
}]);
conf.currency = answers.currency;
done();
});
},
parameters: function (conf, done) {
async.waterfall([
async.apply(simpleFloat, "Universal Dividend %growth", "c", conf),
async.apply(simpleInteger, "Universal Dividend period (in seconds)", "dt", conf),
async.apply(simpleInteger, "First Universal Dividend (UD[0]) amount", "ud0", conf),
async.apply(simpleInteger, "Delay between 2 certifications of a same issuer", "sigPeriod", conf),
async.apply(simpleInteger, "Maximum stock of valid certifications per member", "sigStock", conf),
async.apply(simpleInteger, "Maximum age of a non-written certification", "sigWindow", 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, "Maximum age of a non-written identity", "idtyWindow", conf),
async.apply(simpleInteger, "Maximum age of a non-written membership", "msWindow", conf),
async.apply(simpleFloat, "Percentage of sentries to be reached to match WoT distance rule", "xpercent", conf),
async.apply(simpleInteger, "Membership validity duration", "msValidity", conf),
async.apply(simpleInteger, "Number of blocks on which is computed median time", "medianTimeBlocks", conf),
async.apply(simpleInteger, "The average time for writing 1 block (wished time)", "avgGenTime", conf),
async.apply(simpleInteger, "Frequency, in number of blocks, to wait for changing common difficulty", "dtDiffEval", conf),
async.apply(simpleFloat, "Weight in percent for previous issuers", "percentRot", conf)
], done);
},
pow: function (conf, done) {
async.waterfall([
function (next) {
simpleInteger("Start computation of a new block if none received since (seconds)", "powDelay", conf, next);
}
], done);
}
};
function simpleValue (question, property, defaultValue, conf, validation, done) {
return co(function*() {
const answers = yield inquirer.prompt([{
type: "input",
name: property,
message: question,
default: conf[property],
validate: validation
}])
conf[property] = answers[property]
done()
})
function simpleValue(question, property, defaultValue, conf, validation, done) {
return __awaiter(this, void 0, void 0, function* () {
const answers = yield inquirer.prompt([{
type: "input",
name: property,
message: question,
default: conf[property],
validate: validation
}]);
conf[property] = answers[property];
done();
});
}
function simpleInteger (question, property, conf, done) {
simpleValue(question, property, conf[property], conf, function (input) {
return input && input.toString().match(/^[0-9]+$/) ? true : false;
}, done);
function simpleInteger(question, property, conf, done) {
simpleValue(question, property, conf[property], conf, function (input) {
return input && input.toString().match(/^[0-9]+$/) ? true : false;
}, done);
}
function simpleFloat (question, property, conf, done) {
simpleValue(question, property, conf[property], conf, function (input) {
return input && input.toString().match(/^[0-9]+(\.[0-9]+)?$/) ? true : false;
}, done);
function simpleFloat(question, property, conf, done) {
simpleValue(question, property, conf[property], conf, function (input) {
return input && input.toString().match(/^[0-9]+(\.[0-9]+)?$/) ? true : false;
}, done);
}
//# sourceMappingURL=wizard.js.map
\ No newline at end of file
import {ConfDTO} from "./dto/ConfDTO"
const constants = require('./constants');
const async = require('async');
const inquirer = require('inquirer');
const logger = require('./logger').NewLogger('wizard');
export class Wizard {
static configPoW(conf:ConfDTO) {
return doTasks(['pow'], conf)
}
static configCurrency(conf:ConfDTO) {
return doTasks(['currency'], conf)
}
static configUCP(conf:ConfDTO) {
return doTasks(['parameters'], conf)
}
}
function doTasks (todos:string[], conf:ConfDTO) {
return new Promise((res, rej) => {
async.forEachSeries(todos, function(task:any, callback:any){
tasks[task] && tasks[task](conf, callback);
}, (err:any) => {
if (err) return rej(err)
return res()
});
})
}
const tasks:any = {
currency: async function (conf:ConfDTO, done:any) {
const answers = await inquirer.prompt([{
type: "input",
name: "currency",
message: "Currency name",
default: conf.currency,
validate: function (input:string) {
return input.match(/^[a-zA-Z0-9-_ ]+$/) ? true : false;
}
}])
conf.currency = answers.currency
done()
},
parameters: function (conf:ConfDTO, done:any) {
async.waterfall([
async.apply(simpleFloat, "Universal Dividend %growth", "c", conf),
async.apply(simpleInteger, "Universal Dividend period (in seconds)", "dt", conf),
async.apply(simpleInteger, "First Universal Dividend (UD[0]) amount", "ud0", conf),
async.apply(simpleInteger, "Delay between 2 certifications of a same issuer", "sigPeriod", conf),
async.apply(simpleInteger, "Maximum stock of valid certifications per member", "sigStock", conf),
async.apply(simpleInteger, "Maximum age of a non-written certification", "sigWindow", 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, "Maximum age of a non-written identity", "idtyWindow", conf),
async.apply(simpleInteger, "Maximum age of a non-written membership", "msWindow", conf),
async.apply(simpleFloat, "Percentage of sentries to be reached to match WoT distance rule", "xpercent", conf),
async.apply(simpleInteger, "Membership validity duration", "msValidity", conf),
async.apply(simpleInteger, "Number of blocks on which is computed median time", "medianTimeBlocks", conf),
async.apply(simpleInteger, "The average time for writing 1 block (wished time)", "avgGenTime", conf),
async.apply(simpleInteger, "Frequency, in number of blocks, to wait for changing common difficulty", "dtDiffEval", conf),
async.apply(simpleFloat, "Weight in percent for previous issuers", "percentRot", conf)
], done);
},
pow: function (conf:ConfDTO, done:any) {
async.waterfall([
function (next:any){
simpleInteger("Start computation of a new block if none received since (seconds)", "powDelay", conf, next);
}
], done);
}
};
async function simpleValue (question:string, property:string, defaultValue:any, conf:any, validation:any, done:any) {
const answers = await inquirer.prompt([{