Commit b8c9dc22 authored by Cédric Moreau's avatar Cédric Moreau

[fix] #1037 Remove Q promise library calls

parent 33735971
......@@ -13,5 +13,6 @@ app/lib/dal/fileDAL.js
app/service/*.js
app/lib/rules/local_rules.js
app/lib/rules/global_rules.js
app/modules/wizard.js
test/*.js
test/**/*.js
\ No newline at end of file
......@@ -4,11 +4,9 @@ import {BlockchainOperator} from "./interfaces/BlockchainOperator"
import {ConfDTO} from "../dto/ConfDTO"
import {BlockDTO} from "../dto/BlockDTO"
import {DBHead} from "../db/DBHead"
import {IdentityDTO} from "../dto/IdentityDTO"
import {DBBlock} from "../db/DBBlock"
const _ = require('underscore')
const Q = require('q')
const rules = require('../rules')
const common = require('duniter-common')
const Block = require('../entity/block')
......
......@@ -5,7 +5,6 @@ import {DBTransaction} from "../db/DBTransaction"
import {Indexer} from "../indexer"
import {ConfDTO} from "../dto/ConfDTO"
const Q = require('q');
const _ = require('underscore')
const constants = require('../constants')
const Block = require('../entity/block')
......@@ -46,11 +45,11 @@ export class QuickSynchronizer {
await this.blockchain.saveParametersForRoot(blocks[0], this.conf, this.dal)
}
// Helper to retrieve a block with local cache
const getBlock = (number: number): BlockDTO => {
const getBlock = (number: number): Promise<BlockDTO> => {
const firstLocalNumber = blocks[0].number;
if (number >= firstLocalNumber) {
let offset = number - firstLocalNumber;
return Q(blocks[offset]);
return Promise.resolve(blocks[offset])
}
return this.dal.getBlock(number);
};
......
import {SQLiteDriver} from "./drivers/SQLiteDriver";
import {ConfDAL} from "./fileDALs/ConfDAL";
import {StatDAL} from "./fileDALs/StatDAL";
import {ConfDTO} from "../dto/ConfDTO";
import {BlockDTO} from "../dto/BlockDTO";
import {DBHead} from "../db/DBHead";
import {DBIdentity} from "./sqliteDAL/IdentityDAL";
import {CindexEntry, IindexEntry, IndexEntry, MindexEntry, SindexEntry} from "../indexer";
import {DBPeer} from "./sqliteDAL/PeerDAL";
import {TransactionDTO} from "../dto/TransactionDTO";
import {DBCert} from "./sqliteDAL/CertDAL";
import {DBWallet} from "./sqliteDAL/WalletDAL";
import {DBTx} from "./sqliteDAL/TxsDAL";
import {DBBlock} from "../db/DBBlock";
const Q = require('q');
import {SQLiteDriver} from "./drivers/SQLiteDriver"
import {ConfDAL} from "./fileDALs/ConfDAL"
import {StatDAL} from "./fileDALs/StatDAL"
import {ConfDTO} from "../dto/ConfDTO"
import {BlockDTO} from "../dto/BlockDTO"
import {DBHead} from "../db/DBHead"
import {DBIdentity} from "./sqliteDAL/IdentityDAL"
import {CindexEntry, IindexEntry, IndexEntry, MindexEntry, SindexEntry} from "../indexer"
import {DBPeer} from "./sqliteDAL/PeerDAL"
import {TransactionDTO} from "../dto/TransactionDTO"
import {DBCert} from "./sqliteDAL/CertDAL"
import {DBWallet} from "./sqliteDAL/WalletDAL"
import {DBTx} from "./sqliteDAL/TxsDAL"
import {DBBlock} from "../db/DBBlock"
const fs = require('fs')
const path = require('path')
const readline = require('readline')
......@@ -241,7 +240,7 @@ export class FileDAL {
}
getBlocksBetween (start:number, end:number) {
return Q(this.blockDAL.getBlocks(Math.max(0, start), end))
return Promise.resolve(this.blockDAL.getBlocks(Math.max(0, start), end))
}
getForkBlocksFollowing(current:DBBlock) {
......@@ -295,7 +294,7 @@ export class FileDAL {
async fillInMembershipsOfIdentity(queryPromise:Promise<DBIdentity>) {
try {
const idty = await Q(queryPromise);
const idty:any = await Promise.resolve(queryPromise)
if (idty) {
const mss = await this.msDAL.getMembershipsOfIssuer(idty.pubkey);
const mssFromMindex = await this.mindexDAL.reducable(idty.pubkey);
......
import {AbstractSQLite} from "./AbstractSQLite";
import {SQLiteDriver} from "../drivers/SQLiteDriver";
import {DBBlock} from "../../db/DBBlock";
const Q = require('q');
import {AbstractSQLite} from "./AbstractSQLite"
import {SQLiteDriver} from "../drivers/SQLiteDriver"
import {DBBlock} from "../../db/DBBlock"
const constants = require('../../constants');
const IS_FORK = true;
......@@ -84,7 +83,7 @@ export class BlockDAL extends AbstractSQLite<DBBlock> {
if (!this.current) {
this.current = (await this.query('SELECT * FROM block WHERE NOT fork ORDER BY number DESC LIMIT 1'))[0];
}
return Q(this.current);
return Promise.resolve(this.current)
}
async getBlock(number:string | number) {
......
"use strict";
const Q = require('q');
const stream = require('stream');
const util = require('util');
const request = require('request');
......@@ -176,9 +175,9 @@ function Multicaster (conf, timeout) {
function post(peer, uri, data) {
if (!peer.isReachable()) {
return Q();
return Promise.resolve();
}
return Q.Promise(function(resolve, reject){
return new Promise(function(resolve, reject){
const postReq = request.post({
"uri": protocol(peer.getPort()) + '://' + peer.getURL() + uri,
"timeout": timeout || constants.NETWORK.DEFAULT_TIMEOUT
......
......@@ -4,7 +4,6 @@ const co = require('co');
const opts = require('optimist').argv;
const path = require('path');
const CFSCore = require('../dal/fileDALs/CFSCore').CFSCore
const Q = require('q');
const qfs = require('q-io/fs');
const fs = require('fs');
const SQLiteDriver = require("../dal/drivers/SQLiteDriver").SQLiteDriver
......@@ -71,7 +70,7 @@ const dir = module.exports = {
})
};
const someDelayFix = () => Q.Promise((resolve) => {
const someDelayFix = () => new Promise((resolve) => {
setTimeout(resolve, 100);
});
......@@ -11,44 +11,46 @@ module.exports = function () {
function Wizard () {
this.configPoW = function (conf, program, aLogger, done) {
doTasks(['pow'], conf, done);
};
this.configPoW = function (conf) {
return doTasks(['pow'], conf)
}
this.configCurrency = function (conf, program, aLogger, done) {
doTasks(['currency'], conf, done);
};
this.configCurrency = function (conf) {
return doTasks(['currency'], conf)
}
this.configUCP = function (conf, program, aLogger, done) {
doTasks(['parameters'], conf, done);
};
this.configUCP = function (conf) {
return doTasks(['parameters'], conf)
}
}
function doTasks (todos, conf, done) {
async.forEachSeries(todos, function(task, callback){
tasks[task] && tasks[task](conf, callback);
}, done);
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) {
async.waterfall([
function (next){
inquirer.prompt([{
type: "input",
name: "currency",
message: "Currency name",
default: conf.currency,
validate: function (input) {
return input.match(/^[a-zA-Z0-9-_ ]+$/) ? true : false;
}
}], function (answers) {
conf.currency = answers.currency;
next();
});
}
], 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) {
......@@ -82,16 +84,17 @@ const tasks = {
};
function simpleValue (question, property, defaultValue, conf, validation, done) {
inquirer.prompt([{
type: "input",
name: property,
message: question,
default: conf[property],
validate: validation
}], function (answers) {
conf[property] = answers[property];
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 simpleInteger (question, property, conf, done) {
......
"use strict";
const Q = require('q');
const co = require('co');
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 });
const _ = require('underscore');
const wizard = require('../lib/wizard');
const logger = require('../lib/logger').NewLogger('wizard');
module.exports = {
duniter: {
wizard: {
// The wizard itself also defines its personal tasks
'currency': Q.nbind(wizard().configCurrency, null),
'pow': Q.nbind(wizard().configPoW, null),
'parameters': Q.nbind(wizard().configUCP, null)
},
cli: [{
name: 'wizard [key|network|network-reconfigure|currency|pow|parameters]',
desc: 'Launch the configuration wizard.',
onConfiguredExecute: (server, conf, program, params, wizardTasks) => co(function*() {
const step = params[0];
const tasks = step ? [wizardTasks[step]] : Object.values(wizardTasks);
for (const task of tasks) {
if (!task) {
throw 'Unknown task';
}
yield task(conf, program, server.logger);
}
// Check config
yield server.checkConfig();
yield server.dal.saveConf(conf);
logger.debug("Configuration saved.");
})
}]
}
duniter: {
wizard: {
// The wizard itself also defines its personal tasks
'currency': (conf) => wizard().configCurrency(conf),
'pow': (conf) => wizard().configPoW(conf),
'parameters': (conf) => wizard().configUCP(conf)
},
cli: [{
name: 'wizard [key|network|network-reconfigure|currency|pow|parameters]',
desc: 'Launch the configuration wizard.',
onConfiguredExecute: (server, conf, program, params, wizardTasks) => __awaiter(this, void 0, void 0, function* () {
const step = params[0];
const tasks = step ? [wizardTasks[step]] : _.values(wizardTasks);
for (const task of tasks) {
if (!task) {
throw 'Unknown task';
}
yield task(conf);
}
// Check config
yield server.checkConfig();
yield server.dal.saveConf(conf);
logger.debug("Configuration saved.");
})
}]
}
};
//# sourceMappingURL=wizard.js.map
\ No newline at end of file
import {ConfDTO} from "../lib/dto/ConfDTO"
const _ = require('underscore')
const wizard = require('../lib/wizard');
const logger = require('../lib/logger').NewLogger('wizard');
module.exports = {
duniter: {
wizard: {
// The wizard itself also defines its personal tasks
'currency': (conf:ConfDTO) => wizard().configCurrency(conf),
'pow': (conf:ConfDTO) => wizard().configPoW(conf),
'parameters': (conf:ConfDTO) => wizard().configUCP(conf)
},
cli: [{
name: 'wizard [key|network|network-reconfigure|currency|pow|parameters]',
desc: 'Launch the configuration wizard.',
onConfiguredExecute: async (server:any, conf:ConfDTO, program:any, params:any, wizardTasks:any) => {
const step = params[0];
const tasks = step ? [wizardTasks[step]] : _.values(wizardTasks);
for (const task of tasks) {
if (!task) {
throw 'Unknown task';
}
await task(conf)
}
// Check config
await server.checkConfig();
await server.dal.saveConf(conf);
logger.debug("Configuration saved.");
}
}]
}
};
"use strict";
const async = require('async');
const Q = require('q');
const co = require('co');
const fifo = async.queue(function (task:any, callback:any) {
task(callback);
......@@ -16,24 +14,22 @@ export class GlobalFifoPromise {
/**
* Adds a promise to a FIFO stack of promises, so the given promise will be executed against a shared FIFO stack.
* @param p
* @returns {Q.Promise<T>} A promise wrapping the promise given in the parameter.
* @returns {Promise<T>} A promise wrapping the promise given in the parameter.
*/
static pushFIFO(p: () => Promise<any>) {
// Return a promise that will be done after the fifo has executed the given promise
return Q.Promise((resolve:any, reject:any) => {
return new Promise((resolve:any, reject:any) => {
// Push the promise on the stack
fifo.push(function (cb:any) {
co(function*(){
// OK its the turn of given promise, execute it
try {
const res = yield p();
// Finished, we end the function in the FIFO
cb(null, res);
} catch (e) {
// Errored, we end the function with an error
cb(e);
}
});
fifo.push(async (cb:any) => {
// OK its the turn of given promise, execute it
try {
const res = await p();
// Finished, we end the function in the FIFO
cb(null, res);
} catch (e) {
// Errored, we end the function with an error
cb(e);
}
}, (err:any, res:any) => {
// An error occured => reject promise
if (err) return reject(err);
......
import {GlobalFifoPromise} from "./GlobalFifoPromise";
"use strict";
import {GlobalFifoPromise} from "./GlobalFifoPromise"
import {FileDAL} from "../lib/dal/fileDAL"
import {ConfDTO} from "../lib/dto/ConfDTO"
import {DBIdentity} from "../lib/dal/sqliteDAL/IdentityDAL"
const Q = require('q');
"use strict";
const rules = require('../lib/rules')
const keyring = require('duniter-common').keyring;
const constants = require('../lib/constants');
......@@ -44,7 +43,7 @@ export class IdentityService {
if (!idty) {
throw constants.ERRORS.NO_MEMBER_MATCHING_PUB_OR_UID;
}
await this.dal.fillInMembershipsOfIdentity(Q(idty));
await this.dal.fillInMembershipsOfIdentity(Promise.resolve(idty));
return new Identity(idty);
}
......@@ -156,7 +155,7 @@ export class IdentityService {
return GlobalFifoPromise.pushFIFO(async () => {
this.logger.info('⬇ CERT %s block#%s -> %s', cert.from, cert.block_number, idty.uid);
try {
await rules.HELPERS.checkCertificationIsValid(cert, potentialNext, () => Q(idty), this.conf, this.dal);
await rules.HELPERS.checkCertificationIsValid(cert, potentialNext, () => Promise.resolve(idty), this.conf, this.dal);
} catch (e) {
cert.err = e;
}
......
import {GlobalFifoPromise} from "./GlobalFifoPromise"
import {ConfDTO, Keypair} from "../lib/dto/ConfDTO"
import {ConfDTO} from "../lib/dto/ConfDTO"
import {FileDAL} from "../lib/dal/fileDAL"
import {DBPeer} from "../lib/dal/sqliteDAL/PeerDAL"
import {DBBlock} from "../lib/db/DBBlock"
const util = require('util');
const _ = require('underscore');
const Q = require('q');
const events = require('events');
const rp = require('request-promise');
const multicaster = require('../lib/streams/multicaster');
......@@ -31,6 +30,7 @@ export class PeeringService {
pair:Keyring
pubkey:string
peerInstance:DBPeer | null
logger:any
constructor(private server:any) {
}
......@@ -41,6 +41,7 @@ export class PeeringService {
this.pair = newPair;
this.pubkey = this.pair.publicKey;
this.selfPubkey = this.pubkey;
this.logger = require('../lib/logger').NewLogger(this.dal.profile)
}
async peer(newPeer:DBPeer | null = null) {
......@@ -68,6 +69,7 @@ export class PeeringService {
};
submitP(peering:DBPeer, eraseIfAlreadyRecorded = false, cautious = true) {
this.logger.info('⬇ PEER %s', peering.pubkey.substr(0, 8))
// Force usage of local currency name, do not accept other currencies documents
peering.currency = this.conf.currency || peering.currency;
let thePeer = new Peer(peering);
......@@ -78,82 +80,88 @@ export class PeeringService {
let block:DBBlock | null;
let makeCheckings = cautious || cautious === undefined;
return GlobalFifoPromise.pushFIFO(async () => {
if (makeCheckings) {
let goodSignature = this.checkPeerSignature(thePeer);
if (!goodSignature) {
throw 'Signature from a peer must match';
try {
if (makeCheckings) {
let goodSignature = this.checkPeerSignature(thePeer);
if (!goodSignature) {
throw 'Signature from a peer must match';
}
}
}
if (thePeer.block == constants.PEER.SPECIAL_BLOCK) {
thePeer.statusTS = 0;
thePeer.status = 'UP';
} else {
block = await this.dal.getBlockByNumberAndHashOrNull(blockNumber, blockHash);
if (!block && makeCheckings) {
throw constants.ERROR.PEER.UNKNOWN_REFERENCE_BLOCK;
} else if (!block) {
thePeer.block = constants.PEER.SPECIAL_BLOCK;
if (thePeer.block == constants.PEER.SPECIAL_BLOCK) {
thePeer.statusTS = 0;
thePeer.status = 'UP';
} else {
block = await this.dal.getBlockByNumberAndHashOrNull(blockNumber, blockHash);
if (!block && makeCheckings) {
throw constants.ERROR.PEER.UNKNOWN_REFERENCE_BLOCK;
} else if (!block) {
thePeer.block = constants.PEER.SPECIAL_BLOCK;
thePeer.statusTS = 0;
thePeer.status = 'UP';
}
}
}
sigTime = block ? block.medianTime : 0;
thePeer.statusTS = sigTime;
let found = await this.dal.getPeerOrNull(thePeer.pubkey);
let peerEntity = Peer.statics.peerize(found || thePeer);
if(found){
// Already existing peer
const sp2 = found.block.split('-');
const previousBlockNumber = parseInt(sp2[0]);
const interfacesChanged = Peer.statics.endpointSum(thePeer) != Peer.statics.endpointSum(peerEntity);
const isOutdatedDocument = blockNumber < previousBlockNumber && !eraseIfAlreadyRecorded;
const isAlreadyKnown = blockNumber == previousBlockNumber && !eraseIfAlreadyRecorded;
if (isOutdatedDocument){
const error = _.extend({}, constants.ERRORS.NEWER_PEER_DOCUMENT_AVAILABLE);
_.extend(error.uerr, { peer: found });
throw error;
} else if (isAlreadyKnown) {
throw constants.ERRORS.PEER_DOCUMENT_ALREADY_KNOWN;
}
peerEntity = Peer.statics.peerize(found);
if (interfacesChanged) {
// Warns the old peer of the change
const caster = multicaster();
caster.sendPeering(Peer.statics.peerize(peerEntity), Peer.statics.peerize(thePeer));
sigTime = block ? block.medianTime : 0;
thePeer.statusTS = sigTime;
let found = await this.dal.getPeerOrNull(thePeer.pubkey);
let peerEntity = Peer.statics.peerize(found || thePeer);
if(found){
// Already existing peer
const sp2 = found.block.split('-');
const previousBlockNumber = parseInt(sp2[0]);
const interfacesChanged = Peer.statics.endpointSum(thePeer) != Peer.statics.endpointSum(peerEntity);
const isOutdatedDocument = blockNumber < previousBlockNumber && !eraseIfAlreadyRecorded;
const isAlreadyKnown = blockNumber == previousBlockNumber && !eraseIfAlreadyRecorded;
if (isOutdatedDocument){
const error = _.extend({}, constants.ERRORS.NEWER_PEER_DOCUMENT_AVAILABLE);
_.extend(error.uerr, { peer: found });
throw error;
} else if (isAlreadyKnown) {
throw constants.ERRORS.PEER_DOCUMENT_ALREADY_KNOWN;
}
peerEntity = Peer.statics.peerize(found);
if (interfacesChanged) {
// Warns the old peer of the change
const caster = multicaster();
caster.sendPeering(Peer.statics.peerize(peerEntity), Peer.statics.peerize(thePeer));
}
thePeer.copyValues(peerEntity);
peerEntity.sigDate = new Date(sigTime * 1000);
}
thePeer.copyValues(peerEntity);
peerEntity.sigDate = new Date(sigTime * 1000);
}
// Set the peer as UP again
peerEntity.status = 'UP';
peerEntity.first_down = null;
peerEntity.last_try = null;
peerEntity.hash = String(hashf(peerEntity.getRawSigned())).toUpperCase();
peerEntity.raw = peerEntity.getRaw();
await this.dal.savePeer(peerEntity);
let savedPeer = Peer.statics.peerize(peerEntity);
if (peerEntity.pubkey == this.selfPubkey) {
const localEndpoint = await this.server.getMainEndpoint(this.conf);
const localNodeNotListed = !peerEntity.containsEndpoint(localEndpoint);
const current = localNodeNotListed && (await this.dal.getCurrentBlockOrNull());
if (!localNodeNotListed) {
const indexOfThisNode = peerEntity.endpoints.indexOf(localEndpoint);
if (indexOfThisNode !== -1) {
this.server.push({
nodeIndexInPeers: indexOfThisNode
});
// Set the peer as UP again
peerEntity.status = 'UP';
peerEntity.first_down = null;
peerEntity.last_try = null;
peerEntity.hash = String(hashf(peerEntity.getRawSigned())).toUpperCase();
peerEntity.raw = peerEntity.getRaw();
await this.dal.savePeer(peerEntity);
this.logger.info('✔ PEER %s', peering.pubkey.substr(0, 8))
let savedPeer = Peer.statics.peerize(peerEntity);
if (peerEntity.pubkey == this.selfPubkey) {
const localEndpoint = await this.server.getMainEndpoint(this.conf);
const localNodeNotListed = !peerEntity.containsEndpoint(localEndpoint);
const current = localNodeNotListed && (await this.dal.getCurrentBlockOrNull());
if (!localNodeNotListed) {
const indexOfThisNode = peerEntity.endpoints.indexOf(localEndpoint);
if (indexOfThisNode !== -1) {
this.server.push({