diff --git a/.gitignore b/.gitignore index dbb80f0d968a967cf2f524cc0a930cfc27527112..d8b4d96841d50077f479ed283bf65f6fbd18cc2b 100644 --- a/.gitignore +++ b/.gitignore @@ -88,3 +88,25 @@ test/dal/loki.d.ts test/dal/loki.js* test/dal/blockchain-archive.d.ts test/dal/blockchain-archive.js* +test/dal/basic-dal-tests.d.ts +test/dal/basic-dal-tests.js* + +# In test folders +test/integration/wot/*.d.ts +test/integration/wot/*.js* +test/integration/transactions/*.d.ts +test/integration/transactions/*.js* +test/integration/network/*.d.ts +test/integration/network/*.js* +test/integration/misc/*.d.ts +test/integration/misc/*.js* +test/integration/identity/*.d.ts +test/integration/identity/*.js* +test/integration/certification/*.d.ts +test/integration/certification/*.js* +test/integration/branches/*.d.ts +test/integration/branches/*.js* +test/integration/blocks/*.d.ts +test/integration/blocks/*.js* +test/fast/index/*.d.ts +test/fast/index/*.js* \ No newline at end of file diff --git a/app/lib/blockchain/DuniterBlockchain.ts b/app/lib/blockchain/DuniterBlockchain.ts index 843ab75e08ea49280f00b582804450955ea6bc92..ea76b84517aa7314909d3615b24dc4e0203de852 100644 --- a/app/lib/blockchain/DuniterBlockchain.ts +++ b/app/lib/blockchain/DuniterBlockchain.ts @@ -27,8 +27,7 @@ import {FileDAL} from "../dal/fileDAL" import {DataErrors} from "../common-libs/errors" import {NewLogger} from "../logger" import {DBTx} from "../db/DBTx" - -const _ = require('underscore') +import {Underscore} from "../common-libs/underscore" export class DuniterBlockchain { @@ -334,10 +333,10 @@ export class DuniterBlockchain { } static async updateWallets(sindex:SindexEntry[], aDal:any, reverse = false) { - const differentConditions = _.uniq(sindex.map((entry) => entry.conditions)) + const differentConditions = Underscore.uniq(sindex.map((entry) => entry.conditions)) for (const conditions of differentConditions) { - const creates = _.filter(sindex, (entry:SindexEntry) => entry.conditions === conditions && entry.op === CommonConstants.IDX_CREATE) - const updates = _.filter(sindex, (entry:SindexEntry) => entry.conditions === conditions && entry.op === CommonConstants.IDX_UPDATE) + const creates = Underscore.filter(sindex, (entry:SindexEntry) => entry.conditions === conditions && entry.op === CommonConstants.IDX_CREATE) + const updates = Underscore.filter(sindex, (entry:SindexEntry) => entry.conditions === conditions && entry.op === CommonConstants.IDX_UPDATE) const positives = creates.reduce((sum:number, src:SindexEntry) => sum + src.amount * Math.pow(10, src.base), 0) const negatives = updates.reduce((sum:number, src:SindexEntry) => sum + src.amount * Math.pow(10, src.base), 0) const wallet = await aDal.getWallet(conditions) @@ -476,7 +475,7 @@ export class DuniterBlockchain { } static async computeToBeRevoked(mindex:MindexEntry[], dal:FileDAL) { - const revocations = _.filter(mindex, (entry:MindexEntry) => entry.revoked_on); + const revocations = Underscore.filter(mindex, (entry:MindexEntry) => !!(entry.revoked_on)) for (const revoked of revocations) { await dal.setRevoked(revoked.pub) } diff --git a/app/lib/common-libs/crypto/map.ts b/app/lib/common-libs/crypto/map.ts new file mode 100644 index 0000000000000000000000000000000000000000..a178fde884f70191fa00e56a5e4d2e91ba2f9eaa --- /dev/null +++ b/app/lib/common-libs/crypto/map.ts @@ -0,0 +1,4 @@ + +export interface Map<T> { + [k:string]: T +} diff --git a/app/lib/common-libs/underscore.ts b/app/lib/common-libs/underscore.ts index 4bb08092d66a51db4d01a4733a97214086fdeae8..2592220474e242b23f4e9af5b59609f132c6e8eb 100644 --- a/app/lib/common-libs/underscore.ts +++ b/app/lib/common-libs/underscore.ts @@ -1,28 +1,87 @@ -const _ = require("underscore") +import {Map} from "./crypto/map" + +const _underscore_ = require("underscore") + +export interface UnderscoreClass<T> { + filter(filterFunc: (t: T) => boolean): UnderscoreClass<T> + where(props: { [k in keyof T]?: T[k] }): UnderscoreClass<T> + sortBy(sortFunc:(element:T) => number): UnderscoreClass<T> + pluck<K extends keyof T>(k:K): UnderscoreClass<T> + uniq<K extends keyof T>(isSorted?:boolean, iteratee?:(t:T) => K): UnderscoreClass<T> + value(): T[] +} export const Underscore = { filter: <T>(elements:T[], filterFunc: (t:T) => boolean): T[] => { - return _.filter(elements, filterFunc) + return _underscore_.filter(elements, filterFunc) }, where: <T>(elements:T[], props: { [k in keyof T]?: T[k] }): T[] => { - return _.where(elements, props) + return _underscore_.where(elements, props) + }, + + findWhere: <T>(elements:T[], props: { [k in keyof T]?: T[k] }): T|null => { + return _underscore_.findWhere(elements, props) }, keys: <T>(map:T): (keyof T)[] => { - return _.keys(map) + return _underscore_.keys(map) }, values: <T>(map:{ [k:string]: T }): T[] => { - return _.values(map) + return _underscore_.values(map) }, pluck: <T, K extends keyof T>(elements:T[], k:K): T[K][] => { - return _.pluck(elements, k) + return _underscore_.pluck(elements, k) + }, + + pick: <T, K extends keyof T>(elements:T, ...k:K[]): T[K][] => { + return _underscore_.pick(elements, ...k) + }, + + omit: <T, K extends keyof T>(element:T, ...k:K[]): T[K][] => { + return _underscore_.omit(element, ...k) + }, + + uniq: <T, K>(elements:T[], isSorted:boolean = false, iteratee?:(t:T) => K): T[] => { + return _underscore_.uniq(elements, isSorted, iteratee) + }, + + clone: <T>(t:T): T => { + return _underscore_.clone(t) + }, + + mapObject: <T, K extends keyof T, L extends keyof (T[K])>(t:T, cb:(k:K) => (T[K])[L]): Map<T[K][L]> => { + return _underscore_.mapObject(t, cb) + }, + + mapObjectByProp: <T, K extends keyof T, L extends keyof (T[K])>(t:T, prop:L): Map<T[K][L]> => { + return _underscore_.mapObject(t, (o:T[K]) => o[prop]) + }, + + sortBy: <T, K extends keyof T>(elements:T[], sortFunc:((element:T) => number|string)|K): T[] => { + return _underscore_.sortBy(elements, sortFunc) + }, + + difference: <T>(array1:T[], array2:T[]): T[] => { + return _underscore_.difference(array1, array2) }, - uniq: <T>(elements:T[]): T[] => { - return _.uniq(elements) - } + shuffle: <T>(elements:T[]): T[] => { + return _underscore_.shuffle(elements) + }, + + extend: <T, U>(t1:T, t2:U): T|U => { + return _underscore_.extend(t1, t2) + }, + + range: (count:number, end?:number): number[] => { + return _underscore_.range(count, end) + }, + + chain: <T>(element:T[]): UnderscoreClass<T> => { + return _underscore_.chain(element) + }, } diff --git a/app/lib/computation/BlockchainContext.ts b/app/lib/computation/BlockchainContext.ts index b33f4a7ace0b891835300802f7a6d81fbf8b3735..cc5bb67ad73bc6d346c4d9e4a2f0064ac275c731 100644 --- a/app/lib/computation/BlockchainContext.ts +++ b/app/lib/computation/BlockchainContext.ts @@ -11,15 +11,14 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; import {BlockDTO} from "../dto/BlockDTO" import {DuniterBlockchain} from "../blockchain/DuniterBlockchain" import {QuickSynchronizer} from "./QuickSync" import {DBHead} from "../db/DBHead" import {FileDAL} from "../dal/fileDAL" import {DBBlock} from "../db/DBBlock" +import {Underscore} from "../common-libs/underscore" -const _ = require('underscore'); const indexer = require('../indexer').Indexer const constants = require('../constants'); @@ -28,7 +27,6 @@ export class BlockchainContext { private conf:any private dal:FileDAL private logger:any - private blockchain:DuniterBlockchain private quickSynchronizer:QuickSynchronizer /** @@ -84,7 +82,7 @@ export class BlockchainContext { for (const k of keys) { copy[k] = this.vHEAD[k]; } - _.extend(copy, props); + Underscore.extend(copy, props); return copy; } diff --git a/app/lib/computation/QuickSync.ts b/app/lib/computation/QuickSync.ts index b825912f7b4113adbb6c0dfa427e31d7371cacd6..049b057f993a842bf1f4c6f6d3151bc532d6a1d0 100644 --- a/app/lib/computation/QuickSync.ts +++ b/app/lib/computation/QuickSync.ts @@ -19,8 +19,8 @@ import {CurrencyConfDTO} from "../dto/ConfDTO"; import {FileDAL} from "../dal/fileDAL" import {DBBlock} from "../db/DBBlock" import {DBTx} from "../db/DBTx" +import {Underscore} from "../common-libs/underscore" -const _ = require('underscore') const constants = require('../constants') let sync_bindex: any [] = []; @@ -171,7 +171,7 @@ export class QuickSynchronizer { const nextExpiringChanged = currentNextExpiring !== sync_nextExpiring // Fills in correctly the SINDEX - await Promise.all(_.where(sync_sindex.concat(local_sindex), { op: 'UPDATE' }).map(async (entry: any) => { + await Promise.all(Underscore.where(sync_sindex.concat(local_sindex), { op: 'UPDATE' }).map(async (entry: any) => { if (!entry.conditions) { const src = (await this.dal.sindexDAL.getSource(entry.identifier, entry.pos)) as FullSindexEntry entry.conditions = src.conditions; @@ -246,8 +246,8 @@ export class QuickSynchronizer { await this.dal.cindexDAL.insertBatch(sync_cindex); // Save the intermediary table of wallets - const conditions = _.keys(sync_memoryWallets) - const nonEmptyKeys = _.filter(conditions, (k: any) => sync_memoryWallets[k] && sync_memoryWallets[k].balance > 0) + const conditions = Underscore.keys(sync_memoryWallets) + const nonEmptyKeys = Underscore.filter(conditions, (k: any) => sync_memoryWallets[k] && sync_memoryWallets[k].balance > 0) const walletsToRecord = nonEmptyKeys.map((k: any) => sync_memoryWallets[k]) await this.dal.walletDAL.insertBatch(walletsToRecord) for (const cond of conditions) { diff --git a/app/lib/dal/fileDAL.ts b/app/lib/dal/fileDAL.ts index b15ce341911162e65b385314e8b222a01307f308..99756afbe9c4544024e3eba5f020f3edf503269e 100644 --- a/app/lib/dal/fileDAL.ts +++ b/app/lib/dal/fileDAL.ts @@ -30,7 +30,6 @@ import { IndexEntry, SindexEntry } from "../indexer" -import {DBPeer} from "./sqliteDAL/PeerDAL" import {TransactionDTO} from "../dto/TransactionDTO" import {CertDAL, DBCert} from "./sqliteDAL/CertDAL" import {DBBlock} from "../db/DBBlock" @@ -72,9 +71,10 @@ import {Tristamp} from "../common/Tristamp" import {CFSBlockchainArchive} from "./indexDAL/CFSBlockchainArchive" import {CFSCore} from "./fileDALs/CFSCore" import {BlockchainArchiveDAO} from "./indexDAL/abstract/BlockchainArchiveDAO" +import {Underscore} from "../common-libs/underscore" +import {DBPeer} from "../db/DBPeer" const readline = require('readline') -const _ = require('underscore'); const indexer = require('../indexer').Indexer const logger = require('../logger').NewLogger('filedal'); const constants = require('../constants'); @@ -187,7 +187,7 @@ export class FileDAL { for (const indexDAL of dals) { indexDAL.triggerInit() } - const dalNames = _.keys(this.newDals); + const dalNames = Underscore.keys(this.newDals); for (const dalName of dalNames) { const dal = this.newDals[dalName]; await dal.init(); @@ -321,10 +321,10 @@ export class FileDAL { // Cert period rule const medianTime = vHEAD_1 ? vHEAD_1.medianTime : 0; const linksFrom:FullCindexEntry[] = await this.cindexDAL.reducablesFrom(from) - const unchainables = _.filter(linksFrom, (link:CindexEntry) => link.chainable_on > medianTime); + const unchainables = Underscore.filter(linksFrom, (link:CindexEntry) => link.chainable_on > medianTime); if (unchainables.length > 0) return true; // Max stock rule - let activeLinks = _.filter(linksFrom, (link:CindexEntry) => !link.expired_on); + let activeLinks = Underscore.filter(linksFrom, (link:CindexEntry) => !link.expired_on); return activeLinks.length >= sigStock; } @@ -620,7 +620,7 @@ export class FileDAL { async findPeersWhoseHashIsIn(hashes:string[]) { const peers = await this.peerDAL.listAll(); - return _.chain(peers).filter((p:DBPeer) => hashes.indexOf(p.hash) !== -1).value(); + return Underscore.chain(peers).filter((p:DBPeer) => hashes.indexOf(p.hash) !== -1).value() } getTxByHash(hash:string) { @@ -637,7 +637,7 @@ export class FileDAL { async getNonWritten(pubkey:string) { const pending = await this.idtyDAL.getPendingIdentities(); - return _.chain(pending).where({pubkey: pubkey}).value(); + return Underscore.chain(pending).where({pubkey: pubkey}).value() } async getRevocatingMembers() { @@ -660,18 +660,18 @@ export class FileDAL { return this.mindexDAL.getRevokedPubkeys() } - async searchJustIdentities(search:string) { + async searchJustIdentities(search:string): Promise<DBIdentity[]> { const pendings = await this.idtyDAL.searchThoseMatching(search); const writtens = await this.iindexDAL.searchThoseMatching(search); - const nonPendings = _.filter(writtens, (w:IindexEntry) => { - return _.where(pendings, { pubkey: w.pub }).length == 0; + const nonPendings = Underscore.filter(writtens, (w:IindexEntry) => { + return Underscore.where(pendings, { pubkey: w.pub }).length == 0; }); const found = pendings.concat(nonPendings.map((i:any) => { // Use the correct field i.pubkey = i.pub return i })); - return await Promise.all(found.map(async (f:any) => { + return await Promise.all<DBIdentity>(found.map(async (f:any) => { const ms = await this.mindexDAL.getReducedMS(f.pub); if (ms) { f.revoked_on = ms.revoked_on ? ms.revoked_on : null; @@ -689,7 +689,7 @@ export class FileDAL { await Promise.all(links.map(async (entry:any) => { matching.push(await this.cindexEntry2DBCert(entry)) })) - matching = _.sortBy(matching, (c:DBCert) => -c.block); + matching = Underscore.sortBy(matching, (c:DBCert) => -c.block); matching.reverse(); return matching; } @@ -701,7 +701,7 @@ export class FileDAL { await Promise.all(links.map(async (entry:CindexEntry) => { matching.push(await this.cindexEntry2DBCert(entry)) })) - matching = _.sortBy(matching, (c:DBCert) => -c.block); + matching = Underscore.sortBy(matching, (c:DBCert) => -c.block); matching.reverse(); return matching; } @@ -741,12 +741,12 @@ export class FileDAL { async certsFindNew() { const certs = await this.certDAL.getNotLinked(); - return _.chain(certs).where({linked: false}).sortBy((c:DBCert) => -c.block).value(); + return Underscore.chain(certs).where({linked: false}).sortBy((c:DBCert) => -c.block).value() } async certsNotLinkedToTarget(hash:string) { const certs = await this.certDAL.getNotLinkedToTarget(hash); - return _.chain(certs).sortBy((c:any) => -c.block).value(); + return Underscore.chain(certs).sortBy((c:any) => -c.block).value(); } async getMostRecentMembershipNumberForIssuer(issuer:string) { @@ -761,7 +761,7 @@ export class FileDAL { async lastJoinOfIdentity(target:string) { let pending = await this.msDAL.getPendingINOfTarget(target); - return _(pending).sortBy((ms:any) => -ms.number)[0]; + return Underscore.sortBy(pending, (ms:any) => -ms.number)[0]; } async findNewcomers(blockMedianTime = 0): Promise<DBMembership[]> { @@ -773,24 +773,22 @@ export class FileDAL { } return null })) - return _.chain(mss) - .filter((ms:DBMembership) => ms) + return Underscore.chain(Underscore.filter(mss, ms => !!ms) as DBMembership[]) .sortBy((ms:DBMembership) => -ms.blockNumber) .value() } async findLeavers(blockMedianTime = 0): Promise<DBMembership[]> { const pending = await this.msDAL.getPendingOUT(); - const mss = await Promise.all(pending.map(async (p:any) => { + const mss = await Promise.all<DBMembership|null>(pending.map(async p => { const reduced = await this.mindexDAL.getReducedMS(p.issuer) if (!reduced || !reduced.chainable_on || blockMedianTime >= reduced.chainable_on || blockMedianTime < constants.TIME_TO_TURN_ON_BRG_107) { return p } return null })) - return _.chain(mss) - .filter((ms:DBMembership) => ms) - .sortBy((ms:DBMembership) => -ms.blockNumber) + return Underscore.chain(Underscore.filter(mss, ms => !!ms) as DBMembership[]) + .sortBy(ms => -ms.blockNumber) .value(); } @@ -884,14 +882,14 @@ export class FileDAL { async listAllPeersWithStatusNewUP() { const peers = await this.peerDAL.listAll(); - return _.chain(peers) + return Underscore.chain(peers) .filter((p:DBPeer) => ['UP'] .indexOf(p.status) !== -1).value(); } async listAllPeersWithStatusNewUPWithtout(pub:string) { const peers = await this.peerDAL.listAll(); - return _.chain(peers).filter((p:DBPeer) => p.status == 'UP').filter((p:DBPeer) => p.pubkey !== pub).value(); + return Underscore.chain(peers).filter((p:DBPeer) => p.status == 'UP').filter((p:DBPeer) => p.pubkey !== pub).value(); } async findPeers(pubkey:string): Promise<DBPeer[]> { @@ -903,9 +901,9 @@ export class FileDAL { } } - async getRandomlyUPsWithout(pubkeys:string[]) { + async getRandomlyUPsWithout(pubkeys:string[]): Promise<DBPeer[]> { const peers = await this.listAllPeersWithStatusNewUP(); - return peers.filter((peer:DBPeer) => pubkeys.indexOf(peer.pubkey) == -1); + return peers.filter(peer => pubkeys.indexOf(peer.pubkey) == -1) } async setPeerUP(pubkey:string) { @@ -1098,7 +1096,7 @@ export class FileDAL { async getUDHistory(pubkey:string) { const sources = await this.sindexDAL.getUDSources(pubkey) return { - history: sources.map((src:SindexEntry) => _.extend({ + history: sources.map((src:SindexEntry) => Underscore.extend({ block_number: src.pos, time: src.written_time }, src)) @@ -1114,7 +1112,7 @@ export class FileDAL { const firstBlock = Math.max(0, start); const lastBlock = Math.max(0, Math.min(current.number, end)); const blocks = await this.blockDAL.getBlocks(firstBlock, lastBlock); - return _.chain(blocks).pluck('issuer').uniq().value(); + return Underscore.uniq(blocks.map(b => b.issuer)) } /** @@ -1152,11 +1150,11 @@ export class FileDAL { async loadConf(overrideConf:ConfDTO, defaultConf = false) { let conf = ConfDTO.complete(overrideConf || {}); if (!defaultConf) { - const savedConf = await this.confDAL.loadConf(); - const savedProxyConf = _(savedConf.proxyConf).extend({}); - conf = _(savedConf).extend(overrideConf || {}); + const savedConf = await this.confDAL.loadConf() + const savedProxyConf = Underscore.extend(savedConf.proxyConf, {}) + conf = Underscore.extend(savedConf, overrideConf || {}) if (overrideConf.proxiesConf !== undefined) {} else { - conf.proxyConf = _(savedProxyConf).extend({}); + conf.proxyConf = Underscore.extend(savedProxyConf, {}) } } if (this.loadConfHook) { @@ -1206,11 +1204,11 @@ export class FileDAL { } async cleanCaches() { - await _.values(this.newDals).map((dal:Initiable) => dal.cleanCache && dal.cleanCache()) + await Underscore.values(this.newDals).map((dal:Initiable) => dal.cleanCache && dal.cleanCache()) } async close() { - await _.values(this.newDals).map((dal:Initiable) => dal.cleanCache && dal.cleanCache()) + await Underscore.values(this.newDals).map((dal:Initiable) => dal.cleanCache && dal.cleanCache()) return this.sqliteDriver.closeConnection(); } diff --git a/app/lib/dal/fileDALs/CFSCore.ts b/app/lib/dal/fileDALs/CFSCore.ts index 28971e6c545fc7e8fc39f9513c8fe53ec2f69a41..019155abe5149360d5199937a4de0f9a48732919 100644 --- a/app/lib/dal/fileDALs/CFSCore.ts +++ b/app/lib/dal/fileDALs/CFSCore.ts @@ -14,8 +14,8 @@ "use strict"; import {FileSystem} from "../../system/directory" +import {Underscore} from "../../common-libs/underscore" -const _ = require('underscore'); const path = require('path'); const DEEP_WRITE = true; @@ -92,9 +92,9 @@ export class CFSCore { const deletedOfThisPath = deletedFiles.filter((f:string) => f.match(new RegExp('^' + this.toRemoveDirName(dirPath)))); const locallyDeletedFiles = deletedOfThisPath.map((f:string) => f.replace(this.toRemoveDirName(dirPath), '') .replace(/^__/, '')); - files = _.difference(files, locallyDeletedFiles); + files = Underscore.difference(files, locallyDeletedFiles) } - return _.uniq(files); + return Underscore.uniq(files) }; /** diff --git a/app/lib/dal/fileDALs/ConfDAL.ts b/app/lib/dal/fileDALs/ConfDAL.ts index 5ecef21a9a5cf29ab976ec4cbe9b86064ebccf3d..f42197b7ef4a9200bf0909f268cee68df822a465 100644 --- a/app/lib/dal/fileDALs/ConfDAL.ts +++ b/app/lib/dal/fileDALs/ConfDAL.ts @@ -15,8 +15,7 @@ import {AbstractCFS} from "./AbstractCFS" import {ConfDTO} from "../../dto/ConfDTO" import {CommonConstants} from "../../common-libs/constants"; import {FileSystem} from "../../system/directory" - -const _ = require('underscore'); +import {Underscore} from "../../common-libs/underscore" export class ConfDAL extends AbstractCFS { @@ -62,7 +61,7 @@ export class ConfDAL extends AbstractCFS { async loadConf() { const data = await this.coreFS.readJSON('conf.json'); if (data) { - return _(ConfDTO.defaultConf()).extend(data); + return Underscore.extend(ConfDTO.defaultConf(), data) } else { // Silent error this.logger.warn('No configuration loaded'); diff --git a/app/lib/dal/fileDALs/StatDAL.ts b/app/lib/dal/fileDALs/StatDAL.ts index 6e3501469203c64de026655bae958163439f813a..96f03e5444b18cc43e31047097606a056e105b79 100644 --- a/app/lib/dal/fileDALs/StatDAL.ts +++ b/app/lib/dal/fileDALs/StatDAL.ts @@ -13,8 +13,7 @@ import {AbstractCFS} from "./AbstractCFS"; import {FileSystem} from "../../system/directory" - -const _ = require('underscore'); +import {Underscore} from "../../common-libs/underscore" export class StatDAL extends AbstractCFS { @@ -40,7 +39,7 @@ export class StatDAL extends AbstractCFS { async pushStats(statsToPush:any) { const stats = (await this.loadStats()) || {}; - _.keys(statsToPush).forEach(function(statName:string){ + Underscore.keys(statsToPush).forEach(function(statName:string){ if (!stats[statName]) { stats[statName] = { blocks: [] }; } diff --git a/app/lib/dal/indexDAL/abstract/PeerDAO.ts b/app/lib/dal/indexDAL/abstract/PeerDAO.ts index 9e3423b43b5bf43a925626193b99904223e5b99c..6cedd6230aa5a530e51501f9571720a2a0f1a80c 100644 --- a/app/lib/dal/indexDAL/abstract/PeerDAO.ts +++ b/app/lib/dal/indexDAL/abstract/PeerDAO.ts @@ -1,5 +1,5 @@ import {Initiable} from "../../sqliteDAL/Initiable" -import {DBPeer} from "../../sqliteDAL/PeerDAL" +import {DBPeer} from "../../../db/DBPeer" export interface PeerDAO extends Initiable { diff --git a/app/lib/dal/indexDAL/loki/LokiPeer.ts b/app/lib/dal/indexDAL/loki/LokiPeer.ts index 2614d0ac737ba5295893ec92fbe1b0d86525981b..7aef11957088093557789c6e59e6e0cc1778a6bd 100644 --- a/app/lib/dal/indexDAL/loki/LokiPeer.ts +++ b/app/lib/dal/indexDAL/loki/LokiPeer.ts @@ -1,6 +1,6 @@ import {LokiCollectionManager} from "./LokiCollectionManager" import {PeerDAO} from "../abstract/PeerDAO" -import {DBPeer} from "../../sqliteDAL/PeerDAL" +import {DBPeer} from "../../../db/DBPeer" export class LokiPeer extends LokiCollectionManager<DBPeer> implements PeerDAO { diff --git a/app/lib/dal/indexDAL/loki/LokiSIndex.ts b/app/lib/dal/indexDAL/loki/LokiSIndex.ts index d7d6bb288cc8432baf0433d3aadfa1927a287947..575d529a418fd59fcc1579c3bacc30f6d204fe02 100644 --- a/app/lib/dal/indexDAL/loki/LokiSIndex.ts +++ b/app/lib/dal/indexDAL/loki/LokiSIndex.ts @@ -1,8 +1,7 @@ import {LokiIndex} from "./LokiIndex" import {FullSindexEntry, Indexer, SindexEntry} from "../../../indexer" import {SIndexDAO} from "../abstract/SIndexDAO" - -const _ = require('underscore') +import {Underscore} from "../../../common-libs/underscore" export class LokiSIndex extends LokiIndex<SindexEntry> implements SIndexDAO { @@ -33,7 +32,7 @@ export class LokiSIndex extends LokiIndex<SindexEntry> implements SIndexDAO { src.type = src.tx ? 'T' : 'D' return src }) - return _.sortBy(sources, (row:SindexEntry) => row.type == 'D' ? 0 : 1); + return Underscore.sortBy(sources, (row:SindexEntry) => row.type == 'D' ? 0 : 1) } async getAvailableForPubkey(pubkey: string): Promise<{ amount: number; base: number }[]> { diff --git a/app/lib/dal/indexDAL/loki/LokiTransactions.ts b/app/lib/dal/indexDAL/loki/LokiTransactions.ts index ea8a09ecf5adaa557434eed79304a1a3b5b72a6a..97265aaecf2d34ba568d150794a1c044bd7b1305 100644 --- a/app/lib/dal/indexDAL/loki/LokiTransactions.ts +++ b/app/lib/dal/indexDAL/loki/LokiTransactions.ts @@ -3,8 +3,8 @@ import {TxsDAO} from "../abstract/TxsDAO" import {SandBox} from "../../sqliteDAL/SandBox" import {TransactionDTO} from "../../../dto/TransactionDTO" import {DBTx} from "../../../db/DBTx" +import {Underscore} from "../../../common-libs/underscore" -const _ = require('underscore') const moment = require('moment') const constants = require('../../../constants') @@ -106,7 +106,7 @@ export class LokiTransactions extends LokiIndex<DBTx> implements TxsDAO { written: true }) // Which does not contains the key as issuer - return _.filter(rows, (row: DBTx) => row.issuers.indexOf(pubkey) === -1); + return Underscore.filter(rows, (row: DBTx) => row.issuers.indexOf(pubkey) === -1); } async getPendingWithIssuer(pubkey: string): Promise<DBTx[]> { diff --git a/app/lib/dal/sqliteDAL/AbstractSQLite.ts b/app/lib/dal/sqliteDAL/AbstractSQLite.ts index 4a240425613410f3d2a77829f14f931d79be9f34..7e3c42b70b1724c60e0ff3a6aa7f92031ddf5a8f 100644 --- a/app/lib/dal/sqliteDAL/AbstractSQLite.ts +++ b/app/lib/dal/sqliteDAL/AbstractSQLite.ts @@ -14,12 +14,12 @@ import {SQLiteDriver} from "../drivers/SQLiteDriver" import {Initiable} from "./Initiable" import {getDurationInMicroSeconds, getMicrosecondsTime} from "../../../ProcessCpuProfiler" +import {Underscore} from "../../common-libs/underscore" /** * Created by cgeek on 22/08/15. */ -const _ = require('underscore'); const colors = require('colors'); const logger = require('../../logger').NewLogger('sqlite'); @@ -84,7 +84,7 @@ export abstract class AbstractSQLite<T> extends Initiable { sqlFind(obj:any, sortObj:any = {}): Promise<T[]> { const conditions = this.toConditionsArray(obj).join(' and '); const values = this.toParams(obj); - const sortKeys: string[] = _.keys(sortObj); + const sortKeys: string[] = Underscore.keys(sortObj) const sort = sortKeys.length ? ' ORDER BY ' + sortKeys.map((k) => "`" + k + "` " + (sortObj[k] ? 'DESC' : 'ASC')).join(',') : ''; return this.query('SELECT * FROM ' + this.table + ' WHERE ' + conditions + sort, values); } @@ -95,12 +95,12 @@ export abstract class AbstractSQLite<T> extends Initiable { } sqlFindLikeAny(obj:any): Promise<T[]> { - const keys:string[] = _.keys(obj); + const keys:string[] = Underscore.keys(obj) return this.query('SELECT * FROM ' + this.table + ' WHERE ' + keys.map((k) => 'UPPER(`' + k + '`) like ?').join(' or '), keys.map((k) => obj[k].toUpperCase())) } async sqlRemoveWhere(obj:any): Promise<void> { - const keys:string[] = _.keys(obj); + const keys:string[] = Underscore.keys(obj) await this.query('DELETE FROM ' + this.table + ' WHERE ' + keys.map((k) => '`' + k + '` = ?').join(' and '), keys.map((k) => obj[k])) } @@ -209,7 +209,7 @@ export abstract class AbstractSQLite<T> extends Initiable { } private toConditionsArray(obj:any): string[] { - return _.keys(obj).map((k:string) => { + return Underscore.keys(obj).map((k:string) => { if (obj[k].$lte !== undefined) { return '`' + k + '` <= ?'; } else if (obj[k].$gte !== undefined) { @@ -230,7 +230,7 @@ export abstract class AbstractSQLite<T> extends Initiable { private toParams(obj:any, fields:string[] | null = null): any[] { let params:any[] = []; - (fields || _.keys(obj)).forEach((f:string) => { + (fields || Underscore.keys(obj)).forEach((f:string) => { if (obj[f].$null === undefined) { let pValue; if (obj[f].$lte !== undefined) { pValue = obj[f].$lte; } diff --git a/app/lib/dal/sqliteDAL/MembershipDAL.ts b/app/lib/dal/sqliteDAL/MembershipDAL.ts index 65cb2af3529d60d36ee314d40e0cdb444c4539a6..ddadff48d9138f1bc567666eb79405fa918584b2 100644 --- a/app/lib/dal/sqliteDAL/MembershipDAL.ts +++ b/app/lib/dal/sqliteDAL/MembershipDAL.ts @@ -15,8 +15,8 @@ import {SQLiteDriver} from "../drivers/SQLiteDriver"; import {AbstractSQLite} from "./AbstractSQLite"; import {SandBox} from './SandBox'; import {DBDocument} from './DocumentDAL'; +import {Underscore} from "../../common-libs/underscore" -const _ = require('underscore'); const constants = require('../../constants'); export interface DBMembership extends DBDocument { @@ -128,7 +128,7 @@ export class MembershipDAL extends AbstractSQLite<DBMembership> { savePendingMembership(ms:DBMembership) { ms.membership = ms.membership.toUpperCase(); ms.written = false; - return this.saveEntity(_.pick(ms, 'membership', 'issuer', 'number', 'blockNumber', 'blockHash', 'userid', 'certts', 'block', 'fpr', 'idtyHash', 'expires_on', 'written', 'written_number', 'signature')) + return this.saveEntity(Underscore.pick(ms, 'membership', 'issuer', 'number', 'blockNumber', 'blockHash', 'userid', 'certts', 'block', 'fpr', 'idtyHash', 'expires_on', 'written', 'written_number', 'signature')) } async deleteMS(ms:DBMembership) { diff --git a/app/lib/dal/sqliteDAL/MetaDAL.ts b/app/lib/dal/sqliteDAL/MetaDAL.ts index 023259da4cd28cfb28da618488320e8f8d05b279..53b7b49086d1d7f1a21ff53d8448f7985ca1be03 100644 --- a/app/lib/dal/sqliteDAL/MetaDAL.ts +++ b/app/lib/dal/sqliteDAL/MetaDAL.ts @@ -17,7 +17,6 @@ import {ConfDTO} from "../../dto/ConfDTO" import {TransactionDTO} from "../../dto/TransactionDTO" import {IdentityDAL} from "./IdentityDAL" -const _ = require('underscore') const logger = require('../../logger').NewLogger('metaDAL'); export interface DBMeta { diff --git a/app/lib/dal/sqliteDAL/PeerDAL.ts b/app/lib/dal/sqliteDAL/PeerDAL.ts deleted file mode 100644 index e5662fa8a7ddf683b6000c944052df7c155490d5..0000000000000000000000000000000000000000 --- a/app/lib/dal/sqliteDAL/PeerDAL.ts +++ /dev/null @@ -1,124 +0,0 @@ -// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 -// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -import {SQLiteDriver} from "../drivers/SQLiteDriver" -import {AbstractSQLite} from "./AbstractSQLite" - -export class DBPeer { - - version: number - currency: string - status: string - statusTS: number - hash: string - first_down: number | null - last_try: number | null - pubkey: string - block: string - signature: string - endpoints: string[] - raw: string - - json() { - return { - version: this.version, - currency: this.currency, - endpoints: this.endpoints, - status: this.status, - block: this.block, - signature: this.signature, - raw: this.raw, - pubkey: this.pubkey - } - } -} - -export class PeerDAL extends AbstractSQLite<DBPeer> { - - constructor(driver:SQLiteDriver) { - super( - driver, - 'peer', - // PK fields - ['pubkey'], - // Fields - [ - 'version', - 'currency', - 'status', - 'statusTS', - 'hash', - 'first_down', - 'last_try', - 'pubkey', - 'block', - 'signature', - 'endpoints', - 'raw' - ], - // Arrays - ['endpoints'], - // Booleans - [], - // BigIntegers - [], - // Transient - [] - ) - } - - async init() { - await this.exec('BEGIN;' + - 'CREATE TABLE IF NOT EXISTS ' + this.table + ' (' + - 'version INTEGER NOT NULL,' + - 'currency VARCHAR(50) NOT NULL,' + - 'status VARCHAR(10),' + - 'statusTS INTEGER NOT NULL,' + - 'hash CHAR(64),' + - 'first_down INTEGER,' + - 'last_try INTEGER,' + - 'pubkey VARCHAR(50) NOT NULL,' + - 'block VARCHAR(60) NOT NULL,' + - 'signature VARCHAR(100),' + - 'endpoints TEXT NOT NULL,' + - 'raw TEXT,' + - 'PRIMARY KEY (pubkey)' + - ');' + - 'CREATE INDEX IF NOT EXISTS idx_link_source ON peer (pubkey);' + - 'COMMIT;') - } - - listAll() { - return this.sqlListAll() - } - - getPeer(pubkey:string) { - return this.sqlFindOne({ pubkey: pubkey }) - } - - getPeersWithEndpointsLike(str:string) { - return this.query('SELECT * FROM peer WHERE endpoints LIKE ?', ['%' + str + '%']) - } - - savePeer(peer:DBPeer) { - return this.saveEntity(peer) - } - - removePeerByPubkey(pubkey:string) { - return this.exec('DELETE FROM peer WHERE pubkey LIKE \'' + pubkey + '\'') - } - - async removeAll() { - await this.sqlDeleteAll() - } -} diff --git a/app/lib/db/DBPeer.ts b/app/lib/db/DBPeer.ts new file mode 100644 index 0000000000000000000000000000000000000000..c71fb86e76500e80ecad0184c121606bd762e09e --- /dev/null +++ b/app/lib/db/DBPeer.ts @@ -0,0 +1,47 @@ +import {PeerDTO} from "../dto/PeerDTO" + +export class DBPeer { + + version: number + currency: string + status: string + statusTS: number + hash: string + first_down: number | null + last_try: number | null + pubkey: string + block: string + signature: string + endpoints: string[] + raw: string + + static json(peer:DBPeer): JSONDBPeer { + return { + version: peer.version, + currency: peer.currency, + status: peer.status, + first_down: peer.first_down, + last_try: peer.last_try, + pubkey: peer.pubkey, + block: peer.block, + signature: peer.signature, + endpoints: peer.endpoints + } + } + + static fromPeerDTO(peer:PeerDTO): DBPeer { + return peer.toDBPeer() + } +} + +export class JSONDBPeer { + version: number + currency: string + status: string + first_down: number | null + last_try: number | null + pubkey: string + block: string + signature: string + endpoints: string[] +} diff --git a/app/lib/dto/ConfDTO.ts b/app/lib/dto/ConfDTO.ts index eb9ccef3391badfa479b1ed7dc1fdb013be73f3f..0cfd61f6af14a59f6d1d22ed9b9e0638bedf69be 100644 --- a/app/lib/dto/ConfDTO.ts +++ b/app/lib/dto/ConfDTO.ts @@ -13,7 +13,7 @@ import {CommonConstants} from "../common-libs/constants" import { ProxiesConf } from '../proxy'; -const _ = require('underscore'); +import {Underscore} from "../common-libs/underscore" const constants = require('../constants'); export interface Keypair { @@ -215,6 +215,6 @@ export class ConfDTO implements CurrencyConfDTO, KeypairConfDTO, NetworkConfDTO, } static complete(conf:any) { - return _(ConfDTO.defaultConf()).extend(conf); + return Underscore.extend(ConfDTO.defaultConf(), conf) } } \ No newline at end of file diff --git a/app/lib/dto/PeerDTO.ts b/app/lib/dto/PeerDTO.ts index 119c8a90c7c3938ed7b658d81af88edd418223c7..9fb10b08f28752e8cbd4c3c5ae6675ae193400f7 100644 --- a/app/lib/dto/PeerDTO.ts +++ b/app/lib/dto/PeerDTO.ts @@ -11,11 +11,10 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -import {DBPeer} from "../dal/sqliteDAL/PeerDAL" import {hashf} from "../common" import {CommonConstants} from "../common-libs/constants" import {Cloneable} from "./Cloneable" -import { WS2PConstants } from '../../modules/ws2p/lib/constants'; +import {DBPeer} from "../db/DBPeer" export interface WS2PEndpoint { version:number diff --git a/app/lib/indexer.ts b/app/lib/indexer.ts index 705e632dc366f9689351786d94b4dce913f265dd..c93ac3851b812e6decd1a61e1815ed051311f074 100644 --- a/app/lib/indexer.ts +++ b/app/lib/indexer.ts @@ -210,7 +210,13 @@ export interface BlockchainBlocksDAL { export class Indexer { - static localIndex(block:BlockDTO, conf:CurrencyConfDTO): IndexEntry[] { + static localIndex(block:BlockDTO, conf:{ + sigValidity:number, + msValidity:number, + msPeriod:number, + sigPeriod:number, + sigStock:number + }): IndexEntry[] { /******************** * GENERAL BEHAVIOR @@ -1628,7 +1634,9 @@ export class Indexer { const members = await dal.iindexDAL.getMembersPubkeys() for (const MEMBER of members) { dividends.push({ + index: constants.S_INDEX, op: 'CREATE', + tx: null, identifier: MEMBER.pub, pos: HEAD.number, written_on: [HEAD.number, HEAD.hash].join('-'), @@ -1833,27 +1841,27 @@ export class Indexer { } static iindexCreate(index: IndexEntry[]): IindexEntry[] { - return _(index).filter({ index: constants.I_INDEX, op: constants.IDX_CREATE }) + return Underscore.where(index, { index: constants.I_INDEX, op: constants.IDX_CREATE }) as IindexEntry[] } static mindexCreate(index: IndexEntry[]): MindexEntry[] { - return _(index).filter({ index: constants.M_INDEX, op: constants.IDX_CREATE }) + return Underscore.where(index, { index: constants.M_INDEX, op: constants.IDX_CREATE }) as MindexEntry[] } static iindex(index: IndexEntry[]): IindexEntry[] { - return _(index).filter({ index: constants.I_INDEX }) + return Underscore.where(index, { index: constants.I_INDEX }) as IindexEntry[] } static mindex(index: IndexEntry[]): MindexEntry[] { - return _(index).filter({ index: constants.M_INDEX }) + return Underscore.where(index, { index: constants.M_INDEX }) as MindexEntry[] } static cindex(index: IndexEntry[]): CindexEntry[] { - return _(index).filter({ index: constants.C_INDEX }) + return Underscore.where(index, { index: constants.C_INDEX }) as CindexEntry[] } static sindex(index: IndexEntry[]): SindexEntry[] { - return _(index).filter({ index: constants.S_INDEX }) + return Underscore.where(index, { index: constants.S_INDEX }) as SindexEntry[] } static DUP_HELPERS = { diff --git a/app/lib/rules/global_rules.ts b/app/lib/rules/global_rules.ts index dbd0b858a05c2699b29edd8ac3cc83466e97234e..417b91c35da81ecf4609417c6a31a69e89f2bb3f 100644 --- a/app/lib/rules/global_rules.ts +++ b/app/lib/rules/global_rules.ts @@ -25,8 +25,6 @@ import {Indexer} from "../indexer" import {DBTx} from "../db/DBTx" import {Tristamp} from "../common/Tristamp" -const _ = require('underscore') - const constants = CommonConstants // Empty logger by default diff --git a/app/lib/rules/local_rules.ts b/app/lib/rules/local_rules.ts index d0d819cf7d148053c42b19af436ce777b5580619..2522a45fb361d3373dc240a74bf6079fa66996f3 100644 --- a/app/lib/rules/local_rules.ts +++ b/app/lib/rules/local_rules.ts @@ -11,7 +11,6 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; import {BlockDTO} from "../dto/BlockDTO" import {ConfDTO} from "../dto/ConfDTO" import {CindexEntry, IndexEntry, Indexer, MindexEntry, SindexEntry} from "../indexer" @@ -22,8 +21,7 @@ import {hashf} from "../common" import {CommonConstants} from "../common-libs/constants" import {IdentityDTO} from "../dto/IdentityDTO" import {MembershipDTO} from "../dto/MembershipDTO" - -const _ = require('underscore'); +import {Underscore} from "../common-libs/underscore" const constants = CommonConstants const maxAcceleration = require('./helpers').maxAcceleration @@ -120,7 +118,7 @@ export const LOCAL_RULES_FUNCTIONS = { checkIdentitiesUserIDConflict: async (block:BlockDTO, conf:ConfDTO, index:IndexEntry[]) => { const creates = Indexer.iindexCreate(index); - const uids = _.chain(creates).pluck('uid').uniq().value(); + const uids = Underscore.chain(creates).pluck('uid').uniq().value(); if (creates.length !== uids.length) { throw Error('Block must not contain twice same identity uid'); } @@ -129,7 +127,7 @@ export const LOCAL_RULES_FUNCTIONS = { checkIdentitiesPubkeyConflict: async (block:BlockDTO, conf:ConfDTO, index:IndexEntry[]) => { const creates = Indexer.iindexCreate(index); - const pubkeys = _.chain(creates).pluck('pub').uniq().value(); + const pubkeys = Underscore.chain(creates).pluck('pub').uniq().value(); if (creates.length !== pubkeys.length) { throw Error('Block must not contain twice same identity pubkey'); } @@ -140,7 +138,7 @@ export const LOCAL_RULES_FUNCTIONS = { const icreates = Indexer.iindexCreate(index); const mcreates = Indexer.mindexCreate(index); for (const icreate of icreates) { - const matching = _(mcreates).filter({ pub: icreate.pub }); + const matching = Underscore.where(mcreates, { pub: icreate.pub }); if (matching.length == 0) { throw Error('Each identity must match a newcomer line with same userid and certts'); } @@ -151,12 +149,11 @@ export const LOCAL_RULES_FUNCTIONS = { checkRevokedAreExcluded: async (block:BlockDTO, conf:ConfDTO, index:IndexEntry[]) => { const iindex = Indexer.iindex(index); const mindex = Indexer.mindex(index); - const revocations = _.chain(mindex) - .filter((row:MindexEntry) => row.op == constants.IDX_UPDATE && row.revoked_on !== null) - .pluck('pub') - .value(); + const revocations = mindex + .filter((row:MindexEntry) => !!(row.op == constants.IDX_UPDATE && row.revoked_on !== null)) + .map(e => e.pub) for (const pub of revocations) { - const exclusions = _(iindex).where({ op: constants.IDX_UPDATE, member: false, pub }); + const exclusions = Underscore.where(iindex, { op: constants.IDX_UPDATE, member: false, pub }) if (exclusions.length == 0) { throw Error('A revoked member must be excluded'); } @@ -175,7 +172,7 @@ export const LOCAL_RULES_FUNCTIONS = { checkMembershipUnicity: async (block:BlockDTO, conf:ConfDTO, index:IndexEntry[]) => { const mindex = Indexer.mindex(index); - const pubkeys = _.chain(mindex).pluck('pub').uniq().value(); + const pubkeys = Underscore.chain(mindex).pluck('pub').uniq().value(); if (pubkeys.length !== mindex.length) { throw Error('Unicity constraint PUBLIC_KEY on MINDEX is not respected'); } @@ -256,7 +253,7 @@ export const LOCAL_RULES_FUNCTIONS = { checkCertificationOneByIssuer: async (block:BlockDTO, conf:ConfDTO, index:IndexEntry[]) => { if (block.number > 0) { const cindex = Indexer.cindex(index); - const certFromA = _.uniq(cindex.map((row:CindexEntry) => row.issuer)); + const certFromA = Underscore.uniq(cindex.map((row:CindexEntry) => row.issuer)); if (certFromA.length !== cindex.length) { throw Error('Block cannot contain two certifications from same issuer'); } @@ -266,7 +263,7 @@ export const LOCAL_RULES_FUNCTIONS = { checkCertificationUnicity: async (block:BlockDTO, conf:ConfDTO, index:IndexEntry[]) => { const cindex = Indexer.cindex(index); - const certAtoB = _.uniq(cindex.map((row:CindexEntry) => row.issuer + row.receiver)); + const certAtoB = Underscore.uniq(cindex.map((row:CindexEntry) => row.issuer + row.receiver)); if (certAtoB.length !== cindex.length) { throw Error('Block cannot contain identical certifications (A -> B)'); } @@ -279,8 +276,8 @@ export const LOCAL_RULES_FUNCTIONS = { const mindex = Indexer.mindex(index); const certified = cindex.map((row:CindexEntry) => row.receiver); for (const pub of certified) { - const exclusions = _(iindex).where({ op: constants.IDX_UPDATE, member: false, pub: pub }); - const leavers = _(mindex).where({ op: constants.IDX_UPDATE, leaving: true, pub: pub }); + const exclusions = Underscore.where(iindex, { op: constants.IDX_UPDATE, member: false, pub: pub }) + const leavers = Underscore.where(mindex, { op: constants.IDX_UPDATE, leaving: true, pub: pub }) if (exclusions.length > 0 || leavers.length > 0) { throw Error('Block cannot contain certifications concerning leavers or excluded members'); } @@ -347,12 +344,12 @@ export const LOCAL_RULES_FUNCTIONS = { } } const sindex = Indexer.localSIndex(dto); - const inputs = _.filter(sindex, (row:SindexEntry) => row.op == constants.IDX_UPDATE).map((row:SindexEntry) => [row.op, row.identifier, row.pos].join('-')); - if (inputs.length !== _.uniq(inputs).length) { + const inputs = Underscore.filter(sindex, (row:SindexEntry) => row.op == constants.IDX_UPDATE).map((row:SindexEntry) => [row.op, row.identifier, row.pos].join('-')); + if (inputs.length !== Underscore.uniq(inputs).length) { throw Error('It cannot exist 2 identical sources for transactions inside a given block'); } - const outputs = _.filter(sindex, (row:SindexEntry) => row.op == constants.IDX_CREATE).map((row:SindexEntry) => [row.op, row.identifier, row.pos].join('-')); - if (outputs.length !== _.uniq(outputs).length) { + const outputs = Underscore.filter(sindex, (row:SindexEntry) => row.op == constants.IDX_CREATE).map((row:SindexEntry) => [row.op, row.identifier, row.pos].join('-')); + if (outputs.length !== Underscore.uniq(outputs).length) { throw Error('It cannot exist 2 identical sources for transactions inside a given block'); } return true; @@ -414,7 +411,7 @@ export interface SindexShortEntry { } function getMaxTransactionDepth(sindex:SindexShortEntry[]) { - const ids = _.uniq(_.pluck(sindex, 'tx')) + const ids = Underscore.uniq(Underscore.pluck(sindex, 'tx')) as string[] // We are sure because at this moment no UD is in the sources let maxTxChainingDepth = 0 for (let id of ids) { maxTxChainingDepth = Math.max(maxTxChainingDepth, getTransactionDepth(id, sindex, 0)) @@ -423,13 +420,14 @@ function getMaxTransactionDepth(sindex:SindexShortEntry[]) { } function getTransactionDepth(txHash:string, sindex:SindexShortEntry[], localDepth = 0) { - const inputs = _.filter(sindex, (s:SindexShortEntry) => s.op === 'UPDATE' && s.tx === txHash) + const inputs = Underscore.filter(sindex, (s:SindexShortEntry) => s.op === 'UPDATE' && s.tx === txHash) let depth = localDepth for (let input of inputs) { - const consumedOutput = _.findWhere(sindex, { op: 'CREATE', identifier: input.identifier, pos: input.pos }) + const consumedOutput = Underscore.findWhere(sindex, { op: 'CREATE', identifier: input.identifier, pos: input.pos }) if (consumedOutput) { if (localDepth < 5) { - const subTxDepth = getTransactionDepth(consumedOutput.tx, sindex, localDepth + 1) + // Cast: we are sure because at this moment no UD is in the sources + const subTxDepth = getTransactionDepth(consumedOutput.tx as string, sindex, localDepth + 1) depth = Math.max(depth, subTxDepth) } else { depth++ diff --git a/app/lib/streams/multicaster.ts b/app/lib/streams/multicaster.ts index 43d2a3b0621611c38de47941a7723ff4f19b54ea..cf2cdbf3fc9eb7b2c2e13cd108c14b64c2e03290 100644 --- a/app/lib/streams/multicaster.ts +++ b/app/lib/streams/multicaster.ts @@ -13,7 +13,6 @@ import {ConfDTO} from "../dto/ConfDTO" import * as stream from "stream" -import {DBPeer} from "../dal/sqliteDAL/PeerDAL" import {BlockDTO} from "../dto/BlockDTO" import {RevocationDTO} from "../dto/RevocationDTO" import {IdentityDTO} from "../dto/IdentityDTO" @@ -22,6 +21,7 @@ import {MembershipDTO} from "../dto/MembershipDTO" import {TransactionDTO} from "../dto/TransactionDTO" import {PeerDTO} from "../dto/PeerDTO" import {CommonConstants} from "../common-libs/constants" +import {DBPeer} from "../db/DBPeer" const request = require('request'); const constants = require('../../lib/constants'); diff --git a/app/lib/streams/router.ts b/app/lib/streams/router.ts index 30953a8689928e2ee715e58ce9a5140fb014d078..d5a88d46b883d934588cf2a138466ff11c488df6 100644 --- a/app/lib/streams/router.ts +++ b/app/lib/streams/router.ts @@ -14,8 +14,8 @@ import * as stream from "stream" import {PeeringService} from "../../service/PeeringService" import {FileDAL} from "../dal/fileDAL" -import {DBPeer} from "../dal/sqliteDAL/PeerDAL" import {PeerDTO} from "../dto/PeerDTO" +import {DBPeer} from "../db/DBPeer" const constants = require('../constants'); diff --git a/app/modules/bma/index.ts b/app/modules/bma/index.ts index 462ee2c857bfbb0c2f7097931e341b99f1ac23f1..7bfd78702290cfb9590907750ebe22282a3b9420 100644 --- a/app/modules/bma/index.ts +++ b/app/modules/bma/index.ts @@ -11,25 +11,21 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; import {NetworkConfDTO} from "../../lib/dto/ConfDTO" import {Server} from "../../../server" import * as stream from "stream" -import {BmaApi, Network} from "./lib/network" -import {UpnpApi} from "./lib/upnp" +import {BmaApi, Network, NetworkInterface} from "./lib/network" +import {Upnp, UpnpApi} from "./lib/upnp" import {BMAConstants} from "./lib/constants" import {BMALimitation} from "./lib/limiter" import {PeerDTO} from "../../lib/dto/PeerDTO" +import {Underscore} from "../../lib/common-libs/underscore" +import {bma} from "./lib/bma" const Q = require('q'); -const os = require('os'); const rp = require('request-promise'); const async = require('async'); -const _ = require('underscore'); -const upnp = require('./lib/upnp').Upnp -const bma = require('./lib/bma').bma const dtos = require('./lib/dtos') -const http2raw = require('./lib/http2raw'); const inquirer = require('inquirer'); let networkWizardDone = false; @@ -173,7 +169,7 @@ export const BmaDependency = { if (!conf.ipv6) delete conf.ipv6; if (!conf.remoteipv4) delete conf.remoteipv4; if (!conf.remoteipv6) delete conf.remoteipv6; - conf.dos.whitelist = _.uniq(conf.dos.whitelist); + conf.dos.whitelist = Underscore.uniq(conf.dos.whitelist); } }, @@ -189,7 +185,8 @@ export const BmaDependency = { methods: { noLimit: () => BMALimitation.noLimit(), - bma, dtos, + bma: async (server: Server, interfaces: (NetworkInterface[] | null) = null, httpLogs = false, logger?: any) => bma(server, interfaces, httpLogs, logger), + dtos, getMainEndpoint: (conf:NetworkConfDTO) => Promise.resolve(getEndpoint(conf)) } } @@ -243,7 +240,7 @@ export class BMAPI extends stream.Transform { } if (this.server.conf.upnp) { try { - this.upnpAPI = await upnp(this.server.conf.port, this.server.conf.remoteport, this.logger, this.server.conf); + this.upnpAPI = await Upnp(this.server.conf.port, this.server.conf.remoteport, this.logger, this.server.conf); this.upnpAPI.startRegular(); const gateway = await this.upnpAPI.findGateway(); if (gateway) { @@ -306,7 +303,7 @@ function networkReconfiguration(conf:NetworkConfDTO, autoconf:boolean, logger:an const useUPnPOperations = getUseUPnPOperations(conf, logger, autoconf); if (upnpSuccess) { - _.extend(conf, upnpConf); + Underscore.extend(conf, upnpConf) const local = [conf.ipv4, conf.port].join(':'); const remote = [conf.remoteipv4, conf.remoteport].join(':'); if (autoconf) { @@ -408,7 +405,7 @@ function getLocalNetworkOperations(conf:NetworkConfDTO, autoconf:boolean = false const interfaces = [{ name: "None", value: null }]; osInterfaces.forEach(function(netInterface:any){ const addresses = netInterface.addresses; - const filtered = _(addresses).where({family: 'IPv4'}); + const filtered = Underscore.where(addresses, {family: 'IPv4'}); filtered.forEach(function(addr:any){ interfaces.push({ name: [netInterface.name, addr.address].join(' '), @@ -436,7 +433,7 @@ function getLocalNetworkOperations(conf:NetworkConfDTO, autoconf:boolean = false const interfaces:any = [{ name: "None", value: null }]; osInterfaces.forEach(function(netInterface:any){ const addresses = netInterface.addresses; - const filtered = _(addresses).where({ family: 'IPv6' }); + const filtered = Underscore.where(addresses, { family: 'IPv6' }); filtered.forEach(function(addr:any){ let address = addr.address if (addr.scopeid) @@ -495,7 +492,7 @@ function getRemoteNetworkOperations(conf:NetworkConfDTO, remoteipv4:string|null) const osInterfaces = Network.listInterfaces(); osInterfaces.forEach(function(netInterface:any){ const addresses = netInterface.addresses; - const filtered = _(addresses).where({family: 'IPv4'}); + const filtered = Underscore.where(addresses, {family: 'IPv4'}); filtered.forEach(function(addr:any){ choices.push({ name: [netInterface.name, addr.address].join(' '), diff --git a/app/modules/bma/lib/bma.ts b/app/modules/bma/lib/bma.ts index 183125820a98dcc8ed1773bafed2a2273ae0f288..d821c2e2b72ebb456c73aa42831bc14a7a491b3d 100644 --- a/app/modules/bma/lib/bma.ts +++ b/app/modules/bma/lib/bma.ts @@ -29,7 +29,7 @@ const co = require('co'); const es = require('event-stream'); const WebSocketServer = require('ws').Server; -export const bma = function(server:Server, interfaces:NetworkInterface[], httpLogs:boolean, logger:any): Promise<BmaApi> { +export const bma = function(server:Server, interfaces:NetworkInterface[]|null, httpLogs:boolean, logger:any): Promise<BmaApi> { if (!interfaces) { interfaces = []; diff --git a/app/modules/bma/lib/controllers/blockchain.ts b/app/modules/bma/lib/controllers/blockchain.ts index b035728878b9ae53bd7b1b452ebb7b936cf0f2dd..2fc5fa748dce9a9c453a532cec79b083c30dbf88 100644 --- a/app/modules/bma/lib/controllers/blockchain.ts +++ b/app/modules/bma/lib/controllers/blockchain.ts @@ -11,7 +11,6 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; import {Server} from "../../../../../server" import {AbstractController} from "./AbstractController" import {ParametersService} from "../parameters" @@ -30,8 +29,8 @@ import { } from "../dtos" import {TransactionDTO} from "../../../../lib/dto/TransactionDTO" import {DataErrors} from "../../../../lib/common-libs/errors" +import {Underscore} from "../../../../lib/common-libs/underscore" -const _ = require('underscore'); const http2raw = require('../http2raw'); const toJson = require('../tojson'); @@ -214,7 +213,7 @@ export class BlockchainBinding extends AbstractController { } return { "block": number + 1, - "levels": _.sortBy(difficulties, (diff:any) => diff.level) + "levels": Underscore.sortBy(difficulties, (diff:any) => diff.level) }; } @@ -237,7 +236,7 @@ export class BlockchainBinding extends AbstractController { }; }) } - json.memberships = _.sortBy(json.memberships, 'blockNumber'); + json.memberships = Underscore.sortBy(json.memberships, 'blockNumber') json.memberships.reverse(); return json; } diff --git a/app/modules/bma/lib/controllers/network.ts b/app/modules/bma/lib/controllers/network.ts index 6072103feba92f98cc35fdbe01e59acf590136ba..61bfc34dcfc4f2a1476c20a3f0d170d041ca309e 100644 --- a/app/modules/bma/lib/controllers/network.ts +++ b/app/modules/bma/lib/controllers/network.ts @@ -15,8 +15,8 @@ import {AbstractController} from "./AbstractController" import {BMAConstants} from "../constants" import {HttpMerkleOfPeers, HttpPeer, HttpPeers, HttpWS2PHeads, HttpWS2PInfo} from "../dtos" import {WS2PHead} from "../../../ws2p/lib/WS2PCluster" +import {DBPeer} from "../../../../lib/db/DBPeer" -const _ = require('underscore'); const http2raw = require('../http2raw'); export class NetworkBinding extends AbstractController { @@ -64,19 +64,8 @@ export class NetworkBinding extends AbstractController { async peers(): Promise<HttpPeers> { let peers = await this.server.dal.listAllPeers(); return { - peers: peers.map((p:any) => { - return _.pick(p, - 'version', - 'currency', - 'status', - 'first_down', - 'last_try', - 'pubkey', - 'block', - 'signature', - 'endpoints'); - }) - }; + peers: peers.map(p => DBPeer.json(p)) + } } async ws2pInfo(): Promise<HttpWS2PInfo> { diff --git a/app/modules/bma/lib/controllers/transactions.ts b/app/modules/bma/lib/controllers/transactions.ts index 7676feaa8e1bde90c2796419cfb44046e864ee52..e921f4d88f4f0a1969903445f8eb5c3d90067465 100644 --- a/app/modules/bma/lib/controllers/transactions.ts +++ b/app/modules/bma/lib/controllers/transactions.ts @@ -18,8 +18,8 @@ import {BMAConstants} from "../constants"; import {TransactionDTO} from "../../../../lib/dto/TransactionDTO"; import {HttpSources, HttpTransaction, HttpTxHistory, HttpTxOfHistory, HttpTxPending} from "../dtos"; import {DBTx} from "../../../../lib/db/DBTx" +import {Underscore} from "../../../../lib/common-libs/underscore" -const _ = require('underscore'); const http2raw = require('../http2raw'); export class TransactionBinding extends AbstractController { @@ -96,9 +96,9 @@ export class TransactionBinding extends AbstractController { const to = await ParametersService.getToP(req); return this.getFilteredHistory(pubkey, (res:any) => { const histo = res.history; - histo.sent = _.filter(histo.sent, function(tx:any){ return tx && tx.block_number >= from && tx.block_number <= to; }); - histo.received = _.filter(histo.received, function(tx:any){ return tx && tx.block_number >= from && tx.block_number <= to; }); - _.extend(histo, { sending: [], receiving: [] }); + histo.sent = Underscore.filter(histo.sent, function(tx:any){ return tx && tx.block_number >= from && tx.block_number <= to; }); + histo.received = Underscore.filter(histo.received, function(tx:any){ return tx && tx.block_number >= from && tx.block_number <= to; }); + Underscore.extend(histo, { sending: [], receiving: [] }); return res; }); } @@ -109,9 +109,9 @@ export class TransactionBinding extends AbstractController { const to = await ParametersService.getToP(req); return this.getFilteredHistory(pubkey, (res:any) => { const histo = res.history; - histo.sent = _.filter(histo.sent, function(tx:any){ return tx && tx.time >= from && tx.time <= to; }); - histo.received = _.filter(histo.received, function(tx:any){ return tx && tx.time >= from && tx.time <= to; }); - _.extend(histo, { sending: [], receiving: [] }); + histo.sent = Underscore.filter(histo.sent, function(tx:any){ return tx && tx.time >= from && tx.time <= to; }); + histo.received = Underscore.filter(histo.received, function(tx:any){ return tx && tx.time >= from && tx.time <= to; }); + Underscore.extend(histo, { sending: [], receiving: [] }); return res; }); } @@ -120,7 +120,7 @@ export class TransactionBinding extends AbstractController { const pubkey = await ParametersService.getPubkeyP(req); return this.getFilteredHistory(pubkey, function(res:any) { const histo = res.history; - _.extend(histo, { sent: [], received: [] }); + Underscore.extend(histo, { sent: [], received: [] }); return res; }); } diff --git a/app/modules/bma/lib/controllers/uds.ts b/app/modules/bma/lib/controllers/uds.ts index 14b5f6f29c72c7b0bbd16c0ac8f61cd79a9db377..f2378438797664ce5f6d1c547503f5f66ef9dfd6 100644 --- a/app/modules/bma/lib/controllers/uds.ts +++ b/app/modules/bma/lib/controllers/uds.ts @@ -15,8 +15,7 @@ import {AbstractController} from "./AbstractController" import {ParametersService} from "../parameters" import {Source} from "../entity/source" import {HttpUDHistory} from "../dtos"; - -const _ = require('underscore'); +import {Underscore} from "../../../../lib/common-libs/underscore" export class UDBinding extends AbstractController { @@ -30,7 +29,7 @@ export class UDBinding extends AbstractController { const from = await ParametersService.getFromP(req); const to = await ParametersService.getToP(req); return this.getUDSources(pubkey, (results:any) => { - results.history.history = _.filter(results.history.history, function(ud:any){ return ud.block_number >= from && ud.block_number <= to; }); + results.history.history = Underscore.filter(results.history.history, function(ud:any){ return ud.block_number >= from && ud.block_number <= to; }); return results; }) } @@ -40,7 +39,7 @@ export class UDBinding extends AbstractController { const from = await ParametersService.getFromP(req); const to = await ParametersService.getToP(req); return this.getUDSources(pubkey, (results:any) => { - results.history.history = _.filter(results.history.history, function(ud:any){ return ud.time >= from && ud.time <= to; }); + results.history.history = Underscore.filter(results.history.history, function(ud:any){ return ud.time >= from && ud.time <= to; }); return results; }); } @@ -52,10 +51,10 @@ export class UDBinding extends AbstractController { "pubkey": pubkey, "history": history }; - _.keys(history).map((key:any) => { + Underscore.keys(history).map((key:any) => { history[key].map((src:any, index:number) => { - history[key][index] = _.omit(new Source(src).UDjson(), 'currency', 'raw'); - _.extend(history[key][index], { block_number: src && src.block_number, time: src && src.time }); + history[key][index] = new Source(src).UDjson() + Underscore.extend(history[key][index], { block_number: src && src.block_number, time: src && src.time }); }); }); return filter(result); diff --git a/app/modules/bma/lib/controllers/wot.ts b/app/modules/bma/lib/controllers/wot.ts index a19f44364f93791edf0d7fa692be316d63ec6aec..6a5e8bb23b2d1eea8ad43c1e918f15ec4dcc18b6 100644 --- a/app/modules/bma/lib/controllers/wot.ts +++ b/app/modules/bma/lib/controllers/wot.ts @@ -32,8 +32,9 @@ import { import {IdentityDTO} from "../../../../lib/dto/IdentityDTO" import {FullIindexEntry} from "../../../../lib/indexer" import {DBMembership} from "../../../../lib/dal/sqliteDAL/MembershipDAL" +import {Underscore} from "../../../../lib/common-libs/underscore" +import {Map} from "../../../../lib/common-libs/crypto/map" -const _ = require('underscore'); const http2raw = require('../http2raw'); const constants = require('../../../../lib/constants'); @@ -45,7 +46,7 @@ export class WOTBinding extends AbstractController { // Get the search parameter from HTTP query const search = await ParametersService.getSearchP(req); // Make the research - const identities:any[] = await this.IdentityService.searchIdentities(search); + const identities = await this.IdentityService.searchIdentities(search); // Entitify each result identities.forEach((idty, index) => identities[index] = DBIdentity.copyFromExisting(idty)); // Prepare some data to avoid displaying expired certifications @@ -60,17 +61,17 @@ export class WOTBinding extends AbstractController { cert.wasMember = member.wasMember; } else { const potentials = await this.IdentityService.getPendingFromPubkey(cert.from); - cert.uids = _(potentials).pluck('uid'); + cert.uids = potentials.map(p => p.uid) cert.isMember = false; cert.wasMember = false; } validCerts.push(cert); } idty.certs = validCerts; - const signed = await this.server.dal.certsFrom(idty.pubkey); + const signed:any = await this.server.dal.certsFrom(idty.pubkey); const validSigned = []; for (let j = 0; j < signed.length; j++) { - const cert = _.clone(signed[j]); + const cert = Underscore.clone(signed[j]); cert.idty = await this.server.dal.getGlobalIdentityByHashForLookup(cert.target) if (cert.idty) { validSigned.push(cert); @@ -83,7 +84,7 @@ export class WOTBinding extends AbstractController { if (identities.length == 0) { throw BMAConstants.ERRORS.NO_MATCHING_IDENTITY; } - const resultsByPubkey:{[k:string]:HttpIdentity} = {}; + const resultsByPubkey:Map<HttpIdentity> = {}; identities.forEach((identity) => { const copy = DBIdentity.copyFromExisting(identity) const jsoned = copy.json(); @@ -100,7 +101,7 @@ export class WOTBinding extends AbstractController { }); return { partial: false, - results: _.values(resultsByPubkey) + results: Underscore.values(resultsByPubkey) }; } @@ -290,7 +291,7 @@ export class WOTBinding extends AbstractController { }; }) }; - json.memberships = _.sortBy(json.memberships, 'blockNumber'); + json.memberships = Underscore.sortBy(json.memberships, 'blockNumber'); json.memberships.reverse(); return json; } diff --git a/app/modules/bma/lib/dtos.ts b/app/modules/bma/lib/dtos.ts index 533600a6a350f2e85aa6575a8cac4bac6508e006..d0b7f27d19e7f89c896a36799fc440b2013712cf 100644 --- a/app/modules/bma/lib/dtos.ts +++ b/app/modules/bma/lib/dtos.ts @@ -12,8 +12,8 @@ // GNU Affero General Public License for more details. import {BlockDTO} from "../../../lib/dto/BlockDTO" -import {DBPeer as DBPeer2} from "../../../lib/dal/sqliteDAL/PeerDAL" import {WS2PHead} from "../../ws2p/lib/WS2PCluster" +import {JSONDBPeer} from "../../../lib/db/DBPeer" export const Summary = { duniter: { @@ -400,7 +400,7 @@ export const Peers = { }; export interface HttpPeers { - peers: DBPeer2[] + peers: JSONDBPeer[] } export interface HttpWS2PInfo { @@ -434,7 +434,7 @@ export interface HttpMerkleOfPeers { leaves: string[] leaf: { hash: string - value: DBPeer2 + value: JSONDBPeer } } diff --git a/app/modules/bma/lib/entity/source.ts b/app/modules/bma/lib/entity/source.ts index 2543a55206ffc462e0c6c9e3827b7e738df34070..15e678aacb9569b4d1ed78da3cb97efc3f6ee4c9 100644 --- a/app/modules/bma/lib/entity/source.ts +++ b/app/modules/bma/lib/entity/source.ts @@ -11,15 +11,14 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; -const _ = require('underscore'); +import {Underscore} from "../../../../lib/common-libs/underscore" export class Source { [k:string]: any constructor(json:any) { - _(json || {}).keys().forEach((key:string) => { + Underscore.keys(json || {}).forEach((key:string) => { let value = json[key]; if (key == "number") { value = parseInt(value); diff --git a/app/modules/bma/lib/network.ts b/app/modules/bma/lib/network.ts index 831dd61ddcc28714768dfcf6fad8f67db4d3bf33..c75d8d79451a7db6dbc1ca7cccd24861c338a673 100644 --- a/app/modules/bma/lib/network.ts +++ b/app/modules/bma/lib/network.ts @@ -11,15 +11,14 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; import {NetworkConfDTO} from "../../../lib/dto/ConfDTO" import {Server} from "../../../../server" import {BMAConstants} from "./constants" import {BMALimitation} from "./limiter" +import {Underscore} from "../../../lib/common-libs/underscore" const os = require('os'); const Q = require('q'); -const _ = require('underscore'); const ddos = require('ddos'); const http = require('http'); const express = require('express'); @@ -67,7 +66,7 @@ export const Network = { } const ddosConf = server.conf.dos || {}; ddosConf.silentStart = true - ddosConf.whitelist = _.uniq((ddosConf.whitelist || []).concat(whitelist)); + ddosConf.whitelist = Underscore.uniq((ddosConf.whitelist || []).concat(whitelist)); const ddosInstance = new ddos(ddosConf); app.use(ddosInstance.express); @@ -162,7 +161,7 @@ export const Network = { return { http: httpServer, closeSockets: () => { - _.keys(sockets).map((socketId:number) => { + Underscore.keys(sockets).map((socketId:string) => { sockets[socketId].destroy(); }); } @@ -284,8 +283,8 @@ function getBestLocalIPv6() { const osInterfaces = listInterfaces(); for (let netInterface of osInterfaces) { const addresses = netInterface.addresses; - const filtered = _(addresses).where({family: 'IPv6', scopeid: 0, internal: false }); - const filtered2 = _.filter(filtered, (address:any) => !address.address.match(/^fe80/) && !address.address.match(/^::1/)); + const filtered = Underscore.where(addresses, {family: 'IPv6', scopeid: 0, internal: false }) + const filtered2 = Underscore.filter(filtered, (address:any) => !address.address.match(/^fe80/) && !address.address.match(/^::1/)); if (filtered2[0]) { return filtered2[0].address; } @@ -295,7 +294,7 @@ function getBestLocalIPv6() { function getBestLocal(family:string) { let netInterfaces = os.networkInterfaces(); - let keys = _.keys(netInterfaces); + let keys = Underscore.keys(netInterfaces); let res = []; for (const name of keys) { let addresses = netInterfaces[name]; @@ -321,7 +320,7 @@ function getBestLocal(family:string) { /^Loopback/, /^None/ ]; - const best = _.sortBy(res, function(entry:any) { + const best = Underscore.sortBy(res, function(entry:any) { for (let i = 0; i < interfacePriorityRegCatcher.length; i++) { // `i` is the priority (0 is the better, 1 is the second, ...) if (entry.name.match(interfacePriorityRegCatcher[i])) return i; @@ -333,7 +332,7 @@ function getBestLocal(family:string) { function listInterfaces() { const netInterfaces = os.networkInterfaces(); - const keys = _.keys(netInterfaces); + const keys = Underscore.keys(netInterfaces); const res = []; for (const name of keys) { res.push({ diff --git a/app/modules/bma/lib/sanitize.ts b/app/modules/bma/lib/sanitize.ts index d2a5ce5e70c74d43b881e7911342631587101271..0a2716741e5d207690ed214b07bd9019fd552553 100644 --- a/app/modules/bma/lib/sanitize.ts +++ b/app/modules/bma/lib/sanitize.ts @@ -11,9 +11,7 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; - -let _ = require('underscore'); +import {Underscore} from "../../../lib/common-libs/underscore" module.exports = function sanitize (json:any, contract:any) { @@ -44,9 +42,9 @@ module.exports = function sanitize (json:any, contract:any) { } } - let contractFields = _(contract).keys(); - let objectFields = _(json).keys(); - let toDeleteFromObj = _.difference(objectFields, contractFields); + let contractFields = Underscore.keys(contract) + let objectFields = Underscore.keys(json) + let toDeleteFromObj = Underscore.difference(objectFields, contractFields) // Remove unwanted fields for (let i = 0, len = toDeleteFromObj.length; i < len; i++) { @@ -74,7 +72,7 @@ module.exports = function sanitize (json:any, contract:any) { } } // Check coherence & alter member if needed - if (!_(json[prop]).isNull() && t.toLowerCase() != tjson.toLowerCase()) { + if (json[prop] !== null && t.toLowerCase() != tjson.toLowerCase()) { try { if (t == "String") { let s = json[prop] == undefined ? '' : json[prop]; diff --git a/app/modules/bma/lib/tojson.ts b/app/modules/bma/lib/tojson.ts index d9528205e898778fde147cf89b8d41ae59731037..75441e665c188820fe2980aa4829718494b35158 100644 --- a/app/modules/bma/lib/tojson.ts +++ b/app/modules/bma/lib/tojson.ts @@ -11,10 +11,8 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; import {BlockDTO} from "../../../lib/dto/BlockDTO" - -const _ = require('underscore') +import {Underscore} from "../../../lib/common-libs/underscore" export const stat = (stat:any) => { return { "blocks": stat.blocks } @@ -52,7 +50,7 @@ export const block = (block:any) => { json.certifications = (block.certifications || []) json.transactions = []; block.transactions.forEach((obj:any) => { - json.transactions.push(_(obj).omit('raw', 'certifiers', 'hash')); + json.transactions.push(Underscore.omit(obj, 'raw', 'certifiers', 'hash')) }); json.transactions = block.transactions.map((tx:any) => { tx.inputs = tx.inputs.map((i:any) => i.raw || i) diff --git a/app/modules/config.ts b/app/modules/config.ts index 88556edb73898cc0a7ff3de74ee75f94dca312c3..0442cb20a68a968f896705e89cd4957b2de1fed7 100644 --- a/app/modules/config.ts +++ b/app/modules/config.ts @@ -16,8 +16,7 @@ import {ConfDTO} from "../lib/dto/ConfDTO" import {Server} from "../../server" import {CommonConstants} from "../lib/common-libs/constants" import {Directory} from "../lib/system/directory" - -const _ = require('underscore') +import {Underscore} from "../lib/common-libs/underscore" module.exports = { duniter: { @@ -45,7 +44,7 @@ module.exports = { onConfiguredExecute: async (server:Server, conf:ConfDTO) => { const fs = await Directory.getHomeFS(false, Directory.INSTANCE_HOME, false) const lines = (await fs.fs.fsReadFile(Directory.INSTANCE_HOMELOG_FILE)).split('\n') - const aggregates = _.uniq( + const aggregates = Underscore.uniq( lines .map(l => l.match(/: (\[\w+\](\[\w+\])*)/)) .filter(l => l) diff --git a/app/modules/crawler/index.ts b/app/modules/crawler/index.ts index ddf6fc1fe79a43f8ddb624ea2ed107a561308cef..c27aa53a17adb43bff0187a5d0b4514e19e91707 100644 --- a/app/modules/crawler/index.ts +++ b/app/modules/crawler/index.ts @@ -33,7 +33,7 @@ export const CrawlerDependency = { methods: { - contacter: (host:string, port:number, opts:any) => new Contacter(host, port, opts), + contacter: (host:string, port:number, opts?:any) => new Contacter(host, port, opts), pullBlocks: async (server:Server, pubkey:string) => { const crawler = new Crawler(server, server.conf, server.logger); diff --git a/app/modules/crawler/lib/contacter.ts b/app/modules/crawler/lib/contacter.ts index c2e93c4e33f568f5147afa128f851723706e46ff..7789fc0f6c0da8f65c7dd2d713f0c2430ffc085e 100644 --- a/app/modules/crawler/lib/contacter.ts +++ b/app/modules/crawler/lib/contacter.ts @@ -62,7 +62,7 @@ export class Contacter { return this.get('/network/peering', dtos.Peer) } - getPeers(obj:any) { + getPeers(obj?:any) { return this.get('/network/peering/peers', dtos.MerkleOfPeers, obj) } diff --git a/app/modules/crawler/lib/crawler.ts b/app/modules/crawler/lib/crawler.ts index 0efe1174b3a1a502da992866e8f7ee6a95283c60..de7c52db73cea671af76354005781057b0616b6c 100644 --- a/app/modules/crawler/lib/crawler.ts +++ b/app/modules/crawler/lib/crawler.ts @@ -24,10 +24,9 @@ import {connect} from "./connect" import {CrawlerConstants} from "./constants" import {pullSandboxToLocalServer} from "./sandbox" import {cleanLongDownPeers} from "./garbager" +import {Underscore} from "../../../lib/common-libs/underscore" -const _ = require('underscore'); const async = require('async'); -const querablep = require('querablep'); /** * Service which triggers the server's peering generation (actualization of the Peer document). @@ -119,7 +118,7 @@ export class PeerCrawler implements DuniterService { if (peers.length > CrawlerConstants.COUNT_FOR_ENOUGH_PEERS && dontCrawlIfEnoughPeers == this.DONT_IF_MORE_THAN_FOUR_PEERS) { return; } - let peersToTest = peers.slice().map((p:PeerDTO) => PeerDTO.fromJSONObject(p)); + let peersToTest = peers.slice().map(p => PeerDTO.fromJSONObject(p)) let tested:string[] = []; const found = []; while (peersToTest.length > 0) { @@ -144,7 +143,7 @@ export class PeerCrawler implements DuniterService { } } // Make unique list - peersToTest = _.uniq(peersToTest, false, (p:PeerDTO) => p.pubkey); + peersToTest = Underscore.uniq(peersToTest, false, (p:PeerDTO) => p.pubkey) } this.logger.info('Crawling done.'); for (let i = 0, len = found.length; i < len; i++) { @@ -205,7 +204,7 @@ export class SandboxCrawler implements DuniterService { async sandboxPull(server:Server) { this.logger && this.logger.info('Sandbox pulling started...'); const peers = await server.dal.getRandomlyUPsWithout([this.conf.pair.pub]) - const randoms = chooseXin(peers, CrawlerConstants.SANDBOX_PEERS_COUNT) + const randoms = chooseXin(peers.map(p => PeerDTO.fromDBPeer(p)), CrawlerConstants.SANDBOX_PEERS_COUNT) let peersToTest = randoms.slice().map((p) => PeerDTO.fromJSONObject(p)); for (const peer of peersToTest) { const fromHost = await connect(peer) @@ -241,7 +240,7 @@ export class PeerTester implements DuniterService { private async testPeers(server:Server, conf:ConfDTO, displayDelays:boolean) { let peers = await server.dal.listAllPeers(); let now = (new Date().getTime()); - peers = _.filter(peers, (p:any) => p.pubkey != conf.pair.pub); + peers = Underscore.filter(peers, (p:any) => p.pubkey != conf.pair.pub); await Promise.all(peers.map(async (thePeer:any) => { let p = PeerDTO.fromJSONObject(thePeer); if (thePeer.status == 'DOWN') { @@ -369,17 +368,17 @@ export class BlockCrawler { this.pullingEvent(server, 'start', current.number); this.logger && this.logger.info("Pulling blocks from the network..."); let peers = await server.dal.findAllPeersNEWUPBut([server.conf.pair.pub]); - peers = _.shuffle(peers); + peers = Underscore.shuffle(peers); if (pubkey) { - _(peers).filter((p:any) => p.pubkey == pubkey); + peers = Underscore.filter(peers, (p:any) => p.pubkey == pubkey) } // Shuffle the peers - peers = _.shuffle(peers); + peers = Underscore.shuffle(peers); // Only take at max X of them peers = peers.slice(0, CrawlerConstants.MAX_NUMBER_OF_PEERS_FOR_PULLING); await Promise.all(peers.map(async (thePeer:any, i:number) => { let p = PeerDTO.fromJSONObject(thePeer); - this.pullingEvent(server, 'peer', _.extend({number: i, length: peers.length}, p)); + this.pullingEvent(server, 'peer', Underscore.extend({number: i, length: peers.length}, p)); this.logger && this.logger.trace("Try with %s %s", p.getURL(), p.pubkey.substr(0, 6)); try { let node:any = await connect(p); diff --git a/app/modules/crawler/lib/pulling.ts b/app/modules/crawler/lib/pulling.ts index 7dc23418d1ce38ee117803d74aa8971ba1f9714c..7c785d280b2c2ac671c3990c16168d52c892d3b9 100644 --- a/app/modules/crawler/lib/pulling.ts +++ b/app/modules/crawler/lib/pulling.ts @@ -15,9 +15,8 @@ import {BlockDTO} from "../../../lib/dto/BlockDTO" import {DBBlock} from "../../../lib/db/DBBlock" import {PeerDTO} from "../../../lib/dto/PeerDTO" -import {BranchingDTO, ConfDTO} from "../../../lib/dto/ConfDTO" - -const _ = require('underscore'); +import {BranchingDTO} from "../../../lib/dto/ConfDTO" +import {Underscore} from "../../../lib/common-libs/underscore" export abstract class PullingDao { abstract applyBranch(blocks:BlockDTO[]): Promise<boolean> @@ -211,7 +210,7 @@ export abstract class AbstractDAO extends PullingDao { } return result; }); - memberForks = _.filter(memberForks, (fork:any) => { + memberForks = Underscore.filter(memberForks, (fork:any) => { let blockDistanceInBlocks = (fork.current.number - localCurrent.number) let timeDistanceInBlocks = (fork.current.medianTime - localCurrent.medianTime) / conf.avgGenTime const requiredTimeAdvance = conf.switchOnHeadAdvance diff --git a/app/modules/crawler/lib/sync.ts b/app/modules/crawler/lib/sync.ts index 19dd460f6d428c089e17b6becc6036257a015817..7325a907c457eeaf8840947e181bea893582f9b5 100644 --- a/app/modules/crawler/lib/sync.ts +++ b/app/modules/crawler/lib/sync.ts @@ -30,8 +30,10 @@ import {hashf} from "../../../lib/common" import {ConfDTO} from "../../../lib/dto/ConfDTO" import {PeeringService} from "../../../service/PeeringService" import {CommonConstants} from "../../../lib/common-libs/constants" +import {Underscore} from "../../../lib/common-libs/underscore" +import {HttpMerkleOfPeers} from "../../bma/lib/dtos" +import {DBPeer, JSONDBPeer} from "../../../lib/db/DBPeer" -const _ = require('underscore'); const moment = require('moment'); const multimeter = require('multimeter'); const makeQuerablePromise = require('querablep'); @@ -161,17 +163,17 @@ export class Synchroniser extends stream.Duplex { //======= // Peers (just for P2P download) //======= - let peers:PeerDTO[] = []; + let peers:(JSONDBPeer|null)[] = []; if (!nopeers && (to - localNumber > 1000)) { // P2P download if more than 1000 blocs this.watcher.writeStatus('Peers...'); const merkle = await this.dal.merkleForPeers(); - const getPeers = node.getPeers.bind(node); + const getPeers:(params:any) => Promise<HttpMerkleOfPeers> = node.getPeers.bind(node); const json2 = await getPeers({}); const rm = new NodesMerkle(json2); if(rm.root() != merkle.root()){ const leavesToAdd:string[] = []; const json = await getPeers({ leaves: true }); - _(json.leaves).forEach((leaf:string) => { + json.leaves.forEach((leaf:string) => { if(merkle.leaves().indexOf(leaf) == -1){ leavesToAdd.push(leaf); } @@ -195,7 +197,7 @@ export class Synchroniser extends stream.Duplex { } if (!peers.length) { - peers.push(peer); + peers.push(DBPeer.fromPeerDTO(peer)) } peers = peers.filter((p) => p); @@ -206,7 +208,7 @@ export class Synchroniser extends stream.Duplex { // We use cautious mode if it is asked, or not particulary asked but blockchain has been started const cautious = (askedCautious === true || localNumber >= 0); - const shuffledPeers = noShufflePeers ? peers : _.shuffle(peers); + const shuffledPeers = (noShufflePeers ? peers : Underscore.shuffle(peers)).filter(p => !!(p)) as JSONDBPeer[] const downloader = new P2PDownloader(rCurrent.currency, localNumber, to, rCurrent.hash, shuffledPeers, this.watcher, this.logger, hashf, this.dal, this.slowOption, !cautious, this.otherDAL); downloader.start(); @@ -224,7 +226,7 @@ export class Synchroniser extends stream.Duplex { } async applyBranch(blocks:BlockDTO[]) { - blocks = _.filter(blocks, (b:BlockDTO) => b.number <= to); + blocks = Underscore.filter(blocks, (b:BlockDTO) => b.number <= to); if (cautious) { for (const block of blocks) { if (block.number == 0) { @@ -357,13 +359,13 @@ export class Synchroniser extends stream.Duplex { this.watcher.writeStatus('Peers...'); await this.syncPeer(node); const merkle = await this.dal.merkleForPeers(); - const getPeers = node.getPeers.bind(node); + const getPeers:(params:any) => Promise<HttpMerkleOfPeers> = node.getPeers.bind(node); const json2 = await getPeers({}); const rm = new NodesMerkle(json2); if(rm.root() != merkle.root()){ const leavesToAdd:string[] = []; const json = await getPeers({ leaves: true }); - _(json.leaves).forEach((leaf:string) => { + json.leaves.forEach((leaf:string) => { if(merkle.leaves().indexOf(leaf) == -1){ leavesToAdd.push(leaf); } @@ -374,9 +376,11 @@ export class Synchroniser extends stream.Duplex { const jsonEntry = json3.leaf.value; const sign = json3.leaf.value.signature; const entry:any = {}; - ["version", "currency", "pubkey", "endpoints", "block"].forEach((key) => { - entry[key] = jsonEntry[key]; - }); + entry.version = jsonEntry.version + entry.currency = jsonEntry.currency + entry.pubkey = jsonEntry.pubkey + entry.endpoints = jsonEntry.endpoints + entry.block = jsonEntry.block entry.signature = sign; this.watcher.writeStatus('Peer ' + entry.pubkey); await this.PeeringService.submitP(entry, false, to === undefined); @@ -673,7 +677,7 @@ class P2PDownloader { private localNumber:number, private to:number, private toHash:string, - private peers:PeerDTO[], + private peers:JSONDBPeer[], private watcher:Watcher, private logger:any, private hashf:any, @@ -832,7 +836,7 @@ class P2PDownloader { throw this.NO_NODES_AVAILABLE; } // We remove the nodes impossible to reach (timeout) - let withGoodDelays = _.filter(candidates, (c:any) => c.tta <= this.MAX_DELAY_PER_DOWNLOAD); + let withGoodDelays = Underscore.filter(candidates, (c:any) => c.tta <= this.MAX_DELAY_PER_DOWNLOAD); if (withGoodDelays.length === 0) { // No node can be reached, we can try to lower the number of nodes on which we download this.downloadSlots = Math.floor(this.downloadSlots / 2); @@ -842,7 +846,7 @@ class P2PDownloader { return this.getP2Pcandidates(); } const parallelMax = Math.min(this.PARALLEL_PER_CHUNK, withGoodDelays.length); - withGoodDelays = _.sortBy(withGoodDelays, (c:any) => c.tta); + withGoodDelays = Underscore.sortBy(withGoodDelays, (c:any) => c.tta); withGoodDelays = withGoodDelays.slice(0, parallelMax); // We temporarily augment the tta to avoid asking several times to the same node in parallel withGoodDelays.forEach((c:any) => c.tta = this.MAX_DELAY_PER_DOWNLOAD); @@ -876,8 +880,8 @@ class P2PDownloader { // Opening/Closing slots depending on the Interne connection if (this.slots.length == this.downloadSlots) { - const peers = await Promise.all(_.values(this.nodes)) - const downloading = _.filter(peers, (p:any) => p.downloading && p.ttas.length); + const peers = await Promise.all(Underscore.values(this.nodes)) + const downloading = Underscore.filter(peers, (p:any) => p.downloading && p.ttas.length); const currentAvgDelay = downloading.reduce((sum:number, c:any) => { const tta = Math.round(c.ttas.reduce((sum:number, tta:number) => sum + tta, 0) / c.ttas.length); return sum + tta; diff --git a/app/modules/export-bc.ts b/app/modules/export-bc.ts index 2deb97a2ad1186a798ddf5bee0d3d44629b079e1..1a0de70cbdefa1b29ac33335d5680eb11eebc1c1 100644 --- a/app/modules/export-bc.ts +++ b/app/modules/export-bc.ts @@ -11,13 +11,10 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; import {ConfDTO} from "../lib/dto/ConfDTO" import {Server} from "../../server" import {BlockDTO} from "../lib/dto/BlockDTO" -const _ = require('underscore'); - module.exports = { duniter: { cli: [{ @@ -48,7 +45,7 @@ module.exports = { for (const chunk of chunks) { let blocks = await server.dal.getBlocksBetween(chunk.start, chunk.to); blocks.forEach(function (block:any) { - jsoned.push(_(BlockDTO.fromJSONObject(block).json()).omit('raw')); + jsoned.push(BlockDTO.fromJSONObject(block).json()) }); } if (!program.nostdout) { diff --git a/app/modules/prover/index.ts b/app/modules/prover/index.ts index 71dcdc6a5555a1fec4dd221e811c38deba73b342..2cd89b4d8ec6300b0282947703bbe7f61270c723 100644 --- a/app/modules/prover/index.ts +++ b/app/modules/prover/index.ts @@ -69,7 +69,7 @@ export const ProverDependency = { server.generatorComputeNewCerts = generator.computeNewCerts.bind(generator) server.generatorNewCertsToLinks = generator.newCertsToLinks.bind(generator) }, - prover: (server:Server, conf:ConfDTO, logger:any) => new Prover(server), + prover: (server:Server) => new Prover(server), blockGenerator: (server:Server, prover:any) => new BlockGeneratorWhichProves(server, prover), generateTheNextBlock: async (server:Server, manualValues:any) => { const prover = new BlockProver(server); diff --git a/app/modules/prover/lib/blockGenerator.ts b/app/modules/prover/lib/blockGenerator.ts index 7e9d229ec2630a849be853f1c55cbdb9fba62e5c..0076a28577ed54a19b321ed55fe7b3f7cc9e478b 100644 --- a/app/modules/prover/lib/blockGenerator.ts +++ b/app/modules/prover/lib/blockGenerator.ts @@ -11,7 +11,6 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; import {Server} from "../../../../server" import {BlockchainContext} from "../../../lib/computation/BlockchainContext" import {TransactionDTO} from "../../../lib/dto/TransactionDTO" @@ -30,14 +29,16 @@ import {BlockDTO} from "../../../lib/dto/BlockDTO" import {ConfDTO} from "../../../lib/dto/ConfDTO" import {FileDAL} from "../../../lib/dal/fileDAL" import {DataErrors} from "../../../lib/common-libs/errors" +import {Underscore} from "../../../lib/common-libs/underscore" +import {DBCert} from "../../../lib/dal/sqliteDAL/CertDAL" +import {Map} from "../../../lib/common-libs/crypto/map" -const _ = require('underscore'); const moment = require('moment'); const inquirer = require('inquirer'); const constants = CommonConstants -interface PreJoin { +export interface PreJoin { identity: { pubkey: string uid: string @@ -49,7 +50,7 @@ interface PreJoin { } key: null idHash: string - certs: any[] + certs: DBCert[] ms: any } @@ -107,20 +108,19 @@ export class BlockGenerator { const exclusions = await this.dal.getToBeKickedPubkeys(); const wereExcludeds = await this.dal.getRevokedPubkeys(); const newCertsFromWoT = await generator.findNewCertsFromWoT(current); - const newcomers = await this.findNewcomers(current, (joinersData:any) => generator.filterJoiners(joinersData)) + const newcomers = await this.findNewcomers(current, joinersData => generator.filterJoiners(joinersData)) const leavers = await this.findLeavers(current) const transactions = await this.findTransactions(current, manualValues); - const certifiersOfNewcomers = _.uniq(_.keys(newcomers).reduce((theCertifiers:any, newcomer:string) => { - return theCertifiers.concat(_.pluck(newcomers[newcomer].certs, 'from')); - }, [])); - const certifiers:string[] = [].concat(certifiersOfNewcomers); + const certifiersOfNewcomers = Underscore.uniq(Underscore.keys(newcomers).reduce((theCertifiers, newcomer:string) => { + return theCertifiers.concat(Underscore.pluck(newcomers[newcomer].certs, 'from')); + }, <string[]>[])) // Merges updates - _(newCertsFromWoT).keys().forEach(function(certified:string){ + Underscore.keys(newCertsFromWoT).forEach(function(certified:string){ newCertsFromWoT[certified] = newCertsFromWoT[certified].filter((cert:any) => { // Must not certify a newcomer, since it would mean multiple certifications at same time from one member - const isCertifier = certifiers.indexOf(cert.from) != -1; + const isCertifier = certifiersOfNewcomers.indexOf(cert.from) != -1; if (!isCertifier) { - certifiers.push(cert.from); + certifiersOfNewcomers.push(cert.from); } return !isCertifier; }); @@ -144,7 +144,7 @@ export class BlockGenerator { await LOCAL_RULES_HELPERS.checkBunchOfTransactions(passingTxs.concat(tx), this.conf, options) const nextBlockWithFakeTimeVariation = { medianTime: current.medianTime + 1 }; await GLOBAL_RULES_HELPERS.checkSingleTransaction(tx, nextBlockWithFakeTimeVariation, this.conf, this.dal, async (txHash:string) => { - return _.findWhere(passingTxs, { hash: txHash }) || null + return Underscore.findWhere(passingTxs, { hash: txHash }) || null }); await GLOBAL_RULES_HELPERS.checkTxBlockStamp(tx, this.dal); transactions.push(tx); @@ -191,21 +191,21 @@ export class BlockGenerator { return leaveData; } - private async findNewcomers(current:DBBlock|null, filteringFunc: (joinData: { [pub:string]: any }) => Promise<{ [pub:string]: any }>) { + private async findNewcomers(current:DBBlock|null, filteringFunc: (joinData: Map<PreJoin>) => Promise<Map<PreJoin>>) { const preJoinData = await this.getPreJoinData(current); const joinData = await filteringFunc(preJoinData); const members = await this.dal.getMembers(); - const wotMembers = _.pluck(members, 'pubkey'); + const wotMembers = Underscore.pluck(members, 'pubkey'); // Checking step - let newcomers = _(joinData).keys(); - newcomers = _.shuffle(newcomers) + let newcomers = Underscore.keys(joinData) + newcomers = Underscore.shuffle(newcomers) const nextBlockNumber = current ? current.number + 1 : 0; try { const realNewcomers = await this.iteratedChecking(newcomers, async (someNewcomers:string[]) => { const nextBlock = { number: nextBlockNumber, joiners: someNewcomers, - identities: _.filter(newcomers.map((pub:string) => joinData[pub].identity), { wasMember: false }).map((idty:any) => idty.pubkey) + identities: Underscore.where(newcomers.map((pub:string) => joinData[pub].identity), { wasMember: false }).map((idty:any) => idty.pubkey) }; const theNewLinks = await this.computeNewLinks(nextBlockNumber, someNewcomers, joinData) await this.checkWoTConstraints(nextBlock, theNewLinks, current); @@ -314,22 +314,22 @@ export class BlockGenerator { return preJoinData; } - private async computeNewLinks(forBlock:number, theNewcomers:any, joinData:any) { + private async computeNewLinks(forBlock:number, theNewcomers:any, joinData:Map<PreJoin>) { let newCerts = await this.computeNewCerts(forBlock, theNewcomers, joinData); return this.newCertsToLinks(newCerts); } - newCertsToLinks(newCerts:any) { - let newLinks:any = {}; - _.mapObject(newCerts, function(certs:any, pubkey:string) { - newLinks[pubkey] = _.pluck(certs, 'from'); - }); - return newLinks; + newCertsToLinks(newCerts:Map<DBCert[]>) { + let newLinks: Map<string[]> = {} + for (const pubkey of Underscore.keys(newCerts)) { + newLinks[pubkey] = Underscore.pluck(newCerts[pubkey], 'from') + } + return newLinks } - async computeNewCerts(forBlock:number, theNewcomers:any, joinData:any) { - const newCerts:any = {}, certifiers = []; - const certsByKey = _.mapObject(joinData, function(val:any){ return val.certs; }); + async computeNewCerts(forBlock:number, theNewcomers:any, joinData:Map<PreJoin>) { + const newCerts:Map<DBCert[]> = {}, certifiers:string[] = [] + const certsByKey = Underscore.mapObjectByProp(joinData, 'certs') for (const newcomer of theNewcomers) { // New array of certifiers newCerts[newcomer] = newCerts[newcomer] || []; @@ -352,10 +352,10 @@ export class BlockGenerator { } } } - return newCerts; + return newCerts } - async getSinglePreJoinData(current:DBBlock|null, idHash:string, joiners:string[]) { + async getSinglePreJoinData(current:DBBlock|null, idHash:string, joiners:string[]): Promise<PreJoin> { const identity = await this.dal.getGlobalIdentityByHashForJoining(idHash) let foundCerts = []; const vHEAD_1 = await this.mainContext.getvHEAD_1(); @@ -387,9 +387,9 @@ export class BlockGenerator { if (!current) { // Look for certifications from initial joiners const certs = await this.dal.certsNotLinkedToTarget(idHash); - foundCerts = _.filter(certs, function(cert:any){ + foundCerts = Underscore.filter(certs, (cert:any) => { // Add 'joiners && ': special case when block#0 not written ANd not joiner yet (avoid undefined error) - return joiners && ~joiners.indexOf(cert.from); + return !!(joiners && ~joiners.indexOf(cert.from)) }); } else { // Look for certifications from WoT members @@ -473,20 +473,20 @@ export class BlockGenerator { // Revocations have an impact on exclusions revocations.forEach((idty:any) => exclusions.push(idty.pubkey)); // Prevent writing joins/updates for members who will be excluded - exclusions = _.uniq(exclusions); + exclusions = Underscore.uniq(exclusions); exclusions.forEach((excluded:any) => { delete updates[excluded]; delete joinData[excluded]; delete leaveData[excluded]; }); // Prevent writing joins/updates for excluded members - wereExcluded = _.uniq(wereExcluded); + wereExcluded = Underscore.uniq(wereExcluded); wereExcluded.forEach((excluded:any) => { delete updates[excluded]; delete joinData[excluded]; delete leaveData[excluded]; }); - _(leaveData).keys().forEach((leaver:any) => { + Underscore.keys(leaveData).forEach((leaver:any) => { delete updates[leaver]; delete joinData[leaver]; }); @@ -528,7 +528,7 @@ export class BlockGenerator { block.issuer = this.selfPubkey } // Members merkle - const joiners = _(joinData).keys(); + const joiners = Underscore.keys(joinData) joiners.sort() const previousCount = current ? current.membersCount : 0; if (joiners.length == 0 && !current) { @@ -542,7 +542,7 @@ export class BlockGenerator { * Priority 1: keep the WoT sane */ // Certifications from the WoT, to the WoT - _(updates).keys().forEach((certifiedMember:any) => { + Underscore.keys(updates).forEach((certifiedMember:any) => { const certs = updates[certifiedMember] || []; certs.forEach((cert:any) => { if (blockLen < maxLenOfBlock) { @@ -563,7 +563,7 @@ export class BlockGenerator { } }); // Leavers - const leavers = _(leaveData).keys(); + const leavers = Underscore.keys(leaveData) leavers.forEach((leaver:any) => { const data = leaveData[leaver]; // Join only for non-members @@ -602,7 +602,7 @@ export class BlockGenerator { block.joiners.push(MembershipDTO.fromJSONObject(data.ms).inline()); } }); - block.identities = _.sortBy(block.identities, (line:string) => { + block.identities = Underscore.sortBy(block.identities, (line:string) => { const sp = line.split(':'); return sp[2] + sp[3]; }); @@ -676,7 +676,7 @@ export class BlockGenerator { block.issuersFrameVar = vHEAD.issuersFrameVar; // Manual values before hashing if (manualValues) { - _.extend(block, _.omit(manualValues, 'time')); + Underscore.extend(block, Underscore.omit(manualValues, 'time')); } // InnerHash block.time = block.medianTime; @@ -738,15 +738,16 @@ class NextBlockGenerator implements BlockGeneratorInterface { // Check if writable let duration = current && targetBlock ? current.medianTime - targetBlock.medianTime : 0; if (targetBlock && duration <= this.conf.sigWindow) { - cert.sig = ''; - cert.currency = this.conf.currency; - cert.issuer = cert.from; - cert.idty_issuer = targetIdty.pubkey; - cert.idty_uid = targetIdty.uid; - cert.idty_buid = targetIdty.buid; - cert.idty_sig = targetIdty.sig; - cert.buid = current ? [cert.block_number, targetBlock.hash].join('-') : CommonConstants.SPECIAL_BLOCK; - const rawCert = CertificationDTO.fromJSONObject(cert).getRawUnSigned(); + const rawCert = CertificationDTO.fromJSONObject({ + sig: '', + currency: this.conf.currency, + issuer: cert.from, + idty_issuer: targetIdty.pubkey, + idty_uid: targetIdty.uid, + idty_buid: targetIdty.buid, + idty_sig: targetIdty.sig, + buid: current ? [cert.block_number, targetBlock.hash].join('-') : CommonConstants.SPECIAL_BLOCK, + }).getRawUnSigned(); if (verify(rawCert, certSig, cert.from)) { cert.sig = certSig; let exists = false; @@ -801,7 +802,7 @@ class NextBlockGenerator implements BlockGeneratorInterface { this.logger.warn(err); } } - _.keys(preJoinData).forEach( (joinPubkey:any) => filterings.push(filter(joinPubkey))); + Underscore.keys(preJoinData).forEach( (joinPubkey:any) => filterings.push(filter(joinPubkey))); await Promise.all(filterings) return filtered; } @@ -819,7 +820,7 @@ class ManualRootGenerator implements BlockGeneratorInterface { async filterJoiners(preJoinData:any) { const filtered:any = {}; - const newcomers = _(preJoinData).keys(); + const newcomers = Underscore.keys(preJoinData) const uids:string[] = []; newcomers.forEach((newcomer:string) => uids.push(preJoinData[newcomer].ms.userid)); diff --git a/app/modules/prover/lib/powCluster.ts b/app/modules/prover/lib/powCluster.ts index 4b3fa0127ae5be06215c62bf91ac3b406d7087f0..3ee90d488df904aff629220b522c99ce55b7e63c 100644 --- a/app/modules/prover/lib/powCluster.ts +++ b/app/modules/prover/lib/powCluster.ts @@ -16,8 +16,8 @@ import {ProverConstants} from "./constants" import {createPowWorker} from "./proof" import {PowWorker} from "./PowWorker" import {FileDAL} from "../../../lib/dal/fileDAL"; +import {Underscore} from "../../../lib/common-libs/underscore" -const _ = require('underscore') const nuuid = require('node-uuid'); const cluster = require('cluster') const querablep = require('querablep') @@ -140,7 +140,7 @@ export class Master { value: this.conf }) }) - return Promise.resolve(_.clone(conf)) + return Promise.resolve(Underscore.clone(conf)) } private cancelWorkersWork() { @@ -205,7 +205,7 @@ export class Master { nonceBeginning: s.nonceBeginning, zeros: stuff.newPoW.zeros, highMark: stuff.newPoW.highMark, - pair: _.clone(stuff.newPoW.pair), + pair: Underscore.clone(stuff.newPoW.pair), forcedTime: stuff.newPoW.forcedTime, conf: { powNoSecurity: stuff.newPoW.conf.powNoSecurity, diff --git a/app/modules/wizard.ts b/app/modules/wizard.ts index a6b6e3b4e3cb9e8470d7f4fa13d17d9ff5d7f7f5..51c3e38c08469b79195de403073523d4448500fe 100644 --- a/app/modules/wizard.ts +++ b/app/modules/wizard.ts @@ -14,8 +14,8 @@ import {ConfDTO} from "../lib/dto/ConfDTO" import {Server} from "../../server" import {Wizard} from "../lib/wizard" +import {Underscore} from "../lib/common-libs/underscore" -const _ = require('underscore') const logger = require('../lib/logger').NewLogger('wizard'); module.exports = { @@ -34,7 +34,7 @@ module.exports = { onConfiguredExecute: async (server:Server, conf:ConfDTO, program:any, params:any, wizardTasks:any) => { const step = params[0]; - const tasks = step ? [wizardTasks[step]] : _.values(wizardTasks); + const tasks = step ? [wizardTasks[step]] : Underscore.values(wizardTasks); for (const task of tasks) { if (!task) { throw 'Unknown task'; diff --git a/app/modules/ws2p/lib/WS2PCluster.ts b/app/modules/ws2p/lib/WS2PCluster.ts index 2572225fa4dcdbd42020b06c07cf74e324da31bc..999c28a6b8f0bda0eb8ec968c69bb79d4b32b4af 100644 --- a/app/modules/ws2p/lib/WS2PCluster.ts +++ b/app/modules/ws2p/lib/WS2PCluster.ts @@ -31,10 +31,10 @@ import {CommonConstants} from '../../../lib/common-libs/constants'; import {Package} from "../../../lib/common/package"; import {ProverConstants} from "../../prover/lib/constants"; import {ProxiesConf} from '../../../lib/proxy'; +import {Underscore} from "../../../lib/common-libs/underscore" const es = require('event-stream') const nuuid = require('node-uuid') -const _ = require('underscore') export interface WS2PHead { message:string @@ -699,7 +699,7 @@ export class WS2PCluster { } // Disconnect Private connexions already present under Public let uuids = Object.keys(this.ws2pClients) - uuids = _.shuffle(uuids) + uuids = Underscore.shuffle(uuids) for (const uuid of uuids) { const client = this.ws2pClients[uuid] const pub = client.connection.pubkey @@ -716,7 +716,7 @@ export class WS2PCluster { // Disconnect Private connexions until the maximum size is respected while (this.clientsCount() > this.maxLevel1Size) { let uuids = Object.keys(this.ws2pClients) - uuids = _.shuffle(uuids) + uuids = Underscore.shuffle(uuids) let lowPriorityConnectionUUID:string = uuids[0] let minPriorityLevel = await this.keyPriorityLevel(this.ws2pClients[lowPriorityConnectionUUID].connection.pubkey, preferedKeys) for (const uuid of uuids) { diff --git a/app/service/BlockchainService.ts b/app/service/BlockchainService.ts index 63b6c89e688773bde85ba4cb761f664da62f17e9..bcd1859acc9c31772984ea775bf06acd4131b96c 100644 --- a/app/service/BlockchainService.ts +++ b/app/service/BlockchainService.ts @@ -31,9 +31,6 @@ import {OtherConstants} from "../lib/other_constants" import {DataErrors} from "../lib/common-libs/errors" import {DuniterBlockchain} from "../lib/blockchain/DuniterBlockchain" -"use strict"; - -const _ = require('underscore'); const constants = require('../lib/constants'); export interface IdentityForRequirements { diff --git a/app/service/PeeringService.ts b/app/service/PeeringService.ts index 4187ef593825c12d223da7f46988ae7d4fea1ac2..8e34626a565889010e5d170bc3e778573fce3e39 100644 --- a/app/service/PeeringService.ts +++ b/app/service/PeeringService.ts @@ -13,7 +13,6 @@ 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" import {Multicaster} from "../lib/streams/multicaster" import {PeerDTO} from "../lib/dto/PeerDTO" @@ -22,9 +21,10 @@ import {dos2unix} from "../lib/common-libs/dos2unix" import {rawer} from "../lib/common-libs/index" import {Server} from "../../server" import {GlobalFifoPromise} from "./GlobalFifoPromise" +import {DBPeer} from "../lib/db/DBPeer" +import {Underscore} from "../lib/common-libs/underscore" const util = require('util'); -const _ = require('underscore'); const events = require('events'); const logger = require('../lib/logger').NewLogger('peering'); const constants = require('../lib/constants'); @@ -131,8 +131,8 @@ export class PeeringService { 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 }); + const error = Underscore.extend({}, constants.ERRORS.NEWER_PEER_DOCUMENT_AVAILABLE); + Underscore.extend(error.uerr, { peer: found }); throw error; } else if (isAlreadyKnown) { throw constants.ERRORS.PEER_DOCUMENT_ALREADY_KNOWN; @@ -186,7 +186,7 @@ export class PeeringService { return this.server.writePeer(pretendedNewer) } - async generateSelfPeer(theConf:ConfDTO, signalTimeInterval = 0): Promise<DBPeer|null> { + async generateSelfPeer(theConf:{ currency: string }, signalTimeInterval = 0): Promise<DBPeer|null> { const current = await this.server.dal.getCurrentBlockOrNull(); const currency = theConf.currency || constants.DEFAULT_CURRENCY_NAME; const peers = await this.dal.findPeers(this.selfPubkey); @@ -194,11 +194,13 @@ export class PeeringService { version: constants.DOCUMENTS_VERSION, currency: currency, block: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', - endpoints: [] + endpoints: <string[]>[] }; const currentSelfPeer = peers[0] if (peers.length != 0 && currentSelfPeer) { - p1 = _(currentSelfPeer).extend({version: constants.DOCUMENTS_VERSION, currency: currency}); + p1 = currentSelfPeer + p1.version = constants.DOCUMENTS_VERSION + p1.currency = currency } const localEndpoints = await this.server.getEndpoints() const otherPotentialEndpoints = this.getOtherEndpoints(p1.endpoints, localEndpoints) @@ -239,7 +241,7 @@ export class PeeringService { currency: currency, pubkey: this.selfPubkey, block: targetBlockstamp ? targetBlockstamp : constants.PEER.SPECIAL_BLOCK, - endpoints: _.uniq(endpointsToDeclare) + endpoints: Underscore.uniq(endpointsToDeclare) }; const raw2 = dos2unix(PeerDTO.fromJSONObject(p2).getRaw()); const bmaAccess = PeerDTO.fromJSONObject(p2).getURL() diff --git a/index.ts b/index.ts index f944fabbfe04f12d07a82784201c4ec70cfc3189..a19e14c527b0860666f606b871654c7140538983 100644 --- a/index.ts +++ b/index.ts @@ -25,9 +25,9 @@ import {ProxiesConf} from './app/lib/proxy'; import {RouterDependency} from "./app/modules/router" import {OtherConstants} from "./app/lib/other_constants" import {Directory} from "./app/lib/system/directory" +import {Underscore} from "./app/lib/common-libs/underscore" const path = require('path'); -const _ = require('underscore'); const constants = require('./app/lib/constants'); const logger = require('./app/lib/logger').NewLogger('duniter'); @@ -351,7 +351,7 @@ class Stack { // Register the configuration hook for saving phase (overrides the saved data) server.dal.saveConfHook = async (conf:ConfDTO) => { - const clonedConf = _.clone(conf); + const clonedConf = Underscore.clone(conf) for (const callback of this.configBeforeSaveCallbacks) { await callback(clonedConf, program, logger, server.dal.confDAL); } diff --git a/server.ts b/server.ts index 9f371e3beda80d5993e5b84ff3190b5885a3e6ab..84f7cb4a95f3ae3722f9a43f30a465949d48978a 100644 --- a/server.ts +++ b/server.ts @@ -36,9 +36,9 @@ import {OtherConstants} from "./app/lib/other_constants" import {WS2PCluster} from "./app/modules/ws2p/lib/WS2PCluster" import {DBBlock} from "./app/lib/db/DBBlock" import {ProxiesConf} from './app/lib/proxy'; -import {DBPeer} from "./app/lib/dal/sqliteDAL/PeerDAL" import {Directory, FileSystem} from "./app/lib/system/directory" import {DataErrors} from "./app/lib/common-libs/errors" +import {DBPeer} from "./app/lib/db/DBPeer" export interface HookableServer { generatorGetJoinData: (...args:any[]) => Promise<any> diff --git a/test/dal/dal.js b/test/dal/basic-dal-tests.ts similarity index 76% rename from test/dal/dal.js rename to test/dal/basic-dal-tests.ts index 302879a1309fdc3eed06996eb873aea056d84aa7..3a8143c540c00de0bdfd77b5a06df71226d512e2 100644 --- a/test/dal/dal.js +++ b/test/dal/basic-dal-tests.ts @@ -11,15 +11,15 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; -var co = require('co'); -var _ = require('underscore'); +import {FileDAL} from "../../app/lib/dal/fileDAL" +import {PeerDTO} from "../../app/lib/dto/PeerDTO" +import {Directory} from "../../app/lib/system/directory" +import {DBBlock} from "../../app/lib/db/DBBlock" +import {Underscore} from "../../app/lib/common-libs/underscore" + var should = require('should'); var assert = require('assert'); -var dal = require('../../app/lib/dal/fileDAL').FileDAL -var dir = require('../../app/lib/system/directory').Directory var constants = require('../../app/lib/constants'); -var PeerDTO = require('../../app/lib/dto/PeerDTO').PeerDTO var mocks = { peer1: { @@ -102,22 +102,22 @@ var mocks = { } }; -var fileDAL = null; +let fileDAL:FileDAL describe("DAL", function(){ - before(() => co(function *() { - let params = yield dir.getHomeParams(true, 'db0'); - fileDAL = new dal(params); - yield fileDAL.init(); - return fileDAL.saveConf({ currency: "meta_brouzouf" }); - })); + before(async () => { + let params = await Directory.getHomeParams(true, 'db0'); + fileDAL = new FileDAL(params); + await fileDAL.init({} as any); + return fileDAL.saveConf({ currency: "meta_brouzouf" } as any); + }) - it('should have DB version 21', () => co(function *() { - let version = yield fileDAL.getDBVersion(); + it('should have DB version 21', async () => { + let version = await fileDAL.getDBVersion(); should.exist(version); version.should.equal(constants.CURRENT_DB_VERSION); - })); + }) it('should have no peer in a first time', function(){ return fileDAL.listAllPeers().then(function(peers){ @@ -126,7 +126,7 @@ describe("DAL", function(){ }); it('should have 1 peer if 1 is created', function(){ - return fileDAL.savePeer(PeerDTO.fromJSONObject(mocks.peer1)) + return fileDAL.savePeer(PeerDTO.fromJSONObject(mocks.peer1).toDBPeer()) .then(() => fileDAL.listAllPeers()) .then(function(peers){ peers.should.have.length(1); @@ -150,39 +150,37 @@ describe("DAL", function(){ }); }); - it('should be able to save a Block', function(){ - return co(function *() { - yield fileDAL.saveBlock(_.extend({ fork: false }, mocks.block0)); - let block = yield fileDAL.getFullBlockOf(0); - block.should.have.property('hash').equal(mocks.block0.hash); - block.should.have.property('signature').equal(mocks.block0.signature); - block.should.have.property('version').equal(mocks.block0.version); - block.should.have.property('currency').equal(mocks.block0.currency); - block.should.have.property('issuer').equal(mocks.block0.issuer); - block.should.have.property('parameters').equal(mocks.block0.parameters); - block.should.have.property('previousHash').equal(mocks.block0.previousHash); - block.should.have.property('previousIssuer').equal(mocks.block0.previousIssuer); - block.should.have.property('membersCount').equal(mocks.block0.membersCount); - block.should.have.property('monetaryMass').equal(mocks.block0.monetaryMass); - block.should.have.property('UDTime').equal(mocks.block0.UDTime); - block.should.have.property('medianTime').equal(mocks.block0.medianTime); - block.should.have.property('dividend').equal(mocks.block0.dividend); - block.should.have.property('unitbase').equal(mocks.block0.unitbase); - block.should.have.property('time').equal(mocks.block0.time); - block.should.have.property('powMin').equal(mocks.block0.powMin); - block.should.have.property('number').equal(mocks.block0.number); - block.should.have.property('nonce').equal(mocks.block0.nonce); + it('should be able to save a Block', async () => { + await fileDAL.saveBlock(Underscore.extend({ fork: false } as any, mocks.block0)); + let block = (await fileDAL.getFullBlockOf(0)) as DBBlock + block.should.have.property('hash').equal(mocks.block0.hash); + block.should.have.property('signature').equal(mocks.block0.signature); + block.should.have.property('version').equal(mocks.block0.version); + block.should.have.property('currency').equal(mocks.block0.currency); + block.should.have.property('issuer').equal(mocks.block0.issuer); + block.should.have.property('parameters').equal(mocks.block0.parameters); + block.should.have.property('previousHash').equal(mocks.block0.previousHash); + block.should.have.property('previousIssuer').equal(mocks.block0.previousIssuer); + block.should.have.property('membersCount').equal(mocks.block0.membersCount); + block.should.have.property('monetaryMass').equal(mocks.block0.monetaryMass); + block.should.have.property('UDTime').equal(mocks.block0.UDTime); + block.should.have.property('medianTime').equal(mocks.block0.medianTime); + block.should.have.property('dividend').equal(mocks.block0.dividend); + block.should.have.property('unitbase').equal(mocks.block0.unitbase); + block.should.have.property('time').equal(mocks.block0.time); + block.should.have.property('powMin').equal(mocks.block0.powMin); + block.should.have.property('number').equal(mocks.block0.number); + block.should.have.property('nonce').equal(mocks.block0.nonce); - //assert.deepEqual(block, mocks.block0); - assert.deepEqual(block.identities, mocks.block0.identities); - assert.deepEqual(block.certifications, mocks.block0.certifications); - assert.deepEqual(block.actives, mocks.block0.actives); - assert.deepEqual(block.revoked, mocks.block0.revoked); - assert.deepEqual(block.excluded, mocks.block0.excluded); - assert.deepEqual(block.leavers, mocks.block0.leavers); - assert.deepEqual(block.actives, mocks.block0.actives); - assert.deepEqual(block.joiners, mocks.block0.joiners); - assert.deepEqual(block.transactions, mocks.block0.transactions); - }); + //assert.deepEqual(block, mocks.block0); + assert.deepEqual(block.identities, mocks.block0.identities); + assert.deepEqual(block.certifications, mocks.block0.certifications); + assert.deepEqual(block.actives, mocks.block0.actives); + assert.deepEqual(block.revoked, mocks.block0.revoked); + assert.deepEqual(block.excluded, mocks.block0.excluded); + assert.deepEqual(block.leavers, mocks.block0.leavers); + assert.deepEqual(block.actives, mocks.block0.actives); + assert.deepEqual(block.joiners, mocks.block0.joiners); + assert.deepEqual(block.transactions, mocks.block0.transactions); }); }); diff --git a/test/fast/block_global.disabled b/test/fast/block_global.disabled deleted file mode 100644 index 7611166fd585ea3d7d3ea15ffea5d38b2937f23d..0000000000000000000000000000000000000000 --- a/test/fast/block_global.disabled +++ /dev/null @@ -1,678 +0,0 @@ -"use strict"; -const co = require('co'); -const Q = require('q'); -const _ = require('underscore'); -const async = require('async'); -const should = require('should'); -const rules = require('../../app/lib/rules'); -const wotb = require('../../app/lib/wot'); -const parsers = require('duniter-common').parsers; -const blocks = require('../data/blocks'); -const parser = parsers.parseBlock; -const Block = require('../../app/lib/entity/block'); -const Identity = require('../../app/lib/entity/identity'); - -const conf = { - currency: 'bb', - msValidity: 365.25 * 24 * 3600, // 1 year - sigValidity: 365.25 * 24 * 3600, // 1 year - sigQty: 1, - xpercent: 0.9, - powZeroMin: 1, - powPeriod: 18, - incDateMin: 10, - dt: 100, - ud0: 100, - c: 0.1, - medianTimeBlocks: 200, - percentRot: 2 / 3, - blockRot: 300, - dtDiffEval: 500, - stepMax: 1 -}; - -function getDAL(overrides) { - return _.extend({ - wotb: wotb.memoryInstance(), - getCurrentBlockOrNull: () => Q(null), - getWrittenIdtyByUID: () => Q(null), - getWrittenIdtyByPubkey: () => Q(null), - getToBeKicked: () => Q([]), - isLeaving: () => Q(false), - getPreviousLinks: () => Q(null), - getLastValidFrom: () => Q(null), - lastUDBlock: () => Q(null), - getBlock: () => Q(null), - isMember: () => Q(false), - getBlocksBetween: () => Q([]), - lastBlockOfIssuer: () => Q(null) - }, overrides); -} - -/** - * TODO: reimplement tests according to new convention: - * - * - Name: protocol-brg<number>-<title>.js - * - Content: see existing tests - */ - -describe("Block global coherence:", function(){ - - it('a valid block should not have any error', validate(blocks.VALID_ROOT, getDAL(), { - getIssuerPersonalizedDifficulty: () => Q(1), - getvHEAD_1: () => Q({ version : 2 }) - }, function (err) { - should.not.exist(err); - })); - - it('a valid (next) block should not have any error', validate(blocks.VALID_NEXT, getDAL({ - getCurrentBlockOrNull: () => Q({ number: 2, hash: '52DC8A585C5D89571C511BB83F7E7D3382F0041452064B1272E65F0B42B82D57', issuer: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', membersCount: 3, time: 1411776000, medianTime: 1411776000 }), - getBlock: (number) => { - if (number == 1) { - return Q({ time: 1411776000, powMin: 1 }); - } - if (number == 2) { - return Q({ number: 3, powMin: 1 }); - } - return Q(null); - }, - isMember: () => Q(true), - getBlocksBetween: () => Q([{time:1411776000},{time:1411776000},{time:1411776000}]) - }), { - getIssuerPersonalizedDifficulty: () => Q(2), - getvHEAD_1: () => Q({ version : 2 }) - }, function (err) { - should.not.exist(err); - })); - - it('a block with wrong PreviousHash should fail', test(rules.GLOBAL.checkPreviousHash, blocks.WRONG_PREVIOUS_HASH, { - getCurrentBlockOrNull: () => Q({ number: 50, hash: '4C8800825C44A22F230AFC0D140BF1930331A686899D16EBE4C58C9F34C609E8', issuer: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', membersCount: 3 }) - }, function (err) { - should.exist(err); - err.message.should.equal('PreviousHash not matching hash of current block'); - })); - - it('a block with wrong PreviousIssuer should fail', test(rules.GLOBAL.checkPreviousIssuer, blocks.WRONG_PREVIOUS_ISSUER, { - getCurrentBlockOrNull: () => Q({ number: 50, hash: '4C8800825C44A22F230AFC0D140BF1930331A686899D16EBE4C58C9F34C609E8', issuer: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', membersCount: 3 }) - }, function (err) { - should.exist(err); - err.message.should.equal('PreviousIssuer not matching issuer of current block'); - })); - - it('a block with wrong DifferentIssuersCount following V2 should fail', test(rules.GLOBAL.checkDifferentIssuersCount, blocks.WRONG_DIFFERENT_ISSUERS_COUNT_FOLLOWING_V2, { - getCurrentBlockOrNull: () => Q({ version: 2 }), - getBlocksBetween: () => Q([]) - }, function (err) { - should.exist(err); - err.message.should.equal('DifferentIssuersCount is not correct'); - })); - - it('a block with wrong DifferentIssuersCount following V3 should fail', test(rules.GLOBAL.checkDifferentIssuersCount, blocks.WRONG_DIFFERENT_ISSUERS_COUNT_FOLLOWING_V3, { - getCurrentBlockOrNull: () => Q({ version: 3, issuersCount: 4 }), - getBlocksBetween: () => Q([ - // 5 blocks, 4 different issuers - { issuer: 'A' }, - { issuer: 'B' }, - { issuer: 'A' }, - { issuer: 'C' }, - { issuer: 'D' } - ]) - }, function (err) { - should.exist(err); - err.message.should.equal('DifferentIssuersCount is not correct'); - })); - - it('a block with wrong IssuersFrame following V2 should fail', test(rules.GLOBAL.checkIssuersFrame, blocks.WRONG_ISSUERS_FRAME_FOLLOWING_V2, { - getCurrentBlockOrNull: () => Q({ version: 2 }) - }, function (err) { - should.exist(err); - err.message.should.equal('IssuersFrame is not correct'); - })); - - it('a block with wrong IssuersFrame following V3 should fail', test(rules.GLOBAL.checkIssuersFrameVar, blocks.WRONG_ISSUERS_FRAME_FOLLOWING_V3, { - getCurrentBlockOrNull: () => Q({ version: 3, issuersCount: 3, issuersFrame: 56, issuersFrameVar: 6 }) - }, function (err) { - should.exist(err); - err.message.should.equal('IssuersFrameVar is not correct'); - })); - - it('a block with wrong Issuer should fail', test(rules.GLOBAL.checkIssuerIsMember, blocks.WRONG_ISSUER, { - isMember: () => Q(false) - }, function (err) { - should.exist(err); - err.message.should.equal('Issuer is not a member'); - })); - - it('a block with joiner for root block without root number shoud fail', test(rules.GLOBAL.checkJoiners, blocks.WRONG_JOIN_ROOT_NUMBER, { - getCurrentBlockOrNull: () => Q(null) - }, function (err) { - should.exist(err); - err.message.should.equal('Number must be 0 for root block\'s memberships'); - })); - - it('a block with joiner for root block without root hash shoud fail', test(rules.GLOBAL.checkJoiners, blocks.WRONG_JOIN_ROOT_HASH, { - getCurrentBlockOrNull: () => Q(null) - }, function (err) { - should.exist(err); - err.message.should.equal('Hash must be E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 for root block\'s memberships'); - })); - - it('a block with joiner targeting unexisting block fail', test(rules.GLOBAL.checkJoiners, blocks.WRONG_JOIN_BLOCK_TARGET, { - getCurrentBlockOrNull: () => Q(null) - }, function (err) { - should.exist(err); - err.message.should.equal('Membership based on an unexisting block'); - })); - - it('a block with joiner membership number lower or equal than previous should fail', test(rules.GLOBAL.checkJoiners, blocks.WRONG_JOIN_NUMBER_TOO_LOW, { - getCurrentBlockOrNull: () => Q(null), - getWrittenIdtyByPubkey: () => Q({ currentMSN: 2 }), - getBlockByNumberAndHash: () => Q({ number: 3, powMin: 1 }) - }, function (err) { - should.exist(err); - err.message.should.equal('Membership\'s number must be greater than last membership of the pubkey'); - })); - - it('a block with joiner membership of a yet member should fail', test(rules.GLOBAL.checkJoiners, blocks.WRONG_JOIN_ALREADY_MEMBER, { - isMember: () => Q(true), - getWrittenIdtyByPubkey: () => Q({ currentMSN: 2, member: true }), - getBlockByNumberAndHash: () => Q({ number: 3, powMin: 1 }), - getCurrentBlockOrNull: () => Q({ number: 50, hash: '4C8800825C44A22F230AFC0D140BF1930331A686899D16EBE4C58C9F34C609E8', issuer: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', membersCount: 3 }) - }, function (err) { - should.exist(err); - err.message.should.equal('Cannot be in joiners if already a member'); - })); - - it('a block with at least one revoked joiner should fail', test(rules.GLOBAL.checkJoinersAreNotRevoked, blocks.REVOKED_JOINER, { - getWrittenIdtyByPubkey: () => Q({ currentMSN: 2, revoked: true }) - }, function (err) { - should.exist(err); - err.message.should.equal('Revoked pubkeys cannot join'); - })); - - it('a block with at least one joiner without enough certifications should fail', test(rules.GLOBAL.checkJoinersHaveEnoughCertifications, blocks.NOT_ENOUGH_CERTIFICATIONS_JOINER, { - getValidLinksTo: () => Q([]) - }, function (err) { - should.exist(err); - err.message.should.equal('Joiner/Active does not gathers enough certifications'); - })); - - it('a block with at least one joiner without enough certifications should succeed', test(rules.GLOBAL.checkJoinersHaveEnoughCertifications, blocks.NOT_ENOUGH_CERTIFICATIONS_JOINER_BLOCK_0, { - }, function (err) { - should.not.exist(err); - })); - - it('a block with expired membership should fail', test(rules.GLOBAL.checkJoiners, blocks.EXPIRED_MEMBERSHIP, { - getWrittenIdtyByPubkey: () => Q({ currentMSN: 2 }), - getBlockByNumberAndHash: () => Q({ medianTime: 1411775000, powMin: 1 }), - getCurrentBlockOrNull: () => Q({ time: 1443333600, medianTime: 1443333600 }) - }, function (err) { - should.exist(err); - err.message.should.equal('Membership has expired'); - })); - - it('a block with at least one joiner outdistanced from WoT should fail', test(rules.GLOBAL.checkJoinersAreNotOudistanced, blocks.OUTDISTANCED_JOINER, { - wotb: { - addNode: () => 1, - setEnabled: () => 1, - addLink: () => 1, - removeLink: () => 1, - removeNode: () => 1, - isOutdistanced: () => true - }, - getCurrentBlockOrNull: () => Q({ number: 2, hash: '52DC8A585C5D89571C511BB83F7E7D3382F0041452064B1272E65F0B42B82D57', issuer: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', membersCount: 3, time: 1411776000, medianTime: 1411776000 }), - getWrittenIdtyByPubkey: () => Q({ wotb_id: 0 }) - }, function (err) { - should.exist(err); - err.message.should.equal('Joiner/Active is outdistanced from WoT'); - })); - - it('a block with active targeting unexisting block fail', test(rules.GLOBAL.checkActives, blocks.WRONG_ACTIVE_BLOCK_TARGET, { - getCurrentBlockOrNull: () => Q(null) - }, function (err) { - should.exist(err); - err.message.should.equal('Membership based on an unexisting block'); - })); - - it('a block with certification of unknown pubkey should fail', test(rules.GLOBAL.checkCertificationsAreValid, blocks.WRONGLY_SIGNED_CERTIFICATION, { - getCurrentBlockOrNull: () => Q(null), - getBlock: () => Q({}), - getBlockByNumberAndHash: () => Q({}) - }, function (err) { - should.exist(err); - err.message.should.equal('Wrong signature for certification'); - })); - - it('a block with certification to non-zero block for root block should fail', test(rules.GLOBAL.checkCertificationsAreValid, blocks.CERT_BASED_ON_NON_ZERO_FOR_ROOT, { - getCurrentBlockOrNull: () => Q(null) - }, function (err) { - should.exist(err); - err.message.should.equal('Number must be 0 for root block\'s certifications'); - })); - - it('a block with certification to unknown block should fail', test(rules.GLOBAL.checkCertificationsAreValid, blocks.CERT_BASED_ON_NON_EXISTING_BLOCK, { - getCurrentBlockOrNull: () => Q(null) - }, function (err) { - should.exist(err); - err.message.should.equal('Certification based on an unexisting block'); - })); - - it('a block with expired certifications should fail', test(rules.GLOBAL.checkCertificationsAreValid, blocks.EXPIRED_CERTIFICATIONS, { - getCurrentBlockOrNull: () => Q({ time: 1443333600, medianTime: 1443333600 }), - getBlock: () => Q({ medianTime: 1411775000, powMin: 1 }) - }, function (err) { - should.exist(err); - err.message.should.equal('Certification has expired'); - })); - - it('a block with certification from non-member pubkey should fail', test(rules.GLOBAL.checkCertificationsAreMadeByMembers, blocks.UNKNOWN_CERTIFIER, { - getCurrentBlockOrNull: () => Q(null) - }, function (err) { - should.exist(err); - err.message.should.equal('Certification from non-member'); - })); - - it('a block with certification to non-member pubkey should fail', test(rules.GLOBAL.checkCertificationsAreMadeToMembers, blocks.UNKNOWN_CERTIFIED, { - isMember: () => Q(false) - }, function (err) { - should.exist(err); - err.message.should.equal('Certification to non-member'); - })); - - it('a block with already used UserID should fail', test(rules.GLOBAL.checkIdentityUnicity, blocks.EXISTING_UID, { - getWrittenIdtyByUID: () => Q({}) - }, function (err) { - should.exist(err); - err.message.should.equal('Identity already used'); - })); - - it('a block with already used pubkey should fail', test(rules.GLOBAL.checkPubkeyUnicity, blocks.EXISTING_PUBKEY, { - getWrittenIdtyByPubkey: () => Q({}) - }, function (err) { - should.exist(err); - err.message.should.equal('Pubkey already used'); - })); - - it('a block with too early certification replay should fail', test(rules.GLOBAL.checkCertificationsDelayIsRespected, blocks.TOO_EARLY_CERTIFICATION_REPLAY, { - getPreviousLinks: (from, to) => { - if (from == 'G2CBgZBPLe6FSFUgpx2Jf1Aqsgta6iib3vmDRA1yLiqU' - && to == 'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC') { - // Exactly 1 second remaining - return Q({ timestamp: '1380218401' }); - } - return Q(null); - } - }, function (err) { - should.exist(err); - err.message.should.equal('A similar certification is already active'); - })); - - it('a block with kicked members not written under Excluded field should fail', test(rules.GLOBAL.checkKickedMembersAreExcluded, blocks.KICKED_NOT_EXCLUDED, { - getToBeKicked: () => Q([{}]) - }, function (err) { - should.exist(err); - err.message.should.equal('All kicked members must be present under Excluded members'); - })); - - it('a block with kicked members well written under Excluded field should succeed', test(rules.GLOBAL.checkKickedMembersAreExcluded, blocks.KICKED_EXCLUDED, { - getToBeKicked: () => Q([ - { pubkey: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd' }, - { pubkey: 'G2CBgZBPLe6FSFUgpx2Jf1Aqsgta6iib3vmDRA1yLiqU' } - ]) - }, function (err) { - should.not.exist(err); - })); - it('a block with kicked members not well written under Excluded field should fail', test(rules.GLOBAL.checkKickedMembersAreExcluded, blocks.KICKED_EXCLUDED, { - getToBeKicked: () => Q([ - { pubkey: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd' }, - { pubkey: 'G2CBgZBPLe6FSFUgpx2Jf1Aqsgta6iib3vmDRA1yLiqU' }, - { pubkey: 'D2CBgZBPLe6FSFUgpx2Jf1Aqsgta6iib3vmDRA1yLiqU' } - ]) - }, function (err) { - should.exist(err); - err.message.should.equal('All kicked members must be present under Excluded members'); - })); - - it('a block with wrong members count should fail', test(rules.GLOBAL.checkMembersCountIsGood, blocks.WRONG_MEMBERS_COUNT, { - getCurrentBlockOrNull: () => Q(null) - }, function (err) { - should.exist(err); - err.message.should.equal('Wrong members count'); - })); - - it('a block not starting with a leading zero should fail', test(rules.GLOBAL.checkProofOfWork, blocks.NO_LEADING_ZERO, { - bcContext: { - getIssuerPersonalizedDifficulty: () => Q(8) - } - }, function (err) { - should.exist(err); - err.message.should.equal('Wrong proof-of-work level: given 0 zeros and \'F\', required was 0 zeros and an hexa char between [0-7]'); - })); - - it('a block requiring 2 leading zeros but providing less should fail', test(rules.GLOBAL.checkProofOfWork, blocks.REQUIRES_7_LEADING_ZEROS, { - bcContext: { - getIssuerPersonalizedDifficulty: () => Q(12) - } - }, function (err) { - should.exist(err); - err.message.should.equal('Wrong proof-of-work level: given 0 zeros and \'B\', required was 0 zeros and an hexa char between [0-3]'); - })); - - it('a block requiring 1 leading zeros but providing less should fail', test(rules.GLOBAL.checkProofOfWork, blocks.REQUIRES_6_LEADING_ZEROS, { - bcContext: { - getIssuerPersonalizedDifficulty: () => Q(8) - } - }, function (err) { - should.exist(err); - err.message.should.equal('Wrong proof-of-work level: given 0 zeros and \'8\', required was 0 zeros and an hexa char between [0-7]'); - })); - - it('a block requiring 1 leading zeros as first block of newcomer should succeed', test(rules.GLOBAL.checkProofOfWork, blocks.FIRST_BLOCK_OF_NEWCOMER, { - bcContext: { - getIssuerPersonalizedDifficulty: () => Q(1) - } - }, function (err) { - should.not.exist(err); - })); - - it('a block requiring 40 leading zeros as second block of newcomer should fail', test(rules.GLOBAL.checkProofOfWork, blocks.SECOND_BLOCK_OF_NEWCOMER, { - bcContext: { - getIssuerPersonalizedDifficulty: () => Q(160) - } - }, function (err) { - should.exist(err); - err.message.should.equal('Wrong proof-of-work level: given 0 zeros and \'F\', required was 10 zeros and an hexa char between [0-9A-F]'); - })); - - it('a root block should not fail for time reason', test(rules.GLOBAL.checkTimes, blocks.WRONG_ROOT_DATES, { - getCurrentBlockOrNull: () => Q(null) - }, function (err) { - should.not.exist(err); - })); - - it('a block with wrong median for an odd number of blocks should fail', test(rules.GLOBAL.checkTimes, blocks.WRONG_MEDIAN_TIME_ODD, { - getBlocksBetween: () => Q([{time: 1},{time: 12}]) - }, function (err) { - should.exist(err); - err.message.should.equal('Wrong MedianTime'); - })); - - it('a block with wrong median for an even number of blocks should fail', test(rules.GLOBAL.checkTimes, blocks.WRONG_MEDIAN_TIME_EVEN, { - getBlocksBetween: () => Q([{time: 1},{time: 12}]) - }, function (err) { - should.exist(err); - err.message.should.equal('Wrong MedianTime'); - })); - - it('a block whose median time is correct (odd) should pass', test(rules.GLOBAL.checkTimes, blocks.GOOD_MEDIAN_TIME_ODD, { - getBlocksBetween: () => { - let times = []; - for (let i = 0; i < 103; i++) - times.push({ time: 161 }); - return Q(times); - } - }, function (err) { - should.not.exist(err); - })); - - it('a block whose median time is correct (even) should pass', test(rules.GLOBAL.checkTimes, blocks.GOOD_MEDIAN_TIME_EVEN, { - getBlocksBetween: () => { - let times = []; - for (let i = 0; i < 104; i++) - times.push({ time: 162 }); - return Q(times); - } - }, function (err) { - should.not.exist(err); - })); - - it('a root block with Universal Dividend should fail', test(rules.GLOBAL.checkUD, blocks.ROOT_BLOCK_WITH_UD, { - lastUDBlock: () => Q(null), - getBlock: () => Q(null), - getCurrentBlockOrNull: () => Q(null) - }, function (err) { - should.exist(err); - err.message.should.equal('Root block cannot have UniversalDividend field'); - })); - - it('first block with Universal Dividend should not happen before root time + dt', test(rules.GLOBAL.checkUD, blocks.FIRST_UD_BLOCK_WITH_UD_THAT_SHOULDNT, { - lastUDBlock: () => Q(null), - getBlock: () => Q({ hash: 'E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', medianTime: 1411773000, powMin: 1 }), - getCurrentBlockOrNull: () => Q({ number: 19, time: 1411773000, medianTime: 1411773000 }) - }, function (err) { - should.exist(err); - err.message.should.equal('This block cannot have UniversalDividend'); - })); - - it('first block with Universal Dividend should happen on root time + dt', test(rules.GLOBAL.checkUD, blocks.FIRST_UD_BLOCK_WITH_UD_THAT_SHOULD, { - lastUDBlock: () => Q(null), - getBlock: () => Q({ hash: 'E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', medianTime: 1411773000, powMin: 1 }), - getCurrentBlockOrNull: () => Q({ number: 19, time: 1411773000, medianTime: 1411773000 }) - }, function (err) { - should.exist(err); - err.message.should.equal('Block must have a UniversalDividend field'); - })); - - it('a block without Universal Dividend whereas it have to have one should fail', test(rules.GLOBAL.checkUD, blocks.UD_BLOCK_WIHTOUT_UD, { - lastUDBlock: () => Q(null), - getBlock: () => Q({ hash: 'E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', medianTime: 1411773000, powMin: 1 }), - getCurrentBlockOrNull: () => Q({ number: 19, time: 1411773000, medianTime: 1411773000 }) - }, function (err) { - should.exist(err); - err.message.should.equal('Block must have a UniversalDividend field'); - })); - - it('a block with wrong (version 2) Universal Dividend value should fail', test(rules.GLOBAL.checkUD, blocks.BLOCK_WITH_WRONG_UD, { - lastUDBlock: () => Q({ UDTime: 1411776900, medianTime: 1411776900, monetaryMass: 3620 * 10000, dividend: 110, unitbase: 4 }), - getBlock: () => Q(), - getCurrentBlockOrNull: () => Q({ time: 1411777000, medianTime: 1411777000 }) - }, function (err) { - should.exist(err); - err.message.should.equal('UniversalDividend must be equal to 121'); - })); - - it('a block with wrong (version 3) Universal Dividend value should fail', test(rules.GLOBAL.checkUD, blocks.BLOCK_WITH_WRONG_UD_V3, { - lastUDBlock: () => Q({ UDTime: 1411776900, medianTime: 1411776900, dividend: 110, unitbase: 4 }), - getBlock: () => Q(), - getCurrentBlockOrNull: () => Q({ time: 1411777000, medianTime: 1411777000 }) - }, function (err) { - should.exist(err); - err.message.should.equal('UniversalDividend must be equal to 121'); - })); - - it('a block with wrong UnitBase value should fail', test(rules.GLOBAL.checkUD, blocks.BLOCK_WITH_WRONG_UNIT_BASE, { - lastUDBlock: () => Q({ UDTime: 1411777000, medianTime: 1411777000, monetaryMass: 12345678900, dividend: 100, unitbase: 2 }), - getBlock: () => Q(), - getCurrentBlockOrNull: () => Q({ time: 1411777000, medianTime: 1411777000 }) - }, function (err) { - should.exist(err); - err.message.should.equal('UnitBase must be equal to 3'); - })); - - it('a block without UD with wrong UnitBase value should fail', test(rules.GLOBAL.checkUD, blocks.BLOCK_WITH_WRONG_UNIT_BASE_NO_UD, { - lastUDBlock: () => Q({ UDTime: 1411777000, medianTime: 1411777000, monetaryMass: 12345678900, dividend: 100, unitbase: 8 }), - getBlock: () => Q(), - getCurrentBlockOrNull: () => Q({ time: 1411777000, medianTime: 1411777000, unitbase: 5 }) - }, function (err) { - should.exist(err); - err.message.should.equal('UnitBase must be equal to previous unit base = 5'); - })); - - it('a root block with unlegitimated Universal Dividend presence should fail', test(rules.GLOBAL.checkUD, blocks.BLOCK_UNLEGITIMATE_UD, { - lastUDBlock: () => Q({ UDTime: 1411777000, medianTime: 1411777000, monetaryMass: 3620 * 10000, dividend: 110, unitbase: 4 }), - getBlock: () => Q(), - getCurrentBlockOrNull: () => Q({ time: 1411777000, medianTime: 1411777000 }) - }, function (err) { - should.exist(err); - err.message.should.equal('This block cannot have UniversalDividend'); - })); - - it('a root block with unlegitimated Universal Dividend presence should fail', test(rules.GLOBAL.checkUD, blocks.BLOCK_UNLEGITIMATE_UD_2, { - lastUDBlock: () => Q({ UDTime: 1411777000, medianTime: 1411777000, monetaryMass: 3620 * 10000, dividend: 110, unitbase: 4 }), - getBlock: () => Q(), - getCurrentBlockOrNull: () => Q({ time: 1411777000, medianTime: 1411777000 }) - }, function (err) { - should.exist(err); - err.message.should.equal('This block cannot have UniversalDividend'); - })); - - - it('a block without transactions should pass', test(rules.GLOBAL.checkSourcesAvailability, blocks.BLOCK_WITHOUT_TRANSACTIONS, { - getCurrentBlockOrNull: () => Q(null) - }, function (err) { - should.not.exist(err); - })); - - it('a block with good transactions should pass', test(rules.GLOBAL.checkSourcesAvailability, blocks.BLOCK_WITH_GOOD_TRANSACTIONS, { - getCurrentBlockOrNull: () => Q({ unitbase: 5 }), - getSource: (id, noffset) => { - if (id == '6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3' && noffset == 4) return Q({ amount: 0, base: 4 }); - if (id == '3A09A20E9014110FD224889F13357BAB4EC78A72F95CA03394D8CCA2936A7435' && noffset == 10) return Q({ amount: 0, base: 3 }); - if (id == 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd' && noffset == 46) return Q({ amount: 0, base: 4 }); - if (id == 'A0D9B4CDC113ECE1145C5525873821398890AE842F4B318BD076095A23E70956' && noffset == 66) return Q({ amount: 235, base: 4 }); - if (id == '67F2045B5318777CC52CD38B424F3E40DDA823FA0364625F124BABE0030E7B5B' && noffset == 176) return Q({ amount: 0, base: 4 }); - return Q(null); - } - }, function (err) { - should.not.exist(err); - })); - - it('a block with wrong transaction sum should fail', test(rules.GLOBAL.checkSourcesAvailability, blocks.BLOCK_WITH_WRONG_TRANSACTION_SUMS, { - getCurrentBlockOrNull: () => Q({ unitbase: 5 }), - getSource: (id, noffset) => { - if (id == '6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3' && noffset == 4) return Q({ amount: 0, base: 4 }); - if (id == '3A09A20E9014110FD224889F13357BAB4EC78A72F95CA03394D8CCA2936A7435' && noffset == 10) return Q({ amount: 0, base: 3 }); - if (id == 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd' && noffset == 46) return Q({ amount: 0, base: 4 }); - if (id == 'A0D9B4CDC113ECE1145C5525873821398890AE842F4B318BD076095A23E70956' && noffset == 66) return Q({ amount: 235, base: 4 }); - if (id == '67F2045B5318777CC52CD38B424F3E40DDA823FA0364625F124BABE0030E7B5B' && noffset == 176) return Q({ amount: 0, base: 4 }); - return Q(null); - } - }, function (err) { - should.exist(err); - err.uerr.message.should.equal('Sum of inputs must equal sum of outputs'); - })); - - it('a block with wrong transaction unit bases should fail', test(rules.GLOBAL.checkSourcesAvailability, blocks.BLOCK_WITH_WRONG_TRANSACTION_SUMS, { - getCurrentBlockOrNull: () => Q({ unitbase: 5 }), - getSource: (id, noffset) => { - if (id == '6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3' && noffset == 4) return Q({ amount: 0, base: 4 }); - if (id == '3A09A20E9014110FD224889F13357BAB4EC78A72F95CA03394D8CCA2936A7435' && noffset == 10) return Q({ amount: 0, base: 3 }); - if (id == 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd' && noffset == 46) return Q({ amount: 0, base: 4 }); - if (id == 'A0D9B4CDC113ECE1145C5525873821398890AE842F4B318BD076095A23E70956' && noffset == 66) return Q({ amount: 235, base: 4 }); - if (id == '67F2045B5318777CC52CD38B424F3E40DDA823FA0364625F124BABE0030E7B5B' && noffset == 176) return Q({ amount: 0, base: 4 }); - return Q(null); - } - }, function (err) { - should.exist(err); - err.uerr.message.should.equal('Sum of inputs must equal sum of outputs'); - })); - - it('a block with whose transaction has too high unit bases should fail', test(rules.GLOBAL.checkSourcesAvailability, blocks.BLOCK_WITH_WRONG_TRANSACTION_UNIT_BASES, { - getCurrentBlockOrNull: () => Q({ unitbase: 2 }), - getSource: (id, noffset) => { - if (id == '6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3' && noffset == 4) return Q({ amount: 0, base: 4 }); - if (id == '3A09A20E9014110FD224889F13357BAB4EC78A72F95CA03394D8CCA2936A7435' && noffset == 10) return Q({ amount: 0, base: 3 }); - if (id == 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd' && noffset == 46) return Q({ amount: 0, base: 4 }); - if (id == 'A0D9B4CDC113ECE1145C5525873821398890AE842F4B318BD076095A23E70956' && noffset == 66) return Q({ amount: 235, base: 4 }); - if (id == '67F2045B5318777CC52CD38B424F3E40DDA823FA0364625F124BABE0030E7B5B' && noffset == 176) return Q({ amount: 0, base: 4 }); - return Q(null); - } - }, function (err) { - should.exist(err); - err.uerr.message.should.equal('Wrong unit base for outputs'); - })); - - it('a block with unavailable UD source should fail', test(rules.GLOBAL.checkSourcesAvailability, blocks.BLOCK_WITH_UNAVAILABLE_UD_SOURCE, { - getCurrentBlockOrNull: () => Q({ unitbase: 5 }), - getSource: (id, noffset) => { - if (id == '6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3' && noffset == 4) return Q({ amount: 0, base: 4 }); - if (id == '3A09A20E9014110FD224889F13357BAB4EC78A72F95CA03394D8CCA2936A7435' && noffset == 10) return Q({ amount: 0, base: 3 }); - if (id == 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd' && noffset == 46) return Q({ amount: 0, base: 4 }); - if (id == 'A0D9B4CDC113ECE1145C5525873821398890AE842F4B318BD076095A23E70956' && noffset == 66) return Q({ amount: 235, base: 4 }); - if (id == '67F2045B5318777CC52CD38B424F3E40DDA823FA0364625F124BABE0030E7B5B' && noffset == 176) return Q({ amount: 0, base: 4 }); - return Q(null); - } - }, function (err) { - should.exist(err); - err.should.have.property('uerr').property('message').equal('Source already consumed'); - })); - - it('a block with unavailable TX source should fail', test(rules.GLOBAL.checkSourcesAvailability, blocks.BLOCK_WITH_UNAVAILABLE_TX_SOURCE, { - getCurrentBlockOrNull: () => Q({ unitbase: 5 }), - getSource: (id, noffset) => { - if (id == '6991C993631BED4733972ED7538E41CCC33660F554E3C51963E2A0AC4D6453D3' && noffset == 4) return Q({ amount: 0, base: 4 }); - if (id == '3A09A20E9014110FD224889F13357BAB4EC78A72F95CA03394D8CCA2936A7435' && noffset == 10) return Q({ amount: 0, base: 3 }); - if (id == 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd' && noffset == 46) return Q({ amount: 0, base: 4 }); - if (id == 'A0D9B4CDC113ECE1145C5525873821398890AE842F4B318BD076095A23E70956' && noffset == 66) return Q({ amount: 235, base: 4 }); - if (id == '67F2045B5318777CC52CD38B424F3E40DDA823FA0364625F124BABE0030E7B5B' && noffset == 176) return Q({ amount: 0, base: 4 }); - return Q(null); - } - }, function (err) { - should.exist(err); - err.should.have.property('uerr').property('message').equal('Source already consumed'); - })); - - it('a block with a too high unit base should fail', test(rules.GLOBAL.checkSourcesAvailability, blocks.BLOCK_TX_V3_TOO_HIGH_OUTPUT_BASE, { - getCurrentBlockOrNull: () => Q({ unitbase: 3 }), - getSource: () => Q({ base: 1, amount: 10 }) - }, function (err) { - should.exist(err); - err.should.have.property('uerr').property('message').equal('Wrong unit base for outputs'); - })); - - it('a block with an unknown member revoked should fail', test(rules.GLOBAL.checkRevoked, blocks.BLOCK_UNKNOWN_REVOKED, { - getWrittenIdtyByPubkey: () => Q(null) - }, function (err) { - should.exist(err); - err.message.should.equal('A pubkey who was never a member cannot be revoked'); - })); - - it('a block with a yet revoked identity should fail', test(rules.GLOBAL.checkRevoked, blocks.BLOCK_WITH_YET_REVOKED, { - getWrittenIdtyByPubkey: () => Q({ revoked: true }) - }, function (err) { - should.exist(err); - err.message.should.equal('A revoked identity cannot be revoked again'); - })); - - it('a block with a wrong revocation signature should fail', test(rules.GLOBAL.checkRevoked, blocks.BLOCK_WITH_WRONG_REVOCATION_SIG, { - getWrittenIdtyByPubkey: () => Q({}) - }, function (err) { - should.exist(err); - err.message.should.equal('Revocation signature must match'); - })); -}); - -function test (rule, raw, dal, callback) { - return function() { - return co(function *() { - let obj = parser.syncWrite(raw); - let block = new Block(obj); - if (rule == rules.GLOBAL.checkProofOfWork || rule == rules.GLOBAL.checkVersion) { - yield rule(block, dal.bcContext); - } else if (rule.length == 2) { - yield rule(block, dal); - } else { - yield rule(block, conf, dal); - } - }) - .then(callback).catch(callback); - }; -} - -function validate (raw, dal, bcContext, callback) { - var block; - return function() { - return Q.Promise(function(resolve, reject){ - async.waterfall([ - function (next){ - block = new Block(parser.syncWrite(raw)); - rules.CHECK.ASYNC.ALL_GLOBAL(block, conf, dal, bcContext, next); - } - ], function (err) { - err && console.error(err.stack); - err ? reject(err) : resolve(); - }); - }) - .then(callback).catch(callback); - }; -} diff --git a/test/fast/v1.0-local-index.js b/test/fast/index/v1.0-local-index.ts similarity index 78% rename from test/fast/v1.0-local-index.js rename to test/fast/index/v1.0-local-index.ts index 04772abb104223417a4029af2def869b030eed81..acfc7bcc05dba73aca70d214528795e3c42ca9d2 100644 --- a/test/fast/v1.0-local-index.js +++ b/test/fast/index/v1.0-local-index.ts @@ -11,14 +11,13 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {BlockDTO} from "../../../app/lib/dto/BlockDTO" +import {parsers} from "../../../app/lib/common-libs/parsers/index" +import {CommonConstants} from "../../../app/lib/common-libs/constants" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {IndexEntry, Indexer} from "../../../app/lib/indexer" -const _ = require('underscore'); const should = require('should'); -const parsers = require('../../app/lib/common-libs/parsers').parsers -const indexer = require('../../app/lib/indexer').Indexer -const constants = require('../../app/lib/common-libs/constants').CommonConstants -const BlockDTO = require('../../app/lib/dto/BlockDTO').BlockDTO const raw = "Version: 10\n" + "Type: Block\n" + @@ -94,11 +93,18 @@ const raw = "Version: 10\n" + describe("v1.0 Local Index", function(){ - let block, index; + let block, index:IndexEntry[] before(() => { block = parsers.parseBlock.syncWrite(raw); - index = indexer.localIndex(BlockDTO.fromJSONObject(block), { sigValidity: 100, msValidity: 40 }); + index = Indexer.localIndex(BlockDTO.fromJSONObject(block), { + sigValidity: 100, + msValidity: 40, + // We don't care about these in this test + msPeriod: 0, + sigPeriod: 0, + sigStock: 0 + }); }); it('should have 30 index entries', () => { @@ -110,15 +116,15 @@ describe("v1.0 Local Index", function(){ ********/ it('should have 4 iindex entries', () => { - _(index).where({ index: constants.I_INDEX}).should.have.length(4); + Underscore.where(index, { index: CommonConstants.I_INDEX}).should.have.length(4); }); it('should have 1 iindex CREATE entries', () => { - _(index).where({ index: constants.I_INDEX, op: constants.IDX_CREATE }).should.have.length(1); + Underscore.where(index, { index: CommonConstants.I_INDEX, op: CommonConstants.IDX_CREATE }).should.have.length(1); }); it('should have 3 iindex UPDATE entries', () => { - _(index).where({ index: constants.I_INDEX, op: constants.IDX_UPDATE }).should.have.length(3); + Underscore.where(index, { index: CommonConstants.I_INDEX, op: CommonConstants.IDX_UPDATE }).should.have.length(3); }); /********* @@ -126,15 +132,15 @@ describe("v1.0 Local Index", function(){ ********/ it('should have 5 mindex entries', () => { - _(index).where({ index: constants.M_INDEX}).should.have.length(5); + Underscore.where(index, { index: CommonConstants.M_INDEX}).should.have.length(5); }); it('should have 1 mindex CREATE entries', () => { - _(index).where({ index: constants.M_INDEX, op: constants.IDX_CREATE }).should.have.length(1); + Underscore.where(index, { index: CommonConstants.M_INDEX, op: CommonConstants.IDX_CREATE }).should.have.length(1); }); it('should have 4 mindex UPDATE entries', () => { - _(index).where({ index: constants.M_INDEX, op: constants.IDX_UPDATE }).should.have.length(4); + Underscore.where(index, { index: CommonConstants.M_INDEX, op: CommonConstants.IDX_UPDATE }).should.have.length(4); }); /********* @@ -142,15 +148,15 @@ describe("v1.0 Local Index", function(){ ********/ it('should have 5 cindex entries', () => { - _(index).where({ index: constants.C_INDEX}).should.have.length(5); + Underscore.where(index, { index: CommonConstants.C_INDEX}).should.have.length(5); }); it('should have 5 cindex CREATE entries', () => { - _(index).where({ index: constants.C_INDEX, op: constants.IDX_CREATE }).should.have.length(5); + Underscore.where(index, { index: CommonConstants.C_INDEX, op: CommonConstants.IDX_CREATE }).should.have.length(5); }); it('should have 0 cindex UPDATE entries', () => { - _(index).where({ index: constants.C_INDEX, op: constants.IDX_UPDATE }).should.have.length(0); + Underscore.where(index, { index: CommonConstants.C_INDEX, op: CommonConstants.IDX_UPDATE }).should.have.length(0); }); /********* @@ -158,15 +164,15 @@ describe("v1.0 Local Index", function(){ ********/ it('should have 16 cindex entries', () => { - _(index).where({ index: constants.S_INDEX}).should.have.length(16); + Underscore.where(index, { index: CommonConstants.S_INDEX}).should.have.length(16); }); it('should have 9 cindex CREATE entries', () => { - _(index).where({ index: constants.S_INDEX, op: constants.IDX_CREATE }).should.have.length(9); + Underscore.where(index, { index: CommonConstants.S_INDEX, op: CommonConstants.IDX_CREATE }).should.have.length(9); }); it('should have 7 cindex UPDATE entries', () => { - _(index).where({ index: constants.S_INDEX, op: constants.IDX_UPDATE }).should.have.length(7); + Underscore.where(index, { index: CommonConstants.S_INDEX, op: CommonConstants.IDX_UPDATE }).should.have.length(7); }); }); diff --git a/test/fast/modules/crawler/block_pulling.ts b/test/fast/modules/crawler/block_pulling.ts index 0abac92c7567089dd57e9b17bdd75c285c260a37..fcb3a0b0a4449ae10c55b58f1ae66078dd4fdafc 100644 --- a/test/fast/modules/crawler/block_pulling.ts +++ b/test/fast/modules/crawler/block_pulling.ts @@ -14,9 +14,9 @@ import {AbstractDAO} from "../../../../app/modules/crawler/lib/pulling" import {BlockDTO} from "../../../../app/lib/dto/BlockDTO" import {NewLogger} from "../../../../app/lib/logger" +import {Underscore} from "../../../../app/lib/common-libs/underscore" const should = require('should'); -const _ = require('underscore'); let commonConf = { switchOnHeadAdvance: 1, @@ -240,7 +240,7 @@ class mockDao extends AbstractDAO { let block = bc[number] || null; // Quantum block implementation if (block && block.quantum) { - bc[number] = _.clone(block); + bc[number] = Underscore.clone(block); bc[number].hash = 'Q' + block.hash; } return block; diff --git a/test/fast/protocol-local-rule-chained-tx-depth.ts b/test/fast/protocol-local-rule-chained-tx-depth.ts index 398f9a999cb0e0080644653f5496115d3f2d2675..7ae6e642cc8b9913ccc0bce5efd36312e5ec732b 100644 --- a/test/fast/protocol-local-rule-chained-tx-depth.ts +++ b/test/fast/protocol-local-rule-chained-tx-depth.ts @@ -13,7 +13,6 @@ import {LOCAL_RULES_HELPERS} from "../../app/lib/rules/local_rules" -const _ = require('underscore') const assert = require('assert') describe("Protocol BR_G110 - chained tx depth", () => { diff --git a/test/integration/collapse.js b/test/integration/blocks/community-collapse.ts similarity index 66% rename from test/integration/collapse.js rename to test/integration/blocks/community-collapse.ts index 974790da99cf8170ec0016a0bed76e93721171f5..cb376d803701ef8f6df18eeb8d83721cd73f8ab9 100644 --- a/test/integration/collapse.js +++ b/test/integration/blocks/community-collapse.ts @@ -11,16 +11,13 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {TestUser} from "../tools/TestUser" +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {BmaDependency} from "../../../app/modules/bma/index" +import {Underscore} from "../../../app/lib/common-libs/underscore" -const co = require('co'); -const _ = require('underscore'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const TestUser = require('./tools/TestUser').TestUser -const commit = require('./tools/commit'); -const httpTest = require('./tools/http'); -const shutDownEngine = require('./tools/shutDownEngine'); +const httpTest = require('../tools/http'); +const shutDownEngine = require('../tools/shutDownEngine'); const rp = require('request-promise'); const MEMORY_MODE = true; @@ -32,18 +29,18 @@ const commonConf = { sigQty: 1 }; -let s1, cat, tac +let s1:TestingServer, cat:TestUser, tac:TestUser describe("Community collapse", function() { const now = Math.round(Date.now() / 1000); - before(function() { + before(async () => { - s1 = duniter( - '/bb11', - MEMORY_MODE, - _.extend({ + s1 = NewTestingServer( + Underscore.extend({ + name: 'bb11', + memory: MEMORY_MODE, port: '9340', pair: { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', @@ -56,19 +53,17 @@ describe("Community collapse", function() { cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); tac = new TestUser('tac', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s1 }); - return co(function *() { - yield s1.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); - yield cat.createIdentity(); - yield tac.createIdentity(); - yield cat.join(); - yield tac.join(); - yield cat.cert(tac); - yield tac.cert(cat); - yield commit(s1)({ time: now }); - yield commit(s1)({ time: now + 10 }); - yield commit(s1)({ time: now + 10 }); - yield commit(s1)({ time: now + 10 }); - }); + await s1.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); + await cat.createIdentity(); + await tac.createIdentity(); + await cat.join(); + await tac.join(); + await cat.cert(tac); + await tac.cert(cat); + await s1.commit({ time: now }); + await s1.commit({ time: now + 10 }); + await s1.commit({ time: now + 10 }); + await s1.commit({ time: now + 10 }); }); after(() => { diff --git a/test/integration/blocks/start-generate-blocks.ts b/test/integration/blocks/start-generate-blocks.ts new file mode 100644 index 0000000000000000000000000000000000000000..583e9c972cbdff75012a24bc2358c5ac2aa21bc8 --- /dev/null +++ b/test/integration/blocks/start-generate-blocks.ts @@ -0,0 +1,143 @@ +// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 +// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +import {PeerDTO} from "../../../app/lib/dto/PeerDTO" +import {BmaDependency} from "../../../app/modules/bma/index" +import {CrawlerDependency} from "../../../app/modules/crawler/index" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {NewTestingServer, serverWaitBlock, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {RouterDependency} from "../../../app/modules/router" +import {ProverDependency} from "../../../app/modules/prover/index" + +const rp = require('request-promise'); +const httpTest = require('../tools/http'); +const until = require('../tools/until'); +const sync = require('../tools/sync'); +const shutDownEngine = require('../tools/shutDownEngine'); + +const expectJSON = httpTest.expectJSON; + +const MEMORY_MODE = true; +const commonConf = { + bmaWithCrawler: true, + ipv4: '127.0.0.1', + remoteipv4: '127.0.0.1', + currency: 'bb', + httpLogs: true, + forksize: 0, + sigQty: 1 +}; + +let s1:TestingServer, s2:TestingServer, cat:TestUser, toc:TestUser, tic:TestUser, tuc:TestUser + +let nodeS1; +let nodeS2; + +describe("Generation", function() { + + before(async () => { + + s1 = NewTestingServer( + Underscore.extend({ + name: 'bb7', + memory: MEMORY_MODE, + port: '7790', + pair: { + pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', + sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' + }, + powDelay: 1 + }, commonConf)); + + s2 = NewTestingServer( + Underscore.extend({ + name: 'bb7_2', + memory: MEMORY_MODE, + port: '7791', + pair: { + pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', + sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F' + }, + powDelay: 1 + }, commonConf)); + + cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); + toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); + tic = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s1 }); + tuc = new TestUser('tuc', { pub: '3conGDUXdrTGbQPMQQhEC4Ubu1MCAnFrAYvUaewbUhtk', sec: '5ks7qQ8Fpkin7ycXpxQSxxjVhs8VTzpM3vEBMqM7NfC1ZiFJ93uQryDcoM93Mj77T6hDAABdeHZJDFnkDb35bgiU'}, { server: s1 }); + + let servers = [s1, s2]; + for (const server of servers) { + server._server.addEndpointsDefinitions(() => BmaDependency.duniter.methods.getMainEndpoint(server.conf)) + await server.initWithDAL(); + server.bma = await BmaDependency.duniter.methods.bma(server._server); + await server.bma.openConnections(); + RouterDependency.duniter.methods.routeToNetwork(server._server); + await server.PeeringService.generateSelfPeer(server.conf); + const prover = ProverDependency.duniter.methods.prover(server._server) + server.startBlockComputation = () => prover.startService(); + server.stopBlockComputation = () => prover.stopService(); + } + nodeS1 = CrawlerDependency.duniter.methods.contacter('127.0.0.1', s1.conf.port); + nodeS2 = CrawlerDependency.duniter.methods.contacter('127.0.0.1', s2.conf.port); + // Server 1 + await cat.createIdentity(); + await toc.createIdentity(); + await toc.cert(cat); + await cat.cert(toc); + await cat.join(); + await toc.join(); + await s1.commit(); + // Server 2 syncs block 0 + await sync(0, 0, s1, s2); + // Let each node know each other + let peer1 = await nodeS1.getPeer(); + await nodeS2.postPeer(PeerDTO.fromJSONObject(peer1).getRawSigned()); + let peer2 = await nodeS2.getPeer(); + await nodeS1.postPeer(PeerDTO.fromJSONObject(peer2).getRawSigned()); + s1.startBlockComputation(); + await until(s2, 'block', 1); + s2.startBlockComputation(); + s1.conf.powDelay = 2000; + s2.conf.powDelay = 2000; + await Promise.all([ + serverWaitBlock(s1._server, 3), + serverWaitBlock(s2._server, 3) + ]) + s1.stopBlockComputation(); + s2.stopBlockComputation(); + }); + + after(() => { + return Promise.all([ + shutDownEngine(s1), + shutDownEngine(s2) + ]) + }) + + describe("Server 1 /blockchain", function() { + + it('/current should exist', function() { + return expectJSON(rp('http://127.0.0.1:7790/blockchain/current', { json: true }), { + number: 3 + }); + }); + + it('/current should exist on other node too', function() { + return expectJSON(rp('http://127.0.0.1:7791/blockchain/current', { json: true }), { + number: 3 + }); + }); + }); +}); diff --git a/test/integration/branches2.ts b/test/integration/branches/branches2.ts similarity index 90% rename from test/integration/branches2.ts rename to test/integration/branches/branches2.ts index 5ca0a684cc602bf7a790571614fc59d52673881f..4e12085b10c267e9a62caa6c037c32097102874c 100644 --- a/test/integration/branches2.ts +++ b/test/integration/branches/branches2.ts @@ -11,22 +11,23 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -import {OtherConstants} from "../../app/lib/other_constants" -import {NewLogger} from "../../app/lib/logger" -import {BmaDependency} from "../../app/modules/bma/index" -import {CrawlerDependency} from "../../app/modules/crawler/index" -import {waitForkResolution, waitToHaveBlock} from "./tools/toolbox" -import {TestUser} from "./tools/TestUser"; + +import {BmaDependency} from "../../../app/modules/bma/index" +import {OtherConstants} from "../../../app/lib/other_constants" +import {NewLogger} from "../../../app/lib/logger" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {waitForkResolution, waitToHaveBlock} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {CrawlerDependency} from "../../../app/modules/crawler/index" const co = require('co'); -const _ = require('underscore'); -const duniter = require('../../index'); +const duniter = require('../../../index'); const bma = BmaDependency.duniter.methods.bma; const rp = require('request-promise'); -const httpTest = require('./tools/http'); -const commit = require('./tools/commit'); -const sync = require('./tools/sync'); -const shutDownEngine = require('./tools/shutDownEngine'); +const httpTest = require('../tools/http'); +const commit = require('../tools/commit'); +const sync = require('../tools/sync'); +const shutDownEngine = require('../tools/shutDownEngine'); const expectJSON = httpTest.expectJSON; const expectHttpCode = httpTest.expectHttpCode; @@ -63,7 +64,7 @@ describe("SelfFork", function() { s1 = duniter( '/bb4', MEMORY_MODE, - _.extend({ + Underscore.extend({ port: '7781', pair: { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', @@ -74,7 +75,7 @@ describe("SelfFork", function() { s2 = duniter( '/bb5', MEMORY_MODE, - _.extend({ + Underscore.extend({ port: '7782', pair: { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', diff --git a/test/integration/branches_pending_data.js b/test/integration/branches/branches_pending_data.ts similarity index 67% rename from test/integration/branches_pending_data.js rename to test/integration/branches/branches_pending_data.ts index e4fe8f9c3d16065f1d83a04c2a3469dcf43ddcef..1b8930d8e004194d3e74697f0d10a70ce5998a0e 100644 --- a/test/integration/branches_pending_data.js +++ b/test/integration/branches/branches_pending_data.ts @@ -11,17 +11,14 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {BmaDependency} from "../../../app/modules/bma/index" -const co = require('co'); -const _ = require('underscore'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const TestUser = require('./tools/TestUser').TestUser const rp = require('request-promise'); -const httpTest = require('./tools/http'); -const commit = require('./tools/commit'); -const shutDownEngine = require('./tools/shutDownEngine'); +const httpTest = require('../tools/http'); +const shutDownEngine = require('../tools/shutDownEngine'); const expectJSON = httpTest.expectJSON; const expectAnswer = httpTest.expectAnswer; @@ -35,50 +32,45 @@ const commonConf = { sigQty: 1 }; -let s1, cat, toc, tic, tuc +let s1:TestingServer, cat:TestUser, toc:TestUser, tic:TestUser, tuc:TestUser describe("Pending data", function() { - before(function() { + before(async () => { - s1 = duniter( - '/bb6', - MEMORY_MODE, - _.extend({ - port: '7783', - pair: { - pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', - sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' - } - }, commonConf)); + s1 = NewTestingServer(Underscore.extend({ + memory: MEMORY_MODE, + name: 'bb6', + port: '7783', + pair: { + pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', + sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' + } + }, commonConf)); cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); tic = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s1 }); tuc = new TestUser('tuc', { pub: '3conGDUXdrTGbQPMQQhEC4Ubu1MCAnFrAYvUaewbUhtk', sec: '5ks7qQ8Fpkin7ycXpxQSxxjVhs8VTzpM3vEBMqM7NfC1ZiFJ93uQryDcoM93Mj77T6hDAABdeHZJDFnkDb35bgiU'}, { server: s1 }); - const commitS1 = commit(s1); - - return co(function *() { - yield s1.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); - yield cat.createIdentity(); - yield toc.createIdentity(); - yield toc.cert(cat); - yield cat.cert(toc); - yield cat.join(); - yield toc.join(); - yield commitS1(); - yield commitS1(); - yield tic.createIdentity(); - yield cat.cert(tic); - yield toc.cert(tic); - yield tuc.createIdentity(); - yield tuc.join(); - yield commitS1(); - yield commitS1(); - yield commitS1(); - yield commitS1(); - }); + await s1.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); + await cat.createIdentity(); + await toc.createIdentity(); + await toc.cert(cat); + await cat.cert(toc); + await cat.join(); + await toc.join(); + await s1.commit(); + await s1.commit(); + await tic.createIdentity(); + await cat.cert(tic); + await toc.cert(tic); + await tuc.createIdentity(); + await tuc.join(); + await s1.commit(); + await s1.commit(); + await s1.commit(); + await s1.commit(); }); after(() => { @@ -96,7 +88,7 @@ describe("Pending data", function() { }); it('should have forwarded pending identities + ceritifications of tic', function() { - return expectAnswer(rp('http://127.0.0.1:7783/wot/lookup/tic', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7783/wot/lookup/tic', { json: true }), function(res:any) { res.should.have.property('results').length(1); res.results[0].should.have.property('uids').length(1); res.results[0].uids[0].should.have.property('others').length(2); @@ -104,7 +96,7 @@ describe("Pending data", function() { }); it('should have forwarded pending identities + ceritifications of tuc', function() { - return expectAnswer(rp('http://127.0.0.1:7783/wot/lookup/tuc', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7783/wot/lookup/tuc', { json: true }), function(res:any) { res.should.have.property('results').length(1); res.results[0].should.have.property('uids').length(1); res.results[0].uids[0].should.have.property('others').length(0); diff --git a/test/integration/branches/branches_revert.ts b/test/integration/branches/branches_revert.ts new file mode 100644 index 0000000000000000000000000000000000000000..55c284a4358cf44e51d56227564668165321f27b --- /dev/null +++ b/test/integration/branches/branches_revert.ts @@ -0,0 +1,75 @@ +// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 +// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {Underscore} from "../../../app/lib/common-libs/underscore" + +const commonConf = { + ipv4: '127.0.0.1', + currency: 'bb', + httpLogs: true, + forksize: 3, + sigQty: 1 +}; + +let s1:TestingServer, cat, toc + +describe("Revert root", function() { + + before(async () => { + + s1 = NewTestingServer(Underscore.extend({ + pair: { + pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', + sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' + }, + rootoffset: 10, + sigQty: 1, dt: 1, ud0: 120 + }, commonConf)); + + cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); + toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); + + await s1.initDalBmaConnections(); + await cat.createIdentity(); + await toc.createIdentity(); + await toc.cert(cat); + await cat.cert(toc); + await cat.join(); + await toc.join(); + await s1.commit() + }) + + it('/block/0 should exist', () => s1.expectJSON('/blockchain/block/0', { + number: 0 + })); + + it('/wot/cat should exist', () => s1.expectThat('/wot/lookup/cat', (res:any) => { + res.should.have.property('results').length(1); + res.results[0].should.have.property('uids').length(1); + res.results[0].uids[0].should.have.property('uid').equal('cat'); + res.results[0].uids[0].should.have.property('others').length(1); + })) + + it('reverting should erase everything', async () => { + await s1.revert(); + await s1.expectError('/blockchain/current', 404, 'No current block'); + await s1.expectError('/blockchain/block/0', 404, 'Block not found'); + await s1.expectError('/wot/lookup/cat', 404, 'No matching identity'); // Revert completely removes the identity + }) + + after(() => { + return s1.closeCluster() + }) +}) diff --git a/test/integration/branches_revert2.js b/test/integration/branches/branches_revert2.ts similarity index 80% rename from test/integration/branches_revert2.js rename to test/integration/branches/branches_revert2.ts index cb268cc9113920acc5744c0ed7bf31fae002f1f5..9eb046e4fb8e892eb69d28d1b5d6a0a41186896e 100644 --- a/test/integration/branches_revert2.js +++ b/test/integration/branches/branches_revert2.ts @@ -11,20 +11,20 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {BmaDependency} from "../../../app/modules/bma/index" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {ProverConstants} from "../../../app/modules/prover/lib/constants" -const co = require('co'); -const _ = require('underscore'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const TestUser = require('./tools/TestUser').TestUser +const duniter = require('../../../index'); const rp = require('request-promise'); -const httpTest = require('./tools/http'); -const commit = require('./tools/commit'); -const shutDownEngine = require('./tools/shutDownEngine'); +const httpTest = require('../tools/http'); +const commit = require('../tools/commit'); +const shutDownEngine = require('../tools/shutDownEngine'); -require('../../app/modules/prover/lib/constants').ProverConstants.CORES_MAXIMUM_USE_IN_PARALLEL = 1 -require('../../app/modules/bma').BmaDependency.duniter.methods.noLimit(); // Disables the HTTP limiter +ProverConstants.CORES_MAXIMUM_USE_IN_PARALLEL = 1 +BmaDependency.duniter.methods.noLimit(); // Disables the HTTP limiter const expectJSON = httpTest.expectJSON; const expectHttpCode = httpTest.expectHttpCode; @@ -42,16 +42,16 @@ const commonConf = { sigQty: 1 }; -let s1, cat, toc +let s1:TestingServer, cat:TestUser, toc:TestUser describe("Revert two blocks", function() { - before(function() { + before(async () => { s1 = duniter( '/bb11', MEMORY_MODE, - _.extend({ + Underscore.extend({ port: '7712', pair: { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', @@ -66,20 +66,18 @@ describe("Revert two blocks", function() { cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); - return co(function *() { - yield s1.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); - yield cat.createIdentity(); - yield toc.createIdentity(); - yield toc.cert(cat); - yield cat.cert(toc); - yield cat.join(); - yield toc.join(); - yield commit(s1)({ time: now }); - yield commit(s1)({ time: now + 1 }); - yield commit(s1)({ time: now + 1 }); - yield cat.sendP(51, toc); - yield commit(s1)({ time: now + 1 }); - }); + await s1.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); + await cat.createIdentity(); + await toc.createIdentity(); + await toc.cert(cat); + await cat.cert(toc); + await cat.join(); + await toc.join(); + await commit(s1)({ time: now }); + await commit(s1)({ time: now + 1 }); + await commit(s1)({ time: now + 1 }); + await cat.sendP(51, toc); + await commit(s1)({ time: now + 1 }); }); after(() => { @@ -111,14 +109,14 @@ describe("Revert two blocks", function() { }); it('/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd should have only UD', function() { - return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'), (body) => { + return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'), (body:string) => { let res = JSON.parse(body); res.sources.should.have.length(0) }); }); it('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo should have only UD', function() { - return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'), (body) => { + return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'), (body:string) => { let res = JSON.parse(body); res.sources.should.have.length(2); res.sources[0].should.have.property('identifier').equal('DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'); @@ -133,7 +131,7 @@ describe("Revert two blocks", function() { }); it('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV should have only UD', function() { - return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV'), (body) => { + return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV'), (body:string) => { let res = JSON.parse(body); res.sources.should.have.length(0); }); @@ -142,9 +140,9 @@ describe("Revert two blocks", function() { describe("after revert", () => { - before(() => co(function*() { - yield s1.revert(); - })) + before(async () => { + await s1.revert(); + }) it('/block/0 should exist', function() { return expectJSON(rp('http://127.0.0.1:7712/blockchain/block/0', { json: true }), { @@ -164,7 +162,7 @@ describe("Revert two blocks", function() { }); it('/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd should have only UD', function() { - return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'), (body) => { + return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'), (body:string) => { let res = JSON.parse(body); res.sources.should.have.length(1); res.sources[0].should.have.property('identifier').equal('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); @@ -175,7 +173,7 @@ describe("Revert two blocks", function() { }); it('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo should have only UD', function() { - return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'), (body) => { + return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'), (body:string) => { let res = JSON.parse(body); res.sources.should.have.length(1); res.sources[0].should.have.property('identifier').equal('DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'); @@ -186,7 +184,7 @@ describe("Revert two blocks", function() { }); it('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV should have only UD', function() { - return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV'), (body) => { + return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV'), (body:string) => { let res = JSON.parse(body); res.sources.should.have.length(0); }); @@ -195,12 +193,12 @@ describe("Revert two blocks", function() { describe("commit again (but send less, to check that the account is not cleaned this time)", () => { - before(() => co(function*() { - yield s1.dal.txsDAL.removeAll() - yield cat.sendP(19, toc); - yield s1.dal.blockDAL.removeBlock('DELETE FROM block WHERE fork AND number = 3') - yield commit(s1)({ time: now + 1 }); - })) + before(async () => { + await s1.dal.txsDAL.removeAll() + await cat.sendP(19, toc); + await s1.dal.blockDAL.removeBlock('DELETE FROM block WHERE fork AND number = 3') + await commit(s1)({ time: now + 1 }); + }) it('/block/0 should exist', function() { return expectJSON(rp('http://127.0.0.1:7712/blockchain/block/0', { json: true }), { @@ -223,7 +221,7 @@ describe("Revert two blocks", function() { }); it('/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd should have only UD', function() { - return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'), (body) => { + return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'), (body:string) => { let res = JSON.parse(body); res.sources.should.have.length(1); res.sources[0].should.have.property('identifier').equal('7F951D4B73FB65995A1F343366A8CD3B0C76028120FD590170B251EB109926FB'); @@ -234,7 +232,7 @@ describe("Revert two blocks", function() { }); it('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo should have only UD', function() { - return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'), (body) => { + return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'), (body:string) => { let res = JSON.parse(body); res.sources.should.have.length(2); res.sources[0].should.have.property('identifier').equal('DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'); @@ -249,7 +247,7 @@ describe("Revert two blocks", function() { }); it('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV should have only UD', function() { - return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV'), (body) => { + return expectAnswer(rp('http://127.0.0.1:7712/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV'), (body:string) => { let res = JSON.parse(body); res.sources.should.have.length(0); }); diff --git a/test/integration/branches_revert_balance.js b/test/integration/branches/branches_revert_balance.ts similarity index 51% rename from test/integration/branches_revert_balance.js rename to test/integration/branches/branches_revert_balance.ts index b32d329a335c8b55393372cfa992b17cd9d89eba..8839fb3533d72858a7ed38d47451f53765455122 100644 --- a/test/integration/branches_revert_balance.js +++ b/test/integration/branches/branches_revert_balance.ts @@ -11,16 +11,15 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict" +import {simpleNodeWith2Users, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" -const co = require('co') const should = require('should') -const toolbox = require('./tools/toolbox') describe("Revert balance", () => { const now = 1480000000 - let s1, cat, tac + let s1:TestingServer, cat:TestUser, tac:TestUser const conf = { nbCores: 1, @@ -31,65 +30,65 @@ describe("Revert balance", () => { medianTimeBlocks: 1 // The medianTime always equals previous block's medianTime } - before(() => co(function*() { - const res1 = yield toolbox.simpleNodeWith2Users(conf) + before(async () => { + const res1 = await simpleNodeWith2Users(conf) s1 = res1.s1 cat = res1.cat tac = res1.tac - yield s1.commit({ time: now }) - yield s1.commit({ time: now + 1 }) - yield s1.commit({ time: now + 1 }) - })) + await s1.commit({ time: now }) + await s1.commit({ time: now + 1 }) + await s1.commit({ time: now + 1 }) + }) - it('cat and tac should have 200 units', () => co(function*() { - yield s1.expect('/tx/sources/' + cat.pub, (res) => { + it('cat and tac should have 200 units', async () => { + await s1.expect('/tx/sources/' + cat.pub, (res:any) => { res.sources.should.have.length(2) }) - yield s1.expect('/tx/sources/' + tac.pub, (res) => { + await s1.expect('/tx/sources/' + tac.pub, (res:any) => { res.sources.should.have.length(2) }) - })) + }) - it('cat should be able to send 60 units to tac', () => co(function*() { - yield cat.send(60, tac) - yield s1.commit({ time: now + 1 }) - yield s1.expect('/tx/sources/' + cat.pub, (res) => { + it('cat should be able to send 60 units to tac', async () => { + await cat.sendMoney(60, tac) + await s1.commit({ time: now + 1 }) + await s1.expect('/tx/sources/' + cat.pub, (res:any) => { res.sources.should.have.length(2) }) - yield s1.expect('/tx/sources/' + tac.pub, (res) => { + await s1.expect('/tx/sources/' + tac.pub, (res:any) => { res.sources.should.have.length(3) }) - const block = yield s1.dal.blockDAL.getBlock(3) - // yield s1.writeBlock(block) - })) + const block = await s1.dal.blockDAL.getBlock(3) + // await s1.writeBlock(block) + }) - it('revert: cat and tac should have 100 units', () => co(function*() { - yield s1.revert(); - yield s1.expect('/tx/sources/' + cat.pub, (res) => { + it('revert: cat and tac should have 100 units', async () => { + await s1.revert(); + await s1.expect('/tx/sources/' + cat.pub, (res:any) => { res.sources.should.have.length(2) }) - yield s1.expect('/tx/sources/' + tac.pub, (res) => { + await s1.expect('/tx/sources/' + tac.pub, (res:any) => { res.sources.should.have.length(2) }) - })) + }) - it('cat should be able to RE-send 60 units to tac', () => co(function*() { - const txsPending = yield s1.dal.txsDAL.getAllPending(1) - yield s1.dal.blockDAL.removeForkBlock(3) + it('cat should be able to RE-send 60 units to tac', async () => { + const txsPending = await s1.dal.txsDAL.getAllPending(1) + await s1.dal.blockDAL.removeForkBlock(3) txsPending.should.have.length(1) - yield s1.commit({ time: now + 1 }) - yield s1.expect('/tx/sources/' + cat.pub, (res) => { + await s1.commit({ time: now + 1 }) + await s1.expect('/tx/sources/' + cat.pub, (res:any) => { // Should have 2 sources: // * the 2nd UD = 100 // * the rest of the 1st UD - the money sent (60) = 40 res.sources.should.have.length(2) }) - yield s1.expect('/tx/sources/' + tac.pub, (res) => { + await s1.expect('/tx/sources/' + tac.pub, (res:any) => { res.sources.should.have.length(3) }) - const block = yield s1.dal.blockDAL.getBlock(3) - // yield s1.writeBlock(block) - })) + const block = await s1.dal.blockDAL.getBlock(3) + // await s1.writeBlock(block) + }) after(() => { return s1.closeCluster() diff --git a/test/integration/branches/branches_revert_memberships.ts b/test/integration/branches/branches_revert_memberships.ts new file mode 100644 index 0000000000000000000000000000000000000000..fdaa44e50261dbf4fd4b9d5ef889d133b6828f77 --- /dev/null +++ b/test/integration/branches/branches_revert_memberships.ts @@ -0,0 +1,254 @@ +// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 +// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {FullIindexEntry} from "../../../app/lib/indexer" + +const should = require('should'); + +let s1:TestingServer, i1:TestUser, i2:TestUser, i3:TestUser + +describe("Revert memberships", function() { + + const now = 1482000000; + + before(async () => { + + s1 = NewTestingServer({ + memory: true, + msValidity: 14, + pair: { + pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', + sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' + } + }); + + i1 = new TestUser('i1', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); + i2 = new TestUser('i2', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s1 }); + i3 = new TestUser('i3', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); + + await s1.initDalBmaConnections(); + + await i1.createIdentity(); + await i2.createIdentity(); + + await i1.cert(i2); + await i2.cert(i1); + + await i1.join(); + await i2.join(); + + await s1.commit({ time: now }); + await s1.expect('/blockchain/current', (res:any) => { res.number.should.equal(0); (res.medianTime - now).should.equal(0); }); + await s1.commit({ time: now + 15 }); + await s1.expect('/blockchain/current', (res:any) => { res.number.should.equal(1); (res.medianTime - now).should.equal(0); }); + + await shouldHavePendingMS(0); + await i3.createIdentity(); + await i1.cert(i3); + await shouldBeFreshlyCreated(); + await i3.join(); + await shouldHavePendingMS(1); + await shouldBeJoining(); + await s1.commit({ time: now + 15 }); + await s1.expect('/blockchain/current', (res:any) => { res.number.should.equal(2); (res.medianTime - now).should.equal(7); }); + await shouldHaveJoined(); + await shouldHavePendingMS(0); + }) + + it('should exist 3 members', async () => s1.expect('/blockchain/current', (res:any) => { + res.should.have.property('membersCount').equal(3); + })) + + it('should exist a renew', async () => { + await i3.join(); // Renew + await shouldHavePendingMS(1); + await s1.commit({ time: now + 15 }); + await s1.expect('/blockchain/current', (res:any) => { res.number.should.equal(3); (res.medianTime - now).should.equal(10); }); + await s1.expect('/blockchain/current', (res:any) => { + res.should.have.property('membersCount').equal(3); + res.should.have.property('actives').length(1); + }); + await shouldBeRenewed(); + await shouldHavePendingMS(0); + }) + + it('should exist 2 other renew', async () => { + await s1.commit({ time: now + 15 }); + // await s1.expect('/blockchain/current', (res) => { res.number.should.equal(4); (res.medianTime - now).should.equal(11); }); + await i1.join(); // Renew + await i2.join(); // Renew + await shouldHavePendingMS(2); + await s1.commit({ time: now + 15 }); + // await s1.expect('/blockchain/current', (res) => { res.number.should.equal(5); (res.medianTime - now).should.equal(21); }); + await s1.expect('/blockchain/current', (res:any) => { + res.should.have.property('membersCount').equal(3); + res.should.have.property('actives').length(2); + }); + await shouldBeRenewed(); + await shouldHavePendingMS(0); + }) + + it('should exist a leaver', async () => { + await i3.leave(); + await s1.commit({ time: now + 80 }); + await s1.expect('/blockchain/current', (res:any) => { + // (res.medianTime - now).should.equal(27); + res.should.have.property('membersCount').equal(3); + res.should.have.property('leavers').length(1); + }); + await shouldBeLeaving(); + await shouldHavePendingMS(0); + }) + + it('should exist a kicked member', async () => { + await s1.commit({ time: now + 25 }); + // await s1.expect('/blockchain/current', (res) => { res.number.should.equal(7); (res.medianTime - now).should.equal(25); }); + // await s1.commit({ time: now + 30 }); + // await s1.expect('/blockchain/current', (res) => { res.number.should.equal(8); (res.medianTime - now).should.equal(18); }); + await shouldBeBeingKicked(); + await s1.commit({ time: now + 30 }); + await s1.expect('/blockchain/current', (res:any) => { + res.should.have.property('membersCount').equal(2); + res.should.have.property('excluded').length(1); + }); + // Should: + // * unset "to be kicked" + // * not be a member anymore + await shouldHaveBeenKicked(); + await shouldHavePendingMS(0); + }) + + it('a kicked member should be able to join back', async () => { + await i3.join(); + await s1.commit({ time: now + 30 }); + await shouldHaveComeBack(); + await shouldHavePendingMS(0); + }) + + it('revert the join back', async () => { + await s1.revert(); + await shouldHaveBeenKicked(); + await shouldHavePendingMS(0); // Undone memberships are lost + }) + + it('revert excluded member', async () => { + await s1.revert(); + await shouldBeBeingKicked(); + await shouldHavePendingMS(0); // Undone memberships are lost + }) + + it('revert being kicked', async () => { + await s1.revert(); + await shouldBeLeaving(); + await shouldHavePendingMS(0); // Undone memberships are lost + }) + + it('revert leaving', async () => { + await s1.revert(); + await shouldBeRenewed(); + await shouldHavePendingMS(0); // Undone memberships are lost + }) + + it('revert 2 neutral blocks for i3', async () => { + await s1.revert(); + await shouldBeRenewed(); + await shouldHavePendingMS(0); // Undone memberships are lost + await s1.revert(); + await shouldBeRenewed(); + await shouldHavePendingMS(0); // Undone memberships are lost + }) + + it('revert renewal block', async () => { + await s1.revert(); + await shouldHaveJoined(); + await shouldHavePendingMS(0); // Undone memberships are lost + }) + + it('revert join block', async () => { + await s1.revert(); + await shouldHavePendingMS(0); // Undone memberships are lost + }) + + after(async () => { + return s1.closeCluster() + }) + + /********* + * + * Identity state testing functions + * + ********/ + + async function shouldHavePendingMS(number:number) { + const pendingIN = await s1.dal.msDAL.getPendingIN(); + const pendingOUT = await s1.dal.msDAL.getPendingOUT(); + pendingIN.concat(pendingOUT).should.have.length(number); + } + + async function shouldBeFreshlyCreated() { + const idty = (await s1.dal.idtyDAL.searchThoseMatching(i3.pub))[0]; + idty.should.have.property('wasMember').equal(false); + idty.should.have.property('written').equal(false); + idty.should.have.property('kick').equal(false); + idty.should.have.property('member').equal(false); + } + + async function shouldBeJoining() { + return shouldBeFreshlyCreated(); + } + + async function shouldHaveJoined() { + const idty = await s1.dal.iindexDAL.getFromPubkey(i3.pub) as FullIindexEntry + idty.should.have.property('wasMember').equal(true); + idty.should.have.property('kick').equal(false); + idty.should.have.property('member').equal(true); + } + + async function shouldBeRenewed() { + const idty = await s1.dal.iindexDAL.getFromPubkey(i3.pub) as FullIindexEntry + idty.should.have.property('wasMember').equal(true); + idty.should.have.property('kick').equal(false); + idty.should.have.property('member').equal(true); + } + + async function shouldBeLeaving() { + const idty = await s1.dal.iindexDAL.getFromPubkey(i3.pub) as FullIindexEntry + idty.should.have.property('wasMember').equal(true); + idty.should.have.property('kick').equal(false); + idty.should.have.property('member').equal(true); + } + + async function shouldBeBeingKicked() { + // Should be set as kicked now + const idty = await s1.dal.iindexDAL.getFromPubkey(i3.pub) as FullIindexEntry + idty.should.have.property('wasMember').equal(true); + idty.should.have.property('kick').equal(true); + idty.should.have.property('member').equal(true); + } + + async function shouldHaveBeenKicked() { + const idty = await s1.dal.iindexDAL.getFromPubkey(i3.pub) as FullIindexEntry + idty.should.have.property('wasMember').equal(true); + idty.should.have.property('kick').equal(false); + idty.should.have.property('member').equal(false); + } + + async function shouldHaveComeBack() { + let idty = await s1.dal.iindexDAL.getFromPubkey(i3.pub) as FullIindexEntry + idty.should.have.property('wasMember').equal(true); + idty.should.have.property('kick').equal(false); + idty.should.have.property('member').equal(true); + } +}); diff --git a/test/integration/branches_switch.ts b/test/integration/branches/branches_switch.ts similarity index 85% rename from test/integration/branches_switch.ts rename to test/integration/branches/branches_switch.ts index 08a13ed914bb8fd97550f455e37e44b34ae96a02..b3ebebc4900f8d15f40bfa18bb0cbcecad654a40 100644 --- a/test/integration/branches_switch.ts +++ b/test/integration/branches/branches_switch.ts @@ -11,21 +11,20 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; -import {CrawlerDependency} from "../../app/modules/crawler/index" -import {BmaDependency} from "../../app/modules/bma/index" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {BmaDependency} from "../../../app/modules/bma/index" +import {CrawlerDependency} from "../../../app/modules/crawler/index" const co = require('co'); -const _ = require('underscore'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const TestUser = require('./tools/TestUser').TestUser +const duniter = require('../../../index'); +const bma = require('../../../app/modules/bma').BmaDependency.duniter.methods.bma; +const TestUser = require('../tools/TestUser').TestUser const rp = require('request-promise'); -const httpTest = require('./tools/http'); -const commit = require('./tools/commit'); -const sync = require('./tools/sync'); +const httpTest = require('../tools/http'); +const commit = require('../tools/commit'); +const sync = require('../tools/sync'); const cluster = require('cluster') -const shutDownEngine = require('./tools/shutDownEngine'); +const shutDownEngine = require('../tools/shutDownEngine'); const expectJSON = httpTest.expectJSON; @@ -50,7 +49,7 @@ describe("Switch", function() { s1 = duniter( '/bb11', MEMORY_MODE, - _.extend({ + Underscore.extend({ switchOnHeadAdvance: 0, port: '7788', pair: { @@ -64,7 +63,7 @@ describe("Switch", function() { s2 = duniter( '/bb12', MEMORY_MODE, - _.extend({ + Underscore.extend({ switchOnHeadAdvance: 0, port: '7789', pair: { diff --git a/test/integration/branches_revert.js b/test/integration/branches_revert.js deleted file mode 100644 index d606c049da428dbd3b9b6737d0e286fa72621176..0000000000000000000000000000000000000000 --- a/test/integration/branches_revert.js +++ /dev/null @@ -1,83 +0,0 @@ -// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 -// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -"use strict"; - -const co = require('co'); -const _ = require('underscore'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const TestUser = require('./tools/TestUser').TestUser -const toolbox = require('./tools/toolbox'); -const commit = require('./tools/commit'); - -const commonConf = { - ipv4: '127.0.0.1', - currency: 'bb', - httpLogs: true, - forksize: 3, - sigQty: 1 -}; - -let s1, cat, toc - -describe("Revert root", function() { - - before(function() { - - return co(function *() { - - s1 = toolbox.server(_.extend({ - pair: { - pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', - sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' - }, - rootoffset: 10, - sigQty: 1, dt: 1, ud0: 120 - }, commonConf)); - - cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); - toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); - - yield s1.initDalBmaConnections(); - yield cat.createIdentity(); - yield toc.createIdentity(); - yield toc.cert(cat); - yield cat.cert(toc); - yield cat.join(); - yield toc.join(); - yield commit(s1)(); - }); - }); - - it('/block/0 should exist', () => s1.expectJSON('/blockchain/block/0', { - number: 0 - })); - - it('/wot/cat should exist', () => s1.expectThat('/wot/lookup/cat', (res) => { - res.should.have.property('results').length(1); - res.results[0].should.have.property('uids').length(1); - res.results[0].uids[0].should.have.property('uid').equal('cat'); - res.results[0].uids[0].should.have.property('others').length(1); - })); - - it('reverting should erase everything', () => co(function*() { - yield s1.revert(); - yield s1.expectError('/blockchain/current', 404, 'No current block'); - yield s1.expectError('/blockchain/block/0', 404, 'Block not found'); - yield s1.expectError('/wot/lookup/cat', 404, 'No matching identity'); // Revert completely removes the identity - })); - - after(() => { - return s1.closeCluster() - }) -}); diff --git a/test/integration/branches_revert_memberships.js b/test/integration/branches_revert_memberships.js deleted file mode 100644 index 33446bee4f554b005d67518aa2b328834c612f86..0000000000000000000000000000000000000000 --- a/test/integration/branches_revert_memberships.js +++ /dev/null @@ -1,271 +0,0 @@ -// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 -// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -"use strict"; - -const co = require('co'); -const should = require('should'); -const TestUser = require('./tools/TestUser').TestUser -const toolbox = require('./tools/toolbox'); - -let s1, i1, i2, i3 - -describe("Revert memberships", function() { - - const now = 1482000000; - - before(() => co(function*() { - - s1 = toolbox.server({ - memory: true, - msValidity: 14, - pair: { - pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', - sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' - } - }); - - i1 = new TestUser('i1', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); - i2 = new TestUser('i2', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s1 }); - i3 = new TestUser('i3', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); - - yield s1.initDalBmaConnections(); - - yield i1.createIdentity(); - yield i2.createIdentity(); - - yield i1.cert(i2); - yield i2.cert(i1); - - yield i1.join(); - yield i2.join(); - - yield s1.commit({ time: now }); - yield s1.expect('/blockchain/current', (res) => { res.number.should.equal(0); (res.medianTime - now).should.equal(0); }); - yield s1.commit({ time: now + 15 }); - yield s1.expect('/blockchain/current', (res) => { res.number.should.equal(1); (res.medianTime - now).should.equal(0); }); - - yield shouldHavePendingMS(0); - yield i3.createIdentity(); - yield i1.cert(i3); - yield shouldBeFreshlyCreated(); - yield i3.join(); - yield shouldHavePendingMS(1); - yield shouldBeJoining(); - yield s1.commit({ time: now + 15 }); - yield s1.expect('/blockchain/current', (res) => { res.number.should.equal(2); (res.medianTime - now).should.equal(7); }); - yield shouldHaveJoined(); - yield shouldHavePendingMS(0); - })); - - it('should exist 3 members', () => s1.expect('/blockchain/current', (res) => { - res.should.have.property('membersCount').equal(3); - })); - - it('should exist a renew', () => co(function*() { - yield i3.join(); // Renew - yield shouldHavePendingMS(1); - yield s1.commit({ time: now + 15 }); - yield s1.expect('/blockchain/current', (res) => { res.number.should.equal(3); (res.medianTime - now).should.equal(10); }); - yield s1.expect('/blockchain/current', (res) => { - res.should.have.property('membersCount').equal(3); - res.should.have.property('actives').length(1); - }); - yield shouldBeRenewed(); - yield shouldHavePendingMS(0); - })); - - it('should exist 2 other renew', () => co(function*() { - yield s1.commit({ time: now + 15 }); - // yield s1.expect('/blockchain/current', (res) => { res.number.should.equal(4); (res.medianTime - now).should.equal(11); }); - yield i1.join(); // Renew - yield i2.join(); // Renew - yield shouldHavePendingMS(2); - yield s1.commit({ time: now + 15 }); - // yield s1.expect('/blockchain/current', (res) => { res.number.should.equal(5); (res.medianTime - now).should.equal(21); }); - yield s1.expect('/blockchain/current', (res) => { - res.should.have.property('membersCount').equal(3); - res.should.have.property('actives').length(2); - }); - yield shouldBeRenewed(); - yield shouldHavePendingMS(0); - })); - - it('should exist a leaver', () => co(function*() { - yield i3.leave(); - yield s1.commit({ time: now + 80 }); - yield s1.expect('/blockchain/current', (res) => { - // (res.medianTime - now).should.equal(27); - res.should.have.property('membersCount').equal(3); - res.should.have.property('leavers').length(1); - }); - yield shouldBeLeaving(); - yield shouldHavePendingMS(0); - })); - - it('should exist a kicked member', () => co(function*() { - yield s1.commit({ time: now + 25 }); - // yield s1.expect('/blockchain/current', (res) => { res.number.should.equal(7); (res.medianTime - now).should.equal(25); }); - // yield s1.commit({ time: now + 30 }); - // yield s1.expect('/blockchain/current', (res) => { res.number.should.equal(8); (res.medianTime - now).should.equal(18); }); - yield shouldBeBeingKicked(); - yield s1.commit({ time: now + 30 }); - yield s1.expect('/blockchain/current', (res) => { - res.should.have.property('membersCount').equal(2); - res.should.have.property('excluded').length(1); - }); - // Should: - // * unset "to be kicked" - // * not be a member anymore - yield shouldHaveBeenKicked(); - yield shouldHavePendingMS(0); - })); - - it('a kicked member should be able to join back', () => co(function*() { - yield i3.join(); - yield s1.commit({ time: now + 30 }); - yield shouldHaveComeBack(); - yield shouldHavePendingMS(0); - })); - - it('revert the join back', () => co(function*() { - yield s1.revert(); - yield shouldHaveBeenKicked(); - yield shouldHavePendingMS(0); // Undone memberships are lost - })); - - it('revert excluded member', () => co(function*() { - yield s1.revert(); - yield shouldBeBeingKicked(); - yield shouldHavePendingMS(0); // Undone memberships are lost - })); - - it('revert being kicked', () => co(function*() { - yield s1.revert(); - yield shouldBeLeaving(); - yield shouldHavePendingMS(0); // Undone memberships are lost - })); - - it('revert leaving', () => co(function*() { - yield s1.revert(); - yield shouldBeRenewed(); - yield shouldHavePendingMS(0); // Undone memberships are lost - })); - - it('revert 2 neutral blocks for i3', () => co(function*() { - yield s1.revert(); - yield shouldBeRenewed(); - yield shouldHavePendingMS(0); // Undone memberships are lost - yield s1.revert(); - yield shouldBeRenewed(); - yield shouldHavePendingMS(0); // Undone memberships are lost - })); - - it('revert renewal block', () => co(function*() { - yield s1.revert(); - yield shouldHaveJoined(); - yield shouldHavePendingMS(0); // Undone memberships are lost - })); - - it('revert join block', () => co(function*() { - yield s1.revert(); - yield shouldHavePendingMS(0); // Undone memberships are lost - })); - - after(() => { - return s1.closeCluster() - }) - - /********* - * - * Identity state testing functions - * - ********/ - - function shouldHavePendingMS(number) { - return co(function*() { - const pendingIN = yield s1.dal.msDAL.getPendingIN(); - const pendingOUT = yield s1.dal.msDAL.getPendingOUT(); - pendingIN.concat(pendingOUT).should.have.length(number); - }); - } - - function shouldBeFreshlyCreated() { - return co(function*() { - const idty = (yield s1.dal.idtyDAL.searchThoseMatching(i3.pub))[0]; - idty.should.have.property('wasMember').equal(false); - idty.should.have.property('written').equal(false); - idty.should.have.property('kick').equal(false); - idty.should.have.property('member').equal(false); - }); - } - - function shouldBeJoining() { - return shouldBeFreshlyCreated(); - } - - function shouldHaveJoined() { - return co(function*() { - const idty = yield s1.dal.iindexDAL.getFromPubkey(i3.pub); - idty.should.have.property('wasMember').equal(true); - idty.should.have.property('kick').equal(false); - idty.should.have.property('member').equal(true); - }); - } - - function shouldBeRenewed() { - return co(function*() { - const idty = yield s1.dal.iindexDAL.getFromPubkey(i3.pub); - idty.should.have.property('wasMember').equal(true); - idty.should.have.property('kick').equal(false); - idty.should.have.property('member').equal(true); - }); - } - - function shouldBeLeaving() { - return co(function*() { - const idty = yield s1.dal.iindexDAL.getFromPubkey(i3.pub); - idty.should.have.property('wasMember').equal(true); - idty.should.have.property('kick').equal(false); - idty.should.have.property('member').equal(true); - }); - } - - function shouldBeBeingKicked() { - return co(function*() { - // Should be set as kicked now - const idty = yield s1.dal.iindexDAL.getFromPubkey(i3.pub); - idty.should.have.property('wasMember').equal(true); - idty.should.have.property('kick').equal(true); - idty.should.have.property('member').equal(true); - }); - } - - function shouldHaveBeenKicked() { - return co(function*() { - const idty = yield s1.dal.iindexDAL.getFromPubkey(i3.pub); - idty.should.have.property('wasMember').equal(true); - idty.should.have.property('kick').equal(false); - idty.should.have.property('member').equal(false); - }); - } - - function shouldHaveComeBack() { - return co(function*() { - let idty = yield s1.dal.iindexDAL.getFromPubkey(i3.pub); - idty.should.have.property('wasMember').equal(true); - idty.should.have.property('kick').equal(false); - idty.should.have.property('member').equal(true); - }); - } -}); diff --git a/test/integration/certification_chainability.js b/test/integration/certification/certification_chainability.ts similarity index 67% rename from test/integration/certification_chainability.js rename to test/integration/certification/certification_chainability.ts index 5ca1cf28343a2e0533827e57969cb1cdab9b9615..ca4955b0495587da4f59b0a921e9d113ee93402b 100644 --- a/test/integration/certification_chainability.js +++ b/test/integration/certification/certification_chainability.ts @@ -11,19 +11,16 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {TestUser} from "../tools/TestUser" +import {BmaDependency} from "../../../app/modules/bma/index" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {HttpBlock} from "../../../app/modules/bma/lib/dtos" -const _ = require('underscore'); -const co = require('co'); const should = require('should'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const TestUser = require('./tools/TestUser').TestUser -const constants = require('../../app/lib/constants'); const rp = require('request-promise'); -const httpTest = require('./tools/http'); -const commit = require('./tools/commit'); -const shutDownEngine = require('./tools/shutDownEngine'); +const httpTest = require('../tools/http'); +const shutDownEngine = require('../tools/shutDownEngine'); const expectAnswer = httpTest.expectAnswer; @@ -37,16 +34,16 @@ const commonConf = { sigQty: 1 }; -let s1, cat, tac, tic, toc +let s1:TestingServer, cat:TestUser, tac:TestUser, tic:TestUser, toc:TestUser describe("Certification chainability", function() { - before(function() { + before(async () => { - s1 = duniter( - '/bb11', - MEMORY_MODE, - _.extend({ + s1 = NewTestingServer( + Underscore.extend({ + name: 'bb11', + memory: MEMORY_MODE, port: '9225', pair: { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', @@ -61,41 +58,37 @@ describe("Certification chainability", function() { const now = 1482220000; - const commitS1 = commit(s1); - - return co(function *() { - /** - * tac <===> cat - */ - yield s1.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); - yield cat.createIdentity(); - yield tac.createIdentity(); - yield cat.cert(tac); - yield tac.cert(cat); - yield cat.join(); - yield tac.join(); - yield commitS1({ time: now }); - yield commitS1({ - time: now + 399 - }); - - // Should not happen on the first commit due to certPeriod - yield tic.createIdentity(); - yield tic.join(); - yield cat.cert(tic); - yield commitS1({ time: now + 199 }); - yield commitS1({ time: now + 199 }); - // We still are at +199, and the certPeriod must be OVER (or equal to) current time to allow new certs from cat. - // So if we increment +1 - yield commitS1({ - time: now + 300 - }); - yield commitS1({ - time: now + 300 - }); - // Should be integrated now - yield commitS1({ time: now + 300 }); + /** + * tac <===> cat + */ + await s1.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); + await cat.createIdentity(); + await tac.createIdentity(); + await cat.cert(tac); + await tac.cert(cat); + await cat.join(); + await tac.join(); + await s1.commit({ time: now }); + await s1.commit({ + time: now + 399 }); + + // Should not happen on the first commit due to certPeriod + await tic.createIdentity(); + await tic.join(); + await cat.cert(tic); + await s1.commit({ time: now + 199 }); + await s1.commit({ time: now + 199 }); + // We still are at +199, and the certPeriod must be OVER (or equal to) current time to allow new certs from cat. + // So if we increment +1 + await s1.commit({ + time: now + 300 + }); + await s1.commit({ + time: now + 300 + }); + // Should be integrated now + await s1.commit({ time: now + 300 }); }); after(() => { @@ -105,49 +98,49 @@ describe("Certification chainability", function() { }) it('block 0 should have 2 certs', function() { - return expectAnswer(rp('http://127.0.0.1:9225/blockchain/block/0', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:9225/blockchain/block/0', { json: true }), function(res:HttpBlock) { res.should.have.property('number').equal(0); res.should.have.property('certifications').length(2); }); }); it('block 1 should have 0 certs', function() { - return expectAnswer(rp('http://127.0.0.1:9225/blockchain/block/1', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:9225/blockchain/block/1', { json: true }), function(res:HttpBlock) { res.should.have.property('number').equal(1); res.should.have.property('certifications').length(0); }); }); it('block 2 should have 0 certs', function() { - return expectAnswer(rp('http://127.0.0.1:9225/blockchain/block/2', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:9225/blockchain/block/2', { json: true }), function(res:HttpBlock) { res.should.have.property('number').equal(2); res.should.have.property('certifications').length(0); }); }); it('block 3 should have 0 certs', function() { - return expectAnswer(rp('http://127.0.0.1:9225/blockchain/block/3', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:9225/blockchain/block/3', { json: true }), function(res:HttpBlock) { res.should.have.property('number').equal(3); res.should.have.property('certifications').length(0); }); }); it('block 4 should have 0 certs', function() { - return expectAnswer(rp('http://127.0.0.1:9225/blockchain/block/4', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:9225/blockchain/block/4', { json: true }), function(res:HttpBlock) { res.should.have.property('number').equal(4); res.should.have.property('certifications').length(0); }); }); it('block 5 should have 0 certs', function() { - return expectAnswer(rp('http://127.0.0.1:9225/blockchain/block/5', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:9225/blockchain/block/5', { json: true }), function(res:HttpBlock) { res.should.have.property('number').equal(5); res.should.have.property('certifications').length(0); }); }); it('block 6 should have 1 certs', function() { - return expectAnswer(rp('http://127.0.0.1:9225/blockchain/block/6', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:9225/blockchain/block/6', { json: true }), function(res:HttpBlock) { res.should.have.property('number').equal(6); res.should.have.property('certifications').length(1); }); diff --git a/test/integration/certifier-is-member.js b/test/integration/certification/certifier-is-member.ts similarity index 51% rename from test/integration/certifier-is-member.js rename to test/integration/certification/certifier-is-member.ts index 6c3bfe4568334e19338050e20cf532ab6ff7c936..3a260faa48acabd79888abf7a168465a31057cd3 100644 --- a/test/integration/certifier-is-member.js +++ b/test/integration/certification/certifier-is-member.ts @@ -11,27 +11,22 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {shouldFail} from "../../unit-tools" -const _ = require('underscore'); -const co = require('co'); const assert = require('assert'); const should = require('should'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const TestUser = require('./tools/TestUser').TestUser -const constants = require('../../app/lib/constants'); -const toolbox = require('./tools/toolbox'); const now = 1480000000; -let s1, cat, tac, tic +let s1:TestingServer, cat:TestUser, tac:TestUser, tic:TestUser describe("Certifier must be a member", function() { - before(() => co(function *() { + before(async () => { - s1 = toolbox.server({ + s1 = NewTestingServer({ pair: { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' @@ -46,62 +41,62 @@ describe("Certifier must be a member", function() { tac = new TestUser('tac', { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}, { server: s1 }); tic = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s1 }); - yield s1.initDalBmaConnections(); - yield cat.createIdentity(); - yield tac.createIdentity(); - yield cat.cert(tac); - yield tac.cert(cat); - yield cat.join(); - yield tac.join(); - yield s1.commit({ time: now }); - yield s1.commit({ time: now + 8 }); - yield s1.commit({ time: now + 9 }); - })); - - it('tic should not be able to certify yet', () => co(function*() { - yield tic.createIdentity(); - yield tic.join(); - yield cat.cert(tic); - yield toolbox.shouldFail(tic.cert(cat), 'Certifier must be a member') - })); - - it('block#3 should see tic becoming member', () => co(function*() { - yield cat.join(); - yield tac.join(); - yield s1.commit({ time: now + 16 }); - yield s1.expectThat('/blockchain/block/3', (res) => { + await s1.initDalBmaConnections(); + await cat.createIdentity(); + await tac.createIdentity(); + await cat.cert(tac); + await tac.cert(cat); + await cat.join(); + await tac.join(); + await s1.commit({ time: now }); + await s1.commit({ time: now + 8 }); + await s1.commit({ time: now + 9 }); + }) + + it('tic should not be able to certify yet', async () => { + await tic.createIdentity(); + await tic.join(); + await cat.cert(tic); + await shouldFail(tic.cert(cat), 'Certifier must be a member') + }) + + it('block#3 should see tic becoming member', async () => { + await cat.join(); + await tac.join(); + await s1.commit({ time: now + 16 }); + await s1.expectThat('/blockchain/block/3', (res:any) => { res.should.have.property('joiners').length(1); }) - })); - - it('tic is now a member, he should be able to certify', () => co(function*() { - yield tic.cert(cat); - yield s1.commit({ time: now + 16 }); - yield cat.join(); - yield tac.join(); - yield s1.commit({ time: now + 21 }); - })); - - it('tic should be excluded', () => co(function*() { - yield s1.commit({ time: now + 21 }); - yield s1.commit({ time: now + 22 }); - yield s1.expectThat('/blockchain/block/7', (res) => { + }) + + it('tic is now a member, he should be able to certify', async () => { + await tic.cert(cat); + await s1.commit({ time: now + 16 }); + await cat.join(); + await tac.join(); + await s1.commit({ time: now + 21 }); + }) + + it('tic should be excluded', async () => { + await s1.commit({ time: now + 21 }); + await s1.commit({ time: now + 22 }); + await s1.expectThat('/blockchain/block/7', (res:any) => { res.should.have.property('excluded').length(1); res.excluded[0].should.equal('DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV') }) - })); + }) - it('tic should not be able to certify as he is no more a member', () => co(function*() { - yield toolbox.shouldFail(tic.cert(tac), 'Certifier must be a member') - })); + it('tic should not be able to certify as he is no more a member', async () => { + await shouldFail(tic.cert(tac), 'Certifier must be a member') + }) - it('tic should be able to certify when he joins back', () => co(function*() { - yield tic.join(); - yield s1.commit({ time: now + 23 }); - yield tic.cert(tac); - })); + it('tic should be able to certify when he joins back', async () => { + await tic.join(); + await s1.commit({ time: now + 23 }); + await tic.cert(tac); + }) after(() => { return s1.closeCluster() }) -}); +}) diff --git a/test/integration/identity-expiry.js b/test/integration/identity-expiry.js deleted file mode 100644 index 597752905a9cbbe63e5c571f0d417991a3d5ed3e..0000000000000000000000000000000000000000 --- a/test/integration/identity-expiry.js +++ /dev/null @@ -1,116 +0,0 @@ -// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 -// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -"use strict"; - -const _ = require('underscore'); -const co = require('co'); -const should = require('should'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const prover = require('../../app/modules/prover').ProverDependency.duniter.methods; -const TestUser = require('./tools/TestUser').TestUser -const constants = require('../../app/lib/constants'); -const rp = require('request-promise'); -const httpTest = require('./tools/http'); -const commit = require('./tools/commit'); -const shutDownEngine = require('./tools/shutDownEngine'); - -const expectAnswer = httpTest.expectAnswer; -const expectError = httpTest.expectError; - -const MEMORY_MODE = true; -const commonConf = { - ipv4: '127.0.0.1', - currency: 'bb', - httpLogs: true, - forksize: 3, - xpercent: 0.9, - msValidity: 10000, - idtyWindow: 1, // 1 second of duration - sigQty: 1 -}; - -let s1, cat, tac, tic, toc - -const now = 1482300000; -const commitS1 = (opts) => commit(s1)(opts) - -describe("Identities expiry", function() { - - before(function() { - - return co(function *() { - - s1 = duniter( - '/bb11', - MEMORY_MODE, - _.extend({ - port: '8560', - pair: { - pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', - sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' - } - }, commonConf)); - - cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); - tac = new TestUser('tac', { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}, { server: s1 }); - tic = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s1 }); - toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); - - yield s1.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); - prover.hookServer(s1) - yield cat.createIdentity(); - yield tac.createIdentity(); - yield tic.createIdentity(); - yield cat.cert(tac); - yield tac.cert(cat); - yield cat.join(); - yield tac.join(); - yield commitS1({ - time: now - }); - yield toc.createIdentity(); - yield toc.join(); - yield commitS1({ - time: now + 5 - }); - }); - }); - - after(() => { - return shutDownEngine(s1) - }) - - it('should have requirements failing for tic', function() { - // tic has been cleaned up, since its identity has expired after the root block - return expectError(404, 'No identity matching this pubkey or uid', rp('http://127.0.0.1:8560/wot/requirements/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', { json: true })); - }); - - it('should have requirements failing for toc', function() { - return expectAnswer(rp('http://127.0.0.1:8560/wot/requirements/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', { json: true }), (res) => { - res.should.have.property('identities').length(1); - res.identities[0].should.have.property('pubkey').equal('DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'); - res.identities[0].should.have.property('uid').equal('toc'); - res.identities[0].should.have.property('expired').equal(false); - }); - }); - - it('should have requirements failing for toc', () => co(function*() { - // tic has been cleaned up after the block#2 - yield commitS1({ - time: now + 5 - }); - return expectError(404, 'No identity matching this pubkey or uid', rp('http://127.0.0.1:8560/wot/requirements/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', { json: true })); - })); -}); diff --git a/test/integration/identity-implicit-revocation.js b/test/integration/identity-implicit-revocation.js index 1037ebad4e5c5b8ef4eafc4229948b94b34a8956..d3d98b9f57d2f662f1587ab20c591ca78abd3a3c 100644 --- a/test/integration/identity-implicit-revocation.js +++ b/test/integration/identity-implicit-revocation.js @@ -13,7 +13,6 @@ "use strict"; -const _ = require('underscore'); const co = require('co'); const assert = require('assert'); const should = require('should'); diff --git a/test/integration/identity-absorption.js b/test/integration/identity/identity-absorption.ts similarity index 63% rename from test/integration/identity-absorption.js rename to test/integration/identity/identity-absorption.ts index 3335529e5d17b8334e588e120002094becdfd659..bbaf24fffaecdd8d8d8511ae524020b0954b291e 100644 --- a/test/integration/identity-absorption.js +++ b/test/integration/identity/identity-absorption.ts @@ -11,17 +11,16 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {BmaDependency} from "../../../app/modules/bma/index" +import {shouldFail} from "../../unit-tools" +import {Underscore} from "../../../app/lib/common-libs/underscore" -const _ = require('underscore'); -const co = require('co'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const TestUser = require('./tools/TestUser').TestUser +const duniter = require('../../../index'); const rp = require('request-promise'); -const httpTest = require('./tools/http'); -const toolbox = require('./tools/toolbox'); -const shutDownEngine = require('./tools/shutDownEngine'); +const httpTest = require('../tools/http'); +const shutDownEngine = require('../tools/shutDownEngine'); const expectAnswer = httpTest.expectAnswer; @@ -36,16 +35,16 @@ const commonConf = { sigQty: 1 }; -let s1, s2, cat, tic +let s1:TestingServer, s2:TestingServer, cat:TestUser, tic:TestUser -describe("Identity absorption", function() { +describe("Identity absorption", () => { - before(function() { + before(async () => { s1 = duniter( '/bb12', MEMORY_MODE, - _.extend({ + Underscore.extend({ port: '4450', pair: { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', @@ -56,7 +55,7 @@ describe("Identity absorption", function() { s2 = duniter( '/bb12', MEMORY_MODE, - _.extend({ + Underscore.extend({ port: '4451', pair: { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', @@ -67,12 +66,10 @@ describe("Identity absorption", function() { cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); tic = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s2 }); - return co(function *() { - yield s1.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); - yield s2.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); - yield cat.createIdentity(); - yield tic.cert(cat, s1); - }); + await s1.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); + await s2.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); + await cat.createIdentity(); + await tic.cert(cat, s1); }); after(() => { @@ -82,29 +79,29 @@ describe("Identity absorption", function() { ]) }) - it('cat should exist on server 1', function() { - return expectAnswer(rp('http://127.0.0.1:4450/wot/lookup/cat', { json: true }), function(res) { + it('cat should exist on server 1', () => { + return expectAnswer(rp('http://127.0.0.1:4450/wot/lookup/cat', { json: true }), function(res:any) { res.should.have.property('results').length(1); res.results[0].should.have.property('uids').length(1); res.results[0].uids[0].should.have.property('uid').equal('cat'); }); }); - it('cat should exist on server 2', function() { - return expectAnswer(rp('http://127.0.0.1:4451/wot/lookup/cat', { json: true }), function(res) { + it('cat should exist on server 2', () => { + return expectAnswer(rp('http://127.0.0.1:4451/wot/lookup/cat', { json: true }), function(res:any) { res.should.have.property('results').length(1); res.results[0].should.have.property('uids').length(1); res.results[0].uids[0].should.have.property('uid').equal('cat'); }); }); - it('should test idty absorption refusal', () => co(function*() { - (yield s2.dal.idtyDAL.query('SELECT * FROM idty')).should.have.length(1); - yield s2.dal.idtyDAL.exec('DELETE FROM idty'); - (yield s2.dal.idtyDAL.query('SELECT * FROM idty')).should.have.length(0); - yield toolbox.shouldFail(tic.cert(cat, s1), 'Already up-to-date'); - (yield s2.dal.idtyDAL.query('SELECT * FROM idty')).should.have.length(1); - (yield s2.dal.idtyDAL.query('SELECT * FROM idty WHERE removed')).should.have.length(1); - (yield s2.dal.idtyDAL.query('SELECT * FROM idty WHERE NOT removed')).should.have.length(0); - })); -}); + it('should test idty absorption refusal', async () => { + (await s2.dal.idtyDAL.query('SELECT * FROM idty')).should.have.length(1); + await s2.dal.idtyDAL.exec('DELETE FROM idty'); + (await s2.dal.idtyDAL.query('SELECT * FROM idty')).should.have.length(0); + await shouldFail(tic.cert(cat, s1), 'Already up-to-date'); + (await s2.dal.idtyDAL.query('SELECT * FROM idty')).should.have.length(1); + (await s2.dal.idtyDAL.query('SELECT * FROM idty WHERE removed')).should.have.length(1); + (await s2.dal.idtyDAL.query('SELECT * FROM idty WHERE NOT removed')).should.have.length(0); + }) +}) diff --git a/test/integration/identity-clean-test.js b/test/integration/identity/identity-clean-test.ts similarity index 65% rename from test/integration/identity-clean-test.js rename to test/integration/identity/identity-clean-test.ts index a042d79d8dbe8f2a7d87cdef5e936da0fa4f31ba..f311491a2de403185af73cfbab16a30dc07b5ff0 100644 --- a/test/integration/identity-clean-test.js +++ b/test/integration/identity/identity-clean-test.ts @@ -11,17 +11,17 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {BmaDependency} from "../../../app/modules/bma/index" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {HttpMembers} from "../../../app/modules/bma/lib/dtos" -const _ = require('underscore'); -const co = require('co'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const TestUser = require('./tools/TestUser').TestUser +const duniter = require('../../../index'); const rp = require('request-promise'); -const httpTest = require('./tools/http'); -const commit = require('./tools/commit'); -const shutDownEngine = require('./tools/shutDownEngine'); +const httpTest = require('../tools/http'); +const commit = require('../tools/commit'); +const shutDownEngine = require('../tools/shutDownEngine'); const expectAnswer = httpTest.expectAnswer; @@ -36,16 +36,16 @@ const commonConf = { sigQty: 1 }; -let s1, cat, tac, tic, toc +let s1:TestingServer, cat:TestUser, tac:TestUser, tic:TestUser, toc:TestUser describe("Identities cleaned", function() { - before(function() { + before(async () => { s1 = duniter( '/bb12', MEMORY_MODE, - _.extend({ + Underscore.extend({ port: '7733', pair: { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', @@ -60,31 +60,29 @@ describe("Identities cleaned", function() { const commitS1 = commit(s1); - return co(function *() { - yield s1.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); - yield cat.createIdentity(); - yield tic.createIdentity(); - yield toc.createIdentity(); - - yield expectAnswer(rp('http://127.0.0.1:7733/wot/lookup/cat', { json: true }), function(res) { - res.should.have.property('results').length(2); - res.results[0].should.have.property('uids').length(1); - res.results[0].uids[0].should.have.property('uid').equal('cat'); // This is cat - res.results[1].uids[0].should.have.property('uid').equal('cat'); // This is toc - }); - - yield cat.cert(tic); - yield tic.cert(cat); - yield cat.join(); - yield tic.join(); - yield commitS1(); - - // We have the following WoT (diameter 1): - - /** - * cat <-> tic - */ + await s1.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); + await cat.createIdentity(); + await tic.createIdentity(); + await toc.createIdentity(); + + await expectAnswer(rp('http://127.0.0.1:7733/wot/lookup/cat', { json: true }), function(res:any) { + res.should.have.property('results').length(2); + res.results[0].should.have.property('uids').length(1); + res.results[0].uids[0].should.have.property('uid').equal('cat'); // This is cat + res.results[1].uids[0].should.have.property('uid').equal('cat'); // This is toc }); + + await cat.cert(tic); + await tic.cert(cat); + await cat.join(); + await tic.join(); + await commitS1(); + + // We have the following WoT (diameter 1): + + /** + * cat <-> tic + */ }); after(() => { @@ -94,14 +92,14 @@ describe("Identities cleaned", function() { }) it('should have 2 members', function() { - return expectAnswer(rp('http://127.0.0.1:7733/wot/members', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7733/wot/members', { json: true }), function(res:HttpMembers) { res.should.have.property('results').length(2); - _.pluck(res.results, 'uid').sort().should.deepEqual(['cat', 'tic']); + Underscore.pluck(res.results, 'uid').sort().should.deepEqual(['cat', 'tic']); }); }); it('lookup should give only 1 cat', function() { - return expectAnswer(rp('http://127.0.0.1:7733/wot/lookup/cat', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7733/wot/lookup/cat', { json: true }), function(res:any) { res.should.have.property('results').length(1); res.results[0].should.have.property('uids').length(1); res.results[0].uids[0].should.have.property('uid').equal('cat'); @@ -109,7 +107,7 @@ describe("Identities cleaned", function() { }); it('lookup should give only 1 tic', function() { - return expectAnswer(rp('http://127.0.0.1:7733/wot/lookup/tic', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7733/wot/lookup/tic', { json: true }), function(res:any) { res.should.have.property('results').length(1); res.results[0].should.have.property('uids').length(1); res.results[0].uids[0].should.have.property('uid').equal('tic'); diff --git a/test/integration/identity/identity-expiry.ts b/test/integration/identity/identity-expiry.ts new file mode 100644 index 0000000000000000000000000000000000000000..8b6f9a0e89859b787647d155573199969052699a --- /dev/null +++ b/test/integration/identity/identity-expiry.ts @@ -0,0 +1,109 @@ +// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 +// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +import {BmaDependency} from "../../../app/modules/bma/index" +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {HttpRequirements} from "../../../app/modules/bma/lib/dtos" +import {ProverDependency} from "../../../app/modules/prover/index" + +const should = require('should'); +const rp = require('request-promise'); +const httpTest = require('../tools/http'); +const shutDownEngine = require('../tools/shutDownEngine'); + +const expectAnswer = httpTest.expectAnswer; +const expectError = httpTest.expectError; + +const MEMORY_MODE = true; +const commonConf = { + ipv4: '127.0.0.1', + currency: 'bb', + httpLogs: true, + forksize: 3, + xpercent: 0.9, + msValidity: 10000, + idtyWindow: 1, // 1 second of duration + sigQty: 1 +}; + +let s1:TestingServer, cat:TestUser, tac:TestUser, tic:TestUser, toc:TestUser + +const now = 1482300000; + +describe("Identities expiry", function() { + + before(async () => { + + s1 = NewTestingServer( + Underscore.extend({ + name: 'bb11', + memory: MEMORY_MODE, + port: '8560', + pair: { + pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', + sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' + } + }, commonConf)); + + cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); + tac = new TestUser('tac', { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}, { server: s1 }); + tic = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s1 }); + toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); + + await s1.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); + ProverDependency.duniter.methods.hookServer(s1._server) + await cat.createIdentity(); + await tac.createIdentity(); + await tic.createIdentity(); + await cat.cert(tac); + await tac.cert(cat); + await cat.join(); + await tac.join(); + await s1.commit({ + time: now + }); + await toc.createIdentity(); + await toc.join(); + await s1.commit({ + time: now + 5 + }) + }); + + after(() => { + return shutDownEngine(s1) + }) + + it('should have requirements failing for tic', function() { + // tic has been cleaned up, since its identity has expired after the root block + return expectError(404, 'No identity matching this pubkey or uid', rp('http://127.0.0.1:8560/wot/requirements/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', { json: true })); + }); + + it('should have requirements failing for toc', function() { + return expectAnswer(rp('http://127.0.0.1:8560/wot/requirements/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', { json: true }), (res:HttpRequirements) => { + res.should.have.property('identities').length(1); + res.identities[0].should.have.property('pubkey').equal('DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'); + res.identities[0].should.have.property('uid').equal('toc'); + res.identities[0].should.have.property('expired').equal(false); + }); + }); + + it('should have requirements failing for toc', async () => { + // tic has been cleaned up after the block#2 + await s1.commit({ + time: now + 5 + }); + return expectError(404, 'No identity matching this pubkey or uid', rp('http://127.0.0.1:8560/wot/requirements/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', { json: true })); + }) +}); diff --git a/test/integration/identity-kicking.js b/test/integration/identity/identity-kicking.ts similarity index 53% rename from test/integration/identity-kicking.js rename to test/integration/identity/identity-kicking.ts index 7d1b024b8ce8ffdc149197477f8c4d5b66a09051..aaede1f7e6a092ced0fe0be1ba4942091de9fc03 100644 --- a/test/integration/identity-kicking.js +++ b/test/integration/identity/identity-kicking.ts @@ -11,19 +11,17 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {HttpRequirements} from "../../../app/modules/bma/lib/dtos" +import {BmaDependency} from "../../../app/modules/bma/index" +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {ProverDependency} from "../../../app/modules/prover/index" -const _ = require('underscore'); -const co = require('co'); const should = require('should'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const TestUser = require('./tools/TestUser').TestUser -const constants = require('../../app/lib/constants'); const rp = require('request-promise'); -const httpTest = require('./tools/http'); -const commit = require('./tools/commit'); -const shutDownEngine = require('./tools/shutDownEngine'); +const httpTest = require('../tools/http'); +const shutDownEngine = require('../tools/shutDownEngine'); const expectAnswer = httpTest.expectAnswer; @@ -39,70 +37,65 @@ const commonConf = { sigQty: 1 }; -let s1, cat, tac, toc - -const commitS1 = (opts) => commit(s1)(opts) +let s1:TestingServer, cat:TestUser, tac:TestUser, toc:TestUser describe("Identities kicking", function() { - before(function() { - - return co(function *() { - - s1 = duniter( - '/bb11', - MEMORY_MODE, - _.extend({ - port: '8561', - pair: { - pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', - sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' - } - }, commonConf)); - - cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); - tac = new TestUser('tac', { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}, { server: s1 }); - toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); - - const now = 1400000000 - yield s1.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); - require('../../app/modules/prover').ProverDependency.duniter.methods.hookServer(s1); - yield cat.createIdentity(); - yield tac.createIdentity(); - yield cat.cert(tac); - yield tac.cert(cat); - yield cat.join(); - yield tac.join(); - yield commitS1({ - time: now - }); - yield commitS1({ - time: now + 2000 - }); - yield commitS1({ - time: now + 2000 - }); - // Update their membership - yield cat.join(); - yield tac.join(); - // toc joins thereafter - yield toc.createIdentity(); - yield toc.join(); - yield cat.cert(toc); - yield tac.cert(toc); - yield commitS1({ - time: now + 2000 - }); - yield toc.cert(cat); - yield commitS1({ - time: now + 5000 - }); - yield commitS1({ - time: now + 5000 - }); - yield commitS1({ - time: now + 5000 - }); + before(async () => { + + s1 = NewTestingServer( + Underscore.extend({ + name: 'bb11', + memory: MEMORY_MODE, + port: '8561', + pair: { + pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', + sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' + } + }, commonConf)); + + cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); + tac = new TestUser('tac', { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}, { server: s1 }); + toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); + + const now = 1400000000 + await s1.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); + ProverDependency.duniter.methods.hookServer(s1._server) + await cat.createIdentity(); + await tac.createIdentity(); + await cat.cert(tac); + await tac.cert(cat); + await cat.join(); + await tac.join(); + await s1.commit({ + time: now + }); + await s1.commit({ + time: now + 2000 + }); + await s1.commit({ + time: now + 2000 + }); + // Update their membership + await cat.join(); + await tac.join(); + // toc joins thereafter + await toc.createIdentity(); + await toc.join(); + await cat.cert(toc); + await tac.cert(toc); + await s1.commit({ + time: now + 2000 + }); + await toc.cert(cat); + await s1.commit({ + time: now + 5000 + }); + await s1.commit({ + time: now + 5000 + }); + await s1.commit({ + time: now + 5000 }); }); @@ -117,7 +110,7 @@ describe("Identities kicking", function() { */ it('membershipExpiresIn should be positive for cat (actualized member)', function() { - return expectAnswer(rp('http://127.0.0.1:8561/wot/requirements/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', { json: true }), (res) => { + return expectAnswer(rp('http://127.0.0.1:8561/wot/requirements/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', { json: true }), (res:HttpRequirements) => { res.should.have.property('identities').length(1); res.identities[0].should.have.property('pubkey').equal('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); res.identities[0].should.have.property('uid').equal('cat'); @@ -127,7 +120,7 @@ describe("Identities kicking", function() { }); it('membershipExpiresIn should be positive for toc (member)', function() { - return expectAnswer(rp('http://127.0.0.1:8561/wot/requirements/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', { json: true }), (res) => { + return expectAnswer(rp('http://127.0.0.1:8561/wot/requirements/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', { json: true }), (res:HttpRequirements) => { res.should.have.property('identities').length(1); res.identities[0].should.have.property('pubkey').equal('DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'); res.identities[0].should.have.property('uid').equal('toc'); @@ -137,7 +130,7 @@ describe("Identities kicking", function() { }); it('membershipExpiresIn should equal 0 for a kicked member', function() { - return expectAnswer(rp('http://127.0.0.1:8561/wot/requirements/2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', { json: true }), (res) => { + return expectAnswer(rp('http://127.0.0.1:8561/wot/requirements/2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', { json: true }), (res:HttpRequirements) => { res.should.have.property('identities').length(1); res.identities[0].should.have.property('pubkey').equal('2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc'); res.identities[0].should.have.property('uid').equal('tac'); diff --git a/test/integration/lookup.js b/test/integration/identity/identity-lookup.ts similarity index 80% rename from test/integration/lookup.js rename to test/integration/identity/identity-lookup.ts index 39d776da2fa8c13a03fbc90ed9c068a326ef9f95..c893fb9f8edffe4eec08fe579e12aadd78ca97e2 100644 --- a/test/integration/lookup.js +++ b/test/integration/identity/identity-lookup.ts @@ -11,16 +11,15 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {BmaDependency} from "../../../app/modules/bma/index" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {HttpLookup, HttpMemberships} from "../../../app/modules/bma/lib/dtos" -const _ = require('underscore'); -const co = require('co'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const TestUser = require('./tools/TestUser').TestUser const rp = require('request-promise'); -const httpTest = require('./tools/http'); -const shutDownEngine = require('./tools/shutDownEngine'); +const httpTest = require('../tools/http'); +const shutDownEngine = require('../tools/shutDownEngine'); const MEMORY_MODE = true; const commonConf = { @@ -28,16 +27,16 @@ const commonConf = { currency: 'bb' }; -let s1, cat, tic1, tic2 +let s1:TestingServer, cat:TestUser, tic1:TestUser, tic2:TestUser describe("Lookup identity grouping", () => { - before(() => co(function *() { + before(async () => { - s1 = duniter( - 'bb12', - MEMORY_MODE, - _.extend({ + s1 = NewTestingServer( + Underscore.extend({ + name: 'bb12', + memory: MEMORY_MODE, port: '4452', pair: { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', @@ -50,22 +49,22 @@ describe("Lookup identity grouping", () => { tic2 = new TestUser('tic2', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s1 }); // Server initialization - yield s1.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); + await s1.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); // cat is publishing its identity, no problem - yield cat.createIdentity(); + await cat.createIdentity(); // tic1 is publishing its identity - yield tic1.createIdentity(); + await tic1.createIdentity(); // tic2 is publishing its identity, but he has **the same pubkey as tic1**. // This is OK on the protocol side, but the lookup should group the 2 identities // under the same pubkey - yield tic2.createIdentity(); + await tic2.createIdentity(); - yield cat.join(); - yield tic1.join(); - })); + await cat.join(); + await tic1.join(); + }) after(() => { return Promise.all([ @@ -73,7 +72,7 @@ describe("Lookup identity grouping", () => { ]) }) - it('cat should have only 1 identity in 1 pubkey', () => httpTest.expectAnswer(rp('http://127.0.0.1:4452/wot/lookup/cat', { json: true }), (res) => { + it('cat should have only 1 identity in 1 pubkey', () => httpTest.expectAnswer(rp('http://127.0.0.1:4452/wot/lookup/cat', { json: true }), (res:HttpLookup) => { res.should.have.property('results').length(1); // cat pubkey res.results[0].should.have.property('pubkey').equal('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); @@ -83,7 +82,7 @@ describe("Lookup identity grouping", () => { res.results[0].uids[0].should.have.property('uid').equal('cat'); })); - it('tic should have only 2 identities in 1 pubkey', () => httpTest.expectAnswer(rp('http://127.0.0.1:4452/wot/lookup/tic', { json: true }), (res) => { + it('tic should have only 2 identities in 1 pubkey', () => httpTest.expectAnswer(rp('http://127.0.0.1:4452/wot/lookup/tic', { json: true }), (res:HttpLookup) => { // We want to have only 1 result for the 2 identities res.should.have.property('results').length(1); // because they share the same pubkey @@ -96,7 +95,7 @@ describe("Lookup identity grouping", () => { res.results[0].uids[1].should.have.property('uid').equal('tic2'); })); - it('should exist 2 pending memberships', () => httpTest.expectAnswer(rp('http://127.0.0.1:4452/wot/pending', { json: true }), (res) => { + it('should exist 2 pending memberships', () => httpTest.expectAnswer(rp('http://127.0.0.1:4452/wot/pending', { json: true }), (res:HttpMemberships) => { res.should.have.property('memberships').length(2); res.memberships[0].should.have.property('pubkey').equal('DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV'); res.memberships[0].should.have.property('uid').equal('tic1'); diff --git a/test/integration/identity-pulling.js b/test/integration/identity/identity-pulling.ts similarity index 69% rename from test/integration/identity-pulling.js rename to test/integration/identity/identity-pulling.ts index 8d3058b125856cfadedd0e9eb15eb775f15355bb..6e3640348321b9a034509c8f911ebf6fe44a478d 100644 --- a/test/integration/identity-pulling.js +++ b/test/integration/identity/identity-pulling.ts @@ -11,28 +11,27 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {HttpRequirements} from "../../../app/modules/bma/lib/dtos" +import {CrawlerDependency} from "../../../app/modules/crawler/index" -const _ = require('underscore'); -const co = require('co'); const assert = require('assert'); -const TestUser = require('./tools/TestUser').TestUser -const commit = require('./tools/commit'); -const toolbox = require('./tools/toolbox'); -let s1, s2, cat1, tac1, toc2, tic2, tuc2 +let s1:TestingServer, s2:TestingServer, cat1:TestUser, tac1:TestUser, toc2:TestUser, tic2:TestUser, tuc2:TestUser describe("Identity pulling", function() { - before(() => co(function*() { + before(async () => { - s1 = toolbox.server({ + s1 = NewTestingServer({ pair: { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' } }); - s2 = toolbox.server({ + s2 = NewTestingServer({ pair: { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE' @@ -45,17 +44,17 @@ describe("Identity pulling", function() { tic2 = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s2 }); tuc2 = new TestUser('tuc', { pub: '3conGDUXdrTGbQPMQQhEC4Ubu1MCAnFrAYvUaewbUhtk', sec: '5ks7qQ8Fpkin7ycXpxQSxxjVhs8VTzpM3vEBMqM7NfC1ZiFJ93uQryDcoM93Mj77T6hDAABdeHZJDFnkDb35bgiU'}, { server: s2 }); - yield s1.prepareForNetwork(); - yield s2.prepareForNetwork(); + await s1.prepareForNetwork(); + await s2.prepareForNetwork(); // Publishing identities - yield cat1.createIdentity(); - yield tac1.createIdentity(); - yield cat1.cert(tac1); - yield tac1.cert(cat1); - yield cat1.join(); - yield tac1.join(); - })); + await cat1.createIdentity(); + await tac1.createIdentity(); + await cat1.cert(tac1); + await tac1.cert(cat1); + await cat1.join(); + await tac1.join(); + }) after(() => { return Promise.all([ @@ -64,48 +63,48 @@ describe("Identity pulling", function() { ]) }) - it('toc, tic and tuc can create their account on s2', () => co(function*() { - yield toc2.createIdentity(); - yield tic2.createIdentity(); - yield tuc2.createIdentity(); - yield toc2.join(); - yield tic2.join(); - yield tuc2.join(); + it('toc, tic and tuc can create their account on s2', async () => { + await toc2.createIdentity(); + await tic2.createIdentity(); + await tuc2.createIdentity(); + await toc2.join(); + await tic2.join(); + await tuc2.join(); // 2 certs for toc - yield cat1.cert(toc2, s2, s2); - yield tac1.cert(toc2, s2, s2); + await cat1.cert(toc2, s2, s2); + await tac1.cert(toc2, s2, s2); // 1 certs for tic - yield cat1.cert(tic2, s2, s2); + await cat1.cert(tic2, s2, s2); // 0 certs for tuc // tic2 also revokes its pending identity - yield tic2.revoke() - })); + await tic2.revoke() + }) - it('toc should not be known of s1', () => co(function*() { - yield s1.expectError('/wot/lookup/toc', 404) - })); + it('toc should not be known of s1', async () => { + await s1.expectError('/wot/lookup/toc', 404) + }) - it('tic should not be known of s1', () => co(function*() { - yield s1.expectError('/wot/lookup/tic', 404) - })); + it('tic should not be known of s1', async () => { + await s1.expectError('/wot/lookup/tic', 404) + }) - it('tuc should not be known of s1', () => co(function*() { - yield s1.expectError('/wot/lookup/tuc', 404) - })); + it('tuc should not be known of s1', async () => { + await s1.expectError('/wot/lookup/tuc', 404) + }) - it('toc should have 2 certs on server2', () => co(function*() { - yield s2.expectThat('/wot/requirements-of-pending/2', (json) => { + it('toc should have 2 certs on server2', async () => { + await s2.expectThat('/wot/requirements-of-pending/2', (json:HttpRequirements) => { assert.equal(json.identities.length, 1) assert.equal(json.identities[0].pubkey, 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo') assert.equal(json.identities[0].uid, 'toc') assert.equal(json.identities[0].pendingCerts.length, 2) assert.equal(json.identities[0].pendingMemberships.length, 1) }) - })); + }) - it('tic should have 1 certs on server2', () => co(function*() { - yield s2.expectThat('/wot/requirements-of-pending/1', (json) => { + it('tic should have 1 certs on server2', async () => { + await s2.expectThat('/wot/requirements-of-pending/1', (json:HttpRequirements) => { assert.equal(json.identities.length, 2) assert.equal(json.identities[1].pubkey, 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV') @@ -118,18 +117,18 @@ describe("Identity pulling", function() { assert.equal(json.identities[0].pendingCerts.length, 2) assert.equal(json.identities[0].pendingMemberships.length, 1) }) - })); + }) - it('s1 should be able to pull sandbox data from s2', () => co(function*() { + it('s1 should be able to pull sandbox data from s2', async () => { - yield s2.sharePeeringWith(s1) - const pullSandbox = require('../../app/modules/crawler').CrawlerDependency.duniter.methods.pullSandbox - yield pullSandbox(s1) - yield pullSandbox(s1) + await s2.sharePeeringWith(s1) + const pullSandbox = CrawlerDependency.duniter.methods.pullSandbox + await pullSandbox(s1._server) + await pullSandbox(s1._server) - yield s1.expectThat('/wot/requirements-of-pending/1', (json) => { + await s1.expectThat('/wot/requirements-of-pending/1', (json:HttpRequirements) => { - json.identities = _.sortBy(json.identities, 'pubkey') + json.identities = Underscore.sortBy(json.identities, 'pubkey') assert.equal(json.identities.length, 4) assert.equal(json.identities[3].pubkey, 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd') @@ -156,6 +155,6 @@ describe("Identity pulling", function() { assert.equal(json.identities[1].pendingCerts.length, 2) assert.equal(json.identities[1].pendingMemberships.length, 1) }) - })); + }) -}); +}) diff --git a/test/integration/revocation-test.js b/test/integration/identity/identity-revocation-test.ts similarity index 55% rename from test/integration/revocation-test.js rename to test/integration/identity/identity-revocation-test.ts index c0a62ae78262f77cabc2ad10da6520267125a316..1a60685f1ca9e2343bb229e07d6d88868350dbb7 100644 --- a/test/integration/revocation-test.js +++ b/test/integration/identity/identity-revocation-test.ts @@ -13,20 +13,20 @@ "use strict"; -const _ = require('underscore'); -const co = require('co'); +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {BmaDependency} from "../../../app/modules/bma/index" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {HttpLookup, HttpMembers} from "../../../app/modules/bma/lib/dtos" + const should = require('should'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const TestUser = require('./tools/TestUser').TestUser const rp = require('request-promise'); -const httpTest = require('./tools/http'); -const commit = require('./tools/commit'); -const shutDownEngine = require('./tools/shutDownEngine'); +const httpTest = require('../tools/http'); +const shutDownEngine = require('../tools/shutDownEngine'); const expectAnswer = httpTest.expectAnswer; -require('../../app/modules/bma').BmaDependency.duniter.methods.noLimit(); // Disables the HTTP limiter +BmaDependency.duniter.methods.noLimit(); // Disables the HTTP limiter const MEMORY_MODE = true; const commonConf = { @@ -40,64 +40,59 @@ const commonConf = { avgGenTime: 300 }; -let s1, s2, cat, tic, toc, tacOnS1, tacOnS2 - -const commitS1 = (opts) => commit(s1)(opts) +let s1:TestingServer, s2:TestingServer, cat:TestUser, tic:TestUser, toc:TestUser, tacOnS1:TestUser, tacOnS2:TestUser describe("Revocation", function() { - before(function() { - - return co(function *() { - - s1 = duniter( - '/bb12', - MEMORY_MODE, - _.extend({ - port: '9964', - pair: { - pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', - sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F' - } - }, commonConf)); - - s2 = duniter( - '/bb13', - MEMORY_MODE, - _.extend({ - port: '9965', - pair: { - pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', - sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' - } - }, commonConf)); - - cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); - tic = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s1 }); - toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); - tacOnS1 = new TestUser('tac', { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}, { server: s1 }); - tacOnS2 = new TestUser('tac', { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}, { server: s2 }); - - const now = 1400000000 - yield s1.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); - yield s2.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); - yield cat.createIdentity(); - yield tic.createIdentity(); - yield toc.createIdentity(); - yield cat.cert(tic); - yield tic.cert(cat); - yield tic.cert(toc); - yield toc.cert(tic); - yield cat.join(); - yield tic.join(); - yield toc.join(); - yield commitS1({ time: now }); - - // We have the following WoT: - /** - * cat <-> tic <-> toc - */ - }); + before(async () => { + + s1 = NewTestingServer( + Underscore.extend({ + name: 'bb12', + memory: MEMORY_MODE, + port: '9964', + pair: { + pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', + sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F' + } + }, commonConf)); + + s2 = NewTestingServer( + Underscore.extend({ + name: 'bb13', + memory: MEMORY_MODE, + port: '9965', + pair: { + pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', + sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' + } + }, commonConf)); + + cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); + tic = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s1 }); + toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); + tacOnS1 = new TestUser('tac', { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}, { server: s1 }); + tacOnS2 = new TestUser('tac', { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}, { server: s2 }); + + const now = 1400000000 + await s1.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); + await s2.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); + await cat.createIdentity(); + await tic.createIdentity(); + await toc.createIdentity(); + await cat.cert(tic); + await tic.cert(cat); + await tic.cert(toc); + await toc.cert(tic); + await cat.join(); + await tic.join(); + await toc.join(); + await s1.commit({ time: now }); + + // We have the following WoT: + /** + * cat <-> tic <-> toc + */ }); after(() => { @@ -108,13 +103,13 @@ describe("Revocation", function() { }) it('should have 3 members', function() { - return expectAnswer(rp('http://127.0.0.1:9964/wot/members', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:9964/wot/members', { json: true }), function(res:HttpMembers) { res.should.have.property('results').length(3); - _.pluck(res.results, 'uid').sort().should.deepEqual(['cat', 'tic', 'toc']); + Underscore.pluck(res.results, 'uid').sort().should.deepEqual(['cat', 'tic', 'toc']); }); }); - it('cat should not be revoked yet', () => expectAnswer(rp('http://127.0.0.1:9964/wot/lookup/cat', { json: true }), function(res) { + it('cat should not be revoked yet', () => expectAnswer(rp('http://127.0.0.1:9964/wot/lookup/cat', { json: true }), function(res:HttpLookup) { res.should.have.property('results').length(1); res.results[0].should.have.property('uids').length(1); res.results[0].uids[0].should.have.property('uid').equal('cat'); @@ -123,9 +118,9 @@ describe("Revocation", function() { res.results[0].uids[0].should.have.property('revocation_sig').equal(null); })); - it('sending a revocation for cat should be displayed', () => co(function *() { - yield cat.revoke(); - return expectAnswer(rp('http://127.0.0.1:9964/wot/lookup/cat', { json: true }), function(res) { + it('sending a revocation for cat should be displayed', async () => { + await cat.revoke(); + return expectAnswer(rp('http://127.0.0.1:9964/wot/lookup/cat', { json: true }), function(res:HttpLookup) { res.should.have.property('results').length(1); res.results[0].should.have.property('uids').length(1); res.results[0].uids[0].should.have.property('uid').equal('cat'); @@ -134,14 +129,14 @@ describe("Revocation", function() { res.results[0].uids[0].should.have.property('revocation_sig').not.equal(null); res.results[0].uids[0].should.have.property('revocation_sig').not.equal(''); }); - })); + }) - it('sending a revocation for tac should add an identity', () => co(function *() { - yield tacOnS1.createIdentity(); - const idty = yield tacOnS1.lookup(tacOnS1.pub); - yield tacOnS2.revoke(idty); + it('sending a revocation for tac should add an identity', async () => { + await tacOnS1.createIdentity(); + const idty = await tacOnS1.lookup(tacOnS1.pub); + await tacOnS2.revoke(idty); // On S1 server, tac is known as normal identity - yield expectAnswer(rp('http://127.0.0.1:9964/wot/lookup/tac', { json: true }), function(res) { + await expectAnswer(rp('http://127.0.0.1:9964/wot/lookup/tac', { json: true }), function(res:HttpLookup) { res.should.have.property('results').length(1); res.results[0].should.have.property('uids').length(1); res.results[0].uids[0].should.have.property('uid').equal('tac'); @@ -150,7 +145,7 @@ describe("Revocation", function() { res.results[0].uids[0].should.have.property('revocation_sig').equal(null); }); // On S2 server, tac is known as identity with revocation pending (not written! so `revoked` field is false) - yield expectAnswer(rp('http://127.0.0.1:9965/wot/lookup/tac', { json: true }), function(res) { + await expectAnswer(rp('http://127.0.0.1:9965/wot/lookup/tac', { json: true }), function(res:HttpLookup) { res.should.have.property('results').length(1); res.results[0].should.have.property('uids').length(1); res.results[0].uids[0].should.have.property('uid').equal('tac'); @@ -159,12 +154,12 @@ describe("Revocation", function() { res.results[0].uids[0].should.have.property('revocation_sig').not.equal(null); res.results[0].uids[0].should.have.property('revocation_sig').not.equal(''); }); - })); + }) - it('if we commit a revocation, cat should be revoked', () => co(function *() { - yield commitS1({ revoked: [], excluded: [] }); - yield commitS1(); - return expectAnswer(rp('http://127.0.0.1:9964/wot/lookup/cat', { json: true }), function(res) { + it('if we commit a revocation, cat should be revoked', async () => { + await s1.commit({ revoked: [], excluded: [] }); + await s1.commit(); + return expectAnswer(rp('http://127.0.0.1:9964/wot/lookup/cat', { json: true }), function(res:HttpLookup) { res.should.have.property('results').length(1); res.results[0].should.have.property('uids').length(1); res.results[0].uids[0].should.have.property('uid').equal('cat'); @@ -173,33 +168,33 @@ describe("Revocation", function() { res.results[0].uids[0].should.have.property('revocation_sig').not.equal(null); res.results[0].uids[0].should.have.property('revocation_sig').not.equal(''); }); - })); + }) it('should have 2 members', function() { - return expectAnswer(rp('http://127.0.0.1:9964/wot/members', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:9964/wot/members', { json: true }), function(res:HttpMembers) { res.should.have.property('results').length(2); - _.pluck(res.results, 'uid').sort().should.deepEqual(['tic','toc']); + Underscore.pluck(res.results, 'uid').sort().should.deepEqual(['tic','toc']); }); }); - it('cat should not be able to join back', () => co(function *() { + it('cat should not be able to join back', async () => { try { - yield cat.join(); + await cat.join(); } catch (e) { should.exists(e); } - yield commitS1(); - return expectAnswer(rp('http://127.0.0.1:9964/wot/members', { json: true }), function(res) { + await s1.commit(); + return expectAnswer(rp('http://127.0.0.1:9964/wot/members', { json: true }), function(res:HttpMembers) { res.should.have.property('results').length(2); - _.pluck(res.results, 'uid').sort().should.deepEqual(['tic','toc']); + Underscore.pluck(res.results, 'uid').sort().should.deepEqual(['tic','toc']); }); - })); + }) - it('if we revert the commit, cat should not be revoked', () => co(function *() { - yield s1.revert(); - yield s1.revert(); - yield s1.dal.blockDAL.removeForkBlockAboveOrEqual(2) - return expectAnswer(rp('http://127.0.0.1:9964/wot/lookup/cat', { json: true }), function(res) { + it('if we revert the commit, cat should not be revoked', async () => { + await s1.revert(); + await s1.revert(); + await s1.dal.blockDAL.removeForkBlockAboveOrEqual(2) + return expectAnswer(rp('http://127.0.0.1:9964/wot/lookup/cat', { json: true }), function(res:HttpLookup) { res.should.have.property('results').length(1); res.results[0].should.have.property('uids').length(1); res.results[0].uids[0].should.have.property('uid').equal('cat'); @@ -208,11 +203,11 @@ describe("Revocation", function() { res.results[0].uids[0].should.have.property('revocation_sig').equal(null); // We loose the revocation res.results[0].uids[0].should.have.property('revocation_sig').equal(null); }); - })); + }) - it('if we commit again, cat should NOT be revoked (we have lost the revocation)', () => co(function *() { - yield commitS1(); - return expectAnswer(rp('http://127.0.0.1:9964/wot/lookup/cat', { json: true }), function(res) { + it('if we commit again, cat should NOT be revoked (we have lost the revocation)', async () => { + await s1.commit(); + return expectAnswer(rp('http://127.0.0.1:9964/wot/lookup/cat', { json: true }), function(res:HttpLookup) { res.should.have.property('results').length(1); res.results[0].should.have.property('uids').length(1); res.results[0].uids[0].should.have.property('uid').equal('cat'); @@ -221,6 +216,6 @@ describe("Revocation", function() { res.results[0].uids[0].should.have.property('revocation_sig').equal(null); // We loose the revocation res.results[0].uids[0].should.have.property('revocation_sig').equal(null); }); - })); + }) -}); +}) diff --git a/test/integration/tests.js b/test/integration/identity/identity-several-tests.ts similarity index 57% rename from test/integration/tests.js rename to test/integration/identity/identity-several-tests.ts index 3632bfefb5776f5ecb6c96de65427e7c3c80e5d7..316be2f478cee34a2b9daa1e91b6990eb362eda2 100644 --- a/test/integration/tests.js +++ b/test/integration/identity/identity-several-tests.ts @@ -11,27 +11,26 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {TestUser} from "../tools/TestUser" +import {BmaDependency} from "../../../app/modules/bma/index" +import {HttpBlock, HttpLookup, HttpSigned, HttpSummary} from "../../../app/modules/bma/lib/dtos" +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {Underscore} from "../../../app/lib/common-libs/underscore" -const co = require('co'); -const _ = require('underscore'); const should = require('should'); const assert = require('assert'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const constants = require('../../app/lib/constants'); -const node = require('./tools/node'); -const duniter = require('../../index'); -const TestUser = require('./tools/TestUser').TestUser -const jspckg = require('../../package'); -const commit = require('./tools/commit'); -const httpTest = require('./tools/http'); -const shutDownEngine = require('./tools/shutDownEngine'); +const request = require('request'); +const constants = require('../../../app/lib/constants'); +const node = require('../tools/node'); +const jspckg = require('../../../package'); +const httpTest = require('../tools/http'); +const shutDownEngine = require('../tools/shutDownEngine'); const rp = require('request-promise'); const expectAnswer = httpTest.expectAnswer; const MEMORY_MODE = true; -require('../../app/modules/bma').BmaDependency.duniter.methods.noLimit(); // Disables the HTTP limiter +BmaDependency.duniter.methods.noLimit(); // Disables the HTTP limiter describe("Integration", function() { @@ -65,7 +64,7 @@ describe("Integration", function() { }); after(node1.after()); - it('/node/summary should give package.json version', node1.summary(function(summary, done){ + it('/node/summary should give package.json version', node1.summary(function(summary:HttpSummary, done:any){ should.exists(summary); should.exists(summary.duniter); should.exists(summary.duniter.software); @@ -79,7 +78,39 @@ describe("Integration", function() { describe("Testing malformed documents", function(){ before(function(done) { - node1.before(require('./scenarios/malformed-documents')(node1))(done); + node1.before(function(node1) { + + const malformedTransaction = "Version: 2\n" + + "Type: Transaction\n" + + "Currency: null\n" + + "Issuers:\n" + + "G2CBgZBPLe6FSFUgpx2Jf1Aqsgta6iib3vmDRA1yLiqU\n" + + "Inputs:\n" + + "0:T:1536:539CB0E60CD5F55CF1BE96F067E73BF55C052112:1.0\n" + + "Outputs:Comment: mon comments\n"; + + + function sendRaw (raw:string) { + return function(done:any) { + post('/tx/process', { + "transaction": raw + }, done); + } + } + + function post(uri:string, data:any, done:any) { + const postReq = request.post({ + "uri": 'http://' + [node1.server.conf.remoteipv4, node1.server.conf.remoteport].join(':') + uri, + "timeout": 1000 * 10 + }, function (err:any, res:any, body:any) { + done(err, res, body); + }); + postReq.form(data); + } + return [ + sendRaw(malformedTransaction) + ]; + }(node1))(done); }); after(node1.after()); @@ -90,54 +121,53 @@ describe("Integration", function() { describe("Lookup on", function(){ - before(function() { - return co(function *() { + before(async () => { - // Self certifications - yield cat.createIdentity(); - yield tac.createIdentity(); - yield tic.createIdentity(); - yield toc.createIdentity(); - // Certifications - yield cat.cert(tac); - }); + // Self certifications + await cat.createIdentity(); + await tac.createIdentity(); + await tic.createIdentity(); + await toc.createIdentity(); + // Certifications + await cat.cert(tac); }); + after(node1.after()); describe("identities collisions", () => { - it("sending same identity should fail", () => co(function *() { + it("sending same identity should fail", async () => { // We send again the same try { - yield tic.createIdentity(); + await tic.createIdentity(); throw 'Should have thrown an error'; } catch (e) { JSON.parse(e).ucode.should.equal(constants.ERRORS.ALREADY_UP_TO_DATE.uerr.ucode); } - })); + }) - it("sending same identity (again) should fail", () => co(function *() { + it("sending same identity (again) should fail", async () => { // We send again the same try { - yield tic.createIdentity(); + await tic.createIdentity(); throw 'Should have thrown an error'; } catch (e) { JSON.parse(e).ucode.should.equal(constants.ERRORS.ALREADY_UP_TO_DATE.uerr.ucode); } - })); + }) }); describe("user cat", function(){ - it('should give only 1 result', node1.lookup('cat', function(res, done){ + it('should give only 1 result', node1.lookup('cat', function(res:HttpLookup, done:any){ should.exists(res); assert.equal(res.results.length, 1); done(); })); - it('should have sent 1 signature', node1.lookup('cat', function(res, done){ + it('should have sent 1 signature', node1.lookup('cat', function(res:HttpLookup, done:any){ should.exists(res); assert.equal(res.results[0].signed.length, 1); should.exists(res.results[0].signed[0].isMember); @@ -150,32 +180,32 @@ describe("Integration", function() { describe("user tac", function(){ - it('should give only 1 result', node1.lookup('tac', function(res, done){ + it('should give only 1 result', node1.lookup('tac', function(res:HttpLookup, done:any){ should.exists(res); assert.equal(res.results.length, 1); done(); })); - it('should have 1 signature', node1.lookup('tac', function(res, done){ + it('should have 1 signature', node1.lookup('tac', function(res:HttpLookup, done:any){ should.exists(res); assert.equal(res.results[0].uids[0].others.length, 1); done(); })); - it('should have sent 0 signature', node1.lookup('tac', function(res, done){ + it('should have sent 0 signature', node1.lookup('tac', function(res:HttpLookup, done:any){ should.exists(res); assert.equal(res.results[0].signed.length, 0); done(); })); }); - it('toc should give only 1 result', node1.lookup('toc', function(res, done){ + it('toc should give only 1 result', node1.lookup('toc', function(res:HttpLookup, done:any){ should.exists(res); assert.equal(res.results.length, 1); done(); })); - it('tic should give only 1 result', node1.lookup('tic', function(res, done){ + it('tic should give only 1 result', node1.lookup('tic', function(res:HttpLookup, done:any){ should.exists(res); assert.equal(res.results.length, 1); done(); @@ -185,69 +215,69 @@ describe("Integration", function() { describe("Testing leavers", function(){ - let node3, cat, tac, tic, toc - - before(function() { - return co(function *() { - - node3 = duniter('/db3', MEMORY_MODE, { - currency: 'dd', ipv4: 'localhost', port: 9997, remoteipv4: 'localhost', remoteport: 9997, httplogs: false, - rootoffset: 0, - sigQty: 1, sigPeriod: 0, - pair: { - pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', - sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' - } - }); + let node3:TestingServer, cat:TestUser, tac:TestUser, tic:TestUser, toc:TestUser - cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: node3 }); - tac = new TestUser('tac', { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}, { server: node3 }); - tic = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: node3 }); - toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: node3 }); + before(async () => { - yield node3.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); - const now = 1482220000; + node3 = NewTestingServer({ + name: 'db3', + memory: MEMORY_MODE, + currency: 'dd', ipv4: 'localhost', port: 9997, remoteipv4: 'localhost', remoteport: 9997, httplogs: false, + rootoffset: 0, + sigQty: 1, sigPeriod: 0, + pair: { + pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', + sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' + } + }); - // Self certifications - yield cat.createIdentity(); - yield tac.createIdentity(); - yield tic.createIdentity(); - yield toc.createIdentity(); - yield cat.cert(tac); - yield cat.cert(tic); - yield cat.cert(toc); - yield tac.cert(cat); - yield tac.cert(tic); - yield tic.cert(cat); - yield tic.cert(tac); - yield toc.cert(cat); - yield cat.join(); - yield tac.join(); - yield tic.join(); - yield toc.join(); - yield commit(node3)({ - time: now - }); - yield commit(node3)({ - time: now - }); - yield toc.leave(); - yield commit(node3)({ - time: now - }); - yield tac.cert(toc); - yield tic.cert(toc); - yield toc.cert(tic); // Should be taken in 1 block - yield toc.cert(tac); // Should be taken in 1 other block - yield commit(node3)({ - time: now + 200 - }); - yield commit(node3)({ - time: now + 200 - }); - yield commit(node3)({ - time: now + 200 - }); + cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: node3 }); + tac = new TestUser('tac', { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}, { server: node3 }); + tic = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: node3 }); + toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: node3 }); + + await node3.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); + const now = 1482220000; + + // Self certifications + await cat.createIdentity(); + await tac.createIdentity(); + await tic.createIdentity(); + await toc.createIdentity(); + await cat.cert(tac); + await cat.cert(tic); + await cat.cert(toc); + await tac.cert(cat); + await tac.cert(tic); + await tic.cert(cat); + await tic.cert(tac); + await toc.cert(cat); + await cat.join(); + await tac.join(); + await tic.join(); + await toc.join(); + await node3.commit({ + time: now + }); + await node3.commit({ + time: now + }); + await toc.leave(); + await node3.commit({ + time: now + }); + await tac.cert(toc); + await tic.cert(toc); + await toc.cert(tic); // Should be taken in 1 block + await toc.cert(tac); // Should be taken in 1 other block + await node3.commit({ + time: now + 200 + }); + await node3.commit({ + time: now + 200 + }); + await node3.commit({ + time: now + 200 }); }); @@ -257,24 +287,24 @@ describe("Integration", function() { ]) }) - it('toc should give only 1 result with 3 certification by others', () => expectAnswer(rp('http://127.0.0.1:9997/wot/lookup/toc', { json: true }), function(res) { + it('toc should give only 1 result with 3 certification by others', () => expectAnswer(rp('http://127.0.0.1:9997/wot/lookup/toc', { json: true }), function(res:HttpLookup) { should.exists(res); assert.equal(res.results.length, 1); assert.equal(res.results[0].uids[0].others.length, 3); })); - it('tic should give only 1 results', () => expectAnswer(rp('http://127.0.0.1:9997/wot/lookup/tic', { json: true }), function(res) { + it('tic should give only 1 results', () => expectAnswer(rp('http://127.0.0.1:9997/wot/lookup/tic', { json: true }), function(res:HttpLookup) { should.exists(res); - const uids = _.pluck(res.results[0].signed, 'uid'); + const uids = Underscore.pluck(res.results[0].signed, 'uid'); const uidsShould = ["cat", "tac", "toc"]; uids.sort(); uidsShould.sort(); assert.deepEqual(uids, uidsShould); assert.equal(res.results.length, 1); assert.equal(res.results[0].signed.length, 3); - const cat_signed = _.findWhere(res.results[0].signed, { uid: 'cat'}); - const tac_signed = _.findWhere(res.results[0].signed, { uid: 'tac'}); - const toc_signed = _.findWhere(res.results[0].signed, { uid: 'toc'}); + const cat_signed = Underscore.findWhere(res.results[0].signed, { uid: 'cat'}) as HttpSigned + const tac_signed = Underscore.findWhere(res.results[0].signed, { uid: 'tac'}) as HttpSigned + const toc_signed = Underscore.findWhere(res.results[0].signed, { uid: 'toc'}) as HttpSigned assert.equal(cat_signed.uid, "cat"); assert.equal(cat_signed.isMember, true); assert.equal(cat_signed.wasMember, true); @@ -290,7 +320,7 @@ describe("Integration", function() { assert.equal(res.results[0].uids[0].others[0].wasMember, true); })); - it('it should exist block#2 with 4 members', () => expectAnswer(rp('http://127.0.0.1:9997/blockchain/block/2', { json: true }), function(block) { + it('it should exist block#2 with 4 members', () => expectAnswer(rp('http://127.0.0.1:9997/blockchain/block/2', { json: true }), function(block:HttpBlock) { should.exists(block); assert.equal(block.number, 2); assert.equal(block.membersCount, 4); @@ -303,8 +333,8 @@ describe("Integration", function() { blockShouldHaveCerts(4, 1); blockShouldHaveCerts(5, 0); - function blockShouldHaveCerts(number, certificationsCount) { - it('it should exist block#' + number + ' with ' + certificationsCount + ' certification', () => expectAnswer(rp('http://127.0.0.1:9997/blockchain/block/' + number, { json: true }), function(block) { + function blockShouldHaveCerts(number:number, certificationsCount:number) { + it('it should exist block#' + number + ' with ' + certificationsCount + ' certification', () => expectAnswer(rp('http://127.0.0.1:9997/blockchain/block/' + number, { json: true }), function(block:HttpBlock) { should.exists(block); assert.equal(block.number, number); assert.equal(block.certifications.length, certificationsCount); diff --git a/test/integration/identity-test.js b/test/integration/identity/identity-test.ts similarity index 83% rename from test/integration/identity-test.js rename to test/integration/identity/identity-test.ts index ec434a0d0bccd9e385921f1feaeb918ac42519a4..7580016c48cbc245e3d867688752d9e624f46d6c 100644 --- a/test/integration/identity-test.js +++ b/test/integration/identity/identity-test.ts @@ -11,21 +11,26 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {BmaDependency} from "../../../app/modules/bma/index" +import { + HttpCertifications, + HttpIdentity, + HttpMembers, + HttpMemberships, + HttpRequirements +} from "../../../app/modules/bma/lib/dtos" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {ProverDependency} from "../../../app/modules/prover/index" -const _ = require('underscore'); -const co = require('co'); const should = require('should'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const TestUser = require('./tools/TestUser').TestUser -const constants = require('../../app/lib/constants'); +const constants = require('../../../app/lib/constants'); const rp = require('request-promise'); -const httpTest = require('./tools/http'); -const commit = require('./tools/commit'); -const shutDownEngine = require('./tools/shutDownEngine'); +const httpTest = require('../tools/http'); +const shutDownEngine = require('../tools/shutDownEngine'); -require('../../app/modules/bma').BmaDependency.duniter.methods.noLimit(); // Disables the HTTP limiter +BmaDependency.duniter.methods.noLimit(); // Disables the HTTP limiter const expectAnswer = httpTest.expectAnswer; @@ -40,16 +45,16 @@ const commonConf = { sigQty: 1 }; -let s1, cat, tac, tic, toc, tic2, man1, man2, man3 +let s1:TestingServer, cat:TestUser, tac:TestUser, tic:TestUser, toc:TestUser, tic2:TestUser, man1:TestUser, man2:TestUser, man3:TestUser describe("Identities collision", function() { - before(function() { + before(async () => { - s1 = duniter( - '/bb11', - MEMORY_MODE, - _.extend({ + s1 = NewTestingServer( + Underscore.extend({ + name: 'bb11', + memory: MEMORY_MODE, port: '7799', pair: { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', @@ -66,67 +71,63 @@ describe("Identities collision", function() { man2 = new TestUser('man2', { pub: 'E44RxG9jKZQsaPLFSw2ZTJgW7AVRqo1NGy6KGLbKgtNm', sec: 'pJRwpaCWshKZNWsbDxAHFQbVjk6X8gz9eBy9jaLnVY9gUZRqotrZLZPZe68ag4vEX1Y8mX77NhPXV2hj9F1UkX3'}, { server: s1 }); man3 = new TestUser('man3', { pub: '5bfpAfZJ4xYspUBYseASJrofhRm6e6JMombt43HBaRzW', sec: '2VFQtEcYZRwjoc8Lxwfzcejtw9VP8VAi47WjwDDjCJCXu7g1tXUAbVZN3QmvG6NJqaSuLCuYP7WDHWkFmTrUEMaE'}, { server: s1 }); - const commitS1 = commit(s1); - - return co(function *() { - yield s1.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); - require('../../app/modules/prover').ProverDependency.duniter.methods.hookServer(s1); - yield cat.createIdentity(); - yield tac.createIdentity(); - yield toc.createIdentity(); - yield tic.createIdentity(); - yield toc.cert(cat); - yield cat.cert(toc); - yield cat.cert(tic); - yield tic.cert(tac); - yield tic.cert(cat); - yield cat.join(); - yield toc.join(); - yield tic.join(); - yield tac.join(); - yield commitS1(); - yield commitS1(); - - // We have the following WoT (diameter 3): - - /** - * toc <=> cat <=> tic -> tac - */ - - // cat is the sentry - - // Man1 is someone who just needs a commit to join - yield man1.createIdentity(); - yield man1.join(); - yield tac.cert(man1); - - /** - * toc <=> cat -> tic -> tac -> man1 - */ - - // Man2 is someone who has no certifications yet has sent a JOIN - yield man2.createIdentity(); - yield man2.join(); - - // Man3 is someone who has only published its identity - yield man3.createIdentity(); - - // tic RENEW, but not written - yield tic.join(); - - try { - yield tic.createIdentity(); - throw 'Should have thrown an error for already used pubkey'; - } catch (e) { - JSON.parse(e).message.should.equal('Pubkey already used in the blockchain'); - } - try { - yield tic2.createIdentity(); - throw 'Should have thrown an error for already used uid'; - } catch (e) { - JSON.parse(e).message.should.equal('UID already used in the blockchain'); - } - }); + await s1.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); + ProverDependency.duniter.methods.hookServer(s1._server) + await cat.createIdentity(); + await tac.createIdentity(); + await toc.createIdentity(); + await tic.createIdentity(); + await toc.cert(cat); + await cat.cert(toc); + await cat.cert(tic); + await tic.cert(tac); + await tic.cert(cat); + await cat.join(); + await toc.join(); + await tic.join(); + await tac.join(); + await s1.commit(); + await s1.commit(); + + // We have the following WoT (diameter 3): + + /** + * toc <=> cat <=> tic -> tac + */ + + // cat is the sentry + + // Man1 is someone who just needs a commit to join + await man1.createIdentity(); + await man1.join(); + await tac.cert(man1); + + /** + * toc <=> cat -> tic -> tac -> man1 + */ + + // Man2 is someone who has no certifications yet has sent a JOIN + await man2.createIdentity(); + await man2.join(); + + // Man3 is someone who has only published its identity + await man3.createIdentity(); + + // tic RENEW, but not written + await tic.join(); + + try { + await tic.createIdentity(); + throw 'Should have thrown an error for already used pubkey'; + } catch (e) { + JSON.parse(e).message.should.equal('Pubkey already used in the blockchain'); + } + try { + await tic2.createIdentity(); + throw 'Should have thrown an error for already used uid'; + } catch (e) { + JSON.parse(e).message.should.equal('UID already used in the blockchain'); + } }); after(() => { @@ -136,14 +137,14 @@ describe("Identities collision", function() { }) it('should have 4 members', function() { - return expectAnswer(rp('http://127.0.0.1:7799/wot/members', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7799/wot/members', { json: true }), function(res:HttpMembers) { res.should.have.property('results').length(4); - _.pluck(res.results, 'uid').sort().should.deepEqual(['cat', 'tac', 'tic', 'toc']); + Underscore.pluck(res.results, 'uid').sort().should.deepEqual(['cat', 'tac', 'tic', 'toc']); }); }); it('should have identity-of/cat', function() { - return expectAnswer(rp('http://127.0.0.1:7799/wot/identity-of/cat', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7799/wot/identity-of/cat', { json: true }), function(res:HttpIdentity) { res.should.have.property('pubkey').equal('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); res.should.have.property('uid').equal('cat'); res.should.have.property('sigDate').be.a.Number; @@ -151,7 +152,7 @@ describe("Identities collision", function() { }); it('should have identity-of/toc', function() { - return expectAnswer(rp('http://127.0.0.1:7799/wot/identity-of/toc', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7799/wot/identity-of/toc', { json: true }), function(res:HttpIdentity) { res.should.have.property('pubkey').equal('DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'); res.should.have.property('uid').equal('toc'); res.should.have.property('sigDate').be.a.Number; @@ -159,7 +160,7 @@ describe("Identities collision", function() { }); it('should have identity-of/tic', function() { - return expectAnswer(rp('http://127.0.0.1:7799/wot/identity-of/tic', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7799/wot/identity-of/tic', { json: true }), function(res:HttpIdentity) { res.should.have.property('pubkey').equal('DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV'); res.should.have.property('uid').equal('tic'); res.should.have.property('sigDate').be.a.Number; @@ -171,7 +172,7 @@ describe("Identities collision", function() { }); it('should have certifiers-of/cat giving results', function() { - return expectAnswer(rp('http://127.0.0.1:7799/wot/certifiers-of/cat', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7799/wot/certifiers-of/cat', { json: true }), function(res:HttpCertifications) { res.should.have.property('pubkey').equal('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); res.should.have.property('uid').equal('cat'); res.should.have.property('isMember').equal(true); @@ -194,7 +195,7 @@ describe("Identities collision", function() { }); it('should have certifiers-of/tic giving results', function() { - return expectAnswer(rp('http://127.0.0.1:7799/wot/certifiers-of/tic', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7799/wot/certifiers-of/tic', { json: true }), function(res:HttpCertifications) { res.should.have.property('pubkey').equal('DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV'); res.should.have.property('uid').equal('tic'); res.should.have.property('isMember').equal(true); @@ -215,7 +216,7 @@ describe("Identities collision", function() { }); it('should have certifiers-of/toc giving results', function() { - return expectAnswer(rp('http://127.0.0.1:7799/wot/certifiers-of/toc', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7799/wot/certifiers-of/toc', { json: true }), function(res:HttpCertifications) { res.should.have.property('pubkey').equal('DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'); res.should.have.property('uid').equal('toc'); res.should.have.property('isMember').equal(true); @@ -236,7 +237,7 @@ describe("Identities collision", function() { }); it('requirements of cat', function() { - return expectAnswer(rp('http://127.0.0.1:7799/wot/requirements/cat', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7799/wot/requirements/cat', { json: true }), function(res:HttpRequirements) { res.should.have.property('identities').be.an.Array; res.should.have.property('identities').have.length(1); res.identities[0].should.have.property('pubkey').equal('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); @@ -253,7 +254,7 @@ describe("Identities collision", function() { }); it('requirements of man1', function() { - return expectAnswer(rp('http://127.0.0.1:7799/wot/requirements/man1', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7799/wot/requirements/man1', { json: true }), function(res:HttpRequirements) { res.should.have.property('identities').be.an.Array; res.should.have.property('identities').have.length(1); res.identities[0].should.have.property('pubkey').equal('12AbjvYY5hxV4v2KrN9pnGzgFxogwrzgYyncYHHsyFDK'); @@ -272,7 +273,7 @@ describe("Identities collision", function() { }); it('should have certified-by/tic giving results', function() { - return expectAnswer(rp('http://127.0.0.1:7799/wot/certified-by/tic', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7799/wot/certified-by/tic', { json: true }), function(res:HttpCertifications) { res.should.have.property('pubkey').equal('DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV'); res.should.have.property('uid').equal('tic'); res.should.have.property('isMember').equal(true); @@ -300,7 +301,7 @@ describe("Identities collision", function() { }); it('should have certified-by/tac giving results', function() { - return expectAnswer(rp('http://127.0.0.1:7799/wot/certified-by/tac', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7799/wot/certified-by/tac', { json: true }), function(res:HttpCertifications) { res.should.have.property('pubkey').equal('2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc'); res.should.have.property('uid').equal('tac'); res.should.have.property('isMember').equal(true); @@ -310,7 +311,7 @@ describe("Identities collision", function() { }); it('should have certified-by/cat giving results', function() { - return expectAnswer(rp('http://127.0.0.1:7799/wot/certified-by/cat', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7799/wot/certified-by/cat', { json: true }), function(res:HttpCertifications) { res.should.have.property('pubkey').equal('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); res.should.have.property('uid').equal('cat'); res.should.have.property('isMember').equal(true); @@ -345,7 +346,7 @@ describe("Identities collision", function() { }); it('requirements of man2', function() { - return expectAnswer(rp('http://127.0.0.1:7799/wot/requirements/man2', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7799/wot/requirements/man2', { json: true }), function(res:HttpRequirements) { res.should.have.property('identities').be.an.Array; res.should.have.property('identities').have.length(1); res.identities[0].should.have.property('pubkey').equal('E44RxG9jKZQsaPLFSw2ZTJgW7AVRqo1NGy6KGLbKgtNm'); @@ -361,7 +362,7 @@ describe("Identities collision", function() { }); it('requirements of man3', function() { - return expectAnswer(rp('http://127.0.0.1:7799/wot/requirements/man3', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7799/wot/requirements/man3', { json: true }), function(res:HttpRequirements) { res.should.have.property('identities').be.an.Array; res.should.have.property('identities').have.length(1); res.identities[0].should.have.property('pubkey').equal('5bfpAfZJ4xYspUBYseASJrofhRm6e6JMombt43HBaRzW'); @@ -376,9 +377,9 @@ describe("Identities collision", function() { }); }); - it('requirements of man3 after revocation', () => co(function*() { - yield man3.revoke(); - return expectAnswer(rp('http://127.0.0.1:7799/wot/requirements/man3', { json: true }), function(res) { + it('requirements of man3 after revocation', async () => { + await man3.revoke(); + return expectAnswer(rp('http://127.0.0.1:7799/wot/requirements/man3', { json: true }), function(res:HttpRequirements) { res.should.have.property('identities').be.an.Array; res.should.have.property('identities').have.length(1); res.identities[0].should.have.property('pubkey').equal('5bfpAfZJ4xYspUBYseASJrofhRm6e6JMombt43HBaRzW'); @@ -394,10 +395,10 @@ describe("Identities collision", function() { res.identities[0].should.have.property('revoked_on').equal(null); res.identities[0].should.have.property('revocation_sig').not.equal(null); }); - })); + }) it('memberships of tic', function() { - return expectAnswer(rp('http://127.0.0.1:7799/blockchain/memberships/tic', { json: true }), function(res) { + return expectAnswer(rp('http://127.0.0.1:7799/blockchain/memberships/tic', { json: true }), function(res:HttpMemberships) { res.should.have.property('pubkey').equal('DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV'); res.should.have.property('uid').equal('tic'); res.should.have.property('sigDate').be.a.Number; @@ -410,7 +411,7 @@ describe("Identities collision", function() { res.memberships[0].should.have.property('blockHash').not.equal('E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855'); res.memberships[0].should.have.property('written').equal(null); }); - }); + }) // it('memberships of man3', function() { // return httpTest.expectHttpCode(404, rp('http://127.0.0.1:7799/blockchain/memberships/man3')); @@ -424,4 +425,4 @@ describe("Identities collision", function() { // res.levels[0].should.have.property('level').equal(4); // }); // }); -}); +}) diff --git a/test/integration/membership_chainability.ts b/test/integration/membership_chainability.ts index af5da41eff3d084a17e9d6a4cfbd92698d0990b4..95ffc5f94ba1976ac82634dc624e6af18493dcb5 100644 --- a/test/integration/membership_chainability.ts +++ b/test/integration/membership_chainability.ts @@ -11,7 +11,7 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -const toolbox = require('./tools/toolbox') +import {simpleNodeWith2Users} from "./tools/toolbox" describe("Membership chainability", function() { @@ -31,7 +31,7 @@ describe("Membership chainability", function() { } before(async () => { - const res1 = await toolbox.simpleNodeWith2Users(conf) + const res1 = await simpleNodeWith2Users(conf) s1 = res1.s1 cat = res1.cat await s1.commit({ time: now }) @@ -67,7 +67,7 @@ describe("Membership chainability", function() { } before(async () => { - const res1 = await toolbox.simpleNodeWith2Users(conf) + const res1 = await simpleNodeWith2Users(conf) s1 = res1.s1 cat = res1.cat await s1.commit({ time: now }) diff --git a/test/integration/cli.js b/test/integration/misc/cli.ts similarity index 52% rename from test/integration/cli.js rename to test/integration/misc/cli.ts index 766835cb5ab532e26ef9201cebd578417b3ada75..8abc8acaffa8200c69ffd04ebd8926ba20a51d85 100644 --- a/test/integration/cli.js +++ b/test/integration/misc/cli.ts @@ -11,67 +11,60 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {MerkleDTO} from "../../../app/lib/dto/MerkleDTO" +import {hashf} from "../../../app/lib/common" +import {processForURL} from "../../../app/lib/helpers/merkle" +import {fakeSyncServer} from "../tools/toolbox" +import {Underscore} from "../../../app/lib/common-libs/underscore" const spawn = require('child_process').spawn; const path = require('path'); -const co = require('co'); const should = require('should'); -const _ = require('underscore'); -const toolbox = require('./tools/toolbox'); -const duniter = require('../../index'); -const merkleh = require('../../app/lib/helpers/merkle'); -const hashf = require('../../app/lib/common-libs').hashf -const MerkleDTO = require('../../app/lib/dto/MerkleDTO').MerkleDTO +const duniter = require('../../../index'); const DB_NAME = "unit_tests"; describe("CLI", function() { - let farmOfServers = [], fakeServer; + let farmOfServers:{ host:string, port:number}[] = [], fakeServer:{ host:string, port:number} - before(() => co(function*() { + before(async () => { - const blockchain = require('../data/blockchain.json'); - const peers = []; - const peersMap = {}; - const leaves = []; + const blockchain = require('../../data/blockchain.json'); + const peersMap:any = {}; + const leaves:string[] = []; /******** * HTTP METHODS */ - const onReadBlockchainChunk = (count, from) => Promise.resolve(blockchain.blocks.slice(from, from + count)); - const onReadParticularBlock = (number) => Promise.resolve(blockchain.blocks[number]); - const onPeersRequested = (req) => co(function*() { + const onReadBlockchainChunk = (count:number, from:number) => Promise.resolve(blockchain.blocks.slice(from, from + count)); + const onReadParticularBlock = (number:number) => Promise.resolve(blockchain.blocks[number]); + const onPeersRequested = async (req:any) => { const merkle = new MerkleDTO(); merkle.initialize(leaves); - merkle.leaf = { - "hash": req.params.leaf, - "value": peersMap[req.params.leaf] || "" - }; - return merkleh.processForURL(req, merkle, () => co(function*() { + return processForURL(req, merkle, async () => { return peersMap; - })); - }); + }) + } /** * The fake hash in the blockchain */ const fakeHash = hashf("A wrong content").toUpperCase(); - farmOfServers = yield Array.from({ length: 5 }).map((unused, index) => { + farmOfServers = await Promise.all(Array.from({ length: 5 }).map(async (unused, index) => { if (index < 2) { /*************** * Normal nodes */ - return toolbox.fakeSyncServer(onReadBlockchainChunk, onReadParticularBlock, onPeersRequested); + return fakeSyncServer(onReadBlockchainChunk, onReadParticularBlock, onPeersRequested); } else if (index == 2) { /*************** * Node with wrong chaining between 2 chunks of blocks */ - return toolbox.fakeSyncServer((count, from) => { + return fakeSyncServer((count:number, from:number) => { // We just need to send the wrong chunk from = from - count; return Promise.resolve(blockchain.blocks.slice(from, from + count)); @@ -81,30 +74,30 @@ describe("CLI", function() { /*************** * Node with wrong chaining between 2 blocks */ - return toolbox.fakeSyncServer((count, from) => { + return fakeSyncServer((count:number, from:number) => { // We just need to send the wrong chunk - const chunk = blockchain.blocks.slice(from, from + count).map((block, index2) => { + const chunk = blockchain.blocks.slice(from, from + count).map((block:any, index2:number) => { if (index2 === 10) { - const clone = _.clone(block); + const clone = Underscore.clone(block); clone.hash = fakeHash; } return block; }); return Promise.resolve(chunk); }, onReadParticularBlock, onPeersRequested); - } else if (index == 4) { + } else { /*************** * Node with apparent good chaining, but one of the hashs is WRONG */ - return toolbox.fakeSyncServer((count, from) => { + return fakeSyncServer((count:number, from:number) => { // We just need to send the wrong chunk - const chunk = blockchain.blocks.slice(from, from + count).map((block, index2) => { + const chunk = blockchain.blocks.slice(from, from + count).map((block:any, index2:number) => { if (index2 === 10) { - const clone = _.clone(block); + const clone = Underscore.clone(block); clone.hash = fakeHash; } else if (index2 === 11) { - const clone = _.clone(block); + const clone = Underscore.clone(block); clone.previousHash = fakeHash; return clone; } @@ -113,56 +106,55 @@ describe("CLI", function() { return Promise.resolve(chunk); }, onReadParticularBlock, onPeersRequested); } - }); + })) farmOfServers.map((server, index) => { const peer = { endpoints: [['BASIC_MERKLED_API', server.host, server.port].join(' ')], pubkey: hashf(index + ""), hash: hashf(index + "").toUpperCase() }; - peers.push(peer); leaves.push(peer.hash); peersMap[peer.hash] = peer; }); fakeServer = farmOfServers[0]; - })); + }) - it('config --autoconf', () => co(function*() { - let res = yield execute(['config', '--autoconf', '--noupnp']); + it('config --autoconf', async () => { + let res = await execute(['config', '--autoconf', '--noupnp']); res.should.have.property("pair").property('pub').not.equal(""); res.should.have.property("pair").property('sec').not.equal(""); - })); + }) - it('reset data', () => co(function*() { - yield execute(['reset', 'data']); - // const res = yield execute(['export-bc', '--nostdout']); + it('reset data', async () => { + await execute(['reset', 'data']); + // const res = await execute(['export-bc', '--nostdout']); // res.slice(0, 1).should.have.length(0); - })); + }) - it('sync 7 blocks (fast)', () => co(function*() { - yield execute(['reset', 'data']); - yield execute(['sync', fakeServer.host, fakeServer.port, '7', '--nocautious', '--nointeractive', '--noshuffle']); - const res = yield execute(['export-bc', '--nostdout']); + it('sync 7 blocks (fast)', async () => { + await execute(['reset', 'data']); + await execute(['sync', fakeServer.host, String(fakeServer.port), '7', '--nocautious', '--nointeractive', '--noshuffle']); + const res = await execute(['export-bc', '--nostdout']); res[res.length - 1].should.have.property('number').equal(7); res.should.have.length(7 + 1); // blocks #0..#7 - })); + }) - it('sync 4 blocks (cautious)', () => co(function*() { - yield execute(['sync', fakeServer.host, fakeServer.port, '11', '--nointeractive']); - const res = yield execute(['export-bc', '--nostdout']); + it('sync 4 blocks (cautious)', async () => { + await execute(['sync', fakeServer.host, String(fakeServer.port), '11', '--nointeractive']); + const res = await execute(['export-bc', '--nostdout']); res[res.length - 1].should.have.property('number').equal(11); res.should.have.length(11 + 1); - })); + }) - it('[spawn] reset data', () => co(function*() { - yield executeSpawn(['reset', 'data']); - const res = yield executeSpawn(['export-bc']); + it('[spawn] reset data', async () => { + await executeSpawn(['reset', 'data']); + const res = await executeSpawn(['export-bc']); JSON.parse(res).should.have.length(0); - })); + }) - it('[spawn] sync 10 first blocks --memory', () => co(function*() { - yield execute(['sync', fakeServer.host, fakeServer.port, '10', '--memory', '--cautious', '--nointeractive']); - })); + it('[spawn] sync 10 first blocks --memory', async () => { + await execute(['sync', fakeServer.host, String(fakeServer.port), '10', '--memory', '--cautious', '--nointeractive']); + }) }); /** @@ -170,14 +162,11 @@ describe("CLI", function() { * @param args Array of arguments. * @returns {*|Promise} Returns the command output. */ -function execute(args) { +async function execute(args:(string)[]) { const finalArgs = [process.argv[0], __filename].concat(args).concat(['--mdb', DB_NAME]); - return co(function*() { - - const stack = duniter.statics.autoStack(); - // Executes the command - return stack.executeStack(finalArgs); - }); + const stack = duniter.statics.autoStack(); + // Executes the command + return stack.executeStack(finalArgs); } /** @@ -185,19 +174,17 @@ function execute(args) { * @param command Array of arguments. * @returns {*|Promise} Returns the command output. */ -function executeSpawn(command) { - return co(function*() { - const finalArgs = [path.join(__dirname, '../../bin/duniter')].concat(command).concat(['--mdb', DB_NAME]); - const duniterCmd = spawn(process.argv[0], finalArgs); - return new Promise((resolve, reject) => { - let res = ""; - duniterCmd.stdout.on('data', (data) => { - res += data.toString('utf8').replace(/\n/, ''); - }); - duniterCmd.stderr.on('data', (err) => { - console.log(err.toString('utf8').replace(/\n/, '')); - }); - duniterCmd.on('close', (code) => code ? reject(code) : resolve(res) ); +async function executeSpawn(command:string[]): Promise<string> { + const finalArgs = [path.join(__dirname, '../../../bin/duniter')].concat(command).concat(['--mdb', DB_NAME]); + const duniterCmd = spawn(process.argv[0], finalArgs); + return new Promise<string>((resolve, reject) => { + let res = ""; + duniterCmd.stdout.on('data', (data:any) => { + res += data.toString('utf8').replace(/\n/, ''); + }); + duniterCmd.stderr.on('data', (err:any) => { + console.log(err.toString('utf8').replace(/\n/, '')); }); + duniterCmd.on('close', (code:any) => code ? reject(code) : resolve(res) ); }); } diff --git a/test/integration/http_api.js b/test/integration/misc/http-api.ts similarity index 69% rename from test/integration/http_api.js rename to test/integration/misc/http-api.ts index d793281ec54d1d2034bf464fa16f58d67fb535fe..aeac652483f05e193a4d63c1d11a9dac7fd0af65 100644 --- a/test/integration/http_api.js +++ b/test/integration/misc/http-api.ts @@ -13,34 +13,37 @@ "use strict"; -const co = require('co'); -const _ = require('underscore'); +import {ProverConstants} from "../../../app/modules/prover/lib/constants" +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {BmaDependency} from "../../../app/modules/bma/index" +import {PeerDTO} from "../../../app/lib/dto/PeerDTO" +import {ProverDependency} from "../../../app/modules/prover/index" +import {HttpBlock, HttpDifficulties} from "../../../app/modules/bma/lib/dtos" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {BlockDTO} from "../../../app/lib/dto/BlockDTO" + const should = require('should'); const assert = require('assert'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const PeerDTO = require('../../app/lib/dto/PeerDTO').PeerDTO -const TestUser = require('./tools/TestUser').TestUser -const http = require('./tools/http'); -const shutDownEngine = require('./tools/shutDownEngine'); const rp = require('request-promise'); const ws = require('ws'); +const http = require('../tools/http'); +const shutDownEngine = require('../tools/shutDownEngine'); -require('../../app/modules/prover/lib/constants').ProverConstants.CORES_MAXIMUM_USE_IN_PARALLEL = 1 +ProverConstants.CORES_MAXIMUM_USE_IN_PARALLEL = 1 -let server, server2, cat, toc +let server:TestingServer, server2:TestingServer, cat:TestUser, toc:TestUser describe("HTTP API", function() { const now = 1500000000 - let commit + let commit:(options:any) => Promise<BlockDTO> - before(() => co(function*(){ + before(async () => { - server = duniter( - '/bb11', - true, + server = NewTestingServer( { + name: 'bb11', ipv4: '127.0.0.1', port: '7777', currency: 'bb', @@ -57,10 +60,9 @@ describe("HTTP API", function() { } }); - server2 = duniter( - '/bb12', - true, + server2 = NewTestingServer( { + name: 'bb12', ipv4: '127.0.0.1', port: '30410', currency: 'bb', @@ -82,33 +84,33 @@ describe("HTTP API", function() { commit = makeBlockAndPost(server); - let s = yield server.initWithDAL(); - let bmapi = yield bma(s); - yield bmapi.openConnections(); - - let s2 = yield server2.initWithDAL(); - let bmapi2 = yield bma(s2); - yield bmapi2.openConnections(); - - yield cat.createIdentity(); - yield toc.createIdentity(); - yield toc.cert(cat); - yield cat.cert(toc); - yield cat.join(); - yield toc.join(); - const b0 = yield commit({ time: now }); - const b1 = yield commit({ time: now + 120 }); - yield server2.writeBlock(b0) - yield server2.writeBlock(b1) - server.addEndpointsDefinitions(() => Promise.resolve('SOME_FAKE_ENDPOINT_P1')) - server2.addEndpointsDefinitions(() => Promise.resolve('SOME_FAKE_ENDPOINT_P2')) - const p1 = yield server.PeeringService.generateSelfPeer(server.conf) - yield server2.PeeringService.generateSelfPeer(server2.conf) - yield server2.writePeer(p1) - server2.writeBlock(yield commit({ time: now + 120 * 2 })) - server2.writeBlock(yield commit({ time: now + 120 * 3 })) - server2.writeBlock(yield commit({ time: now + 120 * 4 })) - })); + let s = await server.initWithDAL(); + let bmapi = await BmaDependency.duniter.methods.bma(s); + await bmapi.openConnections(); + + let s2 = await server2.initWithDAL(); + let bmapi2 = await BmaDependency.duniter.methods.bma(s2); + await bmapi2.openConnections(); + + await cat.createIdentity(); + await toc.createIdentity(); + await toc.cert(cat); + await cat.cert(toc); + await cat.join(); + await toc.join(); + const b0 = await commit({ time: now }); + const b1 = await commit({ time: now + 120 }); + await server2.writeBlock(b0) + await server2.writeBlock(b1) + server._server.addEndpointsDefinitions(() => Promise.resolve('SOME_FAKE_ENDPOINT_P1')) + server2._server.addEndpointsDefinitions(() => Promise.resolve('SOME_FAKE_ENDPOINT_P2')) + const p1 = await server.PeeringService.generateSelfPeer(server.conf) + await server2.PeeringService.generateSelfPeer(server2.conf) + await server2.writePeer(p1) + server2.writeBlock(await commit({ time: now + 120 * 2 })) + server2.writeBlock(await commit({ time: now + 120 * 3 })) + server2.writeBlock(await commit({ time: now + 120 * 4 })) + }) after(() => { return Promise.all([ @@ -116,14 +118,12 @@ describe("HTTP API", function() { ]) }) - function makeBlockAndPost(theServer) { - return function(options) { - return co(function*() { - const block = yield require('../../app/modules/prover').ProverDependency.duniter.methods.generateAndProveTheNext(theServer, null, null, options) - const res = yield postBlock(theServer)(block) - return JSON.parse(res) - }) - }; + function makeBlockAndPost(theServer:TestingServer) { + return async function(options:any) { + const block = await ProverDependency.duniter.methods.generateAndProveTheNext(theServer._server, null, null, options) + const res = await postBlock(theServer)(block) + return JSON.parse(res) + } } describe("/blockchain", function() { @@ -227,7 +227,7 @@ describe("HTTP API", function() { }); it('/difficulties should have current block number + 1', function() { - return http.expectAnswer(rp('http://127.0.0.1:7777/blockchain/difficulties', { json: true }), function(res) { + return http.expectAnswer(rp('http://127.0.0.1:7777/blockchain/difficulties', { json: true }), function(res:HttpDifficulties) { res.should.have.property('block').equal(5); res.should.have.property('levels').have.length(1); }); @@ -247,7 +247,7 @@ describe("HTTP API", function() { it('/block should send a block', function(done) { let completed = false const client = new ws('ws://127.0.0.1:7777/ws/block'); - client.once('message', function message(data) { + client.once('message', function message(data:any) { const block = JSON.parse(data); should(block).have.property('number', 4); should(block).have.property('dividend').equal(null) @@ -260,41 +260,41 @@ describe("HTTP API", function() { }); }); - it('/block (number 5,6,7) should send a block', () => co(function*() { - server2.writeBlock(yield commit({ time: now + 120 * 5 })) + it('/block (number 5,6,7) should send a block', async () => { + server2.writeBlock(await commit({ time: now + 120 * 5 })) const client = new ws('ws://127.0.0.1:7777/ws/block'); - let resolve5, resolve6, resolve7 + let resolve5:any, resolve6:any, resolve7:any const p5 = new Promise(res => resolve5 = res) const p6 = new Promise(res => resolve6 = res) const p7 = new Promise(res => resolve7 = res) - client.on('message', function message(data) { + client.on('message', function message(data:string) { const block = JSON.parse(data); if (block.number === 5) resolve5(block) if (block.number === 6) resolve6(block) if (block.number === 7) resolve7(block) }) - server2.writeBlock(yield commit({ time: now + 120 * 6 })) - server2.writeBlock(yield commit({ time: now + 120 * 7 })) - const b5 = yield p5 + server2.writeBlock(await commit({ time: now + 120 * 6 })) + server2.writeBlock(await commit({ time: now + 120 * 7 })) + const b5 = await p5 should(b5).have.property('number', 5); should(b5).have.property('dividend').equal(100) should(b5).have.property('monetaryMass').equal(600) should(b5).have.property('monetaryMass').not.equal("600") - const b6 = yield p6 + const b6 = await p6 should(b6).have.property('number', 6); should(b6).have.property('dividend').equal(null) should(b6).have.property('monetaryMass').equal(600) should(b6).have.property('monetaryMass').not.equal("600") - const b7 = yield p7 + const b7 = await p7 should(b7).have.property('number', 7); should(b7).have.property('dividend').equal(100) should(b7).have.property('monetaryMass').equal(800) should(b7).have.property('monetaryMass').not.equal("800") - })) + }) it('/block should answer to pings', function(done) { const client = new ws('ws://127.0.0.1:7777/ws/block'); - client.on('pong', function message(data, flags) { + client.on('pong', function message() { client.terminate(); done(); }); @@ -303,13 +303,13 @@ describe("HTTP API", function() { }); }); - it('/peer (number 5,6,7) should send a peer document', () => co(function*() { + it('/peer (number 5,6,7) should send a peer document', async () => { const client = new ws('ws://127.0.0.1:30410/ws/peer'); - let resolve5, resolve6, resolve7 + let resolve5:any, resolve6:any const p5 = new Promise(res => resolve5 = res) const p6 = new Promise(res => resolve6 = res) - server.addEndpointsDefinitions(() => Promise.resolve("BASIC_MERKLED_API localhost 7777")) - client.on('message', function message(data) { + server._server.addEndpointsDefinitions(() => Promise.resolve("BASIC_MERKLED_API localhost 7777")) + client.on('message', function message(data:any) { const peer = JSON.parse(data); if (peer.block.match(/2-/)) { server2.PeeringService.generateSelfPeer(server.conf) @@ -319,57 +319,55 @@ describe("HTTP API", function() { return resolve6(peer) } }) - const p1 = yield server.PeeringService.generateSelfPeer({ + const p1 = await server.PeeringService.generateSelfPeer({ currency: server.conf.currency }, 0) - yield server2.writeRawPeer(PeerDTO.fromJSONObject(p1).getRawSigned()) - const b5 = yield p5 + await server2._server.writeRawPeer(PeerDTO.fromJSONObject(p1).getRawSigned()) + const b5 = await p5 should(b5).have.property('version', 10) - const b6 = yield p6 + const b6 = await p6 should(b6).have.property('version', 10) - })) - }); -}); - -function expectJSON(promise, json) { - return co(function*(){ - try { - const resJson = yield promise; - _.keys(json).forEach(function(key){ - resJson.should.have.property(key).equal(json[key]); - }); - } catch (err) { - if (err.response) { - assert.equal(err.response.statusCode, 200); - } - else throw err; + }) + }) +}) + +async function expectJSON<T>(promise:Promise<T>, json:any) { + try { + const resJson = await promise; + Underscore.keys(json).forEach(function(key){ + resJson.should.have.property(key).equal(json[key]); + }); + } catch (err) { + if (err.response) { + assert.equal(err.response.statusCode, 200); } - }); + else throw err; + } } -function postBlock(server2) { - return function(block) { +function postBlock(server2:TestingServer) { + return function(block:any) { return post(server2, '/blockchain/block')({ block: typeof block == 'string' ? block : block.getRawSigned() }) - .then((result) => co(function*() { + .then(async (result:HttpBlock) => { const numberToReach = block.number - yield new Promise((res) => { - const interval = setInterval(() => co(function*() { - const current = yield server2.dal.getCurrentBlockOrNull() + await new Promise((res) => { + const interval = setInterval(async () => { + const current = await server2.dal.getCurrentBlockOrNull() if (current && current.number == numberToReach) { res() clearInterval(interval) } - }), 1) + }, 1) }) return result - })) + }) }; } -function post(server2, uri) { - return function(data) { +function post(server2:TestingServer, uri:string) { + return function(data:any) { return rp.post('http://' + [server2.conf.ipv4, server2.conf.port].join(':') + uri, { form: data }); diff --git a/test/integration/server-import-export.js b/test/integration/misc/server-import-export.ts similarity index 60% rename from test/integration/server-import-export.js rename to test/integration/misc/server-import-export.ts index daab7a580d0a78aaa44cda10aec5c2283574a04a..2f2e7bd5487336cf1fa3bde24bc46cdbd2fc9ec5 100644 --- a/test/integration/server-import-export.js +++ b/test/integration/misc/server-import-export.ts @@ -11,15 +11,11 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; -const _ = require('underscore'); +import {TestUser} from "../tools/TestUser" +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {Underscore} from "../../../app/lib/common-libs/underscore" + const should = require('should'); -const fs = require('fs'); -const co = require('co'); -const unzip = require('unzip'); -const toolbox = require('../integration/tools/toolbox'); -const TestUser = require('../integration/tools/TestUser').TestUser -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; const serverConfig = { memory: false, @@ -29,28 +25,28 @@ const serverConfig = { } }; -let s0, s1; +let s0:TestingServer, s1:TestingServer describe('Import/Export', () => { - before(() => co(function *() { - s0 = toolbox.server(_.extend({ homename: 'dev_unit_tests1', powNoSecurity: true }, serverConfig)); - yield s0.resetHome(); + before(async () => { + s0 = NewTestingServer(Underscore.extend({ homename: 'dev_unit_tests1', powNoSecurity: true }, serverConfig)); + await s0.resetHome(); - s1 = toolbox.server(_.extend({ homename: 'dev_unit_tests1', powNoSecurity: true }, serverConfig)); + s1 = NewTestingServer(Underscore.extend({ homename: 'dev_unit_tests1', powNoSecurity: true }, serverConfig)); const cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); const tac = new TestUser('tac', { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}, { server: s1 }); - yield s1.initDalBmaConnections(); - yield cat.createIdentity(); - yield tac.createIdentity(); - yield cat.cert(tac); - yield tac.cert(cat); - yield cat.join(); - yield tac.join(); - yield s1.commit(); - })); + await s1.initDalBmaConnections(); + await cat.createIdentity(); + await tac.createIdentity(); + await cat.cert(tac); + await tac.cert(cat); + await cat.join(); + await tac.join(); + await s1.commit(); + }) after(() => { return Promise.all([ @@ -59,8 +55,8 @@ describe('Import/Export', () => { ]) }) - it('should be able to export data', () => co(function *() { - const archive = yield s1.exportAllDataAsZIP(); + it('should be able to export data', async () => { + const archive = await s1.exportAllDataAsZIP(); const output = require('fs').createWriteStream(s1.home + '/export.zip'); archive.pipe(output); return new Promise((resolve, reject) => { @@ -69,10 +65,10 @@ describe('Import/Export', () => { resolve(); }); }); - })); + }) - it('should be able to import data', () => co(function *() { - yield s1.unplugFileSystem(); - yield s1.importAllDataFromZIP(s1.home + '/export.zip'); - })); -}); + it('should be able to import data', async () => { + await s1.unplugFileSystem(); + await s1.importAllDataFromZIP(s1.home + '/export.zip'); + }) +}) diff --git a/test/integration/network-update.js b/test/integration/network-update.js deleted file mode 100644 index baae2b7a3ef1527d13cbd8df2d2254dc8959d774..0000000000000000000000000000000000000000 --- a/test/integration/network-update.js +++ /dev/null @@ -1,129 +0,0 @@ -// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 -// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -"use strict"; - -const co = require('co'); -const _ = require('underscore'); -const rp = require('request-promise'); -const httpTest = require('./tools/http'); -const node = require('./tools/node'); -const TestUser = require('./tools/TestUser').TestUser -const commit = require('./tools/commit'); -const sync = require('./tools/sync'); -const until = require('./tools/until'); -const toolbox = require('./tools/toolbox'); -const BlockDTO = require("../../app/lib/dto/BlockDTO"); - -const expectHttpCode = httpTest.expectHttpCode; -const expectAnswer = httpTest.expectAnswer; - -const MEMORY_MODE = true; -const commonConf = { - ipv4: '127.0.0.1', - remoteipv4: '127.0.0.1', - currency: 'bb', - httpLogs: true, - forksize: 3, - sigQty: 1 -}; - -const catKeyPair = { - pair: { - pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', - sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' - } -}; - -const tocKeyPair = { - pair: { - pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', - sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F' - } -}; - -let s1, s2, cat, toc - - -describe("Network updating", function() { - - before(function() { - - return co(function *() { - - s1 = toolbox.server(_.clone(catKeyPair)); - s2 = toolbox.server(_.clone(tocKeyPair)); - - cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); - toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); - - const commitS1 = commit(s1); - const commitS2 = commit(s2); - - yield [s1, s2].reduce((p, server) => co(function*() { - yield p; - yield server.initDalBmaConnections() - require('../../app/modules/router').RouterDependency.duniter.methods.routeToNetwork(server); - }), Promise.resolve()); - - // Server 1 - yield cat.createIdentity(); - yield toc.createIdentity(); - yield toc.cert(cat); - yield cat.cert(toc); - yield cat.join(); - yield toc.join(); - for (const i in _.range(32)) { - yield commitS1(); // block#0 - } - // // s2 syncs from s1 - yield sync(0, 31, s1, s2); - - const b2 = yield s1.makeNext({}); - yield s1.postBlock(b2); - yield s2.postBlock(b2); - yield s1.recomputeSelfPeer(); // peer#1 - yield s1.sharePeeringWith(s2); - const b3 = yield s1.makeNext({}); - yield s1.postBlock(b3); - yield s2.postBlock(b3); - yield s2.waitToHaveBlock(b3.number); - yield s1.recomputeSelfPeer(); // peer#1 - yield s1.sharePeeringWith(s2); - }); - }); - - describe("Server 1 /network/peering", function() { - - it('/peers?leaf=LEAFDATA', () => co(function*() { - const data = yield s1.get('/network/peering/peers?leaves=true'); - const leaf = data.leaves[0]; - const res = yield s1.get('/network/peering/peers?leaf=' + leaf); - res.leaf.value.should.have.property("pubkey").equal('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); - res.leaf.value.should.have.property("block").match(new RegExp('^3-')); - res.leaf.value.should.have.property("raw").match(new RegExp('.*Block: 3-.*')); - })); - }); - - describe("Server 2 /network/peering", function() { - - it('/peers?leaf=LEAFDATA', () => co(function*() { - const data = yield s2.get('/network/peering/peers?leaves=true'); - const leaf = data.leaves[0]; - const res = yield s2.get('/network/peering/peers?leaf=' + leaf); - res.leaf.value.should.have.property("pubkey").equal('DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'); - res.leaf.value.should.have.property("block").match(new RegExp('^0-')); - res.leaf.value.should.have.property("raw").match(new RegExp('.*Block: 0-.*')); - })); - }); - }); diff --git a/test/integration/network.js b/test/integration/network/network-merkle.ts similarity index 89% rename from test/integration/network.js rename to test/integration/network/network-merkle.ts index 9f75b690445779c9511a5629e529cf5a63dc2970..7bda67d167e35ad9fe46ddbae6edcff8b19cf622 100644 --- a/test/integration/network.js +++ b/test/integration/network/network-merkle.ts @@ -11,18 +11,16 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {HttpMerkleOfPeers} from "../../../app/modules/bma/lib/dtos" -const co = require('co'); -const _ = require('underscore'); const rp = require('request-promise'); -const httpTest = require('./tools/http'); -const node = require('./tools/node'); +const httpTest = require('../tools/http'); +const node = require('../tools/node'); const expectHttpCode = httpTest.expectHttpCode; const expectAnswer = httpTest.expectAnswer; -const MEMORY_MODE = true; const commonConf = { bmaWithCrawler: true, ipv4: '127.0.0.1', @@ -33,7 +31,7 @@ const commonConf = { sigQty: 1 }; -const s1 = node('bb33', _.extend({ +const s1 = node('bb33', Underscore.extend({ ipv4: '127.0.0.1', port: '20501', remoteport: '20501', @@ -46,7 +44,7 @@ const s1 = node('bb33', _.extend({ sigQty: 1, dt: 0, ud0: 120 }, commonConf)); -const s2 = node('bb12', _.extend({ +const s2 = node('bb12', Underscore.extend({ port: '20502', remoteport: '20502', ws2p: { upnp: false }, @@ -58,20 +56,17 @@ const s2 = node('bb12', _.extend({ describe("Network Merkle", function() { - before(function() { - - return co(function *() { - yield s1.startTesting(); - yield s2.startTesting(); - let peer1 = yield s1.peeringP(); - yield s2.submitPeerP(peer1); - }); - }); + before(async () => { + await s1.startTesting(); + await s2.startTesting(); + let peer1 = await s1.peeringP(); + await s2.submitPeerP(peer1); + }) describe("Server 1 /network/peering", function() { it('/peers?leaves=true', function() { - return expectAnswer(rp('http://127.0.0.1:20501/network/peering/peers?leaves=true', { json: true }), (res) => { + return expectAnswer(rp('http://127.0.0.1:20501/network/peering/peers?leaves=true', { json: true }), (res:HttpMerkleOfPeers) => { res.should.have.property('depth').equal(0); res.should.have.property('nodesCount').equal(0); res.should.have.property('leavesCount').equal(1); @@ -82,7 +77,7 @@ describe("Network Merkle", function() { }); it('/peers?leaf=C3EAB939F0BEF711461A140A1BA2649C75905107FACA3BE9C5F76F7FD1C7BC5E', function() { - return expectAnswer(rp('http://127.0.0.1:20501/network/peering/peers?leaf=C3EAB939F0BEF711461A140A1BA2649C75905107FACA3BE9C5F76F7FD1C7BC5E', { json: true }), (res) => { + return expectAnswer(rp('http://127.0.0.1:20501/network/peering/peers?leaf=C3EAB939F0BEF711461A140A1BA2649C75905107FACA3BE9C5F76F7FD1C7BC5E', { json: true }), (res:HttpMerkleOfPeers) => { res.should.have.property('depth').equal(0); res.should.have.property('nodesCount').equal(0); res.should.have.property('leavesCount').equal(1); @@ -104,7 +99,7 @@ describe("Network Merkle", function() { describe("Server 2 /network/peering", function() { it('/peers?leaves=true', function() { - return expectAnswer(rp('http://127.0.0.1:20502/network/peering/peers?leaves=true', { json: true }), (res) => { + return expectAnswer(rp('http://127.0.0.1:20502/network/peering/peers?leaves=true', { json: true }), (res:HttpMerkleOfPeers) => { res.should.have.property('depth').equal(1); res.should.have.property('nodesCount').equal(1); res.should.have.property('leavesCount').equal(2); @@ -116,7 +111,7 @@ describe("Network Merkle", function() { }); it('/peers?leaf=BDD850441E3CDEB9005345B425CDBDA83E7BC7E5D83E9130C6012084F93CD220', function() { - return expectAnswer(rp('http://127.0.0.1:20502/network/peering/peers?leaf=BDD850441E3CDEB9005345B425CDBDA83E7BC7E5D83E9130C6012084F93CD220', { json: true }), (res) => { + return expectAnswer(rp('http://127.0.0.1:20502/network/peering/peers?leaf=BDD850441E3CDEB9005345B425CDBDA83E7BC7E5D83E9130C6012084F93CD220', { json: true }), (res:HttpMerkleOfPeers) => { res.should.have.property('depth').equal(1); res.should.have.property('nodesCount').equal(1); res.should.have.property('leavesCount').equal(2); diff --git a/test/integration/peerings.js b/test/integration/network/network-peerings.ts similarity index 54% rename from test/integration/peerings.js rename to test/integration/network/network-peerings.ts index f9c42296e841edfd09aacd026c013116a6aed438..2c135f6448e74a15f1788f67a928ef246b5d3ad0 100644 --- a/test/integration/peerings.js +++ b/test/integration/network/network-peerings.ts @@ -11,25 +11,21 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {CrawlerDependency} from "../../../app/modules/crawler/index" +import {Contacter} from "../../../app/modules/crawler/lib/contacter" +import {PeerDTO} from "../../../app/lib/dto/PeerDTO" +import {BmaDependency} from "../../../app/modules/bma/index" +import {RouterDependency} from "../../../app/modules/router" +import {Underscore} from "../../../app/lib/common-libs/underscore" -const co = require('co'); -const _ = require('underscore'); const should = require('should'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const TestUser = require('./tools/TestUser').TestUser -const constants = require('../../app/lib/constants'); const rp = require('request-promise'); -const httpTest = require('./tools/http'); -const commit = require('./tools/commit'); -const sync = require('./tools/sync'); -const toolbox = require('./tools/toolbox'); -const contacter = require('../../app/modules/crawler').CrawlerDependency.duniter.methods.contacter; -const until = require('./tools/until'); -const shutDownEngine = require('./tools/shutDownEngine'); -const multicaster = require('../../app/lib/streams/multicaster'); -const PeerDTO = require('../../app/lib/dto/PeerDTO').PeerDTO +const httpTest = require('../tools/http'); +const sync = require('../tools/sync'); +const toolbox = require('../tools/toolbox'); +const shutDownEngine = require('../tools/shutDownEngine'); const expectJSON = httpTest.expectJSON; @@ -44,20 +40,20 @@ const commonConf = { sigQty: 1 }; -let s1, s2, s3, cat, toc, tic +let s1:TestingServer, s2:TestingServer, s3:TestingServer, cat:TestUser, toc:TestUser, tic:TestUser -let nodeS1; -let nodeS2; -let nodeS3; +let nodeS1:Contacter +let nodeS2:Contacter +let nodeS3:Contacter -describe("Network", function() { +describe("Network peering", function() { before(function() { - s1 = duniter( - 'bb_net1', - MEMORY_MODE, - _.extend({ + s1 = NewTestingServer( + Underscore.extend({ + name: 'bb_net1', + memory: MEMORY_MODE, port: '7784', pair: { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', @@ -65,10 +61,10 @@ describe("Network", function() { } }, commonConf)); - s2 = duniter( - 'bb_net2', - MEMORY_MODE, - _.extend({ + s2 = NewTestingServer( + Underscore.extend({ + name: 'bb_net2', + memory: MEMORY_MODE, port: '7785', pair: { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', @@ -76,10 +72,10 @@ describe("Network", function() { } }, commonConf)); - s3 = duniter( - 'bb_net3', - MEMORY_MODE, - _.extend({ + s3 = NewTestingServer( + Underscore.extend({ + name: 'bb_net3', + memory: MEMORY_MODE, port: '7786', pair: { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', @@ -91,86 +87,77 @@ describe("Network", function() { toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); tic = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s1 }); - const commitS1 = commit(s1); - const commitS2 = commit(s2); - const commitS3 = commit(s3); - return [s1, s2, s3].reduce(function(p, server) { - server.addEndpointsDefinitions(() => require('../../app/modules/bma').BmaDependency.duniter.methods.getMainEndpoint(server.conf)) + server._server.addEndpointsDefinitions(() => BmaDependency.duniter.methods.getMainEndpoint(server.conf)) return p .then(function(){ return server .initWithDAL() - .then(bma) + .then(BmaDependency.duniter.methods.bma) .then(function(bmaAPI){ return bmaAPI.openConnections() .then(() => { server.bma = bmaAPI; - require('../../app/modules/router').RouterDependency.duniter.methods.routeToNetwork(server); + RouterDependency.duniter.methods.routeToNetwork(server._server); }); }); }); }, Promise.resolve()) - .then(function(){ - return co(function *() { - nodeS1 = contacter('127.0.0.1', s1.conf.port); - nodeS2 = contacter('127.0.0.1', s2.conf.port); - nodeS3 = contacter('127.0.0.1', s3.conf.port); - // Server 1 - yield cat.createIdentity(); - yield toc.createIdentity(); - yield tic.createIdentity(); - yield toc.cert(cat); - yield cat.cert(toc); - yield cat.cert(tic); - yield cat.join(); - yield toc.join(); - yield tic.join(); - yield commitS1(); - // Server 2 syncs block 0 - yield sync(0, 0, s1, s2); - yield toolbox.serverWaitBlock(s1, 0) - // Server 3 syncs block 0 - yield sync(0, 0, s1, s3); - yield toolbox.serverWaitBlock(s3, 0) - yield nodeS1.getPeer().then((peer) => nodeS2.postPeer(PeerDTO.fromJSONObject(peer).getRawSigned())).catch(e => console.error(e)) - yield nodeS2.getPeer().then((peer) => nodeS1.postPeer(PeerDTO.fromJSONObject(peer).getRawSigned())).catch(e => console.error(e)) - yield nodeS3.getPeer().then((peer) => nodeS1.postPeer(PeerDTO.fromJSONObject(peer).getRawSigned())).catch(e => console.error(e)) - yield commitS1(); - yield [ - toolbox.serverWaitBlock(s2, 1), - toolbox.serverWaitBlock(s3, 1) - ]; - // A block was successfully spread accross the network - yield s2.bma.closeConnections(); - yield commitS1(); - yield [ - toolbox.serverWaitBlock(s3, 2) - ]; - // Server 2 syncs block number 2 (it did not have it) - yield sync(2, 2, s1, s2); - yield toolbox.serverWaitBlock(s2, 2) - yield s2.recomputeSelfPeer(); - yield s2.bma.openConnections(); - yield new Promise((resolve) => setTimeout(resolve, 1000)); - yield [ - toolbox.serverWaitBlock(s2, 4), - toolbox.serverWaitBlock(s3, 4), - commitS1() - .then(commitS1) - ]; - yield [ - toolbox.serverWaitBlock(s1, 5), - toolbox.serverWaitBlock(s2, 5), - commitS3() - ]; - yield [ - toolbox.serverWaitBlock(s1, 6), - toolbox.serverWaitBlock(s3, 6), - commitS2() - ]; - }); + .then(async () => { + nodeS1 = CrawlerDependency.duniter.methods.contacter('127.0.0.1', s1.conf.port); + nodeS2 = CrawlerDependency.duniter.methods.contacter('127.0.0.1', s2.conf.port); + nodeS3 = CrawlerDependency.duniter.methods.contacter('127.0.0.1', s3.conf.port); + // Server 1 + await cat.createIdentity(); + await toc.createIdentity(); + await tic.createIdentity(); + await toc.cert(cat); + await cat.cert(toc); + await cat.cert(tic); + await cat.join(); + await toc.join(); + await tic.join(); + await s1.commit(); + // Server 2 syncs block 0 + await sync(0, 0, s1, s2); + await toolbox.serverWaitBlock(s1._server, 0) + // Server 3 syncs block 0 + await sync(0, 0, s1, s3); + await toolbox.serverWaitBlock(s3._server, 0) + await nodeS1.getPeer().then((peer) => nodeS2.postPeer(PeerDTO.fromJSONObject(peer).getRawSigned())).catch(e => console.error(e)) + await nodeS2.getPeer().then((peer) => nodeS1.postPeer(PeerDTO.fromJSONObject(peer).getRawSigned())).catch(e => console.error(e)) + await nodeS3.getPeer().then((peer) => nodeS1.postPeer(PeerDTO.fromJSONObject(peer).getRawSigned())).catch(e => console.error(e)) + await s1.commit(); + await Promise.all([ + toolbox.serverWaitBlock(s2._server, 1), + toolbox.serverWaitBlock(s3._server, 1) + ]) + // A block was successfully spread accross the network + await s2.bma.closeConnections(); + await s1.commit(); + await toolbox.serverWaitBlock(s3._server, 2) + // Server 2 syncs block number 2 (it did not have it) + await sync(2, 2, s1, s2); + await toolbox.serverWaitBlock(s2._server, 2) + await s2.recomputeSelfPeer(); + await s2.bma.openConnections(); + await new Promise((resolve) => setTimeout(resolve, 1000)); + await Promise.all([ + toolbox.serverWaitBlock(s2._server, 4), + toolbox.serverWaitBlock(s3._server, 4), + s1.commit().then(() => s1.commit()) + ]) + await Promise.all([ + toolbox.serverWaitBlock(s1._server, 5), + toolbox.serverWaitBlock(s2._server, 5), + s3.commit() + ]) + await Promise.all([ + toolbox.serverWaitBlock(s1._server, 6), + toolbox.serverWaitBlock(s3._server, 6), + s2.commit() + ]) }) ; }); diff --git a/test/integration/peers-same-pubkey.js b/test/integration/network/network-peers-same-pubkey.ts similarity index 63% rename from test/integration/peers-same-pubkey.js rename to test/integration/network/network-peers-same-pubkey.ts index 3e85615f607b8cf5e553d7802834d6a10bcca791..389a751bf71ccc7c0fc801671e08549bade58680 100644 --- a/test/integration/peers-same-pubkey.js +++ b/test/integration/network/network-peers-same-pubkey.ts @@ -11,17 +11,16 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {TestUser} from "../tools/TestUser" +import {NewTestingServer, serverWaitBlock, TestingServer} from "../tools/toolbox" +import {PeerDTO} from "../../../app/lib/dto/PeerDTO" +import {HttpPeer} from "../../../app/modules/bma/lib/dtos" +import {RouterDependency} from "../../../app/modules/router" +import {Underscore} from "../../../app/lib/common-libs/underscore" -const co = require('co'); -const _ = require('underscore'); const should = require('should'); -const TestUser = require('./tools/TestUser').TestUser -const commit = require('./tools/commit'); -const sync = require('./tools/sync'); -const until = require('./tools/until'); -const toolbox = require('./tools/toolbox'); -const PeerDTO = require('../../app/lib/dto/PeerDTO').PeerDTO +const sync = require('../tools/sync'); +const until = require('../tools/until'); const catKeyPair = { pair: { @@ -30,76 +29,73 @@ const catKeyPair = { } }; -let s1, s2, s3, cat, toc +let s1:TestingServer, s2:TestingServer, s3:TestingServer, cat:TestUser, toc:TestUser describe("Peer document", function() { - before(() => co(function*() { + before(async () => { - s1 = toolbox.server(_.clone(catKeyPair)); - s2 = toolbox.server(_.clone(catKeyPair)); - s3 = toolbox.server(_.clone(catKeyPair)); + s1 = NewTestingServer(Underscore.clone(catKeyPair)); + s2 = NewTestingServer(Underscore.clone(catKeyPair)); + s3 = NewTestingServer(Underscore.clone(catKeyPair)); cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); - const commitS1 = commit(s1); - const commitS2 = commit(s2); - - yield [s1, s2, s3].reduce((p, server) => co(function*() { - yield p; - yield server.initDalBmaConnections() - require('../../app/modules/router').RouterDependency.duniter.methods.routeToNetwork(server); - }), Promise.resolve()); + await [s1, s2, s3].reduce(async (p, server) => { + await p; + await server.initDalBmaConnections() + RouterDependency.duniter.methods.routeToNetwork(server._server) + }, Promise.resolve()) // Server 1 - yield cat.createIdentity(); - yield toc.createIdentity(); - yield toc.cert(cat); - yield cat.cert(toc); - yield cat.join(); - yield toc.join(); - yield commitS1(); // block#0 - yield commitS1(); // block#1 - yield s1.recomputeSelfPeer(); // peer#1 - yield commitS1(); // block#2 + await cat.createIdentity(); + await toc.createIdentity(); + await toc.cert(cat); + await cat.cert(toc); + await cat.join(); + await toc.join(); + await s1.commit(); // block#0 + await s1.commit(); // block#1 + await s1.recomputeSelfPeer(); // peer#1 + await s1.commit(); // block#2 // // s2 syncs from s1 - yield sync(0, 2, s1, s2); - yield toolbox.serverWaitBlock(s1, 2) - yield [ - s1.get('/network/peering').then((peer) => s2.post('/network/peering/peers', { peer: PeerDTO.fromJSONObject(peer).getRawSigned() })), // peer#2 + await sync(0, 2, s1, s2); + await serverWaitBlock(s1._server, 2) + await Promise.all([ + s1.get('/network/peering').then((peer:HttpPeer) => s2.post('/network/peering/peers', { peer: PeerDTO.fromJSONObject(peer).getRawSigned() })), // peer#2 until(s2, 'peer', 1) - ]; + ]) - yield [ - commitS2(), // block#3 - toolbox.serverWaitBlock(s1, 3) - ]; + await Promise.all([ + s2.commit(), // block#3 + serverWaitBlock(s1._server, 3) + ]) - yield sync(0, 3, s1, s3); - yield toolbox.serverWaitBlock(s3, 3) + await sync(0, 3, s1, s3); + await serverWaitBlock(s3._server, 3) - const peer1 = yield s1.get('/network/peering'); + const peer1 = await s1.get('/network/peering'); peer1.should.have.property("block").match(/^2-/); - yield [ + await Promise.all([ s3.post('/network/peering/peers', { peer: PeerDTO.fromJSONObject(peer1).getRawSigned() }), // peer#3 until(s3, 'peer', 2) - ]; - const peer3 = yield s3.get('/network/peering'); + ]) + const peer3 = await s3.get('/network/peering'); peer3.should.have.property("block").match(/^3-/); - yield [ - commitS2(), // block#4 - toolbox.serverWaitBlock(s1, 4), - toolbox.serverWaitBlock(s3, 4) - ]; + await Promise.all([ + s2.commit(), // block#4 + serverWaitBlock(s1._server, 4), + serverWaitBlock(s3._server, 4) + ]) - yield [ - commitS1(), // block#5 - toolbox.serverWaitBlock(s2, 5), - toolbox.serverWaitBlock(s3, 5) - ]; - })); + await Promise.all([ + s1.commit(), // block#5 + serverWaitBlock(s2._server, 5), + serverWaitBlock(s3._server, 5) + ]) + }) after(() => { return Promise.all([ @@ -115,25 +111,25 @@ describe("Peer document", function() { leavesCount: 1 })); - it('leaf data', () => co(function*() { - const data = yield s1.get('/network/peering/peers?leaves=true'); + it('leaf data', async () => { + const data = await s1.get('/network/peering/peers?leaves=true'); const leaf = data.leaves[0]; - const res = yield s1.get('/network/peering/peers?leaf=' + leaf); + const res = await s1.get('/network/peering/peers?leaf=' + leaf); res.leaf.value.should.have.property("pubkey").equal('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); res.leaf.value.should.have.property("block").match(new RegExp('^3-')); res.leaf.value.should.have.property("raw").match(new RegExp('.*Block: 3-.*')); res.leaf.value.should.have.property("endpoints").length(3); - })); + }) - it('peers', () => s1.expectThat('/network/peering', (res) => { + it('peers', () => s1.expectThat('/network/peering', (res:HttpPeer) => { res.should.have.property("pubkey").equal('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); res.should.have.property("block").match(new RegExp('^3-')); res.should.have.property("endpoints").length(3); })); - it('peering should have been updated by node 1', () => s1.expectThat('/network/peering', (res) => { + it('peering should have been updated by node 1', () => s1.expectThat('/network/peering', (res:HttpPeer) => { res.should.have.property("pubkey").equal('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); res.should.have.property("block").match(new RegExp('^3-')); res.should.have.property("endpoints").length(3); @@ -152,18 +148,18 @@ describe("Peer document", function() { })); - it('leaf data', () => co(function*() { - const data = yield s2.get('/network/peering/peers?leaves=true'); + it('leaf data', async () => { + const data = await s2.get('/network/peering/peers?leaves=true'); const leaf = data.leaves[0]; - const res = yield s2.get('/network/peering/peers?leaf=' + leaf); + const res = await s2.get('/network/peering/peers?leaf=' + leaf); res.leaf.value.should.have.property("pubkey").equal('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); res.leaf.value.should.have.property("block").match(new RegExp('^3-')); res.leaf.value.should.have.property("raw").match(new RegExp('.*Block: 3-.*')); res.leaf.value.should.have.property("endpoints").length(3); - })); + }) - it('peering should have been updated by node 1', () => s2.expectThat('/network/peering', (res) => { + it('peering should have been updated by node 1', () => s2.expectThat('/network/peering', (res:HttpPeer) => { res.should.have.property("pubkey").equal('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); res.should.have.property("block").match(new RegExp('^3-')); res.should.have.property("endpoints").length(3); @@ -181,17 +177,17 @@ describe("Peer document", function() { leavesCount: 1 })); - it('leaf data', () => co(function*() { - const data = yield s3.get('/network/peering/peers?leaves=true'); + it('leaf data', async () => { + const data = await s3.get('/network/peering/peers?leaves=true'); const leaf = data.leaves[0]; - const res = yield s3.get('/network/peering/peers?leaf=' + leaf); + const res = await s3.get('/network/peering/peers?leaf=' + leaf); res.leaf.value.should.have.property("pubkey").equal('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); res.leaf.value.should.have.property("block").match(new RegExp('^3-')); res.leaf.value.should.have.property("raw").match(new RegExp('.*Block: 3-.*')); res.leaf.value.should.have.property("endpoints").length(3); - })); + }) - it('peering should have been updated by node 1', () => s3.expectThat('/network/peering', (res) => { + it('peering should have been updated by node 1', () => s3.expectThat('/network/peering', (res:HttpPeer) => { res.should.have.property("pubkey").equal('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); res.should.have.property("block").match(new RegExp('^3-')); res.should.have.property("endpoints").length(3); @@ -200,6 +196,6 @@ describe("Peer document", function() { it('current block', () => s3.expectJSON('/blockchain/current', { number: 5, issuer: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd' - })); - }); -}); + })) + }) +}) diff --git a/test/integration/network/network-update.ts b/test/integration/network/network-update.ts new file mode 100644 index 0000000000000000000000000000000000000000..53c5a98700f3242b9c1178296ad091f9aaae95a4 --- /dev/null +++ b/test/integration/network/network-update.ts @@ -0,0 +1,105 @@ +// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 +// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +"use strict"; + +import {TestUser} from "../tools/TestUser" +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {RouterDependency} from "../../../app/modules/router" + +const sync = require('../tools/sync'); + +const catKeyPair = { + pair: { + pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', + sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' + } +}; + +const tocKeyPair = { + pair: { + pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', + sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F' + } +}; + +let s1:TestingServer, s2:TestingServer, cat:TestUser, toc:TestUser + + +describe("Network updating", function() { + + before(async () => { + + s1 = NewTestingServer(Underscore.clone(catKeyPair)); + s2 = NewTestingServer(Underscore.clone(tocKeyPair)); + + cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); + toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); + + await [s1, s2].reduce(async (p, server) => { + await p; + await server.initDalBmaConnections() + RouterDependency.duniter.methods.routeToNetwork(server._server); + }, Promise.resolve()) + + // Server 1 + await cat.createIdentity(); + await toc.createIdentity(); + await toc.cert(cat); + await cat.cert(toc); + await cat.join(); + await toc.join(); + for (const i in Underscore.range(32)) { + await s1.commit(); // block#0 + } + // // s2 syncs from s1 + await sync(0, 31, s1, s2); + + const b2 = await s1.makeNext({}); + await s1.postBlock(b2); + await s2.postBlock(b2); + await s1.recomputeSelfPeer(); // peer#1 + await s1.sharePeeringWith(s2); + const b3 = await s1.makeNext({}); + await s1.postBlock(b3); + await s2.postBlock(b3); + await s2.waitToHaveBlock(b3.number); + await s1.recomputeSelfPeer(); // peer#1 + await s1.sharePeeringWith(s2); + }); + + describe("Server 1 /network/peering", function() { + + it('/peers?leaf=LEAFDATA', async () => { + const data = await s1.get('/network/peering/peers?leaves=true'); + const leaf = data.leaves[0]; + const res = await s1.get('/network/peering/peers?leaf=' + leaf); + res.leaf.value.should.have.property("pubkey").equal('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); + res.leaf.value.should.have.property("block").match(new RegExp('^3-')); + res.leaf.value.should.have.property("raw").match(new RegExp('.*Block: 3-.*')); + }) + }); + + describe("Server 2 /network/peering", function() { + + it('/peers?leaf=LEAFDATA', async () => { + const data = await s2.get('/network/peering/peers?leaves=true'); + const leaf = data.leaves[0]; + const res = await s2.get('/network/peering/peers?leaf=' + leaf); + res.leaf.value.should.have.property("pubkey").equal('DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'); + res.leaf.value.should.have.property("block").match(new RegExp('^0-')); + res.leaf.value.should.have.property("raw").match(new RegExp('.*Block: 0-.*')); + }) + }) + }) diff --git a/test/integration/newcomers-shuffling.js b/test/integration/newcomers-shuffling.js index 31fb6f1dfcda2d6393712c597e1ec7217f2bdfc4..0a4438d0205274ea1e237fb1db9147b1c22e74ad 100644 --- a/test/integration/newcomers-shuffling.js +++ b/test/integration/newcomers-shuffling.js @@ -13,7 +13,6 @@ "use strict"; -const _ = require('underscore'); const co = require('co'); const assert = require('assert'); const TestUser = require('./tools/TestUser').TestUser diff --git a/test/integration/peer-outdated.js b/test/integration/peer-outdated.js index 79a61acffb5b52c5b85c8528b2ec54791d543ead..d71f0b3cf05915f06f63170e1e819b46dd9782b4 100644 --- a/test/integration/peer-outdated.js +++ b/test/integration/peer-outdated.js @@ -16,7 +16,6 @@ const co = require('co'); const should = require('should'); const es = require('event-stream'); -const _ = require('underscore'); const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; const TestUser = require('./tools/TestUser').TestUser const commit = require('./tools/commit'); diff --git a/test/integration/register-fork-blocks.js b/test/integration/register-fork-blocks.js index e905ed939ec39ec3a2d7bfad99af231a4b780db4..7e7d5d75309205f1ab478bef9e7ca207ff68a083 100644 --- a/test/integration/register-fork-blocks.js +++ b/test/integration/register-fork-blocks.js @@ -13,7 +13,6 @@ "use strict"; -const _ = require('underscore'); const co = require('co'); const assert = require('assert'); const TestUser = require('./tools/TestUser').TestUser diff --git a/test/integration/revoked_pubkey_replay.ts b/test/integration/revoked_pubkey_replay.ts index e0a32f2ede9aa57a05c157262f1762e894cb39a2..39583d8cd7c65fe3cf99acbd5c7c525d2f576886 100644 --- a/test/integration/revoked_pubkey_replay.ts +++ b/test/integration/revoked_pubkey_replay.ts @@ -12,8 +12,8 @@ // GNU Affero General Public License for more details. import {simpleNodeWith2Users, TestingServer} from "./tools/toolbox" +import {Underscore} from "../../app/lib/common-libs/underscore" -const _ = require('underscore') const TestUser = require('./tools/TestUser').TestUser describe("Revoked pubkey replay", function() { @@ -47,7 +47,7 @@ describe("Revoked pubkey replay", function() { await s1.commit() await s1.expect('/wot/members', (res:any) => { res.should.have.property('results').length(3) - const ticEntries = _.filter(res.results, (entry:any) => entry.uid === 'tic') + const ticEntries = Underscore.filter(res.results, (entry:any) => entry.uid === 'tic') ticEntries.should.have.length(1) }) }) @@ -63,7 +63,7 @@ describe("Revoked pubkey replay", function() { await s1.commit() await s1.expect('/wot/members', (res:any) => { res.should.have.property('results').length(2) - const ticEntries = _.filter(res.results, (entry:any) => entry.uid === 'tic') + const ticEntries = Underscore.filter(res.results, (entry:any) => entry.uid === 'tic') ticEntries.should.have.length(0) }) }) diff --git a/test/integration/scenarios/malformed-documents.js b/test/integration/scenarios/malformed-documents.js deleted file mode 100644 index 8ec1d222447895df14c2cb46e31da14ebd63f5d2..0000000000000000000000000000000000000000 --- a/test/integration/scenarios/malformed-documents.js +++ /dev/null @@ -1,50 +0,0 @@ -// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 -// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -"use strict"; - -const request = require('request'); - -module.exports = function(node1) { - - const malformedTransaction = "Version: 2\n" + - "Type: Transaction\n" + - "Currency: null\n" + - "Issuers:\n" + - "G2CBgZBPLe6FSFUgpx2Jf1Aqsgta6iib3vmDRA1yLiqU\n" + - "Inputs:\n" + - "0:T:1536:539CB0E60CD5F55CF1BE96F067E73BF55C052112:1.0\n" + - "Outputs:Comment: mon comments\n"; - - - function sendRaw (raw) { - return function(done) { - post('/tx/process', { - "transaction": raw - }, done); - } - } - - function post(uri, data, done) { - const postReq = request.post({ - "uri": 'http://' + [node1.server.conf.remoteipv4, node1.server.conf.remoteport].join(':') + uri, - "timeout": 1000 * 10 - }, function (err, res, body) { - done(err, res, body); - }); - postReq.form(data); - } - return [ - sendRaw(malformedTransaction) - ]; -}; diff --git a/test/integration/single-document-treatment.js b/test/integration/single-document-treatment.js index 58aa5229afb2810676af006837910cda605708b1..eeb185128118188b08e3cade44e770c76f8541d5 100644 --- a/test/integration/single-document-treatment.js +++ b/test/integration/single-document-treatment.js @@ -13,7 +13,6 @@ "use strict"; -const _ = require('underscore'); const co = require('co'); const assert = require('assert'); const TestUser = require('./tools/TestUser').TestUser diff --git a/test/integration/sources_property.js b/test/integration/sources_property.js index 89467dc86cb71f98c81b8b9b88288fad89bafddc..737cd5053e8ee5c691acd30c3ddfb4c7f529e9fd 100644 --- a/test/integration/sources_property.js +++ b/test/integration/sources_property.js @@ -14,7 +14,6 @@ "use strict"; const co = require('co'); -const _ = require('underscore'); const should = require('should'); const assert = require('assert'); const constants = require('../../app/lib/constants'); diff --git a/test/integration/start_generate_blocks.js b/test/integration/start_generate_blocks.js deleted file mode 100644 index 6cef8f45240145f9e5158d3bcec9d406cf108ceb..0000000000000000000000000000000000000000 --- a/test/integration/start_generate_blocks.js +++ /dev/null @@ -1,150 +0,0 @@ -// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 -// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -"use strict"; - -const co = require('co'); -const _ = require('underscore'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const TestUser = require('./tools/TestUser').TestUser -const rp = require('request-promise'); -const httpTest = require('./tools/http'); -const commit = require('./tools/commit'); -const until = require('./tools/until'); -const toolbox = require('./tools/toolbox'); -const PeerDTO = require('../../app/lib/dto/PeerDTO').PeerDTO -const contacter = require('../../app/modules/crawler').CrawlerDependency.duniter.methods.contacter; -const sync = require('./tools/sync'); -const shutDownEngine = require('./tools/shutDownEngine'); - -const expectJSON = httpTest.expectJSON; - -const MEMORY_MODE = true; -const commonConf = { - bmaWithCrawler: true, - ipv4: '127.0.0.1', - remoteipv4: '127.0.0.1', - currency: 'bb', - httpLogs: true, - forksize: 0, - sigQty: 1 -}; - -let s1, s2, cat, toc, tic, tuc - -let nodeS1; -let nodeS2; - -describe("Generation", function() { - - before(function() { - - return co(function *() { - - s1 = duniter( - '/bb7', - MEMORY_MODE, - _.extend({ - port: '7790', - pair: { - pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', - sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' - }, - powDelay: 1 - }, commonConf)); - - s2 = duniter( - '/bb7_2', - MEMORY_MODE, - _.extend({ - port: '7791', - pair: { - pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', - sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F' - }, - powDelay: 1 - }, commonConf)); - - const commitS1 = commit(s1); - - cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); - toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); - tic = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s1 }); - tuc = new TestUser('tuc', { pub: '3conGDUXdrTGbQPMQQhEC4Ubu1MCAnFrAYvUaewbUhtk', sec: '5ks7qQ8Fpkin7ycXpxQSxxjVhs8VTzpM3vEBMqM7NfC1ZiFJ93uQryDcoM93Mj77T6hDAABdeHZJDFnkDb35bgiU'}, { server: s1 }); - - let servers = [s1, s2]; - for (const server of servers) { - server.addEndpointsDefinitions(() => require('../../app/modules/bma').BmaDependency.duniter.methods.getMainEndpoint(server.conf)) - yield server.initWithDAL(); - server.bma = yield bma(server); - yield server.bma.openConnections(); - require('../../app/modules/router').RouterDependency.duniter.methods.routeToNetwork(server); - yield server.PeeringService.generateSelfPeer(server.conf); - const prover = require('../../app/modules/prover').ProverDependency.duniter.methods.prover(server); - server.startBlockComputation = () => prover.startService(); - server.stopBlockComputation = () => prover.stopService(); - } - nodeS1 = contacter('127.0.0.1', s1.conf.port); - nodeS2 = contacter('127.0.0.1', s2.conf.port); - // Server 1 - yield cat.createIdentity(); - yield toc.createIdentity(); - yield toc.cert(cat); - yield cat.cert(toc); - yield cat.join(); - yield toc.join(); - yield commitS1(); - // Server 2 syncs block 0 - yield sync(0, 0, s1, s2); - // Let each node know each other - let peer1 = yield nodeS1.getPeer(); - yield nodeS2.postPeer(PeerDTO.fromJSONObject(peer1).getRawSigned()); - let peer2 = yield nodeS2.getPeer(); - yield nodeS1.postPeer(PeerDTO.fromJSONObject(peer2).getRawSigned()); - s1.startBlockComputation(); - yield until(s2, 'block', 1); - s2.startBlockComputation(); - s1.conf.powDelay = 2000; - s2.conf.powDelay = 2000; - yield [ - toolbox.serverWaitBlock(s1, 3), - toolbox.serverWaitBlock(s2, 3) - ]; - s1.stopBlockComputation(); - s2.stopBlockComputation(); - }); - }); - - after(() => { - return Promise.all([ - shutDownEngine(s1), - shutDownEngine(s2) - ]) - }) - - describe("Server 1 /blockchain", function() { - - it('/current should exist', function() { - return expectJSON(rp('http://127.0.0.1:7790/blockchain/current', { json: true }), { - number: 3 - }); - }); - - it('/current should exist on other node too', function() { - return expectJSON(rp('http://127.0.0.1:7791/blockchain/current', { json: true }), { - number: 3 - }); - }); - }); -}); diff --git a/test/integration/tools/TestUser.ts b/test/integration/tools/TestUser.ts index edf7b8764d5dd0cd1b7538557e6bf1f0bdc4b126..cf76f7408f7db2e2b7e76637f6fd41ea17616758 100644 --- a/test/integration/tools/TestUser.ts +++ b/test/integration/tools/TestUser.ts @@ -24,9 +24,10 @@ import {parsers} from "../../../app/lib/common-libs/parsers/index" import {TransactionDTO} from "../../../app/lib/dto/TransactionDTO" import {PeerDTO} from "../../../app/lib/dto/PeerDTO" import {Contacter} from "../../../app/modules/crawler/lib/contacter" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {HttpLookup} from "../../../app/modules/bma/lib/dtos" const request = require('request') -const _ = require('underscore') export interface TestInput { src:string @@ -92,7 +93,7 @@ export class TestUser { public async makeCert(user:TestUser, fromServer?:TestingServer, overrideProps?:any) { const lookup = await this.lookup(user.pub, fromServer) const current = await this.node.server.BlockchainService.current() - const idty = _.filter(lookup.results[0].uids, (uidEntry:{ uid: string }) => uidEntry.uid === user.uid)[0] + const idty = Underscore.filter(lookup.results[0].uids, uidEntry => uidEntry.uid === user.uid)[0] let buid = current ? Buid.format.buid(current.number, current.hash) : CommonConstants.SPECIAL_BLOCK const cert = { "version": CommonConstants.DOCUMENTS_VERSION, @@ -105,7 +106,7 @@ export class TestUser { "buid": buid, "sig": "" } - _.extend(cert, overrideProps || {}); + Underscore.extend(cert, overrideProps || {}); const rawCert = CertificationDTO.fromJSONObject(cert).getRawUnSigned() cert.sig = KeyGen(this.pub, this.sec).signSync(rawCert) return CertificationDTO.fromJSONObject(cert) @@ -126,9 +127,9 @@ export class TestUser { return await this.sendMembership("OUT") } - public async makeRevocation(givenLookupIdty?:any, overrideProps?:any) { + public async makeRevocation(givenLookupIdty?:HttpLookup, overrideProps?:any) { const res = givenLookupIdty || (await this.lookup(this.pub)); - const matchingResult = _.filter(res.results[0].uids, (uidEntry: { uid:string }) => uidEntry.uid === this.uid)[0] + const matchingResult = Underscore.filter(res.results[0].uids, uidEntry => uidEntry.uid === this.uid)[0] const idty = { uid: matchingResult.uid, buid: matchingResult.meta.timestamp, @@ -142,7 +143,7 @@ export class TestUser { "buid": idty.buid, "revocation": '' }; - _.extend(revocation, overrideProps || {}); + Underscore.extend(revocation, overrideProps || {}); const rawRevocation = RevocationDTO.fromJSONObject(revocation).getRawUnsigned() revocation.revocation = KeyGen(this.pub, this.sec).signSync(rawRevocation); return RevocationDTO.fromJSONObject(revocation) @@ -170,7 +171,7 @@ export class TestUser { "certts": idty.meta.timestamp, "signature": "" }; - _.extend(join, overrideProps || {}); + Underscore.extend(join, overrideProps || {}); const rawJoin = MembershipDTO.fromJSONObject(join).getRaw() join.signature = KeyGen(this.pub, this.sec).signSync(rawJoin) return MembershipDTO.fromJSONObject(join) @@ -183,7 +184,7 @@ export class TestUser { }) } - public send(amount:number, recipient:string, comment?:string) { + public send(amount:number, recipient:TestUser|string, comment?:string) { const that = this return async function(done:(e?:any)=>void) { try { @@ -351,7 +352,7 @@ export class TestUser { block: '2-00008DF633FC158F9DB4864ABED696C1AA0FE5D617A7B5F7AB8DE7CA2EFCD4CB', endpoints: endpoints }); - _.extend(peer, overrideProps || {}); + Underscore.extend(peer, overrideProps || {}); const rawPeer = PeerDTO.fromJSONObject(peer).getRawUnsigned() peer.signature = KeyGen(this.pub, this.sec).signSync(rawPeer) return PeerDTO.fromJSONObject(peer) @@ -400,14 +401,14 @@ export class TestUser { }); } - public async lookup(pubkey:string, fromServer?:TestingServer) { + public async lookup(pubkey:string, fromServer?:TestingServer): Promise<HttpLookup> { const node2 = await this.getContacter(fromServer) return node2.getLookup(pubkey); } - public async sendP(amount:number, userid:string, comment?:string) { + public async sendP(amount:number, userid:TestUser|string, comment?:string) { return new Promise((res, rej) => { - this.send(amount, userid, comment)((err) => { + this.send(amount, userid, comment)((err:any) => { if (err) return rej(err) res() }) diff --git a/test/integration/tools/commit.js b/test/integration/tools/commit.js index bb5804a8ed22526cd12426261b7eb3cd94fe39a7..91e05bccf5b7d4bb3bae5b242aa797a6948ee945 100644 --- a/test/integration/tools/commit.js +++ b/test/integration/tools/commit.js @@ -13,7 +13,7 @@ "use strict"; -var _ = require('underscore'); +const Underscore = require('../../../app/lib/common-libs/underscore').Underscore; var co = require('co'); var rp = require('request-promise'); var logger = require('../../../app/lib/logger').NewLogger('test'); @@ -24,7 +24,7 @@ module.exports = function makeBlockAndPost(theServer, extraProps, noWait) { return function(manualValues) { if (extraProps) { manualValues = manualValues || {}; - manualValues = _.extend(manualValues, extraProps); + manualValues = Underscore.extend(manualValues, extraProps); } return co(function *() { if (!theServer._utProver) { diff --git a/test/integration/tools/http.js b/test/integration/tools/http.js index a8e13ba87a613af0ac18a5364fd6df868eb8b331..c6f4e0b002737e18b425a87f63a3c39ca3172940 100644 --- a/test/integration/tools/http.js +++ b/test/integration/tools/http.js @@ -16,7 +16,7 @@ const co = require('co'); const should = require('should'); const assert = require('assert'); -const _ = require('underscore'); +const Underscore = require('../../../app/lib/common-libs/underscore').Underscore; module.exports = { @@ -66,7 +66,7 @@ module.exports = { expectJSON: async function expectJSON(promise, json) { try { const resJson = await promise; - _.keys(json).forEach(function(key){ + Underscore.keys(json).forEach(function(key){ resJson.should.have.property(key).equal(json[key]); }); } catch (err) { diff --git a/test/integration/tools/node.js b/test/integration/tools/node.js index 57f696cd56ca7cc981e65d6eaf90ace83005d14c..e4df8cda7d598928049f6c5bbaa0b84f8e6770e5 100644 --- a/test/integration/tools/node.js +++ b/test/integration/tools/node.js @@ -13,7 +13,7 @@ "use strict"; var co = require('co'); -var _ = require('underscore'); +const Underscore = require('../../../app/lib/common-libs/underscore').Underscore; var async = require('async'); var request = require('request'); var contacter = require('../../../app/modules/crawler').CrawlerDependency.duniter.methods.contacter; @@ -166,11 +166,11 @@ function Node (dbName, options) { config: { onLoading: (conf, program) => co(function*() { const overConf = ConfDTO.complete(options); - _.extend(conf, overConf); + Underscore.extend(conf, overConf); }) }, service: { - process: (server) => _.extend(server, { + process: (server) => Underscore.extend(server, { startService: () => { logger.debug('Server Servie Started!'); } diff --git a/test/integration/tools/sync.js b/test/integration/tools/sync.js index b453100665f011266382cd45bf2b33c1bd3192ed..de088fb0020c66db1dc939b8071ed2c37796dbf3 100644 --- a/test/integration/tools/sync.js +++ b/test/integration/tools/sync.js @@ -14,12 +14,12 @@ "use strict"; const co = require('co'); -const _ = require('underscore'); +const Underscore = require('../../../app/lib/common-libs/underscore').Underscore; const rp = require('request-promise'); module.exports = function makeBlockAndPost(fromBlock, toBlock, fromServer, toServer) { // Sync blocks - return _.range(fromBlock, toBlock + 1).reduce((p, number) => co(function*(){ + return Underscore.range(fromBlock, toBlock + 1).reduce((p, number) => co(function*(){ yield p; const json = yield rp('http://' + fromServer.conf.ipv4 + ':' + fromServer.conf.port + '/blockchain/block/' + number, { json: true }); yield toServer.writeBlock(json) diff --git a/test/integration/tools/toolbox.ts b/test/integration/tools/toolbox.ts index 3edfff9c970f4e766548285b9d888b0cedce984a..e2ed9285c4d367f1ebfa2a65f0ba49728fc26d41 100644 --- a/test/integration/tools/toolbox.ts +++ b/test/integration/tools/toolbox.ts @@ -19,7 +19,7 @@ import * as stream from "stream" import {RevocationDTO} from "../../../app/lib/dto/RevocationDTO" import {IdentityDTO} from "../../../app/lib/dto/IdentityDTO" import {PeerDTO} from "../../../app/lib/dto/PeerDTO" -import {Network} from "../../../app/modules/bma/lib/network" +import {BmaApi, Network} from "../../../app/modules/bma/lib/network" import {DBIdentity} from "../../../app/lib/dal/sqliteDAL/IdentityDAL" import {CertificationDTO} from "../../../app/lib/dto/CertificationDTO" import {BlockchainService} from "../../../app/service/BlockchainService" @@ -39,11 +39,11 @@ import {TestUser} from "./TestUser" import {RouterDependency} from "../../../app/modules/router" import {ProverDependency} from "../../../app/modules/prover/index" import {WS2PClient} from "../../../app/modules/ws2p/lib/WS2PClient" -import {DBPeer} from "../../../app/lib/dal/sqliteDAL/PeerDAL" import {DBBlock} from "../../../app/lib/db/DBBlock" +import {DBPeer} from "../../../app/lib/db/DBPeer" +import {Underscore} from "../../../app/lib/common-libs/underscore" const assert = require('assert'); -const _ = require('underscore'); const rp = require('request-promise'); const es = require('event-stream'); const WebSocketServer = require('ws').Server @@ -65,30 +65,6 @@ export const getNewTestingPort = () => { return PORT++ } -export const shouldFail = async (promise:Promise<any>, message:string|null = null) => { - try { - await promise; - throw '{ "message": "Should have thrown an error" }' - } catch(e) { - let err = e - if (typeof e === "string") { - err = JSON.parse(e) - } - err.should.have.property('message').equal(message); - } -} -export const assertThrows = async (promise:Promise<any>, message:string|null = null) => { - try { - await promise; - throw "Should have thrown" - } catch(e) { - if (e === "Should have thrown") { - throw e - } - assert.equal(e, message) - } -} - export const simpleUser = (uid:string, keyring:{ pub:string, sec:string }, server:TestingServer) => { return new TestUser(uid, keyring, { server }); } @@ -97,8 +73,8 @@ export const simpleNetworkOf2NodesAnd2Users = async (options:any) => { const catKeyring = { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}; const tacKeyring = { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}; - const s1 = NewTestingServer(_.extend({ pair: catKeyring }, options || {})); - const s2 = NewTestingServer(_.extend({ pair: tacKeyring }, options || {})); + const s1 = NewTestingServer(Underscore.extend({ pair: catKeyring }, options || {})); + const s2 = NewTestingServer(Underscore.extend({ pair: tacKeyring }, options || {})); const cat = new TestUser('cat', catKeyring, { server: s1 }); const tac = new TestUser('tac', tacKeyring, { server: s1 }); @@ -129,7 +105,7 @@ export const simpleNodeWith2Users = async (options:any) => { const catKeyring = { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}; const tacKeyring = { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}; - const s1 = NewTestingServer(_.extend({ pair: catKeyring }, options || {})); + const s1 = NewTestingServer(Underscore.extend({ pair: catKeyring }, options || {})); const cat = new TestUser('cat', catKeyring, { server: s1 }); const tac = new TestUser('tac', tacKeyring, { server: s1 }); @@ -151,7 +127,7 @@ export const simpleNodeWith2otherUsers = async (options:any) => { const ticKeyring = { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}; const tocKeyring = { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}; - const s1 = NewTestingServer(_.extend({ pair: ticKeyring }, options || {})); + const s1 = NewTestingServer(Underscore.extend({ pair: ticKeyring }, options || {})); const tic = new TestUser('cat', ticKeyring, { server: s1 }); const toc = new TestUser('tac', tocKeyring, { server: s1 }); @@ -262,7 +238,7 @@ export const NewTestingServer = (conf:any) => { const server = new Server( '~/.config/duniter/' + (conf.homename || 'dev_unit_tests'), conf.memory !== undefined ? conf.memory : MEMORY_MODE, - _.extend(conf, commonConf)); + Underscore.extend(conf, commonConf)); return new TestingServer(port, server) } @@ -336,7 +312,7 @@ export class TestingServer { private prover:Prover private permaProver:PermanentProver - private bma:any + public bma:BmaApi constructor( private port:number, @@ -377,6 +353,10 @@ export class TestingServer { return this.server.home } + initWithDAL() { + return this.server.initWithDAL() + } + revert(): Promise<DBBlock> { return this.server.revert() } @@ -482,7 +462,7 @@ export class TestingServer { return httpTest.expectJSON(rp(this.url(uri), { json: true }), expectations); } - expectError(uri:string, code:number, message:string) { + expectError(uri:string, code:number, message = '') { return httpTest.expectError(code, message, rp(this.url(uri), { json: true })); } diff --git a/test/integration/crosschain-test.js b/test/integration/transactions/transaction-crosschain.ts similarity index 57% rename from test/integration/crosschain-test.js rename to test/integration/transactions/transaction-crosschain.ts index 22c436238f7400100e78be9b5a5a9b7c082031cd..463e77f4ef9550439e0176808a567c966bb72d48 100644 --- a/test/integration/crosschain-test.js +++ b/test/integration/transactions/transaction-crosschain.ts @@ -11,19 +11,16 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {HttpSources} from "../../../app/modules/bma/lib/dtos" -const co = require('co'); -const _ = require('underscore'); const assert = require('assert'); const should = require('should'); const rp = require('request-promise'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const commit = require('./tools/commit'); -const toolbox = require('./tools/toolbox'); -const TestUser = require('./tools/TestUser').TestUser -const unit = require('./tools/unit'); -const httpTest = require('./tools/http'); +const unit = require('../tools/unit'); +const httpTest = require('../tools/http'); /** * Test Crosschain algorithm described at https://en.bitcoin.it/wiki/Atomic_cross-chain_trading @@ -44,12 +41,11 @@ describe("Crosschain transactions", function() { describe('Successfull transaction', () => { - let sB, sM, tocB, tocM, ticB, ticM, btx0, mtx0; // Source transactions for coins + let sB:TestingServer, sM:TestingServer, tocB:TestUser, tocM:TestUser, ticB:TestUser, ticM:TestUser, btx0:string, mtx0:string; // Source transactions for coins - before(() => co(function *() { + before(async () => { - - sB = toolbox.server(_.extend({ + sB = NewTestingServer(Underscore.extend({ memory: MEMORY_MODE, name: 'bb11', currency: 'BETA_BROUZOUF', @@ -59,7 +55,7 @@ describe("Crosschain transactions", function() { } }, commonConf)); - sM = toolbox.server(_.extend({ + sM = NewTestingServer(Underscore.extend({ memory: MEMORY_MODE, name: 'bb12', currency: 'META_BROUZOUF', @@ -76,44 +72,43 @@ describe("Crosschain transactions", function() { ticB = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: sB }); ticM = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: sM }); - yield sB.initDalBmaConnections(); - yield sM.initDalBmaConnections(); - - // Initialize BETA - yield ticB.createIdentity(); - yield tocB.createIdentity(); - yield tocB.cert(ticB); - yield ticB.cert(tocB); - yield ticB.join(); - yield tocB.join(); - yield commit(sB)({ time: now }); - yield commit(sB)({ time: now + 10 }); - yield commit(sB)({ time: now + 10 }); - // Preparation: we create a source transaction for our transfer - btx0 = yield tocB.prepareITX(120, tocB); - // We submit it to the network - yield tocB.sendTX(btx0); - // Written - yield commit(sB)({ time: now + 10 }); - - // Initialize META - yield ticM.createIdentity(); - yield tocM.createIdentity(); - yield tocM.cert(ticM); - yield ticM.cert(tocM); - yield ticM.join(); - yield tocM.join(); - yield commit(sM)({ time: now }); - yield commit(sM)({ time: now + 10 }); - yield commit(sM)({ time: now + 10 }); - // Preparation: we create a source transaction for our transfer - mtx0 = yield ticM.prepareITX(120, ticM); - // We submit it to the network - yield ticM.sendTX(mtx0); - // Written - yield commit(sM)({ time: now + 10 }); - }) - ); + await sB.initDalBmaConnections(); + await sM.initDalBmaConnections(); + + // Initialize BETA + await ticB.createIdentity(); + await tocB.createIdentity(); + await tocB.cert(ticB); + await ticB.cert(tocB); + await ticB.join(); + await tocB.join(); + await sB.commit({ time: now }); + await sB.commit({ time: now + 10 }); + await sB.commit({ time: now + 10 }); + // Preparation: we create a source transaction for our transfer + btx0 = await tocB.prepareITX(120, tocB); + // We submit it to the network + await tocB.sendTX(btx0); + // Written + await sB.commit({ time: now + 10 }); + + // Initialize META + await ticM.createIdentity(); + await tocM.createIdentity(); + await tocM.cert(ticM); + await ticM.cert(tocM); + await ticM.join(); + await tocM.join(); + await sM.commit({ time: now }); + await sM.commit({ time: now + 10 }); + await sM.commit({ time: now + 10 }); + // Preparation: we create a source transaction for our transfer + mtx0 = await ticM.prepareITX(120, ticM); + // We submit it to the network + await ticM.sendTX(mtx0); + // Written + await sM.commit({ time: now + 10 }); + }) after(() => { return Promise.all([ @@ -131,35 +126,35 @@ describe("Crosschain transactions", function() { describe('Transfering', () => { - it("commit", () => co(function *() { + it("commit", async () => { - const currentB = yield sB.get('/blockchain/current'); + const currentB = await sB.get('/blockchain/current'); const blockstampB = [currentB.number, currentB.hash].join('-'); - const currentM = yield sM.get('/blockchain/current'); + const currentM = await sM.get('/blockchain/current'); const blockstampM = [currentM.number, currentM.hash].join('-'); // TOCB side (BETA) // 1. toc secretely chooses X password - let btx1 = yield tocB.prepareUTX(btx0, ['SIG(0)'], [{ qty: 120, base: 0, lock: '(XHX(8AFC8DF633FC158F9DB4864ABED696C1AA0FE5D617A7B5F7AB8DE7CA2EFCD4CB) && SIG(' + ticB.pub + ')) || (SIG(' + tocB.pub + ') && SIG(' + ticB.pub + '))' }], { comment: 'BETA toc to tic', blockstamp: blockstampB }); + let btx1 = await tocB.prepareUTX(btx0, ['SIG(0)'], [{ qty: 120, base: 0, lock: '(XHX(8AFC8DF633FC158F9DB4864ABED696C1AA0FE5D617A7B5F7AB8DE7CA2EFCD4CB) && SIG(' + ticB.pub + ')) || (SIG(' + tocB.pub + ') && SIG(' + ticB.pub + '))' }], { comment: 'BETA toc to tic', blockstamp: blockstampB }); // 2. toc makes a rollback transaction from tx1, signed by both parties (through internet): toc and tic - let btx2 = yield tocB.prepareMTX(btx1, ticB, ['XHX(0) SIG(1) SIG(0) SIG(1)'], [{ qty: 120, base: 0, lock: 'SIG(' + tocB.pub + ')' }], { comment: 'money back to tocB in 48h', locktime: 3600 * 48, blockstamp: blockstampB }); // N.B.: locktime should be like 48h in real world + let btx2 = await tocB.prepareMTX(btx1, ticB, ['XHX(0) SIG(1) SIG(0) SIG(1)'], [{ qty: 120, base: 0, lock: 'SIG(' + tocB.pub + ')' }], { comment: 'money back to tocB in 48h', locktime: 3600 * 48, blockstamp: blockstampB }); // N.B.: locktime should be like 48h in real world // TICM side (META) // 3. tic generates a transaction based on H(X) given by toc (through internet) - let mtx3 = yield ticM.prepareUTX(mtx0, ['SIG(0)'], [{ qty: 120, base: 0, lock: '(XHX(8AFC8DF633FC158F9DB4864ABED696C1AA0FE5D617A7B5F7AB8DE7CA2EFCD4CB) && SIG(' + tocM.pub + ')) || (SIG(' + ticM.pub + ') && SIG(' + tocM.pub + '))' }], { comment: 'META tic to toc', blockstamp: blockstampM }); + let mtx3 = await ticM.prepareUTX(mtx0, ['SIG(0)'], [{ qty: 120, base: 0, lock: '(XHX(8AFC8DF633FC158F9DB4864ABED696C1AA0FE5D617A7B5F7AB8DE7CA2EFCD4CB) && SIG(' + tocM.pub + ')) || (SIG(' + ticM.pub + ') && SIG(' + tocM.pub + '))' }], { comment: 'META tic to toc', blockstamp: blockstampM }); // 4. tic makes a rollback transaction from tx1, signed by both parties: toc and tic - let mtx4 = yield ticM.prepareMTX(mtx3, tocM, ['XHX(0) SIG(1) SIG(0) SIG(1)'], [{ qty: 120, base: 0, lock: 'SIG(' + ticM.pub + ')' }], { comment: 'money back to ticM', locktime: 3600 * 24, blockstamp: blockstampM }); // N.B.: locktime should be like 24h in real world + let mtx4 = await ticM.prepareMTX(mtx3, tocM, ['XHX(0) SIG(1) SIG(0) SIG(1)'], [{ qty: 120, base: 0, lock: 'SIG(' + ticM.pub + ')' }], { comment: 'money back to ticM', locktime: 3600 * 24, blockstamp: blockstampM }); // N.B.: locktime should be like 24h in real world // We submit TX1 to the network & write it - yield tocB.sendTX(btx1); + await tocB.sendTX(btx1); // Written - yield commit(sB)({ time: now + 10 }); + await sB.commit({ time: now + 10 }); // We submit TX3 to the network & write it - yield ticM.sendTX(mtx3); + await ticM.sendTX(mtx3); // Written - yield commit(sM)({ time: now + 10 }); + await sM.commit({ time: now + 10 }); /** * So now ... parties can either COMMIT or ROLLBACK. It's UP to the initiator: TOC. @@ -168,58 +163,58 @@ describe("Crosschain transactions", function() { /** * Note: the ROLLBACK transactions have a locktime, and cannot be used before that delay. */ - yield unit.shouldFail(ticM.sendTX(mtx4), 'Locktime not elapsed yet'); - yield unit.shouldFail(tocB.sendTX(btx2), 'Locktime not elapsed yet'); + await unit.shouldFail(ticM.sendTX(mtx4), 'Locktime not elapsed yet'); + await unit.shouldFail(tocB.sendTX(btx2), 'Locktime not elapsed yet'); /** * Let's say TOC agrees & and start COMMIT. */ // TOCM consumes TICM's offered money by revealing the password + signing - let mtx5 = yield tocM.prepareUTX(mtx3, ['XHX(1872767826647264) SIG(0)'], [{ qty: 120, base: 0, lock: 'SIG(' + tocM.pub + ')' }], { comment: 'toc takes money on META_BROUZOUF', blockstamp: blockstampM }); - yield tocM.sendTX(mtx5); + let mtx5 = await tocM.prepareUTX(mtx3, ['XHX(1872767826647264) SIG(0)'], [{ qty: 120, base: 0, lock: 'SIG(' + tocM.pub + ')' }], { comment: 'toc takes money on META_BROUZOUF', blockstamp: blockstampM }); + await tocM.sendTX(mtx5); // Written - yield commit(sM)(); + await sM.commit(); // But now X is revealed: TAC can takes the money offered in TX1 by TOCB - let btx6 = yield ticB.prepareUTX(btx1, ['XHX(1872767826647264) SIG(0)'], [{ qty: 120, base: 0, lock: 'SIG(' + ticB.pub + ')' }], { comment: 'tic takes money on BETA_BROUZOUF', blockstamp: blockstampB }); - yield ticB.sendTX(btx6); + let btx6 = await ticB.prepareUTX(btx1, ['XHX(1872767826647264) SIG(0)'], [{ qty: 120, base: 0, lock: 'SIG(' + ticB.pub + ')' }], { comment: 'tic takes money on BETA_BROUZOUF', blockstamp: blockstampB }); + await ticB.sendTX(btx6); // Written - yield commit(sB)(); + await sB.commit(); /** * Now the transaction is fully COMMITTED! Look at rollback transactions: they will fail. */ - yield unit.shouldFail(tocB.sendTX(btx2), 'Source already consumed'); - yield unit.shouldFail(ticM.sendTX(mtx4), 'Source already consumed'); - })); + await unit.shouldFail(tocB.sendTX(btx2), 'Source already consumed'); + await unit.shouldFail(ticM.sendTX(mtx4), 'Source already consumed'); + }) it('toc should now have 0 BETA_BROUZOUF from Transaction sources due to COMMIT', () => { - return sB.expect('/tx/sources/' + tocB.pub, (res) => { - const txRes = _.filter(res.sources, { type: 'T' }); + return sB.expect('/tx/sources/' + tocB.pub, (res:HttpSources) => { + const txRes = Underscore.where(res.sources, { type: 'T' }); txRes.should.have.length(0); }); }); it('toc should now have 120 META_BROUZOUF from Transaction sources due to COMMIT', () => { - return sM.expect('/tx/sources/' + tocB.pub, (res) => { - const txRes = _.filter(res.sources, { type: 'T' }); + return sM.expect('/tx/sources/' + tocB.pub, (res:HttpSources) => { + const txRes = Underscore.where(res.sources, { type: 'T' }); txRes.should.have.length(1); assert.equal(txRes[0].amount, 120); }); }); it('tic should now have 0 META_BROUZOUF from Transaction sources due to COMMMIT', () => { - return sM.expect('/tx/sources/' + ticM.pub, (res) => { - const txRes = _.filter(res.sources, { type: 'T' }); + return sM.expect('/tx/sources/' + ticM.pub, (res:HttpSources) => { + const txRes = Underscore.where(res.sources, { type: 'T' }); txRes.should.have.length(0); }); }); it('tic should have 120 BETA_BROUZOUF from Transaction sources due to COMMIT', () => { - return sB.expect('/tx/sources/' + ticM.pub, (res) => { - const txRes = _.filter(res.sources, { type: 'T' }); + return sB.expect('/tx/sources/' + ticM.pub, (res:HttpSources) => { + const txRes = Underscore.where(res.sources, { type: 'T' }); txRes.should.have.length(1); assert.equal(txRes[0].amount, 120); }); @@ -229,76 +224,73 @@ describe("Crosschain transactions", function() { describe('Rollbacked transaction', () => { - let sB, sM, tocB, tocM, ticB, ticM, btx0, mtx0; // Source transactions for coins - - before(function() { - - return co(function *() { - - sB = toolbox.server(_.extend({ - memory: MEMORY_MODE, - name: 'bb11', - currency: 'BETA_BROUZOUF2', - pair: { - pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', - sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F' - } - }, commonConf)); - - sM = toolbox.server(_.extend({ - memory: MEMORY_MODE, - name: 'bb12', - currency: 'META_BROUZOUF2', - pair: { - pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', - sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7' - } - }, commonConf)); - - // toc is on 2 currencies - tocB = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: sB }); - tocM = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: sM }); - // tic is on 2 currencies - ticB = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: sB }); - ticM = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: sM }); - - yield sB.initDalBmaConnections(); - yield sM.initDalBmaConnections() - - // Initialize BETA - yield ticB.createIdentity(); - yield tocB.createIdentity(); - yield tocB.cert(ticB); - yield ticB.cert(tocB); - yield ticB.join(); - yield tocB.join(); - yield commit(sB)({ time: now }); - yield commit(sB)({ time: now + 10 }); - yield commit(sB)({ time: now + 10 }); - // Preparation: we create a source transaction for our transfer - btx0 = yield tocB.prepareITX(120, tocB); - // We submit it to the network - yield tocB.sendTX(btx0); - // Written - yield commit(sB)({ time: now + 10 }); - - // Initialize META - yield ticM.createIdentity(); - yield tocM.createIdentity(); - yield tocM.cert(ticM); - yield ticM.cert(tocM); - yield ticM.join(); - yield tocM.join(); - yield commit(sM)({ time: now }); - yield commit(sM)({ time: now + 10 }); - yield commit(sM)({ time: now + 10 }); - // Preparation: we create a source transaction for our transfer - mtx0 = yield ticM.prepareITX(120, ticM); - // We submit it to the network - yield ticM.sendTX(mtx0); - // Written - yield commit(sM)({ time: now + 10 }); - }); + let sB:TestingServer, sM:TestingServer, tocB:TestUser, tocM:TestUser, ticB:TestUser, ticM:TestUser, btx0:string, mtx0:string; // Source transactions for coins + + before(async () => { + + sB = NewTestingServer(Underscore.extend({ + memory: MEMORY_MODE, + name: 'bb11', + currency: 'BETA_BROUZOUF2', + pair: { + pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', + sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F' + } + }, commonConf)) + + sM = NewTestingServer(Underscore.extend({ + memory: MEMORY_MODE, + name: 'bb12', + currency: 'META_BROUZOUF2', + pair: { + pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', + sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7' + } + }, commonConf)); + + // toc is on 2 currencies + tocB = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: sB }); + tocM = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: sM }); + // tic is on 2 currencies + ticB = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: sB }); + ticM = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: sM }); + + await sB.initDalBmaConnections(); + await sM.initDalBmaConnections() + + // Initialize BETA + await ticB.createIdentity(); + await tocB.createIdentity(); + await tocB.cert(ticB); + await ticB.cert(tocB); + await ticB.join(); + await tocB.join(); + await sB.commit({ time: now }); + await sB.commit({ time: now + 10 }); + await sB.commit({ time: now + 10 }); + // Preparation: we create a source transaction for our transfer + btx0 = await tocB.prepareITX(120, tocB); + // We submit it to the network + await tocB.sendTX(btx0); + // Written + await sB.commit({ time: now + 10 }); + + // Initialize META + await ticM.createIdentity(); + await tocM.createIdentity(); + await tocM.cert(ticM); + await ticM.cert(tocM); + await ticM.join(); + await tocM.join(); + await sM.commit({ time: now }); + await sM.commit({ time: now + 10 }); + await sM.commit({ time: now + 10 }); + // Preparation: we create a source transaction for our transfer + mtx0 = await ticM.prepareITX(120, ticM); + // We submit it to the network + await ticM.sendTX(mtx0); + // Written + await sM.commit({ time: now + 10 }); }); after(() => { @@ -317,35 +309,35 @@ describe("Crosschain transactions", function() { describe('Transfering', () => { - it("commit", () => co(function *() { + it("commit", async () => { - const currentB = yield sB.get('/blockchain/current'); + const currentB = await sB.get('/blockchain/current'); const blockstampB = [currentB.number, currentB.hash].join('-'); - const currentM = yield sM.get('/blockchain/current'); + const currentM = await sM.get('/blockchain/current'); const blockstampM = [currentM.number, currentM.hash].join('-'); // TOCB side (BETA) // 1. toc secretely chooses X password - let btx1 = yield tocB.prepareUTX(btx0, ['SIG(0)'], [{ qty: 120, base: 0, lock: '(XHX(8AFC8DF633FC158F9DB4864ABED696C1AA0FE5D617A7B5F7AB8DE7CA2EFCD4CB) && SIG(' + ticB.pub + ')) || (SIG(' + tocB.pub + ') && SIG(' + ticB.pub + '))' }], { comment: 'BETA toc to tic', blockstamp: blockstampB }); + let btx1 = await tocB.prepareUTX(btx0, ['SIG(0)'], [{ qty: 120, base: 0, lock: '(XHX(8AFC8DF633FC158F9DB4864ABED696C1AA0FE5D617A7B5F7AB8DE7CA2EFCD4CB) && SIG(' + ticB.pub + ')) || (SIG(' + tocB.pub + ') && SIG(' + ticB.pub + '))' }], { comment: 'BETA toc to tic', blockstamp: blockstampB }); // 2. toc makes a rollback transaction from tx1, signed by both parties (through internet): toc and tic - let btx2 = yield tocB.prepareMTX(btx1, ticB, ['SIG(0) SIG(1)'], [{ qty: 120, base: 0, lock: 'SIG(' + tocB.pub + ')' }], { comment: 'money back to tocB in 48h', locktime: 3, blockstamp: blockstampB }); // N.B.: locktime should be like 48h in real world + let btx2 = await tocB.prepareMTX(btx1, ticB, ['SIG(0) SIG(1)'], [{ qty: 120, base: 0, lock: 'SIG(' + tocB.pub + ')' }], { comment: 'money back to tocB in 48h', locktime: 3, blockstamp: blockstampB }); // N.B.: locktime should be like 48h in real world // TICM side (META) // 3. tic generates a transaction based on H(X) given by toc (through internet) - let mtx3 = yield ticM.prepareUTX(mtx0, ['SIG(0)'], [{ qty: 120, base: 0, lock: '(XHX(8AFC8DF633FC158F9DB4864ABED696C1AA0FE5D617A7B5F7AB8DE7CA2EFCD4CB) && SIG(' + tocM.pub + ')) || (SIG(' + ticM.pub + ') && SIG(' + tocM.pub + '))' }], { comment: 'META tic to toc', blockstamp: blockstampM }); + let mtx3 = await ticM.prepareUTX(mtx0, ['SIG(0)'], [{ qty: 120, base: 0, lock: '(XHX(8AFC8DF633FC158F9DB4864ABED696C1AA0FE5D617A7B5F7AB8DE7CA2EFCD4CB) && SIG(' + tocM.pub + ')) || (SIG(' + ticM.pub + ') && SIG(' + tocM.pub + '))' }], { comment: 'META tic to toc', blockstamp: blockstampM }); // 4. tic makes a rollback transaction from tx1, signed by both parties: toc and tic - let mtx4 = yield ticM.prepareMTX(mtx3, tocM, ['SIG(0) SIG(1)'], [{ qty: 120, base: 0, lock: 'SIG(' + ticM.pub + ')' }], { comment: 'money back to ticM', locktime: 2, blockstamp: blockstampM }); // N.B.: locktime should be like 24h in real world + let mtx4 = await ticM.prepareMTX(mtx3, tocM, ['SIG(0) SIG(1)'], [{ qty: 120, base: 0, lock: 'SIG(' + ticM.pub + ')' }], { comment: 'money back to ticM', locktime: 2, blockstamp: blockstampM }); // N.B.: locktime should be like 24h in real world // We submit TX1 to the network & write it - yield tocB.sendTX(btx1); + await tocB.sendTX(btx1); // Written - yield commit(sB)({ time: now + 12 }); + await sB.commit({ time: now + 12 }); // We submit TX3 to the network & write it - yield ticM.sendTX(mtx3); + await ticM.sendTX(mtx3); // Written - yield commit(sM)({ time: now + 12 }); + await sM.commit({ time: now + 12 }); /** * So now ... parties can either COMMIT or ROLLBACK. It's UP to the initiator: TOC. @@ -356,50 +348,50 @@ describe("Crosschain transactions", function() { /** * Note: the ROLLBACK transactions have a locktime, and cannot be used before that delay. */ - yield unit.shouldFail(ticM.sendTX(mtx4), 'Locktime not elapsed yet'); - yield unit.shouldFail(tocB.sendTX(btx2), 'Locktime not elapsed yet'); + await unit.shouldFail(ticM.sendTX(mtx4), 'Locktime not elapsed yet'); + await unit.shouldFail(tocB.sendTX(btx2), 'Locktime not elapsed yet'); // Increment the medianTime by 1 - yield commit(sM)({ time: now + 12 }); - yield commit(sB)({ time: now + 14 }); + await sM.commit({ time: now + 12 }); + await sB.commit({ time: now + 14 }); - yield unit.shouldNotFail(ticM.sendTX(mtx4)); // tic can rollback early (24h in real case) if toc does not reveal X - yield unit.shouldFail(tocB.sendTX(btx2), 'Locktime not elapsed yet'); // This one has a longer locktime (48h in real case) + await unit.shouldNotFail(ticM.sendTX(mtx4)); // tic can rollback early (24h in real case) if toc does not reveal X + await unit.shouldFail(tocB.sendTX(btx2), 'Locktime not elapsed yet'); // This one has a longer locktime (48h in real case) // Rollback for TIC(M) should be done - yield commit(sM)({ time: now + 12 }); + await sM.commit({ time: now + 12 }); // Make the medianTime increment by 1 - yield commit(sB)({ time: now + 14 }); + await sB.commit({ time: now + 14 }); - yield unit.shouldNotFail(tocB.sendTX(btx2)); // toc can rollback now (48h has passed). He has not revealed X, so he is safe. - yield commit(sB)({ time: now + 14 }); + await unit.shouldNotFail(tocB.sendTX(btx2)); // toc can rollback now (48h has passed). He has not revealed X, so he is safe. + await sB.commit({ time: now + 14 }); /** * Now the transaction is fully COMMITTED! Look at rollback transactions: they will fail. */ // TOCM consumes TICM's offered money by revealing the password + signing - let mtx5 = yield tocM.prepareUTX(mtx3, ['XHX(1872767826647264) SIG(0)'], [{ qty: 120, base: 0, lock: 'SIG(' + tocM.pub + ')' }], { comment: 'toc takes money on META_BROUZOUF', blockstamp: blockstampM }); + let mtx5 = await tocM.prepareUTX(mtx3, ['XHX(1872767826647264) SIG(0)'], [{ qty: 120, base: 0, lock: 'SIG(' + tocM.pub + ')' }], { comment: 'toc takes money on META_BROUZOUF', blockstamp: blockstampM }); // Assuming X was revealed ... but actually it is not since TOCM did succeed to send the TX - let btx6 = yield ticB.prepareUTX(btx1, ['XHX(1872767826647264) SIG(0)'], [{ qty: 120, base: 0, lock: 'SIG(' + ticB.pub + ')' }], { comment: 'tic takes money on BETA_BROUZOUF', blockstamp: blockstampB }); + let btx6 = await ticB.prepareUTX(btx1, ['XHX(1872767826647264) SIG(0)'], [{ qty: 120, base: 0, lock: 'SIG(' + ticB.pub + ')' }], { comment: 'tic takes money on BETA_BROUZOUF', blockstamp: blockstampB }); - yield unit.shouldFail(tocB.sendTX(btx6), 'Source already consumed'); - yield unit.shouldFail(ticM.sendTX(mtx5), 'Source already consumed'); - })); + await unit.shouldFail(tocB.sendTX(btx6), 'Source already consumed'); + await unit.shouldFail(ticM.sendTX(mtx5), 'Source already consumed'); + }) it('toc should now have 120 BETA_BROUZOUF from Transaction sources due to rollback TX', () => checkHaveSources(tocB, 1, 120)); it('tic should now have 120 META_BROUZOUF from Transaction sources due to rollback TX', () => checkHaveSources(ticM, 1, 120)); it('toc should now have 0 META_BROUZOUF from Transaction sources', () => checkHaveSources(tocM, 0, 0)); it('tic should now have 0 BETA_BROUZOUF from Transaction sources', () => checkHaveSources(ticB, 0, 0)); - }); + }) }); }); -function checkHaveSources(theUser, sourcesCount, sourcesTotalAmount) { - return httpTest.expectAnswer(rp('http://' + theUser.node.server.conf.ipv4 + ':' + theUser.node.server.conf.port + '/tx/sources/' + theUser.pub, { json: true }), (res) => { - const txRes = _.filter(res.sources, { type: 'T' }); +function checkHaveSources(theUser:TestUser, sourcesCount:number, sourcesTotalAmount:number) { + return httpTest.expectAnswer(rp('http://' + theUser.node.server.conf.ipv4 + ':' + theUser.node.server.conf.port + '/tx/sources/' + theUser.pub, { json: true }), (res:HttpSources) => { + const txRes = Underscore.where(res.sources, { type: 'T' }) txRes.should.have.length(sourcesCount); let sum = 0; for (const result of txRes) { diff --git a/test/integration/transactions-cltv.js b/test/integration/transactions/transactions-cltv.ts similarity index 50% rename from test/integration/transactions-cltv.js rename to test/integration/transactions/transactions-cltv.ts index 4722ef30b60416835d0ddd2e56451a0c6fdec288..4e5515d33d84a270a19a1a1816d58ddcb44fa506 100644 --- a/test/integration/transactions-cltv.js +++ b/test/integration/transactions/transactions-cltv.ts @@ -11,18 +11,12 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {simpleNodeWith2Users, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {shouldFail, shouldNotFail} from "../../unit-tools" -const co = require('co'); -const _ = require('underscore'); const should = require('should'); const assert = require('assert'); -const constants = require('../../app/lib/constants'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const toolbox = require('./tools/toolbox'); -const node = require('./tools/node'); -const unit = require('./tools/unit'); -const http = require('./tools/http'); const now = 1480000000; @@ -33,18 +27,18 @@ const conf = { medianTimeBlocks: 1 // Easy: medianTime(b) = time(b-1) }; -let s1, cat, tac +let s1:TestingServer, cat:TestUser, tac:TestUser -describe("Transactions: CLTV", function() { +describe("Transactions: CLTV", () => { - before(() => co(function*() { - const res = yield toolbox.simpleNodeWith2Users(conf); + before(async () => { + const res = await simpleNodeWith2Users(conf); s1 = res.s1; cat = res.cat; tac = res.tac; - yield s1.commit({ time: now }); - yield s1.commit({ time: now + 1 }); - })); + await s1.commit({ time: now }); + await s1.commit({ time: now + 1 }); + }) after(() => { return Promise.all([ @@ -52,27 +46,27 @@ describe("Transactions: CLTV", function() { ]) }) - it('it should exist block#1 with UD of 200', () => s1.expect('/blockchain/block/1', (block) => { + it('it should exist block#1 with UD of 200', () => s1.expect('/blockchain/block/1', (block:any) => { should.exists(block); assert.equal(block.number, 1); assert.equal(block.dividend, 200); })); - it('with SIG and CLTV', () => co(function *() { - let tx1 = yield cat.prepareITX(200, tac); - yield unit.shouldNotFail(cat.sendTX(tx1)); - yield s1.commit({ time: now + 19 }); // TODO: why not in the same block? - let current = yield s1.get('/blockchain/current'); - let tx2 = yield tac.prepareUTX(tx1, ['SIG(0)'], [{ qty: 200, base: 0, lock: 'SIG(' + cat.pub + ') && CLTV(1480000022)' }], { + it('with SIG and CLTV', async () => { + let tx1 = await cat.prepareITX(200, tac); + await shouldNotFail(cat.sendTX(tx1)); + await s1.commit({ time: now + 19 }); // TODO: why not in the same block? + let current = await s1.get('/blockchain/current'); + let tx2 = await tac.prepareUTX(tx1, ['SIG(0)'], [{ qty: 200, base: 0, lock: 'SIG(' + cat.pub + ') && CLTV(1480000022)' }], { comment: 'must wait until time 1480000022', blockstamp: [current.number, current.hash].join('-') }); - yield unit.shouldNotFail(cat.sendTX(tx2)); - yield s1.commit({ time: now + 21 }); // TODO: why not in the same block? - let tx3 = yield cat.prepareITX(200, tac); - yield unit.shouldFail(cat.sendTX(tx3), 'Wrong unlocker in transaction'); - yield s1.commit({ time: now + 22 }); - yield unit.shouldNotFail(cat.sendTX(tx3)); // Because next block will have medianTime = 22 - yield s1.commit({ time: now + 22 }); - })); -}); + await shouldNotFail(cat.sendTX(tx2)); + await s1.commit({ time: now + 21 }); // TODO: why not in the same block? + let tx3 = await cat.prepareITX(200, tac); + await shouldFail(cat.sendTX(tx3), 'Wrong unlocker in transaction'); + await s1.commit({ time: now + 22 }); + await shouldNotFail(cat.sendTX(tx3)); // Because next block will have medianTime = 22 + await s1.commit({ time: now + 22 }); + }) +}) diff --git a/test/integration/transactions-csv.js b/test/integration/transactions/transactions-csv.ts similarity index 50% rename from test/integration/transactions-csv.js rename to test/integration/transactions/transactions-csv.ts index 31d5e912703daf1ed970d10d761b35e49c65edf8..2b3783e157bc2a2fad5bb01bb7cf70be74af0313 100644 --- a/test/integration/transactions-csv.js +++ b/test/integration/transactions/transactions-csv.ts @@ -11,18 +11,12 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {simpleNodeWith2Users, TestingServer} from "../tools/toolbox" +import {TestUser} from "../tools/TestUser" +import {shouldFail, shouldNotFail} from "../../unit-tools" -const co = require('co'); -const _ = require('underscore'); const should = require('should'); const assert = require('assert'); -const constants = require('../../app/lib/constants'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const toolbox = require('./tools/toolbox'); -const node = require('./tools/node'); -const unit = require('./tools/unit'); -const http = require('./tools/http'); const now = 1480000000; @@ -33,18 +27,18 @@ const conf = { medianTimeBlocks: 1 // Easy: medianTime(b) = time(b-1) }; -let s1, cat, tac +let s1:TestingServer, cat:TestUser, tac:TestUser -describe("Transactions: CSV", function() { +describe("Transactions: CSV", () => { - before(() => co(function*() { - const res = yield toolbox.simpleNodeWith2Users(conf); + before(async () => { + const res = await simpleNodeWith2Users(conf); s1 = res.s1; cat = res.cat; tac = res.tac; - yield s1.commit({ time: now }); - yield s1.commit({ time: now + 1 }); - })); + await s1.commit({ time: now }); + await s1.commit({ time: now + 1 }); + }) after(() => { return Promise.all([ @@ -52,27 +46,27 @@ describe("Transactions: CSV", function() { ]) }) - it('it should exist block#1 with UD of 200', () => s1.expect('/blockchain/block/1', (block) => { + it('it should exist block#1 with UD of 200', () => s1.expect('/blockchain/block/1', (block:any) => { should.exists(block); assert.equal(block.number, 1); assert.equal(block.dividend, 200); })); - it('with SIG and CSV', () => co(function *() { - let tx1 = yield cat.prepareITX(200, tac); - yield unit.shouldNotFail(cat.sendTX(tx1)); - yield s1.commit({ time: now + 19 }); // TODO: why not in the same block? - let current = yield s1.get('/blockchain/current'); - let tx2 = yield tac.prepareUTX(tx1, ['SIG(0)'], [{ qty: 200, base: 0, lock: 'SIG(' + cat.pub + ') && CSV(20)' }], { + it('with SIG and CSV', async () => { + let tx1 = await cat.prepareITX(200, tac); + await shouldNotFail(cat.sendTX(tx1)); + await s1.commit({ time: now + 19 }); // TODO: why not in the same block? + let current = await s1.get('/blockchain/current'); + let tx2 = await tac.prepareUTX(tx1, ['SIG(0)'], [{ qty: 200, base: 0, lock: 'SIG(' + cat.pub + ') && CSV(20)' }], { comment: 'must wait 20 seconds', blockstamp: [current.number, current.hash].join('-') }); - yield unit.shouldNotFail(cat.sendTX(tx2)); - yield s1.commit({ time: now + 38 }); // TODO: why not in the same block? - let tx3 = yield cat.prepareITX(200, tac); - yield unit.shouldFail(cat.sendTX(tx3), 'Wrong unlocker in transaction'); - yield s1.commit({ time: now + 39 }); - yield unit.shouldNotFail(cat.sendTX(tx3)); // Because next block will have medianTime = 39 - yield s1.commit({ time: now + 39 }); - })); -}); + await shouldNotFail(cat.sendTX(tx2)); + await s1.commit({ time: now + 38 }); // TODO: why not in the same block? + let tx3 = await cat.prepareITX(200, tac); + await shouldFail(cat.sendTX(tx3), 'Wrong unlocker in transaction'); + await s1.commit({ time: now + 39 }); + await shouldNotFail(cat.sendTX(tx3)); // Because next block will have medianTime = 39 + await s1.commit({ time: now + 39 }); + }) +}) diff --git a/test/integration/transactions-test.js b/test/integration/transactions/transactions-test.ts similarity index 58% rename from test/integration/transactions-test.js rename to test/integration/transactions/transactions-test.ts index 3860f0f8ecd9bc790b39000954582241ea09dab8..fe470cffad02073cb24cd8465154be0528c4b1b4 100644 --- a/test/integration/transactions-test.js +++ b/test/integration/transactions/transactions-test.ts @@ -11,30 +11,23 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; +import {TestUser} from "../tools/TestUser" +import {NewTestingServer, TestingServer} from "../tools/toolbox" +import {Underscore} from "../../../app/lib/common-libs/underscore" +import {shouldFail, shouldNotFail} from "../../unit-tools" -const co = require('co'); -const _ = require('underscore'); const should = require('should'); const assert = require('assert'); -const constants = require('../../app/lib/constants'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const toolbox = require('./tools/toolbox'); -const node = require('./tools/node'); -const TestUser = require('./tools/TestUser').TestUser -const unit = require('./tools/unit'); -const http = require('./tools/http'); - describe("Testing transactions", function() { const now = 1490000000; - let s1, tic, toc + let s1:TestingServer, tic:TestUser, toc:TestUser - before(() => co(function*() { + before(async () => { - s1 = toolbox.server({ + s1 = NewTestingServer({ pair: { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7' @@ -51,32 +44,32 @@ describe("Testing transactions", function() { tic = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s1 }); toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); - yield s1.initDalBmaConnections(); + await s1.initDalBmaConnections(); // Self certifications - yield tic.createIdentity(); - yield toc.createIdentity(); + await tic.createIdentity(); + await toc.createIdentity(); // Certification; - yield tic.cert(toc); - yield toc.cert(tic); - yield tic.join(); - yield toc.join(); - yield s1.commit({ time: now }); - yield s1.commit({ + await tic.cert(toc); + await toc.cert(tic); + await tic.join(); + await toc.join(); + await s1.commit({ time: now }); + await s1.commit({ time: now + 7210 }); - yield s1.commit({ + await s1.commit({ time: now + 7210 }); - yield tic.sendP(510, toc); - yield s1.expect('/tx/history/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', (res) => { + await tic.sendP(510, toc); + await s1.expect('/tx/history/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', (res:any) => { res.should.have.property('pubkey').equal('DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo'); res.should.have.property('history').property('pending').length(1); res.history.pending[0].should.have.property('received').be.a.Number; }); - yield s1.commit({ + await s1.commit({ time: now + 7220 }); - })); + }) after(() => { return Promise.all([ @@ -86,21 +79,21 @@ describe("Testing transactions", function() { describe("Sources", function(){ - it('it should exist block#2 with UD of 1200', () => s1.expect('/blockchain/block/2', (block) => { + it('it should exist block#2 with UD of 1200', () => s1.expect('/blockchain/block/2', (block:any) => { should.exists(block); assert.equal(block.number, 2); assert.equal(block.dividend, 1200); })); - it('tic should be able to send 510 to toc', () => co(function*() { - yield s1.expect('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', (res) => { + it('tic should be able to send 510 to toc', async () => { + await s1.expect('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', (res:any) => { should.exists(res); assert.equal(res.sources.length, 1); assert.equal(res.sources[0].conditions, 'SIG(DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV)') - const txSrc = _.findWhere(res.sources, { type: 'T' }); + const txSrc = (Underscore.findWhere(res.sources, { type: 'T' }) as any) assert.equal(txSrc.amount, 690); }) - const tx = yield s1.get('/tx/hash/B6DCADFB841AC05A902741A8772A70B4086D5AEAB147AD48987DDC3887DD55C8') + const tx = await s1.get('/tx/hash/B6DCADFB841AC05A902741A8772A70B4086D5AEAB147AD48987DDC3887DD55C8') assert.notEqual(tx, null) assert.deepEqual(tx, { "comment": "", @@ -127,94 +120,94 @@ describe("Testing transactions", function() { "version": 10, "written_block": 3 }) - })); + }) - it('toc should have 1510 of sources', () => s1.expect('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', (res) => { + it('toc should have 1510 of sources', () => s1.expect('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', (res:any) => { should.exists(res); assert.equal(res.sources.length, 2); - const txRes = _.findWhere(res.sources, { type: 'T' }); - const duRes = _.filter(res.sources, { type: 'D' }); + const txRes = (Underscore.findWhere(res.sources, { type: 'T' }) as any) + const duRes = (Underscore.where(res.sources, { type: 'D' }) as any) assert.equal(txRes.type, 'T'); assert.equal(txRes.amount, 510); assert.equal(duRes[0].type, 'D'); assert.equal(duRes[0].amount, 1200); })); - it('toc should be able to send 800 to tic', () => co(function *() { - let tx1 = yield toc.prepareITX(1710, tic); - yield toc.sendTX(tx1); - yield s1.commit({ time: now + 15000 }); - (yield s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(0); - })); + it('toc should be able to send 800 to tic', async () => { + let tx1 = await toc.prepareITX(1710, tic); + await toc.sendTX(tx1); + await s1.commit({ time: now + 15000 }); + (await s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(0); + }) }); describe("Chaining", function(){ - it('with SIG and XHX', () => co(function *() { + it('with SIG and XHX', async () => { // Current state - (yield s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(0); - (yield s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(2); - (yield s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(0); - (yield s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(2); + (await s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(0); + (await s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(2); + (await s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(0); + (await s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(2); // Make the time go so another UD is available - yield s1.commit({ time: now + 15000 }); - (yield s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(1); - (yield s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(3); - let tx1 = yield toc.prepareITX(1200, tic); - yield toc.sendTX(tx1); - yield s1.commit({ time: now + 15000 }); - (yield s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(0); - (yield s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(4); + await s1.commit({ time: now + 15000 }); + (await s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(1); + (await s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(3); + let tx1 = await toc.prepareITX(1200, tic); + await toc.sendTX(tx1); + await s1.commit({ time: now + 15000 }); + (await s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(0); + (await s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(4); // Now cat has all the money... - let current = yield s1.get('/blockchain/current'); - let tx2 = yield tic.prepareUTX(tx1, ['SIG(2)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'wrong', blockstamp: [current.number, current.hash].join('-') }); - let tx3 = yield tic.prepareUTX(tx1, ['SIG(1)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'wrong', blockstamp: [current.number, current.hash].join('-') }); - let tx4 = yield tic.prepareUTX(tx1, ['SIG(0)'], [{ qty: 1200, base: 0, lock: 'XHX(8AFC8DF633FC158F9DB4864ABED696C1AA0FE5D617A7B5F7AB8DE7CA2EFCD4CB)' }], { comment: 'ok', blockstamp: [current.number, current.hash].join('-') }); - let tx5 = yield tic.prepareUTX(tx1, ['XHX(2)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'wrong', blockstamp: [current.number, current.hash].join('-') }); - let tx6 = yield tic.prepareUTX(tx1, ['XHX(4)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'wrong', blockstamp: [current.number, current.hash].join('-') }); - yield unit.shouldFail(toc.sendTX(tx2), 'Wrong unlocker in transaction'); - yield unit.shouldFail(toc.sendTX(tx3), 'Wrong unlocker in transaction'); - yield unit.shouldNotFail(toc.sendTX(tx4)); - yield unit.shouldFail(toc.sendTX(tx5), 'Wrong unlocker in transaction'); - yield unit.shouldFail(toc.sendTX(tx6), 'Wrong unlocker in transaction'); - yield s1.commit({ time: now + 19840 }); // TX4 commited - (yield s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(0); // The tx was not sent to someone, but with an XHX! So toc has nothing more than before. - (yield s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(3); - let tx7 = yield tic.prepareUTX(tx4, ['XHX(2872767826647264)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'wrong1', blockstamp: [current.number, current.hash].join('-') }); - let tx8 = yield tic.prepareUTX(tx4, ['XHX(1872767826647264)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'okk', blockstamp: [current.number, current.hash].join('-') }); // tic unlocks the XHX locked amount, and gives it to toc! - yield unit.shouldFail(toc.sendTX(tx7), 'Wrong unlocker in transaction'); - yield unit.shouldNotFail(toc.sendTX(tx8)); - yield s1.commit({ time: now + 19840 }); // TX8 commited - (yield s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(1); // That's why toc now has 1 more source... - (yield s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(3); // ...and why tic's number of sources hasn't changed - })); - - it('with MULTISIG', () => co(function *() { - (yield s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(1); - (yield s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(3); - let tx1 = yield toc.prepareITX(1200, tic); - yield toc.sendTX(tx1); - yield s1.commit({ time: now + 19840 }); - let current = yield s1.get('/blockchain/current'); - (yield s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(0); - (yield s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(4); + let current = await s1.get('/blockchain/current'); + let tx2 = await tic.prepareUTX(tx1, ['SIG(2)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'wrong', blockstamp: [current.number, current.hash].join('-') }); + let tx3 = await tic.prepareUTX(tx1, ['SIG(1)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'wrong', blockstamp: [current.number, current.hash].join('-') }); + let tx4 = await tic.prepareUTX(tx1, ['SIG(0)'], [{ qty: 1200, base: 0, lock: 'XHX(8AFC8DF633FC158F9DB4864ABED696C1AA0FE5D617A7B5F7AB8DE7CA2EFCD4CB)' }], { comment: 'ok', blockstamp: [current.number, current.hash].join('-') }); + let tx5 = await tic.prepareUTX(tx1, ['XHX(2)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'wrong', blockstamp: [current.number, current.hash].join('-') }); + let tx6 = await tic.prepareUTX(tx1, ['XHX(4)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'wrong', blockstamp: [current.number, current.hash].join('-') }); + await shouldFail(toc.sendTX(tx2), 'Wrong unlocker in transaction'); + await shouldFail(toc.sendTX(tx3), 'Wrong unlocker in transaction'); + await shouldNotFail(toc.sendTX(tx4)); + await shouldFail(toc.sendTX(tx5), 'Wrong unlocker in transaction'); + await shouldFail(toc.sendTX(tx6), 'Wrong unlocker in transaction'); + await s1.commit({ time: now + 19840 }); // TX4 commited + (await s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(0); // The tx was not sent to someone, but with an XHX! So toc has nothing more than before. + (await s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(3); + let tx7 = await tic.prepareUTX(tx4, ['XHX(2872767826647264)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'wrong1', blockstamp: [current.number, current.hash].join('-') }); + let tx8 = await tic.prepareUTX(tx4, ['XHX(1872767826647264)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'okk', blockstamp: [current.number, current.hash].join('-') }); // tic unlocks the XHX locked amount, and gives it to toc! + await shouldFail(toc.sendTX(tx7), 'Wrong unlocker in transaction'); + await shouldNotFail(toc.sendTX(tx8)); + await s1.commit({ time: now + 19840 }); // TX8 commited + (await s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(1); // That's why toc now has 1 more source... + (await s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(3); // ...and why tic's number of sources hasn't changed + }) + + it('with MULTISIG', async () => { + (await s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(1); + (await s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(3); + let tx1 = await toc.prepareITX(1200, tic); + await toc.sendTX(tx1); + await s1.commit({ time: now + 19840 }); + let current = await s1.get('/blockchain/current'); + (await s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(0); + (await s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(4); // The funding transaction that can be reverted by its issuer (tic here) or consumed by toc if he knowns X for H(X) - let tx2 = yield tic.prepareUTX(tx1, ['SIG(0)'], [{ qty: 1200, base: 0, lock: '(XHX(8AFC8DF633FC158F9DB4864ABED696C1AA0FE5D617A7B5F7AB8DE7CA2EFCD4CB) && SIG(' + toc.pub + ')) || (SIG(' + tic.pub + ') && SIG(' + toc.pub + '))' }], { comment: 'cross1', blockstamp: [current.number, current.hash].join('-') }); - yield unit.shouldNotFail(toc.sendTX(tx2)); - yield s1.commit({ time: now + 19840 }); // TX2 commited - (yield s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(1); // toc is also present in the target of tx2 - (yield s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(4); // As well as tic - let tx3 = yield tic.prepareUTX(tx2, ['XHX(1872767826647264) SIG(0)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'wrong', blockstamp: [current.number, current.hash].join('-') }); - let tx4 = yield toc.prepareUTX(tx2, ['XHX(1872767826647264) SIG(0)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'ok', blockstamp: [current.number, current.hash].join('-') }); - let tx5 = yield tic.prepareMTX(tx2, toc, ['XHX(1872767826647264) SIG(1) SIG(0)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'multi OK', blockstamp: [current.number, current.hash].join('-') }); - let tx6 = yield toc.prepareMTX(tx2, tic, ['XHX(1872767826647264) SIG(1) SIG(0) SIG(0) SIG(0)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'multi WRONG', blockstamp: [current.number, current.hash].join('-') }); + let tx2 = await tic.prepareUTX(tx1, ['SIG(0)'], [{ qty: 1200, base: 0, lock: '(XHX(8AFC8DF633FC158F9DB4864ABED696C1AA0FE5D617A7B5F7AB8DE7CA2EFCD4CB) && SIG(' + toc.pub + ')) || (SIG(' + tic.pub + ') && SIG(' + toc.pub + '))' }], { comment: 'cross1', blockstamp: [current.number, current.hash].join('-') }); + await shouldNotFail(toc.sendTX(tx2)); + await s1.commit({ time: now + 19840 }); // TX2 commited + (await s1.get('/tx/sources/DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo')).should.have.property('sources').length(1); // toc is also present in the target of tx2 + (await s1.get('/tx/sources/DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV')).should.have.property('sources').length(4); // As well as tic + let tx3 = await tic.prepareUTX(tx2, ['XHX(1872767826647264) SIG(0)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'wrong', blockstamp: [current.number, current.hash].join('-') }); + let tx4 = await toc.prepareUTX(tx2, ['XHX(1872767826647264) SIG(0)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'ok', blockstamp: [current.number, current.hash].join('-') }); + let tx5 = await tic.prepareMTX(tx2, toc, ['XHX(1872767826647264) SIG(1) SIG(0)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'multi OK', blockstamp: [current.number, current.hash].join('-') }); + let tx6 = await toc.prepareMTX(tx2, tic, ['XHX(1872767826647264) SIG(1) SIG(0) SIG(0) SIG(0)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'multi WRONG', blockstamp: [current.number, current.hash].join('-') }); // nLocktime - let tx7 = yield tic.prepareMTX(tx2, toc, ['XHX(1872767826647264) SIG(1) SIG(0)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'wrong locktime', locktime: 100, blockstamp: [current.number, current.hash].join('-') }); - yield unit.shouldFail(toc.sendTX(tx3), 'Wrong unlocker in transaction'); - yield unit.shouldNotFail(toc.sendTX(tx4)); - yield unit.shouldNotFail(toc.sendTX(tx5)); - yield unit.shouldFail(toc.sendTX(tx6), 'Wrong unlocker in transaction'); - yield unit.shouldFail(toc.sendTX(tx7), 'Locktime not elapsed yet'); - })); - }); -}); + let tx7 = await tic.prepareMTX(tx2, toc, ['XHX(1872767826647264) SIG(1) SIG(0)'], [{ qty: 1200, base: 0, lock: 'SIG(' + toc.pub + ')' }], { comment: 'wrong locktime', locktime: 100, blockstamp: [current.number, current.hash].join('-') }); + await shouldFail(toc.sendTX(tx3), 'Wrong unlocker in transaction'); + await shouldNotFail(toc.sendTX(tx4)); + await shouldNotFail(toc.sendTX(tx5)); + await shouldFail(toc.sendTX(tx6), 'Wrong unlocker in transaction'); + await shouldFail(toc.sendTX(tx7), 'Locktime not elapsed yet'); + }) + }) +}) diff --git a/test/integration/v1.0-modules-api.js b/test/integration/v1.0-modules-api.js index 1cee0379a3398af691f82645dab85ed04b423797..e884aa75caf0a106a1d16c6d4e1eeca163bdbbf1 100644 --- a/test/integration/v1.0-modules-api.js +++ b/test/integration/v1.0-modules-api.js @@ -14,7 +14,6 @@ "use strict"; const co = require('co'); -const _ = require('underscore'); const should = require('should'); const util = require('util'); const path = require('path'); diff --git a/test/integration/v1.0-source-garbaging.disabled b/test/integration/v1.0-source-garbaging.disabled deleted file mode 100644 index e667749603216bdd6a0348f5b30e73f426b86a9a..0000000000000000000000000000000000000000 --- a/test/integration/v1.0-source-garbaging.disabled +++ /dev/null @@ -1,206 +0,0 @@ -"use strict"; - -const co = require('co'); -const should = require('should'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const constants = require('../../app/lib/constants'); -const toolbox = require('./tools/toolbox'); - -const now = 1480000000; - -const conf = { - ud0: 9995, - c: .99, - dt: 300, - udTime0: now + 300, - udReevalTime0: now + 300, - avgGenTime: 5000, - medianTimeBlocks: 1 // The medianTime always equals previous block's medianTime -}; - -constants.NB_DIGITS_UD = 4; - -let s1, cat, tac; - -describe("Protocol 1.0 Source Garbaging", function() { - - /***** - * DESCRIPTION - * ----------- - * - * All accounts having less than 100 units of money (current base) must see their money garbaged, i.e. destroyed. - * - * This measure is here to avoid a metastasizing of the database because of users who would spend very little amounts - * of money to random addresses, or to finally destroy very old money (dozens of years). - */ - - before(() => co(function*() { - - const res1 = yield toolbox.simpleNodeWith2Users(conf); - s1 = res1.s1; - cat = res1.cat; // HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd - tac = res1.tac; // 2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc - yield s1.commit({ time: now }); - yield s1.commit({ time: now + 300 }); - })); - - it('cat should have no source initially', () => co(function*() { - yield s1.expectThat('/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', (json) => { - json.sources.should.have.length(0); - }); - })); - - it('cat should have a Dividend, as well as tac', () => co(function*() { - yield s1.commit({ time: now + 300 }); - yield s1.expectThat('/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', (json) => { - json.sources.should.deepEqual([ - { type: 'D', noffset: 2, identifier: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', amount: 9995, base: 0 } - ]); - }); - })); - - it('should be able to send money to tac with no losses', () => co(function*() { - yield cat.sendP(2999, tac); - yield s1.commit({ time: now + 300 }); - yield cat.sendP(1, tac); - yield s1.commit({ time: now + 300 }); - yield s1.expectThat('/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', (json) => { - json.sources.should.deepEqual([ - { type: 'T', noffset: 1, identifier: '50844926EC611BF6BBF9918A657F87E0AA0DE5A5D8DB3D476289BF64C6ED8C25', amount: 6995, base: 0 } - ]); - }); - yield s1.expectThat('/tx/sources/2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', (json) => { - json.sources.should.deepEqual([ - { type: 'D', noffset: 2, identifier: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', amount: 9995, base: 0 }, - { type: 'T', noffset: 0, identifier: 'E84C72FBE788F6F52B293676A8314A6F227F14B0A8FD0168E1C4F08E85D1F8E9', amount: 2999, base: 0 }, - { type: 'T', noffset: 0, identifier: '50844926EC611BF6BBF9918A657F87E0AA0DE5A5D8DB3D476289BF64C6ED8C25', amount: 1, base: 0 } - ]); - }); - })); - - it('should be able to send money to tac with still no losses', () => co(function*() { - yield cat.sendP(5495, tac); - yield s1.commit({ time: now + 300 }); - yield s1.expectThat('/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', (json) => { - json.sources.should.deepEqual([ - { type: 'T', noffset: 1, identifier: 'DA453C8B6300F06AC538D7EFB154DA9AE51F30D525236B9D4AD13944E18AA1B0', amount: 1500, base: 0 } - ]); - }); - yield s1.expectThat('/tx/sources/2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', (json) => { - json.sources.should.deepEqual([ - { type: 'D', noffset: 2, identifier: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', amount: 9995, base: 0 }, - { type: 'T', noffset: 0, identifier: 'E84C72FBE788F6F52B293676A8314A6F227F14B0A8FD0168E1C4F08E85D1F8E9', amount: 2999, base: 0 }, - { type: 'T', noffset: 0, identifier: '50844926EC611BF6BBF9918A657F87E0AA0DE5A5D8DB3D476289BF64C6ED8C25', amount: 1, base: 0 }, - { type: 'T', noffset: 0, identifier: 'DA453C8B6300F06AC538D7EFB154DA9AE51F30D525236B9D4AD13944E18AA1B0', amount: 5495, base: 0 } - ]); - }); - })); - - it('should be able to lose money by sending 1,99,100,999,1000,300+700 units to random accounts', () => co(function*() { - yield s1.expectThat('/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', (json) => { - json.sources.should.deepEqual([ - { type: 'T', noffset: 1, identifier: 'DA453C8B6300F06AC538D7EFB154DA9AE51F30D525236B9D4AD13944E18AA1B0', amount: 1500, base: 0 } - ]); - }); - yield cat.sendP(1, '6EQoFVnFf2xpaRzieNTXmAKU6XkDHYrvgorJ8ppMFa8b'); - yield s1.commit({ time: now + 300 }); - yield s1.expectThat('/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', (json) => { - json.sources.should.deepEqual([ - { type: 'T', noffset: 1, identifier: 'A6F2C3DFF8EFEBE226F103E86193A8F22A51D25DD63C2BB9BF86D9A5F3DC55B8', amount: 1499, base: 0 } - ]); - }); - yield cat.sendP(99, '2EvWF9XM6TY3zUDjwi3qfGRW5zhN11TXcUDXdgK2XK41'); - yield s1.commit({ time: now + 300 }); - yield s1.expectThat('/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', (json) => { - json.sources.should.deepEqual([ - { type: 'T', noffset: 1, identifier: 'F1C86F38F33B2D37561EE927801D8B630BCADA62336E4BBC718BA06B1101584C', amount: 1400, base: 0 } - ]); - }); - yield cat.sendP(100, 'DPFgnVSB14QnYFjKNhbFRYLxroSmaXZ53TzgFZBcCxbF'); - yield s1.commit({ time: now + 300 }); - yield s1.expectThat('/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', (json) => { - json.sources.should.deepEqual([ - { type: 'T', noffset: 1, identifier: '0FAD3D25899C789C1C2B12FE3D90BF26E5794FB31ECF5072A881DF9B83E7CA00', amount: 1300, base: 0 } - ]); - }); - yield tac.sendP(4, 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'); - yield cat.sendP(999, '4WmQWq4NuJtu6mzFDKkmmu6Cm6BZvgoY4b4MMDMwVvu7'); - yield s1.commit({ time: now + 300 }); - yield s1.expectThat('/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', (json) => { - json.sources.should.deepEqual([ - { type: 'T', noffset: 0, identifier: '3B12EEC97704A8CCA31AFD7B60BA09555744703E22A6A47EE4ECBE6DA20B27E5', amount: 4, base: 0 }, - { type: 'T', noffset: 1, identifier: '9B18E2C2CBF9C856560E76F8684665C8677DD0506AAD5195960E30CC37A5706C', amount: 301, base: 0 } - ]); - }); - yield cat.sendP(300, '7kMAi8wttYKPK5QSfCwoDriNTcCTWKzTbuSjsLsjGJX2'); - yield tac.sendP(700, '7kMAi8wttYKPK5QSfCwoDriNTcCTWKzTbuSjsLsjGJX2'); - yield s1.commit({ time: now + 900 }); - // Has spent all its money, + 1 unit destroyed - yield s1.expectThat('/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', (json) => { - json.sources.should.deepEqual([]); - }); - // Has seen 1 unit destroyed - yield s1.expectThat('/tx/sources/6EQoFVnFf2xpaRzieNTXmAKU6XkDHYrvgorJ8ppMFa8b', (json) => { - json.sources.should.deepEqual([]); - }); - // Has seen 99 unit destroyed - yield s1.expectThat('/tx/sources/2EvWF9XM6TY3zUDjwi3qfGRW5zhN11TXcUDXdgK2XK41', (json) => { - json.sources.should.deepEqual([]); - }); - // Has just enough on the account (100 units) - yield s1.expectThat('/tx/sources/DPFgnVSB14QnYFjKNhbFRYLxroSmaXZ53TzgFZBcCxbF', (json) => { - json.sources.should.deepEqual([ - { type: 'T', noffset: 0, identifier: '0FAD3D25899C789C1C2B12FE3D90BF26E5794FB31ECF5072A881DF9B83E7CA00', amount: 100, base: 0 } - ]); - }); - // Has way enough on the account (999 units) - yield s1.expectThat('/tx/sources/4WmQWq4NuJtu6mzFDKkmmu6Cm6BZvgoY4b4MMDMwVvu7', (json) => { - json.sources.should.deepEqual([ - { type: 'T', noffset: 0, identifier: '9B18E2C2CBF9C856560E76F8684665C8677DD0506AAD5195960E30CC37A5706C', amount: 999, base: 0 } - ]); - }); - // Has way enough on the account (300 + 700 units) - yield s1.expectThat('/tx/sources/7kMAi8wttYKPK5QSfCwoDriNTcCTWKzTbuSjsLsjGJX2', (json) => { - json.sources.should.deepEqual([ - { type: 'T', noffset: 0, identifier: '37CD105D17182155978798C773C70950470EBFB27B082F888B3423670F956F35', amount: 300, base: 0 }, - { type: 'T', noffset: 0, identifier: '6EF384807D1100D51BCCB9ED6E6FF4CA12CC1F4F30392CFD43746D4D1C4BC22E', amount: 700, base: 0 } - ]); - }); - })); - - it('should have lost some money with unitBase bumped from 0 to 1', () => co(function*() { - yield s1.commit({ time: now + 900 }); - yield s1.commit({ time: now + 900 }); - // Has no more enough on the account (100x10^0 < 100x10^1) - yield s1.expectThat('/tx/sources/DPFgnVSB14QnYFjKNhbFRYLxroSmaXZ53TzgFZBcCxbF', (json) => { - json.sources.should.deepEqual([]); - }); - // Has NOT enough on the account (999x10^0 = 99.9x10^1 < 100x10^1) - yield s1.expectThat('/tx/sources/4WmQWq4NuJtu6mzFDKkmmu6Cm6BZvgoY4b4MMDMwVvu7', (json) => { - json.sources.should.deepEqual([]); - }); - // Has enough on the account (300x10^0 + 700x10^0 = 1000x10^0 = 100x10^1) - yield s1.expectThat('/tx/sources/7kMAi8wttYKPK5QSfCwoDriNTcCTWKzTbuSjsLsjGJX2', (json) => { - json.sources.should.deepEqual([ - { type: 'T', noffset: 0, identifier: '37CD105D17182155978798C773C70950470EBFB27B082F888B3423670F956F35', amount: 300, base: 0 }, - { type: 'T', noffset: 0, identifier: '6EF384807D1100D51BCCB9ED6E6FF4CA12CC1F4F30392CFD43746D4D1C4BC22E', amount: 700, base: 0 } - ]); - }); - yield s1.commit({ time: now + 1800 }); - // Has enough on the account (300x10^0 + 700x10^0 = 1000x10^0 = 100x10^1) - yield s1.expectThat('/tx/sources/7kMAi8wttYKPK5QSfCwoDriNTcCTWKzTbuSjsLsjGJX2', (json) => { - json.sources.should.deepEqual([ - { type: 'T', noffset: 0, identifier: '37CD105D17182155978798C773C70950470EBFB27B082F888B3423670F956F35', amount: 300, base: 0 }, - { type: 'T', noffset: 0, identifier: '6EF384807D1100D51BCCB9ED6E6FF4CA12CC1F4F30392CFD43746D4D1C4BC22E', amount: 700, base: 0 } - ]); - }); - yield s1.commit({ time: now + 3600 }); - yield s1.expectThat('/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', (json) => { - json.sources.should.deepEqual([ - { type: 'D', noffset: 11, identifier: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', amount: 9995, base: 0 }, - { type: 'D', noffset: 12, identifier: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', amount: 1980, base: 1 }, - { type: 'D', noffset: 14, identifier: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', amount: 3940, base: 1 } - ]); - }); - })); -}); diff --git a/test/integration/wot/wotb.ts b/test/integration/wot/wotb.ts new file mode 100644 index 0000000000000000000000000000000000000000..7ea0074d4c5907c1acbc39465fa17bee9aba3ea9 --- /dev/null +++ b/test/integration/wot/wotb.ts @@ -0,0 +1,452 @@ +// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 +// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +import {TestUser} from "../tools/TestUser" +import {TestingServer} from "../tools/toolbox" +import {BmaDependency} from "../../../app/modules/bma/index" +import {WoTBInstance} from "../../../app/lib/wot" +import {Underscore} from "../../../app/lib/common-libs/underscore" + +const should = require('should'); +const duniter = require('../../../index'); +const commit = require('../tools/commit'); +const shutDownEngine = require('../tools/shutDownEngine'); + +const MEMORY_MODE = true; +const commonConf = { + ipv4: '127.0.0.1', + currency: 'bb', + httpLogs: true, + forksize: 3, + sigQty: 1 +}; + +let s1:TestingServer, + s2:TestingServer, + s3:TestingServer, + cat:TestUser, + toc:TestUser, + tic:TestUser, + cat2:TestUser, + toc2:TestUser, + tic2:TestUser, + cat3:TestUser, + toc3:TestUser, + tic3:TestUser + +const now = 1482000000; +const _100_PERCENT = 1.0; +const MAX_DISTANCE_1 = 1; +const MAX_DISTANCE_2 = 2; +const FROM_1_LINK_SENTRIES = 1; +const __OUTDISTANCED__ = true; +const __OK__ = false; + +describe("WOTB module", () => { + + describe("Server 1", () => { + + let wotb:WoTBInstance + + before(async () => { + s1 = duniter( + '/bb11', + MEMORY_MODE, + Underscore.extend({ + port: '9337', + pair: { + pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', + sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' + }, + rootoffset: 10, + sigQty: 1, dt: 1, ud0: 120 + }, commonConf)); + + s2 = duniter( + '/bb41', + MEMORY_MODE, + Underscore.extend({ + port: '9338', + pair: { + pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', + sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' + }, + rootoffset: 10, + sigQty: 1, dt: 1, ud0: 120, + msValidity: 400 // Memberships expire after 400 second delay + }, commonConf)); + + s3 = duniter( + '/bb11', + MEMORY_MODE, + Underscore.extend({ + port: '9339', + pair: { + pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', + sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7' + }, + rootoffset: 10, + sigQty: 1, dt: 1, ud0: 120, + sigValidity: 1400, sigPeriod: 0 + }, commonConf)); + + cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); + toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); + tic = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s1 }); + + cat2 = new TestUser('cat2', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s2 }); + toc2 = new TestUser('toc2', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s2 }); + tic2 = new TestUser('tic2', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s2 }); + + cat3 = new TestUser('cat3', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s3 }); + toc3 = new TestUser('toc3', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s3 }); + tic3 = new TestUser('tic3', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s3 }); + + /** + * cat <==> toc + */ + await s1.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); + wotb = s1.dal.wotb; + await cat.createIdentity(); + await toc.createIdentity(); + await toc.cert(cat); + await cat.cert(toc); + await cat.join(); + await toc.join(); + await commit(s1)({ + time: now + 500 + }); + await commit(s1)({ + time: now + 500 + }); + }) + + after(() => { + return Promise.all([ + shutDownEngine(s1) + ]) + }) + + it('the wotb_id should be affected to new members', async () => { + let icat = await s1.dal.getWrittenIdtyByUIDForWotbId("cat"); + let itoc = await s1.dal.getWrittenIdtyByUIDForWotbId("toc"); + icat.should.have.property('wotb_id').equal(0); + itoc.should.have.property('wotb_id').equal(1); + wotb.isEnabled(0).should.equal(true); + wotb.isEnabled(1).should.equal(true); + wotb.existsLink(0, 1).should.equal(true); + wotb.existsLink(1, 0).should.equal(true); + wotb.existsLink(1, 1).should.equal(false); + wotb.existsLink(1, 2).should.equal(false); + wotb.existsLink(0, 0).should.equal(false); + wotb.existsLink(0, 2).should.equal(false); + wotb.isOutdistanced(0, FROM_1_LINK_SENTRIES, MAX_DISTANCE_1, _100_PERCENT).should.equal(__OK__); + }); + + it('a newcomer should be affected an ID + links', async () => { + /** + * cat <==> toc --> tic + */ + await tic.createIdentity(); + await toc.cert(tic); + await tic.join(); + await commit(s1)(); + let itic = await s1.dal.getWrittenIdtyByUIDForWotbId("tic"); + itic.should.have.property('wotb_id').equal(2); + wotb.isEnabled(2).should.equal(true); + wotb.existsLink(1, 2).should.equal(true); + wotb.existsLink(0, 2).should.equal(false); + wotb.isOutdistanced(0, FROM_1_LINK_SENTRIES, MAX_DISTANCE_1, _100_PERCENT).should.equal(__OK__); + wotb.isOutdistanced(1, FROM_1_LINK_SENTRIES, MAX_DISTANCE_1, _100_PERCENT).should.equal(__OK__); + // tic is outdistanced if k = 1! (cat can't reach him) + wotb.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_1, _100_PERCENT).should.equal(__OUTDISTANCED__); + // but reachable if k = 2 + wotb.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_2, _100_PERCENT).should.equal(__OK__); + }); + }); + + describe("Server 2", () => { + + let wotb:WoTBInstance + + before(async () => { + /** + * tic <==> cat <==> toc + */ + await s2.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); + wotb = s2.dal.wotb; + await cat2.createIdentity(); + await toc2.createIdentity(); + await tic2.createIdentity(); + // toc2 <==> cat2 + await toc2.cert(cat2); + await cat2.cert(toc2); + // tic2 <==> cat2 + await tic2.cert(cat2); + await cat2.cert(tic2); + await cat2.join(); + await toc2.join(); + await tic2.join(); + await commit(s2)({ + time: now + }); + // Should make MS expire for toc2 + await commit(s2)({ + time: now + 500 + }); + await commit(s2)({ + time: now + 600 + }); + await cat2.join(); // Renew for not to be kicked! + await tic2.join(); // Renew for not to be kicked! + await commit(s2)({ + time: now + 800 + }); + await commit(s2)({ + time: now + 800 + }); + // Members excluded + await commit(s2)({ + time: now + 800 + }); + }); + + after(() => { + return Promise.all([ + shutDownEngine(s2) + ]) + }) + + it('a leaver should still have links but be disabled', async () => { + wotb.isEnabled(0).should.equal(true); + wotb.isEnabled(1).should.equal(true); + wotb.isEnabled(2).should.equal(false); + // tic2 <==> cat2 + wotb.existsLink(0, 1).should.equal(true); + wotb.existsLink(1, 0).should.equal(true); + // toc2 <==> cat2 + wotb.existsLink(0, 2).should.equal(true); + wotb.existsLink(2, 0).should.equal(true); + // toc2 <==> tic2 + wotb.existsLink(1, 2).should.equal(false); + wotb.existsLink(2, 1).should.equal(false); + }); + + it('a leaver who joins back should be enabled', async () => { + await toc2.join(); + await commit(s2)(); + wotb.isEnabled(0).should.equal(true); + wotb.isEnabled(1).should.equal(true); + wotb.isEnabled(2).should.equal(true); + // tic2 <==> cat2 + wotb.existsLink(0, 1).should.equal(true); + wotb.existsLink(1, 0).should.equal(true); + // toc2 <==> cat2 + wotb.existsLink(0, 2).should.equal(true); + wotb.existsLink(2, 0).should.equal(true); + // toc2 <==> tic2 + wotb.existsLink(1, 2).should.equal(false); + wotb.existsLink(2, 1).should.equal(false); + }); + }); + + describe("Server 3", () => { + + let wotb:WoTBInstance + + before(async () => { + await s3.initWithDAL().then(BmaDependency.duniter.methods.bma).then((bmapi) => bmapi.openConnections()); + wotb = s3.dal.wotb; + await cat3.createIdentity(); + await tic3.createIdentity(); + // cat <==> tic + await tic3.cert(cat3); + await cat3.cert(tic3); + await cat3.join(); + await tic3.join(); + }); + + after(() => { + return Promise.all([ + shutDownEngine(s3) + ]) + }) + + it('two first commits: the WoT is new and OK', async () => { + await commit(s3)({ time: now }); + await commit(s3)({ + time: now + 1200 + }); + /** + * cat <==> tic + */ + wotb.isEnabled(0).should.equal(true); + wotb.isEnabled(1).should.equal(true); + // cat3 <==> tic3 + wotb.existsLink(0, 1).should.equal(true); + wotb.existsLink(1, 0).should.equal(true); + // tic3 <==> toc3 + wotb.existsLink(1, 2).should.equal(false); + wotb.existsLink(2, 1).should.equal(false); + }); + + it('third & fourth commits: toc should have joined', async () => { + await commit(s3)({ + time: now + 2400 + }); + // MedianTime is now +500 for next certs + await toc3.createIdentity(); + await toc3.join(); + await tic3.cert(toc3); + await commit(s3)({ + time: now + 4000 + }); + // MedianTime is now +1000 for next certs + /** + * cat <==> tic --> toc + */ + wotb.isEnabled(0).should.equal(true); + wotb.isEnabled(1).should.equal(true); + wotb.isEnabled(2).should.equal(true); + // cat3 <==> tic3 + wotb.existsLink(0, 1).should.equal(true); + wotb.existsLink(1, 0).should.equal(true); + // tic3 <==> toc3 + wotb.existsLink(1, 2).should.equal(true); + wotb.existsLink(2, 1).should.equal(false); + }); + + it('fifth commit: cat still here, but not its certs', async () => { + await toc3.cert(tic3); + await commit(s3)({ + time: now + 4000 + }); + /** + * cat tic <==> toc + */ + wotb.isEnabled(0).should.equal(true); // But marked as to kick: cannot issue new links + wotb.isEnabled(1).should.equal(true); + wotb.isEnabled(2).should.equal(true); + // cat3 <==> tic3 + wotb.existsLink(0, 1).should.equal(false); + wotb.existsLink(1, 0).should.equal(false); + // tic3 <==> toc3 + wotb.existsLink(1, 2).should.equal(true); + wotb.existsLink(2, 1).should.equal(true); + }); + + it('sixth commit: cat is gone with its certs', async () => { + await commit(s3)({ + time: now + 2500 + }); + /** + * tic <-- toc + */ + wotb.isEnabled(0).should.equal(false); + wotb.isEnabled(1).should.equal(true); + wotb.isEnabled(2).should.equal(true); + // cat3 <==> tic3 + wotb.existsLink(0, 1).should.equal(false); + wotb.existsLink(1, 0).should.equal(false); + // tic3 --> toc3 + wotb.existsLink(1, 2).should.equal(false); + wotb.existsLink(2, 1).should.equal(true); + }); + + it('seventh commit: toc is gone, but not its cert to tic', async () => { + await tic3.cert(cat3); + await cat3.join(); + await commit(s3)({ + time: now + 5000 + }); + /** + * cat <-- tic <-- [toc] + */ + wotb.isEnabled(0).should.equal(true); + wotb.isEnabled(1).should.equal(true); + wotb.isEnabled(2).should.equal(false); + // cat3 <==> tic3 + wotb.existsLink(0, 1).should.equal(false); + wotb.existsLink(1, 0).should.equal(true); + // tic3 --> toc3 + wotb.existsLink(1, 2).should.equal(false); + wotb.existsLink(2, 1).should.equal(true); + }); + + it('revert seventh commit: toc is back, cat is gone', async () => { + await s3.revert(); + wotb.isEnabled(0).should.equal(false); + wotb.isEnabled(1).should.equal(true); + wotb.isEnabled(2).should.equal(true); + // cat3 <==> tic3 + wotb.existsLink(0, 1).should.equal(false); + wotb.existsLink(1, 0).should.equal(false); + // tic3 --> toc3 + wotb.existsLink(1, 2).should.equal(false); + wotb.existsLink(2, 1).should.equal(true); + }); + + it('revert sixth commit: cat is back', async () => { + await s3.revert(); + wotb.isEnabled(0).should.equal(true); // But marked as to kick: cannot issue new links + wotb.isEnabled(1).should.equal(true); + wotb.isEnabled(2).should.equal(true); + // cat3 <==> tic3 + wotb.existsLink(0, 1).should.equal(false); + wotb.existsLink(1, 0).should.equal(false); + // tic3 <==> toc3 + wotb.existsLink(1, 2).should.equal(true); + wotb.existsLink(2, 1).should.equal(true); + }); + + it('revert fifth commit', async () => { + await s3.revert(); + wotb.isEnabled(0).should.equal(true); + wotb.isEnabled(1).should.equal(true); + wotb.isEnabled(2).should.equal(true); + // cat3 <==> tic3 + wotb.existsLink(0, 1).should.equal(true); + wotb.existsLink(1, 0).should.equal(true); + // tic3 <==> toc3 + wotb.existsLink(1, 2).should.equal(true); + wotb.existsLink(2, 1).should.equal(false); + }); + + it('revert third & fourth commits', async () => { + await s3.revert(); + await s3.revert(); + wotb.isEnabled(0).should.equal(true); + wotb.isEnabled(1).should.equal(true); + // cat3 <==> tic3 + wotb.existsLink(0, 1).should.equal(true); + wotb.existsLink(1, 0).should.equal(true); + // tic3 <==> toc3 + wotb.existsLink(1, 2).should.equal(false); + wotb.existsLink(2, 1).should.equal(false); + }); + + it('revert first & second commits', async () => { + await s3.revert(); + await s3.revert(); + wotb.isEnabled(0).should.equal(false); + wotb.isEnabled(1).should.equal(false); + wotb.isEnabled(2).should.equal(false); + // cat3 <==> tic3 + wotb.existsLink(0, 1).should.equal(false); + wotb.existsLink(1, 0).should.equal(false); + // tic3 <==> toc3 + wotb.existsLink(1, 2).should.equal(false); + wotb.existsLink(2, 1).should.equal(false); + }); + }); +}); diff --git a/test/integration/wotb.js b/test/integration/wotb.js deleted file mode 100644 index 029cc4b0b06a08d59695eb8c6985418bbad09bc1..0000000000000000000000000000000000000000 --- a/test/integration/wotb.js +++ /dev/null @@ -1,479 +0,0 @@ -// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 -// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -"use strict"; - -const co = require('co'); -const should = require('should'); -const _ = require('underscore'); -const duniter = require('../../index'); -const bma = require('../../app/modules/bma').BmaDependency.duniter.methods.bma; -const TestUser = require('./tools/TestUser').TestUser -const commit = require('./tools/commit'); -const shutDownEngine = require('./tools/shutDownEngine'); - -const MEMORY_MODE = true; -const commonConf = { - ipv4: '127.0.0.1', - currency: 'bb', - httpLogs: true, - forksize: 3, - sigQty: 1 -}; - -let s1, s2, s3, cat, toc, tic, cat2, toc2, tic2, cat3, toc3, tic3 - -const now = 1482000000; -const _100_PERCENT = 1.0; -const MAX_DISTANCE_1 = 1; -const MAX_DISTANCE_2 = 2; -const FROM_1_LINK_SENTRIES = 1; -const __OUTDISTANCED__ = true; -const __OK__ = false; - -describe("WOTB module", function() { - - describe("Server 1", () => { - - let wotb; - - before(function() { - - return co(function *() { - - s1 = duniter( - '/bb11', - MEMORY_MODE, - _.extend({ - port: '9337', - pair: { - pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', - sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' - }, - rootoffset: 10, - sigQty: 1, dt: 1, ud0: 120 - }, commonConf)); - - s2 = duniter( - '/bb41', - MEMORY_MODE, - _.extend({ - port: '9338', - pair: { - pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', - sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' - }, - rootoffset: 10, - sigQty: 1, dt: 1, ud0: 120, - msValidity: 400 // Memberships expire after 400 second delay - }, commonConf)); - - s3 = duniter( - '/bb11', - MEMORY_MODE, - _.extend({ - port: '9339', - pair: { - pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', - sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7' - }, - rootoffset: 10, - sigQty: 1, dt: 1, ud0: 120, - sigValidity: 1400, sigPeriod: 0 - }, commonConf)); - - cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 }); - toc = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s1 }); - tic = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s1 }); - - cat2 = new TestUser('cat2', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s2 }); - toc2 = new TestUser('toc2', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s2 }); - tic2 = new TestUser('tic2', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s2 }); - - cat3 = new TestUser('cat3', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s3 }); - toc3 = new TestUser('toc3', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s3 }); - tic3 = new TestUser('tic3', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s3 }); - - /** - * cat <==> toc - */ - yield s1.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); - wotb = s1.dal.wotb; - yield cat.createIdentity(); - yield toc.createIdentity(); - yield toc.cert(cat); - yield cat.cert(toc); - yield cat.join(); - yield toc.join(); - yield commit(s1)({ - time: now + 500 - }); - yield commit(s1)({ - time: now + 500 - }); - }); - }); - - after(() => { - return Promise.all([ - shutDownEngine(s1) - ]) - }) - - it('the wotb_id should be affected to new members', function() { - return co(function *() { - let icat = yield s1.dal.getWrittenIdtyByUIDForWotbId("cat"); - let itoc = yield s1.dal.getWrittenIdtyByUIDForWotbId("toc"); - icat.should.have.property('wotb_id').equal(0); - itoc.should.have.property('wotb_id').equal(1); - wotb.isEnabled(0).should.equal(true); - wotb.isEnabled(1).should.equal(true); - wotb.existsLink(0, 1).should.equal(true); - wotb.existsLink(1, 0).should.equal(true); - wotb.existsLink(1, 1).should.equal(false); - wotb.existsLink(1, 2).should.equal(false); - wotb.existsLink(0, 0).should.equal(false); - wotb.existsLink(0, 2).should.equal(false); - wotb.isOutdistanced(0, FROM_1_LINK_SENTRIES, MAX_DISTANCE_1, _100_PERCENT).should.equal(__OK__); - }); - }); - - it('a newcomer should be affected an ID + links', function() { - return co(function *() { - /** - * cat <==> toc --> tic - */ - yield tic.createIdentity(); - yield toc.cert(tic); - yield tic.join(); - yield commit(s1)(); - let itic = yield s1.dal.getWrittenIdtyByUIDForWotbId("tic"); - itic.should.have.property('wotb_id').equal(2); - wotb.isEnabled(2).should.equal(true); - wotb.existsLink(1, 2).should.equal(true); - wotb.existsLink(0, 2).should.equal(false); - wotb.isOutdistanced(0, FROM_1_LINK_SENTRIES, MAX_DISTANCE_1, _100_PERCENT).should.equal(__OK__); - wotb.isOutdistanced(1, FROM_1_LINK_SENTRIES, MAX_DISTANCE_1, _100_PERCENT).should.equal(__OK__); - // tic is outdistanced if k = 1! (cat can't reach him) - wotb.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_1, _100_PERCENT).should.equal(__OUTDISTANCED__); - // but reachable if k = 2 - wotb.isOutdistanced(2, FROM_1_LINK_SENTRIES, MAX_DISTANCE_2, _100_PERCENT).should.equal(__OK__); - }); - }); - }); - - describe("Server 2", () => { - - let wotb; - - before(function() { - - return co(function *() { - /** - * tic <==> cat <==> toc - */ - yield s2.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); - wotb = s2.dal.wotb; - yield cat2.createIdentity(); - yield toc2.createIdentity(); - yield tic2.createIdentity(); - // toc2 <==> cat2 - yield toc2.cert(cat2); - yield cat2.cert(toc2); - // tic2 <==> cat2 - yield tic2.cert(cat2); - yield cat2.cert(tic2); - yield cat2.join(); - yield toc2.join(); - yield tic2.join(); - yield commit(s2)({ - time: now - }); - // Should make MS expire for toc2 - yield commit(s2)({ - time: now + 500 - }); - yield commit(s2)({ - time: now + 600 - }); - yield cat2.join(); // Renew for not to be kicked! - yield tic2.join(); // Renew for not to be kicked! - yield commit(s2)({ - time: now + 800 - }); - yield commit(s2)({ - time: now + 800 - }); - // Members excluded - yield commit(s2)({ - time: now + 800 - }); - }); - }); - - after(() => { - return Promise.all([ - shutDownEngine(s2) - ]) - }) - - it('a leaver should still have links but be disabled', function() { - return co(function *() { - wotb.isEnabled(0).should.equal(true); - wotb.isEnabled(1).should.equal(true); - wotb.isEnabled(2).should.equal(false); - // tic2 <==> cat2 - wotb.existsLink(0, 1).should.equal(true); - wotb.existsLink(1, 0).should.equal(true); - // toc2 <==> cat2 - wotb.existsLink(0, 2).should.equal(true); - wotb.existsLink(2, 0).should.equal(true); - // toc2 <==> tic2 - wotb.existsLink(1, 2).should.equal(false); - wotb.existsLink(2, 1).should.equal(false); - }); - }); - - it('a leaver who joins back should be enabled', function() { - return co(function *() { - yield toc2.join(); - yield commit(s2)(); - wotb.isEnabled(0).should.equal(true); - wotb.isEnabled(1).should.equal(true); - wotb.isEnabled(2).should.equal(true); - // tic2 <==> cat2 - wotb.existsLink(0, 1).should.equal(true); - wotb.existsLink(1, 0).should.equal(true); - // toc2 <==> cat2 - wotb.existsLink(0, 2).should.equal(true); - wotb.existsLink(2, 0).should.equal(true); - // toc2 <==> tic2 - wotb.existsLink(1, 2).should.equal(false); - wotb.existsLink(2, 1).should.equal(false); - }); - }); - }); - - describe("Server 3", () => { - - let wotb; - - before(function() { - - return co(function *() { - yield s3.initWithDAL().then(bma).then((bmapi) => bmapi.openConnections()); - wotb = s3.dal.wotb; - yield cat3.createIdentity(); - yield tic3.createIdentity(); - // cat <==> tic - yield tic3.cert(cat3); - yield cat3.cert(tic3); - yield cat3.join(); - yield tic3.join(); - }); - }); - - after(() => { - return Promise.all([ - shutDownEngine(s3) - ]) - }) - - it('two first commits: the WoT is new and OK', function() { - return co(function *() { - yield commit(s3)({ time: now }); - yield commit(s3)({ - time: now + 1200 - }); - /** - * cat <==> tic - */ - wotb.isEnabled(0).should.equal(true); - wotb.isEnabled(1).should.equal(true); - // cat3 <==> tic3 - wotb.existsLink(0, 1).should.equal(true); - wotb.existsLink(1, 0).should.equal(true); - // tic3 <==> toc3 - wotb.existsLink(1, 2).should.equal(false); - wotb.existsLink(2, 1).should.equal(false); - }); - }); - - it('third & fourth commits: toc should have joined', function() { - return co(function *() { - yield commit(s3)({ - time: now + 2400 - }); - // MedianTime is now +500 for next certs - yield toc3.createIdentity(); - yield toc3.join(); - yield tic3.cert(toc3); - yield commit(s3)({ - time: now + 4000 - }); - // MedianTime is now +1000 for next certs - /** - * cat <==> tic --> toc - */ - wotb.isEnabled(0).should.equal(true); - wotb.isEnabled(1).should.equal(true); - wotb.isEnabled(2).should.equal(true); - // cat3 <==> tic3 - wotb.existsLink(0, 1).should.equal(true); - wotb.existsLink(1, 0).should.equal(true); - // tic3 <==> toc3 - wotb.existsLink(1, 2).should.equal(true); - wotb.existsLink(2, 1).should.equal(false); - }); - }); - - it('fifth commit: cat still here, but not its certs', function() { - return co(function *() { - yield toc3.cert(tic3); - yield commit(s3)({ - time: now + 4000 - }); - /** - * cat tic <==> toc - */ - wotb.isEnabled(0).should.equal(true); // But marked as to kick: cannot issue new links - wotb.isEnabled(1).should.equal(true); - wotb.isEnabled(2).should.equal(true); - // cat3 <==> tic3 - wotb.existsLink(0, 1).should.equal(false); - wotb.existsLink(1, 0).should.equal(false); - // tic3 <==> toc3 - wotb.existsLink(1, 2).should.equal(true); - wotb.existsLink(2, 1).should.equal(true); - }); - }); - - it('sixth commit: cat is gone with its certs', function() { - return co(function *() { - yield commit(s3)({ - time: now + 2500 - }); - /** - * tic <-- toc - */ - wotb.isEnabled(0).should.equal(false); - wotb.isEnabled(1).should.equal(true); - wotb.isEnabled(2).should.equal(true); - // cat3 <==> tic3 - wotb.existsLink(0, 1).should.equal(false); - wotb.existsLink(1, 0).should.equal(false); - // tic3 --> toc3 - wotb.existsLink(1, 2).should.equal(false); - wotb.existsLink(2, 1).should.equal(true); - }); - }); - - it('seventh commit: toc is gone, but not its cert to tic', function() { - return co(function *() { - yield tic3.cert(cat3); - yield cat3.join(); - yield commit(s3)({ - time: now + 5000 - }); - /** - * cat <-- tic <-- [toc] - */ - wotb.isEnabled(0).should.equal(true); - wotb.isEnabled(1).should.equal(true); - wotb.isEnabled(2).should.equal(false); - // cat3 <==> tic3 - wotb.existsLink(0, 1).should.equal(false); - wotb.existsLink(1, 0).should.equal(true); - // tic3 --> toc3 - wotb.existsLink(1, 2).should.equal(false); - wotb.existsLink(2, 1).should.equal(true); - }); - }); - - it('revert seventh commit: toc is back, cat is gone', function() { - return co(function *() { - yield s3.revert(); - wotb.isEnabled(0).should.equal(false); - wotb.isEnabled(1).should.equal(true); - wotb.isEnabled(2).should.equal(true); - // cat3 <==> tic3 - wotb.existsLink(0, 1).should.equal(false); - wotb.existsLink(1, 0).should.equal(false); - // tic3 --> toc3 - wotb.existsLink(1, 2).should.equal(false); - wotb.existsLink(2, 1).should.equal(true); - }); - }); - - it('revert sixth commit: cat is back', function() { - return co(function *() { - yield s3.revert(); - wotb.isEnabled(0).should.equal(true); // But marked as to kick: cannot issue new links - wotb.isEnabled(1).should.equal(true); - wotb.isEnabled(2).should.equal(true); - // cat3 <==> tic3 - wotb.existsLink(0, 1).should.equal(false); - wotb.existsLink(1, 0).should.equal(false); - // tic3 <==> toc3 - wotb.existsLink(1, 2).should.equal(true); - wotb.existsLink(2, 1).should.equal(true); - }); - }); - - it('revert fifth commit', function() { - return co(function *() { - yield s3.revert(); - wotb.isEnabled(0).should.equal(true); - wotb.isEnabled(1).should.equal(true); - wotb.isEnabled(2).should.equal(true); - // cat3 <==> tic3 - wotb.existsLink(0, 1).should.equal(true); - wotb.existsLink(1, 0).should.equal(true); - // tic3 <==> toc3 - wotb.existsLink(1, 2).should.equal(true); - wotb.existsLink(2, 1).should.equal(false); - }); - }); - - it('revert third & fourth commits', function() { - return co(function *() { - yield s3.revert(); - yield s3.revert(); - wotb.isEnabled(0).should.equal(true); - wotb.isEnabled(1).should.equal(true); - // cat3 <==> tic3 - wotb.existsLink(0, 1).should.equal(true); - wotb.existsLink(1, 0).should.equal(true); - // tic3 <==> toc3 - wotb.existsLink(1, 2).should.equal(false); - wotb.existsLink(2, 1).should.equal(false); - }); - }); - - it('revert first & second commits', function() { - return co(function *() { - yield s3.revert(); - yield s3.revert(); - wotb.isEnabled(0).should.equal(false); - wotb.isEnabled(1).should.equal(false); - wotb.isEnabled(2).should.equal(false); - // cat3 <==> tic3 - wotb.existsLink(0, 1).should.equal(false); - wotb.existsLink(1, 0).should.equal(false); - // tic3 <==> toc3 - wotb.existsLink(1, 2).should.equal(false); - wotb.existsLink(2, 1).should.equal(false); - }); - }); - }); -}); diff --git a/test/integration/ws2p_connection.ts b/test/integration/ws2p_connection.ts index f252d3407b46bd49b45b77e0b8fe36af8ebe9cd4..c62159d746f86a5c66416c7ea817f0c344f277fb 100644 --- a/test/integration/ws2p_connection.ts +++ b/test/integration/ws2p_connection.ts @@ -19,10 +19,12 @@ import { WS2PRemoteAuth } from "../../app/modules/ws2p/lib/WS2PConnection" import {Key, verify} from "../../app/lib/common-libs/crypto/keyring" -import {assertThrows, getNewTestingPort} from "./tools/toolbox" +import {getNewTestingPort} from "./tools/toolbox" import {WS2PMessageHandler} from "../../app/modules/ws2p/lib/impl/WS2PMessageHandler" import {WS2PResponse} from "../../app/modules/ws2p/lib/impl/WS2PResponse" import {WS2PConstants} from "../../app/modules/ws2p/lib/constants" +import {assertThrows} from "../unit-tools" + const assert = require('assert'); const WebSocketServer = require('ws').Server const logger = require('../../app/lib/logger').NewLogger('ws2p') diff --git a/test/unit-tools.ts b/test/unit-tools.ts index b0f100b204906d1ac1d5f668e718b7176ae2e78d..3c85da7e52f1106f53c323128b1c7636e0eb3ce1 100644 --- a/test/unit-tools.ts +++ b/test/unit-tools.ts @@ -11,6 +11,8 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. +import * as assert from 'assert' + export async function shouldThrow(promise:Promise<any>) { let error = false try { @@ -21,3 +23,40 @@ export async function shouldThrow(promise:Promise<any>) { promise.should.be.rejected() error.should.equal(true) } + +export async function shouldNotFail<T>(promise:Promise<T>) { + try { + await promise + } catch(e) { + let err = e; + if (typeof e === 'string') { + err = JSON.parse((e as any).message) + } + should.not.exist(err); + } +} + +export const shouldFail = async (promise:Promise<any>, message:string|null = null) => { + try { + await promise; + throw '{ "message": "Should have thrown an error" }' + } catch(e) { + let err = e + if (typeof e === "string") { + err = JSON.parse(e) + } + err.should.have.property('message').equal(message); + } +} + +export const assertThrows = async (promise:Promise<any>, message:string|null = null) => { + try { + await promise; + throw "Should have thrown" + } catch(e) { + if (e === "Should have thrown") { + throw e + } + assert.equal(e, message) + } +}