From 9641c5e5c3c6a614b1e27aa279e1d81426655e14 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Moreau?= <cem.moreau@gmail.com>
Date: Fri, 4 May 2018 18:43:50 +0200
Subject: [PATCH] [enh] Remove unused code

---
 app/lib/blockchain/BasicBlockchain.ts         |  71 ---
 app/lib/blockchain/DuniterBlockchain.ts       |  43 +-
 app/lib/blockchain/IndexedBlockchain.ts       | 139 ------
 app/lib/blockchain/MiscIndexedBlockchain.ts   |  50 --
 app/lib/blockchain/SqlBlockchain.ts           |  76 ---
 app/lib/blockchain/SqlIndex.ts                |  86 ----
 .../interfaces/BlockchainOperator.ts          |  51 --
 .../blockchain/interfaces/IndexOperator.ts    |  29 --
 app/lib/computation/BlockchainContext.ts      |   9 +-
 app/lib/computation/QuickSync.ts              |  17 +-
 app/lib/other_constants.ts                    |   2 +-
 app/lib/system/directory.ts                   |   2 +-
 app/service/BlockchainService.ts              |   7 +-
 server.ts                                     |   4 -
 test/blockchain/basic-blockchain.ts           | 174 -------
 test/blockchain/indexed-blockchain.ts         | 467 ------------------
 test/blockchain/lib/ArrayBlockchain.ts        |  48 --
 test/blockchain/lib/MemoryIndex.ts            | 108 ----
 test/blockchain/misc-sql-blockchain.ts        | 233 ---------
 19 files changed, 33 insertions(+), 1583 deletions(-)
 delete mode 100644 app/lib/blockchain/BasicBlockchain.ts
 delete mode 100644 app/lib/blockchain/IndexedBlockchain.ts
 delete mode 100644 app/lib/blockchain/MiscIndexedBlockchain.ts
 delete mode 100644 app/lib/blockchain/SqlBlockchain.ts
 delete mode 100644 app/lib/blockchain/SqlIndex.ts
 delete mode 100644 app/lib/blockchain/interfaces/BlockchainOperator.ts
 delete mode 100644 app/lib/blockchain/interfaces/IndexOperator.ts
 delete mode 100644 test/blockchain/basic-blockchain.ts
 delete mode 100644 test/blockchain/indexed-blockchain.ts
 delete mode 100644 test/blockchain/lib/ArrayBlockchain.ts
 delete mode 100644 test/blockchain/lib/MemoryIndex.ts
 delete mode 100644 test/blockchain/misc-sql-blockchain.ts

diff --git a/app/lib/blockchain/BasicBlockchain.ts b/app/lib/blockchain/BasicBlockchain.ts
deleted file mode 100644
index 40cd0d668..000000000
--- a/app/lib/blockchain/BasicBlockchain.ts
+++ /dev/null
@@ -1,71 +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"
-import {BlockchainOperator} from "./interfaces/BlockchainOperator"
-
-export class BasicBlockchain {
-
-  constructor(private op:BlockchainOperator) {
-  }
-
-  /**
-   * Adds a block at the end of the blockchain.
-   */
-  pushBlock(b:any) {
-    return this.op.store(b)
-  }
-
-  /**
-   * Get the block identified by `number`
-   * @param number block ID.
-   * @returns {*} Promise<Block>
-   */
-  getBlock(number:number) {
-    return this.op.read(number)
-  }
-
-  /**
-   * Get the nth block from the top of the blockchain.
-   * @param index Index from top. Defaults to `0`. E.g. `0` = HEAD, `1` = HEAD~1, etc.
-   * @returns {*} Promise<Block>
-   */
-  head(index = 0) {
-    return this.op.head(index)
-  }
-
-  /**
-   * Blockchain size, in number of blocks.
-   * @returns {*} Size.
-   */
-  height() {
-    return this.op.height()
-  }
-
-  /**
-   * Get the (n+1)th blocks top blocks of the blockchain, ordered by number ascending.
-   * @param n Quantity from top. E.g. `1` = [HEAD], `3` = [HEAD, HEAD~1, HEAD~2], etc.
-   * @returns {*} Promise<Block>
-   */
-  headRange(n:number) {
-    return this.op.headRange(n)
-  }
-
-  /**
-   * Pops the blockchain HEAD.
-   * @returns {*} Promise<Block> The reverted block.
-   */
-  revertHead() {
-    return this.op.revertHead()
-  }
-}
diff --git a/app/lib/blockchain/DuniterBlockchain.ts b/app/lib/blockchain/DuniterBlockchain.ts
index 6f4305c04..1c0402613 100644
--- a/app/lib/blockchain/DuniterBlockchain.ts
+++ b/app/lib/blockchain/DuniterBlockchain.ts
@@ -11,9 +11,7 @@
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU Affero General Public License for more details.
 
-import {MiscIndexedBlockchain} from "./MiscIndexedBlockchain"
 import {FullIindexEntry, IindexEntry, IndexEntry, Indexer, MindexEntry, SindexEntry} from "../indexer"
-import {BlockchainOperator} from "./interfaces/BlockchainOperator"
 import {ConfDTO} from "../dto/ConfDTO"
 import {BlockDTO} from "../dto/BlockDTO"
 import {DBHead} from "../db/DBHead"
@@ -32,11 +30,7 @@ import {NewLogger} from "../logger"
 
 const _ = require('underscore')
 
-export class DuniterBlockchain extends MiscIndexedBlockchain {
-
-  constructor(blockchainStorage:BlockchainOperator, dal:FileDAL) {
-    super(blockchainStorage, dal.mindexDAL, dal.iindexDAL, dal.sindexDAL, dal.cindexDAL)
-  }
+export class DuniterBlockchain {
 
   static async checkBlock(block:BlockDTO, withPoWAndSignature:boolean, conf: ConfDTO, dal:FileDAL) {
     const index = Indexer.localIndex(block, conf)
@@ -186,7 +180,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
     return { index, HEAD }
   }
 
-  async pushTheBlock(obj:BlockDTO, index:IndexEntry[], HEAD:DBHead | null, conf:ConfDTO, dal:FileDAL, logger:any) {
+  static async pushTheBlock(obj:BlockDTO, index:IndexEntry[], HEAD:DBHead | null, conf:ConfDTO, dal:FileDAL, logger:any) {
     const start = Date.now();
     const block = BlockDTO.fromJSONObject(obj)
     try {
@@ -213,7 +207,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
     // await supra.recordIndex(index)
   }
 
-  async saveBlockData(current:DBBlock|null, block:BlockDTO, conf:ConfDTO, dal:FileDAL, logger:any, index:IndexEntry[], HEAD:DBHead | null) {
+  static async saveBlockData(current:DBBlock|null, block:BlockDTO, conf:ConfDTO, dal:FileDAL, logger:any, index:IndexEntry[], HEAD:DBHead | null) {
     if (block.number == 0) {
       await this.saveParametersForRoot(block, conf, dal);
     }
@@ -275,7 +269,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
     return dbb
   }
 
-  async saveParametersForRoot(block:BlockDTO, conf:ConfDTO, dal:FileDAL) {
+  static async saveParametersForRoot(block:BlockDTO, conf:ConfDTO, dal:FileDAL) {
     if (block.parameters) {
       const bconf = BlockDTO.getConf(block)
       conf.c = bconf.c;
@@ -305,7 +299,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
     }
   }
 
-  async createNewcomers(iindex:IindexEntry[], dal:FileDAL, logger:any) {
+  static async createNewcomers(iindex:IindexEntry[], dal:FileDAL, logger:any) {
     for (const i of iindex) {
       if (i.op == CommonConstants.IDX_CREATE) {
         const entry = i as FullIindexEntry
@@ -319,7 +313,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
     }
   }
 
-  async updateMembers(block:BlockDTO, dal:FileDAL) {
+  static async updateMembers(block:BlockDTO, dal:FileDAL) {
     // Joiners (come back)
     for (const inlineMS of block.joiners) {
       let ms = MembershipDTO.fromInline(inlineMS)
@@ -338,7 +332,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
     }
   }
 
-  async updateWallets(sindex:SindexEntry[], aDal:any, reverse = false) {
+  static async updateWallets(sindex:SindexEntry[], aDal:any, reverse = false) {
     const differentConditions = _.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)
@@ -356,7 +350,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
     }
   }
 
-  async revertBlock(number:number, hash:string, dal:FileDAL) {
+  static async revertBlock(number:number, hash:string, dal:FileDAL) {
 
     const blockstamp = [number, hash].join('-');
     const block = await dal.getBlockByBlockstampOrNull(blockstamp)
@@ -406,7 +400,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
     return block
   }
 
-  async undoMembersUpdate(blockstamp:string, dal:FileDAL) {
+  static async undoMembersUpdate(blockstamp:string, dal:FileDAL) {
     const joiners = await dal.iindexDAL.getWrittenOn(blockstamp);
     for (const entry of joiners) {
       // Undo 'join' which can be either newcomers or comebackers
@@ -437,7 +431,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
     }
   }
 
-  async undoDeleteTransactions(block:DBBlock, dal:FileDAL) {
+  static async undoDeleteTransactions(block:DBBlock, dal:FileDAL) {
     for (const obj of block.transactions) {
       obj.currency = block.currency;
       let tx = TransactionDTO.fromJSONObject(obj)
@@ -469,7 +463,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
    * @param block Block in which are contained the certifications to remove from sandbox.
    * @param dal The DAL
    */
-  async removeMembershipsFromSandbox(block:BlockDTO, dal:FileDAL) {
+  static async removeMembershipsFromSandbox(block:BlockDTO, dal:FileDAL) {
     const mss = block.joiners.concat(block.actives).concat(block.leavers);
     for (const inlineMS of mss) {
       let ms = MembershipDTO.fromInline(inlineMS)
@@ -480,14 +474,14 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
     }
   }
 
-  async computeToBeRevoked(mindex:MindexEntry[], dal:FileDAL) {
+  static async computeToBeRevoked(mindex:MindexEntry[], dal:FileDAL) {
     const revocations = _.filter(mindex, (entry:MindexEntry) => entry.revoked_on);
     for (const revoked of revocations) {
       await dal.setRevoked(revoked.pub)
     }
   }
 
-  async deleteTransactions(block:BlockDTO, dal:FileDAL) {
+  static async deleteTransactions(block:BlockDTO, dal:FileDAL) {
     for (const obj of block.transactions) {
       obj.currency = block.currency;
       const tx = TransactionDTO.fromJSONObject(obj)
@@ -496,7 +490,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
     }
   }
 
-  updateBlocksComputedVars(
+  static updateBlocksComputedVars(
     current:{ unitbase:number, monetaryMass:number }|null,
     block:{ number:number, unitbase:number, dividend:number|null, membersCount:number, monetaryMass:number }): void {
     // Unit Base
@@ -548,7 +542,7 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
     return dal.pushStats(stats);
   }
 
-  async pushSideBlock(obj:BlockDTO, dal:FileDAL, logger:any) {
+  static async pushSideBlock(obj:BlockDTO, dal:FileDAL, logger:any) {
     const start = Date.now();
     const block = DBBlock.fromBlockDTO(BlockDTO.fromJSONObject(obj))
     block.fork = true;
@@ -562,11 +556,4 @@ export class DuniterBlockchain extends MiscIndexedBlockchain {
       throw err;
     }
   }
-
-  async revertHead() {
-    const indexRevert = super.indexRevert
-    const headf = super.head
-    const head = await headf()
-    await indexRevert(head.number)
-  }
 }
diff --git a/app/lib/blockchain/IndexedBlockchain.ts b/app/lib/blockchain/IndexedBlockchain.ts
deleted file mode 100644
index dd81222d5..000000000
--- a/app/lib/blockchain/IndexedBlockchain.ts
+++ /dev/null
@@ -1,139 +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"
-import {BasicBlockchain} from "./BasicBlockchain"
-import {IndexOperator} from "./interfaces/IndexOperator"
-import {BlockchainOperator} from "./interfaces/BlockchainOperator"
-
-const _ = require('underscore')
-
-export class IndexedBlockchain extends BasicBlockchain {
-
-  private initIndexer: Promise<void>
-
-  constructor(bcOperations: BlockchainOperator, private indexOperations: IndexOperator, private numberField: string, private pkFields: any) {
-    super(bcOperations)
-    this.initIndexer = indexOperations.initIndexer(pkFields)
-  }
-
-  async recordIndex(index: { [index: string]: any }) {
-    // Wait indexer init
-    await this.initIndexer
-
-    return this.indexOperations.recordIndex(index)
-  }
-
-  async indexTrim(maxNumber:number) {
-
-    // Wait indexer init
-    await this.initIndexer
-
-    const subIndexes = await this.indexOperations.getSubIndexes()
-    // Trim the subIndexes
-    const records: { [index: string]: any } = {}
-    for (const subIndex of subIndexes) {
-      records[subIndex] = []
-      const pks = typeof this.pkFields[subIndex].pk !== 'string' && this.pkFields[subIndex].pk.length ? Array.from(this.pkFields[subIndex].pk) : [this.pkFields[subIndex].pk]
-      const rm = this.pkFields[subIndex].remove
-      let potentialRecords = await this.indexOperations.findTrimable(subIndex, this.numberField, maxNumber)
-      potentialRecords = reduceBy(potentialRecords, pks)
-      for (const potential of potentialRecords) {
-        const subCriteriasRowsToDelete = criteriasFromPks(pks, potential)
-        subCriteriasRowsToDelete[this.numberField] = { $lt: maxNumber }
-        const rowsToReduce = await this.indexOperations.findWhere(subIndex, subCriteriasRowsToDelete)
-        // No reduction if 1 line to delete
-        if (rowsToReduce.length > 1) {
-          const reduced = reduce(rowsToReduce)
-          const subCriteriasRowsToKeep = criteriasFromPks(pks, potential)
-          subCriteriasRowsToKeep[this.numberField] = { $gte: maxNumber }
-          const toKeep = await this.indexOperations.findWhere(subIndex, subCriteriasRowsToKeep)
-          const subCriteriasAllRowsOfObject = criteriasFromPks(pks, potential)
-          await this.indexOperations.removeWhere(subIndex, subCriteriasAllRowsOfObject)
-          // Add the reduced row + rows to keep
-          if (!rm || !reduced[rm]) {
-            records[subIndex] = records[subIndex].concat([reduced]).concat(toKeep)
-          }
-        }
-      }
-    }
-    await this.recordIndex(records)
-    return Promise.resolve()
-  }
-
-  async indexCount(indexName: string, criterias: { [index: string]: any }) {
-
-    // Wait indexer init
-    await this.initIndexer
-
-    const records = await this.indexOperations.findWhere(indexName, criterias)
-    return records.length
-  }
-
-  async indexReduce(indexName: string, criterias: { [index: string]: any }) {
-
-    // Wait indexer init
-    await this.initIndexer
-
-    const records = await this.indexOperations.findWhere(indexName, criterias)
-    return reduce(records)
-  }
-
-  async indexReduceGroupBy(indexName: string, criterias: { [index: string]: any }, properties: string[]) {
-
-    // Wait indexer init
-    await this.initIndexer
-
-    const records = await this.indexOperations.findWhere(indexName, criterias)
-    return reduceBy(records, properties)
-  }
-
-  async indexRevert(blockNumber:number) {
-    const subIndexes = await this.indexOperations.getSubIndexes()
-    for (const subIndex of subIndexes) {
-      const removeCriterias: { [index: string]: any } = {}
-      removeCriterias[this.numberField] = blockNumber
-      await this.indexOperations.removeWhere(subIndex, removeCriterias)
-    }
-  }
-}
-
-function reduce(records: any[]) {
-  return records.reduce((obj, record) => {
-    const keys = Object.keys(record);
-    for (const k of keys) {
-      if (record[k] !== undefined && record[k] !== null) {
-        obj[k] = record[k];
-      }
-    }
-    return obj;
-  }, {});
-}
-
-function reduceBy(reducables: any[], properties: string[]) {
-  const reduced = reducables.reduce((map, entry) => {
-    const id = properties.map((prop) => entry[prop]).join('-');
-    map[id] = map[id] || [];
-    map[id].push(entry);
-    return map;
-  }, {});
-  return _.values(reduced).map((rows: any[]) => reduce(rows))
-}
-
-function criteriasFromPks(pks: string[], values: any): { [index: string]: any } {
-  const criterias: { [index: string]: any } = {}
-  for (const key of pks) {
-    criterias[key] = values[key]
-  }
-  return criterias
-}
diff --git a/app/lib/blockchain/MiscIndexedBlockchain.ts b/app/lib/blockchain/MiscIndexedBlockchain.ts
deleted file mode 100644
index 5f881ba0d..000000000
--- a/app/lib/blockchain/MiscIndexedBlockchain.ts
+++ /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"
-import {IndexedBlockchain} from "./IndexedBlockchain"
-import {SQLIndex} from "./SqlIndex"
-import {BlockchainOperator} from "./interfaces/BlockchainOperator"
-
-export class MiscIndexedBlockchain extends IndexedBlockchain {
-
-  constructor(blockchainStorage: BlockchainOperator, mindexDAL:any, iindexDAL:any, sindexDAL:any, cindexDAL:any) {
-    super(blockchainStorage, new SQLIndex(null, {
-      m_index: { handler: mindexDAL },
-      i_index: { handler: iindexDAL },
-      s_index: {
-        handler: sindexDAL,
-        findTrimable: (maxNumber:number) => sindexDAL.query('SELECT * FROM s_index WHERE consumed AND writtenOn < ?', [maxNumber])
-      },
-      c_index: {
-        handler: cindexDAL,
-        findTrimable: (maxNumber:number) => cindexDAL.query('SELECT * FROM c_index WHERE expired_on > 0 AND writtenOn < ?', [maxNumber])
-      }
-    }), 'writtenOn', {
-      m_index: {
-        pk: ['pub']
-      },
-      i_index: {
-        pk: ['pub']
-      },
-      s_index: {
-        pk: ['identifier', 'pos'],
-        remove: 'consumed'
-      },
-      c_index: {
-        pk: ['issuer', 'receiver', 'created_on'],
-        remove: 'expired_on'
-      }
-    })
-  }
-}
diff --git a/app/lib/blockchain/SqlBlockchain.ts b/app/lib/blockchain/SqlBlockchain.ts
deleted file mode 100644
index 84d2f5b97..000000000
--- a/app/lib/blockchain/SqlBlockchain.ts
+++ /dev/null
@@ -1,76 +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"
-import {BlockchainOperator} from "./interfaces/BlockchainOperator"
-
-const indexer = require('../../lib/indexer').Indexer
-
-export class SQLBlockchain implements BlockchainOperator {
-
-  constructor(private dal: { bindexDAL:any }) {
-  }
-
-  store(b: any): Promise<any> {
-    return this.dal.bindexDAL.saveEntity(b)
-  }
-
-  read(i: number): Promise<any> {
-    return this.dal.bindexDAL.sqlFindOne({ number: i })
-  }
-
-  async head(n = 0): Promise<any> {
-    /**
-     * IMPORTANT NOTICE
-     * ----------------
-     *
-     * There is a difference between the protocol's HEAD (P_HEAD) and the database's HEAD (DB_HEAD). The relation is:
-     *
-     *     DB_HEAD~<i> = P_HEAD~<i+1>
-     *
-     * In this class methods, we expose DB_HEAD logic. But the data is stored/retrieved by DAL objects using P_HEAD logic.
-     *
-     * So if we want DB_HEAD~0 for example, we must ask P_HEAD~(0+1). The DAL object will then retrieve P_HEAD~1, which
-     * is the latest stored block in the blockchain.
-     *
-     * Note: the DAL object cannot retrieve P_HEAD~0, this value does not exist and refers to the potential incoming block.
-     *
-     * Why this behavior?
-     * ------------------
-     *
-     * Because the DAL was wrongly coded. It will be easy to fix this problem once indexer.js will only use **this class'
-     * methods**. Then, we will be able to replace (n + 1) by just (n), and replace also the complementary behavior in
-     * the DAL (BIndexDAL).
-     */
-    return this.dal.bindexDAL.head(n + 1)
-  }
-
-  async height(): Promise<number> {
-    const head = await this.dal.bindexDAL.head(1) // We do not use head(0). See the above notice.
-    if (head) {
-      return head.number + 1
-    } else {
-      return 0
-    }
-  }
-
-  headRange(m: number): Promise<any[]> {
-    return this.dal.bindexDAL.range(1, m) // We do not use range(0, m). See the above notice.
-  }
-
-  async revertHead(): Promise<any> {
-    const head = await this.dal.bindexDAL.head(1) // We do not use head(0). See the above notice.
-    await this.dal.bindexDAL.removeBlock(head.number)
-    return head
-  }
-}
diff --git a/app/lib/blockchain/SqlIndex.ts b/app/lib/blockchain/SqlIndex.ts
deleted file mode 100644
index 53cb379c9..000000000
--- a/app/lib/blockchain/SqlIndex.ts
+++ /dev/null
@@ -1,86 +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"
-import {IndexOperator} from "./interfaces/IndexOperator"
-import {AbstractIndex} from "../dal/sqliteDAL/AbstractIndex";
-
-const _ = require('underscore')
-
-export class SQLIndex implements IndexOperator {
-
-  private indexes: { [k:string]: any } = {}
-
-  constructor(private db:any, private definitions: any) {
-  }
-
-  async initIndexer(pkFields: any): Promise<void> {
-    const keys = _.keys(pkFields)
-    for (const k of keys) {
-      if (this.definitions[k].handler) {
-        // External table: managed by another object
-        this.indexes[k] = this.definitions[k].handler
-      } else {
-        // Internal table: managed here
-        const indexTable = new AbstractIndex<any>(this.db, k, [], this.definitions[k].fields, [], this.definitions[k].booleans)
-        this.indexes[k] = indexTable
-        indexTable.init = () => {
-          return indexTable.exec('BEGIN;' +
-            'CREATE TABLE IF NOT EXISTS ' + indexTable.table + ' (' +
-            this.definitions[k].sqlFields.join(',') +
-            ');' +
-            'COMMIT;')
-        }
-        await indexTable.init()
-      }
-    }
-  }
-
-  getSubIndexes(): Promise<string[]> {
-    return Promise.resolve(_.keys(this.indexes))
-  }
-
-  findTrimable(subIndex: string, numberField: string, maxNumber: number): Promise<any[]> {
-    if (this.definitions[subIndex].findTrimable) {
-      return this.definitions[subIndex].findTrimable(maxNumber)
-    } else {
-      const criterias:any = {}
-      criterias[numberField] = { $lt: maxNumber }
-      return this.indexes[subIndex].sqlFind(criterias)
-    }
-  }
-
-  removeWhere(subIndex: string, criterias: {}): Promise<void> {
-    if (!this.indexes[subIndex]) {
-      return Promise.resolve()
-    }
-    return this.indexes[subIndex].sqlRemoveWhere(criterias)
-  }
-
-  async recordIndex(index: any): Promise<void> {
-    const subIndexes = _.keys(index)
-    // Feed the this.indexes
-    for (const subIndex of subIndexes) {
-      await this.indexes[subIndex].insertBatch(index[subIndex])
-    }
-    return Promise.resolve()
-  }
-
-
-  findWhere(subIndex: string, criterias: {}): Promise<any[]> {
-    if (!this.indexes[subIndex]) {
-      return Promise.resolve([])
-    }
-    return this.indexes[subIndex].sqlFind(criterias)
-  }
-}
diff --git a/app/lib/blockchain/interfaces/BlockchainOperator.ts b/app/lib/blockchain/interfaces/BlockchainOperator.ts
deleted file mode 100644
index f3f50177b..000000000
--- a/app/lib/blockchain/interfaces/BlockchainOperator.ts
+++ /dev/null
@@ -1,51 +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"
-
-export interface BlockchainOperator {
-
-  /**
-   * Pushes a new block at the top of the blockchain.
-   * @param b Block.
-   */
-  store(b:any):Promise<any>
-
-  /**
-   * Reads the block at index `i`.
-   * @param i Block number.
-   */
-  read(i:number):Promise<any>
-
-  /**
-   * Reads the block at index `n` from the top of the blockchain.
-   * @param n Reverse index.
-   */
-  head(n:number):Promise<any>
-
-  /**
-   * Gives the number of blocks in the blockchain.
-   */
-  height():Promise<number>
-
-  /**
-   * Reads the blocks from head(0) to head(m)
-   * @param m Quantity.
-   */
-  headRange(m:number):Promise<any[]>
-
-  /**
-   * Pops the top block.
-   */
-  revertHead():Promise<any>
-}
diff --git a/app/lib/blockchain/interfaces/IndexOperator.ts b/app/lib/blockchain/interfaces/IndexOperator.ts
deleted file mode 100644
index 57b475d63..000000000
--- a/app/lib/blockchain/interfaces/IndexOperator.ts
+++ /dev/null
@@ -1,29 +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"
-
-export interface IndexOperator {
-
-  initIndexer(pkFields: any): Promise<void>,
-
-  getSubIndexes(): Promise<string[]>,
-
-  findWhere(subIndex: string, criterias: {}): Promise<any[]>,
-
-  findTrimable(subIndex: string, numberField: string, maxNumber: number): Promise<any[]>,
-
-  removeWhere(subIndex: string, criterias: {}): Promise<void>,
-
-  recordIndex(index: any): Promise<void>
-}
diff --git a/app/lib/computation/BlockchainContext.ts b/app/lib/computation/BlockchainContext.ts
index 4354b131a..b33f4a7ac 100644
--- a/app/lib/computation/BlockchainContext.ts
+++ b/app/lib/computation/BlockchainContext.ts
@@ -108,10 +108,9 @@ export class BlockchainContext {
     return local_vHEAD.issuerDiff;
   }
 
-  setConfDAL(newConf: any, newDAL: any, theBlockchain: DuniterBlockchain, theQuickSynchronizer: QuickSynchronizer): void {
+  setConfDAL(newConf: any, newDAL: any, theQuickSynchronizer: QuickSynchronizer): void {
     this.dal = newDAL;
     this.conf = newConf;
-    this.blockchain = theBlockchain
     this.quickSynchronizer = theQuickSynchronizer
     this.logger = require('../logger').NewLogger(this.dal.profile);
   }
@@ -121,20 +120,20 @@ export class BlockchainContext {
   }
 
   private async addBlock(obj: BlockDTO, index: any = null, HEAD: DBHead | null = null): Promise<any> {
-    const block = await this.blockchain.pushTheBlock(obj, index, HEAD, this.conf, this.dal, this.logger)
+    const block = await DuniterBlockchain.pushTheBlock(obj, index, HEAD, this.conf, this.dal, this.logger)
     this.vHEAD_1 = this.vHEAD = null
     return block
   }
 
   async addSideBlock(obj:BlockDTO): Promise<BlockDTO> {
-    const dbb = await this.blockchain.pushSideBlock(obj, this.dal, this.logger)
+    const dbb = await DuniterBlockchain.pushSideBlock(obj, this.dal, this.logger)
     return dbb.toBlockDTO()
   }
 
   async revertCurrentBlock(): Promise<DBBlock> {
     const head_1 = await this.dal.bindexDAL.head(1);
     this.logger.debug('Reverting block #%s...', head_1.number);
-    const res = await this.blockchain.revertBlock(head_1.number, head_1.hash, this.dal)
+    const res = await DuniterBlockchain.revertBlock(head_1.number, head_1.hash, this.dal)
     // Invalidates the head, since it has changed.
     await this.refreshHead();
     return res;
diff --git a/app/lib/computation/QuickSync.ts b/app/lib/computation/QuickSync.ts
index 071e07027..f2f94a5ba 100644
--- a/app/lib/computation/QuickSync.ts
+++ b/app/lib/computation/QuickSync.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 {DuniterBlockchain} from "../blockchain/DuniterBlockchain";
 import {BlockDTO} from "../dto/BlockDTO";
 import {DBTransaction} from "../db/DBTransaction";
@@ -50,7 +49,7 @@ const sync_memoryDAL:AccountsGarbagingDAL = {
 
 export class QuickSynchronizer {
 
-  constructor(private blockchain:DuniterBlockchain, private conf: any, private dal:FileDAL, private logger: any) {
+  constructor(private conf: any, private dal:FileDAL, private logger: any) {
   }
 
   async saveBlocksInMainBranch(blocks: BlockDTO[]): Promise<void> {
@@ -73,7 +72,7 @@ export class QuickSynchronizer {
     for (const block of blocks) {
       block.fork = false;
       const current:BlockDTO|null = block.number > 0 ? await getBlock(block.number - 1) : null
-      this.blockchain.updateBlocksComputedVars(current, block)
+      DuniterBlockchain.updateBlocksComputedVars(current, block)
     }
     // Transactions recording
     await this.updateTransactionsForBlocks(blocks, getBlockByNumberAndHash);
@@ -107,7 +106,7 @@ export class QuickSynchronizer {
 
       // VERY FIRST: parameters, otherwise we compute wrong variables such as UDTime
       if (block.number == 0) {
-        await this.blockchain.saveParametersForRoot(block, this.conf, this.dal)
+        await DuniterBlockchain.saveParametersForRoot(block, this.conf, this.dal)
       }
 
       // The new kind of object stored
@@ -140,7 +139,7 @@ export class QuickSynchronizer {
           }
         }
 
-        await this.blockchain.createNewcomers(local_iindex, this.dal, this.logger)
+        await DuniterBlockchain.createNewcomers(local_iindex, this.dal, this.logger)
 
         if (block.dividend
           || block.joiners.length
@@ -191,7 +190,7 @@ export class QuickSynchronizer {
             sync_mindex = sync_mindex.concat(await Indexer.ruleIndexGenImplicitRevocation(HEAD, this.dal));
           }
           // Update balances with UD + local garbagings
-          await this.blockchain.updateWallets(sync_sindex, sync_memoryDAL)
+          await DuniterBlockchain.updateWallets(sync_sindex, sync_memoryDAL)
 
           // --> Update links
           await this.dal.updateWotbLinks(local_cindex.concat(sync_cindex));
@@ -207,7 +206,7 @@ export class QuickSynchronizer {
           sync_sindex = [];
 
           // Create/Update nodes in wotb
-          await this.blockchain.updateMembers(block, this.dal)
+          await DuniterBlockchain.updateMembers(block, this.dal)
         }
 
         // Trim the bindex
@@ -247,12 +246,12 @@ export class QuickSynchronizer {
         }
 
         if (block.number === 0) {
-          await this.blockchain.saveParametersForRoot(block, this.conf, this.dal)
+          await DuniterBlockchain.saveParametersForRoot(block, this.conf, this.dal)
         }
 
         // Last block: cautious mode to trigger all the INDEX expiry mechanisms
         const { index, HEAD } = await DuniterBlockchain.checkBlock(dto, constants.WITH_SIGNATURES_AND_POW, this.conf, this.dal)
-        await this.blockchain.pushTheBlock(dto, index, HEAD, this.conf, this.dal, this.logger)
+        await DuniterBlockchain.pushTheBlock(dto, index, HEAD, this.conf, this.dal, this.logger)
 
         // Clean temporary variables
         sync_bindex = [];
diff --git a/app/lib/other_constants.ts b/app/lib/other_constants.ts
index d10528e99..63162b599 100644
--- a/app/lib/other_constants.ts
+++ b/app/lib/other_constants.ts
@@ -13,7 +13,7 @@
 
 export const OtherConstants = {
 
-  MUTE_LOGS_DURING_UNIT_TESTS: false,
+  MUTE_LOGS_DURING_UNIT_TESTS: true,
   SQL_TRACES: false,
 
   BC_EVENT: {
diff --git a/app/lib/system/directory.ts b/app/lib/system/directory.ts
index d0717051c..c40df48d9 100644
--- a/app/lib/system/directory.ts
+++ b/app/lib/system/directory.ts
@@ -106,7 +106,7 @@ export const RealFS = (): FileSystem => {
 }
 
 export const MemFS = (initialTree:{ [folder:string]: { [file:string]: string }} = {}): FileSystem => {
-  return new QioFileSystem(require('q-io/fs-mock')(initialTree))
+  return new QioFileSystem(require('q-io/fs-mock')(initialTree), true)
 }
 
 export const Directory = {
diff --git a/app/service/BlockchainService.ts b/app/service/BlockchainService.ts
index c9d5a7219..4e4e29e8d 100644
--- a/app/service/BlockchainService.ts
+++ b/app/service/BlockchainService.ts
@@ -29,6 +29,7 @@ import {LOCAL_RULES_FUNCTIONS} from "../lib/rules/local_rules"
 import {Switcher, SwitcherDao} from "../lib/blockchain/Switcher"
 import {OtherConstants} from "../lib/other_constants"
 import {DataErrors} from "../lib/common-libs/errors"
+import {DuniterBlockchain} from "../lib/blockchain/DuniterBlockchain"
 
 "use strict";
 
@@ -141,8 +142,8 @@ export class BlockchainService extends FIFOService {
     this.dal = newDAL;
     this.conf = newConf;
     this.logger = require('../lib/logger').NewLogger(this.dal.profile)
-    this.quickSynchronizer = new QuickSynchronizer(this.server.blockchain, this.conf, this.dal, this.logger)
-    this.mainContext.setConfDAL(this.conf, this.dal, this.server.blockchain, this.quickSynchronizer)
+    this.quickSynchronizer = new QuickSynchronizer(this.conf, this.dal, this.logger)
+    this.mainContext.setConfDAL(this.conf, this.dal, this.quickSynchronizer)
     this.selfPubkey = newKeyPair.publicKey;
   }
 
@@ -444,7 +445,7 @@ export class BlockchainService extends FIFOService {
 
   // This method is called by duniter-crawler 1.3.x
   saveParametersForRootBlock(block:BlockDTO) {
-    return this.server.blockchain.saveParametersForRoot(block, this.conf, this.dal)
+    return DuniterBlockchain.saveParametersForRoot(block, this.conf, this.dal)
   }
 
   async blocksBetween(from:number, count:number): Promise<DBBlock[]> {
diff --git a/server.ts b/server.ts
index 04137cba2..ff02773dd 100644
--- a/server.ts
+++ b/server.ts
@@ -18,8 +18,6 @@ import {BlockchainService} from "./app/service/BlockchainService"
 import {TransactionService} from "./app/service/TransactionsService"
 import {ConfDTO} from "./app/lib/dto/ConfDTO"
 import {FileDAL, FileDALParams} from "./app/lib/dal/fileDAL"
-import {DuniterBlockchain} from "./app/lib/blockchain/DuniterBlockchain"
-import {SQLBlockchain} from "./app/lib/blockchain/SqlBlockchain"
 import * as stream from "stream"
 import {KeyGen, randomKey} from "./app/lib/common-libs/crypto/keyring"
 import {parsers} from "./app/lib/common-libs/parsers/index"
@@ -198,8 +196,6 @@ export class Server extends stream.Duplex implements HookableServer {
     // Extract key pair
     this.keyPair = KeyGen(this.conf.pair.pub, this.conf.pair.sec);
     this.sign = (msg:string) => this.keyPair.sign(msg)
-    // Blockchain object
-    this.blockchain = new DuniterBlockchain(new SQLBlockchain(this.dal), this.dal);
     // Update services
     this.IdentityService.setConfDAL(this.conf, this.dal)
     this.MembershipService.setConfDAL(this.conf, this.dal)
diff --git a/test/blockchain/basic-blockchain.ts b/test/blockchain/basic-blockchain.ts
deleted file mode 100644
index 7acfea13f..000000000
--- a/test/blockchain/basic-blockchain.ts
+++ /dev/null
@@ -1,174 +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 {BasicBlockchain} from "../../app/lib/blockchain/BasicBlockchain"
-import {ArrayBlockchain} from "./lib/ArrayBlockchain"
-import {SQLBlockchain} from "../../app/lib/blockchain/SqlBlockchain"
-import {SQLiteDriver} from "../../app/lib/dal/drivers/SQLiteDriver"
-import {BIndexDAL} from "../../app/lib/dal/sqliteDAL/index/BIndexDAL";
-import {MetaDAL} from "../../app/lib/dal/sqliteDAL/MetaDAL";
-import {ConfDTO} from "../../app/lib/dto/ConfDTO";
-
-const assert = require('assert')
-
-let blockchain:BasicBlockchain,
-  emptyBlockchain:BasicBlockchain
-
-describe('Basic Memory Blockchain', () => {
-
-  before(() => {
-    blockchain = new BasicBlockchain(new ArrayBlockchain())
-    emptyBlockchain = new BasicBlockchain(new ArrayBlockchain())
-  })
-
-  it('should be able to push 3 blocks and read them', async () => {
-    await blockchain.pushBlock({ name: 'A' })
-    await blockchain.pushBlock({ name: 'B' })
-    await blockchain.pushBlock({ name: 'C' })
-    const HEAD0 = await blockchain.head()
-    const HEAD1 = await blockchain.head(1)
-    const HEAD2 = await blockchain.head(2)
-    const BLOCK0 = await blockchain.getBlock(0)
-    const BLOCK1 = await blockchain.getBlock(1)
-    const BLOCK2 = await blockchain.getBlock(2)
-    assert.equal(HEAD0.name, 'C')
-    assert.equal(HEAD1.name, 'B')
-    assert.equal(HEAD2.name, 'A')
-    assert.deepEqual(HEAD2, BLOCK0)
-    assert.deepEqual(HEAD1, BLOCK1)
-    assert.deepEqual(HEAD0, BLOCK2)
-  })
-
-  it('should be able to read a range', async () => {
-    const range1 = await blockchain.headRange(2)
-    assert.equal(range1.length, 2)
-    assert.equal(range1[0].name, 'C')
-    assert.equal(range1[1].name, 'B')
-    const range2 = await blockchain.headRange(6)
-    assert.equal(range2.length, 3)
-    assert.equal(range2[0].name, 'C')
-    assert.equal(range2[1].name, 'B')
-    assert.equal(range2[2].name, 'A')
-  })
-
-  it('should have a good height', async () => {
-    const height1 = await blockchain.height()
-    await blockchain.pushBlock({ name: 'D' })
-    const height2 = await blockchain.height()
-    const height3 = await emptyBlockchain.height()
-    assert.equal(height1, 3)
-    assert.equal(height2, 4)
-    assert.equal(height3, 0)
-  })
-
-  it('should be able to revert blocks', async () => {
-    const reverted = await blockchain.revertHead()
-    const height2 = await blockchain.height()
-    assert.equal(height2, 3)
-    assert.equal(reverted.name, 'D')
-  })
-
-})
-
-describe.skip('Basic SQL Blockchain', () => {
-
-  before(async () => {
-
-    {
-      const db = new SQLiteDriver(':memory:')
-
-      const bindexDAL = new BIndexDAL(db)
-      const metaDAL = new MetaDAL(db)
-
-      await bindexDAL.init()
-      await metaDAL.init()
-      await metaDAL.exec('CREATE TABLE txs (id INTEGER null);')
-      await metaDAL.exec('CREATE TABLE idty (id INTEGER null);')
-      await metaDAL.exec('CREATE TABLE cert (id INTEGER null);')
-      await metaDAL.exec('CREATE TABLE membership (id INTEGER null);')
-      await metaDAL.exec('CREATE TABLE block (fork INTEGER null);')
-      await metaDAL.upgradeDatabase(ConfDTO.mock());
-
-      const dal = { bindexDAL }
-
-      blockchain = new BasicBlockchain(new SQLBlockchain(dal))
-    }
-    {
-      const db = new SQLiteDriver(':memory:')
-
-      const bindexDAL = new BIndexDAL(db)
-      const metaDAL = new MetaDAL(db)
-
-      await bindexDAL.init()
-      await metaDAL.init()
-      await metaDAL.exec('CREATE TABLE txs (id INTEGER null);')
-      await metaDAL.exec('CREATE TABLE idty (id INTEGER null);')
-      await metaDAL.exec('CREATE TABLE cert (id INTEGER null);')
-      await metaDAL.exec('CREATE TABLE membership (id INTEGER null);')
-      await metaDAL.exec('CREATE TABLE block (fork INTEGER null);')
-      await metaDAL.upgradeDatabase(ConfDTO.mock());
-
-      const dal = { bindexDAL }
-
-      emptyBlockchain = new BasicBlockchain(new SQLBlockchain(dal))
-    }
-  })
-
-  it('should be able to push 3 blocks and read them', async () => {
-    await blockchain.pushBlock({ number: 0, version: 1, bsize: 0, hash: 'H', issuer: 'I', time: 1, membersCount: 1, issuersCount: 1, issuersFrame: 1, issuersFrameVar: 1, avgBlockSize: 0, medianTime: 1, dividend: 10, mass: 100, unitBase: 0, powMin: 0, udTime: 0, udReevalTime: 0, diffNumber: 1, speed: 1, massReeval: 1 })
-    await blockchain.pushBlock({ number: 1, version: 1, bsize: 0, hash: 'H', issuer: 'I', time: 1, membersCount: 1, issuersCount: 1, issuersFrame: 1, issuersFrameVar: 1, avgBlockSize: 0, medianTime: 1, dividend: 10, mass: 100, unitBase: 0, powMin: 0, udTime: 0, udReevalTime: 0, diffNumber: 1, speed: 1, massReeval: 1 })
-    await blockchain.pushBlock({ number: 2, version: 1, bsize: 0, hash: 'H', issuer: 'I', time: 1, membersCount: 1, issuersCount: 1, issuersFrame: 1, issuersFrameVar: 1, avgBlockSize: 0, medianTime: 1, dividend: 10, mass: 100, unitBase: 0, powMin: 0, udTime: 0, udReevalTime: 0, diffNumber: 1, speed: 1, massReeval: 1 })
-    const HEAD0 = await blockchain.head()
-    const HEAD1 = await blockchain.head(1)
-    const HEAD2 = await blockchain.head(2)
-    const BLOCK0 = await blockchain.getBlock(0)
-    const BLOCK1 = await blockchain.getBlock(1)
-    const BLOCK2 = await blockchain.getBlock(2)
-    assert.equal(HEAD0.number, 2)
-    assert.equal(HEAD1.number, 1)
-    assert.equal(HEAD2.number, 0)
-    assert.deepEqual(HEAD2, BLOCK0)
-    assert.deepEqual(HEAD1, BLOCK1)
-    assert.deepEqual(HEAD0, BLOCK2)
-  })
-
-  it('should be able to read a range', async () => {
-    const range1 = await blockchain.headRange(2)
-    assert.equal(range1.length, 2)
-    assert.equal(range1[0].number, 2)
-    assert.equal(range1[1].number, 1)
-    const range2 = await blockchain.headRange(6)
-    assert.equal(range2.length, 3)
-    assert.equal(range2[0].number, 2)
-    assert.equal(range2[1].number, 1)
-    assert.equal(range2[2].number, 0)
-  })
-
-  it('should have a good height', async () => {
-    const height1 = await blockchain.height()
-    await blockchain.pushBlock({ number: 3, version: 1, bsize: 0, hash: 'H', issuer: 'I', time: 1, membersCount: 1, issuersCount: 1, issuersFrame: 1, issuersFrameVar: 1, avgBlockSize: 0, medianTime: 1, dividend: 10, mass: 100, unitBase: 0, powMin: 0, udTime: 0, udReevalTime: 0, diffNumber: 1, speed: 1, massReeval: 1 })
-    const height2 = await blockchain.height()
-    const height3 = await emptyBlockchain.height()
-    assert.equal(height1, 3)
-    assert.equal(height2, 4)
-    assert.equal(height3, 0)
-  })
-
-  it('should be able to revert blocks', async () => {
-    const reverted = await blockchain.revertHead()
-    const height2 = await blockchain.height()
-    assert.equal(height2, 3)
-    assert.equal(reverted.number, 3)
-  })
-
-})
diff --git a/test/blockchain/indexed-blockchain.ts b/test/blockchain/indexed-blockchain.ts
deleted file mode 100644
index 8304e1c32..000000000
--- a/test/blockchain/indexed-blockchain.ts
+++ /dev/null
@@ -1,467 +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";
-import {ArrayBlockchain} from "./lib/ArrayBlockchain"
-import {IndexedBlockchain} from "../../app/lib/blockchain/IndexedBlockchain"
-import {MemoryIndex} from "./lib/MemoryIndex"
-import {SQLIndex} from "../../app/lib/blockchain/SqlIndex"
-import {SQLiteDriver} from "../../app/lib/dal/drivers/SQLiteDriver"
-
-const assert = require('assert')
-
-describe('Indexed Blockchain', () => {
-
-  describe('MemoryIndex', () => {
-
-    let blockchain:any
-
-    describe('PK on one field', () => {
-
-      before(() => {
-        blockchain = new IndexedBlockchain(new ArrayBlockchain(), new MemoryIndex(), 'writtenOn', {
-          iindex: {
-            pk: 'name',
-            remove: 'expired'
-          },
-          zindex: {
-            pk: 'name'
-          }
-        })
-      })
-
-      it('should be able to index data', async () => {
-        await blockchain.recordIndex({
-          iindex: [
-            { name: 'A', status: 'OK', writtenOn: 23000, events: 0, member: false },
-            { name: 'A', status: 'OK', writtenOn: 23000, events: 4 },
-            { name: 'A', status: 'OK', writtenOn: 23000, events: 5, member: true },
-            { name: 'A', status: 'OK', writtenOn: 23601 },
-            { name: 'A', status: 'OK', writtenOn: 23888 },
-            { name: 'A', status: 'OK', writtenOn: 23889 },
-            { name: 'B', status: 'OK', writtenOn: 23000, events: 1, member: false },
-            { name: 'B', status: 'KO', writtenOn: 23000, events: null },
-            { name: 'C', status: 'KO', writtenOn: 23500 },
-            { name: 'D', status: 'KO', writtenOn: 23500 },
-            { name: 'D', status: 'KO', writtenOn: 23521, expired: true }
-          ]
-        })
-      })
-
-      it('should be able to reduce data', async () => {
-        const reducedA = await blockchain.indexReduce('iindex', { name: 'A' })
-        const reducedB = await blockchain.indexReduce('iindex', { name: 'B' })
-        assert.deepEqual(reducedA, { name: 'A', status: 'OK', writtenOn: 23889, events: 5, member: true })
-        assert.deepEqual(reducedB, { name: 'B', status: 'KO', writtenOn: 23000, events: 1, member: false })
-      })
-
-      it('should be able to count data', async () => {
-        const countAi = await blockchain.indexCount('iindex', { name: 'A' })
-        const countBi = await blockchain.indexCount('iindex', { name: 'B' })
-        const countCi = await blockchain.indexCount('iindex', { name: 'C' })
-        const countDi = await blockchain.indexCount('iindex', { name: 'D' })
-        const countBz = await blockchain.indexCount('zindex', { name: 'B' })
-        assert.equal(countAi, 6)
-        assert.equal(countBi, 2)
-        assert.equal(countCi, 1)
-        assert.equal(countDi, 2)
-        assert.equal(countBz, 0)
-      })
-
-      it('should be able to reduce grouped data', async () => {
-        const reducedBy = await blockchain.indexReduceGroupBy('iindex', { writtenOn: 23000 }, ['name'])
-        assert.deepEqual(reducedBy, [
-          { name: 'A', status: 'OK', writtenOn: 23000, events: 5, member: true },
-          { name: 'B', status: 'KO', writtenOn: 23000, events: 1, member: false }
-        ])
-      })
-
-      it('should be able to trim data', async () => {
-        // The number of records should decrease
-        await blockchain.indexTrim(23601)
-        const countAi = await blockchain.indexCount('iindex', { name: 'A' })
-        const countBi = await blockchain.indexCount('iindex', { name: 'B' })
-        const countCi = await blockchain.indexCount('iindex', { name: 'C' })
-        const countDi = await blockchain.indexCount('iindex', { name: 'D' })
-        const countBz = await blockchain.indexCount('zindex', { name: 'B' })
-        assert.equal(countAi, 4)
-        assert.equal(countBi, 1)
-        assert.equal(countCi, 1)
-        assert.equal(countDi, 0) // Expired = remove rows on trim
-        assert.equal(countBz, 0)
-        const reducedAi = await blockchain.indexReduce('iindex', { name: 'A' })
-        const reducedBi = await blockchain.indexReduce('iindex', { name: 'B' })
-        const reducedCi = await blockchain.indexReduce('iindex', { name: 'C' })
-        const reducedDi = await blockchain.indexReduce('iindex', { name: 'D' })
-        const reducedBz = await blockchain.indexReduce('zindex', { name: 'B' })
-        assert.deepEqual(reducedAi, { name: 'A', status: 'OK', writtenOn: 23889, events: 5, member: true })
-        assert.deepEqual(reducedBi, { name: 'B', status: 'KO', writtenOn: 23000, events: 1, member: false })
-        assert.deepEqual(reducedCi, { name: 'C', status: 'KO', writtenOn: 23500 })
-        assert.deepEqual(reducedDi, {})
-        assert.deepEqual(reducedBz, {})
-      })
-    })
-
-    describe('PK on two fields', () => {
-
-      before(() => {
-        blockchain = new IndexedBlockchain(new ArrayBlockchain(), new MemoryIndex(), 'writtenOn', {
-          iindex: {
-            pk: ['id', 'pos'],
-            remove: 'expired'
-          },
-          zindex: {
-            pk: 'name'
-          }
-        })
-      })
-
-      it('should be able to index data', async () => {
-        await blockchain.recordIndex({
-          iindex: [
-            { id: 'A', pos: 0, status: 'OK', writtenOn: 23000, events: 0, member: false },
-            { id: 'A', pos: 0, status: 'OK', writtenOn: 23000, events: 4 },
-            { id: 'A', pos: 0, status: 'OK', writtenOn: 23000, events: 5, member: true },
-            { id: 'A', pos: 0, status: 'OK', writtenOn: 23601 },
-            { id: 'A', pos: 1, status: 'OK', writtenOn: 23888 },
-            { id: 'A', pos: 2, status: 'OK', writtenOn: 23889 },
-            { id: 'B', pos: 0, status: 'OK', writtenOn: 23000, events: 1, member: false },
-            { id: 'B', pos: 0, status: 'KO', writtenOn: 23000, events: null },
-            { id: 'C', pos: 0, status: 'KO', writtenOn: 23500 },
-            { id: 'D', pos: 0, status: 'KO', writtenOn: 23500 },
-            { id: 'D', pos: 1, status: 'KO', writtenOn: 23521, expired: true }
-          ]
-        })
-      })
-
-      it('should be able to reduce data', async () => {
-        const reducedA = await blockchain.indexReduce('iindex', { id: 'A', pos: 0 })
-        const reducedB = await blockchain.indexReduce('iindex', { id: 'B', pos: 0 })
-        assert.deepEqual(reducedA, { id: 'A', pos: 0, status: 'OK', writtenOn: 23601, events: 5, member: true })
-        assert.deepEqual(reducedB, { id: 'B', pos: 0, status: 'KO', writtenOn: 23000, events: 1, member: false })
-      })
-
-      it('should be able to count data', async () => {
-        const countAi = await blockchain.indexCount('iindex', { id: 'A', pos: 0 })
-        const countBi = await blockchain.indexCount('iindex', { id: 'B', pos: 0 })
-        const countCi = await blockchain.indexCount('iindex', { id: 'C', pos: 0 })
-        const countDi = await blockchain.indexCount('iindex', { id: 'D', pos: 0 })
-        const countBz = await blockchain.indexCount('zindex', { id: 'B', pos: 0 })
-        assert.equal(countAi, 4)
-        assert.equal(countBi, 2)
-        assert.equal(countCi, 1)
-        assert.equal(countDi, 1)
-        assert.equal(countBz, 0)
-      })
-
-      it('should be able to reduce grouped data', async () => {
-        const reducedBy = await blockchain.indexReduceGroupBy('iindex', { writtenOn: 23000 }, ['id', 'pos'])
-        assert.deepEqual(reducedBy, [
-          { id: 'A', pos: 0, status: 'OK', writtenOn: 23000, events: 5, member: true },
-          { id: 'B', pos: 0, status: 'KO', writtenOn: 23000, events: 1, member: false }
-        ])
-      })
-
-      it('should be able to trim data', async () => {
-        // The number of records should decrease
-        await blockchain.indexTrim(23601)
-        const countAi = await blockchain.indexCount('iindex', { id: 'A', pos: 0 })
-        const countBi = await blockchain.indexCount('iindex', { id: 'B', pos: 0 })
-        const countCi = await blockchain.indexCount('iindex', { id: 'C', pos: 0 })
-        const countDi = await blockchain.indexCount('iindex', { id: 'D', pos: 0 })
-        const countBz = await blockchain.indexCount('zindex', { id: 'B', pos: 0 })
-        assert.equal(countAi, 2)
-        assert.equal(countBi, 1)
-        assert.equal(countCi, 1)
-        assert.equal(countDi, 1) // Not expired!
-        assert.equal(countBz, 0)
-        const reducedAi = await blockchain.indexReduce('iindex', { id: 'A', pos: 0 })
-        const reducedBi = await blockchain.indexReduce('iindex', { id: 'B', pos: 0 })
-        const reducedCi = await blockchain.indexReduce('iindex', { id: 'C', pos: 0 })
-        const reducedDi = await blockchain.indexReduce('iindex', { id: 'D', pos: 0 })
-        const reducedBz = await blockchain.indexReduce('zindex', { id: 'B', pos: 0 })
-        assert.deepEqual(reducedAi, { id: 'A', pos: 0, status: 'OK', writtenOn: 23601, events: 5, member: true })
-        assert.deepEqual(reducedBi, { id: 'B', pos: 0, status: 'KO', writtenOn: 23000, events: 1, member: false })
-        assert.deepEqual(reducedCi, { id: 'C', pos: 0, status: 'KO', writtenOn: 23500 })
-        assert.deepEqual(reducedDi, { id: 'D', pos: 0, status: 'KO', writtenOn: 23500 })
-        assert.deepEqual(reducedBz, {})
-      })
-    })
-  })
-
-  describe('SqlIndex', () => {
-
-    let blockchain:any
-
-    describe('PK on one field', () => {
-
-      before(() => {
-        const db = new SQLiteDriver(':memory:')
-        blockchain = new IndexedBlockchain(new ArrayBlockchain(), new SQLIndex(db, {
-          iindex: {
-            sqlFields: [
-              'name CHAR(1) NULL',
-              'status CHAR(2) NULL',
-              'writtenOn INTEGER NULL',
-              'events INTEGER NULL',
-              'member INTEGER NULL',
-              'expired INTEGER NULL'
-            ],
-            fields: [
-              'name',
-              'status',
-              'writtenOn',
-              'events',
-              'member',
-              'expired'
-            ],
-            booleans: ['member', 'expired']
-          },
-          zindex: {
-            sqlFields: [
-              'name CHAR(1) NULL',
-              'status CHAR(2) NULL',
-              'writtenOn INTEGER NULL',
-              'events INTEGER NULL',
-              'member INTEGER NULL',
-              'expired INTEGER NULL'
-            ],
-            fields: [
-              'name',
-              'status',
-              'writtenOn',
-              'events',
-              'member',
-              'expired'
-            ],
-            booleans: ['member', 'expired']
-          }
-        }), 'writtenOn', {
-          iindex: {
-            pk: 'name',
-            remove: 'expired'
-          },
-          zindex: {
-            pk: 'name'
-          }
-        })
-      })
-
-      it('should be able to index data', async () => {
-        await blockchain.recordIndex({
-          iindex: [
-            { name: 'A', status: 'OK', writtenOn: 23000, events: 0, member: false },
-            { name: 'A', status: 'OK', writtenOn: 23000, events: 4 },
-            { name: 'A', status: 'OK', writtenOn: 23000, events: 5, member: true },
-            { name: 'A', status: 'OK', writtenOn: 23601 },
-            { name: 'A', status: 'OK', writtenOn: 23888 },
-            { name: 'A', status: 'OK', writtenOn: 23889 },
-            { name: 'B', status: 'OK', writtenOn: 23000, events: 1, member: false },
-            { name: 'B', status: 'KO', writtenOn: 23000, events: null },
-            { name: 'C', status: 'KO', writtenOn: 23500 },
-            { name: 'D', status: 'KO', writtenOn: 23500 },
-            { name: 'D', status: 'KO', writtenOn: 23521, expired: true }
-          ]
-        })
-      })
-
-      it('should be able to reduce data', async () => {
-        const reducedA = await blockchain.indexReduce('iindex', { name: 'A' })
-        const reducedB = await blockchain.indexReduce('iindex', { name: 'B' })
-        assert.deepEqual(reducedA, { name: 'A', status: 'OK', writtenOn: 23889, events: 5, member: true })
-        assert.deepEqual(reducedB, { name: 'B', status: 'KO', writtenOn: 23000, events: 1, member: false })
-      })
-
-      it('should be able to count data', async () => {
-        const countAi = await blockchain.indexCount('iindex', { name: 'A' })
-        const countBi = await blockchain.indexCount('iindex', { name: 'B' })
-        const countCi = await blockchain.indexCount('iindex', { name: 'C' })
-        const countDi = await blockchain.indexCount('iindex', { name: 'D' })
-        const countBz = await blockchain.indexCount('zindex', { name: 'B' })
-        assert.equal(countAi, 6)
-        assert.equal(countBi, 2)
-        assert.equal(countCi, 1)
-        assert.equal(countDi, 2)
-        assert.equal(countBz, 0)
-      })
-
-      it('should be able to reduce grouped data', async () => {
-        const reducedBy = await blockchain.indexReduceGroupBy('iindex', { writtenOn: 23000 }, ['name'])
-        assert.deepEqual(reducedBy, [
-          { name: 'A', status: 'OK', writtenOn: 23000, events: 5, member: true },
-          { name: 'B', status: 'KO', writtenOn: 23000, events: 1, member: false }
-        ])
-      })
-
-      it('should be able to trim data', async () => {
-        // The number of records should decrease
-        await blockchain.indexTrim(23601)
-        const countAi = await blockchain.indexCount('iindex', { name: 'A' })
-        const countBi = await blockchain.indexCount('iindex', { name: 'B' })
-        const countCi = await blockchain.indexCount('iindex', { name: 'C' })
-        const countDi = await blockchain.indexCount('iindex', { name: 'D' })
-        const countBz = await blockchain.indexCount('zindex', { name: 'B' })
-        assert.equal(countAi, 4)
-        assert.equal(countBi, 1)
-        assert.equal(countCi, 1)
-        assert.equal(countDi, 0) // Expired = remove rows on trim
-        assert.equal(countBz, 0)
-        const reducedAi = await blockchain.indexReduce('iindex', { name: 'A' })
-        const reducedBi = await blockchain.indexReduce('iindex', { name: 'B' })
-        const reducedCi = await blockchain.indexReduce('iindex', { name: 'C' })
-        const reducedDi = await blockchain.indexReduce('iindex', { name: 'D' })
-        const reducedBz = await blockchain.indexReduce('zindex', { name: 'B' })
-        assert.deepEqual(reducedAi, { name: 'A', status: 'OK', writtenOn: 23889, events: 5, member: true })
-        assert.deepEqual(reducedBi, { name: 'B', status: 'KO', writtenOn: 23000, events: 1, member: false })
-        assert.deepEqual(reducedCi, { name: 'C', status: 'KO', writtenOn: 23500 })
-        assert.deepEqual(reducedDi, {})
-        assert.deepEqual(reducedBz, {})
-      })
-    })
-
-    describe('PK on two fields', () => {
-
-      before(() => {
-        const db = new SQLiteDriver(':memory:')
-        blockchain = new IndexedBlockchain(new ArrayBlockchain(), new SQLIndex(db, {
-          iindex: {
-            sqlFields: [
-              'id INTEGER NULL',
-              'pos INTEGER NULL',
-              'name CHAR(1) NULL',
-              'status CHAR(2) NULL',
-              'writtenOn INTEGER NULL',
-              'events INTEGER NULL',
-              'member INTEGER NULL',
-              'expired INTEGER NULL'
-            ],
-            fields: [
-              'id',
-              'pos',
-              'name',
-              'status',
-              'writtenOn',
-              'events',
-              'member',
-              'expired'
-            ],
-            booleans: ['member', 'expired']
-          },
-          zindex: {
-            sqlFields: [
-              'id INTEGER NULL',
-              'pos INTEGER NULL',
-              'name CHAR(1) NULL',
-              'status CHAR(2) NULL',
-              'writtenOn INTEGER NULL',
-              'events INTEGER NULL',
-              'member INTEGER NULL',
-              'expired INTEGER NULL'
-            ],
-            fields: [
-              'id',
-              'pos',
-              'name',
-              'status',
-              'writtenOn',
-              'events',
-              'member',
-              'expired'
-            ],
-            booleans: ['member', 'expired']
-          }
-        }), 'writtenOn', {
-          iindex: {
-            pk: ['id', 'pos'],
-            remove: 'expired'
-          },
-          zindex: {
-            pk: 'name'
-          }
-        })
-      })
-
-      it('should be able to index data', async () => {
-        await blockchain.recordIndex({
-          iindex: [
-            { id: 'A', pos: 0, status: 'OK', writtenOn: 23000, events: 0, member: false },
-            { id: 'A', pos: 0, status: 'OK', writtenOn: 23000, events: 4 },
-            { id: 'A', pos: 0, status: 'OK', writtenOn: 23000, events: 5, member: true },
-            { id: 'A', pos: 0, status: 'OK', writtenOn: 23601 },
-            { id: 'A', pos: 1, status: 'OK', writtenOn: 23888 },
-            { id: 'A', pos: 2, status: 'OK', writtenOn: 23889 },
-            { id: 'B', pos: 0, status: 'OK', writtenOn: 23000, events: 1, member: false },
-            { id: 'B', pos: 0, status: 'KO', writtenOn: 23000, events: null },
-            { id: 'C', pos: 0, status: 'KO', writtenOn: 23500 },
-            { id: 'D', pos: 0, status: 'KO', writtenOn: 23500 },
-            { id: 'D', pos: 1, status: 'KO', writtenOn: 23521, expired: true }
-          ]
-        })
-      })
-
-      it('should be able to reduce data', async () => {
-        const reducedA = await blockchain.indexReduce('iindex', { id: 'A', pos: 0 })
-        const reducedB = await blockchain.indexReduce('iindex', { id: 'B', pos: 0 })
-        assert.deepEqual(reducedA, { id: 'A', pos: 0, status: 'OK', writtenOn: 23601, events: 5, member: true })
-        assert.deepEqual(reducedB, { id: 'B', pos: 0, status: 'KO', writtenOn: 23000, events: 1, member: false })
-      })
-
-      it('should be able to count data', async () => {
-        const countAi = await blockchain.indexCount('iindex', { id: 'A', pos: 0 })
-        const countBi = await blockchain.indexCount('iindex', { id: 'B', pos: 0 })
-        const countCi = await blockchain.indexCount('iindex', { id: 'C', pos: 0 })
-        const countDi = await blockchain.indexCount('iindex', { id: 'D', pos: 0 })
-        const countBz = await blockchain.indexCount('zindex', { id: 'B', pos: 0 })
-        assert.equal(countAi, 4)
-        assert.equal(countBi, 2)
-        assert.equal(countCi, 1)
-        assert.equal(countDi, 1)
-        assert.equal(countBz, 0)
-      })
-
-      it('should be able to reduce grouped data', async () => {
-        const reducedBy = await blockchain.indexReduceGroupBy('iindex', { writtenOn: 23000 }, ['id', 'pos'])
-        assert.deepEqual(reducedBy, [
-          { id: 'A', pos: 0, status: 'OK', writtenOn: 23000, events: 5, member: true },
-          { id: 'B', pos: 0, status: 'KO', writtenOn: 23000, events: 1, member: false }
-        ])
-      })
-
-      it('should be able to trim data', async () => {
-        // The number of records should decrease
-        await blockchain.indexTrim(23601)
-        const countAi = await blockchain.indexCount('iindex', { id: 'A', pos: 0 })
-        const countBi = await blockchain.indexCount('iindex', { id: 'B', pos: 0 })
-        const countCi = await blockchain.indexCount('iindex', { id: 'C', pos: 0 })
-        const countDi = await blockchain.indexCount('iindex', { id: 'D', pos: 0 })
-        const countBz = await blockchain.indexCount('zindex', { id: 'B', pos: 0 })
-        assert.equal(countAi, 2)
-        assert.equal(countBi, 1)
-        assert.equal(countCi, 1)
-        assert.equal(countDi, 1) // Not expired!
-        assert.equal(countBz, 0)
-        const reducedAi = await blockchain.indexReduce('iindex', { id: 'A', pos: 0 })
-        const reducedBi = await blockchain.indexReduce('iindex', { id: 'B', pos: 0 })
-        const reducedCi = await blockchain.indexReduce('iindex', { id: 'C', pos: 0 })
-        const reducedDi = await blockchain.indexReduce('iindex', { id: 'D', pos: 0 })
-        const reducedBz = await blockchain.indexReduce('zindex', { id: 'B', pos: 0 })
-        assert.deepEqual(reducedAi, { id: 'A', pos: 0, status: 'OK', writtenOn: 23601, events: 5, member: true })
-        assert.deepEqual(reducedBi, { id: 'B', pos: 0, status: 'KO', writtenOn: 23000, events: 1, member: false })
-        assert.deepEqual(reducedCi, { id: 'C', pos: 0, status: 'KO', writtenOn: 23500 })
-        assert.deepEqual(reducedDi, { id: 'D', pos: 0, status: 'KO', writtenOn: 23500 })
-        assert.deepEqual(reducedBz, {})
-      })
-    })
-  })
-
-})
diff --git a/test/blockchain/lib/ArrayBlockchain.ts b/test/blockchain/lib/ArrayBlockchain.ts
deleted file mode 100644
index 25c0fc576..000000000
--- a/test/blockchain/lib/ArrayBlockchain.ts
+++ /dev/null
@@ -1,48 +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 {BlockchainOperator} from "../../../app/lib/blockchain/interfaces/BlockchainOperator"
-
-export class ArrayBlockchain implements BlockchainOperator {
-
-  // The blockchain storage
-  private bcArray: any[] = []
-
-  store(b:any): Promise<any> {
-    this.bcArray.push(b)
-    return Promise.resolve(b)
-  }
-
-  read(i: number): Promise<any> {
-    return Promise.resolve(this.bcArray[i])
-  }
-
-  head(n: number): Promise<any> {
-    const index = Math.max(0, this.bcArray.length - 1 - (n || 0))
-    return Promise.resolve(this.bcArray[index])
-  }
-
-  height(): Promise<number> {
-    return Promise.resolve(this.bcArray.length)
-  }
-
-  headRange(m: number): Promise<any[]> {
-    const index = Math.max(0, this.bcArray.length - (m || 0))
-    return Promise.resolve(this.bcArray.slice(index, this.bcArray.length).reverse())
-  }
-
-  revertHead(): Promise<any> {
-    const reverted = this.bcArray.pop()
-    return Promise.resolve(reverted)
-  }
-}
diff --git a/test/blockchain/lib/MemoryIndex.ts b/test/blockchain/lib/MemoryIndex.ts
deleted file mode 100644
index cfd6471f4..000000000
--- a/test/blockchain/lib/MemoryIndex.ts
+++ /dev/null
@@ -1,108 +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"
-import {IndexOperator} from "../../../app/lib/blockchain/interfaces/IndexOperator"
-
-const _  = require('underscore')
-
-export class MemoryIndex implements IndexOperator {
-
-  // The blockchain storage
-  private indexStorage: { [index: string]: any[] } = { }
-
-  initIndexer(pkFields: any): Promise<void> {
-    return Promise.resolve()
-  }
-
-  getSubIndexes(): Promise<string[]> {
-    return Promise.resolve(_.keys(this.indexStorage))
-  }
-
-  findTrimable(subIndex: string, numberField: string, maxNumber: number): Promise<any[]> {
-    const criterias:any = {}
-    criterias[numberField] = { $lt: maxNumber }
-    return this.findWhere(subIndex, criterias)
-  }
-
-  removeWhere(subIndex: string, criterias: {}): Promise<void> {
-    let i = 0
-    let rows = this.indexStorage[subIndex]
-    while (i < rows.length) {
-      if (MemoryIndex.matchComplexCriterias(criterias, rows[i])) {
-        rows.splice(i, 1)
-      } else {
-        i++
-      }
-    }
-    return Promise.resolve()
-  }
-
-  recordIndex(index: any): Promise<void> {
-    const subIndexes = _.keys(index)
-    // Create subIndexes if they do not exist
-    for (const subIndex of subIndexes) {
-      this.indexStorage[subIndex] = this.indexStorage[subIndex] || []
-    }
-    // Feed the subIndexes
-    for (const subIndex of subIndexes) {
-      this.indexStorage[subIndex] = this.indexStorage[subIndex].concat(index[subIndex])
-    }
-    return Promise.resolve()
-  }
-
-  private static matchComplexCriterias(criterias:any, row:any): boolean {
-    const criteriaKeys = _.keys(criterias)
-    let matches = true
-    let i = 0
-    while (matches && i < criteriaKeys.length) {
-      const k = criteriaKeys[i]
-      if (typeof criterias[k] === 'function') {
-        matches = criterias[k](row[k])
-      } else if (typeof criterias[k] === 'object') {
-        if (criterias[k].$lt) {
-          matches = row[k] < criterias[k].$lt
-        } else if (criterias[k].$gt) {
-          matches = row[k] > criterias[k].$gt
-        } else if (criterias[k].$lte) {
-          matches = row[k] <= criterias[k].$lte
-        } else if (criterias[k].$gte) {
-          matches = row[k] >= criterias[k].$gte
-        } else {
-          // Unknown predicate
-          matches = false
-        }
-      } else {
-        matches = row[k] === criterias[k]
-      }
-      i++
-    }
-    return matches
-  }
-
-  findWhere(subIndex: string, criterias: {}): Promise<any[]> {
-    let res: any[] = []
-    const areBasicCriterias = _.values(criterias).reduce((are:boolean, criteria:any) => are && typeof criteria !== 'function' && typeof criteria !== 'object', true)
-    if (areBasicCriterias) {
-      res = _.where(this.indexStorage[subIndex], criterias)
-    } else {
-      // Slower test, with specific criterias
-      for (const row of this.indexStorage[subIndex]) {
-        if (MemoryIndex.matchComplexCriterias(criterias, row)) {
-          res.push(row)
-        }
-      }
-    }
-    return Promise.resolve(res)
-  }
-}
diff --git a/test/blockchain/misc-sql-blockchain.ts b/test/blockchain/misc-sql-blockchain.ts
deleted file mode 100644
index 8e41ae1f6..000000000
--- a/test/blockchain/misc-sql-blockchain.ts
+++ /dev/null
@@ -1,233 +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";
-import {MiscIndexedBlockchain} from "../../app/lib/blockchain/MiscIndexedBlockchain"
-import {ArrayBlockchain} from "./lib/ArrayBlockchain"
-import {SQLiteDriver} from "../../app/lib/dal/drivers/SQLiteDriver"
-import {MIndexDAL} from "../../app/lib/dal/sqliteDAL/index/MIndexDAL";
-import {IIndexDAL} from "../../app/lib/dal/sqliteDAL/index/IIndexDAL";
-import {SIndexDAL} from "../../app/lib/dal/sqliteDAL/index/SIndexDAL";
-import {CIndexDAL} from "../../app/lib/dal/sqliteDAL/index/CIndexDAL";
-import {MetaDAL} from "../../app/lib/dal/sqliteDAL/MetaDAL";
-import {ConfDTO} from "../../app/lib/dto/ConfDTO";
-
-const assert = require('assert')
-
-describe.skip('MISC SQL Blockchain', () => {
-
-  let blockchain:any
-
-  before(async () => {
-
-    const db = new SQLiteDriver(':memory:')
-
-    const mindexDAL = new MIndexDAL(db)
-    const iindexDAL = new IIndexDAL(db)
-    const sindexDAL = new SIndexDAL(db)
-    const cindexDAL = new CIndexDAL(db)
-    const metaDAL = new MetaDAL(db)
-
-    await iindexDAL.init()
-    await mindexDAL.init()
-    await sindexDAL.init()
-    await cindexDAL.init()
-    await metaDAL.init()
-    // Ghost tables required for DB upgrade
-    await metaDAL.exec('CREATE TABLE txs (id INTEGER null);')
-    await metaDAL.exec('CREATE TABLE idty (id INTEGER null);')
-    await metaDAL.exec('CREATE TABLE cert (id INTEGER null);')
-    await metaDAL.exec('CREATE TABLE membership (id INTEGER null);')
-    await metaDAL.exec('CREATE TABLE block (fork INTEGER null);')
-    await metaDAL.exec('CREATE TABLE b_index (id INTEGER null);')
-    await metaDAL.upgradeDatabase(ConfDTO.mock());
-
-    blockchain = new MiscIndexedBlockchain(new ArrayBlockchain(), mindexDAL, iindexDAL, sindexDAL, cindexDAL)
-  })
-
-  describe('MINDEX', () => {
-
-    it('should be able to index data', async () => {
-      await blockchain.recordIndex({
-        m_index: [
-          { op: 'CREATE', pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', written_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', writtenOn: 0, expires_on: 1520544727, expired_on: null, revokes_on: 1552102327, revoked_on: null, leaving: false, revocation: null, chainable_on: null },
-          { op: 'UPDATE', pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', written_on: '3-0000611A1018A322624853A8AE10D0EBFF3C6AEE37BF4DE5354C720049C22BD1', writtenOn: 3, expires_on: 1520544728, expired_on: null, revokes_on: 1520544728, revoked_on: null, leaving: false, revocation: null, chainable_on: null },
-          { op: 'UPDATE', pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', written_on: '4-0000090B7059E7BF5DD2CCA5E4F0330C1DA42C5DCBD2D1364B99B3FF89DE6744', writtenOn: 4, expires_on: 1520544729, expired_on: null, revokes_on: 1520544729, revoked_on: null, leaving: false, revocation: null, chainable_on: null }
-        ]
-      })
-    })
-
-    it('should be able to reduce data', async () => {
-      const reducedG5 = await blockchain.indexReduce('m_index', { pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT' })
-      assert.deepEqual(reducedG5, { op: 'UPDATE', pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', written_on: '4-0000090B7059E7BF5DD2CCA5E4F0330C1DA42C5DCBD2D1364B99B3FF89DE6744', writtenOn: 4, expires_on: 1520544729, revokes_on: 1520544729, leaving: false })
-    })
-
-    it('should be able to count data', async () => {
-      const countG5 = await blockchain.indexCount('m_index', { pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT' })
-      assert.equal(countG5, 3)
-    })
-
-    it('should be able to reduce grouped data', async () => {
-      const reducedBy = await blockchain.indexReduceGroupBy('m_index', { created_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855' }, ['op', 'pub'])
-      assert.deepEqual(reducedBy, [
-        { op: 'CREATE', pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', written_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', writtenOn: 0, expires_on: 1520544727, revokes_on: 1552102327, leaving: false },
-        { op: 'UPDATE', pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', written_on: '4-0000090B7059E7BF5DD2CCA5E4F0330C1DA42C5DCBD2D1364B99B3FF89DE6744', writtenOn: 4, expires_on: 1520544729, revokes_on: 1520544729, leaving: false }
-      ])
-    })
-
-    it('should be able to trim data', async () => {
-      // The number of records should decrease
-      await blockchain.indexTrim(4)
-      const countG5 = await blockchain.indexCount('m_index', { pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT' })
-      assert.equal(countG5, 2)
-      const reducedG5 = await blockchain.indexReduce('m_index', { pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT' })
-      assert.deepEqual(reducedG5, { op: 'UPDATE', pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', written_on: '4-0000090B7059E7BF5DD2CCA5E4F0330C1DA42C5DCBD2D1364B99B3FF89DE6744', writtenOn: 4, expires_on: 1520544729, revokes_on: 1520544729, leaving: false })
-    })
-  })
-
-  describe('IINDEX', () => {
-
-    it('should be able to index data', async () => {
-      await blockchain.recordIndex({
-        i_index: [
-          { op: 'CREATE', uid: 'pseudo', pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', hash: '1505A45A5EEBFC3AFAD1475A4739C8447A79420A83340559CE5A49F9891167BB', sig: '2vfmih7xhW/QLJ85PZH1Tc6j5fooIXca+yr/esnt0yvdk5LhEKrOB32JFqCctAoRNwpRjBdZ2Q8l15+In1rrDg==', created_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', written_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855',     writtenOn: 0,     member: true,  wasMember: true, kick: false, wotb_id: 164 },
-          { op: 'UPDATE', uid: 'pseudo', pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', hash: '1505A45A5EEBFC3AFAD1475A4739C8447A79420A83340559CE5A49F9891167BB', sig: '2vfmih7xhW/QLJ85PZH1Tc6j5fooIXca+yr/esnt0yvdk5LhEKrOB32JFqCctAoRNwpRjBdZ2Q8l15+In1rrDg==', created_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', written_on: '33396-000009C936CD6F7C5672C1E6D36159E0BEA2B394F386CA0EBA7E73662A09BB43', writtenOn: 33396, member: false, wasMember: true, kick: false, wotb_id: 164 },
-          { op: 'UPDATE', uid: 'pseudo', pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', hash: '1505A45A5EEBFC3AFAD1475A4739C8447A79420A83340559CE5A49F9891167BB', sig: '2vfmih7xhW/QLJ85PZH1Tc6j5fooIXca+yr/esnt0yvdk5LhEKrOB32JFqCctAoRNwpRjBdZ2Q8l15+In1rrDg==', created_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', written_on: '40000-000006C311D2677D101116287718395A2CBB7B94389004D19B0E4AC6DCE2DE5F', writtenOn: 40000, member: true,  wasMember: true, kick: false, wotb_id: 164 }
-        ]
-      })
-    })
-
-    it('should be able to reduce data', async () => {
-      const reducedG5 = await blockchain.indexReduce('i_index', { pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT' })
-      assert.deepEqual(reducedG5, { op: 'UPDATE', uid: 'pseudo', pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', hash: '1505A45A5EEBFC3AFAD1475A4739C8447A79420A83340559CE5A49F9891167BB', sig: '2vfmih7xhW/QLJ85PZH1Tc6j5fooIXca+yr/esnt0yvdk5LhEKrOB32JFqCctAoRNwpRjBdZ2Q8l15+In1rrDg==', created_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', written_on: '40000-000006C311D2677D101116287718395A2CBB7B94389004D19B0E4AC6DCE2DE5F', writtenOn: 40000, member: true,  wasMember: true, kick: false, wotb_id: 164 })
-    })
-
-    it('should be able to count data', async () => {
-      const countG5 = await blockchain.indexCount('i_index', { pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT' })
-      assert.equal(countG5, 3)
-    })
-
-    it('should be able to reduce grouped data', async () => {
-      const reducedBy = await blockchain.indexReduceGroupBy('i_index', { created_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855' }, ['op', 'pub'])
-      assert.deepEqual(reducedBy, [
-        { op: 'CREATE', uid: 'pseudo', pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', hash: '1505A45A5EEBFC3AFAD1475A4739C8447A79420A83340559CE5A49F9891167BB', sig: '2vfmih7xhW/QLJ85PZH1Tc6j5fooIXca+yr/esnt0yvdk5LhEKrOB32JFqCctAoRNwpRjBdZ2Q8l15+In1rrDg==', created_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', written_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855',     writtenOn: 0,     member: true,  wasMember: true, kick: false, wotb_id: 164 },
-        { op: 'UPDATE', uid: 'pseudo', pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', hash: '1505A45A5EEBFC3AFAD1475A4739C8447A79420A83340559CE5A49F9891167BB', sig: '2vfmih7xhW/QLJ85PZH1Tc6j5fooIXca+yr/esnt0yvdk5LhEKrOB32JFqCctAoRNwpRjBdZ2Q8l15+In1rrDg==', created_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', written_on: '40000-000006C311D2677D101116287718395A2CBB7B94389004D19B0E4AC6DCE2DE5F', writtenOn: 40000, member: true,  wasMember: true, kick: false, wotb_id: 164 }
-      ])
-    })
-
-    it('should be able to trim data', async () => {
-      // The number of records should decrease
-      await blockchain.indexTrim(40000)
-      const countG5 = await blockchain.indexCount('i_index', { pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT' })
-      assert.equal(countG5, 2)
-      const reducedG5 = await blockchain.indexReduce('i_index', { pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT' })
-      assert.deepEqual(reducedG5, { op: 'UPDATE', uid: 'pseudo', pub: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', hash: '1505A45A5EEBFC3AFAD1475A4739C8447A79420A83340559CE5A49F9891167BB', sig: '2vfmih7xhW/QLJ85PZH1Tc6j5fooIXca+yr/esnt0yvdk5LhEKrOB32JFqCctAoRNwpRjBdZ2Q8l15+In1rrDg==', created_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855', written_on: '40000-000006C311D2677D101116287718395A2CBB7B94389004D19B0E4AC6DCE2DE5F', writtenOn: 40000, member: true,  wasMember: true, kick: false, wotb_id: 164 })
-    })
-  })
-
-  describe('SINDEX', () => {
-
-    it('should be able to index data', async () => {
-      await blockchain.recordIndex({
-        s_index: [
-          // Dividend
-          { op: 'CREATE', tx: null, identifier: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', pos: 35820, created_on: null, written_on: '35820-00000B363BC8F761EB5343660592D50B872FE1140B350C9780EF5BC6F9DD000B', writtenOn: 35820, written_time: 1500000000, amount: 500, base: 0, locktime: 0, consumed: false, conditions: 'SIG(CPEaW4BGNaBdx6FbAxjNQ9Po2apnX2bDvBXJT9yaZUMc)' },
-          { op: 'UPDATE', tx: null, identifier: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', pos: 35820, created_on: null, written_on: '35821-0000053C7B54AEFAEC4FCFB2763202ECD8382A635340BD622EDBC0CCC553F763', writtenOn: 35821, written_time: 1500000001, amount: 500, base: 0, locktime: 0, consumed: true,  conditions: 'SIG(CPEaW4BGNaBdx6FbAxjNQ9Po2apnX2bDvBXJT9yaZUMc)' },
-          // Transaction
-          { op: 'CREATE', tx: 'D01432C6D7D078CB566C08886FD92CA5D158433D7A8D971124973625BFAB78D9', identifier: 'D01432C6D7D078CB566C08886FD92CA5D158433D7A8D971124973625BFAB78D9', pos: 1, created_on: '33958-0000009CEC38916882EF46C40069EF227F1D7CB4B34EAD5298D84B6658FBB9FB', written_on: '30196-00000A8ABF13284452CD56C9DEC68124D4A31CE1BDD06819EB22E070EBDE1D2D', writtenOn: 30196, written_time: 1499000000, amount: 301, base: 0, locktime: 0, consumed: false, conditions: 'SIG(CPEaW4BGNaBdx6FbAxjNQ9Po2apnX2bDvBXJT9yaZUMc)' },
-          { op: 'UPDATE', tx: '3926D234037264654D9C4A2D44CDDC18998DC48262F3677F23DA5BA81BD530EA', identifier: 'D01432C6D7D078CB566C08886FD92CA5D158433D7A8D971124973625BFAB78D9', pos: 1, created_on: '33958-0000009CEC38916882EF46C40069EF227F1D7CB4B34EAD5298D84B6658FBB9FB', written_on: '30197-0000009CEC38916882EF46C40069EF227F1D7CB4B34EAD5298D84B6658FBB9FB', writtenOn: 30197, written_time: 1499000001, amount: 301, base: 0, locktime: 0, consumed: true,  conditions: 'SIG(CPEaW4BGNaBdx6FbAxjNQ9Po2apnX2bDvBXJT9yaZUMc)' }
-        ]
-      })
-    })
-
-    it('should be able to reduce data', async () => {
-      const reducedUD = await blockchain.indexReduce('s_index', { identifier: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', pos: 35820 })
-      const reducedTX = await blockchain.indexReduce('s_index', { identifier: 'D01432C6D7D078CB566C08886FD92CA5D158433D7A8D971124973625BFAB78D9', pos: 1 })
-      assert.deepEqual(reducedUD, { op: 'UPDATE', identifier: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', pos: 35820, written_on: '35821-0000053C7B54AEFAEC4FCFB2763202ECD8382A635340BD622EDBC0CCC553F763', writtenOn: 35821, written_time: 1500000001, amount: 500, base: 0, locktime: 0, consumed: true,  conditions: 'SIG(CPEaW4BGNaBdx6FbAxjNQ9Po2apnX2bDvBXJT9yaZUMc)' })
-      assert.deepEqual(reducedTX, { op: 'UPDATE', tx: '3926D234037264654D9C4A2D44CDDC18998DC48262F3677F23DA5BA81BD530EA', identifier: 'D01432C6D7D078CB566C08886FD92CA5D158433D7A8D971124973625BFAB78D9', pos: 1, created_on: '33958-0000009CEC38916882EF46C40069EF227F1D7CB4B34EAD5298D84B6658FBB9FB', written_on: '30197-0000009CEC38916882EF46C40069EF227F1D7CB4B34EAD5298D84B6658FBB9FB', writtenOn: 30197, written_time: 1499000001, amount: 301, base: 0, locktime: 0, consumed: true,  conditions: 'SIG(CPEaW4BGNaBdx6FbAxjNQ9Po2apnX2bDvBXJT9yaZUMc)' })
-    })
-
-    it('should be able to count data', async () => {
-      const countUD = await blockchain.indexCount('s_index', { identifier: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', pos: 35820 })
-      const countTX = await blockchain.indexCount('s_index', { identifier: 'D01432C6D7D078CB566C08886FD92CA5D158433D7A8D971124973625BFAB78D9', pos: 1 })
-      assert.equal(countUD, 2)
-      assert.equal(countTX, 2)
-    })
-
-    it('should be able to reduce grouped data', async () => {
-      const reducedBy = await blockchain.indexReduceGroupBy('s_index', { pos: { $gt: 0 } }, ['identifier', 'pos'])
-      assert.deepEqual(reducedBy, [
-        { op: 'UPDATE', tx: '3926D234037264654D9C4A2D44CDDC18998DC48262F3677F23DA5BA81BD530EA', identifier: 'D01432C6D7D078CB566C08886FD92CA5D158433D7A8D971124973625BFAB78D9', pos: 1, created_on: '33958-0000009CEC38916882EF46C40069EF227F1D7CB4B34EAD5298D84B6658FBB9FB', written_on: '30197-0000009CEC38916882EF46C40069EF227F1D7CB4B34EAD5298D84B6658FBB9FB', writtenOn: 30197, written_time: 1499000001, amount: 301, base: 0, locktime: 0, consumed: true,  conditions: 'SIG(CPEaW4BGNaBdx6FbAxjNQ9Po2apnX2bDvBXJT9yaZUMc)' },
-        { op: 'UPDATE', identifier: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', pos: 35820, written_on: '35821-0000053C7B54AEFAEC4FCFB2763202ECD8382A635340BD622EDBC0CCC553F763', writtenOn: 35821, written_time: 1500000001, amount: 500, base: 0, locktime: 0, consumed: true,  conditions: 'SIG(CPEaW4BGNaBdx6FbAxjNQ9Po2apnX2bDvBXJT9yaZUMc)' }
-      ])
-    })
-
-    it('should be able to trim data', async () => {
-      // The number of records should decrease
-      await blockchain.indexTrim(35000)
-      const countUD = await blockchain.indexCount('s_index', { identifier: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', pos: 35820 })
-      const countTX = await blockchain.indexCount('s_index', { identifier: 'D01432C6D7D078CB566C08886FD92CA5D158433D7A8D971124973625BFAB78D9', pos: 1 })
-      assert.equal(countUD, 2)
-      assert.equal(countTX, 0) // This index removes the lines marked `consumed`
-      const reducedUD = await blockchain.indexReduce('s_index', { identifier: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', pos: 35820 })
-      assert.deepEqual(reducedUD, { op: 'UPDATE', identifier: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', pos: 35820, written_on: '35821-0000053C7B54AEFAEC4FCFB2763202ECD8382A635340BD622EDBC0CCC553F763', writtenOn: 35821, written_time: 1500000001, amount: 500, base: 0, locktime: 0, consumed: true,  conditions: 'SIG(CPEaW4BGNaBdx6FbAxjNQ9Po2apnX2bDvBXJT9yaZUMc)' })
-    })
-  })
-
-  describe('CINDEX', () => {
-
-    it('should be able to index data', async () => {
-      await blockchain.recordIndex({
-        c_index: [
-          { op: 'CREATE', issuer: 'D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx', receiver: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: 0,  written_on: '0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855',  writtenOn: 0,  sig: 'MYWlBd2Hw3T/59BDz9HZECBuZ984C23F5lqUGluIUXsvXjsY4xKNqcN2x75s9rn++u4GEzZov6OznLZiHtbAAQ==', expires_on: 1552102327, expired_on: 0,          chainable_on: 1489419127 },
-          { op: 'UPDATE', issuer: 'D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx', receiver: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: 0,  written_on: '9-0000092C94D0257C61A2504092440600487B2C8BEE73F9C8763C9F351543887D',  writtenOn: 9,  sig: 'MYWlBd2Hw3T/59BDz9HZECBuZ984C23F5lqUGluIUXsvXjsY4xKNqcN2x75s9rn++u4GEzZov6OznLZiHtbAAQ==', expires_on: 1552102327, expired_on: 1552102400, chainable_on: 1489419127 },
-          { op: 'CREATE', issuer: 'EV4yZXAgmDd9rMsRCSH2MK7RHWty7CDB9tmHku3iRnEB', receiver: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: 11, written_on: '11-000019EC1161FC9FB1848A58A3137B9CD9A919E86B2394B9682BBC3FADB1AF1F', writtenOn: 11, sig: 'plFuA1vgXJh0CQ9MVCmOgfTfFb5u3qICMfgxVJEsyco+lmZTxaKuruSsRdhw3YZgJgfU6YwC+ta/RcgLF6DvDA==', expires_on: 1556866334, expired_on: 0,          chainable_on: 1494184082}
-        ]
-      })
-    })
-
-    it('should be able to reduce data', async () => {
-      const reducedC1 = await blockchain.indexReduce('c_index', { issuer: 'D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx', receiver: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: 0 })
-      const reducedC2 = await blockchain.indexReduce('c_index', { issuer: 'EV4yZXAgmDd9rMsRCSH2MK7RHWty7CDB9tmHku3iRnEB', receiver: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: 11 })
-      assert.deepEqual(reducedC1, { op: 'UPDATE', issuer: 'D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx', receiver: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: 0,  written_on: '9-0000092C94D0257C61A2504092440600487B2C8BEE73F9C8763C9F351543887D',  writtenOn: 9,  sig: 'MYWlBd2Hw3T/59BDz9HZECBuZ984C23F5lqUGluIUXsvXjsY4xKNqcN2x75s9rn++u4GEzZov6OznLZiHtbAAQ==', expires_on: 1552102327, expired_on: 1552102400, chainable_on: 1489419127 })
-      assert.deepEqual(reducedC2, { op: 'CREATE', issuer: 'EV4yZXAgmDd9rMsRCSH2MK7RHWty7CDB9tmHku3iRnEB', receiver: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: 11, written_on: '11-000019EC1161FC9FB1848A58A3137B9CD9A919E86B2394B9682BBC3FADB1AF1F', writtenOn: 11, sig: 'plFuA1vgXJh0CQ9MVCmOgfTfFb5u3qICMfgxVJEsyco+lmZTxaKuruSsRdhw3YZgJgfU6YwC+ta/RcgLF6DvDA==', expires_on: 1556866334, expired_on: 0,          chainable_on: 1494184082})
-    })
-
-    it('should be able to count data', async () => {
-      const countC1 = await blockchain.indexCount('c_index', { issuer: 'D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx', receiver: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: 0 })
-      const countC2 = await blockchain.indexCount('c_index', { issuer: 'EV4yZXAgmDd9rMsRCSH2MK7RHWty7CDB9tmHku3iRnEB', receiver: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: 11 })
-      assert.equal(countC1, 2)
-      assert.equal(countC2, 1)
-    })
-
-    it('should be able to reduce grouped data', async () => {
-      const reducedBy = await blockchain.indexReduceGroupBy('c_index', { created_on: { $gte: 0 } }, ['issuer', 'receiver', 'created_on'])
-      assert.deepEqual(reducedBy, [
-        { op: 'UPDATE', issuer: 'D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx', receiver: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: 0,  written_on: '9-0000092C94D0257C61A2504092440600487B2C8BEE73F9C8763C9F351543887D',  writtenOn: 9,  sig: 'MYWlBd2Hw3T/59BDz9HZECBuZ984C23F5lqUGluIUXsvXjsY4xKNqcN2x75s9rn++u4GEzZov6OznLZiHtbAAQ==', expires_on: 1552102327, expired_on: 1552102400, chainable_on: 1489419127 },
-        { op: 'CREATE', issuer: 'EV4yZXAgmDd9rMsRCSH2MK7RHWty7CDB9tmHku3iRnEB', receiver: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: 11, written_on: '11-000019EC1161FC9FB1848A58A3137B9CD9A919E86B2394B9682BBC3FADB1AF1F', writtenOn: 11, sig: 'plFuA1vgXJh0CQ9MVCmOgfTfFb5u3qICMfgxVJEsyco+lmZTxaKuruSsRdhw3YZgJgfU6YwC+ta/RcgLF6DvDA==', expires_on: 1556866334, expired_on: 0,          chainable_on: 1494184082}
-      ])
-    })
-
-    it('should be able to trim data', async () => {
-      // The number of records should decrease
-      await blockchain.indexTrim(10)
-      const countC1 = await blockchain.indexCount('c_index', { issuer: 'D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx', receiver: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: 0 })
-      const countC2 = await blockchain.indexCount('c_index', { issuer: 'EV4yZXAgmDd9rMsRCSH2MK7RHWty7CDB9tmHku3iRnEB', receiver: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: 11 })
-      assert.equal(countC1, 0) // This index removes the lines marked `expired_on`
-      assert.equal(countC2, 1)
-      const reducedC2 = await blockchain.indexReduce('c_index', { issuer: 'EV4yZXAgmDd9rMsRCSH2MK7RHWty7CDB9tmHku3iRnEB', receiver: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: 11 })
-      assert.deepEqual(reducedC2, { op: 'CREATE', issuer: 'EV4yZXAgmDd9rMsRCSH2MK7RHWty7CDB9tmHku3iRnEB', receiver: 'G5P7k5t764ybGfFGLnEAwwMDz6y2U4afagAmyJXgKFyT', created_on: 11, written_on: '11-000019EC1161FC9FB1848A58A3137B9CD9A919E86B2394B9682BBC3FADB1AF1F', writtenOn: 11, sig: 'plFuA1vgXJh0CQ9MVCmOgfTfFb5u3qICMfgxVJEsyco+lmZTxaKuruSsRdhw3YZgJgfU6YwC+ta/RcgLF6DvDA==', expires_on: 1556866334, expired_on: 0,          chainable_on: 1494184082})
-    })
-  })
-
-})
-- 
GitLab