From a091ae1ab7cad2fcf02ea8b02d59656ea483c42d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Moreau?= <cem.moreau@gmail.com>
Date: Tue, 8 May 2018 22:29:19 +0200
Subject: [PATCH] [enh] Refactoring: remove `co` library

---
 .eslintrc                                     |  11 +-
 app/lib/common/Tristamp.ts                    |  13 +
 app/modules/bma/lib/bma.ts                    |  23 +-
 bin/duniter                                   |   7 +-
 package.json                                  |   1 -
 release/scripts/create-release.js             |  39 +-
 release/scripts/upload-release.js             |  59 ++--
 test/eslint-test.ts                           |   1 -
 test/fast/modules/bma/bma-ddos-test.ts        |   1 -
 test/fast/modules/bma/bma-limiter-test.ts     |   1 -
 test/fast/prover/prover-pow-3-prover.ts       |  43 ++-
 test/integration/documents-currency.ts        | 120 +++----
 .../proof-of-work/continuous-proof.ts         |   2 +-
 test/integration/sandbox/server-sandbox.ts    | 333 +++++++++---------
 test/integration/scenarios/hello-plugin.js    |   6 +-
 yarn.lock                                     |   2 +-
 16 files changed, 325 insertions(+), 337 deletions(-)

diff --git a/.eslintrc b/.eslintrc
index 1fe67b099..809451a60 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,11 +1,14 @@
 {
+  "parserOptions": {
+    "ecmaVersion": 8
+  },
   "plugins": [
     "mocha"
   ],
-//  "ecmaFeatures": {
-//    "arrowFunctions": true,
-//    "generators": true
-//  },
+  "ecmaFeatures": {
+    "arrowFunctions": true,
+    "generators": true
+  },
   "rules": {
 
     "curly": 0,
diff --git a/app/lib/common/Tristamp.ts b/app/lib/common/Tristamp.ts
index 4ea9d8545..6c3232a66 100644
--- a/app/lib/common/Tristamp.ts
+++ b/app/lib/common/Tristamp.ts
@@ -1,3 +1,16 @@
+// 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.
+
 export interface Tristamp {
   number: number
   hash: string
diff --git a/app/modules/bma/lib/bma.ts b/app/modules/bma/lib/bma.ts
index d821c2e2b..ee53a3726 100644
--- a/app/modules/bma/lib/bma.ts
+++ b/app/modules/bma/lib/bma.ts
@@ -25,7 +25,6 @@ import {PeerDTO} from "../../../lib/dto/PeerDTO"
 import {BlockDTO} from "../../../lib/dto/BlockDTO"
 import {OtherConstants} from "../../../lib/other_constants"
 
-const co = require('co');
 const es = require('event-stream');
 const WebSocketServer = require('ws').Server;
 
@@ -110,7 +109,7 @@ export const bma = function(server:Server, interfaces:NetworkInterface[]|null, h
 
   }, (httpServer:any) => {
 
-    let currentBlock = {};
+    let currentBlock:any = {};
     let wssBlock = new WebSocketServer({
       server: httpServer,
       path: '/ws/block'
@@ -129,18 +128,16 @@ export const bma = function(server:Server, interfaces:NetworkInterface[]|null, h
       logger && logger.error(error);
     });
 
-    wssBlock.on('connection', function connection(ws:any) {
-      co(function *() {
-        try {
-          currentBlock = yield server.dal.getCurrentBlockOrNull();
-          if (currentBlock) {
-            const blockDTO:BlockDTO = BlockDTO.fromJSONObject(currentBlock)
-            ws.send(JSON.stringify(block2HttpBlock(blockDTO)))
-          }
-        } catch (e) {
-          logger.error(e);
+    wssBlock.on('connection', async function connection(ws:any) {
+      try {
+        currentBlock = await server.dal.getCurrentBlockOrNull();
+        if (currentBlock) {
+          const blockDTO:BlockDTO = BlockDTO.fromJSONObject(currentBlock)
+          ws.send(JSON.stringify(block2HttpBlock(blockDTO)))
         }
-      });
+      } catch (e) {
+        logger.error(e);
+      }
     });
 
     wssHeads.on('connection', async (ws:any) => {
diff --git a/bin/duniter b/bin/duniter
index 806c1602e..d91cfe530 100755
--- a/bin/duniter
+++ b/bin/duniter
@@ -1,7 +1,6 @@
 #!/usr/bin/env node
 "use strict";
 
-const co = require('co');
 const logger = require("../app/lib/logger").NewLogger();
 
 // Specific errors handling
@@ -13,12 +12,12 @@ process.on('uncaughtException', (err) => {
   }
 });
 
-return co(function* () {
+(async () => {
 
   try {
     const duniter = require('../index');
     const stack = duniter.statics.autoStack();
-    yield stack.executeStack(process.argv);
+    await stack.executeStack(process.argv);
     // Everything went well, close Duniter quietly.
     process.exit();
   } catch (e) {
@@ -29,4 +28,4 @@ return co(function* () {
     // If we did not succeed to close before, force close with error.
     process.exit(100);
   }
-});
+})()
diff --git a/package.json b/package.json
index bf01b2fba..f2c94cf42 100644
--- a/package.json
+++ b/package.json
@@ -62,7 +62,6 @@
     "bindings": "1.2.1",
     "body-parser": "1.17.1",
     "bs58": "^4.0.1",
-    "co": "4.6.0",
     "colors": "1.1.2",
     "commander": "2.9.0",
     "cors": "2.8.2",
diff --git a/release/scripts/create-release.js b/release/scripts/create-release.js
index badc4b1df..a64b17f98 100644
--- a/release/scripts/create-release.js
+++ b/release/scripts/create-release.js
@@ -13,9 +13,6 @@
 
 "use strict";
 
-const co = require('co');
-const fs = require('fs');
-const path = require('path');
 const rp = require('request-promise');
 
 const GITHUB_TOKEN = process.argv[2]
@@ -23,12 +20,12 @@ const tagName      = process.argv[3]
 const command      = process.argv[4]
 const value        = process.argv[5]
 
-co(function*() {
+(async () => {
   try {
     // Get release URL
     let release
     try {
-      release = yield github('/repos/duniter/duniter/releases/tags/' + tagName)
+      release = await github('/repos/duniter/duniter/releases/tags/' + tagName)
     } catch (e) {
       if (!(e && e.statusCode == 404)) {
         throw e
@@ -38,7 +35,7 @@ co(function*() {
     // Creation
     if (command === "create") {
       if (!release) {
-        release = yield github('/repos/duniter/duniter/releases', 'POST', {
+        release = await github('/repos/duniter/duniter/releases', 'POST', {
           tag_name: tagName,
           draft: false,
           prerelease: true
@@ -59,7 +56,7 @@ co(function*() {
       if (!release) {
         console.error('Release ' + tagName + ' does not exist.')
       } else {
-        release = yield github('/repos/duniter/duniter/releases/' + release.id, 'PATCH', {
+        release = await github('/repos/duniter/duniter/releases/' + release.id, 'PATCH', {
           tag_name: tagName,
           draft: false,
           prerelease: isPreRelease
@@ -77,21 +74,19 @@ co(function*() {
     console.error(e);
   }
   process.exit(0);
-});
+})()
 
-function github(url, method = 'GET', body = undefined) {
-  return co(function*() {
-    yield new Promise((resolve) => setTimeout(resolve, 1));
-    return yield rp({
-      uri: 'https://api.github.com' + url,
-      method,
-      body,
-      json: true,
-      headers: {
-        'User-Agent': 'Request-Promise',
-        'Authorization': 'token ' + GITHUB_TOKEN,
-        'Accept': 'application/vnd.github.v3+json'
-      }
-    });
+async function github(url, method = 'GET', body = undefined) {
+  await new Promise((resolve) => setTimeout(resolve, 1));
+  return await rp({
+    uri: 'https://api.github.com' + url,
+    method,
+    body,
+    json: true,
+    headers: {
+      'User-Agent': 'Request-Promise',
+      'Authorization': 'token ' + GITHUB_TOKEN,
+      'Accept': 'application/vnd.github.v3+json'
+    }
   });
 }
diff --git a/release/scripts/upload-release.js b/release/scripts/upload-release.js
index 3d64eafab..a62e37b1c 100644
--- a/release/scripts/upload-release.js
+++ b/release/scripts/upload-release.js
@@ -13,7 +13,6 @@
 
 "use strict";
 
-const co = require('co');
 const fs = require('fs');
 const path = require('path');
 const rp = require('request-promise');
@@ -23,51 +22,47 @@ const tagName      = process.argv[3]
 const filePath     = process.argv[4]
 const fileType     = getFileType(filePath)
 
-co(function*() {
+(async () => {
   try {
     // Get release URL
-    const release = yield github('/repos/duniter/duniter/releases/tags/' + tagName); // May be a draft
+    const release = await github('/repos/duniter/duniter/releases/tags/' + tagName); // May be a draft
     console.log('Release: ' + release.tag_name);
     const filename = path.basename(filePath)
     console.log('Uploading asset %s...', filename);
     const upload_url = release.upload_url.replace('{?name,label}', '?' + ['name=' + filename].join('&'));
-    yield githubUpload(upload_url, filePath, fileType)
+    await githubUpload(upload_url, filePath, fileType)
   } catch (e) {
     console.error(e);
   }
   process.exit(0);
-});
+})()
 
-function github(url) {
-  return co(function*() {
-    yield new Promise((resolve) => setTimeout(resolve, 1));
-    return yield rp({
-      uri: 'https://api.github.com' + url,
-      json: true,
-      headers: {
-        'User-Agent': 'Request-Promise',
-        'Authorization': 'token ' + GITHUB_TOKEN,
-        'Accept': 'application/vnd.github.v3+json'
-      }
-    });
+async function github(url) {
+  await new Promise((resolve) => setTimeout(resolve, 1));
+  return await rp({
+    uri: 'https://api.github.com' + url,
+    json: true,
+    headers: {
+      'User-Agent': 'Request-Promise',
+      'Authorization': 'token ' + GITHUB_TOKEN,
+      'Accept': 'application/vnd.github.v3+json'
+    }
   });
 }
 
-function githubUpload(upload_url, filePath, type) {
-  return co(function*() {
-    const stats = fs.statSync(filePath);
-    return yield rp({
-      method: 'POST',
-      body: fs.createReadStream(filePath),
-      uri: upload_url,
-      headers: {
-        'User-Agent': 'Request-Promise',
-        'Authorization': 'token ' + GITHUB_TOKEN,
-        'Content-type': type,
-        'Accept': 'application/json',
-        'Content-Length': stats.size
-      }
-    });
+async function githubUpload(upload_url, filePath, type) {
+  const stats = fs.statSync(filePath);
+  return await rp({
+    method: 'POST',
+    body: fs.createReadStream(filePath),
+    uri: upload_url,
+    headers: {
+      'User-Agent': 'Request-Promise',
+      'Authorization': 'token ' + GITHUB_TOKEN,
+      'Content-type': type,
+      'Accept': 'application/json',
+      'Content-Length': stats.size
+    }
   });
 }
 
diff --git a/test/eslint-test.ts b/test/eslint-test.ts
index d0ae93ec6..ae87015a9 100644
--- a/test/eslint-test.ts
+++ b/test/eslint-test.ts
@@ -20,7 +20,6 @@ describe('Linting', () => {
   // matches a glob pattern
     const paths = [
       'app',
-      'bin/duniter',
       'test'
     ];
 
diff --git a/test/fast/modules/bma/bma-ddos-test.ts b/test/fast/modules/bma/bma-ddos-test.ts
index 7c1ab98a1..0a3b551f3 100644
--- a/test/fast/modules/bma/bma-ddos-test.ts
+++ b/test/fast/modules/bma/bma-ddos-test.ts
@@ -13,7 +13,6 @@
 
 "use strict";
 // const should = require('should');
-// const co = require('co');
 // const limiter = require('../../app/lib/system/limiter');
 // const toolbox = require('../integration/tools/toolbox');
 // const TestUser = require('../integration/tools/TestUser').TestUser
diff --git a/test/fast/modules/bma/bma-limiter-test.ts b/test/fast/modules/bma/bma-limiter-test.ts
index f63ae5c4a..cdc113d90 100644
--- a/test/fast/modules/bma/bma-limiter-test.ts
+++ b/test/fast/modules/bma/bma-limiter-test.ts
@@ -13,7 +13,6 @@
 
 "use strict";
 // const should = require('should');
-// const co = require('co');
 // const limiter = require('../lib/limiter');
 // const toolbox = require('../integration/tools/toolbox');
 // const TestUser = require('../integration/tools/TestUser').TestUser
diff --git a/test/fast/prover/prover-pow-3-prover.ts b/test/fast/prover/prover-pow-3-prover.ts
index 9246f8efd..d2da6029e 100644
--- a/test/fast/prover/prover-pow-3-prover.ts
+++ b/test/fast/prover/prover-pow-3-prover.ts
@@ -11,20 +11,17 @@
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU Affero General Public License for more details.
 
-"use strict";
+import {BlockProver} from "../../../app/modules/prover/lib/blockProver"
 
-const co = require('co')
 const should = require('should')
-const moment = require('moment')
 const winston = require('winston')
-const BlockProver = require('../../../app/modules/prover/lib/blockProver').BlockProver
 
 // Mute logger
 winston.remove(winston.transports.Console)
 
 describe('PoW block prover', () => {
 
-  let prover
+  let prover:BlockProver
 
   before(() => {
     prover = new BlockProver({
@@ -39,23 +36,23 @@ describe('PoW block prover', () => {
       },
       push: () => {},
       logger: winston
-    })
+    } as any)
   })
 
-  it('should be configurable', () => co(function*(){
-    const res1 = yield prover.changeCPU(0.2)
+  it('should be configurable', async () => {
+    const res1 = await prover.changeCPU(0.2)
     res1.should.deepEqual({ cpu: 0.2 })
-    const res2 = yield prover.changePoWPrefix('34')
+    const res2 = await prover.changePoWPrefix('34')
     res2.should.deepEqual({ prefix: '34' })
-  }));
+  })
 
-  it('should be able to make a proof', () => co(function*(){
+  it('should be able to make a proof', async () => {
     const block = {
       number: 35,
       issuer: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'
     }
     const forcedTime = 1;
-    const proof = yield prover.prove(block, 24, forcedTime)
+    const proof = await prover.prove(block, 24, forcedTime)
     proof.should.containEql({
       version: 10,
       nonce: 340000000000034,
@@ -79,33 +76,33 @@ describe('PoW block prover', () => {
       certifications: [],
       transactions: []
     });
-  }));
+  })
 
-  it('should be able to use a prefix maxed at 899', () => co(function*(){
+  it('should be able to use a prefix maxed at 899', async () => {
     const block = {
       number: 1,
       issuer: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'
     }
-    const params = yield prover.changePoWPrefix('899')
+    const params = await prover.changePoWPrefix('899')
     params.should.deepEqual({ prefix: '899' })
     const forcedTime = 1;
-    const proof = yield prover.prove(block, 1, forcedTime)
+    const proof = await prover.prove(block, 1, forcedTime)
     proof.nonce.should.equal(8990000000000001)
     String(proof.nonce).should.have.length(16)
-  }));
+  })
 
-  it('should be able to stop a proof', () => co(function*(){
+  it('should be able to stop a proof', async () => {
     const block = {
       number: 35,
       issuer: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd'
     }
     const forcedTime = 1;
     const proofPromise = prover.prove(block, 70, forcedTime)
-    yield new Promise((res) => setTimeout(res, 20))
-    yield prover.cancel()
+    await new Promise((res) => setTimeout(res, 20))
+    await prover.cancel()
     let err = ''
     try {
-      yield proofPromise
+      await proofPromise
     } catch (e) {
       err = e
     } finally {
@@ -114,5 +111,5 @@ describe('PoW block prover', () => {
       }
       err.should.equal('Proof-of-work computation canceled because block received')
     }
-  }));
-});
+  })
+})
diff --git a/test/integration/documents-currency.ts b/test/integration/documents-currency.ts
index eb135a099..1aeb9edc3 100644
--- a/test/integration/documents-currency.ts
+++ b/test/integration/documents-currency.ts
@@ -12,14 +12,10 @@
 // GNU Affero General Public License for more details.
 
 
-import { NewTestingServer, TestingServer } from './tools/toolbox';
-import { unlock } from '../../app/lib/common-libs/txunlock';
-import { ConfDTO, CurrencyConfDTO } from '../../app/lib/dto/ConfDTO';
-import { Server } from '../../server';
+import {NewTestingServer} from './tools/toolbox';
+import {TestUser} from "./tools/TestUser"
 
-const co        = require('co');
 const should    = require('should');
-const TestUser  = require('./tools/TestUser').TestUser
 
 let s1:any, s2:any, cat1:any, tac1:any, toc2:any, tic2:any;
 
@@ -27,7 +23,7 @@ describe("Document pool currency", function() {
 
   const now = 1500000000
 
-  before(() => co(function*() {
+  before(async () => {
 
     s1 = NewTestingServer({
       currency: 'currency_one',
@@ -52,19 +48,19 @@ describe("Document pool currency", function() {
     toc2 = new TestUser('toc', { pub: 'DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo', sec: '64EYRvdPpTfLGGmaX5nijLXRqWXaVz8r1Z1GtaahXwVSJGQRn7tqkxLb288zwSYzELMEG5ZhXSBYSxsTsz1m9y8F'}, { server: s2 });
     tic2 = new TestUser('tic', { pub: 'DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV', sec: '468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7'}, { server: s2 });
 
-    yield s1.prepareForNetwork();
-    yield s2.prepareForNetwork();
+    await s1.prepareForNetwork();
+    await s2.prepareForNetwork();
 
     // Publishing identities
-    yield cat1.createIdentity();
-    yield tac1.createIdentity();
-    yield cat1.join();
-    yield tac1.join();
-    yield toc2.createIdentity();
-    yield tic2.createIdentity();
-    yield toc2.join();
-    yield tic2.join();
-  }));
+    await cat1.createIdentity();
+    await tac1.createIdentity();
+    await cat1.join();
+    await tac1.join();
+    await toc2.createIdentity();
+    await tic2.createIdentity();
+    await toc2.join();
+    await tic2.join();
+  })
 
   after(() => {
     return Promise.all([
@@ -73,95 +69,95 @@ describe("Document pool currency", function() {
     ])
   })
 
-  it('Identity with wrong currency should be rejected', () => co(function*() {
-    const idtyCat1 = yield s1.lookup2identity(cat1.pub);
+  it('Identity with wrong currency should be rejected', async () => {
+    const idtyCat1 = await s1.lookup2identity(cat1.pub);
     idtyCat1.getRawSigned()
     try {
-      yield s2.postIdentity(idtyCat1);
+      await s2.postIdentity(idtyCat1);
       throw "Identity should not have been accepted, since it has an unknown currency name";
     } catch (e) {
       should.exist(e.error);
       e.should.be.an.Object();
       e.error.message.should.match(/Signature does not match/);
     }
-  }));
+  })
 
-  it('Identity absorption with wrong currency should be rejected', () => co(function*() {
+  it('Identity absorption with wrong currency should be rejected', async () => {
     try {
-      const cert = yield toc2.makeCert(cat1, s1);
-      yield s2.postCert(cert);
+      const cert = await toc2.makeCert(cat1, s1);
+      await s2.postCert(cert);
       throw "Certification should not have been accepted, since it has an unknown currency name";
     } catch (e) {
       should.exist(e.error);
       e.should.be.an.Object();
       e.error.message.should.match(/Signature does not match/);
     }
-  }));
+  })
 
-  it('Certification with wrong currency should be rejected', () => co(function*() {
+  it('Certification with wrong currency should be rejected', async () => {
     try {
-      const cert = yield toc2.makeCert(tic2, null, {
+      const cert = await toc2.makeCert(tic2, null, {
         currency: "wrong_currency"
       });
-      yield s2.postCert(cert);
+      await s2.postCert(cert);
       throw "Certification should not have been accepted, since it has an unknown currency name";
     } catch (e) {
       should.exist(e.error);
       e.should.be.an.Object();
       e.error.message.should.match(/Wrong signature for certification/);
     }
-  }));
+  })
 
-  it('Membership with wrong currency should be rejected', () => co(function*() {
+  it('Membership with wrong currency should be rejected', async () => {
     try {
-      const join = yield toc2.makeMembership('IN', null, {
+      const join = await toc2.makeMembership('IN', null, {
         currency: "wrong_currency"
       });
-      yield s2.postMembership(join);
+      await s2.postMembership(join);
       throw "Membership should not have been accepted, since it has an unknown currency name";
     } catch (e) {
       should.exist(e.error);
       e.should.be.an.Object();
       e.error.message.should.match(/wrong signature for membership/);
     }
-  }));
+  })
 
-  it('Revocation with wrong currency should be rejected', () => co(function*() {
+  it('Revocation with wrong currency should be rejected', async () => {
     try {
-      const revocation = yield toc2.makeRevocation(null, {
+      const revocation = await toc2.makeRevocation(null, {
         currency: "wrong_currency"
       });
-      yield s2.postRevocation(revocation);
+      await s2.postRevocation(revocation);
       throw "Revocation should not have been accepted, since it has an unknown currency name";
     } catch (e) {
       should.exist(e.error);
       e.should.be.an.Object();
       e.error.message.should.match(/Wrong signature for revocation/);
     }
-  }));
+  })
 
-  it('Block with wrong currency should be rejected', () => co(function*() {
-    yield toc2.cert(tic2);
-    yield tic2.cert(toc2);
-    yield s2.commit();
-    const b2 = yield s2.makeNext({ currency: "wrong_currency" });
+  it('Block with wrong currency should be rejected', async () => {
+    await toc2.cert(tic2);
+    await tic2.cert(toc2);
+    await s2.commit();
+    const b2 = await s2.makeNext({ currency: "wrong_currency" });
     try {
-      yield s2.postBlock(b2);
+      await s2.postBlock(b2);
       throw "Currency should have been rejected";
     } catch (e) {
       should.exist(e.error);
       e.should.be.an.Object();
       e.error.message.should.match(/Wrong currency/);
     }
-  }));
+  })
 
-  it('Transaction with wrong currency should be rejected', () => co(function*() {
+  it('Transaction with wrong currency should be rejected', async () => {
     try {
-      yield cat1.cert(tac1);
-      yield tac1.cert(cat1);
-      yield s1.commit({ time: now });
-      yield s1.commit({ time: now });
-      const current = yield s1.get('/blockchain/current');
+      await cat1.cert(tac1);
+      await tac1.cert(cat1);
+      await s1.commit({ time: now });
+      await s1.commit({ time: now });
+      const current = await s1.get('/blockchain/current');
       const tx = cat1.makeTX(
         [{
           src: "1500:0:D:DKpQPUL4ckzXYdnDRvCRKAm1gNvSdmAXnTrJZ7LvM5Qo:1",
@@ -176,18 +172,18 @@ describe("Document pool currency", function() {
           currency: "wrong_currency",
           blockstamp: [current.number, current.hash].join('-')
         });
-      yield s1.postRawTX(tx);
+      await s1.postRawTX(tx);
       throw "Transaction should not have been accepted, since it has an unknown currency name";
     } catch (e) {
       should.exist(e.error);
       e.should.be.an.Object();
       e.error.message.should.match(/Signature from a transaction must match/);
     }
-  }));
+  })
 
-  it('Transaction with wrong XHX should be rejected', () => co(function*() {
+  it('Transaction with wrong XHX should be rejected', async () => {
     try {
-      const current = yield s1.get('/blockchain/current');
+      const current = await s1.get('/blockchain/current');
       const tx = cat1.makeTX(
         [{
           src: "1500:1:D:HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd:1",
@@ -201,27 +197,27 @@ describe("Document pool currency", function() {
         {
           blockstamp: [current.number, current.hash].join('-')
         });
-      yield s1.postRawTX(tx);
+      await s1.postRawTX(tx);
       throw "Transaction should not have been accepted, since it has wrong output format";
     } catch (e) {
       should.exist(e.error);
       e.should.be.an.Object();
       e.error.message.should.match(/Wrong output format/);
     }
-  }));
+  })
 
-  it('Peer with wrong currency should be rejected', () => co(function*() {
+  it('Peer with wrong currency should be rejected', async () => {
     try {
-      const peer = yield toc2.makePeer(['BASIC_MERKLED_API localhost 10901'], {
+      const peer = await toc2.makePeer(['BASIC_MERKLED_API localhost 10901'], {
         version: 10,
         currency: "wrong_currency"
       });
-      yield s2.postPeer(peer);
+      await s2.postPeer(peer);
       throw "Peer should not have been accepted, since it has an unknown currency name";
     } catch (e) {
       should.exist(e.error);
       e.should.be.an.Object();
       e.error.message.should.match(/Signature from a peer must match/);
     }
-  }));
-});
+  })
+})
diff --git a/test/integration/proof-of-work/continuous-proof.ts b/test/integration/proof-of-work/continuous-proof.ts
index 539384131..ce0c31662 100644
--- a/test/integration/proof-of-work/continuous-proof.ts
+++ b/test/integration/proof-of-work/continuous-proof.ts
@@ -99,7 +99,7 @@ describe("Continous proof-of-work", function() {
     await s1.permaProver.blockchainChanged();
     await new Promise((resolve) => setTimeout(resolve, 100));
     // * 1 loop for waiting for b#4 but being interrupted
-    s1.permaProver.should.have.property('loops').greaterThanOrEqual(5);
+    s1.permaProver.should.have.property('loops').greaterThanOrEqual(4);
     await s1.stopBlockComputation();
 
     // If we wait a bit, the loop should be ended
diff --git a/test/integration/sandbox/server-sandbox.ts b/test/integration/sandbox/server-sandbox.ts
index 661098359..1bef58893 100644
--- a/test/integration/sandbox/server-sandbox.ts
+++ b/test/integration/sandbox/server-sandbox.ts
@@ -15,7 +15,6 @@ import {CommonConstants} from "../../../app/lib/common-libs/constants"
 import {NewTestingServer, TestingServer} from "../tools/toolbox"
 import {TestUser} from "../tools/TestUser"
 
-const co        = require('co');
 const should    = require('should');
 const constants = require('../../../app/lib/constants');
 
@@ -24,8 +23,8 @@ const now = 1482300000;
 let s1:TestingServer, s2:TestingServer, s3:TestingServer, i1:TestUser, i2:TestUser, i3:TestUser, i4:TestUser, i5:TestUser, i6:TestUser, i7:TestUser, i7onS2:TestUser, i8:TestUser, i9:TestUser, i10:TestUser, i11:TestUser, i12:TestUser, i13:TestUser, i14:TestUser
 
 describe("Sandboxes", function() {
-
-  before(() => co(function*() {
+  
+  before(async () => {
 
     s1 = NewTestingServer({
       idtyWindow: 10,
@@ -71,15 +70,15 @@ describe("Sandboxes", function() {
 // i15 = new TestUser('i15', { pub: '8cHWEmVrdT249w8vJdiBms9mbu6CguQgXx2gRVE8gfnT', sec: '5Fy9GXiLMyhvRLCpoFf35XXNj24WXX29wM6xeCQiy5Uk7ggNhRcZjjp8GcpjRyE94oNR2jRNK4eAGiYUFnvbEnGB' }, { server: s1 });
 // i16 = new TestUser('i16', { pub: 'vi8hUTxss825cFCQE4SzmqBaAwLS236NmtrTQZBAAhG',  sec: '5dVvAdWKcndQSaR9pzjEriRhGkCjef74HzecqKnydBVHdxXDewpAu3mcSU72PRKcCkTYTJPpgWmwuCyZubDKmoy4' }, { server: s1 });
 
-    yield s1.initDalBmaConnections();
-    yield s2.initDalBmaConnections();
-    yield s3.initDalBmaConnections();
+    await s1.initDalBmaConnections();
+    await s2.initDalBmaConnections();
+    await s3.initDalBmaConnections();
     s1.dal.idtyDAL.setSandboxSize(3);
     s1.dal.msDAL.setSandboxSize(2);
     s1.dal.txsDAL.setSandboxSize(2);
     s2.dal.idtyDAL.setSandboxSize(10);
     s3.dal.idtyDAL.setSandboxSize(3);
-  }));
+  })
 
   after(() => {
     return Promise.all([
@@ -92,108 +91,108 @@ describe("Sandboxes", function() {
   describe('Identities', () => {
 
 
-    it('should i1, i2, i3', () => co(function *() {
-      (yield s1.dal.idtyDAL.getSandboxRoom()).should.equal(3);
-      yield i1.createIdentity();
-      yield i2.createIdentity();
-      yield i3.createIdentity();
-      (yield s1.dal.idtyDAL.getSandboxRoom()).should.equal(0);
-    }));
-
-    it('should reject i4', () => shouldThrow(co(function *() {
-      (yield s1.dal.idtyDAL.getSandboxRoom()).should.equal(0);
-      yield i4.createIdentity();
-    })));
-
-    it('should create i4 by i1->i4', () => co(function *() {
-      yield i4.createIdentity(null, s2);
-      yield i1.cert(i4, s2);
-    }));
-
-    it('should accept i1 (already here) by i4->i1', () => co(function *() {
-      yield i4.cert(i1);
-    }));
-
-    it('should commit & make room for sandbox, and commit again', () => co(function *() {
-      yield i1.join();
-      yield i4.join();
-      (yield s1.dal.idtyDAL.getSandboxRoom()).should.equal(0);
-      yield s1.commit({ time: now });
-      (yield s1.dal.idtyDAL.getSandboxRoom()).should.equal(3); // i2, i3 were removed for too old identities (based on virtual root block)
-      yield i2.createIdentity();
-      yield i3.createIdentity();
-      (yield s1.dal.idtyDAL.getSandboxRoom()).should.equal(1);
-      yield s1.commit({ time: now });
-      yield s2.syncFrom(s1._server, 0, 1);
-      yield s3.syncFrom(s1._server, 0, 1);
-    }));
-
-    it('should create i5(1)', () => co(function *() {
-      yield i5.createIdentity();
-      (yield s1.dal.idtyDAL.getSandboxRoom()).should.equal(0);
-    }));
+    it('should i1, i2, i3', async () => {
+      (await s1.dal.idtyDAL.getSandboxRoom()).should.equal(3);
+      await i1.createIdentity();
+      await i2.createIdentity();
+      await i3.createIdentity();
+      (await s1.dal.idtyDAL.getSandboxRoom()).should.equal(0);
+    })
+
+    it('should reject i4', () => shouldThrow((async () => {
+      (await s1.dal.idtyDAL.getSandboxRoom()).should.equal(0);
+      await i4.createIdentity();
+    })()))
+
+    it('should create i4 by i1->i4', async () => {
+      await i4.createIdentity(null, s2);
+      await i1.cert(i4, s2);
+    })
+
+    it('should accept i1 (already here) by i4->i1', async () => {
+      await i4.cert(i1);
+    })
+
+    it('should commit & make room for sandbox, and commit again', async () => {
+      await i1.join();
+      await i4.join();
+      (await s1.dal.idtyDAL.getSandboxRoom()).should.equal(0);
+      await s1.commit({ time: now });
+      (await s1.dal.idtyDAL.getSandboxRoom()).should.equal(3); // i2, i3 were removed for too old identities (based on virtual root block)
+      await i2.createIdentity();
+      await i3.createIdentity();
+      (await s1.dal.idtyDAL.getSandboxRoom()).should.equal(1);
+      await s1.commit({ time: now });
+      await s2.syncFrom(s1._server, 0, 1);
+      await s3.syncFrom(s1._server, 0, 1);
+    })
+
+    it('should create i5(1)', async () => {
+      await i5.createIdentity();
+      (await s1.dal.idtyDAL.getSandboxRoom()).should.equal(0);
+    })
 
     it('should reject i7(1)', () => shouldThrow(i7.createIdentity(true)));
 
-    it('should reject i7(1) by revocation', () => shouldThrow(co(function *() {
-      yield i7onS2.createIdentity(true);
-      const idty = yield i7onS2.lookup(i7onS2.pub);
-      yield i7.revoke(idty);
-    })));
-
-    it('should reject i1 -> i7 by revocation', () => shouldThrow(co(function *() {
-      yield i1.cert(i7, s2);
-    })));
-
-    it('should accept i7(1), i8(1), i9(1) by i1->i7(1), i1->i8(1), i1->i9(1)', () => co(function *() {
-      (yield s1.dal.idtyDAL.getSandboxRoom()).should.equal(0);
-      yield i8.createIdentity(null, s2);
-      yield i1.cert(i8, s2);
-      (yield s1.dal.idtyDAL.getSandboxRoom()).should.equal(0);
-      yield i9.createIdentity(null, s2);
-      yield i1.cert(i9, s2);
-      (yield s1.dal.idtyDAL.getSandboxRoom()).should.equal(0);
-    }));
-
-    it('should reject i10(1) by i1->i10(1)', () => shouldThrow(co(function *() {
-      (yield s1.dal.idtyDAL.getSandboxRoom()).should.equal(0);
-      yield i10.createIdentity(true, s2);
-      yield i1.cert(i10, s2);
-    })));
-
-    it('should accept i10(0) by i1->i10(0) because of an superior date compared to others in sandbox', () => co(function *() {
-      yield i10.createIdentity(null, s3);
-      yield i1.cert(i10, s3);
-    }));
-
-    it('should accept i11(0) and i12(0) for the same reason', () => co(function *() {
-      yield i11.createIdentity(null, s3);
-      yield i12.createIdentity(null, s3);
-    }));
-
-    it('should reject i13(0) because absolutely no more room is available', () => shouldThrow(co(function *() {
-      yield i13.createIdentity(true, s3);
-      yield i1.cert(i13, s3);
-    })));
-
-    it('should accept an identity with the same key as server, always', () => co(function *() {
-      (yield s3.dal.idtyDAL.getSandboxRoom()).should.equal(0);
-      yield i14.createIdentity(null, s3);
-    }));
-
-    it('should make room as identities get expired', () => co(function *() {
-      yield s1.commit({
+    it('should reject i7(1) by revocation', () => shouldThrow((async () => {
+      await i7onS2.createIdentity(true);
+      const idty = await i7onS2.lookup(i7onS2.pub);
+      await i7.revoke(idty);
+    })()))
+
+    it('should reject i1 -> i7 by revocation', () => shouldThrow((async () => {
+      await i1.cert(i7, s2);
+    })()))
+
+    it('should accept i7(1), i8(1), i9(1) by i1->i7(1), i1->i8(1), i1->i9(1)', async () => {
+      (await s1.dal.idtyDAL.getSandboxRoom()).should.equal(0);
+      await i8.createIdentity(null, s2);
+      await i1.cert(i8, s2);
+      (await s1.dal.idtyDAL.getSandboxRoom()).should.equal(0);
+      await i9.createIdentity(null, s2);
+      await i1.cert(i9, s2);
+      (await s1.dal.idtyDAL.getSandboxRoom()).should.equal(0);
+    })
+
+    it('should reject i10(1) by i1->i10(1)', () => shouldThrow((async () => {
+      (await s1.dal.idtyDAL.getSandboxRoom()).should.equal(0);
+      await i10.createIdentity(true, s2);
+      await i1.cert(i10, s2);
+    })()))
+
+    it('should accept i10(0) by i1->i10(0) because of an superior date compared to others in sandbox', async () => {
+      await i10.createIdentity(null, s3);
+      await i1.cert(i10, s3);
+    })
+
+    it('should accept i11(0) and i12(0) for the same reason', async () => {
+      await i11.createIdentity(null, s3);
+      await i12.createIdentity(null, s3);
+    })
+
+    it('should reject i13(0) because absolutely no more room is available', () => shouldThrow((async () => {
+      await i13.createIdentity(true, s3);
+      await i1.cert(i13, s3);
+    })()))
+
+    it('should accept an identity with the same key as server, always', async () => {
+      (await s3.dal.idtyDAL.getSandboxRoom()).should.equal(0);
+      await i14.createIdentity(null, s3);
+    })
+
+    it('should make room as identities get expired', async () => {
+      await s1.commit({
         time: now + 1000
       });
-      yield s1.commit({
+      await s1.commit({
         time: now + 1000
       });
-      yield s1.commit({
+      await s1.commit({
         time: now + 1000
       });
-      (yield s1.dal.idtyDAL.getSandboxRoom()).should.equal(3);
-    }));
-  });
+      (await s1.dal.idtyDAL.getSandboxRoom()).should.equal(3);
+    })
+  })
 
   describe('Certifications', () => {
 
@@ -204,34 +203,34 @@ describe("Sandboxes", function() {
       constants.SANDBOX_SIZE_CERTIFICATIONS = NEW_VALUE
     })
 
-    it('should accept i4->i7(0),i4->i8(0),i4->i9(0)', () => co(function *() {
-      yield i7.createIdentity();
-      yield i8.createIdentity();
-      yield i9.createIdentity();
-      (yield s1.dal.certDAL.getSandboxForKey('2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc').getSandboxRoom()).should.equal(3);
-      yield i4.cert(i7);
-      yield i4.cert(i8);
-      yield i4.cert(i9);
-      (yield s1.dal.certDAL.getSandboxForKey('2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc').getSandboxRoom()).should.equal(0);
-      (yield s1.dal.certDAL.getSandboxForKey('91dWdiyf7KaC4GAiKrwU7nGuue1vvmHqjCXbPziJFYtE').getSandboxRoom()).should.equal(3);
-    }));
-
-    it('should reject i4->i10(0)', () => shouldThrow(co(function *() {
-      (yield s1.dal.certDAL.getSandboxForKey('2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc').getSandboxRoom()).should.equal(0);
-      yield i4.cert(i10);
-    })));
-
-    it('should accept a certification from the same key as server, always', () => co(function *() {
-      (yield s1.dal.certDAL.getSandboxForKey('2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc').getSandboxRoom()).should.equal(0);
-      yield i1.cert(i8);
-    }));
-
-    it('should make room as certs get expired', () => co(function *() {
-      yield s1.commit({
+    it('should accept i4->i7(0),i4->i8(0),i4->i9(0)', async () => {
+      await i7.createIdentity();
+      await i8.createIdentity();
+      await i9.createIdentity();
+      (await s1.dal.certDAL.getSandboxForKey('2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc').getSandboxRoom()).should.equal(3);
+      await i4.cert(i7);
+      await i4.cert(i8);
+      await i4.cert(i9);
+      (await s1.dal.certDAL.getSandboxForKey('2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc').getSandboxRoom()).should.equal(0);
+      (await s1.dal.certDAL.getSandboxForKey('91dWdiyf7KaC4GAiKrwU7nGuue1vvmHqjCXbPziJFYtE').getSandboxRoom()).should.equal(3);
+    })
+
+    it('should reject i4->i10(0)', () => shouldThrow((async () => {
+      (await s1.dal.certDAL.getSandboxForKey('2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc').getSandboxRoom()).should.equal(0);
+      await i4.cert(i10);
+    })()))
+
+    it('should accept a certification from the same key as server, always', async () => {
+      (await s1.dal.certDAL.getSandboxForKey('2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc').getSandboxRoom()).should.equal(0);
+      await i1.cert(i8);
+    })
+
+    it('should make room as certs get expired', async () => {
+      await s1.commit({
         time: now + 1000
       });
-      (yield s1.dal.certDAL.getSandboxForKey('2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc').getSandboxRoom()).should.equal(3);
-    }));
+      (await s1.dal.certDAL.getSandboxForKey('2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc').getSandboxRoom()).should.equal(3);
+    })
 
     after(() => {
       constants.SANDBOX_SIZE_CERTIFICATIONS = OLD_VALUE
@@ -240,31 +239,31 @@ describe("Sandboxes", function() {
 
   describe('Memberships', () => {
 
-    it('should accept i8,i9', () => co(function *() {
-      yield i8.createIdentity(); // Identities have changed
-      yield i9.createIdentity();
-      (yield s1.dal.msDAL.getSandboxRoom()).should.equal(2);
-      yield i8.join();
-      yield i9.join();
-      (yield s1.dal.msDAL.getSandboxRoom()).should.equal(0);
-    }));
-
-    it('should reject i7', () => shouldThrow(co(function *() {
-      (yield s1.dal.msDAL.getSandboxRoom()).should.equal(0);
-      yield i7.join();
-    })));
-
-    it('should accept a membership from the same key as server, always', () => co(function *() {
-      (yield s1.dal.msDAL.getSandboxRoom()).should.equal(0);
-      yield i1.join();
-    }));
-
-    it('should make room as membership get expired', () => co(function *() {
-      yield s1.commit({
+    it('should accept i8,i9', async () => {
+      await i8.createIdentity(); // Identities have changed
+      await i9.createIdentity();
+      (await s1.dal.msDAL.getSandboxRoom()).should.equal(2);
+      await i8.join();
+      await i9.join();
+      (await s1.dal.msDAL.getSandboxRoom()).should.equal(0);
+    })
+
+    it('should reject i7', () => shouldThrow((async () => {
+      (await s1.dal.msDAL.getSandboxRoom()).should.equal(0);
+      await i7.join();
+    })()))
+
+    it('should accept a membership from the same key as server, always', async () => {
+      (await s1.dal.msDAL.getSandboxRoom()).should.equal(0);
+      await i1.join();
+    })
+
+    it('should make room as membership get expired', async () => {
+      await s1.commit({
         time: now + 1000
       });
-      (yield s1.dal.msDAL.getSandboxRoom()).should.equal(2);
-    }));
+      (await s1.dal.msDAL.getSandboxRoom()).should.equal(2);
+    })
   });
 
   describe('Transaction', () => {
@@ -275,28 +274,28 @@ describe("Sandboxes", function() {
       CommonConstants.TRANSACTION_MAX_TRIES = 2;
     })
 
-    it('should accept 2 transactions of 20, 30 units', () => co(function *() {
-      yield i4.send(20, i1);
-      yield i4.send(30, i1);
-      (yield s1.dal.txsDAL.getSandboxRoom()).should.equal(0);
-    }));
+    it('should accept 2 transactions of 20, 30 units', async () => {
+      await i4.sendMoney(20, i1);
+      await i4.sendMoney(30, i1);
+      (await s1.dal.txsDAL.getSandboxRoom()).should.equal(0);
+    })
 
-    it('should reject amount of 10', () => shouldThrow(co(function *() {
-      yield i4.send(10, i1);
-    })));
+    it('should reject amount of 10', () => shouldThrow((async () => {
+      await i4.sendMoney(10, i1);
+    })()))
 
-    it('should accept a transaction from the same key as server, always', () => co(function *() {
-      yield i1.send(10, i4);
-    }));
+    it('should accept a transaction from the same key as server, always', async () => {
+      await i1.sendMoney(10, i4);
+    })
 
-    it('should make room as transactions get commited', () => co(function *() {
-      yield s1.commit();
-      yield s1.commit();
-      (yield s1.dal.txsDAL.getSandboxRoom()).should.equal(2);
+    it('should make room as transactions get commited', async () => {
+      await s1.commit();
+      await s1.commit();
+      (await s1.dal.txsDAL.getSandboxRoom()).should.equal(2);
       CommonConstants.TRANSACTION_MAX_TRIES = tmp;
-    }));
-  });
-});
+    })
+  })
+})
 
 function shouldThrow<T>(promise:Promise<T>) {
   return promise.should.be.rejected();
diff --git a/test/integration/scenarios/hello-plugin.js b/test/integration/scenarios/hello-plugin.js
index 2c0dcf257..c5b981052 100644
--- a/test/integration/scenarios/hello-plugin.js
+++ b/test/integration/scenarios/hello-plugin.js
@@ -13,19 +13,17 @@
 
 "use strict"
 
-const co = require('co')
-
 module.exports = {
   duniter: {
     cli: [{
       name: 'hello-world',
       desc: 'Says hello from \`duniter\` command.',
       logs: false,
-      onDatabaseExecute: (server, conf, program, params) => co(function*() {
+      onDatabaseExecute: async (server, conf, program, params) => {
         const msg = 'Hello world! from within Duniter.'
         console.log(msg)
         return msg
-      })
+      }
     }]
   }
 }
diff --git a/yarn.lock b/yarn.lock
index 40d6244f0..34e53e44c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -634,7 +634,7 @@ cliui@^3.2.0:
     strip-ansi "^3.0.1"
     wrap-ansi "^2.0.0"
 
-co@4.6.0, co@^4.6.0:
+co@^4.6.0:
   version "4.6.0"
   resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
 
-- 
GitLab